Skip to main content

mdwright_lint/stdlib/
stray_dollar.rs

1//! Stray `$` in prose.
2//!
3//! Opinionated rule: some projects (this one included) use Unicode
4//! math inside inline code spans rather than `$…$` LaTeX delimiters,
5//! so a literal `$` in prose is usually a typo. Default-off because
6//! other projects rely on `$…$` for math.
7
8use crate::diagnostic::Diagnostic;
9use crate::diagnostic::Fix;
10use crate::rule::LintRule;
11use mdwright_document::Document;
12
13pub struct StrayDollar;
14
15impl LintRule for StrayDollar {
16    fn name(&self) -> &str {
17        "stray-dollar"
18    }
19
20    fn description(&self) -> &str {
21        "Literal `$` in prose (opt-in for projects that don't use $…$ math)."
22    }
23
24    fn explain(&self) -> &str {
25        include_str!("explain/stray_dollar.md")
26    }
27
28    fn produces_fix(&self) -> bool {
29        true
30    }
31
32    fn is_default(&self) -> bool {
33        false
34    }
35
36    fn check(&self, doc: &Document, out: &mut Vec<Diagnostic>) {
37        for chunk in doc.prose_chunks() {
38            for (idx, _) in chunk.text.match_indices('$') {
39                let message = "stray `$` — this project uses Unicode math in inline code \
40                     spans, not LaTeX delimiters"
41                    .to_owned();
42                if let Some(d) = Diagnostic::at(
43                    doc,
44                    chunk.byte_offset,
45                    idx..idx.saturating_add(1),
46                    message,
47                    Some(Fix {
48                        replacement: "`".to_owned(),
49                        safe: false,
50                    }),
51                ) {
52                    out.push(d);
53                }
54            }
55        }
56    }
57}