@entro314labs/markdownfix 0.0.21 → 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.
Files changed (3) hide show
  1. package/README.md +2 -3
  2. package/cli.js +128 -0
  3. package/package.json +2 -2
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 format
34
+ # markdownfix
35
35
 
36
- # Check formatting without writing changes
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
 
@@ -645,6 +663,116 @@ async function main() {
645
663
  break;
646
664
  }
647
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
+
648
776
  default:
649
777
  console.error(`Unknown command: ${command}`);
650
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.0.21",
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.16",
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",