A custom content taggification (#45)

* a custom content taggification
This commit is contained in:
Utsob Roy 2023-01-19 15:31:35 +06:00 committed by GitHub
parent 80d58a7fd8
commit 92d49c2c54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 266 additions and 239 deletions

View File

@ -1,65 +1,60 @@
const slugify = require("@sindresorhus/slugify"); const slugify = require("@sindresorhus/slugify");
const markdownIt = require("markdown-it"); const markdownIt = require("markdown-it");
const fs = require('fs'); const fs = require("fs");
const matter = require('gray-matter'); const matter = require("gray-matter");
const faviconPlugin = require('eleventy-favicon'); const faviconPlugin = require("eleventy-favicon");
const tocPlugin = require('eleventy-plugin-toc'); const tocPlugin = require("eleventy-plugin-toc");
const {parse} = require("node-html-parser") const { parse } = require("node-html-parser");
const {headerToId, namedHeadingsFilter} = require("./src/helpers/utils") const { headerToId, namedHeadingsFilter } = require("./src/helpers/utils");
module.exports = function(eleventyConfig) {
module.exports = function (eleventyConfig) {
let markdownLib = markdownIt({ let markdownLib = markdownIt({
breaks: true, breaks: true,
html: true html: true,
}) })
.use(require("markdown-it-footnote")) .use(require("markdown-it-footnote"))
.use(require("markdown-it-hashtag"), { .use(function (md) {
hashtagRegExp: `[^\\s!@\\#\\$%\\^&\\*\\(\\)=\\+\\.,\\[\\{\\]\\};:'"\\?><]+`, md.renderer.rules.hashtag_open = function (tokens, idx) {
preceding: "^|\\s", return '<a class="tag" onclick="toggleTagSearch(this)">';
};
}) })
.use(function(md){ .use(require("markdown-it-mathjax3"), {
md.renderer.rules.hashtag_open = function(tokens, idx) {
return '<a class="tag" onclick="toggleTagSearch(this)">'
}
})
.use(require('markdown-it-mathjax3'), {
tex: { tex: {
inlineMath: [ inlineMath: [["$", "$"]],
["$", "$"]
]
}, },
options: { options: {
skipHtmlTags: { '[-]': ['pre'] } skipHtmlTags: { "[-]": ["pre"] },
} },
}) })
.use(require("markdown-it-attrs")) .use(require("markdown-it-attrs"))
.use(require('markdown-it-task-checkbox'), { .use(require("markdown-it-task-checkbox"), {
disabled: true, disabled: true,
divWrap: false, divWrap: false,
divClass: 'checkbox', divClass: "checkbox",
idPrefix: 'cbx_', idPrefix: "cbx_",
ulClass: 'task-list', ulClass: "task-list",
liClass: 'task-list-item' liClass: "task-list-item",
}) })
.use(require('markdown-it-plantuml'), { .use(require("markdown-it-plantuml"), {
openMarker: '```plantuml', openMarker: "```plantuml",
closeMarker: '```' closeMarker: "```",
}) })
.use(namedHeadingsFilter) .use(namedHeadingsFilter)
.use(function(md) { .use(function (md) {
//https://github.com/DCsunset/markdown-it-mermaid-plugin //https://github.com/DCsunset/markdown-it-mermaid-plugin
const origFenceRule = md.renderer.rules.fence || function(tokens, idx, options, env, self) { const origFenceRule =
md.renderer.rules.fence ||
function (tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options, env, self); return self.renderToken(tokens, idx, options, env, self);
}; };
md.renderer.rules.fence = (tokens, idx, options, env, slf) => { md.renderer.rules.fence = (tokens, idx, options, env, slf) => {
const token = tokens[idx]; const token = tokens[idx];
if (token.info === 'mermaid') { if (token.info === "mermaid") {
const code = token.content.trim(); const code = token.content.trim();
return `<pre class="mermaid">${code}</pre>`; return `<pre class="mermaid">${code}</pre>`;
} }
if (token.info === 'transclusion') { if (token.info === "transclusion") {
const code = token.content.trim(); const code = token.content.trim();
return `<div class="transclusion">${md.render(code)}</div>`; return `<div class="transclusion">${md.render(code)}</div>`;
} }
@ -67,35 +62,47 @@ module.exports = function(eleventyConfig) {
const code = token.content.trim(); const code = token.content.trim();
if (code && code.toLowerCase().startsWith("title:")) { if (code && code.toLowerCase().startsWith("title:")) {
const title = code.substring(6, code.indexOf("\n")); const title = code.substring(6, code.indexOf("\n"));
const titleDiv = title ? `<div class="callout-title"><div class="callout-title-inner">${title}</div></div>` : ''; const titleDiv = title
? `<div class="callout-title"><div class="callout-title-inner">${title}</div></div>`
: "";
return `<div class="callout" data-callout="${token.info}">${titleDiv}\n<div class="callout-content">${md.render(code.slice(code.indexOf("\n")))}</div></div>`; return `<div class="callout" data-callout="${
token.info
}">${titleDiv}\n<div class="callout-content">${md.render(
code.slice(code.indexOf("\n"))
)}</div></div>`;
} }
const title = `<div class="callout-title"><div class="callout-title-inner">${ const title = `<div class="callout-title"><div class="callout-title-inner">${token.info
token.info.charAt(3).toUpperCase()}${token.info.substring(4).toLowerCase() .charAt(3)
}</div></div>` .toUpperCase()}${token.info
.substring(4)
.toLowerCase()}</div></div>`;
return `<div class="callout" data-callout="${token.info}">${title}\n<div class="callout-content">${md.render(code)}</div></div>`; return `<div class="callout" data-callout="${
token.info
}">${title}\n<div class="callout-content">${md.render(
code
)}</div></div>`;
} }
// Other languages // Other languages
return origFenceRule(tokens, idx, options, env, slf); return origFenceRule(tokens, idx, options, env, slf);
}; };
const defaultImageRule =
md.renderer.rules.image ||
const defaultImageRule = md.renderer.rules.image || function(tokens, idx, options, env, self) { function (tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options, env, self); return self.renderToken(tokens, idx, options, env, self);
}; };
md.renderer.rules.image = (tokens, idx, options, env, self) => { md.renderer.rules.image = (tokens, idx, options, env, self) => {
const imageName = tokens[idx].content; const imageName = tokens[idx].content;
const [fileName, width] = imageName.split("|"); const [fileName, width] = imageName.split("|");
if (width) { if (width) {
const widthIndex = tokens[idx].attrIndex('width'); const widthIndex = tokens[idx].attrIndex("width");
const widthAttr = `${width}px`; const widthAttr = `${width}px`;
if (widthIndex < 0) { if (widthIndex < 0) {
tokens[idx].attrPush(['width', widthAttr]); tokens[idx].attrPush(["width", widthAttr]);
} else { } else {
tokens[idx].attrs[widthIndex][1] = widthAttr; tokens[idx].attrs[widthIndex][1] = widthAttr;
} }
@ -104,35 +111,37 @@ module.exports = function(eleventyConfig) {
return defaultImageRule(tokens, idx, options, env, self); return defaultImageRule(tokens, idx, options, env, self);
}; };
const defaultLinkRule =
const defaultLinkRule = md.renderer.rules.link_open || function(tokens, idx, options, env, self) { md.renderer.rules.link_open ||
function (tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options, env, self); return self.renderToken(tokens, idx, options, env, self);
}; };
md.renderer.rules.link_open = function(tokens, idx, options, env, self) { md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
const aIndex = tokens[idx].attrIndex('target'); const aIndex = tokens[idx].attrIndex("target");
const classIndex = tokens[idx].attrIndex('class'); const classIndex = tokens[idx].attrIndex("class");
if (aIndex < 0) { if (aIndex < 0) {
tokens[idx].attrPush(['target', '_blank']); tokens[idx].attrPush(["target", "_blank"]);
} else { } else {
tokens[idx].attrs[aIndex][1] = '_blank'; tokens[idx].attrs[aIndex][1] = "_blank";
} }
if (classIndex < 0) { if (classIndex < 0) {
tokens[idx].attrPush(['class', 'external-link']); tokens[idx].attrPush(["class", "external-link"]);
} else { } else {
tokens[idx].attrs[classIndex][1] = 'external-link'; tokens[idx].attrs[classIndex][1] = "external-link";
} }
return defaultLinkRule(tokens, idx, options, env, self); return defaultLinkRule(tokens, idx, options, env, self);
}; };
}); });
eleventyConfig.setLibrary("md", markdownLib); eleventyConfig.setLibrary("md", markdownLib);
eleventyConfig.addFilter('link', function(str) { eleventyConfig.addFilter("link", function (str) {
return str && str.replace(/\[\[(.*?\|.*?)\]\]/g, function(match, p1) { return (
str &&
str.replace(/\[\[(.*?\|.*?)\]\]/g, function (match, p1) {
//Check if it is an embedded excalidraw drawing or mathjax javascript //Check if it is an embedded excalidraw drawing or mathjax javascript
if (p1.indexOf("],[") > -1 || p1.indexOf('"$"') > -1) { if (p1.indexOf("],[") > -1 || p1.indexOf('"$"') > -1) {
return match; return match;
@ -152,11 +161,11 @@ module.exports = function(eleventyConfig) {
let deadLink = false; let deadLink = false;
try { try {
const startPath = './src/site/notes/'; const startPath = "./src/site/notes/";
const fullPath = fileName.endsWith('.md') ? const fullPath = fileName.endsWith(".md")
`${startPath}${fileName}` ? `${startPath}${fileName}`
:`${startPath}${fileName}.md`; : `${startPath}${fileName}.md`;
const file = fs.readFileSync(fullPath, 'utf8'); const file = fs.readFileSync(fullPath, "utf8");
const frontMatter = matter(file); const frontMatter = matter(file);
if (frontMatter.data.permalink) { if (frontMatter.data.permalink) {
permalink = frontMatter.data.permalink; permalink = frontMatter.data.permalink;
@ -165,23 +174,42 @@ module.exports = function(eleventyConfig) {
deadLink = true; deadLink = true;
} }
return `<a class="internal-link ${deadLink?'is-unresolved':''}" href="${permalink}${headerLinkPath}">${title}</a>`; return `<a class="internal-link ${
}); deadLink ? "is-unresolved" : ""
}" href="${permalink}${headerLinkPath}">${title}</a>`;
}) })
);
});
eleventyConfig.addFilter('highlight', function(str) { eleventyConfig.addFilter("highlight", function (str) {
return str && str.replace(/\=\=(.*?)\=\=/g, function(match, p1) { return (
str &&
str.replace(/\=\=(.*?)\=\=/g, function (match, p1) {
return `<mark>${p1}</mark>`; return `<mark>${p1}</mark>`;
}); })
);
}); });
eleventyConfig.addFilter("taggify", function (str) {
return (
str &&
str.replace(
/(^|\s|\>)(#[^\s!@#$%^&*()=+\.\/,\[{\]};:'"?><]+)(?!([^<]*>))/g,
function (match, precede, tag) {
return `${precede}<a class="tag" onclick="toggleTagSearch(this)">${tag}</a>`;
}
)
);
});
eleventyConfig.addTransform('callout-block', function(str) { eleventyConfig.addTransform("callout-block", function (str) {
const parsed = parse(str); const parsed = parse(str);
const transformCalloutBlocks = (blockquotes = parsed.querySelectorAll("blockquote")) => { const transformCalloutBlocks = (
blockquotes = parsed.querySelectorAll("blockquote")
) => {
for (const blockquote of blockquotes) { for (const blockquote of blockquotes) {
transformCalloutBlocks(blockquote.querySelectorAll("blockquote")) transformCalloutBlocks(blockquote.querySelectorAll("blockquote"));
let content = blockquote.innerHTML; let content = blockquote.innerHTML;
@ -194,25 +222,34 @@ module.exports = function(eleventyConfig) {
continue; continue;
} }
content = content.replace(calloutMeta, function(metaInfoMatch, callout, collapse, title) { content = content.replace(
calloutMeta,
function (metaInfoMatch, callout, collapse, title) {
isCollapsable = Boolean(collapse); isCollapsable = Boolean(collapse);
isCollapsed = collapse === "-" isCollapsed = collapse === "-";
const titleText = title.replace(/(<\/{0,1}\w+>)/, "") ? title : `${callout.charAt(0).toUpperCase()}${callout.substring(1).toLowerCase()}` const titleText = title.replace(/(<\/{0,1}\w+>)/, "")
const fold = isCollapsable ? `<div class="callout-fold"><i icon-name="chevron-down"></i></div>` : `` ? title
: `${callout.charAt(0).toUpperCase()}${callout
.substring(1)
.toLowerCase()}`;
const fold = isCollapsable
? `<div class="callout-fold"><i icon-name="chevron-down"></i></div>`
: ``;
calloutType = callout; calloutType = callout;
titleDiv = `<div class="callout-title"><div class="callout-title-inner">${titleText}</div>${fold}</div>` titleDiv = `<div class="callout-title"><div class="callout-title-inner">${titleText}</div>${fold}</div>`;
return ""; return "";
}); }
);
blockquote.tagName = "div"; blockquote.tagName = "div";
blockquote.classList.add("callout"); blockquote.classList.add("callout");
blockquote.classList.add(isCollapsable ? "is-collapsible" : "") blockquote.classList.add(isCollapsable ? "is-collapsible" : "");
blockquote.classList.add(isCollapsed ? "is-collapsed" : "") blockquote.classList.add(isCollapsed ? "is-collapsed" : "");
blockquote.setAttribute("data-callout", calloutType.toLowerCase()); blockquote.setAttribute("data-callout", calloutType.toLowerCase());
blockquote.innerHTML = `${titleDiv}\n<div class="callout-content">${content}</div>`; blockquote.innerHTML = `${titleDiv}\n<div class="callout-content">${content}</div>`;
} }
} };
transformCalloutBlocks(); transformCalloutBlocks();
@ -220,9 +257,12 @@ module.exports = function(eleventyConfig) {
}); });
eleventyConfig.addPassthroughCopy("src/site/img"); eleventyConfig.addPassthroughCopy("src/site/img");
eleventyConfig.addPlugin(faviconPlugin, { destination: 'dist' }); eleventyConfig.addPlugin(faviconPlugin, { destination: "dist" });
eleventyConfig.addPlugin(tocPlugin, {ul:true, tags: ['h1','h2', 'h3', 'h4', 'h5', 'h6']}); eleventyConfig.addPlugin(tocPlugin, {
eleventyConfig.addFilter('jsonify', function (variable) { ul: true,
tags: ["h1", "h2", "h3", "h4", "h5", "h6"],
});
eleventyConfig.addFilter("jsonify", function (variable) {
return JSON.stringify(variable) || '""'; return JSON.stringify(variable) || '""';
}); });
@ -230,12 +270,11 @@ module.exports = function(eleventyConfig) {
dir: { dir: {
input: "src/site", input: "src/site",
output: "dist", output: "dist",
data: `_data` data: `_data`,
}, },
templateFormats: ["njk", "md", "11ty.js", "css"], templateFormats: ["njk", "md", "11ty.js", "css"],
htmlTemplateEngine: "njk", htmlTemplateEngine: "njk",
markdownTemplateEngine: "njk", markdownTemplateEngine: "njk",
passthroughFileCopy: true, passthroughFileCopy: true,
}; };
}; };

11
package-lock.json generated
View File

@ -22,7 +22,6 @@
"markdown-it": "^13.0.1", "markdown-it": "^13.0.1",
"markdown-it-attrs": "^4.1.6", "markdown-it-attrs": "^4.1.6",
"markdown-it-footnote": "^3.0.3", "markdown-it-footnote": "^3.0.3",
"markdown-it-hashtag": "^0.4.0",
"markdown-it-mathjax3": "^4.3.1", "markdown-it-mathjax3": "^4.3.1",
"markdown-it-plantuml": "^1.4.1", "markdown-it-plantuml": "^1.4.1",
"markdown-it-task-checkbox": "^1.0.6" "markdown-it-task-checkbox": "^1.0.6"
@ -3490,11 +3489,6 @@
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz", "resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz",
"integrity": "sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w==" "integrity": "sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w=="
}, },
"node_modules/markdown-it-hashtag": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/markdown-it-hashtag/-/markdown-it-hashtag-0.4.0.tgz",
"integrity": "sha512-+VCMH+f4/Ud5wPEtcAMrlLbUrrGViwR9JvjPy//X3Z7ZG1j5nQuHtDLTGZfMhkqYTMY+cTZgZkVNBsXMfU93Yg=="
},
"node_modules/markdown-it-mathjax3": { "node_modules/markdown-it-mathjax3": {
"version": "4.3.2", "version": "4.3.2",
"resolved": "https://registry.npmjs.org/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz", "resolved": "https://registry.npmjs.org/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz",
@ -9183,11 +9177,6 @@
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz", "resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz",
"integrity": "sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w==" "integrity": "sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w=="
}, },
"markdown-it-hashtag": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/markdown-it-hashtag/-/markdown-it-hashtag-0.4.0.tgz",
"integrity": "sha512-+VCMH+f4/Ud5wPEtcAMrlLbUrrGViwR9JvjPy//X3Z7ZG1j5nQuHtDLTGZfMhkqYTMY+cTZgZkVNBsXMfU93Yg=="
},
"markdown-it-mathjax3": { "markdown-it-mathjax3": {
"version": "4.3.2", "version": "4.3.2",
"resolved": "https://registry.npmjs.org/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz", "resolved": "https://registry.npmjs.org/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz",

View File

@ -36,7 +36,6 @@
"markdown-it": "^13.0.1", "markdown-it": "^13.0.1",
"markdown-it-attrs": "^4.1.6", "markdown-it-attrs": "^4.1.6",
"markdown-it-footnote": "^3.0.3", "markdown-it-footnote": "^3.0.3",
"markdown-it-hashtag": "^0.4.0",
"markdown-it-mathjax3": "^4.3.1", "markdown-it-mathjax3": "^4.3.1",
"markdown-it-plantuml": "^1.4.1", "markdown-it-plantuml": "^1.4.1",
"markdown-it-task-checkbox": "^1.0.6" "markdown-it-task-checkbox": "^1.0.6"

View File

@ -37,7 +37,7 @@ permalink: "notes/{{ page.fileSlug | slugify }}/"
</div> </div>
{% endif %} {% endif %}
</div> </div>
{{ content | link | highlight | safe}} {{ content | link | taggify | highlight | safe}}
</div> </div>
{% if settings.dgShowBacklinks === true or settings.dgShowLocalGraph === true or settings.dgShowToc === true%} {% if settings.dgShowBacklinks === true or settings.dgShowLocalGraph === true or settings.dgShowToc === true%}

View File

@ -35,7 +35,7 @@
</div> </div>
{%- for garden in collections.gardenEntry -%} {%- for garden in collections.gardenEntry -%}
{{garden.templateContent | link | highlight | safe }} {{garden.templateContent | link | taggify | highlight | safe }}
{%- endfor -%} {%- endfor -%}
</div> </div>