react-cheminfo 0.47.0 → 0.49.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.
Files changed (187) hide show
  1. package/README.md +71 -2
  2. package/bin/check-seo.mjs +4 -3
  3. package/lib/core.d.ts +1 -0
  4. package/lib/core.d.ts.map +1 -1
  5. package/lib/core.js +1 -0
  6. package/lib/core.js.map +1 -1
  7. package/lib/download/core/cssPaint.d.ts +27 -0
  8. package/lib/download/core/cssPaint.d.ts.map +1 -0
  9. package/lib/download/core/cssPaint.js +63 -0
  10. package/lib/download/core/cssPaint.js.map +1 -0
  11. package/lib/download/core/drawingMarkup.d.ts +11 -0
  12. package/lib/download/core/drawingMarkup.d.ts.map +1 -0
  13. package/lib/download/core/drawingMarkup.js +32 -0
  14. package/lib/download/core/drawingMarkup.js.map +1 -0
  15. package/lib/download/core/figureHtml.d.ts +25 -0
  16. package/lib/download/core/figureHtml.d.ts.map +1 -0
  17. package/lib/download/core/figureHtml.js +174 -0
  18. package/lib/download/core/figureHtml.js.map +1 -0
  19. package/lib/download/core/figureHtmlMarkup.d.ts +107 -0
  20. package/lib/download/core/figureHtmlMarkup.d.ts.map +1 -0
  21. package/lib/download/core/figureHtmlMarkup.js +75 -0
  22. package/lib/download/core/figureHtmlMarkup.js.map +1 -0
  23. package/lib/download/core/figureSvg.d.ts.map +1 -1
  24. package/lib/download/core/figureSvg.js +16 -35
  25. package/lib/download/core/figureSvg.js.map +1 -1
  26. package/lib/download/core/figureSvgDocument.d.ts +3 -3
  27. package/lib/download/core/figureSvgDocument.d.ts.map +1 -1
  28. package/lib/download/core/figureTarget.d.ts +14 -3
  29. package/lib/download/core/figureTarget.d.ts.map +1 -1
  30. package/lib/download/core/figureTarget.js +42 -3
  31. package/lib/download/core/figureTarget.js.map +1 -1
  32. package/lib/download/core/index.d.ts +1 -1
  33. package/lib/download/core/index.d.ts.map +1 -1
  34. package/lib/download/core/index.js +1 -1
  35. package/lib/download/core/index.js.map +1 -1
  36. package/lib/download/core/textLines.d.ts +27 -0
  37. package/lib/download/core/textLines.d.ts.map +1 -0
  38. package/lib/download/core/textLines.js +51 -0
  39. package/lib/download/core/textLines.js.map +1 -0
  40. package/lib/ecosystem/core/lookup.d.ts +2 -1
  41. package/lib/ecosystem/core/lookup.d.ts.map +1 -1
  42. package/lib/ecosystem/core/lookup.js +10 -3
  43. package/lib/ecosystem/core/lookup.js.map +1 -1
  44. package/lib/ecosystem/core/types.d.ts +2 -2
  45. package/lib/ecosystem/core/types.d.ts.map +1 -1
  46. package/lib/ecosystem/core/unlistedSites.d.ts +9 -0
  47. package/lib/ecosystem/core/unlistedSites.d.ts.map +1 -0
  48. package/lib/ecosystem/core/unlistedSites.js +35 -0
  49. package/lib/ecosystem/core/unlistedSites.js.map +1 -0
  50. package/lib/ecosystem/ui/glyphs.d.ts.map +1 -1
  51. package/lib/ecosystem/ui/glyphs.js +7 -0
  52. package/lib/ecosystem/ui/glyphs.js.map +1 -1
  53. package/lib/i18n/core/chromeCatalog.d.ts +1 -1
  54. package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
  55. package/lib/locales/de.json +55 -1
  56. package/lib/locales/en.json +55 -1
  57. package/lib/locales/es.json +55 -1
  58. package/lib/locales/fr.json +55 -1
  59. package/lib/locales/it.json +55 -1
  60. package/lib/periodic/ui/PeriodicTable.d.ts +3 -107
  61. package/lib/periodic/ui/PeriodicTable.d.ts.map +1 -1
  62. package/lib/periodic/ui/PeriodicTable.js +5 -82
  63. package/lib/periodic/ui/PeriodicTable.js.map +1 -1
  64. package/lib/periodic/ui/PeriodicTableChrome.d.ts.map +1 -1
  65. package/lib/periodic/ui/PeriodicTableChrome.js +3 -25
  66. package/lib/periodic/ui/PeriodicTableChrome.js.map +1 -1
  67. package/lib/periodic/ui/SelectAllCorner.d.ts +23 -0
  68. package/lib/periodic/ui/SelectAllCorner.d.ts.map +1 -0
  69. package/lib/periodic/ui/SelectAllCorner.js +40 -0
  70. package/lib/periodic/ui/SelectAllCorner.js.map +1 -0
  71. package/lib/periodic/ui/headerStyles.d.ts +17 -0
  72. package/lib/periodic/ui/headerStyles.d.ts.map +1 -0
  73. package/lib/periodic/ui/headerStyles.js +19 -0
  74. package/lib/periodic/ui/headerStyles.js.map +1 -0
  75. package/lib/periodic/ui/periodicTableProps.d.ts +115 -0
  76. package/lib/periodic/ui/periodicTableProps.d.ts.map +1 -0
  77. package/lib/periodic/ui/periodicTableProps.js +8 -0
  78. package/lib/periodic/ui/periodicTableProps.js.map +1 -0
  79. package/lib/periodic/ui/tableLayout.d.ts +26 -0
  80. package/lib/periodic/ui/tableLayout.d.ts.map +1 -0
  81. package/lib/periodic/ui/tableLayout.js +86 -0
  82. package/lib/periodic/ui/tableLayout.js.map +1 -0
  83. package/lib/seo/core/routes.d.ts +1 -1
  84. package/lib/seo/core/routes.js +1 -1
  85. package/lib/seo/vite/prerender.d.ts +6 -0
  86. package/lib/seo/vite/prerender.d.ts.map +1 -1
  87. package/lib/seo/vite/prerender.js +7 -1
  88. package/lib/seo/vite/prerender.js.map +1 -1
  89. package/lib/split/ui/SplitColumn.d.ts +0 -1
  90. package/lib/split/ui/SplitColumn.d.ts.map +1 -1
  91. package/lib/split/ui/SplitColumn.js +0 -1
  92. package/lib/split/ui/SplitColumn.js.map +1 -1
  93. package/lib/split/ui/SplitRow.d.ts +0 -1
  94. package/lib/split/ui/SplitRow.d.ts.map +1 -1
  95. package/lib/split/ui/SplitRow.js +0 -1
  96. package/lib/split/ui/SplitRow.js.map +1 -1
  97. package/lib/split/ui/splitPanes.d.ts +12 -1
  98. package/lib/split/ui/splitPanes.d.ts.map +1 -1
  99. package/lib/split/ui/splitPanes.js +1 -4
  100. package/lib/split/ui/splitPanes.js.map +1 -1
  101. package/lib/taxonomy/core/index.d.ts +8 -0
  102. package/lib/taxonomy/core/index.d.ts.map +1 -0
  103. package/lib/taxonomy/core/index.js +5 -0
  104. package/lib/taxonomy/core/index.js.map +1 -0
  105. package/lib/taxonomy/core/lineage.d.ts +83 -0
  106. package/lib/taxonomy/core/lineage.d.ts.map +1 -0
  107. package/lib/taxonomy/core/lineage.js +126 -0
  108. package/lib/taxonomy/core/lineage.js.map +1 -0
  109. package/lib/taxonomy/core/ncbi.d.ts +8 -0
  110. package/lib/taxonomy/core/ncbi.d.ts.map +1 -0
  111. package/lib/taxonomy/core/ncbi.js +10 -0
  112. package/lib/taxonomy/core/ncbi.js.map +1 -0
  113. package/lib/taxonomy/core/organismName.d.ts +28 -0
  114. package/lib/taxonomy/core/organismName.d.ts.map +1 -0
  115. package/lib/taxonomy/core/organismName.js +188 -0
  116. package/lib/taxonomy/core/organismName.js.map +1 -0
  117. package/lib/taxonomy/core/organismWords.d.ts +20 -0
  118. package/lib/taxonomy/core/organismWords.d.ts.map +1 -0
  119. package/lib/taxonomy/core/organismWords.js +86 -0
  120. package/lib/taxonomy/core/organismWords.js.map +1 -0
  121. package/lib/taxonomy/core/ranks.d.ts +51 -0
  122. package/lib/taxonomy/core/ranks.d.ts.map +1 -0
  123. package/lib/taxonomy/core/ranks.js +123 -0
  124. package/lib/taxonomy/core/ranks.js.map +1 -0
  125. package/lib/taxonomy/ui/OrganismName.d.ts +28 -0
  126. package/lib/taxonomy/ui/OrganismName.d.ts.map +1 -0
  127. package/lib/taxonomy/ui/OrganismName.js +28 -0
  128. package/lib/taxonomy/ui/OrganismName.js.map +1 -0
  129. package/lib/taxonomy/ui/TaxonLineage.d.ts +67 -0
  130. package/lib/taxonomy/ui/TaxonLineage.d.ts.map +1 -0
  131. package/lib/taxonomy/ui/TaxonLineage.js +45 -0
  132. package/lib/taxonomy/ui/TaxonLineage.js.map +1 -0
  133. package/lib/taxonomy/ui/index.d.ts +6 -0
  134. package/lib/taxonomy/ui/index.d.ts.map +1 -0
  135. package/lib/taxonomy/ui/index.js +4 -0
  136. package/lib/taxonomy/ui/index.js.map +1 -0
  137. package/lib/taxonomy/ui/rankLabel.d.ts +17 -0
  138. package/lib/taxonomy/ui/rankLabel.d.ts.map +1 -0
  139. package/lib/taxonomy/ui/rankLabel.js +77 -0
  140. package/lib/taxonomy/ui/rankLabel.js.map +1 -0
  141. package/lib/ui.d.ts +1 -0
  142. package/lib/ui.d.ts.map +1 -1
  143. package/lib/ui.js +1 -0
  144. package/lib/ui.js.map +1 -1
  145. package/package.json +1 -1
  146. package/src/core.ts +1 -0
  147. package/src/download/core/cssPaint.ts +71 -0
  148. package/src/download/core/drawingMarkup.ts +35 -0
  149. package/src/download/core/figureHtml.ts +214 -0
  150. package/src/download/core/figureHtmlMarkup.ts +187 -0
  151. package/src/download/core/figureSvg.ts +17 -38
  152. package/src/download/core/figureSvgDocument.ts +3 -3
  153. package/src/download/core/figureTarget.ts +41 -8
  154. package/src/download/core/index.ts +1 -0
  155. package/src/download/core/textLines.ts +67 -0
  156. package/src/ecosystem/core/lookup.ts +11 -3
  157. package/src/ecosystem/core/types.ts +4 -2
  158. package/src/ecosystem/core/unlistedSites.ts +37 -0
  159. package/src/ecosystem/ui/glyphs.tsx +44 -0
  160. package/src/locales/de.json +55 -1
  161. package/src/locales/en.json +55 -1
  162. package/src/locales/es.json +55 -1
  163. package/src/locales/fr.json +55 -1
  164. package/src/locales/it.json +55 -1
  165. package/src/periodic/ui/PeriodicTable.tsx +16 -204
  166. package/src/periodic/ui/PeriodicTableChrome.tsx +3 -24
  167. package/src/periodic/ui/SelectAllCorner.tsx +65 -0
  168. package/src/periodic/ui/headerStyles.ts +23 -0
  169. package/src/periodic/ui/periodicTableProps.ts +117 -0
  170. package/src/periodic/ui/tableLayout.ts +96 -0
  171. package/src/seo/core/routes.ts +1 -1
  172. package/src/seo/vite/prerender.ts +7 -1
  173. package/src/split/ui/SplitColumn.tsx +0 -1
  174. package/src/split/ui/SplitRow.tsx +0 -1
  175. package/src/split/ui/splitPanes.tsx +21 -5
  176. package/src/taxonomy/core/index.ts +20 -0
  177. package/src/taxonomy/core/lineage.ts +161 -0
  178. package/src/taxonomy/core/ncbi.ts +9 -0
  179. package/src/taxonomy/core/organismName.ts +217 -0
  180. package/src/taxonomy/core/organismWords.ts +86 -0
  181. package/src/taxonomy/core/ranks.ts +134 -0
  182. package/src/taxonomy/ui/OrganismName.tsx +59 -0
  183. package/src/taxonomy/ui/TaxonLineage.tsx +183 -0
  184. package/src/taxonomy/ui/index.ts +5 -0
  185. package/src/taxonomy/ui/rankLabel.ts +81 -0
  186. package/src/ui.ts +1 -0
  187. package/styles/chrome.css +135 -6
