Java 10 And Cross References In Asciidoctor

CodeFX Weekly #43 — 11th of November 2017

Hi everyone,

last week I got all excited about Java 10 and claimed that it would contain pattern matching. Yeay! Unfortunately, I got that wrong. Booh! So I took the last week to reign in the excitement and cool down. I am now prepared to offer you a more reasoned introduction to Java’s next release.

And then there’s some background on auto-numbering cross references in Asciidoctor.

I send this newsletter out every Friday. Yes, as an actual email. Subscribe!

Java 10, this time for real

JDK 10 has its own project site, which lists known and proposed features (more on that later) and gives the schedule:

  • 14 Dec 2017: Rampdown Phase One (deadline for merging new features)
  • 11 Jan 2018: All Tests Run
  • 18 Jan 2018: Rampdown Phase Two
  • 22 Feb 2018: Final Release Candidate
  • 20 Mar 2018: General Availability

You can already get Java 10 early-access builds.

IDEs supporting Java 9 should allow experimenting with Java 10 as well, as there aren’t any fundamental changes (you may get compile errors if using var, though). Likewise it should be no problem to use build tools on such projects. In fact, I just started a Java 10 demo project, which works fine in IntelliJ and Maven.


So which features can you expect to be using in March? Here’s the current list (I removed those that are mostly internal):

Targeted to JDK 10:

  • Local-Variable Type Inference (JEP 286; I’m working on a post about this)

Proposed to target JDK 10:

Keep in mind that this list might grow for another five weeks until December 14th. Also note that pattern matching (JEP 305) is not on the list, so maybe check out Vavr after all.

Talks at Devoxx

There were a few interesting talks at Devoxx Belgium 2017 that covered Java’s present and future:

I highly recommend the Ask the JDK Architects session. Two interesting details:

  • the --illegal-access option will likely have warn as default in Java 11
  • in some future Java version, method references can be used in annotations

Asciidoctor References

Last week I complained that Asciidoctor wasn’t powerful enough for me and, in accordance with Cunningham’s Law, I was proven wrong. It took me some time to get it working, so I decided to write it down and send it out.

The problem

For The Java Module System I use Asciidoctor, in which cross references work by setting an anchor with [[anchor-name]] and referencing it with <<anchor-name>>. The text that shows for the reference can be defined following the anchor, i.e. Learn more about <<anchor-name, that thing>>. I link the section numbers, so my text is full of See section <<anchor-name, 6.2>>.

Then I reorganized a third of the book and had to fix all these references. Ugh, I know. Hence my complaint. Fortunately I have attentive readers and one of you gave me the solution. After reading about how references actually work and some fiddling I finally ended up with the result I wanted.

How reference texts are picked out

Important caveat #1: If you use <<anchor-name, the text>> to define a text in the place where you make the reference, nothing else happens and that text is chosen. Makes sense, right?

Important caveat #2: All that follows only works for IDs, not inline anchors:

== [[inline-anchor]]A header [[id]]

No matter what, <<inline-anchor>> always gets replaced with [inline-anchor]. That sucks donkeyballs because all my chapter and section anchors are defined that way (which also tells you why this took me some time to figure out). Looks like some global regex-search-replace is needed to fix that.

Now let’s dive into how exactly the text for a reference like <<anchor-name>> is determined. The attribute that trumps all others is xreflabel, defined in the square brackets after the anchor's name:

== An xreflabel header [[header-xreflabel,xreflabel header]]

If that’s not defined, Asciidoctor uses reftext:

[reftext="reftext header"]
== A reftext header [[header-reftext]]

If neither xreflabel nor reftext are defined, Asciidoctor goes looking for another nice text for the label - e.g. for images it uses their captions and for headers the title itself (in this case A ... header). And here come the good news...

Configure reference style

Since Asciidoctor 1.5.6 that last resort to determine a reference text can be configured. By setting the document attribute xrefstyle to either full, short, or basic various outputs can be achieved. The documentation goes into more details, but I want to focus on my use case - auto-numbering chapters and sections.

When using short, a reference to section X.Y gets the text Section X.Y. That's the right direction, but not exactly what I want:

  • Whether Section or section, any capitalization is bound to be wrong occasionally (unless you prefer capitalizing section mid-sentence, which I don’t).
  • I only want to link the numbers, not the preceding chapter, section, …
  • I occasionally enumerate several chapters and sections and prefer see sections X, Y, Z over see section X, section Y, section Z.

The solution to all of these problems is to the same: remove Section from the auto-text. Fortunately Asciidoctor allows that by unsetting the document attribute section-refsig (and the same for chapter-refsig and appendix-refsig).

Put together, this is my demo document:

= Reference Experiment
Nicolai Parlog
:doctype: article
:xrefstyle: short

== Many headers
=== An xreflabel header [[header-xreflabel,xreflabel header]]
See <<header-xreflabel>>.
[reftext="reftext header"]
=== A reftext header [[header-reftext]]
See <<header-reftext>>.
=== A blank header [[header-blank]]
See section <<header-blank>>.

Formating aside and with links visualized with [], it renders as follows:

1. Many headers
1.1. An xreflabel header
See [xreflabel header].
1.2. A reftext header
See [reftext header].
1.3. A blank header
See section [1.3].

Success! A second round of regex replacements is needed to turn all <<, 1.2>> into <<foo-bar>>, but that should be pretty easy. I can't say I'm looking forward to carefully git add --patch-ing all those changes, but I'll manage.

Project of the week: GDH

GDH, short for Generalized Diffie-Hellman Key Exchange Platform, writes about itself:

A Diffie-Hellman key exchange library for multiple parties built on top of the asynchronous, event-driven Vert.x framework.

The multiple parties bit is important here, because the library implements a version of Diffie–Hellman that is generalized to share a secret between more than two involved parties:

Such cases may arise in complex distributed systems where participants are located on different machines, and need to communicate with each other directly, rather than through one central entity. Instead of generating a secret key for each pair of participants, it is possible to generate a single secret key shared by all participants, in a manner which is resistable to eavesdropping and Man-In-The-Middle attacks.

The lib is pretty new, though, so maybe not bet your company’s future on it being error-free.

PS: Don’t forget to subscribe or recommend! :)