UNPKG

4.38 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3/**
4 * Marked CLI
5 * Copyright (c) 2011-2013, Christopher Jeffrey (MIT License)
6 */
7
8import { promises } from 'fs';
9import { marked } from '../lib/marked.esm.js';
10
11const { readFile, writeFile } = promises;
12
13/**
14 * Man Page
15 */
16
17async 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 // eslint-disable-next-line promise/param-names
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
42async 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 * Main
51 */
52
53async 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 // e.g. --opt
68 arg = arg.split('=');
69 if (arg.length > 1) {
70 // e.g. --opt=val
71 argv.unshift(arg.slice(1).join('='));
72 }
73 arg = arg[0];
74 } else if (arg[0] === '-') {
75 if (arg.length > 2) {
76 // e.g. -abc
77 argv = arg.substring(1).split('').map(function(ch) {
78 return '-' + ch;
79 }).concat(argv);
80 arg = argv.shift();
81 } else {
82 // e.g. -a
83 }
84 } else {
85 // e.g. foo
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 * Helpers
166 */
167
168function 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
191function camelize(text) {
192 return text.replace(/(\w)-(\w)/g, function(_, a, b) {
193 return a + b.toUpperCase();
194 });
195}
196
197function 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 * Expose / Entry Point
207 */
208
209process.title = 'marked';
210main(process.argv.slice()).then(code => {
211 process.exit(code || 0);
212}).catch(err => {
213 handleError(err);
214});