@peaceroad/markdown-it-renderer-fence 0.8.0 → 0.9.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 +11 -6
- package/docs/code-highlighting-design.md +8 -4
- package/docs/custom-highlight-styling-guide.md +12 -6
- package/package.json +7 -5
- package/src/custom-highlight/payload-utils.js +4 -9
- package/src/custom-highlight/shiki-role-rules.js +20 -10
- package/src/custom-highlight/shiki-role.js +50 -50
- package/src/fence/render-api-constants.js +1 -1
- package/src/fence/render-api-provider.js +2 -3
- package/src/fence/render-api-renderer.js +19 -4
- package/src/fence/render-api-runtime.js +29 -10
- package/src/fence/render-markup.js +30 -15
- package/src/fence/render-shared.js +72 -22
- package/src/utils/attr-utils.js +10 -0
- package/theme/_shared/rf-core.css +7 -1
- package/theme/line-notes.css +94 -0
- package/theme/line-number.css +64 -0
- package/theme/rf-basic/README.md +31 -5
- package/theme/rf-basic/api/shiki.css +1 -1
- package/theme/rf-basic/base.css +2 -0
- package/theme/rf-basic/index.js +9 -0
- package/theme/rf-monochrome/README.md +21 -8
- package/theme/rf-monochrome/base.css +2 -0
- package/theme/rf-monochrome/index.js +4 -5
- package/theme/rf-monochrome/markup/highlightjs.css +26 -10
- package/theme/rf-monochrome/markup/shiki.css +12 -1
package/theme/rf-basic/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# rf-basic Theme
|
|
2
2
|
|
|
3
|
-
`rf-basic` is the
|
|
3
|
+
`rf-basic` is the optional first-party color preset for `@peaceroad/markdown-it-renderer-fence`.
|
|
4
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
5
|
|
|
6
6
|
## Markup mode
|
|
@@ -25,10 +25,12 @@ highlight.js markup mode uses the same base plus highlight.js class rules:
|
|
|
25
25
|
|
|
26
26
|
## Custom Highlight API mode
|
|
27
27
|
|
|
28
|
-
Shiki API mode uses the
|
|
28
|
+
Shiki API mode has two distinct profiles. The recommended CSS-managed role profile uses the dedicated helper and `::highlight(hl-shiki-role-*)` CSS:
|
|
29
29
|
|
|
30
30
|
```js
|
|
31
|
-
import {
|
|
31
|
+
import { createRfBasicShikiRoleCustomHighlightOptions } from '@peaceroad/markdown-it-renderer-fence/theme/rf-basic'
|
|
32
|
+
|
|
33
|
+
const customHighlight = createRfBasicShikiRoleCustomHighlightOptions({ highlighter })
|
|
32
34
|
```
|
|
33
35
|
|
|
34
36
|
```css
|
|
@@ -36,6 +38,8 @@ import { createRfBasicShikiCustomHighlightOptions } from '@peaceroad/markdown-it
|
|
|
36
38
|
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic/api/shiki.css";
|
|
37
39
|
```
|
|
38
40
|
|
|
41
|
+
The generic `createRfBasicShikiCustomHighlightOptions()` helper keeps its `semantic` + embedded `scopeStyles` defaults for callers that want provider-owned payload styles. That profile needs `base.css` to define the `--rf-*` variables, but it does not depend on the role-only `api/shiki.css` selectors.
|
|
42
|
+
|
|
39
43
|
highlight.js API mode uses the highlight.js provider helper and API scope CSS:
|
|
40
44
|
|
|
41
45
|
```js
|
|
@@ -55,7 +59,27 @@ For demos or pages that intentionally compare providers, the complete color pres
|
|
|
55
59
|
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic.css";
|
|
56
60
|
```
|
|
57
61
|
|
|
58
|
-
It imports base layout, Shiki API scopes, highlight.js API scopes, and highlight.js markup classes.
|
|
62
|
+
It imports base layout, line-number/line-notes layout, Shiki role-mode API scopes, highlight.js API scopes, Shiki markup correction, and highlight.js markup classes.
|
|
63
|
+
|
|
64
|
+
The base palette follows `prefers-color-scheme`, but applies the CSS `color-scheme` hint only to each `pre` surface. Importing the theme does not change UA colors for the whole document. Sites with an explicit theme can override `--rf-code-color-scheme` and `--rf-samp-color-scheme` together with the palette variables.
|
|
65
|
+
|
|
66
|
+
## Line feature customization
|
|
67
|
+
|
|
68
|
+
The renderer owns line-number markup, counter values, skip/set behavior, and line wrappers. The structural CSS owns presentation, so an application theme can change the layout without changing renderer options:
|
|
69
|
+
|
|
70
|
+
```css
|
|
71
|
+
@import "@peaceroad/markdown-it-renderer-fence/theme/rf-basic.css";
|
|
72
|
+
|
|
73
|
+
.docs-theme {
|
|
74
|
+
--line-number-width: 3ch;
|
|
75
|
+
--line-number-gap: 0.75ch;
|
|
76
|
+
--line-number-rule-gap: 0.5ch;
|
|
77
|
+
--line-number-color: oklch(48% 0.03 250);
|
|
78
|
+
--line-number-rule-color: oklch(82% 0.02 250);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The variables are inherited, so they can be set globally or on a container that owns the rendered Markdown. The preset gives `samp` an inverted terminal palette on `pre:has(> samp)`; override the same variables on that `pre` selector as well when terminal line numbers need a different application-specific treatment.
|
|
59
83
|
|
|
60
84
|
## Color design
|
|
61
85
|
|
|
@@ -76,7 +100,7 @@ The theme favors practical readability and cross-provider consistency over exact
|
|
|
76
100
|
## File roles
|
|
77
101
|
|
|
78
102
|
- `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.
|
|
103
|
+
- `base.css`: public base import; it loads shared renderer-fence block/layout CSS plus package-owned line-number and line-notes layout.
|
|
80
104
|
- `markup/shiki.css`: Shiki markup correction for `samp` terminal surfaces.
|
|
81
105
|
- `markup/highlightjs.css`: highlight.js markup class rules.
|
|
82
106
|
- `api/highlightjs.css`: Custom Highlight API rules for highlight.js provider ranges.
|
|
@@ -85,6 +109,8 @@ The theme favors practical readability and cross-provider consistency over exact
|
|
|
85
109
|
|
|
86
110
|
The private `theme/_shared/rf-core.css` file is an internal source file used to avoid
|
|
87
111
|
duplicating block/layout CSS across themes. Import this theme's public `base.css` instead.
|
|
112
|
+
The theme-neutral structural files are also public as `theme/line-number.css` and `theme/line-notes.css` for consumers that do not want a preset palette.
|
|
113
|
+
The below-block line-note label can be localized without changing renderer HTML by overriding `--line-note-label-prefix` and `--line-note-label-suffix`.
|
|
88
114
|
|
|
89
115
|
## License
|
|
90
116
|
|
package/theme/rf-basic/base.css
CHANGED
package/theme/rf-basic/index.js
CHANGED
|
@@ -126,6 +126,14 @@ const createRfBasicShikiCustomHighlightOptions = ({
|
|
|
126
126
|
includeScopeStyles,
|
|
127
127
|
})
|
|
128
128
|
|
|
129
|
+
const createRfBasicShikiRoleCustomHighlightOptions = (options = {}) => {
|
|
130
|
+
return createRfBasicShikiCustomHighlightOptions({
|
|
131
|
+
...options,
|
|
132
|
+
shikiScopeMode: 'role',
|
|
133
|
+
includeScopeStyles: false,
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
|
|
129
137
|
const createRfBasicHighlightjsCustomHighlightOptions = ({
|
|
130
138
|
hljs,
|
|
131
139
|
hljsHighlight,
|
|
@@ -144,6 +152,7 @@ const rfBasicShikiThemeScopeGroups = rendererFenceShikiThemeScopeGroups
|
|
|
144
152
|
export {
|
|
145
153
|
createRfBasicHighlightjsCustomHighlightOptions,
|
|
146
154
|
createRfBasicShikiCustomHighlightOptions,
|
|
155
|
+
createRfBasicShikiRoleCustomHighlightOptions,
|
|
147
156
|
createRfBasicShikiRoleScopeColorVars,
|
|
148
157
|
createRfBasicShikiTheme,
|
|
149
158
|
rfBasicShikiRoleScopeColorVars,
|
|
@@ -39,32 +39,45 @@ import { rfMonochromeShikiTheme } from '@peaceroad/markdown-it-renderer-fence/th
|
|
|
39
39
|
|
|
40
40
|
- No underline by default; underline makes code harder to scan and can look like links.
|
|
41
41
|
- Keywords, type/class/tag-like structural tokens use bold.
|
|
42
|
-
- Comments
|
|
43
|
-
- Doc tags and method
|
|
42
|
+
- Comments use italic by default; metadata stays normal so it does not become visually indistinguishable from prose comments.
|
|
43
|
+
- Doc tags and ordinary function/method titles stay normal weight so they do not compete with structural keywords. Shiki may classify constructor-like tokens as `storage.type`; keeping those bold avoids a broader override that would also neutralize `const` / `let` / `var` declarations inside method bodies.
|
|
44
44
|
- Terminal-like `<samp>` blocks suppress token-level bold/italic so prompts, commands, and output do not look inconsistently emphasized.
|
|
45
45
|
|
|
46
|
-
Italic comments are only a default.
|
|
46
|
+
Italic comments are only a default. When the rendered code inherits `lang="ja"`, `lang="zh"`, or `lang="ko"` from the document or a nearer container, the preset automatically renders comment tokens upright. CSS `:lang()` matching also covers subtags such as `ja-JP`.
|
|
47
|
+
|
|
48
|
+
You can still disable comment italics explicitly for another language or a specific container:
|
|
47
49
|
|
|
48
50
|
```css
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
.hljs {
|
|
51
|
+
/* Global or scoped to the container that owns rendered Markdown. */
|
|
52
|
+
.docs-theme {
|
|
52
53
|
--rf-monochrome-comment-font-style: normal;
|
|
53
54
|
}
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
For Shiki markup output,
|
|
57
|
+
For Shiki markup output, the preset CSS overrides the default inline italic style for inherited CJK languages. Create the theme with `createRfMonochromeShikiTheme({ commentFontStyle: '' })` when comments should remain upright regardless of language.
|
|
58
|
+
|
|
59
|
+
Typography defaults live on `:root` and inherit into code blocks, so an application can override them globally or on a Markdown container. Structural emphasis can be tuned without rewriting the theme. highlight.js consumers can override `--rf-monochrome-strong-font-weight` (default `700`) and `--rf-monochrome-normal-font-weight` (default `400`). Shiki accepts `createRfMonochromeShikiTheme({ structuralFontStyle: '' })` when an application wants a completely regular-weight one-color rendering. Shiki's TextMate `fontStyle` supports semantic `bold` rather than an arbitrary numeric weight, so exact `600`/`650` parity remains CSS/highlight.js-specific.
|
|
60
|
+
|
|
61
|
+
Metadata is normal by default. Sites that prefer italic preprocessor or metadata tokens can opt in:
|
|
62
|
+
|
|
63
|
+
```css
|
|
64
|
+
.docs-theme {
|
|
65
|
+
--rf-monochrome-meta-font-style: italic;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
57
68
|
|
|
58
69
|
## File roles
|
|
59
70
|
|
|
60
71
|
- `index.css`: complete monochrome markup preset.
|
|
61
|
-
- `base.css`: public base import; it loads shared renderer-fence block/layout CSS.
|
|
72
|
+
- `base.css`: public base import; it loads shared renderer-fence block/layout CSS plus package-owned line-number and line-notes layout.
|
|
62
73
|
- `markup/highlightjs.css`: highlight.js monochrome class rules.
|
|
63
74
|
- `markup/shiki.css`: Shiki markup `samp` override.
|
|
64
75
|
- `index.js`: Shiki monochrome theme object and factory.
|
|
65
76
|
|
|
66
77
|
The private `theme/_shared/rf-core.css` file is an internal source file used to avoid
|
|
67
78
|
duplicating block/layout CSS across themes. Import this theme's public `base.css` instead.
|
|
79
|
+
The structural layouts are also available without a palette as `theme/line-number.css` and `theme/line-notes.css`.
|
|
80
|
+
The below-block line-note label is customizable through `--line-note-label-prefix` and `--line-note-label-suffix`.
|
|
68
81
|
|
|
69
82
|
## License
|
|
70
83
|
|
|
@@ -9,8 +9,6 @@ const createTokenFontStyle = (scope, foreground, fontStyle) => ({
|
|
|
9
9
|
})
|
|
10
10
|
|
|
11
11
|
const rfMonochromeNormalScopeOverrides = Object.freeze([
|
|
12
|
-
'meta.method.declaration.js storage.type.js',
|
|
13
|
-
'meta.method.declaration.ts storage.type.ts',
|
|
14
12
|
'keyword.operator.or.regexp',
|
|
15
13
|
'keyword.operator.quantifier.regexp',
|
|
16
14
|
])
|
|
@@ -35,6 +33,7 @@ const createRfMonochromeShikiTheme = ({
|
|
|
35
33
|
foreground = 'currentColor',
|
|
36
34
|
background = 'transparent',
|
|
37
35
|
commentFontStyle = 'italic',
|
|
36
|
+
structuralFontStyle = 'bold',
|
|
38
37
|
} = {}) => ({
|
|
39
38
|
name,
|
|
40
39
|
type: 'light',
|
|
@@ -45,9 +44,9 @@ const createRfMonochromeShikiTheme = ({
|
|
|
45
44
|
tokenColors: [
|
|
46
45
|
{ settings: { foreground, background } },
|
|
47
46
|
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.comment, foreground, commentFontStyle),
|
|
48
|
-
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.keyword, foreground,
|
|
49
|
-
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.type, foreground,
|
|
50
|
-
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.tag, foreground,
|
|
47
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.keyword, foreground, structuralFontStyle),
|
|
48
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.type, foreground, structuralFontStyle),
|
|
49
|
+
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.tag, foreground, structuralFontStyle),
|
|
51
50
|
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.title, foreground, ''),
|
|
52
51
|
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.string, foreground, ''),
|
|
53
52
|
createTokenFontStyle(rendererFenceShikiThemeScopeGroups.number, foreground, ''),
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
/*! rf-monochrome highlightjs markup theme | MIT License */
|
|
2
2
|
|
|
3
|
+
:root {
|
|
4
|
+
--rf-monochrome-strong-font-weight: 700;
|
|
5
|
+
--rf-monochrome-normal-font-weight: 400;
|
|
6
|
+
--rf-monochrome-comment-font-style: italic;
|
|
7
|
+
--rf-monochrome-meta-font-style: normal;
|
|
8
|
+
--rf-monochrome-meta-font-weight: var(--rf-monochrome-normal-font-weight);
|
|
9
|
+
--rf-monochrome-doctag-font-weight: var(--rf-monochrome-normal-font-weight);
|
|
10
|
+
}
|
|
11
|
+
|
|
3
12
|
pre {
|
|
4
13
|
--rf-monochrome-fg: var(--rf-code-fg);
|
|
5
14
|
--rf-monochrome-bg: var(--rf-code-bg);
|
|
@@ -12,10 +21,6 @@ pre samp,
|
|
|
12
21
|
.hljs {
|
|
13
22
|
color: var(--rf-monochrome-fg, var(--rf-code-fg));
|
|
14
23
|
background: transparent;
|
|
15
|
-
--rf-monochrome-comment-font-style: italic;
|
|
16
|
-
--rf-monochrome-meta-font-style: italic;
|
|
17
|
-
--rf-monochrome-meta-font-weight: 400;
|
|
18
|
-
--rf-monochrome-doctag-font-weight: 400;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
/*
|
|
@@ -39,7 +44,7 @@ pre:has(> samp) {
|
|
|
39
44
|
.hljs-type,
|
|
40
45
|
.hljs-strong {
|
|
41
46
|
color: var(--rf-monochrome-fg, var(--rf-code-fg));
|
|
42
|
-
font-weight: 700;
|
|
47
|
+
font-weight: var(--rf-monochrome-strong-font-weight, 700);
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
.hljs-title,
|
|
@@ -48,7 +53,7 @@ pre:has(> samp) {
|
|
|
48
53
|
.hljs-function,
|
|
49
54
|
.hljs-class {
|
|
50
55
|
color: var(--rf-monochrome-fg, var(--rf-code-fg));
|
|
51
|
-
font-weight: 400;
|
|
56
|
+
font-weight: var(--rf-monochrome-normal-font-weight, 400);
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
.hljs-comment,
|
|
@@ -63,10 +68,21 @@ pre:has(> samp) {
|
|
|
63
68
|
font-style: var(--rf-monochrome-comment-font-style, italic);
|
|
64
69
|
}
|
|
65
70
|
|
|
71
|
+
/*
|
|
72
|
+
* CJK fonts rarely provide a true italic face. Let the inherited document or
|
|
73
|
+
* container language disable synthetic italics for comments automatically.
|
|
74
|
+
* `:lang(ja)` also matches language tags such as `ja-JP`.
|
|
75
|
+
*/
|
|
76
|
+
.hljs-comment:lang(ja),
|
|
77
|
+
.hljs-comment:lang(zh),
|
|
78
|
+
.hljs-comment:lang(ko) {
|
|
79
|
+
--rf-monochrome-comment-font-style: normal;
|
|
80
|
+
}
|
|
81
|
+
|
|
66
82
|
.hljs-meta,
|
|
67
83
|
.hljs-doctag {
|
|
68
84
|
color: var(--rf-monochrome-fg, var(--rf-code-fg));
|
|
69
|
-
font-style: var(--rf-monochrome-meta-font-style,
|
|
85
|
+
font-style: var(--rf-monochrome-meta-font-style, normal);
|
|
70
86
|
font-weight: var(--rf-monochrome-meta-font-weight, 400);
|
|
71
87
|
}
|
|
72
88
|
|
|
@@ -78,7 +94,7 @@ pre:has(> samp) {
|
|
|
78
94
|
.hljs-comment .hljs-type,
|
|
79
95
|
.hljs-comment .hljs-variable {
|
|
80
96
|
font-style: inherit;
|
|
81
|
-
font-weight: 400;
|
|
97
|
+
font-weight: var(--rf-monochrome-normal-font-weight, 400);
|
|
82
98
|
}
|
|
83
99
|
|
|
84
100
|
/*
|
|
@@ -114,7 +130,7 @@ pre:has(> samp) .hljs-meta.prompt_ {
|
|
|
114
130
|
.hljs-deletion {
|
|
115
131
|
color: var(--rf-monochrome-fg, var(--rf-code-fg));
|
|
116
132
|
font-style: normal;
|
|
117
|
-
font-weight: 400;
|
|
133
|
+
font-weight: var(--rf-monochrome-normal-font-weight, 400);
|
|
118
134
|
}
|
|
119
135
|
|
|
120
136
|
.hljs-addition,
|
|
@@ -130,5 +146,5 @@ pre:has(> samp) .hljs-meta.prompt_ {
|
|
|
130
146
|
pre:has(> samp) [class^="hljs-"],
|
|
131
147
|
pre:has(> samp) [class*=" hljs-"] {
|
|
132
148
|
font-style: normal;
|
|
133
|
-
font-weight: 400;
|
|
149
|
+
font-weight: var(--rf-monochrome-normal-font-weight, 400);
|
|
134
150
|
}
|
|
@@ -23,5 +23,16 @@ pre:has(> samp).rf-monochrome {
|
|
|
23
23
|
*/
|
|
24
24
|
pre:has(> samp).rf-monochrome span[style] {
|
|
25
25
|
font-style: normal !important;
|
|
26
|
-
font-weight: 400 !important;
|
|
26
|
+
font-weight: var(--rf-monochrome-normal-font-weight, 400) !important;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
* The rf-monochrome Shiki theme emits italic only for comment scopes by
|
|
31
|
+
* default. Normalize those inline styles when the inherited language is CJK;
|
|
32
|
+
* `!important` is required because Shiki writes font-style inline.
|
|
33
|
+
*/
|
|
34
|
+
pre.rf-monochrome span[style*="font-style"][style*="italic"]:lang(ja),
|
|
35
|
+
pre.rf-monochrome span[style*="font-style"][style*="italic"]:lang(zh),
|
|
36
|
+
pre.rf-monochrome span[style*="font-style"][style*="italic"]:lang(ko) {
|
|
37
|
+
font-style: normal !important;
|
|
27
38
|
}
|