From d08dea6bc97cf0c7b13deab2ff3253850f5ee15d Mon Sep 17 00:00:00 2001 From: csh Date: Fri, 19 May 2023 10:41:46 +0800 Subject: [PATCH] update `TSTag` --- funcext/TSOffice/TOfficeObj.tsf | 85 +++++++++++++---------------- funcext/TSOffice/document/TSTag.tsf | 51 ++++++++++++----- 2 files changed, 76 insertions(+), 60 deletions(-) diff --git a/funcext/TSOffice/TOfficeObj.tsf b/funcext/TSOffice/TOfficeObj.tsf index 83d05d8..80f869d 100644 --- a/funcext/TSOffice/TOfficeObj.tsf +++ b/funcext/TSOffice/TOfficeObj.tsf @@ -5,6 +5,8 @@ Begin case lowercase(n) of "nodeinfo": return new NodeInfo(""); + "trange": + return new TRange(""); "tfont": return new TFont(); "tcomment": @@ -10156,11 +10158,20 @@ End; ///DOCX文档实现 Type TRange = Class - Function Create(t); + Function Create();overload; + Begin + Create(nil); + End; + + Function Create(t);overload; Begin //array(("pNode":nodeObj, "pIndex":p, "rNode":nodeObj, "rIndex":r)) + Init(t); + End; + + Function Init(t); + Begin RunArr_ := t; - rPr_ := new TwrPr(); End; ///清除全部选中内容 @@ -10172,6 +10183,8 @@ Type TRange = Class Property Font read readFont; Function readFont(); Begin + if ifNil(rPr_) then + rPr_ := new TwrPr(); return rPr_; End; @@ -10193,6 +10206,7 @@ Type TRange = Class ///应用字体样式 Function Apply(); Begin + if not ifObj(rPr_) then return; arr := rPr_.Marshal(); if length(arr['attributes']) or length(arr['children']) then Begin for i:=0 to length(RunArr_)-1 do Begin @@ -10204,11 +10218,9 @@ Type TRange = Class Function _clear(first); Begin - for i:=first to length(RunArr_)-1 do Begin - RunArr_[i]['pNode'].DeleteChild(RunArr_[i]['rNode']); - End; for i:=first to length(RunArr_)-1 do Begin pNode := RunArr_[i]['pNode']; + pNode.DeleteChild(RunArr_[i]['rNode']); rNode := pNode.FirstChildElement('w:r'); if not ifObj(rNode) then pNode.Parent().DeleteChild(pNode); @@ -13622,7 +13634,7 @@ Type TDocumentBody = Class(DocObject) End; //[/tag]后 - if k < txtLen then Begin //函数后面分割为新的w:r + if k < txtLen then Begin //后面分割为新的w:r tArr[i]['rNode'] := run._duplicate_r(tArr[i]['rNode']); run._adjust_r(tArr[i]['rNode'], wz, txtLen); iStep := 0; @@ -13633,58 +13645,50 @@ Type TDocumentBody = Class(DocObject) nNode := run._duplicate_r(tagArr[tagInd]['rNode']); run._adjust_r(tagArr[tagInd]['rNode'], 0, tmp['tail-begin-wz'] - 1); tagArr[tagInd]['pNode'].DeleteChild(nNode); + tmp['tag-end'] := tagInd; End else if tmp['tail-begin-pos'] = 1 then Begin - if _remove_run(tagArr[tagInd]['pNode'], tagArr[tagInd]['rNode']) then - tagArr[tagInd]['pNode'] := nil; - tagArr[tagInd]['rNode'] := nil; + tmp['tag-end'] := tagInd - 1; End; - //删除[/TAG]尾部 - for delI := tagInd+1 to length(tagArr)-1 do Begin - if _remove_run(tagArr[delI]['pNode'], tagArr[delI]['rNode']) then - tagArr[delI]['pNode'] := nil; - tagArr[delI]['rNode'] := nil; - End; - + //[tag]后 firstNode := tagArr[0]['rNode']; tagInd := length(tagArr) - i + tmp['head-end-paragraph'] - 1; - //println('===============================head-end-pos={},head-end-txtlen={}',tmp['head-end-pos'] , tmp['head-end-txtlen']); if tmp['head-end-pos'] < tmp['head-end-txtlen'] then Begin oldNode := tagArr[tagInd]['rNode']; tagArr[tagInd]['rNode'] := run._duplicate_r(oldNode); run._adjust_r(tagArr[tagInd]['rNode'], tmp['head-end-wz'] - 1, tmp['head-end-txtlen']); + tmp['tag-beg'] := tagInd; + if tmp['head-begin-paragraph'] <> tmp['head-end-paragraph'] then + tagArr[tagInd]['pNode'].DeleteChild(oldNode); End else if tmp['head-end-pos'] = tmp['head-end-txtlen'] and tagInd then Begin - if _remove_run(tagArr[tagInd]['pNode'], tagArr[tagInd]['rNode']) then - tagArr[tagInd]['pNode'] := nil; - tagArr[tagInd]['rNode'] := nil; + tmp['tag-beg'] := tagInd + 1; End; //前[tag] if tmp['head-begin-pos'] > 1 then Begin run._adjust_r(firstNode, 0, tmp['head-begin-wz'] - 1); - if tmp['head-begin-paragraph'] <> tmp['head-end-paragraph'] then + if firstNode = tagArr[0]['rNode'] then tagArr[0]['rNode'] := nil; End - else if tmp['head-begin-pos'] = 1 then Begin - if _remove_run(tagArr[0]['pNode'], firstNode) then - tagArr[0]['pNode'] := nil; - if tmp['head-begin-paragraph'] <> tmp['head-end-paragraph'] then - tagArr[0]['rNode'] := nil; - End; - for delI := 1 to tagInd-1 do Begin - if _remove_run(tagArr[delI]['pNode'], tagArr[delI]['rNode']) then - tagArr[delI]['pNode'] := nil; - tagArr[delI]['rNode'] := nil; - End; + else if tagInd=0 and tmp['tag-beg']=0 then + tagArr[0]['pNode'].DeleteChild(firstNode); //执行TAG逻辑 r := array(); for nI := 0 to length(tagArr)-1 do Begin - if ifObj(tagArr[nI]['rNode']) then - r[length(r)] := tagArr[nI]; + if not ifObj(tagArr[nI]['rNode']) then continue; + if nI >= tmp['tag-beg'] and nI <= tmp['tag-end'] then + r[length(r)] := tagArr[nI];//标签中间文字内容 + else Begin //删除标签 + tagArr[nI]['pNode'].DeleteChild(tagArr[nI]['rNode']); + node := tagArr[nI]['pNode'].FirstChildElement('w:r'); + if not ifObj(node) then Begin + tagArr[nI]['pNode'].Parent().DeleteChild(tagArr[nI]['pNode']); + End; + End; End; - tagObj.Init(tagName, attribute, r); + tagObj.Init(tagName, tagAttribute, r); tagObj.Apply(); tslTagCount++; @@ -13910,17 +13914,6 @@ Type TDocumentBody = Class(DocObject) End; End; - Function _remove_run(pNode, rNode); - Begin - pNode.DeleteChild(rNode); - node := pNode.FirstChildElement('w:r'); - if not ifObj(node) then Begin - pNode.Parent().DeleteChild(pNode); - return true; - End; - return false; - End; - zipfile_; lastParagraph_; document_; diff --git a/funcext/TSOffice/document/TSTag.tsf b/funcext/TSOffice/document/TSTag.tsf index e642173..99bda57 100644 --- a/funcext/TSOffice/document/TSTag.tsf +++ b/funcext/TSOffice/document/TSTag.tsf @@ -9,6 +9,36 @@ Type TSTag = Class tagName_ := tagName; attribute_ := attribute; runArr_ := r; + range_ := nil; + map_ := nil; + End; + + Property Range read readRange; + Function readRange(); + Begin + if ifNil(range_) then Begin + range_ := TOfficeObj('TRange'); + range_.Init(runArr_); + End; + return range_; + End; + + ///获取TAG中属性 [font size=12]...[/font] + /// tag.GetAttribute('size'); + ///返回:string + Function GetAttribute(key); + Begin + if not ifArray(map_) then Begin + map_ := array(); + println('attribute={}',attribute_); + arr := Str2Array(attribute_, ' '); + for i := 0 to length(arr)-1 do Begin + kv := Str2Array(arr[i], '='); + if length(kv)=2 then + map_[kv[0]] := kv[1]; + End; + End; + return map_[key]; End; Function Apply(); virtual; @@ -23,27 +53,20 @@ Type TSTag = Class Function _add(); Begin - for i:=0 to length(runArr_)-1 do Begin - run := TOfficeObj('TRun'); - run.Init(runArr_[i]['rNode']); - run.Font.Size := 40; - run.Font.Color := 'FF0000'; - run.Font.Bold := true; - run.Apply(); - End; + Range.Font.Size := 40; + Range.Font.Color := 'FF0000'; + Range.Font.Bold := true; + Range.Apply(); End; Function _del(); Begin - for i:=0 to length(runArr_)-1 do Begin - runArr_[i]['pNode'].DeleteChild(runArr_[i]['rNode']); - child := runArr_[i]['pNode'].FirstChildElement('w:r'); - if not ifObj(child) then - runArr_[i]['pNode'].Parent().DeleteChild(runArr_[i]['pNode']); - End; + Range.Clear(); End; tagName_:string; attribute_:string; runArr_; + range_; + map_; End;