@bendyline/squisq 2.1.0 → 2.3.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/README.md +8 -8
- package/dist/{ContentContainer-BXUlIf18.d.ts → ContentContainer-B2w9sUoL.d.ts} +15 -0
- package/dist/{Doc-DynJleo-.d.ts → Doc-COe-rPQB.d.ts} +7 -5
- package/dist/{ImageEditDoc-Ca4Tr9uN.d.ts → ImageEditDoc-dtKahVyD.d.ts} +1 -1
- package/dist/{annotationCoercion-Dr_DY9Hx.d.ts → annotationCoercion-PtRQhk5V.d.ts} +1 -1
- 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-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-XNLB57UD.js → chunk-EK446BUE.js} +18 -2
- package/dist/{chunk-VR7UPJ7C.js → chunk-FCG3BIZN.js} +12 -1
- package/dist/{chunk-JI77MGAK.js → chunk-GIIOY6XR.js} +2178 -1291
- 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-OTKVFVL6.js → chunk-QNTQIEIV.js} +130 -47
- package/dist/{chunk-5UYI3RJB.js → chunk-QWCFK5FN.js} +55 -40
- package/dist/{chunk-GZY66SDN.js → chunk-R3KTTOMS.js} +0 -1
- package/dist/{chunk-ILWDXLUK.js → chunk-RS5AP3J4.js} +49 -10
- package/dist/{chunk-QUUPYOSP.js → chunk-SPTY4C6F.js} +136 -5
- package/dist/{chunk-4X3JQXNM.js → chunk-XOFT65EX.js} +1 -2
- package/dist/{chunk-FVTQSNR7.js → chunk-XRW6P7IF.js} +13 -5
- package/dist/{chunk-R2YZTCLO.js → chunk-ZQKZSJAX.js} +1 -2
- package/dist/doc/index.d.ts +311 -13
- package/dist/doc/index.js +25 -17
- package/dist/generate/index.d.ts +2 -2
- package/dist/generate/index.js +1 -3
- package/dist/icons/index.js +2 -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 +13 -13
- package/dist/index.js +67 -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-BSMOocve.d.ts} +2 -2
- package/dist/narration/index.d.ts +16 -3
- package/dist/narration/index.js +12 -14
- package/dist/random/index.d.ts +11 -2
- package/dist/random/index.js +1 -3
- package/dist/recommend/index.d.ts +1 -1
- package/dist/recommend/index.js +2 -4
- package/dist/schemas/index.d.ts +18 -6
- package/dist/schemas/index.js +7 -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-BUTWjufL.d.ts} +1 -1
- package/dist/timing/index.js +2 -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 +8 -3
- 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
|
@@ -1,616 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canonical block-to-page-section materialization — the Page (linear) mode
|
|
3
|
-
* sibling of `materializeBlockLayers`.
|
|
4
|
-
*
|
|
5
|
-
* `materializePageSections(doc, …)` is the primary entry point: it walks the
|
|
6
|
-
* block tree pre-order, extracts a `PageSection` per block (cover hero,
|
|
7
|
-
* typed template sections, prose, canvas embeds, visible fallbacks), and
|
|
8
|
-
* then applies the theme's art direction across the sequence — background
|
|
9
|
-
* rhythm, accent rotation, and the emphasis curve are sequence-scoped
|
|
10
|
-
* decisions that per-block calls cannot make.
|
|
11
|
-
*
|
|
12
|
-
* Failures are data, not console side effects: an unknown template becomes
|
|
13
|
-
* a visible `callout` section with a structured diagnostic (mirroring
|
|
14
|
-
* `materializeBlockLayers`' fallback posture).
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import type { Block, Doc, StartBlockConfig } from '../../schemas/Doc.js';
|
|
18
|
-
import type { CustomTemplateDefinition } from '../../schemas/CustomTemplates.js';
|
|
19
|
-
import type { Theme, ThemeColorScheme } from '../../schemas/Theme.js';
|
|
20
|
-
import type { ViewportConfig } from '../../schemas/Viewport.js';
|
|
21
|
-
import type {
|
|
22
|
-
PageBackground,
|
|
23
|
-
PageEmphasis,
|
|
24
|
-
PageSectionKind,
|
|
25
|
-
PageSectionOverride,
|
|
26
|
-
ThemePageStyle,
|
|
27
|
-
} from '../../schemas/PageStyle.js';
|
|
28
|
-
import { DEFAULT_THEME } from '../../schemas/themeLibrary.js';
|
|
29
|
-
import { VIEWPORT_PRESETS } from '../../schemas/Viewport.js';
|
|
30
|
-
import { defaultPageStyle } from '../../schemas/pageStyleDefaults.js';
|
|
31
|
-
import { extractPlainText } from '../../markdown/utils.js';
|
|
32
|
-
import type { MarkdownBlockNode } from '../../markdown/types.js';
|
|
33
|
-
import { extractBodyPlainText } from '../templateInputs.js';
|
|
34
|
-
import { isContainerTemplate } from '../templates/templateNames.js';
|
|
35
|
-
import { isTemplatedPageBlock, resolvePageBlock } from './resolvePageBlock.js';
|
|
36
|
-
import { sectionExtractors, type PageSectionDraft } from './sectionExtractors.js';
|
|
37
|
-
import type {
|
|
38
|
-
PageSection,
|
|
39
|
-
PageSectionDiagnostic,
|
|
40
|
-
PageSectionMaterialization,
|
|
41
|
-
PageRichText,
|
|
42
|
-
PageSectionSource,
|
|
43
|
-
} from './PageSection.js';
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Page-mode hints a transform style may carry (`TransformStyleConfig.page`).
|
|
47
|
-
* Defined here (not in `transform/`) so the doc pipeline stays independent
|
|
48
|
-
* of the transform module.
|
|
49
|
-
*/
|
|
50
|
-
export interface PageTransformHints {
|
|
51
|
-
/** Overrides `pageStyle.tokens.sectionSpacing` for this rendition. */
|
|
52
|
-
spacing?: 'compact' | 'comfortable' | 'generous';
|
|
53
|
-
/** 'front-loaded' promotes the first sections' emphasis one step. */
|
|
54
|
-
emphasisCurve?: 'even' | 'front-loaded';
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** Options shared by the per-block and doc-level entry points. */
|
|
58
|
-
export interface MaterializePageSectionOptions {
|
|
59
|
-
/** Theme whose `pageStyle` art-directs the sections. */
|
|
60
|
-
theme?: Theme;
|
|
61
|
-
/** Aspect reference for canvas embeds. Defaults to the landscape preset. */
|
|
62
|
-
viewport?: ViewportConfig;
|
|
63
|
-
/** Zero-based position in the section sequence (per-block calls). */
|
|
64
|
-
blockIndex?: number;
|
|
65
|
-
/** Total sections in the sequence (per-block calls). */
|
|
66
|
-
totalBlocks?: number;
|
|
67
|
-
/** Document-scoped custom templates (render as canvas embeds). */
|
|
68
|
-
customTemplates?: readonly CustomTemplateDefinition[];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/** Doc-level options. */
|
|
72
|
-
export interface MaterializePageSectionsOptions extends MaterializePageSectionOptions {
|
|
73
|
-
/**
|
|
74
|
-
* Cover hero: pass the doc's `startBlock` to synthesize a leading hero
|
|
75
|
-
* section, `false`/undefined to omit. (The caller decides — the editor's
|
|
76
|
-
* Cover toggle maps here.)
|
|
77
|
-
*/
|
|
78
|
-
cover?: StartBlockConfig | false;
|
|
79
|
-
/** Page hints from the active transform style, if any. */
|
|
80
|
-
transformPage?: PageTransformHints;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Resolve the effective page style for a theme: explicit `theme.pageStyle`
|
|
85
|
-
* wins, else a derived default. Transform hints overlay spacing.
|
|
86
|
-
* Never returns undefined.
|
|
87
|
-
*/
|
|
88
|
-
export function resolvePageStyle(theme?: Theme, hints?: PageTransformHints): ThemePageStyle {
|
|
89
|
-
const base = theme?.pageStyle ?? defaultPageStyle(theme ?? DEFAULT_THEME);
|
|
90
|
-
if (!hints?.spacing || hints.spacing === base.tokens.sectionSpacing) return base;
|
|
91
|
-
return { ...base, tokens: { ...base.tokens, sectionSpacing: hints.spacing } };
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** Section kinds that carry a rotating accent scheme. */
|
|
95
|
-
const ACCENT_KINDS: ReadonlySet<PageSectionKind> = new Set([
|
|
96
|
-
'banner',
|
|
97
|
-
'stat-band',
|
|
98
|
-
'quote-band',
|
|
99
|
-
'callout',
|
|
100
|
-
'card-grid',
|
|
101
|
-
'item-list',
|
|
102
|
-
'timeline-rail',
|
|
103
|
-
'footer',
|
|
104
|
-
]);
|
|
105
|
-
|
|
106
|
-
/** Kinds rendered as full-width color bands under the accent-bands rhythm. */
|
|
107
|
-
const BAND_KINDS: ReadonlySet<PageSectionKind> = new Set([
|
|
108
|
-
'banner',
|
|
109
|
-
'quote-band',
|
|
110
|
-
'stat-band',
|
|
111
|
-
'footer',
|
|
112
|
-
]);
|
|
113
|
-
|
|
114
|
-
/** Kinds rendered as tinted panels under the tinted-panels rhythm. */
|
|
115
|
-
const PANEL_KINDS: ReadonlySet<PageSectionKind> = new Set([
|
|
116
|
-
'callout',
|
|
117
|
-
'card-grid',
|
|
118
|
-
'stat-band',
|
|
119
|
-
'item-list',
|
|
120
|
-
'timeline-rail',
|
|
121
|
-
'table-section',
|
|
122
|
-
]);
|
|
123
|
-
|
|
124
|
-
interface DraftResult {
|
|
125
|
-
draft: PageSectionDraft;
|
|
126
|
-
source: PageSectionSource;
|
|
127
|
-
templateName?: string;
|
|
128
|
-
diagnostic?: PageSectionDiagnostic;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function isMermaidFence(node: MarkdownBlockNode): boolean {
|
|
132
|
-
return node.type === 'code' && node.lang?.trim().toLowerCase() === 'mermaid';
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function htmlTreeContainsMedia(nodes: unknown[]): boolean {
|
|
136
|
-
for (const value of nodes) {
|
|
137
|
-
if (!value || typeof value !== 'object') continue;
|
|
138
|
-
const node = value as Record<string, unknown>;
|
|
139
|
-
if (
|
|
140
|
-
node.type === 'htmlElement' &&
|
|
141
|
-
typeof node.tagName === 'string' &&
|
|
142
|
-
['img', 'video', 'audio'].includes(node.tagName.toLowerCase())
|
|
143
|
-
) {
|
|
144
|
-
return true;
|
|
145
|
-
}
|
|
146
|
-
if (Array.isArray(node.children) && htmlTreeContainsMedia(node.children)) return true;
|
|
147
|
-
}
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function markdownNodeContainsMedia(value: unknown): boolean {
|
|
152
|
-
if (!value || typeof value !== 'object') return false;
|
|
153
|
-
const node = value as Record<string, unknown>;
|
|
154
|
-
if (node.type === 'image') return true;
|
|
155
|
-
if (
|
|
156
|
-
(node.type === 'htmlBlock' || node.type === 'htmlInline') &&
|
|
157
|
-
Array.isArray(node.htmlChildren) &&
|
|
158
|
-
htmlTreeContainsMedia(node.htmlChildren)
|
|
159
|
-
) {
|
|
160
|
-
return true;
|
|
161
|
-
}
|
|
162
|
-
return Array.isArray(node.children) && node.children.some(markdownNodeContainsMedia);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/** Rich body content that a typed template has not already consumed. */
|
|
166
|
-
function unconsumedRichContent(block: Block, draft: PageSectionDraft): PageRichText | undefined {
|
|
167
|
-
if (!block.contents || block.contents.length === 0) return undefined;
|
|
168
|
-
const templateHasMedia =
|
|
169
|
-
Boolean(draft.slots.media) ||
|
|
170
|
-
Boolean(draft.slots.items?.some((item) => item.media !== undefined));
|
|
171
|
-
const markdown = block.contents.filter(
|
|
172
|
-
(node) => isMermaidFence(node) || (!templateHasMedia && markdownNodeContainsMedia(node)),
|
|
173
|
-
);
|
|
174
|
-
if (markdown.length === 0) return undefined;
|
|
175
|
-
return {
|
|
176
|
-
text: markdown
|
|
177
|
-
.map((node) => extractPlainText(node))
|
|
178
|
-
.join('\n')
|
|
179
|
-
.trim(),
|
|
180
|
-
markdown,
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function preserveRichContent(block: Block, draft: PageSectionDraft): PageSectionDraft {
|
|
185
|
-
const richContent = unconsumedRichContent(block, draft);
|
|
186
|
-
return richContent ? { ...draft, slots: { ...draft.slots, richContent } } : draft;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/** Extract the pre-art-direction draft for one block. */
|
|
190
|
-
function draftForBlock(
|
|
191
|
-
block: Block,
|
|
192
|
-
viewport: ViewportConfig,
|
|
193
|
-
customTemplates?: readonly CustomTemplateDefinition[],
|
|
194
|
-
): DraftResult {
|
|
195
|
-
if (isTemplatedPageBlock(block)) {
|
|
196
|
-
const resolved = resolvePageBlock(block);
|
|
197
|
-
const templateName = resolved.templateName!;
|
|
198
|
-
const extractor = sectionExtractors[templateName];
|
|
199
|
-
if (extractor) {
|
|
200
|
-
return {
|
|
201
|
-
draft: preserveRichContent(block, extractor(resolved.templateBlock!, { block, viewport })),
|
|
202
|
-
source: 'template',
|
|
203
|
-
templateName,
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const custom = customTemplates?.find((definition) => definition.name === templateName);
|
|
208
|
-
if (custom) {
|
|
209
|
-
const draft: PageSectionDraft = {
|
|
210
|
-
kind: 'canvas-embed',
|
|
211
|
-
variant: 'custom',
|
|
212
|
-
slots: {
|
|
213
|
-
media: {
|
|
214
|
-
type: 'canvas',
|
|
215
|
-
spatial: 'custom',
|
|
216
|
-
block: resolved.templateBlock as unknown as Block,
|
|
217
|
-
aspect: {
|
|
218
|
-
width: custom.viewport?.width ?? viewport.width,
|
|
219
|
-
height: custom.viewport?.height ?? viewport.height,
|
|
220
|
-
},
|
|
221
|
-
},
|
|
222
|
-
},
|
|
223
|
-
};
|
|
224
|
-
return {
|
|
225
|
-
draft: preserveRichContent(block, draft),
|
|
226
|
-
source: 'custom-template',
|
|
227
|
-
templateName,
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const diagnostic: PageSectionDiagnostic = {
|
|
232
|
-
code: 'unknown-template',
|
|
233
|
-
template: templateName,
|
|
234
|
-
message: `Unknown template "${templateName}"`,
|
|
235
|
-
};
|
|
236
|
-
const headingText = block.sourceHeading ? extractPlainText(block.sourceHeading) : undefined;
|
|
237
|
-
const draft: PageSectionDraft = {
|
|
238
|
-
kind: 'callout',
|
|
239
|
-
variant: 'diagnostic',
|
|
240
|
-
slots: {
|
|
241
|
-
title: headingText ?? diagnostic.message,
|
|
242
|
-
body: { text: extractBodyPlainText(block.contents) },
|
|
243
|
-
meta: diagnostic.message,
|
|
244
|
-
},
|
|
245
|
-
emphasis: 'quiet',
|
|
246
|
-
};
|
|
247
|
-
return {
|
|
248
|
-
draft: preserveRichContent(block, draft),
|
|
249
|
-
source: 'fallback',
|
|
250
|
-
templateName,
|
|
251
|
-
diagnostic,
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (block.layers && block.layers.length > 0) {
|
|
256
|
-
const draft: PageSectionDraft = {
|
|
257
|
-
kind: 'canvas-embed',
|
|
258
|
-
variant: 'authored',
|
|
259
|
-
slots: {
|
|
260
|
-
media: {
|
|
261
|
-
type: 'canvas',
|
|
262
|
-
spatial: 'authored',
|
|
263
|
-
block,
|
|
264
|
-
aspect: { width: viewport.width, height: viewport.height },
|
|
265
|
-
},
|
|
266
|
-
},
|
|
267
|
-
};
|
|
268
|
-
return {
|
|
269
|
-
draft: preserveRichContent(block, draft),
|
|
270
|
-
source: 'authored',
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const heading = block.sourceHeading;
|
|
275
|
-
return {
|
|
276
|
-
draft: {
|
|
277
|
-
kind: 'prose',
|
|
278
|
-
slots: {
|
|
279
|
-
title: heading ? extractPlainText(heading) : undefined,
|
|
280
|
-
headingLevel: heading?.depth,
|
|
281
|
-
body:
|
|
282
|
-
block.contents && block.contents.length > 0
|
|
283
|
-
? { text: extractBodyPlainText(block.contents), markdown: block.contents }
|
|
284
|
-
: undefined,
|
|
285
|
-
},
|
|
286
|
-
},
|
|
287
|
-
source: 'prose',
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/** Look up the theme override for a draft: per-template wins over per-kind. */
|
|
292
|
-
function overrideFor(
|
|
293
|
-
pageStyle: ThemePageStyle,
|
|
294
|
-
kind: PageSectionKind,
|
|
295
|
-
templateName?: string,
|
|
296
|
-
): PageSectionOverride | undefined {
|
|
297
|
-
const byTemplate = templateName ? pageStyle.templates?.[templateName] : undefined;
|
|
298
|
-
const byKind = pageStyle.sections?.[kind];
|
|
299
|
-
if (!byTemplate) return byKind;
|
|
300
|
-
if (!byKind) return byTemplate;
|
|
301
|
-
return {
|
|
302
|
-
...byKind,
|
|
303
|
-
...byTemplate,
|
|
304
|
-
hints: { ...byKind.hints, ...byTemplate.hints },
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
interface SectionSeed {
|
|
309
|
-
draft: PageSectionDraft;
|
|
310
|
-
source: PageSectionSource;
|
|
311
|
-
templateName?: string;
|
|
312
|
-
diagnostic?: PageSectionDiagnostic;
|
|
313
|
-
override?: PageSectionOverride;
|
|
314
|
-
block?: Block;
|
|
315
|
-
depth: number;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/** Build the final section from a seed + sequence-scoped decisions. */
|
|
319
|
-
function buildSection(
|
|
320
|
-
seed: SectionSeed,
|
|
321
|
-
index: number,
|
|
322
|
-
totalSections: number,
|
|
323
|
-
background: PageBackground,
|
|
324
|
-
emphasis: PageEmphasis,
|
|
325
|
-
accent: PageSection['accent'],
|
|
326
|
-
): PageSection {
|
|
327
|
-
const { draft, override } = seed;
|
|
328
|
-
const hints = { ...draft.hints, ...override?.hints };
|
|
329
|
-
const section: PageSection = {
|
|
330
|
-
kind: override?.kind ?? draft.kind,
|
|
331
|
-
variant: override?.variant ?? draft.variant,
|
|
332
|
-
blockId: seed.block?.id ?? 'cover',
|
|
333
|
-
template:
|
|
334
|
-
seed.source === 'template' || seed.source === 'custom-template' || seed.source === 'fallback'
|
|
335
|
-
? seed.templateName
|
|
336
|
-
: undefined,
|
|
337
|
-
slots: draft.slots,
|
|
338
|
-
emphasis,
|
|
339
|
-
accent,
|
|
340
|
-
background,
|
|
341
|
-
index,
|
|
342
|
-
totalSections,
|
|
343
|
-
depth: seed.depth,
|
|
344
|
-
source: seed.source,
|
|
345
|
-
};
|
|
346
|
-
if (seed.diagnostic) section.diagnostic = seed.diagnostic;
|
|
347
|
-
if (Object.keys(hints).length > 0) section.hints = hints;
|
|
348
|
-
return section;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
function resolveScheme(theme: Theme, schemeName: string | undefined): ThemeColorScheme | undefined {
|
|
352
|
-
return schemeName ? theme.colorSchemes?.[schemeName] : undefined;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/** The names available for accent rotation, honoring `accentRotation.schemes`. */
|
|
356
|
-
function rotationSchemeNames(pageStyle: ThemePageStyle, theme: Theme): string[] {
|
|
357
|
-
const all = Object.keys(theme.colorSchemes ?? {});
|
|
358
|
-
const requested = pageStyle.accentRotation.schemes;
|
|
359
|
-
if (!requested || requested.length === 0) return all;
|
|
360
|
-
return requested.filter((name) => all.includes(name));
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Materialize one block in isolation. Sequence-scoped art direction
|
|
365
|
-
* (background rhythm, accent rotation, emphasis curve) does not apply —
|
|
366
|
-
* use `materializePageSections` for whole-document rendering.
|
|
367
|
-
*/
|
|
368
|
-
export function materializePageSection(
|
|
369
|
-
block: Block,
|
|
370
|
-
options: MaterializePageSectionOptions = {},
|
|
371
|
-
): PageSectionMaterialization {
|
|
372
|
-
const theme = options.theme ?? DEFAULT_THEME;
|
|
373
|
-
const viewport = options.viewport ?? VIEWPORT_PRESETS.landscape;
|
|
374
|
-
const pageStyle = resolvePageStyle(theme);
|
|
375
|
-
const result = draftForBlock(block, viewport, options.customTemplates);
|
|
376
|
-
const override = overrideFor(pageStyle, result.draft.kind, result.templateName);
|
|
377
|
-
|
|
378
|
-
const background: PageBackground =
|
|
379
|
-
override?.background ?? (result.draft.mediaBackground ? 'media' : 'base');
|
|
380
|
-
const emphasis: PageEmphasis = override?.emphasis ?? result.draft.emphasis ?? 'standard';
|
|
381
|
-
const accent: PageSection['accent'] = result.draft.colorScheme
|
|
382
|
-
? {
|
|
383
|
-
schemeName: result.draft.colorScheme,
|
|
384
|
-
scheme: resolveScheme(theme, result.draft.colorScheme),
|
|
385
|
-
role: 'block',
|
|
386
|
-
}
|
|
387
|
-
: { role: pageStyle.accentRotation.strategy === 'none' ? 'none' : 'primary' };
|
|
388
|
-
|
|
389
|
-
const section = buildSection(
|
|
390
|
-
{ ...result, override, block, depth: 0 },
|
|
391
|
-
options.blockIndex ?? 0,
|
|
392
|
-
options.totalBlocks ?? 1,
|
|
393
|
-
background,
|
|
394
|
-
emphasis,
|
|
395
|
-
accent,
|
|
396
|
-
);
|
|
397
|
-
return {
|
|
398
|
-
section,
|
|
399
|
-
block,
|
|
400
|
-
source: result.source,
|
|
401
|
-
diagnostic: result.diagnostic,
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Materialize a whole document into its ordered page sections, applying
|
|
407
|
-
* the theme's art direction across the sequence. The primary entry point
|
|
408
|
-
* for Page (linear) mode renderers and exporters.
|
|
409
|
-
*/
|
|
410
|
-
export function materializePageSections(
|
|
411
|
-
doc: Doc,
|
|
412
|
-
options: MaterializePageSectionsOptions = {},
|
|
413
|
-
): PageSectionMaterialization[] {
|
|
414
|
-
const theme = options.theme ?? DEFAULT_THEME;
|
|
415
|
-
const viewport = options.viewport ?? VIEWPORT_PRESETS.landscape;
|
|
416
|
-
const pageStyle = resolvePageStyle(theme, options.transformPage);
|
|
417
|
-
const customTemplates = options.customTemplates ?? doc.customTemplates;
|
|
418
|
-
|
|
419
|
-
// ── Collect seeds pre-order ──────────────────────────────────────
|
|
420
|
-
const seeds: SectionSeed[] = [];
|
|
421
|
-
|
|
422
|
-
if (options.cover) {
|
|
423
|
-
const cover = options.cover;
|
|
424
|
-
seeds.push({
|
|
425
|
-
draft: {
|
|
426
|
-
kind: 'hero',
|
|
427
|
-
variant: 'cover',
|
|
428
|
-
slots: {
|
|
429
|
-
title: cover.title,
|
|
430
|
-
subtitle: cover.subtitle,
|
|
431
|
-
media: cover.heroSrc
|
|
432
|
-
? {
|
|
433
|
-
type: 'image',
|
|
434
|
-
src: cover.heroSrc,
|
|
435
|
-
alt: cover.heroAlt ?? '',
|
|
436
|
-
credit: cover.heroCredit,
|
|
437
|
-
license: cover.heroLicense,
|
|
438
|
-
}
|
|
439
|
-
: undefined,
|
|
440
|
-
},
|
|
441
|
-
emphasis: 'lead',
|
|
442
|
-
mediaBackground: !!cover.heroSrc,
|
|
443
|
-
},
|
|
444
|
-
source: 'cover',
|
|
445
|
-
depth: 0,
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
const walk = (blocks: readonly Block[], depth: number): void => {
|
|
450
|
-
for (const block of blocks) {
|
|
451
|
-
const result = draftForBlock(block, viewport, customTemplates);
|
|
452
|
-
seeds.push({ ...result, block, depth });
|
|
453
|
-
// Container templates (diagram/drawing/layout) consume their children
|
|
454
|
-
// inside the canvas; everything else recurses.
|
|
455
|
-
const consumed =
|
|
456
|
-
result.draft.kind === 'canvas-embed' && isContainerTemplate(result.templateName);
|
|
457
|
-
if (!consumed && block.children && block.children.length > 0) {
|
|
458
|
-
walk(block.children, depth + 1);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
|
-
walk(doc.blocks ?? [], 0);
|
|
463
|
-
|
|
464
|
-
// ── Cover dedupe ─────────────────────────────────────────────────
|
|
465
|
-
// The auto-generated cover copies the first H1's title (and its first
|
|
466
|
-
// paragraph as subtitle). On one scrolling page rendering both reads as
|
|
467
|
-
// a duplicate, so suppress the mirrored content from the H1's own
|
|
468
|
-
// section — and drop that section entirely when nothing remains.
|
|
469
|
-
if (options.cover && seeds.length > 1) {
|
|
470
|
-
const cover = options.cover;
|
|
471
|
-
const first = seeds[1];
|
|
472
|
-
if (first.draft.kind === 'hero' && first.draft.slots.title === cover.title) {
|
|
473
|
-
// The author already opens with a title/hero block — that one wins.
|
|
474
|
-
// Graft the cover's hero media onto it when it has none of its own.
|
|
475
|
-
const coverSeed = seeds[0];
|
|
476
|
-
const coverMedia = coverSeed.draft.slots.media;
|
|
477
|
-
if (coverMedia && !first.draft.slots.media) {
|
|
478
|
-
first.draft = {
|
|
479
|
-
...first.draft,
|
|
480
|
-
slots: { ...first.draft.slots, media: coverMedia },
|
|
481
|
-
mediaBackground: true,
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
seeds.splice(0, 1);
|
|
485
|
-
} else if (first.draft.kind === 'prose' && first.draft.slots.title === cover.title) {
|
|
486
|
-
const slots = { ...first.draft.slots };
|
|
487
|
-
delete slots.title;
|
|
488
|
-
delete slots.headingLevel;
|
|
489
|
-
let markdown = slots.body?.markdown;
|
|
490
|
-
if (
|
|
491
|
-
cover.subtitle &&
|
|
492
|
-
markdown &&
|
|
493
|
-
markdown.length > 0 &&
|
|
494
|
-
markdown[0].type === 'paragraph' &&
|
|
495
|
-
extractPlainText(markdown[0]) === cover.subtitle
|
|
496
|
-
) {
|
|
497
|
-
markdown = markdown.slice(1);
|
|
498
|
-
}
|
|
499
|
-
if (markdown && markdown.length > 0) {
|
|
500
|
-
slots.body = {
|
|
501
|
-
text: markdown
|
|
502
|
-
.map((node) => extractPlainText(node))
|
|
503
|
-
.join('\n')
|
|
504
|
-
.trim(),
|
|
505
|
-
markdown,
|
|
506
|
-
};
|
|
507
|
-
first.draft = { ...first.draft, slots };
|
|
508
|
-
} else {
|
|
509
|
-
seeds.splice(1, 1);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
// ── Apply theme overrides + sequence art direction ───────────────
|
|
515
|
-
for (const seed of seeds) {
|
|
516
|
-
seed.override = overrideFor(pageStyle, seed.draft.kind, seed.templateName);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
const totalSections = seeds.length;
|
|
520
|
-
const rhythm = pageStyle.tokens.backgroundRhythm;
|
|
521
|
-
const strategy = pageStyle.accentRotation.strategy;
|
|
522
|
-
const schemeNames = rotationSchemeNames(pageStyle, theme);
|
|
523
|
-
const rotationSize =
|
|
524
|
-
strategy === 'alternate-two' ? Math.min(2, schemeNames.length) : schemeNames.length;
|
|
525
|
-
|
|
526
|
-
let bandCounter = 0;
|
|
527
|
-
let rotationCounter = 0;
|
|
528
|
-
let promotedCount = 0;
|
|
529
|
-
let eyebrowCounter = 0;
|
|
530
|
-
const eyebrowTreatment = pageStyle.tokens.headingTreatment.eyebrow;
|
|
531
|
-
|
|
532
|
-
const results: PageSectionMaterialization[] = [];
|
|
533
|
-
for (let index = 0; index < seeds.length; index++) {
|
|
534
|
-
const seed = seeds[index];
|
|
535
|
-
const kind = seed.override?.kind ?? seed.draft.kind;
|
|
536
|
-
|
|
537
|
-
// Background: explicit override > media background > rhythm.
|
|
538
|
-
let background: PageBackground;
|
|
539
|
-
if (seed.override?.background) {
|
|
540
|
-
background = seed.override.background;
|
|
541
|
-
} else if (seed.draft.mediaBackground) {
|
|
542
|
-
background = 'media';
|
|
543
|
-
} else if (kind === 'prose' || rhythm === 'flat') {
|
|
544
|
-
background = 'base';
|
|
545
|
-
} else if (rhythm === 'accent-bands' && BAND_KINDS.has(kind)) {
|
|
546
|
-
background = 'accent';
|
|
547
|
-
} else if (rhythm === 'tinted-panels') {
|
|
548
|
-
background = PANEL_KINDS.has(kind) ? 'alternate' : 'base';
|
|
549
|
-
} else if (rhythm === 'alternate' || rhythm === 'accent-bands') {
|
|
550
|
-
background = bandCounter % 2 === 1 ? 'alternate' : 'base';
|
|
551
|
-
bandCounter++;
|
|
552
|
-
} else {
|
|
553
|
-
background = 'base';
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// Accent: block-authored scheme > rotation > primary.
|
|
557
|
-
let accent: PageSection['accent'];
|
|
558
|
-
if (seed.draft.colorScheme) {
|
|
559
|
-
accent = {
|
|
560
|
-
schemeName: seed.draft.colorScheme,
|
|
561
|
-
scheme: resolveScheme(theme, seed.draft.colorScheme),
|
|
562
|
-
role: 'block',
|
|
563
|
-
};
|
|
564
|
-
} else if (
|
|
565
|
-
ACCENT_KINDS.has(kind) &&
|
|
566
|
-
(strategy === 'cycle' || strategy === 'alternate-two') &&
|
|
567
|
-
rotationSize > 0
|
|
568
|
-
) {
|
|
569
|
-
const schemeName = schemeNames[rotationCounter % rotationSize];
|
|
570
|
-
rotationCounter++;
|
|
571
|
-
accent = { schemeName, scheme: resolveScheme(theme, schemeName), role: 'rotation' };
|
|
572
|
-
} else if (strategy === 'none') {
|
|
573
|
-
accent = { role: 'none' };
|
|
574
|
-
} else {
|
|
575
|
-
accent = { role: 'primary' };
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
// Emphasis: override > draft > standard, then the transform curve.
|
|
579
|
-
let emphasis: PageEmphasis = seed.override?.emphasis ?? seed.draft.emphasis ?? 'standard';
|
|
580
|
-
if (
|
|
581
|
-
options.transformPage?.emphasisCurve === 'front-loaded' &&
|
|
582
|
-
kind !== 'hero' &&
|
|
583
|
-
kind !== 'prose' &&
|
|
584
|
-
promotedCount < 2
|
|
585
|
-
) {
|
|
586
|
-
if (emphasis === 'standard') emphasis = 'strong';
|
|
587
|
-
promotedCount++;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
// Numbered / mono-tag eyebrows: fill sequential ordinals on the
|
|
591
|
-
// heading-bearing band sections so "01 —" chapter kickers count
|
|
592
|
-
// contiguously down the page. Authored eyebrow text always wins.
|
|
593
|
-
if (
|
|
594
|
-
(eyebrowTreatment === 'numbered' || eyebrowTreatment === 'mono-tag') &&
|
|
595
|
-
(kind === 'hero' || kind === 'banner')
|
|
596
|
-
) {
|
|
597
|
-
eyebrowCounter++;
|
|
598
|
-
if (!seed.draft.slots.eyebrow) {
|
|
599
|
-
seed.draft.slots = {
|
|
600
|
-
...seed.draft.slots,
|
|
601
|
-
eyebrow: String(eyebrowCounter).padStart(2, '0'),
|
|
602
|
-
};
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
const section = buildSection(seed, index, totalSections, background, emphasis, accent);
|
|
607
|
-
results.push({
|
|
608
|
-
section,
|
|
609
|
-
block: seed.block,
|
|
610
|
-
source: seed.source,
|
|
611
|
-
diagnostic: seed.diagnostic,
|
|
612
|
-
});
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
return results;
|
|
616
|
-
}
|