Skip to main content

rumdl_lib/rules/md057_existing_relative_links/
md057_config.rs

1use crate::rule_config_serde::RuleConfig;
2use serde::{Deserialize, Serialize};
3
4/// How to handle absolute links (paths starting with /)
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
6#[serde(rename_all = "snake_case")]
7pub enum AbsoluteLinksOption {
8    /// Ignore absolute links (don't validate them) - this is the default
9    #[default]
10    Ignore,
11    /// Warn about absolute links (they can't be validated as local paths)
12    Warn,
13    /// Resolve absolute links relative to MkDocs docs_dir and validate
14    RelativeToDocs,
15}
16
17/// Configuration for MD057 (relative link validation)
18///
19/// This rule validates that relative links point to existing files.
20#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
21#[serde(default, rename_all = "kebab-case")]
22pub struct MD057Config {
23    /// How to handle absolute links (paths starting with /)
24    /// - "ignore" (default): Skip validation for absolute links
25    /// - "warn": Report a warning for absolute links
26    /// - "relative_to_docs": Resolve relative to MkDocs docs_dir and validate
27    #[serde(alias = "absolute_links")]
28    pub absolute_links: AbsoluteLinksOption,
29
30    /// Warn when relative links contain unnecessary path traversal.
31    /// When enabled, `../sub_dir/file.md` from within `sub_dir/` warns
32    /// and suggests the shorter equivalent `file.md`.
33    #[serde(alias = "compact_paths")]
34    pub compact_paths: bool,
35
36    /// Additional directories to search when a relative link is not found
37    /// relative to the file's directory.
38    ///
39    /// Paths are resolved relative to the project root (where `.rumdl.toml` or
40    /// `pyproject.toml` is found), or relative to the current working directory.
41    ///
42    /// For Obsidian users: the attachment folder is auto-detected from
43    /// `.obsidian/app.json` when `flavor = "obsidian"` is set, so this option
44    /// is typically not needed. Use it for custom setups or non-Obsidian tools.
45    ///
46    /// Example:
47    /// ```toml
48    /// [MD057]
49    /// search-paths = ["assets", "images", "attachments"]
50    /// ```
51    #[serde(alias = "search_paths")]
52    pub search_paths: Vec<String>,
53}
54
55impl RuleConfig for MD057Config {
56    const RULE_NAME: &'static str = "MD057";
57}