odf.js 1.4.0 → 1.6.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/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { XMLBuilder, XMLParser } from "fast-xml-parser";
3
3
  import { unzipSync, zipSync } from "fflate";
4
- import { AlignmentSchema, AlignmentSchema as AlignmentSchema$1, ColorSchema, SLIDE_SIZE_WIDESCREEN, colorToRgbHex, rgbHexToColor } from "document-content-model";
4
+ import { AlignmentSchema, AlignmentSchema as AlignmentSchema$1, ColorSchema, PAGE_SIZE_A4, SLIDE_SIZE_WIDESCREEN, colorToRgbHex, rgbHexToColor } from "document-content-model";
5
5
  //#region src/model/node.ts
6
6
  const AttributeSchema = z.object({
7
7
  name: z.string(),
@@ -1494,6 +1494,28 @@ function parseBox(element) {
1494
1494
  heightPt
1495
1495
  };
1496
1496
  }
1497
+ function parseLinePoints(element) {
1498
+ const x1Value = attrValue(element, "svg:x1");
1499
+ const y1Value = attrValue(element, "svg:y1");
1500
+ const x2Value = attrValue(element, "svg:x2");
1501
+ const y2Value = attrValue(element, "svg:y2");
1502
+ if (x1Value === void 0 || y1Value === void 0 || x2Value === void 0 || y2Value === void 0) return;
1503
+ const x1Pt = parseOdfLength(x1Value);
1504
+ const y1Pt = parseOdfLength(y1Value);
1505
+ const x2Pt = parseOdfLength(x2Value);
1506
+ const y2Pt = parseOdfLength(y2Value);
1507
+ if (x1Pt === void 0 || y1Pt === void 0 || x2Pt === void 0 || y2Pt === void 0) return;
1508
+ return {
1509
+ from: {
1510
+ xPt: x1Pt,
1511
+ yPt: y1Pt
1512
+ },
1513
+ to: {
1514
+ xPt: x2Pt,
1515
+ yPt: y2Pt
1516
+ }
1517
+ };
1518
+ }
1497
1519
  //#endregion
1498
1520
  //#region src/typed/shared/cascade.ts
1499
1521
  const STYLE_PARTS = ["content.xml", "styles.xml"];
@@ -1858,6 +1880,291 @@ function composeOdfGroupTransform(groupFunctions, child) {
1858
1880
  };
1859
1881
  }
1860
1882
  //#endregion
