@udx/md2html 1.1.0 → 1.2.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 +17 -54
  2. package/index.js +99 -8
  3. package/package.json +4 -2
package/README.md CHANGED
@@ -6,9 +6,10 @@ A sophisticated tool for converting markdown files into a single, visually polis
6
6
 
7
7
  - **Markdown Consolidation**: Intelligently combines and sorts multiple markdown files into a single cohesive document
8
8
  - **Magazine-Quality Styling**: Applies high-end editorial styling with precise typography and spacing
9
- - **Code Block Enhancements**: Syntax highlighting with file type indicators and copy buttons
9
+ - **Code Block Enhancements**: Syntax highlighting with file type indicators
10
10
  - **Responsive Images**: Handles high-resolution images with proper sizing and caption support
11
11
  - **Watch Mode**: Automatically rebuilds when source files change with intelligent debouncing
12
+ - **Browser Preview**: Live preview server with automatic browser opening
12
13
  - **Print Optimization**: Carefully crafted print styling for document printing and PDF generation
13
14
  - **Table of Contents**: Auto-generates navigable table of contents from document structure
14
15
  - **Customizable**: External CSS, JavaScript, and HTML templates for easy customization
@@ -36,25 +37,33 @@ npm install --save-dev @udx/md2html
36
37
 
37
38
  ```bash
38
39
  # Convert a single markdown file to HTML
39
- md2html --src path/to/file.md --out output.html
40
+ md2html -s path/to/file.md -o output.html
40
41
 
41
- # Convert all markdown files in a directory
42
- md2html --src path/to/markdown/dir --out documentation.html
42
+ # Convert all markdown files in a directory
43
+ md2html -s path/to/markdown/dir -o documentation.html
43
44
 
44
45
  # Watch for changes and rebuild automatically
45
- md2html --src path/to/markdown/dir --out documentation.html --watch
46
+ md2html -s path/to/markdown/dir -o documentation.html --watch
47
+
48
+ # Open in browser with live preview
49
+ md2html -s path/to/file.md --preview
50
+
51
+ # Custom port for preview server
52
+ md2html -s path/to/markdown/dir --preview --port 3000
46
53
 
47
54
  # Enable debug output
48
- md2html --src path/to/markdown/dir --out documentation.html --debug
55
+ md2html -s path/to/markdown/dir -o documentation.html --debug
49
56
  ```
50
57
 
51
58
  ## CLI Options
52
59
 
53
60
  | Option | Description |
54
61
  |--------|-------------|
55
- | `-s, --src <path>` | Source markdown file or directory (required) |
56
- | `-o, --out <path>` | Output HTML file path (required) |
62
+ | `-s, --src <file>` | Source markdown file or directory (required) |
63
+ | `-o, --out <file>` | Output HTML file path (optional - defaults to ./output.html) |
57
64
  | `-w, --watch` | Watch for changes and rebuild automatically |
65
+ | `-p, --preview` | Open generated HTML in browser with live preview server |
66
+ | `--port <number>` | Port for preview server (default: random) |
58
67
  | `-d, --debug` | Enable debug logging |
59
68
  | `-h, --help` | Display help information |
60
69
  | `-v, --version` | Output the version number |
@@ -101,28 +110,6 @@ Add captions to images with this syntax:
101
110
  *This is the image caption*
102
111
  ```
103
112
 
104
- ### Mermaid Diagrams
105
-
106
- Create professional diagrams using Mermaid syntax:
107
-
108
- ````markdown
109
- ```mermaid
110
- flowchart LR
111
- A[Client] --> B[Load Balancer]
112
- B --> C[Server1]
113
- B --> D[Server2]
114
- ```
115
- ````
116
-
117
- Supported Mermaid diagram types:
118
- - **Flowcharts**: Process flows and workflows
119
- - **Sequence Diagrams**: System interactions over time
120
- - **Gantt Charts**: Project timelines and schedules
121
- - **Entity Relationship Diagrams**: Database schemas
122
- - **User Journey**: User experience flows
123
- - **Git Graphs**: Version control workflows
124
-
125
- The diagrams are automatically rendered when the HTML document loads, with professional styling that matches the document theme.
126
113
 
127
114
  ## Customization
128
115
 
@@ -170,17 +157,6 @@ gh repo clone owner/repo
170
157
  md2html --src ./repo/docs --out documentation.html
171
158
  ```
