1// Run this to update the ToCs in the TRs 2 3const { generateGfmToc } = require('@not-dalia/gfm-toc'); 4const fs = require('fs').promises; 5const path = require('path'); 6 7const dir = '../../../docs/ldml'; 8const trfile = /^tr35.*\.md$/; 9 10const contentsStart = /^## <a name="Contents".*$/; // beginning of contents: always has #Contents 11const contentsEnd = /^## .*$/; // end of contents: the next ## 12 13// ToC entries we don't want, for deletion 14const tocDelete = [ 15 /^\* \[.*Unicode Technical Standard.*$/, 16 /^ \* \[_Summary_\].*$/, 17 /^ \* \[_Status_\].*$/, 18 /^\* \[Parts\].*$/, 19 /^\* \[Contents of.*$/ 20]; 21 22const gfmOpts = { 23 // see gfm-toc docs 24 includeUnlinked: true, 25 createLinks: true, 26}; 27 28/** 29 * 30 * @returns promise to array of source files 31 */ 32async function getSrcFiles() { 33 const f = []; 34 const items = await fs.opendir(dir); 35 for await (const dirent of items) { 36 if (trfile.test(dirent.name)) { 37 f.push(path.join(dir, dirent.name)); 38 } 39 } 40 return f; 41} 42 43/** 44 * Process a single file 45 * @param {String} f 46 * @returns 47 */ 48async function processFile(f) { 49 console.log('Reading: ' + f); 50 const contents = await fs.readFile(f, 'utf-8'); 51 52 // now, reinsert 53 const lines = contents.split('\n'); 54 55 // new lines go into this array. 56 const out = []; 57 58 let i; 59 60 // go through the lines, looking for the header to the old ToC. 61 for (i = 0; i < lines.length; i++) { 62 out.push(lines[i]); // Emit the header line for the old ToC 63 if (contentsStart.test(lines[i])) { 64 break; 65 } 66 } 67 if (i == lines.length) { 68 throw Error(`in ${f}: ran out of lines looking for start of ToC`); 69 } 70 i++; 71 out.push(''); // blank line before ToC 72 73 // Generate the ToC 74 let toc = generateGfmToc(contents, gfmOpts); 75 76 // Delete any patterns in tocDelete from the ToC 77 for (pat of tocDelete) { 78 if (pat.test(toc[0])) { 79 toc = toc.splice(1); // delete first entry 80 } 81 } 82 83 // Push the whole ToC out 84 out.push(toc.join('\n')); 85 out.push(''); 86 87 // Now, look for the end of the old ToC 88 // (the next section following the old ToC) 89 for (; i < lines.length; i++) { 90 if (contentsEnd.test(lines[i])) { 91 break; 92 } 93 } 94 if (i == lines.length) { 95 throw Error(`in ${f}: ran out of lines looking for end of ToC`); 96 } 97 // Write out all remaining lines in the file. 98 for (; i < lines.length; i++) { 99 out.push(lines[i]); 100 } 101 102 // Write the whole file to disk. 103 await fs.writeFile(f, out.join('\n'), 'utf-8'); 104 105 return { 106 name: path.basename(f), 107 lines: out.length, 108 toclines: toc.length 109 }; 110} 111 112// Process everything. 113 114getSrcFiles() 115 .then(f => Promise.all(f.map(p => processFile(p)))) 116 .then(x => console.dir(x), console.error); 117