|
| 1 | +# External callouts for Asciidoctor |
| 2 | + |
| 3 | +## Description |
| 4 | + |
| 5 | +An [Asciidoc](https://asciidoctor.org/) extension which adds support for callout tags added outside the listing block. |
| 6 | + |
| 7 | +## Motivation |
| 8 | + |
| 9 | +Aside from getting little practice around Ruby and JavaScript, I decided to have a crack at this to help with a problem that comes up at work every so often. |
| 10 | + |
| 11 | +The [callout mechanism](https://docs.asciidoctor.org/asciidoc/latest/verbatim/callouts/) for Asciidoc works extremely well in 99% of the cases I run into: |
| 12 | + |
| 13 | +```asciidoc |
| 14 | +[source,ruby] |
| 15 | +---- |
| 16 | +require 'sinatra' #<1> |
| 17 | +
|
| 18 | +get '/hi' do #<2> #<3> |
| 19 | + "Hello World!" |
| 20 | +end |
| 21 | +---- |
| 22 | +<1> Library import |
| 23 | +<2> URL mapping |
| 24 | +<3> Response block |
| 25 | +``` |
| 26 | + |
| 27 | +Great, but it does mean you have to add commented to the tags to the source code to register the callout in the following block. As I've said, this is fine, 99% of the time, but I've run across a few occasions when adding tags to the source code (either in-line or an included file) can be a little problematic: |
| 28 | + |
| 29 | +. Restricted access to the source code: as a humble tech-writer, you might not have access to the included source code to add your own tags. |
| 30 | +. The source code has to remain runnable, but doesn't have a commenting mechanism that works well with Asciidoc (shell scripts spring to mind.) |
| 31 | + |
| 32 | +## A possible Solution |
| 33 | +And that's where this extension comes in: it adds support adding tags outside the source listing block, like this: |
| 34 | + |
| 35 | + |
| 36 | +```asciidoc |
| 37 | +[source,ruby] |
| 38 | +---- |
| 39 | +require 'sinatra' |
| 40 | + |
| 41 | +get '/hi' do |
| 42 | + "Hello World!" |
| 43 | +end |
| 44 | +---- |
| 45 | +. Library import @3 |
| 46 | +. URL mapping @5 |
| 47 | +. Response block @5 |
| 48 | +``` |
| 49 | + |
| 50 | +Rather than tagging the code, you add a location token at the end of a list item, which will then add the tag at the specified line number. Run the source text through Asciidoctor{plus}extension, and it'll spit the same source block complete with callouts. |
| 51 | + |
| 52 | +Two types callouts are supported: |
| 53 | + |
| 54 | +**@nn** – This format takes a numeric value indicating the line in the source block where the callout should appear. The callouts will appear at the end of the line. Multiple callouts on the same line will have a single space between tham. |
| 55 | + |
| 56 | +**@/text/** – The text between the two slashes will be used in a regex search. A callout will be placed at the end of the first matching line. |
| 57 | +If you have a large listing then it may be preferable to use the text search rather than counting all the lines. It may also be preferable to use a smaller listing, as a long listing might mean that your description is a bit too general. |
| 58 | + |
| 59 | +You can have multiple callouts on the same line. |
| 60 | +You can also mix and match numeric and text callout tokens on the same list item. (Though I'm not sure why you would). |
| 61 | + |
| 62 | +## Installation |
| 63 | + |
| 64 | +### Node module |
| 65 | + |
| 66 | +You can include the extension as part of a Node project by running the `npm install`command. |
| 67 | + |
| 68 | +`npm install asciidoctor-external-callout` |
| 69 | + |
| 70 | +To call it as part of an Asciidoctor conversion, then register the module then register before calling a `convert` function: |
| 71 | + |
| 72 | +```javascript |
| 73 | +const asciidoctor = require('@asciidoctor/core')() |
| 74 | +const registry = asciidoctor.Extensions.create() |
| 75 | +require('asciidoctor-external-callout')(registry) |
| 76 | + |
| 77 | +asciidoctor.convertFile('./sample.adoc', {safe: 'safe', standalone: true, extension_registry: registry}) |
| 78 | +``` |
| 79 | + |
| 80 | +### Antora |
| 81 | + |
| 82 | +Install the callout extension as part of the Antora installation. The Node setup is usually the same directory from where you run the `antora` script. |
| 83 | + |
| 84 | +`npm install asciidoctor-external-callout` |
| 85 | + |
| 86 | +You will also need to register the extension in the playbook used to generate the site: |
| 87 | + |
| 88 | +```yaml |
| 89 | + extensions: |
| 90 | + - asciidoctor-external-callout |
| 91 | + |
| 92 | +``` |
| 93 | + |
| 94 | + |
0 commit comments