HUGO
News Docs Themes Community GitHub

Configure markup

Configure markup.

Default handler

In its default configuration, Hugo uses Goldmark to render Markdown to HTML.

markup:
  defaultMarkdownHandler: goldmark
[markup]
  defaultMarkdownHandler = 'goldmark'
{
   "markup": {
      "defaultMarkdownHandler": "goldmark"
   }
}

Files with ending with .md, .mdown, or .markdown are processed as Markdown, unless you’ve explicitly set a different format using the markup field in your front matter.

To use a different renderer for Markdown files, specify one of asciidocext, org, pandoc, or rst in your site configuration.

defaultMarkdownHandlerRenderer
asciidocextAsciiDoc
goldmarkGoldmark
orgEmacs Org Mode
pandocPandoc
rstreStructuredText

To use AsciiDoc, Pandoc, or reStructuredText you must install the relevant renderer and update your security policy.

Unless you need a unique capability provided by one of the alternative Markdown handlers, we strongly recommend that you use the default setting. Goldmark is fast, well maintained, conforms to the CommonMark specification, and is compatible with GitHub Flavored Markdown (GFM).

Goldmark

This is the default configuration for the Goldmark Markdown renderer:

markup:
  goldmark:
    duplicateResourceFiles: false
    extensions:
      cjk:
        eastAsianLineBreaks: false
        eastAsianLineBreaksStyle: simple
        enable: false
        escapedSpace: false
      definitionList: true
      extras:
        delete:
          enable: false
        insert:
          enable: false
        mark:
          enable: false
        subscript:
          enable: false
        superscript:
          enable: false
      footnote: true
      linkify: true
      linkifyProtocol: https
      passthrough:
        delimiters:
          block: []
          inline: []
        enable: false
      strikethrough: true
      table: true
      taskList: true
      typographer:
        apostrophe: '’'
        disable: false
        ellipsis: '…'
        emDash: '—'
        enDash: '–'
        leftAngleQuote: '«'
        leftDoubleQuote: '“'
        leftSingleQuote: '‘'
        rightAngleQuote: '»'
        rightDoubleQuote: '”'
        rightSingleQuote: '’'
    parser:
      attribute:
        block: false
        title: true
      autoDefinitionTermID: false
      autoHeadingID: true
      autoIDType: github
      wrapStandAloneImageWithinParagraph: true
    renderHooks:
      image:
        enableDefault: false
      link:
        enableDefault: false
    renderer:
      hardWraps: false
      unsafe: false
      xhtml: false
