mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
* fix typescript version * fix package versions * fix package versions * [ci:force] fix code
139 lines
4.6 KiB
JavaScript
139 lines
4.6 KiB
JavaScript
const path = require('path');
|
|
const fs = require('fs');
|
|
const remark = require('remark');
|
|
const replaceSection = require('mdast-util-heading-range');
|
|
const toString = require('mdast-util-to-string');
|
|
const ejs = require('ejs');
|
|
const unist = require('../unistHelpers');
|
|
const mdNav = require('../mdNav');
|
|
|
|
const contentsHeading = 'Contents';
|
|
const minHeadingsForToc = 8;
|
|
const maxTocHeadingDepth = 3;
|
|
|
|
const templateFolder = path.resolve('tools', 'doc', 'templates');
|
|
|
|
module.exports = {
|
|
processDocs: processDocs
|
|
};
|
|
|
|
function processDocs(mdCache, aggData, errorMessages) {
|
|
const pathNames = Object.keys(mdCache);
|
|
|
|
pathNames.forEach((pathname) => {
|
|
updateFile(mdCache[pathname].mdOutTree, pathname, aggData, errorMessages);
|
|
});
|
|
}
|
|
|
|
// Find an existing Contents section or add a new empty one if needed.
|
|
// Returns true if section is present/needed, false if not needed.
|
|
function establishContentsSection(mdTree) {
|
|
let firstL2HeadingPos = -1;
|
|
let numTocHeadings = 0;
|
|
let foundContentsHeading = false;
|
|
|
|
for (let i = 0; i < mdTree.children.length; i++) {
|
|
const child = mdTree.children[i];
|
|
|
|
// Look through all headings.
|
|
if (child.type === 'heading') {
|
|
if (child.depth > 1 && child.depth <= maxTocHeadingDepth) {
|
|
numTocHeadings++;
|
|
}
|
|
|
|
if (child.depth === 2) {
|
|
// Note where the first L2 heading is.
|
|
if (firstL2HeadingPos === -1) {
|
|
firstL2HeadingPos = i;
|
|
}
|
|
|
|
// If it is also a Contents heading then we're done. We don't include the
|
|
// Contents heading itself within the ToC, so decrement the count for that.
|
|
if (child.children[0].value === contentsHeading && !foundContentsHeading) {
|
|
foundContentsHeading = true;
|
|
numTocHeadings--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// If we get here then a level 2 Contents heading was not found.
|
|
// If there are enough headings for a ToC to be necessary then
|
|
// add one in the right place.
|
|
if (!foundContentsHeading) {
|
|
const newHeading = unist.makeHeading(unist.makeText(contentsHeading), 2);
|
|
|
|
// If we found another L2 heading then add the Contents in just before it.
|
|
if (firstL2HeadingPos !== -1) {
|
|
mdTree.children.splice(firstL2HeadingPos, 0, newHeading);
|
|
} else {
|
|
// Otherwise, the unlikely situation where a ToC is required but there
|
|
// are no L2 headings! Add it as the second element in the document.
|
|
mdTree.children.splice(1, 0, newHeading);
|
|
}
|
|
}
|
|
|
|
return numTocHeadings;
|
|
}
|
|
|
|
function updateFile(tree, pathname, _aggData, _errorMessages) {
|
|
if (path.basename(pathname, '.md').match(/README|versionIndex/)) {
|
|
return false;
|
|
}
|
|
|
|
// If we need a contents section then add one or update the existing one.
|
|
const numTocHeadings = establishContentsSection(tree);
|
|
|
|
if (numTocHeadings >= minHeadingsForToc) {
|
|
const newToc = makeToc(tree);
|
|
|
|
replaceSection(tree, contentsHeading, function (before, oldSection, after) {
|
|
return [before, newToc, after];
|
|
});
|
|
} else {
|
|
// Otherwise, we don't need one, so remove any existing one.
|
|
replaceSection(tree, contentsHeading, function (before, oldSection, after) {
|
|
return [after];
|
|
});
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function makeToc(tree) {
|
|
const nav = new mdNav.MDNav(tree);
|
|
const headings = nav.headings((h) => h.depth > 1 && h.depth <= maxTocHeadingDepth);
|
|
const context = { headings: [] };
|
|
|
|
headings.forEach((heading) => {
|
|
let linkTitle = '';
|
|
|
|
if (!(heading.item.children.length > 0 && heading.item.children[0].type === 'text' && heading.item.children[0].value === 'Contents')) {
|
|
linkTitle = toString(heading.item).trim();
|
|
}
|
|
|
|
if (linkTitle !== '') {
|
|
context.headings.push({
|
|
level: heading.item.depth - 2,
|
|
title: linkTitle,
|
|
anchor:
|
|
'#' +
|
|
linkTitle
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9\s\-_]/g, '')
|
|
.replace(/\s/g, '-')
|
|
.replace(/-+$/, '')
|
|
});
|
|
}
|
|
});
|
|
|
|
const templateName = path.resolve(templateFolder, 'toc.ejs');
|
|
const templateSource = fs.readFileSync(templateName, 'utf8');
|
|
const template = ejs.compile(templateSource);
|
|
|
|
const mdText = template(context);
|
|
const newMD = remark().parse(mdText);
|
|
|
|
return newMD.children[0];
|
|
}
|