Customize asciidoctor.js HTML output

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Customize asciidoctor.js HTML output

Sylvain Leroux
Hello,
I'm using asciidoctor.js for batch documents processing from a Node.js environment. First of all, congratulations for that great piece of software and I hope you will continue supporting the JavaScript ecosystem.

I'm looking for a way to customize the HTML output. Specifically, I need to produce that HTML fragment for each block image:

<figure class="img-frame">
  <img class="img-fluid" ...>
</figure>

I read several docs about customizing asccidoctor's output, but they are targetting the Ruby world and require creating custom templates using `slim` or `haml` as demonstrated in asciidoctor-backends. And I don't see how this can be applied to asciidoc.js.

Another option I considered was writing a custom JavaScript extension to be loaded as explained in the asciidoctor.js manual. But I'm not sure this is the way to go as according to the docs:

There is currently no extension point for processing a built-in block, such as a normal paragraph. Look for that feature in a future Asciidoctor release.


Unless there are some hooks usable from the JavaScript API I could use to customize the output?


Any help or pointers to the "right" way of customizing asciidoctor.js output would be very appreciated!
Thanks in advance for your time,
- Sylvain
my asciidoctor-based website: https://yesik.it
Reply | Threaded
Open this post in threaded view
|

Re: Customize asciidoctor.js HTML output

Sylvain Leroux
Since my previous post, I wasn't inactive.

I wrote https://www.npmjs.com/package/asciidoctor.js-pug

It requires both ascidoctor.js and the pug  template engine.

When the module is loaded, it registers a new Composite converter instead of the standard Html5Converter that will first try to find a possible pug template on a user-supplied directory to convert the node, then fallback to the standard Html5Converter if not found.

This allows me to "override" the default HTML code generation by a pug template.

The code is 100% JavaScript. I've done a bunch of reverse engineering to understand how Ruby and JS interacts, but since I never used Opal before and I was not familiar with Ruby, the code probably deserve some review. Finally, the API is not necessary very stable since it's evolving on a per-need basis. But as of today, it suits my needs. Maybe that could help someone else?

- Sylvain
my asciidoctor-based website: https://yesik.it
Reply | Threaded
Open this post in threaded view
|

Re: Customize asciidoctor.js HTML output

mojavelinux
Administrator
Sylvain,

