@open-press/cli 0.6.0 → 0.7.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/package.json +1 -1
- package/template/core/CHANGELOG.md +67 -1
- package/template/core/README.md +9 -5
- package/template/core/engine/cli.mjs +2 -5
- package/template/core/engine/commands/_shared.mjs +4 -4
- package/template/core/engine/commands/deploy.mjs +1 -1
- package/template/core/engine/commands/inspect.mjs +3 -3
- package/template/core/engine/commands/replace.mjs +1 -1
- package/template/core/engine/commands/search.mjs +1 -1
- package/template/core/engine/commands/validate.mjs +2 -2
- package/template/core/engine/document-export.mjs +1 -1
- package/template/core/engine/{chrome-pdf.mjs → output/chrome-pdf.mjs} +1 -2
- package/template/core/engine/{deploy-sync.mjs → output/deploy-sync.mjs} +2 -2
- package/template/core/engine/{fonts.mjs → output/fonts.mjs} +1 -1
- package/template/core/engine/{public-assets.mjs → output/public-assets.mjs} +2 -2
- package/template/core/engine/{static-server.mjs → output/static-server.mjs} +2 -2
- package/template/core/engine/react/caption-numbering.mjs +73 -0
- package/template/core/engine/react/comment-marker.mjs +54 -10
- package/template/core/engine/react/document-entry.mjs +124 -64
- package/template/core/engine/react/document-export.mjs +252 -311
- package/template/core/engine/react/mdx-compile.mjs +123 -3
- package/template/core/engine/react/measurement-css.mjs +3 -3
- package/template/core/engine/react/pagination/allocator.mjs +122 -0
- package/template/core/engine/react/pagination/regions.mjs +81 -0
- package/template/core/engine/react/pagination.mjs +9 -121
- package/template/core/engine/react/pipeline/allocate.mjs +248 -0
- package/template/core/engine/react/pipeline/final-render.mjs +94 -0
- package/template/core/engine/react/pipeline/frame-measurement.mjs +271 -0
- package/template/core/engine/react/pipeline/press-tree.mjs +135 -0
- package/template/core/engine/react/project-asset-endpoint.mjs +2 -2
- package/template/core/engine/react/{chapter-css.mjs → section-css.mjs} +12 -9
- package/template/core/engine/react/sources/heading-numbering.mjs +132 -0
- package/template/core/engine/react/sources/mdx-resolver.mjs +441 -0
- package/template/core/engine/react/{workspace-discovery.mjs → style-discovery.mjs} +29 -40
- package/template/core/engine/{config.mjs → runtime/config.mjs} +15 -0
- package/template/core/engine/{file-utils.mjs → runtime/file-utils.mjs} +1 -1
- package/template/core/engine/{inspection.mjs → runtime/inspection.mjs} +3 -4
- package/template/core/engine/{source-text-tools.mjs → runtime/source-text-tools.mjs} +24 -7
- package/template/core/engine/runtime/source-workspace.mjs +186 -0
- package/template/core/engine/{validation.mjs → runtime/validation.mjs} +19 -17
- package/template/core/package.json +5 -2
- package/template/core/src/openpress/anchorMap.ts +27 -0
- package/template/core/src/openpress/core/Frame.tsx +80 -0
- package/template/core/src/openpress/core/FrameContext.tsx +19 -0
- package/template/core/src/openpress/core/MdxArea.tsx +35 -0
- package/template/core/src/openpress/core/Press.tsx +34 -0
- package/template/core/src/openpress/core/index.tsx +34 -15
- package/template/core/src/openpress/core/primitives.tsx +23 -0
- package/template/core/src/openpress/core/types.ts +131 -19
- package/template/core/src/openpress/core/useSource.ts +28 -0
- package/template/core/src/openpress/manuscript/index.tsx +196 -0
- package/template/core/src/openpress/mdx/index.ts +88 -0
- package/template/core/src/openpress/numbering/index.ts +294 -0
- package/template/core/src/openpress/publicPage.tsx +4 -186
- package/template/core/src/openpress/reactDocumentMetadata.ts +2 -16
- package/template/core/src/openpress/types.ts +0 -16
- package/template/core/src/openpress/workbench.tsx +2 -36
- package/template/core/src/styles/openpress/responsive.css +0 -14
- package/template/core/tsconfig.json +4 -1
- package/template/core/vite.config.ts +10 -3
- package/template/packs/academic-paper/document/components/Page.tsx +24 -14
- package/template/packs/academic-paper/document/design.md +2 -2
- package/template/packs/academic-paper/document/index.tsx +98 -74
- package/template/packs/academic-paper/document/theme/page-surfaces/toc.css +19 -9
- package/template/packs/claude-document/document/components/Page.tsx +24 -14
- package/template/packs/claude-document/document/design.md +2 -2
- package/template/packs/claude-document/document/index.tsx +67 -62
- package/template/packs/claude-document/document/theme/page-surfaces/toc.css +19 -7
- package/template/packs/editorial-monograph/document/components/Page.tsx +24 -14
- package/template/packs/editorial-monograph/document/design.md +2 -2
- package/template/packs/editorial-monograph/document/index.tsx +71 -47
- package/template/packs/editorial-monograph/document/theme/page-surfaces/toc.css +19 -9
- package/template/core/engine/commands/migrate-to-react.mjs +0 -27
- package/template/core/engine/page-renderer.mjs +0 -217
- package/template/core/engine/react/migrate-to-react.mjs +0 -355
- package/template/core/engine/source-workspace.mjs +0 -76
- package/template/core/src/openpress/core/basePages.tsx +0 -87
- package/template/core/src/openpress/pagination.ts +0 -845
- package/template/packs/claude-document/document/chapters/01-document-shape/chapter.tsx +0 -30
- package/template/packs/claude-document/document/chapters/02-review-loop/chapter.tsx +0 -30
- /package/template/core/engine/{chrome-pdf.d.mts → output/chrome-pdf.d.mts} +0 -0
- /package/template/core/engine/{katex-assets.mjs → output/katex-assets.mjs} +0 -0
- /package/template/core/engine/{page-block.mjs → output/page-block.mjs} +0 -0
- /package/template/core/engine/{pdf-media.mjs → output/pdf-media.mjs} +0 -0
- /package/template/core/engine/{config.d.mts → runtime/config.d.mts} +0 -0
- /package/template/core/engine/{issue-report.mjs → runtime/issue-report.mjs} +0 -0
|
@@ -33,18 +33,14 @@ import {
|
|
|
33
33
|
ProjectEntryPanel,
|
|
34
34
|
type ProjectMentionItem,
|
|
35
35
|
} from "./projectWorkspace";
|
|
36
|
-
import {
|
|
36
|
+
import { createAnchorPageMap, resolveAnchorPageIndex } from "./anchorMap";
|
|
37
37
|
import { scheduleBrowserFrame } from "./frameScheduler";
|
|
38
38
|
import {
|
|
39
|
-
createAnchorPageMap,
|
|
40
|
-
numberSourceHeadings,
|
|
41
39
|
PUBLIC_DRAWER_BREAKPOINT,
|
|
42
40
|
PublicPage,
|
|
43
|
-
resolveAnchorPageIndex,
|
|
44
41
|
useViewMode,
|
|
45
42
|
} from "./publicPage";
|
|
46
43
|
import { getProjectIdentity } from "./projectIdentity";
|
|
47
|
-
import { hasBuildTimePagination } from "./reactDocumentMetadata";
|
|
48
44
|
import { buildPublicPreviewHref, isLocalWorkspaceHost } from "./runtimeMode";
|
|
49
45
|
import { useReaderRuntime } from "./readerRuntime";
|
|
50
46
|
import type { DeploymentInfo, ReaderDocument, HtmlPageBlock, SourceBlock } from "./types";
|
|
@@ -123,14 +119,9 @@ export function HtmlWorkbench({
|
|
|
123
119
|
deploymentInfo: DeploymentInfo;
|
|
124
120
|
}) {
|
|
125
121
|
const sourceContainerRef = useRef<HTMLDivElement | null>(null);
|
|
126
|
-
const
|
|
122
|
+
const displayPages = pages;
|
|
127
123
|
const viewModeState = useViewMode();
|
|
128
124
|
const { viewMode } = viewModeState;
|
|
129
|
-
const buildTimePaginated = hasBuildTimePagination(document);
|
|
130
|
-
const [paginatedPages, setPaginatedPages] = useState<PaginatedPage[] | null>(null);
|
|
131
|
-
const displayPages: DisplayPage[] = viewMode === "paged" && !buildTimePaginated
|
|
132
|
-
? (paginatedPages ?? numberedPages)
|
|
133
|
-
: numberedPages;
|
|
134
125
|
const mediaAssets = useMemo(() => collectMediaAssetIndex(displayPages), [displayPages]);
|
|
135
126
|
const anchorPageMap = useMemo(() => createAnchorPageMap(displayPages), [displayPages]);
|
|
136
127
|
const projectComponentUsages = useMemo(() => createProjectComponentUsages(displayPages), [displayPages]);
|
|
@@ -163,7 +154,6 @@ export function HtmlWorkbench({
|
|
|
163
154
|
const pdfButtonText = workbenchPdfButtonText(localDeployEnabled, pdfActionStatus, staticPdfHref);
|
|
164
155
|
const pdfStatusMessage = workbenchPdfStatusMessage(localDeployEnabled, pdfActionStatus);
|
|
165
156
|
const pdfButtonDisabled = localDeployEnabled ? pdfActionStatus === "generating" || pdfActionStatus === "opening" : !staticPdfHref;
|
|
166
|
-
const activePaginatedReady = viewMode === "reading" || buildTimePaginated || Boolean(paginatedPages);
|
|
167
157
|
const inspectorSelectionLabel = formatInspectorSelection(inspector.selectedBlock);
|
|
168
158
|
const activeInlineSavedComment = getInlineSavedCommentForTarget(inlineSavedComment, inspector.selectedTarget);
|
|
169
159
|
const inspectorCommentDisabled = !inspector.selectedBlock || !inspectorCommentText.trim() || inspectorCommentStatus === "submitting";
|
|
@@ -392,10 +382,6 @@ export function HtmlWorkbench({
|
|
|
392
382
|
scheduleBrowserFrame(() => reader.setPage(reader.currentPageIndex, { behavior: "auto" }));
|
|
393
383
|
};
|
|
394
384
|
|
|
395
|
-
useLayoutEffect(() => {
|
|
396
|
-
setPaginatedPages(null);
|
|
397
|
-
}, [numberedPages]);
|
|
398
|
-
|
|
399
385
|
useEffect(() => {
|
|
400
386
|
setInspectorCommentStatus("idle");
|
|
401
387
|
setInspectorCommentError("");
|
|
@@ -407,24 +393,6 @@ export function HtmlWorkbench({
|
|
|
407
393
|
void refreshPendingComments();
|
|
408
394
|
}, [devMode, refreshPendingComments, workspaceView]);
|
|
409
395
|
|
|
410
|
-
useLayoutEffect(() => {
|
|
411
|
-
if (buildTimePaginated) return undefined;
|
|
412
|
-
if (viewMode !== "paged" || paginatedPages) return undefined;
|
|
413
|
-
const sourceContainer = sourceContainerRef.current;
|
|
414
|
-
if (!sourceContainer) return undefined;
|
|
415
|
-
|
|
416
|
-
let cancelled = false;
|
|
417
|
-
const cancelFrame = scheduleBrowserFrame(() => {
|
|
418
|
-
const nextPages = paginateSourcePages(sourceContainer, numberedPages);
|
|
419
|
-
if (!cancelled) setPaginatedPages(nextPages);
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
return () => {
|
|
423
|
-
cancelled = true;
|
|
424
|
-
cancelFrame();
|
|
425
|
-
};
|
|
426
|
-
}, [buildTimePaginated, numberedPages, paginatedPages, viewMode]);
|
|
427
|
-
|
|
428
396
|
const actionSection = (
|
|
429
397
|
<section className="openpress-public-action-section" aria-label="輸出">
|
|
430
398
|
<span className="openpress-public-action-heading">輸出</span>
|
|
@@ -512,7 +480,6 @@ export function HtmlWorkbench({
|
|
|
512
480
|
className={`reader-app openpress-reader-app openpress-public-viewer openpress-dev-public-viewer is-ready${reader.rightPanelOpen ? "" : " is-closed-right"}`}
|
|
513
481
|
data-openpress-react-runtime="true"
|
|
514
482
|
data-openpress-view-mode={viewMode}
|
|
515
|
-
data-openpress-pagination={activePaginatedReady ? "ready" : "pending"}
|
|
516
483
|
data-openpress-inspector-mode={inspector.inspectorMode ? "on" : "off"}
|
|
517
484
|
data-active-workspace={workspaceView}
|
|
518
485
|
>
|
|
@@ -533,7 +500,6 @@ export function HtmlWorkbench({
|
|
|
533
500
|
pages={displayPages}
|
|
534
501
|
currentPageIndex={reader.currentPageIndex}
|
|
535
502
|
devMode={devMode}
|
|
536
|
-
paginatedReady={activePaginatedReady}
|
|
537
503
|
sourceContainerRef={sourceContainerRef}
|
|
538
504
|
registerPage={reader.registerPage}
|
|
539
505
|
exposeSourceData={devMode}
|
|
@@ -269,12 +269,6 @@
|
|
|
269
269
|
box-shadow: none;
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
.openpress-public-viewer.openpress-reader-app[data-openpress-pagination="pending"] .openpress-public-navigation {
|
|
273
|
-
transform: translateX(-110%);
|
|
274
|
-
pointer-events: none;
|
|
275
|
-
box-shadow: none;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
272
|
.openpress-public-viewer.openpress-reader-app .openpress-public-scrim {
|
|
279
273
|
position: fixed;
|
|
280
274
|
inset: 0;
|
|
@@ -309,14 +303,6 @@
|
|
|
309
303
|
display: block;
|
|
310
304
|
}
|
|
311
305
|
|
|
312
|
-
.openpress-public-viewer.openpress-reader-app[data-openpress-pagination="pending"] .openpress-public-scrim {
|
|
313
|
-
display: none;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
.openpress-public-viewer.openpress-reader-app[data-openpress-pagination="pending"] .openpress-public-fab {
|
|
317
|
-
display: flex;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
306
|
.openpress-public-viewer[data-openpress-view-mode="paged"] .reader-pages {
|
|
321
307
|
--openpress-public-page-width: min(
|
|
322
308
|
var(--openpress-page-width),
|
|
@@ -17,7 +17,10 @@
|
|
|
17
17
|
"noEmit": true,
|
|
18
18
|
"jsx": "react-jsx",
|
|
19
19
|
"paths": {
|
|
20
|
-
"@
|
|
20
|
+
"@open-press/core": ["./src/openpress/core/index.tsx"],
|
|
21
|
+
"@open-press/core/mdx": ["./src/openpress/mdx/index.ts"],
|
|
22
|
+
"@open-press/core/manuscript": ["./src/openpress/manuscript/index.tsx"],
|
|
23
|
+
"@open-press/core/numbering": ["./src/openpress/numbering/index.ts"],
|
|
21
24
|
"@/components": ["./document/components/index.ts", "./document/components/index.tsx"],
|
|
22
25
|
"@/components/*": ["./document/components/*"],
|
|
23
26
|
"@/*": ["./src/*"]
|
|
@@ -5,7 +5,7 @@ import path from "node:path";
|
|
|
5
5
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
6
6
|
import { defineConfig } from "vite";
|
|
7
7
|
import react from "@vitejs/plugin-react";
|
|
8
|
-
import { loadConfig, publicPdfHref } from "./engine/config.mjs";
|
|
8
|
+
import { loadConfig, publicPdfHref } from "./engine/runtime/config.mjs";
|
|
9
9
|
import { handleCommentRequest } from "./engine/react/comment-endpoint.mjs";
|
|
10
10
|
import { handleProjectAssetRequest } from "./engine/react/project-asset-endpoint.mjs";
|
|
11
11
|
|
|
@@ -15,8 +15,11 @@ const workspaceRoot = process.env.OPENPRESS_WORKSPACE_ROOT
|
|
|
15
15
|
: frameworkRoot;
|
|
16
16
|
const sourceRoot = path.join(frameworkRoot, "src");
|
|
17
17
|
const openpressCliPath = path.join(frameworkRoot, "engine", "cli.mjs");
|
|
18
|
-
const staticServerPath = path.join(frameworkRoot, "engine", "static-server.mjs");
|
|
18
|
+
const staticServerPath = path.join(frameworkRoot, "engine", "output", "static-server.mjs");
|
|
19
19
|
const openpressCoreEntry = path.join(frameworkRoot, "src", "openpress", "core", "index.tsx");
|
|
20
|
+
const openpressMdxEntry = path.join(frameworkRoot, "src", "openpress", "mdx", "index.ts");
|
|
21
|
+
const openpressManuscriptEntry = path.join(frameworkRoot, "src", "openpress", "manuscript", "index.tsx");
|
|
22
|
+
const openpressNumberingEntry = path.join(frameworkRoot, "src", "openpress", "numbering", "index.ts");
|
|
20
23
|
const openpressConfig = await loadConfig(workspaceRoot);
|
|
21
24
|
const outputDir = openpressConfig.paths.outputDir;
|
|
22
25
|
const reactDocumentRoot = openpressConfig.paths.documentRoot;
|
|
@@ -55,7 +58,11 @@ export default defineConfig({
|
|
|
55
58
|
resolve: {
|
|
56
59
|
dedupe: ["react", "react-dom", "@mdx-js/react"],
|
|
57
60
|
alias: {
|
|
58
|
-
|
|
61
|
+
// Subpaths must come before the base path so resolution matches longest first.
|
|
62
|
+
"@open-press/core/mdx": openpressMdxEntry,
|
|
63
|
+
"@open-press/core/manuscript": openpressManuscriptEntry,
|
|
64
|
+
"@open-press/core/numbering": openpressNumberingEntry,
|
|
65
|
+
"@open-press/core": openpressCoreEntry,
|
|
59
66
|
"@/components": reactDocumentComponentsRoot,
|
|
60
67
|
"@": sourceRoot,
|
|
61
68
|
...workspaceAliases,
|
|
@@ -1,27 +1,37 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Frame, MdxArea } from "@open-press/core";
|
|
2
|
+
import type { SectionsPageProps } from "@open-press/core/manuscript";
|
|
2
3
|
|
|
3
4
|
export default function Page({
|
|
5
|
+
frameKey,
|
|
6
|
+
chainId,
|
|
4
7
|
pageIndex,
|
|
5
8
|
totalPages,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}:
|
|
9
|
+
sectionSlug,
|
|
10
|
+
sectionTitle,
|
|
11
|
+
sectionTone,
|
|
12
|
+
}: SectionsPageProps) {
|
|
10
13
|
return (
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
<Frame
|
|
15
|
+
frameKey={frameKey}
|
|
16
|
+
role="manuscript.content"
|
|
17
|
+
className="reader-page--content"
|
|
15
18
|
data-page-index={pageIndex}
|
|
16
19
|
data-total-pages={totalPages}
|
|
17
|
-
data-
|
|
18
|
-
data-chapter-tone={
|
|
20
|
+
data-section-id={sectionSlug}
|
|
21
|
+
data-chapter-tone={sectionTone}
|
|
19
22
|
>
|
|
20
23
|
<div className="page-frame">
|
|
21
24
|
<header className="page-header" aria-hidden="true" />
|
|
22
|
-
<main className="page-body">
|
|
23
|
-
|
|
25
|
+
<main className="page-body">
|
|
26
|
+
<MdxArea chainId={chainId} />
|
|
27
|
+
</main>
|
|
28
|
+
<footer className="page-footer" aria-hidden="true">
|
|
29
|
+
<span className="footer-left">{sectionTitle}</span>
|
|
30
|
+
<span className="footer-right">
|
|
31
|
+
{totalPages > 1 ? `${pageIndex + 1}/${totalPages}` : pageIndex + 1}
|
|
32
|
+
</span>
|
|
33
|
+
</footer>
|
|
24
34
|
</div>
|
|
25
|
-
</
|
|
35
|
+
</Frame>
|
|
26
36
|
);
|
|
27
37
|
}
|
|
@@ -112,7 +112,7 @@ Block-level 強調(callout / warning / note)目前不在 design system 範圍;
|
|
|
112
112
|
|
|
113
113
|
### Chapter & Section Numbering
|
|
114
114
|
|
|
115
|
-
Engine 不在 h2/h3 內容前注入任何編號或前綴;
|
|
115
|
+
Engine 不在 h2/h3 內容前注入任何編號或前綴;export pipeline 會在 build-time 寫入 `data-chapter` / `data-section` attribute(值是 `01`、`1.1` 這種兩位數阿拉伯格式)。實際顯示樣式由 theme 的 `::before content` 決定,這讓不同文件能挑不同 numbering vocabulary 而不動 reader runtime。
|
|
116
116
|
|
|
117
117
|
預設(editorial-monograph 起手樣式):
|
|
118
118
|
|
|
@@ -258,7 +258,7 @@ body 內容區的 page padding(content margin)由 `.reader-page` 內的 `--page-
|
|
|
258
258
|
| 資料歸資料 | chart data 透過 React props 或鄰近的 typed data module 傳入,不寫死在 CSS |
|
|
259
259
|
| 樣式歸樣式 | chart frame 等通用規則放在 `document/theme/patterns/`;變體 CSS 放在元件自己的 `style.css` |
|
|
260
260
|
| 元件歸元件 | 一個視覺 = 一個 `document/components/ComponentName/` 包;MDX 只保留 `<ComponentName />` 呼叫 |
|
|
261
|
-
| Caption 必填 | caption 只寫說明文字,不手寫圖號或表號;
|
|
261
|
+
| Caption 必填 | caption 只寫說明文字,不手寫圖號或表號;export pipeline 會替 content pages 的 figure/table 自動編號 |
|
|
262
262
|
| PDF-safe | 圖表需 `break-inside: avoid`,高度不可壓到 footer |
|
|
263
263
|
|
|
264
264
|
如果使用者要求新的視覺元件,Agent 應先更新本檔說明,再改對應的 `document/components/<name>/style.css` 或 `document/theme/` CSS,最後用 reader 預覽檢查 PDF 輸出。
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { Frame, Press } from "@open-press/core";
|
|
2
|
+
import type { Manifest } from "@open-press/core";
|
|
3
|
+
import { mdxSource } from "@open-press/core/mdx";
|
|
4
|
+
import { Sections, Toc } from "@open-press/core/manuscript";
|
|
5
|
+
import Page from "./components/Page";
|
|
3
6
|
|
|
4
7
|
export const config: Manifest = {
|
|
5
8
|
title: "Paper Title",
|
|
@@ -24,84 +27,105 @@ export const config: Manifest = {
|
|
|
24
27
|
},
|
|
25
28
|
};
|
|
26
29
|
|
|
30
|
+
export const sources = {
|
|
31
|
+
story: mdxSource({ preset: "section-folders", root: "chapters" }),
|
|
32
|
+
};
|
|
33
|
+
|
|
27
34
|
/**
|
|
28
35
|
* The cover renders the academic title block: paper title, author grid,
|
|
29
36
|
* abstract band, and index terms. Replace the placeholders with your own.
|
|
30
37
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
function Cover() {
|
|
39
|
+
return (
|
|
40
|
+
<Frame
|
|
41
|
+
frameKey="cover"
|
|
42
|
+
role="manuscript.cover"
|
|
43
|
+
chrome={false}
|
|
44
|
+
className="reader-page--cover"
|
|
45
|
+
data-page-title="Title page"
|
|
46
|
+
aria-labelledby="paper-title"
|
|
47
|
+
>
|
|
48
|
+
<div className="paper-cover">
|
|
49
|
+
<h1 id="paper-title" className="paper-title">
|
|
50
|
+
Conference Paper Title
|
|
51
|
+
</h1>
|
|
52
|
+
<p className="paper-subtitle">
|
|
53
|
+
Sub-title (optional). Not captured by indexing services like IEEE Xplore.
|
|
54
|
+
</p>
|
|
40
55
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
<ol className="paper-authors" aria-label="Authors">
|
|
57
|
+
<li className="paper-author">
|
|
58
|
+
<p className="paper-author-name">First Author Surname</p>
|
|
59
|
+
<p className="paper-author-affiliation">dept. of organization</p>
|
|
60
|
+
<p className="paper-author-affiliation">name of organization</p>
|
|
61
|
+
<p className="paper-author-location">City, Country</p>
|
|
62
|
+
<p className="paper-author-contact">email or ORCID</p>
|
|
63
|
+
</li>
|
|
64
|
+
<li className="paper-author">
|
|
65
|
+
<p className="paper-author-name">Second Author Surname</p>
|
|
66
|
+
<p className="paper-author-affiliation">dept. of organization</p>
|
|
67
|
+
<p className="paper-author-affiliation">name of organization</p>
|
|
68
|
+
<p className="paper-author-location">City, Country</p>
|
|
69
|
+
<p className="paper-author-contact">email or ORCID</p>
|
|
70
|
+
</li>
|
|
71
|
+
<li className="paper-author">
|
|
72
|
+
<p className="paper-author-name">Third Author Surname</p>
|
|
73
|
+
<p className="paper-author-affiliation">dept. of organization</p>
|
|
74
|
+
<p className="paper-author-affiliation">name of organization</p>
|
|
75
|
+
<p className="paper-author-location">City, Country</p>
|
|
76
|
+
<p className="paper-author-contact">email or ORCID</p>
|
|
77
|
+
</li>
|
|
78
|
+
</ol>
|
|
64
79
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
<section className="paper-abstract" aria-label="Abstract">
|
|
81
|
+
<p>
|
|
82
|
+
<span className="paper-abstract-label">Abstract</span>—This document
|
|
83
|
+
is a model and starting point for an academic paper drafted in
|
|
84
|
+
open-press. Replace this abstract with your own — keep it under
|
|
85
|
+
250 words. Do not use abbreviations, symbols, footnotes, or math
|
|
86
|
+
in the abstract.
|
|
87
|
+
</p>
|
|
88
|
+
</section>
|
|
74
89
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
);
|
|
90
|
+
<section className="paper-index-terms" aria-label="Index terms">
|
|
91
|
+
<p>
|
|
92
|
+
<span className="paper-abstract-label">Index Terms</span>—keyword
|
|
93
|
+
one, keyword two, keyword three, keyword four
|
|
94
|
+
</p>
|
|
95
|
+
</section>
|
|
96
|
+
</div>
|
|
97
|
+
</Frame>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
84
100
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
<
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
101
|
+
function BackCover() {
|
|
102
|
+
return (
|
|
103
|
+
<Frame
|
|
104
|
+
frameKey="back-cover"
|
|
105
|
+
role="manuscript.back-cover"
|
|
106
|
+
chrome={false}
|
|
107
|
+
className="reader-page--back-cover"
|
|
108
|
+
data-page-title="Back cover"
|
|
109
|
+
>
|
|
110
|
+
<div className="paper-back-cover">
|
|
111
|
+
<p className="paper-back-kicker">open-press · academic-paper</p>
|
|
112
|
+
<p className="paper-back-statement">
|
|
113
|
+
Draft built with open-press. When the paper is ready for submission,
|
|
114
|
+
port the prose into the publisher's LaTeX class (IEEEtran, acmart,
|
|
115
|
+
etc.). open-press is the iteration loop, not the camera-ready output.
|
|
116
|
+
</p>
|
|
117
|
+
</div>
|
|
118
|
+
</Frame>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
95
121
|
|
|
96
|
-
export
|
|
97
|
-
|
|
98
|
-
<
|
|
99
|
-
<
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
</BaseBackCoverPage>
|
|
107
|
-
);
|
|
122
|
+
export default function AcademicPaperPress() {
|
|
123
|
+
return (
|
|
124
|
+
<Press>
|
|
125
|
+
<Cover />
|
|
126
|
+
<Toc source="story" heading={<h2 id="toc-title" className="toc-heading">Contents</h2>} />
|
|
127
|
+
<Sections source="story" page={Page} />
|
|
128
|
+
<BackCover />
|
|
129
|
+
</Press>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
/* page-surfaces / toc
|
|
2
|
-
* Table-of-contents page surface
|
|
3
|
-
*
|
|
2
|
+
* Table-of-contents page surface rendered by the manuscript <Toc> helper.
|
|
3
|
+
* Entries flow through the generated toc:<sourceId> chain and TocArea.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
.reader-page--toc {
|
|
7
7
|
padding: 0;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
.reader-page--toc .page-frame {
|
|
11
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.reader-page--toc .toc-header {
|
|
15
|
+
display: block;
|
|
16
|
+
overflow: visible;
|
|
17
|
+
opacity: 1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.reader-page--toc .openpress-toc-area {
|
|
21
|
+
height: 100%;
|
|
22
|
+
}
|
|
23
|
+
|
|
10
24
|
.reader-page--toc h2 {
|
|
11
25
|
margin-top: 0;
|
|
12
26
|
font-family: var(--openpress-font-serif);
|
|
@@ -18,13 +32,7 @@
|
|
|
18
32
|
}
|
|
19
33
|
|
|
20
34
|
.reader-page--toc h2.toc-heading--continuation {
|
|
21
|
-
|
|
22
|
-
color: var(--openpress-color-muted);
|
|
23
|
-
font-family: var(--openpress-font-mono);
|
|
24
|
-
font-size: calc(8.5pt - var(--openpress-type-step-down));
|
|
25
|
-
font-weight: 400;
|
|
26
|
-
letter-spacing: 0.08em;
|
|
27
|
-
text-align: right;
|
|
35
|
+
display: none;
|
|
28
36
|
}
|
|
29
37
|
|
|
30
38
|
.toc-list {
|
|
@@ -51,6 +59,7 @@
|
|
|
51
59
|
align-items: baseline;
|
|
52
60
|
color: var(--openpress-color-ink);
|
|
53
61
|
text-decoration: none;
|
|
62
|
+
font-family: var(--openpress-font-serif);
|
|
54
63
|
padding: 1.6mm 0;
|
|
55
64
|
font-weight: 400;
|
|
56
65
|
line-height: 1.38;
|
|
@@ -117,6 +126,7 @@
|
|
|
117
126
|
gap: 3mm;
|
|
118
127
|
align-items: baseline;
|
|
119
128
|
color: var(--openpress-color-ink);
|
|
129
|
+
font-family: var(--openpress-font-serif);
|
|
120
130
|
}
|
|
121
131
|
|
|
122
132
|
.toc-title::after {
|
|
@@ -1,27 +1,37 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Frame, MdxArea } from "@open-press/core";
|
|
2
|
+
import type { SectionsPageProps } from "@open-press/core/manuscript";
|
|
2
3
|
|
|
3
4
|
export default function Page({
|
|
5
|
+
frameKey,
|
|
6
|
+
chainId,
|
|
4
7
|
pageIndex,
|
|
5
8
|
totalPages,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}:
|
|
9
|
+
sectionSlug,
|
|
10
|
+
sectionTitle,
|
|
11
|
+
sectionTone,
|
|
12
|
+
}: SectionsPageProps) {
|
|
10
13
|
return (
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
<Frame
|
|
15
|
+
frameKey={frameKey}
|
|
16
|
+
role="manuscript.content"
|
|
17
|
+
className="reader-page--content"
|
|
15
18
|
data-page-index={pageIndex}
|
|
16
19
|
data-total-pages={totalPages}
|
|
17
|
-
data-
|
|
18
|
-
data-chapter-tone={
|
|
20
|
+
data-section-id={sectionSlug}
|
|
21
|
+
data-chapter-tone={sectionTone}
|
|
19
22
|
>
|
|
20
23
|
<div className="page-frame">
|
|
21
24
|
<header className="page-header" aria-hidden="true" />
|
|
22
|
-
<main className="page-body">
|
|
23
|
-
|
|
25
|
+
<main className="page-body">
|
|
26
|
+
<MdxArea chainId={chainId} />
|
|
27
|
+
</main>
|
|
28
|
+
<footer className="page-footer" aria-hidden="true">
|
|
29
|
+
<span className="footer-left">{sectionTitle}</span>
|
|
30
|
+
<span className="footer-right">
|
|
31
|
+
{totalPages > 1 ? `${pageIndex + 1}/${totalPages}` : pageIndex + 1}
|
|
32
|
+
</span>
|
|
33
|
+
</footer>
|
|
24
34
|
</div>
|
|
25
|
-
</
|
|
35
|
+
</Frame>
|
|
26
36
|
);
|
|
27
37
|
}
|
|
@@ -102,7 +102,7 @@ Claude Document 以 sans 作為主要閱讀字體,讓正文、表格與長段落
|
|
|
102
102
|
|
|
103
103
|
### Tables
|
|
104
104
|
|
|
105
|
-
Markdown table 前使用 `<TableCaption>...</TableCaption>`,內容只寫說明文字;
|
|
105
|
+
Markdown table 前使用 `<TableCaption>...</TableCaption>`,內容只寫說明文字;export pipeline 會輸出 `表 N:...`。不要手寫表號,也不要使用舊 `表:...` marker。
|
|
106
106
|
|
|
107
107
|
<TableCaption>表格使用規則</TableCaption>
|
|
108
108
|
|
|
@@ -114,7 +114,7 @@ Markdown table 前使用 `<TableCaption>...</TableCaption>`,內容只寫說明
|
|
|
114
114
|
|
|
115
115
|
### Figures
|
|
116
116
|
|
|
117
|
-
Figure component 應輸出標準 `<figure><figcaption>...</figcaption></figure>`。`figcaption` 只放 caption 文字,不放手寫圖號;
|
|
117
|
+
Figure component 應輸出標準 `<figure><figcaption>...</figcaption></figure>`。`figcaption` 只放 caption 文字,不放手寫圖號;export pipeline 會依 content pages 的 DOM 順序產生可見的 `圖 N:` / `表 N:` 前綴,並加上統一的 `data-openpress-caption="true"` 與 `data-openpress-caption-label`。
|
|
118
118
|
|
|
119
119
|
### Diagram Rules
|
|
120
120
|
|