@open-press/cli 0.8.0 → 1.1.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.
Files changed (250) hide show
  1. package/README.md +33 -23
  2. package/dist/cli.js +320 -252
  3. package/package.json +9 -8
  4. package/template/core/AGENTS.md +0 -126
  5. package/template/core/CHANGELOG.md +0 -215
  6. package/template/core/README.md +0 -40
  7. package/template/core/engine/cli.mjs +0 -96
  8. package/template/core/engine/commands/_shared.mjs +0 -177
  9. package/template/core/engine/commands/deploy.mjs +0 -31
  10. package/template/core/engine/commands/dev.mjs +0 -49
  11. package/template/core/engine/commands/doctor.mjs +0 -229
  12. package/template/core/engine/commands/export.mjs +0 -8
  13. package/template/core/engine/commands/init.mjs +0 -24
  14. package/template/core/engine/commands/inspect.mjs +0 -35
  15. package/template/core/engine/commands/pdf.mjs +0 -26
  16. package/template/core/engine/commands/preview.mjs +0 -26
  17. package/template/core/engine/commands/render.mjs +0 -17
  18. package/template/core/engine/commands/replace.mjs +0 -41
  19. package/template/core/engine/commands/search.mjs +0 -33
  20. package/template/core/engine/commands/typecheck.mjs +0 -5
  21. package/template/core/engine/commands/upgrade.mjs +0 -159
  22. package/template/core/engine/commands/validate.mjs +0 -17
  23. package/template/core/engine/document-export.mjs +0 -15
  24. package/template/core/engine/init.mjs +0 -90
  25. package/template/core/engine/output/chrome-pdf.d.mts +0 -34
  26. package/template/core/engine/output/chrome-pdf.mjs +0 -358
  27. package/template/core/engine/output/deploy-sync.mjs +0 -15
  28. package/template/core/engine/output/fonts.mjs +0 -62
  29. package/template/core/engine/output/katex-assets.mjs +0 -45
  30. package/template/core/engine/output/page-block.mjs +0 -30
  31. package/template/core/engine/output/pdf-media.mjs +0 -45
  32. package/template/core/engine/output/public-assets.mjs +0 -19
  33. package/template/core/engine/output/static-server.mjs +0 -532
  34. package/template/core/engine/react/caption-numbering.mjs +0 -73
  35. package/template/core/engine/react/comment-endpoint.d.mts +0 -11
  36. package/template/core/engine/react/comment-endpoint.mjs +0 -102
  37. package/template/core/engine/react/comment-marker.mjs +0 -374
  38. package/template/core/engine/react/document-entry.mjs +0 -324
  39. package/template/core/engine/react/document-export.mjs +0 -373
  40. package/template/core/engine/react/http-json.mjs +0 -24
  41. package/template/core/engine/react/mdx-compile.mjs +0 -599
  42. package/template/core/engine/react/measurement-css.mjs +0 -136
  43. package/template/core/engine/react/object-entities.mjs +0 -119
  44. package/template/core/engine/react/pagination/allocator.mjs +0 -122
  45. package/template/core/engine/react/pagination/regions.mjs +0 -81
  46. package/template/core/engine/react/pagination-constants.mjs +0 -3
  47. package/template/core/engine/react/pagination.mjs +0 -9
  48. package/template/core/engine/react/pipeline/allocate.mjs +0 -251
  49. package/template/core/engine/react/pipeline/final-render.mjs +0 -94
  50. package/template/core/engine/react/pipeline/frame-measurement.mjs +0 -302
  51. package/template/core/engine/react/pipeline/press-tree.mjs +0 -135
  52. package/template/core/engine/react/project-asset-endpoint.d.mts +0 -10
  53. package/template/core/engine/react/project-asset-endpoint.mjs +0 -361
  54. package/template/core/engine/react/section-css.mjs +0 -56
  55. package/template/core/engine/react/source-edit-endpoint.d.mts +0 -10
  56. package/template/core/engine/react/source-edit-endpoint.mjs +0 -75
  57. package/template/core/engine/react/sources/heading-numbering.mjs +0 -132
  58. package/template/core/engine/react/sources/mdx-resolver.mjs +0 -439
  59. package/template/core/engine/react/style-discovery.mjs +0 -142
  60. package/template/core/engine/runtime/config.d.mts +0 -40
  61. package/template/core/engine/runtime/config.mjs +0 -175
  62. package/template/core/engine/runtime/file-utils.mjs +0 -106
  63. package/template/core/engine/runtime/file-walk.mjs +0 -22
  64. package/template/core/engine/runtime/inspection.mjs +0 -328
  65. package/template/core/engine/runtime/issue-report.mjs +0 -44
  66. package/template/core/engine/runtime/path-utils.mjs +0 -20
  67. package/template/core/engine/runtime/source-text-tools.d.mts +0 -102
  68. package/template/core/engine/runtime/source-text-tools.mjs +0 -832
  69. package/template/core/engine/runtime/source-workspace.mjs +0 -159
  70. package/template/core/engine/runtime/validation.mjs +0 -174
  71. package/template/core/index.html +0 -13
  72. package/template/core/openpress.config.mjs +0 -12
  73. package/template/core/package.json +0 -91
  74. package/template/core/src/main.tsx +0 -16
  75. package/template/core/src/openpress/app/OpenPressApp.tsx +0 -140
  76. package/template/core/src/openpress/app/OpenPressRuntime.tsx +0 -94
  77. package/template/core/src/openpress/app/index.ts +0 -2
  78. package/template/core/src/openpress/core/Frame.tsx +0 -78
  79. package/template/core/src/openpress/core/FrameContext.tsx +0 -24
  80. package/template/core/src/openpress/core/MdxArea.tsx +0 -34
  81. package/template/core/src/openpress/core/Press.tsx +0 -34
  82. package/template/core/src/openpress/core/cn.ts +0 -4
  83. package/template/core/src/openpress/core/index.tsx +0 -40
  84. package/template/core/src/openpress/core/primitives.tsx +0 -44
  85. package/template/core/src/openpress/core/types.ts +0 -191
  86. package/template/core/src/openpress/core/useSource.ts +0 -28
  87. package/template/core/src/openpress/document-model/anchorMapModel.ts +0 -27
  88. package/template/core/src/openpress/document-model/documentIndexes.ts +0 -329
  89. package/template/core/src/openpress/document-model/documentTypes.ts +0 -138
  90. package/template/core/src/openpress/document-model/index.ts +0 -6
  91. package/template/core/src/openpress/document-model/objectEntityModel.ts +0 -51
  92. package/template/core/src/openpress/document-model/projectIdentityModel.ts +0 -15
  93. package/template/core/src/openpress/document-model/reactDocumentMetadataModel.ts +0 -27
  94. package/template/core/src/openpress/manuscript/index.tsx +0 -238
  95. package/template/core/src/openpress/mdx/index.ts +0 -88
  96. package/template/core/src/openpress/numbering/index.ts +0 -294
  97. package/template/core/src/openpress/reader/PublicReaderPage.tsx +0 -267
  98. package/template/core/src/openpress/reader/ReaderNavigationPanel.tsx +0 -123
  99. package/template/core/src/openpress/reader/index.ts +0 -10
  100. package/template/core/src/openpress/reader/pageViewportScaleModel.ts +0 -73
  101. package/template/core/src/openpress/reader/readerPageRegistry.ts +0 -41
  102. package/template/core/src/openpress/reader/readerPageRoute.ts +0 -21
  103. package/template/core/src/openpress/reader/readerScroll.ts +0 -92
  104. package/template/core/src/openpress/reader/readerStateModel.ts +0 -15
  105. package/template/core/src/openpress/reader/readerTypes.ts +0 -4
  106. package/template/core/src/openpress/reader/usePageViewportScale.ts +0 -119
  107. package/template/core/src/openpress/reader/usePanelState.ts +0 -56
  108. package/template/core/src/openpress/reader/useReaderHashSync.ts +0 -61
  109. package/template/core/src/openpress/reader/useReaderKeyboardNav.ts +0 -48
  110. package/template/core/src/openpress/reader/useReaderRuntime.ts +0 -146
  111. package/template/core/src/openpress/reader/useReaderScrollAnchor.ts +0 -64
  112. package/template/core/src/openpress/shared/Panel.tsx +0 -77
  113. package/template/core/src/openpress/shared/frameScheduler.ts +0 -32
  114. package/template/core/src/openpress/shared/index.ts +0 -4
  115. package/template/core/src/openpress/shared/numberUtils.ts +0 -3
  116. package/template/core/src/openpress/shared/runtimeMode.ts +0 -11
  117. package/template/core/src/openpress/workbench/Workbench.tsx +0 -407
  118. package/template/core/src/openpress/workbench/actions/DeploymentControl.tsx +0 -157
  119. package/template/core/src/openpress/workbench/actions/PageZoomControl.tsx +0 -182
  120. package/template/core/src/openpress/workbench/actions/SearchControl.tsx +0 -345
  121. package/template/core/src/openpress/workbench/actions/deploymentStatusModel.ts +0 -112
  122. package/template/core/src/openpress/workbench/actions/index.ts +0 -5
  123. package/template/core/src/openpress/workbench/actions/useDeploymentWorkbench.ts +0 -136
  124. package/template/core/src/openpress/workbench/dialog/WorkbenchDialog.tsx +0 -72
  125. package/template/core/src/openpress/workbench/dialog/index.ts +0 -1
  126. package/template/core/src/openpress/workbench/document/components/DocumentPanel.tsx +0 -127
  127. package/template/core/src/openpress/workbench/document/components/InlineSourceEditorLayer.tsx +0 -207
  128. package/template/core/src/openpress/workbench/document/components/ReaderStage.tsx +0 -9
  129. package/template/core/src/openpress/workbench/document/hooks/useDocumentWorkbenchModel.ts +0 -34
  130. package/template/core/src/openpress/workbench/document/hooks/useInlineDocumentEditor.ts +0 -525
  131. package/template/core/src/openpress/workbench/document/index.ts +0 -10
  132. package/template/core/src/openpress/workbench/index.ts +0 -2
  133. package/template/core/src/openpress/workbench/inspector/InlineInspectorLayer.tsx +0 -459
  134. package/template/core/src/openpress/workbench/inspector/index.ts +0 -5
  135. package/template/core/src/openpress/workbench/inspector/inlineCommentModel.ts +0 -125
  136. package/template/core/src/openpress/workbench/inspector/inspectorGeometryModel.ts +0 -160
  137. package/template/core/src/openpress/workbench/inspector/inspectorModel.ts +0 -408
  138. package/template/core/src/openpress/workbench/inspector/useInspectorComments.ts +0 -248
  139. package/template/core/src/openpress/workbench/mentions/MentionSuggestionList.tsx +0 -41
  140. package/template/core/src/openpress/workbench/mentions/index.ts +0 -2
  141. package/template/core/src/openpress/workbench/mentions/useComposerMentions.ts +0 -185
  142. package/template/core/src/openpress/workbench/panels/Panel.tsx +0 -1
  143. package/template/core/src/openpress/workbench/panels/PendingCommentsPanel.tsx +0 -76
  144. package/template/core/src/openpress/workbench/panels/WorkbenchControlPanel.tsx +0 -29
  145. package/template/core/src/openpress/workbench/panels/index.ts +0 -3
  146. package/template/core/src/openpress/workbench/project/ProjectEntryPanel.tsx +0 -523
  147. package/template/core/src/openpress/workbench/project/ProjectPreviewDialog.tsx +0 -35
  148. package/template/core/src/openpress/workbench/project/index.ts +0 -2
  149. package/template/core/src/openpress/workbench/project/projectPreviewTypes.ts +0 -11
  150. package/template/core/src/openpress/workbench/project/projectSourceModel.ts +0 -24
  151. package/template/core/src/openpress/workbench/shell/WorkbenchShell.tsx +0 -167
  152. package/template/core/src/openpress/workbench/shell/index.ts +0 -1
  153. package/template/core/src/openpress/workbench/workbenchFormatters.ts +0 -120
  154. package/template/core/src/openpress/workbench/workbenchTypes.ts +0 -35
  155. package/template/core/src/styles/openpress/app-shell.css +0 -251
  156. package/template/core/src/styles/openpress/media-workspace.css +0 -230
  157. package/template/core/src/styles/openpress/print-route.css +0 -184
  158. package/template/core/src/styles/openpress/project-preview-panel.css +0 -924
  159. package/template/core/src/styles/openpress/public-viewer.css +0 -688
  160. package/template/core/src/styles/openpress/reader-runtime.css +0 -980
  161. package/template/core/src/styles/openpress/responsive.css +0 -245
  162. package/template/core/src/styles/openpress/workbench-panels.css +0 -594
  163. package/template/core/src/styles/openpress/workbench.css +0 -1255
  164. package/template/core/src/styles/openpress.css +0 -14
  165. package/template/core/src/vite-env.d.ts +0 -9
  166. package/template/core/tsconfig.json +0 -40
  167. package/template/core/vite.config.ts +0 -584
  168. package/template/packs/academic-paper/document/chapters/01-introduction/content/01-introduction.mdx +0 -35
  169. package/template/packs/academic-paper/document/chapters/02-methods/content/01-methods.mdx +0 -50
  170. package/template/packs/academic-paper/document/chapters/03-results-and-discussion/content/01-results.mdx +0 -47
  171. package/template/packs/academic-paper/document/chapters/04-acknowledgment/content/01-acknowledgment.mdx +0 -26
  172. package/template/packs/academic-paper/document/chapters/05-references/content/01-references.mdx +0 -32
  173. package/template/packs/academic-paper/document/components/ChapterOpenerVisual/index.tsx +0 -76
  174. package/template/packs/academic-paper/document/components/Page.tsx +0 -60
  175. package/template/packs/academic-paper/document/components/TokenSwatchGrid/index.tsx +0 -46
  176. package/template/packs/academic-paper/document/components/TokenSwatchGrid/style.css +0 -63
  177. package/template/packs/academic-paper/document/components/TypeSpecimen/index.tsx +0 -38
  178. package/template/packs/academic-paper/document/components/TypeSpecimen/style.css +0 -111
  179. package/template/packs/academic-paper/document/design.md +0 -279
  180. package/template/packs/academic-paper/document/index.tsx +0 -123
  181. package/template/packs/academic-paper/document/media/README.md +0 -13
  182. package/template/packs/academic-paper/document/media/figure-placeholder.svg +0 -9
  183. package/template/packs/academic-paper/document/openpress.config.mjs +0 -26
  184. package/template/packs/academic-paper/document/theme/README.md +0 -11
  185. package/template/packs/academic-paper/document/theme/base/page-contract.css +0 -522
  186. package/template/packs/academic-paper/document/theme/base/print.css +0 -93
  187. package/template/packs/academic-paper/document/theme/base/typography.css +0 -333
  188. package/template/packs/academic-paper/document/theme/fonts.css +0 -3
  189. package/template/packs/academic-paper/document/theme/page-surfaces/back-cover.css +0 -43
  190. package/template/packs/academic-paper/document/theme/page-surfaces/chapter-opener.css +0 -205
  191. package/template/packs/academic-paper/document/theme/page-surfaces/cover.css +0 -294
  192. package/template/packs/academic-paper/document/theme/page-surfaces/toc.css +0 -149
  193. package/template/packs/academic-paper/document/theme/patterns/_chart-frame.css +0 -49
  194. package/template/packs/academic-paper/document/theme/patterns/figure-grid.css +0 -68
  195. package/template/packs/academic-paper/document/theme/patterns/table-utilities.css +0 -66
  196. package/template/packs/academic-paper/document/theme/shell/reader-controls.css +0 -761
  197. package/template/packs/academic-paper/document/theme/tokens.css +0 -80
  198. package/template/packs/academic-paper/openpress.config.mjs +0 -5
  199. package/template/packs/claude-document/document/chapters/01-document-shape/content/01-document-shape.mdx +0 -51
  200. package/template/packs/claude-document/document/chapters/02-review-loop/content/01-review-loop.mdx +0 -31
  201. package/template/packs/claude-document/document/components/ChapterOpenerVisual.tsx +0 -96
  202. package/template/packs/claude-document/document/components/Page.tsx +0 -37
  203. package/template/packs/claude-document/document/design.md +0 -142
  204. package/template/packs/claude-document/document/index.tsx +0 -94
  205. package/template/packs/claude-document/document/media/README.md +0 -13
  206. package/template/packs/claude-document/document/openpress.config.mjs +0 -26
  207. package/template/packs/claude-document/document/theme/README.md +0 -15
  208. package/template/packs/claude-document/document/theme/base/page-contract.css +0 -525
  209. package/template/packs/claude-document/document/theme/base/print.css +0 -93
  210. package/template/packs/claude-document/document/theme/base/typography.css +0 -612
  211. package/template/packs/claude-document/document/theme/fonts.css +0 -4
  212. package/template/packs/claude-document/document/theme/page-surfaces/back-cover.css +0 -72
  213. package/template/packs/claude-document/document/theme/page-surfaces/chapter-opener.css +0 -236
  214. package/template/packs/claude-document/document/theme/page-surfaces/cover.css +0 -309
  215. package/template/packs/claude-document/document/theme/page-surfaces/toc.css +0 -225
  216. package/template/packs/claude-document/document/theme/patterns/_chart-frame.css +0 -53
  217. package/template/packs/claude-document/document/theme/patterns/figure-grid.css +0 -68
  218. package/template/packs/claude-document/document/theme/patterns/table-utilities.css +0 -66
  219. package/template/packs/claude-document/document/theme/shell/reader-controls.css +0 -789
  220. package/template/packs/claude-document/document/theme/tokens.css +0 -89
  221. package/template/packs/claude-document/openpress.config.mjs +0 -5
  222. package/template/packs/editorial-monograph/document/chapters/01-product-and-use-cases/content/01-product-and-use-cases.mdx +0 -31
  223. package/template/packs/editorial-monograph/document/chapters/02-workflow/content/01-workflow.mdx +0 -89
  224. package/template/packs/editorial-monograph/document/chapters/03-agent-skills-contributors/content/01-agent-skills-contributors.mdx +0 -51
  225. package/template/packs/editorial-monograph/document/chapters/04-validation-deploy/content/01-validation-deploy.mdx +0 -39
  226. package/template/packs/editorial-monograph/document/components/ChapterOpenerVisual/index.tsx +0 -76
  227. package/template/packs/editorial-monograph/document/components/Page.tsx +0 -37
  228. package/template/packs/editorial-monograph/document/components/TokenSwatchGrid/index.tsx +0 -46
  229. package/template/packs/editorial-monograph/document/components/TokenSwatchGrid/style.css +0 -63
  230. package/template/packs/editorial-monograph/document/components/TypeSpecimen/index.tsx +0 -38
  231. package/template/packs/editorial-monograph/document/components/TypeSpecimen/style.css +0 -111
  232. package/template/packs/editorial-monograph/document/design.md +0 -279
  233. package/template/packs/editorial-monograph/document/index.tsx +0 -97
  234. package/template/packs/editorial-monograph/document/media/README.md +0 -13
  235. package/template/packs/editorial-monograph/document/openpress.config.mjs +0 -26
  236. package/template/packs/editorial-monograph/document/theme/README.md +0 -11
  237. package/template/packs/editorial-monograph/document/theme/base/page-contract.css +0 -505
  238. package/template/packs/editorial-monograph/document/theme/base/print.css +0 -93
  239. package/template/packs/editorial-monograph/document/theme/base/typography.css +0 -336
  240. package/template/packs/editorial-monograph/document/theme/fonts.css +0 -3
  241. package/template/packs/editorial-monograph/document/theme/page-surfaces/back-cover.css +0 -43
  242. package/template/packs/editorial-monograph/document/theme/page-surfaces/chapter-opener.css +0 -205
  243. package/template/packs/editorial-monograph/document/theme/page-surfaces/cover.css +0 -147
  244. package/template/packs/editorial-monograph/document/theme/page-surfaces/toc.css +0 -149
  245. package/template/packs/editorial-monograph/document/theme/patterns/_chart-frame.css +0 -49
  246. package/template/packs/editorial-monograph/document/theme/patterns/figure-grid.css +0 -68
  247. package/template/packs/editorial-monograph/document/theme/patterns/table-utilities.css +0 -66
  248. package/template/packs/editorial-monograph/document/theme/shell/reader-controls.css +0 -761
  249. package/template/packs/editorial-monograph/document/theme/tokens.css +0 -80
  250. package/template/packs/editorial-monograph/openpress.config.mjs +0 -5
