@coco-vexel/coco-office-oojson 0.0.0-stage → 1.0.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/LICENSE +202 -0
- package/README.md +99 -2
- package/THIRD_PARTY_NOTICES.md +1188 -0
- package/dist/oojson.global.js +30 -0
- package/package.json +45 -3
- package/src/color.mjs +38 -0
- package/src/extra.mjs +37 -0
- package/src/flat-opc.mjs +394 -0
- package/src/index.mjs +39 -0
- package/src/json-to-ooxml.mjs +605 -0
- package/src/long-tail-parts.mjs +424 -0
- package/src/numbering-to-ooxml.mjs +120 -0
- package/src/ooxml-drawing-to-json.mjs +209 -0
- package/src/ooxml-to-json.mjs +305 -0
- package/src/ppt-content.mjs +346 -0
- package/src/ppt-deck.mjs +248 -0
- package/src/styles-to-ooxml.mjs +302 -0
- package/src/writeback.mjs +1082 -0
- package/src/xml.mjs +66 -0
package/src/xml.mjs
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// 迷你 XML 解析/序列化(无依赖)。用于 WordprocessingML 片段。
|
|
2
|
+
// 解析结果节点:{ tag, attrs:{}, kids:[node | {text}] };文本节点为 { text }。
|
|
3
|
+
|
|
4
|
+
export function parseXml(xml) {
|
|
5
|
+
let i = 0;
|
|
6
|
+
const n = xml.length;
|
|
7
|
+
function node() {
|
|
8
|
+
while (i < n && /\s/.test(xml[i])) i++; // 跳节点前空白(含 <?xml?> 后换行)
|
|
9
|
+
if (xml[i] !== "<") return null;
|
|
10
|
+
if (xml.startsWith("<?", i) || xml.startsWith("<!", i)) {
|
|
11
|
+
i = xml.indexOf(">", i) + 1;
|
|
12
|
+
return node();
|
|
13
|
+
}
|
|
14
|
+
i++; // <
|
|
15
|
+
let tag = "";
|
|
16
|
+
while (i < n && !/[\s/>]/.test(xml[i])) tag += xml[i++];
|
|
17
|
+
const attrs = {};
|
|
18
|
+
while (i < n && xml[i] !== ">" && xml[i] !== "/") {
|
|
19
|
+
while (/\s/.test(xml[i])) i++;
|
|
20
|
+
if (xml[i] === "/" || xml[i] === ">") break;
|
|
21
|
+
let name = "";
|
|
22
|
+
while (i < n && !/[\s=/>]/.test(xml[i])) name += xml[i++];
|
|
23
|
+
while (/\s/.test(xml[i])) i++;
|
|
24
|
+
let val = "";
|
|
25
|
+
if (xml[i] === "=") {
|
|
26
|
+
i++;
|
|
27
|
+
while (/\s/.test(xml[i])) i++;
|
|
28
|
+
const q = xml[i++];
|
|
29
|
+
while (i < n && xml[i] !== q) val += xml[i++];
|
|
30
|
+
i++;
|
|
31
|
+
}
|
|
32
|
+
attrs[name] = unesc(val);
|
|
33
|
+
}
|
|
34
|
+
if (xml[i] === "/") { i += 2; return { tag, attrs, kids: [] }; }
|
|
35
|
+
i++; // >
|
|
36
|
+
const kids = [];
|
|
37
|
+
while (i < n) {
|
|
38
|
+
if (xml.startsWith("</", i)) { i = xml.indexOf(">", i) + 1; break; }
|
|
39
|
+
if (xml[i] === "<") { const c = node(); if (c) kids.push(c); }
|
|
40
|
+
else { let t = ""; while (i < n && xml[i] !== "<") t += xml[i++]; if (t) kids.push({ text: unesc(t) }); }
|
|
41
|
+
}
|
|
42
|
+
return { tag, attrs, kids };
|
|
43
|
+
}
|
|
44
|
+
while (i < n && xml[i] !== "<") i++;
|
|
45
|
+
return node();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const kid = (node, tag) => (node && node.kids ? node.kids.find((k) => k.tag === tag) : undefined);
|
|
49
|
+
export const kidsOf = (node, tag) => (node && node.kids ? node.kids.filter((k) => k.tag === tag) : []);
|
|
50
|
+
|
|
51
|
+
export const esc = (s) =>
|
|
52
|
+
String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
53
|
+
export const unesc = (s) =>
|
|
54
|
+
String(s)
|
|
55
|
+
.replace(/</g, "<")
|
|
56
|
+
.replace(/>/g, ">")
|
|
57
|
+
.replace(/"/g, '"')
|
|
58
|
+
.replace(/'/g, "'")
|
|
59
|
+
.replace(/&/g, "&");
|
|
60
|
+
|
|
61
|
+
// 把属性对象拼成 ' k="v" ...' (已转义)
|
|
62
|
+
export function attrStr(attrs) {
|
|
63
|
+
let s = "";
|
|
64
|
+
for (const k of Object.keys(attrs)) if (attrs[k] != null) s += ` ${k}="${esc(attrs[k])}"`;
|
|
65
|
+
return s;
|
|
66
|
+
}
|