(
version: 1,
settings: (
heading_too_long_threshold: 120,
unsafe_protocols: ["javascript", "data"],
insecure_link_prefixes: ["http://"],
script_tag_markers: ["<script"],
unknown_code_fallback: "UNKNOWN",
unknown_message_fallback: "Unknown diagnostic",
unknown_fix_suggestion_fallback: "No fix suggestion available.",
unknown_protocol_label: "unknown",
),
groups: [
(
id: "parse",
title: "Parse and ingestion",
description: "Document parse and structural ingestion diagnostics.",
code_prefix: "MD1",
tags: ["core", "parse"],
),
(
id: "links",
title: "Links and references",
description: "Inline links, reference links, and URL protocol diagnostics.",
code_prefix: "MD2",
tags: ["core", "links"],
),
(
id: "code",
title: "Code blocks and spans",
description: "Code fence and code content quality diagnostics.",
code_prefix: "MD3",
tags: ["core", "code"],
),
(
id: "images",
title: "Images",
description: "Image source and accessibility diagnostics.",
code_prefix: "MD4",
tags: ["core", "images", "accessibility"],
),
(
id: "html",
title: "HTML safety",
description: "Inline and block HTML safety diagnostics.",
code_prefix: "MD5",
tags: ["core", "html", "security"],
),
(
id: "blocks",
title: "Block structure",
description: "List, table, blockquote, and definition structure diagnostics.",
code_prefix: "MD7",
tags: ["core", "structure"],
),
(
id: "github-features",
title: "GitHub/GFM features",
description: "Diagnostics for GitHub-flavored and GitHub-supported Markdown features.",
code_prefix: "MG",
tags: ["gfm", "github"],
),
(
id: "marco-features",
title: "Marco native features",
description: "Diagnostics for Marco-only markdown extensions.",
code_prefix: "MO",
tags: ["marco", "extension"],
),
],
features: [
(
key: "task-lists",
title: "Task lists",
category: "gfm",
status: "implemented",
node_kinds: ["List", "ListItem", "TaskCheckbox"],
showcase_doc: Some("documentation/showcase/02_tables_and_task_lists.md"),
related_diagnostics: ["MG701", "MG702"],
notes: "Covers malformed and empty task list items.",
examples: ["- [x] done", "- [ ] todo"],
),
(
key: "math",
title: "Math",
category: "gfm",
status: "implemented",
node_kinds: ["InlineMath", "DisplayMath"],
showcase_doc: Some("documentation/showcase/05_math_katex.md"),
related_diagnostics: ["MG902"],
notes: "Reports empty inline or display math expressions.",
examples: ["$E=mc^2$", "$$a^2+b^2=c^2$$"],
),
(
key: "tab-blocks",
title: "Tab blocks",
category: "marco",
status: "implemented",
node_kinds: ["TabGroup", "TabItem"],
showcase_doc: Some("documentation/showcase/07_tab_blocks.md"),
related_diagnostics: ["MO901", "MO902", "MO903", "MO904"],
notes: "Marco-native tab containers and panels.",
examples: [":::tab", "@tab Overview"],
),
(
key: "slider-decks",
title: "Slider decks",
category: "marco",
status: "implemented",
node_kinds: ["SliderDeck", "Slide"],
showcase_doc: Some("documentation/showcase/08_slider_decks.md"),
related_diagnostics: ["MO905", "MO906", "MO907"],
notes: "Marco-native slide deck syntax.",
examples: ["@slidestart", "---", "@slideend"],
),
],
entries: [
(
key: "ParseFailure",
code: "MD101",
title: "Markdown parse failure",
default_severity: "Error",
fix_suggestion: "Fix the malformed markdown near the reported location and retry parsing.",
description: "The document could not be parsed into a valid AST.",
tags: ["core", "parse"],
examples: ["Unclosed fence or malformed block syntax"],
),
(
key: "InvalidHeadingLevel",
code: "MD102",
title: "Invalid heading level",
message_template: Some("Heading level {level} is invalid; maximum allowed level is 6."),
default_severity: "Warning",
fix_suggestion: "Use heading levels from `#` through `######`.",
description: "A heading uses a level deeper than Markdown supports.",
tags: ["headings", "structure"],
examples: ["####### Too deep"],
),
(
key: "EmptyHeadingText",
code: "MD103",
title: "Empty heading text",
default_severity: "Warning",
fix_suggestion: "Add meaningful text after the heading marker.",
description: "A heading marker exists but the heading text is empty.",
tags: ["headings"],
examples: ["## "],
),
(
key: "DuplicateHeadingId",
code: "MD104",
title: "Duplicate heading id",
message_template: Some("Heading id `{id}` is duplicated (first seen on line {line})."),
default_severity: "Warning",
fix_suggestion: "Assign a unique explicit id to each heading.",
description: "Multiple headings use the same explicit id.",
tags: ["headings", "anchors"],
examples: ["## A {#intro}", "## B {#intro}"],
),
(
key: "HeadingTooLong",
code: "MD105",
title: "Heading text is very long",
default_severity: "Info",
fix_suggestion: "Shorten the heading text for better readability.",
description: "A heading exceeds the configured readability threshold.",
tags: ["headings", "style"],
examples: ["A heading significantly longer than 120 characters"],
),
(
key: "EmptyLinkUrl",
code: "MD201",
title: "Empty link URL",
default_severity: "Error",
fix_suggestion: "Provide a non-empty URL inside `( ... )`.",
description: "A link destination is empty and cannot be resolved.",
tags: ["links"],
examples: ["[docs]()"],
),
(
key: "UnsafeLinkProtocol",
code: "MD202",
title: "Unsafe link protocol",
message_template: Some("Link protocol `{protocol}` is disallowed for safety reasons."),
default_severity: "Error",
fix_suggestion: "Use a safe protocol such as `https:`.",
description: "The link uses a protocol blocked by security policy.",
tags: ["links", "security"],
examples: ["[x](javascript:alert(1))"],
),
(
key: "InsecureLinkProtocol",
code: "MD203",
title: "Insecure link protocol",
default_severity: "Info",
fix_suggestion: "Prefer `https://` over `http://` when possible.",
description: "The link uses an insecure protocol prefix.",
tags: ["links", "security"],
examples: ["[site](http://example.com)"],
),
(
key: "UnresolvedLinkReference",
code: "MD204",
title: "Unresolved link reference",
default_severity: "Warning",
fix_suggestion: "Define the missing link reference label in the document.",
description: "A reference-style link points to a label that is not defined.",
tags: ["links", "references"],
examples: ["[guide][missing]"],
),
(
key: "EmptyLinkReferenceLabel",
code: "MD205",
title: "Empty link reference label",
default_severity: "Warning",
fix_suggestion: "Provide a non-empty reference label.",
description: "A reference-style link uses an empty label.",
tags: ["links", "references"],
examples: ["[guide][]"],
),
(
key: "EmptyCodeBlock",
code: "MD301",
title: "Empty code block",
default_severity: "Warning",
fix_suggestion: "Add code content or remove the empty fenced block.",
description: "A fenced code block contains no code content.",
tags: ["code"],
examples: ["```\n```"],
),
(
key: "MissingCodeBlockLanguage",
code: "MD302",
title: "Missing code block language",
default_severity: "Hint",
fix_suggestion: "Add a language after the fence, for example: ```rust",
description: "A non-empty fenced code block omits its language hint.",
tags: ["code", "syntax-highlighting"],
examples: ["```\nlet x = 1;\n```"],
),
(
key: "EmptyImageUrl",
code: "MD401",
title: "Empty image URL",
default_severity: "Error",
fix_suggestion: "Set a valid image URL between `(` and `)`.",
description: "The image URL is empty, so the renderer cannot render an image from this node.",
tags: ["images", "rendering"],
examples: ["![chart]()"],
),
(
key: "ImageMissingAltText",
code: "MD402",
title: "Image missing alt text",
default_severity: "Warning",
fix_suggestion: "Add descriptive alt text between '[' and ']' for accessibility and better screen-reader output.",
description: "The image is missing meaningful alternative text.",
tags: ["images", "accessibility"],
examples: [""],
),
(
key: "UnsafeImageProtocol",
code: "MD403",
title: "Unsafe image protocol",
message_template: Some("Image protocol `{protocol}` is disallowed for safety reasons."),
default_severity: "Error",
fix_suggestion: "Use a safe image protocol such as `https:`.",
description: "The image source uses a blocked protocol.",
tags: ["images", "security"],
examples: [")"],
),
(
key: "InlineHtmlContainsScript",
code: "MD501",
title: "Inline HTML contains script tag",
default_severity: "Error",
fix_suggestion: "Remove `<script>` from inline HTML.",
description: "Inline HTML contains script markup disallowed by policy.",
tags: ["html", "security"],
examples: ["<span><script>alert(1)</script></span>"],
),
(
key: "InlineHtmlJavascriptUrl",
code: "MD502",
title: "Inline HTML contains unsafe protocol",
default_severity: "Error",
fix_suggestion: "Remove unsafe protocol URLs from inline HTML attributes.",
description: "Inline HTML includes an unsafe URL protocol marker.",
tags: ["html", "security"],
examples: ["<a href=\"javascript:alert(1)\">x</a>"],
),
(
key: "InlineHtmlUnsafeEventHandler",
code: "MD503",
title: "Inline HTML contains unsafe event handler",
default_severity: "Error",
fix_suggestion: "Remove inline event-handler attributes like `onclick=`.",
description: "Inline HTML contains unsafe inline event handler attributes.",
tags: ["html", "security"],
examples: ["<button onclick=\"x()\">go</button>"],
),
(
key: "HtmlBlockContainsScript",
code: "MD601",
title: "HTML block contains script tag",
default_severity: "Error",
fix_suggestion: "Remove `<script>` from HTML blocks.",
description: "An HTML block contains script markup disallowed by policy.",
tags: ["html", "security"],
examples: ["<script>alert(1)</script>"],
),
(
key: "HtmlBlockJavascriptUrl",
code: "MD602",
title: "HTML block contains unsafe protocol",
default_severity: "Error",
fix_suggestion: "Use safe URL protocols in HTML blocks.",
description: "An HTML block includes an unsafe URL protocol marker.",
tags: ["html", "security"],
examples: ["<a href=\"javascript:...\">"],
),
(
key: "EmptyHtmlBlock",
code: "MD603",
title: "Empty HTML block",
default_severity: "Warning",
fix_suggestion: "Remove the empty HTML block or add valid content.",
description: "An HTML block node is present but contains no content.",
tags: ["html"],
examples: ["<div></div>"],
),
(
key: "HtmlBlockMismatchedAngles",
code: "MD604",
title: "HTML block has mismatched angle brackets",
default_severity: "Error",
fix_suggestion: "Balance `<` and `>` characters in the HTML block.",
description: "The HTML block appears malformed due to mismatched angle brackets.",
tags: ["html", "parse"],
examples: ["<div><span</div>"],
),
(
key: "HtmlBlockUnsafeEventHandler",
code: "MD605",
title: "HTML block contains unsafe event handler",
default_severity: "Error",
fix_suggestion: "Remove inline event-handler attributes from the HTML block.",
description: "The HTML block contains unsafe inline event handler attributes.",
tags: ["html", "security"],
examples: ["<img onerror=\"x()\" src=\"a\">"],
),
(
key: "EmptyList",
code: "MD701",
title: "Empty list",
default_severity: "Warning",
fix_suggestion: "Add at least one list item or remove the empty list.",
description: "A list node has no list items.",
tags: ["lists", "structure"],
examples: ["- (no items)"],
),
(
key: "EmptyListItem",
code: "MD702",
title: "Empty list item",
default_severity: "Warning",
fix_suggestion: "Add content to the list item.",
description: "A list item exists but has no content nodes.",
tags: ["lists", "structure"],
examples: ["-"],
),
(
key: "MalformedTaskCheckbox",
code: "MG701",
title: "Malformed task checkbox",
default_severity: "Warning",
fix_suggestion: "Use `[ ]` or `[x]` at the start of the task list item.",
description: "A task list marker is present but malformed for GFM task list syntax.",
tags: ["gfm", "task-lists"],
examples: ["- [maybe] task"],
),
(
key: "EmptyTaskListItem",
code: "MG702",
title: "Empty task list item",
default_severity: "Warning",
fix_suggestion: "Add text after the task checkbox marker.",
description: "A GFM task item has a checkbox but no meaningful task text.",
tags: ["gfm", "task-lists"],
examples: ["- [ ]"],
),
(
key: "EmptyBlockquote",
code: "MD703",
title: "Empty blockquote",
default_severity: "Warning",
fix_suggestion: "Add quoted content or remove the empty blockquote.",
description: "A blockquote node exists without quoted content.",
tags: ["blockquote", "structure"],
examples: [">"],
),
(
key: "EmptyDefinitionList",
code: "MD704",
title: "Empty definition list",
default_severity: "Warning",
fix_suggestion: "Add definition terms and descriptions.",
description: "A definition list contains no entries.",
tags: ["definitions", "structure"],
examples: [":"],
),
(
key: "EmptyDefinitionTerm",
code: "MD705",
title: "Empty definition term",
default_severity: "Warning",
fix_suggestion: "Add text for the definition term.",
description: "A definition term node is present but empty.",
tags: ["definitions", "structure"],
examples: ["\n: description"],
),
(
key: "EmptyDefinitionDescription",
code: "MD706",
title: "Empty definition description",
default_severity: "Warning",
fix_suggestion: "Add explanatory text to the definition description.",
description: "A definition description node is present but empty.",
tags: ["definitions", "structure"],
examples: ["Term\n:"],
),
(
key: "EmptyTableCell",
code: "MG703",
title: "Empty table cell",
default_severity: "Warning",
fix_suggestion: "Fill the table cell with content or remove the column.",
description: "A GFM table cell is present but contains no meaningful text.",
tags: ["gfm", "table"],
examples: ["| a | | c |"],
),
(
key: "MissingFootnoteDefinition",
code: "MG801",
title: "Missing footnote definition",
default_severity: "Warning",
fix_suggestion: "Define the referenced footnote label, e.g. `[^label]: footnote text`.",
description: "A footnote reference does not have a matching GFM footnote definition.",
tags: ["gfm", "footnotes"],
examples: ["Reference[^x] with no `[^x]: ...`"],
),
(
key: "DuplicateFootnoteDefinition",
code: "MG802",
title: "Duplicate footnote definition",
default_severity: "Warning",
fix_suggestion: "Keep only one definition per footnote label.",
description: "The same footnote label is defined more than once.",
tags: ["gfm", "footnotes"],
examples: ["[^x]: first", "[^x]: second"],
),
(
key: "UnusedFootnoteDefinition",
code: "MG803",
title: "Unused footnote definition",
default_severity: "Hint",
fix_suggestion: "Remove the unused definition or add a matching reference.",
description: "A footnote definition exists but is never referenced.",
tags: ["gfm", "footnotes"],
examples: ["[^unused]: text"],
),
(
key: "EmptyTabGroup",
code: "MO901",
title: "Empty tab group",
default_severity: "Warning",
fix_suggestion: "Add at least one `@tab` item inside the `:::tab` container.",
description: "A Marco tab container exists without any tab items.",
tags: ["marco", "tabs"],
examples: [":::tab\n:::"],
),
(
key: "EmptyTabTitle",
code: "MO902",
title: "Empty tab title",
default_severity: "Warning",
fix_suggestion: "Provide a non-empty title after `@tab`.",
description: "A Marco tab item is missing its title text.",
tags: ["marco", "tabs"],
examples: ["@tab "],
),
(
key: "DuplicateTabTitle",
code: "MO903",
title: "Duplicate tab title",
default_severity: "Warning",
fix_suggestion: "Use unique titles for each tab in the same tab group.",
description: "Multiple tabs in a group share the same normalized title.",
tags: ["marco", "tabs"],
examples: ["@tab Overview", "@tab overview"],
),
(
key: "EmptyTabPanel",
code: "MO904",
title: "Empty tab panel",
default_severity: "Warning",
fix_suggestion: "Add panel content below the tab header.",
description: "A tab item exists but its panel body is empty.",
tags: ["marco", "tabs"],
examples: ["@tab Intro\n"],
),
(
key: "EmptySliderDeck",
code: "MO905",
title: "Empty slider deck",
default_severity: "Warning",
fix_suggestion: "Add at least one slide between `@slidestart` and `@slideend`.",
description: "A Marco slider deck is declared without slide content.",
tags: ["marco", "sliders"],
examples: ["@slidestart\n@slideend"],
),
(
key: "EmptySlide",
code: "MO906",
title: "Empty slide",
default_severity: "Warning",
fix_suggestion: "Add content to the slide body.",
description: "A slide node exists but contains no meaningful content.",
tags: ["marco", "sliders"],
examples: ["---\n\n---"],
),
(
key: "EmptyAdmonitionBody",
code: "MG901",
title: "Empty admonition body",
default_severity: "Warning",
fix_suggestion: "Add body content under the admonition marker.",
description: "An admonition block exists without body content.",
tags: ["github", "admonitions"],
examples: ["> [!NOTE]\n>"],
),
(
key: "EmptyMathExpression",
code: "MG902",
title: "Empty math expression",
default_severity: "Warning",
fix_suggestion: "Insert a valid KaTeX expression inside the math delimiters.",
description: "Math delimiters are present but the expression is empty.",
tags: ["github", "math", "katex"],
examples: ["$ $", "$$\n\t\n$$"],
),
(
key: "EmptyMermaidDiagram",
code: "MG903",
title: "Empty mermaid diagram",
default_severity: "Warning",
fix_suggestion: "Add Mermaid syntax content inside the diagram block.",
description: "A Mermaid diagram block is present but has no diagram body.",
tags: ["github", "mermaid"],
examples: ["```mermaid\n```"],
),
(
key: "EmptyAdmonitionTitle",
code: "MG904",
title: "Empty admonition title",
default_severity: "Warning",
fix_suggestion: "Provide a non-empty custom admonition title.",
description: "A custom admonition title is provided but empty after trimming.",
tags: ["github", "admonitions"],
examples: ["> [!TIP] "],
),
(
key: "UnknownAdmonitionKind",
code: "MG905",
title: "Unknown admonition kind",
default_severity: "Warning",
fix_suggestion: "Use one of: NOTE, TIP, IMPORTANT, WARNING, CAUTION.",
description: "The admonition marker kind is not in the supported GitHub set.",
tags: ["github", "admonitions"],
examples: ["> [!CUSTOM]"],
),
(
key: "InvalidSliderTimer",
code: "MO907",
title: "Invalid slider timer",
default_severity: "Warning",
fix_suggestion: "Use a timer value greater than 0 seconds.",
description: "A slider deck timer is configured with an invalid zero value.",
tags: ["marco", "sliders"],
examples: ["@slidestart:0"],
),
(
key: "EmptyPlatformMentionUsername",
code: "MO908",
title: "Empty platform mention username",
default_severity: "Warning",
fix_suggestion: "Provide a non-empty username in the platform mention.",
description: "A Marco platform mention is missing its username.",
tags: ["marco", "mentions"],
examples: ["@github/"],
),
(
key: "UnknownPlatformMentionPlatform",
code: "MO909",
title: "Unknown platform mention platform",
default_severity: "Warning",
fix_suggestion: "Use a supported platform identifier (e.g., github, gitlab, codeberg).",
description: "A Marco platform mention references an unsupported platform.",
tags: ["marco", "mentions"],
examples: ["@unknown/user"],
),
(
key: "UnknownEmojiShortcode",
code: "MG906",
title: "Unknown emoji shortcode",
default_severity: "Hint",
fix_suggestion: "Use a known emoji shortcode or replace with a literal emoji.",
description: "A GitHub-style emoji shortcode token is not recognized.",
tags: ["github", "emoji"],
examples: [":not_an_emoji:"],
),
(
key: "EmptyPlatformMentionDisplayName",
code: "MO910",
title: "Empty platform mention display name",
default_severity: "Hint",
fix_suggestion: "Provide display text or remove the empty display-name wrapper.",
description: "A platform mention display name is present but empty after trimming.",
tags: ["marco", "mentions"],
examples: ["[@github/user]( )"],
),
],
)