[markup]
  [markup.goldmark]
    duplicateResourceFiles = false
    [markup.goldmark.extensions]
      definitionList = true
      footnote = true
      linkify = true
      linkifyProtocol = 'https'
      strikethrough = true
      table = true
      taskList = true
      [markup.goldmark.extensions.cjk]
        eastAsianLineBreaks = false
        eastAsianLineBreaksStyle = 'simple'
        enable = false
        escapedSpace = false
      [markup.goldmark.extensions.extras]
        [markup.goldmark.extensions.extras.delete]
          enable = false
        [markup.goldmark.extensions.extras.insert]
          enable = false
        [markup.goldmark.extensions.extras.mark]
          enable = false
        [markup.goldmark.extensions.extras.subscript]
          enable = false
        [markup.goldmark.extensions.extras.superscript]
          enable = false
      [markup.goldmark.extensions.passthrough]
        enable = false
        [markup.goldmark.extensions.passthrough.delimiters]
          block = []
          inline = []
      [markup.goldmark.extensions.typographer]
        apostrophe = '’'
        disable = false
        ellipsis = '…'
        emDash = '—'
        enDash = '–'
        leftAngleQuote = '«'
        leftDoubleQuote = '“'
        leftSingleQuote = '‘'
        rightAngleQuote = '»'
        rightDoubleQuote = '”'
        rightSingleQuote = '’'
    [markup.goldmark.parser]
      autoDefinitionTermID = false
      autoHeadingID = true
      autoIDType = 'github'
      wrapStandAloneImageWithinParagraph = true
      [markup.goldmark.parser.attribute]
        block = false
        title = true
    [markup.goldmark.renderHooks]
      [markup.goldmark.renderHooks.image]
        enableDefault = false
      [markup.goldmark.renderHooks.link]
        enableDefault = false
    [markup.goldmark.renderer]
      hardWraps = false
      unsafe = false
      xhtml = false
{
   "markup": {
      "goldmark": {
         "duplicateResourceFiles": false,
         "extensions": {
            "cjk": {
               "eastAsianLineBreaks": false,
               "eastAsianLineBreaksStyle": "simple",
               "enable": false,
               "escapedSpace": false
            },
            "definitionList": true,
            "extras": {
               "delete": {
                  "enable": false
               },
               "insert": {
                  "enable": false
               },
               "mark": {
                  "enable": false
               },
               "subscript": {
                  "enable": false
               },
               "superscript": {
                  "enable": false
               }
            },
            "footnote": true,
            "linkify": true,
            "linkifyProtocol": "https",
            "passthrough": {
               "delimiters": {
                  "block": [],
                  "inline": []
               },
               "enable": false
            },
            "strikethrough": true,
            "table": true,
            "taskList": true,
            "typographer": {
               "apostrophe": "\u0026rsquo;",
               "disable": false,
               "ellipsis": "\u0026hellip;",
               "emDash": "\u0026mdash;",
               "enDash": "\u0026ndash;",
               "leftAngleQuote": "\u0026laquo;",
               "leftDoubleQuote": "\u0026ldquo;",
               "leftSingleQuote": "\u0026lsquo;",
               "rightAngleQuote": "\u0026raquo;",
               "rightDoubleQuote": "\u0026rdquo;",
               "rightSingleQuote": "\u0026rsquo;"
            }
         },
         "parser": {
            "attribute": {
               "block": false,
               "title": true
            },
            "autoDefinitionTermID": false,
            "autoHeadingID": true,
            "autoIDType": "github",
            "wrapStandAloneImageWithinParagraph": true
         },
         "renderHooks": {
            "image": {
               "enableDefault": false
            },
            "link": {
               "enableDefault": false
            }
         },
         "renderer": {
            "hardWraps": false,
            "unsafe": false,
            "xhtml": false
         }
      }
   }
}

Extensions

The extensions below, excluding Extras and Passthrough, are enabled by default.

Extras

New in v0.126.0

Enable deleted text, inserted text, mark text, subscript, and superscript elements in Markdown.

ElementMarkdownRendered
Deleted text~~foo~~<del>foo</del>
Inserted text++bar++<ins>bar</ins>
Mark text==baz==<mark>baz</mark>
SubscriptH~2~OH<sub>2</sub>O
Superscript1^st^1<sup>st</sup>

To avoid a conflict when enabling the “subscript” feature of the Extras extension, if you want to render subscript and strikethrough text concurrently you must:

  1. Disable the Strikethrough extension
  2. Enable the “deleted text” feature of the Extras extension

For example:

markup:
  goldmark:
    extensions:
      extras:
        delete:
          enable: true
        subscript:
          enable: true
      strikethrough: false
[markup]
  [markup.goldmark]
    [markup.goldmark.extensions]
      strikethrough = false
      [markup.goldmark.extensions.extras]
        [markup.goldmark.extensions.extras.delete]
          enable = true
        [markup.goldmark.extensions.extras.subscript]
          enable = true
{
   "markup": {
      "goldmark": {
         "extensions": {
            "extras": {
               "delete": {
                  "enable": true
               },
               "subscript": {
                  "enable": true
               }
            },
            "strikethrough": false
         }
      }
   }
}

Passthrough

New in v0.122.0

Enable the Passthrough extension to include mathematical equations and expressions in Markdown using LaTeX markup. See mathematics in Markdown for details.

Typographer

The Typographer extension replaces certain character combinations with HTML entities as specified below:

