1// Build stability table to documentation.html/json/md by generated all.json 2 3import fs from 'fs'; 4 5import raw from 'rehype-raw'; 6import htmlStringify from 'rehype-stringify'; 7import gfm from 'remark-gfm'; 8import markdown from 'remark-parse'; 9import remark2rehype from 'remark-rehype'; 10import { unified } from 'unified'; 11import { visit } from 'unist-util-visit'; 12 13const source = new URL('../../out/doc/api/', import.meta.url); 14const data = JSON.parse(fs.readFileSync(new URL('./all.json', source), 'utf8')); 15const markBegin = '<!-- STABILITY_OVERVIEW_SLOT_BEGIN -->'; 16const markEnd = '<!-- STABILITY_OVERVIEW_SLOT_END -->'; 17const mark = `${markBegin}(.*)${markEnd}`; 18 19const output = { 20 json: new URL('./stability.json', source), 21 docHTML: new URL('./documentation.html', source), 22 docJSON: new URL('./documentation.json', source), 23 docMarkdown: new URL('./documentation.md', source), 24}; 25 26function collectStability(data) { 27 const stability = []; 28 29 for (const mod of data.modules) { 30 if (mod.displayName && mod.stability >= 0) { 31 const link = mod.source.replace('doc/api/', '').replace('.md', '.html'); 32 33 let { stabilityText } = mod; 34 if (stabilityText.includes('. ')) { 35 stabilityText = stabilityText.slice(0, stabilityText.indexOf('.')); 36 } 37 38 stability.push({ 39 api: mod.name, 40 displayName: mod.textRaw, 41 link: link, 42 stability: mod.stability, 43 stabilityText: `(${mod.stability}) ${stabilityText}`, 44 }); 45 } 46 } 47 48 stability.sort((a, b) => a.displayName.localeCompare(b.displayName)); 49 return stability; 50} 51 52function createMarkdownTable(data) { 53 const md = ['| API | Stability |', '| --- | --------- |']; 54 55 for (const mod of data) { 56 md.push(`| [${mod.displayName}](${mod.link}) | ${mod.stabilityText} |`); 57 } 58 59 return md.join('\n'); 60} 61 62function createHTML(md) { 63 const file = unified() 64 .use(markdown) 65 .use(gfm) 66 .use(remark2rehype, { allowDangerousHtml: true }) 67 .use(raw) 68 .use(htmlStringify) 69 .use(processStability) 70 .processSync(md); 71 72 return file.value.trim(); 73} 74 75function processStability() { 76 return (tree) => { 77 visit(tree, { type: 'element', tagName: 'tr' }, (node) => { 78 const [api, stability] = node.children; 79 if (api.tagName !== 'td') { 80 return; 81 } 82 83 api.properties.class = 'module_stability'; 84 85 const level = stability.children[0].value[1]; 86 stability.properties.class = `api_stability api_stability_${level}`; 87 }); 88 }; 89} 90 91function updateStabilityMark(file, value, mark) { 92 const fd = fs.openSync(file, 'r+'); 93 const content = fs.readFileSync(fd, { encoding: 'utf8' }); 94 95 const replaced = content.replace(mark, value); 96 if (replaced !== content) { 97 fs.writeSync(fd, replaced, 0, 'utf8'); 98 } 99 fs.closeSync(fd); 100} 101 102const stability = collectStability(data); 103 104// add markdown 105const markdownTable = createMarkdownTable(stability); 106updateStabilityMark(output.docMarkdown, 107 `${markBegin}\n${markdownTable}\n${markEnd}`, 108 new RegExp(mark, 's')); 109 110// add html table 111const html = createHTML(markdownTable); 112updateStabilityMark(output.docHTML, `${markBegin}${html}${markEnd}`, 113 new RegExp(mark, 's')); 114 115// add json output 116updateStabilityMark(output.docJSON, 117 JSON.stringify(`${markBegin}${html}${markEnd}`), 118 new RegExp(JSON.stringify(mark), 's')); 119