Skip to main content

LintContext

Struct LintContext 

Source
pub struct LintContext<'a> {
    pub content: &'a str,
    pub line_offsets: Vec<usize>,
    pub code_blocks: Vec<(usize, usize)>,
    pub code_block_details: Vec<CodeBlockDetail>,
    pub strong_spans: Vec<StrongSpanDetail>,
    pub lines: Vec<LineInfo>,
    pub list_blocks: Vec<ListBlock>,
    pub char_frequency: CharFrequency,
    pub table_blocks: Vec<TableBlock>,
    pub flavor: MarkdownFlavor,
    /* private fields */
}

Fields§

§content: &'a str§line_offsets: Vec<usize>§code_blocks: Vec<(usize, usize)>§code_block_details: Vec<CodeBlockDetail>§strong_spans: Vec<StrongSpanDetail>§lines: Vec<LineInfo>§list_blocks: Vec<ListBlock>§char_frequency: CharFrequency§table_blocks: Vec<TableBlock>§flavor: MarkdownFlavor

Implementations§

Source§

impl<'a> LintContext<'a>

Source

pub fn source_file(&self) -> Option<&Path>

The native source path available to filesystem-aware rules.

Virtual adapters intentionally leave this unset even when they provide a logical path for configuration matching.

Source

pub fn new( content: &'a str, flavor: MarkdownFlavor, source_file: Option<PathBuf>, ) -> Self

Source

pub fn front_matter_end_line(&self) -> usize

The 1-indexed line number where front matter ends (the closing delimiter line), or 0 when the document has no front matter. Computed once in new(); rules must use this instead of re-scanning the content with FrontMatterUtils.

Source

pub fn is_in_code_span_byte(&self, pos: usize) -> bool

Check if a byte position is within a code span. O(log n).

Check if pos is inside any link byte range. O(log n).

Source

pub fn is_in_bare_url(&self, pos: usize) -> bool

Check if `pos`` is within a bare URL

Source

pub fn inline_config(&self) -> &InlineConfig

Get parsed inline configuration state.

Source

pub fn colon_fence_details(&self) -> &[CodeBlockDetail]

Azure DevOps colon code fences (:::lang … :::), each with its byte range and the opener’s info string. These are detected outside the CommonMark parse, so they never appear in code_block_details. Empty for all other flavors.

Source

pub fn raw_lines(&self) -> &[&'a str]

Get pre-split content lines, avoiding repeated content.lines().collect() allocations.

Lines are 0-indexed (line 0 corresponds to line number 1 in the document).

Source

pub fn is_rule_disabled(&self, rule_name: &str, line_number: usize) -> bool

Check if a rule is disabled at a specific line number (1-indexed)

This method checks both persistent disable comments () and line-specific comments (, ).

Source

pub fn code_spans(&self) -> Arc<Vec<CodeSpan>>

Get code spans - computed lazily on first access

Source

pub fn math_byte_ranges(&self) -> &[(usize, usize)]

Math byte ranges ($...$ inline and $$...$$ display), computed once and cached. Used by is_in_math_context; without the cache that helper rescanned the whole document on every call.

Source

pub fn math_spans(&self) -> Arc<Vec<MathSpan>>

Get math spans - computed lazily on first access

Source

pub fn is_in_math_span(&self, byte_pos: usize) -> bool

Check if a byte position is within a math span (inline $…$ or display $$…$$)

Source

pub fn html_comment_ranges(&self) -> &[ByteRange]

Get HTML comment ranges - pre-computed during LintContext construction

Source

pub fn unterminated_html_comment(&self) -> Option<usize>

Byte offset of a <!-- that no --> closes, if the document has one.

Everything after it is inside the comment as far as the parser is concerned, so no rule sees that text.

Source

pub fn unterminated_obsidian_comment(&self) -> Option<usize>

Byte offset of a %% that no second %% closes, if the document has one. Always None outside the Obsidian flavor, where %% is ordinary text rather than a comment delimiter.

Source

pub fn is_in_obsidian_comment(&self, byte_pos: usize) -> bool

Check if a byte position is inside an Obsidian comment

Returns false for non-Obsidian flavors.

Source

pub fn is_position_in_obsidian_comment( &self, line_num: usize, col: usize, ) -> bool

Check if a line/column position is inside an Obsidian comment

Line number is 1-indexed, column is 1-indexed. Returns false for non-Obsidian flavors.

Source

pub fn myst_directive_ranges(&self) -> &[(usize, usize)]

Get byte ranges of MyST colon directive blocks

Source

pub fn is_in_myst_role(&self, byte_pos: usize) -> bool

Check if a byte position is inside a MyST role ({role}content``)

Source

pub fn is_in_myst_comment(&self, byte_pos: usize) -> bool

Check if a byte position is inside a MyST comment (% comment)

Source

pub fn is_myst_colon_directive_opener_line(&self, line_num: usize) -> bool

Check if a line (1-indexed) is a MyST colon-fence directive opener (:::{name} ...).

The text after {name} on an opener is the directive’s argument (an opaque path, URL, or label), not markdown prose. Rules that reformat prose should skip these lines. Returns false for non-MyST flavors and for directive body or closer lines.

Source

pub fn html_tags(&self) -> Arc<Vec<HtmlTag>>

Get HTML tags - computed lazily on first access.

JSX component tags (e.g. <Card .../>) are excluded so HTML-specific rules keep ignoring them; use Self::jsx_component_tags to access those. The single underlying parse populates both caches at once.

Source

pub fn jsx_component_tags(&self) -> Arc<Vec<HtmlTag>>

Get JSX component tags (e.g. <Card .../>) - computed lazily, sharing the HTML-tag parse. Always empty for flavors without JSX support.

Source

pub fn emphasis_spans(&self) -> Arc<Vec<EmphasisSpan>>

Get emphasis spans - pre-computed during construction

Source

pub fn bare_urls(&self) -> Arc<Vec<BareUrl>>

Get bare URLs - computed lazily on first access

Source

pub fn lazy_continuation_lines(&self) -> Arc<Vec<LazyContLine>>

Get lazy continuation lines - computed lazily on first access

Source

pub fn has_mixed_list_nesting(&self) -> bool

Check if document has mixed ordered/unordered list nesting. Result is cached after first computation (document-level invariant). This is used by MD007 for smart style auto-detection.

Source

pub fn offset_to_line_col(&self, offset: usize) -> (usize, usize)

Map a byte offset to (line, column).

The column is a 1-indexed character offset within the line (rumdl’s diagnostic convention), not a byte offset, so it is correct on lines containing multi-byte UTF-8 characters.

Source

pub fn line_start_byte(&self, line_number: usize) -> Option<usize>

Return the byte offset at which a 1-indexed source line starts.

This is the inverse-facing half of Self::offset_to_line_col. Keeping both conversions on the document prevents rules from depending on the line-index representation or reconstructing it independently.

Source

pub fn line_column_byte_range( &self, line_number: usize, column: usize, ) -> Range<usize>

Return an empty byte range at a 1-indexed line and character column.

Columns are character offsets, not UTF-8 byte offsets. Positions past the end of a line clamp to the end of its content; missing lines clamp to the end of the document.

Source

pub fn line_column_byte_range_with_length( &self, line_number: usize, column: usize, length: usize, ) -> Range<usize>

Return a byte range beginning at a 1-indexed line and character column.

length is measured in characters. The result never crosses the line’s content boundary and excludes its line ending.

Source

pub fn whole_line_byte_range(&self, line_number: usize) -> Range<usize>

Return the byte range of a complete 1-indexed line, including its line ending when one is present.

Source

pub fn line_text_byte_range( &self, line_number: usize, start_column: usize, end_column: usize, ) -> Range<usize>

Return the byte range between two 1-indexed character columns on a line.

The range excludes the line ending and clamps both columns to valid character boundaries in the line content.

Source

pub fn line_content_byte_range(&self, line_number: usize) -> Range<usize>

Return the byte range of a 1-indexed line’s content, excluding its line ending.

Source

pub fn line_span_byte_range( &self, start_line: usize, end_line: usize, ) -> Range<usize>

Return the byte range spanning complete 1-indexed lines, inclusive.

Source

pub fn is_in_code_block_or_span(&self, pos: usize) -> bool

Check if a position is within a code block or code span. O(log n).

Source

pub fn line_info(&self, line_num: usize) -> Option<&LineInfo>

Get line information by line number (1-indexed)

Parsed links in document order.

Source

pub fn images(&self) -> &[ParsedImage<'a>]

Parsed images in document order.

Broken or undefined reference links in document order.

Source

pub fn footnote_references(&self) -> &[FootnoteRef]

Parsed footnote references in document order.

Source

pub fn reference_definitions(&self) -> &[ReferenceDef]

Parsed reference definitions in document order.

Links whose opening delimiter starts on line_number (1-indexed).

Source

pub fn images_on_line(&self, line_number: usize) -> &[ParsedImage<'a>]

Images whose opening delimiter starts on line_number (1-indexed).

Find the link that starts at an exact byte offset. O(log n).

Source

pub fn image_starting_at(&self, byte_offset: usize) -> Option<&ParsedImage<'a>>

Find the image that starts at an exact byte offset. O(log n).

Find the parsed link containing byte_offset. O(log n).

Source

pub fn image_containing(&self, byte_offset: usize) -> Option<&ParsedImage<'a>>

Find the parsed image containing byte_offset. O(log n).

Links that start at or before byte_offset, in document order. O(log n).

Source

pub fn reference_definition(&self, ref_id: &str) -> Option<&ReferenceDef>

Find a reference definition by its case-insensitive identifier.

Source

pub fn get_reference_url(&self, ref_id: &str) -> Option<&str>

Get URL for a reference link/image by its ID (O(1) lookup via HashMap)

Source

pub fn is_in_list_block(&self, line_num: usize) -> bool

Check if a line is part of a list block

Source

pub fn is_in_html_block(&self, line_num: usize) -> bool

Check if a line is within an HTML block

Source

pub fn is_in_table_block(&self, line_num: usize) -> bool

Check if a 1-indexed line number is inside a GFM table block.

Returns true for the header line, delimiter line, and all body rows. TableBlock spans are stored 0-indexed; this helper accepts the 1-indexed line numbers used elsewhere in the rule API.

Source

pub fn is_in_code_span(&self, line_num: usize, col: usize) -> bool

Check if a line and column is within a code span

Source

pub fn is_byte_offset_in_code_span(&self, byte_offset: usize) -> bool

Check if a byte offset is within a code span. O(log n).

Source

pub fn is_in_reference_def(&self, byte_pos: usize) -> bool

Check if a byte position is within a reference definition. O(log n).

Source

pub fn is_in_html_comment(&self, byte_pos: usize) -> bool

Check if a byte position is within an HTML comment. O(log n).

Source

pub fn is_in_html_tag(&self, byte_pos: usize) -> bool

Check if a byte position is within an HTML tag (including multiline tags). Uses the pre-parsed html_tags which correctly handles tags spanning multiple lines. O(log n).

Source

pub fn is_in_jsx_component_tag(&self, byte_pos: usize) -> bool

Check if a byte position is within a JSX component tag (e.g. <Card .../>), including its attribute values and multiline tags. Always false for flavors without JSX support. O(log n).

Source

pub fn is_in_jinja_range(&self, byte_pos: usize) -> bool

Check if a byte position is within a Jinja template ({{ }} or {% %}). O(log n).

Source

pub fn is_in_jsx_expression(&self, byte_pos: usize) -> bool

Check if a byte position is within a JSX expression (MDX: {expression}). O(log n).

Source

pub fn is_in_mdx_comment(&self, byte_pos: usize) -> bool

Check if a byte position is within an MDX comment ({/* … */}). O(log n).

Source

pub fn is_in_citation(&self, byte_pos: usize) -> bool

Check if a byte position is within a Pandoc/Quarto citation (@key or [@key]). Active for Pandoc-compatible flavors. O(log n).

Source

pub fn citation_ranges(&self) -> &[ByteRange]

Pre-computed Pandoc/Quarto citation ranges.

Source

pub fn is_in_div_block(&self, byte_pos: usize) -> bool

Check if a byte position is within a Pandoc/Quarto div block (::: ... :::). Active for Pandoc-compatible flavors. O(log n) via binary search over sorted ranges.

Source

pub fn is_in_inline_footnote(&self, byte_pos: usize) -> bool

Check if a byte position is within a Pandoc inline footnote (^[note text]). Active for Pandoc-compatible flavors. O(log n).

Source

pub fn is_in_example_list_marker(&self, byte_pos: usize) -> bool

Check if a byte position is within a Pandoc example-list marker ((@) / (@label) at line start). Active for Pandoc-compatible flavors. O(log n).

Source

pub fn is_in_example_reference(&self, byte_pos: usize) -> bool

Check if a byte position is within a Pandoc example reference ((@label) inline). Active for Pandoc-compatible flavors. O(log n).

Source

pub fn is_in_subscript_or_superscript(&self, byte_pos: usize) -> bool

Check if a byte position is within a Pandoc subscript (~x~) or superscript (^x^) span. Active for Pandoc-compatible flavors. O(log n).

Source

pub fn is_in_inline_code_attr(&self, byte_pos: usize) -> bool

Check if a byte position is within a Pandoc inline-code attribute block ({.lang} immediately following `code`). Active for Pandoc-compatible flavors. O(log n).

Source

pub fn is_in_bracketed_span(&self, byte_pos: usize) -> bool

Check if a byte position is within a Pandoc bracketed span ([text]{attrs}). Active for Pandoc-compatible flavors. O(log n).

Source

pub fn is_in_line_block(&self, byte_pos: usize) -> bool

Returns true if byte_pos falls inside a Pandoc line block (| text). Active for Pandoc-compatible flavors. O(log n).

Source

pub fn is_in_pipe_table_caption(&self, byte_pos: usize) -> bool

Returns true if byte_pos falls inside a Pandoc pipe-table caption (: caption adjacent to a pipe table). Active for Pandoc-compatible flavors. O(log n).

Source

pub fn is_in_pandoc_metadata(&self, byte_pos: usize) -> bool

Returns true if byte_pos falls inside a Pandoc YAML metadata block. Active for Pandoc-compatible flavors. O(log n).

Source

pub fn is_in_grid_table(&self, byte_pos: usize) -> bool

Returns true if byte_pos falls inside a Pandoc grid table. Active for Pandoc-compatible flavors. O(log n).

Source

pub fn is_in_multi_line_table(&self, byte_pos: usize) -> bool

Returns true if byte_pos falls inside a Pandoc multi-line table. Active for Pandoc-compatible flavors. O(log n).

Source

pub fn matches_implicit_header_reference(&self, link_text: &str) -> bool

Returns true if link_text, after Pandoc slugification, matches a heading in the document. Returns false for non-Pandoc-compatible flavors because the pandoc_header_slugs set is empty when the pre-pass detector is gated off. Use this when the caller has raw bracketed text ([Section name]).

Source

pub fn has_pandoc_slug(&self, slug: &str) -> bool

Returns true if slug (already in Pandoc-slug form) matches a heading in the document. Returns false for non-Pandoc-compatible flavors because the pandoc_header_slugs set is empty when the pre-pass detector is gated off. Use this when the caller already has a slug (e.g. the fragment of a URL after #). O(1).

Source

pub fn is_in_shortcode(&self, byte_pos: usize) -> bool

Check if a byte position is within a Hugo/Quarto shortcode ({{< … >}} or {{% … %}}). O(log n).

Source

pub fn shortcode_ranges(&self) -> &[(usize, usize)]

Pre-computed Hugo/Quarto shortcode ranges.

Check if a byte position is within a link reference definition title. O(log n).

Source

pub fn has_char(&self, ch: char) -> bool

Check if content has any instances of a specific character (fast)

Source

pub fn char_count(&self, ch: char) -> usize

Get count of a specific character (fast)

Source

pub fn likely_has_headings(&self) -> bool

Check if content likely contains headings (fast)

Source

pub fn likely_has_lists(&self) -> bool

Check if content likely contains lists (fast)

Source

pub fn likely_has_emphasis(&self) -> bool

Check if content likely contains emphasis (fast)

Source

pub fn likely_has_tables(&self) -> bool

Check if content likely contains tables (fast)

Source

pub fn likely_has_blockquotes(&self) -> bool

Check if content likely contains blockquotes (fast)

Source

pub fn likely_has_code(&self) -> bool

Check if content likely contains code (fast)

Check if content likely contains links or images (fast)

Source

pub fn likely_has_html(&self) -> bool

Check if content likely contains HTML (fast)

Source

pub fn blockquote_prefix_for_blank_line(&self, line_idx: usize) -> String

Get the blockquote prefix for inserting a blank line at the given line index. Returns the prefix without trailing content (e.g., “>” or “>>”). This is needed because blank lines inside blockquotes must preserve the blockquote structure. Returns an empty string if the line is not inside a blockquote.

Source

pub fn valid_headings(&self) -> ValidHeadingsIter<'_>

Get an iterator over valid headings (skipping invalid ones like #NoSpace)

Valid headings have proper spacing after the # markers (or are level > 1). This is the standard iterator for rules that need to process headings.

§Examples
use rumdl_lib::lint_context::LintContext;
use rumdl_lib::config::MarkdownFlavor;

let content = "# Valid Heading\n#NoSpace\n## Another Valid";
let ctx = LintContext::new(content, MarkdownFlavor::Standard, None);

for heading in ctx.valid_headings() {
    println!("Line {}: {} (level {})", heading.line_num, heading.heading.text, heading.heading.level);
}
// Only prints valid headings, skips `#NoSpace`
Source

pub fn has_valid_headings(&self) -> bool

Check if the document contains any valid CommonMark headings

Returns true if there is at least one heading with proper space after #.

Source

pub fn list_items(&self) -> ParsedListItemsIter<'_>

Iterate over every parsed list item in source order.

Source

pub fn list_item_on_line(&self, line_num: usize) -> Option<ParsedListItem<'_>>

Return the parsed list item on a 1-indexed source line, if any.

Source

pub fn parsed_list_blocks(&self) -> ParsedListBlocks<'_>

Borrow the document’s parsed list blocks and their item iterators.

Source

pub fn list_block_item_groups(&self, block: &ListBlock) -> Vec<Vec<usize>>

The item lines of block grouped into the lists they form, one group per list as CommonMark nests them, in source order, so siblings can be compared without the nested items that sit between them.

Source

pub fn has_list_items(&self) -> bool

Whether the document contains any parsed list items.

Source

pub fn has_unordered_list_items(&self) -> bool

Whether the document contains any parsed unordered-list items.

Source

pub fn commonmark_ordered_lists(&self) -> CommonMarkOrderedLists<'_>

Borrow ordered lists using the membership and start values determined by CommonMark.

Source

pub fn headings(&self) -> ParsedHeadingsIter<'_>

Iterate over every heading recognized in the rendered document.

This includes top-level ATX and Setext headings, ATX headings nested in blockquotes, and malformed top-level ATX headings retained for diagnostics. Code blocks, front matter, raw HTML blocks, and flavor-specific non-Markdown regions are excluded during parsing; explicitly Markdown-enabled HTML containers remain eligible.

Source

pub fn heading_on_line(&self, line_num: usize) -> Option<ParsedHeading<'_>>

Return the parsed heading on a 1-indexed source line, if any.

Trait Implementations§

Source§

impl<'a> FilteredLinesExt for LintContext<'a>

Source§

fn filtered_lines(&self) -> FilteredLinesBuilder<'_>

Start building a filtered lines iterator Read more
Source§

fn content_lines(&self) -> FilteredLinesIter<'_>

Get an iterator over content lines only Read more

Auto Trait Implementations§

§

impl<'a> !Freeze for LintContext<'a>

§

impl<'a> RefUnwindSafe for LintContext<'a>

§

impl<'a> Send for LintContext<'a>

§

impl<'a> Sync for LintContext<'a>

§

impl<'a> Unpin for LintContext<'a>

§

impl<'a> UnsafeUnpin for LintContext<'a>

§

impl<'a> UnwindSafe for LintContext<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more