@@ -45,7 +45,7 @@ private static void Generate(this OpenXmlElement xmlElement, WordprocessingDocum
4545 // avoid {{tag}} like <t>{</t><t>{</t>
4646 //AvoidSplitTagText(xmlElement);
4747 // avoid {{tag}} like <t>aa{</t><t>{</t> test in...
48- AvoidSplitTagText ( xmlElement , GetReplaceKeys ( tags ) ) ;
48+ AvoidSplitTagText ( xmlElement ) ;
4949
5050 //Tables
5151 var tables = xmlElement . Descendants < Table > ( ) . ToArray ( ) ;
@@ -56,16 +56,15 @@ private static void Generate(this OpenXmlElement xmlElement, WordprocessingDocum
5656
5757 foreach ( var tr in trs )
5858 {
59-
6059 var matchs = ( Regex . Matches ( tr . InnerText , "(?<={{).*?\\ ..*?(?=}})" )
6160 . Cast < Match > ( ) . GroupBy ( x => x . Value ) . Select ( varGroup => varGroup . First ( ) . Value ) ) . ToArray ( ) ;
6261 if ( matchs . Length > 0 )
6362 {
6463 var listKeys = matchs . Select ( s => s . Split ( '.' ) [ 0 ] ) . Distinct ( ) . ToArray ( ) ;
6564 // TODO:
66- // not support > 1 list in same tr
67- if ( listKeys . Length > 1 )
68- throw new NotSupportedException ( "MiniWord doesn't support more than 1 list in same row" ) ;
65+ // not support > 2 list in same tr
66+ if ( listKeys . Length > 2 )
67+ throw new NotSupportedException ( "MiniWord doesn't support more than 2 list in same row" ) ;
6968 var listKey = listKeys [ 0 ] ;
7069 if ( tags . ContainsKey ( listKey ) && tags [ listKey ] is IEnumerable )
7170 {
@@ -106,6 +105,7 @@ private static void AvoidSplitTagText(OpenXmlElement xmlElement)
106105 var pool = new List < Text > ( ) ;
107106 var sb = new StringBuilder ( ) ;
108107 var needAppend = false ;
108+ var foreachIncluded = false ;
109109 foreach ( var text in texts )
110110 {
111111 var clear = false ;
@@ -122,10 +122,28 @@ private static void AvoidSplitTagText(OpenXmlElement xmlElement)
122122 // TODO: check tag exist
123123 // TODO: record tag text if without tag then system need to clear them
124124 // TODO: every {{tag}} one <t>for them</t> and add text before first text and copy first one and remove {{, tagname, }}
125-
125+
126+ if ( s . StartsWith ( "{{foreach" ) )
127+ foreachIncluded = true ;
128+
126129 if ( ! s . StartsWith ( "{{" ) )
127130 clear = true ;
128- else if ( s . Contains ( "{{" ) && s . Contains ( "}}" ) )
131+ else if ( s . Contains ( "{{" ) && s . Contains ( "}}" ) && ! foreachIncluded )
132+ {
133+ if ( sb . Length <= 1000 ) // avoid too big tag
134+ {
135+ var first = pool . First ( ) ;
136+ var newText = first . Clone ( ) as Text ;
137+ newText . Text = s ;
138+ first . Parent . InsertBefore ( newText , first ) ;
139+ foreach ( var t in pool )
140+ {
141+ t . Text = "" ;
142+ }
143+ }
144+ clear = true ;
145+ }
146+ else if ( s . Contains ( "{{foreach" ) && s . Contains ( "endforeach}}" ) && foreachIncluded )
129147 {
130148 if ( sb . Length <= 1000 ) // avoid too big tag
131149 {
@@ -139,7 +157,9 @@ private static void AvoidSplitTagText(OpenXmlElement xmlElement)
139157 }
140158 }
141159 clear = true ;
160+ foreachIncluded = false ;
142161 }
162+
143163 }
144164
145165 if ( clear )
@@ -177,7 +197,9 @@ private static List<string> GetReplaceKeys(Dictionary<string, object> tags)
177197 if ( item2 is Dictionary < string , object > dic )
178198 {
179199 foreach ( var item3 in dic . Keys )
200+ {
180201 keys . Add ( "{{" + item . Key + "." + item3 + "}}" ) ;
202+ }
181203 }
182204 break ;
183205 }
@@ -330,6 +352,19 @@ private static void ReplaceText(OpenXmlElement xmlElement, WordprocessingDocumen
330352 foreach ( var tag in tags )
331353 {
332354 var isMatch = t . Text . Contains ( $ "{{{{{tag.Key}}}}}") ;
355+
356+ if ( ! isMatch && tag . Value is List < MiniWordForeach > forTags )
357+ {
358+ if ( forTags . Any ( forTag => forTag . Value . Keys . Any ( dictKey =>
359+ {
360+ var innerTag = "{{" + tag . Key + "." + dictKey + "}}" ;
361+ return t . Text . Contains ( innerTag ) ;
362+ } ) ) )
363+ {
364+ isMatch = true ;
365+ }
366+ }
367+
333368 if ( isMatch )
334369 {
335370 if ( tag . Value is string [ ] || tag . Value is IList < string > || tag . Value is List < string > )
@@ -350,6 +385,31 @@ private static void ReplaceText(OpenXmlElement xmlElement, WordprocessingDocumen
350385 }
351386 t . Remove ( ) ;
352387 }
388+ else if ( tag . Value is List < MiniWordForeach > vs )
389+ {
390+ var currentT = t ;
391+ var generatedText = new Text ( ) ;
392+ currentT . Text = currentT . Text . Replace ( @"{{foreach" , "" ) . Replace ( @"endforeach}}" , "" ) ;
393+ for ( var i = 0 ; i < vs . Count ; i ++ )
394+ {
395+ var newT = t . CloneNode ( true ) as Text ;
396+
397+ foreach ( var vv in vs [ i ] . Value )
398+ {
399+ newT . Text = newT . Text . Replace ( "{{" + tag . Key + "." + vv . Key + "}}" , vv . Value . ToString ( ) ) ;
400+ }
401+
402+ if ( i != vs . Count )
403+ {
404+ newT . Text += vs [ i ] . Separator ;
405+ }
406+
407+ generatedText . Text += newT . Text ;
408+ }
409+
410+ run . Append ( generatedText ) ;
411+ t . Remove ( ) ;
412+ }
353413 else if ( tag . Value is MiniWordPicture )
354414 {
355415 var pic = ( MiniWordPicture ) tag . Value ;
0 commit comments