MarkdownReplaced byDescription
...&hellip;horizontal ellipsis
'&rsquo;apostrophe
--&ndash;en dash
---&mdash;em dash
«&laquo;left angle quote
&ldquo;left double quote
&lsquo;left single quote
»&raquo;right angle quote
&rdquo;right double quote
&rsquo;right single quote

Settings explained

Most of the Goldmark settings above are self-explanatory, but some require explanation.

duplicateResourceFiles
New in v0.123.0
(bool) Whether to duplicate shared page resources for each language on multilingual single-host sites. See multilingual page resources for details. Default is false.

With multilingual single-host sites, setting this parameter to false will enable Hugo’s embedded link render hook and embedded image render hook. This is the default configuration for multilingual single-host sites.

parser.wrapStandAloneImageWithinParagraph
(bool) Whether to wrap image elements without adjacent content within a p element when rendered. This is the default Markdown behavior. Set to false when using an image render hook to render standalone images as figure elements. Default is true.
parser.autoDefinitionTermID
New in v0.144.0
(bool) Whether to automatically add id attributes to description list terms (i.e., dt elements). When true, the id attribute of each dt element is accessible through the Fragments.Identifiers method on a Page object.
parser.autoHeadingID
(bool) Whether to automatically add id attributes to headings (i.e., h1, h2, h3, h4, h5, and h6 elements).
parser.autoIDType
(string) The strategy used to automatically generate id attributes, one of github, github-ascii or blackfriday.
  • github produces GitHub-compatible id attributes
  • github-ascii drops any non-ASCII characters after accent normalization
  • blackfriday produces id attributes compatible with the Blackfriday Markdown renderer

This is also the strategy used by the anchorize template function. Default is github.

parser.attribute.block
(bool) Whether to enable Markdown attributes for block elements. Default is false.
parser.attribute.title
(bool) Whether to enable Markdown attributes for headings. Default is true.
renderHooks.image.enableDefault
New in v0.123.0
(bool) Whether to enable the embedded image render hook. Default is false.

The embedded image render hook is automatically enabled for multilingual single-host sites if duplication of shared page resources is disabled. This is the default configuration for multilingual single-host sites.

renderHooks.link.enableDefault
New in v0.123.0
(bool) Whether to enable the embedded link render hook. Default is false.

The embedded link render hook is automatically enabled for multilingual single-host sites if duplication of shared page resources is disabled. This is the default configuration for multilingual single-host sites.

renderer.hardWraps
(bool) Whether to replace newline characters within a paragraph with br elements. Default is false.
renderer.unsafe
(bool) Whether to render raw HTML mixed within Markdown. This is unsafe unless the content is under your control. Default is false.

AsciiDoc

This is the default configuration for the AsciiDoc renderer:

markup:
  asciidocExt:
    attributes: {}
    backend: html5
    extensions: []
    failureLevel: fatal
    noHeaderOrFooter: true
    preserveTOC: false
    safeMode: unsafe
    sectionNumbers: false
    trace: false
    verbose: false
    workingFolderCurrent: false
[markup]
  [markup.asciidocExt]
    backend = 'html5'
    extensions = []
    failureLevel = 'fatal'
    noHeaderOrFooter = true
    preserveTOC = false
    safeMode = 'unsafe'
    sectionNumbers = false
    trace = false
    verbose = false
    workingFolderCurrent = false
    [markup.asciidocExt.attributes]
{
   "markup": {
      "asciidocExt": {
         "attributes": {},
         "backend": "html5",
         "extensions": [],
         "failureLevel": "fatal",
         "noHeaderOrFooter": true,
         "preserveTOC": false,
         "safeMode": "unsafe",
         "sectionNumbers": false,
         "trace": false,
         "verbose": false,
         "workingFolderCurrent": false
      }
   }
}

Settings explained

attributes
(map) A map of key-value pairs, each a document attribute. See Asciidoctor’s attributes.
backend
(string) The backend output file format. Default is html5.
extensions
(string array) An array of enabled extensions, one or more of asciidoctor-html5s, asciidoctor-bibtex, asciidoctor-diagram, asciidoctor-interdoc-reftext, asciidoctor-katex, asciidoctor-latex, asciidoctor-mathematical, or asciidoctor-question.

