Check for existing issues
Environment
- Vale 3.15.1
- macOS (Darwin 25.5.0)
- Format: AsciiDoc (
.adoc)
Describe the bug / provide steps to reproduce it
Summary
In an AsciiDoc heading, when an inline code span is immediately followed by an inline passthrough (`code`++...++), the text Vale extracts for heading-scoped checks is corrupted: the code span is replaced by a run of *, and the passthrough content is split off as a separate, space-prefixed token. A check scoped to headings then runs against this mangled text and reports a false positive.
I hit this with a capitalization / match: $title rule, but the corruption is in the extracted text itself, so any heading-scoped check is affected.
Steps to reproduce
Three files:
.vale.ini
StylesPath = styles
[*.adoc]
BasedOnStyles = Test
styles/Test/Heading.yml
extends: capitalization
message: "'%s' should use title-style capitalization."
level: error
scope: heading
match: $title
test.adoc
= T
==== Mixing `ResourceProvider`++s++
==== One Tree of `Resource`++s++
==== Using `Foo`++s++ Here
Run:
Actual behavior
test.adoc
3:1 error 'Mixing **************** s' should use title-style capitalization. Test.Heading
7:1 error 'Using *** s Here' should use title-style capitalization. Test.Heading
Two things are visible in the messages themselves:
- The inline code span is masked as
* (16 for ResourceProvider, 3 for Foo), which is expected - Vale skips code.
- The passthrough
++s++ is detached as a separate s token with a leading space, instead of being attached to the code span as ResourceProviders. That stray lowercase s is what the title-case check trips over.
Expected behavior
No error. `ResourceProvider`++s++ renders as ResourceProviders, and "Mixing ResourceProviders" is valid title case. The extracted text should keep the s attached to the (masked) code span rather than splitting it into its own token.
What makes me think it's a tokenization bug, not the rule
The second heading, ==== One Tree of `Resource`++s++, uses the same idiom but does not trigger the error. Same construct, different result - so the rule behaves correctly on the text it gets, and the text it gets is what differs between the two headings. The stray s token appears for some code-span and passthrough combinations but not others.
For context, `word`++s++ is the standard AsciiDoc way to pluralize a monospaced term, since a constrained code span can't be followed directly by a word character (`word`s renders the backticks literally). So this pattern shows up in normal technical writing wherever a code identifier is pluralized in a heading.
Workaround
For anyone landing here: wrap the heading in a toggle, or reword so the heading doesn't end in a pluralized code span.
ifdef::backend-html5[]
++++
<!-- vale Test.Heading = NO -->
++++
endif::[]
==== Mixing `ResourceProvider`++s++
ifdef::backend-html5[]
++++
<!-- vale Test.Heading = YES -->
++++
endif::[]
Check for existing issues
Environment
.adoc)Describe the bug / provide steps to reproduce it
Summary
In an AsciiDoc heading, when an inline code span is immediately followed by an inline passthrough (
`code`++...++), the text Vale extracts for heading-scoped checks is corrupted: the code span is replaced by a run of*, and the passthrough content is split off as a separate, space-prefixed token. A check scoped to headings then runs against this mangled text and reports a false positive.I hit this with a
capitalization/match: $titlerule, but the corruption is in the extracted text itself, so any heading-scoped check is affected.Steps to reproduce
Three files:
.vale.inistyles/Test/Heading.ymltest.adocRun:
Actual behavior
Two things are visible in the messages themselves:
*(16 forResourceProvider, 3 forFoo), which is expected - Vale skips code.++s++is detached as a separatestoken with a leading space, instead of being attached to the code span asResourceProviders. That stray lowercasesis what the title-case check trips over.Expected behavior
No error.
`ResourceProvider`++s++renders asResourceProviders, and "MixingResourceProviders" is valid title case. The extracted text should keep thesattached to the (masked) code span rather than splitting it into its own token.What makes me think it's a tokenization bug, not the rule
The second heading,
==== One Tree of `Resource`++s++, uses the same idiom but does not trigger the error. Same construct, different result - so the rule behaves correctly on the text it gets, and the text it gets is what differs between the two headings. The straystoken appears for some code-span and passthrough combinations but not others.For context,
`word`++s++is the standard AsciiDoc way to pluralize a monospaced term, since a constrained code span can't be followed directly by a word character (`word`srenders the backticks literally). So this pattern shows up in normal technical writing wherever a code identifier is pluralized in a heading.Workaround
For anyone landing here: wrap the heading in a toggle, or reword so the heading doesn't end in a pluralized code span.