~stick/stma.is

2eac0d3bbff808fc991aa062cd982af014c569bb — Stick 2 months ago 6c60308
add hugo asciidoc post
1 files changed, 115 insertions(+), 0 deletions(-)

A content/stick/2020-04-07-hugo-and-asciidoc.ad
A content/stick/2020-04-07-hugo-and-asciidoc.ad => content/stick/2020-04-07-hugo-and-asciidoc.ad +115 -0
@@ 0,0 1,115 @@
---
title: "Hugo and AsciiDoc?"
tags: ["software"]
---

A few weeks ago, https://jianmin.dev/about/[Jianmin] started a blog.
His https://jianmin.dev/2020/mar/06/making-a-static-website-with-hugo/[first post] covered his blogging setup with https://gohugo.io/[Hugo], the same generator I use.
Instead of writing his posts in https://daringfireball.net/projects/markdown/[Markdown], though, he writes them in http://asciidoc.org/[AsciiDoc].
I did a little https://duckduckgo.com[ducking] and the claims for AsciiDoc sound pretty good.
The https://freecontent.manning.com/[Manning Free Content Center] has a https://freecontent.manning.com/using-markup-languages-with-hugo/[comparison of Hugo-supported markup languages]; its author uses AsciiDoc and notes that https://github.com/gohugoio/hugo/issues/470[since 2014] there have been https://github.com/gohugoio/hugo/issues/1435[dicussions] of native AsciiDoc support in Hugo.
Right now, AsciiDoc is supported using an https://gohugo.io/content-management/formats/[external command], either `asciidoc` or `asciidoctor`.
That said, I thought I should at least test it and ensure that my https://git.sr.ht/~stick/hugo-base[hugo-base] theme https://stick/2020-04-08-hugo-base-asciidoc-support/[supports AsciiDoc pages] effectively.

It was more involved than I thought.

== AsciiDoc, Asciidoctor, and https://www.reddit.com/r/linuxmasterrace/comments/aa1bfq/why_is_arch_linux_a_meme/[Arch Linux]

[NOTE]
Throughout this post, I'll use capitalized words for a project or a standard (Hugo, AsciiDoc, etc).
I'll use `monospace` for the names of software.

`asciidoc` is in the Arch repositories, so I installed it.
However, `hugo` hard-codes the options it passes to external generators, and the options it uses for `asciidoc` don't work on my system.

--
[%hardbreaks]
`ERROR 2020/04/06 11:51:26 stick/2020-04-06-hugo-and-asciidoc.ad: asciidoc: ERROR: <stdin>: line 1: unsafe: ifeval invalid
ERROR 2020/04/06 11:51:26 stick/2020-04-06-hugo-and-asciidoc.ad: asciidoc: FAILED: <stdin>: line 1: ifeval invalid safe document
ERROR 2020/04/06 11:51:26 /usr/bin/asciidoc rendering stick/2020-04-06-hugo-and-asciidoc.ad: exit status 1`
--

Not so good.
Fortunately `asciidoctor` is also available, and it works fine.
I didn't try very hard to make `asciidoc` work (more on why in a moment), so it might be possible to set it up correctly; I don't know.

== AsciiDoc HTML is awful

