hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 86e8dd62f0b1c8adf14e9369b089d209317aaf2d
parent a3af4fe46e1e1d184538a83bc8375154a9669316
Author: Chase Adams <realchaseadams@gmail.com>
Date:   Mon, 20 Feb 2017 23:46:03 -0800

all: Add org-mode support

Fixes #1483 
See #936 

Diffstat:
Mdocs/content/content/summaries.md | 6+++---
Mdocs/content/content/supported-formats.md | 2+-
Mhelpers/content.go | 13+++++++++++--
Mhelpers/general.go | 2++
Mhelpers/general_test.go | 1+
Mhugolib/handler_page.go | 10++++++++++
Mhugolib/page.go | 6+++++-
Mparser/frontmatter.go | 7+++++++
Mparser/page.go | 16+++++++++++++---
Mvendor/vendor.json | 6++++++
10 files changed, 59 insertions(+), 10 deletions(-)
diff --git a/docs/content/content/summaries.md b/docs/content/content/summaries.md
@@ -24,14 +24,14 @@ By default, Hugo automatically takes the first 70 words of your content as its s
 
 ## User-defined: manual summary split:
 
-Alternatively, you may add the <code>&#60;&#33;&#45;&#45;more&#45;&#45;&#62;</code> summary divider[^1] where you want to split the article.  Content prior to the summary divider will be used as that content's summary, and stored into the `.Summary` variable with all HTML formatting intact.
+Alternatively, you may add the <code>&#60;&#33;&#45;&#45;more&#45;&#45;&#62;</code> summary divider[^1] (for org content, use <code># more</code>) where you want to split the article.  Content prior to the summary divider will be used as that content's summary, and stored into the `.Summary` variable with all HTML formatting intact.
 
 [^1]: The **summary divider** is also called "more tag", "excerpt separator", etc. in other literature.
 
 * Pros: Freedom, precision, and improved rendering.  All formatting is preserved.
-* Cons: Need to remember to type <code>&#60;&#33;&#45;&#45;more&#45;&#45;&#62;</code> in your content file.  :-)
+* Cons: Need to remember to type <code>&#60;&#33;&#45;&#45;more&#45;&#45;&#62;</code> (or <code># more</code> for org content) in your content file.  :-)
 
-Be careful to enter <code>&#60;&#33;&#45;&#45;more&#45;&#45;&#62;</code> exactly, i.e. all lowercase with no whitespace, otherwise it would be treated as regular comment and ignored.
+Be careful to enter <code>&#60;&#33;&#45;&#45;more&#45;&#45;&#62;</code> (or <code># more</code> for org content) exactly, i.e. all lowercase with no whitespace, otherwise it would be treated as regular comment and ignored.
 
 If there is nothing but spaces and newlines after the summary divider then `.Truncated` will be false.
 
diff --git a/docs/content/content/supported-formats.md b/docs/content/content/supported-formats.md
@@ -13,7 +13,7 @@ weight: 15
 toc: true
 ---
 
