@bendyline/squisq 1.2.2 → 1.4.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/dist/{Doc-BfBhiCNr.d.ts → Doc-BeSeH2iX.d.ts} +141 -33
- package/dist/ImageEditDoc-BTIvw0oq.d.ts +84 -0
- package/dist/__tests__/colorUtils.test.d.ts +2 -0
- package/dist/__tests__/colorUtils.test.d.ts.map +1 -0
- package/dist/__tests__/colorUtils.test.js +94 -0
- package/dist/__tests__/colorUtils.test.js.map +1 -0
- package/dist/__tests__/getLayers.test.js +31 -7
- package/dist/__tests__/getLayers.test.js.map +1 -1
- package/dist/__tests__/iconResolve.test.d.ts +2 -0
- package/dist/__tests__/iconResolve.test.d.ts.map +1 -0
- package/dist/__tests__/iconResolve.test.js +99 -0
- package/dist/__tests__/iconResolve.test.js.map +1 -0
- package/dist/__tests__/imageEditState.test.d.ts +2 -0
- package/dist/__tests__/imageEditState.test.d.ts.map +1 -0
- package/dist/__tests__/imageEditState.test.js +61 -0
- package/dist/__tests__/imageEditState.test.js.map +1 -0
- package/dist/__tests__/imageEditVersions.test.d.ts +2 -0
- package/dist/__tests__/imageEditVersions.test.d.ts.map +1 -0
- package/dist/__tests__/imageEditVersions.test.js +141 -0
- package/dist/__tests__/imageEditVersions.test.js.map +1 -0
- package/dist/__tests__/inferDocumentTitle.test.d.ts +2 -0
- package/dist/__tests__/inferDocumentTitle.test.d.ts.map +1 -0
- package/dist/__tests__/inferDocumentTitle.test.js +42 -0
- package/dist/__tests__/inferDocumentTitle.test.js.map +1 -0
- package/dist/__tests__/jsonForm.chooseControl.test.d.ts +2 -0
- package/dist/__tests__/jsonForm.chooseControl.test.d.ts.map +1 -0
- package/dist/__tests__/jsonForm.chooseControl.test.js +74 -0
- package/dist/__tests__/jsonForm.chooseControl.test.js.map +1 -0
- package/dist/__tests__/jsonForm.evaluateWhen.test.d.ts +2 -0
- package/dist/__tests__/jsonForm.evaluateWhen.test.d.ts.map +1 -0
- package/dist/__tests__/jsonForm.evaluateWhen.test.js +51 -0
- package/dist/__tests__/jsonForm.evaluateWhen.test.js.map +1 -0
- package/dist/__tests__/jsonForm.inferSchema.test.d.ts +2 -0
- package/dist/__tests__/jsonForm.inferSchema.test.d.ts.map +1 -0
- package/dist/__tests__/jsonForm.inferSchema.test.js +23 -0
- package/dist/__tests__/jsonForm.inferSchema.test.js.map +1 -0
- package/dist/__tests__/jsonForm.pointer.test.d.ts +2 -0
- package/dist/__tests__/jsonForm.pointer.test.d.ts.map +1 -0
- package/dist/__tests__/jsonForm.pointer.test.js +94 -0
- package/dist/__tests__/jsonForm.pointer.test.js.map +1 -0
- package/dist/__tests__/markdown.test.js +40 -0
- package/dist/__tests__/markdown.test.js.map +1 -1
- package/dist/__tests__/markdownIcons.test.d.ts +2 -0
- package/dist/__tests__/markdownIcons.test.d.ts.map +1 -0
- package/dist/__tests__/markdownIcons.test.js +93 -0
- package/dist/__tests__/markdownIcons.test.js.map +1 -0
- package/dist/__tests__/markdownToDoc.test.js +15 -4
- package/dist/__tests__/markdownToDoc.test.js.map +1 -1
- package/dist/__tests__/recommendTemplates.test.d.ts +2 -0
- package/dist/__tests__/recommendTemplates.test.d.ts.map +1 -0
- package/dist/__tests__/recommendTemplates.test.js +158 -0
- package/dist/__tests__/recommendTemplates.test.js.map +1 -0
- package/dist/__tests__/scopedContentContainer.test.d.ts +2 -0
- package/dist/__tests__/scopedContentContainer.test.d.ts.map +1 -0
- package/dist/__tests__/scopedContentContainer.test.js +74 -0
- package/dist/__tests__/scopedContentContainer.test.js.map +1 -0
- package/dist/__tests__/slideshowGenerator.test.js +1 -1
- package/dist/__tests__/slideshowGenerator.test.js.map +1 -1
- package/dist/__tests__/surface.test.d.ts +2 -0
- package/dist/__tests__/surface.test.d.ts.map +1 -0
- package/dist/__tests__/surface.test.js +57 -0
- package/dist/__tests__/surface.test.js.map +1 -0
- package/dist/__tests__/templateAnnotationParse.test.d.ts +2 -0
- package/dist/__tests__/templateAnnotationParse.test.d.ts.map +1 -0
- package/dist/__tests__/templateAnnotationParse.test.js +42 -0
- package/dist/__tests__/templateAnnotationParse.test.js.map +1 -0
- package/dist/__tests__/templates.test.js +90 -9
- package/dist/__tests__/templates.test.js.map +1 -1
- package/dist/__tests__/themeCompile.test.d.ts +2 -0
- package/dist/__tests__/themeCompile.test.d.ts.map +1 -0
- package/dist/__tests__/themeCompile.test.js +134 -0
- package/dist/__tests__/themeCompile.test.js.map +1 -0
- package/dist/__tests__/themeValidator.test.d.ts +2 -0
- package/dist/__tests__/themeValidator.test.d.ts.map +1 -0
- package/dist/__tests__/themeValidator.test.js +107 -0
- package/dist/__tests__/themeValidator.test.js.map +1 -0
- package/dist/__tests__/versions.test.d.ts +2 -0
- package/dist/__tests__/versions.test.d.ts.map +1 -0
- package/dist/__tests__/versions.test.js +339 -0
- package/dist/__tests__/versions.test.js.map +1 -0
- package/dist/{chunk-CYQHG27J.js → chunk-2TMAWB4Y.js} +74 -1
- package/dist/chunk-2TMAWB4Y.js.map +1 -0
- package/dist/{chunk-LAZELBON.js → chunk-3K5OG6KI.js} +165 -17
- package/dist/chunk-3K5OG6KI.js.map +1 -0
- package/dist/chunk-57CVQCFX.js +193 -0
- package/dist/chunk-57CVQCFX.js.map +1 -0
- package/dist/{chunk-QM5PKNPW.js → chunk-5WFRKURX.js} +1 -1
- package/dist/chunk-5WFRKURX.js.map +1 -0
- package/dist/chunk-B4EEON3N.js +1317 -0
- package/dist/chunk-B4EEON3N.js.map +1 -0
- package/dist/chunk-DBS6RIFL.js +81 -0
- package/dist/chunk-DBS6RIFL.js.map +1 -0
- package/dist/{chunk-MIBRIRGJ.js → chunk-FR2RBTKO.js} +3 -3
- package/dist/{chunk-MIBRIRGJ.js.map → chunk-FR2RBTKO.js.map} +1 -1
- package/dist/chunk-H3AXU4MJ.js +179 -0
- package/dist/chunk-H3AXU4MJ.js.map +1 -0
- package/dist/chunk-JELIRVDP.js +24 -0
- package/dist/chunk-JELIRVDP.js.map +1 -0
- package/dist/chunk-K32VJONL.js +193 -0
- package/dist/chunk-K32VJONL.js.map +1 -0
- package/dist/{chunk-GAQLMORN.js → chunk-KSWJR66U.js} +248 -44
- package/dist/chunk-KSWJR66U.js.map +1 -0
- package/dist/{chunk-TSG2OSE6.js → chunk-MYIH7FWD.js} +3 -3
- package/dist/chunk-MYIH7FWD.js.map +1 -0
- package/dist/chunk-VLJJHDAC.js +218 -0
- package/dist/chunk-VLJJHDAC.js.map +1 -0
- package/dist/chunk-WMOI7FN3.js +182 -0
- package/dist/chunk-WMOI7FN3.js.map +1 -0
- package/dist/chunk-ZTX4PFFT.js +520 -0
- package/dist/chunk-ZTX4PFFT.js.map +1 -0
- package/dist/doc/audioMapping.d.ts.map +1 -1
- package/dist/doc/audioMapping.js +80 -9
- package/dist/doc/audioMapping.js.map +1 -1
- package/dist/doc/getLayers.d.ts.map +1 -1
- package/dist/doc/getLayers.js +29 -18
- package/dist/doc/getLayers.js.map +1 -1
- package/dist/doc/markdownToDoc.d.ts.map +1 -1
- package/dist/doc/markdownToDoc.js +40 -6
- package/dist/doc/markdownToDoc.js.map +1 -1
- package/dist/doc/templates/featureBlock.d.ts +18 -0
- package/dist/doc/templates/featureBlock.d.ts.map +1 -0
- package/dist/doc/templates/featureBlock.js +180 -0
- package/dist/doc/templates/featureBlock.js.map +1 -0
- package/dist/doc/templates/fullBleedQuote.d.ts +12 -0
- package/dist/doc/templates/fullBleedQuote.d.ts.map +1 -1
- package/dist/doc/templates/fullBleedQuote.js +12 -0
- package/dist/doc/templates/fullBleedQuote.js.map +1 -1
- package/dist/doc/templates/index.d.ts +28 -4
- package/dist/doc/templates/index.d.ts.map +1 -1
- package/dist/doc/templates/index.js +45 -12
- package/dist/doc/templates/index.js.map +1 -1
- package/dist/doc/templates/listBlock.d.ts.map +1 -1
- package/dist/doc/templates/listBlock.js +22 -5
- package/dist/doc/templates/listBlock.js.map +1 -1
- package/dist/doc/templates/statHighlight.d.ts +12 -0
- package/dist/doc/templates/statHighlight.d.ts.map +1 -1
- package/dist/doc/templates/statHighlight.js +12 -0
- package/dist/doc/templates/statHighlight.js.map +1 -1
- package/dist/doc/templates/titleBlock.d.ts +11 -0
- package/dist/doc/templates/titleBlock.d.ts.map +1 -1
- package/dist/doc/templates/titleBlock.js +8 -0
- package/dist/doc/templates/titleBlock.js.map +1 -1
- package/dist/doc/utils/themeUtils.d.ts +4 -4
- package/dist/doc/utils/themeUtils.d.ts.map +1 -1
- package/dist/doc/utils/themeUtils.js +8 -7
- package/dist/doc/utils/themeUtils.js.map +1 -1
- package/dist/generate/slideshowGenerator.js +1 -1
- package/dist/generate/slideshowGenerator.js.map +1 -1
- package/dist/generate/templateMapper.js +2 -2
- package/dist/generate/templateMapper.js.map +1 -1
- package/dist/icons/iconData.d.ts +26 -0
- package/dist/icons/iconData.d.ts.map +1 -0
- package/dist/icons/iconData.js +12 -0
- package/dist/icons/iconData.js.map +1 -0
- package/dist/icons/index.d.ts +12 -0
- package/dist/icons/index.d.ts.map +1 -0
- package/dist/icons/index.js +10 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/icons/resolve.d.ts +61 -0
- package/dist/icons/resolve.d.ts.map +1 -0
- package/dist/icons/resolve.js +130 -0
- package/dist/icons/resolve.js.map +1 -0
- package/dist/imageEdit/ImageEditVersionManager.d.ts +31 -0
- package/dist/imageEdit/ImageEditVersionManager.d.ts.map +1 -0
- package/dist/imageEdit/ImageEditVersionManager.js +39 -0
- package/dist/imageEdit/ImageEditVersionManager.js.map +1 -0
- package/dist/imageEdit/export.d.ts +33 -0
- package/dist/imageEdit/export.d.ts.map +1 -0
- package/dist/imageEdit/export.js +253 -0
- package/dist/imageEdit/export.js.map +1 -0
- package/dist/imageEdit/index.d.ts +14 -0
- package/dist/imageEdit/index.d.ts.map +1 -0
- package/dist/imageEdit/index.js +22 -0
- package/dist/imageEdit/index.js.map +1 -0
- package/dist/imageEdit/persistence.d.ts +15 -0
- package/dist/imageEdit/persistence.d.ts.map +1 -0
- package/dist/imageEdit/persistence.js +49 -0
- package/dist/imageEdit/persistence.js.map +1 -0
- package/dist/imageEdit/state.d.ts +42 -0
- package/dist/imageEdit/state.d.ts.map +1 -0
- package/dist/imageEdit/state.js +98 -0
- package/dist/imageEdit/state.js.map +1 -0
- package/dist/imageEdit/versionPaths.d.ts +27 -0
- package/dist/imageEdit/versionPaths.d.ts.map +1 -0
- package/dist/imageEdit/versionPaths.js +57 -0
- package/dist/imageEdit/versionPaths.js.map +1 -0
- package/dist/imageEdit/versions.d.ts +67 -0
- package/dist/imageEdit/versions.d.ts.map +1 -0
- package/dist/imageEdit/versions.js +161 -0
- package/dist/imageEdit/versions.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/jsonForm/chooseControl.d.ts +20 -0
- package/dist/jsonForm/chooseControl.d.ts.map +1 -0
- package/dist/jsonForm/chooseControl.js +82 -0
- package/dist/jsonForm/chooseControl.js.map +1 -0
- package/dist/jsonForm/evaluateWhen.d.ts +12 -0
- package/dist/jsonForm/evaluateWhen.d.ts.map +1 -0
- package/dist/jsonForm/evaluateWhen.js +65 -0
- package/dist/jsonForm/evaluateWhen.js.map +1 -0
- package/dist/jsonForm/index.d.ts +14 -0
- package/dist/jsonForm/index.d.ts.map +1 -0
- package/dist/jsonForm/index.js +12 -0
- package/dist/jsonForm/index.js.map +1 -0
- package/dist/jsonForm/inferSchema.d.ts +12 -0
- package/dist/jsonForm/inferSchema.d.ts.map +1 -0
- package/dist/jsonForm/inferSchema.js +15 -0
- package/dist/jsonForm/inferSchema.js.map +1 -0
- package/dist/jsonForm/pointer.d.ts +26 -0
- package/dist/jsonForm/pointer.d.ts.map +1 -0
- package/dist/jsonForm/pointer.js +102 -0
- package/dist/jsonForm/pointer.js.map +1 -0
- package/dist/jsonForm/types.d.ts +120 -0
- package/dist/jsonForm/types.d.ts.map +1 -0
- package/dist/jsonForm/types.js +10 -0
- package/dist/jsonForm/types.js.map +1 -0
- package/dist/markdown/convert.d.ts +11 -1
- package/dist/markdown/convert.d.ts.map +1 -1
- package/dist/markdown/convert.js +235 -15
- package/dist/markdown/convert.js.map +1 -1
- package/dist/markdown/index.d.ts +2 -2
- package/dist/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +1 -1
- package/dist/markdown/index.js.map +1 -1
- package/dist/markdown/types.d.ts +34 -1
- package/dist/markdown/types.d.ts.map +1 -1
- package/dist/markdown/utils.d.ts +40 -0
- package/dist/markdown/utils.d.ts.map +1 -1
- package/dist/markdown/utils.js +155 -0
- package/dist/markdown/utils.js.map +1 -1
- package/dist/recommend/index.d.ts +16 -0
- package/dist/recommend/index.d.ts.map +1 -0
- package/dist/recommend/index.js +15 -0
- package/dist/recommend/index.js.map +1 -0
- package/dist/recommend/templates.d.ts +39 -0
- package/dist/recommend/templates.d.ts.map +1 -0
- package/dist/recommend/templates.js +235 -0
- package/dist/recommend/templates.js.map +1 -0
- package/dist/schemas/BlockTemplates.d.ts +46 -8
- package/dist/schemas/BlockTemplates.d.ts.map +1 -1
- package/dist/schemas/BlockTemplates.js +3 -3
- package/dist/schemas/BlockTemplates.js.map +1 -1
- package/dist/schemas/ImageEditDoc.d.ts +81 -0
- package/dist/schemas/ImageEditDoc.d.ts.map +1 -0
- package/dist/schemas/ImageEditDoc.js +20 -0
- package/dist/schemas/ImageEditDoc.js.map +1 -0
- package/dist/schemas/Theme.d.ts +93 -23
- package/dist/schemas/Theme.d.ts.map +1 -1
- package/dist/schemas/Theme.js +80 -13
- package/dist/schemas/Theme.js.map +1 -1
- package/dist/schemas/colorUtils.d.ts +51 -0
- package/dist/schemas/colorUtils.d.ts.map +1 -0
- package/dist/schemas/colorUtils.js +154 -0
- package/dist/schemas/colorUtils.js.map +1 -0
- package/dist/schemas/fontStacks.d.ts +57 -0
- package/dist/schemas/fontStacks.d.ts.map +1 -0
- package/dist/schemas/fontStacks.js +227 -0
- package/dist/schemas/fontStacks.js.map +1 -0
- package/dist/schemas/index.d.ts +5 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +4 -0
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/themeCompile.d.ts +45 -0
- package/dist/schemas/themeCompile.d.ts.map +1 -0
- package/dist/schemas/themeCompile.js +160 -0
- package/dist/schemas/themeCompile.js.map +1 -0
- package/dist/schemas/themeLibrary.d.ts +11 -15
- package/dist/schemas/themeLibrary.d.ts.map +1 -1
- package/dist/schemas/themeLibrary.js +18 -499
- package/dist/schemas/themeLibrary.js.map +1 -1
- package/dist/schemas/themeValidator.d.ts +26 -0
- package/dist/schemas/themeValidator.d.ts.map +1 -0
- package/dist/schemas/themeValidator.js +352 -0
- package/dist/schemas/themeValidator.js.map +1 -0
- package/dist/schemas/themes/bold.json +48 -0
- package/dist/schemas/themes/cinematic.json +54 -0
- package/dist/schemas/themes/documentary.json +49 -0
- package/dist/schemas/themes/gezellig.json +44 -0
- package/dist/schemas/themes/index.d.ts +26 -0
- package/dist/schemas/themes/index.d.ts.map +1 -0
- package/dist/schemas/themes/index.js +49 -0
- package/dist/schemas/themes/index.js.map +1 -0
- package/dist/schemas/themes/magazine.json +44 -0
- package/dist/schemas/themes/minimalist.json +45 -0
- package/dist/schemas/themes/morning-light.json +42 -0
- package/dist/schemas/themes/standard-dark.json +50 -0
- package/dist/schemas/themes/standard.json +42 -0
- package/dist/schemas/themes/tech-dark.json +48 -0
- package/dist/schemas/themes/warm-earth.json +50 -0
- package/dist/storage/ScopedContentContainer.d.ts +44 -0
- package/dist/storage/ScopedContentContainer.d.ts.map +1 -0
- package/dist/storage/ScopedContentContainer.js +94 -0
- package/dist/storage/ScopedContentContainer.js.map +1 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +1 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/story/index.d.ts +53 -13
- package/dist/story/index.js +12 -4
- package/dist/themeLibrary-BHjJ0Qx6.d.ts +40 -0
- package/dist/{types-DYAzisMG.d.ts → types-BdZkdJ3z.d.ts} +35 -2
- package/dist/types-D98li1gV.d.ts +93 -0
- package/dist/versions/DocumentVersionManager.d.ts +31 -0
- package/dist/versions/DocumentVersionManager.d.ts.map +1 -0
- package/dist/versions/DocumentVersionManager.js +33 -0
- package/dist/versions/DocumentVersionManager.js.map +1 -0
- package/dist/versions/index.d.ts +29 -0
- package/dist/versions/index.d.ts.map +1 -0
- package/dist/versions/index.js +28 -0
- package/dist/versions/index.js.map +1 -0
- package/dist/versions/operations.d.ts +44 -0
- package/dist/versions/operations.d.ts.map +1 -0
- package/dist/versions/operations.js +190 -0
- package/dist/versions/operations.js.map +1 -0
- package/dist/versions/paths.d.ts +29 -0
- package/dist/versions/paths.d.ts.map +1 -0
- package/dist/versions/paths.js +66 -0
- package/dist/versions/paths.js.map +1 -0
- package/dist/versions/timestamp.d.ts +22 -0
- package/dist/versions/timestamp.d.ts.map +1 -0
- package/dist/versions/timestamp.js +44 -0
- package/dist/versions/timestamp.js.map +1 -0
- package/dist/versions/types.d.ts +92 -0
- package/dist/versions/types.d.ts.map +1 -0
- package/dist/versions/types.js +11 -0
- package/dist/versions/types.js.map +1 -0
- package/package.json +28 -1
- package/src/__tests__/colorUtils.test.ts +112 -0
- package/src/__tests__/getLayers.test.ts +32 -7
- package/src/__tests__/iconResolve.test.ts +122 -0
- package/src/__tests__/imageEditState.test.ts +74 -0
- package/src/__tests__/imageEditVersions.test.ts +169 -0
- package/src/__tests__/inferDocumentTitle.test.ts +50 -0
- package/src/__tests__/jsonForm.chooseControl.test.ts +86 -0
- package/src/__tests__/jsonForm.evaluateWhen.test.ts +59 -0
- package/src/__tests__/jsonForm.inferSchema.test.ts +25 -0
- package/src/__tests__/jsonForm.pointer.test.ts +103 -0
- package/src/__tests__/markdown.test.ts +44 -0
- package/src/__tests__/markdownIcons.test.ts +104 -0
- package/src/__tests__/markdownToDoc.test.ts +19 -4
- package/src/__tests__/recommendTemplates.test.ts +183 -0
- package/src/__tests__/scopedContentContainer.test.ts +89 -0
- package/src/__tests__/slideshowGenerator.test.ts +1 -1
- package/src/__tests__/surface.test.ts +68 -0
- package/src/__tests__/templateAnnotationParse.test.ts +42 -0
- package/src/__tests__/templates.test.ts +93 -9
- package/src/__tests__/themeCompile.test.ts +156 -0
- package/src/__tests__/themeValidator.test.ts +125 -0
- package/src/__tests__/versions.test.ts +415 -0
- package/src/doc/audioMapping.ts +95 -13
- package/src/doc/getLayers.ts +32 -21
- package/src/doc/markdownToDoc.ts +45 -7
- package/src/doc/templates/featureBlock.ts +202 -0
- package/src/doc/templates/fullBleedQuote.ts +13 -0
- package/src/doc/templates/index.ts +50 -16
- package/src/doc/templates/listBlock.ts +24 -5
- package/src/doc/templates/statHighlight.ts +13 -0
- package/src/doc/templates/titleBlock.ts +9 -0
- package/src/doc/utils/themeUtils.ts +8 -7
- package/src/generate/slideshowGenerator.ts +1 -1
- package/src/generate/templateMapper.ts +2 -2
- package/src/icons/iconData.ts +31 -0
- package/src/icons/index.ts +18 -0
- package/src/icons/resolve.ts +139 -0
- package/src/imageEdit/ImageEditVersionManager.ts +73 -0
- package/src/imageEdit/export.ts +326 -0
- package/src/imageEdit/index.ts +71 -0
- package/src/imageEdit/persistence.ts +62 -0
- package/src/imageEdit/state.ts +112 -0
- package/src/imageEdit/versionPaths.ts +57 -0
- package/src/imageEdit/versions.ts +231 -0
- package/src/index.ts +4 -0
- package/src/jsonForm/chooseControl.ts +88 -0
- package/src/jsonForm/evaluateWhen.ts +59 -0
- package/src/jsonForm/index.ts +22 -0
- package/src/jsonForm/inferSchema.ts +25 -0
- package/src/jsonForm/pointer.ts +109 -0
- package/src/jsonForm/types.ts +167 -0
- package/src/markdown/convert.ts +248 -15
- package/src/markdown/index.ts +4 -0
- package/src/markdown/types.ts +38 -1
- package/src/markdown/utils.ts +159 -0
- package/src/recommend/index.ts +16 -0
- package/src/recommend/templates.ts +273 -0
- package/src/schemas/BlockTemplates.ts +50 -7
- package/src/schemas/ImageEditDoc.ts +95 -0
- package/src/schemas/Theme.ts +152 -23
- package/src/schemas/colorUtils.ts +186 -0
- package/src/schemas/fontStacks.ts +257 -0
- package/src/schemas/index.ts +12 -0
- package/src/schemas/themeCompile.ts +203 -0
- package/src/schemas/themeLibrary.ts +18 -524
- package/src/schemas/themeValidator.ts +388 -0
- package/src/schemas/themes/bold.json +48 -0
- package/src/schemas/themes/cinematic.json +54 -0
- package/src/schemas/themes/documentary.json +49 -0
- package/src/schemas/themes/gezellig.json +44 -0
- package/src/schemas/themes/index.ts +53 -0
- package/src/schemas/themes/magazine.json +44 -0
- package/src/schemas/themes/minimalist.json +45 -0
- package/src/schemas/themes/morning-light.json +42 -0
- package/src/schemas/themes/standard-dark.json +50 -0
- package/src/schemas/themes/standard.json +42 -0
- package/src/schemas/themes/tech-dark.json +48 -0
- package/src/schemas/themes/warm-earth.json +50 -0
- package/src/storage/ScopedContentContainer.ts +113 -0
- package/src/storage/index.ts +1 -0
- package/src/versions/DocumentVersionManager.ts +70 -0
- package/src/versions/index.ts +54 -0
- package/src/versions/operations.ts +230 -0
- package/src/versions/paths.ts +66 -0
- package/src/versions/timestamp.ts +48 -0
- package/src/versions/types.ts +91 -0
- package/dist/chunk-53TZ2UTL.js +0 -470
- package/dist/chunk-53TZ2UTL.js.map +0 -1
- package/dist/chunk-7GF6RDED.js +0 -82
- package/dist/chunk-7GF6RDED.js.map +0 -1
- package/dist/chunk-CYQHG27J.js.map +0 -1
- package/dist/chunk-GAQLMORN.js.map +0 -1
- package/dist/chunk-LAZELBON.js.map +0 -1
- package/dist/chunk-QM5PKNPW.js.map +0 -1
- package/dist/chunk-TSG2OSE6.js.map +0 -1
- package/dist/chunk-XM4WSOHB.js +0 -92
- package/dist/chunk-XM4WSOHB.js.map +0 -1
- package/dist/themeLibrary-IP7EdyRq.d.ts +0 -44
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Pointer helpers (RFC 6901) plus immutable get/set, plus a tiny
|
|
3
|
+
* dotted-path normalizer so hosts can write `user.role` instead of
|
|
4
|
+
* `/user/role`. `$ref` resolution is local-only (`#/$defs/Foo`).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { SquisqAnnotatedSchema } from './types.js';
|
|
8
|
+
|
|
9
|
+
/** Normalize a path to a JSON Pointer string. Accepts both forms. */
|
|
10
|
+
export function toPointer(path: string): string {
|
|
11
|
+
if (path === '' || path === '/') return '';
|
|
12
|
+
if (path.startsWith('/')) return path;
|
|
13
|
+
// Dotted form: split on `.` and escape per RFC 6901.
|
|
14
|
+
return (
|
|
15
|
+
'/' +
|
|
16
|
+
path
|
|
17
|
+
.split('.')
|
|
18
|
+
.map((seg) => seg.replace(/~/g, '~0').replace(/\//g, '~1'))
|
|
19
|
+
.join('/')
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Split a JSON Pointer into decoded segments. Empty string → []. */
|
|
24
|
+
export function pointerSegments(pointer: string): string[] {
|
|
25
|
+
if (pointer === '') return [];
|
|
26
|
+
return pointer
|
|
27
|
+
.slice(1)
|
|
28
|
+
.split('/')
|
|
29
|
+
.map((seg) => seg.replace(/~1/g, '/').replace(/~0/g, '~'));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Read a value from data by path (dotted or pointer). Returns undefined if missing. */
|
|
33
|
+
export function getByPointer(data: unknown, path: string): unknown {
|
|
34
|
+
const segments = pointerSegments(toPointer(path));
|
|
35
|
+
let cur: unknown = data;
|
|
36
|
+
for (const seg of segments) {
|
|
37
|
+
if (cur === null || cur === undefined) return undefined;
|
|
38
|
+
if (Array.isArray(cur)) {
|
|
39
|
+
const idx = Number(seg);
|
|
40
|
+
if (!Number.isInteger(idx) || idx < 0 || idx >= cur.length) return undefined;
|
|
41
|
+
cur = cur[idx];
|
|
42
|
+
} else if (typeof cur === 'object') {
|
|
43
|
+
cur = (cur as Record<string, unknown>)[seg];
|
|
44
|
+
} else {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return cur;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Return a structurally-shared copy of `data` with the value at `path`
|
|
53
|
+
* replaced. Intermediate objects/arrays are cloned along the path; the
|
|
54
|
+
* rest is shared by reference. Creates intermediate objects if missing.
|
|
55
|
+
*/
|
|
56
|
+
export function setByPointer<T>(data: T, path: string, value: unknown): T {
|
|
57
|
+
const segments = pointerSegments(toPointer(path));
|
|
58
|
+
if (segments.length === 0) return value as T;
|
|
59
|
+
return setRec(data, segments, 0, value) as T;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function setRec(node: unknown, segments: string[], i: number, value: unknown): unknown {
|
|
63
|
+
const seg = segments[i];
|
|
64
|
+
const isLast = i === segments.length - 1;
|
|
65
|
+
|
|
66
|
+
// Decide whether the slot we're about to write into is an array index.
|
|
67
|
+
const nextSeg = isLast ? undefined : segments[i + 1];
|
|
68
|
+
const writingArrayChild = nextSeg !== undefined && /^\d+$/.test(nextSeg);
|
|
69
|
+
|
|
70
|
+
if (Array.isArray(node)) {
|
|
71
|
+
const idx = Number(seg);
|
|
72
|
+
const next = node.slice();
|
|
73
|
+
next[idx] = isLast
|
|
74
|
+
? value
|
|
75
|
+
: setRec(node[idx] ?? (writingArrayChild ? [] : {}), segments, i + 1, value);
|
|
76
|
+
return next;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const obj = (node && typeof node === 'object' ? { ...(node as object) } : {}) as Record<
|
|
80
|
+
string,
|
|
81
|
+
unknown
|
|
82
|
+
>;
|
|
83
|
+
obj[seg] = isLast
|
|
84
|
+
? value
|
|
85
|
+
: setRec(obj[seg] ?? (writingArrayChild ? [] : {}), segments, i + 1, value);
|
|
86
|
+
return obj;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Resolve a local `$ref` (e.g. `#/$defs/Foo`) against the root schema.
|
|
91
|
+
* Returns the original schema if no `$ref` is present, or `undefined`
|
|
92
|
+
* if the reference cannot be resolved. Cross-document refs are not
|
|
93
|
+
* supported.
|
|
94
|
+
*/
|
|
95
|
+
export function resolveRef(
|
|
96
|
+
schema: SquisqAnnotatedSchema,
|
|
97
|
+
root: SquisqAnnotatedSchema,
|
|
98
|
+
): SquisqAnnotatedSchema | undefined {
|
|
99
|
+
if (!schema.$ref) return schema;
|
|
100
|
+
const ref = schema.$ref;
|
|
101
|
+
if (!ref.startsWith('#/')) return undefined;
|
|
102
|
+
const segments = pointerSegments(ref.slice(1));
|
|
103
|
+
let cur: unknown = root;
|
|
104
|
+
for (const seg of segments) {
|
|
105
|
+
if (cur === null || cur === undefined || typeof cur !== 'object') return undefined;
|
|
106
|
+
cur = (cur as Record<string, unknown>)[seg];
|
|
107
|
+
}
|
|
108
|
+
return (cur as SquisqAnnotatedSchema | undefined) ?? undefined;
|
|
109
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Form types — Squisq's hint vocabulary layered on JSON Schema.
|
|
3
|
+
*
|
|
4
|
+
* Hints live inline on a JSON Schema under a single `squisq` key. The
|
|
5
|
+
* schema remains a valid JSON Schema; the extra key is ignored by
|
|
6
|
+
* standard validators. Renderers consult the hints to pick a control
|
|
7
|
+
* and tune its presentation.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Every concrete control rendered by `<JsonView>` and `<JsonEditor>`.
|
|
12
|
+
*
|
|
13
|
+
* Auto-defaults pick one based on schema shape; hosts override via
|
|
14
|
+
* `squisq.control` when they want something specific (e.g. radio over
|
|
15
|
+
* segmented for a long, descriptive enum).
|
|
16
|
+
*/
|
|
17
|
+
export type ControlKind =
|
|
18
|
+
| 'text'
|
|
19
|
+
| 'multiline'
|
|
20
|
+
| 'richtext'
|
|
21
|
+
| 'color'
|
|
22
|
+
| 'date'
|
|
23
|
+
| 'time'
|
|
24
|
+
| 'datetime'
|
|
25
|
+
| 'slider'
|
|
26
|
+
| 'stepper'
|
|
27
|
+
| 'segmented'
|
|
28
|
+
| 'radio'
|
|
29
|
+
| 'combobox'
|
|
30
|
+
| 'toggle'
|
|
31
|
+
| 'checkbox'
|
|
32
|
+
| 'card'
|
|
33
|
+
| 'card-stack'
|
|
34
|
+
| 'chip-bin'
|
|
35
|
+
| 'tabs'
|
|
36
|
+
| 'group';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Conditional rule: looked up by field path against the root data and
|
|
40
|
+
* compared with one of the operators. The first defined operator wins
|
|
41
|
+
* (in declaration order: equals, oneOf, matches, truthy).
|
|
42
|
+
*/
|
|
43
|
+
export interface SquisqWhen {
|
|
44
|
+
/**
|
|
45
|
+
* Path to the controlling field, relative to the root data.
|
|
46
|
+
* Accepts dotted-path (`user.role`) or JSON Pointer (`/user/role`).
|
|
47
|
+
*/
|
|
48
|
+
field: string;
|
|
49
|
+
equals?: unknown;
|
|
50
|
+
oneOf?: readonly unknown[];
|
|
51
|
+
/** ECMAScript regex source; matched against the string value. */
|
|
52
|
+
matches?: string;
|
|
53
|
+
/** When true, condition holds if value is truthy; when false, if falsy. */
|
|
54
|
+
truthy?: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Hints for a single schema node. Attach via `squisq` on any JSON
|
|
59
|
+
* Schema object — properties, items, the root, or sub-schemas inside
|
|
60
|
+
* `oneOf`/`anyOf`.
|
|
61
|
+
*/
|
|
62
|
+
export interface SquisqHints {
|
|
63
|
+
/** Force a specific control. If omitted, picked from type/format/enum cardinality. */
|
|
64
|
+
control?: ControlKind;
|
|
65
|
+
|
|
66
|
+
/** Override schema `title` for display. */
|
|
67
|
+
label?: string;
|
|
68
|
+
/** Override schema `description` for the inline helper text. */
|
|
69
|
+
help?: string;
|
|
70
|
+
/** Placeholder text for empty fields. */
|
|
71
|
+
placeholder?: string;
|
|
72
|
+
|
|
73
|
+
/** Suggested layout sizing in a parent grid. Renderers may ignore on narrow viewports. */
|
|
74
|
+
width?: 'full' | 'half' | 'third' | 'auto';
|
|
75
|
+
|
|
76
|
+
/** Hide the field — literal, or a `SquisqWhen` evaluated against root data. */
|
|
77
|
+
hidden?: boolean | SquisqWhen;
|
|
78
|
+
/** Disable the field — literal, or a `SquisqWhen` evaluated against root data. */
|
|
79
|
+
disabled?: boolean | SquisqWhen;
|
|
80
|
+
|
|
81
|
+
/** Override schema's required-ness for the UI only. */
|
|
82
|
+
required?: boolean;
|
|
83
|
+
|
|
84
|
+
/** For arrays of objects: how to label each card in a `card-stack`. */
|
|
85
|
+
itemLabel?: string | { fromField: string };
|
|
86
|
+
/** Label for the "+ Add" button on arrays. */
|
|
87
|
+
addLabel?: string;
|
|
88
|
+
/** Label for the remove button on arrays. */
|
|
89
|
+
removeLabel?: string;
|
|
90
|
+
|
|
91
|
+
/** Slider/stepper visual step. Falls back to schema `multipleOf`. */
|
|
92
|
+
step?: number;
|
|
93
|
+
|
|
94
|
+
/** Optional human-readable labels for enum values. */
|
|
95
|
+
enumLabels?: Record<string, string>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The subset of JSON Schema we understand, with an optional `squisq`
|
|
100
|
+
* key. We deliberately keep this as a structural type so any JSON
|
|
101
|
+
* Schema authored elsewhere can be passed in without conversion.
|
|
102
|
+
*/
|
|
103
|
+
export interface SquisqAnnotatedSchema {
|
|
104
|
+
type?: string | readonly string[];
|
|
105
|
+
format?: string;
|
|
106
|
+
title?: string;
|
|
107
|
+
description?: string;
|
|
108
|
+
default?: unknown;
|
|
109
|
+
examples?: readonly unknown[];
|
|
110
|
+
|
|
111
|
+
enum?: readonly unknown[];
|
|
112
|
+
const?: unknown;
|
|
113
|
+
|
|
114
|
+
// Object
|
|
115
|
+
properties?: Record<string, SquisqAnnotatedSchema>;
|
|
116
|
+
required?: readonly string[];
|
|
117
|
+
additionalProperties?: boolean | SquisqAnnotatedSchema;
|
|
118
|
+
|
|
119
|
+
// Array
|
|
120
|
+
items?: SquisqAnnotatedSchema | readonly SquisqAnnotatedSchema[];
|
|
121
|
+
minItems?: number;
|
|
122
|
+
maxItems?: number;
|
|
123
|
+
|
|
124
|
+
// Number
|
|
125
|
+
minimum?: number;
|
|
126
|
+
maximum?: number;
|
|
127
|
+
exclusiveMinimum?: number;
|
|
128
|
+
exclusiveMaximum?: number;
|
|
129
|
+
multipleOf?: number;
|
|
130
|
+
|
|
131
|
+
// String
|
|
132
|
+
minLength?: number;
|
|
133
|
+
maxLength?: number;
|
|
134
|
+
pattern?: string;
|
|
135
|
+
|
|
136
|
+
// Combinators
|
|
137
|
+
oneOf?: readonly SquisqAnnotatedSchema[];
|
|
138
|
+
anyOf?: readonly SquisqAnnotatedSchema[];
|
|
139
|
+
allOf?: readonly SquisqAnnotatedSchema[];
|
|
140
|
+
|
|
141
|
+
// References
|
|
142
|
+
$ref?: string;
|
|
143
|
+
$defs?: Record<string, SquisqAnnotatedSchema>;
|
|
144
|
+
definitions?: Record<string, SquisqAnnotatedSchema>;
|
|
145
|
+
|
|
146
|
+
// Squisq-native UI hints
|
|
147
|
+
squisq?: SquisqHints;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* A validation error reported by the consumer-supplied `validate` prop.
|
|
152
|
+
* Matches the shape of common validators (ajv, etc.) without depending
|
|
153
|
+
* on any specific one.
|
|
154
|
+
*/
|
|
155
|
+
export interface JsonFormValidationError {
|
|
156
|
+
/** JSON Pointer to the failing value, e.g. `/sections/0/heading`. */
|
|
157
|
+
path: string;
|
|
158
|
+
/** Human-readable message. */
|
|
159
|
+
message: string;
|
|
160
|
+
/** Optional schema keyword that failed (e.g. "required", "minimum"). */
|
|
161
|
+
keyword?: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export type JsonFormValidator = (
|
|
165
|
+
value: unknown,
|
|
166
|
+
schema: SquisqAnnotatedSchema,
|
|
167
|
+
) => readonly JsonFormValidationError[];
|
package/src/markdown/convert.ts
CHANGED
|
@@ -20,8 +20,10 @@ import type {
|
|
|
20
20
|
MarkdownSourcePosition,
|
|
21
21
|
HeadingTemplateAnnotation,
|
|
22
22
|
MarkdownHeading,
|
|
23
|
+
MarkdownInlineIcon,
|
|
23
24
|
} from './types.js';
|
|
24
25
|
import { parseHtmlToNodes } from './htmlParse.js';
|
|
26
|
+
import { resolveIcon } from '../icons/resolve.js';
|
|
25
27
|
|
|
26
28
|
// ============================================
|
|
27
29
|
// Generic mdast node shape
|
|
@@ -132,8 +134,13 @@ function extractText(node: MdastNode): string {
|
|
|
132
134
|
/**
|
|
133
135
|
* Regex matching a trailing `{[templateName key=value …]}` annotation.
|
|
134
136
|
* Captures the content between `{[` and `]}`.
|
|
137
|
+
*
|
|
138
|
+
* The trailing `[\s\]\}]*` tolerates accidental doubled `]}` that users
|
|
139
|
+
* sometimes type when learning the syntax (e.g. `{[foo]}]}`). It does
|
|
140
|
+
* not allow trailing word characters, so a non-trailing annotation like
|
|
141
|
+
* `## The {[chart]} section` still doesn't match.
|
|
135
142
|
*/
|
|
136
|
-
const TEMPLATE_ANNOTATION_RE = /\s*\{\[([^\]]+)\]\}\s*$/;
|
|
143
|
+
const TEMPLATE_ANNOTATION_RE = /\s*\{\[([^\]]+)\]\}[\s\]}]*$/;
|
|
137
144
|
|
|
138
145
|
/**
|
|
139
146
|
* Extract a `{[templateName key=value …]}` annotation from a heading's
|
|
@@ -247,13 +254,187 @@ function convertBlockChildren(children: MdastNode[], parseHtml: boolean): Markdo
|
|
|
247
254
|
return result;
|
|
248
255
|
}
|
|
249
256
|
|
|
250
|
-
function convertInlineChildren(
|
|
257
|
+
function convertInlineChildren(
|
|
258
|
+
children: MdastNode[],
|
|
259
|
+
parseHtml: boolean,
|
|
260
|
+
/** When false, skip the inline-icon split. Headings opt out so the
|
|
261
|
+
* `extractTemplateAnnotation` pass still sees the trailing
|
|
262
|
+
* `{[…]}` in raw text form; the caller runs `splitInlineIcons`
|
|
263
|
+
* itself afterward on the remaining children. */
|
|
264
|
+
applyIconSplit: boolean = true,
|
|
265
|
+
): MarkdownInlineNode[] {
|
|
251
266
|
const result: MarkdownInlineNode[] = [];
|
|
252
267
|
for (const child of children) {
|
|
253
268
|
const node = convertInlineNode(child, parseHtml);
|
|
254
269
|
if (node) result.push(node);
|
|
255
270
|
}
|
|
256
|
-
|
|
271
|
+
const mentioned = coalesceMentions(result);
|
|
272
|
+
return applyIconSplit ? splitInlineIcons(mentioned) : mentioned;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Walk an inline-children list and split each text node on `{[token]}`
|
|
277
|
+
* occurrences whose tokens resolve to known FontAwesome icons. Returns
|
|
278
|
+
* a new array — unresolved tokens are left as literal text so authors
|
|
279
|
+
* can write `{[notathing]}` verbatim if they really mean to.
|
|
280
|
+
*
|
|
281
|
+
* Exposed for the heading code path, which first strips the trailing
|
|
282
|
+
* template annotation and then runs this on what remains.
|
|
283
|
+
*/
|
|
284
|
+
export function splitInlineIcons(nodes: MarkdownInlineNode[]): MarkdownInlineNode[] {
|
|
285
|
+
// First pass: reassemble `text + textDirective + text` patterns
|
|
286
|
+
// formed when a qualified token like `{[fa-solid:user]}` was split
|
|
287
|
+
// by remark-directive's colon recognition. We collapse those triples
|
|
288
|
+
// back into a single text node containing the original token so the
|
|
289
|
+
// regex below can match.
|
|
290
|
+
const recombined = recombineDirectiveTokens(nodes);
|
|
291
|
+
|
|
292
|
+
const out: MarkdownInlineNode[] = [];
|
|
293
|
+
for (const node of recombined) {
|
|
294
|
+
if (node.type !== 'text') {
|
|
295
|
+
out.push(node);
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
out.push(...splitTextOnIcons(node.value, node.position));
|
|
299
|
+
}
|
|
300
|
+
return out;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* When the user types `{[fa-solid:user]}`, remark's directive plugin
|
|
305
|
+
* sees `:user` and emits a `textDirective` node. The result is a
|
|
306
|
+
* three-node sequence `text("…{[fa-solid") + textDirective("user") +
|
|
307
|
+
* text("]}…")`. This helper detects that shape and stitches the three
|
|
308
|
+
* back into one text node so downstream icon detection works on the
|
|
309
|
+
* authored token.
|
|
310
|
+
*/
|
|
311
|
+
function recombineDirectiveTokens(nodes: MarkdownInlineNode[]): MarkdownInlineNode[] {
|
|
312
|
+
const out: MarkdownInlineNode[] = [];
|
|
313
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
314
|
+
const cur = nodes[i];
|
|
315
|
+
const next = nodes[i + 1];
|
|
316
|
+
const after = nodes[i + 2];
|
|
317
|
+
if (
|
|
318
|
+
cur?.type === 'text' &&
|
|
319
|
+
next?.type === 'textDirective' &&
|
|
320
|
+
after?.type === 'text' &&
|
|
321
|
+
/\{\[[a-zA-Z0-9_-]+$/.test(cur.value) &&
|
|
322
|
+
/^\]\}/.test(after.value)
|
|
323
|
+
) {
|
|
324
|
+
const directive = next as unknown as { name?: string };
|
|
325
|
+
const directiveName = directive.name ?? '';
|
|
326
|
+
const merged: MarkdownInlineNode = {
|
|
327
|
+
type: 'text',
|
|
328
|
+
value: cur.value + ':' + directiveName + after.value,
|
|
329
|
+
...(cur.position ? { position: cur.position } : {}),
|
|
330
|
+
};
|
|
331
|
+
out.push(merged);
|
|
332
|
+
i += 2;
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
out.push(cur);
|
|
336
|
+
}
|
|
337
|
+
return out;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const ICON_TOKEN_RE = /\{\[([a-zA-Z0-9_:-]+)\]\}/g;
|
|
341
|
+
|
|
342
|
+
function splitTextOnIcons(value: string, position?: MarkdownSourcePosition): MarkdownInlineNode[] {
|
|
343
|
+
if (!value) return [];
|
|
344
|
+
ICON_TOKEN_RE.lastIndex = 0;
|
|
345
|
+
let lastIndex = 0;
|
|
346
|
+
let match: RegExpExecArray | null;
|
|
347
|
+
const out: MarkdownInlineNode[] = [];
|
|
348
|
+
while ((match = ICON_TOKEN_RE.exec(value)) !== null) {
|
|
349
|
+
const token = match[1];
|
|
350
|
+
const icon = resolveIcon(token);
|
|
351
|
+
if (!icon) continue; // leave the literal `{[…]}` in place
|
|
352
|
+
if (match.index > lastIndex) {
|
|
353
|
+
out.push({
|
|
354
|
+
type: 'text',
|
|
355
|
+
value: value.slice(lastIndex, match.index),
|
|
356
|
+
...(position ? { position } : {}),
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
const iconNode: MarkdownInlineIcon = {
|
|
360
|
+
type: 'inlineIcon',
|
|
361
|
+
token,
|
|
362
|
+
family: icon.family,
|
|
363
|
+
name: icon.name,
|
|
364
|
+
...(position ? { position } : {}),
|
|
365
|
+
};
|
|
366
|
+
out.push(iconNode);
|
|
367
|
+
lastIndex = match.index + match[0].length;
|
|
368
|
+
}
|
|
369
|
+
if (lastIndex === 0) {
|
|
370
|
+
// No matches — return the original text node unchanged.
|
|
371
|
+
return [{ type: 'text', value, ...(position ? { position } : {}) }];
|
|
372
|
+
}
|
|
373
|
+
if (lastIndex < value.length) {
|
|
374
|
+
out.push({
|
|
375
|
+
type: 'text',
|
|
376
|
+
value: value.slice(lastIndex),
|
|
377
|
+
...(position ? { position } : {}),
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
return out;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Post-process an inline-children list to collapse `text('@') + link(scheme:id)`
|
|
385
|
+
* pairs into a single `mention` node. The wire format `@[Display](scheme:id)`
|
|
386
|
+
* comes back from remark as two adjacent nodes — we merge them so consumers
|
|
387
|
+
* see a single atomic mention. A plain link whose URL doesn't have `scheme:id`
|
|
388
|
+
* shape, or that isn't immediately preceded by `@`, is left alone so ordinary
|
|
389
|
+
* links keep working.
|
|
390
|
+
*/
|
|
391
|
+
function coalesceMentions(inlines: MarkdownInlineNode[]): MarkdownInlineNode[] {
|
|
392
|
+
const out: MarkdownInlineNode[] = [];
|
|
393
|
+
for (const cur of inlines) {
|
|
394
|
+
const prev = out[out.length - 1];
|
|
395
|
+
if (
|
|
396
|
+
cur.type === 'link' &&
|
|
397
|
+
typeof cur.url === 'string' &&
|
|
398
|
+
prev &&
|
|
399
|
+
prev.type === 'text' &&
|
|
400
|
+
prev.value.endsWith('@')
|
|
401
|
+
) {
|
|
402
|
+
const schemeMatch = cur.url.match(/^([a-z][a-z0-9+.-]*):(.+)$/i);
|
|
403
|
+
if (schemeMatch && schemeMatch[1] && schemeMatch[2]) {
|
|
404
|
+
const targetKind = schemeMatch[1];
|
|
405
|
+
const targetId = schemeMatch[2];
|
|
406
|
+
const displayName = extractInlineText(cur.children);
|
|
407
|
+
if (prev.value === '@') {
|
|
408
|
+
out.pop();
|
|
409
|
+
} else {
|
|
410
|
+
prev.value = prev.value.slice(0, -1);
|
|
411
|
+
}
|
|
412
|
+
out.push({
|
|
413
|
+
type: 'mention',
|
|
414
|
+
targetKind,
|
|
415
|
+
targetId,
|
|
416
|
+
displayName,
|
|
417
|
+
...(cur.position ? { position: cur.position } : {}),
|
|
418
|
+
});
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
out.push(cur);
|
|
423
|
+
}
|
|
424
|
+
return out;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/** Plain-text of an inline children list — used to pull the display name
|
|
428
|
+
* out of a mention link's children. */
|
|
429
|
+
function extractInlineText(nodes: MarkdownInlineNode[]): string {
|
|
430
|
+
let out = '';
|
|
431
|
+
for (const n of nodes) {
|
|
432
|
+
if (n.type === 'text' || n.type === 'inlineCode') out += n.value;
|
|
433
|
+
else if ('children' in n && Array.isArray(n.children)) {
|
|
434
|
+
out += extractInlineText(n.children as MarkdownInlineNode[]);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return out;
|
|
257
438
|
}
|
|
258
439
|
|
|
259
440
|
function convertBlockNode(node: MdastNode, parseHtml: boolean): MarkdownBlockNode | null {
|
|
@@ -261,12 +442,18 @@ function convertBlockNode(node: MdastNode, parseHtml: boolean): MarkdownBlockNod
|
|
|
261
442
|
|
|
262
443
|
switch (node.type) {
|
|
263
444
|
case 'heading': {
|
|
264
|
-
|
|
445
|
+
// Defer icon splitting so `extractTemplateAnnotation` sees the
|
|
446
|
+
// trailing `{[name]}` as plain text and can decide whether it's
|
|
447
|
+
// a template annotation. Anything that's NOT the template still
|
|
448
|
+
// needs to become an icon node, so we run `splitInlineIcons` on
|
|
449
|
+
// what's left after the template extraction.
|
|
450
|
+
const headingChildren = convertInlineChildren(node.children ?? [], parseHtml, false);
|
|
265
451
|
const annotation = extractTemplateAnnotation(headingChildren);
|
|
452
|
+
const finalChildren = splitInlineIcons(headingChildren);
|
|
266
453
|
const result: MarkdownHeading = {
|
|
267
454
|
type: 'heading',
|
|
268
455
|
depth: (node.depth ?? 1) as 1 | 2 | 3 | 4 | 5 | 6,
|
|
269
|
-
children:
|
|
456
|
+
children: finalChildren,
|
|
270
457
|
...posField(pos),
|
|
271
458
|
};
|
|
272
459
|
if (annotation) {
|
|
@@ -590,7 +777,7 @@ export function toMdast(doc: MarkdownDocument): MdastNode {
|
|
|
590
777
|
function blockToMdast(node: MarkdownBlockNode): MdastNode {
|
|
591
778
|
switch (node.type) {
|
|
592
779
|
case 'heading': {
|
|
593
|
-
const mdastChildren = node.children
|
|
780
|
+
const mdastChildren = inlineChildrenToMdast(node.children);
|
|
594
781
|
if (node.templateAnnotation) {
|
|
595
782
|
const suffix = serializeTemplateAnnotation(node.templateAnnotation);
|
|
596
783
|
// Append to last text node, or create a new one
|
|
@@ -612,7 +799,7 @@ function blockToMdast(node: MarkdownBlockNode): MdastNode {
|
|
|
612
799
|
case 'paragraph':
|
|
613
800
|
return {
|
|
614
801
|
type: 'paragraph',
|
|
615
|
-
children: node.children
|
|
802
|
+
children: inlineChildrenToMdast(node.children),
|
|
616
803
|
...mdastPosField(node.position),
|
|
617
804
|
};
|
|
618
805
|
|
|
@@ -718,7 +905,7 @@ function blockToMdast(node: MarkdownBlockNode): MdastNode {
|
|
|
718
905
|
type: 'leafDirective',
|
|
719
906
|
name: node.name,
|
|
720
907
|
...(node.attributes ? { attributes: node.attributes } : {}),
|
|
721
|
-
children: node.children
|
|
908
|
+
children: inlineChildrenToMdast(node.children),
|
|
722
909
|
...mdastPosField(node.position),
|
|
723
910
|
};
|
|
724
911
|
|
|
@@ -757,11 +944,34 @@ function tableRowToMdast(row: MarkdownTableRow): MdastNode {
|
|
|
757
944
|
function tableCellToMdast(cell: MarkdownTableCell): MdastNode {
|
|
758
945
|
return {
|
|
759
946
|
type: 'tableCell',
|
|
760
|
-
children: cell.children
|
|
947
|
+
children: inlineChildrenToMdast(cell.children),
|
|
761
948
|
...mdastPosField(cell.position),
|
|
762
949
|
};
|
|
763
950
|
}
|
|
764
951
|
|
|
952
|
+
/**
|
|
953
|
+
* Serialize an array of inline nodes to mdast, flat-mapping the result so
|
|
954
|
+
* a single `mention` expands to two mdast nodes (`text('@')` + `link`).
|
|
955
|
+
* Use in place of `.map(inlineToMdast)` wherever we walk a children array.
|
|
956
|
+
*/
|
|
957
|
+
function inlineChildrenToMdast(nodes: MarkdownInlineNode[]): MdastNode[] {
|
|
958
|
+
const out: MdastNode[] = [];
|
|
959
|
+
for (const n of nodes) {
|
|
960
|
+
if (n.type === 'mention') {
|
|
961
|
+
out.push({ type: 'text', value: '@' });
|
|
962
|
+
out.push({
|
|
963
|
+
type: 'link',
|
|
964
|
+
url: `${n.targetKind}:${n.targetId}`,
|
|
965
|
+
children: [{ type: 'text', value: n.displayName }],
|
|
966
|
+
...mdastPosField(n.position),
|
|
967
|
+
});
|
|
968
|
+
} else {
|
|
969
|
+
out.push(inlineToMdast(n));
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
return out;
|
|
973
|
+
}
|
|
974
|
+
|
|
765
975
|
function inlineToMdast(node: MarkdownInlineNode): MdastNode {
|
|
766
976
|
switch (node.type) {
|
|
767
977
|
case 'text':
|
|
@@ -774,21 +984,21 @@ function inlineToMdast(node: MarkdownInlineNode): MdastNode {
|
|
|
774
984
|
case 'emphasis':
|
|
775
985
|
return {
|
|
776
986
|
type: 'emphasis',
|
|
777
|
-
children: node.children
|
|
987
|
+
children: inlineChildrenToMdast(node.children),
|
|
778
988
|
...mdastPosField(node.position),
|
|
779
989
|
};
|
|
780
990
|
|
|
781
991
|
case 'strong':
|
|
782
992
|
return {
|
|
783
993
|
type: 'strong',
|
|
784
|
-
children: node.children
|
|
994
|
+
children: inlineChildrenToMdast(node.children),
|
|
785
995
|
...mdastPosField(node.position),
|
|
786
996
|
};
|
|
787
997
|
|
|
788
998
|
case 'delete':
|
|
789
999
|
return {
|
|
790
1000
|
type: 'delete',
|
|
791
|
-
children: node.children
|
|
1001
|
+
children: inlineChildrenToMdast(node.children),
|
|
792
1002
|
...mdastPosField(node.position),
|
|
793
1003
|
};
|
|
794
1004
|
|
|
@@ -804,7 +1014,7 @@ function inlineToMdast(node: MarkdownInlineNode): MdastNode {
|
|
|
804
1014
|
type: 'link',
|
|
805
1015
|
url: node.url,
|
|
806
1016
|
...(node.title != null ? { title: node.title } : {}),
|
|
807
|
-
children: node.children
|
|
1017
|
+
children: inlineChildrenToMdast(node.children),
|
|
808
1018
|
...mdastPosField(node.position),
|
|
809
1019
|
};
|
|
810
1020
|
|
|
@@ -851,7 +1061,7 @@ function inlineToMdast(node: MarkdownInlineNode): MdastNode {
|
|
|
851
1061
|
identifier: node.identifier,
|
|
852
1062
|
...(node.label != null ? { label: node.label } : {}),
|
|
853
1063
|
referenceType: node.referenceType,
|
|
854
|
-
children: node.children
|
|
1064
|
+
children: inlineChildrenToMdast(node.children),
|
|
855
1065
|
...mdastPosField(node.position),
|
|
856
1066
|
};
|
|
857
1067
|
|
|
@@ -870,7 +1080,30 @@ function inlineToMdast(node: MarkdownInlineNode): MdastNode {
|
|
|
870
1080
|
type: 'textDirective',
|
|
871
1081
|
name: node.name,
|
|
872
1082
|
...(node.attributes ? { attributes: node.attributes } : {}),
|
|
873
|
-
children: node.children
|
|
1083
|
+
children: inlineChildrenToMdast(node.children),
|
|
1084
|
+
...mdastPosField(node.position),
|
|
1085
|
+
};
|
|
1086
|
+
|
|
1087
|
+
case 'mention':
|
|
1088
|
+
// Fallback: when `inlineToMdast` is called directly (not via
|
|
1089
|
+
// `inlineChildrenToMdast`), collapse the mention to just the link
|
|
1090
|
+
// form. The `@` prefix is lost, but the id+name still round-trip.
|
|
1091
|
+
// Normal call sites go through `inlineChildrenToMdast` and get
|
|
1092
|
+
// the proper text('@') + link pair.
|
|
1093
|
+
return {
|
|
1094
|
+
type: 'link',
|
|
1095
|
+
url: `${node.targetKind}:${node.targetId}`,
|
|
1096
|
+
children: [{ type: 'text', value: node.displayName }],
|
|
1097
|
+
...mdastPosField(node.position),
|
|
1098
|
+
};
|
|
1099
|
+
|
|
1100
|
+
case 'inlineIcon':
|
|
1101
|
+
// Serialize back to the authored token so source round-trips
|
|
1102
|
+
// byte-stable. The token already carries the qualified form when
|
|
1103
|
+
// required (the parser preserved it verbatim).
|
|
1104
|
+
return {
|
|
1105
|
+
type: 'text',
|
|
1106
|
+
value: `{[${node.token}]}`,
|
|
874
1107
|
...mdastPosField(node.position),
|
|
875
1108
|
};
|
|
876
1109
|
|
package/src/markdown/index.ts
CHANGED
|
@@ -77,6 +77,7 @@ export type {
|
|
|
77
77
|
MarkdownLinkReference,
|
|
78
78
|
MarkdownImageReference,
|
|
79
79
|
MarkdownTextDirective,
|
|
80
|
+
MarkdownMention,
|
|
80
81
|
|
|
81
82
|
// Union types
|
|
82
83
|
MarkdownBlockNode,
|
|
@@ -107,4 +108,7 @@ export {
|
|
|
107
108
|
countNodes,
|
|
108
109
|
createDocument,
|
|
109
110
|
parseFrontmatter,
|
|
111
|
+
setFrontmatterValues,
|
|
112
|
+
inferDocumentTitle,
|
|
113
|
+
readFrontmatterThemeId,
|
|
110
114
|
} from './utils.js';
|