Inline Directives¶
lang-check supports inline comment directives that control checking behavior within specific regions of a document. Directives are placed inside comments using any of the four supported comment formats.
Basic Directives¶
Disable / Enable¶
Suppress all (or specific) diagnostics between a disable and enable pair:
<!-- lang-check-disable -->
This text is not checked.
<!-- lang-check-enable -->
With rule IDs:
<!-- lang-check-disable spelling.typo grammar.article -->
Only spelling and grammar.article rules are suppressed here.
<!-- lang-check-enable -->
An unclosed lang-check-disable extends to the end of the file.
Disable Next Line¶
Suppress diagnostics on the line immediately following the directive:
<!-- lang-check-disable-next-line -->
This single line is not checked.
This line IS checked.
With rule IDs:
// lang-check-disable-next-line spelling.typo
onlySpellingRuleSuppressedHere
Scoped Begin / End¶
The lang-check-begin / lang-check-end directives define scoped regions
with richer options than basic disable/enable.
<!-- lang-check-begin [OPTIONS] -->
Content in the scoped region.
<!-- lang-check-end -->
An unclosed lang-check-begin extends to the end of the file.
Options¶
Options are space-separated tokens after lang-check-begin.
Rule IDs¶
Bare tokens (not matching any option prefix) are treated as rule IDs. Only those rules are suppressed within the region:
<!-- lang-check-begin spelling.typo -->
Only spelling.typo is suppressed here.
<!-- lang-check-end -->
With no rule IDs and no language override, all diagnostics in the region are suppressed.
Language Override (lang:xx)¶
Check the region in another natural language. Every prose range that starts
inside it is checked in that language; the rest of the document keeps
engines.spell_language.
<!-- lang-check-begin lang:fr -->
Ceci est du texte français.
<!-- lang-check-end -->
A region with only a lang: option (no rule IDs) is a pure language
override — it suppresses nothing.
Regions nest, and the innermost one wins. A lang: directive also beats
whatever the markup itself declares, which is how one quoted passage inside a
#set text(lang: "de") document gets checked in another language without
touching the typesetting.
A tag with no region is resolved before it reaches the engines. It takes the
document default’s region when the language agrees — lang:en under an
en-GB document means en-GB — and a known variant otherwise. This matters:
LanguageTool accepts bare en and de and then reports no spelling errors at
all in them, so an unresolved tag silently checks nothing.
An engine that cannot read the language says so rather than passing the text.
LanguageTool has no Hebrew, so a lang:he region produces a
languagecheck.no-provider diagnostic naming the language, and the
LanguageTool engine is not marked unhealthy for declining it.
Line Slice (check[a:b])¶
Auto-close the region using slice notation. No lang-check-end is needed.
a and b are 0-indexed line offsets after the directive (like Python slicing):
<!-- lang-check-begin check[:5] lang:de -->
Fünf Zeilen auf Deutsch. <!-- line 0 -->
Zweite Zeile. <!-- line 1 -->
Dritte Zeile. <!-- line 2 -->
Vierte Zeile. <!-- line 3 -->
Fünfte Zeile. <!-- line 4 -->
check[:5] covers lines 0–4 (the first 5 lines). You can also start from an
offset — check[2:5] would cover only lines 2–4:
Match Filter (match:/PATTERN/)¶
Only apply the directive to lines matching the given regex:
<!-- lang-check-begin spelling.typo match:/^>\s/ -->
> Quoted text where spelling is suppressed.
Normal text is still checked.
<!-- lang-check-end -->
Exclude Filter (exclude:/PATTERN/)¶
Skip lines matching the given regex — the directive does not apply to them:
<!-- lang-check-begin exclude:/TODO/ -->
This text is suppressed.
TODO: but this line is still checked.
<!-- lang-check-end -->
Type Override (type:FORMAT)¶
Re-parse the region using a different tree-sitter grammar. The content inside the region is extracted as if it were a standalone document of the specified format:
<!-- lang-check-begin type:latex -->
\emph{This region} uses \textbf{LaTeX} parsing rules.
<!-- lang-check-end -->
The format must be a supported language ID (e.g. latex, html, rst,
org). Unknown formats are skipped with a warning.
Combining Options¶
Multiple options can be combined in a single directive:
<!-- lang-check-begin lang:de spelling.typo check[:3] -->
Drei Zeilen auf Deutsch, nur Rechtschreibung unterdrückt.
Zweite Zeile.
Dritte Zeile.
Nesting¶
Begin/end regions can be nested. The inner lang-check-end closes the
most recent lang-check-begin (stack semantics):
<!-- lang-check-begin -->
All rules suppressed.
<!-- lang-check-begin spelling.typo -->
Only spelling suppressed here.
<!-- lang-check-end -->
Back to all rules suppressed.
<!-- lang-check-end -->
Scope markers¶
A bare lang: marker on its own line switches the language from there until
the next marker, with no closing directive:
English up here.
<!-- lang: fr -->
Et du français jusqu'au marqueur suivant.
<!-- lang: en-GB -->
English again.
The comment syntax follows the file: <!-- lang: fr -->, // @lang: fr,
/* @lang: fr */, % @lang: fr. Prose before the first marker keeps
engines.spell_language.
Where both apply to the same position, lang-check-begin lang:xx wins — it
names a region, the marker only names a point.
Languages the markup declares itself¶
Some formats already carry the information, and it is read directly — no directive needed:
Format |
Declaration |
|---|---|
Typst |
|
Typst’s region: becomes the BCP-47 subtag, so lang: "de", region: "CH" is
checked as de-CH. Only text is read; lang means something else on other
functions.
A directive beats the markup, so a document can keep its typesetting language and still have one passage checked in another.
Comment Formats¶
All directives work inside these comment styles:
Format
Syntax
HTML / Markdown
<!-- directive -->Line comment
// directiveBlock comment
/* directive */LaTeX
% directive