Commit ef9a625b5d
ef9a625b5df9c4cc5e1c05853647c506c97b7e91
parent: f59c734997
Verified · cmc
cmc <hello@cleberg.net> · 2026-08-30 06:53 UTC
audit: a construct named inside verbatim is not a use of it (#1)
The entity check skipped `=verbatim=` and `~code~` spans; the other inline
checks did not, so any page documenting org syntax reported constructs it does
not use. `orgo audit docs` reported `OUT macro call` at
`guide/05-org-support.org:186` — the table row naming macros in order to say
they are unsupported, and the only non-zero out-of-scope count in orgo's own
audit.
`scan_inline` now blanks the literal spans once and runs the timestamp, macro
call, radio/internal target, LaTeX and entity checks against that. Emphasis
pairs still see the raw line: `=` and `~` are themselves markers being counted.
docs audits at 100.0% coverage, 0 out-of-scope.
Closes #1
Layout: unified · split
fixtures/audit-verbatim-constructs.org
added
+4
| @@ -0,0 +1,4 @@ |
| 1 | #+TITLE: Verbatim mentions |
| 2 | |
| 3 | A doc explaining syntax, where every mention is inside verbatim: |
| 4 | =${x^2}$=, ={{{name}}}=, =<<<radio>>>=, =[1/3]=, =CLOCK: [2024-01-01]=. |
src/audit.rs
+12 −10
| @@ -330,21 +330,27 @@ impl Audit { |
| 330 | 330 | rest = &after[end..]; |
| 331 | 331 | } |
| 332 | 332 | |
| 333 | | if has_timestamp(line) { |
| 333 | // The rest read a line that has had its `=verbatim=` and `~code~` spans blanked: |
| 334 | // a construct shown inside verbatim is displayed rather than rendered, so a page |
| 335 | // documenting org syntax is not a use of the syntax it names. Emphasis pairs |
| 336 | // below deliberately still see the raw line — `=` is one of the markers scanned. |
| 337 | let bare = without_literal_spans(line); |
| 338 | |
| 339 | if has_timestamp(&bare) { |
| 334 | 340 | self.count(Scope::In, "timestamp", at); |
| 335 | 341 | } |
| 336 | | if line.contains("{{{") { |
| 342 | if bare.contains("{{{") { |
| 337 | 343 | self.count(Scope::Out, "macro call", at); |
| 338 | 344 | } |
| 339 | | if line.contains("<<<") { |
| 345 | if bare.contains("<<<") { |
| 340 | 346 | self.count(Scope::Out, "radio target", at); |
| 341 | | } else if line.contains("<<") && line.contains(">>") { |
| 347 | } else if bare.contains("<<") && bare.contains(">>") { |
| 342 | 348 | self.count(Scope::Out, "internal target", at); |
| 343 | 349 | } |
| 344 | | if line.contains("\\begin{") || latex_inline(line) { |
| 350 | if bare.contains("\\begin{") || latex_inline(&bare) { |
| 345 | 351 | self.count(Scope::Out, "LaTeX fragment", at); |
| 346 | 352 | } |
| 347 | | if entity_ref(line) { |
| 353 | if entity_ref(&bare) { |
| 348 | 354 | // Rendered, and rendered as org renders it: `\alpha` becomes `α` in |
| 349 | 355 | // both exporters. `fixtures/audit-entities.org` holds the oracle to that. |
| 350 | 356 | self.count(Scope::In, "entity (\\name)", at); |
| @@ -510,11 +516,7 @@ fn latex_inline(line: &str) -> bool { |
| 510 | 516 | /// Only names org knows count, matching [`crate::parser`]'s rule for rendering one: a |
| 511 | 517 | /// Windows path (`C:\Users\me`) and a namespaced identifier (`Tumblr\API\Client`) are not |
| 512 | 518 | /// entity references. |
| 513 | | /// |
| 514 | | /// Verbatim and code spans are skipped: `=\alpha=` shows the name rather than rendering |
| 515 | | /// the character, so it is not a use of the feature. |
| 516 | 519 | fn entity_ref(line: &str) -> bool { |
| 517 | | let line = without_literal_spans(line); |
| 518 | 520 | let chars: Vec<char> = line.chars().collect(); |
| 519 | 521 | for (i, c) in chars.iter().enumerate() { |
| 520 | 522 | if *c != '\\' { |
tests/constructs.rs
+15
| @@ -844,3 +844,18 @@ fn audit_counts_special_blocks_as_in_scope() { |
| 844 | 844 | "no block name is unrecognised — every one renders: {flagged:?}" |
| 845 | 845 | ); |
| 846 | 846 | } |
| 847 | |
| 848 | /// A page that documents org syntax names constructs inside `=verbatim=`; the names are |
| 849 | /// displayed, not rendered, so none of them is a use of the construct. Counting them |
| 850 | /// reported orgo's own guide as using macros it does not support. |
| 851 | #[test] |
| 852 | fn audit_ignores_constructs_inside_verbatim() { |
| 853 | let report = audit_fixture("audit-verbatim-constructs.org"); |
| 854 | for construct in ["macro call", "radio target", "internal target", "timestamp", "LaTeX fragment"] |
| 855 | { |
| 856 | assert!( |
| 857 | !report.contains(construct), |
| 858 | "{construct} was counted from a verbatim mention:\n{report}" |
| 859 | ); |
| 860 | } |
| 861 | } |