@open-press/cli 0.7.1 → 1.0.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/README.md +29 -13
- package/dist/cli.js +44 -195
- package/package.json +4 -5
- package/template/core/AGENTS.md +18 -14
- package/template/core/CHANGELOG.md +57 -9
- package/template/core/README.md +6 -3
- package/template/core/engine/cli.mjs +8 -8
- package/template/core/engine/commands/_shared.mjs +37 -15
- package/template/core/engine/commands/dev.mjs +2 -2
- package/template/core/engine/commands/image.mjs +29 -0
- package/template/core/engine/commands/skills-sync.mjs +71 -0
- package/template/core/engine/commands/typecheck.mjs +63 -1
- package/template/core/engine/commands/upgrade.mjs +3 -3
- package/template/core/engine/document-export.mjs +1 -1
- package/template/core/engine/output/chrome-pdf.mjs +110 -3
- package/template/core/engine/output/static-server.mjs +87 -9
- package/template/core/engine/react/comment-endpoint.mjs +13 -39
- package/template/core/engine/react/comment-marker.mjs +43 -19
- package/template/core/engine/react/document-entry.mjs +46 -28
- package/template/core/engine/react/document-export.mjs +328 -164
- package/template/core/engine/react/http-json.mjs +24 -0
- package/template/core/engine/react/mdx-compile.mjs +126 -3
- package/template/core/engine/react/measurement-css.mjs +114 -1
- package/template/core/engine/react/object-entities.mjs +204 -0
- package/template/core/engine/react/pagination/allocator.mjs +48 -3
- package/template/core/engine/react/pagination.mjs +1 -1
- package/template/core/engine/react/pipeline/allocate.mjs +41 -72
- package/template/core/engine/react/pipeline/frame-measurement.mjs +6 -0
- package/template/core/engine/react/press-tree-inspection.mjs +172 -0
- package/template/core/engine/react/project-asset-endpoint.mjs +6 -24
- package/template/core/engine/react/source-edit-endpoint.d.mts +10 -0
- package/template/core/engine/react/source-edit-endpoint.mjs +75 -0
- package/template/core/engine/react/sources/mdx-resolver.mjs +13 -15
- package/template/core/engine/react/style-discovery.mjs +23 -8
- package/template/core/engine/runtime/config.d.mts +8 -0
- package/template/core/engine/runtime/config.mjs +57 -60
- package/template/core/engine/runtime/file-utils.mjs +9 -1
- package/template/core/engine/runtime/file-walk.mjs +22 -0
- package/template/core/engine/runtime/inspection.mjs +1 -20
- package/template/core/engine/runtime/page-geometry.mjs +131 -0
- package/template/core/engine/runtime/path-utils.mjs +20 -0
- package/template/core/engine/runtime/source-text-tools.d.mts +102 -0
- package/template/core/engine/runtime/source-text-tools.mjs +551 -16
- package/template/core/engine/runtime/source-workspace.mjs +16 -34
- package/template/core/engine/runtime/validation.mjs +19 -10
- package/template/core/openpress.config.mjs +3 -7
- package/template/core/package.json +3 -5
- package/template/core/src/main.tsx +2 -2
- package/template/core/src/openpress/app/OpenPressApp.tsx +296 -0
- package/template/core/src/openpress/{renderer.tsx → app/OpenPressRuntime.tsx} +20 -9
- package/template/core/src/openpress/app/WorkspaceGalleryPage.tsx +219 -0
- package/template/core/src/openpress/app/index.ts +2 -0
- package/template/core/src/openpress/core/Frame.tsx +26 -15
- package/template/core/src/openpress/core/FrameContext.tsx +10 -3
- package/template/core/src/openpress/core/MdxArea.tsx +11 -12
- package/template/core/src/openpress/core/Press.tsx +25 -4
- package/template/core/src/openpress/core/Workspace.tsx +36 -0
- package/template/core/src/openpress/core/cn.ts +4 -0
- package/template/core/src/openpress/core/index.tsx +11 -3
- package/template/core/src/openpress/core/primitives.tsx +74 -6
- package/template/core/src/openpress/core/types.ts +94 -41
- package/template/core/src/openpress/core/useSource.ts +1 -1
- package/template/core/src/openpress/{anchorMap.ts → document-model/anchorMapModel.ts} +1 -1
- package/template/core/src/openpress/{indexes.ts → document-model/documentIndexes.ts} +1 -1
- package/template/core/src/openpress/{types.ts → document-model/documentTypes.ts} +51 -0
- package/template/core/src/openpress/document-model/index.ts +7 -0
- package/template/core/src/openpress/document-model/objectEntityModel.ts +55 -0
- package/template/core/src/openpress/{projectIdentity.ts → document-model/projectIdentityModel.ts} +1 -1
- package/template/core/src/openpress/{reactDocumentMetadata.ts → document-model/reactDocumentMetadataModel.ts} +1 -1
- package/template/core/src/openpress/document-model/workspaceManifestModel.ts +57 -0
- package/template/core/src/openpress/manuscript/index.tsx +49 -7
- package/template/core/src/openpress/mdx/index.ts +15 -7
- package/template/core/src/openpress/reader/PageThumbnailsPanel.tsx +168 -0
- package/template/core/src/openpress/{publicPage.tsx → reader/PublicReaderPage.tsx} +31 -51
- package/template/core/src/openpress/{workbenchPanels.tsx → reader/ReaderNavigationPanel.tsx} +6 -5
- package/template/core/src/openpress/reader/index.ts +11 -0
- package/template/core/src/openpress/reader/pageViewportScaleModel.ts +73 -0
- package/template/core/src/openpress/reader/readerTypes.ts +4 -0
- package/template/core/src/openpress/reader/usePageViewportScale.ts +119 -0
- package/template/core/src/openpress/reader/usePanelState.ts +56 -0
- package/template/core/src/openpress/reader/useReaderHashSync.ts +61 -0
- package/template/core/src/openpress/reader/useReaderKeyboardNav.ts +48 -0
- package/template/core/src/openpress/reader/useReaderRuntime.ts +146 -0
- package/template/core/src/openpress/reader/useReaderScrollAnchor.ts +64 -0
- package/template/core/src/openpress/shared/Panel.tsx +77 -0
- package/template/core/src/openpress/shared/index.ts +4 -0
- package/template/core/src/openpress/shared/numberUtils.ts +3 -0
- package/template/core/src/openpress/{runtimeMode.ts → shared/runtimeMode.ts} +0 -11
- package/template/core/src/openpress/workbench/Workbench.tsx +506 -0
- package/template/core/src/openpress/workbench/actions/DeploymentControl.tsx +157 -0
- package/template/core/src/openpress/workbench/actions/ExportImageControl.tsx +96 -0
- package/template/core/src/openpress/workbench/actions/PageZoomControl.tsx +182 -0
- package/template/core/src/openpress/workbench/actions/SearchControl.tsx +345 -0
- package/template/core/src/openpress/workbench/actions/deploymentStatusModel.ts +112 -0
- package/template/core/src/openpress/workbench/actions/index.ts +6 -0
- package/template/core/src/openpress/workbench/actions/useDeploymentWorkbench.ts +136 -0
- package/template/core/src/openpress/workbench/dialog/WorkbenchDialog.tsx +72 -0
- package/template/core/src/openpress/workbench/dialog/index.ts +1 -0
- package/template/core/src/openpress/workbench/document/components/DocumentPanel.tsx +127 -0
- package/template/core/src/openpress/workbench/document/components/InlineSourceEditorLayer.tsx +207 -0
- package/template/core/src/openpress/workbench/document/components/ReaderStage.tsx +9 -0
- package/template/core/src/openpress/workbench/document/hooks/useDocumentWorkbenchModel.ts +34 -0
- package/template/core/src/openpress/workbench/document/hooks/useInlineDocumentEditor.ts +525 -0
- package/template/core/src/openpress/workbench/document/index.ts +10 -0
- package/template/core/src/openpress/workbench/index.ts +2 -0
- package/template/core/src/openpress/workbench/inspector/InlineInspectorLayer.tsx +459 -0
- package/template/core/src/openpress/workbench/inspector/index.ts +5 -0
- package/template/core/src/openpress/workbench/inspector/inlineCommentModel.ts +125 -0
- package/template/core/src/openpress/workbench/inspector/inspectorGeometryModel.ts +160 -0
- package/template/core/src/openpress/workbench/inspector/inspectorModel.ts +408 -0
- package/template/core/src/openpress/workbench/inspector/useInspectorComments.ts +254 -0
- package/template/core/src/openpress/workbench/mentions/MentionSuggestionList.tsx +41 -0
- package/template/core/src/openpress/workbench/mentions/index.ts +2 -0
- package/template/core/src/openpress/{composerMentions.ts → workbench/mentions/useComposerMentions.ts} +1 -4
- package/template/core/src/openpress/workbench/panels/Panel.tsx +1 -0
- package/template/core/src/openpress/workbench/panels/PendingCommentsPanel.tsx +80 -0
- package/template/core/src/openpress/workbench/panels/WorkbenchControlPanel.tsx +29 -0
- package/template/core/src/openpress/workbench/panels/index.ts +3 -0
- package/template/core/src/openpress/workbench/project/ProjectEntryPanel.tsx +525 -0
- package/template/core/src/openpress/workbench/project/ProjectPreviewDialog.tsx +35 -0
- package/template/core/src/openpress/workbench/project/index.ts +2 -0
- package/template/core/src/openpress/workbench/project/projectPreviewTypes.ts +11 -0
- package/template/core/src/openpress/workbench/shell/WorkbenchShell.tsx +167 -0
- package/template/core/src/openpress/workbench/shell/index.ts +1 -0
- package/template/core/src/openpress/workbench/workbenchFormatters.ts +120 -0
- package/template/core/src/openpress/workbench/workbenchTypes.ts +35 -0
- package/template/core/src/styles/openpress/print-route.css +0 -2
- package/template/core/src/styles/openpress/{project-workspace.css → project-preview-panel.css} +13 -407
- package/template/core/src/styles/openpress/public-viewer.css +25 -320
- package/template/core/src/styles/openpress/reader-runtime.css +252 -55
- package/template/core/src/styles/openpress/responsive.css +145 -270
- package/template/core/src/styles/openpress/workbench-panels.css +327 -178
- package/template/core/src/styles/openpress/workbench.css +986 -451
- package/template/core/src/styles/openpress/workspace-gallery.css +300 -0
- package/template/core/src/styles/openpress.css +2 -1
- package/template/core/tsconfig.json +1 -1
- package/template/core/vite.config.ts +50 -0
- package/template/core/engine/commands/init.mjs +0 -24
- package/template/core/engine/init.mjs +0 -90
- package/template/core/src/openpress/App.tsx +0 -127
- package/template/core/src/openpress/inspector.ts +0 -282
- package/template/core/src/openpress/projectWorkspace.tsx +0 -919
- package/template/core/src/openpress/readerRuntime.ts +0 -230
- package/template/core/src/openpress/workbench.tsx +0 -1265
- package/template/core/src/openpress/workbenchTypes.ts +0 -4
- package/template/packs/academic-paper/document/chapters/01-introduction/content/01-introduction.mdx +0 -35
- package/template/packs/academic-paper/document/chapters/02-methods/content/01-methods.mdx +0 -50
- package/template/packs/academic-paper/document/chapters/03-results-and-discussion/content/01-results.mdx +0 -47
- package/template/packs/academic-paper/document/chapters/04-acknowledgment/content/01-acknowledgment.mdx +0 -26
- package/template/packs/academic-paper/document/chapters/05-references/content/01-references.mdx +0 -32
- package/template/packs/academic-paper/document/components/ChapterOpenerVisual/index.tsx +0 -76
- package/template/packs/academic-paper/document/components/Page.tsx +0 -60
- package/template/packs/academic-paper/document/components/TokenSwatchGrid/index.tsx +0 -46
- package/template/packs/academic-paper/document/components/TokenSwatchGrid/style.css +0 -63
- package/template/packs/academic-paper/document/components/TypeSpecimen/index.tsx +0 -38
- package/template/packs/academic-paper/document/components/TypeSpecimen/style.css +0 -111
- package/template/packs/academic-paper/document/design.md +0 -279
- package/template/packs/academic-paper/document/index.tsx +0 -123
- package/template/packs/academic-paper/document/media/README.md +0 -13
- package/template/packs/academic-paper/document/media/figure-placeholder.svg +0 -9
- package/template/packs/academic-paper/document/openpress.config.mjs +0 -26
- package/template/packs/academic-paper/document/theme/README.md +0 -11
- package/template/packs/academic-paper/document/theme/base/page-contract.css +0 -522
- package/template/packs/academic-paper/document/theme/base/print.css +0 -93
- package/template/packs/academic-paper/document/theme/base/typography.css +0 -333
- package/template/packs/academic-paper/document/theme/fonts.css +0 -3
- package/template/packs/academic-paper/document/theme/page-surfaces/back-cover.css +0 -43
- package/template/packs/academic-paper/document/theme/page-surfaces/chapter-opener.css +0 -205
- package/template/packs/academic-paper/document/theme/page-surfaces/cover.css +0 -294
- package/template/packs/academic-paper/document/theme/page-surfaces/toc.css +0 -149
- package/template/packs/academic-paper/document/theme/patterns/_chart-frame.css +0 -49
- package/template/packs/academic-paper/document/theme/patterns/figure-grid.css +0 -68
- package/template/packs/academic-paper/document/theme/patterns/table-utilities.css +0 -66
- package/template/packs/academic-paper/document/theme/shell/reader-controls.css +0 -761
- package/template/packs/academic-paper/document/theme/tokens.css +0 -80
- package/template/packs/academic-paper/openpress.config.mjs +0 -5
- package/template/packs/claude-document/document/chapters/01-document-shape/content/01-document-shape.mdx +0 -51
- package/template/packs/claude-document/document/chapters/02-review-loop/content/01-review-loop.mdx +0 -31
- package/template/packs/claude-document/document/components/ChapterOpenerVisual.tsx +0 -96
- package/template/packs/claude-document/document/components/Page.tsx +0 -37
- package/template/packs/claude-document/document/design.md +0 -142
- package/template/packs/claude-document/document/index.tsx +0 -94
- package/template/packs/claude-document/document/media/README.md +0 -13
- package/template/packs/claude-document/document/openpress.config.mjs +0 -26
- package/template/packs/claude-document/document/theme/README.md +0 -15
- package/template/packs/claude-document/document/theme/base/page-contract.css +0 -525
- package/template/packs/claude-document/document/theme/base/print.css +0 -93
- package/template/packs/claude-document/document/theme/base/typography.css +0 -612
- package/template/packs/claude-document/document/theme/fonts.css +0 -4
- package/template/packs/claude-document/document/theme/page-surfaces/back-cover.css +0 -72
- package/template/packs/claude-document/document/theme/page-surfaces/chapter-opener.css +0 -236
- package/template/packs/claude-document/document/theme/page-surfaces/cover.css +0 -309
- package/template/packs/claude-document/document/theme/page-surfaces/toc.css +0 -225
- package/template/packs/claude-document/document/theme/patterns/_chart-frame.css +0 -53
- package/template/packs/claude-document/document/theme/patterns/figure-grid.css +0 -68
- package/template/packs/claude-document/document/theme/patterns/table-utilities.css +0 -66
- package/template/packs/claude-document/document/theme/shell/reader-controls.css +0 -789
- package/template/packs/claude-document/document/theme/tokens.css +0 -89
- package/template/packs/claude-document/openpress.config.mjs +0 -5
- package/template/packs/editorial-monograph/document/chapters/01-product-and-use-cases/content/01-product-and-use-cases.mdx +0 -31
- package/template/packs/editorial-monograph/document/chapters/02-workflow/content/01-workflow.mdx +0 -89
- package/template/packs/editorial-monograph/document/chapters/03-agent-skills-contributors/content/01-agent-skills-contributors.mdx +0 -51
- package/template/packs/editorial-monograph/document/chapters/04-validation-deploy/content/01-validation-deploy.mdx +0 -39
- package/template/packs/editorial-monograph/document/components/ChapterOpenerVisual/index.tsx +0 -76
- package/template/packs/editorial-monograph/document/components/Page.tsx +0 -37
- package/template/packs/editorial-monograph/document/components/TokenSwatchGrid/index.tsx +0 -46
- package/template/packs/editorial-monograph/document/components/TokenSwatchGrid/style.css +0 -63
- package/template/packs/editorial-monograph/document/components/TypeSpecimen/index.tsx +0 -38
- package/template/packs/editorial-monograph/document/components/TypeSpecimen/style.css +0 -111
- package/template/packs/editorial-monograph/document/design.md +0 -279
- package/template/packs/editorial-monograph/document/index.tsx +0 -97
- package/template/packs/editorial-monograph/document/media/README.md +0 -13
- package/template/packs/editorial-monograph/document/openpress.config.mjs +0 -26
- package/template/packs/editorial-monograph/document/theme/README.md +0 -11
- package/template/packs/editorial-monograph/document/theme/base/page-contract.css +0 -505
- package/template/packs/editorial-monograph/document/theme/base/print.css +0 -93
- package/template/packs/editorial-monograph/document/theme/base/typography.css +0 -336
- package/template/packs/editorial-monograph/document/theme/fonts.css +0 -3
- package/template/packs/editorial-monograph/document/theme/page-surfaces/back-cover.css +0 -43
- package/template/packs/editorial-monograph/document/theme/page-surfaces/chapter-opener.css +0 -205
- package/template/packs/editorial-monograph/document/theme/page-surfaces/cover.css +0 -147
- package/template/packs/editorial-monograph/document/theme/page-surfaces/toc.css +0 -149
- package/template/packs/editorial-monograph/document/theme/patterns/_chart-frame.css +0 -49
- package/template/packs/editorial-monograph/document/theme/patterns/figure-grid.css +0 -68
- package/template/packs/editorial-monograph/document/theme/patterns/table-utilities.css +0 -66
- package/template/packs/editorial-monograph/document/theme/shell/reader-controls.css +0 -761
- package/template/packs/editorial-monograph/document/theme/tokens.css +0 -80
- package/template/packs/editorial-monograph/openpress.config.mjs +0 -5
- /package/template/core/src/openpress/{readerPageRegistry.ts → reader/readerPageRegistry.ts} +0 -0
- /package/template/core/src/openpress/{pageRoute.ts → reader/readerPageRoute.ts} +0 -0
- /package/template/core/src/openpress/{readerScroll.ts → reader/readerScroll.ts} +0 -0
- /package/template/core/src/openpress/{readerState.ts → reader/readerStateModel.ts} +0 -0
- /package/template/core/src/openpress/{frameScheduler.ts → shared/frameScheduler.ts} +0 -0
- /package/template/core/src/openpress/{projectSources.ts → workbench/project/projectSourceModel.ts} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
import type { EditableSourceRef, ObjectEntityKind } from "../document-model/documentTypes";
|
|
2
3
|
|
|
3
4
|
// ---------------------------------------------------------------------------
|
|
4
5
|
// Frame / MdxArea / Press primitives
|
|
@@ -25,8 +26,72 @@ export type MdxAreaProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
|
|
|
25
26
|
className?: string;
|
|
26
27
|
};
|
|
27
28
|
|
|
29
|
+
// PageGeometry — a custom fixed-size geometry passed to <Press page>.
|
|
30
|
+
// Same shape as the engine's normalized geometry (CSS lengths,
|
|
31
|
+
// matching units between width / height).
|
|
32
|
+
export interface PageGeometry {
|
|
33
|
+
id?: string;
|
|
34
|
+
label?: string;
|
|
35
|
+
preset?: string;
|
|
36
|
+
width: string;
|
|
37
|
+
height: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Source descriptor passed inside <Press sources>. The actual type is
|
|
41
|
+
// the return value of mdxSource() from @open-press/core/mdx; we accept
|
|
42
|
+
// "unknown" at the core boundary to avoid a circular type dependency.
|
|
43
|
+
// The engine validates the shape at render time.
|
|
44
|
+
export type PressSource = unknown;
|
|
45
|
+
|
|
28
46
|
export interface PressProps {
|
|
47
|
+
// Document tree — Frames, manuscript helpers, etc.
|
|
48
|
+
children: ReactNode;
|
|
49
|
+
// -------------------------------------------------------------------------
|
|
50
|
+
// 1.0 metadata props — optional during v0.x deprecation, required in v1.0.
|
|
51
|
+
// -------------------------------------------------------------------------
|
|
52
|
+
// Document title. Required in 1.0. Used for PDF metadata, HTML <title>,
|
|
53
|
+
// OG tags, and the Workspace gallery / tab-bar label.
|
|
54
|
+
title?: string;
|
|
55
|
+
// Page geometry preset name or a custom geometry object. Optional;
|
|
56
|
+
// workspace default applies if not set.
|
|
57
|
+
page?: "a4" | "social-square" | "slide-16-9" | PageGeometry;
|
|
58
|
+
// Array of source registrations from mdxSource(). Replaces the v0.x
|
|
59
|
+
// `export const sources` named export.
|
|
60
|
+
sources?: ReadonlyArray<PressSource>;
|
|
61
|
+
// URL / output slug for this Press inside a Workspace. Defaults to
|
|
62
|
+
// "/" when only one Press exists in the Workspace; required when the
|
|
63
|
+
// Workspace has multiple Press children.
|
|
64
|
+
slug?: string;
|
|
65
|
+
// Optional per-Press theme directory. Defaults to "./theme" relative
|
|
66
|
+
// to the document file; inherits from <Workspace theme> if not set.
|
|
67
|
+
theme?: string;
|
|
68
|
+
// Optional per-Press components directory. Default "./components".
|
|
69
|
+
componentsDir?: string;
|
|
70
|
+
// Optional caption numbering overrides. Engine defaults to
|
|
71
|
+
// { figure: "Figure", table: "Table", separator: " " }.
|
|
72
|
+
captionNumbering?: {
|
|
73
|
+
figure?: string;
|
|
74
|
+
table?: string;
|
|
75
|
+
separator?: string;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// Workspace — root component holding one or more Press children
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
export interface WorkspaceProps {
|
|
84
|
+
// One or more <Press> children. 1 child = single-doc workspace; N
|
|
85
|
+
// children = multi-doc workspace (proposal + pitch + social, etc).
|
|
29
86
|
children: ReactNode;
|
|
87
|
+
// Project label surfaced in the gallery header, tab bar, and PDF
|
|
88
|
+
// metadata. Optional.
|
|
89
|
+
name?: string;
|
|
90
|
+
// Workspace-level shared theme directory. Press children that don't
|
|
91
|
+
// set their own `theme` prop inherit from this. Default "./theme".
|
|
92
|
+
theme?: string;
|
|
93
|
+
// Workspace-level shared media directory. Default "./media".
|
|
94
|
+
media?: string;
|
|
30
95
|
}
|
|
31
96
|
|
|
32
97
|
// ---------------------------------------------------------------------------
|
|
@@ -38,6 +103,14 @@ export type BaseFigureProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
|
|
|
38
103
|
children: ReactNode;
|
|
39
104
|
};
|
|
40
105
|
|
|
106
|
+
export type MediaFigureProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
|
|
107
|
+
src: string;
|
|
108
|
+
alt: string;
|
|
109
|
+
caption: ReactNode;
|
|
110
|
+
imgClassName?: string;
|
|
111
|
+
loading?: "eager" | "lazy";
|
|
112
|
+
};
|
|
113
|
+
|
|
41
114
|
export type BaseCalloutKind = "info" | "warn" | "success" | "error" | (string & {});
|
|
42
115
|
|
|
43
116
|
export type BaseCalloutProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
|
|
@@ -45,6 +118,27 @@ export type BaseCalloutProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
|
|
|
45
118
|
children: ReactNode;
|
|
46
119
|
};
|
|
47
120
|
|
|
121
|
+
export type ObjectEntityElement = "span" | "div" | "section" | "article" | "figure" | "p";
|
|
122
|
+
|
|
123
|
+
export type ObjectEntityProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
|
|
124
|
+
as?: ObjectEntityElement;
|
|
125
|
+
objectId: string;
|
|
126
|
+
kind: ObjectEntityKind;
|
|
127
|
+
label: string;
|
|
128
|
+
parentId?: string;
|
|
129
|
+
pageId?: string;
|
|
130
|
+
blockId?: string;
|
|
131
|
+
frameKey?: string;
|
|
132
|
+
chainId?: string;
|
|
133
|
+
source?: EditableSourceRef;
|
|
134
|
+
metadata?: Record<string, string | number | boolean | null>;
|
|
135
|
+
children?: ReactNode;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export type TextProps = Omit<ObjectEntityProps, "kind"> & {
|
|
139
|
+
as?: "span" | "div" | "p";
|
|
140
|
+
};
|
|
141
|
+
|
|
48
142
|
// ---------------------------------------------------------------------------
|
|
49
143
|
// Source descriptors and resolved sources
|
|
50
144
|
// ---------------------------------------------------------------------------
|
|
@@ -140,44 +234,3 @@ export interface ResolvedSource {
|
|
|
140
234
|
// MdxArea by area index.
|
|
141
235
|
export type FrameAllocation = Record<string, Record<string, ReactNode[]>>;
|
|
142
236
|
|
|
143
|
-
// ---------------------------------------------------------------------------
|
|
144
|
-
// Manifest
|
|
145
|
-
// ---------------------------------------------------------------------------
|
|
146
|
-
|
|
147
|
-
export interface Manifest {
|
|
148
|
-
title: string;
|
|
149
|
-
subtitle?: string;
|
|
150
|
-
organization?: string;
|
|
151
|
-
workspaceLabel?: string;
|
|
152
|
-
documentDir?: string;
|
|
153
|
-
sourceDir?: string;
|
|
154
|
-
componentsDir?: string;
|
|
155
|
-
mediaDir?: string;
|
|
156
|
-
themeDir?: string;
|
|
157
|
-
designDoc?: string;
|
|
158
|
-
publicDir?: string;
|
|
159
|
-
outputDir?: string;
|
|
160
|
-
captionNumbering?: {
|
|
161
|
-
figure?: string;
|
|
162
|
-
table?: string;
|
|
163
|
-
separator?: string;
|
|
164
|
-
};
|
|
165
|
-
pdf?: {
|
|
166
|
-
filename?: string;
|
|
167
|
-
};
|
|
168
|
-
deploy?: {
|
|
169
|
-
adapter?: string;
|
|
170
|
-
source?: string;
|
|
171
|
-
projectName?: string | null;
|
|
172
|
-
commitDirty?: boolean;
|
|
173
|
-
requiresConfirmation?: boolean;
|
|
174
|
-
};
|
|
175
|
-
paths?: {
|
|
176
|
-
chaptersDir?: string;
|
|
177
|
-
sourceDir?: string;
|
|
178
|
-
componentsDir?: string;
|
|
179
|
-
mediaDir?: string;
|
|
180
|
-
themeDir?: string;
|
|
181
|
-
designDoc?: string;
|
|
182
|
-
};
|
|
183
|
-
}
|
|
@@ -21,7 +21,7 @@ export function useSource<T extends ResolvedSource = ResolvedSource>(id: string)
|
|
|
21
21
|
const knownText = known.length > 0 ? known.join(", ") : "(none)";
|
|
22
22
|
throw new Error(
|
|
23
23
|
`Unknown source "${id}". Available sources: ${knownText}. ` +
|
|
24
|
-
`Register it
|
|
24
|
+
`Register it as a <Press sources={[mdxSource({ id: "${id}", ... })]}> entry in press/index.tsx.`,
|
|
25
25
|
);
|
|
26
26
|
}
|
|
27
27
|
return source as T;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// `PublicPage` / `HtmlWorkbench` HMR-clean (Fast Refresh expects component
|
|
4
4
|
// files to export only components).
|
|
5
5
|
|
|
6
|
-
import type { DisplayPage } from "
|
|
6
|
+
import type { DisplayPage } from "../reader";
|
|
7
7
|
|
|
8
8
|
export function createAnchorPageMap(pages: DisplayPage[]) {
|
|
9
9
|
const map = new Map<string, number>();
|
|
@@ -25,6 +25,7 @@ export interface DocumentSource {
|
|
|
25
25
|
editMode?: string;
|
|
26
26
|
styles?: DocumentStyle[];
|
|
27
27
|
blockMap?: Record<string, SourceBlock>;
|
|
28
|
+
objectEntities?: Record<string, ObjectEntity>;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export interface DocumentStyle {
|
|
@@ -49,6 +50,9 @@ export interface SourceBlock {
|
|
|
49
50
|
pageIndex?: number;
|
|
50
51
|
pageNumber?: number;
|
|
51
52
|
source?: SourceLocation;
|
|
53
|
+
frameKey?: string;
|
|
54
|
+
chainId?: string;
|
|
55
|
+
sectionSlug?: string;
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
export interface DocumentMeta {
|
|
@@ -61,8 +65,12 @@ export interface DocumentMeta {
|
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
export interface Theme {
|
|
68
|
+
pagePreset?: string;
|
|
69
|
+
pageLabel?: string;
|
|
64
70
|
pageWidth?: string;
|
|
65
71
|
pageHeight?: string;
|
|
72
|
+
pageAspectRatio?: string;
|
|
73
|
+
pageHeightRatio?: string;
|
|
66
74
|
pagePadding?: string;
|
|
67
75
|
fontFamily?: string;
|
|
68
76
|
accentColor?: string;
|
|
@@ -93,4 +101,47 @@ export interface HtmlPageBlock {
|
|
|
93
101
|
anchors?: string[];
|
|
94
102
|
className?: string;
|
|
95
103
|
source?: BlockSource;
|
|
104
|
+
frameKey?: string;
|
|
105
|
+
role?: string | null;
|
|
106
|
+
chrome?: boolean;
|
|
107
|
+
blockIds?: string[];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export type ObjectEntityKind =
|
|
111
|
+
| "page"
|
|
112
|
+
| "frame"
|
|
113
|
+
| "mdx-area"
|
|
114
|
+
| "mdx-block"
|
|
115
|
+
| "text"
|
|
116
|
+
| "component"
|
|
117
|
+
| "media";
|
|
118
|
+
|
|
119
|
+
export interface EditableSourceRef {
|
|
120
|
+
path: string;
|
|
121
|
+
file?: string;
|
|
122
|
+
kind?: string;
|
|
123
|
+
objectId?: string;
|
|
124
|
+
scope?: string;
|
|
125
|
+
component?: string;
|
|
126
|
+
source?: SourceLocation;
|
|
127
|
+
line?: number;
|
|
128
|
+
column?: number;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface ObjectEntityRef {
|
|
132
|
+
id: string;
|
|
133
|
+
kind: ObjectEntityKind;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface ObjectEntity {
|
|
137
|
+
id: string;
|
|
138
|
+
kind: ObjectEntityKind;
|
|
139
|
+
label: string;
|
|
140
|
+
parentId?: string;
|
|
141
|
+
pageId?: string;
|
|
142
|
+
blockId?: string;
|
|
143
|
+
frameKey?: string;
|
|
144
|
+
chainId?: string;
|
|
145
|
+
source?: EditableSourceRef;
|
|
146
|
+
metadata?: Record<string, string | number | boolean | null>;
|
|
96
147
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from "./anchorMapModel";
|
|
2
|
+
export * from "./documentIndexes";
|
|
3
|
+
export * from "./documentTypes";
|
|
4
|
+
export * from "./objectEntityModel";
|
|
5
|
+
export * from "./projectIdentityModel";
|
|
6
|
+
export * from "./reactDocumentMetadataModel";
|
|
7
|
+
export * from "./workspaceManifestModel";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ObjectEntity, ObjectEntityKind, ReaderDocument, SourceBlock } from "./documentTypes";
|
|
2
|
+
|
|
3
|
+
export function createObjectEntityId(kind: ObjectEntityKind, ...parts: Array<string | number>) {
|
|
4
|
+
return [kind, ...parts.map((part) => encodeURIComponent(String(part)))].join(":");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function createScopedObjectEntityId(kind: ObjectEntityKind, parentId: string | undefined, objectId: string) {
|
|
8
|
+
return parentId ? createObjectEntityId(kind, parentId, objectId) : createObjectEntityId(kind, objectId);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function createBlockObjectEntityId(blockId: string) {
|
|
12
|
+
return createObjectEntityId("mdx-block", blockId);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function createFrameObjectEntityId(frameKey: string) {
|
|
16
|
+
return createObjectEntityId("frame", frameKey);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function createPageObjectEntityId(frameKey: string) {
|
|
20
|
+
return createObjectEntityId("page", frameKey);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function createMdxAreaObjectEntityId(frameKey: string, chainId: string, indexInFrame: number) {
|
|
24
|
+
return createObjectEntityId("mdx-area", frameKey, chainId, indexInFrame);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getObjectEntityMap(document: Pick<ReaderDocument, "source"> | null | undefined): Record<string, ObjectEntity> {
|
|
28
|
+
return document?.source?.objectEntities ?? {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function getObjectEntity(document: Pick<ReaderDocument, "source"> | null | undefined, objectId: string): ObjectEntity | null {
|
|
32
|
+
return getObjectEntityMap(document)[objectId] ?? null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function sourceBlockToObjectEntity(block: SourceBlock): ObjectEntity {
|
|
36
|
+
return {
|
|
37
|
+
id: createBlockObjectEntityId(block.id),
|
|
38
|
+
kind: "mdx-block",
|
|
39
|
+
label: block.name ? `${block.name} ${block.id}` : block.id,
|
|
40
|
+
blockId: block.id,
|
|
41
|
+
frameKey: block.frameKey,
|
|
42
|
+
chainId: block.chainId,
|
|
43
|
+
pageId: block.frameKey ? createPageObjectEntityId(block.frameKey) : undefined,
|
|
44
|
+
source: {
|
|
45
|
+
path: block.path,
|
|
46
|
+
source: block.source,
|
|
47
|
+
line: block.source?.line,
|
|
48
|
+
column: block.source?.column,
|
|
49
|
+
},
|
|
50
|
+
metadata: {
|
|
51
|
+
blockKind: block.kind ?? null,
|
|
52
|
+
sectionSlug: block.sectionSlug ?? block.chapterSlug ?? null,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Shape of /openpress/workspace.json — the reader fetches this on
|
|
2
|
+
// boot to decide between gallery routing (multi-Press) and direct
|
|
3
|
+
// load (single Press). One entry per <Press> child of <Workspace>.
|
|
4
|
+
//
|
|
5
|
+
// Single-Press workspaces emit one entry with slug = "" and the
|
|
6
|
+
// legacy /openpress/document.json path. Multi-Press emits one entry
|
|
7
|
+
// per slug; each `documentUrl` resolves to /openpress/<slug>/document.json.
|
|
8
|
+
|
|
9
|
+
export interface WorkspaceManifest {
|
|
10
|
+
version: 1;
|
|
11
|
+
// <Workspace name="..."> prop. Null when the user did not set one.
|
|
12
|
+
// Surfaced as the gallery header in the reader.
|
|
13
|
+
name: string | null;
|
|
14
|
+
presses: WorkspaceManifestPress[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface WorkspaceManifestPress {
|
|
18
|
+
// Slug for this Press. Empty string for single-Press workspaces
|
|
19
|
+
// (legacy root); slug-shaped string for multi-Press.
|
|
20
|
+
slug: string;
|
|
21
|
+
// <Press title="..."> prop. Required in v1.0 contract.
|
|
22
|
+
title: string;
|
|
23
|
+
// Page geometry summary. Same shape as the reader's
|
|
24
|
+
// ReaderDocument.theme — readers can show a thumb in the gallery
|
|
25
|
+
// without loading the full document.json.
|
|
26
|
+
page: {
|
|
27
|
+
pagePreset?: string;
|
|
28
|
+
pageLabel?: string;
|
|
29
|
+
pageWidth?: string;
|
|
30
|
+
pageHeight?: string;
|
|
31
|
+
pageAspectRatio?: string;
|
|
32
|
+
pageHeightRatio?: string;
|
|
33
|
+
} | null;
|
|
34
|
+
// Number of pages produced for this Press.
|
|
35
|
+
pageCount: number;
|
|
36
|
+
// Absolute path the reader fetches for this Press's full document.json.
|
|
37
|
+
documentUrl: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// True when the reader should render the gallery first instead of
|
|
41
|
+
// going straight into a single Press's document.
|
|
42
|
+
export function manifestHasMultiplePresses(manifest: WorkspaceManifest): boolean {
|
|
43
|
+
return manifest.presses.length > 1;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Find a Press entry by slug. Returns null when the slug is unknown.
|
|
47
|
+
export function findManifestPress(
|
|
48
|
+
manifest: WorkspaceManifest,
|
|
49
|
+
slug: string,
|
|
50
|
+
): WorkspaceManifestPress | null {
|
|
51
|
+
const normalized = slug.replace(/^\/+|\/+$/g, "");
|
|
52
|
+
for (const press of manifest.presses) {
|
|
53
|
+
const normalizedSlug = press.slug.replace(/^\/+|\/+$/g, "");
|
|
54
|
+
if (normalizedSlug === normalized) return press;
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
// document type that wants section flow imports from here; documents that
|
|
10
10
|
// do not (slides, folios, calendars) skip this module entirely.
|
|
11
11
|
|
|
12
|
-
import { Fragment, useContext, type ReactNode } from "react";
|
|
13
|
-
import { Frame, FrameContext, PressContext, useSource } from "../core";
|
|
12
|
+
import { Fragment, useContext, type ComponentType, type ReactNode } from "react";
|
|
13
|
+
import { Frame, FrameContext, MdxArea, PressContext, useSource } from "../core";
|
|
14
14
|
import type { MdxAreaOverflow, ResolvedSource } from "../core";
|
|
15
|
+
import { createMdxAreaObjectEntityId } from "../document-model/objectEntityModel";
|
|
15
16
|
|
|
16
17
|
// ---------------------------------------------------------------------------
|
|
17
18
|
// <Sections>
|
|
@@ -38,11 +39,11 @@ export interface SectionsOpenerProps {
|
|
|
38
39
|
|
|
39
40
|
export interface SectionsProps {
|
|
40
41
|
source: string;
|
|
41
|
-
page
|
|
42
|
-
opener?:
|
|
42
|
+
page?: ComponentType<SectionsPageProps>;
|
|
43
|
+
opener?: ComponentType<SectionsOpenerProps>;
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
export function Sections({ source: sourceId, page: Page, opener: Opener }: SectionsProps) {
|
|
46
|
+
export function Sections({ source: sourceId, page: Page = DefaultSectionPage, opener: Opener }: SectionsProps) {
|
|
46
47
|
const source = useSource(sourceId);
|
|
47
48
|
const press = useContext(PressContext);
|
|
48
49
|
const hints = press?.hints ?? null;
|
|
@@ -92,6 +93,41 @@ export function Sections({ source: sourceId, page: Page, opener: Opener }: Secti
|
|
|
92
93
|
export const Chapters = Sections;
|
|
93
94
|
export type ChaptersProps = SectionsProps;
|
|
94
95
|
|
|
96
|
+
export function DefaultSectionPage({
|
|
97
|
+
frameKey,
|
|
98
|
+
chainId,
|
|
99
|
+
pageIndex,
|
|
100
|
+
totalPages,
|
|
101
|
+
sectionSlug,
|
|
102
|
+
sectionTitle,
|
|
103
|
+
sectionTone,
|
|
104
|
+
}: SectionsPageProps) {
|
|
105
|
+
return (
|
|
106
|
+
<Frame
|
|
107
|
+
frameKey={frameKey}
|
|
108
|
+
role="manuscript.content"
|
|
109
|
+
className="reader-page--content"
|
|
110
|
+
data-page-index={pageIndex}
|
|
111
|
+
data-total-pages={totalPages}
|
|
112
|
+
data-section-id={sectionSlug}
|
|
113
|
+
data-chapter-tone={sectionTone}
|
|
114
|
+
>
|
|
115
|
+
<div className="page-frame">
|
|
116
|
+
<header className="page-header" aria-hidden="true" />
|
|
117
|
+
<main className="page-body">
|
|
118
|
+
<MdxArea chainId={chainId} />
|
|
119
|
+
</main>
|
|
120
|
+
<footer className="page-footer" aria-hidden="true">
|
|
121
|
+
<span className="footer-left">{sectionTitle}</span>
|
|
122
|
+
<span className="footer-right">
|
|
123
|
+
{totalPages > 1 ? `${pageIndex + 1}/${totalPages}` : pageIndex + 1}
|
|
124
|
+
</span>
|
|
125
|
+
</footer>
|
|
126
|
+
</div>
|
|
127
|
+
</Frame>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
95
131
|
// ---------------------------------------------------------------------------
|
|
96
132
|
// <Toc>
|
|
97
133
|
// ---------------------------------------------------------------------------
|
|
@@ -178,15 +214,21 @@ function DefaultTocPage({ frameKey, chainId, pageIndex, totalPages, heading, cla
|
|
|
178
214
|
|
|
179
215
|
export function TocArea({ chainId, maxLevel, overflow = "extend", className }: TocAreaProps) {
|
|
180
216
|
const frame = useContext(FrameContext);
|
|
181
|
-
const
|
|
217
|
+
const consumed = frame?.consumeArea(chainId) ?? null;
|
|
218
|
+
const blocks = consumed?.blocks ?? null;
|
|
219
|
+
const objectId = frame && consumed
|
|
220
|
+
? createMdxAreaObjectEntityId(frame.frameKey, chainId, consumed.indexInFrame)
|
|
221
|
+
: undefined;
|
|
182
222
|
return (
|
|
183
223
|
<div
|
|
184
224
|
className="openpress-mdx-area openpress-toc-area"
|
|
185
225
|
data-openpress-mdx-area="true"
|
|
186
226
|
data-openpress-mdx-area-chain={chainId}
|
|
227
|
+
data-openpress-mdx-area-index={consumed?.indexInFrame}
|
|
228
|
+
data-openpress-object-id={objectId}
|
|
187
229
|
data-openpress-toc-max-level={maxLevel}
|
|
188
230
|
data-openpress-mdx-area-overflow={overflow}
|
|
189
|
-
data-openpress-mdx-area-empty={blocks == null ? "true" :
|
|
231
|
+
data-openpress-mdx-area-empty={blocks == null ? "true" : "false"}
|
|
190
232
|
>
|
|
191
233
|
<ol className={["toc-list", className].filter(Boolean).join(" ") || undefined}>
|
|
192
234
|
{blocks}
|
|
@@ -27,14 +27,17 @@ export type {
|
|
|
27
27
|
SourceNode,
|
|
28
28
|
} from "../core/types";
|
|
29
29
|
|
|
30
|
+
// All presets accept an optional `id` for the 1.0 contract where sources
|
|
31
|
+
// are an array passed via <Press sources>. In v0.x the id came from the
|
|
32
|
+
// record key in `export const sources = { story: mdxSource(...) }`.
|
|
30
33
|
type MdxSourceOptions =
|
|
31
|
-
| { preset: "section-folders"; root?: string }
|
|
32
|
-
| { preset: "section-files"; root?: string }
|
|
33
|
-
| { preset: "file-list"; files: string[] };
|
|
34
|
+
| { id?: string; preset: "section-folders"; root?: string }
|
|
35
|
+
| { id?: string; preset: "section-files"; root?: string }
|
|
36
|
+
| { id?: string; preset: "file-list"; files: string[] };
|
|
34
37
|
|
|
35
38
|
const VALID_PRESETS = new Set(["section-folders", "section-files", "file-list"]);
|
|
36
39
|
|
|
37
|
-
export function mdxSource(options: MdxSourceOptions): MdxSourceDescriptor {
|
|
40
|
+
export function mdxSource(options: MdxSourceOptions): MdxSourceDescriptor & { id?: string } {
|
|
38
41
|
if (!options || typeof options !== "object") {
|
|
39
42
|
throw new Error("mdxSource() requires an options object.");
|
|
40
43
|
}
|
|
@@ -46,11 +49,15 @@ export function mdxSource(options: MdxSourceOptions): MdxSourceDescriptor {
|
|
|
46
49
|
);
|
|
47
50
|
}
|
|
48
51
|
|
|
52
|
+
const id = typeof options.id === "string" && options.id.trim() ? options.id.trim() : undefined;
|
|
53
|
+
|
|
49
54
|
if (options.preset === "section-folders") {
|
|
50
|
-
|
|
55
|
+
const desc = normalizeRooted("section-folders", options.root, "chapters") as MdxSourceDescriptorSectionFolders;
|
|
56
|
+
return id ? { ...desc, id } : desc;
|
|
51
57
|
}
|
|
52
58
|
if (options.preset === "section-files") {
|
|
53
|
-
|
|
59
|
+
const desc = normalizeRooted("section-files", options.root, "content") as MdxSourceDescriptorSectionFiles;
|
|
60
|
+
return id ? { ...desc, id } : desc;
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
// file-list
|
|
@@ -69,7 +76,8 @@ export function mdxSource(options: MdxSourceOptions): MdxSourceDescriptor {
|
|
|
69
76
|
if (files.length === 0) {
|
|
70
77
|
throw new Error('mdxSource({ preset: "file-list" }) requires at least one file.');
|
|
71
78
|
}
|
|
72
|
-
|
|
79
|
+
const desc: MdxSourceDescriptor = { type: "mdx", preset: "file-list", files };
|
|
80
|
+
return id ? { ...desc, id } : desc;
|
|
73
81
|
}
|
|
74
82
|
|
|
75
83
|
function normalizeRooted(
|