@particle-academy/fancy-docs 0.0.0 → 0.2.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/CHANGELOG.md CHANGED
@@ -9,6 +9,30 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.2.0] - 2026-10-20
13
+
14
+ ### Added
15
+
16
+ - **Charts.** last-word 0.10 writes a native `chart` block whose `option` is an
17
+ ECharts option (the same field dark-slide charts take); `DocViewer` draws it
18
+ with fancy-echarts, sized as the writer sizes it (`widthPx` / `heightPx`, a
19
+ `width` percentage of the column, or the full column at 0.6 of its width).
20
+ Drawn as Word draws the file by default: last-word's (Office's) palette,
21
+ legend under the plot, values above a bar or point (past the end of a
22
+ horizontal bar), axis titles centred and kept clear of the axis labels. An
23
+ option that sets any of these keeps its own. A chart with no series is
24
+ skipped rather than drawn as an empty box. Checked beside LibreOffice's
25
+ render of a seven-chart last-word document.
26
+ - **`@particle-academy/fancy-echarts` is an OPTIONAL peer** (`>=6.1.0 <7.0.0`),
27
+ loaded only when a document has a chart. Without it a chart shows a labelled
28
+ placeholder instead of failing. **What to do:** install it if your documents
29
+ have charts.
30
+
31
+ ### Known
32
+
33
+ - A chart's `numberFormat` (an Excel format) is not applied to its labels yet:
34
+ a value Word shows as `172` shows as `171.5`.
35
+
12
36
  ## [0.1.0] - 2026-10-19
13
37
 
