Skip to main content

mdwright_lint/stdlib/
unbalanced_backtick.rs

1//! A backtick in prose that pulldown-cmark could not pair.
2//!
3//! `CommonMark`'s parser pairs backtick runs greedily. If a literal
4//! `` ` `` survives into a prose chunk, no matching closing fence
5//! was found and the inline code span did not close. Renderers that
6//! treat the unmatched run as prose tend to mangle nearby `_` or `*`
7//! — flagging this early prevents that.
8
9use crate::diagnostic::Diagnostic;
10use crate::rule::LintRule;
11use mdwright_document::Document;
12
13pub struct UnbalancedBacktick;
14
15impl LintRule for UnbalancedBacktick {
16    fn name(&self) -> &str {
17        "unbalanced-backtick"
18    }
19
20    fn description(&self) -> &str {
21        "Backtick in prose that could not be paired with a closing fence."
22    }
23
24    fn explain(&self) -> &str {
25        include_str!("explain/unbalanced_backtick.md")
26    }
27
28    fn check(&self, doc: &Document, out: &mut Vec<Diagnostic>) {
29        for chunk in doc.prose_chunks() {
30            for (idx, _) in chunk.text.match_indices('`') {
31                let message = "unclosed inline code span — pulldown-cmark could not pair \
32                     this backtick with a closing fence"
33                    .to_owned();
34                if let Some(d) = Diagnostic::at(doc, chunk.byte_offset, idx..idx.saturating_add(1), message, None) {
35                    out.push(d);
36                }
37            }
38        }
39    }
40}