@@ -41,59 +41,9 @@ private static void SaveAsByTemplateImpl(Stream stream, byte[] template, Diction
4141 }
4242 private static void Generate ( this OpenXmlElement xmlElement , WordprocessingDocument docx , Dictionary < string , object > tags )
4343 {
44+ // avoid {{tag}} like <t>{</t><t>{</t>
45+ AvoidSplitTagText ( xmlElement ) ;
4446
45- // Avoid not standard string format e.g. {{<t>tag</t>}}
46- //foreach (var tag in tags)
47- //{
48- // var regexStr = string.Concat(@"((\{\{(?:(?!\{\{|}}).)*>)|\{\{)", tag.Key, @"(}}|<.*?}})");
49-
50- // xmlElement.InnerXml = Regex.Replace(xmlElement.InnerXml, regexStr, $"{{{{{tag.Key?.ToString()}}}}}", RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace | RegexOptions.CultureInvariant);
51- //}
52- // Avoid not standard string format e.g. {{<t>tag</t>}}
53- {
54- var paragraphs = xmlElement . Descendants < Paragraph > ( ) . ToArray ( ) ;
55- foreach ( var p in paragraphs )
56- {
57- var runs = p . Descendants < Run > ( ) . ToArray ( ) ;
58- var isMatch = tags . Any ( tag =>
59- {
60- var b = p . InnerText . Contains ( $ "{{{{{tag.Key}}}}}") ;
61- if ( ! b && tag . Value is IEnumerable )
62- {
63- foreach ( var item in tag . Value as IEnumerable )
64- {
65- if ( item is Dictionary < string , object > )
66- {
67- foreach ( var dic in item as Dictionary < string , object > )
68- {
69- b = p . InnerText . Contains ( $ "{{{{{tag.Key}.{ dic . Key } }}}}") ;
70- if ( b )
71- break ;
72- }
73- }
74- break ;
75- }
76- }
77- return b ;
78- } ) ;
79- if ( isMatch )
80- {
81- var newText = p . InnerText ? . ToString ( ) ;
82- foreach ( var run in runs . Skip ( 1 ) )
83- run . RemoveAllChildren < Text > ( ) ;
84- if ( runs . Length > 0 )
85- {
86- var texts = runs [ 0 ] . Descendants < Text > ( ) . ToArray ( ) ;
87- if ( texts . Length > 0 )
88- {
89- foreach ( var text in texts . Skip ( 1 ) )
90- text . RemoveAllChildren ( ) ;
91- texts [ 0 ] . Text = newText ;
92- }
93- }
94- }
95- }
96- }
9747 //Tables
9848 var tables = xmlElement . Descendants < Table > ( ) . ToArray ( ) ;
9949 {
@@ -143,6 +93,57 @@ private static void Generate(this OpenXmlElement xmlElement, WordprocessingDocum
14393 ReplaceText ( xmlElement , docx , tags ) ;
14494 }
14595
96+ private static void AvoidSplitTagText ( OpenXmlElement xmlElement )
97+ {
98+ var texts = xmlElement . Descendants < Text > ( ) . ToList ( ) ;
99+ var pool = new List < Text > ( ) ;
100+ var sb = new StringBuilder ( ) ;
101+ var needAppend = false ;
102+ foreach ( var text in texts )
103+ {
104+ var clear = false ;
105+ if ( text . InnerText . StartsWith ( "{" ) )
106+ {
107+ needAppend = true ;
108+ }
109+ if ( needAppend )
110+ {
111+ sb . Append ( text . InnerText ) ;
112+ pool . Add ( text ) ;
113+
114+ var s = sb . ToString ( ) ; //TODO:
115+ // TODO: check tag exist
116+ // TODO: record tag text if without tag then system need to clear them
117+ // TODO: every {{tag}} one <t>for them</t> and add text before first text and copy first one and remove {{, tagname, }}
118+
119+ if ( ! s . StartsWith ( "{{" ) )
120+ clear = true ;
121+ else if ( s . Contains ( "{{" ) && s . Contains ( "}}" ) )
122+ {
123+ if ( sb . Length <= 1000 ) // avoid too big tag
124+ {
125+ var first = pool . First ( ) ;
126+ var newText = first . Clone ( ) as Text ;
127+ newText . Text = s ;
128+ first . Parent . InsertBefore ( newText , first ) ;
129+ foreach ( var t in pool )
130+ {
131+ t . Text = "" ;
132+ }
133+ }
134+ clear = true ;
135+ }
136+ }
137+
138+ if ( clear )
139+ {
140+ sb . Clear ( ) ;
141+ pool . Clear ( ) ;
142+ needAppend = false ;
143+ }
144+ }
145+ }
146+
146147 private static void ReplaceText ( OpenXmlElement xmlElement , WordprocessingDocument docx , Dictionary < string , object > tags )
147148 {
148149 var paragraphs = xmlElement . Descendants < Paragraph > ( ) . ToArray ( ) ;
0 commit comments