Thanks for your gratitude and encouragement! I think the fact that Asciidoctor.js has been selected as the AsciiDoc processor for Antora (https://antora.org) is a testament to our commitment to supporting Asciidoctor in the JavaScript ecosystem.

I'll start by answering your original questions. Before I do that, I want to emphasize that Asciidoctor was designed from the beginning to allow you to customize the HTML output. In fact, there's more than one way to do it, as I'll explain.

There are two main ways to customize the HTML output (or any output, for that matter).

1. Write a custom converter, which you either pass to the processor directly or bind to a backend name
2. Write custom templates for each AST node you want to customize

The second option is simpler since it only requires that you override what you need. The custom templates supplement the built-in converter. However, as you have pointed out, there isn't a lot of information yet about how to use custom templates with Asciidoctor.js. That's because we're still sorting out the best way to do it. If you wanted to try it, you could experiment with https://github.com/asciidoctor/asciidoctor-template.js, which currently uses Jade.

Moving on to what you've been working on.

I wrote https://www.npmjs.com/package/asciidoctor.js-pug
it registers a new Composite converter instead of the standard Html5Converter that will first try to find a possible pug template on a user-supplied directory to convert the node, then fallback to the standard Html5Converter if not found.

Nice job!

That's consistent with the behavior of the template converter in Ruby, so it satisfies option (2) from above. I'd like to see if we can merge your effort with https://github.com/asciidoctor/asciidoctor-template.js so users have one solid option. We definitely want to use Pug instead of the deprecated Jade, so perhaps your effort can help us arrive at that.

Perhaps Guillaume could provide guidance on what the next steps would be.

Thanks for participating in the community!

Cheers,

-Dan

On Wed, Mar 14, 2018 at 5:01 AM, Sylvain Leroux [via Asciidoctor :: Discussion] <[hidden email]> wrote:
Since my previous post, I wasn't inactive.

I wrote https://www.npmjs.com/package/asciidoctor.js-pug

It requires both ascidoctor.js and the pug  template engine.

When the module is loaded, it registers a new Composite converter instead of the standard Html5Converter that will first try to find a possible pug template on a user-supplied directory to convert the node, then fallback to the standard Html5Converter if not found.

This allows me to "override" the default HTML code generation by a pug template.

The code is 100% JavaScript. I've done a bunch of reverse engineering to understand how Ruby and JS interacts, but since I never used Opal before and I was not familiar with Ruby, the code probably deserve some review. Finally, the API is not necessary very stable since it's evolving on a per-need basis. But as of today, it suits my needs. Maybe that could help someone else?

- Sylvain
my asciidoctor-based website: https://yesik.it



If you reply to this email, your message will be added to the discussion below:
http://discuss.asciidoctor.org/Customize-asciidoctor-js-HTML-output-tp6214p6217.html
To start a new topic under Asciidoctor :: Discussion, email [hidden email]
To unsubscribe from Asciidoctor :: Discussion, click here.
NAML



--
Dan Allen | @mojavelinux | https://twitter.com/mojavelinux
Reply | Threaded
Open this post in threaded view
|

Re: Customize asciidoctor.js HTML output

Sylvain Leroux
Hi Dan,

Thank you for your reply. Few comments inline:

Thanks for your gratitude and encouragement! I think the fact that Asciidoctor.js has been selected as the AsciiDoc processor for Antora (https://antora.org) is a testament to our commitment to supporting Asciidoctor in the JavaScript ecosystem.
In fact, I learn about Antora after having posted my initial message. This is a very interesting project and this was one of the sources I studied to understand how to interact with the ascidoctor.js API.

That's because we're still sorting out the best way to do it. If you wanted to try it, you could experiment with https://github.com/asciidoctor/asciidoctor-template.js, which currently uses Jade.
That was my second--and most important--source of information. I initially considered using asciidoctor-template.js but it felt too tight to the Reveal.js backend. The second reason I started my own project is I'm not proficient with Ruby. So I wanted a 100% JavaScript solution. From my point of view, if we want a large adoption, JS developers should be able to study the source and hack/patch them without having to go through the Opal toolchain.

Of course, this is not the case for the asciidoctor core, but for asciidoctor-{pug,template} there is so little interfacing code that it is quite manageable in pure-JS. And I think the code is relatively understandable without prior knowledge of Ruby (see https://github.com/s-leroux/asciidoctor.js-pug/blob/master/lib/converter.js).

That's consistent with the behavior of the template converter in Ruby, so it satisfies option (2) from above.
An inconsistency I noticed is the templates provided in https://github.com/asciidoctor/asciidoctor-backends are using the "block_" prefix for block elements. But in my code, in the Converter ::convert method, and using that idiom:

   
template_name = template_name || node_name;

... I don't have that "block_" prefix. I didn't investigate the issue. Probably I missed something!

Perhaps Guillaume could provide guidance on what the next steps would be.
He contacted me through Github: https://github.com/s-leroux/asciidoctor.js-pug/issues/1
I will answer right after having finished this message;)

Thanks for participating in the community!
My pleasure!
- Sylvain
my asciidoctor-based website: https://yesik.it
Reply | Threaded
Open this post in threaded view
|

Re: Customize asciidoctor.js HTML output

mojavelinux
Administrator
Sylvain,

I love to hear that you were able to use Antora and asciidoctor-template.js for ideas.

I initially considered using asciidoctor-template.js but it felt too tight to the Reveal.js backend.

Hmm, this is certainly not the impression we want to give. There's no reason this library should be coupled with Reveal.js in anyway. Sure, it is used in Reveal.js, but it's meant to be a general solution for using custom templates with Asciidoctor.js.

I wanted a 100% JavaScript solution. ...  for asciidoctor-{pug,template} there is so little interfacing code that it is quite manageable in pure-JS.

With that, I agree with you. I think the Asciidoctor.js API has advanced enough now that we can start writing directly against it when creating something new instead of transpiling from Ruby. I agree that's the best way to get adoption and contributors...and performance for that matter.

the "block_" prefix for block elements.

The block_ prefix is deprecated. Those templates are simply out of date. "block" is the implicit default for a template. See https://github.com/asciidoctor/asciidoctor/blob/ca37e975fcebda32a5d0105d50fb56b907836c82/lib/asciidoctor/converter/template.rb#L249-L251

I'll follow-up on https://github.com/s-leroux/asciidoctor.js-pug/issues/1 to see how we can align efforts. It's definitely in all our interests to have a solid and stable way to use custom Pug (and other) templates in Asciidoctor.js. And it will be a big part of the Antora story as well.

Thanks again for your excellent work and for moving this forward!

Cheers,

-Dan

On Fri, Mar 16, 2018 at 5:49 AM, Sylvain Leroux [via Asciidoctor :: Discussion] <[hidden email]> wrote:
Hi Dan,

Thank you for your reply. Few comments inline:

Thanks for your gratitude and encouragement! I think the fact that Asciidoctor.js has been selected as the AsciiDoc processor for Antora (https://antora.org) is a testament to our commitment to supporting Asciidoctor in the JavaScript ecosystem.
In fact, I learn about Antora after having posted my initial message. This is a very interesting project and this was one of the sources I studied to understand how to interact with the ascidoctor.js API.

That's because we're still sorting out the best way to do it. If you wanted to try it, you could experiment with https://github.com/asciidoctor/asciidoctor-template.js, which currently uses Jade.
That was my second--and most important--source of information. I initially considered using asciidoctor-template.js but it felt too tight to the Reveal.js backend. The second reason I started my own project is I'm not proficient with Ruby. So I wanted a 100% JavaScript solution. From my point of view, if we want a large adoption, JS developers should be able to study the source and hack/patch them without having to go through the Opal toolchain.

Of course, this is not the case for the asciidoctor core, but for asciidoctor-{pug,template} there is so little interfacing code that it is quite manageable in pure-JS. And I think the code is relatively understandable without prior knowledge of Ruby (see https://github.com/s-leroux/asciidoctor.js-pug/blob/master/lib/converter.js).

That's consistent with the behavior of the template converter in Ruby, so it satisfies option (2) from above.
An inconsistency I noticed is the templates provided in https://github.com/asciidoctor/asciidoctor-backends are using the "block_" prefix for block elements. But in my code, in the Converter ::convert method, and using that idiom:

   
template_name = template_name || node_name;

... I don't have that "block_" prefix. I didn't investigate the issue. Probably I missed something!

Perhaps Guillaume could provide guidance on what the next steps would be.
He contacted me through Github: https://github.com/s-leroux/asciidoctor.js-pug/issues/1
I will answer right after having finished this message;)

Thanks for participating in the community!
My pleasure!
- Sylvain
my asciidoctor-based website: https://yesik.it



If you reply to this email, your message will be added to the discussion below:
http://discuss.asciidoctor.org/Customize-asciidoctor-js-HTML-output-tp6214p6221.html
To start a new topic under Asciidoctor :: Discussion, email [hidden email]
To unsubscribe from Asciidoctor :: Discussion, click here.
NAML



--
Dan Allen | @mojavelinux | https://twitter.com/mojavelinux