47 lines
2.3 KiB
JavaScript
47 lines
2.3 KiB
JavaScript
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const assert = require('node:assert/strict');
|
|
const root = path.resolve(__dirname, '../..');
|
|
const files = ['docs/104/IEC104_API接口汇总.md', 'docs/104/IEC104_完整调用流程.md'];
|
|
for (const file of files) {
|
|
const bytes = fs.readFileSync(path.join(root, file));
|
|
const source = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
const baseline = fs.readFileSync(path.join(__dirname, path.basename(file) + '.before'));
|
|
assert.equal(bytes.subarray(0, 3).equals(Buffer.from([0xef, 0xbb, 0xbf])),
|
|
baseline.subarray(0, 3).equals(Buffer.from([0xef, 0xbb, 0xbf])), `${file}: BOM changed`);
|
|
assert(!source.includes('\ufffd') && !source.includes('\r'), `${file}: encoding or line ending`);
|
|
assert(source.endsWith('\n') && !/[\t ]+$/m.test(source), `${file}: whitespace`);
|
|
const ids = new Set();
|
|
let fence = '', details = 0, blocks = 0;
|
|
const tableProblems = [];
|
|
let tableColumns = 0;
|
|
for (const [index, line] of source.split('\n').entries()) {
|
|
const marker = /^(`{3,}|~{3,})/.exec(line);
|
|
if (marker) {
|
|
if (!fence) { fence = marker[1]; blocks++; }
|
|
else if (marker[1][0] === fence[0] && marker[1].length >= fence.length) fence = '';
|
|
tableColumns = 0;
|
|
continue;
|
|
}
|
|
if (fence) continue;
|
|
for (const match of line.matchAll(/<a\s+id="([^"]+)"\s*>/g)) {
|
|
assert(!ids.has(match[1]), `${file}:${index + 1}: duplicate id ${match[1]}`);
|
|
ids.add(match[1]);
|
|
}
|
|
if (line.includes('<details>')) details++;
|
|
if (line.includes('</details>')) details--;
|
|
assert(details >= 0, `${file}:${index + 1}: unexpected details close`);
|
|
if (/^\|/.test(line)) {
|
|
const columns = (line.replace(/\\\|/g, '').match(/\|/g) || []).length;
|
|
if (tableColumns && columns !== tableColumns) tableProblems.push(index + 1);
|
|
tableColumns = columns;
|
|
} else tableColumns = 0;
|
|
}
|
|
assert(!fence && details === 0, `${file}: unclosed fence/details`);
|
|
assert.deepEqual(tableProblems, [], `${file}: inconsistent table column count`);
|
|
for (const id of baseline.toString('utf8').matchAll(/<a\s+id="([^"]+)"\s*>/g)) {
|
|
assert(ids.has(id[1]), `${file}: removed existing anchor ${id[1]}`);
|
|
}
|
|
console.log(`${file}: ${blocks} fenced blocks, ${ids.size} stable anchors, UTF-8/LF and tables OK`);
|
|
}
|