@entro314labs/markdownfix 0.0.20 ā 0.1.1
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/README.md +2 -3
- package/cli.js +134 -2
- package/package.json +2 -2
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/README.md
CHANGED
|
@@ -31,10 +31,9 @@ npx markdownfix --help
|
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
# Format all markdown files in current directory
|
|
34
|
-
markdownfix
|
|
34
|
+
# markdownfix
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
markdownfix check
|
|
36
|
+
A comprehensive markdown linting, formatting, and auto-conversion tool that combines the power of remark with ESLint for code blocks, plus intelligent plain-text-to-markdown conversion.
|
|
38
37
|
|
|
39
38
|
# Lint files for issues
|
|
40
39
|
markdownfix lint
|
package/cli.js
CHANGED
|
@@ -18,6 +18,7 @@ import fs from 'fs/promises';
|
|
|
18
18
|
import path from 'path';
|
|
19
19
|
import { glob } from 'glob';
|
|
20
20
|
import { execSync } from 'child_process';
|
|
21
|
+
import { AutoFormatter } from './autoformat.js';
|
|
21
22
|
|
|
22
23
|
const MARKDOWN_EXTENSIONS = ['md', 'mdx', 'mdc', 'mdd'];
|
|
23
24
|
|
|
@@ -59,6 +60,7 @@ COMMANDS:
|
|
|
59
60
|
check [files] Check formatting without writing changes
|
|
60
61
|
lint [files] Lint markdown files (no formatting)
|
|
61
62
|
nuclear [files] š Run ALL linters and fixers (remark + ESLint)
|
|
63
|
+
autoformat [files] š¤ Convert plain text to structured markdown
|
|
62
64
|
init Create .remarkrc.js configuration file
|
|
63
65
|
setup Create example content structure
|
|
64
66
|
|
|
@@ -68,6 +70,15 @@ OPTIONS:
|
|
|
68
70
|
--quiet, -q Suppress output except errors
|
|
69
71
|
--glob <pattern> Use glob pattern (e.g., "**/*.md")
|
|
70
72
|
--nuclear Run complete lint+fix workflow (alias for nuclear command)
|
|
73
|
+
|
|
74
|
+
AUTOFORMAT OPTIONS:
|
|
75
|
+
--plugins <dir> Load custom formatting plugins
|
|
76
|
+
--recursive, -r Process directories recursively
|
|
77
|
+
--semantic Apply semantic line breaks at sentence boundaries
|
|
78
|
+
--smart-quotes Convert straight quotes to curly quotes
|
|
79
|
+
--ellipsis Convert ... to ellipsis character (ā¦)
|
|
80
|
+
--width <n> Set line wrap width (default: 88)
|
|
81
|
+
--auto Enable all smart features (semantic + quotes + ellipsis)
|
|
71
82
|
|
|
72
83
|
EXAMPLES:
|
|
73
84
|
# Format all markdown files in current directory
|
|
@@ -86,6 +97,13 @@ EXAMPLES:
|
|
|
86
97
|
markdownfix nuclear
|
|
87
98
|
markdownfix format --nuclear
|
|
88
99
|
|
|
100
|
+
# š¤ Auto-format plain text to markdown
|
|
101
|
+
markdownfix autoformat unformatted.txt
|
|
102
|
+
markdownfix autoformat --glob "**/*.txt"
|
|
103
|
+
markdownfix autoformat --auto unformatted.txt
|
|
104
|
+
markdownfix autoformat --semantic --smart-quotes file.md
|
|
105
|
+
markdownfix autoformat --plugins ./my-plugins --width 100
|
|
106
|
+
|
|
89
107
|
# Initialize configuration
|
|
90
108
|
markdownfix init
|
|
91
109
|
|
|
@@ -160,7 +178,11 @@ async function processFiles(files, options = {}) {
|
|
|
160
178
|
listItemIndent: 'one',
|
|
161
179
|
rule: '-',
|
|
162
180
|
strong: '*',
|
|
163
|
-
tightDefinitions: true
|
|
181
|
+
tightDefinitions: true,
|
|
182
|
+
handlers: {
|
|
183
|
+
// Custom handler to use two spaces for line breaks instead of backslashes
|
|
184
|
+
break: () => ' \n'
|
|
185
|
+
}
|
|
164
186
|
});
|
|
165
187
|
}
|
|
166
188
|
|
|
@@ -446,7 +468,7 @@ function isFileIgnored(filePath, ignorePatterns) {
|
|
|
446
468
|
// Handle glob patterns
|
|
447
469
|
if (pattern.includes('**')) {
|
|
448
470
|
// **/*.config.js -> matches any .config.js file
|
|
449
|
-
|
|
471
|
+
const regex = new RegExp(pattern.replace(/\./g, '\\.').replace(/\*\*/g, '__DOUBLESTAR__').replace(/\*/g, '[^/]*').replace(/__DOUBLESTAR__/g, '.*'));
|
|
450
472
|
if (regex.test(filePath)) return true;
|
|
451
473
|
} else if (pattern.includes('*')) {
|
|
452
474
|
// *.js -> matches .js files in root
|
|
@@ -641,6 +663,116 @@ async function main() {
|
|
|
641
663
|
break;
|
|
642
664
|
}
|
|
643
665
|
|
|
666
|
+
case 'autoformat': {
|
|
667
|
+
// Parse autoformat-specific options
|
|
668
|
+
const pluginsDir = commandArgs.includes('--plugins')
|
|
669
|
+
? commandArgs[commandArgs.indexOf('--plugins') + 1]
|
|
670
|
+
: null;
|
|
671
|
+
const recursive = commandArgs.includes('--recursive') || commandArgs.includes('-r');
|
|
672
|
+
|
|
673
|
+
// Parse typography and formatting options
|
|
674
|
+
const autoMode = commandArgs.includes('--auto');
|
|
675
|
+
const semanticBreaks = autoMode || commandArgs.includes('--semantic');
|
|
676
|
+
const smartQuotes = autoMode || commandArgs.includes('--smart-quotes');
|
|
677
|
+
const ellipsis = autoMode || commandArgs.includes('--ellipsis');
|
|
678
|
+
|
|
679
|
+
// Parse width option
|
|
680
|
+
let wrapWidth = 88;
|
|
681
|
+
const widthIndex = commandArgs.indexOf('--width');
|
|
682
|
+
if (widthIndex !== -1 && commandArgs[widthIndex + 1]) {
|
|
683
|
+
wrapWidth = parseInt(commandArgs[widthIndex + 1], 10);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// Get files to process
|
|
687
|
+
let filesToProcess = [];
|
|
688
|
+
if (options.glob) {
|
|
689
|
+
filesToProcess = await glob(options.glob, { ignore: ['node_modules/**', '.git/**'] });
|
|
690
|
+
} else if (fileArgs.length > 0) {
|
|
691
|
+
// Check if arguments are files or directories
|
|
692
|
+
for (const arg of fileArgs) {
|
|
693
|
+
try {
|
|
694
|
+
const stat = await fs.stat(arg);
|
|
695
|
+
if (stat.isDirectory()) {
|
|
696
|
+
if (recursive) {
|
|
697
|
+
const pattern = path.join(arg, '**/*.{txt,md,mdx,mdc,mdd}');
|
|
698
|
+
const dirFiles = await glob(pattern, { ignore: ['node_modules/**', '.git/**'] });
|
|
699
|
+
filesToProcess.push(...dirFiles);
|
|
700
|
+
} else {
|
|
701
|
+
console.error(`Error: ${arg} is a directory. Use --recursive to process directories.`);
|
|
702
|
+
process.exit(1);
|
|
703
|
+
}
|
|
704
|
+
} else {
|
|
705
|
+
filesToProcess.push(arg);
|
|
706
|
+
}
|
|
707
|
+
} catch (error) {
|
|
708
|
+
console.error(`Error: Cannot access ${arg}`);
|
|
709
|
+
process.exit(1);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
} else {
|
|
713
|
+
// Default: find all text and markdown files
|
|
714
|
+
filesToProcess = await glob('**/*.{txt,md,mdx,mdc,mdd}', {
|
|
715
|
+
ignore: ['node_modules/**', '.git/**']
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
if (filesToProcess.length === 0) {
|
|
720
|
+
console.log('No files found to auto-format');
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
if (!options.quiet) {
|
|
725
|
+
console.log(`\nš¤ AUTO-FORMAT MODE\n`);
|
|
726
|
+
console.log(`Processing ${filesToProcess.length} file(s)...\n`);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// Initialize auto-formatter with options
|
|
730
|
+
const formatter = new AutoFormatter({
|
|
731
|
+
aggressive: true,
|
|
732
|
+
semanticBreaks,
|
|
733
|
+
smartQuotes,
|
|
734
|
+
ellipsis,
|
|
735
|
+
wrapWidth
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
// Load plugins if specified
|
|
739
|
+
if (pluginsDir) {
|
|
740
|
+
try {
|
|
741
|
+
await formatter.loadPlugins(pluginsDir);
|
|
742
|
+
if (!options.quiet) {
|
|
743
|
+
console.log(`ā Loaded plugins from ${pluginsDir}\n`);
|
|
744
|
+
}
|
|
745
|
+
} catch (error) {
|
|
746
|
+
console.error(`ā ļø Could not load plugins from ${pluginsDir}:`, error.message);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// Format files
|
|
751
|
+
const results = await formatter.formatFiles(filesToProcess, {
|
|
752
|
+
write: true,
|
|
753
|
+
quiet: options.quiet
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
// Summary
|
|
757
|
+
const successful = results.filter(r => r.success).length;
|
|
758
|
+
const failed = results.filter(r => !r.success).length;
|
|
759
|
+
|
|
760
|
+
if (!options.quiet) {
|
|
761
|
+
console.log(`\n${'ā'.repeat(60)}`);
|
|
762
|
+
console.log('AUTO-FORMAT SUMMARY');
|
|
763
|
+
console.log('ā'.repeat(60));
|
|
764
|
+
console.log(`ā Successfully formatted: ${successful} file(s)`);
|
|
765
|
+
if (failed > 0) {
|
|
766
|
+
console.log(`ā Failed: ${failed} file(s)`);
|
|
767
|
+
}
|
|
768
|
+
console.log('ā'.repeat(60));
|
|
769
|
+
console.log();
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
process.exit(failed > 0 ? 1 : 0);
|
|
773
|
+
break;
|
|
774
|
+
}
|
|
775
|
+
|
|
644
776
|
default:
|
|
645
777
|
console.error(`Unknown command: ${command}`);
|
|
646
778
|
console.error('Run "markdownfix --help" for usage information');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entro314labs/markdownfix",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
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": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@adobe/remark-gridtables": "^3.0.16",
|
|
56
56
|
"@code-dot-org/remark-plugins": "^2.0.1",
|
|
57
|
-
"@entro314labs/remark-mdd": "^0.0.
|
|
57
|
+
"@entro314labs/remark-mdd": "^0.0.20",
|
|
58
58
|
"@theguild/remark-mermaid": "^0.3.0",
|
|
59
59
|
"eslint": "^9.39.2",
|
|
60
60
|
"eslint-plugin-mdx": "^3.6.2",
|