Skip to content

print: {{__index}} is the 1-based ordinal of a table / for row (#8610) - #8612

Merged
delchev merged 1 commit into
masterfrom
issue-8610-print-row-index
Nov 13, 2026
Merged

delchev merged 1 commit into
masterfrom
issue-8610-print-row-index

Conversation

@delchev

@delchev delchev commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

Cause

A .print <table source="items"> / <for> had no way to print the row's ordinal: the DataBinder row scope exposed only the row's own fields (plus the enclosing context), so the "№" column a standard invoice items table starts with was not expressible.

Change

A reserved row variable, {{__index}} (double underscore like __label, the other name the binder reserves):

<table source="items">
    <column width="24" label="№">{{__index}}</column>
    <column width="4*" label="Item">{{Name}}</column>
    <column width="*" label="Amount" align="right">{{Amount}}</column>
</table>
  • 1-based, counting the rows actually rendered: numbered after the row filter (filter / match), so a filtered table numbers the kept rows 1, 2, 3 with no gaps.
  • With groupBy it is the ordinal of the group (in the order the groups render).
  • A number like any other: takes a format ({{__index:00}}), composes with text.
  • Nested loops read the innermost row; every table/for counts from 1 again. Outside a row it renders empty.
  • The name is reserved: a row (or document) field called __index is not reachable.

Implementation is confined to DataBinder: the row Scope carries its ordinal, assigned in rowScopes after filtering and grouping, and Scope.resolveOwn answers __index from it.

Docs: modules/parsers/document/README.md (next to groupBy), DataBinder class javadoc, .claude/docs/document-templates.md.

Verification

Run locally in a worktree:

  • mvn test -pl modules/parsers/document,components/engine/engine-document - parsers-document 155 tests, engine-document 82 tests, 0 failures. New: five DataBinderTest cases (table 1..n; filtered table and for numbered contiguously; group ordinal; nested loops / restart per loop / <if> inside a row; format, reserved over a row field, empty outside a row) and XslFoRendererTest.rendersTheRowOrdinalColumnOfAnItemsTable (the acceptance template down to the XSL-FO cells).
  • mvn -T 1C formatter:validate with the formatter cache wiped - green.
  • mvn -P release ... install -pl modules/parsers/document (javadoc) - green.

Not verified: no integration test was run locally; no generator or template changed, so no sample-intent-* fixture is affected.

Fixes #8610

🤖 Generated with Claude Code

A .print table or for loop had no way to print the row's ordinal, so the
line-number column an invoice items table starts with could not be expressed -
the binder exposed only the row's own fields.

The reserved {{__index}} now reads the 1-based position of the row among the
rows actually rendered: counted after the row filter (a filtered table numbers
the kept rows contiguously), and with groupBy the ordinal of the group. It
takes a format like any number, reads the innermost row where loops nest, and
renders empty outside a row.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@delchev
delchev merged commit ec69aa2 into master Nov 13, 2026
16 checks passed
@delchev
delchev deleted the issue-8610-print-row-index branch November 13, 2026 19:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

print: a table / for row has no ordinal - the "№" line-number column of an items table is not expressible

1 participant