Skip to content

Commit

Permalink
all: Add org-mode support
Browse files Browse the repository at this point in the history
Fixes #1483 
See #936
  • Loading branch information
curiouslychase authored and bep committed Feb 21, 2017
1 parent a3af4fe commit 86e8dd6
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 10 deletions.
6 changes: 3 additions & 3 deletions docs/content/content/summaries.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion docs/content/content/supported-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
13 changes: 11 additions & 2 deletions helpers/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -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))
}
2 changes: 2 additions & 0 deletions helpers/general.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ func GuessType(in string) string {
return "rst"
case "html", "htm":
return "html"
case "org":
return "org"
}

return "unknown"
Expand Down
1 change: 1 addition & 0 deletions helpers/general_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func TestGuessType(t *testing.T) {
{"mmark", "mmark"},
{"html", "html"},
{"htm", "html"},
{"org", "org"},
{"excel", "unknown"},
} {
result := GuessType(this.in)
Expand Down
10 changes: 10 additions & 0 deletions hugolib/handler_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func init() {
RegisterHandler(new(asciidocHandler))
RegisterHandler(new(rstHandler))
RegisterHandler(new(mmarkHandler))
RegisterHandler(new(orgHandler))
}

type basicPageHandler Handle
Expand Down Expand Up @@ -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()))
Expand Down
6 changes: 5 additions & 1 deletion hugolib/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions parser/frontmatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"errors"
"strings"

"github.com/chaseadamsio/goorgeous"
toml "github.com/pelletier/go-toml"

"gopkg.in/yaml.v2"
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
}
16 changes: 13 additions & 3 deletions parser/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"regexp"
"strings"
"unicode"

"github.com/chaseadamsio/goorgeous"
)

const (
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions vendor/vendor.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
"revision": "b896c45f5af983b1f416bdf3bb89c4f1f0926f69",
"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",
Expand Down

0 comments on commit 86e8dd6

Please sign in to comment.