@gouvfr/dsfr-roller
Version:
Le module `dsfr-roller` permet de publier le site de documentation du Système de Design de l’État - DSFR
58 lines (48 loc) • 1.8 kB
JavaScript
import { Renderable } from '../core/renderable.js';
import { nodeFactory } from '../node/node-factory.js';
const PERMALINK_CONTENT_REGEX = /<!--\s*NO_PERMALINK_START\s*-->\s(?<content>[\s\S]*)\s<!--\s*NO_PERMALINK_END\s*-->/g;
const PREVENT_PERMALINKS_REGEX = /(?<permalinks><!--\s*NO_PERMALINK_START\s*-->\s(?:[\s\S]*)\s<!--\s*NO_PERMALINK_END\s*-->)/g;
const HEADING_REGEX = /<h(?<level>[2-6])(?<attrs>[^>]*)>(?<content>.*?)<\/h\1>/g;
const ATTRIBUTE_ID_REGEX = /\sid=["'](?<id>[^"']+)["']/;
const PERMALINK_CLASS = 'dsfr-doc-anchor-heading';
const injectPermaLink = (match, level, attrs, content) => {
const idMatch = attrs.match(ATTRIBUTE_ID_REGEX);
if (!idMatch || !idMatch.groups?.id) return match;
const link = `<a href="#${idMatch.groups.id}" class="${PERMALINK_CLASS}">${content}</a>`;
return `<h${level}${attrs}>${link}</h${level}>`;
};
class Template extends Renderable {
constructor (data, hasPermaLinks = false) {
super(data);
nodeFactory.populate(data.fragments);
this._hasPermaLinks = hasPermaLinks;
this._content = nodeFactory.create({
type: 'root',
children: data.nodes
});
}
get content () {
return this._content;
}
get name () {
return this.constructor.NAME;
}
async render () {
const html = await this._content.render();
if (!this._hasPermaLinks) return html;
return this.addPermaLinks(html);
}
addPermaLinks (html) {
return html.split(PREVENT_PERMALINKS_REGEX).map((part) => {
const match = PERMALINK_CONTENT_REGEX.exec(part);
if (match && match.groups && match.groups.content) {
return match.groups.content;
}
return part.replace(HEADING_REGEX, injectPermaLink);
}).join('');
}
get text () {
return this._content.text;
}
}
export { Template };