{"id":15893820,"url":"https://github.com/chinanf-boy/relaxed-explain","last_synced_at":"2025-04-02T18:16:15.175Z","repository":{"id":90548506,"uuid":"132747847","full_name":"chinanf-boy/Relaxed-explain","owner":"chinanf-boy","description":"explain: no just pug or something become pdf, and Watching 使用网络技术创建PDF文档","archived":false,"fork":false,"pushed_at":"2018-05-09T11:37:29.000Z","size":7,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-08T08:47:13.460Z","etag":null,"topics":["explain","pdf","pug"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chinanf-boy.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-09T11:37:16.000Z","updated_at":"2018-05-14T16:32:54.000Z","dependencies_parsed_at":"2023-07-19T01:16:21.745Z","dependency_job_id":null,"html_url":"https://github.com/chinanf-boy/Relaxed-explain","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chinanf-boy%2FRelaxed-explain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chinanf-boy%2FRelaxed-explain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chinanf-boy%2FRelaxed-explain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chinanf-boy%2FRelaxed-explain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chinanf-boy","download_url":"https://codeload.github.com/chinanf-boy/Relaxed-explain/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246866100,"owners_count":20846496,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["explain","pdf","pug"],"created_at":"2024-10-06T08:13:49.166Z","updated_at":"2025-04-02T18:16:15.141Z","avatar_url":"https://github.com/chinanf-boy.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# ReLaXed\n\n「 使用网络技术创建PDF文档 」\n\n[![explain](http://llever.com/explain.svg)](https://github.com/chinanf-boy/Source-Explain)\n    \nExplanation\n\n\u003e \"version\": \"0.1.3\"\n\n[github source](https://github.com/RelaxedJS/ReLaXed)\n\n~~[english](./README.en.md)~~\n\n---\n\n我想这个项目只需要用作者的话来阐述就很好了·\n\n轻松的支持`Markdown, LaTeX-style`数学方程式 (通过[mathjax](https://www.mathjax.org/)) ,csv转换为html表格,绘图生成 (通过[Vega-Lite - 精简版](https://vega.github.io/vega-lite/)要么[chart.js](https://www.chartjs.org/)) 和图表生成 (通过[mermaidjs](https://mermaidjs.github.io/)) 🥄通过导入现有的javascript或css框架,可以添加更多功能. \n\n---\n\n本目录\n\n---\n\n## package.json\n\n``` js\n  \"main\": \"src/index.js\",\n  \"bin\": {\n    \"relaxed\": \"src/index.js\"\n  },\n```\n\n## index\n\n- [x] [require](#require)  导入\n- [x] [cli-commander](#cli-commander)\n- [x] [main](#main)\n- [x] [chokidar](#chokidar)\n- [x] [converters](#converters) \n\n### require\n\n``` js\n#!/usr/bin/env node\nconst colors = require('colors') // 颜色\nconst program = require('commander') // 命令行\nconst chokidar = require('chokidar') // 观察\nconst puppeteer = require('puppeteer') // 命令行-chrome\nconst { performance } = require('perf_hooks')\nconst path = require('path')\nconst fs = require('fs')\nconst converters = require('./converters.js') // 多种转译器\n\n```\n\n\u003cdetails\u003e\n\n\u003csummary\u003e lib github source \u003c/summary\u003e\n\nhttps://github.com/Marak/colors.js\nhttps://github.com/tj/commander.js\nhttps://github.com/paulmillr/chokidar\nhttps://github.com/GoogleChrome/puppeteer\nhttps://nodejs.org/api/perf_hooks.html\n\n\u003c/details\u003e\n\ncli-commander\n\n### cli-commander\n\n``` js\nvar input, output\n\nprogram\n  .version('0.0.1')\n  .usage('\u003cinput\u003e [output] [options]')\n  .arguments('\u003cinput\u003e [output] [options]')\n  .option('--no-sandbox', 'disable puppeteer sandboxing')\n  .option('-w, --watch \u003clocations\u003e', 'Watch other locations', [])\n  .option('-t, --temp [location]', 'Directory for temp file')\n  .action(function (inp, out) {\n    input = inp\n    output = out\n  })\n\nprogram.parse(process.argv) // 开启命令解析\n\nif (!input) { // 返回错误\n  console.error('Please specifiy an input file');\n  process.exit(1)\n}\n\nconst inputPath = ·path.resolve(input)\nconst inputDir = path.resolve(inputPath, '..') // 文件的上层目录·\nconst inputFilenameNoExt = path.basename(input, path.extname(input))\n\nif (!output) {\n  output = path.join(inputDir, inputFilenameNoExt + '.pdf')\n}\n\nconst outputPath = path.resolve(output) // 输出目录\n\nvar tempDir \nif (program.temp) {\n  var validTempPath = fs.existsSync(program.temp) \u0026\u0026 fs.statSync(program.temp).isDirectory()\n  if (validTempPath) {\n    tempDir = path.resolve(program.temp)\n  } else {\n    console.error('Could not find specified --temp directory: ' + program.temp)\n    process.exit(1)\n  }\n} else {\n  tempDir = inputDir\n} // 临时文件的目录 tempDir\n\nconst tempHTMLPath = path.join(tempDir, inputFilenameNoExt + '_temp.htm')\n\nlet watchLocations = [inputDir]\nif (program.watch) { // 添加 观察文件赎罪\n  watchLocations = watchLocations.concat(program.watch)\n}\n\nconst puppeteerConfig = { // 设置浏览器命令配置\n  headless: true,\n  args: program.sandbox ? ['--no-sandbox'] : []\n}\n\n```\n\nmain\n\n### main\n\n``` js\nasync function main () {\n  console.log('Watching ' + input + ' and its directory tree.')\n  const browser = await puppeteer.launch(puppeteerConfig);\n  const page = await browser.newPage()\n  page.on('pageerror', function (err) { // 浏览器命令 错误 配置\n    console.log('Page error: ' + err.toString())\n  }).on('error', function (err) {\n    console.log('Error: ' + err.toString())\n  })\n\n```\n\nchokidar\n\n### chokidar\n\n\u003e 观察文件开始\n\n[chokidar config](https://github.com/paulmillr/chokidar#performance)\n\n``` js\n\n  chokidar.watch(watchLocations, { // 观察文件\n    awaitWriteFinish: {\n      stabilityThreshold: 50,\n      pollInterval: 100\n    }\n  }).on('change', (filepath) =\u003e {\n    if (!(['.pug', '.md', '.html', '.css', '.scss', '.svg', '.mermaid',\n           '.chart.js', '.png', '.flowchart', '.flowchart.json',\n           '.vegalite.json', '.table.csv', 'htable.csv'].some(ext =\u003e filepath.endsWith(ext)))) {\n      return\n    }\n    console.log(`\\nProcessing detected change in ${filepath.replace(inputDir, '')}...`.magenta.bold)\n    var t0 = performance.now() // 开始计数\n    var taskPromise = null\n\n```\n\nconverters\n\n### converters\n\n转译器 使用\n\n[converters explain](./converters.md)\n\n``` js\n    if (['.pug', '.md', '.html', '.css', '.scss', '.svg', '.png'].some(ext =\u003e filepath.endsWith(ext))) {\n        // (输入完整路径, 浏览器APi, 缓存完整路径, 输出完整路径)\n      taskPromise = converters.masterDocumentToPDF(inputPath, page, tempHTMLPath, outputPath)\n    } \n    // 正常情况  文档 变 PDf\n    \n    else if (filepath.endsWith('.chart.js')) {\n      taskPromise = converters.chartjsToPNG(filepath, page)\n    } \n    // .chart.js 变 png 图片\n    \n    \n    else if (filepath.endsWith('.mermaid')) {\n      taskPromise = converters.mermaidToSvg(filepath, page)\n    } \n    // .mermaid 变 Svg\n    \n    \n    else if (filepath.endsWith('.flowchart')) {\n      taskPromise = converters.flowchartToSvg(filepath, page)\n    } \n    // .flowchart 变 Svg\n    \n    \n    else if (filepath.endsWith('.flowchart.json')) {\n      var flowchartFile = filepath.substr(0, filepath.length - 5)\n      taskPromise = converters.flowchartToSvg(flowchartFile, page)\n    } \n      // .flowchart.json 变 SvgartFile, page)\n    \n    \n    else if (filepath.endsWith('.vegalite.json')) {\n      taskPromise = converters.vegaliteToSvg(filepath, page)\n    } \n    // .vegalite.json 变 Svg\n    \n    \n    else if (['.table.csv', '.htable.csv'].some(ext =\u003e filepath.endsWith(ext))) {\n      converters.tableToPug(filepath)\n    }\n    // '.table.csv', '.htable.csv' 变 pug\n\n\n\n    if (taskPromise) { // 要正确 才能显示信息\n      taskPromise.then(function () {\n        var duration = ((performance.now() - t0) / 1000).toFixed(2)\n        console.log(`... done in ${duration}s`.magenta.bold)\n      })\n    }\n  })\n}\n\nmain() // \u003c===== 开启\n\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchinanf-boy%2Frelaxed-explain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchinanf-boy%2Frelaxed-explain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchinanf-boy%2Frelaxed-explain/lists"}