Is it possible to use a constant declared in the source code inside an Asciidoc?

Viewed 121

I have an Ascii doc reporting several times a sentence like:

You can reach the service at https://server:8081/...

The problem I have is that the 8081 may be variable, and depends on a constant which is defined somewhere in the code:

public static final String SERVICE_PORT = "8081";

I would like to do something like:

You can reach the service at https://server:${MyClass.SERVICE_PORT}/...

Like that, each time that the value of the variable changes in the code, it will change in the documentation dynamically.

I've read about DRY URLs, and I've been looking for something similar but with code without success.

Does anyone know if it's possible and, if so, how?

2 Answers

Asciidoctor does not know how to parse source code, so "out of the box" this is not possible.

One approach that you could consider is this:

Before you run Asciidoctor, you can write your own code/script to search for definitions that should be reflected in your documentation, and generate an Asciidoc file containing attribute definitions. Once you have an "attributes" file, you can include it in any other Asciidoc file that needs to use those attributes.

For example, if you generate the attributes.adoc file such that it contains:

:SERVICE_PORT: 8081

And you change your documentation.adoc file to include the attributes (before any other content):

= Documentation

include::attributes.adoc[]

Then your documentation.adoc can use:

You can reach the service at https://server:{SERVICE_PORT}/...

How you go about identifying source values and naming the attributes that reflect those values is up to you. It's often easiest to use the same names as found in the source code, but if multiple source files use a constant in different ways, you'll likely need to determine a prefix to use in the attribute definition (possibly based on the source filename).

You can use the Jamal text processor, which I developed, to solve this problem. It is licensed under Apache 2.0, and it can be used as an asciidoc preprocessor, allowing you to enrich your asciidoc with Jamal macros, which will be calculated during the preprocessing phase.

To do what you want to do, Jamal offers two different solutions:

  1. Define a snippet line in the source code and extract the value using regular expressions in the macro argument {%@snip... %}. This works always for any language in any environment.

  2. Run the preprocessor converting the .adoc.jam file to .adoc during the test of your Java application. In this case the code is available for reflective access and you can use macros like java:field.

The following is a screenshot of the macro used in a sample file in the IntelliJ asciidoc plugin, where the Jamal preprocessor is also installed:

By using Jamal in this way, you can eliminate the need to "write your own code/script" before running Asciidoctor, as eskwayrd's answer recommended.

Related