package/README.md CHANGED
@@ -114,6 +114,7 @@ through a wildcard subpath exactly as `react-science` serves its own.
114
114
  | **Projections** | `pcaResult`, `embeddingResult`, `projectionTabs`, `loadingProfiles`, `explainedShares`, `confidenceEllipse`, `projectEllipse`, `pointsInPolygon`, `resolveProjectionGroups`, `resolveProjectionShapes`, `PROJECTION_COPY` | `PcaViewer`, `ProjectionViewer`, `ScatterPlot`, `ScatterMatrix` |
115
115
  | **Parallel coordinates** | `parallelAxisOf`, `parallelAxisLayouts`, `parallelIncludedMask`, `parallelKeptCount`, `parallelNearestRow`, `parallelSegmentAt`, `parallelBandAt`, `parallelRangeOf`, `parallelPalette`, `parallelColorSteps`, `paintParallelLines` | `ParallelCoordinates` |
116
116
  | **Periodic table** | `PERIODIC_ELEMENTS`, `elementBySymbol`, `elementByAtomicNumber`, `cellOf`, `placedElements`, `elementByArrowKey`, `EMPTY_BLOCK`, `categorySwatch`, `CATEGORY_LABELS` | `PeriodicTable`, `ElementCell`, `CategoryLegend` |
