@entro314labs/markdownfix 0.0.7 → 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 CHANGED
@@ -56,4 +56,6 @@ coverage/
56
56
  # Specific files to ignore
57
57
  CHANGELOG.md
58
58
  LICENSE
59
- README.md
59
+ README.md
60
+ PUBLISHING.md
61
+ ESLINT_INTEGRATION.md
package/.remarkrc.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Opinionated Remark configuration for markdown processing
3
- * Supports .md, and .mdx files with consistent formatting
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 .mdx
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
 
@@ -76,8 +79,6 @@ export default {
76
79
  ['remark-lint-final-newline', true],
77
80
  ['remark-lint-hard-break-spaces', true],
78
81
  ['remark-lint-no-empty-sections', true],
79
- // Allow .md, .mdx, and .mdd file extensions
80
- ['remark-lint-file-extension', ['md', 'mdx', 'mdd']],
81
82
 
82
83
  // Must be last - handles the output formatting
83
84
  'remark-stringify'
@@ -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`, `.mdd`, and `.mdx` files**
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
- - ✅ **Comprehensive linting** - 40+ lint rules for quality and consistency
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
  ```
@@ -103,8 +110,43 @@ markdownfix setup
103
110
  | --------- | ----------- | --------------------------------------- | ------------------------------- |
104
111
  | `.md` | ✅ Full | GFM, frontmatter, tables, task lists | Documentation, READMEs, blogs |
105
112
  | `.mdx` | ✅ Full | Above + JSX components, imports/exports | React docs, interactive content |
113
+ | `.mdc` | ✅ Full | Markdown Components (Nuxt Content) | Nuxt Content, Vue documentation |
106
114
  | `.mdd` | ⚠️ Optional | Business documents (see below) | Invoices, proposals, contracts |
107
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
149
+
108
150
  ### MDD Support
109
151
 
110
152
  This formatter can **optionally** format `.mdd` files if you install the [MDD package](https://www.npmjs.com/package/@entro314labs/mdd):
@@ -127,10 +169,74 @@ pnpm run format
127
169
  markdownfix format [files...] # Format and fix markdown files
128
170
  markdownfix check [files...] # Check without writing changes
129
171
  markdownfix lint [files...] # Lint for issues only
172
+ markdownfix nuclear [files...] # 🚀 Run ALL linters and fixers
130
173
  markdownfix init # Create .remarkrc.js config
131
174
  markdownfix setup # Create example content structure
132
175
  ```
133
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
+
134
240
  ### Command Aliases
135
241
 
136
242
  The CLI is available via two commands:
@@ -182,11 +288,15 @@ pnpm run format # Apply fixes using remark-cli
182
288
  pnpm run format:check # Preview changes
183
289
 
184
290
  # Linting
185
- pnpm run lint # Check compliance
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
186
295
 
187
296
  # Combined
188
- pnpm run process # Format then lint
189
- pnpm run process:safe # Dry-run first, then process
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
190
300
  pnpm test # Same as process:safe
191
301
 
192
302
  # Utilities
@@ -358,6 +468,7 @@ Desktop knowledge management application with MDD integration:
358
468
  ## Documentation
359
469
 
360
470
  - **[content/guides/style-guide.md](content/guides/style-guide.md)** - Style specifications
471
+ - **[ESLINT_INTEGRATION.md](ESLINT_INTEGRATION.md)** - ESLint + MDX integration guide
361
472
 
362
473
  ## Tech Stack
363
474
 
@@ -365,6 +476,8 @@ Desktop knowledge management application with MDD integration:
365
476
  - **Unified** - AST transformation
366
477
  - **GFM** - GitHub Flavored Markdown
367
478
  - **MDX** - JSX in markdown
479
+ - **MDC** - Markdown Components (Nuxt Content)
480
+ - **ESLint** - JavaScript/JSX linting in code blocks
368
481
 
369
482
  ## Contributing
370
483
 
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');
@@ -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.7",
4
- "description": "Opinionated markdown formatter and linter for MD, MDD and MDX files using Remark/Unified ecosystem",
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.7",
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
  }