Outputting minimally-processed markdown

I’m working on a project where I need to output plain text in a readable, structured way. The raw markdown source is really close to what I need, so .RawContent is mostly working for me, with two notable exceptions:

  1. I need the output to be hard-wrapped.
  2. I need shortcodes processed.

I suspect I can tackle #1 with some clever regex, but I’m not that clever. I keep running into edge cases that break in various ways. For example, blockquotes in the source are all on one line, and I need them wrapped like this:

> Lorem ipsum dolor sit amet, consectetur adipiscing
> elit, sed do eiusmod tempor incididunt ut labore et
> dolore magna aliqua.

My feeble regex gives me this:

> Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua.

I realize this is a rather niche use case and might be out of scope for Hugo. The answer is probably to hard-wrap the source files, but that’s just not going to happen manually for us. There’s a plugin for SublimeText that sounds like it does exactly what I want. I might try adapting that into something I can run on an arbitrary folder before or after Hugo in my build/deploy script.

Fixing #2 is harder, but perhaps more useful for the wider Hugo community. My markdown source contains shortcodes for embedding images. This works great with the HTML output. I have an alternative shortcode for my plain text output format that creates a nicely formatted placeholder to display info about the images that are missing from the plaintext version. But it seems the only way to get that shortcode processed is to use .Plain (followed by | htmlUnescape). Doing so removes most of the source’s very readable plain text formatting. .Plain appears to convert the markdown to HTML, then strip the tags out, and that’s not desirable for me.

Does this sound like it would be useful to anyone else? Am I overlooking some way to do this now?


{{ .RawContent | .RenderString }}

Should render your shortcodes (assuming you have a recent Hugo version).

Hmm that actually seems to have done the inverse of what I was hoping for: the .RawContent was converted from Markdown to HTML, and the shortcodes were not expanded. What I’m hoping for is to have the Markdown left as-is, but with the shortcodes converted.

It makes sense that Hugo would have a bias towards rendering Markdown as HTML, but for my custom non-HTML output format, it would be nice to be able to take advantage of shortcodes while leaving the Markdown source as-is.

I’m using Hugo v0.98.0+extended.

If it’s helpful, I can provide a sample project to put this request in context.

Thanks for your help!

Yea, you’re right, but the “shortcode were not expanded” indicates that you’r running an old Hugo version.

Ah ha! I updated from v0.98.0 to v0.104.3 and indeed, now shortcodes are expanded.

This gave me an idea – could I convince .RenderString that the Markdown content is actually already HTML? The docs seem to describe a way. I tried:

{{ $opt := dict "display" "block" "markup" "html" }}
{{ .RawContent | .RenderString $opt }}

This resulted in a build error:

Error: Error building site: failed to render pages: render of "page" failed: "/Users/tmcltr/Developer/myproject/layouts/_default/single.plaintext.txt:8:17": execute of template failed: template: _default/single.plaintext.txt:8:17: executing "_default/single.plaintext.txt" at <.RenderString>: error calling RenderString: "/Users/tmcltr/Developer/myproject/content/a-section/a-post/index.md:1:1": no content renderer found for markup "markdown"

The content file mentioned there doesn’t seem to be the problem. no content renderer found for markup "markdown" appears to be what it says when it doesn’t recognize the markup format argument.

I tried a few different variations. Instead of html, I tried HTML, htm, HTM, md, and foo, but the build error was unchanged. I tried markdown and goldmark, both of which allowed the build to complete without error. But of course my markdown was rendered into HTML.

I might be misunderstanding how .RenderString is designed to work, but it would be neat if there was a way to tell it work its magic on shortcodes, but leave the Markdown in place.