1883
+ //#region src/typed/shared/masterpage.ts
1884
+ const STYLES_PART$1 = "styles.xml";
1885
+ const AUTOMATIC_STYLE_PARTS$1 = ["content.xml", STYLES_PART$1];
1886
+ function findMasterPageElement(pkg, masterPageName) {
1887
+ if (masterPageName === void 0) return;
1888
+ const stylesPart = pkg.parts[STYLES_PART$1];
1889
+ if (stylesPart?.kind !== "xml") return;
1890
+ const root = rootElement(stylesPart.nodes);
1891
+ const masterStyles = root === void 0 ? void 0 : findChildElement(root.children, "office:master-styles");
1892
+ if (masterStyles === void 0) return;
1893
+ return childrenWithTag(masterStyles, "style:master-page").find((element) => attrValue(element, "style:name") === masterPageName);
1894
+ }
1895
+ function findPageLayoutElement$1(pkg, pageLayoutName) {
1896
+ if (pageLayoutName === void 0) return;
1897
+ for (const partPath of AUTOMATIC_STYLE_PARTS$1) {
1898
+ const part = pkg.parts[partPath];
1899
+ if (part?.kind !== "xml") continue;
1900
+ const root = rootElement(part.nodes);
1901
+ const automaticStyles = root === void 0 ? void 0 : findChildElement(root.children, "office:automatic-styles");
1902
+ if (automaticStyles === void 0) continue;
1903
+ const found = childrenWithTag(automaticStyles, "style:page-layout").find((element) => attrValue(element, "style:name") === pageLayoutName);
1904
+ if (found !== void 0) return found;
1905
+ }
1906
+ }
1907
+ function resolveDrawPageSize(page, pkg) {
1908
+ const masterPage = findMasterPageElement(pkg, attrValue(page, "draw:master-page-name"));
1909
+ const pageLayout = findPageLayoutElement$1(pkg, masterPage === void 0 ? void 0 : attrValue(masterPage, "style:page-layout-name"));
1910
+ const properties = pageLayout === void 0 ? void 0 : childrenWithTag(pageLayout, "style:page-layout-properties")[0];
1911
+ return properties === void 0 ? void 0 : parsePageSize(properties);
1912
+ }
1913
+ //#endregion
1914
+ //#region src/typed/shared/path.ts
1915
+ const VIEW_BOX_PATTERN = /^(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)$/;
1916
+ function parseOdfViewBox(value) {
1917
+ const match = VIEW_BOX_PATTERN.exec(value.trim());
1918
+ if (match === null) return;
1919
+ const minX = Number(match[1]);
1920
+ const minY = Number(match[2]);
1921
+ const width = Number(match[3]);
1922
+ const height = Number(match[4]);
1923
+ if (width <= 0 || height <= 0) return;
1924
+ return {
1925
+ minX,
1926
+ minY,
1927
+ width,
1928
+ height
1929
+ };
1930
+ }
1931
+ function parseOdfPointsList(value) {
1932
+ const points = [];
1933
+ for (const pair of value.trim().split(/\s+/)) {
1934
+ if (pair.length === 0) continue;
1935
+ const [xRaw, yRaw] = pair.split(",");
1936
+ if (xRaw === void 0 || yRaw === void 0) continue;
1937
+ const x = Number(xRaw);
1938
+ const y = Number(yRaw);
1939
+ if (!Number.isFinite(x) || !Number.isFinite(y)) continue;
1940
+ points.push({
1941
+ x,
1942
+ y
1943
+ });
1944
+ }
1945
+ return points;
1946
+ }
1947
+ function rawSubpathFromPoints(points, closed) {
1948
+ const start = points[0];
1949
+ if (start === void 0) return;
1950
+ return {
1951
+ start,
1952
+ segments: points.slice(1).map((to) => ({
1953
+ kind: "line",
1954
+ to
1955
+ })),
1956
+ closed
1957
+ };
1958
+ }
1959
+ const COMMAND_LETTERS = /* @__PURE__ */ new Set([
1960
+ "M",
1961
+ "m",
1962
+ "L",
1963
+ "l",
1964
+ "H",
1965
+ "h",
1966
+ "V",
1967
+ "v",
1968
+ "C",
1969
+ "c",
1970
+ "S",
1971
+ "s",
1972
+ "Q",
1973
+ "q",
1974
+ "T",
1975
+ "t",
1976
+ "A",
1977
+ "a",
1978
+ "Z",
1979
+ "z"
1980
+ ]);
1981
+ function isCommandLetter(token) {
1982
+ return COMMAND_LETTERS.has(token);
1983
+ }
1984
+ const PATH_TOKEN_PATTERN = /[MmLlHhVvCcSsQqTtAaZz]|-?(?:\d+\.\d+|\.\d+|\d+)(?:[eE][-+]?\d+)?/g;
1985
+ function tokenizePathData(d) {
1986
+ return d.match(PATH_TOKEN_PATTERN) ?? [];
1987
+ }
1988
+ function parseOdfPathData(d) {
1989
+ const tokens = tokenizePathData(d);
1990
+ const subpaths = [];
1991
+ let current = {
1992
+ x: 0,
1993
+ y: 0
1994
+ };
1995
+ let subpathStart = {
1996
+ x: 0,
1997
+ y: 0
1998
+ };
1999
+ let activeSubpath;
2000
+ let command;
2001
+ let firstMInCommand = true;
2002
+ function startSubpath(point) {
2003
+ activeSubpath = {
2004
+ start: point,
2005
+ segments: [],
2006
+ closed: false
2007
+ };
2008
+ subpaths.push(activeSubpath);
2009
+ subpathStart = point;
2010
+ current = point;
2011
+ }
2012
+ function pushSegment(segment, to) {
2013
+ if (activeSubpath !== void 0) activeSubpath.segments.push(segment);
2014
+ current = to;
2015
+ }
2016
+ let i = 0;
2017
+ while (i < tokens.length) {
2018
+ const token = tokens[i];
2019
+ if (token === void 0) break;
2020
+ if (isCommandLetter(token)) {
2021
+ if (token === "Z" || token === "z") {
2022
+ if (activeSubpath !== void 0) {
2023
+ activeSubpath.closed = true;
2024
+ current = subpathStart;
2025
+ }
2026
+ command = void 0;
2027
+ i += 1;
2028
+ continue;
2029
+ }
2030
+ command = token;
2031
+ firstMInCommand = true;
2032
+ i += 1;
2033
+ continue;
2034
+ }
2035
+ if (command === void 0) {
2036
+ i += 1;
2037
+ continue;
2038
+ }
2039
+ const upper = command.toUpperCase();
2040
+ const relative = command !== upper;
2041
+ if (upper === "M" || upper === "L") {
2042
+ const xTok = tokens[i];
2043
+ const yTok = tokens[i + 1];
2044
+ i += 2;
2045
+ if (xTok === void 0 || yTok === void 0) break;
2046
+ const x = Number(xTok);
2047
+ const y = Number(yTok);
2048
+ if (!Number.isFinite(x) || !Number.isFinite(y)) continue;
2049
+ const point = relative ? {
2050
+ x: current.x + x,
2051
+ y: current.y + y
2052
+ } : {
2053
+ x,
2054
+ y
2055
+ };
2056
+ if (upper === "M" && firstMInCommand) {
2057
+ startSubpath(point);
2058
+ firstMInCommand = false;
2059
+ } else pushSegment({
2060
+ kind: "line",
2061
+ to: point
2062
+ }, point);
2063
+ } else if (upper === "H") {
2064
+ const xTok = tokens[i];
2065
+ i += 1;
2066
+ if (xTok === void 0) break;
2067
+ const x = Number(xTok);
2068
+ if (!Number.isFinite(x)) continue;
2069
+ const point = relative ? {
2070
+ x: current.x + x,
2071
+ y: current.y
2072
+ } : {
2073
+ x,
2074
+ y: current.y
2075
+ };
2076
+ pushSegment({
2077
+ kind: "line",
2078
+ to: point
2079
+ }, point);
2080
+ } else if (upper === "V") {
2081
+ const yTok = tokens[i];
2082
+ i += 1;
2083
+ if (yTok === void 0) break;
2084
+ const y = Number(yTok);
2085
+ if (!Number.isFinite(y)) continue;
2086
+ const point = relative ? {
2087
+ x: current.x,
2088
+ y: current.y + y
2089
+ } : {
2090
+ x: current.x,
2091
+ y
2092
+ };
2093
+ pushSegment({
2094
+ kind: "line",
2095
+ to: point
2096
+ }, point);
2097
+ } else if (upper === "C") {
2098
+ const rawArgs = tokens.slice(i, i + 6);
2099
+ i += 6;
2100
+ if (rawArgs.length < 6) break;
2101
+ const x1 = Number(rawArgs[0]);
2102
+ const y1 = Number(rawArgs[1]);
2103
+ const x2 = Number(rawArgs[2]);
2104
+ const y2 = Number(rawArgs[3]);
2105
+ const x = Number(rawArgs[4]);
2106
+ const y = Number(rawArgs[5]);
2107
+ if (![
2108
+ x1,
2109
+ y1,
2110
+ x2,
2111
+ y2,
2112
+ x,
2113
+ y
2114
+ ].every(Number.isFinite)) continue;
2115
+ const control1 = relative ? {
2116
+ x: current.x + x1,
2117
+ y: current.y + y1
2118
+ } : {
2119
+ x: x1,
2120
+ y: y1
2121
+ };
2122
+ const control2 = relative ? {
2123
+ x: current.x + x2,
2124
+ y: current.y + y2
2125
+ } : {
2126
+ x: x2,
2127
+ y: y2
2128
+ };
2129
+ const to = relative ? {
2130
+ x: current.x + x,
2131
+ y: current.y + y
2132
+ } : {
2133
+ x,
2134
+ y
2135
+ };
2136
+ pushSegment({
2137
+ kind: "cubic",
2138
+ control1,
2139
+ control2,
2140
+ to
2141
+ }, to);
2142
+ } else i += 1;
2143
+ }
2144
+ return subpaths;
2145
+ }
2146
+ function scaleOdfRawPoint(point, viewBox, frame) {
2147
+ return {
2148
+ xPt: (point.x - viewBox.minX) * (frame.widthPt / viewBox.width),
2149
+ yPt: (point.y - viewBox.minY) * (frame.heightPt / viewBox.height)
2150
+ };
2151
+ }
2152
+ function buildOdfSubpaths(rawSubpaths, viewBox, frame) {
2153
+ return rawSubpaths.map((raw) => ({
2154
+ start: scaleOdfRawPoint(raw.start, viewBox, frame),
2155
+ closed: raw.closed,
2156
+ segments: raw.segments.map((segment) => segment.kind === "line" ? {
2157
+ kind: "line",
2158
+ to: scaleOdfRawPoint(segment.to, viewBox, frame)
2159
+ } : {
2160
+ kind: "cubic",
2161
+ control1: scaleOdfRawPoint(segment.control1, viewBox, frame),
2162
+ control2: scaleOdfRawPoint(segment.control2, viewBox, frame),
2163
+ to: scaleOdfRawPoint(segment.to, viewBox, frame)
2164
+ })
2165
+ }));
2166
+ }
2167
+ //#endregion
1861
2168
  //#region src/typed/draw/shapes.ts