117
+ | **Taxonomy** | `TAXON_RANKS`, `PRINCIPAL_RANKS`, `rankOrder`, `isPrincipalRank`, `isGenusOrBelow`, `isAboveGenus`, `principalLineage`, `lineageFromNodes`, `lineageFromRanks`, `genusOrBelow`, `ncbiTaxonomyUrl`, `splitOrganismName` | `TaxonLineage`, `OrganismName`, `useRankLabel` |
117
118
 
118
119
  Everything in that table is exported from `./core`, `./ui`, `./slides`,
119
120
  `./vite` or `./structure` and nothing else is: the sub-components a component is built
@@ -637,6 +638,31 @@ stopped moving. Draw exactly what is on screen; only the box changes.
637
638
  A chart that measures its own container can ignore `size`: the copy is mounted
638
639
  in a box of exactly that size.
639
640
 
641
+ A figure drawn in HTML rather than SVG is saved too. Mark its box
642
+ `data-figure="html"`, and each ground, border, outline and line of words in it
643
+ is painted into the file from where the browser put it, so the copy matches the
644
+ screen. Anything marked `data-figure="chrome"` inside it stays behind. Images,
645
+ gradients, shadows and `::before` / `::after` content are not painted.
646
+
647
+ `PeriodicTable` is one, so the save glyph can sit wherever the site keeps its
648
+ controls. Point it at a box around the table and anything that belongs in the
649
+ picture, such as the site's own colour key:
650
+
651
+ ```tsx
652
+ <div className="no-print">
653
+ <PropertySelect … />
654
+ <FigureDownload targetId="table-figure" fileName="electronegativity" />
655
+ </div>
656
+ <div id="table-figure" data-figure="html">
657
+ <PeriodicTable headers swatchOf={swatchFor} />
658
+ <Legend … />
659
+ </div>
660
+ ```
661
+
662
+ Marking the box itself `data-figure="html"` paints everything in it, the key's
663
+ labels included. The corner that selects the whole table shows itself only when
664
+ pointed at or reached from the keyboard, and is neither printed nor saved.
665
+
640
666
  `downloadFigure(target, options)`, `figureSvg` and `figurePng` are the same thing
