or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdindex.mdlanguages.mdprocessor.mdrules.md
tile.json

rules.mddocs/

Rules

19 specialized ESLint rules for common Markdown issues including heading structure, link validation, content requirements, and GitHub Flavored Markdown table validation.

Capabilities

Rule Categories

The rules are organized into several categories based on their functionality:

  • Content Structure: Heading hierarchy and document organization
  • Link Validation: Link and reference integrity
  • Media Requirements: Image and media accessibility
  • Syntax Correctness: Markdown syntax validation
  • GitHub Flavored Markdown: Table formatting and GFM-specific features

Recommended Rules (16 rules)

Rules that are enabled by default in the recommended configuration:

interface RecommendedRules {
  "markdown/fenced-code-language": "error";
  "markdown/heading-increment": "error"; 
  "markdown/no-duplicate-definitions": "error";
  "markdown/no-empty-definitions": "error";
  "markdown/no-empty-images": "error";
  "markdown/no-empty-links": "error";
  "markdown/no-invalid-label-refs": "error";
  "markdown/no-missing-atx-heading-space": "error";
  "markdown/no-missing-label-refs": "error";
  "markdown/no-missing-link-fragments": "error";
  "markdown/no-multiple-h1": "error";
  "markdown/no-reversed-media-syntax": "error";
  "markdown/no-space-in-emphasis": "error";
  "markdown/no-unused-definitions": "error";
  "markdown/require-alt-text": "error";
  "markdown/table-column-count": "error";
}

Content Structure Rules

fenced-code-language

Requires language specification for fenced code blocks to ensure proper syntax highlighting.

/**
 * Require languages for fenced code blocks
 * Recommended: Yes
 */
"markdown/fenced-code-language": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
```javascript
console.log("Hello");
<!-- ✗ Bad -->
console.log("Hello");
#### heading-increment

Enforces heading levels increment by one (no skipping levels like H1 → H3).

```javascript { .api }
/**
 * Enforce heading levels increment by one
 * Recommended: Yes
 */
"markdown/heading-increment": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
# Main Title (H1)
## Section (H2)
### Subsection (H3)

<!-- ✗ Bad -->
# Main Title (H1)
### Subsection (H3) - skipped H2

no-multiple-h1

Disallows multiple H1 headings in the same document.

/**
 * Disallow multiple H1 headings in the same document
 * Recommended: Yes
 */
"markdown/no-multiple-h1": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
# Main Title
## Section 1
## Section 2

<!-- ✗ Bad -->
# Main Title
# Another Main Title

Link Validation Rules

no-duplicate-definitions

Disallows duplicate link/image reference definitions.

/**
 * Disallow duplicate definitions
 * Recommended: Yes
 */
"markdown/no-duplicate-definitions": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
[link]: https://example.com
[another]: https://other.com

<!-- ✗ Bad -->
[link]: https://example.com
[link]: https://duplicate.com

no-empty-definitions

Disallows empty link/image reference definitions.

/**
 * Disallow empty definitions
 * Recommended: Yes
 */
"markdown/no-empty-definitions": "error" | "warn" | "off"

no-invalid-label-refs

Disallows invalid label references that don't match defined labels.

/**
 * Disallow invalid label references
 * Recommended: Yes
 */
"markdown/no-invalid-label-refs": "error" | "warn" | "off"

no-missing-label-refs

Disallows missing label references (references without definitions).

/**
 * Disallow missing label references
 * Recommended: Yes
 */
"markdown/no-missing-label-refs": "error" | "warn" | "off"

no-missing-link-fragments

Disallows link fragments that don't reference valid headings in the document.

/**
 * Disallow link fragments that do not reference valid headings
 * Recommended: Yes
 */
