@f-fjs/tidy-markdown
Version:
Fix ugly markdown.
101 lines • 4.12 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const html_entities_1 = require("html-entities");
const block_tags_json_1 = __importDefault(require("./block-tags.json"));
const tree_adapter_1 = __importDefault(require("./tree-adapter"));
const void_tags_json_1 = __importDefault(require("./void-tags.json"));
function isElement(val) {
return !!(val && tree_adapter_1.default.isElementNode(val));
}
exports.isElement = isElement;
function isParentNode(val) {
return !!(val && 'childNodes' in val && val['childNodes']);
}
exports.isParentNode = isParentNode;
function assertIsElement(val) {
if (!isElement(val))
throw new Error('Expected Element');
}
exports.assertIsElement = assertIsElement;
/**
* Wrap code with delimiters
* @param {String} code
* @param {String} delimiter The delimiter to start with, additional backticks
* will be added if needed; like if the code contains a sequence of backticks
* that would end the code block prematurely.
*/
function delimitCode(code, delimiter) {
while (new RegExp(`([^\`]|^)${delimiter}([^\`]|$)`).test(code)) {
// Make sure that the delimiter isn't being used inside of the text. If it
// is, we need to increase the number of times the delimiter is repeated.
delimiter += '`';
}
if (code[0] === '`') {
code = ` ${code}`;
} // add starting space
if (code.slice(-1) === '`') {
code += ' ';
} // add ending space
return delimiter + code + delimiter;
}
exports.delimitCode = delimitCode;
function getAttribute(node, attribute) {
var _a;
return ((_a = tree_adapter_1.default.getAttrList(node).find(attr => attr.name === attribute)) === null || _a === void 0 ? void 0 : _a.value) || null;
}
exports.getAttribute = getAttribute;
/**
* Check if node has more attributes than ones provided
* @return {boolean} true if no extra attributes otherwise false
*/
function noExtraAttributes(node, ...attributes) {
const attrSet = new Set(attributes);
return !tree_adapter_1.default.getAttrList(node).find(({ name }) => !attrSet.has(name));
}
exports.noExtraAttributes = noExtraAttributes;
function cleanText(node) {
const parent = node.parentNode;
let text = decodeHtmlEntities(tree_adapter_1.default.getTextNodeContent(node));
if (![isElement(parent) && parent.tagName, isElement(parent.parentNode) ? parent.parentNode.tagName : undefined].includes('pre')) {
text = text.replace(/\s+/g, ' '); // excessive whitespace & linebreaks
}
if (isElement(parent) && ['code', 'pre'].includes(parent.tagName)) {
// these tags contain whitespace-sensitive content, so we can't apply
// advanced text cleaning
return text;
}
else {
return text
.replace(/\u2014/g, '--' /* em-dashes */)
.replace(/\u2018|\u2019/g, '\'' /* opening/closing singles & apostrophes */)
.replace(/\u201c|\u201d/g, '"' /* opening/closing doubles */)
.replace(/\u2026/g, '...' /* ellipses */);
}
}
exports.cleanText = cleanText;
const htmlEntities = new html_entities_1.AllHtmlEntities();
function decodeHtmlEntities(text) {
return htmlEntities.decode(text);
}
exports.decodeHtmlEntities = decodeHtmlEntities;
const blocksSet = new Set(block_tags_json_1.default);
function isBlock(node) {
if (isElement(node))
if (node.tagName === 'code' && (isElement(node.parentNode) ? node.parentNode.tagName : undefined) === 'pre') {
return true; // code tags in a pre are treated as blocks
}
else {
return blocksSet.has(node.tagName);
}
return false;
}
exports.isBlock = isBlock;
const voidsSet = new Set(void_tags_json_1.default);
function isVoid(node) {
return isElement(node) && voidsSet.has(node.tagName);
}
exports.isVoid = isVoid;
//# sourceMappingURL=utils.js.map