rapier-markdown-kit 1.1.79 → 1.1.81
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/dist/kit/render-markdown.mjs +489 -12
- package/dist/kit/render-print.mjs +264 -3
- package/dist/kit/render-sanitize.mjs +128 -8
- package/dist/kit/render-styles.mjs +5 -5
- package/dist/kit/render.mjs +41 -21
- package/dist/spec/md-assets.mjs +3 -2
- package/package.json +1 -1
- package/style.css +56 -63
package/dist/kit/render.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
// The document's renderer. DOM, codecs and host state are explicit inputs.
|
|
3
3
|
function createRenderer(runtime) {
|
|
4
|
-
const {RAPIER_COLOR_CLOSE, RapierLedgerCarried, RapierPageReturnAddress, RapierTextCodec, _rapierArtifactHighlight, _rapierArtifactLexerScript, _rapierArtifactMarkLexed, _rapierArtifactPreference, _rapierArtifactStyles, _rapierBlobDataUrl, _rapierBuildInterchangeContext, _rapierDocumentNameIsAdmissible, _rapierLedgerParts, _rapierDrawReadSVGRecipe, _rapierDrawShapeProfileFor, _rapierFillDiagram, _rapierFormatColorOpen, _rapierLanguageClass, _rapierLineStartOffsets, _rapierMarkdownEnvironment, _rapierPortableHtml, _rapierPrepareInterchangeContext, _rapierProjectPortableRoot, _rapierSourceCharEscaped, _rapierSourceLineSpan, crypto, document, escapeRapierHtmlText, globalThis, rapierConfirm, sanitizeRapierHtml} = runtime;
|
|
4
|
+
const {RAPIER_COLOR_CLOSE, RapierLedgerCarried, RapierPageReturnAddress, RapierTextCodec, _rapierArtifactHighlight, _rapierArtifactLexerScript, _rapierArtifactMarkLexed, _rapierArtifactPreference, _rapierArtifactStyles, _rapierBlobDataUrl, _rapierBuildInterchangeContext, _rapierDocumentNameIsAdmissible, _rapierLedgerParts, _rapierDrawReadSVGRecipe, _rapierDrawShapeProfileFor, _rapierFillDiagram, _rapierFormatColorOpen, _rapierLanguageClass, _rapierLineStartOffsets, _rapierMarkdownEnvironment, _rapierPortableHtml, _rapierPrepareInterchangeContext, _rapierProjectPortableRoot, _rapierProviders, _rapierSourceCharEscaped, _rapierSourceLineSpan, crypto, document, escapeRapierHtmlText, globalThis, rapierConfirm, sanitizeRapierHtml} = runtime;
|
|
5
5
|
let md = runtime.md;
|
|
6
6
|
async function render(source, options = {}) {
|
|
7
7
|
if (typeof source !== 'string') throw new TypeError('Document source must be a string');
|
|
@@ -32,7 +32,7 @@ async function _rapierBuildArtifact(options, providedContext) {
|
|
|
32
32
|
|
|
33
33
|
// The semantic export root is detached and has never entered the live visibility queue.
|
|
34
34
|
// Await the same materialization owner before any projection clones or serializes it.
|
|
35
|
-
for (const diagram of context.semanticRoot.querySelectorAll('.diagram-block[data-diagram-src]')) {
|
|
35
|
+
for (const diagram of opts.kind === 'page' ? [] : context.semanticRoot.querySelectorAll('.diagram-block[data-diagram-src]')) {
|
|
36
36
|
await _rapierFillDiagram(diagram, true);
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -41,21 +41,23 @@ async function _rapierBuildArtifact(options, providedContext) {
|
|
|
41
41
|
const styledRoot = _rapierProjectStyledRoot(context.semanticRoot, {
|
|
42
42
|
metadata,
|
|
43
43
|
print: !!opts.print,
|
|
44
|
+
sourceCode: opts.kind === 'page',
|
|
44
45
|
baseName: base,
|
|
45
46
|
});
|
|
46
47
|
// _rapierProjectStyledRoot already returns the sanitized projection.
|
|
47
48
|
// Print never emits the layout reflow script (see below), so a print artifact has no use for
|
|
48
49
|
// this annotation -- skip it there rather than pay the cost for numbers nothing will read.
|
|
49
|
-
if (!opts.print) _rapierAnnotateExportBoxPolygons(styledRoot);
|
|
50
|
+
if (!opts.print && opts.kind !== 'page') _rapierAnnotateExportBoxPolygons(styledRoot);
|
|
50
51
|
// Share adds its nearest-side no-script float and long-code cap here. Offline-image
|
|
51
52
|
// admission above and the page policy below belong to this common writer, not its callers.
|
|
52
53
|
if (typeof opts.afterRoot === 'function') opts.afterRoot(styledRoot);
|
|
53
54
|
const carrier = opts.kind === 'standalone' ? await _rapierSharedSourceCarrier(context, styledRoot) : '';
|
|
54
|
-
const bodyHtml = styledRoot.innerHTML;
|
|
55
|
+
const bodyHtml = opts.kind === 'page' ? _rapierPageHtml(styledRoot) : styledRoot.innerHTML;
|
|
55
56
|
const theme = opts.print
|
|
56
57
|
? 'light'
|
|
58
|
+
: opts.kind === 'page' ? 'system'
|
|
57
59
|
: _rapierArtifactPreference('theme', ['system', 'light', 'dark']);
|
|
58
|
-
const highlights = _rapierArtifactPreference('highlights', ['accent', 'standard']);
|
|
60
|
+
const highlights = opts.kind === 'page' ? 'standard' : _rapierArtifactPreference('highlights', ['accent', 'standard']);
|
|
59
61
|
const versionMeta = document.querySelector('meta[name="rapier-version"]');
|
|
60
62
|
const version = versionMeta && versionMeta.content ? versionMeta.content.trim() : '0.0.0';
|
|
61
63
|
const bodyClass = theme === 'light' ? 'light' : '';
|
|
@@ -66,20 +68,18 @@ async function _rapierBuildArtifact(options, providedContext) {
|
|
|
66
68
|
// .md-render set and the highlight rules, so a numbered list, a checkbox, a callout and a
|
|
67
69
|
// table are drawn in an exported page exactly as they are drawn here. The one caller with
|
|
68
70
|
// rules of its own -- Share, for the no-script float it alone writes -- appends them.
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
// The print page carries its faces as data: faces of its own, and a Will's carriers' font among them (the secure-runtime host prints this
|
|
76
|
-
// page, not the one it was made in). Its policy alone has font-src data:, which reaches no network, whether or not the page has a Will:
|
|
77
|
-
// with it only for a Will the same document would print in its faces with the Will and in the reader's own without (measured).
|
|
71
|
+
// Diagram geometry was measured with these exact fonts. Carry the same data fonts into
|
|
72
|
+
// offline pages; a fallback face would change labels inside fixed renderer geometry.
|
|
73
|
+
const diagramFonts = !!styledRoot.querySelector('svg.rapier-diagram,svg.rapier-native-flowchart');
|
|
74
|
+
const includeFonts = !!opts.print || diagramFonts;
|
|
75
|
+
const zenFontCss = styledRoot.querySelector('svg[aria-roledescription="zenuml"]')
|
|
76
|
+
? (_rapierProviders?.mermaid?.exportFontCss?.() || '') : '';
|
|
78
77
|
const willFont = opts.print && opts.willFont ? opts.willFont : null;
|
|
79
78
|
const settings = _rapierDocumentSettingsOf(context.canonical);
|
|
80
79
|
const settingsCss = _rapierDocumentSettingsCss(settings);
|
|
81
80
|
const pageTitle = settings && settings.title ? globalThis.RapierMarkdownSpec.documentTitle(settings) : metadata.filename;
|
|
82
|
-
const css = _rapierArtifactStyles(theme,
|
|
81
|
+
const css = _rapierArtifactStyles(theme, includeFonts, !!opts.print || opts.kind === 'standalone', opts.kind === 'page')
|
|
82
|
+
+ (zenFontCss ? '\n\n' + zenFontCss : '')
|
|
83
83
|
+ (opts.extraCss ? '\n\n' + opts.extraCss : '')
|
|
84
84
|
+ (willFont ? '\n\n@font-face{font-family:' + willFont.family + ';src:url(' + await _rapierBlobDataUrl(new Blob([willFont.bytes], { type: 'font/ttf' })) + ') format("truetype")}' : '')
|
|
85
85
|
+ (settingsCss ? '\n' + settingsCss : '');
|
|
@@ -90,11 +90,11 @@ async function _rapierBuildArtifact(options, providedContext) {
|
|
|
90
90
|
// The reflow script is written first, because whether it exists decides the policy. A page that carries no script says so: script-src 'none' refuses every
|
|
91
91
|
// script outright. Declaring a nonce a page has no use for is a widening, small but real -- anything that could inject markup into the file could read the
|
|
92
92
|
// nonce out of it and be admitted.
|
|
93
|
-
const layoutScript = !opts.print ? _rapierArtifactLayoutScript(styledRoot, nonce) : '';
|
|
93
|
+
const layoutScript = !opts.print && opts.kind !== 'page' ? _rapierArtifactLayoutScript(styledRoot, nonce) : '';
|
|
94
94
|
// The lexer for the page's code, under the same nonce, only when a block earned it: the CPU
|
|
95
95
|
// spans are the first paint, and where the reader's browser has WebGPU the lexer repaints them.
|
|
96
|
-
const lexerScript = !opts.print ? _rapierArtifactLexerScript(styledRoot, nonce) : '';
|
|
97
|
-
const inkScript = !opts.print ? _rapierArtifactInkScript(styledRoot, nonce) : '';
|
|
96
|
+
const lexerScript = !opts.print && opts.kind !== 'page' ? _rapierArtifactLexerScript(styledRoot, nonce) : '';
|
|
97
|
+
const inkScript = !opts.print && opts.kind !== 'page' ? _rapierArtifactInkScript(styledRoot, nonce) : '';
|
|
98
98
|
const page = '<!DOCTYPE html>\n'
|
|
99
99
|
+ '<html lang="en" data-rapier-theme="' + theme + '" data-highlights="' + highlights + '">\n'
|
|
100
100
|
+ '<head>\n<meta charset="UTF-8">\n' + (carrier ? RapierPageReturnAddress.PAGE_SEED + '\n' : '')
|
|
@@ -104,7 +104,7 @@ async function _rapierBuildArtifact(options, providedContext) {
|
|
|
104
104
|
// someone's page shows whole, with no inner scroll. Any origin may read the height: the page is the
|
|
105
105
|
// document, published by the person who exported it.
|
|
106
106
|
+ '<meta name="responsive-embedded-sizing" content="allow-origins=*">\n'
|
|
107
|
-
+ '<meta http-equiv="Content-Security-Policy" content="' + _rapierExportedPageCsp(layoutScript || lexerScript || inkScript ? nonce : '',
|
|
107
|
+
+ '<meta http-equiv="Content-Security-Policy" content="' + _rapierExportedPageCsp(layoutScript || lexerScript || inkScript ? nonce : '', includeFonts) + '">\n'
|
|
108
108
|
+ '<meta name="referrer" content="no-referrer">\n'
|
|
109
109
|
+ '<meta name="generator" content="Rapier ' + escapeRapierHtmlText(version) + '">\n'
|
|
110
110
|
+ '<title>' + escapeRapierHtmlText(pageTitle) + '</title>\n'
|
|
@@ -116,12 +116,31 @@ async function _rapierBuildArtifact(options, providedContext) {
|
|
|
116
116
|
html: page,
|
|
117
117
|
filename: base + '.html',
|
|
118
118
|
bodyHtml,
|
|
119
|
+
css,
|
|
119
120
|
docClass,
|
|
120
121
|
metadata,
|
|
121
122
|
documentTitle: settings && settings.title ? pageTitle : '',
|
|
122
123
|
};
|
|
123
124
|
}
|
|
124
125
|
|
|
126
|
+
// Page files have one byte representation across native and inert DOM hosts. Attribute
|
|
127
|
+
// insertion order and a host's optional entity escapes are not document content.
|
|
128
|
+
function _rapierPageHtml(root) {
|
|
129
|
+
const voidTags = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
|
|
130
|
+
const children = node => Array.from(node.childNodes || [], write).join('');
|
|
131
|
+
function write(node) {
|
|
132
|
+
if (node.nodeType === 3) return escapeRapierHtmlText(node.nodeValue || '');
|
|
133
|
+
if (node.nodeType !== 1) return '';
|
|
134
|
+
// This writer emits text/html; the HTML reader restores SVG's camel-cased names.
|
|
135
|
+
const tag = node.localName.toLowerCase();
|
|
136
|
+
const attributes = Array.from(node.attributes).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)
|
|
137
|
+
.map(attribute => ' ' + attribute.name + '="' + escapeRapierHtmlText(attribute.value) + '"').join('');
|
|
138
|
+
const open = '<' + tag + attributes + '>';
|
|
139
|
+
return voidTags.has(tag) ? open : open + children(node) + '</' + tag + '>';
|
|
140
|
+
}
|
|
141
|
+
return children(root);
|
|
142
|
+
}
|
|
143
|
+
|
|
125
144
|
function _rapierProjectStyledRoot(semanticRoot, options) {
|
|
126
145
|
const opts = options || {};
|
|
127
146
|
const root = semanticRoot.cloneNode(true);
|
|
@@ -138,11 +157,12 @@ function _rapierProjectStyledRoot(semanticRoot, options) {
|
|
|
138
157
|
if (code) {
|
|
139
158
|
const lang = _rapierLanguageClass(code) || String(metadata.codeLang || '');
|
|
140
159
|
code.classList.add('artifact-code');
|
|
141
|
-
if (metadata.docKind === 'code') { _rapierPaintCode(code, _rapierArtifactHighlight(code.textContent || '', lang)); _rapierArtifactMarkLexed(code, lang); }
|
|
160
|
+
if (metadata.docKind === 'code' && !opts.sourceCode) { _rapierPaintCode(code, _rapierArtifactHighlight(code.textContent || '', lang)); _rapierArtifactMarkLexed(code, lang); }
|
|
142
161
|
if (lang) code.classList.add('language-' + String(lang).replace(/[^a-z0-9_-]/gi, ''));
|
|
143
162
|
}
|
|
144
163
|
} else {
|
|
145
164
|
root.querySelectorAll('pre > code').forEach(code => {
|
|
165
|
+
if (opts.sourceCode) return;
|
|
146
166
|
const lang = _rapierLanguageClass(code) || 'text';
|
|
147
167
|
_rapierPaintCode(code, _rapierArtifactHighlight(code.textContent || '', lang));
|
|
148
168
|
_rapierArtifactMarkLexed(code, lang);
|
|
@@ -184,7 +204,7 @@ function _rapierProjectStyledRoot(semanticRoot, options) {
|
|
|
184
204
|
_rapierPrefixPortableAnchors(root, opts.baseName || metadata.filename || 'document');
|
|
185
205
|
|
|
186
206
|
const clean = document.createElement('div');
|
|
187
|
-
clean.innerHTML = sanitizeRapierHtml(root.innerHTML, 'export');
|
|
207
|
+
clean.innerHTML = sanitizeRapierHtml(root.innerHTML, opts.sourceCode ? 'source' : 'export');
|
|
188
208
|
return clean;
|
|
189
209
|
}
|
|
190
210
|
|
package/dist/spec/md-assets.mjs
CHANGED
|
@@ -370,7 +370,8 @@ export function serializeAsset(asset) {
|
|
|
370
370
|
return '[' + asset.label + ']: ' + asset.url + title;
|
|
371
371
|
}
|
|
372
372
|
// Pure: re-derived at commit against the moved document; appends only at the text's end.
|
|
373
|
-
|
|
373
|
+
// A replay supplies the retained definition's line ending instead of choosing one from later prose.
|
|
374
|
+
export function appendAssetText(source, asset, lineEnding) {
|
|
374
375
|
if (typeof source !== 'string' || !asset || normalizeLabel(asset.label) !== asset.id) return fail('image_source_invalid');
|
|
375
376
|
const parsed = documentAssets(source), title = assetTitle(asset.title);
|
|
376
377
|
const existing = [...parsed.assets.values()].find(row => row.url === asset.url && row.title === title);
|
|
@@ -382,7 +383,7 @@ export function appendAssetText(source, asset) {
|
|
|
382
383
|
return {source, id: asset.id, reference: asset.label, added: false, suffix: ''};
|
|
383
384
|
}
|
|
384
385
|
if (parsed.assets.size >= IMAGE_LIMITS.assets) return fail('image_asset_count_limit');
|
|
385
|
-
const eol = /\r\n|\n|\r/.exec(source)?.[0] || '\n', tail = /(?:\r\n?|\n)[ \t]*$/.exec(source);
|
|
386
|
+
const eol = lineEnding || /\r\n|\n|\r/.exec(source)?.[0] || '\n', tail = /(?:\r\n?|\n)[ \t]*$/.exec(source);
|
|
386
387
|
const separator = !source || tail && /[\r\n][ \t]*$/.test(source.slice(0, tail.index)) ? '' : tail ? eol : eol + eol;
|
|
387
388
|
const suffix = separator + block + eol, nextSource = source + suffix;
|
|
388
389
|
if (nextSource.length > IMAGE_LIMITS.sourceChars) return fail('image_source_limit');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rapier-markdown-kit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.81",
|
|
4
4
|
"description": "Read, render, write and style Self-contained Markdown, and carry its optional edit ledger: the shared HTML writer, semantic renderer, stylesheet, layout, marks, pictures, Will/1, replay, authorship and offline merge. MIT, no npm dependencies.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown",
|
package/style.css
CHANGED
|
@@ -87,6 +87,36 @@
|
|
|
87
87
|
--md-diagram-c7:light-dark(#5eac56,#002104);
|
|
88
88
|
--md-diagram-c8:light-dark(#d485fc,#330033);
|
|
89
89
|
--md-diagram-c9:light-dark(#c9b49b,#4f3626);
|
|
90
|
+
|
|
91
|
+
--md-mermaid-surface:light-dark(#f2f1ee,#171b1e);
|
|
92
|
+
--md-mermaid-border:light-dark(#757b80,#929ba1);
|
|
93
|
+
--md-mermaid-grid:light-dark(#d0d4d6,#424a4f);
|
|
94
|
+
--md-mermaid-muted:light-dark(#525a60,#b7c0c5);
|
|
95
|
+
--md-mermaid-on-series:light-dark(#fff8ea,#11181c);
|
|
96
|
+
--md-mermaid-series-1:light-dark(#176e85,#6bc2d5);
|
|
97
|
+
--md-mermaid-series-2:light-dark(#b55b2a,#f1a172);
|
|
98
|
+
--md-mermaid-series-3:light-dark(#7652a0,#bda0e1);
|
|
99
|
+
--md-mermaid-series-4:light-dark(#34775c,#7fc4a4);
|
|
100
|
+
--md-mermaid-series-5:light-dark(#a34f68,#e79eb4);
|
|
101
|
+
--md-mermaid-series-6:light-dark(#896e23,#d8be68);
|
|
102
|
+
--md-mermaid-series-7:light-dark(#426caa,#92b7ed);
|
|
103
|
+
--md-mermaid-series-8:light-dark(#876144,#cba886);
|
|
104
|
+
--md-mermaid-series-9:light-dark(#55703a,#afc88e);
|
|
105
|
+
--md-mermaid-series-10:light-dark(#94633c,#e4b185);
|
|
106
|
+
--md-mermaid-series-11:light-dark(#8a5186,#d5a0cf);
|
|
107
|
+
--md-mermaid-series-12:light-dark(#476d70,#91b9ba);
|
|
108
|
+
--md-mermaid-tint-1:light-dark(#e0edf1,#1b3941);
|
|
109
|
+
--md-mermaid-tint-2:light-dark(#f5e6dc,#472e21);
|
|
110
|
+
--md-mermaid-tint-3:light-dark(#ebe4f2,#342941);
|
|
111
|
+
--md-mermaid-tint-4:light-dark(#e2eee7,#223b2e);
|
|
112
|
+
--md-mermaid-tint-5:light-dark(#f3e1e8,#432a33);
|
|
113
|
+
--md-mermaid-tint-6:light-dark(#f3edd9,#40391f);
|
|
114
|
+
--md-mermaid-tint-7:light-dark(#e2eaf6,#26354a);
|
|
115
|
+
--md-mermaid-tint-8:light-dark(#eee5dd,#3b3129);
|
|
116
|
+
--md-mermaid-tint-9:light-dark(#e8eddf,#303921);
|
|
117
|
+
--md-mermaid-tint-10:light-dark(#f1e5d9,#433122);
|
|
118
|
+
--md-mermaid-tint-11:light-dark(#f0e2ed,#3e2a3b);
|
|
119
|
+
--md-mermaid-tint-12:light-dark(#e2ecec,#263a3b);
|
|
90
120
|
}
|
|
91
121
|
.md-render{color-scheme:light}
|
|
92
122
|
/* Geist and Geist Mono both have a 530/1000 x-height. Preserve their size and match a
|
|
@@ -135,6 +165,10 @@
|
|
|
135
165
|
margin: 0 0 var(--md-line);
|
|
136
166
|
max-width: 100%;
|
|
137
167
|
overflow: auto;
|
|
168
|
+
padding-block: 0.55rem 0.85rem;
|
|
169
|
+
background:
|
|
170
|
+
linear-gradient(var(--md-diagram-node-line), var(--md-diagram-node-line)) top / 100% 1px no-repeat,
|
|
171
|
+
linear-gradient(var(--md-diagram-node-line), var(--md-diagram-node-line)) bottom / 100% 1px no-repeat;
|
|
138
172
|
}
|
|
139
173
|
:where(.md-render) .diagram-block .diagram-source {
|
|
140
174
|
font-family: var(--md-font-mono);
|
|
@@ -145,7 +179,12 @@
|
|
|
145
179
|
margin: 0;
|
|
146
180
|
white-space: pre-wrap;
|
|
147
181
|
}
|
|
148
|
-
|
|
182
|
+
/* A drawing in progress keeps its source for the reader and for export, but does not flash
|
|
183
|
+
the fence across the page. The measured height, once known, holds the place. */
|
|
184
|
+
:where(.md-render) .diagram-block:is([data-diagram-state="idle"],[data-diagram-state="pending"]) {
|
|
185
|
+
min-height: 5.25rem;
|
|
186
|
+
}
|
|
187
|
+
:where(.md-render) .diagram-block:is([data-diagram-state="ready"],[data-diagram-state="idle"],[data-diagram-state="pending"]) .diagram-source {
|
|
149
188
|
position: absolute;
|
|
150
189
|
width: 1px;
|
|
151
190
|
height: 1px;
|
|
@@ -159,70 +198,21 @@
|
|
|
159
198
|
:where(.md-render) .diagram-block .diagram-cache {
|
|
160
199
|
max-width: 100%;
|
|
161
200
|
}
|
|
162
|
-
/* Mermaid owns its geometry and typography.
|
|
163
|
-
|
|
201
|
+
/* Mermaid owns its geometry and typography. Its reference palette is projected onto SVG paint
|
|
202
|
+
at admission; only renderer paint omissions are corrected here. */
|
|
164
203
|
:where(.md-render) svg.rapier-native-flowchart{display:block;margin-inline:auto;height:auto}
|
|
165
|
-
:where(.md-render) svg.rapier-diagram{display:block;margin-inline:auto;height:auto}
|
|
166
|
-
|
|
167
|
-
/* Recolour connectors without changing widths, dashes, marker contours or hollow interiors. */
|
|
168
|
-
:where(.md-render) svg.rapier-diagram:is([aria-roledescription^="flowchart"],[aria-roledescription="classDiagram"],[aria-roledescription="stateDiagram"],[aria-roledescription="requirement"],[aria-roledescription="er"]) :is(path.flowchart-link,path.relation,path.relationshipLine,path.transition){stroke:var(--md-diagram-line)!important}
|
|
169
|
-
:where(.md-render) svg.rapier-diagram:is([aria-roledescription^="flowchart"],[aria-roledescription="classDiagram"],[aria-roledescription="stateDiagram"],[aria-roledescription="requirement"],[aria-roledescription="er"],[aria-roledescription="sequence"],[aria-roledescription="c4"],[aria-roledescription="journey"]) marker{fill:var(--md-diagram-arrow)!important}
|
|
170
|
-
|
|
171
|
-
/* Sequence surfaces and their labels move together between paper colours. */
|
|
172
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="sequence"] :is(rect.actor,rect.activation0,rect.activation1,rect.activation2,polygon.labelBox){fill:var(--md-diagram-node-fill)!important;stroke:var(--md-diagram-node-line)!important}
|
|
173
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="sequence"] :is(text.actor,text.labelText,text.loopText,text.messageText,text.sectionTitle),
|
|
174
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="sequence"] :is(text.actor,text.labelText,text.loopText,text.messageText,text.sectionTitle) tspan{fill:var(--md-color-text)!important}
|
|
175
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="sequence"] :is(text.sequenceNumber,text.sequenceNumber tspan){fill:var(--md-color-bg)!important}
|
|
176
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="sequence"] rect.note{fill:var(--md-color-inset)!important;stroke:var(--md-diagram-node-line)!important}
|
|
177
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="sequence"] :is(text.noteText,text.noteText tspan){fill:var(--md-color-text)!important}
|
|
178
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="sequence"] :is(line.messageLine0,line.messageLine1,path.messageLine0,path.messageLine1){stroke:var(--md-diagram-line)!important}
|
|
179
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="sequence"] :is(line.actor-line,line.loopLine){stroke:var(--md-diagram-inner-line)!important}
|
|
180
|
-
|
|
181
|
-
/* A state begins with a dot, ends with a ring, and forks through a bar. */
|
|
182
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="stateDiagram"] :is(circle.state-start,rect.fork-join,circle.end-state-inner){fill:var(--md-color-text)!important;stroke:var(--md-color-text)!important}
|
|
183
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="stateDiagram"] circle.state-end{fill:var(--md-color-bg)!important;stroke:var(--md-color-text)!important}
|
|
184
|
-
/* Compound-state frames follow the paper; their child states keep their own surfaces and ink. */
|
|
185
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="stateDiagram"] g.statediagram-cluster>rect.inner{fill:var(--md-color-bg)!important}
|
|
186
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="stateDiagram"] g.statediagram-cluster>g>rect.outer{fill:var(--md-diagram-node-fill)!important}
|
|
187
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="stateDiagram"] g.statediagram-cluster>.cluster-label :is(text,tspan){fill:var(--md-color-text)!important}
|
|
188
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="stateDiagram"] g.statediagram-cluster>.cluster-label :is(foreignObject,.nodeLabel){color:var(--md-color-text)!important}
|
|
204
|
+
:where(.md-render) svg.rapier-diagram{display:block;margin-inline:auto;height:auto;text-rendering:optimizeLegibility}
|
|
189
205
|
|
|
190
|
-
/*
|
|
191
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="
|
|
192
|
-
|
|
193
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="
|
|
197
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="
|
|
198
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="
|
|
199
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="
|
|
200
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="journey"] text.legend{fill:var(--md-color-text)!important}
|
|
201
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="journey"]>line{stroke:var(--md-diagram-line)!important}
|
|
202
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="journey"] line.task-line{stroke:var(--md-diagram-inner-line)!important}
|
|
203
|
-
|
|
204
|
-
/* Gantt paint selectors name their element type: journey also uses the class "task" on text. */
|
|
205
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] rect:is(.section0,.section2){fill:var(--md-diagram-node-fill)!important}
|
|
206
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] rect:is(.section1,.section3){fill:var(--md-color-bg)!important}
|
|
207
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] rect.task{fill:var(--md-diagram-c1)!important;stroke:var(--md-diagram-c1)!important}
|
|
208
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] rect:is(.active0,.active1,.active2,.active3){fill:var(--md-diagram-c3)!important;stroke:var(--md-diagram-c3)!important}
|
|
209
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] rect:is(.done0,.done1,.done2,.done3){fill:var(--md-diagram-node-line)!important;stroke:var(--md-diagram-node-line)!important}
|
|
210
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] rect:is(.crit0,.crit1,.crit2,.crit3,.activeCrit0,.activeCrit1,.activeCrit2,.activeCrit3,.doneCrit0,.doneCrit1,.doneCrit2,.doneCrit3){fill:var(--md-diagram-c6)!important;stroke:var(--md-diagram-c6)!important}
|
|
211
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] text.taskText{fill:var(--md-diagram-on-colour)!important}
|
|
212
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] text:is(.taskTextOutsideRight,.taskTextOutsideLeft,.sectionTitle,.titleText){fill:var(--md-color-text)!important}
|
|
213
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] .grid .tick line{stroke:var(--md-diagram-inner-line)!important}
|
|
214
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] .grid .tick text{fill:var(--md-diagram-quiet)!important}
|
|
215
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gantt"] line.today{stroke:var(--md-diagram-c6)!important}
|
|
216
|
-
|
|
217
|
-
/* Outside labels never acquire the ink intended for a coloured slice or branch. */
|
|
218
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="pie"] text.pieTitleText,
|
|
219
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="pie"] g.legend text,
|
|
220
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="timeline"]>text{fill:var(--md-color-text)!important}
|
|
221
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="timeline"] g.lineWrapper>line{stroke:var(--md-diagram-line)!important}
|
|
222
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gitGraph"] rect.commit-label-bkg{fill:var(--md-color-bg)!important}
|
|
223
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gitGraph"] text.commit-label{fill:var(--md-diagram-quiet)!important}
|
|
224
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gitGraph"] polygon.tag-label-bkg{fill:var(--md-diagram-node-fill)!important;stroke:var(--md-diagram-node-line)!important}
|
|
225
|
-
:where(.md-render) svg.rapier-diagram[aria-roledescription="gitGraph"] text.tag-label{fill:var(--md-color-text)!important}
|
|
206
|
+
/* Radar gives these SVG labels a color declaration; SVG text needs a fill. */
|
|
207
|
+
:where(.md-render) svg.rapier-diagram[aria-roledescription="radar"] :is(.radarTitle,.radarAxisLabel){fill:currentColor}
|
|
208
|
+
/* Multiplying a ribbon by black paper makes its entire flow disappear. */
|
|
209
|
+
:where(.md-render) svg.rapier-diagram[aria-roledescription="sankey"] .link{mix-blend-mode:normal!important}
|
|
210
|
+
/* Captions keep their baseline while masking chart marks behind their letters. */
|
|
211
|
+
:where(.md-render) svg.rapier-diagram[aria-roledescription="c4"] text:not(.c4-shape *),
|
|
212
|
+
:where(.md-render) svg.rapier-diagram[aria-roledescription="architecture"] .architecture-service text,
|
|
213
|
+
:where(.md-render) svg.rapier-diagram[aria-roledescription="wardley"] .wardley-node-label,
|
|
214
|
+
:where(.md-render) svg.rapier-diagram[aria-roledescription="xychart"] [class^="line-plot-"]>.labels>text,
|
|
215
|
+
:where(.md-render) svg.rapier-diagram[aria-roledescription="cynefin"] :is(text.cynefinSubtitle,text.cynefinArrowLabel,text.cynefinDomainLabel){paint-order:stroke fill;stroke:var(--md-color-bg)!important;stroke-width:2.5px;stroke-linejoin:round}
|
|
226
216
|
|
|
227
217
|
/* Generator styles are removed at admission; these owned keyframes animate only dash offset. */
|
|
228
218
|
@keyframes rapier-mermaid-dash{from{stroke-dashoffset:900}to{stroke-dashoffset:0}}
|
|
@@ -243,6 +233,9 @@
|
|
|
243
233
|
font-size: 0.88em;
|
|
244
234
|
opacity: .78;
|
|
245
235
|
}
|
|
236
|
+
:where(.md-render) .diagram-block--error .diagram-source {
|
|
237
|
+
max-height: 9rem;
|
|
238
|
+
}
|
|
246
239
|
|
|
247
240
|
/* The line model (the way a Word document reads). One line, --md-line, is the body's line box: 1.75rem, 1.6 lines
|
|
248
241
|
of the 1.1rem body, a whole 28 px at the browser's 16 px root so baselines land on pixels. Every block ends one
|