1862
2169
  const ZERO_INSETS = {
1863
2170
  insetLeftPt: 0,
@@ -1939,37 +2246,224 @@ function walkDrawShapes(children, groupFunctions, pkg, out) {
1939
2246
  }
1940
2247
  }
1941
2248
  }
1942
- //#endregion
1943
- //#region src/typed/odp/read.ts
1944
- const CONTENT_PART = "content.xml";
1945
- const STYLES_PART = "styles.xml";
1946
- const AUTOMATIC_STYLE_PARTS = [CONTENT_PART, STYLES_PART];
1947
- function findMasterPageElement(pkg, masterPageName) {
1948
- if (masterPageName === void 0) return;
1949
- const stylesPart = pkg.parts[STYLES_PART];
1950
- if (stylesPart?.kind !== "xml") return;
1951
- const root = rootElement(stylesPart.nodes);
1952
- const masterStyles = root === void 0 ? void 0 : findChildElement(root.children, "office:master-styles");
1953
- if (masterStyles === void 0) return;
1954
- return childrenWithTag(masterStyles, "style:master-page").find((element) => attrValue(element, "style:name") === masterPageName);
2249
+ function readOdfFillAndStroke(element, pkg) {
2250
+ const { elements } = resolveStyleElementChain(attrValue(element, "draw:style-name"), "graphic", pkg);
2251
+ let fill;
2252
+ let stroke;
2253
+ for (const styleElement of elements) {
2254
+ const props = childrenWithTag(styleElement, "style:graphic-properties")[0];
2255
+ if (props === void 0) continue;
2256
+ if (attrValue(props, "draw:fill") === "none") fill = void 0;
2257
+ else {
2258
+ const fillColorValue = attrValue(props, "draw:fill-color");
2259
+ const parsedFill = fillColorValue === void 0 ? void 0 : parseOdfColor(fillColorValue);
2260
+ if (parsedFill !== void 0) fill = parsedFill;
2261
+ }
2262
+ if (attrValue(props, "draw:stroke") === "none") stroke = void 0;
2263
+ else {
2264
+ const strokeColorValue = attrValue(props, "svg:stroke-color");
2265
+ const strokeWidthValue = attrValue(props, "svg:stroke-width");
2266
+ const strokeColor = strokeColorValue === void 0 ? void 0 : parseOdfColor(strokeColorValue);
2267
+ const strokeWidthPt = strokeWidthValue === void 0 ? void 0 : parseOdfLength(strokeWidthValue);
2268
+ if (strokeColor !== void 0 && strokeWidthPt !== void 0 && strokeWidthPt > 0) stroke = {
2269
+ color: strokeColor,
2270
+ widthPt: strokeWidthPt
2271
+ };
2272
+ }
2273
+ }
2274
+ return {
2275
+ fill,
2276
+ stroke
2277
+ };
1955
2278
  }
1956
- function findPageLayoutElement(pkg, pageLayoutName) {
1957
- if (pageLayoutName === void 0) return;
1958
- for (const partPath of AUTOMATIC_STYLE_PARTS) {
1959
- const part = pkg.parts[partPath];
1960
- if (part?.kind !== "xml") continue;
1961
- const root = rootElement(part.nodes);
1962
- const automaticStyles = root === void 0 ? void 0 : findChildElement(root.children, "office:automatic-styles");
1963
- if (automaticStyles === void 0) continue;
1964
- const found = childrenWithTag(automaticStyles, "style:page-layout").find((element) => attrValue(element, "style:name") === pageLayoutName);
1965
- if (found !== void 0) return found;
2279
+ function resolveVectorFrame(element, groupFunctions) {
2280
+ const geometry = resolveOdfShapeGeometry(element);
2281
+ if (geometry === void 0) return;
2282
+ return composeOdfGroupTransform(groupFunctions, geometry).frame;
2283
+ }
2284
+ function readDrawRectVector(element, groupFunctions, pkg) {
2285
+ const frame = resolveVectorFrame(element, groupFunctions);
2286
+ if (frame === void 0) return;
2287
+ const { fill, stroke } = readOdfFillAndStroke(element, pkg);
2288
+ return {
2289
+ kind: "rect",
2290
+ frame,
2291
+ fill,
2292
+ stroke
2293
+ };
2294
+ }
2295
+ function readDrawEllipseVector(element, groupFunctions, pkg) {
2296
+ const frame = resolveVectorFrame(element, groupFunctions);
2297
+ if (frame === void 0) return;
2298
+ const { fill, stroke } = readOdfFillAndStroke(element, pkg);
2299
+ return {
2300
+ kind: "ellipse",
2301
+ frame,
2302
+ fill,
2303
+ stroke
2304
+ };
2305
+ }
2306
+ function readDrawLineVector(element, groupFunctions, pkg) {
2307
+ const raw = parseLinePoints(element);
2308
+ if (raw === void 0) return;
2309
+ const from = groupFunctions.length === 0 ? raw.from : applyOdfTransform(groupFunctions, raw.from);
2310
+ const to = groupFunctions.length === 0 ? raw.to : applyOdfTransform(groupFunctions, raw.to);
2311
+ const { stroke } = readOdfFillAndStroke(element, pkg);
2312
+ if (stroke === void 0) return;
2313
+ return {
2314
+ kind: "line",
2315
+ from,
2316
+ to,
2317
+ stroke
2318
+ };
2319
+ }
2320
+ function readDrawPathVector(element, groupFunctions, pkg) {
2321
+ const frame = resolveVectorFrame(element, groupFunctions);
2322
+ if (frame === void 0) return;
2323
+ const viewBoxValue = attrValue(element, "svg:viewBox");
2324
+ const viewBox = viewBoxValue === void 0 ? void 0 : parseOdfViewBox(viewBoxValue);
2325
+ if (viewBox === void 0) return;
2326
+ let rawSubpaths;
2327
+ if (element.tag === "draw:path") {
2328
+ const d = attrValue(element, "svg:d");
2329
+ rawSubpaths = d === void 0 ? [] : parseOdfPathData(d);
2330
+ } else {
2331
+ const pointsValue = attrValue(element, "draw:points");
2332
+ const subpath = rawSubpathFromPoints(pointsValue === void 0 ? [] : parseOdfPointsList(pointsValue), element.tag === "draw:polygon");
2333
+ rawSubpaths = subpath === void 0 ? [] : [subpath];
1966
2334
  }
2335
+ if (rawSubpaths.length === 0) return;
2336
+ const subpaths = buildOdfSubpaths(rawSubpaths, viewBox, frame);
2337
+ const { fill, stroke } = readOdfFillAndStroke(element, pkg);
2338
+ return {
2339
+ kind: "path",
2340
+ frame,
2341
+ subpaths,
2342
+ fill,
2343
+ stroke
2344
+ };
2345
+ }
2346
+ const RECOGNIZED_CUSTOM_SHAPE_PRESETS = /* @__PURE__ */ new Set([
2347
+ "rectangle",
2348
+ "round-rectangle",
2349
+ "ellipse"
2350
+ ]);
2351
+ function readCustomShapeVector(element, groupFunctions, pkg) {
2352
+ const geometryElement = childrenWithTag(element, "draw:enhanced-geometry")[0];
2353
+ const type = geometryElement === void 0 ? void 0 : attrValue(geometryElement, "draw:type");
2354
+ if (type === void 0 || !RECOGNIZED_CUSTOM_SHAPE_PRESETS.has(type)) return;
2355
+ const frame = resolveVectorFrame(element, groupFunctions);
2356
+ if (frame === void 0) return;
2357
+ const { fill, stroke } = readOdfFillAndStroke(element, pkg);
2358
+ return {
2359
+ kind: type === "ellipse" ? "ellipse" : "rect",
2360
+ frame,
2361
+ fill,
2362
+ stroke
2363
+ };
1967
2364
  }
2365
+ function readCustomShapeAsTextShape(element, groupFunctions, pkg) {
2366
+ const paragraphs = elementsWithTag(element.children, "text:p").map((p) => readOdfParagraph(p, pkg));
2367
+ if (!paragraphs.some((paragraph) => paragraph.runs.some((run) => run.text.length > 0))) return;
2368
+ const ownGeometry = resolveOdfShapeGeometry(element);
2369
+ if (ownGeometry === void 0) return;
2370
+ const geometry = composeOdfGroupTransform(groupFunctions, ownGeometry);
2371
+ return {
2372
+ name: attrValue(element, "draw:name"),
2373
+ frame: geometry.frame,
2374
+ rotationDeg: geometry.rotationDeg,
2375
+ ...readFrameInsets(element, pkg),
2376
+ blocks: paragraphs
2377
+ };
2378
+ }
2379
+ function nextDocumentIndex(state) {
2380
+ const value = state.next;
2381
+ state.next += 1;
2382
+ return value;
2383
+ }
2384
+ function paintOrderKey(element, state) {
2385
+ const documentIndex = nextDocumentIndex(state);
2386
+ const raw = attrValue(element, "draw:z-index");
2387
+ if (raw === void 0) return documentIndex;
2388
+ const parsed = Number.parseInt(raw, 10);
2389
+ return Number.isInteger(parsed) && parsed >= 0 ? parsed : documentIndex;
2390
+ }
2391
+ function byPaintOrder(items) {
2392
+ return items.slice().sort((a, b) => a.zIndex - b.zIndex).map((item) => item.value);
2393
+ }
2394
+ function walkDrawPageContent(children, groupFunctions, pkg, indexState, shapesOut, vectorsOut) {
2395
+ for (const node of children) {
2396
+ if (node.type !== "element") continue;
2397
+ if (node.tag === "draw:frame") {
2398
+ const zIndex = paintOrderKey(node, indexState);
2399
+ const shape = readDrawFrame(node, groupFunctions, pkg);
2400
+ if (shape !== void 0) shapesOut.push({
2401
+ value: shape,
2402
+ zIndex
2403
+ });
2404
+ } else if (node.tag === "draw:g") {
2405
+ const ownFunctions = readOwnTransformFunctions(node);
2406
+ const nested = ownFunctions.length === 0 ? groupFunctions : [...ownFunctions, ...groupFunctions];
2407
+ walkDrawPageContent(node.children, nested, pkg, indexState, shapesOut, vectorsOut);
2408
+ } else if (node.tag === "draw:rect") {
2409
+ const zIndex = paintOrderKey(node, indexState);
2410
+ const vector = readDrawRectVector(node, groupFunctions, pkg);
2411
+ if (vector !== void 0) vectorsOut.push({
2412
+ value: vector,
2413
+ zIndex
2414
+ });
2415
+ } else if (node.tag === "draw:ellipse" || node.tag === "draw:circle") {
2416
+ const zIndex = paintOrderKey(node, indexState);
2417
+ const vector = readDrawEllipseVector(node, groupFunctions, pkg);
2418
+ if (vector !== void 0) vectorsOut.push({
2419
+ value: vector,
2420
+ zIndex
2421
+ });
2422
+ } else if (node.tag === "draw:line") {
2423
+ const zIndex = paintOrderKey(node, indexState);
2424
+ const vector = readDrawLineVector(node, groupFunctions, pkg);
2425
+ if (vector !== void 0) vectorsOut.push({
2426
+ value: vector,
2427
+ zIndex
2428
+ });
2429
+ } else if (node.tag === "draw:path" || node.tag === "draw:polygon" || node.tag === "draw:polyline") {
2430
+ const zIndex = paintOrderKey(node, indexState);
2431
+ const vector = readDrawPathVector(node, groupFunctions, pkg);
2432
+ if (vector !== void 0) vectorsOut.push({
2433
+ value: vector,
2434
+ zIndex
2435
+ });
2436
+ } else if (node.tag === "draw:custom-shape") {
2437
+ const zIndex = paintOrderKey(node, indexState);
2438
+ const vector = readCustomShapeVector(node, groupFunctions, pkg);
2439
+ if (vector !== void 0) vectorsOut.push({
2440
+ value: vector,
2441
+ zIndex
2442
+ });
2443
+ else {
2444
+ const shape = readCustomShapeAsTextShape(node, groupFunctions, pkg);
2445
+ if (shape !== void 0) shapesOut.push({
2446
+ value: shape,
2447
+ zIndex
2448
+ });
2449
+ }
2450
+ }
2451
+ }
2452
+ }
2453
+ function readDrawPageContent(children, pkg) {
2454
+ const shapesOut = [];
2455
+ const vectorsOut = [];
2456
+ walkDrawPageContent(children, [], pkg, { next: 0 }, shapesOut, vectorsOut);
2457
+ return {
2458
+ shapes: byPaintOrder(shapesOut),
2459
+ vectors: byPaintOrder(vectorsOut)
2460
+ };
2461
+ }
2462
+ //#endregion
2463
+ //#region src/typed/odp/read.ts
2464
+ const CONTENT_PART$2 = "content.xml";
1968
2465
  function readSlideSize(page, pkg) {
1969
- const masterPage = findMasterPageElement(pkg, attrValue(page, "draw:master-page-name"));
1970
- const pageLayout = findPageLayoutElement(pkg, masterPage === void 0 ? void 0 : attrValue(masterPage, "style:page-layout-name"));
1971
- const properties = pageLayout === void 0 ? void 0 : childrenWithTag(pageLayout, "style:page-layout-properties")[0];
1972
- return (properties === void 0 ? void 0 : parsePageSize(properties)) ?? SLIDE_SIZE_WIDESCREEN;
2466
+ return resolveDrawPageSize(page, pkg) ?? SLIDE_SIZE_WIDESCREEN;
1973
2467
  }
1974
2468
  function readSlideNotes(page) {
1975
2469
  const notes = childrenWithTag(page, "presentation:notes")[0];
@@ -1986,7 +2480,7 @@ function readSlide(page, pkg) {
1986
2480
  };
1987
2481
  }
1988
2482
  function readOdp(pkg) {
1989
- const contentPart = pkg.parts[CONTENT_PART];
2483
+ const contentPart = pkg.parts[CONTENT_PART$2];
1990
2484
  const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
1991
2485
  const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
1992
2486
  const presentation = body === void 0 ? void 0 : findChildElement(body.children, "office:presentation");
@@ -1997,4 +2491,132 @@ function readOdp(pkg) {
1997
2491
  };
1998
2492
  }
1999
2493
  //#endregion
2000
- export { AlignmentSchema, AttributeSchema, BinaryPartSchema, MANIFEST_PART, META_PART, MIMETYPE_PART, ManifestEntrySchema, ManifestProblemSchema, ManifestSchema, ODF_MEDIA_TYPES, ODF_NAMESPACES, PackageSchema, PartSchema, STYLE_FAMILIES, StylePropertiesSchema, StyleRegistry, TableCursor, XmlCdataSchema, XmlCommentSchema, XmlDeclarationSchema, XmlElementSchema, XmlNodeSchema, XmlPartSchema, XmlPiSchema, XmlTextSchema, applyOdfTransform, attrValue, base64ToBytes, buildManifest, buildStylePropertyElements, buildXml, bytesToBase64, canonicalPropertiesString, cellReference, childrenWithTag, columnIndexToLetters, composeOdfGroupTransform, decodeOdfText, decodePackage, decodeXmlText, el, elementsWithTag, encodePackage, encodeXmlText, ensureSpan, findChildElement, findStyleElement, formatOdfColor, formatOdfLength, formatPercentageMultiplier, formatPt, getOdfSpaceCount, isStyleFamily, isXmlNode, measureOdfNodeLength, mediaTypeForExtension, netRotationDeg, packageCodec, paragraphPropertiesToAttributes, parseBox, parseLength, parseMargins, parseOdfColor, parseOdfLength, parseOdfTransform, parsePackage, parsePageSize, parseParagraphProperties, parseStyleElementProperties, parseTextProperties, parseXml, readDrawFrame, readManifest, readMimetype, readOdfMetadata, readOdfParagraph, readOdfTable, readOdp, resolveOdfShapeGeometry, resolveStyle, resolveStyleElementChain, rootElement, serializePackage, setDocumentMediaType, sniffImageFormat, sumOdfNodeLength, syncManifest, textPropertiesToAttributes, txt, unzipPackage, validateManifest, walkDrawShapes, writeManifest, writeMimetype, xmlCodec, xmlnsAttributes, zipPackage };
2494
+ //#region src/typed/odt/read.ts
2495
+ const CONTENT_PART$1 = "content.xml";
2496
+ const STYLES_PART = "styles.xml";
2497
+ const AUTOMATIC_STYLE_PARTS = [CONTENT_PART$1, STYLES_PART];
2498
+ function readOutlineLevel(headingElement) {
2499
+ const raw = attrValue(headingElement, "text:outline-level");
2500
+ if (raw === void 0) return 1;
2501
+ const parsed = Number.parseInt(raw, 10);
2502
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : 1;
2503
+ }
2504
+ function readParagraphOrHeading(element, pkg, list) {
2505
+ const paragraph = readOdfParagraph(element, pkg);
2506
+ if (element.tag === "text:h") paragraph.styleId = `Heading${readOutlineLevel(element)}`;
2507
+ if (list !== void 0) paragraph.list = list;
2508
+ return paragraph;
2509
+ }
2510
+ function readListItems(listElement, context, pkg, blocks) {
2511
+ for (const item of listElement.children) {
2512
+ if (item.type !== "element" || item.tag !== "text:list-item") continue;
2513
+ for (const itemChild of item.children) {
2514
+ if (itemChild.type !== "element") continue;
2515
+ if (itemChild.tag === "text:p" || itemChild.tag === "text:h") blocks.push(readParagraphOrHeading(itemChild, pkg, context));
2516
+ else if (itemChild.tag === "text:list") readListItems(itemChild, {
2517
+ numId: context.numId,
2518
+ level: context.level + 1
2519
+ }, pkg, blocks);
2520
+ }
2521
+ }
2522
+ }
2523
+ function readBlocks(nodes, pkg, listIdState) {
2524
+ const blocks = [];
2525
+ for (const node of nodes) {
2526
+ if (node.type !== "element") continue;
2527
+ if (node.tag === "text:p" || node.tag === "text:h") blocks.push(readParagraphOrHeading(node, pkg, void 0));
2528
+ else if (node.tag === "text:list") {
2529
+ const numId = `list${listIdState.next}`;
2530
+ listIdState.next += 1;
2531
+ readListItems(node, {
2532
+ numId,
2533
+ level: 0
2534
+ }, pkg, blocks);
2535
+ } else if (node.tag === "table:table") blocks.push(readOdfTable(node, pkg));
2536
+ else if (node.tag === "text:section") blocks.push(...readBlocks(node.children, pkg, listIdState));
2537
+ }
2538
+ return blocks;
2539
+ }
2540
+ function parseKnownOdfLength(value) {
2541
+ const parsed = parseOdfLength(value);
2542
+ if (parsed === void 0) throw new Error(`readOdt: internal error -- "${value}" is not a valid ODF length literal`);
2543
+ return parsed;
2544
+ }
2545
+ const DEFAULT_PAGE_SIZE$1 = PAGE_SIZE_A4;
2546
+ const DEFAULT_MARGIN_PT = parseKnownOdfLength("2cm");
2547
+ const DEFAULT_MARGINS = {
2548
+ topPt: DEFAULT_MARGIN_PT,
2549
+ rightPt: DEFAULT_MARGIN_PT,
2550
+ bottomPt: DEFAULT_MARGIN_PT,
2551
+ leftPt: DEFAULT_MARGIN_PT
2552
+ };
2553
+ function findPageLayoutElement(pkg, pageLayoutName) {
2554
+ if (pageLayoutName === void 0) return;
2555
+ for (const partPath of AUTOMATIC_STYLE_PARTS) {
2556
+ const part = pkg.parts[partPath];
2557
+ if (part?.kind !== "xml") continue;
2558
+ const root = rootElement(part.nodes);
2559
+ const automaticStyles = root === void 0 ? void 0 : findChildElement(root.children, "office:automatic-styles");
2560
+ if (automaticStyles === void 0) continue;
2561
+ const found = childrenWithTag(automaticStyles, "style:page-layout").find((element) => attrValue(element, "style:name") === pageLayoutName);
2562
+ if (found !== void 0) return found;
2563
+ }
2564
+ }
2565
+ function readFirstMasterPageGeometry(pkg) {
2566
+ const stylesPart = pkg.parts[STYLES_PART];
2567
+ const stylesRoot = stylesPart?.kind === "xml" ? rootElement(stylesPart.nodes) : void 0;
2568
+ const masterStyles = stylesRoot === void 0 ? void 0 : findChildElement(stylesRoot.children, "office:master-styles");
2569
+ const masterPage = masterStyles === void 0 ? void 0 : findChildElement(masterStyles.children, "style:master-page");
2570
+ const layout = findPageLayoutElement(pkg, masterPage === void 0 ? void 0 : attrValue(masterPage, "style:page-layout-name"));
2571
+ const properties = layout === void 0 ? void 0 : findChildElement(layout.children, "style:page-layout-properties");
2572
+ const pageSize = properties === void 0 ? void 0 : parsePageSize(properties);
2573
+ const margins = properties === void 0 ? void 0 : parseMargins(properties);
2574
+ return {
2575
+ pageSize: pageSize ?? DEFAULT_PAGE_SIZE$1,
2576
+ margins: margins ?? DEFAULT_MARGINS
2577
+ };
2578
+ }
2579
+ function readOdt(pkg) {
2580
+ const contentPart = pkg.parts[CONTENT_PART$1];
2581
+ if (contentPart?.kind !== "xml") throw new Error(`readOdt: package has no ${CONTENT_PART$1} part`);
2582
+ const contentRoot = rootElement(contentPart.nodes);
2583
+ const body = contentRoot === void 0 ? void 0 : findChildElement(contentRoot.children, "office:body");
2584
+ const textElement = body === void 0 ? void 0 : findChildElement(body.children, "office:text");
2585
+ if (textElement === void 0) throw new Error(`readOdt: ${CONTENT_PART$1} has no office:body/office:text element`);
2586
+ const metadata = readOdfMetadata(pkg);
2587
+ const { pageSize, margins } = readFirstMasterPageGeometry(pkg);
2588
+ return {
2589
+ metadata,
2590
+ sections: [{
2591
+ pageSize,
2592
+ margins,
2593
+ blocks: readBlocks(textElement.children, pkg, { next: 1 })
2594
+ }]
2595
+ };
2596
+ }
2597
+ //#endregion
2598
+ //#region src/typed/odg/read.ts
2599
+ const CONTENT_PART = "content.xml";
2600
+ const DEFAULT_PAGE_SIZE = PAGE_SIZE_A4;
2601
+ function readPage(page, pkg) {
2602
+ const size = resolveDrawPageSize(page, pkg) ?? DEFAULT_PAGE_SIZE;
2603
+ const { shapes, vectors } = readDrawPageContent(page.children, pkg);
2604
+ return {
2605
+ size,
2606
+ shapes,
2607
+ vectors
2608
+ };
2609
+ }
2610
+ function readOdg(pkg) {
2611
+ const contentPart = pkg.parts[CONTENT_PART];
2612
+ const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
2613
+ const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
2614
+ const drawing = body === void 0 ? void 0 : findChildElement(body.children, "office:drawing");
2615
+ const pages = drawing === void 0 ? [] : childrenWithTag(drawing, "draw:page");
2616
+ return {
2617
+ metadata: readOdfMetadata(pkg),
2618
+ pages: pages.map((page) => readPage(page, pkg))
2619
+ };
2620
+ }
2621
+ //#endregion
2622
+ export { AlignmentSchema, AttributeSchema, BinaryPartSchema, MANIFEST_PART, META_PART, MIMETYPE_PART, ManifestEntrySchema, ManifestProblemSchema, ManifestSchema, ODF_MEDIA_TYPES, ODF_NAMESPACES, PackageSchema, PartSchema, STYLE_FAMILIES, StylePropertiesSchema, StyleRegistry, TableCursor, XmlCdataSchema, XmlCommentSchema, XmlDeclarationSchema, XmlElementSchema, XmlNodeSchema, XmlPartSchema, XmlPiSchema, XmlTextSchema, applyOdfTransform, attrValue, base64ToBytes, buildManifest, buildOdfSubpaths, buildStylePropertyElements, buildXml, bytesToBase64, canonicalPropertiesString, cellReference, childrenWithTag, columnIndexToLetters, composeOdfGroupTransform, decodeOdfText, decodePackage, decodeXmlText, el, elementsWithTag, encodePackage, encodeXmlText, ensureSpan, findChildElement, findStyleElement, formatOdfColor, formatOdfLength, formatPercentageMultiplier, formatPt, getOdfSpaceCount, isStyleFamily, isXmlNode, measureOdfNodeLength, mediaTypeForExtension, netRotationDeg, packageCodec, paragraphPropertiesToAttributes, parseBox, parseLength, parseLinePoints, parseMargins, parseOdfColor, parseOdfLength, parseOdfPathData, parseOdfPointsList, parseOdfTransform, parseOdfViewBox, parsePackage, parsePageSize, parseParagraphProperties, parseStyleElementProperties, parseTextProperties, parseXml, rawSubpathFromPoints, readDrawFrame, readDrawPageContent, readManifest, readMimetype, readOdfMetadata, readOdfParagraph, readOdfTable, readOdg, readOdp, readOdt, resolveDrawPageSize, resolveOdfShapeGeometry, resolveStyle, resolveStyleElementChain, rootElement, scaleOdfRawPoint, serializePackage, setDocumentMediaType, sniffImageFormat, sumOdfNodeLength, syncManifest, textPropertiesToAttributes, txt, unzipPackage, validateManifest, walkDrawShapes, writeManifest, writeMimetype, xmlCodec, xmlnsAttributes, zipPackage };