@dougis/markdown-lint-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/CONTRIBUTING.md +474 -0
- package/LICENSE +21 -0
- package/README.md +240 -0
- package/USAGE.md +40 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/rules/index.d.ts +22 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +144 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/md001.d.ts +25 -0
- package/dist/rules/md001.d.ts.map +1 -0
- package/dist/rules/md001.js +79 -0
- package/dist/rules/md001.js.map +1 -0
- package/dist/rules/md003.d.ts +41 -0
- package/dist/rules/md003.d.ts.map +1 -0
- package/dist/rules/md003.js +130 -0
- package/dist/rules/md003.js.map +1 -0
- package/dist/rules/md004.d.ts +28 -0
- package/dist/rules/md004.d.ts.map +1 -0
- package/dist/rules/md004.js +79 -0
- package/dist/rules/md004.js.map +1 -0
- package/dist/rules/md005.d.ts +21 -0
- package/dist/rules/md005.d.ts.map +1 -0
- package/dist/rules/md005.js +88 -0
- package/dist/rules/md005.js.map +1 -0
- package/dist/rules/md007.d.ts +21 -0
- package/dist/rules/md007.d.ts.map +1 -0
- package/dist/rules/md007.js +66 -0
- package/dist/rules/md007.js.map +1 -0
- package/dist/rules/md009.d.ts +35 -0
- package/dist/rules/md009.d.ts.map +1 -0
- package/dist/rules/md009.js +122 -0
- package/dist/rules/md009.js.map +1 -0
- package/dist/rules/md010.d.ts +34 -0
- package/dist/rules/md010.d.ts.map +1 -0
- package/dist/rules/md010.js +75 -0
- package/dist/rules/md010.js.map +1 -0
- package/dist/rules/md011.d.ts +30 -0
- package/dist/rules/md011.d.ts.map +1 -0
- package/dist/rules/md011.js +123 -0
- package/dist/rules/md011.js.map +1 -0
- package/dist/rules/md012.d.ts +33 -0
- package/dist/rules/md012.d.ts.map +1 -0
- package/dist/rules/md012.js +125 -0
- package/dist/rules/md012.js.map +1 -0
- package/dist/rules/md013.d.ts +26 -0
- package/dist/rules/md013.d.ts.map +1 -0
- package/dist/rules/md013.js +32 -0
- package/dist/rules/md013.js.map +1 -0
- package/dist/rules/md014.d.ts +29 -0
- package/dist/rules/md014.d.ts.map +1 -0
- package/dist/rules/md014.js +176 -0
- package/dist/rules/md014.js.map +1 -0
- package/dist/rules/md018.d.ts +22 -0
- package/dist/rules/md018.d.ts.map +1 -0
- package/dist/rules/md018.js +27 -0
- package/dist/rules/md018.js.map +1 -0
- package/dist/rules/md019.d.ts +22 -0
- package/dist/rules/md019.d.ts.map +1 -0
- package/dist/rules/md019.js +27 -0
- package/dist/rules/md019.js.map +1 -0
- package/dist/rules/md020.d.ts +22 -0
- package/dist/rules/md020.d.ts.map +1 -0
- package/dist/rules/md020.js +27 -0
- package/dist/rules/md020.js.map +1 -0
- package/dist/rules/md021.d.ts +22 -0
- package/dist/rules/md021.d.ts.map +1 -0
- package/dist/rules/md021.js +27 -0
- package/dist/rules/md021.js.map +1 -0
- package/dist/rules/md022.d.ts +21 -0
- package/dist/rules/md022.d.ts.map +1 -0
- package/dist/rules/md022.js +43 -0
- package/dist/rules/md022.js.map +1 -0
- package/dist/rules/md023.d.ts +21 -0
- package/dist/rules/md023.d.ts.map +1 -0
- package/dist/rules/md023.js +34 -0
- package/dist/rules/md023.js.map +1 -0
- package/dist/rules/md024.d.ts +30 -0
- package/dist/rules/md024.d.ts.map +1 -0
- package/dist/rules/md024.js +123 -0
- package/dist/rules/md024.js.map +1 -0
- package/dist/rules/md025.d.ts +34 -0
- package/dist/rules/md025.d.ts.map +1 -0
- package/dist/rules/md025.js +134 -0
- package/dist/rules/md025.js.map +1 -0
- package/dist/rules/md026.d.ts +21 -0
- package/dist/rules/md026.d.ts.map +1 -0
- package/dist/rules/md026.js +31 -0
- package/dist/rules/md026.js.map +1 -0
- package/dist/rules/md027.d.ts +22 -0
- package/dist/rules/md027.d.ts.map +1 -0
- package/dist/rules/md027.js +27 -0
- package/dist/rules/md027.js.map +1 -0
- package/dist/rules/md028.d.ts +37 -0
- package/dist/rules/md028.d.ts.map +1 -0
- package/dist/rules/md028.js +84 -0
- package/dist/rules/md028.js.map +1 -0
- package/dist/rules/md029.d.ts +30 -0
- package/dist/rules/md029.d.ts.map +1 -0
- package/dist/rules/md029.js +36 -0
- package/dist/rules/md029.js.map +1 -0
- package/dist/rules/md030.d.ts +28 -0
- package/dist/rules/md030.d.ts.map +1 -0
- package/dist/rules/md030.js +76 -0
- package/dist/rules/md030.js.map +1 -0
- package/dist/rules/md031.d.ts +22 -0
- package/dist/rules/md031.d.ts.map +1 -0
- package/dist/rules/md031.js +55 -0
- package/dist/rules/md031.js.map +1 -0
- package/dist/rules/md032.d.ts +21 -0
- package/dist/rules/md032.d.ts.map +1 -0
- package/dist/rules/md032.js +69 -0
- package/dist/rules/md032.js.map +1 -0
- package/dist/rules/md033.d.ts +28 -0
- package/dist/rules/md033.d.ts.map +1 -0
- package/dist/rules/md033.js +34 -0
- package/dist/rules/md033.js.map +1 -0
- package/dist/rules/md034.d.ts +28 -0
- package/dist/rules/md034.d.ts.map +1 -0
- package/dist/rules/md034.js +100 -0
- package/dist/rules/md034.js.map +1 -0
- package/dist/rules/md035.d.ts +23 -0
- package/dist/rules/md035.d.ts.map +1 -0
- package/dist/rules/md035.js +52 -0
- package/dist/rules/md035.js.map +1 -0
- package/dist/rules/md036.d.ts +34 -0
- package/dist/rules/md036.d.ts.map +1 -0
- package/dist/rules/md036.js +112 -0
- package/dist/rules/md036.js.map +1 -0
- package/dist/rules/md037.d.ts +28 -0
- package/dist/rules/md037.d.ts.map +1 -0
- package/dist/rules/md037.js +122 -0
- package/dist/rules/md037.js.map +1 -0
- package/dist/rules/md038.d.ts +28 -0
- package/dist/rules/md038.d.ts.map +1 -0
- package/dist/rules/md038.js +62 -0
- package/dist/rules/md038.js.map +1 -0
- package/dist/rules/md039.d.ts +21 -0
- package/dist/rules/md039.d.ts.map +1 -0
- package/dist/rules/md039.js +34 -0
- package/dist/rules/md039.js.map +1 -0
- package/dist/rules/md040.d.ts +21 -0
- package/dist/rules/md040.d.ts.map +1 -0
- package/dist/rules/md040.js +46 -0
- package/dist/rules/md040.js.map +1 -0
- package/dist/rules/md041.d.ts +33 -0
- package/dist/rules/md041.d.ts.map +1 -0
- package/dist/rules/md041.js +92 -0
- package/dist/rules/md041.js.map +1 -0
- package/dist/rules/md042.d.ts +22 -0
- package/dist/rules/md042.d.ts.map +1 -0
- package/dist/rules/md042.js +50 -0
- package/dist/rules/md042.js.map +1 -0
- package/dist/rules/md043.d.ts +39 -0
- package/dist/rules/md043.d.ts.map +1 -0
- package/dist/rules/md043.js +116 -0
- package/dist/rules/md043.js.map +1 -0
- package/dist/rules/md044.d.ts +40 -0
- package/dist/rules/md044.d.ts.map +1 -0
- package/dist/rules/md044.js +167 -0
- package/dist/rules/md044.js.map +1 -0
- package/dist/rules/md045.d.ts +22 -0
- package/dist/rules/md045.d.ts.map +1 -0
- package/dist/rules/md045.js +57 -0
- package/dist/rules/md045.js.map +1 -0
- package/dist/rules/md046.d.ts +23 -0
- package/dist/rules/md046.d.ts.map +1 -0
- package/dist/rules/md046.js +174 -0
- package/dist/rules/md046.js.map +1 -0
- package/dist/rules/md047.d.ts +22 -0
- package/dist/rules/md047.d.ts.map +1 -0
- package/dist/rules/md047.js +35 -0
- package/dist/rules/md047.js.map +1 -0
- package/dist/rules/md048.d.ts +22 -0
- package/dist/rules/md048.d.ts.map +1 -0
- package/dist/rules/md048.js +80 -0
- package/dist/rules/md048.js.map +1 -0
- package/dist/rules/md049.d.ts +33 -0
- package/dist/rules/md049.d.ts.map +1 -0
- package/dist/rules/md049.js +189 -0
- package/dist/rules/md049.js.map +1 -0
- package/dist/rules/md050.d.ts +22 -0
- package/dist/rules/md050.d.ts.map +1 -0
- package/dist/rules/md050.js +32 -0
- package/dist/rules/md050.js.map +1 -0
- package/dist/rules/md051.d.ts +23 -0
- package/dist/rules/md051.d.ts.map +1 -0
- package/dist/rules/md051.js +63 -0
- package/dist/rules/md051.js.map +1 -0
- package/dist/rules/md052.d.ts +21 -0
- package/dist/rules/md052.d.ts.map +1 -0
- package/dist/rules/md052.js +71 -0
- package/dist/rules/md052.js.map +1 -0
- package/dist/rules/md053.d.ts +21 -0
- package/dist/rules/md053.d.ts.map +1 -0
- package/dist/rules/md053.js +95 -0
- package/dist/rules/md053.js.map +1 -0
- package/dist/rules/md054.d.ts +21 -0
- package/dist/rules/md054.d.ts.map +1 -0
- package/dist/rules/md054.js +87 -0
- package/dist/rules/md054.js.map +1 -0
- package/dist/rules/md055.d.ts +22 -0
- package/dist/rules/md055.d.ts.map +1 -0
- package/dist/rules/md055.js +157 -0
- package/dist/rules/md055.js.map +1 -0
- package/dist/rules/md056.d.ts +21 -0
- package/dist/rules/md056.d.ts.map +1 -0
- package/dist/rules/md056.js +154 -0
- package/dist/rules/md056.js.map +1 -0
- package/dist/rules/md058.d.ts +27 -0
- package/dist/rules/md058.d.ts.map +1 -0
- package/dist/rules/md058.js +71 -0
- package/dist/rules/md058.js.map +1 -0
- package/dist/rules/md059.d.ts +22 -0
- package/dist/rules/md059.d.ts.map +1 -0
- package/dist/rules/md059.js +161 -0
- package/dist/rules/md059.js.map +1 -0
- package/dist/rules/rule-interface.d.ts +51 -0
- package/dist/rules/rule-interface.d.ts.map +1 -0
- package/dist/rules/rule-interface.js +2 -0
- package/dist/rules/rule-interface.js.map +1 -0
- package/dist/server.d.ts +59 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +419 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file.d.ts +39 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +124 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/logger.d.ts +61 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +85 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/safe-match.d.ts +4 -0
- package/dist/utils/safe-match.d.ts.map +1 -0
- package/dist/utils/safe-match.js +51 -0
- package/dist/utils/safe-match.js.map +1 -0
- package/package.json +85 -0
package/README.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# markdownlint-mcp
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server for markdown linting, formatting, and compliance checking.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This MCP server provides AI assistants with the ability to lint, validate, and auto-fix Markdown files to ensure compliance with established Markdown standards and best practices.
|
|
8
|
+
|
|
9
|
+
## The Problem
|
|
10
|
+
|
|
11
|
+
While many MCP servers exist for converting various file formats **to** Markdown, there was no MCP server specifically designed for **linting and ensuring compliance** of existing Markdown files. This creates a gap in the workflow where Markdown content may be created or converted but not validated for quality and consistency.
|
|
12
|
+
|
|
13
|
+
## Solution
|
|
14
|
+
|
|
15
|
+
`markdownlint-mcp` bridges this gap by providing:
|
|
16
|
+
|
|
17
|
+
- **Markdown linting** using industry-standard rules
|
|
18
|
+
- **Automatic fixing** of common Markdown issues
|
|
19
|
+
- **Compliance validation** against established standards
|
|
20
|
+
- **Seamless integration** with MCP-compatible AI assistants
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
### MCP Tools Provided
|
|
26
|
+
|
|
27
|
+
1. **`lint_markdown`** - Analyze a Markdown file and return detailed issues
|
|
28
|
+
2. **`fix_markdown`** - Automatically fix Markdown issues and return corrected content
|
|
29
|
+
3. **`get_configuration`** - Display current linting rules and configuration
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Standards-Based Approach
|
|
33
|
+
|
|
34
|
+
- Uses **markdownlint** default ruleset (community standard)
|
|
35
|
+
- Based on **CommonMark specification**
|
|
36
|
+
- Follows **GitHub Flavored Markdown** conventions
|
|
37
|
+
- Supports **all 52 official markdownlint rules**
|
|
38
|
+
|
|
39
|
+
## Auto-Fixable Rules
|
|
40
|
+
|
|
41
|
+
Our MCP server can automatically fix 30 out of 52 official markdownlint rules (58%). These rules are deterministic and can be fixed without human judgment:
|
|
42
|
+
|
|
43
|
+
### Whitespace & Formatting (9 rules)
|
|
44
|
+
- **MD009** - Trailing spaces
|
|
45
|
+
- **MD010** - Hard tabs
|
|
46
|
+
- **MD012** - Multiple consecutive blank lines
|
|
47
|
+
- **MD022** - Headings surrounded by blank lines
|
|
48
|
+
- **MD031** - Fenced code blocks surrounded by blank lines
|
|
49
|
+
- **MD032** - Lists surrounded by blank lines
|
|
50
|
+
- **MD047** - Files should end with single newline
|
|
51
|
+
- **MD058** - Tables surrounded by blank lines
|
|
52
|
+
- **MD027** - Multiple spaces after blockquote symbol
|
|
53
|
+
|
|
54
|
+
### Heading Formatting (6 rules)
|
|
55
|
+
- **MD018** - No space after hash
|
|
56
|
+
- **MD019** - Multiple spaces after hash
|
|
57
|
+
- **MD020** - No space inside closed ATX
|
|
58
|
+
- **MD021** - Multiple spaces inside closed ATX
|
|
59
|
+
- **MD023** - Headings start at line beginning
|
|
60
|
+
- **MD026** - Trailing punctuation in heading
|
|
61
|
+
|
|
62
|
+
### List Formatting (4 rules)
|
|
63
|
+
- **MD004** - Unordered list style
|
|
64
|
+
- **MD005** - List item indentation consistency
|
|
65
|
+
- **MD007** - Unordered list indentation
|
|
66
|
+
- **MD030** - Spaces after list markers
|
|
67
|
+
|
|
68
|
+
### Link & Text Formatting (7 rules)
|
|
69
|
+
- **MD011** - Reversed link syntax
|
|
70
|
+
- **MD034** - Bare URL used
|
|
71
|
+
- **MD037** - Spaces inside emphasis
|
|
72
|
+
- **MD038** - Spaces inside code spans
|
|
73
|
+
- **MD039** - Spaces inside link text
|
|
74
|
+
- **MD049** - Emphasis style
|
|
75
|
+
- **MD050** - Strong style
|
|
76
|
+
|
|
77
|
+
### Advanced Fixable (4 rules)
|
|
78
|
+
- **MD014** - Dollar signs before commands
|
|
79
|
+
- **MD044** - Proper names capitalization
|
|
80
|
+
- **MD051** - Link fragments validation
|
|
81
|
+
- **MD053** - Unused reference definitions
|
|
82
|
+
|
|
83
|
+
## Detection-Only Rules
|
|
84
|
+
|
|
85
|
+
The following 22 rules (42%) cannot be automatically fixed because they require human judgment, content understanding, or style decisions:
|
|
86
|
+
|
|
87
|
+
### Structural/Content Rules (12 rules)
|
|
88
|
+
- **MD001** - Heading increment (requires understanding document structure)
|
|
89
|
+
- **MD003** - Heading style consistency (needs style preference decision)
|
|
90
|
+
- **MD013** - Line length (requires content-aware line breaking)
|
|
91
|
+
- **MD024** - Duplicate headings (could break document structure/navigation)
|
|
92
|
+
- **MD025** - Multiple H1s (requires understanding document hierarchy)
|
|
93
|
+
- **MD028** - Blank line in blockquote (ambiguous semantic intent)
|
|
94
|
+
- **MD029** - Ordered list numbering (style preference)
|
|
95
|
+
- **MD035** - Horizontal rule style (style preference)
|
|
96
|
+
- **MD036** - Emphasis as heading (requires semantic understanding)
|
|
97
|
+
- **MD041** - First line H1 (may break existing document structure)
|
|
98
|
+
- **MD043** - Required heading structure (document-specific requirements)
|
|
99
|
+
- **MD046** - Code block style (style preference)
|
|
100
|
+
|
|
101
|
+
### Content/Language Rules (5 rules)
|
|
102
|
+
- **MD033** - Inline HTML (may be intentional/necessary)
|
|
103
|
+
- **MD040** - Code language specification (requires code language knowledge)
|
|
104
|
+
- **MD045** - Alt text for images (requires understanding image content)
|
|
105
|
+
- **MD059** - Descriptive link text (requires understanding context/purpose)
|
|
106
|
+
- **MD042** - Empty links (may be placeholders or templates)
|
|
107
|
+
|
|
108
|
+
### Reference/Link Rules (3 rules)
|
|
109
|
+
- **MD052** - Reference links defined (may be external or conditional)
|
|
110
|
+
- **MD054** - Link/image style (style preference)
|
|
111
|
+
- **MD056** - Table column count (may be intentional formatting)
|
|
112
|
+
|
|
113
|
+
### Table Rules (2 rules)
|
|
114
|
+
- **MD055** - Table pipe style (style preference)
|
|
115
|
+
- **MD048** - Code fence style (style preference)
|
|
116
|
+
|
|
117
|
+
## Installation
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npm install markdownlint-mcp
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Usage
|
|
124
|
+
|
|
125
|
+
### With Claude Desktop
|
|
126
|
+
|
|
127
|
+
Add to your Claude Desktop MCP configuration:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"mcpServers": {
|
|
132
|
+
"markdownlint": {
|
|
133
|
+
"command": "npx",
|
|
134
|
+
"args": ["markdownlint-mcp"]
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### With Other MCP Clients
|
|
141
|
+
|
|
142
|
+
This server works with any MCP-compatible client including:
|
|
143
|
+
|
|
144
|
+
- Claude Desktop
|
|
145
|
+
- Cursor
|
|
146
|
+
- Cline
|
|
147
|
+
- VS Code with MCP support
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
## Example Workflows
|
|
151
|
+
|
|
152
|
+
### Lint a Markdown File
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
User: "Please lint my README.md file and tell me what issues exist"
|
|
156
|
+
AI: Uses lint_markdown tool to analyze and report issues
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Fix Markdown Issues
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
User: "Fix all the markdown issues in my documentation files"
|
|
163
|
+
AI: Uses fix_markdown tool to automatically correct problems
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Validate Compliance
|
|
167
|
+
|
|
168
|
+
```text
|
|
169
|
+
User: "Is my markdown compliant with standard formatting rules?"
|
|
170
|
+
AI: Uses lint_markdown to validate and provide compliance status
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Technical Approach
|
|
174
|
+
|
|
175
|
+
- **Direct library integration** with `markdownlint` npm package
|
|
176
|
+
- **No external CLI dependencies** required
|
|
177
|
+
- **Cross-platform** support (Windows, macOS, Linux)
|
|
178
|
+
- **Single installation** - no additional tools needed
|
|
179
|
+
- **Efficient processing** via direct API calls
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
## Development Status
|
|
183
|
+
|
|
184
|
+
🚀 **Production Ready** - This project has reached a high level of maturity with:
|
|
185
|
+
|
|
186
|
+
1. ✅ **Complete MCP server implementation** with all 52 markdownlint rules
|
|
187
|
+
2. ✅ **Comprehensive testing suite** - 82% coverage (42/51 rules with full tests)
|
|
188
|
+
3. ✅ **522 passing tests** with 100% success rate
|
|
189
|
+
4. ✅ **All Priority 1 rules fully tested** (11/11 critical rules)
|
|
190
|
+
5. 🔄 **Final testing phase** for remaining specialized rules
|
|
191
|
+
6. 📋 **Ready for community testing** and feedback
|
|
192
|
+
|
|
193
|
+
### Testing Coverage Status
|
|
194
|
+
|
|
195
|
+
Our test suite demonstrates production quality with extensive validation:
|
|
196
|
+
|
|
197
|
+
- **✅ 19 test suites** all passing
|
|
198
|
+
- **✅ 522 total tests** with 0 failures
|
|
199
|
+
- **✅ 82% rule coverage** (42 out of 51 rules fully tested)
|
|
200
|
+
- **✅ 100% Priority 1 rules tested** (all critical functionality)
|
|
201
|
+
- **✅ Detection and fix validation** for all tested rules
|
|
202
|
+
- **✅ Edge case and configuration testing** implemented
|
|
203
|
+
|
|
204
|
+
### Remaining Work (8% of rules)
|
|
205
|
+
|
|
206
|
+
Only 9 specialized rules remain to be tested:
|
|
207
|
+
- MD039, MD050, MD051, MD052, MD053, MD054 - Link and styling rules
|
|
208
|
+
- Integration testing for rule combinations
|
|
209
|
+
- Performance testing with large files
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
## Contributing
|
|
213
|
+
|
|
214
|
+
We welcome contributions! This project follows MCP best practices and maintains high code quality standards.
|
|
215
|
+
|
|
216
|
+
### Roadmap
|
|
217
|
+
|
|
218
|
+
- [x] ✅ Core MCP server implementation
|
|
219
|
+
- [x] ✅ Comprehensive testing suite (82% complete)
|
|
220
|
+
- [x] ✅ Production-quality code with 522 passing tests
|
|
221
|
+
- [ ] 🔄 Complete remaining 9 rules testing
|
|
222
|
+
- [ ] 📚 Enhanced documentation and examples
|
|
223
|
+
- [ ] 🤝 Community feedback integration
|
|
224
|
+
- [ ] 📦 Submission to official MCP collection
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
MIT License - see LICENSE file for details
|
|
230
|
+
|
|
231
|
+
## Related Projects
|
|
232
|
+
|
|
233
|
+
- [markdownlint](https://github.com/DavidAnson/markdownlint) - The underlying linting engine
|
|
234
|
+
- [Model Context Protocol](https://modelcontextprotocol.io/) - The protocol this server implements
|
|
235
|
+
- [MCP Servers Collection](https://github.com/modelcontextprotocol/servers) - Official MCP servers
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
## Support
|
|
239
|
+
|
|
240
|
+
For issues, questions, or contributions, please use the GitHub issues page.
|
package/USAGE.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Usage Instructions
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install -g markdownlint-mcp
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Configuration with Claude Desktop
|
|
10
|
+
|
|
11
|
+
Add this to your Claude Desktop MCP configuration file:
|
|
12
|
+
|
|
13
|
+
### Location of config file:
|
|
14
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
15
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
16
|
+
|
|
17
|
+
### Configuration:
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"mcpServers": {
|
|
21
|
+
"markdownlint": {
|
|
22
|
+
"command": "markdownlint-mcp"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Available Tools
|
|
29
|
+
|
|
30
|
+
Once configured, you can ask Claude to:
|
|
31
|
+
|
|
32
|
+
1. **Lint markdown files**: "Please lint my README.md file"
|
|
33
|
+
2. **Fix markdown issues**: "Fix all markdown issues in my documentation"
|
|
34
|
+
3. **Check configuration**: "Show me the current markdownlint configuration"
|
|
35
|
+
|
|
36
|
+
## Examples
|
|
37
|
+
|
|
38
|
+
- "Analyze the markdown issues in my project's README.md"
|
|
39
|
+
- "Fix the formatting in docs/guide.md and save the changes"
|
|
40
|
+
- "What markdown linting rules are currently active?"
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createServer } from './server';
|
|
3
|
+
import logger, { LogLevel } from './utils/logger';
|
|
4
|
+
/**
|
|
5
|
+
* Main entry point for the markdownlint-mcp server
|
|
6
|
+
*/
|
|
7
|
+
function main() {
|
|
8
|
+
// Set logging level based on environment variable or default to INFO
|
|
9
|
+
const logLevel = process.env.LOG_LEVEL || 'INFO';
|
|
10
|
+
switch (logLevel.toUpperCase()) {
|
|
11
|
+
case 'DEBUG':
|
|
12
|
+
logger.setLogLevel(LogLevel.DEBUG);
|
|
13
|
+
break;
|
|
14
|
+
case 'INFO':
|
|
15
|
+
logger.setLogLevel(LogLevel.INFO);
|
|
16
|
+
break;
|
|
17
|
+
case 'WARN':
|
|
18
|
+
logger.setLogLevel(LogLevel.WARN);
|
|
19
|
+
break;
|
|
20
|
+
case 'ERROR':
|
|
21
|
+
logger.setLogLevel(LogLevel.ERROR);
|
|
22
|
+
break;
|
|
23
|
+
case 'NONE':
|
|
24
|
+
logger.setLogLevel(LogLevel.NONE);
|
|
25
|
+
break;
|
|
26
|
+
default:
|
|
27
|
+
logger.setLogLevel(LogLevel.INFO);
|
|
28
|
+
}
|
|
29
|
+
// Create and start the server
|
|
30
|
+
const server = createServer();
|
|
31
|
+
// Start the server and handle any startup errors
|
|
32
|
+
server.run().catch(error => {
|
|
33
|
+
logger.error('Failed to start markdownlint MCP server', error);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// Execute the main function
|
|
38
|
+
main();
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAElD;;GAEG;AACH,SAAS,IAAI;IACX,qEAAqE;IACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC;IACjD,QAAQ,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/B,KAAK,OAAO;YACV,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM;QACR,KAAK,MAAM;YACT,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM;QACR,KAAK,MAAM;YACT,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM;QACR,KAAK,OAAO;YACV,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM;QACR,KAAK,MAAM;YACT,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM;QACR;YACE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,8BAA8B;IAC9B,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAE9B,iDAAiD;IACjD,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QACzB,MAAM,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,4BAA4B;AAC5B,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exports all rule implementations
|
|
3
|
+
*/
|
|
4
|
+
import { RuleMap } from './rule-interface';
|
|
5
|
+
/**
|
|
6
|
+
* Rule implementation map by rule name
|
|
7
|
+
* This will be populated as rules are implemented
|
|
8
|
+
*/
|
|
9
|
+
export declare const rules: RuleMap;
|
|
10
|
+
/**
|
|
11
|
+
* Get a list of implemented rule names
|
|
12
|
+
* @returns Array of rule names that have been implemented
|
|
13
|
+
*/
|
|
14
|
+
export declare function getImplementedRules(): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Apply all rule fixes to an array of lines
|
|
17
|
+
* @param lines Array of string lines to fix
|
|
18
|
+
* @param ruleNames Array of rule names to apply (e.g., ["MD009", "MD010"])
|
|
19
|
+
* @returns Fixed lines array
|
|
20
|
+
*/
|
|
21
|
+
export declare function applyRuleFixes(lines: string[], ruleNames: string[]): string[];
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AA2D3C;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,OAuDnB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAa7E"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exports all rule implementations
|
|
3
|
+
*/
|
|
4
|
+
// Import implemented rules
|
|
5
|
+
import md001 from './md001';
|
|
6
|
+
import md003 from './md003';
|
|
7
|
+
import md004 from './md004';
|
|
8
|
+
import md024 from './md024';
|
|
9
|
+
import md025 from './md025';
|
|
10
|
+
import md036 from './md036';
|
|
11
|
+
import md005 from './md005';
|
|
12
|
+
import md007 from './md007';
|
|
13
|
+
import md009 from './md009';
|
|
14
|
+
import md010 from './md010';
|
|
15
|
+
import md011 from './md011';
|
|
16
|
+
import md012 from './md012';
|
|
17
|
+
import md013 from './md013';
|
|
18
|
+
import md014 from './md014';
|
|
19
|
+
import md018 from './md018';
|
|
20
|
+
import md019 from './md019';
|
|
21
|
+
import md020 from './md020';
|
|
22
|
+
import md021 from './md021';
|
|
23
|
+
import md022 from './md022';
|
|
24
|
+
import md023 from './md023';
|
|
25
|
+
import md026 from './md026';
|
|
26
|
+
import md027 from './md027';
|
|
27
|
+
import md028 from './md028';
|
|
28
|
+
import md029 from './md029';
|
|
29
|
+
import md030 from './md030';
|
|
30
|
+
import md031 from './md031';
|
|
31
|
+
import md032 from './md032';
|
|
32
|
+
import md033 from './md033';
|
|
33
|
+
import md034 from './md034';
|
|
34
|
+
import md037 from './md037';
|
|
35
|
+
import md038 from './md038';
|
|
36
|
+
import md039 from './md039';
|
|
37
|
+
import md040 from './md040';
|
|
38
|
+
import md041 from './md041';
|
|
39
|
+
import md042 from './md042';
|
|
40
|
+
import md043 from './md043';
|
|
41
|
+
import md044 from './md044';
|
|
42
|
+
import md045 from './md045';
|
|
43
|
+
import md046 from './md046';
|
|
44
|
+
import md047 from './md047';
|
|
45
|
+
import md048 from './md048';
|
|
46
|
+
import md049 from './md049';
|
|
47
|
+
import md050 from './md050';
|
|
48
|
+
import md051 from './md051';
|
|
49
|
+
import md052 from './md052';
|
|
50
|
+
import md053 from './md053';
|
|
51
|
+
import md054 from './md054';
|
|
52
|
+
import md055 from './md055';
|
|
53
|
+
import md056 from './md056';
|
|
54
|
+
import md058 from './md058';
|
|
55
|
+
import md059 from './md059';
|
|
56
|
+
import md035 from './md035';
|
|
57
|
+
// Future rule imports (to be implemented)
|
|
58
|
+
// Add more rule imports as they are implemented
|
|
59
|
+
/**
|
|
60
|
+
* Rule implementation map by rule name
|
|
61
|
+
* This will be populated as rules are implemented
|
|
62
|
+
*/
|
|
63
|
+
export const rules = {
|
|
64
|
+
MD001: md001,
|
|
65
|
+
MD003: md003,
|
|
66
|
+
MD004: md004,
|
|
67
|
+
MD005: md005,
|
|
68
|
+
MD007: md007,
|
|
69
|
+
MD009: md009,
|
|
70
|
+
MD010: md010,
|
|
71
|
+
MD011: md011,
|
|
72
|
+
MD012: md012,
|
|
73
|
+
MD013: md013,
|
|
74
|
+
MD014: md014,
|
|
75
|
+
MD018: md018,
|
|
76
|
+
MD019: md019,
|
|
77
|
+
MD020: md020,
|
|
78
|
+
MD021: md021,
|
|
79
|
+
MD022: md022,
|
|
80
|
+
MD023: md023,
|
|
81
|
+
MD024: md024,
|
|
82
|
+
MD025: md025,
|
|
83
|
+
MD026: md026,
|
|
84
|
+
MD027: md027,
|
|
85
|
+
MD028: md028,
|
|
86
|
+
MD029: md029,
|
|
87
|
+
MD030: md030,
|
|
88
|
+
MD031: md031,
|
|
89
|
+
MD032: md032,
|
|
90
|
+
MD033: md033,
|
|
91
|
+
MD034: md034,
|
|
92
|
+
MD035: md035,
|
|
93
|
+
MD036: md036,
|
|
94
|
+
MD037: md037,
|
|
95
|
+
MD038: md038,
|
|
96
|
+
MD039: md039,
|
|
97
|
+
MD040: md040,
|
|
98
|
+
MD041: md041,
|
|
99
|
+
MD042: md042,
|
|
100
|
+
MD043: md043,
|
|
101
|
+
MD044: md044,
|
|
102
|
+
MD045: md045,
|
|
103
|
+
MD046: md046,
|
|
104
|
+
MD047: md047,
|
|
105
|
+
MD048: md048,
|
|
106
|
+
MD049: md049,
|
|
107
|
+
MD050: md050,
|
|
108
|
+
MD051: md051,
|
|
109
|
+
MD052: md052,
|
|
110
|
+
MD053: md053,
|
|
111
|
+
MD054: md054,
|
|
112
|
+
MD055: md055,
|
|
113
|
+
MD056: md056,
|
|
114
|
+
MD058: md058,
|
|
115
|
+
MD059: md059,
|
|
116
|
+
// Add more rules as they are implemented
|
|
117
|
+
// ...
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Get a list of implemented rule names
|
|
121
|
+
* @returns Array of rule names that have been implemented
|
|
122
|
+
*/
|
|
123
|
+
export function getImplementedRules() {
|
|
124
|
+
return Object.keys(rules);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Apply all rule fixes to an array of lines
|
|
128
|
+
* @param lines Array of string lines to fix
|
|
129
|
+
* @param ruleNames Array of rule names to apply (e.g., ["MD009", "MD010"])
|
|
130
|
+
* @returns Fixed lines array
|
|
131
|
+
*/
|
|
132
|
+
export function applyRuleFixes(lines, ruleNames) {
|
|
133
|
+
// Create a copy of the lines array to avoid modifying the original
|
|
134
|
+
let fixedLines = [...lines];
|
|
135
|
+
// Apply each rule fix in sequence, but only if the rule is implemented
|
|
136
|
+
for (const ruleName of ruleNames) {
|
|
137
|
+
const rule = rules[ruleName];
|
|
138
|
+
if (rule?.fix) {
|
|
139
|
+
fixedLines = rule.fix(fixedLines);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return fixedLines;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Rule } from './rule-interface';
|
|
2
|
+
/**
|
|
3
|
+
* MD001: Heading levels should only increment by one level at a time
|
|
4
|
+
*
|
|
5
|
+
* This rule is triggered when you skip heading levels in a markdown document, for example:
|
|
6
|
+
*
|
|
7
|
+
* # Heading 1
|
|
8
|
+
* ### Heading 3
|
|
9
|
+
*
|
|
10
|
+
* This rule requires that heading levels only increment by one level at a time.
|
|
11
|
+
*/
|
|
12
|
+
export declare const name = "MD001";
|
|
13
|
+
export declare const description = "Heading levels should only increment by one level at a time";
|
|
14
|
+
/**
|
|
15
|
+
* Fixes markdown content to ensure heading levels only increment by one level at a time
|
|
16
|
+
* @param lines Array of string lines to fix
|
|
17
|
+
* @returns Fixed lines array with proper heading level increments
|
|
18
|
+
*/
|
|
19
|
+
export declare function fix(lines: string[]): string[];
|
|
20
|
+
/**
|
|
21
|
+
* Rule implementation for MD001
|
|
22
|
+
*/
|
|
23
|
+
export declare const rule: Rule;
|
|
24
|
+
export default rule;
|
|
25
|
+
//# sourceMappingURL=md001.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md001.d.ts","sourceRoot":"","sources":["../../src/rules/md001.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI,UAAU,CAAC;AAC5B,eAAO,MAAM,WAAW,gEAAgE,CAAC;AAEzF;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA0D7C;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,IAIlB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MD001: Heading levels should only increment by one level at a time
|
|
3
|
+
*
|
|
4
|
+
* This rule is triggered when you skip heading levels in a markdown document, for example:
|
|
5
|
+
*
|
|
6
|
+
* # Heading 1
|
|
7
|
+
* ### Heading 3
|
|
8
|
+
*
|
|
9
|
+
* This rule requires that heading levels only increment by one level at a time.
|
|
10
|
+
*/
|
|
11
|
+
export const name = 'MD001';
|
|
12
|
+
export const description = 'Heading levels should only increment by one level at a time';
|
|
13
|
+
/**
|
|
14
|
+
* Fixes markdown content to ensure heading levels only increment by one level at a time
|
|
15
|
+
* @param lines Array of string lines to fix
|
|
16
|
+
* @returns Fixed lines array with proper heading level increments
|
|
17
|
+
*/
|
|
18
|
+
export function fix(lines) {
|
|
19
|
+
if (lines.length === 0)
|
|
20
|
+
return lines;
|
|
21
|
+
const result = [...lines];
|
|
22
|
+
let previousLevel = 0;
|
|
23
|
+
// Helper to extract heading level from a line
|
|
24
|
+
function getHeadingLevel(line) {
|
|
25
|
+
const match = line.match(/^(#{1,6})(?:\s|$)/);
|
|
26
|
+
return match ? match[1].length : 0;
|
|
27
|
+
}
|
|
28
|
+
// Helper to change a heading's level
|
|
29
|
+
function changeHeadingLevel(line, newLevel) {
|
|
30
|
+
// ATX heading (# style)
|
|
31
|
+
if (/^#{1,6}\s/.test(line)) {
|
|
32
|
+
const content = line.replace(/^#{1,6}\s+/, '');
|
|
33
|
+
return '#'.repeat(newLevel) + ' ' + content;
|
|
34
|
+
}
|
|
35
|
+
// Closed ATX heading (# style #)
|
|
36
|
+
else if (/^#{1,6}\s.*\s+#{1,6}$/.test(line)) {
|
|
37
|
+
const content = line.replace(/^#{1,6}\s+/, '').replace(/\s+#{1,6}$/, '');
|
|
38
|
+
return '#'.repeat(newLevel) + ' ' + content + ' ' + '#'.repeat(newLevel);
|
|
39
|
+
}
|
|
40
|
+
// If we can't determine the heading style, return original line
|
|
41
|
+
return line;
|
|
42
|
+
}
|
|
43
|
+
// Scan through each line to find headings and fix levels
|
|
44
|
+
for (let i = 0; i < lines.length; i++) {
|
|
45
|
+
const line = lines[i];
|
|
46
|
+
const level = getHeadingLevel(line);
|
|
47
|
+
// Skip non-heading lines
|
|
48
|
+
if (level === 0) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
// For the first heading, just set the previous level
|
|
52
|
+
if (previousLevel === 0) {
|
|
53
|
+
previousLevel = level;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
// If we skip levels (e.g., from h1 to h3), fix it
|
|
57
|
+
if (level > previousLevel + 1) {
|
|
58
|
+
// Change to one level deeper than previous
|
|
59
|
+
const newLevel = previousLevel + 1;
|
|
60
|
+
result[i] = changeHeadingLevel(line, newLevel);
|
|
61
|
+
previousLevel = newLevel;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// If no issues, update previous level
|
|
65
|
+
previousLevel = level;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Rule implementation for MD001
|
|
72
|
+
*/
|
|
73
|
+
export const rule = {
|
|
74
|
+
name,
|
|
75
|
+
description,
|
|
76
|
+
fix,
|
|
77
|
+
};
|
|
78
|
+
export default rule;
|
|
79
|
+
//# sourceMappingURL=md001.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md001.js","sourceRoot":"","sources":["../../src/rules/md001.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC;AAC5B,MAAM,CAAC,MAAM,WAAW,GAAG,6DAA6D,CAAC;AAEzF;;;;GAIG;AACH,MAAM,UAAU,GAAG,CAAC,KAAe;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAErC,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAC1B,IAAI,aAAa,GAAG,CAAC,CAAC;IAEtB,8CAA8C;IAC9C,SAAS,eAAe,CAAC,IAAY;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,qCAAqC;IACrC,SAAS,kBAAkB,CAAC,IAAY,EAAE,QAAgB;QACxD,wBAAwB;QACxB,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAC/C,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC;QAC9C,CAAC;QACD,iCAAiC;aAC5B,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YACzE,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3E,CAAC;QAED,gEAAgE;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yDAAyD;IACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QAEpC,yBAAyB;QACzB,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,SAAS;QACX,CAAC;QAED,qDAAqD;QACrD,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;YACxB,aAAa,GAAG,KAAK,CAAC;YACtB,SAAS;QACX,CAAC;QAED,kDAAkD;QAClD,IAAI,KAAK,GAAG,aAAa,GAAG,CAAC,EAAE,CAAC;YAC9B,2CAA2C;YAC3C,MAAM,QAAQ,GAAG,aAAa,GAAG,CAAC,CAAC;YACnC,MAAM,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC/C,aAAa,GAAG,QAAQ,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,sCAAsC;YACtC,aAAa,GAAG,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,IAAI,GAAS;IACxB,IAAI;IACJ,WAAW;IACX,GAAG;CACJ,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Rule } from './rule-interface';
|
|
2
|
+
/**
|
|
3
|
+
* MD003: Heading style
|
|
4
|
+
*
|
|
5
|
+
* This rule enforces a consistent heading style, which could be:
|
|
6
|
+
* - atx: # Heading
|
|
7
|
+
* - atx_closed: # Heading #
|
|
8
|
+
* - setext: Heading
|
|
9
|
+
* =======
|
|
10
|
+
*
|
|
11
|
+
* The default is atx, but this can be configured in .markdownlint.json.
|
|
12
|
+
*/
|
|
13
|
+
export declare const name = "MD003";
|
|
14
|
+
export declare const description = "Heading style";
|
|
15
|
+
/**
|
|
16
|
+
* Enum for heading styles
|
|
17
|
+
*/
|
|
18
|
+
declare enum HeadingStyle {
|
|
19
|
+
ATX = "atx",
|
|
20
|
+
ATX_CLOSED = "atx_closed",
|
|
21
|
+
SETEXT = "setext"
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Configuration options for MD003
|
|
25
|
+
*/
|
|
26
|
+
interface MD003Config {
|
|
27
|
+
style?: HeadingStyle;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Fix headings to use a consistent style
|
|
31
|
+
* @param lines Array of string lines to fix
|
|
32
|
+
* @param config Optional configuration object
|
|
33
|
+
* @returns Fixed lines array with consistent heading styles
|
|
34
|
+
*/
|
|
35
|
+
export declare function fix(lines: string[], config?: MD003Config): string[];
|
|
36
|
+
/**
|
|
37
|
+
* Rule implementation for MD003
|
|
38
|
+
*/
|
|
39
|
+
export declare const rule: Rule;
|
|
40
|
+
export default rule;
|
|
41
|
+
//# sourceMappingURL=md003.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md003.d.ts","sourceRoot":"","sources":["../../src/rules/md003.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,IAAI,UAAU,CAAC;AAC5B,eAAO,MAAM,WAAW,kBAAkB,CAAC;AAE3C;;GAEG;AACH,aAAK,YAAY;IACf,GAAG,QAAQ;IACX,UAAU,eAAe;IACzB,MAAM,WAAW;CAClB;AAED;;GAEG;AACH,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAyED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,CA6CnE;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,IAIlB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|