172
159
 
173
- ## Command Line Options
174
-
175
- ```
176
- Options:
177
- -V, --version output the version number
178
- -s, --src <directory> Source directory containing markdown files
179
- -o, --out <file> Output HTML file path
180
- -w, --watch Watch for changes and rebuild automatically (default: false)
181
- -d, --debug Enable debug logging (default: false)
182
- -h, --help display help for command
183
- ```
184
160
 
185
161
  ## Output Example
186
162
 
@@ -193,19 +169,6 @@ The generated HTML document includes:
193
169
  - Print-optimized layout with page breaks
194
170
  - Responsive design for various screen sizes
195
171
 
196
- ## API Usage
197
-
198
- md2html can also be used programmatically:
199
-
200
- ```javascript
201
- import { buildHtml, watchMarkdown } from '@udx/md2html';
202
-
203
- // Build HTML once
204
- await buildHtml('/path/to/markdown/dir', 'output.html');
205
-
206
- // Watch for changes
207
- watchMarkdown('/path/to/markdown/dir', 'output.html');
208
- ```
209
172
 
210
173
  ## Best Practices
211
174
 
package/index.js CHANGED
@@ -50,6 +50,9 @@ import { marked } from 'marked';
50
50
  import { program } from 'commander';
51
51
  import chokidar from 'chokidar';
52
52
  import Handlebars from 'handlebars';
53
+ import express from 'express';
54
+ import { createServer } from 'http';
55
+ import open from 'open';
53
56
 
54
57
  // Custom renderer for handling math blocks
55
58
  const renderer = new marked.Renderer();
