Adding Attributes to Source Blocks in AsciidoctorJ

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

Adding Attributes to Source Blocks in AsciidoctorJ

sean.osterberg
Hi guys, I'm trying to write a tree or block processor to add the linenums attribute on [source] code snippets. The back story here is that we have thousands of files with the [source] attribute, but few with linenums, and I want to force the presentation to use CodeRay's table mode with linenums.

Basically my problem is that things are not processing correctly and I've tried everything I can think of to make it work. To start things off, here is my original test source block:

[source,java]
----
Foobar
----

First I tried creating a Block processor, but couldn't get it to run. What I mean specifically is that I tried to register the extension like shown below, and my block processor was never hit:

public void registerExtensions() {
    JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
    extensionRegistry.block("source", SourceBlockProcessor.class);
}

Question 1: Is the source block style reserved in some way? I can successfully process my own custom block styles (such as [tabs] per a previous post) using this syntax.

After I didn't get anywhere trying that, then I tried creating a TreeProcessor. My results were much more interesting.

I updated my source block with the linenums attribute and then read it to see what the exactly key/value pair seemed to be for a block with [source,java,linenums] as the header. These were the results:

Test block:

[source,java,linenums]
----
Foobar
----

Resulting attribute pairs:

Key: linenums
Value: linenums

Key: style
Value: source

Key: language
Value: java

This is the HTML output with CodeRay selected as the syntax highlighter:

<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><table class="CodeRay"><tr>
  <td class="line-numbers"><pre>1
</pre></td>
  <td class="code"><pre>Foobar</pre></td>
</tr></table></code></pre>
</div>
</div>

With these results, it seems clear that I can add a key/value pair of "linenums"/"linenums" and it should add the linenums:

Updated test block:

[source,java]
----
Foobar
----

Code:
if (style.equals("source")) {
    block.setAttr("linenums", "linenums", false);
}

Resulting attribute pairs:
Key: linenums
Value: linenums

Key: style
Value: source

Key: language
Value: java

Once again, the HTML output was as expected:

<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><table class="CodeRay"><tr>
  <td class="line-numbers"><pre>1
</pre></td>
  <td class="code"><pre>Foobar</pre></td>
</tr></table></code></pre>
</div>
</div>

Here's where things get confusing. We have a lot of source blocks with no language specified, so for those I want to add the language "text". Therefore, the source attributes should look like this: [source,text,linenums]. For testing consistency, I kept the language as "java." So, my code adds these attributes to a source block that doesn't have any other attributes.

Updated test block:

[source]
----
Foobar
----

Updated code:

if (style.equals("source")) {
    block.setAttr("language", "java", false);
    block.setAttr("linenums", "linenums", false);
}

Resulting attribute pairs:

Key: linenums
Value: linenums

Key: style
Value: source

Key: language
Value: java

Everything looks good, except the HTML doesn't render properly:

<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">Foobar</code></pre>
</div>
</div>

As you can see, it's ignoring the linenums. I've tried many variations of trying to get the line numbers in there, tried it with other languages, but it just doesn't detect the linenums attribute even though it shows up in the key/value pair set.

Any ideas?

Thanks,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Adding Attributes to Source Blocks in AsciidoctorJ

sean.osterberg
I did some more debugging on this today and I noticed something odd: when you inspect the list of attributes on a block, the total count is 2x than the ones that are visible in my IDE (IntelliJ). I'm newish to Java so there could be a reason I don't understand, but this seems like an issue between the interface of Asciidoctor and AsciidoctorJ.

For example, given the following block:

[source]
----
foobar
----

The attribute Map (RubyAttributesMapDecorator) shows a size of 2, but I can only see one key/value pair: "style" --> "source".

Given the following block with three attributes, the size() of the Map is 6, but only the actual key/value pairs are visible:

[source,java,linenums]
----
foobar
----

I'm probably ignorant about something going on under the covers, but given that I can't set the line numbers using AsciidoctorJ, this seems like a bug.