@entro314labs/markdownfix 0.0.6 → 0.0.10
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/.remarkignore +3 -1
- package/.remarkrc.js +5 -2
- package/ESLINT_INTEGRATION.md +345 -0
- package/README.md +186 -39
- package/cli.js +176 -1
- package/eslint.config.js +82 -0
- package/package.json +18 -6
package/.remarkignore
CHANGED
package/.remarkrc.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Opinionated Remark configuration for markdown processing
|
|
3
|
-
* Supports .md, and .
|
|
3
|
+
* Supports .md, .mdx, and .mdc files with consistent formatting
|
|
4
4
|
* Optionally supports .mdd files if mdd package is installed
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -18,7 +18,7 @@ try {
|
|
|
18
18
|
];
|
|
19
19
|
console.log('✓ MDD support enabled');
|
|
20
20
|
} catch (e) {
|
|
21
|
-
// MDD package not installed - only support .md and .
|
|
21
|
+
// MDD package not installed - only support .md, .mdx, and .mdc
|
|
22
22
|
mddPlugins = ['remark-mdx'];
|
|
23
23
|
console.log('ℹ MDD support not available (install mdd package for .mdd file support)');
|
|
24
24
|
}
|
|
@@ -50,6 +50,9 @@ export default {
|
|
|
50
50
|
// Enable GitHub Flavored Markdown (tables, strikethrough, etc.)
|
|
51
51
|
'remark-gfm',
|
|
52
52
|
|
|
53
|
+
// Enable MDC syntax (Markdown Components for Nuxt Content)
|
|
54
|
+
'remark-mdc',
|
|
55
|
+
|
|
53
56
|
// MDX/MDD plugins (loaded dynamically above)
|
|
54
57
|
...mddPlugins,
|
|
55
58
|
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# ESLint + MDX Integration Guide
|
|
2
|
+
|
|
3
|
+
This project integrates `eslint-plugin-mdx` with the existing remark-lint setup to provide comprehensive linting for MDX files.
|
|
4
|
+
|
|
5
|
+
## Why ESLint for MDX?
|
|
6
|
+
|
|
7
|
+
While remark-lint handles markdown syntax and formatting, ESLint adds:
|
|
8
|
+
|
|
9
|
+
- **JavaScript/JSX linting** - Lint code inside MDX code blocks
|
|
10
|
+
- **IDE integration** - Better VS Code support with ESLint extension
|
|
11
|
+
- **Unified error reporting** - Consistent error format across tools
|
|
12
|
+
- **Code quality checks** - Catch unused variables, syntax errors in examples
|
|
13
|
+
|
|
14
|
+
## Architecture
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
┌─────────────────────────────────────────────────┐
|
|
18
|
+
│ Your MDX/Markdown Files │
|
|
19
|
+
└─────────────────────────────────────────────────┘
|
|
20
|
+
│
|
|
21
|
+
┌───────────┴───────────┐
|
|
22
|
+
│ │
|
|
23
|
+
▼ ▼
|
|
24
|
+
┌──────────────┐ ┌──────────────────┐
|
|
25
|
+
│ remark-cli │ │ eslint-plugin- │
|
|
26
|
+
│ │ │ mdx │
|
|
27
|
+
│ • Formatting │ │ │
|
|
28
|
+
│ • MD syntax │ │ • JS/JSX linting │
|
|
29
|
+
│ • 40+ rules │ │ • Reads .remarkrc│
|
|
30
|
+
└──────────────┘ │ • Code blocks │
|
|
31
|
+
└──────────────────┘
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## How It Works
|
|
35
|
+
|
|
36
|
+
1. **remark-cli** - Primary formatter and markdown linter
|
|
37
|
+
- Uses [.remarkrc.js](./.remarkrc.js) configuration
|
|
38
|
+
- Handles all markdown syntax and formatting
|
|
39
|
+
- Fixes issues automatically with `--output`
|
|
40
|
+
|
|
41
|
+
2. **eslint-plugin-mdx** - Complementary JavaScript linter
|
|
42
|
+
- Reads [eslint.config.js](./eslint.config.js) (ESLint 9 flat config)
|
|
43
|
+
- **Automatically uses remark-lint rules** from `.remarkrc.js`
|
|
44
|
+
- Lints JavaScript/JSX code in MDX code blocks
|
|
45
|
+
- Provides IDE integration
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
Already installed in this project:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pnpm add -D eslint eslint-plugin-mdx eslint-plugin-react
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Configuration Files
|
|
56
|
+
|
|
57
|
+
### [eslint.config.js](./eslint.config.js)
|
|
58
|
+
|
|
59
|
+
ESLint 9 flat config that:
|
|
60
|
+
|
|
61
|
+
- Configures MDX plugin for `.md`, `.mdx`, `.mdd` files
|
|
62
|
+
- Uses `mdx/remark` rule to integrate remark-lint
|
|
63
|
+
- Enables code block linting
|
|
64
|
+
- Defines globals for documentation examples
|
|
65
|
+
|
|
66
|
+
### [.remarkrc.js](./.remarkrc.js)
|
|
67
|
+
|
|
68
|
+
Existing remark configuration with 40+ lint rules. This is **automatically used** by ESLint via the `mdx/remark` rule.
|
|
69
|
+
|
|
70
|
+
## Available Scripts
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Markdown formatting (remark-cli)
|
|
74
|
+
pnpm run format # Auto-fix markdown formatting
|
|
75
|
+
pnpm run format:check # Check without writing changes
|
|
76
|
+
|
|
77
|
+
# Linting
|
|
78
|
+
pnpm run lint # Remark-lint only
|
|
79
|
+
pnpm run lint:eslint # ESLint + MDX only
|
|
80
|
+
pnpm run lint:eslint:fix # ESLint auto-fix
|
|
81
|
+
pnpm run lint:all # Both remark and ESLint
|
|
82
|
+
|
|
83
|
+
# Complete workflow
|
|
84
|
+
pnpm run process # Format + lint all
|
|
85
|
+
pnpm run process:safe # Check + lint all
|
|
86
|
+
pnpm run nuclear # 🚀 Run ALL linters and fixers
|
|
87
|
+
pnpm test # Same as process:safe
|
|
88
|
+
|
|
89
|
+
# CLI usage
|
|
90
|
+
markdownfix nuclear # Nuclear mode via CLI
|
|
91
|
+
mdfix nuclear --quiet # Silent nuclear mode
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Workflow
|
|
95
|
+
|
|
96
|
+
### Recommended Development Workflow
|
|
97
|
+
|
|
98
|
+
#### Quick Fix Everything (Recommended)
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# 🚀 One command to rule them all
|
|
102
|
+
markdownfix nuclear
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This runs the complete 4-step workflow:
|
|
106
|
+
|
|
107
|
+
1. Remark formatting
|
|
108
|
+
2. Remark linting
|
|
109
|
+
3. ESLint auto-fix
|
|
110
|
+
4. ESLint linting
|
|
111
|
+
|
|
112
|
+
#### Manual Step-by-Step
|
|
113
|
+
|
|
114
|
+
1. **Write/edit markdown files**
|
|
115
|
+
|
|
116
|
+
2. **Format with remark**
|
|
117
|
+
```bash
|
|
118
|
+
pnpm run format
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
3. **Lint with both tools**
|
|
122
|
+
```bash
|
|
123
|
+
pnpm run lint:all
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
4. **Or use the complete workflow**
|
|
127
|
+
```bash
|
|
128
|
+
pnpm run process
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### CI/CD Workflow
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
pnpm test
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
This runs `process:safe` which:
|
|
138
|
+
1. Checks formatting (no writes)
|
|
139
|
+
2. Runs remark-lint
|
|
140
|
+
3. Runs ESLint
|
|
141
|
+
|
|
142
|
+
## What Gets Checked
|
|
143
|
+
|
|
144
|
+
### Remark-lint (40+ rules)
|
|
145
|
+
|
|
146
|
+
- Markdown syntax (headings, lists, tables)
|
|
147
|
+
- Formatting consistency (emphasis, strong, code blocks)
|
|
148
|
+
- Link validation
|
|
149
|
+
- Table alignment
|
|
150
|
+
- Line length
|
|
151
|
+
- Trailing spaces
|
|
152
|
+
- Final newlines
|
|
153
|
+
|
|
154
|
+
See [.remarkrc.js](./.remarkrc.js) for full configuration.
|
|
155
|
+
|
|
156
|
+
### ESLint (JavaScript in code blocks)
|
|
157
|
+
|
|
158
|
+
- `no-var` - Enforce const/let
|
|
159
|
+
- `prefer-const` - Use const when possible
|
|
160
|
+
- `no-unused-vars` - Warn about unused variables
|
|
161
|
+
- Syntax errors in code examples
|
|
162
|
+
|
|
163
|
+
## IDE Integration
|
|
164
|
+
|
|
165
|
+
### VS Code
|
|
166
|
+
|
|
167
|
+
1. **Install ESLint extension**
|
|
168
|
+
```
|
|
169
|
+
ext install dbaeumer.vscode-eslint
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
2. **Configure workspace settings** (`.vscode/settings.json`)
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"eslint.validate": [
|
|
176
|
+
"javascript",
|
|
177
|
+
"typescript",
|
|
178
|
+
"markdown",
|
|
179
|
+
"mdx"
|
|
180
|
+
],
|
|
181
|
+
"eslint.probe": [
|
|
182
|
+
"javascript",
|
|
183
|
+
"typescript",
|
|
184
|
+
"markdown",
|
|
185
|
+
"mdx"
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
3. **MDX files will show inline errors** from both remark-lint and ESLint
|
|
191
|
+
|
|
192
|
+
## Examples
|
|
193
|
+
|
|
194
|
+
### Catching Code Block Issues
|
|
195
|
+
|
|
196
|
+
**Before:**
|
|
197
|
+
```javascript
|
|
198
|
+
function example() {
|
|
199
|
+
var unused = "bad";
|
|
200
|
+
return "hello"
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**ESLint warnings:**
|
|
205
|
+
- `no-var`: Unexpected var, use let or const instead
|
|
206
|
+
- `no-unused-vars`: 'unused' is assigned but never used
|
|
207
|
+
|
|
208
|
+
**After:**
|
|
209
|
+
```javascript
|
|
210
|
+
function greet(name) {
|
|
211
|
+
return `Hello ${name}`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
console.log(greet("World"));
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Markdown Issues (remark-lint)
|
|
218
|
+
|
|
219
|
+
**Before:**
|
|
220
|
+
```markdown
|
|
221
|
+
#No Space After Hash
|
|
222
|
+
- item 1
|
|
223
|
+
- item 2
|
|
224
|
+
- nested
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Remark-lint errors:**
|
|
228
|
+
- Headings must have space after `#`
|
|
229
|
+
- List items need blank lines between them
|
|
230
|
+
|
|
231
|
+
**After:**
|
|
232
|
+
```markdown
|
|
233
|
+
# Proper Heading
|
|
234
|
+
|
|
235
|
+
- item 1
|
|
236
|
+
|
|
237
|
+
- item 2
|
|
238
|
+
- nested
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Ignoring Files
|
|
242
|
+
|
|
243
|
+
Files are ignored via:
|
|
244
|
+
|
|
245
|
+
1. **ESLint** - `ignores` array in [eslint.config.js](./eslint.config.js)
|
|
246
|
+
2. **Remark** - [.remarkignore](./.remarkignore)
|
|
247
|
+
|
|
248
|
+
Common ignored files:
|
|
249
|
+
- `README.md`
|
|
250
|
+
- `CHANGELOG.md`
|
|
251
|
+
- `LICENSE`
|
|
252
|
+
- `node_modules/`
|
|
253
|
+
- Build outputs
|
|
254
|
+
|
|
255
|
+
## Troubleshooting
|
|
256
|
+
|
|
257
|
+
### ESLint not finding MDX files
|
|
258
|
+
|
|
259
|
+
Make sure you're using the correct extension flag:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Correct
|
|
263
|
+
eslint --ext .md,.mdx,.mdd .
|
|
264
|
+
|
|
265
|
+
# Wrong (won't work)
|
|
266
|
+
eslint .
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Remark-lint rules not appearing in ESLint
|
|
270
|
+
|
|
271
|
+
The `mdx/remark` rule automatically reads `.remarkrc.js`. If changes don't appear:
|
|
272
|
+
|
|
273
|
+
1. Restart your IDE/ESLint server
|
|
274
|
+
2. Check `.remarkrc.js` syntax is valid
|
|
275
|
+
3. Verify `mdx/remark` rule is enabled in `eslint.config.js`
|
|
276
|
+
|
|
277
|
+
### Code block linting not working
|
|
278
|
+
|
|
279
|
+
Ensure code blocks have language identifiers:
|
|
280
|
+
|
|
281
|
+
```javascript
|
|
282
|
+
// This will be linted
|
|
283
|
+
const x = 1;
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Performance
|
|
287
|
+
|
|
288
|
+
For large projects, you can:
|
|
289
|
+
|
|
290
|
+
1. **Disable code block linting**
|
|
291
|
+
```javascript
|
|
292
|
+
// In eslint.config.js
|
|
293
|
+
processor: mdxPlugin.createRemarkProcessor({
|
|
294
|
+
lintCodeBlocks: false
|
|
295
|
+
})
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
2. **Run tools separately**
|
|
299
|
+
```bash
|
|
300
|
+
pnpm run lint # Just remark
|
|
301
|
+
pnpm run lint:eslint # Just ESLint
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Comparison with Alternatives
|
|
305
|
+
|
|
306
|
+
### Why not just remark-cli?
|
|
307
|
+
|
|
308
|
+
Remark-cli is excellent for markdown formatting but doesn't lint JavaScript code in code blocks.
|
|
309
|
+
|
|
310
|
+
### Why not just ESLint?
|
|
311
|
+
|
|
312
|
+
ESLint alone doesn't understand markdown-specific rules like table formatting, heading hierarchy, etc.
|
|
313
|
+
|
|
314
|
+
### Why not Biome?
|
|
315
|
+
|
|
316
|
+
As of 2025, Biome does not support MDX or stable Markdown linting. Markdown support is on their roadmap but not yet available.
|
|
317
|
+
|
|
318
|
+
### Why not Prettier?
|
|
319
|
+
|
|
320
|
+
Prettier formats but doesn't lint. This project uses remark for both formatting and linting with 40+ opinionated rules.
|
|
321
|
+
|
|
322
|
+
## Benefits of This Setup
|
|
323
|
+
|
|
324
|
+
✅ **Comprehensive** - Both markdown and JavaScript linting
|
|
325
|
+
✅ **IDE integration** - Real-time feedback in VS Code
|
|
326
|
+
✅ **Automatic fixes** - Most issues can be auto-fixed
|
|
327
|
+
✅ **Unified workflow** - Single `pnpm test` command
|
|
328
|
+
✅ **Flexible** - Can use tools separately or together
|
|
329
|
+
✅ **No conflicts** - ESLint uses remark rules, no duplication
|
|
330
|
+
|
|
331
|
+
## Migration Notes
|
|
332
|
+
|
|
333
|
+
If you were using only remark-cli before:
|
|
334
|
+
|
|
335
|
+
1. ✅ All existing remark rules still work
|
|
336
|
+
2. ✅ All existing scripts still work
|
|
337
|
+
3. ✅ New ESLint scripts are additive
|
|
338
|
+
4. ✅ No breaking changes to workflow
|
|
339
|
+
|
|
340
|
+
## Further Reading
|
|
341
|
+
|
|
342
|
+
- [eslint-plugin-mdx documentation](https://github.com/mdx-js/eslint-mdx)
|
|
343
|
+
- [remark-lint rules](https://github.com/remarkjs/remark-lint)
|
|
344
|
+
- [ESLint flat config](https://eslint.org/docs/latest/use/configure/)
|
|
345
|
+
- [MDX documentation](https://mdxjs.com/)
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Markdown Formatter (markdownfix)
|
|
2
2
|
|
|
3
|
-
**Opinionated markdown formatter and linter for `.md`, `.
|
|
3
|
+
**Opinionated markdown formatter and linter for `.md`, `.mdx`, `.mdc`, and `.mdd` files**
|
|
4
4
|
|
|
5
5
|
Built on the Remark ecosystem with strict, consistent formatting rules for developer documentation, technical writing, and web content. Perfect for README files, technical docs, blogs, and GitHub wikis.
|
|
6
6
|
|
|
@@ -8,10 +8,13 @@ Built on the Remark ecosystem with strict, consistent formatting rules for devel
|
|
|
8
8
|
|
|
9
9
|
- ✅ **Opinionated formatting** - Consistent style across all markdown files
|
|
10
10
|
- ✅ **GitHub Flavored Markdown** - Tables, task lists, strikethrough, autolinks
|
|
11
|
-
- ✅ **MDX support** - JSX components in markdown
|
|
12
|
-
- ✅ **
|
|
11
|
+
- ✅ **MDX support** - JSX components in markdown with ESLint integration
|
|
12
|
+
- ✅ **MDC syntax support** - Markdown Components for Nuxt Content
|
|
13
|
+
- ✅ **Comprehensive linting** - 40+ remark-lint rules for quality and consistency
|
|
14
|
+
- ✅ **Code block linting** - ESLint integration for JavaScript/JSX in code blocks
|
|
13
15
|
- ✅ **Link validation** - Check for broken links
|
|
14
16
|
- ✅ **Auto-fixing** - Automatically fix formatting issues
|
|
17
|
+
- ✅ **IDE integration** - Works with VS Code ESLint extension
|
|
15
18
|
|
|
16
19
|
## Installation
|
|
17
20
|
|
|
@@ -35,6 +38,9 @@ markdownfix check
|
|
|
35
38
|
# Lint files for issues
|
|
36
39
|
markdownfix lint
|
|
37
40
|
|
|
41
|
+
# 🚀 Nuclear mode - run ALL linters and fixers
|
|
42
|
+
markdownfix nuclear
|
|
43
|
+
|
|
38
44
|
# Format specific files
|
|
39
45
|
markdownfix format README.md docs/*.md
|
|
40
46
|
|
|
@@ -53,7 +59,8 @@ Add to your `package.json`:
|
|
|
53
59
|
{
|
|
54
60
|
"scripts": {
|
|
55
61
|
"format:md": "markdownfix format",
|
|
56
|
-
"lint:md": "markdownfix lint"
|
|
62
|
+
"lint:md": "markdownfix lint",
|
|
63
|
+
"fix:md": "markdownfix nuclear"
|
|
57
64
|
}
|
|
58
65
|
}
|
|
59
66
|
```
|
|
@@ -71,22 +78,27 @@ markdownfix setup
|
|
|
71
78
|
## What Gets Formatted
|
|
72
79
|
|
|
73
80
|
### Lists
|
|
81
|
+
|
|
74
82
|
- **Unordered**: `-` (never `*` or `+`)
|
|
75
83
|
- **Ordered**: `1.` incremental (never `1)`)
|
|
76
84
|
|
|
77
85
|
### Emphasis
|
|
86
|
+
|
|
78
87
|
- **Italic**: `_text_` (underscore, not asterisk)
|
|
79
88
|
- **Bold**: `**text**` (double asterisk, not underscore)
|
|
80
89
|
|
|
81
90
|
### Headings
|
|
91
|
+
|
|
82
92
|
- **Style**: ATX (`# Title`), never setext (`===`)
|
|
83
93
|
- **Hierarchy**: Must progress sequentially (no skipping levels)
|
|
84
94
|
|
|
85
95
|
### Code Blocks
|
|
96
|
+
|
|
86
97
|
- Always fenced (` ``` `) with language identifiers
|
|
87
98
|
- Never indented code blocks
|
|
88
99
|
|
|
89
100
|
### Formatting
|
|
101
|
+
|
|
90
102
|
- **Line length**: 100 characters max with smart wrapping
|
|
91
103
|
- **Tables**: Padded cells with aligned pipes (auto-formatted)
|
|
92
104
|
- **Final newline**: All files must end with `\n`
|
|
@@ -94,11 +106,46 @@ markdownfix setup
|
|
|
94
106
|
|
|
95
107
|
## File Support
|
|
96
108
|
|
|
97
|
-
| Extension | Support
|
|
98
|
-
|
|
99
|
-
| `.md`
|
|
100
|
-
| `.mdx`
|
|
101
|
-
| `.
|
|
109
|
+
| Extension | Support | Features | Use Case |
|
|
110
|
+
| --------- | ----------- | --------------------------------------- | ------------------------------- |
|
|
111
|
+
| `.md` | ✅ Full | GFM, frontmatter, tables, task lists | Documentation, READMEs, blogs |
|
|
112
|
+
| `.mdx` | ✅ Full | Above + JSX components, imports/exports | React docs, interactive content |
|
|
113
|
+
| `.mdc` | ✅ Full | Markdown Components (Nuxt Content) | Nuxt Content, Vue documentation |
|
|
114
|
+
| `.mdd` | ⚠️ Optional | Business documents (see below) | Invoices, proposals, contracts |
|
|
115
|
+
|
|
116
|
+
### MDC Support
|
|
117
|
+
|
|
118
|
+
This formatter includes **full support for `.mdc` files** and MDC (Markdown Components) syntax via `remark-mdc`. MDC is a superset of Markdown developed by Nuxt that allows you to use Vue-like components.
|
|
119
|
+
|
|
120
|
+
**MDC Features:**
|
|
121
|
+
|
|
122
|
+
```markdown
|
|
123
|
+
<!-- Block components -->
|
|
124
|
+
::card
|
|
125
|
+
This is card content with **formatting**.
|
|
126
|
+
::
|
|
127
|
+
|
|
128
|
+
<!-- Inline components -->
|
|
129
|
+
This is text with an :icon{name="rocket"} inline component.
|
|
130
|
+
|
|
131
|
+
<!-- Props and attributes -->
|
|
132
|
+
![Image]{.rounded width="400"}
|
|
133
|
+
|
|
134
|
+
<!-- Slots and nesting -->
|
|
135
|
+
::alert{type="warning"}
|
|
136
|
+
This is a warning message!
|
|
137
|
+
::
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Perfect for:**
|
|
141
|
+
- Nuxt Content projects
|
|
142
|
+
- Component-driven documentation
|
|
143
|
+
- Interactive markdown content
|
|
144
|
+
- Vue.js documentation sites
|
|
145
|
+
|
|
146
|
+
**File Usage:**
|
|
147
|
+
- `.mdc` extension - Dedicated MDC files (like `.mdx` for JSX)
|
|
148
|
+
- MDC syntax also works in `.md` and `.mdx` files
|
|
102
149
|
|
|
103
150
|
### MDD Support
|
|
104
151
|
|
|
@@ -106,7 +153,7 @@ This formatter can **optionally** format `.mdd` files if you install the [MDD pa
|
|
|
106
153
|
|
|
107
154
|
```bash
|
|
108
155
|
# Install MDD support
|
|
109
|
-
pnpm add mdd
|
|
156
|
+
pnpm add @entro314labs/mdd
|
|
110
157
|
|
|
111
158
|
# Now .mdd files will be formatted
|
|
112
159
|
pnpm run format
|
|
@@ -122,10 +169,74 @@ pnpm run format
|
|
|
122
169
|
markdownfix format [files...] # Format and fix markdown files
|
|
123
170
|
markdownfix check [files...] # Check without writing changes
|
|
124
171
|
markdownfix lint [files...] # Lint for issues only
|
|
172
|
+
markdownfix nuclear [files...] # 🚀 Run ALL linters and fixers
|
|
125
173
|
markdownfix init # Create .remarkrc.js config
|
|
126
174
|
markdownfix setup # Create example content structure
|
|
127
175
|
```
|
|
128
176
|
|
|
177
|
+
### 🚀 Nuclear Mode
|
|
178
|
+
|
|
179
|
+
The `nuclear` command runs a comprehensive 4-step workflow that applies **all** available linters and fixers:
|
|
180
|
+
|
|
181
|
+
1. **Remark Formatting** - Auto-fix markdown syntax
|
|
182
|
+
2. **Remark Linting** - Validate markdown rules (40+ rules)
|
|
183
|
+
3. **ESLint Auto-fix** - Fix JavaScript/JSX in code blocks
|
|
184
|
+
4. **ESLint Linting** - Validate code quality
|
|
185
|
+
|
|
186
|
+
**Perfect for:**
|
|
187
|
+
|
|
188
|
+
- Pre-commit hooks
|
|
189
|
+
- CI/CD pipelines
|
|
190
|
+
- Major cleanup sessions
|
|
191
|
+
- Ensuring everything is pristine
|
|
192
|
+
|
|
193
|
+
**Usage:**
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Run on all markdown files
|
|
197
|
+
markdownfix nuclear
|
|
198
|
+
|
|
199
|
+
# Run on specific directory
|
|
200
|
+
markdownfix nuclear --glob "docs/**/*.{md,mdx}"
|
|
201
|
+
|
|
202
|
+
# Add to package.json
|
|
203
|
+
{
|
|
204
|
+
"scripts": {
|
|
205
|
+
"precommit": "markdownfix nuclear"
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Example Output:**
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
🚀 NUCLEAR MODE ACTIVATED
|
|
214
|
+
|
|
215
|
+
Processing 15 file(s) with comprehensive workflow...
|
|
216
|
+
|
|
217
|
+
Step 1/4: Running remark formatting...
|
|
218
|
+
✓ Remark formatting completed
|
|
219
|
+
|
|
220
|
+
Step 2/4: Running remark linting...
|
|
221
|
+
✓ Remark linting passed
|
|
222
|
+
|
|
223
|
+
Step 3/4: Running ESLint auto-fix...
|
|
224
|
+
✓ ESLint auto-fix completed
|
|
225
|
+
|
|
226
|
+
Step 4/4: Running ESLint linting...
|
|
227
|
+
✓ ESLint linting passed
|
|
228
|
+
|
|
229
|
+
════════════════════════════════════════════════════════════
|
|
230
|
+
NUCLEAR MODE SUMMARY
|
|
231
|
+
════════════════════════════════════════════════════════════
|
|
232
|
+
✓ Remark Format PASS Formatted 15/15 files
|
|
233
|
+
✓ Remark Lint PASS Linted 15 files
|
|
234
|
+
✓ ESLint Fix PASS Auto-fixed code blocks
|
|
235
|
+
✓ ESLint Lint PASS All code blocks valid
|
|
236
|
+
════════════════════════════════════════════════════════════
|
|
237
|
+
🎉 All checks passed! Your markdown is pristine.
|
|
238
|
+
```
|
|
239
|
+
|
|
129
240
|
### Command Aliases
|
|
130
241
|
|
|
131
242
|
The CLI is available via two commands:
|
|
@@ -177,11 +288,15 @@ pnpm run format # Apply fixes using remark-cli
|
|
|
177
288
|
pnpm run format:check # Preview changes
|
|
178
289
|
|
|
179
290
|
# Linting
|
|
180
|
-
pnpm run lint #
|
|
291
|
+
pnpm run lint # Remark-lint only
|
|
292
|
+
pnpm run lint:eslint # ESLint + MDX only
|
|
293
|
+
pnpm run lint:eslint:fix # ESLint auto-fix
|
|
294
|
+
pnpm run lint:all # Both remark and ESLint
|
|
181
295
|
|
|
182
296
|
# Combined
|
|
183
|
-
pnpm run process # Format then lint
|
|
184
|
-
pnpm run process:safe # Dry-run first, then
|
|
297
|
+
pnpm run process # Format then lint all
|
|
298
|
+
pnpm run process:safe # Dry-run first, then lint all
|
|
299
|
+
pnpm run nuclear # 🚀 Run ALL linters and fixers
|
|
185
300
|
pnpm test # Same as process:safe
|
|
186
301
|
|
|
187
302
|
# Utilities
|
|
@@ -209,11 +324,13 @@ markdownfix/
|
|
|
209
324
|
### `.remarkrc.js`
|
|
210
325
|
|
|
211
326
|
Central configuration defining:
|
|
327
|
+
|
|
212
328
|
- All formatting rules
|
|
213
329
|
- Plugin chain order
|
|
214
330
|
- Lint rule settings
|
|
215
331
|
|
|
216
332
|
**Plugin order is critical:**
|
|
333
|
+
|
|
217
334
|
1. `remark-frontmatter` - Parse YAML/TOML
|
|
218
335
|
2. `remark-gfm` - GitHub Flavored Markdown
|
|
219
336
|
3. `remark-mdx` - MDX support (conditional)
|
|
@@ -223,6 +340,7 @@ Central configuration defining:
|
|
|
223
340
|
### `.remarkignore`
|
|
224
341
|
|
|
225
342
|
Files excluded from processing:
|
|
343
|
+
|
|
226
344
|
- `README.md`
|
|
227
345
|
- `CHANGELOG.md`
|
|
228
346
|
- `LICENSE`
|
|
@@ -246,6 +364,7 @@ author: Optional but recommended
|
|
|
246
364
|
**Cause**: No markdown files found or all files excluded
|
|
247
365
|
|
|
248
366
|
**Solution**:
|
|
367
|
+
|
|
249
368
|
- Ensure markdown files exist in `content/` directory
|
|
250
369
|
- Check `.remarkignore` patterns
|
|
251
370
|
- Verify correct file extensions (`.md`, `.mdx`)
|
|
@@ -255,6 +374,7 @@ author: Optional but recommended
|
|
|
255
374
|
**Cause**: Some rules require manual fixes (duplicate headings, broken links)
|
|
256
375
|
|
|
257
376
|
**Solution**:
|
|
377
|
+
|
|
258
378
|
- Read console output for specific violations
|
|
259
379
|
- Manually fix reported issues
|
|
260
380
|
- Use `pnpm run format:check` to separate formatting from lint errors
|
|
@@ -264,6 +384,7 @@ author: Optional but recommended
|
|
|
264
384
|
**Cause**: Invalid JSX syntax
|
|
265
385
|
|
|
266
386
|
**Solution**:
|
|
387
|
+
|
|
267
388
|
- Verify JSX is valid JavaScript
|
|
268
389
|
- Check all tags are properly closed
|
|
269
390
|
- Ensure React components use `<Component />` not `<Component>`
|
|
@@ -285,46 +406,69 @@ pnpm run process:safe
|
|
|
285
406
|
|
|
286
407
|
**Disable VS Code remark extensions** - they may conflict with this opinionated configuration. Always use command line processing.
|
|
287
408
|
|
|
288
|
-
##
|
|
409
|
+
## Entro314 Labs Markdown Ecosystem
|
|
410
|
+
|
|
411
|
+
markdownfix is part of a comprehensive markdown ecosystem. For complete documentation, see [PROJECT\_ECOSYSTEM.md](../PROJECT_ECOSYSTEM.md).
|
|
412
|
+
|
|
413
|
+
### Companion Projects
|
|
414
|
+
|
|
415
|
+
#### 📄 [MDD (Markdown Document)](https://github.com/entro314-labs/mdd)
|
|
289
416
|
|
|
290
|
-
|
|
417
|
+
**The missing document layer for the AI-to-Office pipeline.**
|
|
291
418
|
|
|
292
|
-
|
|
419
|
+
Semantic document format for professional business documents:
|
|
293
420
|
|
|
294
|
-
|
|
421
|
+
- **Semantic directives**: `::letterhead`, `::signature-block`, `::header`, `::footer`
|
|
422
|
+
- **Multi-format output**: HTML, PDF, DOCX from single source
|
|
423
|
+
- **AI workflow integration**: ChatGPT/Claude markdown → professional documents
|
|
424
|
+
- **Zero configuration**: Professional styling built-in
|
|
425
|
+
- **200+ document types**: Comprehensive business document catalog
|
|
426
|
+
- **Version control friendly**: Plain text `.mdd` files
|
|
295
427
|
|
|
296
|
-
|
|
428
|
+
**Installation**: `npm install -g @entro314labs/mdd`
|
|
297
429
|
|
|
298
|
-
|
|
299
|
-
- Signature blocks
|
|
300
|
-
- Contact information blocks
|
|
301
|
-
- Professional PDF/DOCX output
|
|
302
|
-
- Invoice and proposal templates
|
|
430
|
+
**Quick start**:
|
|
303
431
|
|
|
304
432
|
```bash
|
|
305
|
-
#
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
#
|
|
433
|
+
# Preview business document
|
|
434
|
+
mdd-preview document.mdd
|
|
435
|
+
|
|
436
|
+
# Or use with npx
|
|
437
|
+
npx mdd-preview examples/invoice.mdd
|
|
309
438
|
```
|
|
310
439
|
|
|
311
|
-
**
|
|
440
|
+
markdownfix can **optionally format `.mdd` files** by installing MDD as a dependency.
|
|
441
|
+
|
|
442
|
+
#### 🖥️ [Anasa](https://github.com/entro314-labs/anasa)
|
|
443
|
+
|
|
444
|
+
Desktop knowledge management application with MDD integration:
|
|
445
|
+
|
|
446
|
+
- Bidirectional linking and graph visualization
|
|
447
|
+
- TipTap WYSIWYG editor
|
|
448
|
+
- **First GUI editor for MDD format**
|
|
449
|
+
- Create professional business documents inside your knowledge base
|
|
450
|
+
- Live preview and PDF export
|
|
312
451
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
|
318
|
-
|
|
|
319
|
-
|
|
|
320
|
-
|
|
|
321
|
-
|
|
|
322
|
-
|
|
|
452
|
+
**Status**: MDD integration planned ([see integration spec](../anasa/MDD_INTEGRATION_SPEC.md))
|
|
453
|
+
|
|
454
|
+
### When to Use Which
|
|
455
|
+
|
|
456
|
+
| Document Type | Use | File Extension | Package |
|
|
457
|
+
| ------------------------------ | ----------- | -------------- | --------------------------- |
|
|
458
|
+
| README files | markdownfix | `.md` | `@entro314labs/markdownfix` |
|
|
459
|
+
| Technical documentation | markdownfix | `.md` | `@entro314labs/markdownfix` |
|
|
460
|
+
| Blog posts | markdownfix | `.md` / `.mdx` | `@entro314labs/markdownfix` |
|
|
461
|
+
| React component docs | markdownfix | `.mdx` | `@entro314labs/markdownfix` |
|
|
462
|
+
| **Business letters** | **MDD** | **`.mdd`** | **`@entro314labs/mdd`** |
|
|
463
|
+
| **Invoices** | **MDD** | **`.mdd`** | **`@entro314labs/mdd`** |
|
|
464
|
+
| **Proposals** | **MDD** | **`.mdd`** | **`@entro314labs/mdd`** |
|
|
465
|
+
| **Contracts** | **MDD** | **`.mdd`** | **`@entro314labs/mdd`** |
|
|
466
|
+
| Knowledge base + business docs | Anasa + MDD | `.md` + `.mdd` | Desktop app |
|
|
323
467
|
|
|
324
468
|
## Documentation
|
|
325
469
|
|
|
326
|
-
- **[COMPREHENSIVE-GUIDE.md](COMPREHENSIVE-GUIDE.md)** - Detailed technical guide
|
|
327
470
|
- **[content/guides/style-guide.md](content/guides/style-guide.md)** - Style specifications
|
|
471
|
+
- **[ESLINT_INTEGRATION.md](ESLINT_INTEGRATION.md)** - ESLint + MDX integration guide
|
|
328
472
|
|
|
329
473
|
## Tech Stack
|
|
330
474
|
|
|
@@ -332,10 +476,13 @@ pnpm run preview examples/invoice.mdd
|
|
|
332
476
|
- **Unified** - AST transformation
|
|
333
477
|
- **GFM** - GitHub Flavored Markdown
|
|
334
478
|
- **MDX** - JSX in markdown
|
|
479
|
+
- **MDC** - Markdown Components (Nuxt Content)
|
|
480
|
+
- **ESLint** - JavaScript/JSX linting in code blocks
|
|
335
481
|
|
|
336
482
|
## Contributing
|
|
337
483
|
|
|
338
484
|
This is an opinionated formatter with specific style decisions. Contributions should:
|
|
485
|
+
|
|
339
486
|
- Maintain existing formatting rules
|
|
340
487
|
- Add value for developer documentation
|
|
341
488
|
- Not break existing lint rules
|
package/cli.js
CHANGED
|
@@ -17,8 +17,9 @@ import remarkStringify from 'remark-stringify';
|
|
|
17
17
|
import fs from 'fs/promises';
|
|
18
18
|
import path from 'path';
|
|
19
19
|
import { glob } from 'glob';
|
|
20
|
+
import { execSync } from 'child_process';
|
|
20
21
|
|
|
21
|
-
const MARKDOWN_EXTENSIONS = ['md', 'mdx', 'mdd'];
|
|
22
|
+
const MARKDOWN_EXTENSIONS = ['md', 'mdx', 'mdc', 'mdd'];
|
|
22
23
|
|
|
23
24
|
// Import configuration from .remarkrc.js
|
|
24
25
|
let remarkConfig;
|
|
@@ -44,6 +45,7 @@ COMMANDS:
|
|
|
44
45
|
format [files] Format markdown files (writes changes)
|
|
45
46
|
check [files] Check formatting without writing changes
|
|
46
47
|
lint [files] Lint markdown files (no formatting)
|
|
48
|
+
nuclear [files] 🚀 Run ALL linters and fixers (remark + ESLint)
|
|
47
49
|
init Create .remarkrc.js configuration file
|
|
48
50
|
setup Create example content structure
|
|
49
51
|
|
|
@@ -52,6 +54,7 @@ OPTIONS:
|
|
|
52
54
|
--version, -v Show version number
|
|
53
55
|
--quiet, -q Suppress output except errors
|
|
54
56
|
--glob <pattern> Use glob pattern (e.g., "**/*.md")
|
|
57
|
+
--nuclear Run complete lint+fix workflow (alias for nuclear command)
|
|
55
58
|
|
|
56
59
|
EXAMPLES:
|
|
57
60
|
# Format all markdown files in current directory
|
|
@@ -66,9 +69,22 @@ EXAMPLES:
|
|
|
66
69
|
# Format quietly
|
|
67
70
|
markdownfix format --quiet
|
|
68
71
|
|
|
72
|
+
# 🚀 Nuclear option - fix EVERYTHING
|
|
73
|
+
markdownfix nuclear
|
|
74
|
+
markdownfix format --nuclear
|
|
75
|
+
|
|
69
76
|
# Initialize configuration
|
|
70
77
|
markdownfix init
|
|
71
78
|
|
|
79
|
+
NUCLEAR MODE:
|
|
80
|
+
The nuclear command runs a comprehensive fix workflow:
|
|
81
|
+
1. Remark formatting (auto-fix markdown syntax)
|
|
82
|
+
2. Remark linting (validate markdown rules)
|
|
83
|
+
3. ESLint auto-fix (fix JavaScript in code blocks)
|
|
84
|
+
4. ESLint linting (validate code quality)
|
|
85
|
+
|
|
86
|
+
Perfect for: CI/CD, pre-commit hooks, major cleanups
|
|
87
|
+
|
|
72
88
|
For more information, visit: https://github.com/entro314-labs/markdownfix
|
|
73
89
|
`);
|
|
74
90
|
}
|
|
@@ -168,6 +184,145 @@ async function processFiles(files, options = {}) {
|
|
|
168
184
|
return { hasErrors, processedCount, totalFiles: files.length };
|
|
169
185
|
}
|
|
170
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Run nuclear mode - comprehensive fix workflow
|
|
189
|
+
* Executes: remark format -> remark lint -> eslint fix -> eslint lint
|
|
190
|
+
*/
|
|
191
|
+
async function runNuclearMode(files, options = {}) {
|
|
192
|
+
const { quiet = false } = options;
|
|
193
|
+
const hasEslint = await checkEslintAvailable();
|
|
194
|
+
|
|
195
|
+
if (!quiet) {
|
|
196
|
+
console.log('\n🚀 NUCLEAR MODE ACTIVATED\n');
|
|
197
|
+
console.log(`Processing ${files.length} file(s) with comprehensive workflow...\n`);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
let overallSuccess = true;
|
|
201
|
+
const steps = [];
|
|
202
|
+
|
|
203
|
+
// Step 1: Remark formatting
|
|
204
|
+
if (!quiet) console.log('Step 1/4: Running remark formatting...');
|
|
205
|
+
try {
|
|
206
|
+
const result = await processFiles(files, { write: true, quiet: true });
|
|
207
|
+
steps.push({
|
|
208
|
+
name: 'Remark Format',
|
|
209
|
+
success: !result.hasErrors,
|
|
210
|
+
details: `Formatted ${result.processedCount}/${result.totalFiles} files`
|
|
211
|
+
});
|
|
212
|
+
if (result.hasErrors) overallSuccess = false;
|
|
213
|
+
if (!quiet) console.log(` ✓ Remark formatting completed\n`);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
steps.push({ name: 'Remark Format', success: false, details: error.message });
|
|
216
|
+
overallSuccess = false;
|
|
217
|
+
if (!quiet) console.log(` ✗ Remark formatting failed: ${error.message}\n`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Step 2: Remark linting
|
|
221
|
+
if (!quiet) console.log('Step 2/4: Running remark linting...');
|
|
222
|
+
try {
|
|
223
|
+
const result = await processFiles(files, { lintOnly: true, quiet: true });
|
|
224
|
+
steps.push({
|
|
225
|
+
name: 'Remark Lint',
|
|
226
|
+
success: !result.hasErrors,
|
|
227
|
+
details: `Linted ${result.totalFiles} files`
|
|
228
|
+
});
|
|
229
|
+
if (result.hasErrors) {
|
|
230
|
+
if (!quiet) console.log(' ⚠️ Remark linting found issues (check output above)\n');
|
|
231
|
+
overallSuccess = false;
|
|
232
|
+
} else {
|
|
233
|
+
if (!quiet) console.log(` ✓ Remark linting passed\n`);
|
|
234
|
+
}
|
|
235
|
+
} catch (error) {
|
|
236
|
+
steps.push({ name: 'Remark Lint', success: false, details: error.message });
|
|
237
|
+
overallSuccess = false;
|
|
238
|
+
if (!quiet) console.log(` ✗ Remark linting failed: ${error.message}\n`);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Step 3 & 4: ESLint (only if available)
|
|
242
|
+
if (hasEslint) {
|
|
243
|
+
// Step 3: ESLint auto-fix
|
|
244
|
+
if (!quiet) console.log('Step 3/4: Running ESLint auto-fix...');
|
|
245
|
+
try {
|
|
246
|
+
const fileList = files.join(' ');
|
|
247
|
+
const eslintCmd = `npx eslint --ext .md,.mdx,.mdc,.mdd --fix ${fileList}`;
|
|
248
|
+
|
|
249
|
+
try {
|
|
250
|
+
execSync(eslintCmd, {
|
|
251
|
+
stdio: quiet ? 'pipe' : 'inherit',
|
|
252
|
+
cwd: process.cwd()
|
|
253
|
+
});
|
|
254
|
+
steps.push({ name: 'ESLint Fix', success: true, details: 'Auto-fixed code blocks' });
|
|
255
|
+
if (!quiet) console.log(` ✓ ESLint auto-fix completed\n`);
|
|
256
|
+
} catch (eslintError) {
|
|
257
|
+
// ESLint returns non-zero even if it fixes issues
|
|
258
|
+
steps.push({ name: 'ESLint Fix', success: false, details: 'Some issues could not be auto-fixed' });
|
|
259
|
+
if (!quiet) console.log(` ⚠️ ESLint auto-fix completed with warnings\n`);
|
|
260
|
+
}
|
|
261
|
+
} catch (error) {
|
|
262
|
+
steps.push({ name: 'ESLint Fix', success: false, details: error.message });
|
|
263
|
+
if (!quiet) console.log(` ✗ ESLint auto-fix failed: ${error.message}\n`);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Step 4: ESLint linting
|
|
267
|
+
if (!quiet) console.log('Step 4/4: Running ESLint linting...');
|
|
268
|
+
try {
|
|
269
|
+
const fileList = files.join(' ');
|
|
270
|
+
const eslintCmd = `npx eslint --ext .md,.mdx,.mdc,.mdd ${fileList}`;
|
|
271
|
+
|
|
272
|
+
execSync(eslintCmd, {
|
|
273
|
+
stdio: quiet ? 'pipe' : 'inherit',
|
|
274
|
+
cwd: process.cwd()
|
|
275
|
+
});
|
|
276
|
+
steps.push({ name: 'ESLint Lint', success: true, details: 'All code blocks valid' });
|
|
277
|
+
if (!quiet) console.log(` ✓ ESLint linting passed\n`);
|
|
278
|
+
} catch (eslintError) {
|
|
279
|
+
steps.push({ name: 'ESLint Lint', success: false, details: 'Linting issues found' });
|
|
280
|
+
overallSuccess = false;
|
|
281
|
+
if (!quiet) console.log(` ⚠️ ESLint linting found issues\n`);
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
if (!quiet) {
|
|
285
|
+
console.log('Step 3/4: Skipping ESLint (not installed)');
|
|
286
|
+
console.log(' ℹ️ Install ESLint with: npm install -D eslint eslint-plugin-mdx\n');
|
|
287
|
+
console.log('Step 4/4: Skipping ESLint linting\n');
|
|
288
|
+
}
|
|
289
|
+
steps.push({ name: 'ESLint Fix', success: true, details: 'Skipped (not installed)' });
|
|
290
|
+
steps.push({ name: 'ESLint Lint', success: true, details: 'Skipped (not installed)' });
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Summary
|
|
294
|
+
if (!quiet) {
|
|
295
|
+
console.log('═'.repeat(60));
|
|
296
|
+
console.log('NUCLEAR MODE SUMMARY');
|
|
297
|
+
console.log('═'.repeat(60));
|
|
298
|
+
steps.forEach(step => {
|
|
299
|
+
const icon = step.success ? '✓' : '✗';
|
|
300
|
+
const status = step.success ? 'PASS' : 'FAIL';
|
|
301
|
+
console.log(`${icon} ${step.name.padEnd(20)} ${status.padEnd(6)} ${step.details}`);
|
|
302
|
+
});
|
|
303
|
+
console.log('═'.repeat(60));
|
|
304
|
+
if (overallSuccess) {
|
|
305
|
+
console.log('🎉 All checks passed! Your markdown is pristine.\n');
|
|
306
|
+
} else {
|
|
307
|
+
console.log('⚠️ Some issues remain. Review the output above.\n');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return { success: overallSuccess, steps };
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Check if ESLint is available in the project
|
|
316
|
+
*/
|
|
317
|
+
async function checkEslintAvailable() {
|
|
318
|
+
try {
|
|
319
|
+
execSync('npx eslint --version', { stdio: 'pipe' });
|
|
320
|
+
return true;
|
|
321
|
+
} catch {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
171
326
|
/**
|
|
172
327
|
* Initialize .remarkrc.js configuration
|
|
173
328
|
*/
|
|
@@ -250,6 +405,7 @@ async function main() {
|
|
|
250
405
|
// Parse options
|
|
251
406
|
const options = {
|
|
252
407
|
quiet: commandArgs.includes('--quiet') || commandArgs.includes('-q'),
|
|
408
|
+
nuclear: commandArgs.includes('--nuclear'),
|
|
253
409
|
glob: null
|
|
254
410
|
};
|
|
255
411
|
|
|
@@ -274,6 +430,14 @@ async function main() {
|
|
|
274
430
|
console.log('No markdown files found');
|
|
275
431
|
return;
|
|
276
432
|
}
|
|
433
|
+
|
|
434
|
+
// Check for --nuclear flag
|
|
435
|
+
if (options.nuclear) {
|
|
436
|
+
const result = await runNuclearMode(files, { quiet: options.quiet });
|
|
437
|
+
process.exit(result.success ? 0 : 1);
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
|
|
277
441
|
if (!options.quiet) {
|
|
278
442
|
console.log(`Formatting ${files.length} file(s)...`);
|
|
279
443
|
}
|
|
@@ -331,6 +495,17 @@ async function main() {
|
|
|
331
495
|
break;
|
|
332
496
|
}
|
|
333
497
|
|
|
498
|
+
case 'nuclear': {
|
|
499
|
+
const files = await getFiles(fileArgs, options.glob);
|
|
500
|
+
if (files.length === 0) {
|
|
501
|
+
console.log('No markdown files found');
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
const result = await runNuclearMode(files, { quiet: options.quiet });
|
|
505
|
+
process.exit(result.success ? 0 : 1);
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
508
|
+
|
|
334
509
|
default:
|
|
335
510
|
console.error(`Unknown command: ${command}`);
|
|
336
511
|
console.error('Run "markdownfix --help" for usage information');
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint configuration for MDX files
|
|
3
|
+
* Uses eslint-plugin-mdx with existing remark-lint configuration
|
|
4
|
+
*
|
|
5
|
+
* This integrates with the existing .remarkrc.js file to provide:
|
|
6
|
+
* - JSX/JavaScript linting inside MDX code blocks
|
|
7
|
+
* - IDE integration for better developer experience
|
|
8
|
+
* - Unified linting workflow alongside remark-lint
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import * as mdxPlugin from 'eslint-plugin-mdx';
|
|
12
|
+
|
|
13
|
+
export default [
|
|
14
|
+
{
|
|
15
|
+
// Ignore common directories
|
|
16
|
+
// Replaces .eslintignore file (no longer supported in ESLint 9)
|
|
17
|
+
ignores: [
|
|
18
|
+
'node_modules/**',
|
|
19
|
+
'dist/**',
|
|
20
|
+
'build/**',
|
|
21
|
+
'.next/**',
|
|
22
|
+
'coverage/**',
|
|
23
|
+
'pnpm-lock.yaml',
|
|
24
|
+
'**/*.config.js',
|
|
25
|
+
'**/*.config.mjs',
|
|
26
|
+
'README.md',
|
|
27
|
+
'CHANGELOG.md',
|
|
28
|
+
'LICENSE',
|
|
29
|
+
'PUBLISHING.md',
|
|
30
|
+
'ESLINT_INTEGRATION.md',
|
|
31
|
+
'.cache/**',
|
|
32
|
+
'.remark-cache/**'
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
// MDX/MDC files configuration
|
|
37
|
+
{
|
|
38
|
+
name: 'custom/mdx/recommended',
|
|
39
|
+
files: ['**/*.{md,mdx,mdc,mdd}'],
|
|
40
|
+
...mdxPlugin.flat,
|
|
41
|
+
processor: mdxPlugin.createRemarkProcessor({
|
|
42
|
+
lintCodeBlocks: true, // Enable linting of code blocks
|
|
43
|
+
languageMapper: {} // Use default language mappings
|
|
44
|
+
}),
|
|
45
|
+
rules: {
|
|
46
|
+
// MDX-specific rules from eslint-plugin-mdx
|
|
47
|
+
// The remark-lint rules from .remarkrc.js will be automatically used
|
|
48
|
+
'mdx/remark': 'error',
|
|
49
|
+
},
|
|
50
|
+
settings: {
|
|
51
|
+
'mdx/code-blocks': true, // Enable code block linting
|
|
52
|
+
'mdx/language-mapper': {} // Use default mappings
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
// Code blocks in MDX/MDC (optional - for stricter linting)
|
|
57
|
+
{
|
|
58
|
+
name: 'custom/mdx/code-blocks',
|
|
59
|
+
files: ['**/*.{md,mdx,mdc,mdd}'],
|
|
60
|
+
...mdxPlugin.flatCodeBlocks,
|
|
61
|
+
languageOptions: {
|
|
62
|
+
globals: {
|
|
63
|
+
console: 'readonly',
|
|
64
|
+
process: 'readonly',
|
|
65
|
+
require: 'readonly',
|
|
66
|
+
module: 'readonly',
|
|
67
|
+
exports: 'readonly',
|
|
68
|
+
__dirname: 'readonly',
|
|
69
|
+
__filename: 'readonly',
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
rules: {
|
|
73
|
+
...mdxPlugin.flatCodeBlocks.rules,
|
|
74
|
+
// Add JavaScript rules for code blocks
|
|
75
|
+
'no-var': 'error',
|
|
76
|
+
'prefer-const': 'error',
|
|
77
|
+
'no-unused-vars': 'warn',
|
|
78
|
+
// Allow common globals in documentation examples
|
|
79
|
+
'no-undef': 'off',
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entro314labs/markdownfix",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Opinionated markdown formatter and linter for MD,
|
|
3
|
+
"version": "0.0.10",
|
|
4
|
+
"description": "Opinionated markdown formatter and linter for MD, MDX, MDC, and MDD files using Remark/Unified ecosystem",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -14,9 +14,11 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
".remarkrc.js",
|
|
16
16
|
".remarkignore",
|
|
17
|
+
"eslint.config.js",
|
|
17
18
|
"setup.js",
|
|
18
19
|
"cli.js",
|
|
19
20
|
"README.md",
|
|
21
|
+
"ESLINT_INTEGRATION.md",
|
|
20
22
|
"LICENSE"
|
|
21
23
|
],
|
|
22
24
|
"bin": {
|
|
@@ -27,6 +29,7 @@
|
|
|
27
29
|
"keywords": [
|
|
28
30
|
"markdown",
|
|
29
31
|
"mdx",
|
|
32
|
+
"mdc",
|
|
30
33
|
"mdd",
|
|
31
34
|
"linter",
|
|
32
35
|
"formatter",
|
|
@@ -35,11 +38,16 @@
|
|
|
35
38
|
"unified",
|
|
36
39
|
"markdownfix",
|
|
37
40
|
"markdown-linter",
|
|
41
|
+
"markdown-components",
|
|
42
|
+
"nuxt-content",
|
|
38
43
|
"opinionated"
|
|
39
44
|
],
|
|
40
45
|
"author": "Dominikos Pritis",
|
|
41
46
|
"license": "MIT",
|
|
42
47
|
"devDependencies": {
|
|
48
|
+
"eslint": "^9.38.0",
|
|
49
|
+
"eslint-plugin-mdx": "^3.6.2",
|
|
50
|
+
"eslint-plugin-react": "^7.37.5",
|
|
43
51
|
"markdown-link-check": "^3.14.1",
|
|
44
52
|
"remark-cli": "^12.0.1"
|
|
45
53
|
},
|
|
@@ -49,7 +57,7 @@
|
|
|
49
57
|
"dependencies": {
|
|
50
58
|
"@adobe/remark-gridtables": "^3.0.15",
|
|
51
59
|
"@code-dot-org/remark-plugins": "^2.0.0",
|
|
52
|
-
"@entro314labs/mdd": "^0.0.
|
|
60
|
+
"@entro314labs/remark-mdd": "^0.0.10",
|
|
53
61
|
"@theguild/remark-mermaid": "^0.3.0",
|
|
54
62
|
"fumadocs-docgen": "^3.0.2",
|
|
55
63
|
"glob": "^11.0.3",
|
|
@@ -118,11 +126,15 @@
|
|
|
118
126
|
},
|
|
119
127
|
"scripts": {
|
|
120
128
|
"lint": "remark . --quiet --frail",
|
|
129
|
+
"lint:eslint": "eslint --ext .md,.mdx,.mdc,.mdd .",
|
|
130
|
+
"lint:eslint:fix": "eslint --ext .md,.mdx,.mdc,.mdd --fix .",
|
|
131
|
+
"lint:all": "pnpm run lint && pnpm run lint:eslint",
|
|
121
132
|
"format": "remark . --output --quiet",
|
|
122
133
|
"format:check": "remark . --quiet",
|
|
123
|
-
"check-links": "markdown-link-check **/*.{md,mdx,mdd}",
|
|
124
|
-
"process": "pnpm run format && pnpm run lint",
|
|
125
|
-
"process:safe": "pnpm run format:check && pnpm run lint",
|
|
134
|
+
"check-links": "markdown-link-check **/*.{md,mdx,mdc,mdd}",
|
|
135
|
+
"process": "pnpm run format && pnpm run lint:all",
|
|
136
|
+
"process:safe": "pnpm run format:check && pnpm run lint:all",
|
|
137
|
+
"nuclear": "node cli.js nuclear",
|
|
126
138
|
"clean-cache": "rm -rf .remark-cache",
|
|
127
139
|
"test": "pnpm run process:safe"
|
|
128
140
|
}
|