Here's a sample (which I have cleaned up quite a bit already) that shows the horror of ``asciidoc``'s (and ``asciidoctor``'s) generated HTML.

[source,html,linenums]
----
<div class="paragraph"><p>...</p></div>
<div class="paragraph"><p>...</p></div>
<div class="paragraph"><p>...</p></div>
<div class="listingblock"><div class="content">
	<pre class="...">
		<code class="..." data-lang="...">...</code>
	</pre>
</div></div>
----

Let's not.

Thankfully, there is a way around it.
Hat tip to https://ratfactor.com/about/[ratfactor] for their https://ratfactor.com/hugo-adoc-html5s/[write-up] of https://github.com/jirutka/asciidoctor-html5s[asciidoctor-html5s], a backend for `asciidoctor` which generates (relatively) semantic HTML5.
Because `asciidoctor-html5s` wasn't available on Arch, I followed the https://wiki.archlinux.org/index.php/Ruby_Gem_package_guidelines[Ruby Gem package guidelines] and added it https://aur.archlinux.org/packages/ruby-asciidoctor-html5s/[to the AUR] (`ruby-asciidoctor-html5s`).

Once it's installed, we run into the same problem we had with `hugo` and `asciidoc` earlier: hard-coded options.
https://ratfactor.com/hugo-adoc-html5s/[ratfactor's post] includes a way around this, as does https://bitbucket.org/nimnaij/hugo-adoc-container/src/master/bin/asciidoctor[jianmin's Dockerfile].
The basic gist is to override the actual `asciidoctor` command with a script, so that we can control which of ``hugo``'s arguments actually get passed to the generator.
I already use similar functionality for other commands via an `overrides` folder in my https://git.sr.ht/~stick/dotfiles[dotfiles].
The folder is added at the beginning of my `$PATH` so that executable there overrides other executables of the same name later in the `$PATH`.
Here's my script for `asciidoctor`:

[source,sh]
----
#!/bin/sh

/usr/bin/asciidoctor -r asciidoctor-html5s -b html5s \
	--attribute tabsize=4 \
	--attribute source-highlighter=rouge \
	--attribute rouge-css=style \
	--attribute rouge-style=base16.monokai \
	"$@"
----

No bashisms, so I use a https://stackoverflow.com/a/53116875[POSIX shebang].
`command -v asciidoctor` finds the _actual_ `asciidoctor` command, which here is `/usr/bin/asciidoctor`.
To that, we add the call to the `html5s` backend, along with some options for formatting and highlighting, and then add the options passed by `hugo` (`"$@"`).

== Syntax Highlighting

Speaking of syntax highlighting, all but one of the articles I looked at used http://rouge.jneen.net/[Rouge] for source highlighting.
The https://foo-dogsquared.github.io/blog/posts/blogging-with-asciidoctor-and-hugo/[odd one out] uses a client-side JavaScript option.
No thanks.
https://gohugo.io/content-management/syntax-highlighting/[Hugo uses Chroma], a replacement for https://pygments.org/[Pygments].
I suppose I could use Chroma to do it, but I would need to write a lot of pipe.
Maybe later.
Rouge is compatible with Pygments, it's the default syntax highlighting solution for https://jekyllrb.com/[Jekyll], and it's already integrated with `asciidoctor`.
So be it.

Rouge is available in the Arch repositories, thankfully (`ruby-rouge`).
Once installed, it seems the default way to use it is to add attributes to the AsciiDoc header.
I could not get that to work; no matter what I tried, either `hugo` incorrectly stripped the header, or `asciidoctor` did not recognize the attribute.
In the end, the solution was to add the attributes to the `asciidoctor` override script (shown above); this keeps the document files cleaner anyway.

Once I had it working, the next hurdle was theming.
If you are looking online, https://github.com/rouge-ruby/rouge/tree/master/lib/rouge/themes[this is not the whole list of themes].
Thank you to https://mcpride.github.io/about/en/[mcpride] for his post pointing out that you can https://mcpride.github.io/posts/development/2019/03/06/syntax-highlighting-with-jekyll/[list all highlighting themes with rougify] (`rougify help style`).

== Vim Workflow

There is limited support in Vim; https://github.com/asciidoc/vim-asciidoc[syntax highlighting] works out of the box but nothing fancy.
If your file extension is `.ad`, be sure to `set filetype=asciidoc` since Vim auto-detects `xdefaults` instead.
You can do this in https://vim.fandom.com/wiki/Filetype.vim[`filetype.vim`] as below:

[source,vim]
----
if exists('did_load_filetypes')
  finish
endif
augroup filetypedetect
	autocmd! BufNewFile,BufRead *.ad setlocal filetype=asciidoc
augroup END
----