230 lines
6.4 KiB
Plaintext
230 lines
6.4 KiB
Plaintext
Type TSWdCommon = Class
|
||
|
||
Class Function AddRun(rootNode, parentNode, runNode, tParagraph, pStart, pEnd, pTotal, arr);
|
||
Begin
|
||
run_obj := TOfficeObj("TRun");
|
||
run_obj.Init(runNode);
|
||
text := ifObj(runNode) ? run_obj.Text() : "";
|
||
len := text ? length(text) : 1;
|
||
|
||
if pTotal + len > pStart then
|
||
begin
|
||
length := length(arr);
|
||
// 左边切割
|
||
if pTotal < pstart and pTotal + len > pStart + 1 then
|
||
arr[length]["lsplit"] := pStart - pTotal; // 左边丢弃的字符数
|
||
// 右边切割
|
||
if pTotal + len > pEnd then
|
||
arr[length]["rsplit"] := pTotal + len - pEnd; // 右边丢弃的字符数
|
||
arr[length]["tparagraph"] := tparagraph;
|
||
arr[length]["trun"] := run_obj;
|
||
arr[length]["text"] := text;
|
||
arr[length]["root"] := rootNode;
|
||
arr[length]["parent"] := parentNode;
|
||
end
|
||
return len;
|
||
End;
|
||
|
||
Class Function SplitRange(root, startNode, pStart, pEnd, pTotal, arr);
|
||
Begin
|
||
node := startNode.FirstChildElement();
|
||
while ifObj(node) do
|
||
begin
|
||
case node.GetName() of
|
||
"w:p":
|
||
begin
|
||
paragraph_obj := TOfficeObj("TParagraph");
|
||
paragraph_obj.Init(node);
|
||
if paragraph_obj.Empty() then
|
||
begin
|
||
class(TSWdCommon).AddRun(root, startNode, nil, paragraph_obj, pStart, pEnd, pTotal, arr);
|
||
end
|
||
else begin
|
||
paragraph_len := length(arr); // 标记段落完整的起始位置
|
||
sub_node := node.FirstChildElement();
|
||
while ifObj(sub_node) do
|
||
begin
|
||
case sub_node.GetName() of
|
||
"w:r":
|
||
begin
|
||
pTotal += class(TSWdCommon).AddRun(root, startNode, sub_node, paragraph_obj, pStart, pEnd, pTotal, arr);
|
||
if pTotal >= pEnd then return 1;
|
||
end
|
||
|
||
"w:ins", "w:del":
|
||
begin
|
||
run_node := sub_node.FirstChildElement("w:r");
|
||
while ifObj(run_node) do
|
||
begin
|
||
class(TSWdCommon).AddRun(paragraph_obj, root, run_node, pStart, pEnd, pTotal, arr);
|
||
run_node := run_node.NextElement("w:r");
|
||
end
|
||
end
|
||
end;
|
||
sub_node := sub_node.NextElement();
|
||
end
|
||
for i:=paragraph_len to length(arr)-1 do
|
||
arr[i]["entirety"] := node;
|
||
end
|
||
pTotal += 1;
|
||
if pTotal >= pEnd then return 1;
|
||
end
|
||
|
||
"w:tbl":
|
||
begin
|
||
table_len := length(arr);
|
||
tr := node.FirstChildElement("w:tr");
|
||
while ifObj(tr) do
|
||
begin
|
||
tc := tr.FirstChildElement("w:tc");
|
||
while ifObj(tc) do
|
||
begin
|
||
cell_len := length(arr);
|
||
flag := class(TSWdCommon).SplitRange(root, tc, pStart, pEnd, pTotal, arr);
|
||
if flag then return 1;
|
||
tc := tc.NextElement("w:tc");
|
||
if pTotal >= pEnd then return 1;
|
||
for i:=cell_len to length(arr)-1 do
|
||
arr[i]["entirety"] := node;
|
||
end
|
||
tr := tr.NextElement("w:tr");
|
||
pTotal += 1;
|
||
if pTotal >= pEnd then return 1;
|
||
end
|
||
for i:=table_len to length(arr)-1 do
|
||
arr[i]["entirety"] := node;
|
||
end
|
||
end;
|
||
node := node.NextElement();
|
||
end
|
||
End;
|
||
|
||
Class Function AddRange(root, startNode, findNode, tParagraph, runNode, arr);
|
||
Begin
|
||
run_obj := TOfficeObj("TRun");
|
||
run_obj.Init(runNode);
|
||
length := length(arr);
|
||
arr[length]["tparagraph"] := tParagraph;
|
||
arr[length]["trun"] := run_obj;
|
||
arr[length]["root"] := root;
|
||
arr[length]["parent"] := startNode;
|
||
arr[length]["entirety"] := findNode;
|
||
text := ifObj(runNode) ? run_obj.Text() : "";
|
||
return text ? length(text) : 1;
|
||
End;
|
||
|
||
Class Function ParagraphRange(root, startNode, findNode, node, pend, arr);
|
||
Begin
|
||
paragraph_obj := TOfficeObj("TParagraph");
|
||
paragraph_obj.Init(node);
|
||
if paragraph_obj.Empty() then
|
||
begin
|
||
class(TSWdCommon).AddRange(root, startNode, findNode, paragraph_obj, nil, arr);
|
||
end
|
||
else begin
|
||
sub_node := node.FirstChildElement();
|
||
while ifObj(sub_node) do
|
||
begin
|
||
case sub_node.GetName() of
|
||
"w:r": pend += class(TSWdCommon).AddRange(root, startNode, findNode, paragraph_obj, sub_node, arr);
|
||
|
||
"w:ins", "w:del":
|
||
begin
|
||
run_node := sub_node.FirstChildElement("w:r");
|
||
while ifObj(run_node) do
|
||
begin
|
||
pend += class(TSWdCommon).AddRange(root, findNode, paragraph_obj, run_node, arr);
|
||
run_node := run_node.NextElement("w:r");
|
||
end
|
||
end
|
||
end;
|
||
sub_node := sub_node.NextElement();
|
||
end
|
||
end
|
||
pend += 1;
|
||
End;
|
||
|
||
Class Function CalculateRange(root, startNode, findNode, findFlag, pbegin, pend, arr);
|
||
Begin
|
||
if findFlag then arr := array();
|
||
node := startNode.FirstChildElement();
|
||
while ifObj(node) do
|
||
begin
|
||
if node.Eq(findNode) then
|
||
begin
|
||
find_flag2 := true;
|
||
arr := array();
|
||
end
|
||
case node.GetName() of
|
||
"w:p": class(TSWdCommon).ParagraphRange(root, startNode, findNode, node, pend, arr);
|
||
"w:tbl":
|
||
begin
|
||
tr := node.FirstChildElement("w:tr");
|
||
while ifObj(tr) do
|
||
begin
|
||
tc := tr.FirstChildElement("w:tc");
|
||
while ifObj(tc) do
|
||
begin
|
||
tc_node := tc;
|
||
new_flag := tc_node.Eq(findNode);
|
||
if new_flag then temp := pbegin; // 把pbegin存起来,防止递归覆盖
|
||
flag := CalculateRange(root, tc_node, findNode, new_flag, pbegin, pend, arr);
|
||
if new_flag then pbegin := temp;
|
||
if flag then return 1;
|
||
tc := tc.NextElement("w:tc");
|
||
end
|
||
tr := tr.NextElement("w:tr");
|
||
pend += 1;
|
||
end
|
||
end
|
||
end;
|
||
if find_flag2 then return 1;
|
||
if not flag then pbegin := pend;
|
||
node := node.NextElement();
|
||
end
|
||
if findFlag then return 1;
|
||
End;
|
||
|
||
Class Function SplitRangeRun(rangeArr);overload;
|
||
Begin
|
||
for i:=0 to length(rangeArr)-1 do
|
||
rangeArr[i] := class(TSWdCommon).SplitSingleRangeRun(rangeArr[i]);
|
||
End;
|
||
|
||
Class Function SplitSingleRangeRun(arr);overload;
|
||
Begin
|
||
insert_run := function(root, node);
|
||
begin
|
||
new_node := root.InsertAfterChild(node, "element", "w:r");
|
||
run := TOfficeObj("TRun");
|
||
run.Init(new_node);
|
||
return run;
|
||
end
|
||
paragraph := arr["tparagraph"];
|
||
run := arr["trun"];
|
||
text := arr["text"];
|
||
if arr["lsplit"] then // 分割左边
|
||
begin
|
||
lpos := arr["lsplit"];
|
||
run.SetText(text[:lpos]);
|
||
run := ##insert_run(paragraph.Root(), run.Root());
|
||
text := text[lpos + 1:];
|
||
run.SetText(text);
|
||
arr["text"] := text;
|
||
arr["lsplit"] := nil;
|
||
end
|
||
if arr["rsplit"] then // 分割右边的run
|
||
begin
|
||
rpos := length(text) - arr["rsplit"];
|
||
run.SetText(text[1:rpos]);
|
||
new_run := ##insert_run(paragraph.Root(), run.Root());
|
||
new_run.SetText(text[rpos+1:]);
|
||
arr["rsplit"] := nil;
|
||
arr["text"] := text[1:rpos];
|
||
end
|
||
arr["trun"] := run;
|
||
return arr;
|
||
End;
|
||
|
||
End;
|