@webdoc/template-library
Version:
Goodies for @webdoc template packages! See @webdoc/legacy-template for an example!
104 lines (97 loc) • 3.01 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TemplateTagsResolver = void 0;
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
const CODE_PATTERN = /{@code ([^}]*)}/g;
const LINK_PATTERN = /{@link ([^|\s}]*)([\s|])?([^}]*)}/g;
class TemplateTagsResolver {
constructor(options = {}) {
_defineProperty(this, "linkClass", void 0);
_defineProperty(this, "renderer", void 0);
this.linkClass = options.linkClass;
}
attachTo(pipeline) {
this.renderer = pipeline.renderer;
}
run(input, pipelineData) {
input = this.runCodeTag(input);
input = this.runLinkTag(input);
return input;
}
runCodeTag(input) {
const codePattern = CODE_PATTERN;
let codeMatch = codePattern.exec(input);
while (codeMatch) {
const code = codeMatch[1];
const startIndex = codeMatch.index;
const endIndex = codeMatch.index + codeMatch[0].length;
input = input.slice(0, startIndex) + `<code>${code}</code>` + input.slice(endIndex);
codeMatch = codePattern.exec(input);
}
return input;
}
runLinkTag(input) {
const linkPattern = LINK_PATTERN;
let linkMatch = linkPattern.exec(input);
while (linkMatch) {
const linkTextMatch = matchTextPrefix(input, linkMatch.index);
const link = linkMatch[1];
const linkName = linkMatch[3];
const linkText = linkTextMatch ? linkTextMatch[0].slice(1, -1) : linkName || link;
let replaced;
if (isValidUrl(link)) {
replaced = `<a ${this.linkClass ? "class=\"" + this.linkClass + "\"" : ""}` + `href="${link}">${linkText}</a>`;
} else {
replaced = this.renderer.linkTo(link, linkText);
}
const startIndex = linkTextMatch ? linkTextMatch.index : linkMatch.index;
const endIndex = linkMatch.index + linkMatch[0].length;
input = input.slice(0, startIndex) + replaced + input.slice(endIndex);
linkMatch = linkPattern.exec(input);
}
return input;
}
clone() {
return new TemplateTagsResolver({
linkClass: this.linkClass
});
}
close() {}
}
exports.TemplateTagsResolver = TemplateTagsResolver;
function isValidUrl(string) {
try {
new URL(string);
} catch (_) {
return false;
}
return true;
}
function matchTextPrefix(content, tagStart) {
const index = tagStart - 1;
if (content.charAt(index) !== "]") {
return;
}
let bracketDepth = 1;
let openIndex = -1;
for (let i = index - 1; i >= 0; i--) {
const char = content.charAt(i);
if (char === "[") {
--bracketDepth;
if (bracketDepth === 0) {
openIndex = i;
break;
}
} else if (char === "]") {
++bracketDepth;
}
}
if (openIndex === -1) {
return;
}
const result = [content.slice(openIndex, index + 1)];
result.index = openIndex;
return result;
}