641
667
  without the button, for a site saving a figure from its own menu.
642
668
 
@@ -671,6 +697,49 @@ import { RangeSlider } from 'react-cheminfo/ui';
671
697
  - **`histogram`** takes one count per equal-width bin, drawn over the track with
672
698
  the part the handles keep in the brand colour.
673
699
 
700
+ ### `TaxonLineage` and `OrganismName`
701
+
702
+ Where an organism sits in the tree of life, as a breadcrumb, and its name set
703
+ the way nomenclature sets it.
704
+
705
+ ```tsx
706
+ import { lineageFromNodes } from 'react-cheminfo/core';
707
+ import { OrganismName, TaxonLineage } from 'react-cheminfo/ui';
708
+
709
+ <OrganismName name="Catharanthus roseus (L.) G. Don" />;
710
+
711
+ <TaxonLineage
712
+ lineage={lineageFromNodes(taxa, taxId)}
713
+ taxonHref={(taxon) => `/taxonomy/${taxon.taxId}`}
714
+ onTaxonSelect={(taxon) => navigate(`/taxonomy/${taxon.taxId}`)}
715
+ ncbiLink
716
+ />;
717
+ ```
718
+
719
+ - **A lineage is `{ rank, name, taxId? }[]`, from the top down.** It is read
720
+ from a map of NCBI nodes pointing at their parents (`lineageFromNodes`), from
721
+ a record of names by rank as octochemdb stores it (`lineageFromRanks`), or
722
+ written as it is.
723
+ - **The principal ranks are shown by default** — domain, kingdom, phylum,
724
+ class, order, family, genus, species — with the last taxon kept whatever its
725
+ rank. `principal={false}` shows every clade, for a page walking the tree.
726
+ - **Each rank is a tooltip, or a small label over the name** with `showRanks`.
727
+ The labels are the chrome's words, translated with it; `useRankLabel()` names
728
+ a rank the same way anywhere else on the page.
729
+ - **A taxon is a link only when `taxonHref` gives it an address**, and
730
+ `onTaxonSelect` takes over its plain click so the site moves without a
731
+ reload. `current` marks the last taxon as the page being read; `ncbiLink`
732
+ adds the way out to the NCBI Taxonomy Browser.
733
+ - **Italics follow the rank, then the name.** The names from the genus down go
734
+ through `splitOrganismName`, which sets the genus and the epithets in italics
735
+ and the authority, the strain, `sp.`, a cultivar and the words announcing a
736
+ rank (`subsp.`, `var.`, `f.`) upright. It reads a name by its shape, as the
737
+ source wrote it, and leaves upright what it cannot place.
738
+
739
+ The type is `TaxonLineage` in `react-cheminfo/core` and the component
740
+ `TaxonLineage` in `react-cheminfo/ui`; a file needing both imports one of them
741
+ under another name.
742
+
674
743
  ### `ParallelCoordinates`
675
744
 
676
745
  Many rows against many properties at once: one vertical axis per column, one
@@ -974,7 +1043,7 @@ keep in step.
974
1043
  ```ts
975
1044
  cheminfoPrerender({ site: 'surge', routes: PAGE_ROUTES });
976
1045
  // origin defaults to https://surge.cheminfo.org — the site owns its host,
977
- // the mount is '', and /exercises is written at dist/exercises/index.html.
1046
+ // the mount is '', and /exercises is written at dist/exercises.html.
978
1047
 
979
1048
  cheminfoPrerender({
980
1049
  site: 'surge',
@@ -986,7 +1055,7 @@ cheminfoPrerender({
986
1055
  ```
987
1056
 
988
1057
  The **files on disk are laid out from the build's own root either way** —
989
- `dist/exercises/index.html`, never `dist/surge/exercises/index.html`. It is the
1058
+ `dist/exercises.html`, never `dist/surge/exercises.html`. It is the
990
1059
  server that puts them under the mount. An origin must be an absolute `http` or
991
1060
  `https` address or it is refused: one written `localhost:3000` parses with
992
1061
  `localhost:` as its scheme, which would read the mount back as `/3000`.
