@ng-doc/utils 22.0.0 → 22.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/html/plugins/cached-shiki.plugin.d.ts +21 -6
- package/html/plugins/keyword-positions.d.ts +58 -0
- package/html/process-html.d.ts +18 -0
- package/html/shiki-grammars.d.ts +58 -0
- package/index.esm.js +842 -40
- package/index.esm.js.map +1 -1
- package/package.json +6 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Aleksandr Skoropad
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type RehypeShikiOptions } from '@shikijs/rehype';
|
|
2
1
|
import type { Root } from 'hast';
|
|
3
2
|
/**
|
|
4
3
|
* Everything a highlighted code block depends on, apart from the installed Shiki release. A cache
|
|
@@ -12,6 +11,8 @@ export interface NgDocHighlightBlock {
|
|
|
12
11
|
readonly light: string;
|
|
13
12
|
readonly dark: string;
|
|
14
13
|
};
|
|
14
|
+
/** The identity of the extra languages (`processHtml`'s `langs`); absent without any. */
|
|
15
|
+
readonly languages?: string;
|
|
15
16
|
/** The language of the block's class, or the default language: before the fallback. */
|
|
16
17
|
readonly lang: string;
|
|
17
18
|
/** The raw meta string, before it is parsed. */
|
|
@@ -21,8 +22,10 @@ export interface NgDocHighlightBlock {
|
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
24
|
* A cache of highlighted code blocks for `processHtml`. Values are the JSON of the HAST nodes that
|
|
24
|
-
* replace a block's `pre` element
|
|
25
|
-
*
|
|
25
|
+
* replace a block's `pre` element: `@shikijs/rehype` replaces it with the root of the highlighted
|
|
26
|
+
* fragment, which holds the new `pre` element. A value that is not a JSON array of HAST elements or
|
|
27
|
+
* such roots is a miss. The cache only ever receives values of blocks that were highlighted without
|
|
28
|
+
* an error.
|
|
26
29
|
*/
|
|
27
30
|
export interface NgDocHighlightCache {
|
|
28
31
|
/** The key of a block. It must change whenever anything in the block or the Shiki release does. */
|
|
@@ -44,13 +47,24 @@ export interface NgDocHighlightCache {
|
|
|
44
47
|
export interface CachedShikiOptions {
|
|
45
48
|
cache: NgDocHighlightCache;
|
|
46
49
|
themes: NgDocHighlightBlock['themes'];
|
|
47
|
-
/**
|
|
50
|
+
/** The identity of the extra languages the transformer highlights with; absent without any. */
|
|
51
|
+
languages?: string;
|
|
52
|
+
/**
|
|
53
|
+
* `used` when the transformer loads only the grammars blocks use. It gives the same result, so
|
|
54
|
+
* it is not part of a key; it only selects the transformer.
|
|
55
|
+
*/
|
|
56
|
+
grammars?: 'used';
|
|
57
|
+
/** What the options stand for in a key: change it whenever the options or this plugin change. */
|
|
48
58
|
identity: NgDocHighlightBlock['options'];
|
|
49
59
|
/** The language of a block without a `language-*` class (the options' `defaultLanguage`). */
|
|
50
60
|
defaultLanguage: string;
|
|
51
|
-
/**
|
|
52
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Creates the `@shikijs/rehype` transformer that highlights a miss, with the plugin's options;
|
|
63
|
+
* called once per thread, theme pair and languages.
|
|
64
|
+
*/
|
|
65
|
+
transformer: () => Highlighter;
|
|
53
66
|
}
|
|
67
|
+
type Highlighter = (tree: Root) => Promise<void> | void;
|
|
54
68
|
/**
|
|
55
69
|
* The plain `@shikijs/rehype` plugin, with a cache of its results per block.
|
|
56
70
|
*
|
|
@@ -66,3 +80,4 @@ export interface CachedShikiOptions {
|
|
|
66
80
|
* loads Shiki once the cache shows that its themes load.
|
|
67
81
|
*/
|
|
68
82
|
export default function cachedShikiPlugin(settings: CachedShikiOptions): (tree: Root) => Promise<void>;
|
|
83
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a keyword may link inside code.
|
|
3
|
+
*
|
|
4
|
+
* The keywords plugin splits code into words and looks each one up. A word that happens to be a
|
|
5
|
+
* keyword is not always a reference to it: an object key (`group: 'Colors'`), a property after a
|
|
6
|
+
* dot, a string, an HTML attribute value or a file name in inline code (`vite.config.mjs`) only
|
|
7
|
+
* share its name. Highlighted code carries no token scopes (Shiki emits colours only, and adjacent
|
|
8
|
+
* tokens of one colour are merged), so this module reads the position of a word from the code text
|
|
9
|
+
* itself with a small lexer: strings and comments, the characters around the word, and the names
|
|
10
|
+
* the code declares. The result only depends on the code, never on the keyword set, so the words a
|
|
11
|
+
* page records as used keywords are exactly the ones that may link.
|
|
12
|
+
*/
|
|
13
|
+
/** How the code around a word is read. */
|
|
14
|
+
export type CodeMode = 'typescript' | 'html';
|
|
15
|
+
/** What the plugin does with one word. */
|
|
16
|
+
export type WordPosition =
|
|
17
|
+
/** Not a reference: the word stays plain text and is not recorded as used. */
|
|
18
|
+
{
|
|
19
|
+
readonly link: false;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A reference. `keyword`, when present, is the key to look up instead of the word's own key: a
|
|
23
|
+
* member after a dot is looked up as `Owner.member`.
|
|
24
|
+
*/
|
|
25
|
+
| {
|
|
26
|
+
readonly link: true;
|
|
27
|
+
readonly keyword?: string;
|
|
28
|
+
};
|
|
29
|
+
/** The positions of the words of one code element. */
|
|
30
|
+
export interface CodeScan {
|
|
31
|
+
/** Whether the whole element is a single keyword reference (inline code only). */
|
|
32
|
+
readonly whole: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The position of the word at `[start, end)` of the element's text.
|
|
35
|
+
* @param start - The offset of the word's first character.
|
|
36
|
+
* @param end - The offset after the word's last character.
|
|
37
|
+
* @param key - The word's key: the word without its `.member`/`#anchor` and query.
|
|
38
|
+
*/
|
|
39
|
+
position(start: number, end: number, key: string): WordPosition;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The positions of the words of inline code, or `undefined` when no word of it may link.
|
|
43
|
+
*
|
|
44
|
+
* Inline code links when it is one keyword reference as a whole (`NgDocPage`, `*GuidePage#anchor`,
|
|
45
|
+
* `NgDocPage.title`, with an optional `?query`), or when it reads as TypeScript: it contains code
|
|
46
|
+
* punctuation (a call, generics, a union, an array type, a decorator, a type annotation) or starts
|
|
47
|
+
* with a declaration. Then its words link where they would in a TypeScript code block. Anything
|
|
48
|
+
* else (a file name like `vite.ng-doc.config.mjs`, a path, a command, prose, an HTML tag) stays
|
|
49
|
+
* plain text.
|
|
50
|
+
* @param text - The text of the inline code element.
|
|
51
|
+
*/
|
|
52
|
+
export declare function scanInlineCode(text: string): CodeScan | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* The positions of the words of a code block.
|
|
55
|
+
* @param text - The text of the block's `code` element.
|
|
56
|
+
* @param mode - How the block's language is read.
|
|
57
|
+
*/
|
|
58
|
+
export declare function scanCodeBlock(text: string, mode: CodeMode): CodeScan;
|
package/html/process-html.d.ts
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
1
|
import { NgDocHeading, NgDocPageAnchor } from '@ng-doc/core';
|
|
2
2
|
import { NgDocHighlightCache } from './plugins/cached-shiki.plugin';
|
|
3
3
|
export type { NgDocHighlightBlock, NgDocHighlightCache } from './plugins/cached-shiki.plugin';
|
|
4
|
+
/** A Shiki language registration: a TextMate grammar as plain JSON, with its name. */
|
|
5
|
+
export interface NgDocHighlightLanguage {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly scopeName: string;
|
|
8
|
+
}
|
|
4
9
|
export interface NgDocHtmlProcessorConfig {
|
|
5
10
|
lightTheme?: string;
|
|
6
11
|
darkTheme?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Languages that code blocks can use besides those bundled with Shiki. A registration named like
|
|
14
|
+
* a bundled language replaces it. With languages, code is highlighted by a highlighter of its
|
|
15
|
+
* own, created once per thread for these languages and themes.
|
|
16
|
+
*/
|
|
17
|
+
langs?: readonly NgDocHighlightLanguage[];
|
|
18
|
+
/**
|
|
19
|
+
* Which bundled Shiki grammars the highlighter loads: `all` (the default) sets it up with every
|
|
20
|
+
* bundled grammar, as `@shikijs/rehype` does; `used` loads only the grammars the document's code
|
|
21
|
+
* blocks can reach, into a highlighter kept per thread and theme pair, which takes a fraction of
|
|
22
|
+
* the time and gives the same HTML. With `langs`, every grammar is loaded.
|
|
23
|
+
*/
|
|
24
|
+
grammars?: 'all' | 'used';
|
|
7
25
|
headings?: NgDocHeading[];
|
|
8
26
|
route?: string;
|
|
9
27
|
/**
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Root } from 'hast';
|
|
2
|
+
import { type HighlighterGeneric, type LanguageRegistration, createHighlighter } from 'shiki';
|
|
3
|
+
/**
|
|
4
|
+
* Loading only the Shiki grammars that code blocks use, with the same result as loading every
|
|
5
|
+
* bundled grammar.
|
|
6
|
+
*
|
|
7
|
+
* `@shikijs/rehype` sets its highlighter up with every bundled grammar, which takes seconds. A
|
|
8
|
+
* grammar's highlighting depends only on the grammars it can reach: the languages it embeds
|
|
9
|
+
* (`embeddedLangs`, and `embeddedLangsLazy`, which it uses once they are loaded), the scopes its
|
|
10
|
+
* rules include, and the grammars that inject into its scopes (`injectTo`, matched by scope
|
|
11
|
+
* prefix, in registration order). {@link ShikiGrammars.closure} is that set, closed under the
|
|
12
|
+
* same rules, plus every grammar that shares an injection target with an injector in it, so the
|
|
13
|
+
* injections of a scope are always registered together. Loaded in the order in which loading every
|
|
14
|
+
* bundled grammar registers them (the first mention of each name), a closure gives the
|
|
15
|
+
* highlighter the same grammars, injections and injection order for its languages as loading
|
|
16
|
+
* everything, whatever else was loaded before: a highlighter only grows by whole closures, and
|
|
17
|
+
* each scope's grammars are complete when the scope is first loaded.
|
|
18
|
+
*/
|
|
19
|
+
export declare class ShikiGrammars {
|
|
20
|
+
private readonly byName;
|
|
21
|
+
private readonly byScope;
|
|
22
|
+
private readonly injectors;
|
|
23
|
+
private readonly order;
|
|
24
|
+
private readonly closures;
|
|
25
|
+
private readonly loaded;
|
|
26
|
+
private constructor();
|
|
27
|
+
/**
|
|
28
|
+
* The bundled grammars, in the order `@shikijs/rehype` registers them: every bundled language
|
|
29
|
+
* name, each with the registrations of its module.
|
|
30
|
+
*/
|
|
31
|
+
static create(): Promise<ShikiGrammars>;
|
|
32
|
+
/**
|
|
33
|
+
* The grammars that a block of `language` can reach, in registration order; empty for a
|
|
34
|
+
* language that no bundled grammar names (it falls back to plain text, as before).
|
|
35
|
+
* @param language
|
|
36
|
+
*/
|
|
37
|
+
closure(language: string): readonly LanguageRegistration[];
|
|
38
|
+
/**
|
|
39
|
+
* Loads the closures of `languages` that `highlighter` does not hold yet.
|
|
40
|
+
* @param highlighter
|
|
41
|
+
* @param languages
|
|
42
|
+
*/
|
|
43
|
+
load(highlighter: HighlighterGeneric<string, string>, languages: Iterable<string>): void;
|
|
44
|
+
}
|
|
45
|
+
/** The bundled grammars of this thread, read once. */
|
|
46
|
+
export declare function shikiGrammars(): Promise<ShikiGrammars>;
|
|
47
|
+
/**
|
|
48
|
+
* A highlighter with the given themes and no language: {@link ShikiGrammars.load} adds them.
|
|
49
|
+
* @param themes
|
|
50
|
+
*/
|
|
51
|
+
export declare function createGrammarlessHighlighter(themes: Parameters<typeof createHighlighter>[0]['themes']): Promise<HighlighterGeneric<string, string>>;
|
|
52
|
+
/**
|
|
53
|
+
* The language of every block `@shikijs/rehype` highlights in `tree` (a `pre` whose first child is
|
|
54
|
+
* a `code` element with properties): its `language-*` class, or `defaultLanguage`.
|
|
55
|
+
* @param tree
|
|
56
|
+
* @param defaultLanguage
|
|
57
|
+
*/
|
|
58
|
+
export declare function blockLanguages(tree: Root, defaultLanguage: string): Set<string>;
|