Re: CustomHTMLConverter

Posted by abelsromero on
URL: https://discuss.asciidoctor.org/CustomHTMLConverter-tp8088p8091.html

This explanation may be daunting at first, but it's not that complicated once you understand the template syntax. Take it from someone with no idea of Ruby and still able to mess with them.

As intro...a template will replace the code generated for a "block"* by default by what the template build. The template is nothing else than a DSL that builds the HTML. So Asciidoctor instead of calling its own code calls the template passing all the information it internally uses.
There are several languages, and I think that even plain Ruby also works (using 'puts' to output HTML). Here I will use Slim, for a reference of the syntax I check here https://rdoc.info/gems/slim/frames. There are examples of slime alongside the generated HTML.

* Using block as generic term, not as strict Asciidoctor block.

That how I do:
1. Know what you want to modify. In this case, "section", in the examples repo there's a file called "section.*" that can be the starting point. My previous link points directly to it.
2. Copy it to a folder and build your docs with the '-T' option pointing to that folder -> "asciidoctor -T templates demo.adoc". The path is relative to where the command is executed. If you are using some other build tool, check the options.
3. Now if you run it, it will fail with "undefined local variable or method `section_level' for #<Asciidoctor::Section:0x0000558cdfa2ae38>". As said above, the template is executed from the converter, in this case, the error says there's a reference it cannot resolve. That's because the templates are for reference and not updated to latest Asciidoctor engine, so some variables or methods are no longer available or have changed names. To now the current values, I go to the source code and check how the section is currectly build https://github.com/asciidoctor/asciidoctor/blob/master/lib/asciidoctor/converter/html5.rb#L380. There you can see the variables and methods being used. For example, the section title should be corrected from 'section_title' to 'captioned_title', and the numeral can be obtained with 'sectnum'. Click on them to see where they are declared, some are methods and can accept options. For example sectnum can add/remove the dot or use a different character as separator. The code is well documented.
4. With this process I build this, is far from perfect, but it adds a span element with a custom class arround the number when the attribute "sectanchors" is set, just for example sake. I just removed what failed, fixed some references and added the span using slim sintax "span(class="title-num") =sectnum"
----
*{tag: %(h#{level + 1}), id: id}
  - if id && (document.attr? :sectanchors)
    a.anchor href="##{id}"
    span(class="title-num") =sectnum
    =captioned_title
  - elsif id && (document.attr? :sectlinks)
    a.link href="##{id}" =captioned_title
  - else
    =captioned_title
- if level == 1
  .sectionbody =content
- else
  =content
----