14
38
  ### Added
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Particle Academy
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Particle Academy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -60,6 +60,7 @@ registerOfficeViewer("docx", DocFileView, { read: (bytes) => new DocxReader().re
60
60
  | Headings | levels 1–6 at the writer's sizes |
61
61
  | Lists | ordered and bulleted, nested |
62
62
  | Tables | column widths, table width and alignment, borders (including removed ones), header rows and their default fill, cell fills, padding, vertical alignment, row and column spans |
63
+ | Charts | last-word's `chart` block (bar, column, line, pie; an ECharts option), drawn with `@particle-academy/fancy-echarts`, an optional peer: install it if your documents have charts |
63
64
  | Also | code blocks, quotes, rules, embedded images |
64
65
 
65
66
  An unstyled document gets the writer's own defaults (Calibri 11pt, 8pt after
package/dist/index.cjs CHANGED
@@ -133,6 +133,82 @@ function runCss(run) {
133
133
  if (spacing) out.letterSpacing = `${spacing}pt`;
134
134
  return out;
135
135
  }
136
+ var ChartInner = react.lazy(async () => {
137
+ try {
138
+ const mod = await import('@particle-academy/fancy-echarts');
139
+ const EChart = mod.EChart;
140
+ if (!EChart) return { default: Missing };
141
+ mod.registerAll?.();
142
+ return {
143
+ default: ({ option }) => /* @__PURE__ */ jsxRuntime.jsx(EChart, { option, style: { width: "100%", height: "100%" } })
144
+ };
145
+ } catch {
146
+ return { default: Missing };
147
+ }
148
+ });
149
+ function Missing() {
150
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", height: "100%", alignItems: "center", justifyContent: "center", border: "0.5pt dashed #9CA3AF", color: "#6B7280", fontSize: "9pt" }, children: "Chart (install @particle-academy/fancy-echarts to draw it)" });
151
+ }
152
+ function pageChartOption(option) {
153
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
154
+ const hasAxes = option.xAxis !== void 0 || option.yAxis !== void 0;
155
+ const xAxis = isObj(option.xAxis) ? option.xAxis : void 0;
156
+ const yAxis = isObj(option.yAxis) ? option.yAxis : void 0;
157
+ const horizontal = (yAxis?.type ?? "value") === "category";
158
+ const legendShown = isObj(option.legend) && option.legend.show !== false;
159
+ const legend = isObj(option.legend) && legendShown && option.legend.top === void 0 && option.legend.bottom === void 0 ? { ...option.legend, bottom: 0 } : option.legend;
160
+ const named = (axis, extra) => axis && typeof axis.name === "string" && axis.name !== "" && axis.nameLocation === void 0 ? { ...axis, nameLocation: "middle", ...extra } : axis;
161
+ const series = Array.isArray(option.series) ? option.series.map((s) => {
162
+ if (!isObj(s) || !isObj(s.label) || s.label.show !== true || s.label.position !== void 0) return s;
163
+ if (s.type === "bar") return { ...s, label: { ...s.label, position: horizontal ? "right" : "top" } };
164
+ if (s.type === "line") return { ...s, label: { ...s.label, position: "top" } };
165
+ return s;
166
+ }) : option.series;
167
+ return {
168
+ backgroundColor: "transparent",
169
+ // The palette last-word's writer uses when a chart names no colours, so an
170
+ // unstyled chart is the colour it is in Word, not ECharts' own.
171
+ color: OFFICE_PALETTE,
172
+ ...option,
173
+ ...legend === void 0 ? {} : { legend },
174
+ ...series === void 0 ? {} : { series },
175
+ // nameMoveOverlap (ECharts 6) measures the gap from the axis LABELS, so a
176
+ // long category label never ends up under the title; outerBoundsContain
177
+ // 'all' makes the plot area leave room for labels and titles alike.
178
+ ...xAxis ? { xAxis: named(xAxis, { nameGap: 10, nameMoveOverlap: true }) } : {},
179
+ ...yAxis ? { yAxis: named(yAxis, { nameGap: 10, nameRotate: 90, nameMoveOverlap: true }) } : {},
180
+ ...hasAxes ? {
181
+ grid: option.grid ?? {
182
+ top: option.title ? 36 : 16,
183
+ right: 16,
184
+ bottom: 8 + (legendShown ? 28 : 0),
185
+ left: 8,
186
+ outerBoundsMode: "same",
187
+ outerBoundsContain: "all"
188
+ }
189
+ } : {}
190
+ };
191
+ }
192
+ var OFFICE_PALETTE = ["#4472C4", "#ED7D31", "#A5A5A5", "#FFC000", "#5B9BD5", "#70AD47", "#264478", "#9E480E"];
193
+ function isPlottable(block) {
194
+ const option = block?.option;
195
+ if (!option || typeof option !== "object") return false;
196
+ const series = option.series;
197
+ return Array.isArray(series) ? series.length > 0 : series !== void 0 && series !== null;
198
+ }
199
+ function ChartBlock({ block }) {
200
+ const widthPx = num(block.widthPx);
201
+ const heightPx = num(block.heightPx);
202
+ const percent = num(block.width);
203
+ const style = {
204
+ width: widthPx !== void 0 ? `${widthPx}px` : percent !== void 0 ? `${percent}%` : "100%",
205
+ maxWidth: "100%",
206
+ margin: `0 0 ${DEFAULTS.spaceAfter}pt`
207
+ };
208
+ if (heightPx !== void 0) style.height = `${heightPx}px`;
209
+ else style.aspectRatio = "5 / 3";
210
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-fancy-docs-block": "chart", role: "img", "aria-label": typeof block.alt === "string" ? block.alt : void 0, style, children: /* @__PURE__ */ jsxRuntime.jsx(react.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(ChartInner, { option: pageChartOption(block.option) }) }) });
211
+ }
136
212
  function DocViewer({ doc, frame = true, frameProps, className }) {
137
213
  const pages = splitPages(Array.isArray(doc?.blocks) ? doc.blocks : []);
138
214
  const total = pages.length;
@@ -302,6 +378,8 @@ function BlockView({ block }) {
302
378
  }
303
379
  );
304
380
  }
381
+ case "chart":
382
+ return isPlottable(block) ? /* @__PURE__ */ jsxRuntime.jsx(ChartBlock, { block }) : null;
305
383
  case "hr":
306
384
  return /* @__PURE__ */ jsxRuntime.jsx("hr", { "data-fancy-docs-block": "hr", style: { border: 0, borderTop: "0.5pt solid #000000", margin: `0 0 ${DEFAULTS.spaceAfter}pt` } });
307
385
  default:
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/style.ts","../src/DocViewer.tsx","../src/DocFileView.tsx"],"names":["jsx","FauxClient","jsxs","Fragment","sanitizeHref","Callout"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { CSSProperties } from \"react\";\nimport type { Border, BoxBorders, BoxSides, ParagraphProps, Run } from \"./types\";\n\n/**\n * What last-word's writer gives a document that asks for nothing, so an\n * unstyled document looks here as it does in Word. Read off the writer's\n * styles part (docDefaults, Heading1-6, Quote, CodeBlock, Hyperlink) rather\n * than guessed.\n */\nexport const DEFAULTS = {\n font: \"Calibri\",\n /** Points. */\n size: 11,\n /** w:spacing after=\"160\": 8pt after every paragraph. */\n spaceAfter: 8,\n /** w:line=\"259\" of 240: 1.08. */\n lineHeight: 1.08,\n /** Heading 1-6, points. */\n headingSizes: [20, 16, 14, 13, 12, 11],\n headingSpaceBefore: 12,\n headingSpaceAfter: 6,\n quoteIndent: 36,\n quoteColor: \"#595959\",\n codeFont: \"Consolas\",\n codeSize: 10,\n codeFill: \"#F2F2F2\",\n linkColor: \"#0563C1\",\n /** Cell margins 60 / 108 twips. */\n cellPadding: { top: 3, right: 5.4, bottom: 3, left: 5.4 },\n /** The header-cell grey the writer and all three engines share. */\n headerFill: \"#E7E7E7\",\n /** A border edge that names no width. */\n borderWidth: 0.5,\n /** Page margins when none are given: 1440 twips. */\n margin: 72,\n /** Header / footer distance from the page edge: 720 twips. */\n bandDistance: 36,\n bandSize: 9,\n};\n\n/** Page sizes in points, portrait. */\nexport const PAGE_SIZES: Record<string, [number, number]> = {\n letter: [612, 792],\n legal: [612, 1008],\n a4: [595, 842],\n};\n\n/**\n * `#RRGGBB` (or `RRGGBB`), or nothing. A colour comes out of a file, so anything\n * else -- a CSS expression smuggled into a colour field -- is dropped rather\n * than handed to a style.\n */\nexport function hex(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const v = value.trim();\n if (/^#[0-9a-fA-F]{6}$/.test(v)) return v.toUpperCase();\n if (/^[0-9a-fA-F]{6}$/.test(v)) return `#${v.toUpperCase()}`;\n return undefined;\n}\n\n/** A finite number, or nothing. */\nexport function num(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\n/** A font name as a CSS family list: quoted, with a generic fallback. */\nexport function fontStack(font: unknown, generic = \"sans-serif\"): string | undefined {\n if (typeof font !== \"string\" || font.trim() === \"\") return undefined;\n const name = font.replace(/[\"\\\\;{}<>]/g, \"\").trim();\n return `\"${name}\", ${generic}`;\n}\n\nconst CSS_STYLE: Record<string, string> = { single: \"solid\", double: \"double\", dashed: \"dashed\", dotted: \"dotted\" };\n\n/** One border edge as CSS. `style: \"none\"` removes the edge. */\nexport function borderCss(border: Border | undefined): string | undefined {\n if (!border) return undefined;\n if (border.style === \"none\") return \"none\";\n const width = num(border.width) ?? DEFAULTS.borderWidth;\n const style = CSS_STYLE[border.style ?? \"single\"] ?? \"solid\";\n return `${width}pt ${style} ${hex(border.color) ?? \"#000000\"}`;\n}\n\nexport function boxBorders(borders: BoxBorders | undefined): CSSProperties {\n if (!borders) return {};\n const out: CSSProperties = {};\n const top = borderCss(borders.top);\n const right = borderCss(borders.right);\n const bottom = borderCss(borders.bottom);\n const left = borderCss(borders.left);\n if (top) out.borderTop = top;\n if (right) out.borderRight = right;\n if (bottom) out.borderBottom = bottom;\n if (left) out.borderLeft = left;\n return out;\n}\n\nexport function padding(sides: BoxSides | undefined, fallback?: BoxSides): CSSProperties {\n const pick = (k: keyof BoxSides) => num(sides?.[k]) ?? num(fallback?.[k]);\n const out: CSSProperties = {};\n const t = pick(\"top\");\n const r = pick(\"right\");\n const b = pick(\"bottom\");\n const l = pick(\"left\");\n if (t !== undefined) out.paddingTop = `${t}pt`;\n if (r !== undefined) out.paddingRight = `${r}pt`;\n if (b !== undefined) out.paddingBottom = `${b}pt`;\n if (l !== undefined) out.paddingLeft = `${l}pt`;\n return out;\n}\n\n/**\n * Word's \"single\" line is the font's own line height -- ascent + descent + gap,\n * about 1.2 em for Calibri and most text faces -- where CSS's 1.0 is the bare\n * em. So a document's 1.08 lines is 1.08 x 1.2 here; set as 1.08 it drew every\n * paragraph visibly tighter than LibreOffice's render of the same file.\n */\nexport const SINGLE_LINE = 1.2;\n\nexport function lineHeightCss(lines: number): number {\n return Math.round(lines * SINGLE_LINE * 1000) / 1000;\n}\n\n/** A paragraph-shaped block's box: alignment, spacing, indents, shading, borders. */\nexport function paragraphCss(p: ParagraphProps, defaults: { before?: number; after?: number } = {}): CSSProperties {\n const out: CSSProperties = {\n marginTop: `${num(p.spaceBefore) ?? defaults.before ?? 0}pt`,\n marginBottom: `${num(p.spaceAfter) ?? defaults.after ?? DEFAULTS.spaceAfter}pt`,\n lineHeight: String(lineHeightCss(num(p.lineHeight) ?? DEFAULTS.lineHeight)),\n ...boxBorders(p.borders),\n };\n if (p.align) out.textAlign = p.align;\n const left = num(p.indentLeft);\n const right = num(p.indentRight);\n if (left !== undefined) out.marginLeft = `${left}pt`;\n if (right !== undefined) out.marginRight = `${right}pt`;\n const fill = hex(p.shading);\n if (fill) {\n out.backgroundColor = fill;\n // Word draws the shading behind the text with a little room; without it\n // the fill hugs the glyphs and a callout reads as a highlight.\n out.padding = \"2pt 4pt\";\n }\n return out;\n}\n\n/** A run's character style. */\nexport function runCss(run: Run): CSSProperties {\n const out: CSSProperties = {};\n if (run.bold) out.fontWeight = 700;\n if (run.italic) out.fontStyle = \"italic\";\n const lines = [run.underline ? \"underline\" : \"\", run.strike ? \"line-through\" : \"\"].filter(Boolean);\n if (lines.length) out.textDecorationLine = lines.join(\" \");\n const color = hex(run.color);\n if (color) out.color = color;\n const highlight = hex(run.highlight);\n if (highlight) out.backgroundColor = highlight;\n const size = num(run.size);\n if (size !== undefined && size > 0) out.fontSize = `${size}pt`;\n const font = fontStack(run.font);\n if (font) out.fontFamily = font;\n if (run.smallCaps) out.fontVariant = \"small-caps\";\n const spacing = num(run.letterSpacing);\n if (spacing) out.letterSpacing = `${spacing}pt`;\n return out;\n}\n","import { Fragment, type CSSProperties, type ReactNode } from \"react\";\nimport { FauxClient, sanitizeHref, type FauxClientProps } from \"@particle-academy/react-fancy\";\nimport type { Band, Block, Doc, ListItem, Run, TableBorders, TableCell } from \"./types\";\nimport { borderCss, boxBorders, DEFAULTS, fontStack, hex, num, padding, PAGE_SIZES, paragraphCss, runCss } from \"./style\";\n\nexport interface DocViewerProps {\n /** A last-word document, as its readers return it. */\n doc: Doc;\n /**\n * Show the document in react-fancy's `FauxClient` frame: zoom and full screen,\n * revealed on hover, like every file viewer. Default `true`.\n */\n frame?: boolean;\n /** Passed to the frame: `variant`, a controlled `zoom`, `onFullscreenChange`, … */\n frameProps?: Partial<FauxClientProps>;\n className?: string;\n}\n\n/**\n * A last-word document rendered the way Word renders it: page size, margins and\n * running header / footer per page; runs, paragraphs, lists, tables (fills,\n * borders, spans, alignment), code, quotes and images.\n *\n * Measurements stay in points, the model's own unit, so a 0.5pt rule is a 0.5pt\n * rule and the page is the page's size; the frame scales the whole sheet to fit\n * and zooms it.\n *\n * Everything shown came out of a file, so links go through react-fancy's\n * `sanitizeHref`, images are `data:` rasters only (a remote URL in a document\n * is a tracking pixel waiting to fire), and colours must be `#RRGGBB`.\n */\nexport function DocViewer({ doc, frame = true, frameProps, className }: DocViewerProps) {\n const pages = splitPages(Array.isArray(doc?.blocks) ? doc.blocks : []);\n const total = pages.length;\n\n const sheets = (\n <div\n data-fancy-docs-viewer=\"\"\n className={className}\n style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 16, padding: 16, background: \"#E5E7EB\" }}\n >\n {pages.map((blocks, i) => (\n <PageSheet key={i} doc={doc} blocks={blocks} number={i + 1} total={total} />\n ))}\n </div>\n );\n\n if (!frame) return sheets;\n\n // The frame lays the sheets out at their real width and scales them to fit,\n // as a word processor opens at \"fit page width\"; zoom works on top of that.\n return (\n <FauxClient\n variant=\"device\"\n controls\n fill\n width={logicalWidth(doc)}\n scale=\"fit\"\n bodyClassName=\"overflow-auto\"\n {...frameProps}\n >\n {sheets}\n </FauxClient>\n );\n}\n\n/** The sheets' width in CSS pixels, gutter included: the frame's logical width. */\nfunction logicalWidth(doc: Doc): number {\n const page = doc?.page ?? {};\n const [w, h] = PAGE_SIZES[page.size ?? \"letter\"] ?? PAGE_SIZES.letter;\n const width = page.orientation === \"landscape\" ? h : w;\n return Math.ceil((width * 4) / 3) + 32;\n}\n\n/** Page breaks split the flow into sheets; an empty document is one blank sheet. */\nfunction splitPages(blocks: Block[]): Block[][] {\n const pages: Block[][] = [[]];\n for (const block of blocks) {\n if (block?.type === \"pageBreak\") pages.push([]);\n else pages[pages.length - 1].push(block);\n }\n return pages;\n}\n\nfunction PageSheet({ doc, blocks, number, total }: { doc: Doc; blocks: Block[]; number: number; total: number }) {\n const page = doc.page ?? {};\n const [w, h] = PAGE_SIZES[page.size ?? \"letter\"] ?? PAGE_SIZES.letter;\n const [width, height] = page.orientation === \"landscape\" ? [h, w] : [w, h];\n const m = page.margins ?? {};\n const margin = (side: \"top\" | \"right\" | \"bottom\" | \"left\") => num(m[side]) ?? DEFAULTS.margin;\n\n const style: CSSProperties = {\n position: \"relative\",\n width: `${width}pt`,\n minHeight: `${height}pt`,\n background: \"#FFFFFF\",\n color: \"#000000\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.15)\",\n fontFamily: fontStack(doc.defaultFont ?? DEFAULTS.font),\n fontSize: `${num(doc.defaultSize) ?? DEFAULTS.size}pt`,\n flexShrink: 0,\n };\n\n return (\n <section data-fancy-docs-page={number} style={style}>\n {page.header && <BandLine band={page.header} kind=\"header\" number={number} total={total} left={margin(\"left\")} right={margin(\"right\")} />}\n <div\n data-fancy-docs-body=\"\"\n style={{ paddingTop: `${margin(\"top\")}pt`, paddingRight: `${margin(\"right\")}pt`, paddingBottom: `${margin(\"bottom\")}pt`, paddingLeft: `${margin(\"left\")}pt` }}\n >\n {blocks.map((block, i) => (\n <BlockView key={i} block={block} />\n ))}\n </div>\n {page.footer && <BandLine band={page.footer} kind=\"footer\" number={number} total={total} left={margin(\"left\")} right={margin(\"right\")} />}\n </section>\n );\n}\n\n/** A running header or footer: left / center / right, with `{page}` and `{pages}` filled in. */\nfunction BandLine({ band, kind, number, total, left, right }: { band: Band; kind: \"header\" | \"footer\"; number: number; total: number; left: number; right: number }) {\n const fill = (s: unknown) => (typeof s === \"string\" ? s.split(\"{page}\").join(String(number)).split(\"{pages}\").join(String(total)) : \"\");\n const style: CSSProperties = {\n position: \"absolute\",\n left: `${left}pt`,\n right: `${right}pt`,\n [kind === \"header\" ? \"top\" : \"bottom\"]: `${DEFAULTS.bandDistance}pt`,\n display: \"grid\",\n gridTemplateColumns: \"1fr auto 1fr\",\n fontSize: `${num(band.size) ?? DEFAULTS.bandSize}pt`,\n color: hex(band.color) ?? \"#595959\",\n };\n return (\n <div data-fancy-docs-band={kind} style={style}>\n <span style={{ textAlign: \"left\" }}>{fill(band.left)}</span>\n <span style={{ textAlign: \"center\" }}>{fill(band.center)}</span>\n <span style={{ textAlign: \"right\" }}>{fill(band.right)}</span>\n </div>\n );\n}\n\nfunction Runs({ runs }: { runs: Run[] | undefined }) {\n return (\n <>\n {(Array.isArray(runs) ? runs : []).map((run, i) => (\n <RunView key={i} run={run} />\n ))}\n </>\n );\n}\n\nfunction RunView({ run }: { run: Run }) {\n const text = typeof run?.text === \"string\" ? run.text : \"\";\n const style = runCss(run);\n const href = typeof run.link === \"string\" ? sanitizeHref(run.link) : undefined;\n\n if (run.code) {\n style.fontFamily = style.fontFamily ?? fontStack(DEFAULTS.codeFont, \"monospace\");\n style.backgroundColor = style.backgroundColor ?? DEFAULTS.codeFill;\n }\n if (href) {\n style.color = style.color ?? DEFAULTS.linkColor;\n style.textDecorationLine = style.textDecorationLine ?? \"underline\";\n }\n\n // Line breaks inside a run are real breaks, as Word shows them.\n const parts = text.split(\"\\n\");\n const content = parts.map((part, i) => (\n <Fragment key={i}>\n {i > 0 && <br />}\n {part}\n </Fragment>\n ));\n const span = run.code ? (\n <code data-fancy-docs-run=\"\" style={style}>{content}</code>\n ) : (\n <span data-fancy-docs-run=\"\" style={style}>{content}</span>\n );\n\n return href ? (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer nofollow\">\n {span}\n </a>\n ) : (\n span\n );\n}\n\nfunction BlockView({ block }: { block: Block }): ReactNode {\n switch (block?.type) {\n case \"heading\": {\n const level = Math.min(6, Math.max(1, Math.round(num(block.level) ?? 1)));\n const Tag = `h${level}` as \"h1\";\n const style: CSSProperties = {\n ...paragraphCss(block, { before: DEFAULTS.headingSpaceBefore, after: DEFAULTS.headingSpaceAfter }),\n fontSize: `${DEFAULTS.headingSizes[level - 1]}pt`,\n fontWeight: 700,\n };\n return (\n <Tag data-fancy-docs-block=\"heading\" style={style}>\n <Runs runs={block.runs} />\n </Tag>\n );\n }\n case \"paragraph\":\n return (\n <p data-fancy-docs-block=\"paragraph\" style={paragraphCss(block)}>\n <Runs runs={block.runs} />\n </p>\n );\n case \"list\":\n return <ListView items={block.items} ordered={!!block.ordered} />;\n case \"table\":\n return <TableView block={block} />;\n case \"code\":\n return (\n <pre\n data-fancy-docs-block=\"code\"\n style={{\n margin: `0 0 ${DEFAULTS.spaceAfter}pt`,\n padding: \"4pt 6pt\",\n background: DEFAULTS.codeFill,\n fontFamily: fontStack(DEFAULTS.codeFont, \"monospace\"),\n fontSize: `${DEFAULTS.codeSize}pt`,\n lineHeight: 1,\n whiteSpace: \"pre-wrap\",\n }}\n >\n <code>{typeof block.text === \"string\" ? block.text : \"\"}</code>\n </pre>\n );\n case \"quote\":\n return (\n <blockquote\n data-fancy-docs-block=\"quote\"\n style={{ margin: `0 0 0 ${DEFAULTS.quoteIndent}pt`, fontStyle: \"italic\", color: DEFAULTS.quoteColor }}\n >\n {(Array.isArray(block.blocks) ? block.blocks : []).map((b, i) => (\n <BlockView key={i} block={b} />\n ))}\n </blockquote>\n );\n case \"image\": {\n // Rasters embedded in the file only: a remote URL would fetch as soon as\n // the document opened -- a tracking pixel in a file someone sent you.\n const src = typeof block.src === \"string\" && /^data:image\\/(png|jpeg|gif|webp);base64,[A-Za-z0-9+/=]+$/.test(block.src) ? block.src : null;\n if (!src) return null;\n return (\n <img\n data-fancy-docs-block=\"image\"\n src={src}\n alt={typeof block.alt === \"string\" ? block.alt : \"\"}\n style={{ display: \"block\", maxWidth: \"100%\", width: num(block.widthPx), height: num(block.heightPx) ? undefined : \"auto\", margin: `0 0 ${DEFAULTS.spaceAfter}pt` }}\n />\n );\n }\n case \"hr\":\n return <hr data-fancy-docs-block=\"hr\" style={{ border: 0, borderTop: \"0.5pt solid #000000\", margin: `0 0 ${DEFAULTS.spaceAfter}pt` }} />;\n default:\n return null;\n }\n}\n\nfunction ListView({ items, ordered }: { items: ListItem[] | undefined; ordered: boolean }) {\n const Tag = ordered ? \"ol\" : \"ul\";\n return (\n <Tag data-fancy-docs-block=\"list\" style={{ margin: `0 0 ${DEFAULTS.spaceAfter}pt`, paddingLeft: \"18pt\", listStyleType: ordered ? \"decimal\" : \"disc\" }}>\n {(Array.isArray(items) ? items : []).map((item, i) => (\n <li key={i} style={{ ...paragraphCss(item, { after: 0 }) }}>\n <Runs runs={item.runs} />\n {Array.isArray(item.children) && item.children.length > 0 && <ListView items={item.children} ordered={ordered} />}\n </li>\n ))}\n </Tag>\n );\n}\n\ntype TableBlock = Extract<Block, { type: \"table\" }>;\n\nfunction TableView({ block }: { block: TableBlock }) {\n const rows = Array.isArray(block.rows) ? block.rows : [];\n const widths = Array.isArray(block.widths) ? block.widths.filter((w) => num(w) !== undefined && w > 0) : [];\n const sum = widths.reduce((a, b) => a + b, 0);\n const width = num(block.width);\n const borders: TableBorders = block.borders ?? {};\n\n const style: CSSProperties = {\n borderCollapse: \"collapse\",\n width: width !== undefined ? `${width}%` : \"100%\",\n tableLayout: widths.length > 0 ? \"fixed\" : \"auto\",\n marginBottom: `${DEFAULTS.spaceAfter}pt`,\n ...(block.align === \"center\" ? { marginLeft: \"auto\", marginRight: \"auto\" } : block.align === \"right\" ? { marginLeft: \"auto\" } : {}),\n };\n\n // Every edge defaults to the writer's 0.5pt single line; `{ style: \"none\" }` removes one.\n const edge = (b: TableBorders[keyof TableBorders]) => borderCss(b) ?? `${DEFAULTS.borderWidth}pt solid #000000`;\n\n return (\n <table data-fancy-docs-block=\"table\" style={style}>\n {widths.length > 0 && (\n <colgroup>\n {widths.map((w, i) => (\n <col key={i} style={{ width: `${Math.round((w / sum) * 1000) / 10}%` }} />\n ))}\n </colgroup>\n )}\n <tbody>\n {rows.map((row, r) => (\n <tr key={r}>\n {(Array.isArray(row.cells) ? row.cells : []).map((cell, c, cells) => {\n const header = !!row.header;\n const Tag = header ? \"th\" : \"td\";\n const first = c === 0;\n const last = c === cells.length - 1;\n const cellStyle: CSSProperties = {\n // Outer edges from the table's box; inner ones from insideH / insideV.\n borderTop: r === 0 ? edge(borders.top) : edge(borders.insideH),\n borderBottom: r === rows.length - 1 ? edge(borders.bottom) : edge(borders.insideH),\n borderLeft: first ? edge(borders.left) : edge(borders.insideV),\n borderRight: last ? edge(borders.right) : edge(borders.insideV),\n ...padding(cell.padding, { ...DEFAULTS.cellPadding, ...(block.cellPadding ?? {}) }),\n ...boxBorders(cell.borders),\n verticalAlign: cell.valign === \"center\" ? \"middle\" : cell.valign ?? \"top\",\n textAlign: \"left\",\n fontWeight: header ? 700 : undefined,\n backgroundColor: hex(cell.shading) ?? (header ? DEFAULTS.headerFill : undefined),\n };\n return (\n <Tag\n key={c}\n style={cellStyle}\n colSpan={num(cell.colSpan) && cell.colSpan! > 1 ? cell.colSpan : undefined}\n rowSpan={num(cell.rowSpan) && cell.rowSpan! > 1 ? cell.rowSpan : undefined}\n >\n <CellBlocks cell={cell} />\n </Tag>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n\n/** A cell's blocks, with the last paragraph's trailing space dropped as Word does inside a cell. */\nfunction CellBlocks({ cell }: { cell: TableCell }) {\n const blocks = Array.isArray(cell.blocks) ? cell.blocks : [];\n return (\n <>\n {blocks.map((b, i) =>\n b?.type === \"paragraph\" ? (\n <p key={i} data-fancy-docs-block=\"paragraph\" style={{ ...paragraphCss(b), ...(i === blocks.length - 1 && num(b.spaceAfter) === undefined ? { marginBottom: 0 } : {}) }}>\n <Runs runs={b.runs} />\n </p>\n ) : (\n <BlockView key={i} block={b} />\n ),\n )}\n </>\n );\n}\n","import { Callout, type FauxClientProps } from \"@particle-academy/react-fancy\";\nimport { DocViewer } from \"./DocViewer\";\nimport type { Doc } from \"./types\";\n\nexport interface DocFileViewProps {\n /** A document as last-word's reader returns it. */\n document: unknown;\n filename?: string;\n /** Passed to the FauxClient frame. */\n frameProps?: Partial<FauxClientProps>;\n}\n\n/**\n * A .docx in fancy-code's `FileViewer`: register it once at app start.\n *\n * ```ts\n * registerOfficeViewer(\"docx\", DocFileView, { read: (b) => new DocxReader().read(b) });\n * ```\n *\n * The props match fancy-code's `OfficeViewerProps` without importing them, so\n * this package does not depend on fancy-code.\n */\nexport function DocFileView({ document, filename, frameProps }: DocFileViewProps) {\n const doc = document as Partial<Doc> | null;\n\n // A reader that returned something else would otherwise draw a blank page.\n if (!doc || typeof doc !== \"object\" || !Array.isArray(doc.blocks)) {\n return <Callout color=\"red\">{filename ?? \"This file\"} did not read as a document.</Callout>;\n }\n\n return <DocViewer doc={doc as Doc} frameProps={frameProps} />;\n}\n"]}
1
+ {"version":3,"sources":["../src/style.ts","../src/ChartBlock.tsx","../src/DocViewer.tsx","../src/DocFileView.tsx"],"names":["lazy","jsx","Suspense","FauxClient","jsxs","Fragment","sanitizeHref","Callout"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { CSSProperties } from \"react\";\nimport type { Border, BoxBorders, BoxSides, ParagraphProps, Run } from \"./types\";\n\n/**\n * What last-word's writer gives a document that asks for nothing, so an\n * unstyled document looks here as it does in Word. Read off the writer's\n * styles part (docDefaults, Heading1-6, Quote, CodeBlock, Hyperlink) rather\n * than guessed.\n */\nexport const DEFAULTS = {\n font: \"Calibri\",\n /** Points. */\n size: 11,\n /** w:spacing after=\"160\": 8pt after every paragraph. */\n spaceAfter: 8,\n /** w:line=\"259\" of 240: 1.08. */\n lineHeight: 1.08,\n /** Heading 1-6, points. */\n headingSizes: [20, 16, 14, 13, 12, 11],\n headingSpaceBefore: 12,\n headingSpaceAfter: 6,\n quoteIndent: 36,\n quoteColor: \"#595959\",\n codeFont: \"Consolas\",\n codeSize: 10,\n codeFill: \"#F2F2F2\",\n linkColor: \"#0563C1\",\n /** Cell margins 60 / 108 twips. */\n cellPadding: { top: 3, right: 5.4, bottom: 3, left: 5.4 },\n /** The header-cell grey the writer and all three engines share. */\n headerFill: \"#E7E7E7\",\n /** A border edge that names no width. */\n borderWidth: 0.5,\n /** Page margins when none are given: 1440 twips. */\n margin: 72,\n /** Header / footer distance from the page edge: 720 twips. */\n bandDistance: 36,\n bandSize: 9,\n};\n\n/** Page sizes in points, portrait. */\nexport const PAGE_SIZES: Record<string, [number, number]> = {\n letter: [612, 792],\n legal: [612, 1008],\n a4: [595, 842],\n};\n\n/**\n * `#RRGGBB` (or `RRGGBB`), or nothing. A colour comes out of a file, so anything\n * else -- a CSS expression smuggled into a colour field -- is dropped rather\n * than handed to a style.\n */\nexport function hex(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const v = value.trim();\n if (/^#[0-9a-fA-F]{6}$/.test(v)) return v.toUpperCase();\n if (/^[0-9a-fA-F]{6}$/.test(v)) return `#${v.toUpperCase()}`;\n return undefined;\n}\n\n/** A finite number, or nothing. */\nexport function num(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\n/** A font name as a CSS family list: quoted, with a generic fallback. */\nexport function fontStack(font: unknown, generic = \"sans-serif\"): string | undefined {\n if (typeof font !== \"string\" || font.trim() === \"\") return undefined;\n const name = font.replace(/[\"\\\\;{}<>]/g, \"\").trim();\n return `\"${name}\", ${generic}`;\n}\n\nconst CSS_STYLE: Record<string, string> = { single: \"solid\", double: \"double\", dashed: \"dashed\", dotted: \"dotted\" };\n\n/** One border edge as CSS. `style: \"none\"` removes the edge. */\nexport function borderCss(border: Border | undefined): string | undefined {\n if (!border) return undefined;\n if (border.style === \"none\") return \"none\";\n const width = num(border.width) ?? DEFAULTS.borderWidth;\n const style = CSS_STYLE[border.style ?? \"single\"] ?? \"solid\";\n return `${width}pt ${style} ${hex(border.color) ?? \"#000000\"}`;\n}\n\nexport function boxBorders(borders: BoxBorders | undefined): CSSProperties {\n if (!borders) return {};\n const out: CSSProperties = {};\n const top = borderCss(borders.top);\n const right = borderCss(borders.right);\n const bottom = borderCss(borders.bottom);\n const left = borderCss(borders.left);\n if (top) out.borderTop = top;\n if (right) out.borderRight = right;\n if (bottom) out.borderBottom = bottom;\n if (left) out.borderLeft = left;\n return out;\n}\n\nexport function padding(sides: BoxSides | undefined, fallback?: BoxSides): CSSProperties {\n const pick = (k: keyof BoxSides) => num(sides?.[k]) ?? num(fallback?.[k]);\n const out: CSSProperties = {};\n const t = pick(\"top\");\n const r = pick(\"right\");\n const b = pick(\"bottom\");\n const l = pick(\"left\");\n if (t !== undefined) out.paddingTop = `${t}pt`;\n if (r !== undefined) out.paddingRight = `${r}pt`;\n if (b !== undefined) out.paddingBottom = `${b}pt`;\n if (l !== undefined) out.paddingLeft = `${l}pt`;\n return out;\n}\n\n/**\n * Word's \"single\" line is the font's own line height -- ascent + descent + gap,\n * about 1.2 em for Calibri and most text faces -- where CSS's 1.0 is the bare\n * em. So a document's 1.08 lines is 1.08 x 1.2 here; set as 1.08 it drew every\n * paragraph visibly tighter than LibreOffice's render of the same file.\n */\nexport const SINGLE_LINE = 1.2;\n\nexport function lineHeightCss(lines: number): number {\n return Math.round(lines * SINGLE_LINE * 1000) / 1000;\n}\n\n/** A paragraph-shaped block's box: alignment, spacing, indents, shading, borders. */\nexport function paragraphCss(p: ParagraphProps, defaults: { before?: number; after?: number } = {}): CSSProperties {\n const out: CSSProperties = {\n marginTop: `${num(p.spaceBefore) ?? defaults.before ?? 0}pt`,\n marginBottom: `${num(p.spaceAfter) ?? defaults.after ?? DEFAULTS.spaceAfter}pt`,\n lineHeight: String(lineHeightCss(num(p.lineHeight) ?? DEFAULTS.lineHeight)),\n ...boxBorders(p.borders),\n };\n if (p.align) out.textAlign = p.align;\n const left = num(p.indentLeft);\n const right = num(p.indentRight);\n if (left !== undefined) out.marginLeft = `${left}pt`;\n if (right !== undefined) out.marginRight = `${right}pt`;\n const fill = hex(p.shading);\n if (fill) {\n out.backgroundColor = fill;\n // Word draws the shading behind the text with a little room; without it\n // the fill hugs the glyphs and a callout reads as a highlight.\n out.padding = \"2pt 4pt\";\n }\n return out;\n}\n\n/** A run's character style. */\nexport function runCss(run: Run): CSSProperties {\n const out: CSSProperties = {};\n if (run.bold) out.fontWeight = 700;\n if (run.italic) out.fontStyle = \"italic\";\n const lines = [run.underline ? \"underline\" : \"\", run.strike ? \"line-through\" : \"\"].filter(Boolean);\n if (lines.length) out.textDecorationLine = lines.join(\" \");\n const color = hex(run.color);\n if (color) out.color = color;\n const highlight = hex(run.highlight);\n if (highlight) out.backgroundColor = highlight;\n const size = num(run.size);\n if (size !== undefined && size > 0) out.fontSize = `${size}pt`;\n const font = fontStack(run.font);\n if (font) out.fontFamily = font;\n if (run.smallCaps) out.fontVariant = \"small-caps\";\n const spacing = num(run.letterSpacing);\n if (spacing) out.letterSpacing = `${spacing}pt`;\n return out;\n}\n","import { lazy, Suspense, type ComponentType, type CSSProperties } from \"react\";\nimport { DEFAULTS, num } from \"./style\";\n\nexport interface ChartBlockData {\n type: \"chart\";\n /** An Apache ECharts option -- the same field a dark-slide chart element takes. */\n option: Record<string, unknown>;\n /** Pixels. */\n widthPx?: number;\n heightPx?: number;\n /** Percentage of the text column. */\n width?: number;\n /** Excel number format for the chart's values. */\n numberFormat?: string;\n alt?: string;\n}\n\ninterface InnerProps {\n option: unknown;\n}\n\n/**\n * fancy-echarts is an OPTIONAL peer: a document without a chart must not make\n * an app install a charting engine. So it is loaded on first use, and an app\n * without it gets a labelled placeholder rather than a build failure -- the\n * pattern fancy-slides' chart host uses.\n */\nconst ChartInner: ComponentType<InnerProps> = lazy(async () => {\n try {\n const mod: Record<string, unknown> = await import(\"@particle-academy/fancy-echarts\");\n const EChart = mod.EChart as ComponentType<{ option: unknown; style?: CSSProperties }> | undefined;\n if (!EChart) return { default: Missing };\n (mod.registerAll as (() => void) | undefined)?.();\n return {\n default: ({ option }: InnerProps) => <EChart option={option} style={{ width: \"100%\", height: \"100%\" }} />,\n };\n } catch {\n return { default: Missing };\n }\n});\n\nfunction Missing() {\n return (\n <div style={{ display: \"flex\", height: \"100%\", alignItems: \"center\", justifyContent: \"center\", border: \"0.5pt dashed #9CA3AF\", color: \"#6B7280\", fontSize: \"9pt\" }}>\n Chart (install @particle-academy/fancy-echarts to draw it)\n </div>\n );\n}\n\n/**\n * The option laid out for a page: transparent behind it (the page shows\n * through, as in Word) and a grid that keeps axis labels inside the box.\n * Defaults only -- an option that sets its own keeps it.\n */\nexport function pageChartOption(option: Record<string, unknown>): Record<string, unknown> {\n const isObj = (v: unknown): v is Record<string, unknown> => typeof v === \"object\" && v !== null && !Array.isArray(v);\n const hasAxes = option.xAxis !== undefined || option.yAxis !== undefined;\n const xAxis = isObj(option.xAxis) ? option.xAxis : undefined;\n const yAxis = isObj(option.yAxis) ? option.yAxis : undefined;\n // Bars run sideways when the CATEGORY axis is y.\n const horizontal = (yAxis?.type ?? \"value\") === \"category\";\n\n // Legend below the plot, as Word places it; only when the file did not.\n const legendShown = isObj(option.legend) && option.legend.show !== false;\n const legend =\n isObj(option.legend) && legendShown && option.legend.top === undefined && option.legend.bottom === undefined\n ? { ...option.legend, bottom: 0 }\n : option.legend;\n\n // Axis titles centred along their axis, as Word draws them. ECharts puts a\n // name at the END of the axis, where a long one is clipped.\n const named = (axis: Record<string, unknown> | undefined, extra: Record<string, unknown>) =>\n axis && typeof axis.name === \"string\" && axis.name !== \"\" && axis.nameLocation === undefined\n ? { ...axis, nameLocation: \"middle\", ...extra }\n : axis;\n\n // Values printed past the end of the bar or above the point (outEnd), as\n // Word prints them; ECharts' default puts a bar's value inside it.\n const series = Array.isArray(option.series)\n ? option.series.map((s) => {\n if (!isObj(s) || !isObj(s.label) || s.label.show !== true || s.label.position !== undefined) return s;\n if (s.type === \"bar\") return { ...s, label: { ...s.label, position: horizontal ? \"right\" : \"top\" } };\n if (s.type === \"line\") return { ...s, label: { ...s.label, position: \"top\" } };\n return s;\n })\n : option.series;\n\n return {\n backgroundColor: \"transparent\",\n // The palette last-word's writer uses when a chart names no colours, so an\n // unstyled chart is the colour it is in Word, not ECharts' own.\n color: OFFICE_PALETTE,\n ...option,\n ...(legend === undefined ? {} : { legend }),\n ...(series === undefined ? {} : { series }),\n // nameMoveOverlap (ECharts 6) measures the gap from the axis LABELS, so a\n // long category label never ends up under the title; outerBoundsContain\n // 'all' makes the plot area leave room for labels and titles alike.\n ...(xAxis ? { xAxis: named(xAxis, { nameGap: 10, nameMoveOverlap: true }) } : {}),\n ...(yAxis ? { yAxis: named(yAxis, { nameGap: 10, nameRotate: 90, nameMoveOverlap: true }) } : {}),\n ...(hasAxes\n ? {\n grid: option.grid ?? {\n top: option.title ? 36 : 16,\n right: 16,\n bottom: 8 + (legendShown ? 28 : 0),\n left: 8,\n outerBoundsMode: \"same\",\n outerBoundsContain: \"all\",\n },\n }\n : {}),\n };\n}\n\n/** last-word's default chart palette (Office's): 4472C4, ED7D31, A5A5A5, … */\nconst OFFICE_PALETTE = [\"#4472C4\", \"#ED7D31\", \"#A5A5A5\", \"#FFC000\", \"#5B9BD5\", \"#70AD47\", \"#264478\", \"#9E480E\"];\n\n/** Whether the block has anything to plot. ECharts draws an empty box for an option with no series. */\nexport function isPlottable(block: ChartBlockData): boolean {\n const option = block?.option;\n if (!option || typeof option !== \"object\") return false;\n const series = (option as { series?: unknown }).series;\n return Array.isArray(series) ? series.length > 0 : series !== undefined && series !== null;\n}\n\n/**\n * A chart block, sized as the writer sizes it: `widthPx` / `heightPx` when given,\n * a `width` percentage of the column, or the full column at 0.6 of its width tall.\n */\nexport function ChartBlock({ block }: { block: ChartBlockData }) {\n const widthPx = num(block.widthPx);\n const heightPx = num(block.heightPx);\n const percent = num(block.width);\n\n const style: CSSProperties = {\n width: widthPx !== undefined ? `${widthPx}px` : percent !== undefined ? `${percent}%` : \"100%\",\n maxWidth: \"100%\",\n margin: `0 0 ${DEFAULTS.spaceAfter}pt`,\n };\n if (heightPx !== undefined) style.height = `${heightPx}px`;\n else style.aspectRatio = \"5 / 3\";\n\n return (\n <div data-fancy-docs-block=\"chart\" role=\"img\" aria-label={typeof block.alt === \"string\" ? block.alt : undefined} style={style}>\n <Suspense fallback={null}>\n <ChartInner option={pageChartOption(block.option)} />\n </Suspense>\n </div>\n );\n}\n","import { Fragment, type CSSProperties, type ReactNode } from \"react\";\nimport { FauxClient, sanitizeHref, type FauxClientProps } from \"@particle-academy/react-fancy\";\nimport type { Band, Block, Doc, ListItem, Run, TableBorders, TableCell } from \"./types\";\nimport { borderCss, boxBorders, DEFAULTS, fontStack, hex, num, padding, PAGE_SIZES, paragraphCss, runCss } from \"./style\";\nimport { ChartBlock, isPlottable } from \"./ChartBlock\";\n\nexport interface DocViewerProps {\n /** A last-word document, as its readers return it. */\n doc: Doc;\n /**\n * Show the document in react-fancy's `FauxClient` frame: zoom and full screen,\n * revealed on hover, like every file viewer. Default `true`.\n */\n frame?: boolean;\n /** Passed to the frame: `variant`, a controlled `zoom`, `onFullscreenChange`, … */\n frameProps?: Partial<FauxClientProps>;\n className?: string;\n}\n\n/**\n * A last-word document rendered the way Word renders it: page size, margins and\n * running header / footer per page; runs, paragraphs, lists, tables (fills,\n * borders, spans, alignment), code, quotes and images.\n *\n * Measurements stay in points, the model's own unit, so a 0.5pt rule is a 0.5pt\n * rule and the page is the page's size; the frame scales the whole sheet to fit\n * and zooms it.\n *\n * Everything shown came out of a file, so links go through react-fancy's\n * `sanitizeHref`, images are `data:` rasters only (a remote URL in a document\n * is a tracking pixel waiting to fire), and colours must be `#RRGGBB`.\n */\nexport function DocViewer({ doc, frame = true, frameProps, className }: DocViewerProps) {\n const pages = splitPages(Array.isArray(doc?.blocks) ? doc.blocks : []);\n const total = pages.length;\n\n const sheets = (\n <div\n data-fancy-docs-viewer=\"\"\n className={className}\n style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 16, padding: 16, background: \"#E5E7EB\" }}\n >\n {pages.map((blocks, i) => (\n <PageSheet key={i} doc={doc} blocks={blocks} number={i + 1} total={total} />\n ))}\n </div>\n );\n\n if (!frame) return sheets;\n\n // The frame lays the sheets out at their real width and scales them to fit,\n // as a word processor opens at \"fit page width\"; zoom works on top of that.\n return (\n <FauxClient\n variant=\"device\"\n controls\n fill\n width={logicalWidth(doc)}\n scale=\"fit\"\n bodyClassName=\"overflow-auto\"\n {...frameProps}\n >\n {sheets}\n </FauxClient>\n );\n}\n\n/** The sheets' width in CSS pixels, gutter included: the frame's logical width. */\nfunction logicalWidth(doc: Doc): number {\n const page = doc?.page ?? {};\n const [w, h] = PAGE_SIZES[page.size ?? \"letter\"] ?? PAGE_SIZES.letter;\n const width = page.orientation === \"landscape\" ? h : w;\n return Math.ceil((width * 4) / 3) + 32;\n}\n\n/** Page breaks split the flow into sheets; an empty document is one blank sheet. */\nfunction splitPages(blocks: Block[]): Block[][] {\n const pages: Block[][] = [[]];\n for (const block of blocks) {\n if (block?.type === \"pageBreak\") pages.push([]);\n else pages[pages.length - 1].push(block);\n }\n return pages;\n}\n\nfunction PageSheet({ doc, blocks, number, total }: { doc: Doc; blocks: Block[]; number: number; total: number }) {\n const page = doc.page ?? {};\n const [w, h] = PAGE_SIZES[page.size ?? \"letter\"] ?? PAGE_SIZES.letter;\n const [width, height] = page.orientation === \"landscape\" ? [h, w] : [w, h];\n const m = page.margins ?? {};\n const margin = (side: \"top\" | \"right\" | \"bottom\" | \"left\") => num(m[side]) ?? DEFAULTS.margin;\n\n const style: CSSProperties = {\n position: \"relative\",\n width: `${width}pt`,\n minHeight: `${height}pt`,\n background: \"#FFFFFF\",\n color: \"#000000\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.15)\",\n fontFamily: fontStack(doc.defaultFont ?? DEFAULTS.font),\n fontSize: `${num(doc.defaultSize) ?? DEFAULTS.size}pt`,\n flexShrink: 0,\n };\n\n return (\n <section data-fancy-docs-page={number} style={style}>\n {page.header && <BandLine band={page.header} kind=\"header\" number={number} total={total} left={margin(\"left\")} right={margin(\"right\")} />}\n <div\n data-fancy-docs-body=\"\"\n style={{ paddingTop: `${margin(\"top\")}pt`, paddingRight: `${margin(\"right\")}pt`, paddingBottom: `${margin(\"bottom\")}pt`, paddingLeft: `${margin(\"left\")}pt` }}\n >\n {blocks.map((block, i) => (\n <BlockView key={i} block={block} />\n ))}\n </div>\n {page.footer && <BandLine band={page.footer} kind=\"footer\" number={number} total={total} left={margin(\"left\")} right={margin(\"right\")} />}\n </section>\n );\n}\n\n/** A running header or footer: left / center / right, with `{page}` and `{pages}` filled in. */\nfunction BandLine({ band, kind, number, total, left, right }: { band: Band; kind: \"header\" | \"footer\"; number: number; total: number; left: number; right: number }) {\n const fill = (s: unknown) => (typeof s === \"string\" ? s.split(\"{page}\").join(String(number)).split(\"{pages}\").join(String(total)) : \"\");\n const style: CSSProperties = {\n position: \"absolute\",\n left: `${left}pt`,\n right: `${right}pt`,\n [kind === \"header\" ? \"top\" : \"bottom\"]: `${DEFAULTS.bandDistance}pt`,\n display: \"grid\",\n gridTemplateColumns: \"1fr auto 1fr\",\n fontSize: `${num(band.size) ?? DEFAULTS.bandSize}pt`,\n color: hex(band.color) ?? \"#595959\",\n };\n return (\n <div data-fancy-docs-band={kind} style={style}>\n <span style={{ textAlign: \"left\" }}>{fill(band.left)}</span>\n <span style={{ textAlign: \"center\" }}>{fill(band.center)}</span>\n <span style={{ textAlign: \"right\" }}>{fill(band.right)}</span>\n </div>\n );\n}\n\nfunction Runs({ runs }: { runs: Run[] | undefined }) {\n return (\n <>\n {(Array.isArray(runs) ? runs : []).map((run, i) => (\n <RunView key={i} run={run} />\n ))}\n </>\n );\n}\n\nfunction RunView({ run }: { run: Run }) {\n const text = typeof run?.text === \"string\" ? run.text : \"\";\n const style = runCss(run);\n const href = typeof run.link === \"string\" ? sanitizeHref(run.link) : undefined;\n\n if (run.code) {\n style.fontFamily = style.fontFamily ?? fontStack(DEFAULTS.codeFont, \"monospace\");\n style.backgroundColor = style.backgroundColor ?? DEFAULTS.codeFill;\n }\n if (href) {\n style.color = style.color ?? DEFAULTS.linkColor;\n style.textDecorationLine = style.textDecorationLine ?? \"underline\";\n }\n\n // Line breaks inside a run are real breaks, as Word shows them.\n const parts = text.split(\"\\n\");\n const content = parts.map((part, i) => (\n <Fragment key={i}>\n {i > 0 && <br />}\n {part}\n </Fragment>\n ));\n const span = run.code ? (\n <code data-fancy-docs-run=\"\" style={style}>{content}</code>\n ) : (\n <span data-fancy-docs-run=\"\" style={style}>{content}</span>\n );\n\n return href ? (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer nofollow\">\n {span}\n </a>\n ) : (\n span\n );\n}\n\nfunction BlockView({ block }: { block: Block }): ReactNode {\n switch (block?.type) {\n case \"heading\": {\n const level = Math.min(6, Math.max(1, Math.round(num(block.level) ?? 1)));\n const Tag = `h${level}` as \"h1\";\n const style: CSSProperties = {\n ...paragraphCss(block, { before: DEFAULTS.headingSpaceBefore, after: DEFAULTS.headingSpaceAfter }),\n fontSize: `${DEFAULTS.headingSizes[level - 1]}pt`,\n fontWeight: 700,\n };\n return (\n <Tag data-fancy-docs-block=\"heading\" style={style}>\n <Runs runs={block.runs} />\n </Tag>\n );\n }\n case \"paragraph\":\n return (\n <p data-fancy-docs-block=\"paragraph\" style={paragraphCss(block)}>\n <Runs runs={block.runs} />\n </p>\n );\n case \"list\":\n return <ListView items={block.items} ordered={!!block.ordered} />;\n case \"table\":\n return <TableView block={block} />;\n case \"code\":\n return (\n <pre\n data-fancy-docs-block=\"code\"\n style={{\n margin: `0 0 ${DEFAULTS.spaceAfter}pt`,\n padding: \"4pt 6pt\",\n background: DEFAULTS.codeFill,\n fontFamily: fontStack(DEFAULTS.codeFont, \"monospace\"),\n fontSize: `${DEFAULTS.codeSize}pt`,\n lineHeight: 1,\n whiteSpace: \"pre-wrap\",\n }}\n >\n <code>{typeof block.text === \"string\" ? block.text : \"\"}</code>\n </pre>\n );\n case \"quote\":\n return (\n <blockquote\n data-fancy-docs-block=\"quote\"\n style={{ margin: `0 0 0 ${DEFAULTS.quoteIndent}pt`, fontStyle: \"italic\", color: DEFAULTS.quoteColor }}\n >\n {(Array.isArray(block.blocks) ? block.blocks : []).map((b, i) => (\n <BlockView key={i} block={b} />\n ))}\n </blockquote>\n );\n case \"image\": {\n // Rasters embedded in the file only: a remote URL would fetch as soon as\n // the document opened -- a tracking pixel in a file someone sent you.\n const src = typeof block.src === \"string\" && /^data:image\\/(png|jpeg|gif|webp);base64,[A-Za-z0-9+/=]+$/.test(block.src) ? block.src : null;\n if (!src) return null;\n return (\n <img\n data-fancy-docs-block=\"image\"\n src={src}\n alt={typeof block.alt === \"string\" ? block.alt : \"\"}\n style={{ display: \"block\", maxWidth: \"100%\", width: num(block.widthPx), height: num(block.heightPx) ? undefined : \"auto\", margin: `0 0 ${DEFAULTS.spaceAfter}pt` }}\n />\n );\n }\n case \"chart\":\n // An option with no series draws an empty box; skip it rather than show one.\n return isPlottable(block) ? <ChartBlock block={block} /> : null;\n case \"hr\":\n return <hr data-fancy-docs-block=\"hr\" style={{ border: 0, borderTop: \"0.5pt solid #000000\", margin: `0 0 ${DEFAULTS.spaceAfter}pt` }} />;\n default:\n return null;\n }\n}\n\nfunction ListView({ items, ordered }: { items: ListItem[] | undefined; ordered: boolean }) {\n const Tag = ordered ? \"ol\" : \"ul\";\n return (\n <Tag data-fancy-docs-block=\"list\" style={{ margin: `0 0 ${DEFAULTS.spaceAfter}pt`, paddingLeft: \"18pt\", listStyleType: ordered ? \"decimal\" : \"disc\" }}>\n {(Array.isArray(items) ? items : []).map((item, i) => (\n <li key={i} style={{ ...paragraphCss(item, { after: 0 }) }}>\n <Runs runs={item.runs} />\n {Array.isArray(item.children) && item.children.length > 0 && <ListView items={item.children} ordered={ordered} />}\n </li>\n ))}\n </Tag>\n );\n}\n\ntype TableBlock = Extract<Block, { type: \"table\" }>;\n\nfunction TableView({ block }: { block: TableBlock }) {\n const rows = Array.isArray(block.rows) ? block.rows : [];\n const widths = Array.isArray(block.widths) ? block.widths.filter((w) => num(w) !== undefined && w > 0) : [];\n const sum = widths.reduce((a, b) => a + b, 0);\n const width = num(block.width);\n const borders: TableBorders = block.borders ?? {};\n\n const style: CSSProperties = {\n borderCollapse: \"collapse\",\n width: width !== undefined ? `${width}%` : \"100%\",\n tableLayout: widths.length > 0 ? \"fixed\" : \"auto\",\n marginBottom: `${DEFAULTS.spaceAfter}pt`,\n ...(block.align === \"center\" ? { marginLeft: \"auto\", marginRight: \"auto\" } : block.align === \"right\" ? { marginLeft: \"auto\" } : {}),\n };\n\n // Every edge defaults to the writer's 0.5pt single line; `{ style: \"none\" }` removes one.\n const edge = (b: TableBorders[keyof TableBorders]) => borderCss(b) ?? `${DEFAULTS.borderWidth}pt solid #000000`;\n\n return (\n <table data-fancy-docs-block=\"table\" style={style}>\n {widths.length > 0 && (\n <colgroup>\n {widths.map((w, i) => (\n <col key={i} style={{ width: `${Math.round((w / sum) * 1000) / 10}%` }} />\n ))}\n </colgroup>\n )}\n <tbody>\n {rows.map((row, r) => (\n <tr key={r}>\n {(Array.isArray(row.cells) ? row.cells : []).map((cell, c, cells) => {\n const header = !!row.header;\n const Tag = header ? \"th\" : \"td\";\n const first = c === 0;\n const last = c === cells.length - 1;\n const cellStyle: CSSProperties = {\n // Outer edges from the table's box; inner ones from insideH / insideV.\n borderTop: r === 0 ? edge(borders.top) : edge(borders.insideH),\n borderBottom: r === rows.length - 1 ? edge(borders.bottom) : edge(borders.insideH),\n borderLeft: first ? edge(borders.left) : edge(borders.insideV),\n borderRight: last ? edge(borders.right) : edge(borders.insideV),\n ...padding(cell.padding, { ...DEFAULTS.cellPadding, ...(block.cellPadding ?? {}) }),\n ...boxBorders(cell.borders),\n verticalAlign: cell.valign === \"center\" ? \"middle\" : cell.valign ?? \"top\",\n textAlign: \"left\",\n fontWeight: header ? 700 : undefined,\n backgroundColor: hex(cell.shading) ?? (header ? DEFAULTS.headerFill : undefined),\n };\n return (\n <Tag\n key={c}\n style={cellStyle}\n colSpan={num(cell.colSpan) && cell.colSpan! > 1 ? cell.colSpan : undefined}\n rowSpan={num(cell.rowSpan) && cell.rowSpan! > 1 ? cell.rowSpan : undefined}\n >\n <CellBlocks cell={cell} />\n </Tag>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n\n/** A cell's blocks, with the last paragraph's trailing space dropped as Word does inside a cell. */\nfunction CellBlocks({ cell }: { cell: TableCell }) {\n const blocks = Array.isArray(cell.blocks) ? cell.blocks : [];\n return (\n <>\n {blocks.map((b, i) =>\n b?.type === \"paragraph\" ? (\n <p key={i} data-fancy-docs-block=\"paragraph\" style={{ ...paragraphCss(b), ...(i === blocks.length - 1 && num(b.spaceAfter) === undefined ? { marginBottom: 0 } : {}) }}>\n <Runs runs={b.runs} />\n </p>\n ) : (\n <BlockView key={i} block={b} />\n ),\n )}\n </>\n );\n}\n","import { Callout, type FauxClientProps } from \"@particle-academy/react-fancy\";\nimport { DocViewer } from \"./DocViewer\";\nimport type { Doc } from \"./types\";\n\nexport interface DocFileViewProps {\n /** A document as last-word's reader returns it. */\n document: unknown;\n filename?: string;\n /** Passed to the FauxClient frame. */\n frameProps?: Partial<FauxClientProps>;\n}\n\n/**\n * A .docx in fancy-code's `FileViewer`: register it once at app start.\n *\n * ```ts\n * registerOfficeViewer(\"docx\", DocFileView, { read: (b) => new DocxReader().read(b) });\n * ```\n *\n * The props match fancy-code's `OfficeViewerProps` without importing them, so\n * this package does not depend on fancy-code.\n */\nexport function DocFileView({ document, filename, frameProps }: DocFileViewProps) {\n const doc = document as Partial<Doc> | null;\n\n // A reader that returned something else would otherwise draw a blank page.\n if (!doc || typeof doc !== \"object\" || !Array.isArray(doc.blocks)) {\n return <Callout color=\"red\">{filename ?? \"This file\"} did not read as a document.</Callout>;\n }\n\n return <DocViewer doc={doc as Doc} frameProps={frameProps} />;\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -110,6 +110,16 @@ type Block = ({
110
110
  type: "pageBreak";
111
111
  } | {
112
112
  type: "hr";
113
+ } | {
114
+ type: "chart";
115
+ /** An Apache ECharts option, as last-word 0.10 writes it (the same field dark-slide charts take). */
116
+ option: Record<string, unknown>;
117
+ widthPx?: number;
118
+ heightPx?: number;
119
+ /** Percentage of the text column. */
120
+ width?: number;
121
+ numberFormat?: string;
122
+ alt?: string;
113
123
  };
114
124
  /** A running header or footer: three slots; `{page}` and `{pages}` are filled in. */
115
125
  interface Band {
package/dist/index.d.ts CHANGED
@@ -110,6 +110,16 @@ type Block = ({
110
110
  type: "pageBreak";
111
111
  } | {
112
112
  type: "hr";
113
+ } | {
114
+ type: "chart";
115
+ /** An Apache ECharts option, as last-word 0.10 writes it (the same field dark-slide charts take). */
116
+ option: Record<string, unknown>;
117
+ widthPx?: number;
118
+ heightPx?: number;
119
+ /** Percentage of the text column. */
120
+ width?: number;
121
+ numberFormat?: string;
122
+ alt?: string;
113
123
  };
114
124
  /** A running header or footer: three slots; `{page}` and `{pages}` are filled in. */
115
125
  interface Band {
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Fragment as Fragment$1 } from 'react';
1
+ import { lazy, Suspense, Fragment as Fragment$1 } from 'react';
2
2
  import { FauxClient, Callout, sanitizeHref } from '@particle-academy/react-fancy';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
 
@@ -131,6 +131,82 @@ function runCss(run) {
131
131
  if (spacing) out.letterSpacing = `${spacing}pt`;
132
132
  return out;
133
133
  }
134
+ var ChartInner = lazy(async () => {
135
+ try {
136
+ const mod = await import('@particle-academy/fancy-echarts');
137
+ const EChart = mod.EChart;
138
+ if (!EChart) return { default: Missing };
139
+ mod.registerAll?.();
140
+ return {
141
+ default: ({ option }) => /* @__PURE__ */ jsx(EChart, { option, style: { width: "100%", height: "100%" } })
142
+ };
143
+ } catch {
144
+ return { default: Missing };
145
+ }
146
+ });
147
+ function Missing() {
148
+ return /* @__PURE__ */ jsx("div", { style: { display: "flex", height: "100%", alignItems: "center", justifyContent: "center", border: "0.5pt dashed #9CA3AF", color: "#6B7280", fontSize: "9pt" }, children: "Chart (install @particle-academy/fancy-echarts to draw it)" });
149
+ }
150
+ function pageChartOption(option) {
151
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
152
+ const hasAxes = option.xAxis !== void 0 || option.yAxis !== void 0;
153
+ const xAxis = isObj(option.xAxis) ? option.xAxis : void 0;
154
+ const yAxis = isObj(option.yAxis) ? option.yAxis : void 0;
155
+ const horizontal = (yAxis?.type ?? "value") === "category";
156
+ const legendShown = isObj(option.legend) && option.legend.show !== false;
157
+ const legend = isObj(option.legend) && legendShown && option.legend.top === void 0 && option.legend.bottom === void 0 ? { ...option.legend, bottom: 0 } : option.legend;
158
+ const named = (axis, extra) => axis && typeof axis.name === "string" && axis.name !== "" && axis.nameLocation === void 0 ? { ...axis, nameLocation: "middle", ...extra } : axis;
159
+ const series = Array.isArray(option.series) ? option.series.map((s) => {
160
+ if (!isObj(s) || !isObj(s.label) || s.label.show !== true || s.label.position !== void 0) return s;
161
+ if (s.type === "bar") return { ...s, label: { ...s.label, position: horizontal ? "right" : "top" } };
162
+ if (s.type === "line") return { ...s, label: { ...s.label, position: "top" } };
163
+ return s;
164
+ }) : option.series;
165
+ return {
166
+ backgroundColor: "transparent",
167
+ // The palette last-word's writer uses when a chart names no colours, so an
168
+ // unstyled chart is the colour it is in Word, not ECharts' own.
169
+ color: OFFICE_PALETTE,
170
+ ...option,
171
+ ...legend === void 0 ? {} : { legend },
172
+ ...series === void 0 ? {} : { series },
173
+ // nameMoveOverlap (ECharts 6) measures the gap from the axis LABELS, so a
174
+ // long category label never ends up under the title; outerBoundsContain
175
+ // 'all' makes the plot area leave room for labels and titles alike.
176
+ ...xAxis ? { xAxis: named(xAxis, { nameGap: 10, nameMoveOverlap: true }) } : {},
177
+ ...yAxis ? { yAxis: named(yAxis, { nameGap: 10, nameRotate: 90, nameMoveOverlap: true }) } : {},
178
+ ...hasAxes ? {
179
+ grid: option.grid ?? {
180
+ top: option.title ? 36 : 16,
181
+ right: 16,
182
+ bottom: 8 + (legendShown ? 28 : 0),
183
+ left: 8,
184
+ outerBoundsMode: "same",
185
+ outerBoundsContain: "all"
186
+ }
187
+ } : {}
188
+ };
189
+ }
190
+ var OFFICE_PALETTE = ["#4472C4", "#ED7D31", "#A5A5A5", "#FFC000", "#5B9BD5", "#70AD47", "#264478", "#9E480E"];
191
+ function isPlottable(block) {
192
+ const option = block?.option;
193
+ if (!option || typeof option !== "object") return false;
194
+ const series = option.series;
195
+ return Array.isArray(series) ? series.length > 0 : series !== void 0 && series !== null;
196
+ }
197
+ function ChartBlock({ block }) {
198
+ const widthPx = num(block.widthPx);
199
+ const heightPx = num(block.heightPx);
200
+ const percent = num(block.width);
201
+ const style = {
202
+ width: widthPx !== void 0 ? `${widthPx}px` : percent !== void 0 ? `${percent}%` : "100%",
203
+ maxWidth: "100%",
204
+ margin: `0 0 ${DEFAULTS.spaceAfter}pt`
205
+ };
206
+ if (heightPx !== void 0) style.height = `${heightPx}px`;
207
+ else style.aspectRatio = "5 / 3";
208
+ return /* @__PURE__ */ jsx("div", { "data-fancy-docs-block": "chart", role: "img", "aria-label": typeof block.alt === "string" ? block.alt : void 0, style, children: /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(ChartInner, { option: pageChartOption(block.option) }) }) });
209
+ }
134
210
  function DocViewer({ doc, frame = true, frameProps, className }) {
135
211
  const pages = splitPages(Array.isArray(doc?.blocks) ? doc.blocks : []);
136
212
  const total = pages.length;
@@ -300,6 +376,8 @@ function BlockView({ block }) {
300
376
  }
301
377
  );
302
378
  }
