@heycys/gallery 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +50 -2
- package/THIRD-PARTY-NOTICES.md +3303 -0
- package/assets/writing-preferences.md +107 -0
- package/bin/gallery.mjs +10 -0
- package/browser/editor/components/bookmark/icons.mjs +6 -0
- package/browser/editor/components/bookmark/index.mjs +80 -0
- package/browser/editor/components/bookmark/page.mjs +147 -0
- package/browser/editor/components/builders.mjs +19 -0
- package/browser/editor/components/callout/index.mjs +64 -0
- package/browser/editor/components/code/index.mjs +327 -0
- package/browser/editor/components/code/page.mjs +561 -0
- package/browser/editor/components/colors.mjs +50 -0
- package/browser/editor/components/columns/index.mjs +104 -0
- package/browser/editor/components/columns/page.mjs +310 -0
- package/browser/editor/components/details/index.mjs +73 -0
- package/browser/editor/components/details/page.mjs +86 -0
- package/browser/editor/components/dialog/index.mjs +84 -0
- package/browser/editor/components/dialog/page.mjs +201 -0
- package/browser/editor/components/divider/index.mjs +48 -0
- package/browser/editor/components/embed/icons.mjs +11 -0
- package/browser/editor/components/embed/index.mjs +123 -0
- package/browser/editor/components/embed/page.mjs +309 -0
- package/browser/editor/components/figure/index.mjs +87 -0
- package/browser/editor/components/figure/page.mjs +42 -0
- package/browser/editor/components/file/icons.mjs +14 -0
- package/browser/editor/components/file/index.mjs +77 -0
- package/browser/editor/components/file/page.mjs +114 -0
- package/browser/editor/components/flowchart/add.mjs +123 -0
- package/browser/editor/components/flowchart/index.mjs +246 -0
- package/browser/editor/components/flowchart/page.mjs +453 -0
- package/browser/editor/components/heading/index.mjs +53 -0
- package/browser/editor/components/heading/page.mjs +6 -0
- package/browser/editor/components/highlight/index.mjs +63 -0
- package/browser/editor/components/icon/index.mjs +57 -0
- package/browser/editor/components/icon/page.mjs +286 -0
- package/browser/editor/components/icons.mjs +48 -0
- package/browser/editor/components/image/crop.mjs +189 -0
- package/browser/editor/components/image/index.mjs +104 -0
- package/browser/editor/components/image/page.mjs +385 -0
- package/browser/editor/components/image/viewer.mjs +213 -0
- package/browser/editor/components/installed/index.mjs +179 -0
- package/browser/editor/components/installed/page.mjs +523 -0
- package/browser/editor/components/installed/served.mjs +35 -0
- package/browser/editor/components/kit.mjs +67 -0
- package/browser/editor/components/list/index.mjs +194 -0
- package/browser/editor/components/list/join.mjs +68 -0
- package/browser/editor/components/list/numbers.mjs +107 -0
- package/browser/editor/components/list/page.mjs +632 -0
- package/browser/editor/components/math/index.mjs +88 -0
- package/browser/editor/components/math/page.mjs +236 -0
- package/browser/editor/components/math/tex-logo.mjs +6 -0
- package/browser/editor/components/media/icons.mjs +19 -0
- package/browser/editor/components/media/page.mjs +192 -0
- package/browser/editor/components/media/parts.mjs +60 -0
- package/browser/editor/components/media/size.mjs +20 -0
- package/browser/editor/components/media/toolbar.mjs +37 -0
- package/browser/editor/components/media/write.mjs +7 -0
- package/browser/editor/components/pages.mjs +46 -0
- package/browser/editor/components/paragraph/index.mjs +43 -0
- package/browser/editor/components/paragraph/page.mjs +52 -0
- package/browser/editor/components/placeholder-bar.mjs +17 -0
- package/browser/editor/components/placeholder.mjs +128 -0
- package/browser/editor/components/quote/index.mjs +33 -0
- package/browser/editor/components/registry.mjs +859 -0
- package/browser/editor/components/rows.mjs +16 -0
- package/browser/editor/components/section/index.mjs +42 -0
- package/browser/editor/components/section/page.mjs +141 -0
- package/browser/editor/components/set-apart.mjs +24 -0
- package/browser/editor/components/sheets/index.mjs +137 -0
- package/browser/editor/components/sheets/page.mjs +227 -0
- package/browser/editor/components/sheets/pills.mjs +226 -0
- package/browser/editor/components/table/grid.mjs +73 -0
- package/browser/editor/components/table/index.mjs +308 -0
- package/browser/editor/components/table/page.mjs +683 -0
- package/browser/editor/components/table/slots.mjs +41 -0
- package/browser/editor/components/widget/index.mjs +50 -0
- package/browser/editor/page/annotate/anchors.mjs +230 -0
- package/browser/editor/page/annotate/card.mjs +102 -0
- package/browser/editor/page/annotate/index.mjs +1656 -0
- package/browser/editor/page/at-menu/index.mjs +317 -0
- package/browser/editor/page/autosave.mjs +1023 -0
- package/browser/editor/page/beside.mjs +21 -0
- package/browser/editor/page/block-info.mjs +63 -0
- package/browser/editor/page/block-menu/colors.mjs +84 -0
- package/browser/editor/page/block-menu/index.mjs +217 -0
- package/browser/editor/page/blocks.mjs +255 -0
- package/browser/editor/page/caret.mjs +682 -0
- package/browser/editor/page/changes/bar.mjs +102 -0
- package/browser/editor/page/changes/ghost.mjs +206 -0
- package/browser/editor/page/changes/gone-words.mjs +94 -0
- package/browser/editor/page/changes/index.mjs +447 -0
- package/browser/editor/page/changes/words.mjs +27 -0
- package/browser/editor/page/chip-fills.mjs +126 -0
- package/browser/editor/page/clipboard/import/colors.mjs +192 -0
- package/browser/editor/page/clipboard/import/html.mjs +792 -0
- package/browser/editor/page/clipboard/import/inline.mjs +232 -0
- package/browser/editor/page/clipboard/import/languages.mjs +42 -0
- package/browser/editor/page/clipboard/import/markdown.mjs +760 -0
- package/browser/editor/page/clipboard/import/math.mjs +100 -0
- package/browser/editor/page/clipboard/import/office.mjs +245 -0
- package/browser/editor/page/clipboard/import/read.mjs +120 -0
- package/browser/editor/page/clipboard/import/rich.mjs +29 -0
- package/browser/editor/page/clipboard/import/to-blocks.mjs +290 -0
- package/browser/editor/page/clipboard/index.mjs +816 -0
- package/browser/editor/page/clipboard/own/blocks.mjs +211 -0
- package/browser/editor/page/clipboard/own/chart-keys.mjs +58 -0
- package/browser/editor/page/clipboard/own/describe.mjs +124 -0
- package/browser/editor/page/clipboard/own/export.mjs +167 -0
- package/browser/editor/page/clipboard/own/ids.mjs +39 -0
- package/browser/editor/page/clipboard/own/index.mjs +13 -0
- package/browser/editor/page/clipboard/own/rules.mjs +44 -0
- package/browser/editor/page/clipboard/own/selection.mjs +159 -0
- package/browser/editor/page/clipboard/own/writers.mjs +315 -0
- package/browser/editor/page/columns/index.mjs +360 -0
- package/browser/editor/page/commit.mjs +1813 -0
- package/browser/editor/page/conflicts.mjs +249 -0
- package/browser/editor/page/convert.mjs +831 -0
- package/browser/editor/page/core.mjs +1693 -0
- package/browser/editor/page/drag/drop.mjs +307 -0
- package/browser/editor/page/drag/index.mjs +351 -0
- package/browser/editor/page/drag/preview.mjs +126 -0
- package/browser/editor/page/edge-scroll.mjs +50 -0
- package/browser/editor/page/editor.mjs +1780 -0
- package/browser/editor/page/emoji-picker/emoji-tab.mjs +287 -0
- package/browser/editor/page/emoji-picker/glyph-html.mjs +26 -0
- package/browser/editor/page/emoji-picker/grid.mjs +81 -0
- package/browser/editor/page/emoji-picker/icon-tab.mjs +217 -0
- package/browser/editor/page/emoji-picker/icons.mjs +31 -0
- package/browser/editor/page/emoji-picker/index.mjs +166 -0
- package/browser/editor/page/emoji-picker/styles.mjs +161 -0
- package/browser/editor/page/emoji-picker/support.mjs +204 -0
- package/browser/editor/page/emoji-picker/upload.mjs +236 -0
- package/browser/editor/page/export-report.mjs +23 -0
- package/browser/editor/page/fills.mjs +62 -0
- package/browser/editor/page/find/index.mjs +107 -0
- package/browser/editor/page/flags.mjs +70 -0
- package/browser/editor/page/fold/index.mjs +348 -0
- package/browser/editor/page/fold/rule.mjs +125 -0
- package/browser/editor/page/folded.mjs +23 -0
- package/browser/editor/page/format-bar/bar.mjs +449 -0
- package/browser/editor/page/format-bar/brush.mjs +77 -0
- package/browser/editor/page/format-bar/colors.mjs +46 -0
- package/browser/editor/page/format-bar/index.mjs +404 -0
- package/browser/editor/page/formula/index.mjs +236 -0
- package/browser/editor/page/formula/panel.mjs +336 -0
- package/browser/editor/page/formula/symbols.mjs +156 -0
- package/browser/editor/page/frame.mjs +74 -0
- package/browser/editor/page/frames.mjs +196 -0
- package/browser/editor/page/geometry.mjs +402 -0
- package/browser/editor/page/gesture.mjs +45 -0
- package/browser/editor/page/handle/index.mjs +650 -0
- package/browser/editor/page/handle-sizes.mjs +14 -0
- package/browser/editor/page/hints/index.mjs +84 -0
- package/browser/editor/page/history.mjs +401 -0
- package/browser/editor/page/insert/index.mjs +256 -0
- package/browser/editor/page/kept.mjs +38 -0
- package/browser/editor/page/links/address.mjs +40 -0
- package/browser/editor/page/links/index.mjs +866 -0
- package/browser/editor/page/links/pages.mjs +131 -0
- package/browser/editor/page/links/views.mjs +369 -0
- package/browser/editor/page/long-runs.mjs +75 -0
- package/browser/editor/page/look.mjs +77 -0
- package/browser/editor/page/made.mjs +24 -0
- package/browser/editor/page/margin.mjs +373 -0
- package/browser/editor/page/markdown/index.mjs +88 -0
- package/browser/editor/page/markdown/rules.mjs +33 -0
- package/browser/editor/page/marks.mjs +377 -0
- package/browser/editor/page/media-menu/index.mjs +158 -0
- package/browser/editor/page/menu.mjs +544 -0
- package/browser/editor/page/merge.mjs +124 -0
- package/browser/editor/page/notices.mjs +142 -0
- package/browser/editor/page/offered.mjs +32 -0
- package/browser/editor/page/outline/folds.mjs +53 -0
- package/browser/editor/page/outline/index.mjs +783 -0
- package/browser/editor/page/outline/list.mjs +184 -0
- package/browser/editor/page/outline/read.mjs +201 -0
- package/browser/editor/page/outline/strip.mjs +287 -0
- package/browser/editor/page/outline/tree.mjs +248 -0
- package/browser/editor/page/overlay-layer.mjs +227 -0
- package/browser/editor/page/overlays.mjs +205 -0
- package/browser/editor/page/own.mjs +28 -0
- package/browser/editor/page/pads.mjs +71 -0
- package/browser/editor/page/page-objects.mjs +105 -0
- package/browser/editor/page/panel.mjs +65 -0
- package/browser/editor/page/placement.mjs +58 -0
- package/browser/editor/page/post.mjs +41 -0
- package/browser/editor/page/present-links.mjs +50 -0
- package/browser/editor/page/quiet.mjs +48 -0
- package/browser/editor/page/resize/index.mjs +327 -0
- package/browser/editor/page/select-all/index.mjs +262 -0
- package/browser/editor/page/selection/delete.mjs +61 -0
- package/browser/editor/page/selection/index.mjs +164 -0
- package/browser/editor/page/selection/marquee.mjs +174 -0
- package/browser/editor/page/session.mjs +168 -0
- package/browser/editor/page/slash-menu/index.mjs +291 -0
- package/browser/editor/page/storage.mjs +48 -0
- package/browser/editor/page/sync-state.mjs +267 -0
- package/browser/editor/page/table/aligns.mjs +29 -0
- package/browser/editor/page/table/cell-bar.mjs +141 -0
- package/browser/editor/page/table/cells.mjs +527 -0
- package/browser/editor/page/table/icons.mjs +40 -0
- package/browser/editor/page/table/index.mjs +990 -0
- package/browser/editor/page/table/lists.mjs +187 -0
- package/browser/editor/page/table/widths.mjs +313 -0
- package/browser/editor/page/tex.mjs +32 -0
- package/browser/editor/page/text-select/index.mjs +671 -0
- package/browser/editor/page/tooltip.mjs +98 -0
- package/browser/editor/page/type-grid.mjs +83 -0
- package/browser/editor/page/typing/code-edges.mjs +274 -0
- package/browser/editor/page/typing/index.mjs +282 -0
- package/browser/editor/page/typing/leave.mjs +68 -0
- package/browser/editor/page/ui.mjs +160 -0
- package/browser/shared/annotations.mjs +569 -0
- package/browser/shared/code-folds.mjs +14 -0
- package/browser/shared/code-languages.mjs +70 -0
- package/browser/shared/code-lines.mjs +30 -0
- package/browser/shared/colors.mjs +30 -0
- package/browser/shared/component-catalog.mjs +573 -0
- package/browser/shared/components/bookmark.mjs +26 -0
- package/browser/shared/components/callout.mjs +9 -0
- package/browser/shared/components/chart.mjs +20 -0
- package/browser/shared/components/code.mjs +37 -0
- package/browser/shared/components/columns.mjs +16 -0
- package/browser/shared/components/details.mjs +15 -0
- package/browser/shared/components/dialog.mjs +28 -0
- package/browser/shared/components/diff.mjs +18 -0
- package/browser/shared/components/divider.mjs +6 -0
- package/browser/shared/components/embed.mjs +25 -0
- package/browser/shared/components/figure.mjs +14 -0
- package/browser/shared/components/file.mjs +23 -0
- package/browser/shared/components/heading.mjs +6 -0
- package/browser/shared/components/highlight.mjs +9 -0
- package/browser/shared/components/icon.mjs +18 -0
- package/browser/shared/components/image.mjs +39 -0
- package/browser/shared/components/index.mjs +396 -0
- package/browser/shared/components/installed.mjs +232 -0
- package/browser/shared/components/list.mjs +146 -0
- package/browser/shared/components/math.mjs +49 -0
- package/browser/shared/components/mention.mjs +33 -0
- package/browser/shared/components/page.mjs +46 -0
- package/browser/shared/components/paragraph.mjs +9 -0
- package/browser/shared/components/quote.mjs +6 -0
- package/browser/shared/components/section.mjs +8 -0
- package/browser/shared/components/sheets.mjs +80 -0
- package/browser/shared/components/state.mjs +20 -0
- package/browser/shared/components/table.mjs +49 -0
- package/browser/shared/components/text.mjs +14 -0
- package/browser/shared/components/widget.mjs +10 -0
- package/browser/shared/copy-ids.mjs +72 -0
- package/browser/shared/css-references.mjs +110 -0
- package/browser/shared/document-look.mjs +178 -0
- package/browser/shared/emoji/custom.mjs +91 -0
- package/browser/shared/emoji/data/LICENSE-lucide.txt +43 -0
- package/browser/shared/emoji/data/LICENSE-mingcute.txt +202 -0
- package/browser/shared/emoji/data/LICENSE-tabler.txt +21 -0
- package/browser/shared/emoji/data/README.md +28 -0
- package/browser/shared/emoji/data/categories.json +1 -0
- package/browser/shared/emoji/data/icons.json +1 -0
- package/browser/shared/emoji/data/keywords-en.json +1 -0
- package/browser/shared/emoji/data/keywords-zh.json +1 -0
- package/browser/shared/emoji/data/names.json +1 -0
- package/browser/shared/emoji/data/positions.json +1 -0
- package/browser/shared/emoji/data/twemoji-index.json +1 -0
- package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
- package/browser/shared/emoji/data.mjs +194 -0
- package/browser/shared/emoji/emoji.mjs +38 -0
- package/browser/shared/emoji/glyphs.mjs +134 -0
- package/browser/shared/emoji/icon-value.mjs +91 -0
- package/browser/shared/escape.mjs +20 -0
- package/browser/shared/export-wrap.mjs +89 -0
- package/browser/shared/files.mjs +33 -0
- package/browser/shared/html-tree.mjs +59 -0
- package/browser/shared/http.mjs +22 -0
- package/browser/shared/i18n/en.mjs +1223 -0
- package/browser/shared/i18n/index.mjs +132 -0
- package/browser/shared/ids.mjs +24 -0
- package/browser/shared/import-types.mjs +23 -0
- package/browser/shared/inline-spacing.mjs +97 -0
- package/browser/shared/layers.mjs +42 -0
- package/browser/shared/long-runs.mjs +39 -0
- package/browser/shared/media.mjs +162 -0
- package/browser/shared/new-names.mjs +67 -0
- package/browser/shared/number-reading.mjs +92 -0
- package/browser/shared/old-names.mjs +143 -0
- package/browser/shared/outline.mjs +194 -0
- package/browser/shared/page-address.mjs +140 -0
- package/browser/shared/page-links.mjs +86 -0
- package/browser/shared/paths.mjs +73 -0
- package/browser/shared/preferences.mjs +116 -0
- package/browser/shared/preview-server.mjs +247 -0
- package/browser/shared/qa-levels.mjs +93 -0
- package/browser/shared/reading-place.mjs +91 -0
- package/browser/shared/renamed-storage.mjs +220 -0
- package/browser/shared/reports.mjs +46 -0
- package/browser/shared/search.mjs +85 -0
- package/browser/shared/session.mjs +77 -0
- package/browser/shared/table-chart.mjs +113 -0
- package/browser/shared/table-hides.mjs +120 -0
- package/browser/shared/table-slots.mjs +75 -0
- package/browser/shared/words.mjs +23 -0
- package/browser/shared/workspace-look.mjs +91 -0
- package/browser/shared/workspace.mjs +535 -0
- package/browser/shared/writing-preferences.mjs +68 -0
- package/browser/shared/zoom.mjs +57 -0
- package/dist/chunk-2B5E4CDJ.mjs +2 -0
- package/dist/chunk-342HXE3Q.mjs +2 -0
- package/dist/chunk-3HIRPVLU.mjs +2 -0
- package/dist/chunk-43B75J5T.mjs +2 -0
- package/dist/chunk-4FS7Z7WR.mjs +2 -0
- package/dist/chunk-4K5KC6V2.mjs +2 -0
- package/dist/chunk-5L7RYZCL.mjs +2 -0
- package/dist/chunk-5MHMDLZD.mjs +4 -0
- package/dist/chunk-5ZKJ3H4P.mjs +8 -0
- package/dist/chunk-64K7IPLO.mjs +255 -0
- package/dist/chunk-6QXGZM36.mjs +8 -0
- package/dist/chunk-6RGJOMJP.mjs +16 -0
- package/dist/chunk-742D2WWJ.mjs +19 -0
- package/dist/chunk-7DTINW6U.mjs +48 -0
- package/dist/chunk-A55HN5OK.mjs +2 -0
- package/dist/chunk-AGDILNWB.mjs +2 -0
- package/dist/chunk-AJ73XJF3.mjs +2 -0
- package/dist/chunk-AUZGSZJH.mjs +13 -0
- package/dist/chunk-BFE45AKL.mjs +2 -0
- package/dist/chunk-BGGDRNYQ.mjs +10 -0
- package/dist/chunk-BXO2ZY5P.mjs +2 -0
- package/dist/chunk-C564NU2H.mjs +77 -0
- package/dist/chunk-CEH4MRCC.mjs +2 -0
- package/dist/chunk-CY2FNNAB.mjs +16 -0
- package/dist/chunk-DFUDV4LX.mjs +2 -0
- package/dist/chunk-DKXG4XDG.mjs +2 -0
- package/dist/chunk-E7LWZRXY.mjs +4 -0
- package/dist/chunk-EZQ34M3F.mjs +124 -0
- package/dist/chunk-EZY3WC6Z.mjs +15 -0
- package/dist/chunk-FDLXYYG4.mjs +4 -0
- package/dist/chunk-FUKQNOQS.mjs +9 -0
- package/dist/chunk-GB5SOYQJ.mjs +7 -0
- package/dist/chunk-GRAXKKG4.mjs +2 -0
- package/dist/chunk-HYMEEXKN.mjs +4 -0
- package/dist/chunk-IVDLMMBD.mjs +2 -0
- package/dist/chunk-JPOSLGOC.mjs +6 -0
- package/dist/chunk-JVHHHGEA.mjs +3 -0
- package/dist/chunk-L3QKH4OK.mjs +26 -0
- package/dist/chunk-LAE5NQ4B.mjs +2 -0
- package/dist/chunk-LCTHTZIL.mjs +960 -0
- package/dist/chunk-LEF6DRCK.mjs +59 -0
- package/dist/chunk-LKX55H76.mjs +2 -0
- package/dist/chunk-LS4F7JUM.mjs +2 -0
- package/dist/chunk-MAFIGVXY.mjs +2 -0
- package/dist/chunk-NO5NJCHO.mjs +2 -0
- package/dist/chunk-NQPVAU63.mjs +2 -0
- package/dist/chunk-NSKUTQ5J.mjs +5 -0
- package/dist/chunk-O35FIXRB.mjs +2 -0
- package/dist/chunk-P2CAZPDP.mjs +3 -0
- package/dist/chunk-PL6GHLGD.mjs +15 -0
- package/dist/chunk-QAIHRH3I.mjs +13 -0
- package/dist/chunk-QJIR2BLP.mjs +6 -0
- package/dist/chunk-QR6A54KJ.mjs +3 -0
- package/dist/chunk-QUPLVPB2.mjs +7 -0
- package/dist/chunk-R7BNENLY.mjs +4 -0
- package/dist/chunk-S6O4UHLC.mjs +2 -0
- package/dist/chunk-SGJWQKEI.mjs +2 -0
- package/dist/chunk-SYGN7GLU.mjs +2 -0
- package/dist/chunk-TMYZB6AV.mjs +2 -0
- package/dist/chunk-TX6JH7TR.mjs +2 -0
- package/dist/chunk-TYK6VNAB.mjs +10 -0
- package/dist/chunk-U3SSPL4K.mjs +8 -0
- package/dist/chunk-U6KNPJPR.mjs +2 -0
- package/dist/chunk-UALRNVSE.mjs +4 -0
- package/dist/chunk-UH4SIXTR.mjs +2 -0
- package/dist/chunk-UMHUSOPJ.mjs +2 -0
- package/dist/chunk-V3HXVQEM.mjs +2 -0
- package/dist/chunk-V5JTW2LH.mjs +27 -0
- package/dist/chunk-V5VXUJKG.mjs +2 -0
- package/dist/chunk-V6XZ4VIR.mjs +2 -0
- package/dist/chunk-VBXMADMP.mjs +2 -0
- package/dist/chunk-VNV55RUA.mjs +2 -0
- package/dist/chunk-VPD2PS35.mjs +2 -0
- package/dist/chunk-W3BGBJQW.mjs +2 -0
- package/dist/chunk-W4VKN3GF.mjs +7 -0
- package/dist/chunk-W5BXXPDJ.mjs +3 -0
- package/dist/chunk-W7XHE4CT.mjs +2 -0
- package/dist/chunk-XNROSH2T.mjs +4 -0
- package/dist/chunk-XUNHRCOG.mjs +6 -0
- package/dist/chunk-Y34NR5JL.mjs +2 -0
- package/dist/chunk-Y6RLRPG3.mjs +3 -0
- package/dist/chunk-YEY3RSFQ.mjs +2 -0
- package/dist/cli.mjs +2 -0
- package/dist/server.mjs +2 -0
- package/dist/worker.mjs +5 -0
- package/kit/charts.js +355 -0
- package/kit/code.js +164 -0
- package/kit/dialogs.js +157 -0
- package/kit/math.js +2004 -0
- package/kit/report.css +2932 -0
- package/kit/runtime.js +1782 -0
- package/kit/sheets.js +123 -0
- package/kit/state.js +217 -0
- package/kit/tables.js +1499 -0
- package/kit/tokens.js +29 -0
- package/kit/ui.js +658 -0
- package/package.json +41 -4
- package/release.json +25 -0
- package/sdk/column-widths.d.ts +56 -0
- package/sdk/doc-charts.d.ts +82 -0
- package/sdk/doc-code.d.ts +28 -0
- package/sdk/doc-dialogs.d.ts +4 -0
- package/sdk/doc-kit.d.ts +147 -0
- package/sdk/doc-math.d.ts +3 -0
- package/sdk/doc-sheets.d.ts +15 -0
- package/sdk/doc-state.d.ts +41 -0
- package/sdk/doc-tables.d.ts +24 -0
- package/sdk/doc-tokens.d.ts +22 -0
- package/sdk/index.d.ts +30 -0
- package/skill/SKILL.md +150 -0
- package/skill/agents/openai.yaml +5 -0
- package/skill/references/building-components.md +367 -0
- package/skill/references/example-report.html +356 -0
- package/skill/references/writing-html.md +187 -0
- package/skill/sdk/column-widths.d.ts +56 -0
- package/skill/sdk/doc-charts.d.ts +82 -0
- package/skill/sdk/doc-code.d.ts +28 -0
- package/skill/sdk/doc-dialogs.d.ts +4 -0
- package/skill/sdk/doc-kit.d.ts +147 -0
- package/skill/sdk/doc-math.d.ts +3 -0
- package/skill/sdk/doc-sheets.d.ts +15 -0
- package/skill/sdk/doc-state.d.ts +41 -0
- package/skill/sdk/doc-tables.d.ts +24 -0
- package/skill/sdk/doc-tokens.d.ts +22 -0
- package/skill/sdk/index.d.ts +30 -0
- package/starter/doc.html +21 -0
- package/starter/doc.json +5 -0
- package/vendor/d3.v7.9.0.min.js +2 -0
- package/vendor/katex/auto-render.min.js +1 -0
- package/vendor/katex/contrib/mhchem.min.js +1 -0
- package/vendor/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/vendor/katex/katex.min.css +1 -0
- package/vendor/katex/katex.min.js +1 -0
- package/vendor/pdfjs/LICENSE +177 -0
- package/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
- package/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
- package/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
- package/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
- package/vendor/pdfjs/cmaps/LICENSE +36 -0
- package/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
- package/vendor/pdfjs/legacy/build/pdf.min.mjs +27 -0
- package/vendor/pdfjs/legacy/build/pdf.worker.min.mjs +27 -0
- package/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
- package/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +363 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/vendor/types/@types/d3/LICENSE +21 -0
- package/vendor/types/@types/d3/index.d.ts +39 -0
- package/vendor/types/@types/d3/package.json +81 -0
- package/vendor/types/@types/d3-array/LICENSE +21 -0
- package/vendor/types/@types/d3-array/index.d.ts +1118 -0
- package/vendor/types/@types/d3-array/package.json +56 -0
- package/vendor/types/@types/d3-axis/LICENSE +21 -0
- package/vendor/types/@types/d3-axis/index.d.ts +293 -0
- package/vendor/types/@types/d3-axis/package.json +47 -0
- package/vendor/types/@types/d3-brush/LICENSE +21 -0
- package/vendor/types/@types/d3-brush/index.d.ts +255 -0
- package/vendor/types/@types/d3-brush/package.json +42 -0
- package/vendor/types/@types/d3-chord/LICENSE +21 -0
- package/vendor/types/@types/d3-chord/index.d.ts +471 -0
- package/vendor/types/@types/d3-chord/package.json +40 -0
- package/vendor/types/@types/d3-color/LICENSE +21 -0
- package/vendor/types/@types/d3-color/index.d.ts +669 -0
- package/vendor/types/@types/d3-color/package.json +55 -0
- package/vendor/types/@types/d3-contour/LICENSE +21 -0
- package/vendor/types/@types/d3-contour/index.d.ts +222 -0
- package/vendor/types/@types/d3-contour/package.json +38 -0
- package/vendor/types/@types/d3-delaunay/LICENSE +21 -0
- package/vendor/types/@types/d3-delaunay/index.d.ts +316 -0
- package/vendor/types/@types/d3-delaunay/package.json +30 -0
- package/vendor/types/@types/d3-dispatch/LICENSE +21 -0
- package/vendor/types/@types/d3-dispatch/index.d.ts +96 -0
- package/vendor/types/@types/d3-dispatch/package.json +51 -0
- package/vendor/types/@types/d3-drag/LICENSE +21 -0
- package/vendor/types/@types/d3-drag/index.d.ts +395 -0
- package/vendor/types/@types/d3-drag/package.json +42 -0
- package/vendor/types/@types/d3-dsv/LICENSE +21 -0
- package/vendor/types/@types/d3-dsv/index.d.ts +482 -0
- package/vendor/types/@types/d3-dsv/package.json +45 -0
- package/vendor/types/@types/d3-ease/LICENSE +21 -0
- package/vendor/types/@types/d3-ease/index.d.ts +316 -0
- package/vendor/types/@types/d3-ease/package.json +40 -0
- package/vendor/types/@types/d3-fetch/LICENSE +21 -0
- package/vendor/types/@types/d3-fetch/index.d.ts +282 -0
- package/vendor/types/@types/d3-fetch/package.json +37 -0
- package/vendor/types/@types/d3-force/LICENSE +21 -0
- package/vendor/types/@types/d3-force/index.d.ts +899 -0
- package/vendor/types/@types/d3-force/package.json +45 -0
- package/vendor/types/@types/d3-format/LICENSE +21 -0
- package/vendor/types/@types/d3-format/index.d.ts +337 -0
- package/vendor/types/@types/d3-format/package.json +45 -0
- package/vendor/types/@types/d3-geo/LICENSE +21 -0
- package/vendor/types/@types/d3-geo/index.d.ts +1371 -0
- package/vendor/types/@types/d3-geo/package.json +48 -0
- package/vendor/types/@types/d3-hierarchy/LICENSE +21 -0
- package/vendor/types/@types/d3-hierarchy/index.d.ts +928 -0
- package/vendor/types/@types/d3-hierarchy/package.json +50 -0
- package/vendor/types/@types/d3-interpolate/LICENSE +21 -0
- package/vendor/types/@types/d3-interpolate/index.d.ts +387 -0
- package/vendor/types/@types/d3-interpolate/package.json +47 -0
- package/vendor/types/@types/d3-path/LICENSE +21 -0
- package/vendor/types/@types/d3-path/index.d.ts +108 -0
- package/vendor/types/@types/d3-path/package.json +41 -0
- package/vendor/types/@types/d3-polygon/LICENSE +21 -0
- package/vendor/types/@types/d3-polygon/index.d.ts +41 -0
- package/vendor/types/@types/d3-polygon/package.json +40 -0
- package/vendor/types/@types/d3-quadtree/LICENSE +21 -0
- package/vendor/types/@types/d3-quadtree/index.d.ts +204 -0
- package/vendor/types/@types/d3-quadtree/package.json +45 -0
- package/vendor/types/@types/d3-random/LICENSE +21 -0
- package/vendor/types/@types/d3-random/index.d.ts +313 -0
- package/vendor/types/@types/d3-random/package.json +41 -0
- package/vendor/types/@types/d3-scale/LICENSE +21 -0
- package/vendor/types/@types/d3-scale/index.d.ts +2669 -0
- package/vendor/types/@types/d3-scale/package.json +53 -0
- package/vendor/types/@types/d3-scale-chromatic/LICENSE +21 -0
- package/vendor/types/@types/d3-scale-chromatic/index.d.ts +520 -0
- package/vendor/types/@types/d3-scale-chromatic/package.json +46 -0
- package/vendor/types/@types/d3-selection/LICENSE +21 -0
- package/vendor/types/@types/d3-selection/index.d.ts +1210 -0
- package/vendor/types/@types/d3-selection/package.json +56 -0
- package/vendor/types/@types/d3-shape/LICENSE +21 -0
- package/vendor/types/@types/d3-shape/index.d.ts +2792 -0
- package/vendor/types/@types/d3-shape/package.json +53 -0
- package/vendor/types/@types/d3-time/LICENSE +21 -0
- package/vendor/types/@types/d3-time/index.d.ts +697 -0
- package/vendor/types/@types/d3-time/package.json +46 -0
- package/vendor/types/@types/d3-time-format/LICENSE +21 -0
- package/vendor/types/@types/d3-time-format/index.d.ts +202 -0
- package/vendor/types/@types/d3-time-format/package.json +40 -0
- package/vendor/types/@types/d3-timer/LICENSE +21 -0
- package/vendor/types/@types/d3-timer/index.d.ts +68 -0
- package/vendor/types/@types/d3-timer/package.json +45 -0
- package/vendor/types/@types/d3-transition/LICENSE +21 -0
- package/vendor/types/@types/d3-transition/index.d.ts +664 -0
- package/vendor/types/@types/d3-transition/package.json +47 -0
- package/vendor/types/@types/d3-zoom/LICENSE +21 -0
- package/vendor/types/@types/d3-zoom/index.d.ts +611 -0
- package/vendor/types/@types/d3-zoom/package.json +48 -0
- package/vendor/types/@types/geojson/LICENSE +21 -0
- package/vendor/types/@types/geojson/index.d.ts +202 -0
- package/vendor/types/@types/geojson/package.json +46 -0
- package/vendor/typescript/LICENSE.txt +55 -0
- package/vendor/typescript/lib.decorators.d.ts +384 -0
- package/vendor/typescript/lib.decorators.legacy.d.ts +22 -0
- package/vendor/typescript/lib.dom.d.ts +39429 -0
- package/vendor/typescript/lib.dom.iterable.d.ts +571 -0
- package/vendor/typescript/lib.es2015.collection.d.ts +147 -0
- package/vendor/typescript/lib.es2015.core.d.ts +597 -0
- package/vendor/typescript/lib.es2015.d.ts +28 -0
- package/vendor/typescript/lib.es2015.generator.d.ts +77 -0
- package/vendor/typescript/lib.es2015.iterable.d.ts +605 -0
- package/vendor/typescript/lib.es2015.promise.d.ts +81 -0
- package/vendor/typescript/lib.es2015.proxy.d.ts +128 -0
- package/vendor/typescript/lib.es2015.reflect.d.ts +144 -0
- package/vendor/typescript/lib.es2015.symbol.d.ts +46 -0
- package/vendor/typescript/lib.es2015.symbol.wellknown.d.ts +326 -0
- package/vendor/typescript/lib.es2016.array.include.d.ts +116 -0
- package/vendor/typescript/lib.es2016.d.ts +21 -0
- package/vendor/typescript/lib.es2016.intl.d.ts +31 -0
- package/vendor/typescript/lib.es2017.arraybuffer.d.ts +21 -0
- package/vendor/typescript/lib.es2017.d.ts +26 -0
- package/vendor/typescript/lib.es2017.date.d.ts +31 -0
- package/vendor/typescript/lib.es2017.intl.d.ts +44 -0
- package/vendor/typescript/lib.es2017.object.d.ts +49 -0
- package/vendor/typescript/lib.es2017.sharedmemory.d.ts +135 -0
- package/vendor/typescript/lib.es2017.string.d.ts +45 -0
- package/vendor/typescript/lib.es2017.typedarrays.d.ts +53 -0
- package/vendor/typescript/lib.es2018.asyncgenerator.d.ts +77 -0
- package/vendor/typescript/lib.es2018.asynciterable.d.ts +53 -0
- package/vendor/typescript/lib.es2018.d.ts +24 -0
- package/vendor/typescript/lib.es2018.intl.d.ts +83 -0
- package/vendor/typescript/lib.es2018.promise.d.ts +30 -0
- package/vendor/typescript/lib.es2018.regexp.d.ts +37 -0
- package/vendor/typescript/lib.es2019.array.d.ts +79 -0
- package/vendor/typescript/lib.es2019.d.ts +24 -0
- package/vendor/typescript/lib.es2019.intl.d.ts +23 -0
- package/vendor/typescript/lib.es2019.object.d.ts +33 -0
- package/vendor/typescript/lib.es2019.string.d.ts +37 -0
- package/vendor/typescript/lib.es2019.symbol.d.ts +24 -0
- package/vendor/typescript/lib.es2020.bigint.d.ts +765 -0
- package/vendor/typescript/lib.es2020.d.ts +27 -0
- package/vendor/typescript/lib.es2020.date.d.ts +42 -0
- package/vendor/typescript/lib.es2020.intl.d.ts +474 -0
- package/vendor/typescript/lib.es2020.number.d.ts +28 -0
- package/vendor/typescript/lib.es2020.promise.d.ts +47 -0
- package/vendor/typescript/lib.es2020.sharedmemory.d.ts +99 -0
- package/vendor/typescript/lib.es2020.string.d.ts +44 -0
- package/vendor/typescript/lib.es2020.symbol.wellknown.d.ts +41 -0
- package/vendor/typescript/lib.es2021.d.ts +23 -0
- package/vendor/typescript/lib.es2021.intl.d.ts +166 -0
- package/vendor/typescript/lib.es2021.promise.d.ts +48 -0
- package/vendor/typescript/lib.es2021.string.d.ts +33 -0
- package/vendor/typescript/lib.es2021.weakref.d.ts +78 -0
- package/vendor/typescript/lib.es2022.array.d.ts +121 -0
- package/vendor/typescript/lib.es2022.d.ts +25 -0
- package/vendor/typescript/lib.es2022.error.d.ts +75 -0
- package/vendor/typescript/lib.es2022.intl.d.ts +145 -0
- package/vendor/typescript/lib.es2022.object.d.ts +26 -0
- package/vendor/typescript/lib.es2022.regexp.d.ts +39 -0
- package/vendor/typescript/lib.es2022.string.d.ts +25 -0
- package/vendor/typescript/lib.es5.d.ts +4601 -0
- package/vendor/typescript/package.json +4 -0
- package/vendor/typescript/typescript.js +446 -0
- package/web/assets/index-Bh74DfsV.css +1 -0
- package/web/assets/index-UW0RyFFt.js +13 -0
- package/web/index.html +14 -0
|
@@ -0,0 +1,760 @@
|
|
|
1
|
+
import { languageFromFence } from "./languages.mjs";
|
|
2
|
+
import { decodeEntities, parseInlineMarkdown, unescapeMarkdown } from "./inline.mjs";
|
|
3
|
+
import { spec } from "./rich.mjs";
|
|
4
|
+
|
|
5
|
+
// Markdown and plain text as block specs (notion-lite editor/input/clipboard/parse.js). Notion
|
|
6
|
+
// (860313) turns several lines of pasted text into HTML with markdown-it and converts that; this
|
|
7
|
+
// reads the blocks directly. Notion's own export reads back with its structure (own/export.mjs
|
|
8
|
+
// writes the same):
|
|
9
|
+
// # … ###### (5 and 6 are heading 4, as Notion's), - * + • items, 1. 1) items, - [ ] / - [x] to-dos,
|
|
10
|
+
// ``` and ~~~ code (its language after the fence), $$ math $$ and the forms AI answers copy (below),
|
|
11
|
+
// ---, | tables |, > quotes (lines in a row are one quote; after an empty line or a nested > its
|
|
12
|
+
// blocks), <aside> callouts </aside> (the first line an emoji and text), .
|
|
13
|
+
// Indentation (any number of spaces; Notion writes 4) makes blocks of the line above; empty
|
|
14
|
+
// lines are skipped; inline text is inline.mjs's. An item whose line holds " " alone is one of
|
|
15
|
+
// no words, as a page export (复制页面内容's) writes an item of none over what it holds (own/
|
|
16
|
+
// writers.mjs lineOf), and as the import reads it.
|
|
17
|
+
//
|
|
18
|
+
// A whole document (readMarkdownDocument: the import's, src/transfer/import.mjs, never a paste) is
|
|
19
|
+
// read as a Markdown viewer shows it (CommonMark and GFM, as GitHub shows a .md file), on the same
|
|
20
|
+
// rules where they agree:
|
|
21
|
+
// paragraphs the lines of one (up to an empty line or a line that starts another block; a line 4
|
|
22
|
+
// spaces deeper than it is a block under it, Notion's) joined by a space, none between
|
|
23
|
+
// two East Asian characters (Pandoc's east_asian_line_breaks); a line ending in two
|
|
24
|
+
// spaces or a backslash a line break; a line of === or --- right under one makes it a
|
|
25
|
+
// heading (setext); a display formula amid its words ($$…$$) a formula block between
|
|
26
|
+
// its parts, as a viewer shows one on a line of its own
|
|
27
|
+
// items their lines joined so too (a line less than 4 spaces deeper than the item's text);
|
|
28
|
+
// a numbered one's number kept (props.number: a list that starts at 3 goes on so); one
|
|
29
|
+
// of no words on its line ("- ", or "- " as a page export writes one over what it
|
|
30
|
+
// holds) holds the blocks indented under it, its text empty
|
|
31
|
+
// headings their level and line kept (props.level, props.line: the import makes the report's
|
|
32
|
+
// title and sections of them), a {#id} after one left off
|
|
33
|
+
// code its title from the fence's info string, ```js title="src/x.js" (title=src/x.js,
|
|
34
|
+
// title='…'; Pandoc's ```{.js title="…"} too); a language the kit does not know kept
|
|
35
|
+
// by the fence's name (props.fence); a ```mermaid flowchart that is one chain of
|
|
36
|
+
// steps (flowchart or graph, edges A --> B --> C, labels in [] or ()) a flow of its
|
|
37
|
+
// steps, a spec { type: "flow", props: { steps, line } } (the import writes the flow
|
|
38
|
+
// component's markup); any other mermaid stays code,
|
|
39
|
+
// noted. A title is the fence's alone: a bold line above the fence is a paragraph
|
|
40
|
+
// math a display formula ($$, \[ on a line) by Pandoc's rule: closed before an empty line, at
|
|
41
|
+
// a line ending in its close or starting with it ("$$ (1)": its number a \tag, other
|
|
42
|
+
// words a paragraph after it); one not closed so ends at the empty line (or a heading,
|
|
43
|
+
// a fence), noted, and one with nothing in it stays its line's text. \begin{equation|
|
|
44
|
+
// align|gather|multline|…} … \end{…} on lines of its own a formula block too, ended so
|
|
45
|
+
// (its \end added), one KaTeX does not draw (multline, flalign, eqnarray) as the
|
|
46
|
+
// nearest it does, noted
|
|
47
|
+
// tables GFM's: a header row and its delimiter row (pipes at the ends or not; \| a pipe in
|
|
48
|
+
// a cell, inside code and formulas too), then its rows up to an empty line or a line
|
|
49
|
+
// that starts another block
|
|
50
|
+
// quotes > lines and the lazy lines after them, read as a document: its paragraphs a quote,
|
|
51
|
+
// any other block of it (a list, code, a table…) standing in place out of the quote,
|
|
52
|
+
// which holds paragraphs alone, noted; GitHub's alerts (> [!NOTE], [!TIP],
|
|
53
|
+
// [!IMPORTANT], [!WARNING], [!CAUTION]) callouts
|
|
54
|
+
// pictures a paragraph's pictures blocks of their own, the text around them paragraphs; an
|
|
55
|
+
// item's blocks it holds; elsewhere (a heading, a cell, a disclosure's title) a
|
|
56
|
+
// picture of the web a link, any other its alt text, noted
|
|
57
|
+
// HTML <details><summary> … </details> a toggle, its blocks read as Markdown; an HTML block
|
|
58
|
+
// of pictures alone (<p align="center"><img …></p>, a link around them) its picture
|
|
59
|
+
// blocks, of an <hr> a divider, of line breaks or empty tags nothing; any other HTML
|
|
60
|
+
// block (CommonMark's: a block element's tag starting a line, up to an empty line;
|
|
61
|
+
// <pre> up to </pre>; a tag alone on its line) kept as written, a spec { type:
|
|
62
|
+
// "html", props: { html, line } }; comments left out, <script>, <style> and
|
|
63
|
+
// <textarea> left out and noted
|
|
64
|
+
// footnotes [^label]: definitions (and their indented lines) taken out and returned as
|
|
65
|
+
// `footnotes`, numbered as first referred to (those never referred to after them);
|
|
66
|
+
// a reference is inline.mjs's
|
|
67
|
+
// links [label]: address "title" definitions taken out (an address with a . / : or #, or in
|
|
68
|
+
// <>: "[注]: 一句话" stays words), their references inline.mjs's
|
|
69
|
+
// dividers "- - -", "* * *" too; a [TOC] line left out
|
|
70
|
+
// What it leaves out or keeps otherwise than a viewer shows it is noted, with its line (counted from
|
|
71
|
+
// `firstLine`): `notes` [{ line, kind, text }]; what the import tries or looks for afterwards is
|
|
72
|
+
// returned with its line too: the formulas (`formulas`, KaTeX draws them or not) and the links to
|
|
73
|
+
// addresses that are no web ones (`links`: a file beside the document, a place in it).
|
|
74
|
+
|
|
75
|
+
// A callout's first line: an emoji first is its icon, then its text.
|
|
76
|
+
const EMOJI = /^(\p{Extended_Pictographic}(?:[\u{FE0F}\u{200D}\u{1F3FB}-\u{1F3FF}]|\p{Extended_Pictographic})*)\s*/u;
|
|
77
|
+
function callout(head, children, inline = parseInlineMarkdown) {
|
|
78
|
+
const match = EMOJI.exec(head);
|
|
79
|
+
const text = (match ? head.slice(match[0].length) : head).trim();
|
|
80
|
+
const blocks = text ? [spec("text", inline(text)), ...children] : children;
|
|
81
|
+
return spec("callout", [], match ? { icon: match[1] } : {}, blocks.length ? blocks : [spec("text")]);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** A table spec of rows of rich text (columns c0, c1, …). */
|
|
85
|
+
export function tableSpec(rows, header) {
|
|
86
|
+
const width = Math.max(1, ...rows.map((row) => row.length));
|
|
87
|
+
const columns = Array.from({ length: width }, (_, i) => `c${i}`);
|
|
88
|
+
return spec("table", [], { table_block_column_order: columns, table_block_column_format: {}, table_block_column_header: header, table_block_row_header: false },
|
|
89
|
+
rows.map((row) => spec("table_row", [], { cells: Object.fromEntries(row.map((cell, i) => [columns[i], cell])) })));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const indentOf = (raw) => raw.match(/^[ \t]*/)[0].replace(/\t/g, " ").length;
|
|
93
|
+
const dedent = (lines, n) => lines.map((line) => line.replace(new RegExp(`^[ \\t]{0,${n}}`), ""));
|
|
94
|
+
|
|
95
|
+
/** Markdown (or any plain text) as block specs. */
|
|
96
|
+
export const fromMarkdown = (text) => parseLines(text.replace(/\r\n?/g, "\n").split("\n"));
|
|
97
|
+
|
|
98
|
+
// Display formulas: $$ on lines of their own (Notion's export) and what AI answers copy: $$ … $$ in
|
|
99
|
+
// one line, $$ followed by the formula up to a line ending in $$, \[ … \] in one line or on lines
|
|
100
|
+
// of their own, \\[ … \\] (escaped Markdown, ChatGPT's: unescaped inside). Returns { close, unescape,
|
|
101
|
+
// rest, single } when the line starts one (rest: the formula's part on that line).
|
|
102
|
+
const DISPLAY_MATH = [
|
|
103
|
+
{ open: "\\\\[", close: "\\\\]", unescape: true },
|
|
104
|
+
{ open: "\\[", close: "\\]", unescape: false },
|
|
105
|
+
{ open: "$$", close: "$$", unescape: false },
|
|
106
|
+
];
|
|
107
|
+
function displayMathStart(line) {
|
|
108
|
+
for (const d of DISPLAY_MATH) {
|
|
109
|
+
if (!line.startsWith(d.open)) continue;
|
|
110
|
+
const rest = line.slice(d.open.length).trimEnd();
|
|
111
|
+
if (!rest.endsWith(d.close) && rest.includes(d.close)) return null; // text after its end: an inline one
|
|
112
|
+
return { ...d, rest, single: rest.endsWith(d.close) };
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
const mathTitle = (body, unescape) => {
|
|
117
|
+
const tex = body.join("\n").trim();
|
|
118
|
+
const text = unescape ? unescapeMarkdown(tex) : tex;
|
|
119
|
+
return text ? [[text]] : [];
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// A table row's cells: split at |, but not at \|, nor inside `code` or a formula (GFM's rule, and
|
|
123
|
+
// formulas). `escaped`: a whole document's, where \| is a pipe inside code and formulas too (GFM).
|
|
124
|
+
function tableCells(line, escaped = false) {
|
|
125
|
+
const s = line.trim().replace(/^\|/, "").replace(/(?<!\\)\|$/, "");
|
|
126
|
+
const cells = [];
|
|
127
|
+
let cell = "";
|
|
128
|
+
for (let i = 0; i < s.length;) {
|
|
129
|
+
const rest = s.slice(i);
|
|
130
|
+
const span = /^(`+)[\s\S]*?\1/.exec(rest) || /^\\\\\([\s\S]*?\\\\\)/.exec(rest) || /^\\\([\s\S]*?\\\)/.exec(rest) || /^\$\$[^$]*?\$\$/.exec(rest) || /^\$(?=\S)[^$]*?\S\$/.exec(rest);
|
|
131
|
+
if (span) {
|
|
132
|
+
cell += escaped ? span[0].replace(/\\\|/g, "|") : span[0];
|
|
133
|
+
i += span[0].length;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (rest.startsWith("\\|")) {
|
|
137
|
+
cell += "|";
|
|
138
|
+
i += 2;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (s[i] === "|") {
|
|
142
|
+
cells.push(cell.trim());
|
|
143
|
+
cell = "";
|
|
144
|
+
i++;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
cell += s[i++];
|
|
148
|
+
}
|
|
149
|
+
cells.push(cell.trim());
|
|
150
|
+
return cells;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const HEADINGS = ["header", "sub_header", "sub_sub_header", "header_4", "header_4", "header_4"];
|
|
154
|
+
const FENCE = /^(`{3,}|~{3,})\s*([\w+#.-]*)([^`]*)$/;
|
|
155
|
+
const HEADING = /^(#{1,6})\s+(.*?)(?:\s+#+)?$/;
|
|
156
|
+
// The line of an item of no words over what it holds, as a page export writes it (own/writers.mjs lineOf).
|
|
157
|
+
const NO_WORDS = " ";
|
|
158
|
+
|
|
159
|
+
function parseLines(lines, doc = null, base = 0) {
|
|
160
|
+
const root = [];
|
|
161
|
+
const stack = [{ depth: -1, children: root }];
|
|
162
|
+
const add = (block, indent) => {
|
|
163
|
+
while (stack.length > 1 && stack.at(-1).depth >= indent) stack.pop();
|
|
164
|
+
stack.at(-1).children.push(block);
|
|
165
|
+
stack.push({ depth: indent, children: block.children });
|
|
166
|
+
};
|
|
167
|
+
const lineOf = (i) => (doc ? doc.firstLine + base + i : 0);
|
|
168
|
+
// Inline text: Notion's rules for a paste; a document's rules, its pictures links or words (textOnly), for a document.
|
|
169
|
+
const inline = (text, i) => (doc ? textOnly(docInline(doc, text, lineOf(i)), lineOf(i), doc) : parseInlineMarkdown(text));
|
|
170
|
+
// A list item: Notion's rules for a paste (a page export's line of no words, " ", none); a
|
|
171
|
+
// document's, its pictures blocks it holds (before the blocks indented under it).
|
|
172
|
+
const item = (type, text, i, props = {}) => {
|
|
173
|
+
if (!doc) return spec(type, text === NO_WORDS ? [] : parseInlineMarkdown(text), props);
|
|
174
|
+
const title = docInline(doc, text, lineOf(i));
|
|
175
|
+
return spec(type, trimmed(title.filter((piece) => !pictureOf(piece))), props, title.filter(pictureOf).map((piece) => pictureSpec(pictureOf(piece), lineOf(i))));
|
|
176
|
+
};
|
|
177
|
+
for (let i = 0; i < lines.length; i++) {
|
|
178
|
+
const raw = lines[i];
|
|
179
|
+
if (!raw.trim()) continue;
|
|
180
|
+
const indent = indentOf(raw);
|
|
181
|
+
const line = raw.trim();
|
|
182
|
+
let block;
|
|
183
|
+
let blocks = null; // several blocks of one source (a paragraph and its pictures)
|
|
184
|
+
let m;
|
|
185
|
+
let math;
|
|
186
|
+
let html;
|
|
187
|
+
if ((m = FENCE.exec(line))) {
|
|
188
|
+
// Code: ``` or ~~~ (a language after it), up to a fence of the same kind, no shorter.
|
|
189
|
+
const fence = m[1];
|
|
190
|
+
const start = i;
|
|
191
|
+
const body = [];
|
|
192
|
+
for (i++; i < lines.length && !(lines[i].trim().startsWith(fence[0].repeat(fence.length)) && /^(`+|~+)$/.test(lines[i].trim())); i++) body.push(lines[i]);
|
|
193
|
+
const code = dedent(body, indent).join("\n").replace(/\n+$/, ""); // no empty lines at its end (Notion 760354 _)
|
|
194
|
+
if (doc) block = documentCode(m[2], m[3], code, lineOf(start), doc);
|
|
195
|
+
else {
|
|
196
|
+
const language = m[2] ? languageFromFence(m[2]) ?? m[2][0].toUpperCase() + m[2].slice(1) : undefined;
|
|
197
|
+
block = spec("code", code ? [[code]] : [], language ? { language } : {});
|
|
198
|
+
}
|
|
199
|
+
} else if ((math = displayMathStart(line))) {
|
|
200
|
+
if (math.single) {
|
|
201
|
+
block = spec("equation", mathTitle([math.rest.slice(0, -math.close.length)], math.unescape));
|
|
202
|
+
if (doc && block.title.length) doc.formulas.push({ tex: block.title[0][0], line: lineOf(i), display: true });
|
|
203
|
+
} else if (doc) {
|
|
204
|
+
// A whole document's (Pandoc's rule): closed before an empty line, at a line that ends in its
|
|
205
|
+
// close or starts with it ("$$ (1)": its number a \tag, other words a paragraph after it).
|
|
206
|
+
// One that is not ends there, noted; one with nothing in it its line as text.
|
|
207
|
+
const start = i;
|
|
208
|
+
const end = displayEnd(lines, i, math.close);
|
|
209
|
+
const body = [math.rest, ...lines.slice(i + 1, end.at).map((each) => each.trim()), end.rest].filter((each) => each.trim());
|
|
210
|
+
i = end.closed ? end.at : end.at - 1;
|
|
211
|
+
if (!end.closed && !body.length) {
|
|
212
|
+
doc.notes.push({ line: lineOf(start), kind: "math", text: `${math.open} opens no formula (an empty line follows it): kept as text` });
|
|
213
|
+
block = spec("text", [[line]]);
|
|
214
|
+
} else {
|
|
215
|
+
if (!end.closed) doc.notes.push({ line: lineOf(start), kind: "math", text: `the display formula opened by ${math.open} is not closed before an empty line: it ends at line ${lineOf(i)}` });
|
|
216
|
+
let tex = mathTitle(body, math.unescape)[0]?.[0] ?? "";
|
|
217
|
+
const number = /^\(([\w.:-]{1,16})\)$/.exec(end.after);
|
|
218
|
+
if (number && !/\\(tag|notag|nonumber)\b/.test(tex)) tex += ` \\tag{${number[1]}}`;
|
|
219
|
+
blocks = [spec("equation", tex ? [[tex]] : [])];
|
|
220
|
+
if (tex) doc.formulas.push({ tex, line: lineOf(start), display: true });
|
|
221
|
+
if (end.after && !number) blocks.push(...paragraphBlocks(docInline(doc, end.after, lineOf(i)), lineOf(i)));
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
const body = math.rest.trim() ? [math.rest] : [];
|
|
225
|
+
for (i++; i < lines.length; i++) {
|
|
226
|
+
const next = lines[i].trim();
|
|
227
|
+
if (next.endsWith(math.close)) {
|
|
228
|
+
body.push(next.slice(0, -math.close.length));
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
body.push(next);
|
|
232
|
+
}
|
|
233
|
+
block = spec("equation", mathTitle(body, math.unescape));
|
|
234
|
+
}
|
|
235
|
+
} else if (doc && (m = BEGIN.exec(line))) {
|
|
236
|
+
// \begin{align} … \end{align}: the whole environment, KaTeX draws it as a display formula; one
|
|
237
|
+
// KaTeX has not (multline, flalign, eqnarray) as the nearest it has, noted.
|
|
238
|
+
// One not ended before an empty line (a heading, a fence) ends there, its \end{…} added, noted.
|
|
239
|
+
const start = i;
|
|
240
|
+
const end = `\\end{${m[1]}}`;
|
|
241
|
+
const body = [line];
|
|
242
|
+
let closed = line.includes(end);
|
|
243
|
+
for (let j = i + 1; !closed && j < lines.length; j++) {
|
|
244
|
+
const next = lines[j].trim();
|
|
245
|
+
if (!next || HEADING.test(next) || FENCE.test(next)) break;
|
|
246
|
+
body.push(next);
|
|
247
|
+
i = j;
|
|
248
|
+
closed = next.includes(end);
|
|
249
|
+
}
|
|
250
|
+
if (!closed) {
|
|
251
|
+
body.push(end);
|
|
252
|
+
doc.notes.push({ line: lineOf(start), kind: "math", text: `\\begin{${m[1]}} is not ended before an empty line: ${end} added at line ${lineOf(i)}` });
|
|
253
|
+
}
|
|
254
|
+
let tex = body.join("\n");
|
|
255
|
+
const name = m[1].replace(/\*$/, "");
|
|
256
|
+
if (KATEX_LACKS[name]) {
|
|
257
|
+
const as = KATEX_LACKS[name] + m[1].slice(name.length);
|
|
258
|
+
tex = tex.replace(`\\begin{${m[1]}}`, `\\begin{${as}}`).replace(end, `\\end{${as}}`);
|
|
259
|
+
doc.notes.push({ line: lineOf(start), kind: "math", text: `KaTeX draws no ${m[1]} environment: written as ${as}` });
|
|
260
|
+
}
|
|
261
|
+
block = spec("equation", [[tex]]);
|
|
262
|
+
doc.formulas.push({ tex, line: lineOf(start), display: true });
|
|
263
|
+
} else if (line === "<aside>") {
|
|
264
|
+
// Notion's callout: its first line an icon and text, then its blocks, up to its own </aside> (a
|
|
265
|
+
// callout in a highlight block has its own too).
|
|
266
|
+
const start = i;
|
|
267
|
+
const body = [];
|
|
268
|
+
for (let depth = 1, at = i + 1; at < lines.length; at++) {
|
|
269
|
+
const each = lines[at].trim();
|
|
270
|
+
depth += each === "<aside>" ? 1 : each === "</aside>" ? -1 : 0;
|
|
271
|
+
i = at;
|
|
272
|
+
if (depth === 0) break;
|
|
273
|
+
body.push(lines[at]);
|
|
274
|
+
}
|
|
275
|
+
const inner = dedent(body, indent);
|
|
276
|
+
const first = inner.findIndex((l) => l.trim());
|
|
277
|
+
const head = first < 0 ? "" : inner[first].trim();
|
|
278
|
+
block = doc
|
|
279
|
+
? callout(head, first < 0 ? [] : parseLines(inner.slice(first + 1), doc, base + start + first + 2), (text) => inline(text, start + first + 1))
|
|
280
|
+
: callout(head, first < 0 ? [] : parseLines(inner.slice(first + 1)));
|
|
281
|
+
} else if (doc && /^<details(?=[\s>]|$)/i.test(line)) {
|
|
282
|
+
// A disclosure of HTML: its summary its title, what is between its tags read as Markdown.
|
|
283
|
+
const start = i;
|
|
284
|
+
const body = [];
|
|
285
|
+
let depth = 0;
|
|
286
|
+
for (; i < lines.length; i++) {
|
|
287
|
+
body.push(lines[i]);
|
|
288
|
+
depth += (lines[i].match(/<details(?=[\s>])/gi) ?? []).length - (lines[i].match(/<\/details\s*>/gi) ?? []).length;
|
|
289
|
+
if (depth <= 0) break;
|
|
290
|
+
}
|
|
291
|
+
const text = body.join("\n");
|
|
292
|
+
const summary = /<summary(?:\s[^>]*)?>([\s\S]*?)<\/summary\s*>/i.exec(text);
|
|
293
|
+
let inner = text.replace(/^\s*<details(?:\s[^>]*)?>/i, "").replace(/<\/details\s*>\s*$/i, "");
|
|
294
|
+
if (summary) inner = inner.replace(summary[0], "");
|
|
295
|
+
block = spec("toggle", summary ? inline(summary[1].replace(/\s+/g, " ").trim(), start) : [], {}, parseLines(dedent(inner.split("\n"), indent), doc, base + start));
|
|
296
|
+
} else if (doc && (html = htmlStart(line))) {
|
|
297
|
+
// An HTML block: up to an empty line, or up to its end tag's line (<pre>, <script>, a comment).
|
|
298
|
+
const start = i;
|
|
299
|
+
const body = [raw];
|
|
300
|
+
if (html.end) {
|
|
301
|
+
if (!line.toLowerCase().slice(1).includes(html.end)) {
|
|
302
|
+
for (i++; i < lines.length; i++) {
|
|
303
|
+
body.push(lines[i]);
|
|
304
|
+
if (lines[i].toLowerCase().includes(html.end)) break;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
} else for (; i + 1 < lines.length && lines[i + 1].trim(); i++) body.push(lines[i + 1]);
|
|
308
|
+
if (html.kind === "comment") continue;
|
|
309
|
+
if (DROPPED_HTML.has(html.kind)) {
|
|
310
|
+
doc.notes.push({ line: lineOf(start), kind: "html", text: `a <${html.kind}> block is left out` });
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const written = dedent(body, indent).join("\n").trim();
|
|
314
|
+
const bare = written.replace(/<!--[\s\S]*?-->/g, "").replace(PICTURE_TAGS, "").trim();
|
|
315
|
+
if (!bare && /<img\s/i.test(written)) blocks = paragraphBlocks(docInline(doc, written.replace(/\s+/g, " "), lineOf(start)), lineOf(start)); // pictures alone (<p align="center"><img …></p>): picture blocks
|
|
316
|
+
else if (!bare && /<hr\b/i.test(written)) block = spec("divider");
|
|
317
|
+
else if (!bare) continue; // line breaks or empty tags alone: a viewer's spacing
|
|
318
|
+
else block = spec("html", [], { html: written, line: lineOf(start) });
|
|
319
|
+
} else if (/^>/.test(line)) {
|
|
320
|
+
if (doc) {
|
|
321
|
+
// A quote: its > lines (and the lazy lines after its text) read as a document.
|
|
322
|
+
const start = i;
|
|
323
|
+
const body = [];
|
|
324
|
+
for (; i < lines.length; i++) {
|
|
325
|
+
if (/^\s*>/.test(lines[i])) body.push(lines[i].replace(/^\s*>\s?/, ""));
|
|
326
|
+
else if (lines[i].trim() && body.length && body.at(-1).trim() && !startsBlock(lines[i].trim())) body.push(lines[i].trim());
|
|
327
|
+
else break;
|
|
328
|
+
}
|
|
329
|
+
i--;
|
|
330
|
+
blocks = documentQuote(body, doc, base + start);
|
|
331
|
+
} else {
|
|
332
|
+
// Lines of > in a row are one quote: its first lines (up to an empty line or a nested >) its
|
|
333
|
+
// text, the rest its blocks (a nested > a quote of its own).
|
|
334
|
+
const body = [];
|
|
335
|
+
for (; i < lines.length && /^\s*>/.test(lines[i]); i++) body.push(lines[i].trim().replace(/^>\s?/, ""));
|
|
336
|
+
i--;
|
|
337
|
+
const end = body.findIndex((l) => !l.trim() || /^>/.test(l.trim()));
|
|
338
|
+
const head = end < 0 ? body : body.slice(0, end);
|
|
339
|
+
block = spec("quote", parseInlineMarkdown(head.join("\n")), {}, end < 0 ? [] : parseLines(body.slice(end)));
|
|
340
|
+
}
|
|
341
|
+
} else if (doc && tableAt(lines, i)) {
|
|
342
|
+
// GFM's table: its header row, its delimiter row, then its rows.
|
|
343
|
+
// Each row's cells read at its line (what they leave out noted there).
|
|
344
|
+
const rows = [[tableCells(lines[i], true), i]];
|
|
345
|
+
for (i += 2; i < lines.length && lines[i].trim() && (/^\s*\|/.test(lines[i]) || !startsBlock(lines[i].trim())); i++) rows.push([tableCells(lines[i], true), i]);
|
|
346
|
+
i--;
|
|
347
|
+
block = tableSpec(rows.map(([row, at]) => row.map((cell) => inline(cell, at))), true);
|
|
348
|
+
} else if (/^\|.*\|$/.test(line)) {
|
|
349
|
+
const rows = [];
|
|
350
|
+
let header = false;
|
|
351
|
+
for (; i < lines.length && /^\s*\|.*\|\s*$/.test(lines[i]); i++) {
|
|
352
|
+
const cells = tableCells(lines[i], Boolean(doc));
|
|
353
|
+
if (cells.every((cell) => /^:?-+:?$/.test(cell))) {
|
|
354
|
+
if (rows.length === 1) header = true;
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
rows.push(cells.map((cell) => (doc ? inline(cell, i) : parseInlineMarkdown(cell))));
|
|
358
|
+
}
|
|
359
|
+
i--;
|
|
360
|
+
block = tableSpec(rows, header);
|
|
361
|
+
} else if ((m = HEADING.exec(line))) {
|
|
362
|
+
const text = doc ? m[2].replace(/\s*\{#[^}\s]*\}$/, "") : m[2];
|
|
363
|
+
block = spec(HEADINGS[m[1].length - 1], doc ? inline(text, i) : parseInlineMarkdown(text), doc ? { level: m[1].length, line: lineOf(i) } : {});
|
|
364
|
+
} else if (doc && HR.test(line)) block = spec("divider");
|
|
365
|
+
else if ((m = /^[-*+•]\s+\[([ xX])\]\s*(.*)$/.exec(line)) || (m = /^\[([ xX]?)\]\s+(.*)$/.exec(line))) {
|
|
366
|
+
const start = i;
|
|
367
|
+
const text = doc ? itemText(lines, i, indent, line.length - m[2].length, (end) => (i = end)) : m[2];
|
|
368
|
+
block = item("to_do", text, start, { checked: /x/i.test(m[1]) });
|
|
369
|
+
} else if ((m = /^[-*+•]\s+(.*)$/.exec(line)) || /^[-*+•]$/.test(line)) {
|
|
370
|
+
const start = i;
|
|
371
|
+
const text = doc && m ? itemText(lines, i, indent, line.length - m[1].length, (end) => (i = end)) : m ? m[1] : "";
|
|
372
|
+
block = item("bulleted_list", text, start);
|
|
373
|
+
} else if ((m = /^\d+[.)]\s+(.*)$/.exec(line))) {
|
|
374
|
+
const start = i;
|
|
375
|
+
const text = doc ? itemText(lines, i, indent, line.length - m[1].length, (end) => (i = end)) : m[1];
|
|
376
|
+
block = item("numbered_list", text, start, doc ? { number: Number.parseInt(line, 10) } : {});
|
|
377
|
+
} else if (/^(-{3,}|\*{3,}|_{3,})$/.test(line)) block = spec("divider");
|
|
378
|
+
else if (!doc && (m = /^!\[([^\]]*)\]\(([^)\s]+)\)$/.exec(line))) block = spec("image", [], { source: m[2], ...(m[1] ? { caption: [[m[1]]] } : {}) });
|
|
379
|
+
else if (doc && /^\[\[?toc\]\]?$/i.test(line)) continue; // a viewer's table of contents
|
|
380
|
+
else if (doc) {
|
|
381
|
+
// A paragraph: its lines, then a setext heading's underline under it.
|
|
382
|
+
const start = i;
|
|
383
|
+
const end = continuationEnd(lines, i, indent + 4);
|
|
384
|
+
const text = joinLines(lines.slice(i, end + 1));
|
|
385
|
+
i = end;
|
|
386
|
+
const under = lines[i + 1];
|
|
387
|
+
if (under !== undefined && indentOf(under) <= 3 && /^(=+|-+)\s*$/.test(under.trim())) {
|
|
388
|
+
i++;
|
|
389
|
+
const level = under.trim()[0] === "=" ? 1 : 2;
|
|
390
|
+
block = spec(HEADINGS[level - 1], inline(text, start), { level, line: lineOf(start) });
|
|
391
|
+
} else blocks = paragraphBlocks(docInline(doc, text, lineOf(start)), lineOf(start));
|
|
392
|
+
} else block = spec("text", parseInlineMarkdown(line));
|
|
393
|
+
for (const each of blocks ?? [block]) add(each, indent);
|
|
394
|
+
}
|
|
395
|
+
return root;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// ---------- a whole document ----------
|
|
399
|
+
|
|
400
|
+
const BEGIN = /^\\begin\{((?:equation|align|alignat|gather|multline|flalign|eqnarray)\*?)\}/;
|
|
401
|
+
// LaTeX's display environments KaTeX has not, and the nearest it has.
|
|
402
|
+
const KATEX_LACKS = { multline: "gather", flalign: "align", eqnarray: "align" };
|
|
403
|
+
const HR = /^([-*_])(?:[ \t]*\1){2,}$/;
|
|
404
|
+
// CommonMark's HTML blocks that end at an empty line: these elements' tags starting a line.
|
|
405
|
+
const BLOCK_TAGS = new Set(("address article aside base basefont blockquote body caption center col colgroup dd details dialog dir div dl dt "
|
|
406
|
+
+ "fieldset figcaption figure footer form frame frameset h1 h2 h3 h4 h5 h6 head header hr html iframe legend li link main menu menuitem nav "
|
|
407
|
+
+ "noframes ol optgroup option p param search section summary table tbody td tfoot th thead title tr track ul").split(" "));
|
|
408
|
+
const DROPPED_HTML = new Set(["script", "style", "textarea"]);
|
|
409
|
+
// The tags an HTML block of pictures alone is made of (a README's <p align="center"><img …></p>).
|
|
410
|
+
const PICTURE_TAGS = /<\/?(?:p|div|a|center|picture|source|span|br|img|hr)(?=[\s/>])[^>]*>/gi;
|
|
411
|
+
const ALERTS = { note: "ℹ️", tip: "💡", important: "❗", warning: "⚠️", caution: "🚨" };
|
|
412
|
+
const LINK_DEFINITION = /^\[([^\]^][^\]]*)\]:\s*(<[^>]*>|\S+)(?:\s+("[^"]*"|'[^']*'|\([^)]*\)))?\s*$/;
|
|
413
|
+
const FOOTNOTE_DEFINITION = /^\[\^([^\]\s]+)\]:\s?(.*)$/;
|
|
414
|
+
// East Asian wide characters (CJK, kana, Hangul, their punctuation and full-width forms): a line
|
|
415
|
+
// break between two of them is no space.
|
|
416
|
+
const WIDE = /[\u{1100}-\u{115F}\u{2E80}-\u{303E}\u{3041}-\u{33FF}\u{3400}-\u{4DBF}\u{4E00}-\u{9FFF}\u{A960}-\u{A97F}\u{AC00}-\u{D7A3}\u{F900}-\u{FAFF}\u{FE30}-\u{FE4F}\u{FF00}-\u{FF60}\u{FFE0}-\u{FFE6}\u{20000}-\u{3FFFD}]/u;
|
|
417
|
+
|
|
418
|
+
/** The HTML block a line starts in a whole document: { kind, end? }, or null. */
|
|
419
|
+
function htmlStart(line) {
|
|
420
|
+
if (line.startsWith("<!--")) return { kind: "comment", end: "-->" };
|
|
421
|
+
let m = /^<(script|pre|style|textarea)(?=[\s>]|$)/i.exec(line);
|
|
422
|
+
if (m) return { kind: m[1].toLowerCase(), end: `</${m[1].toLowerCase()}>` };
|
|
423
|
+
m = /^<\/?([A-Za-z][A-Za-z0-9-]*)(?=[\s/>]|$)/.exec(line);
|
|
424
|
+
if (m && BLOCK_TAGS.has(m[1].toLowerCase())) return { kind: "block" };
|
|
425
|
+
// A tag alone on its line (CommonMark's 7th kind, which cannot interrupt a paragraph).
|
|
426
|
+
if (/^(?:<[A-Za-z][A-Za-z0-9-]*(?:\s+[A-Za-z_:][\w.:-]*(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'=<>`]+))?)*\s*\/?>|<\/[A-Za-z][A-Za-z0-9-]*\s*>)$/.test(line)) return { kind: "tag" };
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Where a whole document's display formula opened at lines[start] ends, by Pandoc's rule (no empty
|
|
432
|
+
* line in it): { at, closed, rest, after }. Closed, `at` is the line that closes it (one that ends in
|
|
433
|
+
* `close`, for $$ a $$ not paired in that line, or one that starts with it), `rest` the formula's
|
|
434
|
+
* part of that line and `after` the words after its close; else `at` is the first line it does not
|
|
435
|
+
* take (an empty one, a heading, a fence, or the end).
|
|
436
|
+
*/
|
|
437
|
+
function displayEnd(lines, start, close) {
|
|
438
|
+
let at = start + 1;
|
|
439
|
+
for (; at < lines.length; at++) {
|
|
440
|
+
const line = lines[at].trim();
|
|
441
|
+
if (!line || HEADING.test(line) || FENCE.test(line)) break;
|
|
442
|
+
if (line.startsWith(close)) return { at, closed: true, rest: "", after: line.slice(close.length).trim() };
|
|
443
|
+
if (line.endsWith(close) && (close !== "$$" || line.split("$$").length % 2 === 0)) return { at, closed: true, rest: line.slice(0, -close.length), after: "" };
|
|
444
|
+
}
|
|
445
|
+
return { at, closed: false, rest: "", after: "" };
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/** Whether a line (trimmed) starts a block that ends a paragraph before it (a whole document's). */
|
|
449
|
+
function startsBlock(line) {
|
|
450
|
+
return FENCE.test(line) || Boolean(displayMathStart(line)) || BEGIN.test(line) || HEADING.test(line) || /^>/.test(line) || HR.test(line)
|
|
451
|
+
|| /^[-*+•](\s|$)/.test(line) || /^\d+[.)](\s|$)/.test(line) || /^\|/.test(line) || /^=+$/.test(line)
|
|
452
|
+
|| line === "<aside>" || (htmlStart(line)?.kind ?? "tag") !== "tag" || FOOTNOTE_DEFINITION.test(line);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/** Whether lines[i] is a GFM table's header row: its delimiter row under it, of as many cells. */
|
|
456
|
+
function tableAt(lines, i) {
|
|
457
|
+
const head = lines[i]?.trim();
|
|
458
|
+
const next = lines[i + 1]?.trim();
|
|
459
|
+
if (!head?.includes("|") || !next || !/^\|?\s*:?-+:?\s*(\|\s*:?-+:?\s*)*\|?$/.test(next) || !next.includes("|") && !head.startsWith("|")) return false;
|
|
460
|
+
return tableCells(head, true).length === tableCells(next, true).length;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// The last line of the text that starts at lines[i]: the lines after it up to an empty line, one
|
|
464
|
+
// that starts a block, a table's header, or one `limit` spaces in or deeper (a block under it).
|
|
465
|
+
function continuationEnd(lines, i, limit) {
|
|
466
|
+
let end = i;
|
|
467
|
+
while (end + 1 < lines.length) {
|
|
468
|
+
const next = lines[end + 1];
|
|
469
|
+
if (!next.trim() || indentOf(next) >= limit || startsBlock(next.trim()) || tableAt(lines, end + 1)) break;
|
|
470
|
+
end++;
|
|
471
|
+
}
|
|
472
|
+
return end;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/** A list item's text in a whole document: its line's after the marker (`marker` long) and the lines that go on with it. */
|
|
476
|
+
function itemText(lines, i, indent, marker, moved) {
|
|
477
|
+
const end = continuationEnd(lines, i, indent + marker + 4);
|
|
478
|
+
moved(end);
|
|
479
|
+
return joinLines([lines[i].trim().slice(marker), ...lines.slice(i + 1, end + 1)]);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Lines of one paragraph as one text: each ended by a space (none between two East Asian
|
|
484
|
+
* characters), or by a line break where it ends in two spaces or a backslash.
|
|
485
|
+
*/
|
|
486
|
+
function joinLines(raws) {
|
|
487
|
+
let text = "";
|
|
488
|
+
raws.forEach((raw, index) => {
|
|
489
|
+
let line = raw.trim();
|
|
490
|
+
if (index === raws.length - 1) {
|
|
491
|
+
text += line;
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
const slashes = /\\*$/.exec(line)[0].length;
|
|
495
|
+
const hard = / {2,}$/.test(raw.replace(/\t/g, " ")) || slashes % 2 === 1;
|
|
496
|
+
if (slashes % 2 === 1) line = line.slice(0, -1);
|
|
497
|
+
const next = raws[index + 1].trim();
|
|
498
|
+
text += line + (hard ? "\n" : WIDE.test(line.at(-1) ?? "") && WIDE.test(next[0] ?? "") ? "" : " ");
|
|
499
|
+
});
|
|
500
|
+
return text;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
const docInline = (doc, text, line) => {
|
|
504
|
+
doc.at = line;
|
|
505
|
+
return parseInlineMarkdown(text, doc);
|
|
506
|
+
};
|
|
507
|
+
const pictureOf = (piece) => piece[1]?.find((annotation) => annotation[0] === "img") ?? null;
|
|
508
|
+
const fileName = (src) => {
|
|
509
|
+
const name = src.split(/[?#]/)[0].split("/").pop() || src;
|
|
510
|
+
try {
|
|
511
|
+
return decodeURIComponent(name);
|
|
512
|
+
} catch {
|
|
513
|
+
return name; // a % that encodes nothing: as written
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
/** Rich text with its pictures (inline.mjs's pieces) as text where a block cannot hold one: a web picture's link, any other's alt text, noted. */
|
|
518
|
+
function textOnly(title, line, doc) {
|
|
519
|
+
if (!title.some(pictureOf)) return title;
|
|
520
|
+
return title.map((piece) => {
|
|
521
|
+
const picture = pictureOf(piece);
|
|
522
|
+
if (!picture) return piece;
|
|
523
|
+
const [, src, alt] = picture;
|
|
524
|
+
const others = piece[1].filter((annotation) => annotation !== picture);
|
|
525
|
+
doc.notes.push({ line, kind: "picture-in-text", text: `the picture ${src} stands in a line of text, kept as ${/^https?:\/\//i.test(src) ? "a link to it" : "its words"}` });
|
|
526
|
+
if (/^https?:\/\//i.test(src)) return [alt || src, [...others.filter((annotation) => annotation[0] !== "a"), ["a", src]]];
|
|
527
|
+
return others.length ? [alt || fileName(src), others] : [alt || fileName(src)];
|
|
528
|
+
}).filter((piece) => piece[0]);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// A rich text's pieces with the white space at its ends taken off (empty: none).
|
|
532
|
+
function trimmed(title) {
|
|
533
|
+
const out = title.map((piece) => [...piece]);
|
|
534
|
+
while (out.length && !out[0][0].trim()) out.shift();
|
|
535
|
+
while (out.length && !out.at(-1)[0].trim()) out.pop();
|
|
536
|
+
if (out.length) {
|
|
537
|
+
out[0][0] = out[0][0].replace(/^\s+/, "");
|
|
538
|
+
out.at(-1)[0] = out.at(-1)[0].replace(/\s+$/, "");
|
|
539
|
+
}
|
|
540
|
+
return out.map((piece) => (piece[1] ? piece : [piece[0]]));
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// A display formula in a line of text ($$…$$ amid words, inline.mjs's): its TeX, or null.
|
|
544
|
+
const displayOf = (piece) => (piece[1]?.some((annotation) => annotation[0] === "display") ? piece[1].find((annotation) => annotation[0] === "e")[1] : null);
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* A paragraph's rich text as blocks: its pictures and display formulas ($$…$$ amid its words, as a
|
|
548
|
+
* viewer shows one: on a line of its own) blocks of their own, the text between them paragraphs,
|
|
549
|
+
* each of them with the paragraph's line (the import joins the words around a picture it does not
|
|
550
|
+
* find again).
|
|
551
|
+
*/
|
|
552
|
+
function paragraphBlocks(title, line) {
|
|
553
|
+
if (!title.some((piece) => pictureOf(piece) || displayOf(piece) !== null)) return [spec("text", title)];
|
|
554
|
+
const blocks = [];
|
|
555
|
+
let run = [];
|
|
556
|
+
const flush = () => {
|
|
557
|
+
const text = trimmed(run);
|
|
558
|
+
if (text.length) blocks.push(spec("text", text, { line }));
|
|
559
|
+
run = [];
|
|
560
|
+
};
|
|
561
|
+
for (const piece of title) {
|
|
562
|
+
const picture = pictureOf(piece);
|
|
563
|
+
const display = displayOf(piece);
|
|
564
|
+
if (!picture && display === null) {
|
|
565
|
+
run.push(piece);
|
|
566
|
+
continue;
|
|
567
|
+
}
|
|
568
|
+
flush();
|
|
569
|
+
blocks.push(picture ? pictureSpec(picture, line) : spec("equation", display ? [[display]] : []));
|
|
570
|
+
}
|
|
571
|
+
flush();
|
|
572
|
+
return blocks;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/** A picture (inline.mjs's img annotation) as a picture block: its alt text its caption, else its title. */
|
|
576
|
+
function pictureSpec([, source, alt, title], line) {
|
|
577
|
+
const caption = (alt || title).trim();
|
|
578
|
+
return spec("image", [], { source, ...(caption ? { caption: [[caption]] } : {}), line });
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/** A fenced code block of a whole document: its title and language from its info string; a simple mermaid flowchart its steps. */
|
|
582
|
+
function documentCode(name, meta, code, line, doc) {
|
|
583
|
+
const braces = /^\{([^}]*)\}/.exec(meta.trim());
|
|
584
|
+
const fence = name || /\.([\w+#-]+)/.exec(braces?.[1] ?? "")?.[1] || "";
|
|
585
|
+
const title = /(?:^|[\s{])title=(?:"([^"]*)"|'([^']*)'|([^\s}]+))/.exec(meta);
|
|
586
|
+
if (fence.toLowerCase() === "mermaid") {
|
|
587
|
+
const steps = flowSteps(code);
|
|
588
|
+
if (steps) return spec("flow", [], { steps, line });
|
|
589
|
+
doc.notes.push({ line, kind: "mermaid", text: "a mermaid diagram that is not one chain of steps is kept as its code" });
|
|
590
|
+
}
|
|
591
|
+
const language = fence ? languageFromFence(fence) ?? fence[0].toUpperCase() + fence.slice(1) : undefined;
|
|
592
|
+
const titled = title ? (title[1] ?? title[2] ?? title[3]).trim() : "";
|
|
593
|
+
return spec("code", code ? [[code]] : [], {
|
|
594
|
+
...(language ? { language } : {}),
|
|
595
|
+
...(/^[a-z][\w+#.-]{0,23}$/i.test(fence) ? { fence: fence.toLowerCase() } : {}),
|
|
596
|
+
...(titled ? { title: titled } : {}),
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// A mermaid flowchart that is one chain of steps: "flowchart" or "graph" (any direction), then edges
|
|
601
|
+
// A --> B, chained (A --> B --> C) or one a line, each node's label in [] or () (([ ]), [[ ]], (( ))
|
|
602
|
+
// too; else its id), styling lines (style, classDef, class, linkStyle) and %% comments aside. Its
|
|
603
|
+
// steps' labels in order, or null: a node alone, a branch, a join, a loop, a labelled or another kind
|
|
604
|
+
// of edge, a subgraph.
|
|
605
|
+
function flowSteps(code) {
|
|
606
|
+
const statements = code.split("\n").map((each) => each.replace(/%%.*$/, "").trim().replace(/;+$/, "").trim()).filter(Boolean);
|
|
607
|
+
if (!/^(flowchart|graph)(\s+(LR|RL|TD|TB|BT))?$/i.test(statements[0] ?? "")) return null;
|
|
608
|
+
const NODE = /^([^\s[\](){}|<>"]+)\s*(?:\(\[([^\]]*)\]\)|\[\[([^\]]*)\]\]|\(\(([^)]*)\)\)|\[([^\]]*)\]|\(([^)]*)\))?$/;
|
|
609
|
+
const labels = new Map();
|
|
610
|
+
const after = new Map();
|
|
611
|
+
const before = new Map();
|
|
612
|
+
for (const statement of statements.slice(1)) {
|
|
613
|
+
if (/^(style|classDef|class|linkStyle)\s/.test(statement)) continue;
|
|
614
|
+
const parts = statement.split(/\s*-->\s*/);
|
|
615
|
+
if (parts.length < 2) return null;
|
|
616
|
+
let previous = null;
|
|
617
|
+
for (const part of parts) {
|
|
618
|
+
const node = NODE.exec(part);
|
|
619
|
+
if (!node) return null;
|
|
620
|
+
const [, id, ...shapes] = node;
|
|
621
|
+
const label = shapes.find((shape) => shape !== undefined);
|
|
622
|
+
if (label !== undefined) labels.set(id, flowLabel(label));
|
|
623
|
+
else if (!labels.has(id)) labels.set(id, id);
|
|
624
|
+
if (previous !== null) {
|
|
625
|
+
if (after.has(previous) || before.has(id)) return null;
|
|
626
|
+
after.set(previous, id);
|
|
627
|
+
before.set(id, previous);
|
|
628
|
+
}
|
|
629
|
+
previous = id;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
const starts = [...labels.keys()].filter((id) => !before.has(id));
|
|
633
|
+
if (labels.size < 2 || starts.length !== 1) return null;
|
|
634
|
+
const steps = [];
|
|
635
|
+
for (let id = starts[0]; id !== undefined && steps.length <= labels.size; id = after.get(id)) steps.push(labels.get(id));
|
|
636
|
+
return steps.length === labels.size && steps.every(Boolean) ? steps : null;
|
|
637
|
+
}
|
|
638
|
+
const flowLabel = (label) => decodeEntities(label.trim().replace(/^"([\s\S]*)"$/, "$1").replace(/<br\s*\/?>/gi, " ").replace(/<[^>]*>/g, "")).replace(/\s+/g, " ").trim();
|
|
639
|
+
|
|
640
|
+
// What a quote's blocks other than paragraphs are called in a note.
|
|
641
|
+
const KINDS = {
|
|
642
|
+
bulleted_list: "list", numbered_list: "list", to_do: "list", code: "code", table: "table", equation: "formula", image: "picture", html: "HTML",
|
|
643
|
+
callout: "callout", toggle: "disclosure", divider: "divider", flow: "flow", header: "heading", sub_header: "heading", sub_sub_header: "heading", header_4: "heading",
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* A quote of a whole document, its lines without their > (`base`: the number of its first line in
|
|
648
|
+
* the lines read): GitHub's alert a callout; else what they read as, its paragraphs a quote (the
|
|
649
|
+
* kit's holds paragraphs alone, a quote in it its paragraphs too) and its other blocks standing
|
|
650
|
+
* where they are, out of it (the paragraphs after one a quote again; a heading starting no section:
|
|
651
|
+
* props.boxed), noted. Returns its blocks.
|
|
652
|
+
*/
|
|
653
|
+
function documentQuote(body, doc, base) {
|
|
654
|
+
const first = body.findIndex((line) => line.trim());
|
|
655
|
+
const alert = first < 0 ? null : /^\[!(note|tip|important|warning|caution)\]\s*$/i.exec(body[first].trim());
|
|
656
|
+
if (alert) {
|
|
657
|
+
const blocks = parseLines(body.slice(first + 1), doc, base + first + 1);
|
|
658
|
+
return [spec("callout", [], { icon: ALERTS[alert[1].toLowerCase()] }, blocks.length ? blocks : [spec("text")])];
|
|
659
|
+
}
|
|
660
|
+
const inner = parseLines(body, doc, base);
|
|
661
|
+
if (!inner.length) return [spec("quote")];
|
|
662
|
+
const paragraphs = (s) => (s.type === "quote" ? [spec("text", s.title), ...s.children.flatMap(paragraphs)] : [s]);
|
|
663
|
+
const out = [];
|
|
664
|
+
const outside = new Set();
|
|
665
|
+
let run = null;
|
|
666
|
+
for (const s of inner.flatMap(paragraphs)) {
|
|
667
|
+
if (s.type === "text" && !s.children.length) {
|
|
668
|
+
if (run) run.push(s);
|
|
669
|
+
else out.push(run = [s]);
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
672
|
+
run = null;
|
|
673
|
+
if (/header/.test(s.type)) s.props.boxed = true;
|
|
674
|
+
outside.add(KINDS[s.type] ?? "block");
|
|
675
|
+
out.push(s);
|
|
676
|
+
}
|
|
677
|
+
if (outside.size) doc.notes.push({ line: doc.firstLine + base, kind: "quote", text: `a quote holds paragraphs alone: its ${[...outside].join(", ")} kept in place, out of it` });
|
|
678
|
+
return out.map((each) => (Array.isArray(each) ? spec("quote", each[0].title, {}, each.slice(1)) : each));
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// Link and footnote definitions, taken out of a document's lines (each emptied, so that the lines
|
|
682
|
+
// keep their numbers) before it is read, as a viewer reads them wherever they stand. Code is left alone.
|
|
683
|
+
function takeDefinitions(lines, doc) {
|
|
684
|
+
let fence = null;
|
|
685
|
+
for (let i = 0; i < lines.length; i++) {
|
|
686
|
+
const line = lines[i].trim();
|
|
687
|
+
const open = /^(`{3,}|~{3,})/.exec(line);
|
|
688
|
+
if (fence) {
|
|
689
|
+
if (open && line[0] === fence[0] && open[1].length >= fence.length && /^(`+|~+)$/.test(line)) fence = null;
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
692
|
+
if (open) {
|
|
693
|
+
fence = open[1];
|
|
694
|
+
continue;
|
|
695
|
+
}
|
|
696
|
+
if (indentOf(lines[i]) > 3) continue;
|
|
697
|
+
let m;
|
|
698
|
+
if ((m = FOOTNOTE_DEFINITION.exec(line))) {
|
|
699
|
+
// Its first line, the lines that go on with it, and paragraphs after an empty line 4 spaces in.
|
|
700
|
+
const start = i;
|
|
701
|
+
const paragraphs = [[m[2]]];
|
|
702
|
+
lines[i] = "";
|
|
703
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
704
|
+
const next = lines[j];
|
|
705
|
+
if (!next.trim()) {
|
|
706
|
+
const ahead = lines.slice(j + 1).findIndex((each) => each.trim());
|
|
707
|
+
if (ahead < 0 || indentOf(lines[j + 1 + ahead]) < 4) break;
|
|
708
|
+
paragraphs.push([]);
|
|
709
|
+
continue;
|
|
710
|
+
}
|
|
711
|
+
if (indentOf(next) < 2 && (startsBlock(next.trim()) || paragraphs.length > 1)) break;
|
|
712
|
+
paragraphs.at(-1).push(next);
|
|
713
|
+
lines[j] = "";
|
|
714
|
+
i = j;
|
|
715
|
+
}
|
|
716
|
+
const key = m[1].toLowerCase();
|
|
717
|
+
if (!doc.definitions.has(key)) doc.definitions.set(key, { line: doc.firstLine + start, text: paragraphs.filter((each) => each.length).map(joinLines).join("\n"), number: 0 });
|
|
718
|
+
} else if ((m = LINK_DEFINITION.exec(line)) && /^<|[./:#]/.test(m[2])) {
|
|
719
|
+
const label = m[1].trim().replace(/\s+/g, " ").toLowerCase();
|
|
720
|
+
if (!doc.refs.has(label)) doc.refs.set(label, { href: m[2].replace(/^<|>$/g, ""), title: m[3] ? m[3].slice(1, -1) : "" });
|
|
721
|
+
lines[i] = "";
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* A whole Markdown document (the import's) as block specs, read as a Markdown viewer shows it (the
|
|
728
|
+
* header of this file says what that adds to a paste's rules): { specs, footnotes: [{ number,
|
|
729
|
+
* title }] (in order), notes: [{ line, kind, text }], formulas: [{ tex, line, display }] (each
|
|
730
|
+
* formula read, for the import to try), links: [{ href, line }] (each link to an address that is no
|
|
731
|
+
* web one: a file beside it, a place in it) }. `firstLine`: the number of its first line in its file
|
|
732
|
+
* (after a front matter the import took off).
|
|
733
|
+
*/
|
|
734
|
+
export function readMarkdownDocument(text, { firstLine = 1 } = {}) {
|
|
735
|
+
const lines = text.replace(/\r\n?/g, "\n").split("\n");
|
|
736
|
+
const doc = { firstLine, refs: new Map(), definitions: new Map(), order: [], notes: [], formulas: [], links: [], at: firstLine };
|
|
737
|
+
doc.footnote = (label) => {
|
|
738
|
+
const definition = doc.definitions.get(label.toLowerCase());
|
|
739
|
+
if (!definition) {
|
|
740
|
+
doc.notes.push({ line: doc.at, kind: "footnote", text: `the footnote [^${label}] has no definition, kept as text` });
|
|
741
|
+
return null;
|
|
742
|
+
}
|
|
743
|
+
if (!definition.number) {
|
|
744
|
+
definition.number = doc.order.length + 1;
|
|
745
|
+
doc.order.push(definition);
|
|
746
|
+
}
|
|
747
|
+
return definition.number;
|
|
748
|
+
};
|
|
749
|
+
takeDefinitions(lines, doc);
|
|
750
|
+
const specs = parseLines(lines, doc);
|
|
751
|
+
// Each note's text, read in turn (one may refer to another, numbered then), then those never referred to.
|
|
752
|
+
for (let index = 0; index < doc.order.length; index++) doc.order[index].title = textOnly(docInline(doc, doc.order[index].text, doc.order[index].line), doc.order[index].line, doc);
|
|
753
|
+
for (const definition of doc.definitions.values()) {
|
|
754
|
+
if (definition.number) continue;
|
|
755
|
+
definition.number = doc.order.length + 1;
|
|
756
|
+
doc.order.push(definition);
|
|
757
|
+
definition.title = textOnly(docInline(doc, definition.text, definition.line), definition.line, doc);
|
|
758
|
+
}
|
|
759
|
+
return { specs, footnotes: doc.order.map(({ number, title }) => ({ number, title })), notes: doc.notes.sort((a, b) => a.line - b.line), formulas: doc.formulas, links: doc.links };
|
|
760
|
+
}
|