@bendyline/squisq 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE.md +24 -0
- package/dist/{ContentContainer-BXUlIf18.d.ts → ContentContainer-B2w9sUoL.d.ts} +15 -0
- package/dist/{Doc-DynJleo-.d.ts → Doc-BubIpWsp.d.ts} +1 -1
- package/dist/{ImageEditDoc-Ca4Tr9uN.d.ts → ImageEditDoc-CGxk5CHc.d.ts} +1 -1
- package/dist/{annotationCoercion-Dr_DY9Hx.d.ts → annotationCoercion-PtRQhk5V.d.ts} +1 -1
- package/dist/chunk-2L55443L.js +0 -0
- package/dist/{chunk-VWCJ2WXC.js → chunk-2ZWIXGAC.js} +0 -1
- package/dist/{chunk-VYFRI7R6.js → chunk-32R2RZAO.js} +72 -3
- package/dist/chunk-3IGPAPQ7.js +645 -0
- package/dist/{chunk-QE7TWGVT.js → chunk-4VOD55SX.js} +0 -1
- package/dist/{chunk-3E5F2XMR.js → chunk-67L6WRJN.js} +0 -1
- package/dist/{chunk-5DKBFXPY.js → chunk-6ECMNUIP.js} +26 -18
- package/dist/{chunk-JI77MGAK.js → chunk-7ARJZYQY.js} +159 -120
- package/dist/{chunk-DBS6RIFL.js → chunk-7N4G32LG.js} +0 -1
- package/dist/{chunk-JOQYPRDZ.js → chunk-7YEZFHLS.js} +10 -8
- package/dist/{chunk-2UQOHYE2.js → chunk-7ZAAICW4.js} +0 -1
- package/dist/{chunk-66QO7XFB.js → chunk-ACZOVWX3.js} +117 -7
- package/dist/{chunk-5J4HKRJF.js → chunk-BAOV476U.js} +0 -1
- package/dist/chunk-BCCXTMN5.js +699 -0
- package/dist/{chunk-JHZWYRSW.js → chunk-C33GTPUZ.js} +11 -4
- package/dist/{chunk-QUUPYOSP.js → chunk-CB45YGAM.js} +2 -3
- package/dist/{chunk-XNLB57UD.js → chunk-DYPMOPIW.js} +18 -2
- package/dist/{chunk-VR7UPJ7C.js → chunk-FCG3BIZN.js} +12 -1
- package/dist/{chunk-5UYI3RJB.js → chunk-FDYDYL77.js} +54 -40
- package/dist/{chunk-OTKVFVL6.js → chunk-I2O6W7DX.js} +116 -44
- package/dist/{chunk-Q7LROV2H.js → chunk-NKNMGIIN.js} +0 -1
- package/dist/chunk-OPO5K4DZ.js +241 -0
- package/dist/{chunk-TUWMK62B.js → chunk-PUS54YU6.js} +45 -2
- package/dist/chunk-QKPXHDLR.js +0 -0
- package/dist/{chunk-GZY66SDN.js → chunk-R3KTTOMS.js} +0 -1
- package/dist/{chunk-ILWDXLUK.js → chunk-RS5AP3J4.js} +49 -10
- package/dist/chunk-WV5ARNDA.js +0 -0
- package/dist/{chunk-4X3JQXNM.js → chunk-XOFT65EX.js} +1 -2
- package/dist/{chunk-FVTQSNR7.js → chunk-XRW6P7IF.js} +13 -5
- package/dist/chunk-XWNNA3KE.js +0 -0
- package/dist/chunk-YZNGMV3G.js +0 -0
- package/dist/{chunk-R2YZTCLO.js → chunk-ZQKZSJAX.js} +1 -2
- package/dist/doc/index.d.ts +27 -12
- package/dist/doc/index.js +16 -17
- package/dist/generate/index.d.ts +2 -2
- package/dist/generate/index.js +2 -3
- package/dist/icons/index.js +3 -4
- package/dist/icons/inlineIconMarker.js +1 -2
- package/dist/imageEdit/index.d.ts +48 -17
- package/dist/imageEdit/index.js +3 -4
- package/dist/index.d.ts +11 -11
- package/dist/index.js +60 -33
- package/dist/jsonForm/index.d.ts +10 -3
- package/dist/jsonForm/index.js +8 -7
- package/dist/markdown/index.d.ts +75 -11
- package/dist/markdown/index.js +32 -7
- package/dist/{materializePageSection-DDzubQXo.d.ts → materializePageSection-wSLA2A1g.d.ts} +2 -2
- package/dist/narration/index.d.ts +16 -3
- package/dist/narration/index.js +13 -14
- package/dist/random/index.d.ts +11 -2
- package/dist/random/index.js +2 -3
- package/dist/recommend/index.d.ts +1 -1
- package/dist/recommend/index.js +3 -4
- package/dist/schemas/index.d.ts +5 -5
- package/dist/schemas/index.js +5 -6
- package/dist/spatial/index.d.ts +2 -1
- package/dist/spatial/index.js +1 -2
- package/dist/storage/index.d.ts +4 -2
- package/dist/storage/index.js +1 -2
- package/dist/{themeLibrary-B72m0W1y.d.ts → themeLibrary-DU9mUmVl.d.ts} +1 -1
- package/dist/timing/index.js +3 -4
- package/dist/transform/index.d.ts +3 -3
- package/dist/transform/index.js +6 -7
- package/dist/{types-C4kiRn_k.d.ts → types-8QjefM9J.d.ts} +38 -2
- package/dist/{types-BwMPl2CB.d.ts → types-CUNc9biN.d.ts} +24 -1
- package/dist/versions/index.d.ts +14 -11
- package/dist/versions/index.js +2 -3
- package/package.json +4 -2
- package/dist/chunk-2UQOHYE2.js.map +0 -1
- package/dist/chunk-3E5F2XMR.js.map +0 -1
- package/dist/chunk-4X3JQXNM.js.map +0 -1
- package/dist/chunk-5DKBFXPY.js.map +0 -1
- package/dist/chunk-5J4HKRJF.js.map +0 -1
- package/dist/chunk-5UYI3RJB.js.map +0 -1
- package/dist/chunk-66QO7XFB.js.map +0 -1
- package/dist/chunk-AMIR72JP.js +0 -380
- package/dist/chunk-AMIR72JP.js.map +0 -1
- package/dist/chunk-DBS6RIFL.js.map +0 -1
- package/dist/chunk-DNJKBAI7.js +0 -1
- package/dist/chunk-DNJKBAI7.js.map +0 -1
- package/dist/chunk-ET53IIEP.js +0 -1
- package/dist/chunk-ET53IIEP.js.map +0 -1
- package/dist/chunk-FVTQSNR7.js.map +0 -1
- package/dist/chunk-GZY66SDN.js.map +0 -1
- package/dist/chunk-ILWDXLUK.js.map +0 -1
- package/dist/chunk-JHZWYRSW.js.map +0 -1
- package/dist/chunk-JI77MGAK.js.map +0 -1
- package/dist/chunk-JOQYPRDZ.js.map +0 -1
- package/dist/chunk-OTKVFVL6.js.map +0 -1
- package/dist/chunk-PGGGKYWG.js +0 -1
- package/dist/chunk-PGGGKYWG.js.map +0 -1
- package/dist/chunk-Q7LROV2H.js.map +0 -1
- package/dist/chunk-QE7TWGVT.js.map +0 -1
- package/dist/chunk-QUUPYOSP.js.map +0 -1
- package/dist/chunk-R2GC6RLD.js +0 -344
- package/dist/chunk-R2GC6RLD.js.map +0 -1
- package/dist/chunk-R2YZTCLO.js.map +0 -1
- package/dist/chunk-S7A5D7ZJ.js +0 -174
- package/dist/chunk-S7A5D7ZJ.js.map +0 -1
- package/dist/chunk-TUWMK62B.js.map +0 -1
- package/dist/chunk-V543AI2F.js +0 -1
- package/dist/chunk-V543AI2F.js.map +0 -1
- package/dist/chunk-VR7UPJ7C.js.map +0 -1
- package/dist/chunk-VWCJ2WXC.js.map +0 -1
- package/dist/chunk-VYFRI7R6.js.map +0 -1
- package/dist/chunk-XNLB57UD.js.map +0 -1
- package/dist/chunk-ZLQKNOZQ.js +0 -1
- package/dist/chunk-ZLQKNOZQ.js.map +0 -1
- package/dist/doc/index.js.map +0 -1
- package/dist/generate/index.js.map +0 -1
- package/dist/icons/index.js.map +0 -1
- package/dist/icons/inlineIconMarker.js.map +0 -1
- package/dist/imageEdit/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jsonForm/index.js.map +0 -1
- package/dist/markdown/index.js.map +0 -1
- package/dist/narration/index.js.map +0 -1
- package/dist/random/index.js.map +0 -1
- package/dist/recommend/index.js.map +0 -1
- package/dist/schemas/index.js.map +0 -1
- package/dist/spatial/index.js.map +0 -1
- package/dist/storage/index.js.map +0 -1
- package/dist/timing/index.js.map +0 -1
- package/dist/transform/index.js.map +0 -1
- package/dist/versions/index.js.map +0 -1
- package/src/__tests__/animationUtils.test.ts +0 -117
- package/src/__tests__/annotationCoercion.test.ts +0 -243
- package/src/__tests__/applyNarrationTiming.test.ts +0 -190
- package/src/__tests__/applyRenderStyle.test.ts +0 -146
- package/src/__tests__/asciiDiagramBattle.test.ts +0 -246
- package/src/__tests__/asciiDiagramDetect.test.ts +0 -162
- package/src/__tests__/asciiDiagramMapping.test.ts +0 -38
- package/src/__tests__/asciiDiagramParse.test.ts +0 -233
- package/src/__tests__/asciiDiagramPipeline.test.ts +0 -273
- package/src/__tests__/asciiDiagramRender.test.ts +0 -162
- package/src/__tests__/asciiDiagramRepair.test.ts +0 -84
- package/src/__tests__/asciiTimelineDetect.test.ts +0 -157
- package/src/__tests__/asciiTimelineParse.test.ts +0 -205
- package/src/__tests__/asciiTimelinePipeline.test.ts +0 -349
- package/src/__tests__/asciiTimelineRender.test.ts +0 -376
- package/src/__tests__/atmosphereLayers.test.ts +0 -108
- package/src/__tests__/attrTokens.test.ts +0 -167
- package/src/__tests__/colorUtils.test.ts +0 -112
- package/src/__tests__/contentContainer.test.ts +0 -325
- package/src/__tests__/contentExtractor.test.ts +0 -243
- package/src/__tests__/coverBlock.test.ts +0 -310
- package/src/__tests__/customTemplateSample.test.ts +0 -144
- package/src/__tests__/customTemplatesFrontmatter.test.ts +0 -221
- package/src/__tests__/customThemesFrontmatter.test.ts +0 -146
- package/src/__tests__/dataTable.test.ts +0 -145
- package/src/__tests__/diagramBlock.test.ts +0 -122
- package/src/__tests__/diagramLayout.test.ts +0 -134
- package/src/__tests__/diagramText.test.ts +0 -26
- package/src/__tests__/docToMarkdownMedia.test.ts +0 -83
- package/src/__tests__/drawing.test.ts +0 -109
- package/src/__tests__/drawingBlock.test.ts +0 -124
- package/src/__tests__/drawingLayout.test.ts +0 -171
- package/src/__tests__/fixtures/asciiDiagramBattle.ts +0 -512
- package/src/__tests__/fixtures/asciiDiagrams.ts +0 -287
- package/src/__tests__/fixtures/asciiTimelines.ts +0 -35
- package/src/__tests__/fixtures/treeviewFixtures.ts +0 -243
- package/src/__tests__/geohash.test.ts +0 -110
- package/src/__tests__/getLayers.test.ts +0 -243
- package/src/__tests__/getLayersFallback.test.ts +0 -103
- package/src/__tests__/haversine.test.ts +0 -63
- package/src/__tests__/iconResolve.test.ts +0 -122
- package/src/__tests__/imageEditExportSvg.test.ts +0 -70
- package/src/__tests__/imageEditState.test.ts +0 -74
- package/src/__tests__/imageEditVersions.test.ts +0 -243
- package/src/__tests__/inferDocumentTitle.test.ts +0 -50
- package/src/__tests__/inlineIconMarker.test.ts +0 -36
- package/src/__tests__/inputDescriptors.test.ts +0 -162
- package/src/__tests__/jsonForm.chooseControl.test.ts +0 -86
- package/src/__tests__/jsonForm.evaluateWhen.test.ts +0 -59
- package/src/__tests__/jsonForm.inferSchema.test.ts +0 -25
- package/src/__tests__/jsonForm.pointer.test.ts +0 -149
- package/src/__tests__/jsonForm.tokens.test.ts +0 -84
- package/src/__tests__/layoutBlock.test.ts +0 -83
- package/src/__tests__/layoutLayout.test.ts +0 -169
- package/src/__tests__/localForageAdapter.test.ts +0 -155
- package/src/__tests__/majorApiTypes.test.ts +0 -18
- package/src/__tests__/markdown.test.ts +0 -1009
- package/src/__tests__/markdownIcons.test.ts +0 -104
- package/src/__tests__/markdownSanitize.test.ts +0 -81
- package/src/__tests__/markdownToDoc.test.ts +0 -957
- package/src/__tests__/matchFontFamily.test.ts +0 -114
- package/src/__tests__/materializeBlockLayers.test.ts +0 -167
- package/src/__tests__/materializePageSections.test.ts +0 -404
- package/src/__tests__/materializeTestUtils.ts +0 -17
- package/src/__tests__/mediaAnnotations.test.ts +0 -91
- package/src/__tests__/mediaSchedule.test.ts +0 -118
- package/src/__tests__/narrationAlign.test.ts +0 -150
- package/src/__tests__/narrationFeatures.test.ts +0 -71
- package/src/__tests__/narrationNuclei.test.ts +0 -45
- package/src/__tests__/narrationPacing.test.ts +0 -189
- package/src/__tests__/narrationScript.test.ts +0 -149
- package/src/__tests__/narrationSessionRepro.test.ts +0 -62
- package/src/__tests__/narrationSidecar.test.ts +0 -88
- package/src/__tests__/narrationSyllables.test.ts +0 -65
- package/src/__tests__/narrationTestSignals.ts +0 -167
- package/src/__tests__/narrationVad.test.ts +0 -66
- package/src/__tests__/pageStyle.test.ts +0 -258
- package/src/__tests__/pandocAttrParse.test.ts +0 -187
- package/src/__tests__/recommendTemplates.test.ts +0 -183
- package/src/__tests__/resolveDocTheme.test.ts +0 -69
- package/src/__tests__/rootExports.test.ts +0 -61
- package/src/__tests__/scopedContentContainer.test.ts +0 -109
- package/src/__tests__/seededRandom.test.ts +0 -142
- package/src/__tests__/shapeGeometry.test.ts +0 -138
- package/src/__tests__/shapeVocabulary.test.ts +0 -133
- package/src/__tests__/storage.test.ts +0 -60
- package/src/__tests__/structuredData.test.ts +0 -249
- package/src/__tests__/surface.test.ts +0 -68
- package/src/__tests__/templateAnnotationParse.test.ts +0 -173
- package/src/__tests__/templateInputs.test.ts +0 -69
- package/src/__tests__/templateMetadata.test.ts +0 -32
- package/src/__tests__/templates.test.ts +0 -710
- package/src/__tests__/themeCompile.test.ts +0 -225
- package/src/__tests__/themeValidator.test.ts +0 -131
- package/src/__tests__/timing.test.ts +0 -167
- package/src/__tests__/transformProvenance.test.ts +0 -160
- package/src/__tests__/transformV2.test.ts +0 -163
- package/src/__tests__/transitionNormalize.test.ts +0 -61
- package/src/__tests__/treeviewBattle.test.ts +0 -76
- package/src/__tests__/treeviewDetect.test.ts +0 -168
- package/src/__tests__/treeviewParse.test.ts +0 -118
- package/src/__tests__/treeviewPipeline.test.ts +0 -183
- package/src/__tests__/treeviewRender.test.ts +0 -91
- package/src/__tests__/validateDoc.test.ts +0 -260
- package/src/__tests__/versions.test.ts +0 -459
- package/src/doc/annotationBlocks.ts +0 -117
- package/src/doc/applyNarrationTiming.ts +0 -244
- package/src/doc/asciiDiagram/chars.ts +0 -210
- package/src/doc/asciiDiagram/detect.ts +0 -175
- package/src/doc/asciiDiagram/index.ts +0 -38
- package/src/doc/asciiDiagram/mapping.ts +0 -225
- package/src/doc/asciiDiagram/parse.ts +0 -1095
- package/src/doc/asciiDiagram/render.ts +0 -963
- package/src/doc/asciiDiagram/repair.ts +0 -400
- package/src/doc/asciiDiagram/types.ts +0 -65
- package/src/doc/asciiTimeline/detect.ts +0 -138
- package/src/doc/asciiTimeline/index.ts +0 -26
- package/src/doc/asciiTimeline/mapping.ts +0 -43
- package/src/doc/asciiTimeline/parse.ts +0 -870
- package/src/doc/asciiTimeline/render.ts +0 -427
- package/src/doc/asciiTimeline/types.ts +0 -73
- package/src/doc/asciiTimeline/wrappedFlow.ts +0 -427
- package/src/doc/audioMapping.ts +0 -442
- package/src/doc/customTemplatesFrontmatter.ts +0 -273
- package/src/doc/customThemesFrontmatter.ts +0 -95
- package/src/doc/docToMarkdown.ts +0 -284
- package/src/doc/index.ts +0 -161
- package/src/doc/markdownToDoc.ts +0 -1054
- package/src/doc/materializeBlockLayers.ts +0 -465
- package/src/doc/mediaAnnotations.ts +0 -120
- package/src/doc/page/PageSection.ts +0 -174
- package/src/doc/page/materializePageSection.ts +0 -616
- package/src/doc/page/resolvePageBlock.ts +0 -108
- package/src/doc/page/sectionExtractors.ts +0 -466
- package/src/doc/pageCss.ts +0 -628
- package/src/doc/resolveDocTheme.ts +0 -56
- package/src/doc/standaloneAnnotation.ts +0 -58
- package/src/doc/structuredData.ts +0 -301
- package/src/doc/templateInputs.ts +0 -424
- package/src/doc/templates/__tests__/customTemplate.test.ts +0 -170
- package/src/doc/templates/__tests__/customTemplateRegistry.test.ts +0 -124
- package/src/doc/templates/__tests__/listBlock.test.ts +0 -64
- package/src/doc/templates/accentImage.ts +0 -362
- package/src/doc/templates/captionUtils.ts +0 -56
- package/src/doc/templates/comparisonBar.ts +0 -173
- package/src/doc/templates/coverBlock.ts +0 -255
- package/src/doc/templates/customTemplate.ts +0 -51
- package/src/doc/templates/dataTable.ts +0 -102
- package/src/doc/templates/dateEvent.ts +0 -147
- package/src/doc/templates/definitionCard.ts +0 -140
- package/src/doc/templates/diagramBlock.ts +0 -403
- package/src/doc/templates/diagramLayout.ts +0 -159
- package/src/doc/templates/drawingBlock.ts +0 -325
- package/src/doc/templates/drawingLayout.ts +0 -539
- package/src/doc/templates/factCard.ts +0 -146
- package/src/doc/templates/fallbackBlock.ts +0 -123
- package/src/doc/templates/featureBlock.ts +0 -209
- package/src/doc/templates/fullBleedQuote.ts +0 -83
- package/src/doc/templates/imageWithCaption.ts +0 -186
- package/src/doc/templates/index.ts +0 -642
- package/src/doc/templates/inputDescriptors.ts +0 -451
- package/src/doc/templates/layoutBlock.ts +0 -43
- package/src/doc/templates/layoutLayout.ts +0 -243
- package/src/doc/templates/listBlock.ts +0 -207
- package/src/doc/templates/mapBlock.ts +0 -138
- package/src/doc/templates/metadata.ts +0 -130
- package/src/doc/templates/persistentLayers.ts +0 -526
- package/src/doc/templates/photoGrid.ts +0 -190
- package/src/doc/templates/pullQuote.ts +0 -141
- package/src/doc/templates/quoteBlock.ts +0 -141
- package/src/doc/templates/registry.ts +0 -88
- package/src/doc/templates/sectionHeader.ts +0 -120
- package/src/doc/templates/statHighlight.ts +0 -146
- package/src/doc/templates/templateNames.ts +0 -22
- package/src/doc/templates/timelineBlock.ts +0 -613
- package/src/doc/templates/titleBlock.ts +0 -150
- package/src/doc/templates/tokens/__tests__/resolveTokens.test.ts +0 -487
- package/src/doc/templates/tokens/resolveTokens.ts +0 -453
- package/src/doc/templates/treeBlock.ts +0 -131
- package/src/doc/templates/twoColumn.ts +0 -263
- package/src/doc/templates/videoPullQuote.ts +0 -142
- package/src/doc/templates/videoWithCaption.ts +0 -135
- package/src/doc/treeview/chars.ts +0 -72
- package/src/doc/treeview/detect.ts +0 -145
- package/src/doc/treeview/index.ts +0 -30
- package/src/doc/treeview/mapping.ts +0 -95
- package/src/doc/treeview/parse.ts +0 -201
- package/src/doc/treeview/render.ts +0 -41
- package/src/doc/treeview/types.ts +0 -43
- package/src/doc/utils/animationUtils.ts +0 -399
- package/src/doc/utils/applyRenderStyle.ts +0 -106
- package/src/doc/utils/diagramText.ts +0 -78
- package/src/doc/utils/imageTreatment.ts +0 -70
- package/src/doc/utils/nearest.ts +0 -59
- package/src/doc/utils/shapeGeometry.ts +0 -614
- package/src/doc/utils/themeUtils.ts +0 -243
- package/src/doc/validate.ts +0 -575
- package/src/generate/contentExtractor.ts +0 -921
- package/src/generate/index.ts +0 -18
- package/src/generate/templateMapper.ts +0 -177
- package/src/icons/iconData.ts +0 -31
- package/src/icons/index.ts +0 -26
- package/src/icons/inlineIconMarker.ts +0 -73
- package/src/icons/resolve.ts +0 -139
- package/src/imageEdit/ImageEditVersionManager.ts +0 -73
- package/src/imageEdit/export.ts +0 -410
- package/src/imageEdit/index.ts +0 -72
- package/src/imageEdit/persistence.ts +0 -113
- package/src/imageEdit/state.ts +0 -112
- package/src/imageEdit/versionPaths.ts +0 -44
- package/src/imageEdit/versions.ts +0 -152
- package/src/index.ts +0 -15
- package/src/internal/immutable.ts +0 -58
- package/src/jsonForm/chooseControl.ts +0 -88
- package/src/jsonForm/evaluateWhen.ts +0 -59
- package/src/jsonForm/index.ts +0 -32
- package/src/jsonForm/inferSchema.ts +0 -25
- package/src/jsonForm/pointer.ts +0 -154
- package/src/jsonForm/tokens.ts +0 -78
- package/src/jsonForm/types.ts +0 -167
- package/src/markdown/annotationCoercion.ts +0 -295
- package/src/markdown/attrTokens.ts +0 -243
- package/src/markdown/convert.ts +0 -1353
- package/src/markdown/htmlParse.ts +0 -212
- package/src/markdown/index.ts +0 -152
- package/src/markdown/parse.ts +0 -103
- package/src/markdown/sanitize.ts +0 -318
- package/src/markdown/stringify.ts +0 -207
- package/src/markdown/types.ts +0 -710
- package/src/markdown/utils.ts +0 -459
- package/src/narration/align.ts +0 -514
- package/src/narration/features.ts +0 -231
- package/src/narration/index.ts +0 -86
- package/src/narration/nuclei.ts +0 -118
- package/src/narration/pacing.ts +0 -211
- package/src/narration/script.ts +0 -239
- package/src/narration/session.ts +0 -100
- package/src/narration/sidecar.ts +0 -187
- package/src/narration/syllables.ts +0 -85
- package/src/narration/trace.ts +0 -50
- package/src/narration/types.ts +0 -299
- package/src/narration/vad.ts +0 -131
- package/src/ngeohash.d.ts +0 -11
- package/src/random/SeededRandom.ts +0 -127
- package/src/random/index.ts +0 -1
- package/src/recommend/index.ts +0 -16
- package/src/recommend/numberHighlight.ts +0 -25
- package/src/recommend/templates.ts +0 -393
- package/src/schemas/BlockTemplates.ts +0 -1046
- package/src/schemas/CustomTemplates.ts +0 -126
- package/src/schemas/Doc.ts +0 -1073
- package/src/schemas/ImageEditDoc.ts +0 -102
- package/src/schemas/LayoutStrategy.ts +0 -178
- package/src/schemas/Media.ts +0 -179
- package/src/schemas/MediaProvider.ts +0 -70
- package/src/schemas/PageStyle.ts +0 -213
- package/src/schemas/Theme.ts +0 -413
- package/src/schemas/Transitions.ts +0 -224
- package/src/schemas/Types.ts +0 -15
- package/src/schemas/Viewport.ts +0 -91
- package/src/schemas/colorUtils.ts +0 -219
- package/src/schemas/fontStacks.ts +0 -339
- package/src/schemas/index.ts +0 -31
- package/src/schemas/pageStyleDefaults.ts +0 -204
- package/src/schemas/themeCompile.ts +0 -244
- package/src/schemas/themeConstants.ts +0 -2
- package/src/schemas/themeLibrary.ts +0 -60
- package/src/schemas/themeValidator.ts +0 -609
- package/src/schemas/themes/bold.json +0 -77
- package/src/schemas/themes/cinematic.json +0 -143
- package/src/schemas/themes/documentary.json +0 -125
- package/src/schemas/themes/gezellig.json +0 -123
- package/src/schemas/themes/index.ts +0 -53
- package/src/schemas/themes/magazine.json +0 -126
- package/src/schemas/themes/minimalist.json +0 -74
- package/src/schemas/themes/morning-light.json +0 -117
- package/src/schemas/themes/standard-dark.json +0 -109
- package/src/schemas/themes/standard.json +0 -98
- package/src/schemas/themes/tech-dark.json +0 -143
- package/src/schemas/themes/warm-earth.json +0 -74
- package/src/spatial/Geohash.ts +0 -196
- package/src/spatial/Haversine.ts +0 -59
- package/src/spatial/index.ts +0 -2
- package/src/storage/ContentContainer.ts +0 -220
- package/src/storage/LocalForageAdapter.ts +0 -103
- package/src/storage/LocalStorageAdapter.ts +0 -57
- package/src/storage/MediaProviderFromContainer.ts +0 -92
- package/src/storage/MemoryStorageAdapter.ts +0 -37
- package/src/storage/ScopedContentContainer.ts +0 -143
- package/src/storage/Storage.ts +0 -28
- package/src/storage/index.ts +0 -9
- package/src/timing/index.ts +0 -17
- package/src/timing/narrationTiming.ts +0 -220
- package/src/timing/readingTime.ts +0 -94
- package/src/transform/applyTransform.ts +0 -122
- package/src/transform/blockAnalyzer.ts +0 -181
- package/src/transform/index.ts +0 -23
- package/src/transform/registry.ts +0 -217
- package/src/transform/styles/dataDriven.ts +0 -18
- package/src/transform/styles/documentary.ts +0 -18
- package/src/transform/styles/index.ts +0 -5
- package/src/transform/styles/magazine.ts +0 -19
- package/src/transform/styles/minimal.ts +0 -18
- package/src/transform/styles/narrative.ts +0 -19
- package/src/transform/templateSelector.ts +0 -389
- package/src/transform/timingAllocator.ts +0 -257
- package/src/transform/types.ts +0 -158
- package/src/versions/DocumentVersionManager.ts +0 -70
- package/src/versions/gitignore.ts +0 -34
- package/src/versions/index.ts +0 -56
- package/src/versions/operations.ts +0 -144
- package/src/versions/paths.ts +0 -51
- package/src/versions/snapshotStore.ts +0 -202
- package/src/versions/timestamp.ts +0 -48
- package/src/versions/types.ts +0 -93
package/src/markdown/utils.ts
DELETED
|
@@ -1,459 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Markdown Tree Utilities
|
|
3
|
-
*
|
|
4
|
-
* Helper functions for traversing and querying the MarkdownDocument tree.
|
|
5
|
-
* All functions are pure and operate on the JSON node interfaces.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { MarkdownNode, MarkdownDocument, HtmlNode } from './types.js';
|
|
9
|
-
import { parseHtmlToNodes } from './htmlParse.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Get the children of any markdown node, if it has children.
|
|
13
|
-
* Returns an empty array for leaf nodes (text, code, break, etc.).
|
|
14
|
-
*
|
|
15
|
-
* This is useful for generic tree walking where you don't want to
|
|
16
|
-
* check the specific node type.
|
|
17
|
-
*/
|
|
18
|
-
export function getChildren(node: MarkdownNode): MarkdownNode[] {
|
|
19
|
-
if ('children' in node && Array.isArray(node.children)) {
|
|
20
|
-
return node.children as MarkdownNode[];
|
|
21
|
-
}
|
|
22
|
-
return [];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Walk the markdown tree depth-first, calling the visitor for each node.
|
|
27
|
-
*
|
|
28
|
-
* The visitor receives the current node and its parent. Return `true`
|
|
29
|
-
* from the visitor to skip the node's children (prune).
|
|
30
|
-
*
|
|
31
|
-
* @param node - The root node to start walking from
|
|
32
|
-
* @param visitor - Called for each node; return true to skip children
|
|
33
|
-
* @param parent - (internal) Parent node
|
|
34
|
-
*/
|
|
35
|
-
export function walkMarkdownTree(
|
|
36
|
-
node: MarkdownNode,
|
|
37
|
-
visitor: (node: MarkdownNode, parent?: MarkdownNode) => void | boolean,
|
|
38
|
-
parent?: MarkdownNode,
|
|
39
|
-
): void {
|
|
40
|
-
const skip = visitor(node, parent);
|
|
41
|
-
if (skip === true) return;
|
|
42
|
-
|
|
43
|
-
const children = getChildren(node);
|
|
44
|
-
for (const child of children) {
|
|
45
|
-
walkMarkdownTree(child, visitor, node);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Find all nodes of a specific type in the tree.
|
|
51
|
-
*
|
|
52
|
-
* @param root - The document or node to search within
|
|
53
|
-
* @param type - The node type to find (e.g., 'heading', 'link', 'text')
|
|
54
|
-
* @returns Array of matching nodes
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```ts
|
|
58
|
-
* const headings = findNodesByType(doc, 'heading');
|
|
59
|
-
* const links = findNodesByType(doc, 'link');
|
|
60
|
-
* ```
|
|
61
|
-
*/
|
|
62
|
-
export function findNodesByType<T extends MarkdownNode>(root: MarkdownNode, type: T['type']): T[] {
|
|
63
|
-
const results: T[] = [];
|
|
64
|
-
walkMarkdownTree(root, (node) => {
|
|
65
|
-
if (node.type === type) {
|
|
66
|
-
results.push(node as T);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
return results;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Extract all plain text content from a node and its descendants.
|
|
74
|
-
* Concatenates text values, ignoring formatting, links, etc.
|
|
75
|
-
*
|
|
76
|
-
* @param node - The node to extract text from
|
|
77
|
-
* @returns Plain text content
|
|
78
|
-
*
|
|
79
|
-
* @example
|
|
80
|
-
* ```ts
|
|
81
|
-
* const heading = doc.children[0]; // { type: 'heading', children: [{ type: 'text', value: 'Hello' }] }
|
|
82
|
-
* extractPlainText(heading); // 'Hello'
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
|
-
export function extractPlainText(node: MarkdownNode): string {
|
|
86
|
-
if ('value' in node && typeof node.value === 'string') {
|
|
87
|
-
return node.value;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const children = getChildren(node);
|
|
91
|
-
// Preserve boundaries between block-level elements (list items, paragraphs
|
|
92
|
-
// inside list items, blockquotes) so downstream consumers like caption
|
|
93
|
-
// splitting can treat each item as a separate phrase.
|
|
94
|
-
const separator = node.type === 'list' || node.type === 'listItem' ? '\n' : '';
|
|
95
|
-
return children.map(extractPlainText).join(separator);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Count the total number of nodes in the tree.
|
|
100
|
-
*
|
|
101
|
-
* @param node - The root node
|
|
102
|
-
* @returns Total node count (including the root)
|
|
103
|
-
*/
|
|
104
|
-
export function countNodes(node: MarkdownNode): number {
|
|
105
|
-
let count = 1;
|
|
106
|
-
const children = getChildren(node);
|
|
107
|
-
for (const child of children) {
|
|
108
|
-
count += countNodes(child);
|
|
109
|
-
}
|
|
110
|
-
return count;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Parse a YAML frontmatter string into a key-value record.
|
|
115
|
-
*
|
|
116
|
-
* Handles simple `key: value` pairs common in markdown frontmatter.
|
|
117
|
-
* Values are trimmed; quoted strings have their quotes removed.
|
|
118
|
-
* Returns `null` if parsing fails or the input is empty.
|
|
119
|
-
*
|
|
120
|
-
* @param yaml - The raw YAML string (without the `---` delimiters)
|
|
121
|
-
* @returns A record of string keys to parsed values, or null
|
|
122
|
-
*/
|
|
123
|
-
export function parseFrontmatter(yaml: string): Record<string, unknown> | null {
|
|
124
|
-
if (!yaml || !yaml.trim()) return null;
|
|
125
|
-
|
|
126
|
-
const result: Record<string, unknown> = {};
|
|
127
|
-
const lines = yaml.split('\n');
|
|
128
|
-
|
|
129
|
-
// Define keys as data properties so a frontmatter key named `__proto__`
|
|
130
|
-
// cannot invoke Object.prototype's legacy setter.
|
|
131
|
-
const assign = (key: string, value: unknown): void => {
|
|
132
|
-
Object.defineProperty(result, key, {
|
|
133
|
-
value,
|
|
134
|
-
enumerable: true,
|
|
135
|
-
configurable: true,
|
|
136
|
-
writable: true,
|
|
137
|
-
});
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
for (let i = 0; i < lines.length; i++) {
|
|
141
|
-
const line = lines[i];
|
|
142
|
-
const trimmed = line.trim();
|
|
143
|
-
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
144
|
-
|
|
145
|
-
const colonIdx = trimmed.indexOf(':');
|
|
146
|
-
if (colonIdx < 1) continue;
|
|
147
|
-
|
|
148
|
-
const key = trimmed.slice(0, colonIdx).trim();
|
|
149
|
-
const value = trimmed.slice(colonIdx + 1).trim();
|
|
150
|
-
|
|
151
|
-
// YAML literal block scalar: `key: |` or `key: |-`. Subsequent lines
|
|
152
|
-
// that are more-indented than the key belong to the scalar; they are
|
|
153
|
-
// dedented by their common leading indent and joined with `\n`. A line
|
|
154
|
-
// at the key's indent (or less) ends the scalar. Both `|` and `|-`
|
|
155
|
-
// yield the joined string here (`|-` without a trailing newline); we do
|
|
156
|
-
// not model `|`'s trailing-newline / `+`/`-` chomping nuances beyond
|
|
157
|
-
// stripping trailing blank lines.
|
|
158
|
-
if (value === '|' || value === '|-') {
|
|
159
|
-
const keyIndent = line.length - line.trimStart().length;
|
|
160
|
-
const blockLines: string[] = [];
|
|
161
|
-
let j = i + 1;
|
|
162
|
-
for (; j < lines.length; j++) {
|
|
163
|
-
const bl = lines[j];
|
|
164
|
-
if (bl.trim() === '') {
|
|
165
|
-
blockLines.push('');
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
const indent = bl.length - bl.trimStart().length;
|
|
169
|
-
if (indent <= keyIndent) break; // dedent ends the scalar
|
|
170
|
-
blockLines.push(bl);
|
|
171
|
-
}
|
|
172
|
-
i = j - 1; // resume the outer walk at the terminating line
|
|
173
|
-
|
|
174
|
-
// Drop trailing blank lines captured inside the scalar.
|
|
175
|
-
while (blockLines.length > 0 && blockLines[blockLines.length - 1] === '') {
|
|
176
|
-
blockLines.pop();
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Dedent by the common leading whitespace of the non-blank lines.
|
|
180
|
-
let commonIndent = Infinity;
|
|
181
|
-
for (const bl of blockLines) {
|
|
182
|
-
if (bl === '') continue;
|
|
183
|
-
commonIndent = Math.min(commonIndent, bl.length - bl.trimStart().length);
|
|
184
|
-
}
|
|
185
|
-
if (!isFinite(commonIndent)) commonIndent = 0;
|
|
186
|
-
assign(key, blockLines.map((bl) => (bl === '' ? '' : bl.slice(commonIndent))).join('\n'));
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Quoted scalars are always strings, even when their contents look like a
|
|
191
|
-
// number or boolean. Double-quoted values emitted by
|
|
192
|
-
// formatFrontmatterValue use JSON-compatible escaping; single-quoted YAML
|
|
193
|
-
// represents a literal quote as two consecutive quotes.
|
|
194
|
-
if (value.startsWith('"') && value.endsWith('"')) {
|
|
195
|
-
try {
|
|
196
|
-
assign(key, JSON.parse(value));
|
|
197
|
-
} catch {
|
|
198
|
-
// Be permissive for hand-authored YAML outside our formatter's subset.
|
|
199
|
-
assign(key, value.slice(1, -1));
|
|
200
|
-
}
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
if (value.startsWith("'") && value.endsWith("'")) {
|
|
204
|
-
assign(key, value.slice(1, -1).replace(/''/g, "'"));
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Parse booleans and numbers
|
|
209
|
-
if (value === 'true') {
|
|
210
|
-
assign(key, true);
|
|
211
|
-
} else if (value === 'false') {
|
|
212
|
-
assign(key, false);
|
|
213
|
-
} else if (value !== '' && !isNaN(Number(value))) {
|
|
214
|
-
assign(key, Number(value));
|
|
215
|
-
} else {
|
|
216
|
-
assign(key, value);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return Object.keys(result).length > 0 ? result : null;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Format a multi-line string as a YAML literal block scalar body, i.e.
|
|
225
|
-
* `|-` followed by each source line indented two spaces. Paired with
|
|
226
|
-
* {@link parseFrontmatter}'s block-scalar reader so multi-line frontmatter
|
|
227
|
-
* values (e.g. pretty-printed JSON payloads) round-trip. Blank lines stay
|
|
228
|
-
* blank (no trailing whitespace) so the output diffs cleanly.
|
|
229
|
-
*/
|
|
230
|
-
export function formatBlockScalar(value: string): string {
|
|
231
|
-
const body = value
|
|
232
|
-
.split('\n')
|
|
233
|
-
.map((line) => (line === '' ? '' : ` ${line}`))
|
|
234
|
-
.join('\n');
|
|
235
|
-
return `|-\n${body}`;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const FRONTMATTER_BLOCK_RE = /^---\r?\n([\s\S]*?)\r?\n---(\r?\n)?/;
|
|
239
|
-
|
|
240
|
-
/** Quote a frontmatter scalar so it round-trips cleanly through `parseFrontmatter`. */
|
|
241
|
-
export function formatFrontmatterValue(value: string | number | boolean): string {
|
|
242
|
-
if (typeof value === 'boolean' || typeof value === 'number') return String(value);
|
|
243
|
-
// Multi-line strings can't live on one line — emit a YAML literal block
|
|
244
|
-
// scalar (`|-`) that `parseFrontmatter` reads back. This carries pretty-
|
|
245
|
-
// printed JSON payloads (opt-in custom templates/themes). Single-line
|
|
246
|
-
// values keep their exact historical output below.
|
|
247
|
-
if (/[\r\n]/.test(value)) return formatBlockScalar(value.replace(/\r\n?/g, '\n'));
|
|
248
|
-
// A single-line JSON object/array literal round-trips verbatim through
|
|
249
|
-
// the line-based `parseFrontmatter` (no leading quote to strip, no
|
|
250
|
-
// newline to split on), so write it unquoted to keep it human-readable
|
|
251
|
-
// — matching how `stringifyMarkdown` emits string values. Used by the
|
|
252
|
-
// compact custom-layouts payload.
|
|
253
|
-
if (/^[{[]/.test(value) && !/[\r\n]/.test(value)) return value;
|
|
254
|
-
// Quote when needed: leading/trailing whitespace, leading punctuation that
|
|
255
|
-
// could trigger YAML modes, or values that look like reserved literals.
|
|
256
|
-
const needsQuote =
|
|
257
|
-
/^\s|\s$/.test(value) ||
|
|
258
|
-
/^[!&*?|>%@`]/.test(value) ||
|
|
259
|
-
/[:#]/.test(value) ||
|
|
260
|
-
value === '' ||
|
|
261
|
-
value === 'true' ||
|
|
262
|
-
value === 'false' ||
|
|
263
|
-
(value !== '' && !Number.isNaN(Number(value))) ||
|
|
264
|
-
(/^["']/.test(value) && /["']$/.test(value));
|
|
265
|
-
if (!needsQuote) return value;
|
|
266
|
-
// Prefer double quotes; escape any embedded double-quote / backslash.
|
|
267
|
-
const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
268
|
-
return `"${escaped}"`;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Update a markdown source string's YAML frontmatter block, applying the
|
|
273
|
-
* given key/value updates. A `null` or `undefined` value removes the key.
|
|
274
|
-
* If no frontmatter block exists and any non-null update is supplied, a
|
|
275
|
-
* new block is prepended; if every update is a removal and no block
|
|
276
|
-
* exists, the source is returned unchanged.
|
|
277
|
-
*
|
|
278
|
-
* Existing key order is preserved; new keys are appended in the order
|
|
279
|
-
* they appear in `updates`. The simple parser used here handles plain
|
|
280
|
-
* `key: value` pairs only — comments, multi-line scalars, and nested
|
|
281
|
-
* structures are left untouched (we only rewrite lines whose key matches
|
|
282
|
-
* one in `updates`).
|
|
283
|
-
*
|
|
284
|
-
* @param source - The markdown source string.
|
|
285
|
-
* @param updates - Map of key → new value (or null/undefined to remove).
|
|
286
|
-
* @returns The updated markdown source string.
|
|
287
|
-
*/
|
|
288
|
-
export function setFrontmatterValues(
|
|
289
|
-
source: string,
|
|
290
|
-
updates: Record<string, string | number | boolean | null | undefined>,
|
|
291
|
-
): string {
|
|
292
|
-
const updateKeys = Object.keys(updates);
|
|
293
|
-
if (updateKeys.length === 0) return source;
|
|
294
|
-
|
|
295
|
-
const match = source.match(FRONTMATTER_BLOCK_RE);
|
|
296
|
-
const handled = new Set<string>();
|
|
297
|
-
|
|
298
|
-
// Existing frontmatter block — rewrite line-by-line, preserving order.
|
|
299
|
-
if (match) {
|
|
300
|
-
const inner = match[1];
|
|
301
|
-
const lines = inner.split(/\r?\n/);
|
|
302
|
-
const newLines: string[] = [];
|
|
303
|
-
|
|
304
|
-
for (const line of lines) {
|
|
305
|
-
const trimmed = line.trim();
|
|
306
|
-
if (!trimmed || trimmed.startsWith('#')) {
|
|
307
|
-
newLines.push(line);
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
const colonIdx = trimmed.indexOf(':');
|
|
311
|
-
if (colonIdx < 1) {
|
|
312
|
-
newLines.push(line);
|
|
313
|
-
continue;
|
|
314
|
-
}
|
|
315
|
-
const key = trimmed.slice(0, colonIdx).trim();
|
|
316
|
-
if (!Object.prototype.hasOwnProperty.call(updates, key)) {
|
|
317
|
-
newLines.push(line);
|
|
318
|
-
continue;
|
|
319
|
-
}
|
|
320
|
-
handled.add(key);
|
|
321
|
-
const next = updates[key];
|
|
322
|
-
if (next === null || next === undefined) continue; // remove
|
|
323
|
-
newLines.push(`${key}: ${formatFrontmatterValue(next)}`);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Append any keys that weren't already present.
|
|
327
|
-
for (const key of updateKeys) {
|
|
328
|
-
if (handled.has(key)) continue;
|
|
329
|
-
const next = updates[key];
|
|
330
|
-
if (next === null || next === undefined) continue;
|
|
331
|
-
newLines.push(`${key}: ${formatFrontmatterValue(next)}`);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// If every line got removed, drop the block entirely.
|
|
335
|
-
const nonEmpty = newLines.filter((l) => l.trim().length > 0);
|
|
336
|
-
const rest = source.slice(match[0].length);
|
|
337
|
-
if (nonEmpty.length === 0) return rest;
|
|
338
|
-
return `---\n${newLines.join('\n')}\n---\n${rest}`;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// No existing block — only create one if there's at least one non-null
|
|
342
|
-
// value to write.
|
|
343
|
-
const fresh: string[] = [];
|
|
344
|
-
for (const key of updateKeys) {
|
|
345
|
-
const next = updates[key];
|
|
346
|
-
if (next === null || next === undefined) continue;
|
|
347
|
-
fresh.push(`${key}: ${formatFrontmatterValue(next)}`);
|
|
348
|
-
}
|
|
349
|
-
if (fresh.length === 0) return source;
|
|
350
|
-
return `---\n${fresh.join('\n')}\n---\n${source}`;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* Create a minimal MarkdownDocument from a list of block nodes.
|
|
355
|
-
* Convenience function for programmatic document construction.
|
|
356
|
-
*/
|
|
357
|
-
export function createDocument(...children: MarkdownDocument['children']): MarkdownDocument {
|
|
358
|
-
return {
|
|
359
|
-
type: 'document',
|
|
360
|
-
children,
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
/**
|
|
365
|
-
* Infer a human-readable title for a markdown document.
|
|
366
|
-
*
|
|
367
|
-
* Resolution order:
|
|
368
|
-
* 1. `title:` value in YAML frontmatter (when present and non-empty)
|
|
369
|
-
* 2. Text of the first heading found, walking top-level depth (H1, then
|
|
370
|
-
* H2, etc.) — the shallowest heading wins regardless of source order
|
|
371
|
-
*
|
|
372
|
-
* Returns `undefined` when no usable title is found.
|
|
373
|
-
*/
|
|
374
|
-
export function inferDocumentTitle(doc: MarkdownDocument): string | undefined {
|
|
375
|
-
const fmTitle = doc.frontmatter?.title;
|
|
376
|
-
if (typeof fmTitle === 'string') {
|
|
377
|
-
const trimmed = fmTitle.trim();
|
|
378
|
-
if (trimmed) return trimmed;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
let best: { depth: number; text: string } | null = null;
|
|
382
|
-
for (const node of doc.children) {
|
|
383
|
-
if (node.type !== 'heading') continue;
|
|
384
|
-
const text = extractPlainText(node).trim();
|
|
385
|
-
if (!text) continue;
|
|
386
|
-
if (best === null || node.depth < best.depth) {
|
|
387
|
-
best = { depth: node.depth, text };
|
|
388
|
-
if (best.depth === 1) break;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
return best?.text;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Read a theme id from a markdown document's frontmatter.
|
|
397
|
-
*
|
|
398
|
-
* Checks the editor's canonical `squisq-theme` key first, then the
|
|
399
|
-
* shorter legacy aliases (`themeId`, `theme`). Returns `undefined`
|
|
400
|
-
* when none of them carry a non-empty string. Centralizing the lookup
|
|
401
|
-
* keeps the export pipelines (DOCX, PPTX, HTML, plain-HTML bundle) in
|
|
402
|
-
* sync with whatever the editor writes — adding a new frontmatter
|
|
403
|
-
* spelling later is a one-file change.
|
|
404
|
-
*/
|
|
405
|
-
export function readFrontmatterThemeId(
|
|
406
|
-
frontmatter: Record<string, unknown> | undefined,
|
|
407
|
-
): string | undefined {
|
|
408
|
-
if (!frontmatter) return undefined;
|
|
409
|
-
const keys = ['squisq-theme', 'themeId', 'theme'] as const;
|
|
410
|
-
for (const key of keys) {
|
|
411
|
-
const raw = frontmatter[key];
|
|
412
|
-
if (typeof raw === 'string') {
|
|
413
|
-
const trimmed = raw.trim();
|
|
414
|
-
if (trimmed) return trimmed;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
return undefined;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
/**
|
|
421
|
-
* Project an inline-HTML string (as stored on `TextLayer.content.html`) down
|
|
422
|
-
* to plain text — the value mirrored into `content.text` for plain consumers
|
|
423
|
-
* (PDF/markdown export, search, accessibility) and the SVG `<text>` fallback.
|
|
424
|
-
*
|
|
425
|
-
* `<br>` and block-level tags (`p`, `div`, `h1`–`h6`, `li`, `blockquote`,
|
|
426
|
-
* `pre`) become line breaks so multi-line rich content reads sensibly. Entity
|
|
427
|
-
* decoding is handled by {@link parseHtmlToNodes} (parse5-backed), so this is
|
|
428
|
-
* more correct than a regex tag-stripper.
|
|
429
|
-
*/
|
|
430
|
-
export function plainTextFromInlineHtml(html: string): string {
|
|
431
|
-
const BLOCK = new Set([
|
|
432
|
-
'p',
|
|
433
|
-
'div',
|
|
434
|
-
'h1',
|
|
435
|
-
'h2',
|
|
436
|
-
'h3',
|
|
437
|
-
'h4',
|
|
438
|
-
'h5',
|
|
439
|
-
'h6',
|
|
440
|
-
'li',
|
|
441
|
-
'blockquote',
|
|
442
|
-
'pre',
|
|
443
|
-
]);
|
|
444
|
-
const walk = (nodes: HtmlNode[]): string =>
|
|
445
|
-
nodes
|
|
446
|
-
.map((n) => {
|
|
447
|
-
if (n.type === 'htmlText') return n.value;
|
|
448
|
-
if (n.type !== 'htmlElement') return '';
|
|
449
|
-
const tag = n.tagName.toLowerCase();
|
|
450
|
-
if (tag === 'br') return '\n';
|
|
451
|
-
const inner = walk(n.children);
|
|
452
|
-
return BLOCK.has(tag) ? `${inner}\n` : inner;
|
|
453
|
-
})
|
|
454
|
-
.join('');
|
|
455
|
-
return walk(parseHtmlToNodes(html))
|
|
456
|
-
.replace(/\u00A0/g, ' ')
|
|
457
|
-
.replace(/\n{3,}/g, '\n\n')
|
|
458
|
-
.trim();
|
|
459
|
-
}
|