1 | #!/usr/bin/env node
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | import { promises } from 'fs';
|
9 | import { marked } from '../lib/marked.esm.js';
|
10 |
|
11 | const { readFile, writeFile } = promises;
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | async function help() {
|
18 | const { spawn } = await import('child_process');
|
19 |
|
20 | const options = {
|
21 | cwd: process.cwd(),
|
22 | env: process.env,
|
23 | setsid: false,
|
24 | stdio: 'inherit'
|
25 | };
|
26 |
|
27 | const { dirname, resolve } = await import('path');
|
28 | const { fileURLToPath } = await import('url');
|
29 | const __dirname = dirname(fileURLToPath(import.meta.url));
|
30 | const helpText = await readFile(resolve(__dirname, '../man/marked.1.txt'), 'utf8');
|
31 |
|
32 |
|
33 | await new Promise(res => {
|
34 | spawn('man', [resolve(__dirname, '../man/marked.1')], options)
|
35 | .on('error', () => {
|
36 | console.log(helpText);
|
37 | })
|
38 | .on('close', res);
|
39 | });
|
40 | }
|
41 |
|
42 | async function version() {
|
43 | const { createRequire } = await import('module');
|
44 | const require = createRequire(import.meta.url);
|
45 | const pkg = require('../package.json');
|
46 | console.log(pkg.version);
|
47 | }
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 | async function main(argv) {
|
54 | const files = [];
|
55 | const options = {};
|
56 | let input;
|
57 | let output;
|
58 | let string;
|
59 | let arg;
|
60 | let tokens;
|
61 | let opt;
|
62 |
|
63 | function getarg() {
|
64 | let arg = argv.shift();
|
65 |
|
66 | if (arg.indexOf('--') === 0) {
|
67 |
|
68 | arg = arg.split('=');
|
69 | if (arg.length > 1) {
|
70 |
|
71 | argv.unshift(arg.slice(1).join('='));
|
72 | }
|
73 | arg = arg[0];
|
74 | } else if (arg[0] === '-') {
|
75 | if (arg.length > 2) {
|
76 |
|
77 | argv = arg.substring(1).split('').map(function(ch) {
|
78 | return '-' + ch;
|
79 | }).concat(argv);
|
80 | arg = argv.shift();
|
81 | } else {
|
82 |
|
83 | }
|
84 | } else {
|
85 |
|
86 | }
|
87 |
|
88 | return arg;
|
89 | }
|
90 |
|
91 | while (argv.length) {
|
92 | arg = getarg();
|
93 | switch (arg) {
|
94 | case '-o':
|
95 | case '--output':
|
96 | output = argv.shift();
|
97 | break;
|
98 | case '-i':
|
99 | case '--input':
|
100 | input = argv.shift();
|
101 | break;
|
102 | case '-s':
|
103 | case '--string':
|
104 | string = argv.shift();
|
105 | break;
|
106 | case '-t':
|
107 | case '--tokens':
|
108 | tokens = true;
|
109 | break;
|
110 | case '-h':
|
111 | case '--help':
|
112 | return await help();
|
113 | case '-v':
|
114 | case '--version':
|
115 | return await version();
|
116 | default:
|
117 | if (arg.indexOf('--') === 0) {
|
118 | opt = camelize(arg.replace(/^--(no-)?/, ''));
|
119 | if (!marked.defaults.hasOwnProperty(opt)) {
|
120 | continue;
|
121 | }
|
122 | if (arg.indexOf('--no-') === 0) {
|
123 | options[opt] = typeof marked.defaults[opt] !== 'boolean'
|
124 | ? null
|
125 | : false;
|
126 | } else {
|
127 | options[opt] = typeof marked.defaults[opt] !== 'boolean'
|
128 | ? argv.shift()
|
129 | : true;
|
130 | }
|
131 | } else {
|
132 | files.push(arg);
|
133 | }
|
134 | break;
|
135 | }
|
136 | }
|
137 |
|
138 | async function getData() {
|
139 | if (!input) {
|
140 | if (files.length <= 2) {
|
141 | if (string) {
|
142 | return string;
|
143 | }
|
144 | return await getStdin();
|
145 | }
|
146 | input = files.pop();
|
147 | }
|
148 | return await readFile(input, 'utf8');
|
149 | }
|
150 |
|
151 | const data = await getData();
|
152 |
|
153 | const html = tokens
|
154 | ? JSON.stringify(marked.lexer(data, options), null, 2)
|
155 | : marked(data, options);
|
156 |
|
157 | if (output) {
|
158 | return await writeFile(output, html);
|
159 | }
|
160 |
|
161 | process.stdout.write(html + '\n');
|
162 | }
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 | function getStdin() {
|
169 | return new Promise((resolve, reject) => {
|
170 | const stdin = process.stdin;
|
171 | let buff = '';
|
172 |
|
173 | stdin.setEncoding('utf8');
|
174 |
|
175 | stdin.on('data', function(data) {
|
176 | buff += data;
|
177 | });
|
178 |
|
179 | stdin.on('error', function(err) {
|
180 | reject(err);
|
181 | });
|
182 |
|
183 | stdin.on('end', function() {
|
184 | resolve(buff);
|
185 | });
|
186 |
|
187 | stdin.resume();
|
188 | });
|
189 | }
|
190 |
|
191 | function camelize(text) {
|
192 | return text.replace(/(\w)-(\w)/g, function(_, a, b) {
|
193 | return a + b.toUpperCase();
|
194 | });
|
195 | }
|
196 |
|
197 | function handleError(err) {
|
198 | if (err.code === 'ENOENT') {
|
199 | console.error('marked: output to ' + err.path + ': No such directory');
|
200 | return process.exit(1);
|
201 | }
|
202 | throw err;
|
203 | }
|
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 | process.title = 'marked';
|
210 | main(process.argv.slice()).then(code => {
|
211 | process.exit(code || 0);
|
212 | }).catch(err => {
|
213 | handleError(err);
|
214 | });
|