ggrossetie / asciidoctor-web-pdf

Convert AsciiDoc documents to PDF using web technologies
https://asciidoctor.org
MIT License
448 stars 92 forks source link

Allow partial override of templates #649

Open siaccarino opened 2 years ago

siaccarino commented 2 years ago

The current template solution does not allow to override parts of the template - it is always a complete override but parts of the asciidoc environment are not available in the template - it is for example hard to realize a TOC with the current template solution.

I solved this temporary by a template which overrides asciidoc-web-pdf code:

'use strict';

// require() does not search for global modules
const modules = require('child_process').execSync('npm root -g').toString().trim()

var DocumentPDFConverter = require(modules + '/asciidoctor-pdf/lib/document/document-converter')

// override https://github.com/Mogztter/asciidoctor-web-pdf/blob/0a27de7423f12fe1f8b5ff7bcb720b786fb63e5b/lib/document/document-converter.js#L490-L504
class MyDocumentPDFConverter extends DocumentPDFConverter {
    titlePage (node) {
        if (node.getDocumentTitle()) {
          const doc = node.getDocument()
          if (this.hasTitlePage(doc)) {
            return `<div id="cover" class="title-page front-matter">
      <h1>${node.getDocumentTitle()} ${node.getRevisionNumber()}</h1>
      <h2>${node.getDocument().getAuthor()}</h2>
      <version>${node.getRevisionRemark()}</version>
    </div>`
          }
          return `<div class="title-document">
      <h1>${node.getDocumentTitle()}</h1>
    </div>`
        }
        return ''
      } // inject revision number
}

const instance = new MyDocumentPDFConverter()

// copy & paste
// https://github.com/Mogztter/asciidoctor-web-pdf/blob/0a27de7423f12fe1f8b5ff7bcb720b786fb63e5b/lib/document/document-converter.js#L532-L542
module.exports = {
    document: (node, opts) => instance.convert_document(node, opts),
    convert_outline: (node, opts) => instance.convert_outline(node, opts),
    admonition: node => instance.convert_admonition(node),
    inline_callout: node => instance.convert_inline_callout(node),
    inline_image: node => instance.convert_inline_image(node),
    inline_footnote: node => instance.convert_inline_footnote(node),
    colist: node => instance.convert_colist(node),
    page_break: node => instance.convert_page_break(node),
    preamble: node => instance.convert_preamble(node)
}

But this solution is a bit hacky - it might be better to pass more data into the template or to allow partial overrides of convert_document.

ggrossetie commented 2 years ago

If you want to extend the built-in DocumentConverter, you should install asciidoctor-pdf locally. Then, you can then register your custom converter:

https://github.com/Mogztter/asciidoctor-web-pdf/blob/0a27de7423f12fe1f8b5ff7bcb720b786fb63e5b/test/document_convert_test.js#L22-L22

Once that's done, you can require your file:

asciidoctor-web-pdf -r ./custom-converter.js -b custom-web-pdf doc.adoc

I think you can also replace the built-in converter if you register your custom converter as web-pdf. If you do that, you can omit -b custom-web-pdf.