-  Since 0.14, Hugo has defined a new concept called _external helpers_. It means that you can write your content using Asciidoc[tor], or reStructuredText. If you have files with associated extensions ([details](https://github.com/spf13/hugo/blob/77c60a3440806067109347d04eb5368b65ea0fe8/helpers/general.go#L65)), then Hugo will call external commands to generate the content.
+  Since 0.14, Hugo has defined a new concept called _external helpers_. It means that you can write your content using Asciidoc[tor], reStructuredText or Org-Mode. If you have files with associated extensions ([details](https://github.com/spf13/hugo/blob/77c60a3440806067109347d04eb5368b65ea0fe8/helpers/general.go#L65)), then Hugo will call external commands to generate the content (the exception being Org-Mode content, which is parsed natively).
 
   This means that you will have to install the associated tool on your machine to be able to use those formats.
 
diff --git a/helpers/content.go b/helpers/content.go
@@ -24,12 +24,12 @@ import (
 	"unicode"
 	"unicode/utf8"
 
-	"github.com/spf13/hugo/config"
-
+	"github.com/chaseadamsio/goorgeous"
 	"github.com/miekg/mmark"
 	"github.com/mitchellh/mapstructure"
 	"github.com/russross/blackfriday"
 	bp "github.com/spf13/hugo/bufferpool"
+	"github.com/spf13/hugo/config"
 	jww "github.com/spf13/jwalterweatherman"
 
 	"strings"
@@ -415,6 +415,8 @@ func (c ContentSpec) RenderBytes(ctx *RenderingContext) []byte {
 		return c.mmarkRender(ctx)
 	case "rst":
 		return getRstContent(ctx)
+	case "org":
+		return orgRender(ctx, c)
 	}
 }
 
@@ -663,3 +665,10 @@ func getRstContent(ctx *RenderingContext) []byte {
 
 	return result[bodyStart+7 : bodyEnd]
 }
+
+func orgRender(ctx *RenderingContext, c ContentSpec) []byte {
+	content := ctx.Content
+	cleanContent := bytes.Replace(content, []byte("# more"), []byte(""), 1)
+	return goorgeous.Org(cleanContent,
+		c.getHTMLRenderer(blackfriday.HTML_TOC, ctx))
+}
diff --git a/helpers/general.go b/helpers/general.go
@@ -80,6 +80,8 @@ func GuessType(in string) string {
 		return "rst"
 	case "html", "htm":
 		return "html"
+	case "org":
+		return "org"
 	}
 
 	return "unknown"
diff --git a/helpers/general_test.go b/helpers/general_test.go
@@ -36,6 +36,7 @@ func TestGuessType(t *testing.T) {
 		{"mmark", "mmark"},
 		{"html", "html"},
 		{"htm", "html"},
+		{"org", "org"},
 		{"excel", "unknown"},
 	} {
 		result := GuessType(this.in)
diff --git a/hugolib/handler_page.go b/hugolib/handler_page.go
@@ -26,6 +26,7 @@ func init() {
 	RegisterHandler(new(asciidocHandler))
 	RegisterHandler(new(rstHandler))
 	RegisterHandler(new(mmarkHandler))
+	RegisterHandler(new(orgHandler))
 }
 
 type basicPageHandler Handle
@@ -110,6 +111,15 @@ func (h mmarkHandler) PageConvert(p *Page) HandledResult {
 	return commonConvert(p)
 }
 
+type orgHandler struct {
+	basicPageHandler
+}
+
+func (h orgHandler) Extensions() []string { return []string{"org"} }
+func (h orgHandler) PageConvert(p *Page) HandledResult {
+	return commonConvert(p)
+}
+
 func commonConvert(p *Page) HandledResult {
 	if p.rendered {
 		panic(fmt.Sprintf("Page %q already rendered, does not need conversion", p.BaseFileName()))
diff --git a/hugolib/page.go b/hugolib/page.go
@@ -420,7 +420,11 @@ var (
 // rendering engines.
 // TODO(bep) inline replace
 func (p *Page) replaceDivider(content []byte) []byte {
-	sections := bytes.Split(content, helpers.SummaryDivider)
+	summaryDivider := helpers.SummaryDivider
+	if p.Ext() == "org" {
+		summaryDivider = []byte("# more")
+	}
+	sections := bytes.Split(content, summaryDivider)
 
 	// If the raw content has nothing but whitespace after the summary
 	// marker then the page shouldn't be marked as truncated.  This check
diff --git a/parser/frontmatter.go b/parser/frontmatter.go
@@ -19,6 +19,7 @@ import (
 	"errors"
 	"strings"
 
+	"github.com/chaseadamsio/goorgeous"
 	toml "github.com/pelletier/go-toml"
 
 	"gopkg.in/yaml.v2"
@@ -154,6 +155,8 @@ func DetectFrontMatter(mark rune) (f *frontmatterType) {
 		return &frontmatterType{[]byte(TOMLDelim), []byte(TOMLDelim), HandleTOMLMetaData, false}
 	case '{':
 		return &frontmatterType{[]byte{'{'}, []byte{'}'}, HandleJSONMetaData, true}
+	case '#':
+		return &frontmatterType{[]byte("#+"), []byte("\n"), HandleOrgMetaData, false}
 	default:
 		return nil
 	}
@@ -189,3 +192,7 @@ func HandleJSONMetaData(datum []byte) (interface{}, error) {
 	err := json.Unmarshal(datum, &f)
 	return f, err
 }
+
+func HandleOrgMetaData(datum []byte) (interface{}, error) {
+	return goorgeous.OrgHeaders(datum)
+}
diff --git a/parser/page.go b/parser/page.go
@@ -21,6 +21,8 @@ import (
 	"regexp"
 	"strings"
 	"unicode"
+
+	"github.com/chaseadamsio/goorgeous"
 )
 
 const (
@@ -91,9 +93,11 @@ func (p *page) Metadata() (meta interface{}, err error) {
 
 	if len(frontmatter) != 0 {
 		fm := DetectFrontMatter(rune(frontmatter[0]))
-		meta, err = fm.Parse(frontmatter)
-		if err != nil {
-			return
+		if fm != nil {
+			meta, err = fm.Parse(frontmatter)
+			if err != nil {
+				return
+			}
 		}
 	}
 	return
@@ -129,6 +133,12 @@ func ReadFrom(r io.Reader) (p Page, err error) {
 			return nil, err
 		}
 		newp.frontmatter = fm
+	} else if newp.render && goorgeous.IsKeyword(firstLine) {
+		fm, err := goorgeous.ExtractOrgHeaders(reader)
+		if err != nil {
+			return nil, err
+		}
+		newp.frontmatter = fm
 	}
 
 	content, err := extractContent(reader)
diff --git a/vendor/vendor.json b/vendor/vendor.json
@@ -33,6 +33,12 @@
 			"revisionTime": "2016-04-08T19:03:23Z"
 		},
 		{
+			"checksumSHA1": "RxIwAgjIuBpwde5BCZRLLK7VRG8=",
+			"path": "github.com/chaseadamsio/goorgeous",
+			"revision": "72a06e1b07db57f3931f5a9c00f3f04e636ad0a8",
+			"revisionTime": "2017-02-17T13:03:04Z"
+		},
+		{
 			"checksumSHA1": "ntacCkWfMT63DaehXLG5FeXWyNM=",
 			"path": "github.com/cpuguy83/go-md2man/md2man",
 			"revision": "a65d4d2de4d5f7c74868dfa9b202a3c8be315aaa",