@peaceroad/markdown-it-renderer-fence 0.6.1 → 0.8.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/README.md +183 -430
- package/docs/README.md +37 -0
- package/docs/code-highlighting-design.md +317 -0
- package/docs/custom-highlight-styling-guide.md +204 -0
- package/package.json +22 -13
- package/src/custom-highlight/option-validator.js +19 -10
- package/src/custom-highlight/scope-name.js +23 -0
- package/src/custom-highlight/{shiki-keyword-rules.js → shiki-role-rules.js} +229 -44
- package/src/custom-highlight/{shiki-keyword.js → shiki-role.js} +64 -56
- package/src/custom-highlight/shiki-theme-role.js +176 -0
- package/src/entry/markup-highlight.js +4 -0
- package/src/fence/line-notes.js +199 -0
- package/src/fence/render-api-provider.js +62 -62
- package/src/fence/render-api-renderer.js +26 -11
- package/src/fence/render-api-runtime.js +5 -13
- package/src/fence/render-api.js +24 -12
- package/src/fence/render-markup.js +24 -16
- package/src/fence/render-shared.js +232 -20
- package/theme/_shared/rf-core.css +164 -0
- package/theme/rf-basic/README.md +91 -0
- package/theme/rf-basic/api/highlightjs.css +71 -0
- package/theme/rf-basic/api/shiki.css +67 -0
- package/theme/rf-basic/base.css +3 -0
- package/theme/rf-basic/index.css +7 -0
- package/theme/rf-basic/index.js +155 -0
- package/theme/rf-basic/markup/highlightjs.css +77 -0
- package/theme/rf-basic/markup/shiki.css +11 -0
- package/theme/rf-monochrome/README.md +71 -0
- package/theme/rf-monochrome/base.css +3 -0
- package/theme/rf-monochrome/index.css +5 -0
- package/theme/rf-monochrome/index.js +72 -0
- package/theme/rf-monochrome/markup/highlightjs.css +134 -0
- package/theme/rf-monochrome/markup/shiki.css +27 -0
- package/THIRD_PARTY_NOTICES.md +0 -56
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# rf-basic Theme
|
|
2
|
+
|
|
3
|
+
`rf-basic` is the default color preset for `@peaceroad/markdown-it-renderer-fence`.
|
|
4
|
+
It is a mode/provider-aware theme package: import only the CSS and JavaScript helper that matches the renderer mode you actually run.
|
|
5
|
+
|
|
6
|
+
## Markup mode
|
|
7
|
+
|
|
8
|
+
Shiki markup mode uses the JavaScript Shiki theme object plus the shared block styling:
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
import { rfBasicShikiTheme } from '@peaceroad/markdown-it-renderer-fence/theme/rf-basic'
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```css
|
|
15
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic/base.css";
|
|
16
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic/markup/shiki.css";
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
highlight.js markup mode uses the same base plus highlight.js class rules:
|
|
20
|
+
|
|
21
|
+
```css
|
|
22
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic/base.css";
|
|
23
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic/markup/highlightjs.css";
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Custom Highlight API mode
|
|
27
|
+
|
|
28
|
+
Shiki API mode uses the provider helper and `::highlight(hl-shiki-role-*)` CSS:
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
import { createRfBasicShikiCustomHighlightOptions } from '@peaceroad/markdown-it-renderer-fence/theme/rf-basic'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```css
|
|
35
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic/base.css";
|
|
36
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic/api/shiki.css";
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
highlight.js API mode uses the highlight.js provider helper and API scope CSS:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import { createRfBasicHighlightjsCustomHighlightOptions } from '@peaceroad/markdown-it-renderer-fence/theme/rf-basic'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```css
|
|
46
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic/base.css";
|
|
47
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic/api/highlightjs.css";
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Complete preset
|
|
51
|
+
|
|
52
|
+
For demos or pages that intentionally compare providers, the complete color preset is available:
|
|
53
|
+
|
|
54
|
+
```css
|
|
55
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic.css";
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
It imports base layout, Shiki API scopes, highlight.js API scopes, and highlight.js markup classes.
|
|
59
|
+
|
|
60
|
+
## Color design
|
|
61
|
+
|
|
62
|
+
The palette is neutral-first: code backgrounds stay close to monochrome, syntax roles keep high contrast, and `samp` blocks invert the code palette so terminal output remains visually distinct in both light and dark color schemes.
|
|
63
|
+
|
|
64
|
+
Role directions:
|
|
65
|
+
|
|
66
|
+
- keyword: red/coral
|
|
67
|
+
- string: blue
|
|
68
|
+
- number/literal: blue-violet
|
|
69
|
+
- title/type: purple/magenta
|
|
70
|
+
- variable: amber/brown
|
|
71
|
+
- tag: green/teal
|
|
72
|
+
- punctuation/meta: neutral
|
|
73
|
+
|
|
74
|
+
The theme favors practical readability and cross-provider consistency over exact parity with any one editor theme.
|
|
75
|
+
|
|
76
|
+
## File roles
|
|
77
|
+
|
|
78
|
+
- `index.css`: complete color preset for demos and mixed-provider pages.
|
|
79
|
+
- `base.css`: public base import; it loads shared renderer-fence block/layout CSS.
|
|
80
|
+
- `markup/shiki.css`: Shiki markup correction for `samp` terminal surfaces.
|
|
81
|
+
- `markup/highlightjs.css`: highlight.js markup class rules.
|
|
82
|
+
- `api/highlightjs.css`: Custom Highlight API rules for highlight.js provider ranges.
|
|
83
|
+
- `api/shiki.css`: Custom Highlight API rules for Shiki role-mode ranges.
|
|
84
|
+
- `index.js`: Shiki theme object and provider option helpers.
|
|
85
|
+
|
|
86
|
+
The private `theme/_shared/rf-core.css` file is an internal source file used to avoid
|
|
87
|
+
duplicating block/layout CSS across themes. Import this theme's public `base.css` instead.
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
MIT, same as the package.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/*! rf-basic highlightjs API scopes | MIT License */
|
|
2
|
+
|
|
3
|
+
::highlight(hl-hljs-language-javascript),
|
|
4
|
+
::highlight(hl-hljs-subst) {
|
|
5
|
+
color: var(--rf-code-fg);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
::highlight(hl-hljs-keyword),
|
|
9
|
+
::highlight(hl-hljs-built-in),
|
|
10
|
+
::highlight(hl-hljs-built_in) {
|
|
11
|
+
color: var(--rf-syntax-keyword);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
::highlight(hl-hljs-string) {
|
|
15
|
+
color: var(--rf-syntax-string);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
::highlight(hl-hljs-number) {
|
|
19
|
+
color: var(--rf-syntax-number);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
::highlight(hl-hljs-comment) {
|
|
23
|
+
color: var(--rf-syntax-comment);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
::highlight(hl-hljs-literal) {
|
|
27
|
+
color: var(--rf-syntax-literal);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
::highlight(hl-hljs-type) {
|
|
31
|
+
color: var(--rf-syntax-type);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
::highlight(hl-hljs-title),
|
|
35
|
+
::highlight(hl-hljs-title-function),
|
|
36
|
+
::highlight(hl-hljs-title-class),
|
|
37
|
+
::highlight(hl-hljs-title-function-invoke),
|
|
38
|
+
::highlight(hl-hljs-function),
|
|
39
|
+
::highlight(hl-hljs-class) {
|
|
40
|
+
color: var(--rf-syntax-title);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
::highlight(hl-hljs-variable),
|
|
44
|
+
::highlight(hl-hljs-variable-constant),
|
|
45
|
+
::highlight(hl-hljs-variable-language),
|
|
46
|
+
::highlight(hl-hljs-params),
|
|
47
|
+
::highlight(hl-hljs-property) {
|
|
48
|
+
color: var(--rf-syntax-variable);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
::highlight(hl-hljs-tag),
|
|
52
|
+
::highlight(hl-hljs-name),
|
|
53
|
+
::highlight(hl-hljs-selector-pseudo) {
|
|
54
|
+
color: var(--rf-syntax-tag);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
::highlight(hl-hljs-attr),
|
|
58
|
+
::highlight(hl-hljs-attribute),
|
|
59
|
+
::highlight(hl-hljs-selector-class) {
|
|
60
|
+
color: var(--rf-syntax-attribute);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
::highlight(hl-hljs-punctuation),
|
|
64
|
+
::highlight(hl-hljs-meta),
|
|
65
|
+
::highlight(hl-hljs-operator) {
|
|
66
|
+
color: var(--rf-syntax-punctuation);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
::highlight(hl-hljs-symbol) {
|
|
70
|
+
color: var(--rf-syntax-literal);
|
|
71
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*! rf-basic Shiki API scopes | MIT License */
|
|
2
|
+
|
|
3
|
+
::highlight(hl-shiki-role-text) {
|
|
4
|
+
color: var(--rf-code-fg);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
::highlight(hl-shiki-role-keyword),
|
|
8
|
+
::highlight(hl-shiki-role-type-primitive) {
|
|
9
|
+
color: var(--rf-syntax-keyword);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
::highlight(hl-shiki-role-string),
|
|
13
|
+
::highlight(hl-shiki-role-string-unquoted) {
|
|
14
|
+
color: var(--rf-syntax-string);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
::highlight(hl-shiki-role-number) {
|
|
18
|
+
color: var(--rf-syntax-number);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
::highlight(hl-shiki-role-comment),
|
|
22
|
+
::highlight(hl-shiki-role-meta-shebang) {
|
|
23
|
+
color: var(--rf-syntax-comment);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
::highlight(hl-shiki-role-literal),
|
|
27
|
+
::highlight(hl-shiki-role-variable-this) {
|
|
28
|
+
color: var(--rf-syntax-literal);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
::highlight(hl-shiki-role-type),
|
|
32
|
+
::highlight(hl-shiki-role-type-name),
|
|
33
|
+
::highlight(hl-shiki-role-title-class),
|
|
34
|
+
::highlight(hl-shiki-role-namespace) {
|
|
35
|
+
color: var(--rf-syntax-type);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
::highlight(hl-shiki-role-title-function),
|
|
39
|
+
::highlight(hl-shiki-role-title-function-builtin) {
|
|
40
|
+
color: var(--rf-syntax-title);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
::highlight(hl-shiki-role-variable),
|
|
44
|
+
::highlight(hl-shiki-role-variable-const),
|
|
45
|
+
::highlight(hl-shiki-role-variable-member),
|
|
46
|
+
::highlight(hl-shiki-role-variable-plain),
|
|
47
|
+
::highlight(hl-shiki-role-variable-property),
|
|
48
|
+
::highlight(hl-shiki-role-variable-parameter) {
|
|
49
|
+
color: var(--rf-syntax-variable);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
::highlight(hl-shiki-role-tag) {
|
|
53
|
+
color: var(--rf-syntax-tag);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
::highlight(hl-shiki-role-attribute) {
|
|
57
|
+
color: var(--rf-syntax-attribute);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
::highlight(hl-shiki-role-punctuation),
|
|
61
|
+
::highlight(hl-shiki-role-tag-delimiter) {
|
|
62
|
+
color: var(--rf-syntax-punctuation);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
::highlight(hl-shiki-role-meta) {
|
|
66
|
+
color: var(--rf-code-fg);
|
|
67
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { rendererFenceShikiThemeScopeGroups } from '../../src/custom-highlight/shiki-theme-role.js'
|
|
2
|
+
|
|
3
|
+
const rfBasicThemeName = 'rf-basic'
|
|
4
|
+
const rfBasicShikiThemeName = rfBasicThemeName
|
|
5
|
+
|
|
6
|
+
const rfBasicSyntaxCssVars = Object.freeze({
|
|
7
|
+
background: 'var(--rf-code-bg)',
|
|
8
|
+
text: 'var(--rf-code-fg)',
|
|
9
|
+
keyword: 'var(--rf-syntax-keyword)',
|
|
10
|
+
string: 'var(--rf-syntax-string)',
|
|
11
|
+
number: 'var(--rf-syntax-number)',
|
|
12
|
+
comment: 'var(--rf-syntax-comment)',
|
|
13
|
+
type: 'var(--rf-syntax-type)',
|
|
14
|
+
title: 'var(--rf-syntax-title)',
|
|
15
|
+
variable: 'var(--rf-syntax-variable)',
|
|
16
|
+
literal: 'var(--rf-syntax-literal)',
|
|
17
|
+
tag: 'var(--rf-syntax-tag)',
|
|
18
|
+
attribute: 'var(--rf-syntax-attribute)',
|
|
19
|
+
punctuation: 'var(--rf-syntax-punctuation)',
|
|
20
|
+
meta: 'var(--rf-syntax-meta)',
|
|
21
|
+
|
|
22
|
+
// Backward-friendly role aliases for highlighter APIs that use these names.
|
|
23
|
+
constant: 'var(--rf-syntax-literal)',
|
|
24
|
+
builtIn: 'var(--rf-syntax-variable)',
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const mergePalette = (palette) => palette
|
|
28
|
+
? Object.assign({}, rfBasicSyntaxCssVars, palette)
|
|
29
|
+
: rfBasicSyntaxCssVars
|
|
30
|
+
|
|
31
|
+
const createTokenColor = (scope, foreground) => ({
|
|
32
|
+
scope: Array.isArray(scope) ? scope.slice() : scope,
|
|
33
|
+
settings: { foreground },
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const createRfBasicShikiTheme = ({
|
|
37
|
+
name = rfBasicShikiThemeName,
|
|
38
|
+
palette = null,
|
|
39
|
+
} = {}) => {
|
|
40
|
+
const p = mergePalette(palette)
|
|
41
|
+
return {
|
|
42
|
+
name,
|
|
43
|
+
type: 'light',
|
|
44
|
+
colors: {
|
|
45
|
+
'editor.foreground': p.text,
|
|
46
|
+
'editor.background': p.background,
|
|
47
|
+
},
|
|
48
|
+
tokenColors: [
|
|
49
|
+
{ settings: { foreground: p.text } },
|
|
50
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.comment, p.comment),
|
|
51
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.string, p.string),
|
|
52
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.number, p.number),
|
|
53
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.literal, p.literal),
|
|
54
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.keyword, p.keyword),
|
|
55
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.punctuation, p.punctuation),
|
|
56
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.title, p.title),
|
|
57
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.type, p.type),
|
|
58
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.variable, p.variable),
|
|
59
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.tag, p.tag),
|
|
60
|
+
createTokenColor(rendererFenceShikiThemeScopeGroups.attribute, p.attribute),
|
|
61
|
+
],
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const rfBasicShikiTheme = createRfBasicShikiTheme()
|
|
66
|
+
|
|
67
|
+
const createRfBasicShikiRoleScopeColorVars = (palette = null) => {
|
|
68
|
+
const p = mergePalette(palette)
|
|
69
|
+
return {
|
|
70
|
+
'hl-shiki-role-keyword': p.keyword,
|
|
71
|
+
'hl-shiki-role-type-primitive': p.keyword,
|
|
72
|
+
'hl-shiki-role-number': p.number,
|
|
73
|
+
'hl-shiki-role-string': p.string,
|
|
74
|
+
'hl-shiki-role-string-unquoted': p.string,
|
|
75
|
+
'hl-shiki-role-variable': p.variable,
|
|
76
|
+
'hl-shiki-role-variable-this': p.literal,
|
|
77
|
+
'hl-shiki-role-variable-const': p.variable,
|
|
78
|
+
'hl-shiki-role-variable-member': p.variable,
|
|
79
|
+
'hl-shiki-role-variable-plain': p.variable,
|
|
80
|
+
'hl-shiki-role-variable-property': p.variable,
|
|
81
|
+
'hl-shiki-role-variable-parameter': p.variable,
|
|
82
|
+
'hl-shiki-role-title-function': p.title,
|
|
83
|
+
'hl-shiki-role-title-function-builtin': p.title,
|
|
84
|
+
'hl-shiki-role-title-class': p.type,
|
|
85
|
+
'hl-shiki-role-namespace': p.type,
|
|
86
|
+
'hl-shiki-role-literal': p.literal,
|
|
87
|
+
'hl-shiki-role-comment': p.comment,
|
|
88
|
+
'hl-shiki-role-meta-shebang': p.comment,
|
|
89
|
+
'hl-shiki-role-punctuation': p.punctuation,
|
|
90
|
+
'hl-shiki-role-meta': p.text,
|
|
91
|
+
'hl-shiki-role-type': p.type,
|
|
92
|
+
'hl-shiki-role-type-name': p.type,
|
|
93
|
+
'hl-shiki-role-tag': p.tag,
|
|
94
|
+
'hl-shiki-role-tag-delimiter': p.punctuation,
|
|
95
|
+
'hl-shiki-role-attribute': p.attribute,
|
|
96
|
+
'hl-shiki-role-text': p.text,
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const rfBasicShikiRoleScopeColorVars = Object.freeze(
|
|
101
|
+
createRfBasicShikiRoleScopeColorVars(),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
const createHighlightjsHighlightFn = (hljs) => {
|
|
105
|
+
if (!hljs || typeof hljs.highlight !== 'function') return null
|
|
106
|
+
return (code, lang) => {
|
|
107
|
+
const target = (lang && typeof hljs.getLanguage === 'function' && hljs.getLanguage(lang))
|
|
108
|
+
? lang
|
|
109
|
+
: 'plaintext'
|
|
110
|
+
return hljs.highlight(code, { language: target })
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const createRfBasicShikiCustomHighlightOptions = ({
|
|
115
|
+
highlighter,
|
|
116
|
+
theme = rfBasicShikiThemeName,
|
|
117
|
+
shikiScopeMode = 'semantic',
|
|
118
|
+
includeScopeStyles = shikiScopeMode === 'role' ? false : true,
|
|
119
|
+
...overrides
|
|
120
|
+
} = {}) => ({
|
|
121
|
+
...overrides,
|
|
122
|
+
provider: 'shiki',
|
|
123
|
+
highlighter,
|
|
124
|
+
theme,
|
|
125
|
+
shikiScopeMode,
|
|
126
|
+
includeScopeStyles,
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
const createRfBasicHighlightjsCustomHighlightOptions = ({
|
|
130
|
+
hljs,
|
|
131
|
+
hljsHighlight,
|
|
132
|
+
highlight,
|
|
133
|
+
includeScopeStyles = false,
|
|
134
|
+
...overrides
|
|
135
|
+
} = {}) => ({
|
|
136
|
+
...overrides,
|
|
137
|
+
provider: 'hljs',
|
|
138
|
+
includeScopeStyles,
|
|
139
|
+
hljsHighlight: hljsHighlight || highlight || createHighlightjsHighlightFn(hljs),
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const rfBasicShikiThemeScopeGroups = rendererFenceShikiThemeScopeGroups
|
|
143
|
+
|
|
144
|
+
export {
|
|
145
|
+
createRfBasicHighlightjsCustomHighlightOptions,
|
|
146
|
+
createRfBasicShikiCustomHighlightOptions,
|
|
147
|
+
createRfBasicShikiRoleScopeColorVars,
|
|
148
|
+
createRfBasicShikiTheme,
|
|
149
|
+
rfBasicShikiRoleScopeColorVars,
|
|
150
|
+
rfBasicShikiTheme,
|
|
151
|
+
rfBasicShikiThemeName,
|
|
152
|
+
rfBasicShikiThemeScopeGroups,
|
|
153
|
+
rfBasicSyntaxCssVars,
|
|
154
|
+
rfBasicThemeName,
|
|
155
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*! rf-basic highlight.js markup scopes | MIT License */
|
|
2
|
+
|
|
3
|
+
.hljs-keyword,
|
|
4
|
+
.hljs-built_in {
|
|
5
|
+
color: var(--rf-syntax-keyword);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.hljs-string {
|
|
9
|
+
color: var(--rf-syntax-string);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.hljs-number {
|
|
13
|
+
color: var(--rf-syntax-number);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.hljs-comment {
|
|
17
|
+
color: var(--rf-syntax-comment);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.hljs-literal,
|
|
21
|
+
.hljs-symbol {
|
|
22
|
+
color: var(--rf-syntax-literal);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.hljs-type {
|
|
26
|
+
color: var(--rf-syntax-type);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.hljs-title,
|
|
30
|
+
.hljs-title.function_,
|
|
31
|
+
.hljs-title.class_,
|
|
32
|
+
.hljs-function,
|
|
33
|
+
.hljs-class {
|
|
34
|
+
color: var(--rf-syntax-title);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.hljs-variable,
|
|
38
|
+
.hljs-variable.constant_,
|
|
39
|
+
.hljs-params,
|
|
40
|
+
.hljs-property {
|
|
41
|
+
color: var(--rf-syntax-variable);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.hljs-tag,
|
|
45
|
+
.hljs-name {
|
|
46
|
+
color: var(--rf-syntax-tag);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.hljs-attr,
|
|
50
|
+
.hljs-attribute,
|
|
51
|
+
.hljs-selector-class {
|
|
52
|
+
color: var(--rf-syntax-attribute);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.hljs-punctuation,
|
|
56
|
+
.hljs-meta,
|
|
57
|
+
.hljs-operator {
|
|
58
|
+
color: var(--rf-syntax-punctuation);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.hljs-meta.prompt_ {
|
|
62
|
+
color: var(--rf-code-muted);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.hljs-subst,
|
|
66
|
+
.language-javascript {
|
|
67
|
+
color: var(--rf-code-fg);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
pre:has(> samp) .hljs-meta.prompt_ {
|
|
71
|
+
color: var(--rf-samp-prompt);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
pre:has(> samp) .hljs-subst,
|
|
75
|
+
pre:has(> samp) .language-javascript {
|
|
76
|
+
color: var(--rf-samp-fg);
|
|
77
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*! rf-basic Shiki markup scopes | MIT License */
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Shiki writes background/color as inline styles on `<pre>`. When renderer-fence
|
|
5
|
+
* outputs a Shiki-highlighted `<samp>`, re-apply the rf-basic terminal surface
|
|
6
|
+
* so the samp syntax variables are not rendered on the normal code background.
|
|
7
|
+
*/
|
|
8
|
+
pre.shiki:has(> samp) {
|
|
9
|
+
color: var(--rf-samp-fg) !important;
|
|
10
|
+
background-color: var(--rf-samp-bg) !important;
|
|
11
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# rf-monochrome Theme
|
|
2
|
+
|
|
3
|
+
`rf-monochrome` is a one-color markup-mode preset for `@peaceroad/markdown-it-renderer-fence`.
|
|
4
|
+
It uses the shared renderer-fence code surface plus bold/italic cues instead of syntax colors. It is intended for print, photocopy-safe output, or documents that must keep code in a single text color.
|
|
5
|
+
|
|
6
|
+
## Scope
|
|
7
|
+
|
|
8
|
+
This is intentionally a markup-mode theme. Browser Custom Highlight API rules cannot reliably apply `font-weight` or `font-style`, so API-mode monochrome would mostly be `color: currentColor` and would not provide the intended structure cues.
|
|
9
|
+
|
|
10
|
+
## highlight.js markup
|
|
11
|
+
|
|
12
|
+
```css
|
|
13
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-monochrome.css";
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
or, if you want split imports:
|
|
17
|
+
|
|
18
|
+
```css
|
|
19
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-monochrome/base.css";
|
|
20
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-monochrome/markup/highlightjs.css";
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Shiki markup
|
|
24
|
+
|
|
25
|
+
Use the Shiki theme object plus base CSS:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
import { rfMonochromeShikiTheme } from '@peaceroad/markdown-it-renderer-fence/theme/rf-monochrome'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-monochrome/base.css";
|
|
33
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-monochrome/markup/shiki.css";
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`markup/shiki.css` maps Shiki's inline `currentColor` / transparent surface back to the shared code and `samp` surfaces; the main Shiki token styling comes from `rfMonochromeShikiTheme`.
|
|
37
|
+
|
|
38
|
+
## Design notes
|
|
39
|
+
|
|
40
|
+
- No underline by default; underline makes code harder to scan and can look like links.
|
|
41
|
+
- Keywords, type/class/tag-like structural tokens use bold.
|
|
42
|
+
- Comments and meta-like regions use italic by default.
|
|
43
|
+
- Doc tags and method-like titles stay normal weight so they do not compete with structural keywords.
|
|
44
|
+
- Terminal-like `<samp>` blocks suppress token-level bold/italic so prompts, commands, and output do not look inconsistently emphasized.
|
|
45
|
+
|
|
46
|
+
Italic comments are only a default. CJK comments may be easier to read without italics:
|
|
47
|
+
|
|
48
|
+
```css
|
|
49
|
+
pre code,
|
|
50
|
+
pre samp,
|
|
51
|
+
.hljs {
|
|
52
|
+
--rf-monochrome-comment-font-style: normal;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For Shiki markup output, create the theme with `createRfMonochromeShikiTheme({ commentFontStyle: '' })`.
|
|
57
|
+
|
|
58
|
+
## File roles
|
|
59
|
+
|
|
60
|
+
- `index.css`: complete monochrome markup preset.
|
|
61
|
+
- `base.css`: public base import; it loads shared renderer-fence block/layout CSS.
|
|
62
|
+
- `markup/highlightjs.css`: highlight.js monochrome class rules.
|
|
63
|
+
- `markup/shiki.css`: Shiki markup `samp` override.
|
|
64
|
+
- `index.js`: Shiki monochrome theme object and factory.
|
|
65
|
+
|
|
66
|
+
The private `theme/_shared/rf-core.css` file is an internal source file used to avoid
|
|
67
|
+
duplicating block/layout CSS across themes. Import this theme's public `base.css` instead.
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT, same as the package.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { rendererFenceShikiThemeScopeGroups } from '../../src/custom-highlight/shiki-theme-role.js'
|
|
2
|
+
|
|
3
|
+
const rfMonochromeThemeName = 'rf-monochrome'
|
|
4
|
+
const rfMonochromeShikiThemeName = rfMonochromeThemeName
|
|
5
|
+
|
|
6
|
+
const createTokenFontStyle = (scope, foreground, fontStyle) => ({
|
|
7
|
+
scope: Array.isArray(scope) ? scope.slice() : scope,
|
|
8
|
+
settings: { foreground, fontStyle },
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const rfMonochromeNormalScopeOverrides = Object.freeze([
|
|
12
|
+
'meta.method.declaration.js storage.type.js',
|
|
13
|
+
'meta.method.declaration.ts storage.type.ts',
|
|
14
|
+
'keyword.operator.or.regexp',
|
|
15
|
+
'keyword.operator.quantifier.regexp',
|
|
16
|
+
])
|
|
17
|
+
|
|
18
|
+
const rfMonochromeCommentScopeOverrides = Object.freeze([
|
|
19
|
+
'comment.block.documentation.js storage.type.class.jsdoc',
|
|
20
|
+
'comment.block.documentation.ts storage.type.class.jsdoc',
|
|
21
|
+
'comment.block.documentation.js entity.name.type.instance.jsdoc',
|
|
22
|
+
'comment.block.documentation.ts entity.name.type.instance.jsdoc',
|
|
23
|
+
'comment.block.documentation.js variable.other.jsdoc',
|
|
24
|
+
'comment.block.documentation.ts variable.other.jsdoc',
|
|
25
|
+
'comment.block.documentation.js punctuation.definition.block.tag.jsdoc',
|
|
26
|
+
'comment.block.documentation.ts punctuation.definition.block.tag.jsdoc',
|
|
27
|
+
'comment.block.documentation.js punctuation.definition.bracket.curly.begin.jsdoc',
|
|
28
|
+
'comment.block.documentation.ts punctuation.definition.bracket.curly.begin.jsdoc',
|
|
29
|
+
'comment.block.documentation.js punctuation.definition.bracket.curly.end.jsdoc',
|
|
30
|
+
'comment.block.documentation.ts punctuation.definition.bracket.curly.end.jsdoc',
|
|
31
|
+
])
|
|
32
|
+
|
|
33
|
+
const createRfMonochromeShikiTheme = ({
|
|
34
|
+
name = rfMonochromeShikiThemeName,
|
|
35
|
+
foreground = 'currentColor',
|
|
36
|
+
background = 'transparent',
|
|
37
|
+
commentFontStyle = 'italic',
|
|
38
|
+
} = {}) => ({
|
|
39
|
+
name,
|
|
40
|
+
type: 'light',
|
|
41
|
+
colors: {
|
|
42
|
+
'editor.foreground': foreground,
|
|
43
|
+
'editor.background': background,
|
|
44
|
+
},
|
|
45
|
+
tokenColors: [
|
|
46
|
+
{ settings: { foreground, background } },
|
|
47
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.comment, foreground, commentFontStyle),
|
|
48
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.keyword, foreground, 'bold'),
|
|
49
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.type, foreground, 'bold'),
|
|
50
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.tag, foreground, 'bold'),
|
|
51
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.title, foreground, ''),
|
|
52
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.string, foreground, ''),
|
|
53
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.number, foreground, ''),
|
|
54
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.literal, foreground, ''),
|
|
55
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.variable, foreground, ''),
|
|
56
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.attribute, foreground, ''),
|
|
57
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.punctuation, foreground, ''),
|
|
58
|
+
createTokenFontStyle(rfMonochromeNormalScopeOverrides, foreground, ''),
|
|
59
|
+
createTokenFontStyle(rfMonochromeCommentScopeOverrides, foreground, commentFontStyle),
|
|
60
|
+
],
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const rfMonochromeShikiTheme = createRfMonochromeShikiTheme()
|
|
64
|
+
const rfMonochromeShikiThemeScopeGroups = rendererFenceShikiThemeScopeGroups
|
|
65
|
+
|
|
66
|
+
export {
|
|
67
|
+
createRfMonochromeShikiTheme,
|
|
68
|
+
rfMonochromeShikiTheme,
|
|
69
|
+
rfMonochromeShikiThemeName,
|
|
70
|
+
rfMonochromeShikiThemeScopeGroups,
|
|
71
|
+
rfMonochromeThemeName,
|
|
72
|
+
}
|