379
+ case "chart":
380
+ return isPlottable(block) ? /* @__PURE__ */ jsx(ChartBlock, { block }) : null;
303
381
  case "hr":
304
382
  return /* @__PURE__ */ jsx("hr", { "data-fancy-docs-block": "hr", style: { border: 0, borderTop: "0.5pt solid #000000", margin: `0 0 ${DEFAULTS.spaceAfter}pt` } });
305
383
  default:
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/style.ts","../src/DocViewer.tsx","../src/DocFileView.tsx"],"names":["Fragment","jsxs","jsx"],"mappings":"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","file":"index.js","sourcesContent":["import type { CSSProperties } from \"react\";\nimport type { Border, BoxBorders, BoxSides, ParagraphProps, Run } from \"./types\";\n\n/**\n * What last-word's writer gives a document that asks for nothing, so an\n * unstyled document looks here as it does in Word. Read off the writer's\n * styles part (docDefaults, Heading1-6, Quote, CodeBlock, Hyperlink) rather\n * than guessed.\n */\nexport const DEFAULTS = {\n font: \"Calibri\",\n /** Points. */\n size: 11,\n /** w:spacing after=\"160\": 8pt after every paragraph. */\n spaceAfter: 8,\n /** w:line=\"259\" of 240: 1.08. */\n lineHeight: 1.08,\n /** Heading 1-6, points. */\n headingSizes: [20, 16, 14, 13, 12, 11],\n headingSpaceBefore: 12,\n headingSpaceAfter: 6,\n quoteIndent: 36,\n quoteColor: \"#595959\",\n codeFont: \"Consolas\",\n codeSize: 10,\n codeFill: \"#F2F2F2\",\n linkColor: \"#0563C1\",\n /** Cell margins 60 / 108 twips. */\n cellPadding: { top: 3, right: 5.4, bottom: 3, left: 5.4 },\n /** The header-cell grey the writer and all three engines share. */\n headerFill: \"#E7E7E7\",\n /** A border edge that names no width. */\n borderWidth: 0.5,\n /** Page margins when none are given: 1440 twips. */\n margin: 72,\n /** Header / footer distance from the page edge: 720 twips. */\n bandDistance: 36,\n bandSize: 9,\n};\n\n/** Page sizes in points, portrait. */\nexport const PAGE_SIZES: Record<string, [number, number]> = {\n letter: [612, 792],\n legal: [612, 1008],\n a4: [595, 842],\n};\n\n/**\n * `#RRGGBB` (or `RRGGBB`), or nothing. A colour comes out of a file, so anything\n * else -- a CSS expression smuggled into a colour field -- is dropped rather\n * than handed to a style.\n */\nexport function hex(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const v = value.trim();\n if (/^#[0-9a-fA-F]{6}$/.test(v)) return v.toUpperCase();\n if (/^[0-9a-fA-F]{6}$/.test(v)) return `#${v.toUpperCase()}`;\n return undefined;\n}\n\n/** A finite number, or nothing. */\nexport function num(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\n/** A font name as a CSS family list: quoted, with a generic fallback. */\nexport function fontStack(font: unknown, generic = \"sans-serif\"): string | undefined {\n if (typeof font !== \"string\" || font.trim() === \"\") return undefined;\n const name = font.replace(/[\"\\\\;{}<>]/g, \"\").trim();\n return `\"${name}\", ${generic}`;\n}\n\nconst CSS_STYLE: Record<string, string> = { single: \"solid\", double: \"double\", dashed: \"dashed\", dotted: \"dotted\" };\n\n/** One border edge as CSS. `style: \"none\"` removes the edge. */\nexport function borderCss(border: Border | undefined): string | undefined {\n if (!border) return undefined;\n if (border.style === \"none\") return \"none\";\n const width = num(border.width) ?? DEFAULTS.borderWidth;\n const style = CSS_STYLE[border.style ?? \"single\"] ?? \"solid\";\n return `${width}pt ${style} ${hex(border.color) ?? \"#000000\"}`;\n}\n\nexport function boxBorders(borders: BoxBorders | undefined): CSSProperties {\n if (!borders) return {};\n const out: CSSProperties = {};\n const top = borderCss(borders.top);\n const right = borderCss(borders.right);\n const bottom = borderCss(borders.bottom);\n const left = borderCss(borders.left);\n if (top) out.borderTop = top;\n if (right) out.borderRight = right;\n if (bottom) out.borderBottom = bottom;\n if (left) out.borderLeft = left;\n return out;\n}\n\nexport function padding(sides: BoxSides | undefined, fallback?: BoxSides): CSSProperties {\n const pick = (k: keyof BoxSides) => num(sides?.[k]) ?? num(fallback?.[k]);\n const out: CSSProperties = {};\n const t = pick(\"top\");\n const r = pick(\"right\");\n const b = pick(\"bottom\");\n const l = pick(\"left\");\n if (t !== undefined) out.paddingTop = `${t}pt`;\n if (r !== undefined) out.paddingRight = `${r}pt`;\n if (b !== undefined) out.paddingBottom = `${b}pt`;\n if (l !== undefined) out.paddingLeft = `${l}pt`;\n return out;\n}\n\n/**\n * Word's \"single\" line is the font's own line height -- ascent + descent + gap,\n * about 1.2 em for Calibri and most text faces -- where CSS's 1.0 is the bare\n * em. So a document's 1.08 lines is 1.08 x 1.2 here; set as 1.08 it drew every\n * paragraph visibly tighter than LibreOffice's render of the same file.\n */\nexport const SINGLE_LINE = 1.2;\n\nexport function lineHeightCss(lines: number): number {\n return Math.round(lines * SINGLE_LINE * 1000) / 1000;\n}\n\n/** A paragraph-shaped block's box: alignment, spacing, indents, shading, borders. */\nexport function paragraphCss(p: ParagraphProps, defaults: { before?: number; after?: number } = {}): CSSProperties {\n const out: CSSProperties = {\n marginTop: `${num(p.spaceBefore) ?? defaults.before ?? 0}pt`,\n marginBottom: `${num(p.spaceAfter) ?? defaults.after ?? DEFAULTS.spaceAfter}pt`,\n lineHeight: String(lineHeightCss(num(p.lineHeight) ?? DEFAULTS.lineHeight)),\n ...boxBorders(p.borders),\n };\n if (p.align) out.textAlign = p.align;\n const left = num(p.indentLeft);\n const right = num(p.indentRight);\n if (left !== undefined) out.marginLeft = `${left}pt`;\n if (right !== undefined) out.marginRight = `${right}pt`;\n const fill = hex(p.shading);\n if (fill) {\n out.backgroundColor = fill;\n // Word draws the shading behind the text with a little room; without it\n // the fill hugs the glyphs and a callout reads as a highlight.\n out.padding = \"2pt 4pt\";\n }\n return out;\n}\n\n/** A run's character style. */\nexport function runCss(run: Run): CSSProperties {\n const out: CSSProperties = {};\n if (run.bold) out.fontWeight = 700;\n if (run.italic) out.fontStyle = \"italic\";\n const lines = [run.underline ? \"underline\" : \"\", run.strike ? \"line-through\" : \"\"].filter(Boolean);\n if (lines.length) out.textDecorationLine = lines.join(\" \");\n const color = hex(run.color);\n if (color) out.color = color;\n const highlight = hex(run.highlight);\n if (highlight) out.backgroundColor = highlight;\n const size = num(run.size);\n if (size !== undefined && size > 0) out.fontSize = `${size}pt`;\n const font = fontStack(run.font);\n if (font) out.fontFamily = font;\n if (run.smallCaps) out.fontVariant = \"small-caps\";\n const spacing = num(run.letterSpacing);\n if (spacing) out.letterSpacing = `${spacing}pt`;\n return out;\n}\n","import { Fragment, type CSSProperties, type ReactNode } from \"react\";\nimport { FauxClient, sanitizeHref, type FauxClientProps } from \"@particle-academy/react-fancy\";\nimport type { Band, Block, Doc, ListItem, Run, TableBorders, TableCell } from \"./types\";\nimport { borderCss, boxBorders, DEFAULTS, fontStack, hex, num, padding, PAGE_SIZES, paragraphCss, runCss } from \"./style\";\n\nexport interface DocViewerProps {\n /** A last-word document, as its readers return it. */\n doc: Doc;\n /**\n * Show the document in react-fancy's `FauxClient` frame: zoom and full screen,\n * revealed on hover, like every file viewer. Default `true`.\n */\n frame?: boolean;\n /** Passed to the frame: `variant`, a controlled `zoom`, `onFullscreenChange`, … */\n frameProps?: Partial<FauxClientProps>;\n className?: string;\n}\n\n/**\n * A last-word document rendered the way Word renders it: page size, margins and\n * running header / footer per page; runs, paragraphs, lists, tables (fills,\n * borders, spans, alignment), code, quotes and images.\n *\n * Measurements stay in points, the model's own unit, so a 0.5pt rule is a 0.5pt\n * rule and the page is the page's size; the frame scales the whole sheet to fit\n * and zooms it.\n *\n * Everything shown came out of a file, so links go through react-fancy's\n * `sanitizeHref`, images are `data:` rasters only (a remote URL in a document\n * is a tracking pixel waiting to fire), and colours must be `#RRGGBB`.\n */\nexport function DocViewer({ doc, frame = true, frameProps, className }: DocViewerProps) {\n const pages = splitPages(Array.isArray(doc?.blocks) ? doc.blocks : []);\n const total = pages.length;\n\n const sheets = (\n <div\n data-fancy-docs-viewer=\"\"\n className={className}\n style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 16, padding: 16, background: \"#E5E7EB\" }}\n >\n {pages.map((blocks, i) => (\n <PageSheet key={i} doc={doc} blocks={blocks} number={i + 1} total={total} />\n ))}\n </div>\n );\n\n if (!frame) return sheets;\n\n // The frame lays the sheets out at their real width and scales them to fit,\n // as a word processor opens at \"fit page width\"; zoom works on top of that.\n return (\n <FauxClient\n variant=\"device\"\n controls\n fill\n width={logicalWidth(doc)}\n scale=\"fit\"\n bodyClassName=\"overflow-auto\"\n {...frameProps}\n >\n {sheets}\n </FauxClient>\n );\n}\n\n/** The sheets' width in CSS pixels, gutter included: the frame's logical width. */\nfunction logicalWidth(doc: Doc): number {\n const page = doc?.page ?? {};\n const [w, h] = PAGE_SIZES[page.size ?? \"letter\"] ?? PAGE_SIZES.letter;\n const width = page.orientation === \"landscape\" ? h : w;\n return Math.ceil((width * 4) / 3) + 32;\n}\n\n/** Page breaks split the flow into sheets; an empty document is one blank sheet. */\nfunction splitPages(blocks: Block[]): Block[][] {\n const pages: Block[][] = [[]];\n for (const block of blocks) {\n if (block?.type === \"pageBreak\") pages.push([]);\n else pages[pages.length - 1].push(block);\n }\n return pages;\n}\n\nfunction PageSheet({ doc, blocks, number, total }: { doc: Doc; blocks: Block[]; number: number; total: number }) {\n const page = doc.page ?? {};\n const [w, h] = PAGE_SIZES[page.size ?? \"letter\"] ?? PAGE_SIZES.letter;\n const [width, height] = page.orientation === \"landscape\" ? [h, w] : [w, h];\n const m = page.margins ?? {};\n const margin = (side: \"top\" | \"right\" | \"bottom\" | \"left\") => num(m[side]) ?? DEFAULTS.margin;\n\n const style: CSSProperties = {\n position: \"relative\",\n width: `${width}pt`,\n minHeight: `${height}pt`,\n background: \"#FFFFFF\",\n color: \"#000000\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.15)\",\n fontFamily: fontStack(doc.defaultFont ?? DEFAULTS.font),\n fontSize: `${num(doc.defaultSize) ?? DEFAULTS.size}pt`,\n flexShrink: 0,\n };\n\n return (\n <section data-fancy-docs-page={number} style={style}>\n {page.header && <BandLine band={page.header} kind=\"header\" number={number} total={total} left={margin(\"left\")} right={margin(\"right\")} />}\n <div\n data-fancy-docs-body=\"\"\n style={{ paddingTop: `${margin(\"top\")}pt`, paddingRight: `${margin(\"right\")}pt`, paddingBottom: `${margin(\"bottom\")}pt`, paddingLeft: `${margin(\"left\")}pt` }}\n >\n {blocks.map((block, i) => (\n <BlockView key={i} block={block} />\n ))}\n </div>\n {page.footer && <BandLine band={page.footer} kind=\"footer\" number={number} total={total} left={margin(\"left\")} right={margin(\"right\")} />}\n </section>\n );\n}\n\n/** A running header or footer: left / center / right, with `{page}` and `{pages}` filled in. */\nfunction BandLine({ band, kind, number, total, left, right }: { band: Band; kind: \"header\" | \"footer\"; number: number; total: number; left: number; right: number }) {\n const fill = (s: unknown) => (typeof s === \"string\" ? s.split(\"{page}\").join(String(number)).split(\"{pages}\").join(String(total)) : \"\");\n const style: CSSProperties = {\n position: \"absolute\",\n left: `${left}pt`,\n right: `${right}pt`,\n [kind === \"header\" ? \"top\" : \"bottom\"]: `${DEFAULTS.bandDistance}pt`,\n display: \"grid\",\n gridTemplateColumns: \"1fr auto 1fr\",\n fontSize: `${num(band.size) ?? DEFAULTS.bandSize}pt`,\n color: hex(band.color) ?? \"#595959\",\n };\n return (\n <div data-fancy-docs-band={kind} style={style}>\n <span style={{ textAlign: \"left\" }}>{fill(band.left)}</span>\n <span style={{ textAlign: \"center\" }}>{fill(band.center)}</span>\n <span style={{ textAlign: \"right\" }}>{fill(band.right)}</span>\n </div>\n );\n}\n\nfunction Runs({ runs }: { runs: Run[] | undefined }) {\n return (\n <>\n {(Array.isArray(runs) ? runs : []).map((run, i) => (\n <RunView key={i} run={run} />\n ))}\n </>\n );\n}\n\nfunction RunView({ run }: { run: Run }) {\n const text = typeof run?.text === \"string\" ? run.text : \"\";\n const style = runCss(run);\n const href = typeof run.link === \"string\" ? sanitizeHref(run.link) : undefined;\n\n if (run.code) {\n style.fontFamily = style.fontFamily ?? fontStack(DEFAULTS.codeFont, \"monospace\");\n style.backgroundColor = style.backgroundColor ?? DEFAULTS.codeFill;\n }\n if (href) {\n style.color = style.color ?? DEFAULTS.linkColor;\n style.textDecorationLine = style.textDecorationLine ?? \"underline\";\n }\n\n // Line breaks inside a run are real breaks, as Word shows them.\n const parts = text.split(\"\\n\");\n const content = parts.map((part, i) => (\n <Fragment key={i}>\n {i > 0 && <br />}\n {part}\n </Fragment>\n ));\n const span = run.code ? (\n <code data-fancy-docs-run=\"\" style={style}>{content}</code>\n ) : (\n <span data-fancy-docs-run=\"\" style={style}>{content}</span>\n );\n\n return href ? (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer nofollow\">\n {span}\n </a>\n ) : (\n span\n );\n}\n\nfunction BlockView({ block }: { block: Block }): ReactNode {\n switch (block?.type) {\n case \"heading\": {\n const level = Math.min(6, Math.max(1, Math.round(num(block.level) ?? 1)));\n const Tag = `h${level}` as \"h1\";\n const style: CSSProperties = {\n ...paragraphCss(block, { before: DEFAULTS.headingSpaceBefore, after: DEFAULTS.headingSpaceAfter }),\n fontSize: `${DEFAULTS.headingSizes[level - 1]}pt`,\n fontWeight: 700,\n };\n return (\n <Tag data-fancy-docs-block=\"heading\" style={style}>\n <Runs runs={block.runs} />\n </Tag>\n );\n }\n case \"paragraph\":\n return (\n <p data-fancy-docs-block=\"paragraph\" style={paragraphCss(block)}>\n <Runs runs={block.runs} />\n </p>\n );\n case \"list\":\n return <ListView items={block.items} ordered={!!block.ordered} />;\n case \"table\":\n return <TableView block={block} />;\n case \"code\":\n return (\n <pre\n data-fancy-docs-block=\"code\"\n style={{\n margin: `0 0 ${DEFAULTS.spaceAfter}pt`,\n padding: \"4pt 6pt\",\n background: DEFAULTS.codeFill,\n fontFamily: fontStack(DEFAULTS.codeFont, \"monospace\"),\n fontSize: `${DEFAULTS.codeSize}pt`,\n lineHeight: 1,\n whiteSpace: \"pre-wrap\",\n }}\n >\n <code>{typeof block.text === \"string\" ? block.text : \"\"}</code>\n </pre>\n );\n case \"quote\":\n return (\n <blockquote\n data-fancy-docs-block=\"quote\"\n style={{ margin: `0 0 0 ${DEFAULTS.quoteIndent}pt`, fontStyle: \"italic\", color: DEFAULTS.quoteColor }}\n >\n {(Array.isArray(block.blocks) ? block.blocks : []).map((b, i) => (\n <BlockView key={i} block={b} />\n ))}\n </blockquote>\n );\n case \"image\": {\n // Rasters embedded in the file only: a remote URL would fetch as soon as\n // the document opened -- a tracking pixel in a file someone sent you.\n const src = typeof block.src === \"string\" && /^data:image\\/(png|jpeg|gif|webp);base64,[A-Za-z0-9+/=]+$/.test(block.src) ? block.src : null;\n if (!src) return null;\n return (\n <img\n data-fancy-docs-block=\"image\"\n src={src}\n alt={typeof block.alt === \"string\" ? block.alt : \"\"}\n style={{ display: \"block\", maxWidth: \"100%\", width: num(block.widthPx), height: num(block.heightPx) ? undefined : \"auto\", margin: `0 0 ${DEFAULTS.spaceAfter}pt` }}\n />\n );\n }\n case \"hr\":\n return <hr data-fancy-docs-block=\"hr\" style={{ border: 0, borderTop: \"0.5pt solid #000000\", margin: `0 0 ${DEFAULTS.spaceAfter}pt` }} />;\n default:\n return null;\n }\n}\n\nfunction ListView({ items, ordered }: { items: ListItem[] | undefined; ordered: boolean }) {\n const Tag = ordered ? \"ol\" : \"ul\";\n return (\n <Tag data-fancy-docs-block=\"list\" style={{ margin: `0 0 ${DEFAULTS.spaceAfter}pt`, paddingLeft: \"18pt\", listStyleType: ordered ? \"decimal\" : \"disc\" }}>\n {(Array.isArray(items) ? items : []).map((item, i) => (\n <li key={i} style={{ ...paragraphCss(item, { after: 0 }) }}>\n <Runs runs={item.runs} />\n {Array.isArray(item.children) && item.children.length > 0 && <ListView items={item.children} ordered={ordered} />}\n </li>\n ))}\n </Tag>\n );\n}\n\ntype TableBlock = Extract<Block, { type: \"table\" }>;\n\nfunction TableView({ block }: { block: TableBlock }) {\n const rows = Array.isArray(block.rows) ? block.rows : [];\n const widths = Array.isArray(block.widths) ? block.widths.filter((w) => num(w) !== undefined && w > 0) : [];\n const sum = widths.reduce((a, b) => a + b, 0);\n const width = num(block.width);\n const borders: TableBorders = block.borders ?? {};\n\n const style: CSSProperties = {\n borderCollapse: \"collapse\",\n width: width !== undefined ? `${width}%` : \"100%\",\n tableLayout: widths.length > 0 ? \"fixed\" : \"auto\",\n marginBottom: `${DEFAULTS.spaceAfter}pt`,\n ...(block.align === \"center\" ? { marginLeft: \"auto\", marginRight: \"auto\" } : block.align === \"right\" ? { marginLeft: \"auto\" } : {}),\n };\n\n // Every edge defaults to the writer's 0.5pt single line; `{ style: \"none\" }` removes one.\n const edge = (b: TableBorders[keyof TableBorders]) => borderCss(b) ?? `${DEFAULTS.borderWidth}pt solid #000000`;\n\n return (\n <table data-fancy-docs-block=\"table\" style={style}>\n {widths.length > 0 && (\n <colgroup>\n {widths.map((w, i) => (\n <col key={i} style={{ width: `${Math.round((w / sum) * 1000) / 10}%` }} />\n ))}\n </colgroup>\n )}\n <tbody>\n {rows.map((row, r) => (\n <tr key={r}>\n {(Array.isArray(row.cells) ? row.cells : []).map((cell, c, cells) => {\n const header = !!row.header;\n const Tag = header ? \"th\" : \"td\";\n const first = c === 0;\n const last = c === cells.length - 1;\n const cellStyle: CSSProperties = {\n // Outer edges from the table's box; inner ones from insideH / insideV.\n borderTop: r === 0 ? edge(borders.top) : edge(borders.insideH),\n borderBottom: r === rows.length - 1 ? edge(borders.bottom) : edge(borders.insideH),\n borderLeft: first ? edge(borders.left) : edge(borders.insideV),\n borderRight: last ? edge(borders.right) : edge(borders.insideV),\n ...padding(cell.padding, { ...DEFAULTS.cellPadding, ...(block.cellPadding ?? {}) }),\n ...boxBorders(cell.borders),\n verticalAlign: cell.valign === \"center\" ? \"middle\" : cell.valign ?? \"top\",\n textAlign: \"left\",\n fontWeight: header ? 700 : undefined,\n backgroundColor: hex(cell.shading) ?? (header ? DEFAULTS.headerFill : undefined),\n };\n return (\n <Tag\n key={c}\n style={cellStyle}\n colSpan={num(cell.colSpan) && cell.colSpan! > 1 ? cell.colSpan : undefined}\n rowSpan={num(cell.rowSpan) && cell.rowSpan! > 1 ? cell.rowSpan : undefined}\n >\n <CellBlocks cell={cell} />\n </Tag>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n\n/** A cell's blocks, with the last paragraph's trailing space dropped as Word does inside a cell. */\nfunction CellBlocks({ cell }: { cell: TableCell }) {\n const blocks = Array.isArray(cell.blocks) ? cell.blocks : [];\n return (\n <>\n {blocks.map((b, i) =>\n b?.type === \"paragraph\" ? (\n <p key={i} data-fancy-docs-block=\"paragraph\" style={{ ...paragraphCss(b), ...(i === blocks.length - 1 && num(b.spaceAfter) === undefined ? { marginBottom: 0 } : {}) }}>\n <Runs runs={b.runs} />\n </p>\n ) : (\n <BlockView key={i} block={b} />\n ),\n )}\n </>\n );\n}\n","import { Callout, type FauxClientProps } from \"@particle-academy/react-fancy\";\nimport { DocViewer } from \"./DocViewer\";\nimport type { Doc } from \"./types\";\n\nexport interface DocFileViewProps {\n /** A document as last-word's reader returns it. */\n document: unknown;\n filename?: string;\n /** Passed to the FauxClient frame. */\n frameProps?: Partial<FauxClientProps>;\n}\n\n/**\n * A .docx in fancy-code's `FileViewer`: register it once at app start.\n *\n * ```ts\n * registerOfficeViewer(\"docx\", DocFileView, { read: (b) => new DocxReader().read(b) });\n * ```\n *\n * The props match fancy-code's `OfficeViewerProps` without importing them, so\n * this package does not depend on fancy-code.\n */\nexport function DocFileView({ document, filename, frameProps }: DocFileViewProps) {\n const doc = document as Partial<Doc> | null;\n\n // A reader that returned something else would otherwise draw a blank page.\n if (!doc || typeof doc !== \"object\" || !Array.isArray(doc.blocks)) {\n return <Callout color=\"red\">{filename ?? \"This file\"} did not read as a document.</Callout>;\n }\n\n return <DocViewer doc={doc as Doc} frameProps={frameProps} />;\n}\n"]}
1
+ {"version":3,"sources":["../src/style.ts","../src/ChartBlock.tsx","../src/DocViewer.tsx","../src/DocFileView.tsx"],"names":["jsx","Fragment","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import type { CSSProperties } from \"react\";\nimport type { Border, BoxBorders, BoxSides, ParagraphProps, Run } from \"./types\";\n\n/**\n * What last-word's writer gives a document that asks for nothing, so an\n * unstyled document looks here as it does in Word. Read off the writer's\n * styles part (docDefaults, Heading1-6, Quote, CodeBlock, Hyperlink) rather\n * than guessed.\n */\nexport const DEFAULTS = {\n font: \"Calibri\",\n /** Points. */\n size: 11,\n /** w:spacing after=\"160\": 8pt after every paragraph. */\n spaceAfter: 8,\n /** w:line=\"259\" of 240: 1.08. */\n lineHeight: 1.08,\n /** Heading 1-6, points. */\n headingSizes: [20, 16, 14, 13, 12, 11],\n headingSpaceBefore: 12,\n headingSpaceAfter: 6,\n quoteIndent: 36,\n quoteColor: \"#595959\",\n codeFont: \"Consolas\",\n codeSize: 10,\n codeFill: \"#F2F2F2\",\n linkColor: \"#0563C1\",\n /** Cell margins 60 / 108 twips. */\n cellPadding: { top: 3, right: 5.4, bottom: 3, left: 5.4 },\n /** The header-cell grey the writer and all three engines share. */\n headerFill: \"#E7E7E7\",\n /** A border edge that names no width. */\n borderWidth: 0.5,\n /** Page margins when none are given: 1440 twips. */\n margin: 72,\n /** Header / footer distance from the page edge: 720 twips. */\n bandDistance: 36,\n bandSize: 9,\n};\n\n/** Page sizes in points, portrait. */\nexport const PAGE_SIZES: Record<string, [number, number]> = {\n letter: [612, 792],\n legal: [612, 1008],\n a4: [595, 842],\n};\n\n/**\n * `#RRGGBB` (or `RRGGBB`), or nothing. A colour comes out of a file, so anything\n * else -- a CSS expression smuggled into a colour field -- is dropped rather\n * than handed to a style.\n */\nexport function hex(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const v = value.trim();\n if (/^#[0-9a-fA-F]{6}$/.test(v)) return v.toUpperCase();\n if (/^[0-9a-fA-F]{6}$/.test(v)) return `#${v.toUpperCase()}`;\n return undefined;\n}\n\n/** A finite number, or nothing. */\nexport function num(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\n/** A font name as a CSS family list: quoted, with a generic fallback. */\nexport function fontStack(font: unknown, generic = \"sans-serif\"): string | undefined {\n if (typeof font !== \"string\" || font.trim() === \"\") return undefined;\n const name = font.replace(/[\"\\\\;{}<>]/g, \"\").trim();\n return `\"${name}\", ${generic}`;\n}\n\nconst CSS_STYLE: Record<string, string> = { single: \"solid\", double: \"double\", dashed: \"dashed\", dotted: \"dotted\" };\n\n/** One border edge as CSS. `style: \"none\"` removes the edge. */\nexport function borderCss(border: Border | undefined): string | undefined {\n if (!border) return undefined;\n if (border.style === \"none\") return \"none\";\n const width = num(border.width) ?? DEFAULTS.borderWidth;\n const style = CSS_STYLE[border.style ?? \"single\"] ?? \"solid\";\n return `${width}pt ${style} ${hex(border.color) ?? \"#000000\"}`;\n}\n\nexport function boxBorders(borders: BoxBorders | undefined): CSSProperties {\n if (!borders) return {};\n const out: CSSProperties = {};\n const top = borderCss(borders.top);\n const right = borderCss(borders.right);\n const bottom = borderCss(borders.bottom);\n const left = borderCss(borders.left);\n if (top) out.borderTop = top;\n if (right) out.borderRight = right;\n if (bottom) out.borderBottom = bottom;\n if (left) out.borderLeft = left;\n return out;\n}\n\nexport function padding(sides: BoxSides | undefined, fallback?: BoxSides): CSSProperties {\n const pick = (k: keyof BoxSides) => num(sides?.[k]) ?? num(fallback?.[k]);\n const out: CSSProperties = {};\n const t = pick(\"top\");\n const r = pick(\"right\");\n const b = pick(\"bottom\");\n const l = pick(\"left\");\n if (t !== undefined) out.paddingTop = `${t}pt`;\n if (r !== undefined) out.paddingRight = `${r}pt`;\n if (b !== undefined) out.paddingBottom = `${b}pt`;\n if (l !== undefined) out.paddingLeft = `${l}pt`;\n return out;\n}\n\n/**\n * Word's \"single\" line is the font's own line height -- ascent + descent + gap,\n * about 1.2 em for Calibri and most text faces -- where CSS's 1.0 is the bare\n * em. So a document's 1.08 lines is 1.08 x 1.2 here; set as 1.08 it drew every\n * paragraph visibly tighter than LibreOffice's render of the same file.\n */\nexport const SINGLE_LINE = 1.2;\n\nexport function lineHeightCss(lines: number): number {\n return Math.round(lines * SINGLE_LINE * 1000) / 1000;\n}\n\n/** A paragraph-shaped block's box: alignment, spacing, indents, shading, borders. */\nexport function paragraphCss(p: ParagraphProps, defaults: { before?: number; after?: number } = {}): CSSProperties {\n const out: CSSProperties = {\n marginTop: `${num(p.spaceBefore) ?? defaults.before ?? 0}pt`,\n marginBottom: `${num(p.spaceAfter) ?? defaults.after ?? DEFAULTS.spaceAfter}pt`,\n lineHeight: String(lineHeightCss(num(p.lineHeight) ?? DEFAULTS.lineHeight)),\n ...boxBorders(p.borders),\n };\n if (p.align) out.textAlign = p.align;\n const left = num(p.indentLeft);\n const right = num(p.indentRight);\n if (left !== undefined) out.marginLeft = `${left}pt`;\n if (right !== undefined) out.marginRight = `${right}pt`;\n const fill = hex(p.shading);\n if (fill) {\n out.backgroundColor = fill;\n // Word draws the shading behind the text with a little room; without it\n // the fill hugs the glyphs and a callout reads as a highlight.\n out.padding = \"2pt 4pt\";\n }\n return out;\n}\n\n/** A run's character style. */\nexport function runCss(run: Run): CSSProperties {\n const out: CSSProperties = {};\n if (run.bold) out.fontWeight = 700;\n if (run.italic) out.fontStyle = \"italic\";\n const lines = [run.underline ? \"underline\" : \"\", run.strike ? \"line-through\" : \"\"].filter(Boolean);\n if (lines.length) out.textDecorationLine = lines.join(\" \");\n const color = hex(run.color);\n if (color) out.color = color;\n const highlight = hex(run.highlight);\n if (highlight) out.backgroundColor = highlight;\n const size = num(run.size);\n if (size !== undefined && size > 0) out.fontSize = `${size}pt`;\n const font = fontStack(run.font);\n if (font) out.fontFamily = font;\n if (run.smallCaps) out.fontVariant = \"small-caps\";\n const spacing = num(run.letterSpacing);\n if (spacing) out.letterSpacing = `${spacing}pt`;\n return out;\n}\n","import { lazy, Suspense, type ComponentType, type CSSProperties } from \"react\";\nimport { DEFAULTS, num } from \"./style\";\n\nexport interface ChartBlockData {\n type: \"chart\";\n /** An Apache ECharts option -- the same field a dark-slide chart element takes. */\n option: Record<string, unknown>;\n /** Pixels. */\n widthPx?: number;\n heightPx?: number;\n /** Percentage of the text column. */\n width?: number;\n /** Excel number format for the chart's values. */\n numberFormat?: string;\n alt?: string;\n}\n\ninterface InnerProps {\n option: unknown;\n}\n\n/**\n * fancy-echarts is an OPTIONAL peer: a document without a chart must not make\n * an app install a charting engine. So it is loaded on first use, and an app\n * without it gets a labelled placeholder rather than a build failure -- the\n * pattern fancy-slides' chart host uses.\n */\nconst ChartInner: ComponentType<InnerProps> = lazy(async () => {\n try {\n const mod: Record<string, unknown> = await import(\"@particle-academy/fancy-echarts\");\n const EChart = mod.EChart as ComponentType<{ option: unknown; style?: CSSProperties }> | undefined;\n if (!EChart) return { default: Missing };\n (mod.registerAll as (() => void) | undefined)?.();\n return {\n default: ({ option }: InnerProps) => <EChart option={option} style={{ width: \"100%\", height: \"100%\" }} />,\n };\n } catch {\n return { default: Missing };\n }\n});\n\nfunction Missing() {\n return (\n <div style={{ display: \"flex\", height: \"100%\", alignItems: \"center\", justifyContent: \"center\", border: \"0.5pt dashed #9CA3AF\", color: \"#6B7280\", fontSize: \"9pt\" }}>\n Chart (install @particle-academy/fancy-echarts to draw it)\n </div>\n );\n}\n\n/**\n * The option laid out for a page: transparent behind it (the page shows\n * through, as in Word) and a grid that keeps axis labels inside the box.\n * Defaults only -- an option that sets its own keeps it.\n */\nexport function pageChartOption(option: Record<string, unknown>): Record<string, unknown> {\n const isObj = (v: unknown): v is Record<string, unknown> => typeof v === \"object\" && v !== null && !Array.isArray(v);\n const hasAxes = option.xAxis !== undefined || option.yAxis !== undefined;\n const xAxis = isObj(option.xAxis) ? option.xAxis : undefined;\n const yAxis = isObj(option.yAxis) ? option.yAxis : undefined;\n // Bars run sideways when the CATEGORY axis is y.\n const horizontal = (yAxis?.type ?? \"value\") === \"category\";\n\n // Legend below the plot, as Word places it; only when the file did not.\n const legendShown = isObj(option.legend) && option.legend.show !== false;\n const legend =\n isObj(option.legend) && legendShown && option.legend.top === undefined && option.legend.bottom === undefined\n ? { ...option.legend, bottom: 0 }\n : option.legend;\n\n // Axis titles centred along their axis, as Word draws them. ECharts puts a\n // name at the END of the axis, where a long one is clipped.\n const named = (axis: Record<string, unknown> | undefined, extra: Record<string, unknown>) =>\n axis && typeof axis.name === \"string\" && axis.name !== \"\" && axis.nameLocation === undefined\n ? { ...axis, nameLocation: \"middle\", ...extra }\n : axis;\n\n // Values printed past the end of the bar or above the point (outEnd), as\n // Word prints them; ECharts' default puts a bar's value inside it.\n const series = Array.isArray(option.series)\n ? option.series.map((s) => {\n if (!isObj(s) || !isObj(s.label) || s.label.show !== true || s.label.position !== undefined) return s;\n if (s.type === \"bar\") return { ...s, label: { ...s.label, position: horizontal ? \"right\" : \"top\" } };\n if (s.type === \"line\") return { ...s, label: { ...s.label, position: \"top\" } };\n return s;\n })\n : option.series;\n\n return {\n backgroundColor: \"transparent\",\n // The palette last-word's writer uses when a chart names no colours, so an\n // unstyled chart is the colour it is in Word, not ECharts' own.\n color: OFFICE_PALETTE,\n ...option,\n ...(legend === undefined ? {} : { legend }),\n ...(series === undefined ? {} : { series }),\n // nameMoveOverlap (ECharts 6) measures the gap from the axis LABELS, so a\n // long category label never ends up under the title; outerBoundsContain\n // 'all' makes the plot area leave room for labels and titles alike.\n ...(xAxis ? { xAxis: named(xAxis, { nameGap: 10, nameMoveOverlap: true }) } : {}),\n ...(yAxis ? { yAxis: named(yAxis, { nameGap: 10, nameRotate: 90, nameMoveOverlap: true }) } : {}),\n ...(hasAxes\n ? {\n grid: option.grid ?? {\n top: option.title ? 36 : 16,\n right: 16,\n bottom: 8 + (legendShown ? 28 : 0),\n left: 8,\n outerBoundsMode: \"same\",\n outerBoundsContain: \"all\",\n },\n }\n : {}),\n };\n}\n\n/** last-word's default chart palette (Office's): 4472C4, ED7D31, A5A5A5, … */\nconst OFFICE_PALETTE = [\"#4472C4\", \"#ED7D31\", \"#A5A5A5\", \"#FFC000\", \"#5B9BD5\", \"#70AD47\", \"#264478\", \"#9E480E\"];\n\n/** Whether the block has anything to plot. ECharts draws an empty box for an option with no series. */\nexport function isPlottable(block: ChartBlockData): boolean {\n const option = block?.option;\n if (!option || typeof option !== \"object\") return false;\n const series = (option as { series?: unknown }).series;\n return Array.isArray(series) ? series.length > 0 : series !== undefined && series !== null;\n}\n\n/**\n * A chart block, sized as the writer sizes it: `widthPx` / `heightPx` when given,\n * a `width` percentage of the column, or the full column at 0.6 of its width tall.\n */\nexport function ChartBlock({ block }: { block: ChartBlockData }) {\n const widthPx = num(block.widthPx);\n const heightPx = num(block.heightPx);\n const percent = num(block.width);\n\n const style: CSSProperties = {\n width: widthPx !== undefined ? `${widthPx}px` : percent !== undefined ? `${percent}%` : \"100%\",\n maxWidth: \"100%\",\n margin: `0 0 ${DEFAULTS.spaceAfter}pt`,\n };\n if (heightPx !== undefined) style.height = `${heightPx}px`;\n else style.aspectRatio = \"5 / 3\";\n\n return (\n <div data-fancy-docs-block=\"chart\" role=\"img\" aria-label={typeof block.alt === \"string\" ? block.alt : undefined} style={style}>\n <Suspense fallback={null}>\n <ChartInner option={pageChartOption(block.option)} />\n </Suspense>\n </div>\n );\n}\n","import { Fragment, type CSSProperties, type ReactNode } from \"react\";\nimport { FauxClient, sanitizeHref, type FauxClientProps } from \"@particle-academy/react-fancy\";\nimport type { Band, Block, Doc, ListItem, Run, TableBorders, TableCell } from \"./types\";\nimport { borderCss, boxBorders, DEFAULTS, fontStack, hex, num, padding, PAGE_SIZES, paragraphCss, runCss } from \"./style\";\nimport { ChartBlock, isPlottable } from \"./ChartBlock\";\n\nexport interface DocViewerProps {\n /** A last-word document, as its readers return it. */\n doc: Doc;\n /**\n * Show the document in react-fancy's `FauxClient` frame: zoom and full screen,\n * revealed on hover, like every file viewer. Default `true`.\n */\n frame?: boolean;\n /** Passed to the frame: `variant`, a controlled `zoom`, `onFullscreenChange`, … */\n frameProps?: Partial<FauxClientProps>;\n className?: string;\n}\n\n/**\n * A last-word document rendered the way Word renders it: page size, margins and\n * running header / footer per page; runs, paragraphs, lists, tables (fills,\n * borders, spans, alignment), code, quotes and images.\n *\n * Measurements stay in points, the model's own unit, so a 0.5pt rule is a 0.5pt\n * rule and the page is the page's size; the frame scales the whole sheet to fit\n * and zooms it.\n *\n * Everything shown came out of a file, so links go through react-fancy's\n * `sanitizeHref`, images are `data:` rasters only (a remote URL in a document\n * is a tracking pixel waiting to fire), and colours must be `#RRGGBB`.\n */\nexport function DocViewer({ doc, frame = true, frameProps, className }: DocViewerProps) {\n const pages = splitPages(Array.isArray(doc?.blocks) ? doc.blocks : []);\n const total = pages.length;\n\n const sheets = (\n <div\n data-fancy-docs-viewer=\"\"\n className={className}\n style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 16, padding: 16, background: \"#E5E7EB\" }}\n >\n {pages.map((blocks, i) => (\n <PageSheet key={i} doc={doc} blocks={blocks} number={i + 1} total={total} />\n ))}\n </div>\n );\n\n if (!frame) return sheets;\n\n // The frame lays the sheets out at their real width and scales them to fit,\n // as a word processor opens at \"fit page width\"; zoom works on top of that.\n return (\n <FauxClient\n variant=\"device\"\n controls\n fill\n width={logicalWidth(doc)}\n scale=\"fit\"\n bodyClassName=\"overflow-auto\"\n {...frameProps}\n >\n {sheets}\n </FauxClient>\n );\n}\n\n/** The sheets' width in CSS pixels, gutter included: the frame's logical width. */\nfunction logicalWidth(doc: Doc): number {\n const page = doc?.page ?? {};\n const [w, h] = PAGE_SIZES[page.size ?? \"letter\"] ?? PAGE_SIZES.letter;\n const width = page.orientation === \"landscape\" ? h : w;\n return Math.ceil((width * 4) / 3) + 32;\n}\n\n/** Page breaks split the flow into sheets; an empty document is one blank sheet. */\nfunction splitPages(blocks: Block[]): Block[][] {\n const pages: Block[][] = [[]];\n for (const block of blocks) {\n if (block?.type === \"pageBreak\") pages.push([]);\n else pages[pages.length - 1].push(block);\n }\n return pages;\n}\n\nfunction PageSheet({ doc, blocks, number, total }: { doc: Doc; blocks: Block[]; number: number; total: number }) {\n const page = doc.page ?? {};\n const [w, h] = PAGE_SIZES[page.size ?? \"letter\"] ?? PAGE_SIZES.letter;\n const [width, height] = page.orientation === \"landscape\" ? [h, w] : [w, h];\n const m = page.margins ?? {};\n const margin = (side: \"top\" | \"right\" | \"bottom\" | \"left\") => num(m[side]) ?? DEFAULTS.margin;\n\n const style: CSSProperties = {\n position: \"relative\",\n width: `${width}pt`,\n minHeight: `${height}pt`,\n background: \"#FFFFFF\",\n color: \"#000000\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.15)\",\n fontFamily: fontStack(doc.defaultFont ?? DEFAULTS.font),\n fontSize: `${num(doc.defaultSize) ?? DEFAULTS.size}pt`,\n flexShrink: 0,\n };\n\n return (\n <section data-fancy-docs-page={number} style={style}>\n {page.header && <BandLine band={page.header} kind=\"header\" number={number} total={total} left={margin(\"left\")} right={margin(\"right\")} />}\n <div\n data-fancy-docs-body=\"\"\n style={{ paddingTop: `${margin(\"top\")}pt`, paddingRight: `${margin(\"right\")}pt`, paddingBottom: `${margin(\"bottom\")}pt`, paddingLeft: `${margin(\"left\")}pt` }}\n >\n {blocks.map((block, i) => (\n <BlockView key={i} block={block} />\n ))}\n </div>\n {page.footer && <BandLine band={page.footer} kind=\"footer\" number={number} total={total} left={margin(\"left\")} right={margin(\"right\")} />}\n </section>\n );\n}\n\n/** A running header or footer: left / center / right, with `{page}` and `{pages}` filled in. */\nfunction BandLine({ band, kind, number, total, left, right }: { band: Band; kind: \"header\" | \"footer\"; number: number; total: number; left: number; right: number }) {\n const fill = (s: unknown) => (typeof s === \"string\" ? s.split(\"{page}\").join(String(number)).split(\"{pages}\").join(String(total)) : \"\");\n const style: CSSProperties = {\n position: \"absolute\",\n left: `${left}pt`,\n right: `${right}pt`,\n [kind === \"header\" ? \"top\" : \"bottom\"]: `${DEFAULTS.bandDistance}pt`,\n display: \"grid\",\n gridTemplateColumns: \"1fr auto 1fr\",\n fontSize: `${num(band.size) ?? DEFAULTS.bandSize}pt`,\n color: hex(band.color) ?? \"#595959\",\n };\n return (\n <div data-fancy-docs-band={kind} style={style}>\n <span style={{ textAlign: \"left\" }}>{fill(band.left)}</span>\n <span style={{ textAlign: \"center\" }}>{fill(band.center)}</span>\n <span style={{ textAlign: \"right\" }}>{fill(band.right)}</span>\n </div>\n );\n}\n\nfunction Runs({ runs }: { runs: Run[] | undefined }) {\n return (\n <>\n {(Array.isArray(runs) ? runs : []).map((run, i) => (\n <RunView key={i} run={run} />\n ))}\n </>\n );\n}\n\nfunction RunView({ run }: { run: Run }) {\n const text = typeof run?.text === \"string\" ? run.text : \"\";\n const style = runCss(run);\n const href = typeof run.link === \"string\" ? sanitizeHref(run.link) : undefined;\n\n if (run.code) {\n style.fontFamily = style.fontFamily ?? fontStack(DEFAULTS.codeFont, \"monospace\");\n style.backgroundColor = style.backgroundColor ?? DEFAULTS.codeFill;\n }\n if (href) {\n style.color = style.color ?? DEFAULTS.linkColor;\n style.textDecorationLine = style.textDecorationLine ?? \"underline\";\n }\n\n // Line breaks inside a run are real breaks, as Word shows them.\n const parts = text.split(\"\\n\");\n const content = parts.map((part, i) => (\n <Fragment key={i}>\n {i > 0 && <br />}\n {part}\n </Fragment>\n ));\n const span = run.code ? (\n <code data-fancy-docs-run=\"\" style={style}>{content}</code>\n ) : (\n <span data-fancy-docs-run=\"\" style={style}>{content}</span>\n );\n\n return href ? (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer nofollow\">\n {span}\n </a>\n ) : (\n span\n );\n}\n\nfunction BlockView({ block }: { block: Block }): ReactNode {\n switch (block?.type) {\n case \"heading\": {\n const level = Math.min(6, Math.max(1, Math.round(num(block.level) ?? 1)));\n const Tag = `h${level}` as \"h1\";\n const style: CSSProperties = {\n ...paragraphCss(block, { before: DEFAULTS.headingSpaceBefore, after: DEFAULTS.headingSpaceAfter }),\n fontSize: `${DEFAULTS.headingSizes[level - 1]}pt`,\n fontWeight: 700,\n };\n return (\n <Tag data-fancy-docs-block=\"heading\" style={style}>\n <Runs runs={block.runs} />\n </Tag>\n );\n }\n case \"paragraph\":\n return (\n <p data-fancy-docs-block=\"paragraph\" style={paragraphCss(block)}>\n <Runs runs={block.runs} />\n </p>\n );\n case \"list\":\n return <ListView items={block.items} ordered={!!block.ordered} />;\n case \"table\":\n return <TableView block={block} />;\n case \"code\":\n return (\n <pre\n data-fancy-docs-block=\"code\"\n style={{\n margin: `0 0 ${DEFAULTS.spaceAfter}pt`,\n padding: \"4pt 6pt\",\n background: DEFAULTS.codeFill,\n fontFamily: fontStack(DEFAULTS.codeFont, \"monospace\"),\n fontSize: `${DEFAULTS.codeSize}pt`,\n lineHeight: 1,\n whiteSpace: \"pre-wrap\",\n }}\n >\n <code>{typeof block.text === \"string\" ? block.text : \"\"}</code>\n </pre>\n );\n case \"quote\":\n return (\n <blockquote\n data-fancy-docs-block=\"quote\"\n style={{ margin: `0 0 0 ${DEFAULTS.quoteIndent}pt`, fontStyle: \"italic\", color: DEFAULTS.quoteColor }}\n >\n {(Array.isArray(block.blocks) ? block.blocks : []).map((b, i) => (\n <BlockView key={i} block={b} />\n ))}\n </blockquote>\n );\n case \"image\": {\n // Rasters embedded in the file only: a remote URL would fetch as soon as\n // the document opened -- a tracking pixel in a file someone sent you.\n const src = typeof block.src === \"string\" && /^data:image\\/(png|jpeg|gif|webp);base64,[A-Za-z0-9+/=]+$/.test(block.src) ? block.src : null;\n if (!src) return null;\n return (\n <img\n data-fancy-docs-block=\"image\"\n src={src}\n alt={typeof block.alt === \"string\" ? block.alt : \"\"}\n style={{ display: \"block\", maxWidth: \"100%\", width: num(block.widthPx), height: num(block.heightPx) ? undefined : \"auto\", margin: `0 0 ${DEFAULTS.spaceAfter}pt` }}\n />\n );\n }\n case \"chart\":\n // An option with no series draws an empty box; skip it rather than show one.\n return isPlottable(block) ? <ChartBlock block={block} /> : null;\n case \"hr\":\n return <hr data-fancy-docs-block=\"hr\" style={{ border: 0, borderTop: \"0.5pt solid #000000\", margin: `0 0 ${DEFAULTS.spaceAfter}pt` }} />;\n default:\n return null;\n }\n}\n\nfunction ListView({ items, ordered }: { items: ListItem[] | undefined; ordered: boolean }) {\n const Tag = ordered ? \"ol\" : \"ul\";\n return (\n <Tag data-fancy-docs-block=\"list\" style={{ margin: `0 0 ${DEFAULTS.spaceAfter}pt`, paddingLeft: \"18pt\", listStyleType: ordered ? \"decimal\" : \"disc\" }}>\n {(Array.isArray(items) ? items : []).map((item, i) => (\n <li key={i} style={{ ...paragraphCss(item, { after: 0 }) }}>\n <Runs runs={item.runs} />\n {Array.isArray(item.children) && item.children.length > 0 && <ListView items={item.children} ordered={ordered} />}\n </li>\n ))}\n </Tag>\n );\n}\n\ntype TableBlock = Extract<Block, { type: \"table\" }>;\n\nfunction TableView({ block }: { block: TableBlock }) {\n const rows = Array.isArray(block.rows) ? block.rows : [];\n const widths = Array.isArray(block.widths) ? block.widths.filter((w) => num(w) !== undefined && w > 0) : [];\n const sum = widths.reduce((a, b) => a + b, 0);\n const width = num(block.width);\n const borders: TableBorders = block.borders ?? {};\n\n const style: CSSProperties = {\n borderCollapse: \"collapse\",\n width: width !== undefined ? `${width}%` : \"100%\",\n tableLayout: widths.length > 0 ? \"fixed\" : \"auto\",\n marginBottom: `${DEFAULTS.spaceAfter}pt`,\n ...(block.align === \"center\" ? { marginLeft: \"auto\", marginRight: \"auto\" } : block.align === \"right\" ? { marginLeft: \"auto\" } : {}),\n };\n\n // Every edge defaults to the writer's 0.5pt single line; `{ style: \"none\" }` removes one.\n const edge = (b: TableBorders[keyof TableBorders]) => borderCss(b) ?? `${DEFAULTS.borderWidth}pt solid #000000`;\n\n return (\n <table data-fancy-docs-block=\"table\" style={style}>\n {widths.length > 0 && (\n <colgroup>\n {widths.map((w, i) => (\n <col key={i} style={{ width: `${Math.round((w / sum) * 1000) / 10}%` }} />\n ))}\n </colgroup>\n )}\n <tbody>\n {rows.map((row, r) => (\n <tr key={r}>\n {(Array.isArray(row.cells) ? row.cells : []).map((cell, c, cells) => {\n const header = !!row.header;\n const Tag = header ? \"th\" : \"td\";\n const first = c === 0;\n const last = c === cells.length - 1;\n const cellStyle: CSSProperties = {\n // Outer edges from the table's box; inner ones from insideH / insideV.\n borderTop: r === 0 ? edge(borders.top) : edge(borders.insideH),\n borderBottom: r === rows.length - 1 ? edge(borders.bottom) : edge(borders.insideH),\n borderLeft: first ? edge(borders.left) : edge(borders.insideV),\n borderRight: last ? edge(borders.right) : edge(borders.insideV),\n ...padding(cell.padding, { ...DEFAULTS.cellPadding, ...(block.cellPadding ?? {}) }),\n ...boxBorders(cell.borders),\n verticalAlign: cell.valign === \"center\" ? \"middle\" : cell.valign ?? \"top\",\n textAlign: \"left\",\n fontWeight: header ? 700 : undefined,\n backgroundColor: hex(cell.shading) ?? (header ? DEFAULTS.headerFill : undefined),\n };\n return (\n <Tag\n key={c}\n style={cellStyle}\n colSpan={num(cell.colSpan) && cell.colSpan! > 1 ? cell.colSpan : undefined}\n rowSpan={num(cell.rowSpan) && cell.rowSpan! > 1 ? cell.rowSpan : undefined}\n >\n <CellBlocks cell={cell} />\n </Tag>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n\n/** A cell's blocks, with the last paragraph's trailing space dropped as Word does inside a cell. */\nfunction CellBlocks({ cell }: { cell: TableCell }) {\n const blocks = Array.isArray(cell.blocks) ? cell.blocks : [];\n return (\n <>\n {blocks.map((b, i) =>\n b?.type === \"paragraph\" ? (\n <p key={i} data-fancy-docs-block=\"paragraph\" style={{ ...paragraphCss(b), ...(i === blocks.length - 1 && num(b.spaceAfter) === undefined ? { marginBottom: 0 } : {}) }}>\n <Runs runs={b.runs} />\n </p>\n ) : (\n <BlockView key={i} block={b} />\n ),\n )}\n </>\n );\n}\n","import { Callout, type FauxClientProps } from \"@particle-academy/react-fancy\";\nimport { DocViewer } from \"./DocViewer\";\nimport type { Doc } from \"./types\";\n\nexport interface DocFileViewProps {\n /** A document as last-word's reader returns it. */\n document: unknown;\n filename?: string;\n /** Passed to the FauxClient frame. */\n frameProps?: Partial<FauxClientProps>;\n}\n\n/**\n * A .docx in fancy-code's `FileViewer`: register it once at app start.\n *\n * ```ts\n * registerOfficeViewer(\"docx\", DocFileView, { read: (b) => new DocxReader().read(b) });\n * ```\n *\n * The props match fancy-code's `OfficeViewerProps` without importing them, so\n * this package does not depend on fancy-code.\n */\nexport function DocFileView({ document, filename, frameProps }: DocFileViewProps) {\n const doc = document as Partial<Doc> | null;\n\n // A reader that returned something else would otherwise draw a blank page.\n if (!doc || typeof doc !== \"object\" || !Array.isArray(doc.blocks)) {\n return <Callout color=\"red\">{filename ?? \"This file\"} did not read as a document.</Callout>;\n }\n\n return <DocViewer doc={doc as Doc} frameProps={frameProps} />;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@particle-academy/fancy-docs",
3
- "version": "0.0.0",
3
+ "version": "0.2.0",
4
4
  "description": "Render a last-word document (docx) the way Word does: run, paragraph, table and cell styling, header and footer bands, in react-fancy's FauxClient frame",
5
5
  "repository": {
6
6
  "type": "git",
@@ -40,9 +40,11 @@
40
40
  "peerDependencies": {
41
41
  "@particle-academy/react-fancy": ">=5.49.1 <6.0.0",
42
42
  "react": "^19.0.0",
43
- "react-dom": "^19.0.0"
43
+ "react-dom": "^19.0.0",
44
+ "@particle-academy/fancy-echarts": ">=6.1.0 <7.0.0"
44
45
  },
45
46
  "devDependencies": {
47
+ "@particle-academy/fancy-echarts": "^6.1.0",
46
48
  "@particle-academy/react-fancy": "^5.49.1",
47
49
  "@types/react": "^19.2.18",
48
50
  "@types/react-dom": "^19.2.4",
@@ -67,5 +69,10 @@
67
69
  "sideEffects": false,
68
70
  "engines": {
69
71
  "node": ">=22"
72
+ },
73
+ "peerDependenciesMeta": {
74
+ "@particle-academy/fancy-echarts": {
75
+ "optional": true
76
+ }
70
77
  }
71
78
  }