rapier-markdown-kit 1.1.80 → 1.1.82

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.
@@ -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');
@@ -68,20 +68,18 @@ async function _rapierBuildArtifact(options, providedContext) {
68
68
  // .md-render set and the highlight rules, so a numbered list, a checkbox, a callout and a
69
69
  // table are drawn in an exported page exactly as they are drawn here. The one caller with
70
70
  // rules of its own -- Share, for the no-script float it alone writes -- appends them.
71
- // The type faces ride only where they can load. A written page's policy is default-src
72
- // 'none' with no font-src, so a data: font in one is fetched by nothing and would be tens of
73
- // kilobytes of bytes no reader ever sees; those pages take the reader's own sans matched to
74
- // Geist's metrics (_rapierArtifactStyles), which is the one difference between a Rapier
75
- // document and its exported page. A print artifact renders inside this page, under this
76
- // page's policy, so it keeps the real faces.
77
- // 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
78
- // 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:
79
- // 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?.() || '') : '';
80
77
  const willFont = opts.print && opts.willFont ? opts.willFont : null;
81
78
  const settings = _rapierDocumentSettingsOf(context.canonical);
82
79
  const settingsCss = _rapierDocumentSettingsCss(settings);
83
80
  const pageTitle = settings && settings.title ? globalThis.RapierMarkdownSpec.documentTitle(settings) : metadata.filename;
84
- const css = _rapierArtifactStyles(theme, !!opts.print, !!opts.print || opts.kind === 'standalone', opts.kind === 'page')
81
+ const css = _rapierArtifactStyles(theme, includeFonts, !!opts.print || opts.kind === 'standalone', opts.kind === 'page')
82
+ + (zenFontCss ? '\n\n' + zenFontCss : '')
85
83
  + (opts.extraCss ? '\n\n' + opts.extraCss : '')
86
84
  + (willFont ? '\n\n@font-face{font-family:' + willFont.family + ';src:url(' + await _rapierBlobDataUrl(new Blob([willFont.bytes], { type: 'font/ttf' })) + ') format("truetype")}' : '')
87
85
  + (settingsCss ? '\n' + settingsCss : '');
@@ -106,7 +104,7 @@ async function _rapierBuildArtifact(options, providedContext) {
106
104
  // someone's page shows whole, with no inner scroll. Any origin may read the height: the page is the
107
105
  // document, published by the person who exported it.
108
106
  + '<meta name="responsive-embedded-sizing" content="allow-origins=*">\n'
109
- + '<meta http-equiv="Content-Security-Policy" content="' + _rapierExportedPageCsp(layoutScript || lexerScript || inkScript ? nonce : '', !!opts.print) + '">\n'
107
+ + '<meta http-equiv="Content-Security-Policy" content="' + _rapierExportedPageCsp(layoutScript || lexerScript || inkScript ? nonce : '', includeFonts) + '">\n'
110
108
  + '<meta name="referrer" content="no-referrer">\n'
111
109
  + '<meta name="generator" content="Rapier ' + escapeRapierHtmlText(version) + '">\n'
112
110
  + '<title>' + escapeRapierHtmlText(pageTitle) + '</title>\n'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rapier-markdown-kit",
3
- "version": "1.1.80",
3
+ "version": "1.1.82",
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
- :where(.md-render) .diagram-block[data-diagram-state="ready"] .diagram-source {
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. Only known paint roles are themed here;
163
- other families keep their generator's matching fill and ink. Authored inline pairs win. */
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
- /* C4 node colours include their own label ink. Outside captions and connections use the page. */
191
- :where(.md-render) svg.rapier-diagram[aria-roledescription="c4"] text:not(.c4-shape *){fill:var(--md-color-text)!important}
192
- :where(.md-render) svg.rapier-diagram[aria-roledescription="c4"] :is(line,path)[stroke]:not(.c4-shape *):not(marker *):not(symbol *){stroke:var(--md-diagram-line)!important}
193
- :where(.md-render) svg.rapier-diagram[aria-roledescription="c4"] rect[fill="none"][stroke]:not(.c4-shape *){stroke:var(--md-diagram-node-line)!important}
194
-
195
- /* Journey cards pair their surface with both HTML and SVG label branches; faces keep their paints. */
196
- :where(.md-render) svg.rapier-diagram[aria-roledescription="journey"] rect:is(.journey-section,.task){fill:var(--md-diagram-node-fill)!important}
197
- :where(.md-render) svg.rapier-diagram[aria-roledescription="journey"] rect:is(.journey-section,.task)+switch :is(text,tspan){fill:var(--md-color-text)!important}
198
- :where(.md-render) svg.rapier-diagram[aria-roledescription="journey"] rect:is(.journey-section,.task)+switch foreignObject{color:var(--md-color-text)!important}
199
- :where(.md-render) svg.rapier-diagram[aria-roledescription="journey"]>text,
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