@terra-symposium/docs 0.0.0-stage → 0.1.71
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 +201 -0
- package/README.md +72 -2
- package/lib-dist/assets/fonts/AUTHENTICSans-130.woff +0 -0
- package/lib-dist/assets/fonts/AUTHENTICSans-130.woff2 +0 -0
- package/lib-dist/assets/fonts/AUTHENTICSans-150.woff +0 -0
- package/lib-dist/assets/fonts/AUTHENTICSans-150.woff2 +0 -0
- package/lib-dist/assets/fonts/AUTHENTICSans-90.woff +0 -0
- package/lib-dist/assets/fonts/AUTHENTICSans-90.woff2 +0 -0
- package/lib-dist/assets/fonts/Avara-Bold.woff +0 -0
- package/lib-dist/assets/fonts/Avara-Bold.woff2 +0 -0
- package/lib-dist/assets/fonts/Avara-BoldItalic.woff +0 -0
- package/lib-dist/assets/fonts/Avara-BoldItalic.woff2 +0 -0
- package/lib-dist/assets/fonts/InterVariable-Italic-latin-20260728.woff2 +0 -0
- package/lib-dist/assets/fonts/InterVariable-latin-20260728.woff2 +0 -0
- package/lib-dist/assets/fonts/OFL-1.1.txt +93 -0
- package/lib-dist/assets/fonts/README.md +7 -0
- package/lib-dist/assets/fonts/licenses/Inter-OFL-1.1.txt +92 -0
- package/lib-dist/assets/fonts/licenses/OFL-1.1.txt +93 -0
- package/lib-dist/components/Docs.d.ts +22 -0
- package/lib-dist/components/Docs.d.ts.map +1 -0
- package/lib-dist/components/Docs.js +9 -0
- package/lib-dist/components/Docs.js.map +1 -0
- package/lib-dist/components/LocalDocsWorkspace.d.ts +37 -0
- package/lib-dist/components/LocalDocsWorkspace.d.ts.map +1 -0
- package/lib-dist/components/LocalDocsWorkspace.js +207 -0
- package/lib-dist/components/LocalDocsWorkspace.js.map +1 -0
- package/lib-dist/components/NotFound.d.ts +8 -0
- package/lib-dist/components/NotFound.d.ts.map +1 -0
- package/lib-dist/components/NotFound.js +6 -0
- package/lib-dist/components/NotFound.js.map +1 -0
- package/lib-dist/components/SiteLayout.d.ts +25 -0
- package/lib-dist/components/SiteLayout.d.ts.map +1 -0
- package/lib-dist/components/SiteLayout.js +12 -0
- package/lib-dist/components/SiteLayout.js.map +1 -0
- package/lib-dist/components/StaticWorkspace.d.ts +25 -0
- package/lib-dist/components/StaticWorkspace.d.ts.map +1 -0
- package/lib-dist/components/StaticWorkspace.js +245 -0
- package/lib-dist/components/StaticWorkspace.js.map +1 -0
- package/lib-dist/components/StrictLocalWorkspaceHarness.d.ts +10 -0
- package/lib-dist/components/StrictLocalWorkspaceHarness.d.ts.map +1 -0
- package/lib-dist/components/StrictLocalWorkspaceHarness.js +12 -0
- package/lib-dist/components/StrictLocalWorkspaceHarness.js.map +1 -0
- package/lib-dist/components/blocks.d.ts +23 -0
- package/lib-dist/components/blocks.d.ts.map +1 -0
- package/lib-dist/components/blocks.js +396 -0
- package/lib-dist/components/blocks.js.map +1 -0
- package/lib-dist/components/navigation.d.ts +18 -0
- package/lib-dist/components/navigation.d.ts.map +1 -0
- package/lib-dist/components/navigation.js +9 -0
- package/lib-dist/components/navigation.js.map +1 -0
- package/lib-dist/components/terra/Workspace.d.ts +5 -0
- package/lib-dist/components/terra/Workspace.d.ts.map +1 -0
- package/lib-dist/components/terra/Workspace.js +190 -0
- package/lib-dist/components/terra/Workspace.js.map +1 -0
- package/lib-dist/components/terra/editor/TerraContentEditor.d.ts +15 -0
- package/lib-dist/components/terra/editor/TerraContentEditor.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/TerraContentEditor.js +358 -0
- package/lib-dist/components/terra/editor/TerraContentEditor.js.map +1 -0
- package/lib-dist/components/terra/editor/_blocks.d.ts +70 -0
- package/lib-dist/components/terra/editor/_blocks.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/_blocks.js +120 -0
- package/lib-dist/components/terra/editor/_blocks.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/BlockContext.d.ts +7 -0
- package/lib-dist/components/terra/editor/docs/BlockContext.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/BlockContext.js +60 -0
- package/lib-dist/components/terra/editor/docs/BlockContext.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/DocsAttachmentPicker.d.ts +12 -0
- package/lib-dist/components/terra/editor/docs/DocsAttachmentPicker.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/DocsAttachmentPicker.js +66 -0
- package/lib-dist/components/terra/editor/docs/DocsAttachmentPicker.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/TerraToolbar.d.ts +12 -0
- package/lib-dist/components/terra/editor/docs/TerraToolbar.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/TerraToolbar.js +169 -0
- package/lib-dist/components/terra/editor/docs/TerraToolbar.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Callout.d.ts +14 -0
- package/lib-dist/components/terra/editor/docs/_Callout.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Callout.js +45 -0
- package/lib-dist/components/terra/editor/docs/_Callout.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_CodeBlock.d.ts +39 -0
- package/lib-dist/components/terra/editor/docs/_CodeBlock.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_CodeBlock.js +560 -0
- package/lib-dist/components/terra/editor/docs/_CodeBlock.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_DocsCode.d.ts +14 -0
- package/lib-dist/components/terra/editor/docs/_DocsCode.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_DocsCode.js +128 -0
- package/lib-dist/components/terra/editor/docs/_DocsCode.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_DocsImage.d.ts +18 -0
- package/lib-dist/components/terra/editor/docs/_DocsImage.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_DocsImage.js +62 -0
- package/lib-dist/components/terra/editor/docs/_DocsImage.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Embed.d.ts +17 -0
- package/lib-dist/components/terra/editor/docs/_Embed.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Embed.js +73 -0
- package/lib-dist/components/terra/editor/docs/_Embed.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Math.d.ts +31 -0
- package/lib-dist/components/terra/editor/docs/_Math.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Math.js +138 -0
- package/lib-dist/components/terra/editor/docs/_Math.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Nodes.d.ts +15 -0
- package/lib-dist/components/terra/editor/docs/_Nodes.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Nodes.js +62 -0
- package/lib-dist/components/terra/editor/docs/_Nodes.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Raw.d.ts +15 -0
- package/lib-dist/components/terra/editor/docs/_Raw.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Raw.js +31 -0
- package/lib-dist/components/terra/editor/docs/_Raw.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Table.d.ts +12 -0
- package/lib-dist/components/terra/editor/docs/_Table.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Table.js +99 -0
- package/lib-dist/components/terra/editor/docs/_Table.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Tabs.d.ts +14 -0
- package/lib-dist/components/terra/editor/docs/_Tabs.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_Tabs.js +125 -0
- package/lib-dist/components/terra/editor/docs/_Tabs.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_TsDocs.d.ts +15 -0
- package/lib-dist/components/terra/editor/docs/_TsDocs.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_TsDocs.js +83 -0
- package/lib-dist/components/terra/editor/docs/_TsDocs.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/_math_inline.d.ts +14 -0
- package/lib-dist/components/terra/editor/docs/_math_inline.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/_math_inline.js +30 -0
- package/lib-dist/components/terra/editor/docs/_math_inline.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/heading.d.ts +23 -0
- package/lib-dist/components/terra/editor/docs/heading.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/heading.js +63 -0
- package/lib-dist/components/terra/editor/docs/heading.js.map +1 -0
- package/lib-dist/components/terra/editor/docs/index.d.ts +13 -0
- package/lib-dist/components/terra/editor/docs/index.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/docs/index.js +14 -0
- package/lib-dist/components/terra/editor/docs/index.js.map +1 -0
- package/lib-dist/components/terra/editor/terra-content.styles.d.ts +3 -0
- package/lib-dist/components/terra/editor/terra-content.styles.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/terra-content.styles.js +3 -0
- package/lib-dist/components/terra/editor/terra-content.styles.js.map +1 -0
- package/lib-dist/components/terra/editor/types.d.ts +40 -0
- package/lib-dist/components/terra/editor/types.d.ts.map +1 -0
- package/lib-dist/components/terra/editor/types.js +11 -0
- package/lib-dist/components/terra/editor/types.js.map +1 -0
- package/lib-dist/components/terra/flow/Nodes.d.ts +78 -0
- package/lib-dist/components/terra/flow/Nodes.d.ts.map +1 -0
- package/lib-dist/components/terra/flow/Nodes.js +1019 -0
- package/lib-dist/components/terra/flow/Nodes.js.map +1 -0
- package/lib-dist/components/terra/flow/_chrome.d.ts +267 -0
- package/lib-dist/components/terra/flow/_chrome.d.ts.map +1 -0
- package/lib-dist/components/terra/flow/_chrome.js +1009 -0
- package/lib-dist/components/terra/flow/_chrome.js.map +1 -0
- package/lib-dist/components/terra/flow/menuContext.d.ts +13 -0
- package/lib-dist/components/terra/flow/menuContext.d.ts.map +1 -0
- package/lib-dist/components/terra/flow/menuContext.js +10 -0
- package/lib-dist/components/terra/flow/menuContext.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_attachments.d.ts +20 -0
- package/lib-dist/components/terra/pages/docs/_attachments.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_attachments.js +1148 -0
- package/lib-dist/components/terra/pages/docs/_attachments.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_blocks.d.ts +48 -0
- package/lib-dist/components/terra/pages/docs/_blocks.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_blocks.js +203 -0
- package/lib-dist/components/terra/pages/docs/_blocks.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_editable.d.ts +61 -0
- package/lib-dist/components/terra/pages/docs/_editable.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_editable.js +442 -0
- package/lib-dist/components/terra/pages/docs/_editable.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_export-dialog.d.ts +19 -0
- package/lib-dist/components/terra/pages/docs/_export-dialog.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_export-dialog.js +78 -0
- package/lib-dist/components/terra/pages/docs/_export-dialog.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_icons.d.ts +20 -0
- package/lib-dist/components/terra/pages/docs/_icons.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_icons.js +29 -0
- package/lib-dist/components/terra/pages/docs/_icons.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_main.d.ts +54 -0
- package/lib-dist/components/terra/pages/docs/_main.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_main.js +710 -0
- package/lib-dist/components/terra/pages/docs/_main.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_manage-attachments-dialog.d.ts +10 -0
- package/lib-dist/components/terra/pages/docs/_manage-attachments-dialog.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_manage-attachments-dialog.js +597 -0
- package/lib-dist/components/terra/pages/docs/_manage-attachments-dialog.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_sidebar.d.ts +33 -0
- package/lib-dist/components/terra/pages/docs/_sidebar.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_sidebar.js +1437 -0
- package/lib-dist/components/terra/pages/docs/_sidebar.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_toc.d.ts +4 -0
- package/lib-dist/components/terra/pages/docs/_toc.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_toc.js +212 -0
- package/lib-dist/components/terra/pages/docs/_toc.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_toolbar-find-replace.d.ts +15 -0
- package/lib-dist/components/terra/pages/docs/_toolbar-find-replace.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_toolbar-find-replace.js +207 -0
- package/lib-dist/components/terra/pages/docs/_toolbar-find-replace.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_toolbar.d.ts +22 -0
- package/lib-dist/components/terra/pages/docs/_toolbar.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_toolbar.js +1508 -0
- package/lib-dist/components/terra/pages/docs/_toolbar.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/_tree.d.ts +178 -0
- package/lib-dist/components/terra/pages/docs/_tree.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/_tree.js +1123 -0
- package/lib-dist/components/terra/pages/docs/_tree.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/use-block-nav.d.ts +5 -0
- package/lib-dist/components/terra/pages/docs/use-block-nav.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/use-block-nav.js +1306 -0
- package/lib-dist/components/terra/pages/docs/use-block-nav.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/use-media-paste.d.ts +5 -0
- package/lib-dist/components/terra/pages/docs/use-media-paste.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/use-media-paste.js +391 -0
- package/lib-dist/components/terra/pages/docs/use-media-paste.js.map +1 -0
- package/lib-dist/components/terra/pages/docs/use-render-tripwire.d.ts +2 -0
- package/lib-dist/components/terra/pages/docs/use-render-tripwire.d.ts.map +1 -0
- package/lib-dist/components/terra/pages/docs/use-render-tripwire.js +25 -0
- package/lib-dist/components/terra/pages/docs/use-render-tripwire.js.map +1 -0
- package/lib-dist/components/terra/ui.d.ts +28 -0
- package/lib-dist/components/terra/ui.d.ts.map +1 -0
- package/lib-dist/components/terra/ui.js +20 -0
- package/lib-dist/components/terra/ui.js.map +1 -0
- package/lib-dist/components/workspace-demo-fixture.d.ts +35 -0
- package/lib-dist/components/workspace-demo-fixture.d.ts.map +1 -0
- package/lib-dist/components/workspace-demo-fixture.js +820 -0
- package/lib-dist/components/workspace-demo-fixture.js.map +1 -0
- package/lib-dist/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/lib-dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/lib-dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Main-Bold.woff +0 -0
- package/lib-dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/lib-dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Main-Italic.woff +0 -0
- package/lib-dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Main-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/lib-dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Math-Italic.woff +0 -0
- package/lib-dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/lib-dist/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/lib-dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/lib-dist/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/lib-dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Script-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/lib-dist/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/lib-dist/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/lib-dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/lib-dist/lib/astro.d.ts +8 -0
- package/lib-dist/lib/astro.d.ts.map +1 -0
- package/lib-dist/lib/astro.js +27 -0
- package/lib-dist/lib/astro.js.map +1 -0
- package/lib-dist/lib/docs-catalog.d.ts +5 -0
- package/lib-dist/lib/docs-catalog.d.ts.map +1 -0
- package/lib-dist/lib/docs-catalog.js +75 -0
- package/lib-dist/lib/docs-catalog.js.map +1 -0
- package/lib-dist/lib/docs-theme.d.ts +7 -0
- package/lib-dist/lib/docs-theme.d.ts.map +1 -0
- package/lib-dist/lib/docs-theme.js +51 -0
- package/lib-dist/lib/docs-theme.js.map +1 -0
- package/lib-dist/lib/host-runtime.d.ts +5 -0
- package/lib-dist/lib/host-runtime.d.ts.map +1 -0
- package/lib-dist/lib/host-runtime.js +23 -0
- package/lib-dist/lib/host-runtime.js.map +1 -0
- package/lib-dist/lib/host.d.ts +190 -0
- package/lib-dist/lib/host.d.ts.map +1 -0
- package/lib-dist/lib/host.js +2 -0
- package/lib-dist/lib/host.js.map +1 -0
- package/lib-dist/lib/index.d.ts +34 -0
- package/lib-dist/lib/index.d.ts.map +1 -0
- package/lib-dist/lib/index.js +27 -0
- package/lib-dist/lib/index.js.map +1 -0
- package/lib-dist/lib/markdown-model.d.ts +7 -0
- package/lib-dist/lib/markdown-model.d.ts.map +1 -0
- package/lib-dist/lib/markdown-model.js +2031 -0
- package/lib-dist/lib/markdown-model.js.map +1 -0
- package/lib-dist/lib/markdown.d.ts +3 -0
- package/lib-dist/lib/markdown.d.ts.map +1 -0
- package/lib-dist/lib/markdown.js +222 -0
- package/lib-dist/lib/markdown.js.map +1 -0
- package/lib-dist/lib/schema.d.ts +167 -0
- package/lib-dist/lib/schema.d.ts.map +1 -0
- package/lib-dist/lib/schema.js +63 -0
- package/lib-dist/lib/schema.js.map +1 -0
- package/lib-dist/lib/terra/custom-components.d.ts +5 -0
- package/lib-dist/lib/terra/custom-components.d.ts.map +1 -0
- package/lib-dist/lib/terra/custom-components.js +6 -0
- package/lib-dist/lib/terra/custom-components.js.map +1 -0
- package/lib-dist/lib/terra/docs/archive.d.ts +3 -0
- package/lib-dist/lib/terra/docs/archive.d.ts.map +1 -0
- package/lib-dist/lib/terra/docs/archive.js +654 -0
- package/lib-dist/lib/terra/docs/archive.js.map +1 -0
- package/lib-dist/lib/terra/docs/assets.d.ts +26 -0
- package/lib-dist/lib/terra/docs/assets.d.ts.map +1 -0
- package/lib-dist/lib/terra/docs/assets.js +74 -0
- package/lib-dist/lib/terra/docs/assets.js.map +1 -0
- package/lib-dist/lib/terra/docs/attachments.d.ts +4 -0
- package/lib-dist/lib/terra/docs/attachments.d.ts.map +1 -0
- package/lib-dist/lib/terra/docs/attachments.js +5 -0
- package/lib-dist/lib/terra/docs/attachments.js.map +1 -0
- package/lib-dist/lib/terra/docs/editor-dom.d.ts +50 -0
- package/lib-dist/lib/terra/docs/editor-dom.d.ts.map +1 -0
- package/lib-dist/lib/terra/docs/editor-dom.js +236 -0
- package/lib-dist/lib/terra/docs/editor-dom.js.map +1 -0
- package/lib-dist/lib/terra/docs/mutations.d.ts +10 -0
- package/lib-dist/lib/terra/docs/mutations.d.ts.map +1 -0
- package/lib-dist/lib/terra/docs/mutations.js +105 -0
- package/lib-dist/lib/terra/docs/mutations.js.map +1 -0
- package/lib-dist/lib/terra/docs/navigation.d.ts +6 -0
- package/lib-dist/lib/terra/docs/navigation.d.ts.map +1 -0
- package/lib-dist/lib/terra/docs/navigation.js +21 -0
- package/lib-dist/lib/terra/docs/navigation.js.map +1 -0
- package/lib-dist/lib/terra/docs/state.d.ts +186 -0
- package/lib-dist/lib/terra/docs/state.d.ts.map +1 -0
- package/lib-dist/lib/terra/docs/state.js +255 -0
- package/lib-dist/lib/terra/docs/state.js.map +1 -0
- package/lib-dist/lib/terra/docs/toolbar.d.ts +11 -0
- package/lib-dist/lib/terra/docs/toolbar.d.ts.map +1 -0
- package/lib-dist/lib/terra/docs/toolbar.js +41 -0
- package/lib-dist/lib/terra/docs/toolbar.js.map +1 -0
- package/lib-dist/lib/terra/docs/tree.d.ts +15 -0
- package/lib-dist/lib/terra/docs/tree.d.ts.map +1 -0
- package/lib-dist/lib/terra/docs/tree.js +61 -0
- package/lib-dist/lib/terra/docs/tree.js.map +1 -0
- package/lib-dist/lib/terra/docs/workspace.d.ts +396 -0
- package/lib-dist/lib/terra/docs/workspace.d.ts.map +1 -0
- package/lib-dist/lib/terra/docs/workspace.js +923 -0
- package/lib-dist/lib/terra/docs/workspace.js.map +1 -0
- package/lib-dist/lib/terra/flow/_layout.d.ts +30 -0
- package/lib-dist/lib/terra/flow/_layout.d.ts.map +1 -0
- package/lib-dist/lib/terra/flow/_layout.js +63 -0
- package/lib-dist/lib/terra/flow/_layout.js.map +1 -0
- package/lib-dist/lib/terra/flow/powerSource.d.ts +16 -0
- package/lib-dist/lib/terra/flow/powerSource.d.ts.map +1 -0
- package/lib-dist/lib/terra/flow/powerSource.js +65 -0
- package/lib-dist/lib/terra/flow/powerSource.js.map +1 -0
- package/lib-dist/lib/terra/regex.mjs +403 -0
- package/lib-dist/lib/terra/runtime/action-proxy.d.ts +45 -0
- package/lib-dist/lib/terra/runtime/action-proxy.d.ts.map +1 -0
- package/lib-dist/lib/terra/runtime/action-proxy.js +19 -0
- package/lib-dist/lib/terra/runtime/action-proxy.js.map +1 -0
- package/lib-dist/lib/terra/runtime/content/block-jsx.d.ts +23 -0
- package/lib-dist/lib/terra/runtime/content/block-jsx.d.ts.map +1 -0
- package/lib-dist/lib/terra/runtime/content/block-jsx.js +225 -0
- package/lib-dist/lib/terra/runtime/content/block-jsx.js.map +1 -0
- package/lib-dist/lib/terra/runtime/content/document-markdown.d.ts +41 -0
- package/lib-dist/lib/terra/runtime/content/document-markdown.d.ts.map +1 -0
- package/lib-dist/lib/terra/runtime/content/document-markdown.js +536 -0
- package/lib-dist/lib/terra/runtime/content/document-markdown.js.map +1 -0
- package/lib-dist/lib/terra/runtime/content/markdown.d.ts +109 -0
- package/lib-dist/lib/terra/runtime/content/markdown.d.ts.map +1 -0
- package/lib-dist/lib/terra/runtime/content/markdown.js +428 -0
- package/lib-dist/lib/terra/runtime/content/markdown.js.map +1 -0
- package/lib-dist/lib/terra/runtime/content.d.ts +150 -0
- package/lib-dist/lib/terra/runtime/content.d.ts.map +1 -0
- package/lib-dist/lib/terra/runtime/content.js +1256 -0
- package/lib-dist/lib/terra/runtime/content.js.map +1 -0
- package/lib-dist/lib/terra/runtime/leaf.d.ts +5 -0
- package/lib-dist/lib/terra/runtime/leaf.d.ts.map +1 -0
- package/lib-dist/lib/terra/runtime/leaf.js +13 -0
- package/lib-dist/lib/terra/runtime/leaf.js.map +1 -0
- package/lib-dist/lib/terra/runtime/nodes.d.ts +112 -0
- package/lib-dist/lib/terra/runtime/nodes.d.ts.map +1 -0
- package/lib-dist/lib/terra/runtime/nodes.js +606 -0
- package/lib-dist/lib/terra/runtime/nodes.js.map +1 -0
- package/lib-dist/lib/terra/runtime/runtime.d.ts +31 -0
- package/lib-dist/lib/terra/runtime/runtime.d.ts.map +1 -0
- package/lib-dist/lib/terra/runtime/runtime.js +86 -0
- package/lib-dist/lib/terra/runtime/runtime.js.map +1 -0
- package/lib-dist/lib/terra/runtime/shared.d.ts +35 -0
- package/lib-dist/lib/terra/runtime/shared.d.ts.map +1 -0
- package/lib-dist/lib/terra/runtime/shared.js +124 -0
- package/lib-dist/lib/terra/runtime/shared.js.map +1 -0
- package/lib-dist/lib/terra/runtime/types.d.ts +529 -0
- package/lib-dist/lib/terra/runtime/types.d.ts.map +1 -0
- package/lib-dist/lib/terra/runtime/types.js +44 -0
- package/lib-dist/lib/terra/runtime/types.js.map +1 -0
- package/lib-dist/lib/workspace-types.d.ts +29 -0
- package/lib-dist/lib/workspace-types.d.ts.map +1 -0
- package/lib-dist/lib/workspace-types.js +2 -0
- package/lib-dist/lib/workspace-types.js.map +1 -0
- package/lib-dist/style.css +237 -0
- package/package.json +108 -3
- package/src/components/NotFound.astro +6 -0
- package/src/components/NotFound.tsx +48 -0
- package/src/components/SiteLayout.astro +42 -0
- package/src/components/navigation.tsx +48 -0
|
@@ -0,0 +1,1256 @@
|
|
|
1
|
+
// @ts-nocheck -- canonical website serializer, now isolated from host imports.
|
|
2
|
+
/**
|
|
3
|
+
* astro/src/actions/docs/content.ts
|
|
4
|
+
* Shared helpers for normalizing and serializing docs content versions, syntax, and tables.
|
|
5
|
+
*/
|
|
6
|
+
/*//////////////////////////////////////////////////
|
|
7
|
+
IMPORTS
|
|
8
|
+
//////////////////////////////////////////////////*/
|
|
9
|
+
// API
|
|
10
|
+
import { createTrace } from './runtime.js';
|
|
11
|
+
import { encodeNodesPayload } from './nodes.js';
|
|
12
|
+
import { isEndpointVal } from './shared.js';
|
|
13
|
+
// COMPONENTS
|
|
14
|
+
import * as TerraQualityRegex from '../regex.mjs';
|
|
15
|
+
// DATA
|
|
16
|
+
import { TESTIMONIALS_EXPORT } from './shared.js';
|
|
17
|
+
/*//////////////////////////////////////////////////
|
|
18
|
+
CONFIG
|
|
19
|
+
//////////////////////////////////////////////////*/
|
|
20
|
+
/**
|
|
21
|
+
* Checks whether a value is a plain record.
|
|
22
|
+
*
|
|
23
|
+
* @param val - Candidate value to narrow to a non-array record.
|
|
24
|
+
*
|
|
25
|
+
* @returns True when the value is a non-array object with own properties.
|
|
26
|
+
*/
|
|
27
|
+
const isRec = (val) => Boolean(val && typeof val === 'object' && !Array.isArray(val));
|
|
28
|
+
const trace = createTrace('DOCS:content', false);
|
|
29
|
+
trace('module.loaded');
|
|
30
|
+
// prettier-ignore
|
|
31
|
+
/** Portable Text object types accepted by problem authoring. */
|
|
32
|
+
export const PROBLEM_BLOCK_TYPES = [
|
|
33
|
+
'hint', 'headline', 'nodes', 'entity', 'definition', 'countryReference', 'notes', 'photo', 'audio',
|
|
34
|
+
'video', 'choicesReference', 'question', 'prompts', 'timer', 'table', 'map', 'tabs', 'accordion',
|
|
35
|
+
];
|
|
36
|
+
/*//////////////////////////////////////////////////
|
|
37
|
+
HELPERS
|
|
38
|
+
//////////////////////////////////////////////////*/
|
|
39
|
+
/**
|
|
40
|
+
* Checks whether a value is a Portable Text span node.
|
|
41
|
+
*
|
|
42
|
+
* @param val - Candidate Portable Text node to narrow to a text span.
|
|
43
|
+
*
|
|
44
|
+
* @returns True when the value is a Portable Text span node.
|
|
45
|
+
*/
|
|
46
|
+
const ptText = (val) => isRec(val) && val._type === 'span';
|
|
47
|
+
/** Narrows persisted mark definitions before the Markdown serializer reads link fields. */
|
|
48
|
+
const ptMarkDefs = (val) => Array.isArray(val)
|
|
49
|
+
? val.filter((d) => isRec(d) &&
|
|
50
|
+
d._type === 'link' &&
|
|
51
|
+
(d._key === undefined || typeof d._key === 'string') &&
|
|
52
|
+
(d.href === undefined || typeof d.href === 'string'))
|
|
53
|
+
: [];
|
|
54
|
+
/**
|
|
55
|
+
* Wraps text in the Portable Text marks used by the docs serializer.
|
|
56
|
+
*
|
|
57
|
+
* @param text - Text content to decorate.
|
|
58
|
+
* @param marks - Marks to apply in render order.
|
|
59
|
+
* @param defs - Portable Text mark definitions.
|
|
60
|
+
*
|
|
61
|
+
* @returns Text wrapped in the mark syntax used by docs Markdown.
|
|
62
|
+
*/
|
|
63
|
+
const renderMarks = (text, marks, defs) => marks.reduce((a, m) => {
|
|
64
|
+
if (m === 'code')
|
|
65
|
+
return `\`${a}\``;
|
|
66
|
+
if (m === 'em')
|
|
67
|
+
return `_${a}_`;
|
|
68
|
+
if (m === 'strong')
|
|
69
|
+
return `**${a}**`;
|
|
70
|
+
const href = defs.find((d) => d._key === m && typeof d.href === 'string')?.href;
|
|
71
|
+
return href ? `[${a}](${href})` : a;
|
|
72
|
+
}, text);
|
|
73
|
+
/**
|
|
74
|
+
* Reads the list style flag from a Portable Text block, if one was stored.
|
|
75
|
+
*
|
|
76
|
+
* @param val - Portable Text block or other persisted value whose list marker is inspected.
|
|
77
|
+
*
|
|
78
|
+
* @returns Stored list style, or an empty string when the block is not part of a list.
|
|
79
|
+
*/
|
|
80
|
+
const listKind = (val) => isRec(val) && typeof val.listItem === 'string' ? val.listItem : '';
|
|
81
|
+
/**
|
|
82
|
+
* Serializes a string literal so it can be embedded safely in JSX attributes.
|
|
83
|
+
*
|
|
84
|
+
* @param value - String literal to quote.
|
|
85
|
+
*
|
|
86
|
+
* @returns A quoted string literal that can survive MDX parsing unchanged.
|
|
87
|
+
*/
|
|
88
|
+
const quote = (val) => JSON.stringify(val);
|
|
89
|
+
/**
|
|
90
|
+
* Escapes HTML control characters before text is embedded in serialized docs markup.
|
|
91
|
+
*
|
|
92
|
+
* @param value - HTML text to escape.
|
|
93
|
+
*
|
|
94
|
+
* @returns Text with HTML metacharacters escaped for serialization.
|
|
95
|
+
*/
|
|
96
|
+
const escHtml = (val) => val
|
|
97
|
+
.replace(TerraQualityRegex.REGEX_G_REGEX_17(), '&')
|
|
98
|
+
.replace(TerraQualityRegex.REGEX_G_REGEX_23(), '<')
|
|
99
|
+
.replace(TerraQualityRegex.REGEX_G_REGEX_24(), '>')
|
|
100
|
+
.replace(TerraQualityRegex.REGEX_G_REGEX_5(), '"')
|
|
101
|
+
.replace(TerraQualityRegex.REGEX_G_REGEX_4(), ''');
|
|
102
|
+
/**
|
|
103
|
+
* Extracts readable text from nested docs content when structured serializers cannot recover it.
|
|
104
|
+
*
|
|
105
|
+
* @param val - Nested docs content or leaf payload.
|
|
106
|
+
*
|
|
107
|
+
* @returns Plain text recovered from the input.
|
|
108
|
+
*/
|
|
109
|
+
const bodyText = (val) => {
|
|
110
|
+
if (typeof val === 'string')
|
|
111
|
+
return val;
|
|
112
|
+
if (!val)
|
|
113
|
+
return '';
|
|
114
|
+
if (Array.isArray(val))
|
|
115
|
+
return val.map(bodyText).join('');
|
|
116
|
+
if (!isRec(val))
|
|
117
|
+
return '';
|
|
118
|
+
if (typeof val.text === 'string')
|
|
119
|
+
return val.text;
|
|
120
|
+
if (typeof val.markdown === 'string' && val.markdown.trim())
|
|
121
|
+
return fromBlockJsx(val.markdown).replace(TerraQualityRegex.REGEX_G_REGEX_22(), '');
|
|
122
|
+
if (typeof val.html === 'string' && val.html.trim())
|
|
123
|
+
return val.html.replace(TerraQualityRegex.REGEX_G_REGEX_22(), ' ');
|
|
124
|
+
const children = Array.isArray(val.children) ? val.children : [];
|
|
125
|
+
return bodyText(children.length > 0 ? children : (val.c ?? val.content ?? val.body ?? []));
|
|
126
|
+
};
|
|
127
|
+
/*//////////////////////////////////////////////////
|
|
128
|
+
BLOCK SYNTAX
|
|
129
|
+
//////////////////////////////////////////////////*/
|
|
130
|
+
/**
|
|
131
|
+
* Registry of the custom accordion and tabs block syntaxes used in docs content.
|
|
132
|
+
*
|
|
133
|
+
* @remarks
|
|
134
|
+
* The registry is intentionally tiny so the parser can stay predictable.
|
|
135
|
+
*/
|
|
136
|
+
const BLOCKS = [
|
|
137
|
+
{
|
|
138
|
+
id: 'accordion',
|
|
139
|
+
syntax: '===',
|
|
140
|
+
root: 'AccordionGroup',
|
|
141
|
+
item: 'AccordionItem',
|
|
142
|
+
label: 'Accordion',
|
|
143
|
+
},
|
|
144
|
+
{ id: 'tabs', syntax: '|||', root: 'TabsGroup', item: 'TabsItem', label: 'Tabs' },
|
|
145
|
+
];
|
|
146
|
+
/**
|
|
147
|
+
* Handles docs editor mount ids.
|
|
148
|
+
*
|
|
149
|
+
* @param source - Source text containing the Docs blocks to parse.
|
|
150
|
+
*/
|
|
151
|
+
export const docsEditorMountIds = (src) => {
|
|
152
|
+
return [
|
|
153
|
+
'root',
|
|
154
|
+
...Array.from(toBlockJsx(src)
|
|
155
|
+
.replace(/```[\s\S]*?```/g, '')
|
|
156
|
+
.replace(TerraQualityRegex.REGEX_CODE_B_S_S_CODE_G_REGEX(), '')
|
|
157
|
+
.replace(/<TabsGroup\b[^>]*>([\s\S]*?)<\/TabsGroup>/g, (g, i) => `${g.slice(0, g.indexOf('>') + 1)}${i.match(/<TabsItem\b[\s\S]*?<\/TabsItem>/)?.[0] || ''}</TabsGroup>`)
|
|
158
|
+
.matchAll(/<(AccordionGroup|AccordionItem|TabsGroup|DocsTable|Nodes)\b/g), (m) => `${m[1]}:${m.index}`),
|
|
159
|
+
];
|
|
160
|
+
};
|
|
161
|
+
/** Returns stable mount identifiers for every asynchronous Docs editor renderer. */
|
|
162
|
+
/**
|
|
163
|
+
* Separates compact tabs markers before they reach the line-based block parser.
|
|
164
|
+
*
|
|
165
|
+
* @param md - Markdown or MDX source containing docs block markers.
|
|
166
|
+
*
|
|
167
|
+
* @returns Source with tab labels, bodies, and adjacent delimiters on distinct lines.
|
|
168
|
+
*/
|
|
169
|
+
const normBlockMarkers = (md) => md
|
|
170
|
+
.replace(/([^\n])[ \t]+(?=\|\|\|(?:[ \t]*(?:\|\|\||$)))/g, '$1\n\n')
|
|
171
|
+
.replace(/(\|\|\|[ \t]*\[[^\]\n]*\])[ \t]+(?=\S)/g, '$1\n\n')
|
|
172
|
+
.replace(/(^|\n)[ \t]*\|\|\|[ \t]+(?=\|\|\|[ \t]*\[)/gm, '$1|||\n\n');
|
|
173
|
+
/**
|
|
174
|
+
* Rewrites the supported docs block markers into their JSX wrapper forms.
|
|
175
|
+
*
|
|
176
|
+
* @param md - Markdown or MDX source to normalize.
|
|
177
|
+
*
|
|
178
|
+
* @return Source where supported block markers have been rewritten to their JSX wrappers.
|
|
179
|
+
*
|
|
180
|
+
* @remarks
|
|
181
|
+
* Only the supported block syntaxes are rewritten; everything else is preserved.
|
|
182
|
+
*/
|
|
183
|
+
export function toBlockJsx(md) {
|
|
184
|
+
if (!md)
|
|
185
|
+
return '';
|
|
186
|
+
const code = new Map();
|
|
187
|
+
const lns = normBlockMarkers(md)
|
|
188
|
+
.replace(TerraQualityRegex.REGEX_CODE_B_S_S_CODE_G_REGEX(), (m) => {
|
|
189
|
+
const key = `TERRA_CODE_${code.size}`;
|
|
190
|
+
code.set(key, m);
|
|
191
|
+
return key;
|
|
192
|
+
})
|
|
193
|
+
.replace(TerraQualityRegex.REGEX_S_S_N_G_REGEX(), (m) => {
|
|
194
|
+
let res = '';
|
|
195
|
+
for (let i = 0; i < m.length; i++)
|
|
196
|
+
res +=
|
|
197
|
+
m[i] && ['{', '}', '<', '>'].includes(m[i]) && (i === 0 || m[i - 1] !== '\\')
|
|
198
|
+
? '\\' + m[i]
|
|
199
|
+
: (m[i] ?? '');
|
|
200
|
+
return res;
|
|
201
|
+
})
|
|
202
|
+
.replace(TerraQualityRegex.REGEX_XA0_U2002_U2003_U200B_G_REGEX(), ' ')
|
|
203
|
+
.split(TerraQualityRegex.REGEX_R_N_REGEX());
|
|
204
|
+
const res = [];
|
|
205
|
+
let icode = false;
|
|
206
|
+
const grp = new Set();
|
|
207
|
+
const itm = new Set();
|
|
208
|
+
for (let i = 0; i < lns.length; i++) {
|
|
209
|
+
const line = lns[i];
|
|
210
|
+
const t = line.trimStart();
|
|
211
|
+
const tClean = t.trimEnd();
|
|
212
|
+
if (t.startsWith('```')) {
|
|
213
|
+
icode = !icode;
|
|
214
|
+
res.push(t);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (icode) {
|
|
218
|
+
res.push(line);
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
const _m = BLOCKS.find((b) => tClean.startsWith(b.syntax));
|
|
222
|
+
if (_m) {
|
|
223
|
+
const rM = tClean.match(new RegExp(`^${_m.syntax.replace(TerraQualityRegex.REGEX_G_REGEX_9(), '\\$&')}(?:\\s*\\[(.*?)\\])?$`));
|
|
224
|
+
if (tClean === _m.syntax) {
|
|
225
|
+
if (itm.has(_m.item)) {
|
|
226
|
+
res.push('', `</${_m.item}>`);
|
|
227
|
+
itm.delete(_m.item);
|
|
228
|
+
}
|
|
229
|
+
let nIsSameGroup = false;
|
|
230
|
+
for (let j = i + 1; j < lns.length; j++) {
|
|
231
|
+
const nLine = lns[j]?.trim();
|
|
232
|
+
if (!nLine)
|
|
233
|
+
continue;
|
|
234
|
+
if (nLine.startsWith(_m.syntax) && nLine !== _m.syntax)
|
|
235
|
+
nIsSameGroup = true;
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
if (!nIsSameGroup && grp.has(_m.label)) {
|
|
239
|
+
res.push(`</${_m.root}>`, '');
|
|
240
|
+
grp.delete(_m.label);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
else if (rM) {
|
|
244
|
+
if (itm.has(_m.item)) {
|
|
245
|
+
res.push('', `</${_m.item}>`);
|
|
246
|
+
itm.delete(_m.item);
|
|
247
|
+
}
|
|
248
|
+
if (!grp.has(_m.label)) {
|
|
249
|
+
res.push('', `<${_m.root}>`);
|
|
250
|
+
grp.add(_m.label);
|
|
251
|
+
}
|
|
252
|
+
res.push(`<${_m.item} title=${quote(rM?.[1] || 'Section')}>`, '');
|
|
253
|
+
itm.add(_m.item);
|
|
254
|
+
}
|
|
255
|
+
else
|
|
256
|
+
res.push(t);
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
res.push(line);
|
|
260
|
+
}
|
|
261
|
+
for (const label of grp) {
|
|
262
|
+
const b = BLOCKS.find((x) => x.label === label);
|
|
263
|
+
if (b) {
|
|
264
|
+
if (itm.has(b.item)) {
|
|
265
|
+
res.push('', `</${b.item}>`);
|
|
266
|
+
itm.delete(b.item);
|
|
267
|
+
}
|
|
268
|
+
res.push(`</${b.root}>`, '');
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const n = res.join('\n');
|
|
272
|
+
return code.size
|
|
273
|
+
? n.replace(TerraQualityRegex.REGEX_TERRA_CODE_D_G_REGEX(), (k) => code.get(k) || k)
|
|
274
|
+
: n;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Restores the custom docs JSX wrappers back to the markdown block syntax they came from.
|
|
278
|
+
*
|
|
279
|
+
* @param jsx - Canonical JSX source to restore.
|
|
280
|
+
*
|
|
281
|
+
* @return Markdown where supported docs JSX wrappers have been converted back to block syntax.
|
|
282
|
+
*
|
|
283
|
+
* @remarks
|
|
284
|
+
* This is the inverse of `toBlockJsx` for the supported docs block shapes.
|
|
285
|
+
*/
|
|
286
|
+
export function fromBlockJsx(jsx) {
|
|
287
|
+
if (!jsx)
|
|
288
|
+
return '';
|
|
289
|
+
const code = new Map();
|
|
290
|
+
let _rs = toCodeJsx(jsx)
|
|
291
|
+
.replace(/<Code\b[\s\S]*?<\/Code>/g, (m) => {
|
|
292
|
+
const key = `TERRA_CODE_${code.size}`;
|
|
293
|
+
code.set(key, m);
|
|
294
|
+
return key;
|
|
295
|
+
})
|
|
296
|
+
.replace(/^\\?=\\?=\\?=/gm, '===')
|
|
297
|
+
.replace(/^\\?\|\\?\|\\?\|/gm, '|||')
|
|
298
|
+
.replace(/^\\?:\\?:\\?:/gm, ':::')
|
|
299
|
+
.replace(/^(===|\|\|\||\^\^\^|:::)[ \t]*\\?\[(.*?)\\?\]/gm, (_m, p, c) => `${p}[${c.replace(/\\\]/g, ']').replace(/\\\[/g, '[')}]`);
|
|
300
|
+
_rs = _rs
|
|
301
|
+
.replace(TerraQualityRegex.REGEX_XA0_U2002_U2003_U200B_G_REGEX(), ' ')
|
|
302
|
+
.replace(/<DocsMath\b([\s\S]*?)code=(?:\{\s*("(?:\\[\s\S]|[^"\\])*"|'(?:\\[\s\S]|[^'\\])*'|`(?:\\[\s\S]|[^`\\])*`)\s*\}|(["'])([\s\S]*?)\3)([\s\S]*?)\/>/gi, (_m, p, e, _quote, s, v) => {
|
|
303
|
+
// prettier-ignore
|
|
304
|
+
const parsed = e
|
|
305
|
+
? e.startsWith('`')
|
|
306
|
+
? e.slice(1, -1).replace(TerraQualityRegex.REGEX_G_REGEX_15(), '`').replace(TerraQualityRegex.REGEX_G_REGEX_14(), '$').replace(TerraQualityRegex.REGEX_G_REGEX_13(), '\\')
|
|
307
|
+
: e.startsWith('"') ? JSON.parse(e.replace(TerraQualityRegex.REGEX_N_G_REGEX_3(), '\\n')) : e.slice(1, -1).replace(/\\([`'"])/g, '$1')
|
|
308
|
+
: s;
|
|
309
|
+
return TerraQualityRegex.REGEX_BINLINE_B_I_REGEX().test(p) ||
|
|
310
|
+
TerraQualityRegex.REGEX_BINLINE_B_I_REGEX().test(v)
|
|
311
|
+
? `$${parsed}$`
|
|
312
|
+
: `\n\n$$${parsed}$$\n\n`;
|
|
313
|
+
})
|
|
314
|
+
.replace(TerraQualityRegex.REGEX_S_S_N_G_REGEX(), (_m) => _m.replace(/\\\{/g, '{').replace(/\\\}/g, '}').replace(/\\</g, '<').replace(/\\>/g, '>'));
|
|
315
|
+
_rs = _rs
|
|
316
|
+
.replace(/(<\/?(?:AccordionGroup|TabsGroup|AccordionItem|TabsItem)\b[^>]*>)/g, '\n$1\n')
|
|
317
|
+
.replace(TerraQualityRegex.REGEX_N_3_G_REGEX(), '\n\n');
|
|
318
|
+
if (code.size)
|
|
319
|
+
_rs = _rs.replace(TerraQualityRegex.REGEX_TERRA_CODE_D_G_REGEX(), (k) => code.get(k) || k);
|
|
320
|
+
const lns = _rs.split('\n');
|
|
321
|
+
const out = [];
|
|
322
|
+
let icode = false;
|
|
323
|
+
let pad = '';
|
|
324
|
+
for (let i = 0; i < lns.length; i++) {
|
|
325
|
+
const raw = lns[i] || '';
|
|
326
|
+
const t = raw.trimStart();
|
|
327
|
+
if (t.startsWith('```')) {
|
|
328
|
+
icode = !icode;
|
|
329
|
+
if (icode)
|
|
330
|
+
pad = raw.match(/^[ \t]*/)?.[0] || '';
|
|
331
|
+
out.push(t);
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (icode) {
|
|
335
|
+
out.push(raw.startsWith(pad) ? raw.slice(pad.length) : t);
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
if (BLOCKS.find((b) => t === `<${b.root}>`)) {
|
|
339
|
+
out.push('');
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
if (BLOCKS.find((b) => t === `</${b.root}>`)) {
|
|
343
|
+
out.push('');
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
if (BLOCKS.find((b) => {
|
|
347
|
+
const match = t.match(new RegExp(`^<${b.item}\\b[^>]*title="([^"]*)"[^>]*>$`));
|
|
348
|
+
if (!match)
|
|
349
|
+
return false;
|
|
350
|
+
out.push(`\n\n${b.syntax}[${match[1] || 'Section'}]\n\n`);
|
|
351
|
+
return true;
|
|
352
|
+
}))
|
|
353
|
+
continue;
|
|
354
|
+
const itemClose = BLOCKS.find((b) => t === `</${b.item}>`);
|
|
355
|
+
if (itemClose) {
|
|
356
|
+
out.push(`\n\n${itemClose.syntax}\n\n`);
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (t.length === 0) {
|
|
360
|
+
out.push('');
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (/^(===|\|\|\||\^\^\^|:::)/.test(t)) {
|
|
364
|
+
out.push(t);
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
out.push(raw.replace(/^[ \t]{1,8}/, ''));
|
|
368
|
+
}
|
|
369
|
+
return (
|
|
370
|
+
/* prettier-ignore */ out.join('\n').replace(TerraQualityRegex.REGEX_N_3_G_REGEX(), '\n\n').trim() + '\n');
|
|
371
|
+
}
|
|
372
|
+
/*//////////////////////////////////////////////////
|
|
373
|
+
CODE SYNTAX
|
|
374
|
+
//////////////////////////////////////////////////*/
|
|
375
|
+
/**
|
|
376
|
+
* Emits the optional language attribute used by serialized code fences.
|
|
377
|
+
*
|
|
378
|
+
* @param language - Code fence language label.
|
|
379
|
+
*
|
|
380
|
+
* @returns `language` attribute when the fence declares one, otherwise an empty string.
|
|
381
|
+
*/
|
|
382
|
+
const codeAttrs = (lang) => lang?.trim() ? ` language=${JSON.stringify(lang.trim())}` : '';
|
|
383
|
+
/**
|
|
384
|
+
* Converts any code payload into a printable string before it is written into docs markup.
|
|
385
|
+
*
|
|
386
|
+
* @param val - Any code-like value to stringify.
|
|
387
|
+
*
|
|
388
|
+
* @return Printable code string used by the markdown and MDX serializers.
|
|
389
|
+
*
|
|
390
|
+
* @remarks
|
|
391
|
+
* Prefers compact primitives and pretty-prints structured values.
|
|
392
|
+
*/
|
|
393
|
+
export function stringifyCodeValue(val) {
|
|
394
|
+
if (typeof val === 'string') {
|
|
395
|
+
let n = val;
|
|
396
|
+
for (let i = 0; i < 16; i++) {
|
|
397
|
+
const match = n.match(/^\s*\{`([\s\S]*)`}\s*$/);
|
|
398
|
+
if (!match)
|
|
399
|
+
break;
|
|
400
|
+
const unwrapped = match[1]
|
|
401
|
+
.replace(TerraQualityRegex.REGEX_G_REGEX_11(), '$1')
|
|
402
|
+
.replace(TerraQualityRegex.REGEX_N_G_REGEX_2(), '\n');
|
|
403
|
+
if (unwrapped === n)
|
|
404
|
+
break;
|
|
405
|
+
n = unwrapped;
|
|
406
|
+
}
|
|
407
|
+
return n.replace(/\\r\\n|\\n|\\r/g, (m) => (m === '\\r' ? '\r' : '\n'));
|
|
408
|
+
}
|
|
409
|
+
if (typeof val === 'number' || typeof val === 'boolean' || typeof val === 'bigint')
|
|
410
|
+
return String(val);
|
|
411
|
+
if (val == null)
|
|
412
|
+
return '';
|
|
413
|
+
try {
|
|
414
|
+
return JSON.stringify(val, null, 2);
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
return String(val);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Serializes fenced code into the canonical `<Code>` JSX used by docs content.
|
|
422
|
+
*
|
|
423
|
+
* @param lang - Code fence language label.
|
|
424
|
+
* @param val - Raw code text.
|
|
425
|
+
*
|
|
426
|
+
* @return Canonical `Code` JSX for the code block.
|
|
427
|
+
*
|
|
428
|
+
* @remarks
|
|
429
|
+
* The code payload is HTML-escaped so it can round-trip through MDX safely.
|
|
430
|
+
*/
|
|
431
|
+
export function codeJsx(lang, val) {
|
|
432
|
+
return `\n<Code${codeAttrs(lang)}>\n{\`
|
|
433
|
+
${val.replace(TerraQualityRegex.REGEX_G_REGEX_12(), '\\\\').replace(TerraQualityRegex.REGEX_G_REGEX_18(), '\\`').replace(TerraQualityRegex.REGEX_G_REGEX_16(), '\\$')}
|
|
434
|
+
\`}\n</Code>\n`;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Handles code src jsx.
|
|
438
|
+
*
|
|
439
|
+
* @param lang - Code language label used for the generated code block.
|
|
440
|
+
* @param src - Source code text to wrap in the code block.
|
|
441
|
+
*/
|
|
442
|
+
export const codeSrcJsx = (lang, src) => `\n<Code${codeAttrs(lang)} source=${quote(src)} />\n`;
|
|
443
|
+
/**
|
|
444
|
+
* Normalizes markdown fences into the canonical Code JSX form.
|
|
445
|
+
*
|
|
446
|
+
* @param src - Markdown, fenced code, or legacy HTML source.
|
|
447
|
+
*
|
|
448
|
+
* @return Canonical `Code` JSX where code blocks were found.
|
|
449
|
+
*
|
|
450
|
+
* @remarks
|
|
451
|
+
* The function leaves unrelated prose untouched so callers can run it on whole documents.
|
|
452
|
+
*/
|
|
453
|
+
export function toCodeJsx(src) {
|
|
454
|
+
if (!src)
|
|
455
|
+
return '';
|
|
456
|
+
const out = [];
|
|
457
|
+
let fenced = false;
|
|
458
|
+
let lang = '';
|
|
459
|
+
let body = [];
|
|
460
|
+
for (const line of src.replace(TerraQualityRegex.REGEX_R_N_G_REGEX(), '\n').split('\n')) {
|
|
461
|
+
const trim = line.trimStart();
|
|
462
|
+
if (trim.startsWith('```')) {
|
|
463
|
+
if (fenced) {
|
|
464
|
+
out.push(codeJsx(lang, body.join('\n')));
|
|
465
|
+
lang = '';
|
|
466
|
+
body = [];
|
|
467
|
+
}
|
|
468
|
+
fenced = !fenced;
|
|
469
|
+
if (fenced) {
|
|
470
|
+
lang = trim.slice(3).trim();
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
if (fenced) {
|
|
476
|
+
body.push(line);
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
out.push(line);
|
|
480
|
+
}
|
|
481
|
+
let res = out.join('\n');
|
|
482
|
+
const blocks = [];
|
|
483
|
+
res = protectMarkupBlocks(res, 'Code', blocks);
|
|
484
|
+
if (res.includes('<pre><code'))
|
|
485
|
+
res = res.replace(/<pre><code(?:\s+class="language-([^"]+)")?>([\s\S]*?)<\/code><\/pre>/gi, (_, l, v) => codeJsx(l || '', v));
|
|
486
|
+
if (/<(?:td|th)\b[^>]*>\s*<code\b/i.test(res))
|
|
487
|
+
res = res.replace(/<(t[dh])(\b[^>]*)>\s*<code(?:\s+class="language-([^"]+)")?>([\s\S]*?)<\/code>\s*<\/\1>/gi, (_, t, a, l, v) => `<${t}${a}>${codeJsx(l || '', v
|
|
488
|
+
.replace(/ /g, '\n')
|
|
489
|
+
.replace(/ /g, '\r')
|
|
490
|
+
.replace(TerraQualityRegex.REGEX_QUOT_G_REGEX(), '"')
|
|
491
|
+
.replace(/'/g, "'")
|
|
492
|
+
.replace(TerraQualityRegex.REGEX_AMP_G_REGEX(), '&')
|
|
493
|
+
.replace(TerraQualityRegex.REGEX_LT_G_REGEX(), '<')
|
|
494
|
+
.replace(TerraQualityRegex.REGEX_GT_G_REGEX(), '>'))}</${t}>`);
|
|
495
|
+
res = res.replace(/<Code\b([\s\S]*?)\s+code=(?:"([\s\S]*?)"|\{`((?:\\.|[^`])*?)`\})\s*\/>/g, (_match, p, q, e) => {
|
|
496
|
+
return `<Code${p} source=${quote(e !== undefined ? e.replace(TerraQualityRegex.REGEX_G_REGEX_11(), '$1') : q)} />`;
|
|
497
|
+
});
|
|
498
|
+
return blocks.reduce((n, b, i) => n.replace(new RegExp(`TERRA_PROTECTED_${i}__`, 'g'), b), res);
|
|
499
|
+
}
|
|
500
|
+
/*//////////////////////////////////////////////////
|
|
501
|
+
TABLE HTML
|
|
502
|
+
//////////////////////////////////////////////////*/
|
|
503
|
+
/**
|
|
504
|
+
* Removes the outer `|` characters from a pipe-table row while respecting escaped pipes.
|
|
505
|
+
*
|
|
506
|
+
* @param value - Pipe-delimited text to trim.
|
|
507
|
+
* @param side - Side of the pipe to trim.
|
|
508
|
+
*
|
|
509
|
+
* @returns Row fragment with the requested outer pipe removed.
|
|
510
|
+
*/
|
|
511
|
+
const trimPipe = (val, side) => {
|
|
512
|
+
if (side === 'start' && val.startsWith('|'))
|
|
513
|
+
return val.slice(1);
|
|
514
|
+
if (side === 'end' && val.endsWith('|')) {
|
|
515
|
+
let slashes = 0;
|
|
516
|
+
for (let i = val.length - 2; i >= 0 && val[i] === '\\'; i--)
|
|
517
|
+
slashes++;
|
|
518
|
+
return slashes % 2 === 0 ? val.slice(0, -1) : val;
|
|
519
|
+
}
|
|
520
|
+
return val;
|
|
521
|
+
};
|
|
522
|
+
/**
|
|
523
|
+
* Renders a markdown pipe table into HTML when the row widths and separator row are valid.
|
|
524
|
+
*
|
|
525
|
+
* @param md - Table markdown to render.
|
|
526
|
+
* @param renderCell - Cell renderer used for each value.
|
|
527
|
+
*
|
|
528
|
+
* @returns HTML table markup when the input is a valid pipe table, otherwise `null`.
|
|
529
|
+
*
|
|
530
|
+
* @remarks
|
|
531
|
+
* Callers can supply a custom cell renderer to preserve nested markdown or JSX.
|
|
532
|
+
*/
|
|
533
|
+
export const mdTableToHtml = (md, renderCell = escHtml) => {
|
|
534
|
+
const lines = md.replace(TerraQualityRegex.REGEX_R_N_G_REGEX(), '\n').trim().split('\n');
|
|
535
|
+
if (lines.length < 2 || lines.some((l) => !l.trim()))
|
|
536
|
+
return null;
|
|
537
|
+
const rows = lines.map((line) => {
|
|
538
|
+
const cells = [];
|
|
539
|
+
let cell = '';
|
|
540
|
+
let esc = false;
|
|
541
|
+
for (const ch of trimPipe(trimPipe(line.trim(), 'start'), 'end')) {
|
|
542
|
+
if (esc) {
|
|
543
|
+
cell += ch;
|
|
544
|
+
esc = false;
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
if (ch === '\\') {
|
|
548
|
+
esc = true;
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
551
|
+
if (ch === '|') {
|
|
552
|
+
cells.push(cell.trim());
|
|
553
|
+
cell = '';
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
cell += ch;
|
|
557
|
+
}
|
|
558
|
+
cells.push(cell.trim());
|
|
559
|
+
return cells;
|
|
560
|
+
});
|
|
561
|
+
const width = rows[0]?.length || 0;
|
|
562
|
+
if (!width ||
|
|
563
|
+
rows.some((r) => r.length !== width) ||
|
|
564
|
+
!rows[1]?.every((val) => /^:?-{3,}:?$/u.test(val.trim())))
|
|
565
|
+
return null;
|
|
566
|
+
// prettier-ignore
|
|
567
|
+
const body = rows.slice(2).map(r => `<tr>${r.map(c => `<td>${renderCell(c)}</td>`).join('')}</tr>`).join('');
|
|
568
|
+
return `<table><thead><tr>${ /* prettier-ignore */rows[0].map(renderCell).map(c => `<th>${c}</th>`).join('')}</tr></thead>${body ? `<tbody>${body}</tbody>` : ''}</table>`;
|
|
569
|
+
};
|
|
570
|
+
/*//////////////////////////////////////////////////
|
|
571
|
+
CONTENT SERIALIZATION
|
|
572
|
+
//////////////////////////////////////////////////*/
|
|
573
|
+
/**
|
|
574
|
+
* Converts plain markdown into HTML for the serializer's fallback path.
|
|
575
|
+
*
|
|
576
|
+
* @param value - Markdown source to parse.
|
|
577
|
+
*
|
|
578
|
+
* @returns Rendered HTML string used when markdown does not map to richer docs blocks.
|
|
579
|
+
*/
|
|
580
|
+
const renderMd = (val) => {
|
|
581
|
+
const text = val.trim();
|
|
582
|
+
if (!text)
|
|
583
|
+
return '';
|
|
584
|
+
const code = text.match(/^```([^\n`]*)\n([\s\S]*?)\n```$/);
|
|
585
|
+
if (code)
|
|
586
|
+
return `<pre><code${code[1]?.trim() ? ` class="language-${escHtml(code[1].trim())}"` : ''}>${escHtml(code[2] || '')}</code></pre>`;
|
|
587
|
+
const codes = [];
|
|
588
|
+
const lines = text.split(/\n{2,}/);
|
|
589
|
+
let html = escHtml(text)
|
|
590
|
+
.replace(/`([^`]+)`/g, (_, c) => {
|
|
591
|
+
codes.push(`<code>${escHtml(c)}</code>`);
|
|
592
|
+
return `__CODE_${codes.length - 1}__`;
|
|
593
|
+
})
|
|
594
|
+
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, l, h) => `<a href="${escHtml(h)}">${l}</a>`)
|
|
595
|
+
.replace(TerraQualityRegex.REGEX_S_S_G_REGEX(), '<strong>$1</strong>')
|
|
596
|
+
.replace(TerraQualityRegex.REGEX_N_G_REGEX(), (_, a, b, v) => `${a}<em>${b}</em>${v}`)
|
|
597
|
+
.replace(TerraQualityRegex.REGEX_N_G_REGEX_3(), '<br />');
|
|
598
|
+
codes.forEach((c, i) => {
|
|
599
|
+
html = html.replace(`__CODE_${i}__`, c);
|
|
600
|
+
});
|
|
601
|
+
if (lines.length > 1)
|
|
602
|
+
return lines.map((l) => `<p>${renderMd(l)}</p>`).join('');
|
|
603
|
+
return html;
|
|
604
|
+
};
|
|
605
|
+
/**
|
|
606
|
+
* Handles strip nested anchors.
|
|
607
|
+
*
|
|
608
|
+
* @param val - Table cell markup to sanitize before it is embedded in a Docs table.
|
|
609
|
+
*/
|
|
610
|
+
export const stripNestedAnchors = (val) => val
|
|
611
|
+
.replace(/<a([^>]*)>\s*<a[^>]*>([\s\S]*?)<\/a>\s*<\/a>/gi, '<a$1>$2</a>')
|
|
612
|
+
.replace(/\[\[([^\]]+)\]\(([^)]+)\)\]\(\2\)/g, '[$1]($2)');
|
|
613
|
+
/**
|
|
614
|
+
* Handles sanitize table html.
|
|
615
|
+
*
|
|
616
|
+
* @param val - Table markup whose inline styles should be removed.
|
|
617
|
+
*/
|
|
618
|
+
export const sanitizeTableHtml = (val) => val
|
|
619
|
+
.replace(/<style\b[^>]*>[\s\S]*?<\/style\s*>/gi, '')
|
|
620
|
+
.replace(/\sstyle\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, '');
|
|
621
|
+
/**
|
|
622
|
+
* Formats raw table HTML with consistent indentation so docs tables round-trip cleanly.
|
|
623
|
+
*
|
|
624
|
+
* @param value - Table HTML to format.
|
|
625
|
+
*
|
|
626
|
+
* @returns Formatted table HTML string with stable indentation.
|
|
627
|
+
*/
|
|
628
|
+
const fmtRawTable = (val) => {
|
|
629
|
+
if (!TerraQualityRegex.REGEX_TABLE_B_I_REGEX().test(val))
|
|
630
|
+
return val;
|
|
631
|
+
let depth = 0;
|
|
632
|
+
return val
|
|
633
|
+
.replace(/\s*\n\s*/g, ' ')
|
|
634
|
+
.replace(/(<(?:td|th)\b[^>]*>)\s+(?=<(?:p|ul|ol|table|pre|div)\b)/gi, '$1')
|
|
635
|
+
.replace(/(<\/(?:th|td)>)\s*(?=<(?:th|td)\b)/gi, '$1\n')
|
|
636
|
+
.replace(/(<\/(?:p|ul|ol|pre|div)>)\s*(?=<\/td>)/gi, '$1')
|
|
637
|
+
.replace(/(<\/li>)\s*(?=<li\b)/gi, '$1\n')
|
|
638
|
+
.replace(/(<\/?(?:table|thead|tbody|tfoot|tr|ul|ol)\b[^>]*>)/gi, '\n$1\n')
|
|
639
|
+
.split('\n')
|
|
640
|
+
.map((l) => l.trim())
|
|
641
|
+
.filter(Boolean)
|
|
642
|
+
.map((l) => {
|
|
643
|
+
if (/^<\/(?:table|thead|tbody|tfoot|tr|th|td|ul|ol)\b[^>]*>$/iu.test(l))
|
|
644
|
+
depth = Math.max(0, depth - 1);
|
|
645
|
+
if (/^<(?:table|thead|tbody|tfoot|tr|th|td|ul|ol)\b[^>]*>$/iu.test(l))
|
|
646
|
+
depth++;
|
|
647
|
+
return `${'\t'.repeat(depth)}${l}`;
|
|
648
|
+
})
|
|
649
|
+
.join('\n');
|
|
650
|
+
};
|
|
651
|
+
/** Identifies complete canonical HTML table markup. */
|
|
652
|
+
export const TABLE_TAG = /<\/?(?:table|thead|tbody|tfoot|tr|th|td)\b/i;
|
|
653
|
+
/**
|
|
654
|
+
* Handles atomic table html.
|
|
655
|
+
*
|
|
656
|
+
* @param val - Complete table markup captured from a Docs source block.
|
|
657
|
+
*/
|
|
658
|
+
const atomicTableHtml = (val) => {
|
|
659
|
+
return sanitizeTableHtml(val).trim();
|
|
660
|
+
};
|
|
661
|
+
/**
|
|
662
|
+
* Handles fmt raw tables.
|
|
663
|
+
*
|
|
664
|
+
* @param source - Source text containing markup blocks to protect during normalization.
|
|
665
|
+
*/
|
|
666
|
+
/**
|
|
667
|
+
* Replaces complete literal markup blocks without scanning past an unclosed legacy tag.
|
|
668
|
+
*
|
|
669
|
+
* @param src - Document source that may contain the requested markup blocks.
|
|
670
|
+
* @param tag - Literal JSX or HTML tag name to protect.
|
|
671
|
+
* @param blocks - Protected block collection restored after spacing normalization.
|
|
672
|
+
*
|
|
673
|
+
* @returns Source with complete matching blocks substituted by stable placeholders.
|
|
674
|
+
*
|
|
675
|
+
* @remarks
|
|
676
|
+
* Legacy leaves can contain an incomplete opening tag; `indexOf` leaves that text untouched rather than allowing a regex to consume the rest of the document.
|
|
677
|
+
*/
|
|
678
|
+
const protectMarkupBlocks = (src, tag, blocks) => {
|
|
679
|
+
const open = `<${tag}`;
|
|
680
|
+
const close = `</${tag}>`;
|
|
681
|
+
const parts = [];
|
|
682
|
+
let i = 0;
|
|
683
|
+
for (;;) {
|
|
684
|
+
const start = src.indexOf(open, i);
|
|
685
|
+
if (start === -1)
|
|
686
|
+
return parts.join('') + src.slice(i);
|
|
687
|
+
const end = src.indexOf(close, start + open.length);
|
|
688
|
+
if (end === -1)
|
|
689
|
+
return parts.join('') + src.slice(i);
|
|
690
|
+
blocks.push(src.slice(start, end + close.length));
|
|
691
|
+
parts.push(src.slice(i, start), `TERRA_PROTECTED_${blocks.length - 1}__`);
|
|
692
|
+
i = end + close.length;
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
/**
|
|
696
|
+
* Normalizes block spacing in serialized docs source.
|
|
697
|
+
*
|
|
698
|
+
* @param src - Markdown or MDX source to normalize.
|
|
699
|
+
*
|
|
700
|
+
* @returns Source with headings and block delimiters separated onto their own lines.
|
|
701
|
+
*/
|
|
702
|
+
export const normDocsSpacing = (src) => {
|
|
703
|
+
if (!src)
|
|
704
|
+
return '';
|
|
705
|
+
const blocks = [];
|
|
706
|
+
let n = protectMarkupBlocks(protectMarkupBlocks(normBlockMarkers(toCodeJsx(src).replace(/(<Code\b[^>]*>\s*\{`(?:\\.|[^`])*`\})(?!\s*<\/Code>)/g, '$1\n</Code>')), 'Code', blocks), 'table', blocks);
|
|
707
|
+
for (let i = 0; i < 4; i++) {
|
|
708
|
+
n = n
|
|
709
|
+
.replace(/([^\n])\s+(?=(?:#{1,6}\s+|===|\|\|\||:::(?![A-Za-z])))/g, '$1\n\n')
|
|
710
|
+
.replace(/([^\n])\s+(?=:::[A-Za-z])/g, '$1\n\n')
|
|
711
|
+
.replace(/^(?:===|\|\|\||:::[A-Za-z][\w-]*)(?:\[[^\]]*\])?\s+(?=\S)/gm, (m) => `${m.trimEnd()}\n\n`)
|
|
712
|
+
.replace(/([^\n])\s+(?=(?:[*-]|\d+\.)\s)/g, '$1\n')
|
|
713
|
+
.replace(/([^\n])\n(?=<table\b)/g, '$1\n\n')
|
|
714
|
+
.replace(/([^\n])\n(?=<Code\b)/g, '$1\n\n')
|
|
715
|
+
.replace(/([^\n])\n(?=:::(?!:))/g, '$1\n\n')
|
|
716
|
+
.replace(/^(:::[A-Za-z][\w-]*(?:\[[^\]]*\])?)\s+(.+)$/gm, '$1\n\n$2')
|
|
717
|
+
.replace(/^:::\s+(.+)$/gm, ':::\n\n$1')
|
|
718
|
+
.replace(/([^\n])\s+(?=:::(?![A-Za-z]))/g, '$1\n\n')
|
|
719
|
+
.replace(TerraQualityRegex.REGEX_N_3_G_REGEX(), '\n\n');
|
|
720
|
+
if (n === n)
|
|
721
|
+
break;
|
|
722
|
+
}
|
|
723
|
+
n = n
|
|
724
|
+
.split('\n')
|
|
725
|
+
.reduce((a, l) => {
|
|
726
|
+
const currList = TerraQualityRegex.REGEX_S_D_S_REGEX().test(l);
|
|
727
|
+
const prevList = TerraQualityRegex.REGEX_S_D_S_REGEX().test(a.prev);
|
|
728
|
+
if (!l.trim()) {
|
|
729
|
+
a.lines.push(l);
|
|
730
|
+
return a;
|
|
731
|
+
}
|
|
732
|
+
if (currList && !prevList && a.lines.at(-1) !== '')
|
|
733
|
+
a.lines.push('');
|
|
734
|
+
if (currList && prevList)
|
|
735
|
+
while (a.lines.length && a.lines.at(-1) === '')
|
|
736
|
+
a.lines.pop();
|
|
737
|
+
a.lines.push(l);
|
|
738
|
+
a.prev = l;
|
|
739
|
+
return a;
|
|
740
|
+
}, { lines: [], prev: '' })
|
|
741
|
+
.lines.join('\n')
|
|
742
|
+
.split('\n')
|
|
743
|
+
.flatMap((l) => {
|
|
744
|
+
const heading = l.match(/^(#{1,6}\s+)(.+)$/);
|
|
745
|
+
if (!heading)
|
|
746
|
+
return [l];
|
|
747
|
+
const words = heading[2].trim().split(TerraQualityRegex.REGEX_S_REGEX_2()).filter(Boolean);
|
|
748
|
+
if (words.length < 2)
|
|
749
|
+
return [l];
|
|
750
|
+
let cap = 0;
|
|
751
|
+
for (const word of words) {
|
|
752
|
+
if (/^[A-Z0-9]/.test(word))
|
|
753
|
+
cap++;
|
|
754
|
+
else
|
|
755
|
+
break;
|
|
756
|
+
}
|
|
757
|
+
if (cap < 2)
|
|
758
|
+
return [l];
|
|
759
|
+
if (!words.slice(cap).some((w) => /[a-z]/.test(w)))
|
|
760
|
+
return [l];
|
|
761
|
+
return [
|
|
762
|
+
`${heading[1]}${words.slice(0, Math.max(1, cap - 1)).join(' ')}`,
|
|
763
|
+
'',
|
|
764
|
+
words.slice(Math.max(1, cap - 1)).join(' '),
|
|
765
|
+
];
|
|
766
|
+
})
|
|
767
|
+
.join('\n')
|
|
768
|
+
.replace(TerraQualityRegex.REGEX_N_3_G_REGEX(), '\n\n');
|
|
769
|
+
return blocks
|
|
770
|
+
.reduceRight((o, b, i) => o.replace(new RegExp(`TERRA_PROTECTED_${i}__`, 'g'), b), n)
|
|
771
|
+
.replace(/(<\/Code>)[ \t]*(\d+)(?=\s|$)/g, '$1')
|
|
772
|
+
.replace(/(<\/Code>)\n+\s*(\d+)\s*(?=\n|$)/g, '$1')
|
|
773
|
+
.replace(/^(#{1,6})[ \t]*\n[ \t]*(?:\n[ \t]*)?(\d+\.\s+\S[^\n]*)/gm, (m, h, i, o, v) => /^\n\s*\d+\.\s/.test(v.slice(o + m.length)) ? m : `${h} ${i}`)
|
|
774
|
+
.trim();
|
|
775
|
+
};
|
|
776
|
+
/**
|
|
777
|
+
* Renders a Portable Text table block into HTML with a header row followed by body rows.
|
|
778
|
+
*
|
|
779
|
+
* @param rows - Table rows to serialize.
|
|
780
|
+
*
|
|
781
|
+
* @returns HTML table markup for the stored Portable Text rows.
|
|
782
|
+
*/
|
|
783
|
+
const tableHtml = (rows) => {
|
|
784
|
+
/**
|
|
785
|
+
* Renders the Row for the docs.
|
|
786
|
+
*
|
|
787
|
+
* @param row - Table row to render.
|
|
788
|
+
* @param tag - Cell tag to emit for the row.
|
|
789
|
+
*
|
|
790
|
+
* @returns Table row markup for the rendered header or body row.
|
|
791
|
+
*/
|
|
792
|
+
const renderRow = (row, tag) => {
|
|
793
|
+
return `\t<tr>\n${(Array.isArray(row.cells) ? row.cells : [])
|
|
794
|
+
.map((cell) => {
|
|
795
|
+
let html;
|
|
796
|
+
if (cell.html?.trim())
|
|
797
|
+
html = sanitizeTableHtml(stripNestedAnchors(cell.html.trim()))
|
|
798
|
+
.replace(TerraQualityRegex.REGEX_S_S_G_REGEX(), '<strong>$1</strong>')
|
|
799
|
+
.replace(TerraQualityRegex.REGEX_N_G_REGEX(), '$1<em>$2</em>$3');
|
|
800
|
+
else {
|
|
801
|
+
const body = stringifyDocBody(cell.content).trim();
|
|
802
|
+
if (TerraQualityRegex.REGEX_CODE_B_S_S_CODE_REGEX().test(body))
|
|
803
|
+
html = body;
|
|
804
|
+
else {
|
|
805
|
+
const table = body ? mdTableToHtml(body, renderMd) : null;
|
|
806
|
+
if (table)
|
|
807
|
+
html = table;
|
|
808
|
+
else if (body)
|
|
809
|
+
html = sanitizeTableHtml(TerraQualityRegex.REGEX_TABLE_B_I_REGEX().test(body) ? body : renderMd(body));
|
|
810
|
+
else {
|
|
811
|
+
const md = fromBlockJsx(cell.markdown || '').trim();
|
|
812
|
+
const fallback = mdTableToHtml(md, renderMd);
|
|
813
|
+
if (fallback)
|
|
814
|
+
html = sanitizeTableHtml(fallback);
|
|
815
|
+
else if (TerraQualityRegex.REGEX_TABLE_B_I_REGEX().test(md))
|
|
816
|
+
html = sanitizeTableHtml(md);
|
|
817
|
+
else {
|
|
818
|
+
const text = bodyText(cell.content) || bodyText(cell.markdown) || bodyText(cell.html);
|
|
819
|
+
html = text ? sanitizeTableHtml(renderMd(text)) : '';
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
if (html.includes('\n') || /<(?:p|ul|ol|table|pre|div)\b/i.test(html)) {
|
|
825
|
+
let depth = 0;
|
|
826
|
+
return `\t\t<${tag}>\n${html
|
|
827
|
+
.split(TerraQualityRegex.REGEX_R_N_REGEX())
|
|
828
|
+
.map((l) => l.trim())
|
|
829
|
+
.filter(Boolean)
|
|
830
|
+
.map((l) => {
|
|
831
|
+
if (/^<\//u.test(l))
|
|
832
|
+
depth = Math.max(0, depth - 1);
|
|
833
|
+
if (/^<(?:ul|ol|table)\b[^>]*>$/u.test(l))
|
|
834
|
+
depth++;
|
|
835
|
+
return `${'\t'.repeat(depth + 3)}${l}`;
|
|
836
|
+
})
|
|
837
|
+
.join('\n')}\n\t\t</${tag}>\n`;
|
|
838
|
+
}
|
|
839
|
+
return `\t\t<${tag}>${html}</${tag}>\n`;
|
|
840
|
+
})
|
|
841
|
+
.join('')}\t</tr>`;
|
|
842
|
+
};
|
|
843
|
+
const sRows = Array.isArray(rows) ? rows : [];
|
|
844
|
+
if (!sRows.length)
|
|
845
|
+
return '';
|
|
846
|
+
// prettier-ignore
|
|
847
|
+
return fmtRawTable(sanitizeTableHtml(`<table>\n${sRows[0] ? `<thead>\n${renderRow(sRows[0], 'th')}\n</thead>\n` : ''}<tbody>\n${sRows.slice(1).map(r => renderRow(r, 'td')).join('\n')}\n</tbody>\n</table>`));
|
|
848
|
+
};
|
|
849
|
+
/**
|
|
850
|
+
* Prefers the already-serialized body, then falls back to the original markdown source.
|
|
851
|
+
*
|
|
852
|
+
* @param body - Body content to process.
|
|
853
|
+
* @param md - Markdown source to parse.
|
|
854
|
+
*
|
|
855
|
+
* @returns Serialized docs source, falling back to the original markdown when body content is empty.
|
|
856
|
+
*/
|
|
857
|
+
const nestedMd = (body, md = '') => {
|
|
858
|
+
const content = stringifyDocBody(body).trim();
|
|
859
|
+
if (content)
|
|
860
|
+
return content;
|
|
861
|
+
return fromBlockJsx(md).trim();
|
|
862
|
+
};
|
|
863
|
+
/**
|
|
864
|
+
* Serializes a block defensively so malformed history entries do not break export.
|
|
865
|
+
*
|
|
866
|
+
* @param block - Block record to normalize.
|
|
867
|
+
* @param number - Ordered list number for nested list items.
|
|
868
|
+
*
|
|
869
|
+
* @returns Serialized block Markdown, or an empty string when the block cannot be rendered safely.
|
|
870
|
+
*/
|
|
871
|
+
const sBlockMd = (block, number = 1) => {
|
|
872
|
+
try {
|
|
873
|
+
return isRec(block) && typeof block._type === 'string'
|
|
874
|
+
? blockMd(block, number)
|
|
875
|
+
: '';
|
|
876
|
+
}
|
|
877
|
+
catch (err) {
|
|
878
|
+
if (isRec(block) && typeof block.markdown === 'string')
|
|
879
|
+
return fromBlockJsx(block.markdown);
|
|
880
|
+
console.error('[DOCS:content] Failed to serialize block.', {
|
|
881
|
+
type: isRec(block) && typeof block._type === 'string' ? block._type : typeof block,
|
|
882
|
+
err,
|
|
883
|
+
});
|
|
884
|
+
return '';
|
|
885
|
+
}
|
|
886
|
+
};
|
|
887
|
+
/**
|
|
888
|
+
* Serializes a Portable Text block into docs Markdown, preserving nested tables, lists, and custom blocks.
|
|
889
|
+
*
|
|
890
|
+
* @param b - Portable Text block to serialize.
|
|
891
|
+
* @param number - Ordered list number for nested list items.
|
|
892
|
+
*
|
|
893
|
+
* @returns Markdown string for the supplied block, including nested custom syntax when present.
|
|
894
|
+
*/
|
|
895
|
+
const blockMd = (b, number = 1) => {
|
|
896
|
+
if (b._type === 'block') {
|
|
897
|
+
const text = (Array.isArray(b.c) && b.c.length > 0
|
|
898
|
+
? b.c
|
|
899
|
+
: Array.isArray(b.children)
|
|
900
|
+
? b.children
|
|
901
|
+
: [])
|
|
902
|
+
.map((c) => {
|
|
903
|
+
if (ptText(c))
|
|
904
|
+
return renderMarks(c.text || '', Array.isArray(c.marks) ? c.marks : [], ptMarkDefs(b.markDefs));
|
|
905
|
+
return isRec(c) && typeof c._type === 'string' ? sBlockMd(c, number) : '';
|
|
906
|
+
})
|
|
907
|
+
.join('');
|
|
908
|
+
if (TABLE_TAG.test(text)) {
|
|
909
|
+
const table = atomicTableHtml(text);
|
|
910
|
+
return table ? `\n${table}\n` : '';
|
|
911
|
+
}
|
|
912
|
+
if (b.style && TerraQualityRegex.REGEX_H_1_6_U_REGEX().test(b.style))
|
|
913
|
+
return `\n${'#'.repeat(Number(b.style.slice(1)))} ${text}\n`;
|
|
914
|
+
if (b.listItem)
|
|
915
|
+
return `\n${b.listItem === 'number' ? `${number}.` : '*'} ${text}\n`;
|
|
916
|
+
return text ? `\n${text}\n` : '';
|
|
917
|
+
}
|
|
918
|
+
switch (b._type) {
|
|
919
|
+
case 'accordion':
|
|
920
|
+
case 'tabs': {
|
|
921
|
+
const syntax = b._type === 'tabs' ? '|||' : '===';
|
|
922
|
+
return (Array.isArray(b.items) ? b.items : [])
|
|
923
|
+
.map((t) => {
|
|
924
|
+
const content = nestedMd(t.content, t.markdown || '');
|
|
925
|
+
return content
|
|
926
|
+
? `\n${syntax}[${t.title}]\n\n${content}\n\n${syntax}\n`
|
|
927
|
+
: `\n${syntax}[${t.title}]\n\n${syntax}\n`;
|
|
928
|
+
})
|
|
929
|
+
.join('');
|
|
930
|
+
}
|
|
931
|
+
case 'callout': {
|
|
932
|
+
const content = nestedMd(b.content, b.markdown || '');
|
|
933
|
+
return content
|
|
934
|
+
? `\n:::${b.kind}${b.title ? `[${b.title}]` : ''}\n\n${content}\n\n:::\n`
|
|
935
|
+
: `\n:::${b.kind}${b.title ? `[${b.title}]` : ''}\n\n:::\n`;
|
|
936
|
+
}
|
|
937
|
+
case 'code': {
|
|
938
|
+
const val = stringifyCodeValue(b.value);
|
|
939
|
+
return `\n${b.source ? codeSrcJsx(b.language, b.source) : isEndpointVal(val) ? codeSrcJsx(b.language, val) : codeJsx(b.language, val)}\n`;
|
|
940
|
+
}
|
|
941
|
+
case 'embed':
|
|
942
|
+
return `\n<Embed ${Object.entries({
|
|
943
|
+
src: b.src,
|
|
944
|
+
title: b.title,
|
|
945
|
+
width: b.width,
|
|
946
|
+
height: b.height,
|
|
947
|
+
})
|
|
948
|
+
.filter(([, v]) => v !== undefined && v !== null && v !== '')
|
|
949
|
+
.map(([k, v]) => {
|
|
950
|
+
if (v === true)
|
|
951
|
+
return k;
|
|
952
|
+
if (typeof v === 'string')
|
|
953
|
+
return `${k}=${quote(v)}`;
|
|
954
|
+
if (typeof v === 'number' || typeof v === 'boolean')
|
|
955
|
+
return `${k}={${String(v)}}`;
|
|
956
|
+
return `${k}={${JSON.stringify(v)}}`;
|
|
957
|
+
})
|
|
958
|
+
.join(' ')} />\n`;
|
|
959
|
+
case 'heading':
|
|
960
|
+
return `\n${'#'.repeat(b.depth)} ${b.text}\n`;
|
|
961
|
+
case 'docImage':
|
|
962
|
+
return `\n\n`;
|
|
963
|
+
case 'math':
|
|
964
|
+
return b.inline ? `$${b.code}$` : `\n\n$$\n${b.code}\n$$\n\n`;
|
|
965
|
+
case 'nodes':
|
|
966
|
+
// prettier-ignore
|
|
967
|
+
void { direction: b.direction, height: b.height, nodeSep: b.nodeSep, nodesCount: Array.isArray(b.nodes) ? b.nodes.length : 0, edgesCount: Array.isArray(b.edges) ? b.edges.length : 0, head: Array.isArray(b.nodes) ? encodeNodesPayload(b.nodes ?? []).slice(0, 160) : '', };
|
|
968
|
+
return `\n<Nodes\n${b.direction !== undefined ? ` direction=${quote(String(b.direction))}\n` : ''}${b.nodes !== undefined ? ` nodes={${encodeNodesPayload(b.nodes ?? [])}}\n` : ''}${b.edges !== undefined ? ` edges={${encodeNodesPayload(b.edges ?? [])}}\n` : ''}${b.height !== undefined ? ` height={${b.height}}\n` : ''}${b.nodeSep !== undefined ? ` nodeSep={${b.nodeSep}}\n` : ''}${b.rankSep !== undefined ? ` rankSep={${b.rankSep}}\n` : ''}${b.proximityConnect ? ' proximityConnect\n' : ''}/>\n`;
|
|
969
|
+
case 'paragraph':
|
|
970
|
+
return fromBlockJsx(b.markdown || '');
|
|
971
|
+
case 'raw':
|
|
972
|
+
return b.markdown?.trim() === '<Testimonials />'
|
|
973
|
+
? TESTIMONIALS_EXPORT
|
|
974
|
+
: fmtRawTable(fromBlockJsx(b.markdown || ''));
|
|
975
|
+
case 'table': {
|
|
976
|
+
const html = tableHtml(b.rows || []);
|
|
977
|
+
if (html)
|
|
978
|
+
return `\n${html}\n`;
|
|
979
|
+
const md = fromBlockJsx(b.markdown || '').trim();
|
|
980
|
+
const fallback = mdTableToHtml(md, renderMd);
|
|
981
|
+
return fallback ? `\n${fallback}\n` : md ? `\n${md}\n` : '';
|
|
982
|
+
}
|
|
983
|
+
case 'tsDocs':
|
|
984
|
+
return `\n<TsDocs scope=${quote(b.scope || '')} />\n`;
|
|
985
|
+
default:
|
|
986
|
+
return '';
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
/**
|
|
990
|
+
* Prefers editor-formatted body content, then falls back to markdown restored from custom blocks.
|
|
991
|
+
*
|
|
992
|
+
* @param body - Body content to process.
|
|
993
|
+
* @param md - Markdown source to parse.
|
|
994
|
+
*
|
|
995
|
+
* @returns Editor Markdown source, using canonical JSX wrappers for nested blocks.
|
|
996
|
+
*/
|
|
997
|
+
const escDocsTableTemplates = (md) => md.replace(/<DocsTable\b[\s\S]*?html=\{`([\s\S]*?)`\}\s*\/>/g, (_match, h) => `<DocsTable html={\`${h.replace(/(?<!\\)`/g, '\\`').replace(/(?<!\\)\$\{/g, '\\${')}\`} />`);
|
|
998
|
+
/**
|
|
999
|
+
* Handles editor nested md.
|
|
1000
|
+
*
|
|
1001
|
+
* @param body - Structured body used as the serialization source.
|
|
1002
|
+
* @param markdown - Markdown fallback used when structured content is unavailable.
|
|
1003
|
+
*/
|
|
1004
|
+
const editorNestedMd = (body, markdown = '') => {
|
|
1005
|
+
const tables = [];
|
|
1006
|
+
return tables.reduce((n, t, i) => n.replace(`TERRA_EDITOR_TABLE_${i}`, t), escDocsTableTemplates(Array.isArray(body) && body.length > 0
|
|
1007
|
+
? stringifyEditorContentBody(body)
|
|
1008
|
+
: fromBlockJsx(markdown || '').trim())
|
|
1009
|
+
.replace(/<DocsTable\s+html=\{`(?:\\.|[^`])*`\}\s*\/>/g, (m) => {
|
|
1010
|
+
tables.push(m);
|
|
1011
|
+
return `TERRA_EDITOR_TABLE_${tables.length - 1}`;
|
|
1012
|
+
})
|
|
1013
|
+
.replace(TerraQualityRegex.REGEX_TABLE_B_S_S_TABLE_GI_REGEX(), (t) => `<DocsTable html={\`${toCodeJsx(fmtRawTable(t).trim()).replace(TerraQualityRegex.REGEX_G_REGEX_12(), '\\\\').replace(TerraQualityRegex.REGEX_G_REGEX_18(), '\\`').replace(TerraQualityRegex.REGEX_G_REGEX_16(), '\\$')}\`} />`));
|
|
1014
|
+
};
|
|
1015
|
+
/**
|
|
1016
|
+
* Serializes a problem block payload into the custom `ProblemBlock` JSX wrapper.
|
|
1017
|
+
*
|
|
1018
|
+
* @param b - Problem block record to serialize.
|
|
1019
|
+
*
|
|
1020
|
+
* @returns `ProblemBlock` JSX wrapper, or fallback Markdown when serialization fails.
|
|
1021
|
+
*/
|
|
1022
|
+
const problemBlockMd = (b) => {
|
|
1023
|
+
try {
|
|
1024
|
+
return `<ProblemBlock type=${quote(typeof b._type === 'string' ? b._type : 'unknown')} data={${JSON.stringify(b)}} />`;
|
|
1025
|
+
}
|
|
1026
|
+
catch (err) {
|
|
1027
|
+
console.error('[DOCS:content] Failed to serialize problem block.', { type: b._type, err });
|
|
1028
|
+
return typeof b.markdown === 'string' ? fromBlockJsx(b.markdown) : '';
|
|
1029
|
+
}
|
|
1030
|
+
};
|
|
1031
|
+
/**
|
|
1032
|
+
* Serializes Portable Text blocks for the editor variant of the docs Markdown pipeline.
|
|
1033
|
+
*
|
|
1034
|
+
* @param b - Portable Text block to serialize.
|
|
1035
|
+
* @param number - Ordered list number for nested list items.
|
|
1036
|
+
* @param mode - Output mode to switch between docs and problem formatting.
|
|
1037
|
+
*
|
|
1038
|
+
* @returns Editor Markdown block, with tables and problem blocks kept in editor-safe JSX.
|
|
1039
|
+
*/
|
|
1040
|
+
const editorBlockMd = (b, number = 1, mode = 'docs') => {
|
|
1041
|
+
if (b._type === 'block') {
|
|
1042
|
+
const text = (Array.isArray(b.c) && b.c.length > 0
|
|
1043
|
+
? b.c
|
|
1044
|
+
: Array.isArray(b.children)
|
|
1045
|
+
? b.children
|
|
1046
|
+
: [])
|
|
1047
|
+
.map((s) => {
|
|
1048
|
+
if (ptText(s))
|
|
1049
|
+
return renderMarks(s.text || '', Array.isArray(s.marks) ? s.marks : [], ptMarkDefs(b.markDefs));
|
|
1050
|
+
return isRec(s) && typeof s._type === 'string'
|
|
1051
|
+
? editorBlockMd(s, number, mode)
|
|
1052
|
+
: '';
|
|
1053
|
+
})
|
|
1054
|
+
.join('');
|
|
1055
|
+
if (mode === 'docs' && TABLE_TAG.test(text)) {
|
|
1056
|
+
const table = atomicTableHtml(text);
|
|
1057
|
+
return table ? `\n${editorNestedMd(null, table)}\n` : '';
|
|
1058
|
+
}
|
|
1059
|
+
if (b.style && TerraQualityRegex.REGEX_H_1_6_U_REGEX().test(b.style))
|
|
1060
|
+
return `\n${'#'.repeat(Number(b.style.slice(1)))} ${text}\n`;
|
|
1061
|
+
if (b.listItem)
|
|
1062
|
+
return `\n${b.listItem === 'number' ? `${number}.` : '*'} ${text}\n`;
|
|
1063
|
+
return text ? `\n${text}\n` : '';
|
|
1064
|
+
}
|
|
1065
|
+
switch (b._type) {
|
|
1066
|
+
case 'accordion':
|
|
1067
|
+
case 'tabs': {
|
|
1068
|
+
if (mode === 'problem')
|
|
1069
|
+
return problemBlockMd({ ...b });
|
|
1070
|
+
const root = b._type === 'tabs' ? 'TabsGroup' : 'AccordionGroup';
|
|
1071
|
+
const item = b._type === 'tabs' ? 'TabsItem' : 'AccordionItem';
|
|
1072
|
+
return `<${root}>\n\n${(Array.isArray(b.items) ? b.items : []).map((e) => `<${item} title=${quote(e.title || 'Section')}>\n\n${editorNestedMd(e.content, e.markdown || '')}\n\n</${item}>`).join('\n\n')}\n\n</${root}>`;
|
|
1073
|
+
}
|
|
1074
|
+
case 'callout': {
|
|
1075
|
+
const content = editorNestedMd(b.content, b.markdown || '');
|
|
1076
|
+
return content
|
|
1077
|
+
? `\n:::${b.kind}${b.title ? `[${b.title}]` : ''}\n\n${content}\n\n:::\n`
|
|
1078
|
+
: `\n:::${b.kind}${b.title ? `[${b.title}]` : ''}\n\n:::\n`;
|
|
1079
|
+
}
|
|
1080
|
+
case 'table': {
|
|
1081
|
+
if (mode === 'problem')
|
|
1082
|
+
return problemBlockMd({ ...b });
|
|
1083
|
+
const html = tableHtml(b.rows || []) || mdTableToHtml(fromBlockJsx(b.markdown || '').trim(), renderMd);
|
|
1084
|
+
return html ? `\n${editorNestedMd(null, html)}\n` : '';
|
|
1085
|
+
}
|
|
1086
|
+
case 'math':
|
|
1087
|
+
return `<DocsMath code=${quote(b.code || '')}${b.inline ? ' inline' : ''} />`;
|
|
1088
|
+
case 'raw': {
|
|
1089
|
+
const raw = atomicTableHtml(fromBlockJsx(b.markdown || '').trim());
|
|
1090
|
+
if (!raw && TABLE_TAG.test(fromBlockJsx(b.markdown || '').trim()))
|
|
1091
|
+
return '';
|
|
1092
|
+
return TABLE_TAG.test(raw) ? `\n${editorNestedMd(null, raw)}\n` : blockMd(b, number);
|
|
1093
|
+
}
|
|
1094
|
+
case 'paragraph': {
|
|
1095
|
+
const md = fromBlockJsx(b.markdown || '').trim();
|
|
1096
|
+
if (!TABLE_TAG.test(md))
|
|
1097
|
+
return md;
|
|
1098
|
+
const table = atomicTableHtml(md);
|
|
1099
|
+
return table ? `\n${editorNestedMd(null, table)}\n` : '';
|
|
1100
|
+
}
|
|
1101
|
+
default:
|
|
1102
|
+
return mode === 'problem' &&
|
|
1103
|
+
PROBLEM_BLOCK_TYPES.includes(b._type)
|
|
1104
|
+
? problemBlockMd({ ...b })
|
|
1105
|
+
: blockMd(b, number);
|
|
1106
|
+
}
|
|
1107
|
+
};
|
|
1108
|
+
/*//////////////////////////////////////////////////
|
|
1109
|
+
EXPORTS
|
|
1110
|
+
//////////////////////////////////////////////////*/
|
|
1111
|
+
/**
|
|
1112
|
+
* Stringifies the Doc Content Body for the docs.
|
|
1113
|
+
*
|
|
1114
|
+
* @param body - Structured docs content to serialize.
|
|
1115
|
+
*
|
|
1116
|
+
* @returns Markdown or MDX source for the provided body, or an empty string for empty input.
|
|
1117
|
+
*
|
|
1118
|
+
* @remarks
|
|
1119
|
+
* Empty bodies return an empty string so callers can short-circuit easily.
|
|
1120
|
+
*/
|
|
1121
|
+
export const stringifyDocBody = (body) => {
|
|
1122
|
+
trace('serialize.main.start', { blocks: Array.isArray(body) ? body.length : 0 });
|
|
1123
|
+
if (!Array.isArray(body) || body.length === 0)
|
|
1124
|
+
return '';
|
|
1125
|
+
void {
|
|
1126
|
+
length: body.length,
|
|
1127
|
+
firstTypes: body
|
|
1128
|
+
.slice(0, 6)
|
|
1129
|
+
.map((b) => (isRec(b) && typeof b._type === 'string' ? b._type : typeof b)),
|
|
1130
|
+
};
|
|
1131
|
+
let md = '';
|
|
1132
|
+
let number = 1;
|
|
1133
|
+
for (let i = 0; i < body.length; i++) {
|
|
1134
|
+
const block = body[i];
|
|
1135
|
+
const listNumber = listKind(block) === 'number' && listKind(body[i - 1]) === 'number' ? number + 1 : 1;
|
|
1136
|
+
const text = sBlockMd(block, listNumber).trim();
|
|
1137
|
+
void {
|
|
1138
|
+
index: i,
|
|
1139
|
+
type: isRec(block) && typeof block._type === 'string' ? block._type : typeof block,
|
|
1140
|
+
textLength: text.length,
|
|
1141
|
+
textHead: text.slice(0, 120),
|
|
1142
|
+
};
|
|
1143
|
+
if (!text)
|
|
1144
|
+
continue;
|
|
1145
|
+
number = listNumber;
|
|
1146
|
+
if (md) {
|
|
1147
|
+
const prevList = listKind(body[i - 1]);
|
|
1148
|
+
const currList = listKind(block);
|
|
1149
|
+
md += prevList && currList && prevList === currList ? '\n' : '\n\n';
|
|
1150
|
+
}
|
|
1151
|
+
md += text;
|
|
1152
|
+
}
|
|
1153
|
+
const src = toCodeJsx(md).trim();
|
|
1154
|
+
trace('serialize.main.complete', { length: src.length });
|
|
1155
|
+
return src;
|
|
1156
|
+
};
|
|
1157
|
+
/**
|
|
1158
|
+
* Stringifies the Editor Content Body for the docs.
|
|
1159
|
+
*
|
|
1160
|
+
* @param body - Structured docs content to serialize.
|
|
1161
|
+
*
|
|
1162
|
+
* @returns MDX source that MDXEditor can reopen without delimiter-rewrite drift.
|
|
1163
|
+
*
|
|
1164
|
+
* @remarks
|
|
1165
|
+
* Accordions, tabs, and tables are emitted as explicit JSX so nested HTML never relies on regex block rewriting.
|
|
1166
|
+
*/
|
|
1167
|
+
export const stringifyEditorContentBody = (body) => {
|
|
1168
|
+
trace('serialize.editor.start', { blocks: Array.isArray(body) ? body.length : 0 });
|
|
1169
|
+
if (!Array.isArray(body) || body.length === 0)
|
|
1170
|
+
return '';
|
|
1171
|
+
void {
|
|
1172
|
+
length: body.length,
|
|
1173
|
+
firstTypes: body
|
|
1174
|
+
.slice(0, 6)
|
|
1175
|
+
.map((b) => (isRec(b) && typeof b._type === 'string' ? b._type : typeof b)),
|
|
1176
|
+
};
|
|
1177
|
+
let md = '';
|
|
1178
|
+
let number = 1;
|
|
1179
|
+
for (let i = 0; i < body.length; i++) {
|
|
1180
|
+
const block = body[i];
|
|
1181
|
+
const listNumber = listKind(block) === 'number' && listKind(body[i - 1]) === 'number' ? number + 1 : 1;
|
|
1182
|
+
const text = editorBlockMd(block, listNumber).trim();
|
|
1183
|
+
void {
|
|
1184
|
+
index: i,
|
|
1185
|
+
type: isRec(block) && typeof block._type === 'string' ? block._type : typeof block,
|
|
1186
|
+
textLength: text.length,
|
|
1187
|
+
textHead: text.slice(0, 120),
|
|
1188
|
+
};
|
|
1189
|
+
if (!text)
|
|
1190
|
+
continue;
|
|
1191
|
+
number = listNumber;
|
|
1192
|
+
if (md) {
|
|
1193
|
+
const prevList = listKind(body[i - 1]);
|
|
1194
|
+
const currList = listKind(block);
|
|
1195
|
+
md += prevList && currList && prevList === currList ? '\n' : '\n\n';
|
|
1196
|
+
}
|
|
1197
|
+
md += text;
|
|
1198
|
+
}
|
|
1199
|
+
const src = escDocsTableTemplates(normDocsSpacing(md));
|
|
1200
|
+
trace('serialize.editor.complete', { length: src.length });
|
|
1201
|
+
return src;
|
|
1202
|
+
};
|
|
1203
|
+
/**
|
|
1204
|
+
* Handles stringify problem editor content body.
|
|
1205
|
+
*
|
|
1206
|
+
* @param body - Problem editor body to serialize into Markdown source.
|
|
1207
|
+
*/
|
|
1208
|
+
export const stringifyProblemEditorContentBody = (body) => {
|
|
1209
|
+
if (!Array.isArray(body) || body.length === 0)
|
|
1210
|
+
return '';
|
|
1211
|
+
let md = '';
|
|
1212
|
+
let number = 1;
|
|
1213
|
+
for (let i = 0; i < body.length; i++) {
|
|
1214
|
+
const block = body[i];
|
|
1215
|
+
const list = listKind(block);
|
|
1216
|
+
const text = editorBlockMd(block, list === 'number' && listKind(body[i - 1]) === 'number' ? number + 1 : 1, 'problem').trim();
|
|
1217
|
+
if (!text)
|
|
1218
|
+
continue;
|
|
1219
|
+
if (md)
|
|
1220
|
+
md += list && listKind(body[i - 1]) === list ? '\n' : '\n\n';
|
|
1221
|
+
md += text;
|
|
1222
|
+
number = list === 'number' ? number + 1 : 1;
|
|
1223
|
+
}
|
|
1224
|
+
return normDocsSpacing(md);
|
|
1225
|
+
};
|
|
1226
|
+
/**
|
|
1227
|
+
* Serializes the current leaf content payload without inspecting ver history.
|
|
1228
|
+
*
|
|
1229
|
+
* @param content - Direct `leaf.content` value or a compatibility wrapper around it.
|
|
1230
|
+
*
|
|
1231
|
+
* @returns Markdown or MDX for the active document body only.
|
|
1232
|
+
*
|
|
1233
|
+
* @remarks
|
|
1234
|
+
* This is the preferred live-doc read path now that leaf content is stored directly.
|
|
1235
|
+
*/
|
|
1236
|
+
export const currDocMd = (content) => {
|
|
1237
|
+
void {
|
|
1238
|
+
kind: typeof content,
|
|
1239
|
+
isArray: Array.isArray(content),
|
|
1240
|
+
hasContent: Boolean(content && typeof content === 'object' && 'content' in content),
|
|
1241
|
+
};
|
|
1242
|
+
if (typeof content === 'string') {
|
|
1243
|
+
return normDocsSpacing(content.trim() === '<Testimonials />' ? TESTIMONIALS_EXPORT : content);
|
|
1244
|
+
}
|
|
1245
|
+
if (Array.isArray(content)) {
|
|
1246
|
+
return normDocsSpacing(stringifyDocBody(content));
|
|
1247
|
+
}
|
|
1248
|
+
if (isRec(content) && Array.isArray(content.content)) {
|
|
1249
|
+
return normDocsSpacing(stringifyDocBody(content.content));
|
|
1250
|
+
}
|
|
1251
|
+
if (isRec(content) && typeof content.content === 'string') {
|
|
1252
|
+
return normDocsSpacing(content.content.trim() === '<Testimonials />' ? TESTIMONIALS_EXPORT : content.content);
|
|
1253
|
+
}
|
|
1254
|
+
return '';
|
|
1255
|
+
};
|
|
1256
|
+
//# sourceMappingURL=content.js.map
|