"markdown/no-missing-link-fragments": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
# Section One
[Link to section](#section-one)

<!-- ✗ Bad -->
# Section One
[Link to non-existent](#section-two)

no-unused-definitions

Disallows unused link/image reference definitions.

/**
 * Disallow unused definitions
 * Recommended: Yes
 */
"markdown/no-unused-definitions": "error" | "warn" | "off"

Media Requirements Rules

no-empty-images

Disallows empty images (images without src/url).

/**
 * Disallow empty images
 * Recommended: Yes
 */
"markdown/no-empty-images": "error" | "warn" | "off"

no-empty-links

Disallows empty links (links without href/url).

/**
 * Disallow empty links
 * Recommended: Yes
 */
"markdown/no-empty-links": "error" | "warn" | "off"

require-alt-text

Requires alternative text for images for accessibility.

/**
 * Require alternative text for images
 * Recommended: Yes
 */  
"markdown/require-alt-text": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
![Description of image](image.png)

<!-- ✗ Bad -->
![](image.png)

Syntax Correctness Rules

no-missing-atx-heading-space

Disallows ATX headings without space after hash characters.

/**
 * Disallow headings without a space after the hash characters
 * Recommended: Yes
 */
"markdown/no-missing-atx-heading-space": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
# Heading with space

<!-- ✗ Bad -->
#Heading without space

no-reversed-media-syntax

Disallows reversed link and image syntax (common mistake).

/**
 * Disallow reversed link and image syntax
 * Recommended: Yes
 */
"markdown/no-reversed-media-syntax": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
![alt text](image.png)
[link text](url)

<!-- ✗ Bad -->
(image.png)[alt text]
(url)[link text]

no-space-in-emphasis

Disallows spaces around emphasis markers (italics and bold).

/**
 * Disallow spaces around emphasis markers
 * Recommended: Yes
 */
"markdown/no-space-in-emphasis": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
*italic text*
**bold text**

<!-- ✗ Bad -->
* italic text *
** bold text **

GitHub Flavored Markdown Rules

table-column-count

Disallows data rows in GFM tables from having more cells than the header row.

/**
 * Disallow data rows in a GitHub Flavored Markdown table from having more cells than the header row
 * Recommended: Yes
 */
"markdown/table-column-count": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
| Name | Age |
|------|-----|
| John | 25  |

<!-- ✗ Bad -->
| Name | Age |
|------|-----|
| John | 25  | Extra |

Optional Rules (3 rules)

Rules that are not enabled by default but can be configured manually:

no-bare-urls

Disallows bare URLs (URLs without link syntax).

/**
 * Disallow bare URLs
 * Recommended: No
 */
"markdown/no-bare-urls": "error" | "warn" | "off"

Examples:

<!-- ✓ Good -->
[Example](https://example.com)

<!-- ✗ Bad (when rule is enabled) -->
https://example.com

no-duplicate-headings

Disallows duplicate headings in the same document.

/**
 * Disallow duplicate headings in the same document
 * Recommended: No
 */
"markdown/no-duplicate-headings": "error" | "warn" | "off"

no-html

Disallows HTML tags in Markdown content.

/**
 * Disallow HTML tags
 * Recommended: No
 * Options: { allowed?: string[], allowedIgnoreCase?: boolean }
 */
"markdown/no-html": "error" | "warn" | "off" | ["error", {
  allowed?: string[];
  allowedIgnoreCase?: boolean;
}]

Configuration Examples:

// Disallow all HTML
"markdown/no-html": "error"

// Allow specific HTML tags
"markdown/no-html": ["error", {
  allowed: ["br", "strong", "em"]
}]

// Allow specific tags (case insensitive)
"markdown/no-html": ["error", {
  allowed: ["BR", "STRONG"],
  allowedIgnoreCase: true
}]

Types

Rule Definition Types

/**
 * Base rule definition for Markdown rules
 */
interface MarkdownRuleDefinition<Options = {}> {
  meta: {
    type: "problem" | "suggestion" | "layout";
    docs: {
      description: string;
      recommended: boolean;
      url?: string;
    };
    fixable?: "code" | "whitespace";
    schema?: JSONSchema7 | JSONSchema7[];
    messages: { [messageId: string]: string };
  };
  create(context: RuleContext): MarkdownRuleVisitor;
}

/**
 * Rule context with Markdown-specific methods
 */
interface RuleContext {
  report(descriptor: ReportDescriptor): void;
  getSourceCode(): MarkdownSourceCode;
  // ... other ESLint context methods
}

/**
 * Rule visitor for Markdown AST nodes
 */
interface MarkdownRuleVisitor {
  root?(node: Root): void;
  heading?(node: Heading): void;
  paragraph?(node: Paragraph): void;
  link?(node: Link): void;
  image?(node: Image): void;
  code?(node: Code): void;
  html?(node: Html): void;
  table?(node: Table): void;
  // ... exit handlers with :exit suffix
}

Rule Options

/**
 * Options for no-html rule
 */
interface NoHtmlOptions {
  allowed?: string[];
  allowedIgnoreCase?: boolean;
}

/**
 * Generic rule configuration
 */
type RuleConfig<T = any> = 
  | "off" 
  | "warn" 
  | "error" 
  | ["off"] 
  | ["warn"] 
  | ["error"] 
  | ["warn", T] 
  | ["error", T];

Usage Examples

Individual Rule Configuration

import markdown from "@eslint/markdown";

export default [
    {
        files: ["**/*.md"],
        plugins: { markdown },
        language: "markdown/gfm",
        rules: {
            // Enable specific rules
            "markdown/no-html": "error",
            "markdown/no-bare-urls": "warn",
            
            // Configure rule with options
            "markdown/no-html": ["error", {
                allowed: ["br", "strong", "em"],
                allowedIgnoreCase: true
            }],
            
            // Disable specific rules
            "markdown/no-duplicate-headings": "off"
        }
    }
];

Rule Overrides for Specific Files

export default [
    // Default rules for all Markdown files
    {
        files: ["**/*.md"],
        plugins: { markdown },
        language: "markdown/commonmark",
        rules: {
            "markdown/no-html": "error"
        }
    },
    // Allow HTML in README files
    {
        files: ["README.md", "**/README.md"],
        rules: {
            "markdown/no-html": "off"
        }
    }
];