shithub: hugo

Download patch

ref: b6867bf8068fcaaddf1cb7478f4d52a9c1be1411
parent: 9df57154ee3e3185d024bfe376101b404d8b7cc4
author: Niklas Fasching <[email protected]>
date: Tue Jun 4 08:21:25 EDT 2019

Improve Org mode support: Replace goorgeous with go-org

Sadly, goorgeous has not been updated in over a year and still has a lot of
open issues (e.g. no support for nested lists).

go-org fixes most of those issues and supports a larger subset of Org mode
syntax.

--- a/README.md
+++ b/README.md
@@ -132,7 +132,7 @@
  | [github.com/bep/debounce](https://github.com/bep/debounce) |    MIT License |
  | [github.com/bep/gitmap](https://github.com/bep/gitmap) |  MIT License |
  | [github.com/bep/go-tocss](https://github.com/bep/go-tocss) | MIT License |
- | [github.com/chaseadamsio/goorgeous](https://github.com/chaseadamsio/goorgeous) | MIT License |
+ | [github.com/niklasfasching/go-org](https://github.com/niklasfasching/go-org) | MIT License |
  | [github.com/cpuguy83/go-md2man](https://github.com/cpuguy83/go-md2man) | MIT License |
  | [github.com/danwakefield/fnmatch](https://github.com/danwakefield/fnmatch) | BSD 2-Clause "Simplified" License |
  | [github.com/disintegration/imaging](https://github.com/disintegration/imaging) |  MIT License |
--- a/docs/content/en/content-management/formats.md
+++ b/docs/content/en/content-management/formats.md
@@ -19,7 +19,7 @@
 
 **Markdown is the main content format** and comes in two flavours:  The excellent [Blackfriday project][blackfriday] (name your files `*.md` or set `markup = "markdown"` in front matter) or its fork [Mmark][mmark] (name your files `*.mmark` or set `markup = "mmark"` in front matter), both very fast markdown engines written in Go.
 
-For Emacs users, [goorgeous](https://github.com/chaseadamsio/goorgeous) provides built-in native support for Org-mode  (name your files `*.org` or set `markup = "org"` in front matter)
+For Emacs users, [go-org](https://github.com/niklasfasching/go-org) provides built-in native support for Org-mode  (name your files `*.org` or set `markup = "org"` in front matter)
 
 But in many situations, plain HTML is what you want. Just name your files with `.html` or `.htm` extension inside your content folder. Note that if you want your HTML files to have a layout, they need front matter. It can be empty, but it has to be there:
 
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,6 @@
 	github.com/bep/debounce v1.2.0
 	github.com/bep/gitmap v1.1.0
 	github.com/bep/go-tocss v0.6.0
-	github.com/chaseadamsio/goorgeous v1.1.0
 	github.com/cpuguy83/go-md2man v1.0.8 // indirect
 	github.com/disintegration/imaging v1.6.0
 	github.com/dustin/go-humanize v1.0.0
@@ -38,6 +37,7 @@
 	github.com/muesli/smartcrop v0.0.0-20180228075044-f6ebaa786a12
 	github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
 	github.com/nicksnyder/go-i18n v1.10.0
+	github.com/niklasfasching/go-org v0.0.0-20190112190817-da99094e202f
 	github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84
 	github.com/pelletier/go-toml v1.4.0 // indirect
 	github.com/pkg/errors v0.8.1
@@ -66,7 +66,5 @@
 	google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69 // indirect
 	gopkg.in/yaml.v2 v2.2.2
 )
-
-exclude github.com/chaseadamsio/goorgeous v2.0.0+incompatible
 
 replace github.com/markbates/inflect => github.com/markbates/inflect v0.0.0-20171215194931-a12c3aec81a6
--- a/helpers/content.go
+++ b/helpers/content.go
@@ -27,8 +27,8 @@
 	"unicode/utf8"
 
 	"github.com/gohugoio/hugo/common/maps"
+	"github.com/niklasfasching/go-org/org"
 
-	"github.com/chaseadamsio/goorgeous"
 	bp "github.com/gohugoio/hugo/bufferpool"
 	"github.com/gohugoio/hugo/config"
 	"github.com/miekg/mmark"
@@ -756,10 +756,24 @@
 }
 
 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))
+	config := org.New()
+	config.Log = jww.WARN
+	writer := org.NewHTMLWriter()
+	writer.HighlightCodeBlock = func(source, lang string) string {
+		highlightedSource, err := c.Highlight(source, lang, "")
+		if err != nil {
+			jww.ERROR.Printf("Could not highlight source as lang %s. Using raw source.", lang)
+			return source
+		}
+		return highlightedSource
+	}
+
+	html, err := config.Parse(bytes.NewReader(ctx.Content), ctx.DocumentName).Write(writer)
+	if err != nil {
+		jww.ERROR.Printf("Could not render org: %s. Using unrendered content.", err)
+		return ctx.Content
+	}
+	return []byte(html)
 }
 
 func externallyRenderContent(ctx *RenderingContext, path string, args []string) []byte {
--- a/hugolib/page_test.go
+++ b/hugolib/page_test.go
@@ -1216,12 +1216,12 @@
 	)
 
 	b.AssertFileContent("public/page-org-shortcode/index.html",
-		"SUMMARY:<p>This is a a shortcode.</p>:END",
-		"CONTENT:<p>This is a a shortcode.</p>\n\n<p>Content.\t</p>\n",
+		"SUMMARY:<p>\nThis is a a shortcode.\n</p>:END",
+		"CONTENT:<p>\nThis is a a shortcode.\n</p>\n<p>\nContent.\t\n</p>\n",
 	)
 	b.AssertFileContent("public/page-org-variant1/index.html",
-		"SUMMARY:<p>Summary.</p>:END",
-		"CONTENT:<p>Summary.</p>\n\n<p>Content.\t</p>\n",
+		"SUMMARY:<p>\nSummary.\n</p>:END",
+		"CONTENT:<p>\nSummary.\n</p>\n<p>\nContent.\t\n</p>\n",
 	)
 
 	b.AssertFileContent("public/page-md-only-shortcode/index.html",
--- a/parser/metadecoders/decoder.go
+++ b/parser/metadecoders/decoder.go
@@ -21,12 +21,13 @@
 	"strings"
 
 	"github.com/gohugoio/hugo/common/herrors"
+	"github.com/niklasfasching/go-org/org"
 
 	"github.com/BurntSushi/toml"
-	"github.com/chaseadamsio/goorgeous"
 	"github.com/pkg/errors"
 	"github.com/spf13/afero"
 	"github.com/spf13/cast"
+	jww "github.com/spf13/jwalterweatherman"
 	yaml "gopkg.in/yaml.v2"
 )
 
@@ -106,16 +107,7 @@
 
 	switch f {
 	case ORG:
-		vv, err := goorgeous.OrgHeaders(data)
-		if err != nil {
-			return toFileError(f, errors.Wrap(err, "failed to unmarshal ORG headers"))
-		}
-		switch v.(type) {
-		case *map[string]interface{}:
-			*v.(*map[string]interface{}) = vv
-		default:
-			*v.(*interface{}) = vv
-		}
+		err = d.unmarshalORG(data, v)
 	case JSON:
 		err = json.Unmarshal(data, v)
 	case TOML:
@@ -183,6 +175,31 @@
 
 	return nil
 
+}
+
+func (d Decoder) unmarshalORG(data []byte, v interface{}) error {
+	config := org.New()
+	config.Log = jww.WARN
+	document := config.Parse(bytes.NewReader(data), "")
+	if document.Error != nil {
+		return document.Error
+	}
+	frontMatter := make(map[string]interface{}, len(document.BufferSettings))
+	for k, v := range document.BufferSettings {
+		k = strings.ToLower(k)
+		if k == "tags" || k == "categories" || k == "aliases" {
+			frontMatter[k] = strings.Fields(v)
+		} else {
+			frontMatter[k] = v
+		}
+	}
+	switch v.(type) {
+	case *map[string]interface{}:
+		*v.(*map[string]interface{}) = frontMatter
+	default:
+		*v.(*interface{}) = frontMatter
+	}
+	return nil
 }
 
 func toFileError(f Format, err error) error {