parent
a3af4fe46e
commit
86e8dd62f0
10 changed files with 59 additions and 10 deletions
|
@ -24,14 +24,14 @@ By default, Hugo automatically takes the first 70 words of your content as its s
|
||||||
|
|
||||||
## User-defined: manual summary split:
|
## User-defined: manual summary split:
|
||||||
|
|
||||||
Alternatively, you may add the <code><!--more--></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><!--more--></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.
|
[^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.
|
* Pros: Freedom, precision, and improved rendering. All formatting is preserved.
|
||||||
* Cons: Need to remember to type <code><!--more--></code> in your content file. :-)
|
* Cons: Need to remember to type <code><!--more--></code> (or <code># more</code> for org content) in your content file. :-)
|
||||||
|
|
||||||
Be careful to enter <code><!--more--></code> exactly, i.e. all lowercase with no whitespace, otherwise it would be treated as regular comment and ignored.
|
Be careful to enter <code><!--more--></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.
|
If there is nothing but spaces and newlines after the summary divider then `.Truncated` will be false.
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ weight: 15
|
||||||
toc: true
|
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.
|
This means that you will have to install the associated tool on your machine to be able to use those formats.
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,12 @@ import (
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/spf13/hugo/config"
|
"github.com/chaseadamsio/goorgeous"
|
||||||
|
|
||||||
"github.com/miekg/mmark"
|
"github.com/miekg/mmark"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
"github.com/russross/blackfriday"
|
"github.com/russross/blackfriday"
|
||||||
bp "github.com/spf13/hugo/bufferpool"
|
bp "github.com/spf13/hugo/bufferpool"
|
||||||
|
"github.com/spf13/hugo/config"
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
jww "github.com/spf13/jwalterweatherman"
|
||||||
|
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -415,6 +415,8 @@ func (c ContentSpec) RenderBytes(ctx *RenderingContext) []byte {
|
||||||
return c.mmarkRender(ctx)
|
return c.mmarkRender(ctx)
|
||||||
case "rst":
|
case "rst":
|
||||||
return getRstContent(ctx)
|
return getRstContent(ctx)
|
||||||
|
case "org":
|
||||||
|
return orgRender(ctx, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,3 +665,10 @@ func getRstContent(ctx *RenderingContext) []byte {
|
||||||
|
|
||||||
return result[bodyStart+7 : bodyEnd]
|
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))
|
||||||
|
}
|
||||||
|
|
|
@ -80,6 +80,8 @@ func GuessType(in string) string {
|
||||||
return "rst"
|
return "rst"
|
||||||
case "html", "htm":
|
case "html", "htm":
|
||||||
return "html"
|
return "html"
|
||||||
|
case "org":
|
||||||
|
return "org"
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown"
|
return "unknown"
|
||||||
|
|
|
@ -36,6 +36,7 @@ func TestGuessType(t *testing.T) {
|
||||||
{"mmark", "mmark"},
|
{"mmark", "mmark"},
|
||||||
{"html", "html"},
|
{"html", "html"},
|
||||||
{"htm", "html"},
|
{"htm", "html"},
|
||||||
|
{"org", "org"},
|
||||||
{"excel", "unknown"},
|
{"excel", "unknown"},
|
||||||
} {
|
} {
|
||||||
result := GuessType(this.in)
|
result := GuessType(this.in)
|
||||||
|
|
|
@ -26,6 +26,7 @@ func init() {
|
||||||
RegisterHandler(new(asciidocHandler))
|
RegisterHandler(new(asciidocHandler))
|
||||||
RegisterHandler(new(rstHandler))
|
RegisterHandler(new(rstHandler))
|
||||||
RegisterHandler(new(mmarkHandler))
|
RegisterHandler(new(mmarkHandler))
|
||||||
|
RegisterHandler(new(orgHandler))
|
||||||
}
|
}
|
||||||
|
|
||||||
type basicPageHandler Handle
|
type basicPageHandler Handle
|
||||||
|
@ -110,6 +111,15 @@ func (h mmarkHandler) PageConvert(p *Page) HandledResult {
|
||||||
return commonConvert(p)
|
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 {
|
func commonConvert(p *Page) HandledResult {
|
||||||
if p.rendered {
|
if p.rendered {
|
||||||
panic(fmt.Sprintf("Page %q already rendered, does not need conversion", p.BaseFileName()))
|
panic(fmt.Sprintf("Page %q already rendered, does not need conversion", p.BaseFileName()))
|
||||||
|
|
|
@ -420,7 +420,11 @@ var (
|
||||||
// rendering engines.
|
// rendering engines.
|
||||||
// TODO(bep) inline replace
|
// TODO(bep) inline replace
|
||||||
func (p *Page) replaceDivider(content []byte) []byte {
|
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
|
// If the raw content has nothing but whitespace after the summary
|
||||||
// marker then the page shouldn't be marked as truncated. This check
|
// marker then the page shouldn't be marked as truncated. This check
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/chaseadamsio/goorgeous"
|
||||||
toml "github.com/pelletier/go-toml"
|
toml "github.com/pelletier/go-toml"
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
@ -154,6 +155,8 @@ func DetectFrontMatter(mark rune) (f *frontmatterType) {
|
||||||
return &frontmatterType{[]byte(TOMLDelim), []byte(TOMLDelim), HandleTOMLMetaData, false}
|
return &frontmatterType{[]byte(TOMLDelim), []byte(TOMLDelim), HandleTOMLMetaData, false}
|
||||||
case '{':
|
case '{':
|
||||||
return &frontmatterType{[]byte{'{'}, []byte{'}'}, HandleJSONMetaData, true}
|
return &frontmatterType{[]byte{'{'}, []byte{'}'}, HandleJSONMetaData, true}
|
||||||
|
case '#':
|
||||||
|
return &frontmatterType{[]byte("#+"), []byte("\n"), HandleOrgMetaData, false}
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -189,3 +192,7 @@ func HandleJSONMetaData(datum []byte) (interface{}, error) {
|
||||||
err := json.Unmarshal(datum, &f)
|
err := json.Unmarshal(datum, &f)
|
||||||
return f, err
|
return f, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HandleOrgMetaData(datum []byte) (interface{}, error) {
|
||||||
|
return goorgeous.OrgHeaders(datum)
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/chaseadamsio/goorgeous"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -91,9 +93,11 @@ func (p *page) Metadata() (meta interface{}, err error) {
|
||||||
|
|
||||||
if len(frontmatter) != 0 {
|
if len(frontmatter) != 0 {
|
||||||
fm := DetectFrontMatter(rune(frontmatter[0]))
|
fm := DetectFrontMatter(rune(frontmatter[0]))
|
||||||
meta, err = fm.Parse(frontmatter)
|
if fm != nil {
|
||||||
if err != nil {
|
meta, err = fm.Parse(frontmatter)
|
||||||
return
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -129,6 +133,12 @@ func ReadFrom(r io.Reader) (p Page, err error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
newp.frontmatter = fm
|
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)
|
content, err := extractContent(reader)
|
||||||
|
|
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
|
@ -32,6 +32,12 @@
|
||||||
"revision": "b896c45f5af983b1f416bdf3bb89c4f1f0926f69",
|
"revision": "b896c45f5af983b1f416bdf3bb89c4f1f0926f69",
|
||||||
"revisionTime": "2016-04-08T19:03:23Z"
|
"revisionTime": "2016-04-08T19:03:23Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "RxIwAgjIuBpwde5BCZRLLK7VRG8=",
|
||||||
|
"path": "github.com/chaseadamsio/goorgeous",
|
||||||
|
"revision": "72a06e1b07db57f3931f5a9c00f3f04e636ad0a8",
|
||||||
|
"revisionTime": "2017-02-17T13:03:04Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "ntacCkWfMT63DaehXLG5FeXWyNM=",
|
"checksumSHA1": "ntacCkWfMT63DaehXLG5FeXWyNM=",
|
||||||
"path": "github.com/cpuguy83/go-md2man/md2man",
|
"path": "github.com/cpuguy83/go-md2man/md2man",
|
||||||
|
|
Loading…
Add table
Reference in a new issue