package/bin/check-seo.mjs CHANGED
@@ -63,7 +63,7 @@ if (stats === undefined || !stats.isDirectory()) {
63
63
  const pages = [];
64
64
  collect(root, pages);
65
65
  if (pages.length === 0) {
66
- process.exit(usageError(TOOL, `no index.html under ${root}`));
66
+ process.exit(usageError(TOOL, `no HTML page under ${root}`));
67
67
  }
68
68
 
69
69
  const problems = [];
@@ -367,8 +367,9 @@ function collect(path, pages) {
367
367
  const next = join(path, entry.name);
368
368
  if (entry.isDirectory()) {
369
369
  collect(next, pages);
370
- } else if (entry.name === 'index.html') {
371
- const address = `/${relative(root, next).replace(/index\.html$/, '')}`;
370
+ } else if (entry.name.endsWith('.html')) {
371
+ const page = relative(root, next).replace(/\.html$/, '');
372
+ const address = `/${page.replace(/(?:^|\/)index$/, '')}`;
372
373
  pages.push({ file: next, address: trimSlash(address) });
373
374
  }
374
375
  }
package/lib/core.d.ts CHANGED
@@ -31,6 +31,7 @@ export * from './slides/core/index.ts';
31
31
  export * from './split/core/index.ts';
32
32
  export * from './state/core/index.ts';
33
33
  export * from './structure/core/index.ts';
34
+ export * from './taxonomy/core/index.ts';
34
35
  export * from './tokens/core/index.ts';
35
36
  export * from './worker/core/index.ts';
36
37
  //# sourceMappingURL=core.d.ts.map
package/lib/core.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
package/lib/core.js CHANGED
@@ -35,6 +35,7 @@ export * from "./state/core/index.js";
35
35
  // Framework-free molfile and editor-value helpers, so a worker can read a
36
36
  // molfile without loading the editor that `react-cheminfo/structure` exports.
37
37
  export * from "./structure/core/index.js";
38
+ export * from "./taxonomy/core/index.js";
38
39
  export * from "./tokens/core/index.js";
39
40
  export * from "./worker/core/index.js";
40
41
  //# sourceMappingURL=core.js.map
package/lib/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,+EAA+E;AAC/E,2EAA2E;AAC3E,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,0EAA0E;AAC1E,8EAA8E;AAC9E,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,+EAA+E;AAC/E,2EAA2E;AAC3E,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,0EAA0E;AAC1E,8EAA8E;AAC9E,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * What a computed style says is painted, read the way a figure file needs it.
3
+ */
4
+ /**
5
+ * A colour, or nothing where the page paints nothing with it.
6
+ * @param color - A computed colour, as `getComputedStyle` writes it.
7
+ * @returns The colour, or undefined where it is transparent.
8
+ */
9
+ export declare function visibleColor(color: string): string | undefined;
10
+ /**
11
+ * The dashes a CSS line style is drawn with.
12
+ * @param style - The computed `border-*-style` or `outline-style`.
13
+ * @param width - The line's width, in pixels.
14
+ * @returns The dashes and gaps in pixels — empty for a solid line — or
15
+ * undefined where no line is drawn. `auto` is a focus ring, which is the
16
+ * state of the pointer rather than a part of the figure.
17
+ */
18
+ export declare function lineDash(style: string, width: number): readonly number[] | undefined;
19
+ /**
20
+ * A corner radius in pixels.
21
+ * @param radius - The computed `border-*-radius`, in pixels or as a share.
22
+ * @param width - The box's width, which a share is taken of.
23
+ * @param height - Its height.
24
+ * @returns The radius, in pixels.
25
+ */
26
+ export declare function cornerRadius(radius: string, width: number, height: number): number;
27
+ //# sourceMappingURL=cssPaint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cssPaint.d.ts","sourceRoot":"","sources":["../../../src/download/core/cssPaint.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO9D;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,SAAS,MAAM,EAAE,GAAG,SAAS,CAe/B;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM,CAOR"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * What a computed style says is painted, read the way a figure file needs it.
3
+ */
4
+ /**
5
+ * A colour, or nothing where the page paints nothing with it.
6
+ * @param color - A computed colour, as `getComputedStyle` writes it.
7
+ * @returns The colour, or undefined where it is transparent.
8
+ */
9
+ export function visibleColor(color) {
10
+ const value = color.trim();
11
+ if (value === '' || value === 'transparent')
12
+ return undefined;
13
+ if (ZERO_ALPHA_COMMAS.test(value) || ZERO_ALPHA_SLASH.test(value)) {
14
+ return undefined;
15
+ }
16
+ return value;
17
+ }
18
+ /**
19
+ * The dashes a CSS line style is drawn with.
20
+ * @param style - The computed `border-*-style` or `outline-style`.
21
+ * @param width - The line's width, in pixels.
22
+ * @returns The dashes and gaps in pixels — empty for a solid line — or
23
+ * undefined where no line is drawn. `auto` is a focus ring, which is the
24
+ * state of the pointer rather than a part of the figure.
25
+ */
26
+ export function lineDash(style, width) {
27
+ if (!(width > 0))
28
+ return undefined;
29
+ switch (style) {
30
+ case 'none':
31
+ case 'hidden':
32
+ case 'auto':
33
+ case '':
34
+ return undefined;
35
+ case 'dashed':
36
+ return [width * 3, width * 3];
37
+ case 'dotted':
38
+ return [width, width];
39
+ default:
40
+ return [];
41
+ }
42
+ }
43
+ /**
44
+ * A corner radius in pixels.
45
+ * @param radius - The computed `border-*-radius`, in pixels or as a share.
46
+ * @param width - The box's width, which a share is taken of.
47
+ * @param height - Its height.
48
+ * @returns The radius, in pixels.
49
+ */
50
+ export function cornerRadius(radius, width, height) {
51
+ const value = Number.parseFloat(radius);
52
+ if (!Number.isFinite(value) || value <= 0)
53
+ return 0;
54
+ if (radius.trim().endsWith('%')) {
55
+ return (Math.min(width, height) * value) / 100;
56
+ }
57
+ return value;
58
+ }
59
+ /** `rgba(r, g, b, 0)`, which is what a transparent ground computes to. */
60
+ const ZERO_ALPHA_COMMAS = /^rgba\((?:[^,]+,){3}\s*0(?:\.0*)?\)$/;
61
+ /** `rgb(r g b / 0)` and `color(srgb r g b / 0)`. */
62
+ const ZERO_ALPHA_SLASH = /\/\s*0(?:\.0*)?%?\)$/;
63
+ //# sourceMappingURL=cssPaint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cssPaint.js","sourceRoot":"","sources":["../../../src/download/core/cssPaint.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,aAAa;QAAE,OAAO,SAAS,CAAC;IAC9D,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAClE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAa,EACb,KAAa;IAEb,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACnC,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM,CAAC;QACZ,KAAK,EAAE;YACL,OAAO,SAAS,CAAC;QACnB,KAAK,QAAQ;YACX,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAChC,KAAK,QAAQ;YACX,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACxB;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAc,EACd,KAAa,EACb,MAAc;IAEd,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACpD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC;IACjD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0EAA0E;AAC1E,MAAM,iBAAiB,GAAG,sCAAsC,CAAC;AAEjE,oDAAoD;AACpD,MAAM,gBAAgB,GAAG,sBAAsB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * One drawing, serialized with every token it names written out.
3
+ *
4
+ * The copy is taken first and read from the original, because the values are a
5
+ * property of where the figure sits on the page: a detached clone inherits
6
+ * nothing and would resolve every token to an empty string.
7
+ * @param drawing - The drawing, as it sits on the page.
8
+ * @returns Its markup.
9
+ */
10
+ export declare function drawingMarkup(drawing: SVGSVGElement): string;
11
+ //# sourceMappingURL=drawingMarkup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawingMarkup.d.ts","sourceRoot":"","sources":["../../../src/download/core/drawingMarkup.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAI5D"}
@@ -0,0 +1,32 @@
1
+ import { cssTokenNames, resolveCssTokens } from "./cssTokens.js";
2
+ /**
3
+ * One drawing, serialized with every token it names written out.
4
+ *
5
+ * The copy is taken first and read from the original, because the values are a
6
+ * property of where the figure sits on the page: a detached clone inherits
7
+ * nothing and would resolve every token to an empty string.
8
+ * @param drawing - The drawing, as it sits on the page.
9
+ * @returns Its markup.
10
+ */
11
+ export function drawingMarkup(drawing) {
12
+ const clone = drawing.cloneNode(true);
13
+ const markup = new XMLSerializer().serializeToString(clone);
14
+ return resolveCssTokens(markup, tokenValues(drawing, cssTokenNames(markup)));
15
+ }
16
+ /**
17
+ * What each token the markup names is worth where the figure is drawn.
18
+ * @param drawing - The drawing, as it sits on the page.
19
+ * @param names - The tokens it asks for.
20
+ * @returns The values, keyed by token name.
21
+ */
22
+ function tokenValues(drawing, names) {
23
+ const values = {};
24
+ if (names.length === 0)
25
+ return values;
26
+ const styles = window.getComputedStyle(drawing);
27
+ for (const name of names) {
28
+ values[name] = styles.getPropertyValue(name);
29
+ }
30
+ return values;
31
+ }
32
+ //# sourceMappingURL=drawingMarkup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawingMarkup.js","sourceRoot":"","sources":["../../../src/download/core/drawingMarkup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEjE;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,OAAsB;IAClD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAkB,CAAC;IACvD,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC5D,OAAO,gBAAgB,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAClB,OAAsB,EACtB,KAAwB;IAExB,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * A part of a figure the page draws in HTML, painted from where the browser put
3
+ * it.
4
+ *
5
+ * Some figures are not drawings: a periodic table is a grid of buttons, because
6
+ * every cell has to be reachable by Tab and read by a screen reader. Saved as
7
+ * SVG it still has to look like the table the reader saw, so each box, each
8
+ * line round it and each line of words is measured off the page and painted
9
+ * again — never re-derived from the styles that made it, so the copy cannot
10
+ * drift from the screen.
11
+ *
12
+ * What is painted: a box's ground, its border (as drawn on its top edge), its
13
+ * corner, its outline, its opacity, every line of its words in their colour,
14
+ * size, weight and style, and any `<svg>` inside it. What is not: images,
15
+ * gradients, shadows, filters and generated `::before` / `::after` content.
16
+ * Chrome inside the part — `data-figure="chrome"` — is left behind.
17
+ */
18
+ /**
19
+ * One part of a figure drawn in HTML, as SVG markup.
20
+ * @param part - The element the part is drawn in.
21
+ * @param documentFont - The font family the saved document is set in.
22
+ * @returns The markup, in the part's own coordinates: the caller places it.
23
+ */
24
+ export declare function figureHtml(part: Element, documentFont: string): string;
25
+ //# sourceMappingURL=figureHtml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figureHtml.d.ts","sourceRoot":"","sources":["../../../src/download/core/figureHtml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAqBH;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAStE"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * A part of a figure the page draws in HTML, painted from where the browser put
3
+ * it.
4
+ *
5
+ * Some figures are not drawings: a periodic table is a grid of buttons, because
6
+ * every cell has to be reachable by Tab and read by a screen reader. Saved as
7
+ * SVG it still has to look like the table the reader saw, so each box, each
8
+ * line round it and each line of words is measured off the page and painted
9
+ * again — never re-derived from the styles that made it, so the copy cannot
10
+ * drift from the screen.
11
+ *
12
+ * What is painted: a box's ground, its border (as drawn on its top edge), its
13
+ * corner, its outline, its opacity, every line of its words in their colour,
14
+ * size, weight and style, and any `<svg>` inside it. What is not: images,
15
+ * gradients, shadows, filters and generated `::before` / `::after` content.
16
+ * Chrome inside the part — `data-figure="chrome"` — is left behind.
17
+ */
18
+ import { cornerRadius, lineDash, visibleColor } from "./cssPaint.js";
19
+ import { drawingMarkup } from "./drawingMarkup.js";
20
+ import { figureHtmlMarkup } from "./figureHtmlMarkup.js";
21
+ import { lineBoxes } from "./textLines.js";
22
+ /** Chrome inside the part, which is not part of the picture. */
23
+ const CHROME = '[data-figure="chrome"]';
24
+ /**
25
+ * One part of a figure drawn in HTML, as SVG markup.
26
+ * @param part - The element the part is drawn in.
27
+ * @param documentFont - The font family the saved document is set in.
28
+ * @returns The markup, in the part's own coordinates: the caller places it.
29
+ */
30
+ export function figureHtml(part, documentFont) {
31
+ const context = {
32
+ origin: part.getBoundingClientRect(),
33
+ documentFont,
34
+ range: document.createRange(),
35
+ };
36
+ const paints = [];
37
+ paintElement(part, context, paints);
38
+ return figureHtmlMarkup(paints);
39
+ }
40
+ function paintElement(element, context, into) {
41
+ if (element.matches(CHROME))
42
+ return;
43
+ const styles = window.getComputedStyle(element);
44
+ if (styles.display === 'none')
45
+ return;
46
+ const visible = styles.visibility === 'visible';
47
+ const box = element.getBoundingClientRect();
48
+ if (element instanceof SVGSVGElement) {
49
+ if (!visible || box.width <= 0 || box.height <= 0)
50
+ return;
51
+ into.push({
52
+ kind: 'drawing',
53
+ markup: drawingMarkup(element),
54
+ x: box.left - context.origin.left,
55
+ y: box.top - context.origin.top,
56
+ });
57
+ return;
58
+ }
59
+ const own = [];
60
+ if (visible)
61
+ paintGround(box, styles, context, own);
62
+ for (const child of element.childNodes) {
63
+ if (child instanceof Text) {
64
+ if (visible)
65
+ paintText(child, styles, context, own);
66
+ }
67
+ else if (child instanceof Element) {
68
+ paintElement(child, context, own);
69
+ }
70
+ }
71
+ if (visible)
72
+ paintOutline(box, styles, context, own);
73
+ if (own.length === 0)
74
+ return;
75
+ const opacity = Number.parseFloat(styles.opacity);
76
+ if (Number.isFinite(opacity) && opacity < 1) {
77
+ into.push({ kind: 'group', opacity, children: own });
78
+ return;
79
+ }
80
+ for (const paint of own)
81
+ into.push(paint);
82
+ }
83
+ function paintGround(box, styles, context, into) {
84
+ if (box.width <= 0 || box.height <= 0)
85
+ return;
86
+ const x = box.left - context.origin.left;
87
+ const y = box.top - context.origin.top;
88
+ const radius = cornerRadius(styles.borderTopLeftRadius, box.width, box.height);
89
+ const fill = visibleColor(styles.backgroundColor);
90
+ if (fill !== undefined) {
91
+ into.push({
92
+ kind: 'box',
93
+ x,
94
+ y,
95
+ width: box.width,
96
+ height: box.height,
97
+ radius,
98
+ fill,
99
+ });
100
+ }
101
+ // A border lies inside the box, where a stroke straddles its line: the
102
+ // stroke is drawn half a width in, over the ground the page drew under it.
103
+ const width = Number.parseFloat(styles.borderTopWidth);
104
+ const dash = lineDash(styles.borderTopStyle, width);
105
+ const stroke = visibleColor(styles.borderTopColor);
106
+ if (dash === undefined || stroke === undefined)
107
+ return;
108
+ const half = width / 2;
109
+ into.push({
110
+ kind: 'box',
111
+ x: x + half,
112
+ y: y + half,
113
+ width: box.width - width,
114
+ height: box.height - width,
115
+ radius: Math.max(0, radius - half),
116
+ stroke,
117
+ strokeWidth: width,
118
+ dash,
119
+ });
120
+ }
121
+ function paintOutline(box, styles, context, into) {
122
+ const width = Number.parseFloat(styles.outlineWidth);
123
+ const dash = lineDash(styles.outlineStyle, width);
124
+ const stroke = visibleColor(styles.outlineColor);
125
+ if (dash === undefined || stroke === undefined)
126
+ return;
127
+ const offset = Number.parseFloat(styles.outlineOffset) || 0;
128
+ const grow = offset + width / 2;
129
+ const radius = cornerRadius(styles.borderTopLeftRadius, box.width, box.height);
130
+ into.push({
131
+ kind: 'box',
132
+ x: box.left - context.origin.left - grow,
133
+ y: box.top - context.origin.top - grow,
134
+ width: box.width + grow * 2,
135
+ height: box.height + grow * 2,
136
+ radius: radius > 0 ? Math.max(0, radius + grow) : 0,
137
+ stroke,
138
+ strokeWidth: width,
139
+ dash,
140
+ });
141
+ }
142
+ function paintText(node, styles, context, into) {
143
+ const color = visibleColor(styles.color);
144
+ if (color === undefined || node.data.trim() === '')
145
+ return;
146
+ const fontSize = Number.parseFloat(styles.fontSize);
147
+ const fontStyle = styles.fontStyle === 'normal' ? undefined : styles.fontStyle;
148
+ const fontFamily = styles.fontFamily === context.documentFont ? undefined : styles.fontFamily;
149
+ for (const line of lineBoxes(node, context.range)) {
150
+ const words = transformed(node.data.slice(line.start, line.end).replaceAll(/\s+/g, ' ').trim(), styles.textTransform);
151
+ if (words === '')
152
+ continue;
153
+ into.push({
154
+ kind: 'text',
155
+ text: words,
156
+ x: line.left - context.origin.left,
157
+ y: (line.top + line.bottom) / 2 - context.origin.top,
158
+ width: line.right - line.left,
159
+ color,
160
+ fontSize,
161
+ fontWeight: styles.fontWeight,
162
+ fontStyle,
163
+ fontFamily,
164
+ });
165
+ }
166
+ }
167
+ function transformed(words, transform) {
168
+ if (transform === 'uppercase')
169
+ return words.toUpperCase();
170
+ if (transform === 'lowercase')
171
+ return words.toLowerCase();
172
+ return words;
173
+ }
174
+ //# sourceMappingURL=figureHtml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figureHtml.js","sourceRoot":"","sources":["../../../src/download/core/figureHtml.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * A part of a figure drawn in HTML, written out as SVG.
3
+ *
4
+ * The part is measured off the page first (`figureHtml.ts`); what reaches this
5
+ * module is already a list of boxes, runs of words and drawings with where each
6
+ * one sits, so the file it becomes can be read — and tested — without a page.
7
+ */
8
+ /** A box the browser painted: a ground, a line round it, or both. */
9
+ export interface HtmlPaintBox {
10
+ /** What it is. */
11
+ kind: 'box';
12
+ /** Its left edge, in pixels from the left of the part. */
13
+ x: number;
14
+ /** Its top edge, in pixels from the top of the part. */
15
+ y: number;
16
+ /** Its width, in pixels. */
17
+ width: number;
18
+ /** Its height. */
19
+ height: number;
20
+ /**
21
+ * How round its corners are, in pixels.
22
+ * @default 0
23
+ */
24
+ radius?: number;
25
+ /**
26
+ * What fills it.
27
+ * @default undefined — it is not filled
28
+ */
29
+ fill?: string;
30
+ /**
31
+ * The colour of the line round it, centred on its edge.
32
+ * @default undefined — no line is drawn
33
+ */
34
+ stroke?: string;
35
+ /**
36
+ * How heavy that line is, in pixels.
37
+ * @default 1
38
+ */
39
+ strokeWidth?: number;
40
+ /**
41
+ * The line's dashes and gaps, in pixels.
42
+ * @default undefined — a solid line
43
+ */
44
+ dash?: readonly number[];
45
+ }
46
+ /** One line of words, set where the browser set it. */
47
+ export interface HtmlPaintText {
48
+ /** What it is. */
49
+ kind: 'text';
50
+ /** What it says, its spaces already collapsed. */
51
+ text: string;
52
+ /** Its left edge, in pixels from the left of the part. */
53
+ x: number;
54
+ /** The middle of its line, in pixels from the top of the part. */
55
+ y: number;
56
+ /**
57
+ * How wide the browser drew it. The words are fitted to it, so a run the
58
+ * page condensed stays condensed and a reader opening the file with another
59
+ * font gets the same layout.
60
+ */
61
+ width: number;
62
+ /** Its colour. */
63
+ color: string;
64
+ /** Its size, in pixels. */
65
+ fontSize: number;
66
+ /** Its weight. */
67
+ fontWeight: string;
68
+ /**
69
+ * Its style.
70
+ * @default undefined — upright
71
+ */
72
+ fontStyle?: string;
73
+ /**
74
+ * Its type, where it is not the one the document is set in.
75
+ * @default undefined — the document's own
76
+ */
77
+ fontFamily?: string;
78
+ }
79
+ /** A drawing inside the part, already an SVG of its own. */
80
+ export interface HtmlPaintDrawing {
81
+ /** What it is. */
82
+ kind: 'drawing';
83
+ /** The `<svg>` element as it was serialized, tokens already resolved. */
84
+ markup: string;
85
+ /** Its left edge, in pixels from the left of the part. */
86
+ x: number;
87
+ /** Its top edge, in pixels from the top of the part. */
88
+ y: number;
89
+ }
90
+ /** Everything inside an element the page drew faded. */
91
+ export interface HtmlPaintGroup {
92
+ /** What it is. */
93
+ kind: 'group';
94
+ /** How opaque the whole of it is, from 0 to 1. */
95
+ opacity: number;
96
+ /** What it holds, in the order it is painted. */
97
+ children: readonly HtmlPaint[];
98
+ }
99
+ /** One thing painted from a part of the page. */
100
+ export type HtmlPaint = HtmlPaintBox | HtmlPaintText | HtmlPaintDrawing | HtmlPaintGroup;
101
+ /**
102
+ * The part, as the markup that goes into the saved figure.
103
+ * @param paints - What was measured, in the order it is painted.
104
+ * @returns The markup, in the part's own coordinates: the caller places it.
105
+ */
106
+ export declare function figureHtmlMarkup(paints: readonly HtmlPaint[]): string;
107
+ //# sourceMappingURL=figureHtmlMarkup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figureHtmlMarkup.d.ts","sourceRoot":"","sources":["../../../src/download/core/figureHtmlMarkup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC3B,kBAAkB;IAClB,IAAI,EAAE,KAAK,CAAC;IACZ,0DAA0D;IAC1D,CAAC,EAAE,MAAM,CAAC;IACV,wDAAwD;IACxD,CAAC,EAAE,MAAM,CAAC;IACV,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,CAAC,EAAE,MAAM,CAAC;IACV,kEAAkE;IAClE,CAAC,EAAE,MAAM,CAAC;IACV;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,4DAA4D;AAC5D,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,CAAC,EAAE,MAAM,CAAC;IACV,wDAAwD;IACxD,CAAC,EAAE,MAAM,CAAC;CACX;AAED,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,kBAAkB;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAC;CAChC;AAED,iDAAiD;AACjD,MAAM,MAAM,SAAS,GACnB,YAAY,GAAG,aAAa,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAEnE;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAIrE"}