• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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