@@ -27,9 +27,9 @@ class BlockElementExpression: PhrasingElementExpression
27
27
{
28
28
private readonly OpenXmlLeafElement [ ] ? defaultStyleProperties ;
29
29
protected readonly ParagraphProperties paraProperties = new ( ) ;
30
- // some style attributes, such as borders, must be applied on multiple paragraphs
31
- // in order to render as one single block of content.
32
- protected bool renderAsOneBlock ;
30
+ // some style attributes, such as borders or bgcolor, will convert this node to a framed container
31
+ protected bool renderAsFramed ;
32
+ private HtmlBorder styleBorder ;
33
33
34
34
35
35
public BlockElementExpression ( IHtmlElement node , OpenXmlLeafElement ? styleProperty ) : base ( node )
@@ -58,20 +58,69 @@ public override IEnumerable<OpenXmlElement> Interpret (ParsingContext context)
58
58
p . AppendChild ( new BookmarkEnd ( ) { Id = bookmarkId } ) ;
59
59
}
60
60
61
- if ( ! renderAsOneBlock || childElements . Count ( ) < 2 )
61
+ if ( ! renderAsFramed )
62
62
return childElements ;
63
63
64
- // to group together those paragraphs, we must force some indentation requirement
65
- foreach ( var p in childElements . OfType < Paragraph > ( ) )
64
+ var paragraphs = childElements . OfType < Paragraph > ( ) ;
65
+ if ( ! paragraphs . Any ( ) ) return childElements ;
66
+
67
+ // if we have only 1 paragraph, just inline the styles
68
+ if ( paragraphs . Count ( ) == 1 )
66
69
{
67
- p . ParagraphProperties ??= new ( ) ;
68
- // do not override indentation if `text-indent` was previously set
69
- if ( ( p . ParagraphProperties . Indentation ? . FirstLine ? . HasValue ) != true )
70
+ var p = paragraphs . First ( ) ;
71
+
72
+ if ( ! styleBorder . IsEmpty && p . ParagraphProperties ? . ParagraphBorders is null )
70
73
{
71
- p . ParagraphProperties . Indentation = new ( ) { Right = "0" } ;
74
+ p . ParagraphProperties ??= new ( ) ;
75
+ p . ParagraphProperties ! . ParagraphBorders = new ParagraphBorders {
76
+ LeftBorder = Converter . ToBorder < LeftBorder > ( styleBorder . Left ) ,
77
+ RightBorder = Converter . ToBorder < RightBorder > ( styleBorder . Right ) ,
78
+ TopBorder = Converter . ToBorder < TopBorder > ( styleBorder . Top ) ,
79
+ BottomBorder = Converter . ToBorder < BottomBorder > ( styleBorder . Bottom )
80
+ } ;
72
81
}
82
+
83
+ return childElements ;
84
+ }
85
+
86
+ // if we have 2+ paragraphs, we will embed them inside a stylised table
87
+ return [ CreateFrame ( childElements ) ] ;
88
+ }
89
+
90
+ /// <summary>
91
+ /// Group all the paragraph inside a framed table.
92
+ /// </summary>
93
+ private Table CreateFrame ( IEnumerable < OpenXmlElement > childElements )
94
+ {
95
+ TableCell cell ;
96
+ TableProperties tableProperties ;
97
+ Table framedTable = new (
98
+ tableProperties = new TableProperties {
99
+ TableWidth = new ( ) { Type = TableWidthUnitValues . Auto , Width = "0" } // 100%
100
+ } ,
101
+ new TableGrid (
102
+ new GridColumn ( ) { Width = "5610" } ) ,
103
+ new TableRow (
104
+ cell = new TableCell ( childElements )
105
+ )
106
+ ) ;
107
+
108
+ if ( ! styleBorder . IsEmpty )
109
+ {
110
+ tableProperties . TableBorders = new TableBorders {
111
+ LeftBorder = Converter . ToBorder < LeftBorder > ( styleBorder . Left ) ,
112
+ RightBorder = Converter . ToBorder < RightBorder > ( styleBorder . Right ) ,
113
+ TopBorder = Converter . ToBorder < TopBorder > ( styleBorder . Top ) ,
114
+ BottomBorder = Converter . ToBorder < BottomBorder > ( styleBorder . Bottom )
115
+ } ;
116
+ }
117
+
118
+ if ( runProperties . Shading != null )
119
+ {
120
+ cell . TableCellProperties = new ( ) { Shading = ( Shading ? ) runProperties . Shading . Clone ( ) } ;
73
121
}
74
- return childElements ;
122
+
123
+ return framedTable ;
75
124
}
76
125
77
126
protected override IEnumerable < OpenXmlElement > Interpret (
@@ -163,18 +212,10 @@ protected override void ComposeStyles (ParsingContext context)
163
212
}
164
213
165
214
166
- var styleBorder = styleAttributes . GetBorders ( ) ;
215
+ styleBorder = styleAttributes . GetBorders ( ) ;
167
216
if ( ! styleBorder . IsEmpty )
168
217
{
169
- var borders = new ParagraphBorders {
170
- LeftBorder = Converter . ToBorder < LeftBorder > ( styleBorder . Left ) ,
171
- RightBorder = Converter . ToBorder < RightBorder > ( styleBorder . Right ) ,
172
- TopBorder = Converter . ToBorder < TopBorder > ( styleBorder . Top ) ,
173
- BottomBorder = Converter . ToBorder < BottomBorder > ( styleBorder . Bottom )
174
- } ;
175
-
176
- paraProperties . ParagraphBorders = borders ;
177
- renderAsOneBlock = true ;
218
+ renderAsFramed = true ;
178
219
}
179
220
180
221
foreach ( string className in node . ClassList )
@@ -187,8 +228,8 @@ protected override void ComposeStyles (ParsingContext context)
187
228
}
188
229
}
189
230
190
- Margin margin = styleAttributes . GetMargin ( "margin" ) ;
191
- Indentation ? indentation = null ;
231
+ var margin = styleAttributes . GetMargin ( "margin" ) ;
232
+ Indentation ? indentation = null ;
192
233
if ( ! margin . IsEmpty )
193
234
{
194
235
if ( margin . Top . IsFixed || margin . Bottom . IsFixed )
@@ -264,6 +305,9 @@ protected override void ComposeStyles (ParsingContext context)
264
305
} ;
265
306
}
266
307
}
308
+
309
+ if ( runProperties . Shading != null )
310
+ renderAsFramed = true ;
267
311
}
268
312
269
313
/// <summary>
0 commit comments