2

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?

Matteo NNZ
  • 11,930
  • 12
  • 52
  • 89
  • I don't think its possible. In order to do that the asciidoc compiler would need to be able to read java source code and parse it and understand it ... very complicated feature to add with little pay of and little use cases. If you want to document your REST API like this, maybe add Swagger to your project ? – Arthur Klezovich Nov 04 '21 at 13:51
  • @ArthurKlezovich I had some hope when I saw that [they can already parse methods from source code](http://www.lordofthejars.com/2014/01/dry-with-examples-on-documentation.html). Unfortunately it's not a REST Api doc that I need to, I used that just as an example but it really is a value that can change in the code and should be updated in the asciidoc too. – Matteo NNZ Nov 04 '21 at 13:54
  • 1
    Related: [Can I include Java constant value in AsciiDoctor document?](https://stackoverflow.com/questions/69734228/can-i-include-java-constant-value-in-asciidoctor-document) – Mark Rotteveel Nov 04 '21 at 13:58
  • @MarkRotteveel I hadn't seen this question, I would say it's rather an exact duplicate of my question. Unfortunately there's no answer. – Matteo NNZ Nov 04 '21 at 14:10
  • Indeed. I would have closed as a duplicate if there had been an answer, but for now the link might help if one or the other gets answered in the future. – Mark Rotteveel Nov 04 '21 at 14:13
  • See my answer over there (https://stackoverflow.com/questions/69734228/can-i-include-java-constant-value-in-asciidoctor-document) – Craig Jones Nov 21 '21 at 02:21
  • FYI: The link to "they can already parse methods from source code" is incorrect. The official documentation for the `include` macro is here: https://docs.asciidoctor.org/asciidoc/latest/directives/include/ – eskwayrd Dec 08 '21 at 21:34

2 Answers2

1

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).

eskwayrd
  • 3,691
  • 18
  • 23
0

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.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Peter Verhas
  • 268
  • 1
  • 6