Author: Tristano Ajmone

# Modded HighlightTreeprocessor Example

Tristano Ajmone
tajmone@gmail.com
mod v1.3.0, 2019-03-30
Last edited: 2019-03-12

A demonstration of the modded HighlightTreeprocessor extension with some usage instructions.

Associated files:

- `docinfo.html`

- `/haml/block_listing.html.haml`

- `highlight-treeprocessor_mod.rb` v1.3.0

- `highlight_mod.css`

## Highlighting Previews

A couple of examples of how the rendered code looks like. The custom CSS stylesheet defines a default theme plus some dedicated themes targeting specific syntaxes.

### Example 1

For PureBasic code I’ve defined a dedicated theme mimicking the native IDE of the language.

    ; ==============================================================================
    ;                   PureBasic 5.62 - Syntax Highlighting Test
    ; ==============================================================================
    ; by Tristano Ajmone (2018/10/04), public domain: http://unlicense.org

    Declare.i CountdownDialog(text.s)

    Macro IsEven(num)
      (num & 1 = 0)
    EndMacro

    For i=5 To 1 Step -1
      If isEven(i) : Debug Str(i) +" is even." : EndIf
      TEXT$ = "Iteration number: " + Str(i) + ~"\n\nDo you wish to continue?"
      If CountdownDialog(TEXT$) : Break : EndIf
    Next

    MyVar = %1011 << 1
    EnableASM
    INC MyVar ; Mix ASM keywords with PureBasic variable
    DisableASM
    Debug "MyVar: "+Str(MyVar)

    Procedure.i CountdownDialog(text.s)
      UserChoice = MessageRequester("Countdown Dialog", text, #PB_MessageRequester_YesNo |
                                                              #PB_MessageRequester_Info)
      If UserChoice = #PB_MessageRequester_No
        CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
          !mov rax,1
        CompilerElse
          !mov eax,1
        CompilerEndIf
      Else
        ProcedureReturn 0
      EndIf
      ProcedureReturn ; RAX/EAX will be the implicit return value
    EndProcedure

### Example 2: Line Numbers

In this example we add the `linenum` option to enable line-numbering. Again, for the Alan syntax there is a dedicated CSS theme.

     1 --==============================================================================
     2 -- "Chez Alan" by Tristano Ajmone, 2018 || Public domain: http://unlicense.org
     3 --==============================================================================
     4 Import 'library.i'. --> ALAN Standard Library v2.1
     5
     6 The my_game IsA definition_block
     7   Has title    "Chez Alan".
     8   Has subtitle "A small demo adventure".
     9   Has author   "Tristano Ajmone".
    10   Has year     2018.
    11   Has version  "1".
    12 End The.
    13
    14 The 'IF Plaza' IsA location
    15   Exit north to ChezAlan.
    16   Description "North lies ""Chez Alan"", the renown French brasserie."
    17 End The 'IF Plaza'.
    18
    19 The ChezAlan IsA room.
    20   Name 'Chez Alan Brasserie'.
    21   Description
    22     "Today Chez Alan seems busier then ever."
    23   Entered
    24     """Welcome back Sir!"" the maitre greets you.
    25     $nHe has a strong French accent."
    26 End The ChezAlan.
    27
    28 The Pierre IsA male At ChezAlan.
    29   Name Pierre.
    30   Name 'Alan''s' brother.
    31   Is named.
    32   Has ex "Pierre is Alan's brother.".
    33 End The Pierre.
    34
    35 Start At 'IF Plaza'.
    36 Describe banner.

When `linenums` is used, Highlight is invoked with the `-l -j 2` options.

### Example 3: Substitutions

In this example we’ll enable substitutions inside the listing code via the `subs=quotes` option.

Asciidoc source

    [source,alan,subs=quotes]
    ------------------------
    The 'dance hall' #IsA location#
      Description
        "The hall is #_bigger_ than you expected#, and
         far too crowded. You feel the urge to leave."
    End the.
    ------------------------

HTML result

    The 'dance hall' IsA location
      Description
        "The hall is bigger than you expected, and
         far too crowded. You feel the urge to leave."
    End the.

Text enclosed within single or double `#` symbols will be wrapped in the `<mark>` tag (See Asciidoctor Manual §19.5), which I’ve customized to mimic a smeared fluorescent marker. Also notice how the word ‘bigger’ is rendered as emphasized text.

## Usage Instructions

To enable the modded HighlightTreeprocessor extension you must invoke Asciidoctor with the `-r` (`--require`) option:

    asciidoctor \
      -r ./highlight-treeprocessor_mod.rb \
      -a source-highlighter=highlight \
      -a docinfo=shared \
      -T haml \
      example_mod.asciidoc

To enable using Highlight, you need to set the `source-highlighter` attribute to `highlight`. You may do so via the command line, using the `-a` (`--attribute`) option:

    asciidoctor \
      -r ./highlight-treeprocessor_mod.rb \
      -a source-highlighter=highlight \
      -a docinfo=shared \
      -T haml \
      example_mod.asciidoc

or you can set the `source-highlighter` attribute inside the document header:

    :source-highlighter: highlight

### Custom CSS Stylesheets

Because the modded extension doesn’t rely on Highlight to convert themes to CSS, you’ll need to add to the output document your custom CSS.

The easiest way to do so without interfering with the native stylesheet of the Asciidoctor HTML backend is to incorporate the CSS file via a head docinfo file, and then enable it via the `docinfo` attribute, either in the document header:

    :docinfo: shared

or via CLI options:

    asciidoctor \
      -r ./highlight-treeprocessor_mod.rb \
      -a source-highlighter=highlight \
      -a docinfo=shared \
      -T haml \
      example_mod.asciidoc

The `docinfo.html` file used for this document contains a single header line to load the external CSS stylesheet:

    <link rel="stylesheet" href="highlight_mod.css">

Further more, if you want to be able to customize themes on a per language base, and use different background colors for each theme, you’ll need to use the customized Haml template provided with this example:

- `/haml/block_listing.html.haml`

and tell Asciidoctor where to look for the custom templates folder via the `-T` (`--template-dir`) option:

    asciidoctor \
      -r ./highlight-treeprocessor_mod.rb \
      -a source-highlighter=highlight \
      -a docinfo=shared \
      -T haml \
      example_mod.asciidoc

The customized template ensures that the `lang` attribute is added also to the `<pre>` tag, so it might be targeted via custom CSS:

    <pre class="highlight" lang="alan">
      <code class="language-alan" data-lang="alan">

whereas by default Asciidoctor will only emit the `lang` attribute on the `<code>` tag:

    <pre class="highlight">
      <code class="language-alan" data-lang="alan">

In the `/sass/` folder you’ll find the commented SCSS sources used by this document, and a useful Sass template for quickly generating Highlight themes targeting specific syntaxes.

### Custom LangDefs

If you’d like to make available to Highlight some custom langDefs, or override the native language definitions of Highlight with your same-named customized versions, you only need to set the `HIGHLIGHT_DATADIR` environment variable to point to your custom Highlight settings folder before invoking Asciidoctor.

The modded extension will check if the `HIGHLIGHT_DATADIR` environment variable is set, and if it is it will enforce it by invoking Highlight with the `--data-dir=<HIGHLIGHT_DATADIR>` option so that it gets the highest override priority.

This ensures that custom langDefs inside `HIGHLIGHT_DATADIR` will always override the predefined ones, whereas ordinarily the path of the `HIGHLIGHT_DATADIR` env var would be searched after Highlight installation folder.

Since it’s not possible to control the `--data-dir` option from within AsciiDoc documents, this hardcoded workaround is a convenient solution for projects which need to override Highlight default configurations.