Skip to content

AsciiDoc: a body-prose match is reported at the wrong line and column, on a document-header attribute #1112

Description

@ciechanowiec

Check for existing issues

  • Completed

Environment

Component Value
Vale 3.15.1
Asciidoctor 2.0.26
OS macOS, Darwin 25.5.0
Format AsciiDoc

Describe the bug / provide steps to reproduce it

This report documents a source-position defect in Vale's AsciiDoc support. Vale matches a semicolon in body prose and reports the match on a different line, at the column of an unrelated semicolon in the document header. The report is written for the Vale maintainers. After running the reproduction below, a maintainer can confirm the wrong position and judge whether the defect shares a root cause with issue #1109.

Reproduction

Create three files in an empty directory.

.vale.ini:

StylesPath = styles
MinAlertLevel = error
[*.adoc]
BasedOnStyles = Repro

styles/Repro/Semicolons.yml, a minimal existence rule that flags every semicolon:

extends: existence
message: "semicolon match"
scope: sentence
level: error
nonword: true
tokens:
  - ';'

repro.adoc, three lines: a header attribute whose value contains a semicolon, one long paragraph whose only semicolon sits after several inline-code spans and an xref: macro, and an orphan level-2 list item:

:pdf-fontsdir: {sourcedir}/docs/themes/fonts;GEM_FONTS_DIR
the component fails two checks the phase requires, and screenshot of the full table hides both. The first pass uses the stock Tailwind utilities `text-yellow-500`, `text-gray-400`, and `text-amber-700`, not the theme tokens, so a later brand change to the teal would skip this table; and it applies them as colored text on a white header, where the muted colors fall below the contrast bar in xref:#done[] (the brand teal on white is about 2.5:1, under the 4.5:1 minimum for text). The art-direction note already calls for the theme color as a fill rather than as text, so the fix is a token-bound `bg-theme-*` fill with dark text on top, which both binds to the token and clears the contrast bar. An empty `records` array renders an empty bordered table, which a reader can't tell apart from a broken page. The refresh feed returns no values in the initial load, so that state is real, and the first pass left it unhandled.
.. *Correction*

Run Vale from that directory:

vale repro.adoc

Expected behavior

Vale reports the match on line 2, column 283, the column of the semicolon in the phrase skip this table;.

Actual behavior

Vale reports the match on line 1, column 45.

 repro.adoc
 1:45  error  semicolon match  Repro.Semicolons

✖ 1 error, 0 warnings and 0 suggestions in 1 file.

Line 1 holds no prose. Column 45 of line 1 is the semicolon inside the attribute value fonts;GEM_FONTS_DIR. The only prose semicolon is on line 2.

The match is the line-2 semicolon, not the header semicolon

Replacing the line-2 semicolon with a period clears the alert. This confirms the matched token is the line-2 semicolon rather than the attribute semicolon on line 1.

sed 's/skip this table; and it applies/skip this table. and it applies/' repro.adoc > repro2.adoc
vale repro2.adoc
# ✔ 0 errors, 0 warnings and 0 suggestions in 1 file.

What the reproduction needs

The defect needs all three of the following at once. Changing any one of them restores the correct position, line 2, column 283.

  • The orphan level-2 list item .. *Correction* on line 3. Replacing it with a plain .. x restores the correct position, so the bold span in the item is part of the trigger. Removing line 3 also restores the correct position.
  • The long paragraph on line 2. The reduction kept about 160 words, several inline-code spans, and one xref: macro. Shortening the paragraph restores the correct position, so a length threshold is involved.
  • The header attribute on line 1, whose semicolon sits at column 45. Shortening the attribute value restores the correct position. While the defect is active, the reported column equals the column of the line-1 semicolon, and moving that semicolon moves the reported column with it. A value long enough to keep the defect active, with its semicolon at column 54, is reported at line 1, column 54.

Relationship to existing issues

Issue #1109, "Heading-scoped rules silently skip sections when a block anchor and an xref: macro coexist," is open against 3.15.1 and describes a source-line desync in AsciiDoc caused by complex constructs. This report is likely the same root cause with a different symptom. There the desync hides heading-scoped matches. Here it places a body-prose match onto a header attribute on a distant line. If the maintainers confirm a shared cause, this report can serve as an added reproduction angle on #1109 rather than a separate defect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions