CoolFace
Apppublic

Ejdjdososs/fable-ai

sourceHugging Facemitupdated 3mo agoView on Hugging Face
0likes
main.js279 linesDownload Raw Back to bin
1#!/usr/bin/env node2 3/**4 * Marked CLI5 * Copyright (c) 2011-2013, Christopher Jeffrey (MIT License)6 */7 8import { promises } from 'node:fs';9import { dirname, resolve } from 'node:path';10import { homedir } from 'node:os';11import { createRequire } from 'node:module';12import { marked } from '../lib/marked.esm.js';13 14const { access, readFile, writeFile } = promises;15const require = createRequire(import.meta.url);16 17/**18 * @param {Process} nodeProcess inject process so it can be mocked in tests.19 */20export async function main(nodeProcess) {21  /**22   * Man Page23   */24  async function help() {25    const { spawn } = await import('child_process');26    const { fileURLToPath } = await import('url');27 28    const options = {29      cwd: nodeProcess.cwd(),30      env: nodeProcess.env,31      stdio: 'inherit',32    };33 34    const __dirname = dirname(fileURLToPath(import.meta.url));35    const helpText = await readFile(resolve(__dirname, '../man/marked.1.md'), 'utf8');36 37    await new Promise(res => {38      spawn('man', [resolve(__dirname, '../man/marked.1')], options)39        .on('error', () => {40          console.log(helpText);41        })42        .on('close', res);43    });44  }45 46  async function version() {47    const pkg = require('../package.json');48    console.log(pkg.version);49  }50 51  /**52   * Main53   */54  async function start(argv) {55    const files = [];56    const options = {};57    let input;58    let output;59    let string;60    let arg;61    let tokens;62    let config;63    let opt;64    let noclobber;65 66    function getArg() {67      let arg = argv.shift();68 69      if (arg.indexOf('--') === 0) {70        // e.g. --opt71        arg = arg.split('=');72        if (arg.length > 1) {73          // e.g. --opt=val74          argv.unshift(arg.slice(1).join('='));75        }76        arg = arg[0];77      } else if (arg[0] === '-') {78        if (arg.length > 2) {79          // e.g. -abc80          argv = arg.substring(1).split('').map(function(ch) {81            return '-' + ch;82          }).concat(argv);83          arg = argv.shift();84        } else {85          // e.g. -a86        }87      } else {88        // e.g. foo89      }90 91      return arg;92    }93 94    while (argv.length) {95      arg = getArg();96      switch (arg) {97        case '-o':98        case '--output':99          output = argv.shift();100          break;101        case '-i':102        case '--input':103          input = argv.shift();104          break;105        case '-s':106        case '--string':107          string = argv.shift();108          break;109        case '-t':110        case '--tokens':111          tokens = true;112          break;113        case '-c':114        case '--config':115          config = argv.shift();116          break;117        case '-n':118        case '--no-clobber':119          noclobber = true;120          break;121        case '-h':122        case '--help':123          return await help();124        case '-v':125        case '--version':126          return await version();127        default:128          if (arg.indexOf('--') === 0) {129            opt = camelize(arg.replace(/^--(no-)?/, ''));130            if (!(opt in marked.defaults)) {131              continue;132            }133            if (arg.indexOf('--no-') === 0) {134              options[opt] = typeof marked.defaults[opt] !== 'boolean'135                ? null136                : false;137            } else {138              options[opt] = typeof marked.defaults[opt] !== 'boolean'139                ? argv.shift()140                : true;141            }142          } else {143            files.push(arg);144          }145          break;146      }147    }148 149    async function getData() {150      if (!input) {151        if (files.length <= 2) {152          if (string) {153            return string;154          }155          return await getStdin();156        }157        input = files.pop();158      }159      return await readFile(input, 'utf8');160    }161 162    function resolveFile(file) {163      return resolve(file.replace(/^~/, homedir));164    }165 166    function fileExists(file) {167      return access(resolveFile(file)).then(() => true, () => false);168    }169 170    async function runConfig(file) {171      const configFile = resolveFile(file);172      let markedConfig;173      try {174        // try require for json175        markedConfig = require(configFile);176      } catch (err) {177        if (err.code !== 'ERR_REQUIRE_ESM') {178          throw err;179        }180        // must import esm181        markedConfig = await import('file:///' + configFile);182      }183 184      if (markedConfig.default) {185        markedConfig = markedConfig.default;186      }187 188      if (typeof markedConfig === 'function') {189        markedConfig(marked);190      } else {191        marked.use(markedConfig);192      }193    }194 195    const data = await getData();196 197    if (config) {198      if (!await fileExists(config)) {199        throw Error(`Cannot load config file '${config}'`);200      }201 202      await runConfig(config);203    } else {204      const defaultConfig = [205        '~/.marked.json',206        '~/.marked.js',207        '~/.marked/index.js',208      ];209 210      for (const configFile of defaultConfig) {211        if (await fileExists(configFile)) {212          await runConfig(configFile);213          break;214        }215      }216    }217 218    const html = tokens219      ? JSON.stringify(marked.lexer(data, options), null, 2)220      : await marked.parse(data, options);221 222    if (output) {223      if (noclobber && await fileExists(output)) {224        throw Error('marked: output file \'' + output + '\' already exists, disable the \'-n\' / \'--no-clobber\' flag to overwrite\n');225      }226      return await writeFile(output, html);227    }228 229    nodeProcess.stdout.write(html + '\n');230  }231 232  /**233   * Helpers234   */235  function getStdin() {236    return new Promise((resolve, reject) => {237      const stdin = nodeProcess.stdin;238      let buff = '';239 240      stdin.setEncoding('utf8');241 242      stdin.on('data', function(data) {243        buff += data;244      });245 246      stdin.on('error', function(err) {247        reject(err);248      });249 250      stdin.on('end', function() {251        resolve(buff);252      });253 254      stdin.resume();255    });256  }257 258  /**259   * @param {string} text260   */261  function camelize(text) {262    return text.replace(/(\w)-(\w)/g, function(_, a, b) {263      return a + b.toUpperCase();264    });265  }266 267  try {268    await start(nodeProcess.argv.slice());269    nodeProcess.exit(0);270  } catch (err) {271    if (err.code === 'ENOENT') {272      nodeProcess.stderr.write('marked: ' + err.path + ': No such file or directory');273    } else {274      nodeProcess.stderr.write(err.message);275    }276    return nodeProcess.exit(1);277  }278}279