@@ -1,94 +0,0 @@
1
- import { useMemo, type CSSProperties } from "react";
2
- import { PrintDocument, PublicViewer } from "../reader";
3
- import { isPrintModeLocation, isWorkspaceModeLocation } from "../shared";
4
- import { HtmlWorkbench } from "../workbench";
5
- import type {
6
- DeploymentInfo,
7
- ReaderDocument,
8
- HtmlPageBlock,
9
- Theme,
10
- } from "../document-model";
11
-
12
- interface OpenPressRuntimeProps {
13
- document: ReaderDocument;
14
- deploymentInfo?: DeploymentInfo;
15
- onDocumentRefresh?: () => void | Promise<void>;
16
- }
17
-
18
- export function OpenPressRuntime({
19
- document,
20
- deploymentInfo = { online: false },
21
- onDocumentRefresh,
22
- }: OpenPressRuntimeProps) {
23
- const style = themeToCssVariables(document.theme);
24
- const htmlPages = document.blocks.filter((block): block is HtmlPageBlock => block.kind === "htmlPage");
25
- const workspaceMode = useMemo(() => {
26
- if (typeof window === "undefined") return false;
27
- return isWorkspaceModeLocation(window.location);
28
- }, []);
29
- const printMode = useMemo(() => {
30
- if (typeof window === "undefined") return false;
31
- return isPrintModeLocation(window.location);
32
- }, []);
33
-
34
- if (htmlPages.length > 0) {
35
- if (printMode) {
36
- return <PrintDocument document={document} pages={htmlPages} style={style} />;
37
- }
38
-
39
- if (!workspaceMode) {
40
- return <PublicViewer document={document} pages={htmlPages} style={style} deploymentInfo={deploymentInfo} />;
41
- }
42
-
43
- return (
44
- <HtmlWorkbench
45
- document={document}
46
- pages={htmlPages}
47
- style={style}
48
- devMode={workspaceMode}
49
- deploymentInfo={deploymentInfo}
50
- onDocumentRefresh={onDocumentRefresh}
51
- />
52
- );
53
- }
54
-
55
- return <EmptyState style={style} workspaceMode={workspaceMode} />;
56
- }
57
-
58
- function EmptyState({ style, workspaceMode }: { style: CSSProperties; workspaceMode: boolean }) {
59
- return (
60
- <main className="openpress-shell openpress-empty-state" style={style}>
61
- <section className="openpress-empty-state__panel">
62
- <p className="openpress-empty-state__eyebrow">OpenPress</p>
63
- <h1 className="openpress-empty-state__title">This document has no content yet.</h1>
64
- <p className="openpress-empty-state__body">
65
- Add React MDX chapter files under <code>document/chapters/**/content/</code>, then re-export.
66
- </p>
67
- {workspaceMode ? (
68
- <ol className="openpress-empty-state__steps">
69
- <li><code>npm run openpress:export</code> &nbsp;— refreshes <code>public/openpress/document.json</code></li>
70
- <li>Reload this page</li>
71
- </ol>
72
- ) : (
73
- <p className="openpress-empty-state__body">
74
- (If you are the document author, run <code>npm run dev</code> locally to edit.)
75
- </p>
76
- )}
77
- </section>
78
- </main>
79
- );
80
- }
81
-
82
- function themeToCssVariables(theme?: Theme) {
83
- const style: CSSProperties & Record<`--${string}`, string> = {
84
- "--openpress-font-family": theme?.fontFamily ?? "'Noto Sans TC', 'PingFang TC', sans-serif",
85
- "--openpress-accent": theme?.accentColor ?? "#df4b21",
86
- "--openpress-text": theme?.textColor ?? "#20242a",
87
- };
88
-
89
- if (theme?.pageWidth) style["--openpress-page-width"] = theme.pageWidth;
90
- if (theme?.pageHeight) style["--openpress-page-height"] = theme.pageHeight;
91
- if (theme?.pagePadding) style["--openpress-page-padding"] = theme.pagePadding;
92
-
93
- return style;
94
- }
@@ -1,2 +0,0 @@
1
- export { OpenPressApp } from "./OpenPressApp";
2
- export { OpenPressRuntime } from "./OpenPressRuntime";
@@ -1,78 +0,0 @@
1
- import { useContext } from "react";
2
- import { cn } from "./cn";
3
- import { FrameContext, type FrameContextValue } from "./FrameContext";
4
- import { PressContext } from "./Press";
5
- import type { FrameProps } from "./types";
6
- import { createFrameObjectEntityId } from "../document-model/objectEntityModel";
7
-
8
- // Substring reserved for the overflow extension pipeline.
9
- const RESERVED_EXTENDED = ":extended:";
10
-
11
- export const FRAME_MARKER: unique symbol = Symbol.for("@open-press/core:Frame");
12
-
13
- export function Frame({
14
- frameKey,
15
- role,
16
- chrome = true,
17
- className,
18
- children,
19
- ...rest
20
- }: FrameProps) {
21
- if (!frameKey || !String(frameKey).trim()) {
22
- throw new Error("Frame requires a non-empty frameKey.");
23
- }
24
- if (frameKey && frameKey.includes(RESERVED_EXTENDED)) {
25
- throw new Error(
26
- `Frame frameKey="${frameKey}" contains reserved substring ":extended:". ` +
27
- `This pattern is reserved for the overflow-extension pipeline.`,
28
- );
29
- }
30
-
31
- const press = useContext(PressContext);
32
- const allocation = press?.allocation ?? null;
33
- const frameAllocation = frameKey && allocation ? allocation[frameKey] : undefined;
34
-
35
- // Mutable per-render counter. SSR renders a Frame exactly once, so a plain
36
- // object is fine — no useRef needed.
37
- const areaCounts: Record<string, number> = {};
38
- const frameContextValue: FrameContextValue = {
39
- frameKey: frameKey ?? "",
40
- consumeArea(chainId: string) {
41
- const index = areaCounts[chainId] ?? 0;
42
- areaCounts[chainId] = index + 1;
43
- if (!frameAllocation) return { indexInFrame: index, blocks: null };
44
- const chainSlots = frameAllocation[chainId];
45
- if (!chainSlots) return { indexInFrame: index, blocks: null };
46
- return { indexInFrame: index, blocks: chainSlots[index] ?? null };
47
- },
48
- };
49
-
50
- const pageKind = derivePageKind(role);
51
-
52
- return (
53
- <FrameContext.Provider value={frameContextValue}>
54
- <section
55
- {...(rest as Record<string, unknown>)}
56
- className={cn("reader-page", className)}
57
- data-openpress-frame-key={frameKey}
58
- data-openpress-object-id={createFrameObjectEntityId(frameKey)}
59
- data-frame-role={role}
60
- data-page-kind={pageKind}
61
- data-frame-chrome={chrome ? "true" : "false"}
62
- data-page-footer={chrome ? "true" : "false"}
63
- >
64
- {children}
65
- </section>
66
- </FrameContext.Provider>
67
- );
68
- }
69
-
70
- (Frame as unknown as { openpressMarker: typeof FRAME_MARKER }).openpressMarker = FRAME_MARKER;
71
-
72
- function derivePageKind(role: string | undefined): string | undefined {
73
- if (!role) return undefined;
74
- const trimmed = role.trim();
75
- if (!trimmed) return undefined;
76
- const lastDot = trimmed.lastIndexOf(".");
77
- return lastDot === -1 ? trimmed : trimmed.slice(lastDot + 1);
78
- }
@@ -1,24 +0,0 @@
1
- import { createContext, type ReactNode } from "react";
2
-
3
- // FrameContext is the runtime channel between Frame and its descendant
4
- // MdxArea instances. Frame creates one of these on each render; MdxArea
5
- // reads it to claim its slot of allocated content.
6
- //
7
- // "Claiming" is order-sensitive: the first <MdxArea chainId="X"> rendered
8
- // inside a Frame takes areaIndex 0 for chain X, the next takes index 1,
9
- // and so on. Empty Frames (no allocation) return null, which renders the
10
- // MdxArea as a measurement placeholder.
11
-
12
- export interface ConsumedMdxArea {
13
- indexInFrame: number;
14
- // Null when the frame has no allocation (measurement pass) or no blocks
15
- // for this chain at the claimed index.
16
- blocks: ReactNode | null;
17
- }
18
-
19
- export interface FrameContextValue {
20
- frameKey: string;
21
- consumeArea(chainId: string): ConsumedMdxArea;
22
- }
23
-
24
- export const FrameContext = createContext<FrameContextValue | null>(null);
@@ -1,34 +0,0 @@
1
- import { useContext, type ReactNode } from "react";
2
- import { cn } from "./cn";
3
- import { FrameContext } from "./FrameContext";
4
- import type { MdxAreaProps } from "./types";
5
- import { createMdxAreaObjectEntityId } from "../document-model/objectEntityModel";
6
-
7
- export function MdxArea({
8
- chainId,
9
- overflow = "extend",
10
- className,
11
- ...rest
12
- }: MdxAreaProps) {
13
- const frame = useContext(FrameContext);
14
- const consumed = frame?.consumeArea(chainId) ?? null;
15
- const blocks: ReactNode | null = consumed?.blocks ?? null;
16
- const objectId = frame && consumed
17
- ? createMdxAreaObjectEntityId(frame.frameKey, chainId, consumed.indexInFrame)
18
- : undefined;
19
-
20
- return (
21
- <div
22
- {...(rest as Record<string, unknown>)}
23
- className={cn("openpress-mdx-area", className)}
24
- data-openpress-mdx-area="true"
25
- data-openpress-mdx-area-chain={chainId}
26
- data-openpress-mdx-area-index={consumed?.indexInFrame}
27
- data-openpress-object-id={objectId}
28
- data-openpress-mdx-area-overflow={overflow}
29
- data-openpress-mdx-area-empty={blocks == null ? "true" : "false"}
30
- >
31
- {blocks}
32
- </div>
33
- );
34
- }
@@ -1,34 +0,0 @@
1
- import { createContext, Fragment, type ReactNode } from "react";
2
- import type { FrameAllocation, ResolvedSource, TocEntry } from "./types";
3
-
4
- // Marker the engine uses to distinguish a Press default export from any other
5
- // React component. Workspaces register a default export whose `type` is this
6
- // `Press` component; the engine identity-checks against it.
7
- export const PRESS_MARKER: unique symbol = Symbol.for("@open-press/core:Press");
8
-
9
- // Allocation hints feed Layer 4 results back to Layer 2 so helpers like
10
- // <Sections> can emit the correct number of pages per chain. Null during
11
- // the first pass; populated after the allocator has decided how many
12
- // frames each chain needs.
13
- export interface AllocationHints {
14
- totalPagesPerChain: Record<string, number>;
15
- }
16
-
17
- export interface PressContextValue {
18
- sources: Record<string, ResolvedSource>;
19
- // Allocation map keyed by frameKey -> chainId -> areaIndex -> blocks.
20
- // null during measurement passes; populated during final render.
21
- allocation: FrameAllocation | null;
22
- // Allocation hints fed back from Layer 4 to Layer 2 helpers. null on
23
- // the first measurement pass.
24
- hints: AllocationHints | null;
25
- toc: Record<string, TocEntry[]> | null;
26
- }
27
-
28
- export const PressContext = createContext<PressContextValue | null>(null);
29
-
30
- export function Press({ children }: { children: ReactNode }) {
31
- return <Fragment>{children}</Fragment>;
32
- }
33
-
34
- (Press as unknown as { openpressMarker: typeof PRESS_MARKER }).openpressMarker = PRESS_MARKER;
@@ -1,4 +0,0 @@
1
- export function cn(...values: Array<string | false | null | undefined>) {
2
- const joined = values.filter(Boolean).join(" ");
3
- return joined.length > 0 ? joined : undefined;
4
- }
@@ -1,40 +0,0 @@
1
- // @open-press/core — Press tree primitives.
2
- //
3
- // Layout: this entry exports only the kernel. Source descriptors live in
4
- // `@open-press/core/mdx`; manuscript helpers live in
5
- // `@open-press/core/manuscript`. Keeping the surface small is intentional —
6
- // the engine is not allowed to know about higher-level conventions.
7
-
8
- export { Press, PressContext, PRESS_MARKER } from "./Press";
9
- export { Frame, FRAME_MARKER } from "./Frame";
10
- export { FrameContext } from "./FrameContext";
11
- export { MdxArea } from "./MdxArea";
12
- export { useSource } from "./useSource";
13
- export { BaseFigure, BaseCallout, MediaFigure, ImageFigure } from "./primitives";
14
-
15
- export type {
16
- FrameProps,
17
- FrameRole,
18
- MdxAreaProps,
19
- MdxAreaOverflow,
20
- PressProps,
21
- BaseFigureProps,
22
- MediaFigureProps,
23
- BaseCalloutKind,
24
- BaseCalloutProps,
25
- Manifest,
26
- // Source-side types are re-exported here for convenience so authors can
27
- // import `ResolvedSource` from the same place they import primitives.
28
- ResolvedSource,
29
- SourceNode,
30
- OutlineItem,
31
- SourceFileRecord,
32
- SourceBlock,
33
- TocEntry,
34
- MdxSourceDescriptor,
35
- SourceDescriptor,
36
- FrameAllocation,
37
- } from "./types";
38
-
39
- export type { PressContextValue, AllocationHints } from "./Press";
40
- export type { FrameContextValue } from "./FrameContext";
@@ -1,44 +0,0 @@
1
- import { cn } from "./cn";
2
- import type { BaseCalloutProps, BaseFigureProps, MediaFigureProps } from "./types";
3
-
4
- export function BaseFigure({ caption, className, children, ...figureProps }: BaseFigureProps) {
5
- return (
6
- <figure {...figureProps} className={cn("openpress-figure", className)}>
7
- <div data-figure-body>{children}</div>
8
- {caption === undefined ? null : <figcaption>{caption}</figcaption>}
9
- </figure>
10
- );
11
- }
12
-
13
- export function BaseCallout({ kind = "info", className, children, ...calloutProps }: BaseCalloutProps) {
14
- return (
15
- <aside {...calloutProps} className={cn("openpress-callout", className)} data-callout-kind={kind}>
16
- {children}
17
- </aside>
18
- );
19
- }
20
-
21
- export function MediaFigure({
22
- src,
23
- alt,
24
- caption,
25
- className,
26
- imgClassName,
27
- loading = "eager",
28
- ...figureProps
29
- }: MediaFigureProps) {
30
- return (
31
- <BaseFigure {...figureProps} className={cn("openpress-media-figure", className)} caption={caption}>
32
- <img src={resolveMediaSrc(src)} alt={alt} loading={loading} className={imgClassName} />
33
- </BaseFigure>
34
- );
35
- }
36
-
37
- export const ImageFigure = MediaFigure;
38
-
39
- function resolveMediaSrc(src: string) {
40
- const trimmed = String(src ?? "").trim();
41
- if (!trimmed) return "";
42
- if (/^(?:[a-z][a-z0-9+.-]*:|\/)/i.test(trimmed)) return trimmed;
43
- return `/openpress/media/${trimmed.replace(/^\.?\/*/, "")}`;
44
- }
@@ -1,191 +0,0 @@
1
- import type { HTMLAttributes, ReactNode } from "react";
2
-
3
- // ---------------------------------------------------------------------------
4
- // Frame / MdxArea / Press primitives
5
- // ---------------------------------------------------------------------------
6
-
7
- // `role` is opaque to core. Helpers and themes interpret it; the engine
8
- // never branches on its value. Format convention is dotted, e.g.
9
- // "manuscript.cover", "manuscript.content", "folio.page".
10
- export type FrameRole = string;
11
-
12
- export type FrameProps = Omit<HTMLAttributes<HTMLElement>, "role" | "children"> & {
13
- frameKey: string;
14
- role?: FrameRole;
15
- chrome?: boolean;
16
- className?: string;
17
- children?: ReactNode;
18
- };
19
-
20
- export type MdxAreaOverflow = "extend" | "truncate" | "error";
21
-
22
- export type MdxAreaProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
23
- chainId: string;
24
- overflow?: MdxAreaOverflow;
25
- className?: string;
26
- };
27
-
28
- export interface PressProps {
29
- children: ReactNode;
30
- }
31
-
32
- // ---------------------------------------------------------------------------
33
- // Content primitives (figure, callout)
34
- // ---------------------------------------------------------------------------
35
-
36
- export type BaseFigureProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
37
- caption?: ReactNode;
38
- children: ReactNode;
39
- };
40
-
41
- export type MediaFigureProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
42
- src: string;
43
- alt: string;
44
- caption: ReactNode;
45
- imgClassName?: string;
46
- loading?: "eager" | "lazy";
47
- };
48
-
49
- export type BaseCalloutKind = "info" | "warn" | "success" | "error" | (string & {});
50
-
51
- export type BaseCalloutProps = Omit<HTMLAttributes<HTMLElement>, "children"> & {
52
- kind?: BaseCalloutKind;
53
- children: ReactNode;
54
- };
55
-
56
- // ---------------------------------------------------------------------------
57
- // Source descriptors and resolved sources
58
- // ---------------------------------------------------------------------------
59
-
60
- export interface MdxSourceDescriptorSectionFolders {
61
- type: "mdx";
62
- preset: "section-folders";
63
- root?: string;
64
- }
65
-
66
- export interface MdxSourceDescriptorSectionFiles {
67
- type: "mdx";
68
- preset: "section-files";
69
- root?: string;
70
- }
71
-
72
- export interface MdxSourceDescriptorFileList {
73
- type: "mdx";
74
- preset: "file-list";
75
- files: string[];
76
- }
77
-
78
- export type MdxSourceDescriptor =
79
- | MdxSourceDescriptorSectionFolders
80
- | MdxSourceDescriptorSectionFiles
81
- | MdxSourceDescriptorFileList;
82
-
83
- export type SourceDescriptor = MdxSourceDescriptor;
84
-
85
- export interface SourceNode {
86
- id: string;
87
- slug: string;
88
- title: string;
89
- meta?: Record<string, unknown>;
90
- children?: SourceNode[];
91
- }
92
-
93
- export interface OutlineItem {
94
- id: string;
95
- depth: number;
96
- title: string;
97
- sectionSlug: string;
98
- pageNumber?: number;
99
- }
100
-
101
- export interface TocEntry {
102
- id: string;
103
- blockId: string;
104
- sourceId: string;
105
- sectionSlug: string;
106
- title: string;
107
- href: string;
108
- level: 2 | 3;
109
- label: string;
110
- pageNumber?: number;
111
- }
112
-
113
- export interface SourceFileRecord {
114
- path: string;
115
- absolutePath: string;
116
- sectionSlug: string;
117
- }
118
-
119
- export interface SourceBlock {
120
- id: string;
121
- kind: string;
122
- name?: string;
123
- chainId: string;
124
- sectionSlug: string;
125
- path: string;
126
- source: {
127
- file: string;
128
- line?: number;
129
- column?: number;
130
- offset?: number;
131
- };
132
- }
133
-
134
- export interface ResolvedSource {
135
- id: string;
136
- type: "mdx";
137
- tree: SourceNode[];
138
- outline: OutlineItem[];
139
- chains: Record<string, SourceBlock[]>;
140
- files: SourceFileRecord[];
141
- }
142
-
143
- // ---------------------------------------------------------------------------
144
- // Allocation context shape (engine -> Frame -> MdxArea)
145
- // ---------------------------------------------------------------------------
146
-
147
- // Per-frame, per-chain, ordered list of React nodes assigned to each
148
- // MdxArea by area index.
149
- export type FrameAllocation = Record<string, Record<string, ReactNode[]>>;
150
-
151
- // ---------------------------------------------------------------------------
152
- // Manifest
153
- // ---------------------------------------------------------------------------
154
-
155
- export interface Manifest {
156
- title: string;
157
- subtitle?: string;
158
- organization?: string;
159
- workspaceLabel?: string;
160
- documentDir?: string;
161
- sourceDir?: string;
162
- componentsDir?: string;
163
- mediaDir?: string;
164
- themeDir?: string;
165
- designDoc?: string;
166
- publicDir?: string;
167
- outputDir?: string;
168
- captionNumbering?: {
169
- figure?: string;
170
- table?: string;
171
- separator?: string;
172
- };
173
- pdf?: {
174
- filename?: string;
175
- };
176
- deploy?: {
177
- adapter?: string;
178
- source?: string;
179
- projectName?: string | null;
180
- commitDirty?: boolean;
181
- requiresConfirmation?: boolean;
182
- };
183
- paths?: {
184
- chaptersDir?: string;
185
- sourceDir?: string;
186
- componentsDir?: string;
187
- mediaDir?: string;
188
- themeDir?: string;
189
- designDoc?: string;
190
- };
191
- }
@@ -1,28 +0,0 @@
1
- import { useContext } from "react";
2
- import { PressContext } from "./Press";
3
- import type { ResolvedSource } from "./types";
4
-
5
- // Read a resolved source by its registered key. The engine populates the
6
- // PressContext before rendering, so this is synchronous and safe to call
7
- // from any component inside <Press>.
8
- //
9
- // Throws if the source is missing, with a hint listing known sources.
10
- export function useSource<T extends ResolvedSource = ResolvedSource>(id: string): T {
11
- const ctx = useContext(PressContext);
12
- if (!ctx) {
13
- throw new Error(
14
- `useSource("${id}") called outside <Press> tree. ` +
15
- `Source hooks only work inside the default-exported <Press> component.`,
16
- );
17
- }
18
- const source = ctx.sources[id];
19
- if (!source) {
20
- const known = Object.keys(ctx.sources).sort();
21
- const knownText = known.length > 0 ? known.join(", ") : "(none)";
22
- throw new Error(
23
- `Unknown source "${id}". Available sources: ${knownText}. ` +
24
- `Register it under \`export const sources\` in document/index.tsx.`,
25
- );
26
- }
27
- return source as T;
28
- }
@@ -1,27 +0,0 @@
1
- // Anchor → page-index resolution shared between the public viewer and
2
- // the workbench. Lives in its own module so React Fast Refresh can keep
3
- // `PublicPage` / `HtmlWorkbench` HMR-clean (Fast Refresh expects component
4
- // files to export only components).
5
-
6
- import type { DisplayPage } from "../reader";
7
-
8
- export function createAnchorPageMap(pages: DisplayPage[]) {
9
- const map = new Map<string, number>();
10
- pages.forEach((page, index) => {
11
- page.anchors?.forEach((anchor) => {
12
- if (anchor && !map.has(anchor)) map.set(anchor, index);
13
- });
14
- });
15
- return map;
16
- }
17
-
18
- export function resolveAnchorPageIndex(
19
- anchorPageMap: Map<string, number>,
20
- pageCount: number,
21
- anchorId: string,
22
- pageIndex?: number,
23
- ): number | null {
24
- if (typeof pageIndex === "number" && Number.isInteger(pageIndex) && pageIndex >= 0 && pageIndex < pageCount) return pageIndex;
25
- const mapped = anchorPageMap.get(anchorId);
26
- return mapped === undefined ? null : mapped;
27
- }