To mitigate security risks, entries in the extension array may not contain forward slashes (/), backslashes (\), or periods. Due to this restriction, extensions must be in Ruby’s $LOAD_PATH.

failureLevel
(string) The minimum logging level that triggers a non-zero exit code (failure). Default is fatal.
noHeaderOrFooter
(bool) Whether to output an embeddable document, which excludes the header, the footer, and everything outside the body of the document. Default is true.
preserveTOC
(bool) Whether to preserve the table of contents (TOC) rendered by Asciidoctor. By default, to make the TOC compatible with existing themes, Hugo removes the TOC rendered by Asciidoctor. To render the TOC, use the TableOfContents method on a Page object in your templates. Default is false.
safeMode
(string) The safe mode level, one of unsafe, safe, server, or secure. Default is unsafe.
sectionNumbers
(bool) Whether to number each section title. Default is false.
trace
(bool) Whether to include backtrace information on errors. Default is false.
verbose
(bool) Whether to verbosely print processing information and configuration file checks to stderr. Default is false.
workingFolderCurrent
(bool) Whether to set the working directory to be the same as that of the AsciiDoc file being processed, allowing includes to work with relative paths. Set to true to render diagrams with the asciidoctor-diagram extension. Default is false.

Configuration example

markup:
  asciidocExt:
    attributes:
      my-attribute-name: my value
      my-base-url: https://example.com/
    extensions:
    - asciidoctor-html5s
    - asciidoctor-diagram
    workingFolderCurrent: true
[markup]
  [markup.asciidocExt]
    extensions = ['asciidoctor-html5s', 'asciidoctor-diagram']
    workingFolderCurrent = true
    [markup.asciidocExt.attributes]
      my-attribute-name = 'my value'
      my-base-url = 'https://example.com/'
{
   "markup": {
      "asciidocExt": {
         "attributes": {
            "my-attribute-name": "my value",
            "my-base-url": "https://example.com/"
         },
         "extensions": [
            "asciidoctor-html5s",
            "asciidoctor-diagram"
         ],
         "workingFolderCurrent": true
      }
   }
}

Syntax highlighting

Follow the steps below to enable syntax highlighting.

Step 1

Set the source-highlighter attribute in your site configuration. For example:

markup:
  asciidocExt:
    attributes:
      source-highlighter: rouge
[markup]
  [markup.asciidocExt]
    [markup.asciidocExt.attributes]
      source-highlighter = 'rouge'
{
   "markup": {
      "asciidocExt": {
         "attributes": {
            "source-highlighter": "rouge"
         }
      }
   }
}

Step 2

Generate the highlighter CSS. For example:

rougify style monokai.sublime > assets/css/syntax.css

Step 3

In your base template add a link to the CSS file:

layouts/_default/baseof.html
<head>
  ...
  {{ with resources.Get "css/syntax.css" }}
    <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
  {{ end }}
  ...
</head>

Then add the code to be highlighted to your markup:

