@entro314labs/markdownfix 0.0.16 ā 0.0.21
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/.remarkrc.js +1 -0
- package/ESLINT_INTEGRATION.md +1 -1
- package/README.md +53 -17
- package/cli.js +180 -77
- package/package.json +8 -8
package/.remarkrc.js
CHANGED
|
@@ -42,6 +42,7 @@ export default {
|
|
|
42
42
|
setext: false, // Use # instead of === underlines
|
|
43
43
|
tightDefinitions: true, // No blank lines between definitions
|
|
44
44
|
resourceLink: false, // Don't escape link URLs unnecessarily
|
|
45
|
+
break: 'spaces', // Use two spaces for line breaks instead of backslashes
|
|
45
46
|
},
|
|
46
47
|
|
|
47
48
|
plugins: [
|
package/ESLINT_INTEGRATION.md
CHANGED
package/README.md
CHANGED
|
@@ -179,12 +179,11 @@ markdownfix setup # Create example content structure
|
|
|
179
179
|
|
|
180
180
|
### š Nuclear Mode
|
|
181
181
|
|
|
182
|
-
The `nuclear` command runs a comprehensive
|
|
182
|
+
The `nuclear` command runs a comprehensive 3-step workflow that applies **all** available linters and fixers:
|
|
183
183
|
|
|
184
184
|
1. **Remark Formatting** - Auto-fix markdown syntax
|
|
185
|
-
2. **
|
|
186
|
-
3. **
|
|
187
|
-
4. **ESLint Linting** - Validate code quality
|
|
185
|
+
2. **ESLint Auto-fix** - Fix JavaScript/JSX in code blocks
|
|
186
|
+
3. **Final Validation** - Report any remaining issues
|
|
188
187
|
|
|
189
188
|
**Perfect for:**
|
|
190
189
|
|
|
@@ -210,36 +209,73 @@ markdownfix nuclear --glob "docs/**/*.{md,mdx}"
|
|
|
210
209
|
}
|
|
211
210
|
```
|
|
212
211
|
|
|
213
|
-
**Example Output:**
|
|
212
|
+
**Example Output (Success):**
|
|
214
213
|
|
|
215
214
|
```
|
|
216
215
|
š NUCLEAR MODE ACTIVATED
|
|
217
216
|
|
|
218
217
|
Processing 15 file(s) with comprehensive workflow...
|
|
219
218
|
|
|
220
|
-
Step 1/
|
|
221
|
-
ā
|
|
219
|
+
Step 1/3: Running remark formatting...
|
|
220
|
+
ā Formatted 15 file(s)
|
|
222
221
|
|
|
223
|
-
Step 2/
|
|
224
|
-
ā Remark linting passed
|
|
225
|
-
|
|
226
|
-
Step 3/4: Running ESLint auto-fix...
|
|
222
|
+
Step 2/3: Running ESLint auto-fix on code blocks...
|
|
227
223
|
ā ESLint auto-fix completed
|
|
228
224
|
|
|
229
|
-
Step
|
|
230
|
-
ā
|
|
225
|
+
Step 3/3: Running final validation...
|
|
226
|
+
ā All validation checks passed
|
|
231
227
|
|
|
232
228
|
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
233
229
|
NUCLEAR MODE SUMMARY
|
|
234
230
|
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
235
|
-
ā Remark Format PASS
|
|
236
|
-
ā
|
|
237
|
-
ā
|
|
238
|
-
ā ESLint Lint PASS All code blocks valid
|
|
231
|
+
ā Remark Format PASS Formatted 15/15 files
|
|
232
|
+
ā ESLint Fix PASS Fixed code blocks
|
|
233
|
+
ā Validation PASS All checks passed
|
|
239
234
|
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
240
235
|
š All checks passed! Your markdown is pristine.
|
|
241
236
|
```
|
|
242
237
|
|
|
238
|
+
**Example Output (Issues Found):**
|
|
239
|
+
|
|
240
|
+
````
|
|
241
|
+
š NUCLEAR MODE ACTIVATED
|
|
242
|
+
|
|
243
|
+
Processing 8 file(s) with comprehensive workflow...
|
|
244
|
+
|
|
245
|
+
Step 1/3: Running remark formatting...
|
|
246
|
+
ā Formatted 8 file(s)
|
|
247
|
+
ā¹ļø Some issues require manual fixes
|
|
248
|
+
|
|
249
|
+
Step 2/3: Running ESLint auto-fix on code blocks...
|
|
250
|
+
ā ļø ESLint found issues that need manual fixes
|
|
251
|
+
|
|
252
|
+
Step 3/3: Running final validation...
|
|
253
|
+
ā ļø Validation found remaining issues
|
|
254
|
+
|
|
255
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
256
|
+
REMAINING ISSUES
|
|
257
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
258
|
+
file.md
|
|
259
|
+
3:128 error Line too long (max 80 chars)
|
|
260
|
+
17:1 error Missing code block language flag
|
|
261
|
+
|
|
262
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
263
|
+
NUCLEAR MODE SUMMARY
|
|
264
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
265
|
+
ā Remark Format PASS Formatted 8/8 files
|
|
266
|
+
ā ļø ESLint Fix NEEDS ATTENTION Some issues remain
|
|
267
|
+
ā ļø Validation NEEDS ATTENTION Issues found
|
|
268
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
269
|
+
|
|
270
|
+
š NEXT STEPS:
|
|
271
|
+
Review the issues above and fix them manually.
|
|
272
|
+
Common fixes:
|
|
273
|
+
⢠Shorten long lines (max 80 chars)
|
|
274
|
+
⢠Add language flags to code blocks (```js, ```bash, etc.)
|
|
275
|
+
⢠Fix filename issues (use lowercase, avoid special chars)
|
|
276
|
+
⢠Add blank lines between list items
|
|
277
|
+
````
|
|
278
|
+
|
|
243
279
|
### Command Aliases
|
|
244
280
|
|
|
245
281
|
The CLI is available via two commands:
|
package/cli.js
CHANGED
|
@@ -22,15 +22,28 @@ import { execSync } from 'child_process';
|
|
|
22
22
|
const MARKDOWN_EXTENSIONS = ['md', 'mdx', 'mdc', 'mdd'];
|
|
23
23
|
|
|
24
24
|
// Import configuration from .remarkrc.js
|
|
25
|
+
// Suppress console output during import to avoid MDD warnings in nuclear mode
|
|
26
|
+
const originalLog = console.log;
|
|
27
|
+
const originalInfo = console.info;
|
|
28
|
+
console.log = () => {};
|
|
29
|
+
console.info = () => {};
|
|
30
|
+
|
|
25
31
|
let remarkConfig;
|
|
26
32
|
try {
|
|
27
33
|
const configModule = await import(path.join(process.cwd(), '.remarkrc.js'));
|
|
28
34
|
remarkConfig = configModule.default;
|
|
29
35
|
} catch (e) {
|
|
36
|
+
// Restore console before warning
|
|
37
|
+
console.log = originalLog;
|
|
38
|
+
console.info = originalInfo;
|
|
30
39
|
console.warn('ā ļø No .remarkrc.js found in current directory, using default config');
|
|
31
40
|
remarkConfig = null;
|
|
32
41
|
}
|
|
33
42
|
|
|
43
|
+
// Restore console
|
|
44
|
+
console.log = originalLog;
|
|
45
|
+
console.info = originalInfo;
|
|
46
|
+
|
|
34
47
|
/**
|
|
35
48
|
* Show help text
|
|
36
49
|
*/
|
|
@@ -79,9 +92,8 @@ EXAMPLES:
|
|
|
79
92
|
NUCLEAR MODE:
|
|
80
93
|
The nuclear command runs a comprehensive fix workflow:
|
|
81
94
|
1. Remark formatting (auto-fix markdown syntax)
|
|
82
|
-
2.
|
|
83
|
-
3.
|
|
84
|
-
4. ESLint linting (validate code quality)
|
|
95
|
+
2. ESLint auto-fix (fix JavaScript/JSX in code blocks)
|
|
96
|
+
3. Final validation (report remaining issues)
|
|
85
97
|
|
|
86
98
|
Perfect for: CI/CD, pre-commit hooks, major cleanups
|
|
87
99
|
|
|
@@ -148,7 +160,11 @@ async function processFiles(files, options = {}) {
|
|
|
148
160
|
listItemIndent: 'one',
|
|
149
161
|
rule: '-',
|
|
150
162
|
strong: '*',
|
|
151
|
-
tightDefinitions: true
|
|
163
|
+
tightDefinitions: true,
|
|
164
|
+
handlers: {
|
|
165
|
+
// Custom handler to use two spaces for line breaks instead of backslashes
|
|
166
|
+
break: () => ' \n'
|
|
167
|
+
}
|
|
152
168
|
});
|
|
153
169
|
}
|
|
154
170
|
|
|
@@ -188,34 +204,53 @@ async function processFiles(files, options = {}) {
|
|
|
188
204
|
|
|
189
205
|
/**
|
|
190
206
|
* Run nuclear mode - comprehensive fix workflow
|
|
191
|
-
* Executes: remark format ->
|
|
207
|
+
* Executes: remark format -> eslint fix -> final validation
|
|
192
208
|
*/
|
|
193
209
|
async function runNuclearMode(files, options = {}) {
|
|
194
210
|
const { quiet = false } = options;
|
|
195
211
|
const hasEslint = await checkEslintAvailable();
|
|
196
212
|
|
|
213
|
+
// Filter out ESLint-ignored files in nuclear mode
|
|
214
|
+
let filteredFiles = files;
|
|
215
|
+
let ignoredCount = 0;
|
|
216
|
+
if (hasEslint) {
|
|
217
|
+
const ignorePatterns = await getEslintIgnorePatterns();
|
|
218
|
+
const originalCount = files.length;
|
|
219
|
+
filteredFiles = files.filter(file => !isFileIgnored(file, ignorePatterns));
|
|
220
|
+
ignoredCount = originalCount - filteredFiles.length;
|
|
221
|
+
}
|
|
222
|
+
|
|
197
223
|
if (!quiet) {
|
|
198
224
|
console.log('\nš NUCLEAR MODE ACTIVATED\n');
|
|
199
|
-
|
|
225
|
+
if (ignoredCount > 0) {
|
|
226
|
+
console.log(`Found ${files.length} file(s), processing ${filteredFiles.length} (${ignoredCount} ignored by ESLint config)\n`);
|
|
227
|
+
} else {
|
|
228
|
+
console.log(`Processing ${filteredFiles.length} file(s) with comprehensive workflow...\n`);
|
|
229
|
+
}
|
|
200
230
|
}
|
|
201
231
|
|
|
202
232
|
let overallSuccess = true;
|
|
203
233
|
const steps = [];
|
|
234
|
+
let remarkIssues = [];
|
|
235
|
+
let eslintIssues = [];
|
|
204
236
|
|
|
205
|
-
// Step 1: Remark formatting
|
|
206
|
-
if (!quiet) console.log('Step 1/
|
|
237
|
+
// Step 1: Remark formatting (auto-fixes what it can)
|
|
238
|
+
if (!quiet) console.log('Step 1/3: Running remark formatting...');
|
|
207
239
|
try {
|
|
208
|
-
const result = await processFiles(
|
|
240
|
+
const result = await processFiles(filteredFiles, { write: true, quiet: true });
|
|
241
|
+
const formatted = result.processedCount;
|
|
242
|
+
const withIssues = result.hasErrors;
|
|
243
|
+
|
|
209
244
|
steps.push({
|
|
210
245
|
name: 'Remark Format',
|
|
211
|
-
success:
|
|
212
|
-
details: `
|
|
246
|
+
success: formatted > 0,
|
|
247
|
+
details: `Formatted ${formatted}/${result.totalFiles} files`
|
|
213
248
|
});
|
|
214
|
-
|
|
249
|
+
|
|
215
250
|
if (!quiet) {
|
|
216
|
-
console.log(` ā
|
|
217
|
-
if (
|
|
218
|
-
console.log(`
|
|
251
|
+
console.log(` ā Formatted ${formatted} file(s)`);
|
|
252
|
+
if (withIssues) {
|
|
253
|
+
console.log(` ā¹ļø Some issues require manual fixes\n`);
|
|
219
254
|
} else {
|
|
220
255
|
console.log();
|
|
221
256
|
}
|
|
@@ -226,87 +261,94 @@ async function runNuclearMode(files, options = {}) {
|
|
|
226
261
|
if (!quiet) console.log(` ā Remark formatting failed: ${error.message}\n`);
|
|
227
262
|
}
|
|
228
263
|
|
|
229
|
-
// Step 2: Remark linting
|
|
230
|
-
if (!quiet) console.log('Step 2/4: Running remark linting...');
|
|
231
|
-
try {
|
|
232
|
-
const result = await processFiles(files, { lintOnly: true, quiet: true });
|
|
233
|
-
steps.push({
|
|
234
|
-
name: 'Remark Lint',
|
|
235
|
-
success: !result.hasErrors,
|
|
236
|
-
details: `Linted ${result.totalFiles} files`
|
|
237
|
-
});
|
|
238
|
-
if (result.hasErrors) {
|
|
239
|
-
if (!quiet) console.log(' ā ļø Remark linting found issues (check output above)\n');
|
|
240
|
-
overallSuccess = false;
|
|
241
|
-
} else {
|
|
242
|
-
if (!quiet) console.log(` ā Remark linting passed\n`);
|
|
243
|
-
}
|
|
244
|
-
} catch (error) {
|
|
245
|
-
steps.push({ name: 'Remark Lint', success: false, details: error.message });
|
|
246
|
-
overallSuccess = false;
|
|
247
|
-
if (!quiet) console.log(` ā Remark linting failed: ${error.message}\n`);
|
|
248
|
-
}
|
|
249
264
|
|
|
250
|
-
// Step
|
|
265
|
+
// Step 2: ESLint auto-fix (only if ESLint is available)
|
|
251
266
|
if (hasEslint) {
|
|
252
267
|
const eslintConfigInfo = await getEslintConfigPath();
|
|
253
268
|
const { configPath, source } = eslintConfigInfo;
|
|
254
269
|
|
|
255
|
-
if (!quiet
|
|
256
|
-
console.log(' ā¹ļø Using bundled ESLint config (no local config found)\n');
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Step 3: ESLint auto-fix
|
|
260
|
-
if (!quiet) console.log('Step 3/4: Running ESLint auto-fix...');
|
|
270
|
+
if (!quiet) console.log('Step 2/3: Running ESLint auto-fix on code blocks...');
|
|
261
271
|
try {
|
|
262
|
-
|
|
263
|
-
const fileList = files.map(f => `"${f}"`).join(' ');
|
|
272
|
+
const fileList = filteredFiles.map(f => `"${f}"`).join(' ');
|
|
264
273
|
const eslintCmd = `npx eslint --config "${configPath}" --fix ${fileList}`;
|
|
265
274
|
|
|
266
275
|
try {
|
|
267
|
-
execSync(eslintCmd, {
|
|
268
|
-
stdio:
|
|
276
|
+
const result = execSync(eslintCmd, {
|
|
277
|
+
stdio: 'pipe',
|
|
269
278
|
cwd: process.cwd()
|
|
270
279
|
});
|
|
271
|
-
steps.push({ name: 'ESLint Fix', success: true, details: '
|
|
280
|
+
steps.push({ name: 'ESLint Fix', success: true, details: 'Fixed code blocks' });
|
|
272
281
|
if (!quiet) console.log(` ā ESLint auto-fix completed\n`);
|
|
273
282
|
} catch (eslintError) {
|
|
274
|
-
// ESLint returns non-zero
|
|
275
|
-
|
|
276
|
-
|
|
283
|
+
// ESLint returns non-zero if there are unfixable issues
|
|
284
|
+
const output = eslintError.stdout?.toString() || eslintError.stderr?.toString() || '';
|
|
285
|
+
|
|
286
|
+
// Filter out "File ignored" warnings - these are expected
|
|
287
|
+
const lines = output.split('\n').filter(line =>
|
|
288
|
+
!line.includes('File ignored because of a matching ignore pattern')
|
|
289
|
+
);
|
|
290
|
+
const filteredOutput = lines.join('\n');
|
|
291
|
+
|
|
292
|
+
const hasWarnings = filteredOutput.includes('warning');
|
|
293
|
+
const hasErrors = filteredOutput.includes('error');
|
|
294
|
+
|
|
295
|
+
if (hasErrors || hasWarnings) {
|
|
296
|
+
steps.push({ name: 'ESLint Fix', success: false, details: 'Some issues remain' });
|
|
297
|
+
if (!quiet) console.log(` ā ļø ESLint found issues that need manual fixes\n`);
|
|
298
|
+
} else {
|
|
299
|
+
steps.push({ name: 'ESLint Fix', success: true, details: 'Fixed code blocks' });
|
|
300
|
+
if (!quiet) console.log(` ā ESLint auto-fix completed\n`);
|
|
301
|
+
}
|
|
277
302
|
}
|
|
278
303
|
} catch (error) {
|
|
279
304
|
steps.push({ name: 'ESLint Fix', success: false, details: error.message });
|
|
280
305
|
if (!quiet) console.log(` ā ESLint auto-fix failed: ${error.message}\n`);
|
|
281
306
|
}
|
|
307
|
+
} else {
|
|
308
|
+
if (!quiet) {
|
|
309
|
+
console.log('Step 2/3: Skipping ESLint (not installed)');
|
|
310
|
+
console.log(' ā¹ļø Install with: npm install -D eslint eslint-plugin-mdx\n');
|
|
311
|
+
}
|
|
312
|
+
steps.push({ name: 'ESLint Fix', success: true, details: 'Skipped (not installed)' });
|
|
313
|
+
}
|
|
282
314
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
stdio: quiet ? 'pipe' : 'inherit',
|
|
292
|
-
cwd: process.cwd()
|
|
293
|
-
});
|
|
294
|
-
steps.push({ name: 'ESLint Lint', success: true, details: 'All code blocks valid' });
|
|
295
|
-
if (!quiet) console.log(` ā ESLint linting passed\n`);
|
|
296
|
-
} catch (eslintError) {
|
|
297
|
-
steps.push({ name: 'ESLint Lint', success: false, details: 'Linting issues found' });
|
|
315
|
+
// Step 3: Final validation
|
|
316
|
+
if (!quiet) console.log('Step 3/3: Running final validation...');
|
|
317
|
+
let validationResult;
|
|
318
|
+
try {
|
|
319
|
+
validationResult = await processFiles(filteredFiles, { lintOnly: true, quiet: true });
|
|
320
|
+
const hasIssues = validationResult.hasErrors;
|
|
321
|
+
|
|
322
|
+
if (hasIssues) {
|
|
298
323
|
overallSuccess = false;
|
|
299
|
-
if (!quiet) console.log(` ā ļø ESLint linting found issues\n`);
|
|
300
324
|
}
|
|
301
|
-
|
|
302
|
-
|
|
325
|
+
|
|
326
|
+
steps.push({
|
|
327
|
+
name: 'Validation',
|
|
328
|
+
success: !hasIssues,
|
|
329
|
+
details: hasIssues ? 'Issues found' : 'All checks passed'
|
|
330
|
+
});
|
|
331
|
+
|
|
303
332
|
if (!quiet) {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
333
|
+
if (hasIssues) {
|
|
334
|
+
console.log(` ā ļø Validation found remaining issues\n`);
|
|
335
|
+
} else {
|
|
336
|
+
console.log(` ā All validation checks passed\n`);
|
|
337
|
+
}
|
|
307
338
|
}
|
|
308
|
-
|
|
309
|
-
steps.push({ name: '
|
|
339
|
+
} catch (error) {
|
|
340
|
+
steps.push({ name: 'Validation', success: false, details: error.message });
|
|
341
|
+
overallSuccess = false;
|
|
342
|
+
if (!quiet) console.log(` ā Validation failed: ${error.message}\n`);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Show detailed issues if validation failed
|
|
346
|
+
if (!quiet && validationResult?.hasErrors) {
|
|
347
|
+
console.log('ā'.repeat(60));
|
|
348
|
+
console.log('REMAINING ISSUES');
|
|
349
|
+
console.log('ā'.repeat(60));
|
|
350
|
+
await processFiles(filteredFiles, { lintOnly: true, quiet: false });
|
|
351
|
+
console.log();
|
|
310
352
|
}
|
|
311
353
|
|
|
312
354
|
// Summary
|
|
@@ -315,15 +357,22 @@ async function runNuclearMode(files, options = {}) {
|
|
|
315
357
|
console.log('NUCLEAR MODE SUMMARY');
|
|
316
358
|
console.log('ā'.repeat(60));
|
|
317
359
|
steps.forEach(step => {
|
|
318
|
-
const icon = step.success ? 'ā' : '
|
|
319
|
-
const status = step.success ? 'PASS' : '
|
|
320
|
-
console.log(`${icon} ${step.name.padEnd(20)} ${status.padEnd(
|
|
360
|
+
const icon = step.success ? 'ā' : 'ā ļø';
|
|
361
|
+
const status = step.success ? 'PASS' : 'NEEDS ATTENTION';
|
|
362
|
+
console.log(`${icon} ${step.name.padEnd(20)} ${status.padEnd(16)} ${step.details}`);
|
|
321
363
|
});
|
|
322
364
|
console.log('ā'.repeat(60));
|
|
365
|
+
|
|
323
366
|
if (overallSuccess) {
|
|
324
367
|
console.log('š All checks passed! Your markdown is pristine.\n');
|
|
325
368
|
} else {
|
|
326
|
-
console.log('
|
|
369
|
+
console.log('\nš NEXT STEPS:');
|
|
370
|
+
console.log(' Review the issues above and fix them manually.');
|
|
371
|
+
console.log(' Common fixes:');
|
|
372
|
+
console.log(' ⢠Shorten long lines (max 80 chars)');
|
|
373
|
+
console.log(' ⢠Add language flags to code blocks (```js, ```bash, etc.)');
|
|
374
|
+
console.log(' ⢠Fix filename issues (use lowercase, avoid special chars)');
|
|
375
|
+
console.log(' ⢠Add blank lines between list items\n');
|
|
327
376
|
}
|
|
328
377
|
}
|
|
329
378
|
|
|
@@ -359,6 +408,60 @@ async function getEslintConfigPath() {
|
|
|
359
408
|
const bundledConfig = new URL('./eslint.config.js', import.meta.url).pathname;
|
|
360
409
|
return { configPath: bundledConfig, source: 'bundled' };
|
|
361
410
|
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Get ESLint ignore patterns from config
|
|
415
|
+
* Returns array of ignore patterns to filter files in nuclear mode
|
|
416
|
+
* Note: We parse the config file as text instead of importing it because
|
|
417
|
+
* the config has dependencies that require ESLint to be in the require cache
|
|
418
|
+
*/
|
|
419
|
+
async function getEslintIgnorePatterns() {
|
|
420
|
+
try {
|
|
421
|
+
const { configPath } = await getEslintConfigPath();
|
|
422
|
+
const configContent = await fs.readFile(configPath, 'utf-8');
|
|
423
|
+
|
|
424
|
+
// Extract the ignores array using regex
|
|
425
|
+
// Look for: ignores: [ ... ]
|
|
426
|
+
const ignoresMatch = configContent.match(/ignores:\s*\[([\s\S]*?)\]/);
|
|
427
|
+
if (!ignoresMatch) return [];
|
|
428
|
+
|
|
429
|
+
const ignoresContent = ignoresMatch[1];
|
|
430
|
+
|
|
431
|
+
// Extract quoted strings from the array
|
|
432
|
+
const patterns = [];
|
|
433
|
+
const stringMatches = ignoresContent.matchAll(/['"]([^'"]+)['"]/g);
|
|
434
|
+
for (const match of stringMatches) {
|
|
435
|
+
patterns.push(match[1]);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
return patterns;
|
|
439
|
+
} catch (error) {
|
|
440
|
+
return [];
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Check if a file matches any of the ignore patterns
|
|
446
|
+
*/
|
|
447
|
+
function isFileIgnored(filePath, ignorePatterns) {
|
|
448
|
+
// Convert ignore patterns to regex-like matching
|
|
449
|
+
for (const pattern of ignorePatterns) {
|
|
450
|
+
// Handle glob patterns
|
|
451
|
+
if (pattern.includes('**')) {
|
|
452
|
+
// **/*.config.js -> matches any .config.js file
|
|
453
|
+
const regex = new RegExp(pattern.replace(/\./g, '\\.').replace(/\*\*/g, '__DOUBLESTAR__').replace(/\*/g, '[^/]*').replace(/__DOUBLESTAR__/g, '.*'));
|
|
454
|
+
if (regex.test(filePath)) return true;
|
|
455
|
+
} else if (pattern.includes('*')) {
|
|
456
|
+
// *.js -> matches .js files in root
|
|
457
|
+
const regex = new RegExp('^' + pattern.replace(/\*/g, '[^/]*').replace(/\./g, '\\.') + '$');
|
|
458
|
+
if (regex.test(filePath)) return true;
|
|
459
|
+
} else {
|
|
460
|
+
// Exact match or ends with pattern
|
|
461
|
+
if (filePath === pattern || filePath.endsWith('/' + pattern)) return true;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return false;
|
|
362
465
|
}/**
|
|
363
466
|
* Initialize .remarkrc.js configuration
|
|
364
467
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entro314labs/markdownfix",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.21",
|
|
4
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": {
|
|
@@ -45,27 +45,27 @@
|
|
|
45
45
|
"author": "Dominikos Pritis",
|
|
46
46
|
"license": "MIT",
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"markdown-link-check": "^3.14.
|
|
48
|
+
"markdown-link-check": "^3.14.2",
|
|
49
49
|
"remark-cli": "^12.0.1"
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
52
|
"node": ">=22.x"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@adobe/remark-gridtables": "^3.0.
|
|
55
|
+
"@adobe/remark-gridtables": "^3.0.16",
|
|
56
56
|
"@code-dot-org/remark-plugins": "^2.0.1",
|
|
57
57
|
"@entro314labs/remark-mdd": "^0.0.16",
|
|
58
58
|
"@theguild/remark-mermaid": "^0.3.0",
|
|
59
|
-
"eslint": "^9.39.
|
|
59
|
+
"eslint": "^9.39.2",
|
|
60
60
|
"eslint-plugin-mdx": "^3.6.2",
|
|
61
61
|
"eslint-plugin-react": "^7.37.5",
|
|
62
62
|
"fumadocs-docgen": "^3.0.4",
|
|
63
|
-
"glob": "^
|
|
63
|
+
"glob": "^13.0.0",
|
|
64
64
|
"js-yaml": "^4.1.1",
|
|
65
65
|
"rehype-remark": "^10.0.1",
|
|
66
66
|
"remark": "latest",
|
|
67
67
|
"remark-directive": "^4.0.0",
|
|
68
|
-
"remark-docx": "^0.
|
|
68
|
+
"remark-docx": "^0.3.19",
|
|
69
69
|
"remark-emoji": "^5.0.2",
|
|
70
70
|
"remark-frontmatter": "^5.0.0",
|
|
71
71
|
"remark-gfm": "^4.0.1",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"remark-lint-no-empty-sections": "^4.0.0",
|
|
100
100
|
"remark-lint-no-heading-indent": "^5.0.1",
|
|
101
101
|
"remark-lint-no-heading-punctuation": "^4.0.1",
|
|
102
|
-
"remark-lint-no-trailing-spaces": "^
|
|
102
|
+
"remark-lint-no-trailing-spaces": "^4.0.3",
|
|
103
103
|
"remark-lint-ordered-list-marker-style": "^4.0.1",
|
|
104
104
|
"remark-lint-ordered-list-marker-value": "^4.0.1",
|
|
105
105
|
"remark-lint-strong-marker": "^4.0.1",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
"remark-lint-table-pipe-alignment": "^4.1.1",
|
|
108
108
|
"remark-lint-table-pipes": "^5.0.1",
|
|
109
109
|
"remark-lint-unordered-list-marker-style": "^4.0.1",
|
|
110
|
-
"remark-mdc": "^3.
|
|
110
|
+
"remark-mdc": "^3.10.0",
|
|
111
111
|
"remark-mdx": "^3.1.1",
|
|
112
112
|
"remark-mdx-frontmatter": "^5.2.0",
|
|
113
113
|
"remark-preset-lint-consistent": "^6.0.1",
|