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