[#hello,ruby]
----
require 'sinatra'

get '/hi' do
  "Hello World!"
end
----

Troubleshooting

Run hugo --logLevel debug to examine Hugo’s call to the Asciidoctor executable:

INFO 2019/12/22 09:08:48 Rendering book-as-pdf.adoc with C:\Ruby26-x64\bin\asciidoctor.bat using asciidoc args [--no-header-footer -r asciidoctor-html5s -b html5s -r asciidoctor-diagram --base-dir D:\prototypes\hugo_asciidoc_ddd\docs -a outdir=D:\prototypes\hugo_asciidoc_ddd\build -] ...

Highlight

This is the default configuration.

markup:
  highlight:
    anchorLineNos: false
    codeFences: true
    guessSyntax: false
    hl_Lines: ""
    hl_inline: false
    lineAnchors: ""
    lineNoStart: 1
    lineNos: false
    lineNumbersInTable: true
    noClasses: true
    style: monokai
    tabWidth: 4
    wrapperClass: highlight
[markup]
  [markup.highlight]
    anchorLineNos = false
    codeFences = true
    guessSyntax = false
    hl_Lines = ''
    hl_inline = false
    lineAnchors = ''
    lineNoStart = 1
    lineNos = false
    lineNumbersInTable = true
    noClasses = true
    style = 'monokai'
    tabWidth = 4
    wrapperClass = 'highlight'
{
   "markup": {
      "highlight": {
         "anchorLineNos": false,
         "codeFences": true,
         "guessSyntax": false,
         "hl_Lines": "",
         "hl_inline": false,
         "lineAnchors": "",
         "lineNoStart": 1,
         "lineNos": false,
         "lineNumbersInTable": true,
         "noClasses": true,
         "style": "monokai",
         "tabWidth": 4,
         "wrapperClass": "highlight"
      }
   }
}
anchorLineNos
(bool) Whether to render each line number as an HTML anchor element, setting the id attribute of the surrounding span element to the line number. Irrelevant if lineNos is false. Default is false.
codeFences
(bool) Whether to highlight fenced code blocks. Default is true.
guessSyntax
(bool) Whether to automatically detect the language if the LANG argument is blank or set to a language for which there is no corresponding lexer. Falls back to a plain text lexer if unable to automatically detect the language. Default is false.

The Chroma syntax highlighter includes lexers for approximately 250 languages, but only 5 of these have implemented automatic language detection.

hl_Lines
(string) A space-delimited list of lines to emphasize within the highlighted code. To emphasize lines 2, 3, 4, and 7, set this value to 2-4 7. This option is independent of the lineNoStart option.
hl_inline
(bool) Whether to render the highlighted code without a wrapping container. Default is false.
lineAnchors
(string) When rendering a line number as an HTML anchor element, prepend this value to the id attribute of the surrounding span element. This provides unique id attributes when a page contains two or more code blocks. Irrelevant if lineNos or anchorLineNos is false.
lineNoStart
(int) The number to display at the beginning of the first line. Irrelevant if lineNos is false. Default is 1.
lineNos
(bool) Whether to display a number at the beginning of each line. Default is false.
lineNumbersInTable
(bool) Whether to render the highlighted code in an HTML table with two cells. The left table cell contains the line numbers, while the right table cell contains the code. Irrelevant if lineNos is false. Default is true.
noClasses
(bool) Whether to use inline CSS styles instead of an external CSS file. Default is true. To use an external CSS file, set this value to false and generate the CSS file from the command line:
hugo gen chromastyles --style=monokai > syntax.css
style
(string) The CSS styles to apply to the highlighted code. Case-sensitive. Default is monokai. See syntax highlighting styles.
tabWidth
(int) Substitute this number of spaces for each tab character in your highlighted code. Irrelevant if noClasses is false. Default is 4.
wrapperClass
New in v0.140.2
(string) The class or classes to use for the outermost element of the highlighted code. Default is highlight.

Instead of specifying both lineNos and lineNumbersInTable, you can use the following shorthand notation:

lineNos=inline
equivalent to lineNos=true and lineNumbersInTable=false
lineNos=table
equivalent to lineNos=true and lineNumbersInTable=true

Table of contents

This is the default configuration for the table of contents, applicable to Goldmark and Asciidoctor:

markup:
  tableOfContents:
    endLevel: 3
    ordered: false
    startLevel: 2
[markup]
  [markup.tableOfContents]
    endLevel = 3
    ordered = false
    startLevel = 2
{
   "markup": {
      "tableOfContents": {
         "endLevel": 3,
         "ordered": false,
         "startLevel": 2
      }
   }
}
startLevel
(int) Heading levels less than this value will be excluded from the table of contents. For example, to exclude h1 elements from the table of contents, set this value to 2. Default is 2.
endLevel
(int) Heading levels greater than this value will be excluded from the table of contents. For example, to exclude h4, h5, and h6 elements from the table of contents, set this value to 3. Default is 3.
ordered
(bool) Whether to generates an ordered list instead of an unordered list. Default is false.