mirror of
https://github.com/praktimarc/kst4contest.git
synced 2026-07-13 08:07:11 +02:00
Generate manual overviews from github_docs
This commit is contained in:
@@ -1,6 +1,59 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const markdownIt = require("markdown-it");
|
||||||
|
const markdownItAnchor = require("markdown-it-anchor");
|
||||||
|
|
||||||
module.exports = function (eleventyConfig) {
|
module.exports = function (eleventyConfig) {
|
||||||
eleventyConfig.addPassthroughCopy({ "src/assets": "assets" });
|
eleventyConfig.addPassthroughCopy({ "src/assets": "assets" });
|
||||||
|
|
||||||
|
const md = markdownIt({
|
||||||
|
html: true,
|
||||||
|
linkify: true,
|
||||||
|
typographer: true
|
||||||
|
}).use(markdownItAnchor, {
|
||||||
|
permalink: markdownItAnchor.permalink.headerLink()
|
||||||
|
});
|
||||||
|
|
||||||
|
eleventyConfig.addFilter("markdown", function (value) {
|
||||||
|
return md.render(value || "");
|
||||||
|
});
|
||||||
|
|
||||||
|
eleventyConfig.addCollection("manualPages", function () {
|
||||||
|
const docsDir = path.join(__dirname, "..", "github_docs");
|
||||||
|
|
||||||
|
if (!fs.existsSync(docsDir)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return fs.readdirSync(docsDir)
|
||||||
|
.filter(file => /^(en|de)-.+\.md$/.test(file))
|
||||||
|
.map(file => {
|
||||||
|
const fullPath = path.join(docsDir, file);
|
||||||
|
const raw = fs.readFileSync(fullPath, "utf8");
|
||||||
|
|
||||||
|
const lang = file.startsWith("de-") ? "de" : "en";
|
||||||
|
const slug = file
|
||||||
|
.replace(/^en-/, "")
|
||||||
|
.replace(/^de-/, "")
|
||||||
|
.replace(/\.md$/, "")
|
||||||
|
.toLowerCase();
|
||||||
|
|
||||||
|
const title = file
|
||||||
|
.replace(/^en-/, "")
|
||||||
|
.replace(/^de-/, "")
|
||||||
|
.replace(/\.md$/, "")
|
||||||
|
.replace(/-/g, " ");
|
||||||
|
|
||||||
|
return {
|
||||||
|
file,
|
||||||
|
lang,
|
||||||
|
slug,
|
||||||
|
title,
|
||||||
|
content: raw
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dir: {
|
dir: {
|
||||||
input: "src",
|
input: "src",
|
||||||
|
|||||||
@@ -114,3 +114,37 @@ nav a:hover {
|
|||||||
padding: 40px 7vw;
|
padding: 40px 7vw;
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.manual-content {
|
||||||
|
max-width: 980px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-content h1,
|
||||||
|
.manual-content h2,
|
||||||
|
.manual-content h3 {
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-content pre {
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: #020617;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-content code {
|
||||||
|
color: #bae6fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-content table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-content th,
|
||||||
|
.manual-content td {
|
||||||
|
border-bottom: 1px solid rgba(148, 163, 184, 0.22);
|
||||||
|
padding: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
@@ -43,10 +43,97 @@
|
|||||||
|
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="card"><h3>Installation</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/de-Installation">Installationsanleitung öffnen</a></p></div>
|
|
||||||
<div class="card"><h3>Konfiguration</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/de-Konfiguration">Konfiguration öffnen</a></p></div>
|
|
||||||
<div class="card"><h3>Funktionen</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/de-Funktionen">Funktionsübersicht öffnen</a></p></div>
|
<div class="card">
|
||||||
<div class="card"><h3>AirScout-Integration</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/de-AirScout-Integration">AirScout-Anleitung öffnen</a></p></div>
|
<h3><a href="/manual/de/airscout-integration/">AirScout Integration</a></h3>
|
||||||
|
<p>Handbuchseite „AirScout Integration“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/de/benutzeroberflaeche/">Benutzeroberflaeche</a></h3>
|
||||||
|
<p>Handbuchseite „Benutzeroberflaeche“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/de/changelog/">Changelog</a></h3>
|
||||||
|
<p>Handbuchseite „Changelog“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/de/dx-cluster-server/">DX Cluster Server</a></h3>
|
||||||
|
<p>Handbuchseite „DX Cluster Server“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/de/funktionen/">Funktionen</a></h3>
|
||||||
|
<p>Handbuchseite „Funktionen“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/de/home/">Home</a></h3>
|
||||||
|
<p>Handbuchseite „Home“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/de/installation/">Installation</a></h3>
|
||||||
|
<p>Handbuchseite „Installation“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/de/konfiguration/">Konfiguration</a></h3>
|
||||||
|
<p>Handbuchseite „Konfiguration“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/de/log-synchronisation/">Log Synchronisation</a></h3>
|
||||||
|
<p>Handbuchseite „Log Synchronisation“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/de/makros-und-variablen/">Makros und Variablen</a></h3>
|
||||||
|
<p>Handbuchseite „Makros und Variablen“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -43,10 +43,97 @@
|
|||||||
|
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="card"><h3>Installation</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/en-Installation">Open installation guide</a></p></div>
|
|
||||||
<div class="card"><h3>Configuration</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/en-Configuration">Open configuration guide</a></p></div>
|
|
||||||
<div class="card"><h3>Features</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/en-Features">Open feature documentation</a></p></div>
|
|
||||||
<div class="card"><h3>AirScout Integration</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/en-AirScout-Integration">Open AirScout guide</a></p></div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/en/airscout-integration/">AirScout Integration</a></h3>
|
||||||
|
<p>Open the AirScout Integration manual page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/en/changelog/">Changelog</a></h3>
|
||||||
|
<p>Open the Changelog manual page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/en/configuration/">Configuration</a></h3>
|
||||||
|
<p>Open the Configuration manual page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/en/dx-cluster-server/">DX Cluster Server</a></h3>
|
||||||
|
<p>Open the DX Cluster Server manual page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/en/features/">Features</a></h3>
|
||||||
|
<p>Open the Features manual page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/en/home/">Home</a></h3>
|
||||||
|
<p>Open the Home manual page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/en/installation/">Installation</a></h3>
|
||||||
|
<p>Open the Installation manual page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/en/log-sync/">Log Sync</a></h3>
|
||||||
|
<p>Open the Log Sync manual page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/en/macros-and-variables/">Macros and Variables</a></h3>
|
||||||
|
<p>Open the Macros and Variables manual page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3><a href="/manual/en/user-interface/">User Interface</a></h3>
|
||||||
|
<p>Open the User Interface manual page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -39,4 +39,7 @@
|
|||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/manual/de/</loc>
|
<loc>https://kst4contest.hamradioonline.de/manual/de/</loc>
|
||||||
</url>
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/manual/de/airscout-integration/</loc>
|
||||||
|
</url>
|
||||||
</urlset>
|
</urlset>
|
||||||
+35
-7
@@ -222,6 +222,31 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/linkify-it": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@types/markdown-it": {
|
||||||
|
"version": "14.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
|
||||||
|
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/linkify-it": "^5",
|
||||||
|
"@types/mdurl": "^2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/mdurl": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/a-sync-waterfall": {
|
"node_modules/a-sync-waterfall": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
|
||||||
@@ -286,7 +311,6 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
"dev": true,
|
|
||||||
"license": "Python-2.0"
|
"license": "Python-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/asap": {
|
"node_modules/asap": {
|
||||||
@@ -1029,7 +1053,6 @@
|
|||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
|
||||||
"integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==",
|
"integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -1087,7 +1110,6 @@
|
|||||||
"version": "14.3.0",
|
"version": "14.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz",
|
||||||
"integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==",
|
"integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -1111,11 +1133,20 @@
|
|||||||
"markdown-it": "bin/markdown-it.mjs"
|
"markdown-it": "bin/markdown-it.mjs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/markdown-it-anchor": {
|
||||||
|
"version": "9.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-9.2.0.tgz",
|
||||||
|
"integrity": "sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg==",
|
||||||
|
"license": "Unlicense",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/markdown-it": "*",
|
||||||
|
"markdown-it": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/markdown-it/node_modules/entities": {
|
"node_modules/markdown-it/node_modules/entities": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.12"
|
"node": ">=0.12"
|
||||||
@@ -1128,7 +1159,6 @@
|
|||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
||||||
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/mime": {
|
"node_modules/mime": {
|
||||||
@@ -1400,7 +1430,6 @@
|
|||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
||||||
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
@@ -1618,7 +1647,6 @@
|
|||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
||||||
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/unpipe": {
|
"node_modules/unpipe": {
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) Microsoft Corporation.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
# Installation
|
||||||
|
> `npm install --save @types/linkify-it`
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
This package contains type definitions for linkify-it (https://github.com/markdown-it/linkify-it).
|
||||||
|
|
||||||
|
# Details
|
||||||
|
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/linkify-it.
|
||||||
|
|
||||||
|
### Additional Details
|
||||||
|
* Last updated: Wed, 01 May 2024 18:07:45 GMT
|
||||||
|
* Dependencies: none
|
||||||
|
|
||||||
|
# Credits
|
||||||
|
These definitions were written by [Lindsey Smith](https://github.com/praxxis), [Robert Coie](https://github.com/rapropos/typed-linkify-it), [Alex Plumb](https://github.com/alexplumb), and [Rafa Gares](https://github.com/ragafus).
|
||||||
+174
@@ -0,0 +1,174 @@
|
|||||||
|
export type Validate = (text: string, pos: number, self: LinkifyIt) => number | boolean;
|
||||||
|
|
||||||
|
export interface FullRule {
|
||||||
|
validate: string | RegExp | Validate;
|
||||||
|
normalize?: ((match: Match) => void) | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Rule = string | FullRule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object, where each key/value describes protocol/rule:
|
||||||
|
*
|
||||||
|
* - __key__ - link prefix (usually, protocol name with `:` at the end, `skype:`
|
||||||
|
* for example). `linkify-it` makes sure that prefix is not preceded with
|
||||||
|
* alphanumeric char and symbols. Only whitespaces and punctuation allowed.
|
||||||
|
* - __value__ - rule to check tail after link prefix
|
||||||
|
* - _String_ - just alias to existing rule
|
||||||
|
* - _Object_
|
||||||
|
* - _validate_ - validator function (should return matched length on success),
|
||||||
|
* or `RegExp`.
|
||||||
|
* - _normalize_ - optional function to normalize text & url of matched result
|
||||||
|
* (for example, for `@twitter` mentions).
|
||||||
|
*/
|
||||||
|
export interface SchemaRules {
|
||||||
|
[schema: string]: Rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Options {
|
||||||
|
/**
|
||||||
|
* recognize URL-s without `http(s):` prefix. Default `true`.
|
||||||
|
*/
|
||||||
|
fuzzyLink?: boolean | undefined;
|
||||||
|
/**
|
||||||
|
* allow IPs in fuzzy links above. Can conflict with some texts
|
||||||
|
* like version numbers. Default `false`.
|
||||||
|
*/
|
||||||
|
fuzzyIP?: boolean | undefined;
|
||||||
|
/**
|
||||||
|
* recognize emails without `mailto:` prefix. Default `true`.
|
||||||
|
*/
|
||||||
|
fuzzyEmail?: boolean | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match result. Single element of array, returned by {@link LinkifyIt#match}.
|
||||||
|
*/
|
||||||
|
declare class Match {
|
||||||
|
constructor(self: LinkifyIt, shift: number);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First position of matched string.
|
||||||
|
*/
|
||||||
|
index: number;
|
||||||
|
/**
|
||||||
|
* Next position after matched string.
|
||||||
|
*/
|
||||||
|
lastIndex: number;
|
||||||
|
/**
|
||||||
|
* Matched string.
|
||||||
|
*/
|
||||||
|
raw: string;
|
||||||
|
/**
|
||||||
|
* Prefix (protocol) for matched string.
|
||||||
|
*/
|
||||||
|
schema: string;
|
||||||
|
/**
|
||||||
|
* Normalized text of matched string.
|
||||||
|
*/
|
||||||
|
text: string;
|
||||||
|
/**
|
||||||
|
* Normalized url of matched string.
|
||||||
|
*/
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { Match };
|
||||||
|
|
||||||
|
declare class LinkifyIt {
|
||||||
|
/**
|
||||||
|
* new LinkifyIt(schemas, options)
|
||||||
|
* - schemas (Object): Optional. Additional schemas to validate (prefix/validator)
|
||||||
|
* - options (Object): { fuzzyLink|fuzzyEmail|fuzzyIP: true|false }
|
||||||
|
*
|
||||||
|
* Creates new linkifier instance with optional additional schemas.
|
||||||
|
* Can be called without `new` keyword for convenience.
|
||||||
|
*
|
||||||
|
* By default understands:
|
||||||
|
*
|
||||||
|
* - `http(s)://...` , `ftp://...`, `mailto:...` & `//...` links
|
||||||
|
* - "fuzzy" links and emails (example.com, foo@bar.com).
|
||||||
|
*/
|
||||||
|
constructor(schemas?: SchemaRules | Options, options?: Options);
|
||||||
|
|
||||||
|
// Use overloads to provide contextual typing to `FullRule.normalize`, which is ambiguous with string.normalize
|
||||||
|
/**
|
||||||
|
* Add new rule definition. See constructor description for details.
|
||||||
|
*
|
||||||
|
* @param schema rule name (fixed pattern prefix)
|
||||||
|
* @param definition schema definition
|
||||||
|
*/
|
||||||
|
add(schema: string, definition: string): this;
|
||||||
|
add(schema: string, definition: FullRule | null): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set recognition options for links without schema.
|
||||||
|
*/
|
||||||
|
set(options: Options): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches linkifiable pattern and returns `true` on success or `false` on fail.
|
||||||
|
*/
|
||||||
|
test(text: string): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Very quick check, that can give false positives. Returns true if link MAY BE
|
||||||
|
* can exists. Can be used for speed optimization, when you need to check that
|
||||||
|
* link NOT exists.
|
||||||
|
*/
|
||||||
|
pretest(text: string): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to {@link LinkifyIt#test} but checks only specific protocol tail exactly
|
||||||
|
* at given position. Returns length of found pattern (0 on fail).
|
||||||
|
*
|
||||||
|
* @param text text to scan
|
||||||
|
* @param schema rule (schema) name
|
||||||
|
* @param pos text offset to check from
|
||||||
|
*/
|
||||||
|
testSchemaAt(text: string, schema: string, pos: number): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns array of found link descriptions or `null` on fail. We strongly
|
||||||
|
* recommend to use {@link LinkifyIt#test} first, for best speed.
|
||||||
|
*/
|
||||||
|
match(text: string): Match[] | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns fully-formed (not fuzzy) link if it starts at the beginning
|
||||||
|
* of the string, and null otherwise.
|
||||||
|
*/
|
||||||
|
matchAtStart(text: string): Match | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load (or merge) new tlds list. Those are user for fuzzy links (without prefix)
|
||||||
|
* to avoid false positives. By default this algorythm used:
|
||||||
|
*
|
||||||
|
* - hostname with any 2-letter root zones are ok.
|
||||||
|
* - biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф
|
||||||
|
* are ok.
|
||||||
|
* - encoded (`xn--...`) root zones are ok.
|
||||||
|
*
|
||||||
|
* If list is replaced, then exact match for 2-chars root zones will be checked.
|
||||||
|
*
|
||||||
|
* @param list list of tlds
|
||||||
|
* @param keepOld merge with current list if `true` (`false` by default)
|
||||||
|
*/
|
||||||
|
tlds(list: string | string[], keepOld?: boolean): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default normalizer (if schema does not define it's own).
|
||||||
|
*/
|
||||||
|
normalize(match: Match): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override to modify basic RegExp-s.
|
||||||
|
*/
|
||||||
|
onCompile(): void;
|
||||||
|
|
||||||
|
re: {
|
||||||
|
[key: string]: RegExp;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LinkifyIt;
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
import LinkifyIt = require("./build/index.cjs.js");
|
||||||
|
|
||||||
|
export = LinkifyIt;
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"name": "@types/linkify-it",
|
||||||
|
"version": "5.0.0",
|
||||||
|
"description": "TypeScript definitions for linkify-it",
|
||||||
|
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/linkify-it",
|
||||||
|
"license": "MIT",
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"name": "Lindsey Smith",
|
||||||
|
"githubUsername": "praxxis",
|
||||||
|
"url": "https://github.com/praxxis"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Robert Coie",
|
||||||
|
"url": "https://github.com/rapropos/typed-linkify-it"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Alex Plumb",
|
||||||
|
"githubUsername": "alexplumb",
|
||||||
|
"url": "https://github.com/alexplumb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Rafa Gares",
|
||||||
|
"githubUsername": "ragafus",
|
||||||
|
"url": "https://github.com/ragafus"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"main": "",
|
||||||
|
"types": "index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./index.d.mts",
|
||||||
|
"require": "./build/index.cjs.d.ts"
|
||||||
|
},
|
||||||
|
"./*": {
|
||||||
|
"import": "./*",
|
||||||
|
"require": "./*"
|
||||||
|
},
|
||||||
|
"./package.json": "./package.json"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||||
|
"directory": "types/linkify-it"
|
||||||
|
},
|
||||||
|
"scripts": {},
|
||||||
|
"dependencies": {},
|
||||||
|
"typesPublisherContentHash": "884f8e9f827ff23c410016d9edc6e2410efbd2555c6e9e6c0ed734edd4145036",
|
||||||
|
"typeScriptVersion": "4.7"
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) Microsoft Corporation.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
# Installation
|
||||||
|
> `npm install --save @types/markdown-it`
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
This package contains type definitions for markdown-it (https://github.com/markdown-it/markdown-it).
|
||||||
|
|
||||||
|
# Details
|
||||||
|
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/markdown-it.
|
||||||
|
|
||||||
|
### Additional Details
|
||||||
|
* Last updated: Thu, 25 Jul 2024 05:07:29 GMT
|
||||||
|
* Dependencies: [@types/linkify-it](https://npmjs.com/package/@types/linkify-it), [@types/mdurl](https://npmjs.com/package/@types/mdurl)
|
||||||
|
|
||||||
|
# Credits
|
||||||
|
These definitions were written by [York Yao](https://github.com/plantain-00), [Robert Coie](https://github.com/rapropos), [duduluu](https://github.com/duduluu), and [Piotr Błażejewicz](https://github.com/peterblazejewicz).
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
export { default, Options, PluginSimple, PluginWithOptions, PluginWithParams, PresetName } from "./lib/index.mjs";
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
import MarkdownIt = require("./dist/index.cjs.js");
|
||||||
|
|
||||||
|
export = MarkdownIt;
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* List of valid html blocks names, according to commonmark spec
|
||||||
|
* @see https://spec.commonmark.org/0.30/#html-blocks
|
||||||
|
*/
|
||||||
|
declare const htmlBlocks: string[];
|
||||||
|
|
||||||
|
export default htmlBlocks;
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
export const HTML_TAG_RE: RegExp;
|
||||||
|
export const HTML_OPEN_CLOSE_TAG_RE: RegExp;
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
import * as mdurl from "mdurl";
|
||||||
|
// import * as ucmicro from "uc.micro";
|
||||||
|
|
||||||
|
export const lib: {
|
||||||
|
mdurl: typeof mdurl;
|
||||||
|
ucmicro: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge objects
|
||||||
|
*/
|
||||||
|
export function assign(obj: any, ...from: any[]): any;
|
||||||
|
|
||||||
|
export function isString(obj: any): obj is string;
|
||||||
|
|
||||||
|
export function has(obj: any, key: keyof any): boolean;
|
||||||
|
|
||||||
|
export function unescapeMd(str: string): string;
|
||||||
|
|
||||||
|
export function unescapeAll(str: string): string;
|
||||||
|
|
||||||
|
export function isValidEntityCode(c: number): boolean;
|
||||||
|
|
||||||
|
export function fromCodePoint(c: number): string;
|
||||||
|
|
||||||
|
export function escapeHtml(str: string): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove element from array and put another array at those position.
|
||||||
|
* Useful for some operations with tokens
|
||||||
|
*/
|
||||||
|
export function arrayReplaceAt<T>(src: T[], pos: number, newElements: T[]): T[];
|
||||||
|
|
||||||
|
export function isSpace(code: number): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zs (unicode class) || [\t\f\v\r\n]
|
||||||
|
*/
|
||||||
|
export function isWhiteSpace(code: number): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Markdown ASCII punctuation characters.
|
||||||
|
*
|
||||||
|
* !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, or ~
|
||||||
|
*
|
||||||
|
* Don't confuse with unicode punctuation !!! It lacks some chars in ascii range.
|
||||||
|
*
|
||||||
|
* @see http://spec.commonmark.org/0.15/#ascii-punctuation-character
|
||||||
|
*/
|
||||||
|
export function isMdAsciiPunct(code: number): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currently without astral characters support.
|
||||||
|
*/
|
||||||
|
export function isPunctChar(ch: string): boolean;
|
||||||
|
|
||||||
|
export function escapeRE(str: string): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to unify [reference labels].
|
||||||
|
*/
|
||||||
|
export function normalizeReference(str: string): string;
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
import parseLinkDestination from "./parse_link_destination.mjs";
|
||||||
|
import parseLinkLabel from "./parse_link_label.mjs";
|
||||||
|
import parseLinkTitle from "./parse_link_title.mjs";
|
||||||
|
|
||||||
|
export { parseLinkDestination, parseLinkLabel, parseLinkTitle };
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
export interface ParseLinkDestinationResult {
|
||||||
|
ok: boolean;
|
||||||
|
pos: number;
|
||||||
|
str: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function parseLinkDestination(str: string, start: number, max: number): ParseLinkDestinationResult;
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
import StateInline from "../rules_inline/state_inline.mjs";
|
||||||
|
|
||||||
|
export default function parseLinkLabel(state: StateInline, start: number, disableNested?: boolean): number;
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
export interface ParseLinkTitleResult {
|
||||||
|
/**
|
||||||
|
* if `true`, this is a valid link title
|
||||||
|
*/
|
||||||
|
ok: boolean;
|
||||||
|
/**
|
||||||
|
* if `true`, this link can be continued on the next line
|
||||||
|
*/
|
||||||
|
can_continue: boolean;
|
||||||
|
/**
|
||||||
|
* if `ok`, it's the position of the first character after the closing marker
|
||||||
|
*/
|
||||||
|
pos: number;
|
||||||
|
/**
|
||||||
|
* if `ok`, it's the unescaped title
|
||||||
|
*/
|
||||||
|
str: string;
|
||||||
|
/**
|
||||||
|
* expected closing marker character code
|
||||||
|
*/
|
||||||
|
marker: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function parseLinkTitle(
|
||||||
|
str: string,
|
||||||
|
start: number,
|
||||||
|
max: number,
|
||||||
|
prev_state?: ParseLinkTitleResult,
|
||||||
|
): ParseLinkTitleResult;
|
||||||
+404
@@ -0,0 +1,404 @@
|
|||||||
|
import LinkifyIt from "linkify-it";
|
||||||
|
|
||||||
|
import * as utils from "./common/utils.mjs";
|
||||||
|
import * as helpers from "./helpers/index.mjs";
|
||||||
|
import ParserBlock from "./parser_block.mjs";
|
||||||
|
import ParserCore from "./parser_core.mjs";
|
||||||
|
import ParserInline from "./parser_inline.mjs";
|
||||||
|
import Renderer from "./renderer.mjs";
|
||||||
|
import Token from "./token.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MarkdownIt provides named presets as a convenience to quickly
|
||||||
|
* enable/disable active syntax rules and options for common use cases.
|
||||||
|
*
|
||||||
|
* - ["commonmark"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.js) -
|
||||||
|
* configures parser to strict [CommonMark](http://commonmark.org/) mode.
|
||||||
|
* - [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.js) -
|
||||||
|
* similar to GFM, used when no preset name given. Enables all available rules,
|
||||||
|
* but still without html, typographer & autolinker.
|
||||||
|
* - ["zero"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.js) -
|
||||||
|
* all rules disabled. Useful to quickly setup your config via `.enable()`.
|
||||||
|
* For example, when you need only `bold` and `italic` markup and nothing else.
|
||||||
|
*/
|
||||||
|
export type PresetName = "default" | "zero" | "commonmark";
|
||||||
|
|
||||||
|
export interface Options {
|
||||||
|
/**
|
||||||
|
* Set `true` to enable HTML tags in source. Be careful!
|
||||||
|
* That's not safe! You may need external sanitizer to protect output from XSS.
|
||||||
|
* It's better to extend features via plugins, instead of enabling HTML.
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
html?: boolean | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set `true` to add '/' when closing single tags
|
||||||
|
* (`<br />`). This is needed only for full CommonMark compatibility. In real
|
||||||
|
* world you will need HTML output.
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
xhtmlOut?: boolean | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set `true` to convert `\n` in paragraphs into `<br>`.
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
breaks?: boolean | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CSS language class prefix for fenced blocks.
|
||||||
|
* Can be useful for external highlighters.
|
||||||
|
* @default 'language-'
|
||||||
|
*/
|
||||||
|
langPrefix?: string | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set `true` to autoconvert URL-like text to links.
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
linkify?: boolean | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set `true` to enable [some language-neutral replacement](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.js) +
|
||||||
|
* quotes beautification (smartquotes).
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
typographer?: boolean | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Double + single quotes replacement
|
||||||
|
* pairs, when typographer enabled and smartquotes on. For example, you can
|
||||||
|
* use `'«»„“'` for Russian, `'„“‚‘'` for German, and
|
||||||
|
* `['«\xA0', '\xA0»', '‹\xA0', '\xA0›']` for French (including nbsp).
|
||||||
|
* @default '“”‘’'
|
||||||
|
*/
|
||||||
|
quotes?: string | string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highlighter function for fenced code blocks.
|
||||||
|
* Highlighter `function (str, lang, attrs)` should return escaped HTML. It can
|
||||||
|
* also return empty string if the source was not changed and should be escaped
|
||||||
|
* externally. If result starts with <pre... internal wrapper is skipped.
|
||||||
|
* @default null
|
||||||
|
*/
|
||||||
|
highlight?: ((str: string, lang: string, attrs: string) => string) | null | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PluginSimple = (md: MarkdownIt) => void;
|
||||||
|
export type PluginWithOptions<T = any> = (md: MarkdownIt, options?: T) => void;
|
||||||
|
export type PluginWithParams = (md: MarkdownIt, ...params: any[]) => void;
|
||||||
|
|
||||||
|
interface MarkdownItConstructor {
|
||||||
|
new(): MarkdownIt;
|
||||||
|
new(presetName: PresetName, options?: Options): MarkdownIt;
|
||||||
|
new(options: Options): MarkdownIt;
|
||||||
|
(): MarkdownIt;
|
||||||
|
(presetName: PresetName, options?: Options): MarkdownIt;
|
||||||
|
(options: Options): MarkdownIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MarkdownIt {
|
||||||
|
/**
|
||||||
|
* Instance of {@link ParserInline}. You may need it to add new rules when
|
||||||
|
* writing plugins. For simple rules control use {@link MarkdownIt.disable} and
|
||||||
|
* {@link MarkdownIt.enable}.
|
||||||
|
*/
|
||||||
|
readonly inline: ParserInline;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of {@link ParserBlock}. You may need it to add new rules when
|
||||||
|
* writing plugins. For simple rules control use {@link MarkdownIt.disable} and
|
||||||
|
* {@link MarkdownIt.enable}.
|
||||||
|
*/
|
||||||
|
readonly block: ParserBlock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of {@link Core} chain executor. You may need it to add new rules when
|
||||||
|
* writing plugins. For simple rules control use {@link MarkdownIt.disable} and
|
||||||
|
* {@link MarkdownIt.enable}.
|
||||||
|
*/
|
||||||
|
readonly core: ParserCore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of {@link Renderer}. Use it to modify output look. Or to add rendering
|
||||||
|
* rules for new token types, generated by plugins.
|
||||||
|
*
|
||||||
|
* ##### Example
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var md = require('markdown-it')();
|
||||||
|
*
|
||||||
|
* function myToken(tokens, idx, options, env, self) {
|
||||||
|
* //...
|
||||||
|
* return result;
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* md.renderer.rules['my_token'] = myToken
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* See {@link Renderer} docs and [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js).
|
||||||
|
*/
|
||||||
|
readonly renderer: Renderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [linkify-it](https://github.com/markdown-it/linkify-it) instance.
|
||||||
|
* Used by [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js)
|
||||||
|
* rule.
|
||||||
|
*/
|
||||||
|
readonly linkify: LinkifyIt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link validation function. CommonMark allows too much in links. By default
|
||||||
|
* we disable `javascript:`, `vbscript:`, `file:` schemas, and almost all `data:...` schemas
|
||||||
|
* except some embedded image types.
|
||||||
|
*
|
||||||
|
* You can change this behaviour:
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var md = require('markdown-it')();
|
||||||
|
* // enable everything
|
||||||
|
* md.validateLink = function () { return true; }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
validateLink(url: string): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function used to encode link url to a machine-readable format,
|
||||||
|
* which includes url-encoding, punycode, etc.
|
||||||
|
*/
|
||||||
|
normalizeLink(url: string): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function used to decode link url to a human-readable format`
|
||||||
|
*/
|
||||||
|
normalizeLinkText(url: string): string;
|
||||||
|
|
||||||
|
readonly utils: typeof utils;
|
||||||
|
|
||||||
|
readonly helpers: typeof helpers;
|
||||||
|
|
||||||
|
readonly options: Options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *chainable*
|
||||||
|
*
|
||||||
|
* Set parser options (in the same format as in constructor). Probably, you
|
||||||
|
* will never need it, but you can change options after constructor call.
|
||||||
|
*
|
||||||
|
* ##### Example
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var md = require('markdown-it')()
|
||||||
|
* .set({ html: true, breaks: true })
|
||||||
|
* .set({ typographer: true });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* __Note:__ To achieve the best possible performance, don't modify a
|
||||||
|
* `markdown-it` instance options on the fly. If you need multiple configurations
|
||||||
|
* it's best to create multiple instances and initialize each with separate
|
||||||
|
* config.
|
||||||
|
*/
|
||||||
|
set(options: Options): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *chainable*, *internal*
|
||||||
|
*
|
||||||
|
* Batch load of all options and compenent settings. This is internal method,
|
||||||
|
* and you probably will not need it. But if you with - see available presets
|
||||||
|
* and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets)
|
||||||
|
*
|
||||||
|
* We strongly recommend to use presets instead of direct config loads. That
|
||||||
|
* will give better compatibility with next versions.
|
||||||
|
*/
|
||||||
|
configure(presets: PresetName): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *chainable*
|
||||||
|
*
|
||||||
|
* Enable list or rules. It will automatically find appropriate components,
|
||||||
|
* containing rules with given names. If rule not found, and `ignoreInvalid`
|
||||||
|
* not set - throws exception.
|
||||||
|
*
|
||||||
|
* ##### Example
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var md = require('markdown-it')()
|
||||||
|
* .enable(['sub', 'sup'])
|
||||||
|
* .disable('smartquotes');
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param list rule name or list of rule names to enable
|
||||||
|
* @param ignoreInvalid set `true` to ignore errors when rule not found.
|
||||||
|
*/
|
||||||
|
enable(list: string | string[], ignoreInvalid?: boolean): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *chainable*
|
||||||
|
*
|
||||||
|
* The same as {@link MarkdownIt.enable}, but turn specified rules off.
|
||||||
|
*
|
||||||
|
* @param list rule name or list of rule names to disable.
|
||||||
|
* @param ignoreInvalid set `true` to ignore errors when rule not found.
|
||||||
|
*/
|
||||||
|
disable(list: string | string[], ignoreInvalid?: boolean): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *chainable*
|
||||||
|
*
|
||||||
|
* Load specified plugin with given params into current parser instance.
|
||||||
|
* It's just a sugar to call `plugin(md, params)` with curring.
|
||||||
|
*
|
||||||
|
* ##### Example
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var iterator = require('markdown-it-for-inline');
|
||||||
|
* var md = require('markdown-it')()
|
||||||
|
* .use(iterator, 'foo_replace', 'text', function (tokens, idx) {
|
||||||
|
* tokens[idx].content = tokens[idx].content.replace(/foo/g, 'bar');
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
use(plugin: PluginSimple): this;
|
||||||
|
use<T = any>(plugin: PluginWithOptions<T>, options?: T): this;
|
||||||
|
use(plugin: PluginWithParams, ...params: any[]): this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *internal*
|
||||||
|
*
|
||||||
|
* Parse input string and returns list of block tokens (special token type
|
||||||
|
* "inline" will contain list of inline tokens). You should not call this
|
||||||
|
* method directly, until you write custom renderer (for example, to produce
|
||||||
|
* AST).
|
||||||
|
*
|
||||||
|
* `env` is used to pass data between "distributed" rules and return additional
|
||||||
|
* metadata like reference info, needed for the renderer. It also can be used to
|
||||||
|
* inject data in specific cases. Usually, you will be ok to pass `{}`,
|
||||||
|
* and then pass updated object to renderer.
|
||||||
|
*
|
||||||
|
* @param src source string
|
||||||
|
* @param env environment sandbox
|
||||||
|
*/
|
||||||
|
parse(src: string, env: any): Token[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render markdown string into html. It does all magic for you :).
|
||||||
|
*
|
||||||
|
* `env` can be used to inject additional metadata (`{}` by default).
|
||||||
|
* But you will not need it with high probability. See also comment
|
||||||
|
* in {@link MarkdownIt.parse}.
|
||||||
|
*
|
||||||
|
* @param src source string
|
||||||
|
* @param env environment sandbox
|
||||||
|
*/
|
||||||
|
render(src: string, env?: any): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *internal*
|
||||||
|
*
|
||||||
|
* The same as {@link MarkdownIt.parse} but skip all block rules. It returns the
|
||||||
|
* block tokens list with the single `inline` element, containing parsed inline
|
||||||
|
* tokens in `children` property. Also updates `env` object.
|
||||||
|
*
|
||||||
|
* @param src source string
|
||||||
|
* @param env environment sandbox
|
||||||
|
*/
|
||||||
|
parseInline(src: string, env: any): Token[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to {@link MarkdownIt.render} but for single paragraph content. Result
|
||||||
|
* will NOT be wrapped into `<p>` tags.
|
||||||
|
*
|
||||||
|
* @param src source string
|
||||||
|
* @param env environment sandbox
|
||||||
|
*/
|
||||||
|
renderInline(src: string, env?: any): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main parser/renderer class.
|
||||||
|
*
|
||||||
|
* ##### Usage
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* // node.js, "classic" way:
|
||||||
|
* var MarkdownIt = require('markdown-it'),
|
||||||
|
* md = new MarkdownIt();
|
||||||
|
* var result = md.render('# markdown-it rulezz!');
|
||||||
|
*
|
||||||
|
* // node.js, the same, but with sugar:
|
||||||
|
* var md = require('markdown-it')();
|
||||||
|
* var result = md.render('# markdown-it rulezz!');
|
||||||
|
*
|
||||||
|
* // browser without AMD, added to "window" on script load
|
||||||
|
* // Note, there are no dash.
|
||||||
|
* var md = window.markdownit();
|
||||||
|
* var result = md.render('# markdown-it rulezz!');
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Single line rendering, without paragraph wrap:
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var md = require('markdown-it')();
|
||||||
|
* var result = md.renderInline('__markdown-it__ rulezz!');
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ##### Example
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* // commonmark mode
|
||||||
|
* var md = require('markdown-it')('commonmark');
|
||||||
|
*
|
||||||
|
* // default mode
|
||||||
|
* var md = require('markdown-it')();
|
||||||
|
*
|
||||||
|
* // enable everything
|
||||||
|
* var md = require('markdown-it')({
|
||||||
|
* html: true,
|
||||||
|
* linkify: true,
|
||||||
|
* typographer: true
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ##### Syntax highlighting
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* var hljs = require('highlight.js') // https://highlightjs.org/
|
||||||
|
*
|
||||||
|
* var md = require('markdown-it')({
|
||||||
|
* highlight: function (str, lang) {
|
||||||
|
* if (lang && hljs.getLanguage(lang)) {
|
||||||
|
* try {
|
||||||
|
* return hljs.highlight(lang, str, true).value;
|
||||||
|
* } catch (__) {}
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* return ''; // use external default escaping
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Or with full wrapper override (if you need assign class to `<pre>`):
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var hljs = require('highlight.js') // https://highlightjs.org/
|
||||||
|
*
|
||||||
|
* // Actual default values
|
||||||
|
* var md = require('markdown-it')({
|
||||||
|
* highlight: function (str, lang) {
|
||||||
|
* if (lang && hljs.getLanguage(lang)) {
|
||||||
|
* try {
|
||||||
|
* return '<pre class="hljs"><code>' +
|
||||||
|
* hljs.highlight(lang, str, true).value +
|
||||||
|
* '</code></pre>';
|
||||||
|
* } catch (__) {}
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
declare const MarkdownIt: MarkdownItConstructor;
|
||||||
|
|
||||||
|
export default MarkdownIt;
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import MarkdownIt from "./index.mjs";
|
||||||
|
import Ruler from "./ruler.mjs";
|
||||||
|
import StateBlock from "./rules_block/state_block.mjs";
|
||||||
|
import Token from "./token.mjs";
|
||||||
|
|
||||||
|
export type RuleBlock = (state: StateBlock, startLine: number, endLine: number, silent: boolean) => boolean;
|
||||||
|
|
||||||
|
export default class ParserBlock {
|
||||||
|
/**
|
||||||
|
* {@link Ruler} instance. Keep configuration of block rules.
|
||||||
|
*/
|
||||||
|
ruler: Ruler<RuleBlock>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate tokens for input range
|
||||||
|
*/
|
||||||
|
tokenize(state: StateBlock, startLine: number, endLine: number): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process input string and push block tokens into `outTokens`
|
||||||
|
*/
|
||||||
|
parse(str: string, md: MarkdownIt, env: any, outTokens: Token[]): void;
|
||||||
|
|
||||||
|
State: typeof StateBlock;
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
import Ruler from "./ruler.mjs";
|
||||||
|
import StateCore from "./rules_core/state_core.mjs";
|
||||||
|
|
||||||
|
export type RuleCore = (state: StateCore) => void;
|
||||||
|
|
||||||
|
export default class Core {
|
||||||
|
/**
|
||||||
|
* {@link Ruler} instance. Keep configuration of core rules.
|
||||||
|
*/
|
||||||
|
ruler: Ruler<RuleCore>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes core chain rules.
|
||||||
|
*/
|
||||||
|
process(state: StateCore): void;
|
||||||
|
|
||||||
|
State: typeof StateCore;
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
import MarkdownIt from "./index.mjs";
|
||||||
|
import Ruler from "./ruler.mjs";
|
||||||
|
import StateInline from "./rules_inline/state_inline.mjs";
|
||||||
|
import Token from "./token.mjs";
|
||||||
|
|
||||||
|
export type RuleInline = (state: StateInline, silent: boolean) => boolean;
|
||||||
|
export type RuleInline2 = (state: StateInline) => boolean;
|
||||||
|
|
||||||
|
export default class ParserInline {
|
||||||
|
/**
|
||||||
|
* {@link Ruler} instance. Keep configuration of inline rules.
|
||||||
|
*/
|
||||||
|
ruler: Ruler<RuleInline>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Ruler} instance. Second ruler used for post-processing
|
||||||
|
* (e.g. in emphasis-like rules).
|
||||||
|
*/
|
||||||
|
ruler2: Ruler<RuleInline2>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip single token by running all rules in validation mode;
|
||||||
|
* returns `true` if any rule reported success
|
||||||
|
*/
|
||||||
|
skipToken(state: StateInline): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate tokens for input range
|
||||||
|
*/
|
||||||
|
tokenize(state: StateInline): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process input string and push inline tokens into `outTokens`
|
||||||
|
*/
|
||||||
|
parse(str: string, md: MarkdownIt, env: any, outTokens: Token[]): void;
|
||||||
|
|
||||||
|
State: typeof StateInline;
|
||||||
|
}
|
||||||
+96
@@ -0,0 +1,96 @@
|
|||||||
|
import { Options } from "./index.mjs";
|
||||||
|
import Token from "./token.mjs";
|
||||||
|
|
||||||
|
export type RenderRule = (tokens: Token[], idx: number, options: Options, env: any, self: Renderer) => string;
|
||||||
|
|
||||||
|
export interface RenderRuleRecord {
|
||||||
|
[type: string]: RenderRule | undefined;
|
||||||
|
code_inline?: RenderRule | undefined;
|
||||||
|
code_block?: RenderRule | undefined;
|
||||||
|
fence?: RenderRule | undefined;
|
||||||
|
image?: RenderRule | undefined;
|
||||||
|
hardbreak?: RenderRule | undefined;
|
||||||
|
softbreak?: RenderRule | undefined;
|
||||||
|
text?: RenderRule | undefined;
|
||||||
|
html_block?: RenderRule | undefined;
|
||||||
|
html_inline?: RenderRule | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Renderer {
|
||||||
|
/**
|
||||||
|
* Creates new {@link Renderer} instance and fill {@link Renderer#rules} with defaults.
|
||||||
|
*/
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains render rules for tokens. Can be updated and extended.
|
||||||
|
*
|
||||||
|
* ##### Example
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var md = require('markdown-it')();
|
||||||
|
*
|
||||||
|
* md.renderer.rules.strong_open = function () { return '<b>'; };
|
||||||
|
* md.renderer.rules.strong_close = function () { return '</b>'; };
|
||||||
|
*
|
||||||
|
* var result = md.renderInline(...);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Each rule is called as independent static function with fixed signature:
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* function my_token_render(tokens, idx, options, env, renderer) {
|
||||||
|
* // ...
|
||||||
|
* return renderedHTML;
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @see https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.mjs
|
||||||
|
*/
|
||||||
|
rules: RenderRuleRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render token attributes to string.
|
||||||
|
*/
|
||||||
|
renderAttrs(token: Token): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default token renderer. Can be overriden by custom function
|
||||||
|
* in {@link Renderer#rules}.
|
||||||
|
*
|
||||||
|
* @param tokens list of tokens
|
||||||
|
* @param idx token index to render
|
||||||
|
* @param options params of parser instance
|
||||||
|
*/
|
||||||
|
renderToken(tokens: Token[], idx: number, options: Options): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same as {@link Renderer.render}, but for single token of `inline` type.
|
||||||
|
*
|
||||||
|
* @param tokens list of block tokens to render
|
||||||
|
* @param options params of parser instance
|
||||||
|
* @param env additional data from parsed input (references, for example)
|
||||||
|
*/
|
||||||
|
renderInline(tokens: Token[], options: Options, env: any): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special kludge for image `alt` attributes to conform CommonMark spec.
|
||||||
|
* Don't try to use it! Spec requires to show `alt` content with stripped markup,
|
||||||
|
* instead of simple escaping.
|
||||||
|
*
|
||||||
|
* @param tokens list of block tokens to render
|
||||||
|
* @param options params of parser instance
|
||||||
|
* @param env additional data from parsed input (references, for example)
|
||||||
|
*/
|
||||||
|
renderInlineAsText(tokens: Token[], options: Options, env: any): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes token stream and generates HTML. Probably, you will never need to call
|
||||||
|
* this method directly.
|
||||||
|
*
|
||||||
|
* @param tokens list of block tokens to render
|
||||||
|
* @param options params of parser instance
|
||||||
|
* @param env additional data from parsed input (references, for example)
|
||||||
|
*/
|
||||||
|
render(tokens: Token[], options: Options, env: any): string;
|
||||||
|
}
|
||||||
+158
@@ -0,0 +1,158 @@
|
|||||||
|
export interface RuleOptions {
|
||||||
|
/**
|
||||||
|
* array with names of "alternate" chains.
|
||||||
|
*/
|
||||||
|
alt: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class, used by {@link MarkdownIt#core}, {@link MarkdownIt#block} and
|
||||||
|
* {@link MarkdownIt#inline} to manage sequences of functions (rules):
|
||||||
|
*
|
||||||
|
* - keep rules in defined order
|
||||||
|
* - assign the name to each rule
|
||||||
|
* - enable/disable rules
|
||||||
|
* - add/replace rules
|
||||||
|
* - allow assign rules to additional named chains (in the same)
|
||||||
|
* - caching lists of active rules
|
||||||
|
*
|
||||||
|
* You will not need use this class directly until write plugins. For simple
|
||||||
|
* rules control use {@link MarkdownIt.disable}, {@link MarkdownIt.enable} and
|
||||||
|
* {@link MarkdownIt.use}.
|
||||||
|
*/
|
||||||
|
export default class Ruler<T> {
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace rule by name with new function & options. Throws error if name not
|
||||||
|
* found.
|
||||||
|
*
|
||||||
|
* ##### Example
|
||||||
|
*
|
||||||
|
* Replace existing typographer replacement rule with new one:
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var md = require('markdown-it')();
|
||||||
|
*
|
||||||
|
* md.core.ruler.at('replacements', function replace(state) {
|
||||||
|
* //...
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param name rule name to replace.
|
||||||
|
* @param fn new rule function.
|
||||||
|
* @param options new rule options (not mandatory).
|
||||||
|
*/
|
||||||
|
at(name: string, fn: T, options?: RuleOptions): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new rule to chain before one with given name.
|
||||||
|
*
|
||||||
|
* ##### Example
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var md = require('markdown-it')();
|
||||||
|
*
|
||||||
|
* md.block.ruler.before('paragraph', 'my_rule', function replace(state) {
|
||||||
|
* //...
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @see {@link Ruler.after}, {@link Ruler.push}
|
||||||
|
*
|
||||||
|
* @param beforeName new rule will be added before this one.
|
||||||
|
* @param ruleName name of added rule.
|
||||||
|
* @param fn rule function.
|
||||||
|
* @param options rule options (not mandatory).
|
||||||
|
*/
|
||||||
|
before(beforeName: string, ruleName: string, fn: T, options?: RuleOptions): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new rule to chain after one with given name.
|
||||||
|
*
|
||||||
|
* ##### Example
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var md = require('markdown-it')();
|
||||||
|
*
|
||||||
|
* md.inline.ruler.after('text', 'my_rule', function replace(state) {
|
||||||
|
* //...
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @see {@link Ruler.before}, {@link Ruler.push}
|
||||||
|
*
|
||||||
|
* @param afterName new rule will be added after this one.
|
||||||
|
* @param ruleName name of added rule.
|
||||||
|
* @param fn rule function.
|
||||||
|
* @param options rule options (not mandatory).
|
||||||
|
*/
|
||||||
|
after(afterName: string, ruleName: string, fn: T, options?: RuleOptions): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push new rule to the end of chain.
|
||||||
|
*
|
||||||
|
* ##### Example
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* var md = require('markdown-it')();
|
||||||
|
*
|
||||||
|
* md.core.ruler.push('my_rule', function replace(state) {
|
||||||
|
* //...
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @see {@link Ruler.before}, {@link Ruler.after}
|
||||||
|
*
|
||||||
|
* @param ruleName name of added rule.
|
||||||
|
* @param fn rule function.
|
||||||
|
* @param options rule options (not mandatory).
|
||||||
|
*/
|
||||||
|
push(ruleName: string, fn: T, options?: RuleOptions): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable rules with given names. If any rule name not found - throw Error.
|
||||||
|
* Errors can be disabled by second param.
|
||||||
|
*
|
||||||
|
* Returns list of found rule names (if no exception happened).
|
||||||
|
*
|
||||||
|
* @see {@link Ruler.disable}, {@link Ruler.enableOnly}
|
||||||
|
*
|
||||||
|
* @param list list of rule names to enable.
|
||||||
|
* @param ignoreInvalid set `true` to ignore errors when rule not found.
|
||||||
|
*/
|
||||||
|
enable(list: string | string[], ignoreInvalid?: boolean): string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable rules with given names, and disable everything else. If any rule name
|
||||||
|
* not found - throw Error. Errors can be disabled by second param.
|
||||||
|
*
|
||||||
|
* @see {@link Ruler.disable}, {@link Ruler.enable}
|
||||||
|
*
|
||||||
|
* @param list list of rule names to enable (whitelist).
|
||||||
|
* @param ignoreInvalid set `true` to ignore errors when rule not found.
|
||||||
|
*/
|
||||||
|
enableOnly(list: string | string[], ignoreInvalid?: boolean): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable rules with given names. If any rule name not found - throw Error.
|
||||||
|
* Errors can be disabled by second param.
|
||||||
|
*
|
||||||
|
* Returns list of found rule names (if no exception happened).
|
||||||
|
*
|
||||||
|
* @see {@link Ruler.enable}, {@link Ruler.enableOnly}
|
||||||
|
*
|
||||||
|
* @param list list of rule names to disable.
|
||||||
|
* @param ignoreInvalid set `true` to ignore errors when rule not found.
|
||||||
|
*/
|
||||||
|
disable(list: string | string[], ignoreInvalid?: boolean): string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return array of active functions (rules) for given chain name. It analyzes
|
||||||
|
* rules configuration, compiles caches if not exists and returns result.
|
||||||
|
*
|
||||||
|
* Default chain name is `''` (empty string). It can't be skipped. That's
|
||||||
|
* done intentionally, to keep signature monomorphic for high speed.
|
||||||
|
*/
|
||||||
|
getRules(chainName: string): T[];
|
||||||
|
}
|
||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
import MarkdownIt from "../index.mjs";
|
||||||
|
import Token, { Nesting } from "../token.mjs";
|
||||||
|
|
||||||
|
export type ParentType = "blockquote" | "list" | "root" | "paragraph" | "reference";
|
||||||
|
|
||||||
|
export default class StateBlock {
|
||||||
|
constructor(src: string, md: MarkdownIt, env: any, tokens: Token[]);
|
||||||
|
|
||||||
|
src: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* link to parser instance
|
||||||
|
*/
|
||||||
|
md: MarkdownIt;
|
||||||
|
|
||||||
|
env: any;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal state vartiables
|
||||||
|
//
|
||||||
|
|
||||||
|
tokens: Token[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* line begin offsets for fast jumps
|
||||||
|
*/
|
||||||
|
bMarks: number[];
|
||||||
|
/**
|
||||||
|
* line end offsets for fast jumps
|
||||||
|
*/
|
||||||
|
eMarks: number[];
|
||||||
|
/**
|
||||||
|
* offsets of the first non-space characters (tabs not expanded)
|
||||||
|
*/
|
||||||
|
tShift: number[];
|
||||||
|
/**
|
||||||
|
* indents for each line (tabs expanded)
|
||||||
|
*/
|
||||||
|
sCount: number[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An amount of virtual spaces (tabs expanded) between beginning
|
||||||
|
* of each line (bMarks) and real beginning of that line.
|
||||||
|
*
|
||||||
|
* It exists only as a hack because blockquotes override bMarks
|
||||||
|
* losing information in the process.
|
||||||
|
*
|
||||||
|
* It's used only when expanding tabs, you can think about it as
|
||||||
|
* an initial tab length, e.g. bsCount=21 applied to string `\t123`
|
||||||
|
* means first tab should be expanded to 4-21%4 === 3 spaces.
|
||||||
|
*/
|
||||||
|
bsCount: number[];
|
||||||
|
|
||||||
|
// block parser variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* required block content indent (for example, if we are
|
||||||
|
* inside a list, it would be positioned after list marker)
|
||||||
|
*/
|
||||||
|
blkIndent: number;
|
||||||
|
/**
|
||||||
|
* line index in src
|
||||||
|
*/
|
||||||
|
line: number;
|
||||||
|
/**
|
||||||
|
* lines count
|
||||||
|
*/
|
||||||
|
lineMax: number;
|
||||||
|
/**
|
||||||
|
* loose/tight mode for lists
|
||||||
|
*/
|
||||||
|
tight: boolean;
|
||||||
|
/**
|
||||||
|
* indent of the current dd block (-1 if there isn't any)
|
||||||
|
*/
|
||||||
|
ddIndent: number;
|
||||||
|
/**
|
||||||
|
* indent of the current list block (-1 if there isn't any)
|
||||||
|
*/
|
||||||
|
listIndent: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used in lists to determine if they interrupt a paragraph
|
||||||
|
*/
|
||||||
|
parentType: ParentType;
|
||||||
|
|
||||||
|
level: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push new token to "stream".
|
||||||
|
*/
|
||||||
|
push(type: string, tag: string, nesting: Nesting): Token;
|
||||||
|
|
||||||
|
isEmpty(line: number): boolean;
|
||||||
|
|
||||||
|
skipEmptyLines(from: number): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip spaces from given position.
|
||||||
|
*/
|
||||||
|
skipSpaces(pos: number): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip spaces from given position in reverse.
|
||||||
|
*/
|
||||||
|
skipSpacesBack(pos: number, min: number): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip char codes from given position
|
||||||
|
*/
|
||||||
|
skipChars(pos: number, code: number): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip char codes reverse from given position - 1
|
||||||
|
*/
|
||||||
|
skipCharsBack(pos: number, code: number, min: number): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cut lines range from source.
|
||||||
|
*/
|
||||||
|
getLines(begin: number, end: number, indent: number, keepLastLF: boolean): string;
|
||||||
|
|
||||||
|
Token: typeof Token;
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
import MarkdownIt from "../index.mjs";
|
||||||
|
import Token from "../token.mjs";
|
||||||
|
|
||||||
|
export default class StateCore {
|
||||||
|
constructor(src: string, md: MarkdownIt, env: any);
|
||||||
|
|
||||||
|
src: string;
|
||||||
|
env: any;
|
||||||
|
tokens: Token[];
|
||||||
|
inlineMode: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* link to parser instance
|
||||||
|
*/
|
||||||
|
md: MarkdownIt;
|
||||||
|
|
||||||
|
Token: typeof Token;
|
||||||
|
}
|
||||||
+73
@@ -0,0 +1,73 @@
|
|||||||
|
import MarkdownIt from "../index.mjs";
|
||||||
|
import Token, { Nesting } from "../token.mjs";
|
||||||
|
|
||||||
|
export interface Scanned {
|
||||||
|
can_open: boolean;
|
||||||
|
can_close: boolean;
|
||||||
|
length: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Delimiter {
|
||||||
|
marker: number;
|
||||||
|
length: number;
|
||||||
|
token: number;
|
||||||
|
end: number;
|
||||||
|
open: boolean;
|
||||||
|
close: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TokenMeta {
|
||||||
|
delimiters: Delimiter[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class StateInline {
|
||||||
|
constructor(src: string, md: MarkdownIt, env: any, outTokens: Token[]);
|
||||||
|
|
||||||
|
src: string;
|
||||||
|
env: any;
|
||||||
|
md: MarkdownIt;
|
||||||
|
tokens: Token[];
|
||||||
|
tokens_meta: Array<TokenMeta | null>;
|
||||||
|
|
||||||
|
pos: number;
|
||||||
|
posMax: number;
|
||||||
|
level: number;
|
||||||
|
pending: string;
|
||||||
|
pendingLevel: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores { start: end } pairs. Useful for backtrack
|
||||||
|
* optimization of pairs parse (emphasis, strikes).
|
||||||
|
*/
|
||||||
|
cache: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of emphasis-like delimiters for current tag
|
||||||
|
*/
|
||||||
|
delimiters: Delimiter[];
|
||||||
|
|
||||||
|
// Stack of delimiter lists for upper level tags
|
||||||
|
// _prev_delimiters: StateInline.Delimiter[][];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush pending text
|
||||||
|
*/
|
||||||
|
pushPending(): Token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push new token to "stream".
|
||||||
|
* If pending text exists - flush it as text token
|
||||||
|
*/
|
||||||
|
push(type: string, tag: string, nesting: Nesting): Token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan a sequence of emphasis-like markers, and determine whether
|
||||||
|
* it can start an emphasis sequence or end an emphasis sequence.
|
||||||
|
*
|
||||||
|
* @param start position to scan from (it should point at a valid marker)
|
||||||
|
* @param canSplitWord determine if these markers can be found inside a word
|
||||||
|
*/
|
||||||
|
scanDelims(start: number, canSplitWord: boolean): Scanned;
|
||||||
|
|
||||||
|
Token: typeof Token;
|
||||||
|
}
|
||||||
+108
@@ -0,0 +1,108 @@
|
|||||||
|
export type Nesting = 1 | 0 | -1;
|
||||||
|
|
||||||
|
export default class Token {
|
||||||
|
/**
|
||||||
|
* Create new token and fill passed properties.
|
||||||
|
*/
|
||||||
|
constructor(type: string, tag: string, nesting: Nesting);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of the token, e.g. "paragraph_open"
|
||||||
|
*/
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML tag name, e.g. "p"
|
||||||
|
*/
|
||||||
|
tag: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML attributes. Format: `[ [ name1, value1 ], [ name2, value2 ] ]`
|
||||||
|
*/
|
||||||
|
attrs: Array<[string, string]> | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source map info. Format: `[ line_begin, line_end ]`
|
||||||
|
*/
|
||||||
|
map: [number, number] | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Level change (number in {-1, 0, 1} set), where:
|
||||||
|
*
|
||||||
|
* - `1` means the tag is opening
|
||||||
|
* - `0` means the tag is self-closing
|
||||||
|
* - `-1` means the tag is closing
|
||||||
|
*/
|
||||||
|
nesting: Nesting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nesting level, the same as `state.level`
|
||||||
|
*/
|
||||||
|
level: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of child nodes (inline and img tokens)
|
||||||
|
*/
|
||||||
|
children: Token[] | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In a case of self-closing tag (code, html, fence, etc.),
|
||||||
|
* it has contents of this tag.
|
||||||
|
*/
|
||||||
|
content: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* '*' or '_' for emphasis, fence string for fence, etc.
|
||||||
|
*/
|
||||||
|
markup: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* - Info string for "fence" tokens
|
||||||
|
* - The value "auto" for autolink "link_open" and "link_close" tokens
|
||||||
|
* - The string value of the item marker for ordered-list "list_item_open" tokens
|
||||||
|
*/
|
||||||
|
info: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A place for plugins to store an arbitrary data
|
||||||
|
*/
|
||||||
|
meta: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True for block-level tokens, false for inline tokens.
|
||||||
|
* Used in renderer to calculate line breaks
|
||||||
|
*/
|
||||||
|
block: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If it's true, ignore this element when rendering. Used for tight lists
|
||||||
|
* to hide paragraphs.
|
||||||
|
*/
|
||||||
|
hidden: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search attribute index by name.
|
||||||
|
*/
|
||||||
|
attrIndex(name: string): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add `[ name, value ]` attribute to list. Init attrs if necessary
|
||||||
|
*/
|
||||||
|
attrPush(attrData: [string, string]): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set `name` attribute to `value`. Override old value if exists.
|
||||||
|
*/
|
||||||
|
attrSet(name: string, value: string): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of attribute `name`, or null if it does not exist.
|
||||||
|
*/
|
||||||
|
attrGet(name: string): string | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Join value to existing attribute via space. Or create new attribute if not
|
||||||
|
* exists. Useful to operate with token classes.
|
||||||
|
*/
|
||||||
|
attrJoin(name: string, value: string): void;
|
||||||
|
}
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"name": "@types/markdown-it",
|
||||||
|
"version": "14.1.2",
|
||||||
|
"description": "TypeScript definitions for markdown-it",
|
||||||
|
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/markdown-it",
|
||||||
|
"license": "MIT",
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"name": "York Yao",
|
||||||
|
"githubUsername": "plantain-00",
|
||||||
|
"url": "https://github.com/plantain-00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Robert Coie",
|
||||||
|
"githubUsername": "rapropos",
|
||||||
|
"url": "https://github.com/rapropos"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "duduluu",
|
||||||
|
"githubUsername": "duduluu",
|
||||||
|
"url": "https://github.com/duduluu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Piotr Błażejewicz",
|
||||||
|
"githubUsername": "peterblazejewicz",
|
||||||
|
"url": "https://github.com/peterblazejewicz"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"main": "",
|
||||||
|
"types": "index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./index.d.mts",
|
||||||
|
"require": "./dist/index.cjs.d.ts"
|
||||||
|
},
|
||||||
|
"./*": {
|
||||||
|
"import": "./*",
|
||||||
|
"require": "./*"
|
||||||
|
},
|
||||||
|
"./package.json": "./package.json"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||||
|
"directory": "types/markdown-it"
|
||||||
|
},
|
||||||
|
"scripts": {},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/linkify-it": "^5",
|
||||||
|
"@types/mdurl": "^2"
|
||||||
|
},
|
||||||
|
"typesPublisherContentHash": "72b750af20eb4973f000b8b6a751de43787503125afcd200798f88f096b221e7",
|
||||||
|
"typeScriptVersion": "4.8"
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) Microsoft Corporation.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
# Installation
|
||||||
|
> `npm install --save @types/mdurl`
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
This package contains type definitions for mdurl (https://github.com/markdown-it/mdurl#readme).
|
||||||
|
|
||||||
|
# Details
|
||||||
|
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/mdurl.
|
||||||
|
|
||||||
|
### Additional Details
|
||||||
|
* Last updated: Wed, 01 May 2024 18:07:45 GMT
|
||||||
|
* Dependencies: none
|
||||||
|
|
||||||
|
# Credits
|
||||||
|
These definitions were written by [Junyoung Choi](https://github.com/rokt33r).
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
import decode from "./lib/decode.mjs";
|
||||||
|
import encode from "./lib/encode.mjs";
|
||||||
|
import format from "./lib/format.mjs";
|
||||||
|
import parse, { Url } from "./lib/parse.mjs";
|
||||||
|
|
||||||
|
export { decode, encode, format, parse, Url };
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
import mdurl = require("./build/index.cjs.js");
|
||||||
|
|
||||||
|
export = mdurl;
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
declare const decode: {
|
||||||
|
defaultChars: string;
|
||||||
|
componentChars: string;
|
||||||
|
/**
|
||||||
|
* Decode percent-encoded string.
|
||||||
|
*/
|
||||||
|
(str: string, exclude?: string): string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default decode;
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
declare const encode: {
|
||||||
|
defaultChars: string;
|
||||||
|
componentChars: string;
|
||||||
|
/**
|
||||||
|
* Encode unsafe characters with percent-encoding, skipping already
|
||||||
|
* encoded sequences.
|
||||||
|
*
|
||||||
|
* @param str string to encode
|
||||||
|
* @param exclude list of characters to ignore (in addition to a-zA-Z0-9)
|
||||||
|
* @param keepEscaped don't encode '%' in a correct escape sequence (default: true)
|
||||||
|
*/
|
||||||
|
(str: string, exclude?: string, keepEscaped?: boolean): string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default encode;
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
import { Url } from "./parse.mjs";
|
||||||
|
|
||||||
|
export default function format(url: Omit<Url, "parse" | "parseHost">): string;
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
declare class Url {
|
||||||
|
protocol: string;
|
||||||
|
slashes: string;
|
||||||
|
auth: string;
|
||||||
|
port: string;
|
||||||
|
hostname: string;
|
||||||
|
hash: string;
|
||||||
|
search: string;
|
||||||
|
pathname: string;
|
||||||
|
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
parse(url: string, slashesDenoteHost?: boolean): this;
|
||||||
|
parseHost(host: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function parse(url: string | Url, slashesDenoteHost?: boolean): Url;
|
||||||
|
export type { Url };
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "@types/mdurl",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"description": "TypeScript definitions for mdurl",
|
||||||
|
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/mdurl",
|
||||||
|
"license": "MIT",
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"name": "Junyoung Choi",
|
||||||
|
"githubUsername": "rokt33r",
|
||||||
|
"url": "https://github.com/rokt33r"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"main": "",
|
||||||
|
"types": "index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./index.d.mts",
|
||||||
|
"require": "./build/index.cjs.d.ts"
|
||||||
|
},
|
||||||
|
"./*": {
|
||||||
|
"import": "./*",
|
||||||
|
"require": "./*"
|
||||||
|
},
|
||||||
|
"./package.json": "./package.json"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||||
|
"directory": "types/mdurl"
|
||||||
|
},
|
||||||
|
"scripts": {},
|
||||||
|
"dependencies": {},
|
||||||
|
"typesPublisherContentHash": "3dc3a8535d7207c6d737adfe2aac315c7f6546b2372bd343794994106ee251a5",
|
||||||
|
"typeScriptVersion": "4.7"
|
||||||
|
}
|
||||||
+600
@@ -0,0 +1,600 @@
|
|||||||
|
# markdown-it-anchor [](https://www.npmjs.org/package/markdown-it-anchor)
|
||||||
|
|
||||||
|
> A markdown-it plugin that adds an `id` attribute to headings and
|
||||||
|
> optionally permalinks.
|
||||||
|
|
||||||
|
[markdown-it]: https://github.com/markdown-it/markdown-it
|
||||||
|
|
||||||
|
English | [中文 (v7.0.1)](./README-zh_CN.md)
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This plugin adds an `id` attribute to headings, e.g. `## Foo` becomes
|
||||||
|
`<h2 id="foo">Foo</h2>`.
|
||||||
|
|
||||||
|
Optionally it can also include [permalinks](#permalinks), e.g.
|
||||||
|
`<h2 id="foo"><a class="header-anchor" href="#foo">Foo</a></h2>`
|
||||||
|
and a bunch of other variants!
|
||||||
|
|
||||||
|
* [**Usage**](#usage)
|
||||||
|
* [User-friendly URLs](#user-friendly-urls)
|
||||||
|
* [Manually setting the `id` attribute](#manually-setting-the-id-attribute)
|
||||||
|
* [Compatible table of contents plugin](#compatible-table-of-contents-plugin)
|
||||||
|
* [Parsing headings from HTML blocks](#parsing-headings-from-html-blocks)
|
||||||
|
* [Browser example](#browser-example)
|
||||||
|
* [**Permalinks**](#permalinks)
|
||||||
|
* [Header link](#header-link)
|
||||||
|
* [Link after header](#link-after-header)
|
||||||
|
* [Link inside header](#link-inside-header)
|
||||||
|
* [ARIA hidden](#aria-hidden)
|
||||||
|
* [Custom permalink](#custom-permalink)
|
||||||
|
* [Debugging](#debugging)
|
||||||
|
* [Development](#development)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
.use(require('markdown-it-anchor'), opts)
|
||||||
|
```
|
||||||
|
|
||||||
|
See a [demo as JSFiddle](https://jsfiddle.net/9ukc8dy6/).
|
||||||
|
|
||||||
|
The `opts` object can contain:
|
||||||
|
|
||||||
|
| Name | Description | Default |
|
||||||
|
|------------------------|---------------------------------------------------------------------------|-----------------------------------------|
|
||||||
|
| `level` | Minimum level to apply anchors, or array of selected levels. | 1 |
|
||||||
|
| `permalink` | A function to render permalinks, see [permalinks] below. | `undefined` |
|
||||||
|
| `slugify` | A custom slugification function. | See [`index.js`][index-slugify] |
|
||||||
|
| `callback` | Called with token and info after rendering. | `undefined` |
|
||||||
|
| `getTokensText` | A custom function to get the text contents of the title from its tokens. | See [`index.js`][index-get-tokens-text] |
|
||||||
|
| `tabIndex` | Value of the `tabindex` attribute on headings, set to `false` to disable. | `-1` |
|
||||||
|
| `uniqueSlugStartIndex` | Index to start with when making duplicate slugs unique. | 1 |
|
||||||
|
|
||||||
|
[index-slugify]: https://github.com/valeriangalliat/markdown-it-anchor/blob/master/index.js#L3
|
||||||
|
[index-get-tokens-text]: https://github.com/valeriangalliat/markdown-it-anchor/blob/master/index.js#L5
|
||||||
|
[permalinks]: #permalinks
|
||||||
|
|
||||||
|
All headers greater than the minimum `level` will have an `id` attribute
|
||||||
|
with a slug of their content. For example, you can set `level` to 2 to
|
||||||
|
add anchors to all headers but `h1`. You can also pass an array of
|
||||||
|
header levels to apply the anchor, like `[2, 3]` to have an anchor on
|
||||||
|
only level 2 and 3 headers.
|
||||||
|
|
||||||
|
If a `permalink` renderer is given, it will be called for each matching header
|
||||||
|
to add a permalink. See [permalinks] below.
|
||||||
|
|
||||||
|
If a `slugify` function is given, you can decide how to transform a
|
||||||
|
heading text to a URL slug. See [user-friendly URLs](#user-friendly-urls).
|
||||||
|
|
||||||
|
The `callback` option is a function that will be called at the end of
|
||||||
|
rendering with the `token` and an `info` object. The `info` object has
|
||||||
|
`title` and `slug` properties with the token content and the slug used
|
||||||
|
for the identifier.
|
||||||
|
|
||||||
|
We set by default [`tabindex="-1"`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex)
|
||||||
|
on headers. This marks the headers as focusable elements that are not
|
||||||
|
reachable by keyboard navigation. The effect is that screen readers will
|
||||||
|
read the title content when it's being jumped to. Outside of screen
|
||||||
|
readers, the experience is the same as not setting that attribute. You
|
||||||
|
can override this behavior with the `tabIndex` option. Set it to `false`
|
||||||
|
to remove the attribute altogether, otherwise the value will be used as
|
||||||
|
attribute value.
|
||||||
|
|
||||||
|
Finally, you can customize how the title text is extracted from the
|
||||||
|
markdown-it tokens (to later generate the slug). See [user-friendly URLs](#user-friendly-urls).
|
||||||
|
|
||||||
|
## User-friendly URLs
|
||||||
|
|
||||||
|
Starting from v5.0.0, markdown-it-anchor dropped the [`string`](https://github.com/jprichardson/string.js)
|
||||||
|
package to retain our core value of being an impartial and secure
|
||||||
|
library. Nevertheless, users looking for backward compatibility may want
|
||||||
|
the old `slugify` function:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install string
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
const string = require('string')
|
||||||
|
const slugify = s => string(s).slugify().toString()
|
||||||
|
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
.use(require('markdown-it-anchor'), { slugify })
|
||||||
|
```
|
||||||
|
|
||||||
|
Another popular library for this is [`@sindresorhus/slugify`](https://github.com/sindresorhus/slugify),
|
||||||
|
which have better Unicode support and other cool features:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install @sindresorhus/slugify
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
const slugify = require('@sindresorhus/slugify')
|
||||||
|
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
.use(require('markdown-it-anchor'), { slugify: s => slugify(s) })
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custimizing the slugify input
|
||||||
|
|
||||||
|
Additionally, if you want to further customize the title that gets
|
||||||
|
passed to the `slugify` function, you can do so by customizing the
|
||||||
|
`getTokensText` function, that gets the plain text from a list of
|
||||||
|
markdown-it inline tokens:
|
||||||
|
|
||||||
|
```js
|
||||||
|
function getTokensText (tokens) {
|
||||||
|
return tokens
|
||||||
|
.filter(token => !['html_inline', 'image'].includes(token.type))
|
||||||
|
.map(t => t.content)
|
||||||
|
.join('')
|
||||||
|
}
|
||||||
|
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
.use(require('markdown-it-anchor'), { getTokensText })
|
||||||
|
```
|
||||||
|
|
||||||
|
By default we include only `text` and `code_inline` tokens, which
|
||||||
|
appeared to be a sensible approach for the vast majority of use cases.
|
||||||
|
|
||||||
|
An alternative approach is to include every token's content except for
|
||||||
|
`html_inline` and `image` tokens, which yields the exact same results as
|
||||||
|
the previous approach with a stock markdown-it, but would also include
|
||||||
|
custom tokens added by any of your markdown-it plugins, which might or
|
||||||
|
might not be desirable for you. Now you have the option!
|
||||||
|
|
||||||
|
### Slugifying with state
|
||||||
|
|
||||||
|
If you need access to the markdown-it state from the slugify function,
|
||||||
|
e.g. to access `state.env`, you can use `slugifyWithState` instead.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
.use(require('markdown-it-anchor'), {
|
||||||
|
slugifyWithState: (title, state) => `${state.env.id}-${slugify(title)}`
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Manually setting the `id` attribute
|
||||||
|
|
||||||
|
You might want to explicitly set the `id` attribute of your headings
|
||||||
|
from the Markdown document, for example to keep them consistent across
|
||||||
|
translations.
|
||||||
|
|
||||||
|
markdown-it-anchor is designed to reuse any existing `id`, making [markdown-it-attrs](https://www.npmjs.com/package/markdown-it-attrs)
|
||||||
|
a perfect fit for this use case. Make sure to load it before markdown-it-anchor!
|
||||||
|
|
||||||
|
Then you can do something like this:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Your title {#your-custom-id}
|
||||||
|
```
|
||||||
|
|
||||||
|
The anchor link will reuse the `id` that you explicitly defined.
|
||||||
|
|
||||||
|
## Compatible table of contents plugin
|
||||||
|
|
||||||
|
Looking for an automatic table of contents (TOC) generator? Take a look at
|
||||||
|
[markdown-it-toc-done-right](https://www.npmjs.com/package/markdown-it-toc-done-right)
|
||||||
|
it's made from the ground to be a great companion of this plugin.
|
||||||
|
|
||||||
|
## Parsing headings from HTML blocks
|
||||||
|
|
||||||
|
markdown-it-anchor doesn't parse HTML blocks, so headings defined in
|
||||||
|
HTML blocks will be ignored. If you need to add anchors to both HTML
|
||||||
|
headings and Markdown headings, the easiest way would be to do it on the
|
||||||
|
final HTML rather than during the Markdown parsing phase:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { parse } = require('node-html-parser')
|
||||||
|
|
||||||
|
const root = parse(html)
|
||||||
|
|
||||||
|
for (const h of root.querySelectorAll('h1, h2, h3, h4, h5, h6')) {
|
||||||
|
const slug = h.getAttribute('id') || slugify(h.textContent)
|
||||||
|
h.setAttribute('id', slug)
|
||||||
|
h.innerHTML = `<a href="#${slug}">${h.innerHTML}</a>`
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(root.toString())
|
||||||
|
```
|
||||||
|
|
||||||
|
Or with a (not accessible) GitHub-style anchor, replace the
|
||||||
|
`h.innerHTML` part with:
|
||||||
|
|
||||||
|
```js
|
||||||
|
h.insertAdjacentHTML('afterbegin', `<a class="anchor" aria-hidden="true" href="#${slug}">🔗</a> `)
|
||||||
|
```
|
||||||
|
|
||||||
|
While this still needs extra work like handling duplicated slugs and
|
||||||
|
IDs, this should give you a solid base.
|
||||||
|
|
||||||
|
That said if you really want to use markdown-it-anchor for this even
|
||||||
|
though it's not designed to, you can do like npm does with their
|
||||||
|
[marky-markdown](https://github.com/npm/marky-markdown) parser, and
|
||||||
|
[transform the `html_block` tokens](https://github.com/npm/marky-markdown/blob/master/lib/plugin/html-heading.js)
|
||||||
|
into a sequence of `heading_open`, `inline`, and `heading_close` tokens
|
||||||
|
that can be handled by markdown-it-anchor:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
.use(require('@npmcorp/marky-markdown/lib/plugin/html-heading'))
|
||||||
|
.use(require('markdown-it-anchor'), opts)
|
||||||
|
```
|
||||||
|
|
||||||
|
While they use regexes to parse the HTML and it won't gracefully handle
|
||||||
|
any arbitrary HTML, it should work okay for the happy path, which might
|
||||||
|
be good enough for you.
|
||||||
|
|
||||||
|
You might also want to check [this implementation](https://github.com/valeriangalliat/markdown-it-anchor/issues/105#issuecomment-907323858)
|
||||||
|
which uses [Cheerio](https://www.npmjs.com/package/cheerio) for a more
|
||||||
|
solid parsing, including support for HTML attributes.
|
||||||
|
|
||||||
|
The only edge cases I see it failing with are multiple headings defined
|
||||||
|
in the same HTML block with arbitrary content between them, or headings
|
||||||
|
where the opening and closing tag are defined in separate `html_block`
|
||||||
|
tokens, both which should very rarely happen.
|
||||||
|
|
||||||
|
If you need a bulletproof implementation, I would recommend the first
|
||||||
|
HTML parser approach I documented instead.
|
||||||
|
|
||||||
|
## Browser example
|
||||||
|
|
||||||
|
See [`example.html`](example.html).
|
||||||
|
|
||||||
|
## Permalinks
|
||||||
|
|
||||||
|
Version 8.0.0 completely reworked the way permalinks work in order to
|
||||||
|
offer more accessible options out of the box. You can also [make your own permalink](#custom-permalink).
|
||||||
|
|
||||||
|
Instead of a single default way of rendering permalinks (which used to
|
||||||
|
have a poor UX on screen readers), we now have multiple styles of
|
||||||
|
permalinks for you to chose from.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const anchor = require('markdown-it-anchor')
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
|
||||||
|
md.use(anchor, {
|
||||||
|
permalink: anchor.permalink[styleOfPermalink](permalinkOpts)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, `styleOfPermalink` is one of the available styles documented
|
||||||
|
below, and `permalinkOpts` is an options object.
|
||||||
|
|
||||||
|
<div id="common-options"></div>
|
||||||
|
|
||||||
|
All renderers share a common set of options:
|
||||||
|
|
||||||
|
| Name | Description | Default |
|
||||||
|
|---------------|---------------------------------------------------|------------------------------------|
|
||||||
|
| `class` | The class of the permalink anchor. | `header-anchor` |
|
||||||
|
| `symbol` | The symbol in the permalink anchor. | `#` |
|
||||||
|
| `renderHref` | A custom permalink `href` rendering function. | See [`permalink.js`](permalink.js) |
|
||||||
|
| `renderAttrs` | A custom permalink attributes rendering function. | See [`permalink.js`](permalink.js) |
|
||||||
|
|
||||||
|
For the `symbol`, you may want to use the [link symbol](http://graphemica.com/🔗),
|
||||||
|
or a symbol from your favorite web font.
|
||||||
|
|
||||||
|
### Header link
|
||||||
|
|
||||||
|
This style wraps the header itself in an anchor link. It doesn't use the
|
||||||
|
`symbol` option as there's no symbol needed in the markup (though you
|
||||||
|
could add it with CSS using `::before` if you like).
|
||||||
|
|
||||||
|
It's so simple it doesn't have any behaviour to custom, and it's also
|
||||||
|
accessible out of the box without any further configuration, hence it
|
||||||
|
doesn't have other options than the common ones described above.
|
||||||
|
|
||||||
|
You can find this style on the [MDN] as well as [HTTP Archive] and their
|
||||||
|
[Web Almanac], which to me is a good sign that this is a thoughtful way of
|
||||||
|
implementing permalinks. This is also the style that I chose for my own
|
||||||
|
[blog].
|
||||||
|
|
||||||
|
[MDN]: https://developer.mozilla.org/en-US/docs/Web
|
||||||
|
[HTTP Archive]: https://httparchive.org/reports/state-of-the-web
|
||||||
|
[Web Almanac]: https://almanac.httparchive.org/en/2020/table-of-contents
|
||||||
|
[blog]: https://www.codejam.info/
|
||||||
|
|
||||||
|
|
||||||
|
| Name | Description | Default |
|
||||||
|
|-------------------|-----------------------------------------------------------------------|---------------------------------------|
|
||||||
|
| `safariReaderFix` | Add a `span` inside the link so Safari shows headings in reader view. | `false` (for backwards compatibility) |
|
||||||
|
| | See [common options](#common-options). | |
|
||||||
|
|
||||||
|
```js
|
||||||
|
const anchor = require('markdown-it-anchor')
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
|
||||||
|
md.use(anchor, {
|
||||||
|
permalink: anchor.permalink.headerLink()
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h2 id="title"><a class="header-anchor" href="#title">Title</a></h2>
|
||||||
|
```
|
||||||
|
|
||||||
|
The main caveat of this approach is that you can't include links inside
|
||||||
|
headers. If you do, consider the other styles.
|
||||||
|
|
||||||
|
Also note that this pattern [breaks reader mode in Safari](https://www.leereamsnyder.com/blog/making-headings-with-links-show-up-in-safari-reader),
|
||||||
|
an issue you can also notice on the referenced websites above. This was
|
||||||
|
already [reported to Apple](https://bugs.webkit.org/show_bug.cgi?id=225609#c2)
|
||||||
|
but their bug tracker is not public. In the meantime, a fix mentioned in
|
||||||
|
the article above is to insert a `span` inside the link. You can use the
|
||||||
|
`safariReaderFix` option to enable it.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const anchor = require('markdown-it-anchor')
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
|
||||||
|
md.use(anchor, {
|
||||||
|
permalink: anchor.permalink.headerLink({ safariReaderFix: true })
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h2 id="title"><a class="header-anchor" href="#title"><span>Title</span></a></h2>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Link after header
|
||||||
|
|
||||||
|
If you want to customize further the screen reader experience of your
|
||||||
|
permalinks, this style gives you much more freedom than the [header link](#header-link).
|
||||||
|
|
||||||
|
It works by leaving the header itself alone, and adding the permalink
|
||||||
|
*after* it, giving you different methods of customizing the assistive
|
||||||
|
text. It makes the permalink symbol `aria-hidden` to not pollute the
|
||||||
|
experience, and leverages a `visuallyHiddenClass` to hide the assistive
|
||||||
|
text from the visual experience.
|
||||||
|
|
||||||
|
| Name | Description | Default |
|
||||||
|
|-----------------------|-----------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------|
|
||||||
|
| `style` | The (sub) style of link, one of `visually-hidden`, `aria-label`, `aria-describedby` or `aria-labelledby`. | `visually-hidden` |
|
||||||
|
| `assistiveText` | A function that takes the title and returns the assistive text. | `undefined`, required for `visually-hidden` and `aria-label` styles |
|
||||||
|
| `visuallyHiddenClass` | The class you use to make an element visually hidden. | `undefined`, required for `visually-hidden` style |
|
||||||
|
| `space` | Add a space between the assistive text and the permalink symbol. | `true` |
|
||||||
|
| `placement` | Placement of the permalink symbol relative to the assistive text, can be `before` or `after` the header. | `after` |
|
||||||
|
| `wrapper` | Opening and closing wrapper string, e.g. `['<div class="wrapper">', '</div>']`. | `null` |
|
||||||
|
| | See [common options](#common-options). | |
|
||||||
|
|
||||||
|
```js
|
||||||
|
const anchor = require('markdown-it-anchor')
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
|
||||||
|
md.use(anchor, {
|
||||||
|
permalink: anchor.permalink.linkAfterHeader({
|
||||||
|
style: 'visually-hidden',
|
||||||
|
assistiveText: title => `Permalink to “${title}”`,
|
||||||
|
visuallyHiddenClass: 'visually-hidden',
|
||||||
|
wrapper: ['<div class="wrapper">', '</div>']
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="wrapper">
|
||||||
|
<h2 id="title">Title</h2>
|
||||||
|
<a class="header-anchor" href="#title">
|
||||||
|
<span class="visually-hidden">Permalink to “Title”</span>
|
||||||
|
<span aria-hidden="true">#</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
By using a visually hidden element for the assistive text, we make sure
|
||||||
|
that the assistive text can be picked up by translation services, as
|
||||||
|
most of the popular translation services (including Google Translate)
|
||||||
|
currently ignore `aria-label`.
|
||||||
|
|
||||||
|
If you prefer an alternative method for the assistive text, see other
|
||||||
|
styles:
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><code>aria-label</code> variant</summary>
|
||||||
|
|
||||||
|
This removes the need from a visually hidden `span`, but will likely
|
||||||
|
hurt the permalink experience when using a screen reader through a
|
||||||
|
translation service.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const anchor = require('markdown-it-anchor')
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
|
||||||
|
md.use(anchor, {
|
||||||
|
permalink: anchor.permalink.linkAfterHeader({
|
||||||
|
style: 'aria-label'
|
||||||
|
assistiveText: title => `Permalink to “${title}”`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h2 id="title">Title</h2>
|
||||||
|
<a class="header-anchor" href="#title" aria-label="Permalink to “Title”">#</a>
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><code>aria-describedby</code> and <code>aria-labelledby</code> variants</summary>
|
||||||
|
|
||||||
|
This removes the need to customize the assistive text to your locale and
|
||||||
|
doesn't need a visually hidden `span` either, but since the anchor will
|
||||||
|
be described by just the text of the title without any context, it might
|
||||||
|
be confusing.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const anchor = require('markdown-it-anchor')
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
|
||||||
|
md.use(anchor, {
|
||||||
|
permalink: anchor.permalink.linkAfterHeader({
|
||||||
|
style: 'aria-describedby' // Or `aria-labelledby`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h2 id="title">Title</h2>
|
||||||
|
<a class="header-anchor" href="#title" aria-describedby="title">#</a>
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Link inside header
|
||||||
|
|
||||||
|
This is the equivalent of the default permalink in previous versions.
|
||||||
|
The reason it's not the first one in the list is because this method has
|
||||||
|
accessibility issues.
|
||||||
|
|
||||||
|
If you use a symbol like just `#` without adding any markup around,
|
||||||
|
screen readers will read it as part of every heading (in the case of
|
||||||
|
`#`, it could be read "pound", "number" or "number sign") meaning that
|
||||||
|
if you title is "my beautiful title", it will read "number sign my
|
||||||
|
beautiful title" for example. For other common symbols, `🔗` is usually
|
||||||
|
read as "link symbol" and `¶` as "pilcrow".
|
||||||
|
|
||||||
|
Additionally, screen readers users commonly request the list of all
|
||||||
|
links in the page, so they'll be flooded with "number sign, number sign,
|
||||||
|
number sign" for each of your headings.
|
||||||
|
|
||||||
|
I would highly recommend using one of the markups above which have a
|
||||||
|
better experience, but if you really want to use this markup, make sure
|
||||||
|
to pass accessible HTML as `symbol` to make things usable, like in the
|
||||||
|
example below, but even that has some flaws.
|
||||||
|
|
||||||
|
With that said, this permalink allows the following options:
|
||||||
|
|
||||||
|
| Name | Description | Default |
|
||||||
|
|--------------|--------------------------------------------------------------------------------------------------------------------------|---------|
|
||||||
|
| `space` | Add a space between the header text and the permalink symbol. Set it to a string to customize the space (e.g. ` `). | `true` |
|
||||||
|
| `placement` | Placement of the permalink, can be `before` or `after` the header. This option used to be called `permalinkBefore`. | `after` |
|
||||||
|
| `ariaHidden` | Whether to add `aria-hidden="true"`, see [ARIA hidden](#aria-hidden). | `false` |
|
||||||
|
| | See [common options](#common-options). | |
|
||||||
|
|
||||||
|
```js
|
||||||
|
const anchor = require('markdown-it-anchor')
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
|
||||||
|
md.use(anchor, {
|
||||||
|
permalink: anchor.permalink.linkInsideHeader({
|
||||||
|
symbol: `
|
||||||
|
<span class="visually-hidden">Jump to heading</span>
|
||||||
|
<span aria-hidden="true">#</span>
|
||||||
|
`,
|
||||||
|
placement: 'before'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h2 id="title">
|
||||||
|
<a class="header-anchor" href="#title">
|
||||||
|
<span class="visually-hidden">Jump to heading</span>
|
||||||
|
<span aria-hidden="true">#</span>
|
||||||
|
</a>
|
||||||
|
Title
|
||||||
|
</h2>
|
||||||
|
```
|
||||||
|
|
||||||
|
While this example allows more accessible anchors with the same markup
|
||||||
|
as previous versions of markdown-it-anchor, it's still not ideal. The
|
||||||
|
assistive text for permalinks will be read as part of the heading when
|
||||||
|
listing all the titles of the page, e.g. "jump to heading title 1, jump
|
||||||
|
to heading title 2" and so on. Also that assistive text is not very
|
||||||
|
useful when listing the links in the page (which will read "jump to
|
||||||
|
heading, jump to heading, jump to heading" for each of your permalinks).
|
||||||
|
|
||||||
|
### ARIA hidden
|
||||||
|
|
||||||
|
This is just an alias for [`linkInsideHeader`](#link-inside-header) with
|
||||||
|
`ariaHidden: true` by default, to mimic GitHub's way of rendering
|
||||||
|
permalinks.
|
||||||
|
|
||||||
|
Setting `aria-hidden="true"` makes the permalink explicitly inaccessible
|
||||||
|
instead of having the permalink and its symbol being read by screen
|
||||||
|
readers as part of every single headings (which was a pretty terrible
|
||||||
|
experience).
|
||||||
|
|
||||||
|
```js
|
||||||
|
const anchor = require('markdown-it-anchor')
|
||||||
|
const md = require('markdown-it')()
|
||||||
|
|
||||||
|
md.use(anchor, {
|
||||||
|
permalink: anchor.permalink.ariaHidden({
|
||||||
|
placement: 'before'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h2 id="title"><a class="header-anchor" href="#title" aria-hidden="true">#</a> Title</h2>
|
||||||
|
```
|
||||||
|
|
||||||
|
While no experience might be arguably better than a bad experience, I
|
||||||
|
would instead recommend using one of the above renderers to provide an
|
||||||
|
accessible experience. My favorite one is the [header link](#header-link),
|
||||||
|
which is also the simplest one.
|
||||||
|
|
||||||
|
### Custom permalink
|
||||||
|
|
||||||
|
If none of those options suit you, you can always make your own
|
||||||
|
renderer! Take inspiration from [the code behind all permalinks](permalink.js).
|
||||||
|
|
||||||
|
The signature of the function you pass in the `permalink` option is the
|
||||||
|
following:
|
||||||
|
|
||||||
|
```js
|
||||||
|
function renderPermalink (slug, opts, state, idx) {}
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `opts` are the markdown-it-anchor options, `state` is a
|
||||||
|
markdown-it [`StateCore`](https://github.com/markdown-it/markdown-it)
|
||||||
|
instance, and `idx` is the index of the `heading_open` token in the
|
||||||
|
`state.tokens` array. That array contains [`Token`](https://markdown-it.github.io/markdown-it/#Token)
|
||||||
|
objects.
|
||||||
|
|
||||||
|
To make sense of the "token stream" and the way token objects are
|
||||||
|
organized, you will probably want to read the [markdown-it design principles](https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md)
|
||||||
|
page.
|
||||||
|
|
||||||
|
This function can freely modify the token stream (`state.tokens`),
|
||||||
|
usually around the given `idx`, to construct the anchor.
|
||||||
|
|
||||||
|
Because of the way the token stream works, a `heading_open` token is
|
||||||
|
usually followed by a `inline` token that contains the actual text (and
|
||||||
|
inline markup) of the heading, and finally a `heading_close` token. This
|
||||||
|
is why you'll see most built-in permalink renderers touch
|
||||||
|
`state.tokens[idx + 1]`, because they update the contents of the
|
||||||
|
`inline` token that follows a `heading_open`.
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
If you want to debug this library more easily, we support source maps.
|
||||||
|
|
||||||
|
Use the [source-map-support](https://www.npmjs.com/package/source-map-support)
|
||||||
|
module to enable it with Node.js.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
node -r source-map-support/register your-script.js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Build the library in the `dist/` directory.
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Watch file changes to update `dist/`.
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# Run tests, will use the build version so make sure to build after
|
||||||
|
# making changes.
|
||||||
|
npm test
|
||||||
|
```
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org/>
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"name": "markdown-it-anchor",
|
||||||
|
"version": "9.2.0",
|
||||||
|
"description": "Header anchors for markdown-it.",
|
||||||
|
"keywords": [
|
||||||
|
"markdown",
|
||||||
|
"markdown-it",
|
||||||
|
"markdown-it-plugin",
|
||||||
|
"header",
|
||||||
|
"anchor"
|
||||||
|
],
|
||||||
|
"license": "Unlicense",
|
||||||
|
"contributors": [
|
||||||
|
"Val (https://val.codejam.info/)",
|
||||||
|
"Nagao, Fabio Zendhi <nagaozen@gmail.com> (https://github.com/nagaozen/)"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"README.md",
|
||||||
|
"UNLICENSE",
|
||||||
|
"dist/*",
|
||||||
|
"runkit.js",
|
||||||
|
"types/*"
|
||||||
|
],
|
||||||
|
"main": "dist/markdownItAnchor.js",
|
||||||
|
"module": "dist/markdownItAnchor.mjs",
|
||||||
|
"types": "./types/index.d.ts",
|
||||||
|
"repository": "valeriangalliat/markdown-it-anchor",
|
||||||
|
"scripts": {
|
||||||
|
"build": "microbundle --generateTypes false",
|
||||||
|
"dev": "microbundle --generateTypes false watch",
|
||||||
|
"lint": "standard index.js test.js",
|
||||||
|
"prepare": "npm run build && npm test",
|
||||||
|
"test": "npm run lint && ava test.js"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@sindresorhus/slugify": "^2.2.1",
|
||||||
|
"ava": "^5.1.0",
|
||||||
|
"markdown-it": "*",
|
||||||
|
"markdown-it-attrs": "^4.1.6",
|
||||||
|
"microbundle": "^0.15.1",
|
||||||
|
"source-map-support": "^0.5.19",
|
||||||
|
"standard": "^17.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/markdown-it": "*",
|
||||||
|
"markdown-it": "*"
|
||||||
|
},
|
||||||
|
"source": "index.js",
|
||||||
|
"unpkg": "dist/markdownItAnchor.umd.js",
|
||||||
|
"mangle": {
|
||||||
|
"regex": "^_"
|
||||||
|
},
|
||||||
|
"runkitExampleFilename": "runkit.js"
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
const md = require('markdown-it')()
|
||||||
|
const anchor = require('markdown-it-anchor')
|
||||||
|
|
||||||
|
md.use(anchor, {
|
||||||
|
level: 1,
|
||||||
|
// slugify: string => string,
|
||||||
|
permalink: false,
|
||||||
|
// renderPermalink: (slug, opts, state, permalink) => {},
|
||||||
|
permalinkClass: 'header-anchor',
|
||||||
|
permalinkSymbol: '¶',
|
||||||
|
permalinkBefore: false
|
||||||
|
})
|
||||||
|
|
||||||
|
const src = `# First header
|
||||||
|
|
||||||
|
Lorem ipsum.
|
||||||
|
|
||||||
|
## Next section!
|
||||||
|
|
||||||
|
This is totaly awesome.`
|
||||||
|
|
||||||
|
console.log(md.render(src))
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
import MarkdownIt from 'markdown-it';
|
||||||
|
import { default as MarkdownItToken } from 'markdown-it/lib/token.mjs';
|
||||||
|
import { default as MarkdownItState} from 'markdown-it/lib/rules_core/state_core.mjs';
|
||||||
|
|
||||||
|
declare namespace anchor {
|
||||||
|
export type Token = MarkdownItToken
|
||||||
|
export type State = MarkdownItState
|
||||||
|
export type RenderHref = (slug: string, state: State) => string;
|
||||||
|
export type RenderAttrs = (slug: string, state: State) => Record<string, string | number>;
|
||||||
|
|
||||||
|
export interface PermalinkOptions {
|
||||||
|
class?: string,
|
||||||
|
symbol?: string,
|
||||||
|
renderHref?: RenderHref,
|
||||||
|
renderAttrs?: RenderAttrs
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HeaderLinkPermalinkOptions extends PermalinkOptions {
|
||||||
|
safariReaderFix?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LinkAfterHeaderPermalinkOptions extends PermalinkOptions {
|
||||||
|
style?: 'visually-hidden' | 'aria-label' | 'aria-describedby' | 'aria-labelledby',
|
||||||
|
assistiveText?: (title: string) => string,
|
||||||
|
visuallyHiddenClass?: string,
|
||||||
|
space?: boolean | string,
|
||||||
|
placement?: 'before' | 'after'
|
||||||
|
wrapper?: [string, string] | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LinkInsideHeaderPermalinkOptions extends PermalinkOptions {
|
||||||
|
space?: boolean | string,
|
||||||
|
placement?: 'before' | 'after',
|
||||||
|
ariaHidden?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AriaHiddenPermalinkOptions extends PermalinkOptions {
|
||||||
|
space?: boolean | string,
|
||||||
|
placement?: 'before' | 'after'
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PermalinkGenerator = (slug: string, opts: PermalinkOptions, state: State, index: number) => void;
|
||||||
|
|
||||||
|
export interface AnchorInfo {
|
||||||
|
slug: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AnchorOptions {
|
||||||
|
level?: number | number[];
|
||||||
|
|
||||||
|
slugify?(str: string): string;
|
||||||
|
slugifyWithState?(str: string, state: State): string;
|
||||||
|
getTokensText?(tokens: Token[]): string;
|
||||||
|
|
||||||
|
uniqueSlugStartIndex?: number;
|
||||||
|
permalink?: PermalinkGenerator;
|
||||||
|
|
||||||
|
callback?(token: Token, anchor_info: AnchorInfo): void;
|
||||||
|
|
||||||
|
tabIndex?: number | false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const permalink: {
|
||||||
|
headerLink: (opts?: HeaderLinkPermalinkOptions) => PermalinkGenerator
|
||||||
|
linkAfterHeader: (opts?: LinkAfterHeaderPermalinkOptions) => PermalinkGenerator
|
||||||
|
linkInsideHeader: (opts?: LinkInsideHeaderPermalinkOptions) => PermalinkGenerator
|
||||||
|
ariaHidden: (opts?: AriaHiddenPermalinkOptions) => PermalinkGenerator
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
declare function anchor(md: MarkdownIt, opts?: anchor.AnchorOptions): void;
|
||||||
|
|
||||||
|
export default anchor;
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
Generated
+39
-7
@@ -7,6 +7,10 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "kst4contest-website",
|
"name": "kst4contest-website",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
"dependencies": {
|
||||||
|
"markdown-it": "^14.3.0",
|
||||||
|
"markdown-it-anchor": "^9.2.0"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@11ty/eleventy": "^3.0.0"
|
"@11ty/eleventy": "^3.0.0"
|
||||||
}
|
}
|
||||||
@@ -229,6 +233,31 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/linkify-it": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@types/markdown-it": {
|
||||||
|
"version": "14.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
|
||||||
|
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/linkify-it": "^5",
|
||||||
|
"@types/mdurl": "^2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/mdurl": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/a-sync-waterfall": {
|
"node_modules/a-sync-waterfall": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
|
||||||
@@ -293,7 +322,6 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
"dev": true,
|
|
||||||
"license": "Python-2.0"
|
"license": "Python-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/asap": {
|
"node_modules/asap": {
|
||||||
@@ -1051,7 +1079,6 @@
|
|||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
|
||||||
"integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==",
|
"integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -1109,7 +1136,6 @@
|
|||||||
"version": "14.3.0",
|
"version": "14.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz",
|
||||||
"integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==",
|
"integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -1133,11 +1159,20 @@
|
|||||||
"markdown-it": "bin/markdown-it.mjs"
|
"markdown-it": "bin/markdown-it.mjs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/markdown-it-anchor": {
|
||||||
|
"version": "9.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-9.2.0.tgz",
|
||||||
|
"integrity": "sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg==",
|
||||||
|
"license": "Unlicense",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/markdown-it": "*",
|
||||||
|
"markdown-it": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/markdown-it/node_modules/entities": {
|
"node_modules/markdown-it/node_modules/entities": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.12"
|
"node": ">=0.12"
|
||||||
@@ -1150,7 +1185,6 @@
|
|||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
||||||
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/mime": {
|
"node_modules/mime": {
|
||||||
@@ -1422,7 +1456,6 @@
|
|||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
||||||
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
@@ -1640,7 +1673,6 @@
|
|||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
||||||
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/unpipe": {
|
"node_modules/unpipe": {
|
||||||
|
|||||||
@@ -8,5 +8,9 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@11ty/eleventy": "^3.0.0"
|
"@11ty/eleventy": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"markdown-it": "^14.3.0",
|
||||||
|
"markdown-it-anchor": "^9.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,3 +114,37 @@ nav a:hover {
|
|||||||
padding: 40px 7vw;
|
padding: 40px 7vw;
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.manual-content {
|
||||||
|
max-width: 980px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-content h1,
|
||||||
|
.manual-content h2,
|
||||||
|
.manual-content h3 {
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-content pre {
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: #020617;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-content code {
|
||||||
|
color: #bae6fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-content table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-content th,
|
||||||
|
.manual-content td {
|
||||||
|
border-bottom: 1px solid rgba(148, 163, 184, 0.22);
|
||||||
|
padding: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
pagination:
|
||||||
|
data: collections.manualPages
|
||||||
|
size: 1
|
||||||
|
alias: manual
|
||||||
|
permalink: "/manual/{{ manual.lang }}/{{ manual.slug }}/"
|
||||||
|
layout: base.njk
|
||||||
|
title: "{{ manual.title }} | KST4Contest Manual"
|
||||||
|
description: "KST4Contest manual page: {{ manual.title }}"
|
||||||
|
---
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<div class="card manual-content">
|
||||||
|
<p><a href="/manual/{{ manual.lang }}/">← Back to manual overview</a></p>
|
||||||
|
<h1>{{ manual.title }}</h1>
|
||||||
|
{{ manual.content | markdown | safe }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
@@ -11,9 +11,13 @@ description: Deutsches Benutzerhandbuch für KST4Contest.
|
|||||||
|
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="card"><h3>Installation</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/de-Installation">Installationsanleitung öffnen</a></p></div>
|
{% for manual in collections.manualPages %}
|
||||||
<div class="card"><h3>Konfiguration</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/de-Konfiguration">Konfiguration öffnen</a></p></div>
|
{% if manual.lang == "de" %}
|
||||||
<div class="card"><h3>Funktionen</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/de-Funktionen">Funktionsübersicht öffnen</a></p></div>
|
<div class="card">
|
||||||
<div class="card"><h3>AirScout-Integration</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/de-AirScout-Integration">AirScout-Anleitung öffnen</a></p></div>
|
<h3><a href="/manual/de/{{ manual.slug }}/">{{ manual.title }}</a></h3>
|
||||||
|
<p>Handbuchseite „{{ manual.title }}“ öffnen.</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -11,9 +11,13 @@ description: English user manual for KST4Contest.
|
|||||||
|
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="card"><h3>Installation</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/en-Installation">Open installation guide</a></p></div>
|
{% for manual in collections.manualPages %}
|
||||||
<div class="card"><h3>Configuration</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/en-Configuration">Open configuration guide</a></p></div>
|
{% if manual.lang == "en" %}
|
||||||
<div class="card"><h3>Features</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/en-Features">Open feature documentation</a></p></div>
|
<div class="card">
|
||||||
<div class="card"><h3>AirScout Integration</h3><p><a href="https://github.com/praktimarc/kst4contest/wiki/en-AirScout-Integration">Open AirScout guide</a></p></div>
|
<h3><a href="/manual/en/{{ manual.slug }}/">{{ manual.title }}</a></h3>
|
||||||
|
<p>Open the {{ manual.title }} manual page.</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
Reference in New Issue
Block a user