mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
Merge pull request #2 from tychoish/yaml-rst-support
Switching to YAML and adding support for optional restructured text parsing
This commit is contained in:
commit
94e577740d
22 changed files with 200 additions and 169 deletions
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"Indexes" : {"tag": "tags"},
|
|
||||||
"BaseUrl" : "http://localhost"
|
|
||||||
}
|
|
4
docs/config.yaml
Normal file
4
docs/config.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
Indexes:
|
||||||
|
tag: 'tags'
|
||||||
|
BaseUrl: 'http://localhost'
|
||||||
|
...
|
|
@ -1,19 +1,21 @@
|
||||||
{
|
---
|
||||||
"title": "Configuring Hugo",
|
title: "Configuring Hugo"
|
||||||
"Pubdate": "2013-07-01"
|
pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
The directory structure and templates provide the majority of the
|
The directory structure and templates provide the majority of the
|
||||||
configuration for a site. In fact a config file isn't even needed for many websites
|
configuration for a site. In fact a config file isn't even needed for many websites
|
||||||
since the defaults used follow commonly used patterns.
|
since the defaults used follow commonly used patterns.
|
||||||
|
|
||||||
The following is an example of a config file with the default values
|
The following is an example of a config file with the default values:
|
||||||
|
|
||||||
|
SourceDir: "content"
|
||||||
|
LayoutDir: "layouts"
|
||||||
|
PublishDir: "public"
|
||||||
|
BuildDrafts: false
|
||||||
|
Tags:
|
||||||
|
category: "categories"
|
||||||
|
tag: "tags"
|
||||||
|
BaseUrl: "http://yourSite.com/"
|
||||||
|
...
|
||||||
|
|
||||||
{
|
|
||||||
"SourceDir" : "content",
|
|
||||||
"LayoutDir" : "layouts",
|
|
||||||
"PublishDir" : "public",
|
|
||||||
"BuildDrafts" : false,
|
|
||||||
"Tags" : { "category" : "categories", "tag" : "tags" },
|
|
||||||
"BaseUrl" : "http://yourSite.com/"
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "Contributing to Hugo",
|
title: "Contributing to Hugo"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
1. Fork it from https://github.com/spf13/hugo
|
1. Fork it from https://github.com/spf13/hugo
|
||||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "Contributors",
|
title: "Contributors"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
Hugo was built with love and golang by:
|
Hugo was built with love and golang by:
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
{
|
---
|
||||||
"title": "Example Content File",
|
title: "Example Content File"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
Somethings are better shown than explained. The following is a very basic example of a content file:
|
Somethings are better shown than explained. The following is a very basic example of a content file:
|
||||||
|
|
||||||
**mysite/project/nitro.md <- http://mysite.com/project/nitro.html**
|
**mysite/project/nitro.md <- http://mysite.com/project/nitro.html**
|
||||||
|
|
||||||
{
|
---
|
||||||
"Title": "Nitro : A quick and simple profiler for golang",
|
Title: "Nitro : A quick and simple profiler for golang"
|
||||||
"Description": "",
|
Description": ""
|
||||||
"Keywords": [ "Development", "golang", "profiling" ],
|
Keywords": [ "Development", "golang", "profiling" ]
|
||||||
"Tags": [ "Development", "golang", "profiling" ],
|
Tags": [ "Development", "golang", "profiling" ]
|
||||||
"Pubdate": "2013-06-19",
|
Pubdate": "2013-06-19"
|
||||||
"Topics": [ "Development", "GoLang" ],
|
Topics": [ "Development", "GoLang" ]
|
||||||
"Slug": "nitro",
|
Slug": "nitro"
|
||||||
"project_url": "http://github.com/spf13/nitro"
|
project_url": "http://github.com/spf13/nitro"
|
||||||
}
|
...
|
||||||
|
|
||||||
# Nitro
|
# Nitro
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
{
|
---
|
||||||
"title": "Front Matter",
|
title: "Front Matter"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
The front matter is one of the features that gives Hugo it's strength. It enables
|
The front matter is one of the features that gives Hugo it's strength. It enables
|
||||||
you to include the meta data of the content right with it. Hugo supports a few
|
you to include the meta data of the content right with it. Hugo supports a few
|
||||||
different formats. The main format supported is JSON. Here is an example:
|
different formats. The main format supported is YAML. Here is an example:
|
||||||
|
|
||||||
{
|
---
|
||||||
"Title": "spf13-vim 3.0 release and new website",
|
Title: "spf13-vim 3.0 release and new website"
|
||||||
"Description": "spf13-vim is a cross platform distribution of vim plugins and resources for Vim.",
|
Description: "spf13-vim is a cross platform distribution of vim plugins and resources for Vim."
|
||||||
"Tags": [ ".vimrc", "plugins", "spf13-vim", "vim" ],
|
Tags: [ ".vimrc", "plugins", "spf13-vim", "vim" ]
|
||||||
"Pubdate": "2012-04-06",
|
Pubdate: "2012-04-06"
|
||||||
"Categories": [ "Development", "VIM" ],
|
Categories:
|
||||||
"Slug": "spf13-vim-3-0-release-and-new-website"
|
- "Development"
|
||||||
}
|
- "VIM"
|
||||||
|
Slug: "spf13-vim-3-0-release-and-new-website"
|
||||||
|
...
|
||||||
|
|
||||||
### Variables
|
### Variables
|
||||||
|
|
||||||
There are a few predefined variables that Hugo is aware of and utilizes. The user can also create
|
There are a few predefined variables that Hugo is aware of and utilizes. The user can also create
|
||||||
any variable they want to. These will be placed into the `.Params` variable available to the templates.
|
any variable they want to. These will be placed into the `.Params` variable available to the templates.
|
||||||
|
|
||||||
|
@ -31,6 +34,8 @@ any variable they want to. These will be placed into the `.Params` variable avai
|
||||||
|
|
||||||
**Draft** If true the content will not be rendered unless `hugo` is called with -d<br>
|
**Draft** If true the content will not be rendered unless `hugo` is called with -d<br>
|
||||||
**Type** The type of the content (will be derived from the directory automatically if unset).<br>
|
**Type** The type of the content (will be derived from the directory automatically if unset).<br>
|
||||||
|
**Markup** (Experimental) Specify "rst" for reStructuredText (requires
|
||||||
|
`rst2html`,) or "md" (default) for the Markdown.<br>
|
||||||
**Slug** The token to appear in the tail of the url.<br>
|
**Slug** The token to appear in the tail of the url.<br>
|
||||||
*or*<br>
|
*or*<br>
|
||||||
**Url** The full path to the content from the web root.<br>
|
**Url** The full path to the content from the web root.<br>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
---
|
||||||
"title": "Installing Hugo",
|
title: "Installing Hugo"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
Hugo is written in GoLang with support for Windows, Linux, FreeBSD and OSX.
|
Hugo is written in GoLang with support for Windows, Linux, FreeBSD and OSX.
|
||||||
|
|
||||||
The latest release can be found at [hugo releases](https://github.com/spf13/hugo/releases).
|
The latest release can be found at [hugo releases](https://github.com/spf13/hugo/releases).
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "License",
|
title: "License"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
Hugo is released under the Simple Public License.
|
Hugo is released under the Simple Public License.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "Organization",
|
title: "Organization"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
Hugo uses markdown files with headers commonly called the front matter. Hugo respects the organization
|
Hugo uses markdown files with headers commonly called the front matter. Hugo respects the organization
|
||||||
that you provide for your content to minimize any extra configuration, though this can be overridden
|
that you provide for your content to minimize any extra configuration, though this can be overridden
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "Release Notes",
|
title: "Release Notes"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
|
...
|
||||||
}
|
|
||||||
|
|
||||||
* **0.7.0** July 4, 2013
|
* **0.7.0** July 4, 2013
|
||||||
* Hugo now includes a simple server
|
* Hugo now includes a simple server
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "Roadmap",
|
title: "Roadmap"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
In no particular order, here is what I'm working on:
|
In no particular order, here is what I'm working on:
|
||||||
|
|
||||||
|
|
14
docs/content/doc/rst.rst
Normal file
14
docs/content/doc/rst.rst
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
Markup: 'rst'
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
==============
|
||||||
|
This is a Test
|
||||||
|
==============
|
||||||
|
|
||||||
|
|
||||||
|
Really
|
||||||
|
------
|
||||||
|
|
||||||
|
text *here* and **HERE**.
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "Shortcodes",
|
title: "Shortcodes"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
Because Hugo uses markdown for it's content format, it was clear that there's a lot of things that
|
Because Hugo uses markdown for it's content format, it was clear that there's a lot of things that
|
||||||
markdown doesn't support well. This is good, the simple nature of markdown is exactly why we chose it.
|
markdown doesn't support well. This is good, the simple nature of markdown is exactly why we chose it.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "Source Directory Organization",
|
title: "Source Directory Organization"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
Hugo takes a single directory and uses it as the input for creating a complete website.
|
Hugo takes a single directory and uses it as the input for creating a complete website.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "Templates",
|
title: "Templates"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
Hugo uses the excellent golang html/template library for it's template engine. It is an extremely
|
Hugo uses the excellent golang html/template library for it's template engine. It is an extremely
|
||||||
lightweight engine that provides a very small amount of logic. In our
|
lightweight engine that provides a very small amount of logic. In our
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "Using Hugo",
|
title: "Using Hugo"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
Make sure either hugo is in your path or provide a path to it.
|
Make sure either hugo is in your path or provide a path to it.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
---
|
||||||
"title": "Variables",
|
title: "Variables"
|
||||||
"Pubdate": "2013-07-01"
|
Pubdate: "2013-07-01"
|
||||||
}
|
...
|
||||||
|
|
||||||
Hugo makes a set of values available to the templates. Go templates are context based. The following
|
Hugo makes a set of values available to the templates. Go templates are context based. The following
|
||||||
are available in the context for the templates.
|
are available in the context for the templates.
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
package hugolib
|
package hugolib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"launchpad.net/goyaml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
@ -55,7 +55,7 @@ func SetupConfig(cfgfile *string, path *string) *Config {
|
||||||
|
|
||||||
file, err := ioutil.ReadFile(configPath)
|
file, err := ioutil.ReadFile(configPath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if err := json.Unmarshal(file, &c); err != nil {
|
if err := goyaml.Unmarshal(file, &c); err != nil {
|
||||||
fmt.Printf("Error parsing config: %s", err)
|
fmt.Printf("Error parsing config: %s", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ func interfaceToBool(i interface{}) bool {
|
||||||
case bool:
|
case bool:
|
||||||
return b
|
return b
|
||||||
default:
|
default:
|
||||||
Error("Only Boolean values are supported for this JSON key")
|
Error("Only Boolean values are supported for this YAML key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -106,7 +106,7 @@ func interfaceToString(i interface{}) string {
|
||||||
case string:
|
case string:
|
||||||
return s
|
return s
|
||||||
default:
|
default:
|
||||||
Error("Only Strings are supported for this JSON key")
|
Error("Only Strings are supported for this YAML key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
148
hugolib/page.go
148
hugolib/page.go
|
@ -16,11 +16,13 @@ package hugolib
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"launchpad.net/goyaml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/theplant/blackfriday"
|
"github.com/theplant/blackfriday"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -30,16 +32,17 @@ import (
|
||||||
var _ = filepath.Base("")
|
var _ = filepath.Base("")
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
Status string
|
Status string
|
||||||
Images []string
|
Images []string
|
||||||
Content template.HTML
|
Content template.HTML
|
||||||
Summary template.HTML
|
Summary template.HTML
|
||||||
RawMarkdown string // TODO should be []byte
|
RawMarkdown string // TODO should be []byte
|
||||||
Params map[string]interface{}
|
Params map[string]interface{}
|
||||||
RenderedContent *bytes.Buffer
|
RenderedContent *bytes.Buffer
|
||||||
contentType string
|
contentType string
|
||||||
Draft bool
|
Draft bool
|
||||||
Tmpl *template.Template
|
Tmpl *template.Template
|
||||||
|
Markup string
|
||||||
PageMeta
|
PageMeta
|
||||||
File
|
File
|
||||||
Position
|
Position
|
||||||
|
@ -64,12 +67,12 @@ type Position struct {
|
||||||
|
|
||||||
type Pages []*Page
|
type Pages []*Page
|
||||||
|
|
||||||
func (p Pages) Len() int { return len(p) }
|
func (p Pages) Len() int { return len(p) }
|
||||||
func (p Pages) Less(i, j int) bool { return p[i].Date.Unix() > p[j].Date.Unix() }
|
func (p Pages) Less(i, j int) bool { return p[i].Date.Unix() > p[j].Date.Unix() }
|
||||||
func (p Pages) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
func (p Pages) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||||
|
|
||||||
// TODO eliminate unnecessary things
|
// TODO eliminate unnecessary things
|
||||||
func (p Pages) Sort() { sort.Sort(p) }
|
func (p Pages) Sort() { sort.Sort(p) }
|
||||||
func (p Pages) Limit(n int) Pages { return p[0:n] }
|
func (p Pages) Limit(n int) Pages { return p[0:n] }
|
||||||
|
|
||||||
func initializePage(filename string) (page Page) {
|
func initializePage(filename string) (page Page) {
|
||||||
|
@ -80,6 +83,7 @@ func initializePage(filename string) (page Page) {
|
||||||
page.Extension = "html"
|
page.Extension = "html"
|
||||||
page.Params = make(map[string]interface{})
|
page.Params = make(map[string]interface{})
|
||||||
page.Keywords = make([]string, 10, 30)
|
page.Keywords = make([]string, 10, 30)
|
||||||
|
page.Markup = "md"
|
||||||
page.setSection()
|
page.setSection()
|
||||||
|
|
||||||
return page
|
return page
|
||||||
|
@ -141,36 +145,47 @@ func (p *Page) analyzePage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO //rewrite to use byte methods instead
|
// TODO //rewrite to use byte methods instead
|
||||||
|
func (page *Page) parseYamlMetaData(data []byte) ([]string, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
datum, lines := splitPageContent(data, "---", "...")
|
||||||
|
|
||||||
|
err = page.handleMetaData(page.handleYamlMetaData([]byte(strings.Join(datum, "\n"))))
|
||||||
|
return lines, err
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func (page *Page) parseJsonMetaData(data []byte) ([]string, error) {
|
func (page *Page) parseJsonMetaData(data []byte) ([]string, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
datum, lines := splitPageContent(data, "{", "}")
|
||||||
|
|
||||||
|
err = page.handleMetaData(page.handleJsonMetaData([]byte(strings.Join(datum, "\n"))))
|
||||||
|
return lines, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitPageContent(data []byte, start string, end string) ([]string, []string) {
|
||||||
lines := strings.Split(string(data), "\n")
|
lines := strings.Split(string(data), "\n")
|
||||||
datum := lines[0:]
|
datum := lines[0:]
|
||||||
|
|
||||||
// go through content parse between "{" and "}"
|
|
||||||
// must be on their own lines (for now)
|
|
||||||
var found = 0
|
var found = 0
|
||||||
for i, line := range lines {
|
for i, line := range lines {
|
||||||
line = strings.TrimSpace(line)
|
|
||||||
|
|
||||||
if line == "{" {
|
if strings.HasPrefix(line, start) {
|
||||||
found += 1
|
found += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if line == "}" {
|
if strings.HasPrefix(line, end) {
|
||||||
found -= 1
|
found -= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if found == 0 {
|
if found == 0 {
|
||||||
datum = lines[0 : i+1]
|
datum = lines[1: i+1]
|
||||||
lines = lines[i+1:]
|
lines = lines[i+1:]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return datum, lines
|
||||||
err = page.handleJsonMetaData([]byte(strings.Join(datum, "\n")))
|
|
||||||
|
|
||||||
return lines, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Page) Permalink() template.HTML {
|
func (p *Page) Permalink() template.HTML {
|
||||||
|
@ -185,12 +200,24 @@ func (p *Page) Permalink() template.HTML {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (page *Page) handleJsonMetaData(datum []byte) error {
|
func (page *Page) handleYamlMetaData(datum []byte) interface{} {
|
||||||
|
m := map[string]interface{}{}
|
||||||
|
if err := goyaml.Unmarshal(datum, &m); err != nil {
|
||||||
|
return fmt.Errorf("Invalid YAML in %s \nError parsing page meta data: %s", page.FileName, err)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (page *Page) handleJsonMetaData(datum []byte) interface{} {
|
||||||
var f interface{}
|
var f interface{}
|
||||||
if err := json.Unmarshal(datum, &f); err != nil {
|
if err := json.Unmarshal(datum, &f); err != nil {
|
||||||
return fmt.Errorf("Invalide JSON in $v \nError parsing page meta data: %s", page.FileName, err)
|
return fmt.Errorf("Invalide JSON in $v \nError parsing page meta data: %s", page.FileName, err)
|
||||||
}
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (page *Page) handleMetaData(f interface{}) error {
|
||||||
m := f.(map[string]interface{})
|
m := f.(map[string]interface{})
|
||||||
|
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
|
@ -216,6 +243,8 @@ func (page *Page) handleJsonMetaData(datum []byte) error {
|
||||||
page.Draft = interfaceToBool(v)
|
page.Draft = interfaceToBool(v)
|
||||||
case "layout":
|
case "layout":
|
||||||
page.layout = interfaceToString(v)
|
page.layout = interfaceToString(v)
|
||||||
|
case "markup":
|
||||||
|
page.Markup = interfaceToString(v)
|
||||||
case "status":
|
case "status":
|
||||||
page.Status = interfaceToString(v)
|
page.Status = interfaceToString(v)
|
||||||
default:
|
default:
|
||||||
|
@ -236,8 +265,8 @@ func (page *Page) handleJsonMetaData(datum []byte) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Printer(page.Params)
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (page *Page) GetParam(key string) interface{} {
|
func (page *Page) GetParam(key string) interface{} {
|
||||||
|
@ -256,47 +285,6 @@ func (page *Page) GetParam(key string) interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (page *Page) parseFileMetaData(data []byte) ([]string, error) {
|
|
||||||
lines := strings.Split(string(data), "\n")
|
|
||||||
|
|
||||||
// go through content parse from --- to ---
|
|
||||||
var found = 0
|
|
||||||
for i, line := range lines {
|
|
||||||
line = strings.TrimSpace(line)
|
|
||||||
|
|
||||||
if found == 1 {
|
|
||||||
// parse line for param
|
|
||||||
colonIndex := strings.Index(line, ":")
|
|
||||||
if colonIndex > 0 {
|
|
||||||
key := strings.TrimSpace(line[:colonIndex])
|
|
||||||
value := strings.TrimSpace(line[colonIndex+1:])
|
|
||||||
value = strings.Trim(value, "\"") //remove quotes
|
|
||||||
switch key {
|
|
||||||
case "title":
|
|
||||||
page.Title = value
|
|
||||||
case "layout":
|
|
||||||
page.layout = value
|
|
||||||
case "extension":
|
|
||||||
page.Extension = "." + value
|
|
||||||
default:
|
|
||||||
page.Params[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if found >= 2 {
|
|
||||||
// params over
|
|
||||||
lines = lines[i:]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if line == "---" {
|
|
||||||
found += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lines, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (page *Page) Err(message string) {
|
func (page *Page) Err(message string) {
|
||||||
fmt.Println(page.FileName + " : " + message)
|
fmt.Println(page.FileName + " : " + message)
|
||||||
}
|
}
|
||||||
|
@ -306,10 +294,10 @@ func (page *Page) parseFileHeading(data []byte) ([]string, error) {
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
page.Err("Empty File, skipping")
|
page.Err("Empty File, skipping")
|
||||||
} else {
|
} else {
|
||||||
if data[0] == '-' {
|
if data[0] == '{' {
|
||||||
return page.parseFileMetaData(data)
|
return page.parseJsonMetaData(data)
|
||||||
}
|
}
|
||||||
return page.parseJsonMetaData(data)
|
return page.parseYamlMetaData(data)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -352,7 +340,12 @@ func (page *Page) buildPageFromFile() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
page.convertMarkdown(content)
|
switch page.Markup {
|
||||||
|
case "md":
|
||||||
|
page.convertMarkdown(content)
|
||||||
|
case "rst":
|
||||||
|
page.convertRestructuredText(content)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,3 +372,20 @@ func (page *Page) convertMarkdown(lines []string) {
|
||||||
page.Content = template.HTML(content)
|
page.Content = template.HTML(content)
|
||||||
page.Summary = template.HTML(TruncateWordsToWholeSentence(StripHTML(StripShortcodes(content)), summaryLength))
|
page.Summary = template.HTML(TruncateWordsToWholeSentence(StripHTML(StripShortcodes(content)), summaryLength))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (page *Page) convertRestructuredText(lines []string) {
|
||||||
|
|
||||||
|
page.RawMarkdown = strings.Join(lines, " ")
|
||||||
|
|
||||||
|
cmd := exec.Command("rst2html.py", "--template=/tmp/template.txt")
|
||||||
|
cmd.Stdin = strings.NewReader(page.RawMarkdown)
|
||||||
|
var out bytes.Buffer
|
||||||
|
cmd.Stdout = &out
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
content := out.String()
|
||||||
|
page.Content = template.HTML(content)
|
||||||
|
page.Summary = template.HTML(TruncateWordsToWholeSentence(StripHTML(StripShortcodes(content)), summaryLength))
|
||||||
|
}
|
||||||
|
|
6
main.go
6
main.go
|
@ -14,10 +14,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"./hugolib"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/howeyc/fsnotify"
|
"github.com/howeyc/fsnotify"
|
||||||
"github.com/spf13/hugo/hugolib"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -26,12 +26,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
cfgFiledefault = "config.json"
|
cfgFiledefault = "config.yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
baseUrl = flag.String("b", "", "hostname (and path) to the root eg. http://spf13.com/")
|
baseUrl = flag.String("b", "", "hostname (and path) to the root eg. http://spf13.com/")
|
||||||
cfgfile = flag.String("c", cfgFiledefault, "config file (default is path/config.json)")
|
cfgfile = flag.String("c", cfgFiledefault, "config file (default is path/config.yaml)")
|
||||||
checkMode = flag.Bool("k", false, "analyze content and provide feedback")
|
checkMode = flag.Bool("k", false, "analyze content and provide feedback")
|
||||||
draft = flag.Bool("d", false, "include content marked as draft")
|
draft = flag.Bool("d", false, "include content marked as draft")
|
||||||
help = flag.Bool("h", false, "show this help")
|
help = flag.Bool("h", false, "show this help")
|
||||||
|
|
Loading…
Reference in a new issue