diff --git a/website/.eleventy.js b/website/.eleventy.js index e00f166..16de85d 100644 --- a/website/.eleventy.js +++ b/website/.eleventy.js @@ -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) { 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 { dir: { input: "src", diff --git a/website/_site/assets/css/main.css b/website/_site/assets/css/main.css index c585dbb..b722831 100644 --- a/website/_site/assets/css/main.css +++ b/website/_site/assets/css/main.css @@ -113,4 +113,38 @@ nav a:hover { .site-footer { padding: 40px 7vw; 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; } \ No newline at end of file diff --git a/website/_site/manual/de/index.html b/website/_site/manual/de/index.html index 3eb6734..1c93563 100644 --- a/website/_site/manual/de/index.html +++ b/website/_site/manual/de/index.html @@ -43,10 +43,97 @@
- - - -

AirScout-Integration

AirScout-Anleitung öffnen

+ + +
+

AirScout Integration

+

Handbuchseite „AirScout Integration“ öffnen.

+
+ + + +
+

Benutzeroberflaeche

+

Handbuchseite „Benutzeroberflaeche“ öffnen.

+
+ + + +
+

Changelog

+

Handbuchseite „Changelog“ öffnen.

+
+ + + +
+

DX Cluster Server

+

Handbuchseite „DX Cluster Server“ öffnen.

+
+ + + +
+

Funktionen

+

Handbuchseite „Funktionen“ öffnen.

+
+ + + +
+

Home

+

Handbuchseite „Home“ öffnen.

+
+ + + +
+

Installation

+

Handbuchseite „Installation“ öffnen.

+
+ + + +
+

Konfiguration

+

Handbuchseite „Konfiguration“ öffnen.

+
+ + + +
+

Log Synchronisation

+

Handbuchseite „Log Synchronisation“ öffnen.

+
+ + + +
+

Makros und Variablen

+

Handbuchseite „Makros und Variablen“ öffnen.

+
+ + + + + + + + + + + + + + + + + + + + + +
diff --git a/website/_site/manual/en/index.html b/website/_site/manual/en/index.html index b575a40..90dc8fa 100644 --- a/website/_site/manual/en/index.html +++ b/website/_site/manual/en/index.html @@ -43,10 +43,97 @@
- - - -

AirScout Integration

Open AirScout guide

+ + + + + + + + + + + + + + + + + + + + + + +
+

AirScout Integration

+

Open the AirScout Integration manual page.

+
+ + + +
+

Changelog

+

Open the Changelog manual page.

+
+ + + +
+

Configuration

+

Open the Configuration manual page.

+
+ + + +
+

DX Cluster Server

+

Open the DX Cluster Server manual page.

+
+ + + +
+

Features

+

Open the Features manual page.

+
+ + + +
+

Home

+

Open the Home manual page.

+
+ + + +
+

Installation

+

Open the Installation manual page.

+
+ + + +
+

Log Sync

+

Open the Log Sync manual page.

+
+ + + +
+

Macros and Variables

+

Open the Macros and Variables manual page.

+
+ + + +
+

User Interface

+

Open the User Interface manual page.

+
+ +
diff --git a/website/_site/sitemap.xml b/website/_site/sitemap.xml index 573d638..77e7943 100644 --- a/website/_site/sitemap.xml +++ b/website/_site/sitemap.xml @@ -39,4 +39,7 @@ https://kst4contest.hamradioonline.de/manual/de/ + + https://kst4contest.hamradioonline.de/manual/de/airscout-integration/ + \ No newline at end of file diff --git a/website/node_modules/.package-lock.json b/website/node_modules/.package-lock.json index 0d12246..47a8359 100644 --- a/website/node_modules/.package-lock.json +++ b/website/node_modules/.package-lock.json @@ -222,6 +222,31 @@ "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": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", @@ -286,7 +311,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, "license": "Python-2.0" }, "node_modules/asap": { @@ -1029,7 +1053,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz", "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==", - "dev": true, "funding": [ { "type": "github", @@ -1087,7 +1110,6 @@ "version": "14.3.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz", "integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==", - "dev": true, "funding": [ { "type": "github", @@ -1111,11 +1133,20 @@ "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": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -1128,7 +1159,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true, "license": "MIT" }, "node_modules/mime": { @@ -1400,7 +1430,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -1618,7 +1647,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true, "license": "MIT" }, "node_modules/unpipe": { diff --git a/website/node_modules/@types/linkify-it/LICENSE b/website/node_modules/@types/linkify-it/LICENSE new file mode 100644 index 0000000..9e841e7 --- /dev/null +++ b/website/node_modules/@types/linkify-it/LICENSE @@ -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 diff --git a/website/node_modules/@types/linkify-it/README.md b/website/node_modules/@types/linkify-it/README.md new file mode 100644 index 0000000..63d0594 --- /dev/null +++ b/website/node_modules/@types/linkify-it/README.md @@ -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). diff --git a/website/node_modules/@types/linkify-it/index.d.mts b/website/node_modules/@types/linkify-it/index.d.mts new file mode 100644 index 0000000..910cc5e --- /dev/null +++ b/website/node_modules/@types/linkify-it/index.d.mts @@ -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; diff --git a/website/node_modules/@types/linkify-it/index.d.ts b/website/node_modules/@types/linkify-it/index.d.ts new file mode 100644 index 0000000..780d419 --- /dev/null +++ b/website/node_modules/@types/linkify-it/index.d.ts @@ -0,0 +1,3 @@ +import LinkifyIt = require("./build/index.cjs.js"); + +export = LinkifyIt; diff --git a/website/node_modules/@types/linkify-it/package.json b/website/node_modules/@types/linkify-it/package.json new file mode 100644 index 0000000..69c36b0 --- /dev/null +++ b/website/node_modules/@types/linkify-it/package.json @@ -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" +} \ No newline at end of file diff --git a/website/node_modules/@types/markdown-it/LICENSE b/website/node_modules/@types/markdown-it/LICENSE new file mode 100644 index 0000000..9e841e7 --- /dev/null +++ b/website/node_modules/@types/markdown-it/LICENSE @@ -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 diff --git a/website/node_modules/@types/markdown-it/README.md b/website/node_modules/@types/markdown-it/README.md new file mode 100644 index 0000000..1a021e8 --- /dev/null +++ b/website/node_modules/@types/markdown-it/README.md @@ -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). diff --git a/website/node_modules/@types/markdown-it/index.d.mts b/website/node_modules/@types/markdown-it/index.d.mts new file mode 100644 index 0000000..21578d5 --- /dev/null +++ b/website/node_modules/@types/markdown-it/index.d.mts @@ -0,0 +1 @@ +export { default, Options, PluginSimple, PluginWithOptions, PluginWithParams, PresetName } from "./lib/index.mjs"; diff --git a/website/node_modules/@types/markdown-it/index.d.ts b/website/node_modules/@types/markdown-it/index.d.ts new file mode 100644 index 0000000..00967db --- /dev/null +++ b/website/node_modules/@types/markdown-it/index.d.ts @@ -0,0 +1,3 @@ +import MarkdownIt = require("./dist/index.cjs.js"); + +export = MarkdownIt; diff --git a/website/node_modules/@types/markdown-it/lib/common/html_blocks.d.mts b/website/node_modules/@types/markdown-it/lib/common/html_blocks.d.mts new file mode 100644 index 0000000..f4d5926 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/common/html_blocks.d.mts @@ -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; diff --git a/website/node_modules/@types/markdown-it/lib/common/html_re.d.mts b/website/node_modules/@types/markdown-it/lib/common/html_re.d.mts new file mode 100644 index 0000000..9ac33eb --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/common/html_re.d.mts @@ -0,0 +1,2 @@ +export const HTML_TAG_RE: RegExp; +export const HTML_OPEN_CLOSE_TAG_RE: RegExp; diff --git a/website/node_modules/@types/markdown-it/lib/common/utils.d.mts b/website/node_modules/@types/markdown-it/lib/common/utils.d.mts new file mode 100644 index 0000000..fced9e8 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/common/utils.d.mts @@ -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(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; diff --git a/website/node_modules/@types/markdown-it/lib/helpers/index.d.mts b/website/node_modules/@types/markdown-it/lib/helpers/index.d.mts new file mode 100644 index 0000000..7d79ac8 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/helpers/index.d.mts @@ -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 }; diff --git a/website/node_modules/@types/markdown-it/lib/helpers/parse_link_destination.d.mts b/website/node_modules/@types/markdown-it/lib/helpers/parse_link_destination.d.mts new file mode 100644 index 0000000..87a0c04 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/helpers/parse_link_destination.d.mts @@ -0,0 +1,7 @@ +export interface ParseLinkDestinationResult { + ok: boolean; + pos: number; + str: string; +} + +export default function parseLinkDestination(str: string, start: number, max: number): ParseLinkDestinationResult; diff --git a/website/node_modules/@types/markdown-it/lib/helpers/parse_link_label.d.mts b/website/node_modules/@types/markdown-it/lib/helpers/parse_link_label.d.mts new file mode 100644 index 0000000..43195fb --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/helpers/parse_link_label.d.mts @@ -0,0 +1,3 @@ +import StateInline from "../rules_inline/state_inline.mjs"; + +export default function parseLinkLabel(state: StateInline, start: number, disableNested?: boolean): number; diff --git a/website/node_modules/@types/markdown-it/lib/helpers/parse_link_title.d.mts b/website/node_modules/@types/markdown-it/lib/helpers/parse_link_title.d.mts new file mode 100644 index 0000000..8c59718 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/helpers/parse_link_title.d.mts @@ -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; diff --git a/website/node_modules/@types/markdown-it/lib/index.d.mts b/website/node_modules/@types/markdown-it/lib/index.d.mts new file mode 100644 index 0000000..551db79 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/index.d.mts @@ -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 + * (`
`). 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 `
`. + * @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 string) | null | undefined; +} + +export type PluginSimple = (md: MarkdownIt) => void; +export type PluginWithOptions = (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(plugin: PluginWithOptions, 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 `

` 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 `

`):
+ *
+ * ```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 '
' +
+ *                hljs.highlight(lang, str, true).value +
+ *                '
'; + * } catch (__) {} + * } + * + * return '
' + md.utils.escapeHtml(str) + '
'; + * } + * }); + * ``` + */ +declare const MarkdownIt: MarkdownItConstructor; + +export default MarkdownIt; diff --git a/website/node_modules/@types/markdown-it/lib/parser_block.d.mts b/website/node_modules/@types/markdown-it/lib/parser_block.d.mts new file mode 100644 index 0000000..15f2b2e --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/parser_block.d.mts @@ -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; + + /** + * 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; +} diff --git a/website/node_modules/@types/markdown-it/lib/parser_core.d.mts b/website/node_modules/@types/markdown-it/lib/parser_core.d.mts new file mode 100644 index 0000000..1cc10a2 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/parser_core.d.mts @@ -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; + + /** + * Executes core chain rules. + */ + process(state: StateCore): void; + + State: typeof StateCore; +} diff --git a/website/node_modules/@types/markdown-it/lib/parser_inline.d.mts b/website/node_modules/@types/markdown-it/lib/parser_inline.d.mts new file mode 100644 index 0000000..8282475 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/parser_inline.d.mts @@ -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; + + /** + * {@link Ruler} instance. Second ruler used for post-processing + * (e.g. in emphasis-like rules). + */ + ruler2: Ruler; + + /** + * 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; +} diff --git a/website/node_modules/@types/markdown-it/lib/renderer.d.mts b/website/node_modules/@types/markdown-it/lib/renderer.d.mts new file mode 100644 index 0000000..ce9adc1 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/renderer.d.mts @@ -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 ''; }; + * md.renderer.rules.strong_close = function () { return ''; }; + * + * 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; +} diff --git a/website/node_modules/@types/markdown-it/lib/ruler.d.mts b/website/node_modules/@types/markdown-it/lib/ruler.d.mts new file mode 100644 index 0000000..cdd7023 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/ruler.d.mts @@ -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 { + 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[]; +} diff --git a/website/node_modules/@types/markdown-it/lib/rules_block/state_block.d.mts b/website/node_modules/@types/markdown-it/lib/rules_block/state_block.d.mts new file mode 100644 index 0000000..1128f02 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/rules_block/state_block.d.mts @@ -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; +} diff --git a/website/node_modules/@types/markdown-it/lib/rules_core/state_core.d.mts b/website/node_modules/@types/markdown-it/lib/rules_core/state_core.d.mts new file mode 100644 index 0000000..8eae6e3 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/rules_core/state_core.d.mts @@ -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; +} diff --git a/website/node_modules/@types/markdown-it/lib/rules_inline/state_inline.d.mts b/website/node_modules/@types/markdown-it/lib/rules_inline/state_inline.d.mts new file mode 100644 index 0000000..9c9aada --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/rules_inline/state_inline.d.mts @@ -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; + + 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; +} diff --git a/website/node_modules/@types/markdown-it/lib/token.d.mts b/website/node_modules/@types/markdown-it/lib/token.d.mts new file mode 100644 index 0000000..3f666d6 --- /dev/null +++ b/website/node_modules/@types/markdown-it/lib/token.d.mts @@ -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; +} diff --git a/website/node_modules/@types/markdown-it/package.json b/website/node_modules/@types/markdown-it/package.json new file mode 100644 index 0000000..bfefade --- /dev/null +++ b/website/node_modules/@types/markdown-it/package.json @@ -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" +} \ No newline at end of file diff --git a/website/node_modules/@types/mdurl/LICENSE b/website/node_modules/@types/mdurl/LICENSE new file mode 100644 index 0000000..9e841e7 --- /dev/null +++ b/website/node_modules/@types/mdurl/LICENSE @@ -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 diff --git a/website/node_modules/@types/mdurl/README.md b/website/node_modules/@types/mdurl/README.md new file mode 100644 index 0000000..4e7e309 --- /dev/null +++ b/website/node_modules/@types/mdurl/README.md @@ -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). diff --git a/website/node_modules/@types/mdurl/index.d.mts b/website/node_modules/@types/mdurl/index.d.mts new file mode 100644 index 0000000..dbd33af --- /dev/null +++ b/website/node_modules/@types/mdurl/index.d.mts @@ -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 }; diff --git a/website/node_modules/@types/mdurl/index.d.ts b/website/node_modules/@types/mdurl/index.d.ts new file mode 100644 index 0000000..22fe742 --- /dev/null +++ b/website/node_modules/@types/mdurl/index.d.ts @@ -0,0 +1,3 @@ +import mdurl = require("./build/index.cjs.js"); + +export = mdurl; diff --git a/website/node_modules/@types/mdurl/lib/decode.d.mts b/website/node_modules/@types/mdurl/lib/decode.d.mts new file mode 100644 index 0000000..503603b --- /dev/null +++ b/website/node_modules/@types/mdurl/lib/decode.d.mts @@ -0,0 +1,10 @@ +declare const decode: { + defaultChars: string; + componentChars: string; + /** + * Decode percent-encoded string. + */ + (str: string, exclude?: string): string; +}; + +export default decode; diff --git a/website/node_modules/@types/mdurl/lib/encode.d.mts b/website/node_modules/@types/mdurl/lib/encode.d.mts new file mode 100644 index 0000000..0c95eb4 --- /dev/null +++ b/website/node_modules/@types/mdurl/lib/encode.d.mts @@ -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; diff --git a/website/node_modules/@types/mdurl/lib/format.d.mts b/website/node_modules/@types/mdurl/lib/format.d.mts new file mode 100644 index 0000000..7ad47f2 --- /dev/null +++ b/website/node_modules/@types/mdurl/lib/format.d.mts @@ -0,0 +1,3 @@ +import { Url } from "./parse.mjs"; + +export default function format(url: Omit): string; diff --git a/website/node_modules/@types/mdurl/lib/parse.d.mts b/website/node_modules/@types/mdurl/lib/parse.d.mts new file mode 100644 index 0000000..2e0d8f2 --- /dev/null +++ b/website/node_modules/@types/mdurl/lib/parse.d.mts @@ -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 }; diff --git a/website/node_modules/@types/mdurl/package.json b/website/node_modules/@types/mdurl/package.json new file mode 100644 index 0000000..11e09b7 --- /dev/null +++ b/website/node_modules/@types/mdurl/package.json @@ -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" +} \ No newline at end of file diff --git a/website/node_modules/markdown-it-anchor/README.md b/website/node_modules/markdown-it-anchor/README.md new file mode 100644 index 0000000..e9e69e9 --- /dev/null +++ b/website/node_modules/markdown-it-anchor/README.md @@ -0,0 +1,600 @@ +# markdown-it-anchor [![npm version](http://img.shields.io/npm/v/markdown-it-anchor.svg?style=flat-square)](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 +`

Foo

`. + +Optionally it can also include [permalinks](#permalinks), e.g. +`

Foo

` +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 = `${h.innerHTML}` +} + +console.log(root.toString()) +``` + +Or with a (not accessible) GitHub-style anchor, replace the +`h.innerHTML` part with: + +```js +h.insertAdjacentHTML('afterbegin', ` `) +``` + +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. + +
+ +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 +

Title

+``` + +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 +

Title

+``` + +### 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. `['
', '
']`. | `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: ['
', '
'] + }) +}) +``` + +```html + +``` + +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: + +
+aria-label variant + +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 +

Title

+# +``` + +
+ +
+aria-describedby and aria-labelledby variants + +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 +

Title

+# +``` + +
+ +### 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: ` + Jump to heading + + `, + placement: 'before' + }) +}) +``` + +```html +

+ + Jump to heading + + + Title +

+``` + +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 +

Title

+``` + +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 +``` diff --git a/website/node_modules/markdown-it-anchor/UNLICENSE b/website/node_modules/markdown-it-anchor/UNLICENSE new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/website/node_modules/markdown-it-anchor/UNLICENSE @@ -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 diff --git a/website/node_modules/markdown-it-anchor/package.json b/website/node_modules/markdown-it-anchor/package.json new file mode 100644 index 0000000..6fd57ef --- /dev/null +++ b/website/node_modules/markdown-it-anchor/package.json @@ -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 (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" +} diff --git a/website/node_modules/markdown-it-anchor/runkit.js b/website/node_modules/markdown-it-anchor/runkit.js new file mode 100644 index 0000000..df7624e --- /dev/null +++ b/website/node_modules/markdown-it-anchor/runkit.js @@ -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)) diff --git a/website/node_modules/markdown-it-anchor/types/index.d.ts b/website/node_modules/markdown-it-anchor/types/index.d.ts new file mode 100644 index 0000000..40c25c0 --- /dev/null +++ b/website/node_modules/markdown-it-anchor/types/index.d.ts @@ -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; + + 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; diff --git a/website/node_modules/markdown-it-anchor/types/package.json b/website/node_modules/markdown-it-anchor/types/package.json new file mode 100644 index 0000000..3dbc1ca --- /dev/null +++ b/website/node_modules/markdown-it-anchor/types/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/website/package-lock.json b/website/package-lock.json index b241269..5c4ec1f 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -7,6 +7,10 @@ "": { "name": "kst4contest-website", "version": "0.1.0", + "dependencies": { + "markdown-it": "^14.3.0", + "markdown-it-anchor": "^9.2.0" + }, "devDependencies": { "@11ty/eleventy": "^3.0.0" } @@ -229,6 +233,31 @@ "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": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", @@ -293,7 +322,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, "license": "Python-2.0" }, "node_modules/asap": { @@ -1051,7 +1079,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz", "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==", - "dev": true, "funding": [ { "type": "github", @@ -1109,7 +1136,6 @@ "version": "14.3.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz", "integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==", - "dev": true, "funding": [ { "type": "github", @@ -1133,11 +1159,20 @@ "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": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -1150,7 +1185,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true, "license": "MIT" }, "node_modules/mime": { @@ -1422,7 +1456,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -1640,7 +1673,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true, "license": "MIT" }, "node_modules/unpipe": { diff --git a/website/package.json b/website/package.json index dd8c927..fdb38b9 100644 --- a/website/package.json +++ b/website/package.json @@ -8,5 +8,9 @@ }, "devDependencies": { "@11ty/eleventy": "^3.0.0" + }, + "dependencies": { + "markdown-it": "^14.3.0", + "markdown-it-anchor": "^9.2.0" } -} \ No newline at end of file +} diff --git a/website/src/assets/css/main.css b/website/src/assets/css/main.css index c585dbb..b722831 100644 --- a/website/src/assets/css/main.css +++ b/website/src/assets/css/main.css @@ -113,4 +113,38 @@ nav a:hover { .site-footer { padding: 40px 7vw; 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; } \ No newline at end of file diff --git a/website/src/manual-pages/manual-page.njk b/website/src/manual-pages/manual-page.njk index e69de29..10031ca 100644 --- a/website/src/manual-pages/manual-page.njk +++ b/website/src/manual-pages/manual-page.njk @@ -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 }}" +--- + +
+
+

← Back to manual overview

+

{{ manual.title }}

+ {{ manual.content | markdown | safe }} +
+
\ No newline at end of file diff --git a/website/src/manual/de/index.njk b/website/src/manual/de/index.njk index 03cd1b5..5225a2a 100644 --- a/website/src/manual/de/index.njk +++ b/website/src/manual/de/index.njk @@ -11,9 +11,13 @@ description: Deutsches Benutzerhandbuch für KST4Contest.
- - - -

AirScout-Integration

AirScout-Anleitung öffnen

+ {% for manual in collections.manualPages %} + {% if manual.lang == "de" %} +
+

{{ manual.title }}

+

Handbuchseite „{{ manual.title }}“ öffnen.

+
+ {% endif %} + {% endfor %}
\ No newline at end of file diff --git a/website/src/manual/en/index.njk b/website/src/manual/en/index.njk index ce613c0..de23f8d 100644 --- a/website/src/manual/en/index.njk +++ b/website/src/manual/en/index.njk @@ -11,9 +11,13 @@ description: English user manual for KST4Contest.
- - - -

AirScout Integration

Open AirScout guide

+ {% for manual in collections.manualPages %} + {% if manual.lang == "en" %} +
+

{{ manual.title }}

+

Open the {{ manual.title }} manual page.

+
+ {% endif %} + {% endfor %}
\ No newline at end of file