ref: 358dcce7a6b4a8100964597f81cf371451f6c4d3
parent: fbcda03029ae6ca04253b7008cfd62921baa092a
author: Anthony Fok <[email protected]>
date: Fri Jan 23 06:59:14 EST 2015
Experimental AsciiDoc support with external helpers See #470 * Based on existing support for reStructuredText files * Handles content files with extensions `.asciidoc` and `.ad` * Pipes content through `asciidoctor --safe -`. If `asciidoctor` is not installed, then `asciidoc --safe -`. * To make sure `asciidoctor` or `asciidoc` is found, after adding a piece of AsciiDoc content, run `hugo` with the `-v` flag and look for this message: INFO: 2015/01/23 Rendering with /usr/bin/asciidoctor ... Caveats: * The final "Last updated" timestamp is currently not stripped. * When `hugo` is run with `-v`, you may see a lot of these messages INFO: 2015/01/23 Rendering with /usr/bin/asciidoctor ... if you have lots of `*.ad`, `*.adoc` or `*.asciidoc` files. * Some versions of `asciidoc` may have trouble with its safe mode. To test if you are affected, try this: $ echo "Hello" | asciidoc --safe - asciidoc: ERROR: unsafe: ifeval invalid asciidoc: FAILED: ifeval invalid safe document If so, I recommend that you install `asciidoctor` instead. Feedback and patches welcome! Ideally, we should be using https://github.com/VonC/asciidocgo, @VonC's wonderful Go implementation of Asciidoctor. However, there is still a bit of work needed for asciidocgo to expose its API so that Hugo can actually use it. Until then, hope this "experimental AsciiDoc support through external helpers" can serve as a stopgap solution for our community. :-) 2015-01-30: Updated for the replaceShortcodeTokens() syntax change 2015-02-21: Add `.adoc` extension as suggested by @Fale Conflicts: helpers/content.go
--- a/helpers/content.go
+++ b/helpers/content.go
@@ -230,6 +230,8 @@
return markdownRenderWithTOC(ctx)
case "markdown":
return markdownRenderWithTOC(ctx)
+ case "asciidoc":
+ return []byte(GetAsciidocContent(ctx.Content))
case "rst":
return []byte(GetRstContent(ctx.Content))
}
@@ -242,6 +244,8 @@
return markdownRender(ctx)
case "markdown":
return markdownRender(ctx)
+ case "asciidoc":
+ return []byte(GetAsciidocContent(ctx.Content))
case "rst":
return []byte(GetRstContent(ctx.Content))
}
@@ -297,6 +301,39 @@
}
return strings.Join(words[:max], " "), true
+}
+
+// GetAsciidocContent calls asciidoctor or asciidoc as an external helper
+// to convert AsciiDoc content to HTML.
+func GetAsciidocContent(content []byte) string {
+ cleanContent := bytes.Replace(content, SummaryDivider, []byte(""), 1)
+
+ path, err := exec.LookPath("asciidoctor")
+ if err != nil {
+ path, err = exec.LookPath("asciidoc")
+ if err != nil {
+ jww.ERROR.Println("asciidoctor / asciidoc not found in $PATH: Please install.\n",
+ " Leaving AsciiDoc content unrendered.")
+ return (string(content))
+ }
+ }
+
+ jww.INFO.Println("Rendering with", path, "...")
+ cmd := exec.Command(path, "--safe", "-")
+ cmd.Stdin = bytes.NewReader(cleanContent)
+ var out bytes.Buffer
+ cmd.Stdout = &out
+ if err := cmd.Run(); err != nil {
+ jww.ERROR.Println(err)
+ }
+
+ asciidocLines := strings.Split(out.String(), "\n")
+ for i, line := range asciidocLines {
+ if strings.HasPrefix(line, "<body") {
+ asciidocLines = (asciidocLines[i+1 : len(asciidocLines)-3])
+ }
+ }
+ return strings.Join(asciidocLines, "\n")
}
// GetRstContent calls the Python script rst2html as an external helper
--- a/helpers/general.go
+++ b/helpers/general.go
@@ -63,6 +63,8 @@
switch strings.ToLower(in) {
case "md", "markdown", "mdown":
return "markdown"
+ case "asciidoc", "adoc", "ad":
+ return "asciidoc"
case "rst":
return "rst"
case "html", "htm":
--- a/helpers/general_test.go
+++ b/helpers/general_test.go
@@ -15,6 +15,9 @@
{"md", "markdown"},
{"markdown", "markdown"},
{"mdown", "markdown"},
+ {"asciidoc", "asciidoc"},
+ {"adoc", "asciidoc"},
+ {"ad", "asciidoc"},
{"rst", "rst"},
{"html", "html"},
{"htm", "html"},
--- a/hugolib/handler_page.go
+++ b/hugolib/handler_page.go
@@ -95,7 +95,22 @@
func (h asciidocHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
p.ProcessShortcodes(t)
- // TODO(spf13) Add Ascii Doc Logic here
+ // TODO(spf13) Add/Refactor AsciiDoc Logic here
+ tmpContent, tmpTableOfContents := helpers.ExtractTOC(p.renderContent(helpers.RemoveSummaryDivider(p.rawContent)))
+
+ if len(p.contentShortCodes) > 0 {
+ tmpContentWithTokensReplaced, err := replaceShortcodeTokens(tmpContent, shortcodePlaceholderPrefix, true, p.contentShortCodes)
+
+ if err != nil {
+ jww.FATAL.Printf("Fail to replace short code tokens in %s:\n%s", p.BaseFileName(), err.Error())
+ return HandledResult{err: err}
+ } else {
+ tmpContent = tmpContentWithTokensReplaced
+ }
+ }
+
+ p.Content = helpers.BytesToHTML(tmpContent)
+ p.TableOfContents = helpers.BytesToHTML(tmpTableOfContents)
//err := p.Convert()
return HandledResult{page: p, err: nil}