@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.
- package/README.md +33 -23
- package/dist/cli.js +320 -252
- package/package.json +9 -8
- package/template/core/AGENTS.md +0 -126
- package/template/core/CHANGELOG.md +0 -215
- package/template/core/README.md +0 -40
- package/template/core/engine/cli.mjs +0 -96
- package/template/core/engine/commands/_shared.mjs +0 -177
- package/template/core/engine/commands/deploy.mjs +0 -31
- package/template/core/engine/commands/dev.mjs +0 -49
- package/template/core/engine/commands/doctor.mjs +0 -229
- package/template/core/engine/commands/export.mjs +0 -8
- package/template/core/engine/commands/init.mjs +0 -24
- package/template/core/engine/commands/inspect.mjs +0 -35
- package/template/core/engine/commands/pdf.mjs +0 -26
- package/template/core/engine/commands/preview.mjs +0 -26
- package/template/core/engine/commands/render.mjs +0 -17
- package/template/core/engine/commands/replace.mjs +0 -41
- package/template/core/engine/commands/search.mjs +0 -33
- package/template/core/engine/commands/typecheck.mjs +0 -5
- package/template/core/engine/commands/upgrade.mjs +0 -159
- package/template/core/engine/commands/validate.mjs +0 -17
- package/template/core/engine/document-export.mjs +0 -15
- package/template/core/engine/init.mjs +0 -90
- package/template/core/engine/output/chrome-pdf.d.mts +0 -34
- package/template/core/engine/output/chrome-pdf.mjs +0 -358
- package/template/core/engine/output/deploy-sync.mjs +0 -15
- package/template/core/engine/output/fonts.mjs +0 -62
- package/template/core/engine/output/katex-assets.mjs +0 -45
- package/template/core/engine/output/page-block.mjs +0 -30
- package/template/core/engine/output/pdf-media.mjs +0 -45
- package/template/core/engine/output/public-assets.mjs +0 -19
- package/template/core/engine/output/static-server.mjs +0 -532
- package/template/core/engine/react/caption-numbering.mjs +0 -73
- package/template/core/engine/react/comment-endpoint.d.mts +0 -11
- package/template/core/engine/react/comment-endpoint.mjs +0 -102
- package/template/core/engine/react/comment-marker.mjs +0 -374
- package/template/core/engine/react/document-entry.mjs +0 -324
- package/template/core/engine/react/document-export.mjs +0 -373
- package/template/core/engine/react/http-json.mjs +0 -24
- package/template/core/engine/react/mdx-compile.mjs +0 -599
- package/template/core/engine/react/measurement-css.mjs +0 -136
- package/template/core/engine/react/object-entities.mjs +0 -119
- package/template/core/engine/react/pagination/allocator.mjs +0 -122
- package/template/core/engine/react/pagination/regions.mjs +0 -81
- package/template/core/engine/react/pagination-constants.mjs +0 -3
- package/template/core/engine/react/pagination.mjs +0 -9
- package/template/core/engine/react/pipeline/allocate.mjs +0 -251
- package/template/core/engine/react/pipeline/final-render.mjs +0 -94
- package/template/core/engine/react/pipeline/frame-measurement.mjs +0 -302
- package/template/core/engine/react/pipeline/press-tree.mjs +0 -135
- package/template/core/engine/react/project-asset-endpoint.d.mts +0 -10
- package/template/core/engine/react/project-asset-endpoint.mjs +0 -361
- package/template/core/engine/react/section-css.mjs +0 -56
- package/template/core/engine/react/source-edit-endpoint.d.mts +0 -10
- package/template/core/engine/react/source-edit-endpoint.mjs +0 -75
- package/template/core/engine/react/sources/heading-numbering.mjs +0 -132
- package/template/core/engine/react/sources/mdx-resolver.mjs +0 -439
- package/template/core/engine/react/style-discovery.mjs +0 -142
- package/template/core/engine/runtime/config.d.mts +0 -40
- package/template/core/engine/runtime/config.mjs +0 -175
- package/template/core/engine/runtime/file-utils.mjs +0 -106
- package/template/core/engine/runtime/file-walk.mjs +0 -22
- package/template/core/engine/runtime/inspection.mjs +0 -328
- package/template/core/engine/runtime/issue-report.mjs +0 -44
- package/template/core/engine/runtime/path-utils.mjs +0 -20
- package/template/core/engine/runtime/source-text-tools.d.mts +0 -102
- package/template/core/engine/runtime/source-text-tools.mjs +0 -832
- package/template/core/engine/runtime/source-workspace.mjs +0 -159
- package/template/core/engine/runtime/validation.mjs +0 -174
- package/template/core/index.html +0 -13
- package/template/core/openpress.config.mjs +0 -12
- package/template/core/package.json +0 -91
- package/template/core/src/main.tsx +0 -16
- package/template/core/src/openpress/app/OpenPressApp.tsx +0 -140
- package/template/core/src/openpress/app/OpenPressRuntime.tsx +0 -94
- package/template/core/src/openpress/app/index.ts +0 -2
- package/template/core/src/openpress/core/Frame.tsx +0 -78
- package/template/core/src/openpress/core/FrameContext.tsx +0 -24
- package/template/core/src/openpress/core/MdxArea.tsx +0 -34
- package/template/core/src/openpress/core/Press.tsx +0 -34
- package/template/core/src/openpress/core/cn.ts +0 -4
- package/template/core/src/openpress/core/index.tsx +0 -40
- package/template/core/src/openpress/core/primitives.tsx +0 -44
- package/template/core/src/openpress/core/types.ts +0 -191
- package/template/core/src/openpress/core/useSource.ts +0 -28
- package/template/core/src/openpress/document-model/anchorMapModel.ts +0 -27
- package/template/core/src/openpress/document-model/documentIndexes.ts +0 -329
- package/template/core/src/openpress/document-model/documentTypes.ts +0 -138
- package/template/core/src/openpress/document-model/index.ts +0 -6
- package/template/core/src/openpress/document-model/objectEntityModel.ts +0 -51
- package/template/core/src/openpress/document-model/projectIdentityModel.ts +0 -15
- package/template/core/src/openpress/document-model/reactDocumentMetadataModel.ts +0 -27
- package/template/core/src/openpress/manuscript/index.tsx +0 -238
- package/template/core/src/openpress/mdx/index.ts +0 -88
- package/template/core/src/openpress/numbering/index.ts +0 -294
- package/template/core/src/openpress/reader/PublicReaderPage.tsx +0 -267
- package/template/core/src/openpress/reader/ReaderNavigationPanel.tsx +0 -123
- package/template/core/src/openpress/reader/index.ts +0 -10
- package/template/core/src/openpress/reader/pageViewportScaleModel.ts +0 -73
- package/template/core/src/openpress/reader/readerPageRegistry.ts +0 -41
- package/template/core/src/openpress/reader/readerPageRoute.ts +0 -21
- package/template/core/src/openpress/reader/readerScroll.ts +0 -92
- package/template/core/src/openpress/reader/readerStateModel.ts +0 -15
- package/template/core/src/openpress/reader/readerTypes.ts +0 -4
- package/template/core/src/openpress/reader/usePageViewportScale.ts +0 -119
- package/template/core/src/openpress/reader/usePanelState.ts +0 -56
- package/template/core/src/openpress/reader/useReaderHashSync.ts +0 -61
- package/template/core/src/openpress/reader/useReaderKeyboardNav.ts +0 -48
- package/template/core/src/openpress/reader/useReaderRuntime.ts +0 -146
- package/template/core/src/openpress/reader/useReaderScrollAnchor.ts +0 -64
- package/template/core/src/openpress/shared/Panel.tsx +0 -77
- package/template/core/src/openpress/shared/frameScheduler.ts +0 -32
- package/template/core/src/openpress/shared/index.ts +0 -4
- package/template/core/src/openpress/shared/numberUtils.ts +0 -3
- package/template/core/src/openpress/shared/runtimeMode.ts +0 -11
- package/template/core/src/openpress/workbench/Workbench.tsx +0 -407
- package/template/core/src/openpress/workbench/actions/DeploymentControl.tsx +0 -157
- package/template/core/src/openpress/workbench/actions/PageZoomControl.tsx +0 -182
- package/template/core/src/openpress/workbench/actions/SearchControl.tsx +0 -345
- package/template/core/src/openpress/workbench/actions/deploymentStatusModel.ts +0 -112
- package/template/core/src/openpress/workbench/actions/index.ts +0 -5
- package/template/core/src/openpress/workbench/actions/useDeploymentWorkbench.ts +0 -136
- package/template/core/src/openpress/workbench/dialog/WorkbenchDialog.tsx +0 -72
- package/template/core/src/openpress/workbench/dialog/index.ts +0 -1
- package/template/core/src/openpress/workbench/document/components/DocumentPanel.tsx +0 -127
- package/template/core/src/openpress/workbench/document/components/InlineSourceEditorLayer.tsx +0 -207
- package/template/core/src/openpress/workbench/document/components/ReaderStage.tsx +0 -9
- package/template/core/src/openpress/workbench/document/hooks/useDocumentWorkbenchModel.ts +0 -34
- package/template/core/src/openpress/workbench/document/hooks/useInlineDocumentEditor.ts +0 -525
- package/template/core/src/openpress/workbench/document/index.ts +0 -10
- package/template/core/src/openpress/workbench/index.ts +0 -2
- package/template/core/src/openpress/workbench/inspector/InlineInspectorLayer.tsx +0 -459
- package/template/core/src/openpress/workbench/inspector/index.ts +0 -5
- package/template/core/src/openpress/workbench/inspector/inlineCommentModel.ts +0 -125
- package/template/core/src/openpress/workbench/inspector/inspectorGeometryModel.ts +0 -160
- package/template/core/src/openpress/workbench/inspector/inspectorModel.ts +0 -408
- package/template/core/src/openpress/workbench/inspector/useInspectorComments.ts +0 -248
- package/template/core/src/openpress/workbench/mentions/MentionSuggestionList.tsx +0 -41
- package/template/core/src/openpress/workbench/mentions/index.ts +0 -2
- package/template/core/src/openpress/workbench/mentions/useComposerMentions.ts +0 -185
- package/template/core/src/openpress/workbench/panels/Panel.tsx +0 -1
- package/template/core/src/openpress/workbench/panels/PendingCommentsPanel.tsx +0 -76
- package/template/core/src/openpress/workbench/panels/WorkbenchControlPanel.tsx +0 -29
- package/template/core/src/openpress/workbench/panels/index.ts +0 -3
- package/template/core/src/openpress/workbench/project/ProjectEntryPanel.tsx +0 -523
- package/template/core/src/openpress/workbench/project/ProjectPreviewDialog.tsx +0 -35
- package/template/core/src/openpress/workbench/project/index.ts +0 -2
- package/template/core/src/openpress/workbench/project/projectPreviewTypes.ts +0 -11
- package/template/core/src/openpress/workbench/project/projectSourceModel.ts +0 -24
- package/template/core/src/openpress/workbench/shell/WorkbenchShell.tsx +0 -167
- package/template/core/src/openpress/workbench/shell/index.ts +0 -1
- package/template/core/src/openpress/workbench/workbenchFormatters.ts +0 -120
- package/template/core/src/openpress/workbench/workbenchTypes.ts +0 -35
- package/template/core/src/styles/openpress/app-shell.css +0 -251
- package/template/core/src/styles/openpress/media-workspace.css +0 -230
- package/template/core/src/styles/openpress/print-route.css +0 -184
- package/template/core/src/styles/openpress/project-preview-panel.css +0 -924
- package/template/core/src/styles/openpress/public-viewer.css +0 -688
- package/template/core/src/styles/openpress/reader-runtime.css +0 -980
- package/template/core/src/styles/openpress/responsive.css +0 -245
- package/template/core/src/styles/openpress/workbench-panels.css +0 -594
- package/template/core/src/styles/openpress/workbench.css +0 -1255
- package/template/core/src/styles/openpress.css +0 -14
- package/template/core/src/vite-env.d.ts +0 -9
- package/template/core/tsconfig.json +0 -40
- package/template/core/vite.config.ts +0 -584
- 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
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { documentRelativePath } from "../runtime/path-utils.mjs";
|
|
4
|
-
|
|
5
|
-
// Style discovery — only used to find per-section CSS files for the
|
|
6
|
-
// section-folders preset. MDX content discovery lives in `sources/mdx-resolver`.
|
|
7
|
-
// This module exists because section-scoped CSS (`[data-section-id]`) needs
|
|
8
|
-
// to know which section slugs exist before the source descriptor pass.
|
|
9
|
-
|
|
10
|
-
const COMPONENT_EXT = ".tsx";
|
|
11
|
-
|
|
12
|
-
export async function discoverSectionStyles(root = ".", config = {}) {
|
|
13
|
-
const workspaceRoot = path.resolve(root);
|
|
14
|
-
const documentRoot = config.paths?.documentRoot ?? path.join(workspaceRoot, "document");
|
|
15
|
-
const componentsRoot = config.paths?.componentsDir ?? path.join(documentRoot, "components");
|
|
16
|
-
const sectionsRoot = config.paths?.chaptersDir ?? config.paths?.sourceDir ?? path.join(documentRoot, "chapters");
|
|
17
|
-
const globalComponents = await discoverComponents(componentsRoot, documentRoot, "global");
|
|
18
|
-
const sections = await discoverSections(documentRoot, sectionsRoot);
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
root: workspaceRoot,
|
|
22
|
-
documentRoot,
|
|
23
|
-
globalComponents,
|
|
24
|
-
sections,
|
|
25
|
-
// Back-compat: `chapters` alias for callers that still expect the old shape.
|
|
26
|
-
chapters: sections,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function discoverSections(documentRoot, sectionsDir) {
|
|
31
|
-
const entries = await readDirectoryEntries(sectionsDir);
|
|
32
|
-
const sectionDirs = entries.filter((entry) => entry.isDirectory()).sort(compareSectionDirectories);
|
|
33
|
-
|
|
34
|
-
const sections = [];
|
|
35
|
-
for (const entry of sectionDirs) {
|
|
36
|
-
const sectionPath = path.join(sectionsDir, entry.name);
|
|
37
|
-
const contentFiles = await discoverContentFiles(path.join(sectionPath, "content"), documentRoot);
|
|
38
|
-
const styleFiles = await discoverStyleFiles(path.join(sectionPath, "styles"), documentRoot);
|
|
39
|
-
|
|
40
|
-
sections.push({
|
|
41
|
-
directoryName: entry.name,
|
|
42
|
-
slug: sectionSlugFromDirectory(entry.name),
|
|
43
|
-
absolutePath: sectionPath,
|
|
44
|
-
documentPath: documentRelativePath(sectionPath, documentRoot),
|
|
45
|
-
contentFiles,
|
|
46
|
-
styleFiles,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return sections;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function discoverComponents(componentsDir, documentRoot, scope) {
|
|
54
|
-
const entries = await readDirectoryEntries(componentsDir);
|
|
55
|
-
const components = [];
|
|
56
|
-
|
|
57
|
-
for (const entry of entries) {
|
|
58
|
-
if (entry.isFile() && path.extname(entry.name) === COMPONENT_EXT) {
|
|
59
|
-
const absolutePath = path.join(componentsDir, entry.name);
|
|
60
|
-
components.push(componentRecord(path.basename(entry.name, COMPONENT_EXT), absolutePath, documentRoot, scope));
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (entry.isDirectory()) {
|
|
65
|
-
const indexPath = path.join(componentsDir, entry.name, `index${COMPONENT_EXT}`);
|
|
66
|
-
if (await fileExists(indexPath)) {
|
|
67
|
-
components.push(componentRecord(entry.name, indexPath, documentRoot, scope));
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return components.sort((a, b) => a.name.localeCompare(b.name) || a.documentPath.localeCompare(b.documentPath));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function discoverContentFiles(contentDir, documentRoot) {
|
|
76
|
-
return discoverFilesByExtension(contentDir, documentRoot, ".mdx");
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async function discoverStyleFiles(stylesDir, documentRoot) {
|
|
80
|
-
return discoverFilesByExtension(stylesDir, documentRoot, ".css");
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async function discoverFilesByExtension(directory, documentRoot, extension) {
|
|
84
|
-
const entries = await readDirectoryEntries(directory);
|
|
85
|
-
return entries
|
|
86
|
-
.filter((entry) => entry.isFile() && path.extname(entry.name) === extension)
|
|
87
|
-
.sort((a, b) => a.name.localeCompare(b.name))
|
|
88
|
-
.map((entry) => pathRecord(path.join(directory, entry.name), documentRoot));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function componentRecord(name, absolutePath, documentRoot, scope) {
|
|
92
|
-
return {
|
|
93
|
-
name,
|
|
94
|
-
scope,
|
|
95
|
-
...pathRecord(absolutePath, documentRoot),
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function pathRecord(absolutePath, documentRoot) {
|
|
100
|
-
return {
|
|
101
|
-
absolutePath,
|
|
102
|
-
documentPath: documentRelativePath(absolutePath, documentRoot),
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function compareSectionDirectories(a, b) {
|
|
107
|
-
const left = sectionSortKey(a.name);
|
|
108
|
-
const right = sectionSortKey(b.name);
|
|
109
|
-
if (left.order !== right.order) return left.order - right.order;
|
|
110
|
-
return left.name.localeCompare(right.name);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function sectionSortKey(directoryName) {
|
|
114
|
-
const match = directoryName.match(/^(\d+)[-_]?(.*)$/);
|
|
115
|
-
if (!match) {
|
|
116
|
-
return { order: Number.POSITIVE_INFINITY, name: directoryName };
|
|
117
|
-
}
|
|
118
|
-
return { order: Number.parseInt(match[1], 10), name: match[2] || directoryName };
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function sectionSlugFromDirectory(directoryName) {
|
|
122
|
-
return directoryName.replace(/^\d+[-_]?/, "");
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
async function readDirectoryEntries(directory) {
|
|
126
|
-
try {
|
|
127
|
-
return await fs.readdir(directory, { withFileTypes: true });
|
|
128
|
-
} catch (error) {
|
|
129
|
-
if (error?.code === "ENOENT") return [];
|
|
130
|
-
throw error;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
async function fileExists(filePath) {
|
|
135
|
-
try {
|
|
136
|
-
const stat = await fs.stat(filePath);
|
|
137
|
-
return stat.isFile();
|
|
138
|
-
} catch (error) {
|
|
139
|
-
if (error?.code === "ENOENT") return false;
|
|
140
|
-
throw error;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
export interface ResolvedConfig {
|
|
2
|
-
root: string;
|
|
3
|
-
configPath: string;
|
|
4
|
-
title: string;
|
|
5
|
-
documentDir: string;
|
|
6
|
-
sourceDir: string;
|
|
7
|
-
mediaDir: string;
|
|
8
|
-
themeDir: string;
|
|
9
|
-
designDoc: string;
|
|
10
|
-
componentsDir: string;
|
|
11
|
-
publicDir: string;
|
|
12
|
-
outputDir: string;
|
|
13
|
-
pdf: {
|
|
14
|
-
filename: string;
|
|
15
|
-
};
|
|
16
|
-
deploy: {
|
|
17
|
-
adapter: string;
|
|
18
|
-
source: string;
|
|
19
|
-
projectName: string | null;
|
|
20
|
-
commitDirty: boolean;
|
|
21
|
-
requiresConfirmation: boolean;
|
|
22
|
-
};
|
|
23
|
-
paths: {
|
|
24
|
-
documentRoot: string;
|
|
25
|
-
sourceDir: string;
|
|
26
|
-
mediaDir: string;
|
|
27
|
-
themeDir: string;
|
|
28
|
-
designDoc: string;
|
|
29
|
-
componentsDir: string;
|
|
30
|
-
publicDir: string;
|
|
31
|
-
outputDir: string;
|
|
32
|
-
pdf: string;
|
|
33
|
-
deploySource: string;
|
|
34
|
-
deployMetadata: string;
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function loadConfig(root?: string): Promise<ResolvedConfig>;
|
|
39
|
-
export function normalizeConfig(root: string, userConfig?: Record<string, unknown>, configPath?: string): ResolvedConfig;
|
|
40
|
-
export function publicPdfHref(config: ResolvedConfig): string;
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { pathToFileURL } from "node:url";
|
|
4
|
-
|
|
5
|
-
const DEFAULT_CONFIG = {
|
|
6
|
-
title: "OpenPress Document",
|
|
7
|
-
subtitle: "",
|
|
8
|
-
organization: "",
|
|
9
|
-
workspaceLabel: "",
|
|
10
|
-
documentDir: ".",
|
|
11
|
-
sourceDir: "content",
|
|
12
|
-
mediaDir: "media",
|
|
13
|
-
themeDir: "theme",
|
|
14
|
-
designDoc: "design.md",
|
|
15
|
-
componentsDir: "components",
|
|
16
|
-
publicDir: "public/openpress",
|
|
17
|
-
outputDir: "dist",
|
|
18
|
-
captionNumbering: {
|
|
19
|
-
figure: "Figure",
|
|
20
|
-
table: "Table",
|
|
21
|
-
separator: " ",
|
|
22
|
-
},
|
|
23
|
-
pdf: {
|
|
24
|
-
filename: "document.pdf",
|
|
25
|
-
},
|
|
26
|
-
deploy: {
|
|
27
|
-
adapter: "cloudflare-pages",
|
|
28
|
-
source: ".deploy/openpress",
|
|
29
|
-
projectName: null,
|
|
30
|
-
commitDirty: false,
|
|
31
|
-
requiresConfirmation: true,
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export async function loadConfig(root = ".") {
|
|
36
|
-
const workspaceRoot = path.resolve(root);
|
|
37
|
-
const configPath = path.join(workspaceRoot, "openpress.config.mjs");
|
|
38
|
-
const rootConfig = await readUserConfig(configPath);
|
|
39
|
-
const { config, sourceConfigPath } = await resolveUserConfig(workspaceRoot, rootConfig, configPath);
|
|
40
|
-
return normalizeConfig(workspaceRoot, config, sourceConfigPath);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function normalizeConfig(root, userConfig = {}, configPath = path.join(root, "openpress.config.mjs")) {
|
|
44
|
-
const config = {
|
|
45
|
-
root: path.resolve(root),
|
|
46
|
-
configPath,
|
|
47
|
-
title: stringValue(userConfig.title, DEFAULT_CONFIG.title),
|
|
48
|
-
subtitle: optionalStringValue(userConfig.subtitle, DEFAULT_CONFIG.subtitle) ?? "",
|
|
49
|
-
organization: optionalStringValue(userConfig.organization, DEFAULT_CONFIG.organization) ?? "",
|
|
50
|
-
workspaceLabel: optionalStringValue(userConfig.workspaceLabel, DEFAULT_CONFIG.workspaceLabel) ?? "",
|
|
51
|
-
documentDir: documentPathValue(userConfig.documentDir, DEFAULT_CONFIG.documentDir),
|
|
52
|
-
sourceDir: relativePathValue(userConfig.sourceDir, DEFAULT_CONFIG.sourceDir),
|
|
53
|
-
mediaDir: relativePathValue(userConfig.mediaDir, DEFAULT_CONFIG.mediaDir),
|
|
54
|
-
themeDir: relativePathValue(userConfig.themeDir, DEFAULT_CONFIG.themeDir),
|
|
55
|
-
designDoc: relativePathValue(userConfig.designDoc, DEFAULT_CONFIG.designDoc),
|
|
56
|
-
componentsDir: relativePathValue(userConfig.componentsDir, DEFAULT_CONFIG.componentsDir),
|
|
57
|
-
publicDir: relativePathValue(userConfig.publicDir, DEFAULT_CONFIG.publicDir),
|
|
58
|
-
outputDir: relativePathValue(userConfig.outputDir, DEFAULT_CONFIG.outputDir),
|
|
59
|
-
captionNumbering: captionNumberingValue(userConfig.captionNumbering, DEFAULT_CONFIG.captionNumbering),
|
|
60
|
-
pdf: {
|
|
61
|
-
filename: fileNameValue(userConfig.pdf?.filename, DEFAULT_CONFIG.pdf.filename),
|
|
62
|
-
},
|
|
63
|
-
deploy: {
|
|
64
|
-
adapter: stringValue(userConfig.deploy?.adapter, DEFAULT_CONFIG.deploy.adapter),
|
|
65
|
-
source: relativePathValue(userConfig.deploy?.source, DEFAULT_CONFIG.deploy.source),
|
|
66
|
-
projectName: optionalStringValue(userConfig.deploy?.projectName, DEFAULT_CONFIG.deploy.projectName),
|
|
67
|
-
commitDirty: booleanValue(userConfig.deploy?.commitDirty, DEFAULT_CONFIG.deploy.commitDirty),
|
|
68
|
-
requiresConfirmation: booleanValue(userConfig.deploy?.requiresConfirmation, DEFAULT_CONFIG.deploy.requiresConfirmation),
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const documentRoot = config.documentDir === "." ? config.root : path.join(config.root, config.documentDir);
|
|
73
|
-
config.paths = {
|
|
74
|
-
documentRoot,
|
|
75
|
-
sourceDir: path.join(documentRoot, config.sourceDir),
|
|
76
|
-
mediaDir: path.join(documentRoot, config.mediaDir),
|
|
77
|
-
themeDir: path.join(documentRoot, config.themeDir),
|
|
78
|
-
designDoc: path.join(documentRoot, config.designDoc),
|
|
79
|
-
componentsDir: path.join(documentRoot, config.componentsDir),
|
|
80
|
-
publicDir: path.join(config.root, config.publicDir),
|
|
81
|
-
outputDir: path.join(config.root, config.outputDir),
|
|
82
|
-
pdf: path.join(config.root, config.outputDir, config.pdf.filename),
|
|
83
|
-
deploySource: path.join(config.root, config.deploy.source),
|
|
84
|
-
deployMetadata: path.join(config.root, config.deploy.source, "openpress", "deploy.json"),
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
return config;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function publicPdfHref(config) {
|
|
91
|
-
return `/${config.pdf.filename}`;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async function readUserConfig(configPath) {
|
|
95
|
-
try {
|
|
96
|
-
const stat = await fs.stat(configPath);
|
|
97
|
-
const configUrl = `${pathToFileURL(configPath).href}?mtime=${stat.mtimeMs}`;
|
|
98
|
-
const mod = await import(configUrl);
|
|
99
|
-
return mod.default ?? {};
|
|
100
|
-
} catch (error) {
|
|
101
|
-
if (error?.code === "ENOENT") return {};
|
|
102
|
-
throw error;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async function resolveUserConfig(root, rootConfig, configPath) {
|
|
107
|
-
const documentConfigPath = configPathValue(rootConfig.config ?? rootConfig.documentConfig);
|
|
108
|
-
if (!documentConfigPath) {
|
|
109
|
-
return { config: rootConfig, sourceConfigPath: configPath };
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const sourceConfigPath = path.resolve(root, documentConfigPath);
|
|
113
|
-
const documentConfig = await readUserConfig(sourceConfigPath);
|
|
114
|
-
return {
|
|
115
|
-
config: { ...documentConfig, ...rootConfig },
|
|
116
|
-
sourceConfigPath,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function stringValue(value, fallback) {
|
|
121
|
-
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function optionalStringValue(value, fallback) {
|
|
125
|
-
if (value === null) return null;
|
|
126
|
-
if (typeof value === "string" && value.trim()) return value.trim();
|
|
127
|
-
return fallback;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function captionNumberingValue(value, fallback) {
|
|
131
|
-
const input = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
132
|
-
return {
|
|
133
|
-
figure: optionalStringValue(input.figure, fallback.figure) ?? fallback.figure,
|
|
134
|
-
table: optionalStringValue(input.table, fallback.table) ?? fallback.table,
|
|
135
|
-
separator: typeof input.separator === "string" ? input.separator : fallback.separator,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function booleanValue(value, fallback) {
|
|
140
|
-
return typeof value === "boolean" ? value : fallback;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function fileNameValue(value, fallback) {
|
|
144
|
-
const fileName = stringValue(value, fallback);
|
|
145
|
-
if (fileName.includes("/") || fileName.includes("\\") || fileName === "." || fileName === "..") {
|
|
146
|
-
throw new Error(`OpenPress config pdf.filename must be a file name, got: ${fileName}`);
|
|
147
|
-
}
|
|
148
|
-
return fileName;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function configPathValue(value) {
|
|
152
|
-
if (typeof value !== "string" || !value.trim()) return null;
|
|
153
|
-
return relativePathValue(value, null);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function documentPathValue(value, fallback) {
|
|
157
|
-
const raw = stringValue(value, fallback).replaceAll("\\", "/");
|
|
158
|
-
if (path.isAbsolute(raw)) throw new Error(`OpenPress config paths must be relative, got: ${raw}`);
|
|
159
|
-
const normalized = path.posix.normalize(raw).replace(/^\.\//, "");
|
|
160
|
-
if (normalized === ".") return ".";
|
|
161
|
-
if (!normalized || normalized === ".." || normalized.startsWith("../")) {
|
|
162
|
-
throw new Error(`OpenPress config path escapes workspace: ${raw}`);
|
|
163
|
-
}
|
|
164
|
-
return normalized;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function relativePathValue(value, fallback) {
|
|
168
|
-
const raw = stringValue(value, fallback).replaceAll("\\", "/");
|
|
169
|
-
if (path.isAbsolute(raw)) throw new Error(`OpenPress config paths must be relative, got: ${raw}`);
|
|
170
|
-
const normalized = path.posix.normalize(raw).replace(/^\.\//, "");
|
|
171
|
-
if (!normalized || normalized === "." || normalized === ".." || normalized.startsWith("../")) {
|
|
172
|
-
throw new Error(`OpenPress config path escapes workspace: ${raw}`);
|
|
173
|
-
}
|
|
174
|
-
return normalized;
|
|
175
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { loadConfig } from "./config.mjs";
|
|
4
|
-
import { readKatexCss } from "../output/katex-assets.mjs";
|
|
5
|
-
|
|
6
|
-
const CONTENT_CSS_LAYERS = [
|
|
7
|
-
"base/page-contract.css",
|
|
8
|
-
"base/typography.css",
|
|
9
|
-
"page-surfaces/cover.css",
|
|
10
|
-
{ path: "page-surfaces/chapter-opener.css", optional: true },
|
|
11
|
-
"page-surfaces/back-cover.css",
|
|
12
|
-
"page-surfaces/toc.css",
|
|
13
|
-
"shell/reader-controls.css",
|
|
14
|
-
"base/print.css",
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
export async function copyDirectory(src, dst) {
|
|
18
|
-
await fs.rm(dst, { recursive: true, force: true });
|
|
19
|
-
await fs.mkdir(path.dirname(dst), { recursive: true });
|
|
20
|
-
await fs.cp(src, dst, { recursive: true });
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export async function writeContentCss(root, targetDir, config) {
|
|
24
|
-
config ??= await loadConfig(root);
|
|
25
|
-
const css = await buildContentCss(root, config);
|
|
26
|
-
await fs.mkdir(targetDir, { recursive: true });
|
|
27
|
-
await fs.writeFile(path.join(targetDir, "content.css"), css, "utf8");
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export async function buildContentCss(root, config) {
|
|
31
|
-
config ??= await loadConfig(root);
|
|
32
|
-
const contentAssetsDir = config.paths.themeDir;
|
|
33
|
-
const parts = [];
|
|
34
|
-
for (const layer of CONTENT_CSS_LAYERS) {
|
|
35
|
-
const relativePath = typeof layer === "string" ? layer : layer.path;
|
|
36
|
-
const cssPath = path.join(contentAssetsDir, relativePath);
|
|
37
|
-
let css;
|
|
38
|
-
try {
|
|
39
|
-
css = await fs.readFile(cssPath, "utf8");
|
|
40
|
-
} catch (error) {
|
|
41
|
-
if (typeof layer !== "string" && layer.optional && error.code === "ENOENT") continue;
|
|
42
|
-
throw error;
|
|
43
|
-
}
|
|
44
|
-
parts.push(`/* === ${relativePath} === */\n`);
|
|
45
|
-
parts.push(css.trimEnd());
|
|
46
|
-
parts.push("\n\n");
|
|
47
|
-
}
|
|
48
|
-
parts.push("/* === engine/katex.css === */\n");
|
|
49
|
-
parts.push((await readKatexCss()).trimEnd());
|
|
50
|
-
parts.push("\n\n");
|
|
51
|
-
return parts.join("");
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export async function writeComponentsCss(root, targetDir, config) {
|
|
55
|
-
config ??= await loadConfig(root);
|
|
56
|
-
const css = await buildComponentsCss(root, config);
|
|
57
|
-
await fs.mkdir(targetDir, { recursive: true });
|
|
58
|
-
await fs.writeFile(path.join(targetDir, "components.css"), css, "utf8");
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export async function buildComponentsCss(root, config) {
|
|
62
|
-
config ??= await loadConfig(root);
|
|
63
|
-
const parts = [];
|
|
64
|
-
await appendCssDirectory(parts, path.join(config.paths.themeDir, "patterns"), "theme/patterns");
|
|
65
|
-
await appendComponentScopedCss(parts, config.paths.componentsDir);
|
|
66
|
-
return parts.join("");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function appendCssDirectory(parts, directory, labelPrefix) {
|
|
70
|
-
let entries;
|
|
71
|
-
try {
|
|
72
|
-
entries = await fs.readdir(directory);
|
|
73
|
-
} catch {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
for (const name of entries.filter((entry) => entry.endsWith(".css")).sort()) {
|
|
77
|
-
parts.push(`/* === ${labelPrefix}/${name} === */\n`);
|
|
78
|
-
parts.push((await fs.readFile(path.join(directory, name), "utf8")).trimEnd());
|
|
79
|
-
parts.push("\n\n");
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async function appendComponentScopedCss(parts, componentsDir) {
|
|
84
|
-
let entries;
|
|
85
|
-
try {
|
|
86
|
-
entries = await fs.readdir(componentsDir, { withFileTypes: true });
|
|
87
|
-
} catch {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
for (const entry of entries.filter((item) => item.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
92
|
-
const cssPath = path.join(componentsDir, entry.name, "style.css");
|
|
93
|
-
let css;
|
|
94
|
-
try {
|
|
95
|
-
css = await fs.readFile(cssPath, "utf8");
|
|
96
|
-
} catch (error) {
|
|
97
|
-
if (error.code === "ENOENT") {
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
throw error;
|
|
101
|
-
}
|
|
102
|
-
parts.push(`/* === components/${entry.name}/style.css === */\n`);
|
|
103
|
-
parts.push(css.trimEnd());
|
|
104
|
-
parts.push("\n\n");
|
|
105
|
-
}
|
|
106
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
|
|
4
|
-
export async function walkFiles(directory, visit) {
|
|
5
|
-
let entries;
|
|
6
|
-
try {
|
|
7
|
-
entries = await fs.readdir(directory, { withFileTypes: true });
|
|
8
|
-
} catch (error) {
|
|
9
|
-
if (error?.code === "ENOENT") return;
|
|
10
|
-
throw error;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
for (const entry of entries) {
|
|
14
|
-
if (entry.name.startsWith(".")) continue;
|
|
15
|
-
const absolutePath = path.join(directory, entry.name);
|
|
16
|
-
if (entry.isDirectory()) {
|
|
17
|
-
await walkFiles(absolutePath, visit);
|
|
18
|
-
} else if (entry.isFile()) {
|
|
19
|
-
await visit(absolutePath);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|