@@ -86,24 +89,41 @@ const CHAPTER_NAV_STYLES_PATH = path.join(path.dirname(new URL(import.meta.url).
86
89
  const SCRIPTS_PATH = path.join(path.dirname(new URL(import.meta.url).pathname), 'static/scripts.js');
87
90
 
88
91
  program
89
- .version('1.1.0')
92
+ .version('1.2.0')
90
93
  .description('Convert markdown files to a single HTML document with Google Docs styling')
91
- .option('-s, --src <directory>', 'Source directory containing markdown files')
92
- .option('-o, --out <file>', 'Output HTML file path')
94
+ .option('-s, --src <file>', 'Source markdown file or directory')
95
+ .option('-o, --out <file>', 'Output HTML file path (optional - defaults to ./output.html)')
93
96
  .option('-w, --watch', 'Watch for changes and rebuild automatically', false)
94
97
  .option('-d, --debug', 'Enable debug logging', false)
98
+ .option('-p, --preview', 'Open generated HTML in browser with live preview server', false)
99
+ .option('--port <number>', 'Port for preview server (default: random)', parseInt)
100
+ .addHelpText('after', `
101
+ Examples:
102
+ Basic conversion:
103
+ md2html -s content/docs
104
+ md2html --src=content/docs --out=output.html
105
+
106
+ Watch mode:
107
+ md2html -s content/docs --watch
108
+
109
+ Browser preview:
110
+ md2html -s content/docs --preview
111
+ md2html -s content/docs --preview --port 3000
112
+
113
+ Single file:
114
+ md2html -s document.md --preview`)
95
115
  .parse(process.argv);
96
116
 
97
117
  const options = program.opts();
98
118
 
99
- if (!options.src || !options.out) {
100
- console.error('Error: Source directory and output file are required');
119
+ if (!options.src) {
120
+ console.error('Error: Source markdown file or directory is required');
101
121
  program.help();
102
122
  process.exit(1);
103
123
  }
104
124
 
105
125
  const srcPath = path.resolve(options.src);
106
- const outputFile = path.resolve(options.out);
126
+ const outputFile = options.out ? path.resolve(options.out) : path.resolve('./output.html');
107
127
 
108
128
  const debug = (message) => {
109
129
  if (options.debug) {
@@ -647,6 +667,57 @@ async function buildHtml(srcDir, outputFile) {
647
667
  }
648
668
  }
649
669
 
670
+ /**
671
+ * Gets a random port between 3000-9999
672
+ */
673
+ function getRandomPort() {
674
+ return Math.floor(Math.random() * (9999 - 3000 + 1)) + 3000;
675
+ }
676
+
677
+ /**
678
+ * Starts a preview server for the generated HTML
679
+ * @param {string} outputFile - Path to the HTML file to serve
680
+ * @param {number|null} port - Port to use (null for random)
681
+ * @returns {Promise<number>} The port the server is running on
682
+ */
683
+ function startPreviewServer(outputFile, port = null) {
684
+ return new Promise((resolve, reject) => {
685
+ const app = express();
686
+ const targetPort = port || getRandomPort();
687
+
688
+ // Serve the generated HTML file at root
689
+ app.get('/', (req, res) => {
690
+ if (!fs.existsSync(outputFile)) {
691
+ res.status(404).send('<h1>HTML file not found</h1><p>Try rebuilding first</p>');
692
+ return;
693
+ }
694
+ res.sendFile(path.resolve(outputFile));
695
+ });
696
+
697
+ // Serve any static assets if they exist
698
+ const staticDir = path.join(path.dirname(outputFile), 'assets');
699
+ if (fs.existsSync(staticDir)) {
700
+ app.use('/assets', express.static(staticDir));
701
+ }
702
+
703
+ const server = createServer(app);
704
+
705
+ server.listen(targetPort, () => {
706
+ console.log(`šŸš€ Preview server running at http://localhost:${targetPort}`);
707
+ resolve(targetPort);
708
+ });
709
+
710
+ server.on('error', (err) => {
711
+ if (err.code === 'EADDRINUSE' && !port) {
712
+ // If random port is in use, try another random port
713
+ startPreviewServer(outputFile, null).then(resolve).catch(reject);
714
+ } else {
715
+ reject(err);
716
+ }
717
+ });
718
+ });
719
+ }
720
+
650
721
  /**
651
722
  * Watches for changes in markdown files and rebuilds HTML
652
723
  * @param {string} srcDir - Source directory containing markdown files
@@ -730,8 +801,28 @@ function watchMarkdown(srcDir, outputFile) {
730
801
  });
731
802
  }
732
803
 
733
- // Watch for changes if enabled
734
- if (options.watch) {
804
+ // Handle different execution modes
805
+ if (options.preview) {
806
+ // Preview mode: build HTML, start server, and optionally watch
807
+ buildHtml(srcPath, outputFile).then((success) => {
808
+ if (success) {
809
+ startPreviewServer(outputFile, options.port).then((port) => {
810
+ // Open browser
811
+ open(`http://localhost:${port}`);
812
+
813
+ if (options.watch) {
814
+ console.log('\nšŸ‘€ Watching for file changes...');
815
+ watchMarkdown(srcPath, outputFile);
816
+ } else {
817
+ console.log('\nšŸ’” Use --watch flag to auto-rebuild on file changes');
818
+ console.log('Press Ctrl+C to stop the server');
819
+ }
820
+ }).catch((err) => {
821
+ console.error('Failed to start preview server:', err);
822
+ });
823
+ }
824
+ });
825
+ } else if (options.watch) {
735
826
  watchMarkdown(srcPath, outputFile);
736
827
  } else {
737
828
  buildHtml(srcPath, outputFile);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@udx/md2html",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Magazine-quality Markdown to HTML converter with professional styling",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -34,8 +34,10 @@
34
34
  "dependencies": {
35
35
  "chokidar": "^3.5.3",
36
36
  "commander": "^11.0.0",
37
+ "express": "^4.18.2",
37
38
  "handlebars": "^4.7.8",
38
- "marked": "^9.1.0"
39
+ "marked": "^9.1.0",
40
+ "open": "^9.1.0"
39
41
  },
40
42
  "engines": {
41
43
  "node": ">=14.16"