@diplodoc/transform
Version:
A simple transformer of text in YFM (Yandex Flavored Markdown) to HTML
130 lines • 5.47 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
const chalk_1 = require("chalk");
const github_slugger_1 = __importDefault(require("github-slugger"));
const slugify_1 = __importDefault(require("slugify"));
const utils_1 = require("../../utils");
const constants_1 = require("./constants");
const custom_id_1 = require("./custom-id");
function createAnchorButtonTokens(state, id, setId = false, href, title) {
const open = new state.Token('anchor_open', 'button', 1);
const close = new state.Token('anchor_close', 'button', -1);
if (setId) {
open.attrSet('id', id);
}
open.attrSet('class', 'yfm-clipboard-anchor');
open.attrSet('data-href', href + '#' + id);
open.attrSet('aria-label', title);
open.attrSet('title', title);
return [open, close];
}
function createAnchorLinkTokens(state, id, setId = false, href, title) {
const open = new state.Token('link_open', 'a', 1);
const close = new state.Token('link_close', 'a', -1);
if (setId) {
open.attrSet('id', id);
}
open.attrSet('href', href + '#' + id);
open.attrSet('class', 'yfm-anchor yfm-clipboard-anchor');
open.attrSet('aria-hidden', 'true');
// SEO: render invisible heading title because link must have text content.
const hiddenDesc = new state.Token('anchor_hidden_desc', '', 0);
hiddenDesc.content = title;
return [open, hiddenDesc, close];
}
const index = (md, options) => {
const { extractTitle, path, log, supportGithubAnchors, getPublicPath, disableCommonAnchors, useCommonAnchorButtons, lang, } = options;
const plugin = (state) => {
/* Do not use the plugin if it is included in the file */
if (state.env.includes && state.env.includes.length) {
return;
}
const href = getPublicPath ? getPublicPath(options, state.env.path) : '';
const ids = {};
const tokens = state.tokens;
let i = 0;
const slugger = new github_slugger_1.default();
const createAnchorTokens = useCommonAnchorButtons
? createAnchorButtonTokens
: createAnchorLinkTokens;
while (i < tokens.length) {
const token = tokens[i];
const isHeading = token.type === 'heading_open';
if (isHeading) {
const { title, level } = (0, utils_1.headingInfo)(tokens, i);
const inlineToken = tokens[i + 1];
let id = token.attrGet('id');
let ghId;
if (!title) {
log.warn(`Header without title${path ? ` in ${(0, chalk_1.bold)(path)}` : ''}`);
}
if (level < 2 && extractTitle) {
// if there are any custom ids in the level 1 heading we should clear them
(0, custom_id_1.removeCustomIds)(tokens[i + 1]);
i += 3;
continue;
}
const customIds = (0, custom_id_1.getCustomIds)(inlineToken.content);
if (customIds) {
id = customIds[0];
(0, custom_id_1.removeCustomIds)(tokens[i + 1]);
}
else {
id = (0, slugify_1.default)(title, {
lower: true,
remove: /[^\w\s$_\-,;=/]+/g,
});
ghId = slugger.slug(title);
}
token.attrSet('id', id);
if (ids[id]) {
id = id + ids[id]++;
token.attrSet('id', id);
}
else {
ids[id] = 1;
}
const allAnchorIds = customIds ? customIds : [id];
const anchorTitle = useCommonAnchorButtons
? constants_1.ANCHOR_TITLES[lang]
: (0, custom_id_1.removeCustomId)(title).replace(/`/g, '');
allAnchorIds.forEach((customId) => {
var _a, _b;
const setId = id !== customId;
if (!disableCommonAnchors) {
const linkTokens = createAnchorTokens(state, customId, setId, href, anchorTitle);
(_a = inlineToken.children) === null || _a === void 0 ? void 0 : _a.unshift(...linkTokens);
}
if (supportGithubAnchors) {
const ghLinkTokens = createAnchorTokens(state, ghId, true, href, anchorTitle);
(_b = inlineToken.children) === null || _b === void 0 ? void 0 : _b.unshift(...ghLinkTokens);
}
});
i += 3;
continue;
}
i++;
}
};
try {
md.core.ruler.after('includes', 'anchors', plugin);
}
catch (_a) {
try {
md.core.ruler.after('curly_attributes', 'anchors', plugin);
}
catch (_b) {
md.core.ruler.push('anchors', plugin);
}
}
const { escapeHtml } = md.utils;
md.renderer.rules.anchor_hidden_desc = function (tokens, index) {
return ('<span class="visually-hidden" data-no-index="true">' +
escapeHtml(tokens[index].content) +
'</span>');
};
};
module.exports = index;
//# sourceMappingURL=index.js.map