Figure type identification

Hello all,

In the context of the Numbered Figures Application, we wish to be able to distinguish between figures containing any content (e.g., an image) from figures containing a single table client side (e.g., using css/javascript).

The main use case is to ba able to customize the numbered prefix of the captions with a contextual label. “Figure X” by default, and “Table X” for the figures containing a table.
Note that the figures and table will have separate counters. See the screenshot below, they each have a counter value of 1.

image

Figure annotation

Numbered Figures Application depends on XS 14.2+, where nothing is provided to identify figures containing a single table.

I propose to:

  • Make an improvement on 14.5RC1+ to annotate the figure tags with some information. What kind of information is to be defined, see below.
  • Override the figure macro in a new application-numbered-content-figures-ui module for versions lower than 14.5RC1 (this overriding macro will be removed once the extension depends on 14.5RC1+)
  • Update the figure numbering CSS to adapt the label according to these additional information

Figure with table identification: class vs data attribute

I see two solutions here:

  • add a specific class to the figure tag. Note that the table class is already used (see the footnotes below), so it’s better to use something else. I propose to use wikigeneratedfigurenumber which was used by the Numbered Reference Macro
  • add a data attribute to the figure tag, for instance data-xwiki-rendering-figure-type, with value table or figure.

I prefer the css based solution that is compatible with legacy use cases of the same kind.

WDYT?

Foonotes:

Table specific css:

.table, table {
  width: 100%;
  max-width: 100%;
  margin-bottom: 20px;
}

You didn’t say it but from what I read between the lines, the issue is that you’re doing this on the client side in javascript. We used to have this feature before without the need to have anything in XS (we were just checked the XDOM blocks in Java). Is that why you need it in the XDOM vs computing it?

So what you’re proposing would be to modify the Figure macro in XS to add the metadata in the generated XDOM from what I understand.

I don’t understand. You want to generate the figure and table numbers on the server side, and put that in the XDOM? That sounds too specific and not generic enough for this code to be in XS.

This wouldn’t require any numbering computation on the server side, right?

That’s correct. I’ve updated to proposal to be more explicit.

Exactly, the goal is to generate some “flag” that can be used by client side code (css/javascript) to decide what to render. In our case some css adding a prefix to the figureCaption text.

I proposed wikigeneratedfigurenumber because it was already used by Numbered Reference Macro but since the semantics is not the same, that’s probably misleading.
Another option is to add the classes numbered-figure for the figures, and numbered-table for the tables.

Why would the Figure macro do this since it doesn’t have the concept of numbering?

Right, that’s not correct. To follow the logic proposed for the data attribute, the classes could be figure-type-figure and figure-type-table.

Also, I’ve looked a bit more into the detail of how to identify the type of a figure.

A helper exists to identify if a figure is of type table, FigureTypeRecognizer#isTable. This method expects its FigureBlock parameter to already have had the macro transformation executed on.

This means that isTable cannot be called directly from FigureMacro. I propose to introduce a low priority figureTypeIdentifier macro, and to insert it in the list of blocks returned by the figure macro:

List.of(new CompositeBlock(List.of(
  new MacroBlock("figureTypeIdentifier", Map.of(), false),
  new FigureBlock(contentBlock))
))

Then, when the figureTypeIdentifier macro is executed, its job is to navigate to its sibling (context.getCurrentMacroBlock().getNextSibling), and to call isTable on it, and to annotate it with an attribute (and its return value is the empty list).

Note: another option is to change the logic of isTable to support not yet macro transformed blocks, at the risk of having false negative. In this case we could also add a parameter to the figure macro, to allow users to define the type of the figures manually. But it add complexity while the first solution is fully transparent to the end user.

WDYT?

Corresponding Pull Request: https://github.com/xwiki/xwiki-rendering/pull/215