Skip to content

Commit 38e6df0

Browse files
committed
Support more table formatting in RTF to DOCX converter
1 parent c86502b commit 38e6df0

4 files changed

Lines changed: 415 additions & 126 deletions

File tree

src/DocSharp.Docx/DocxToRtf/DocxToRtfConverter.Table.cs

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ internal override void ProcessTable(Table table, RtfStringWriter sb)
2020
var tableProperties = new RtfStringWriter();
2121

2222
// In RTF, table properties are usually specified for single rows.
23-
// However, if spacing between cells is present, table row shading is not applied there,
24-
// unlike table shading.
23+
// However, if spacing between cells is present, table row shading is not applied there, unlike table shading.
2524
// This is a limitation of RTF and also occurs when converting DOCX to RTF using Word.
2625
// So we just process table cell shading in ProcessTableCellProperties, since there is no difference
2726
// (it will retrieve table shading if cell shading is not specified).
@@ -649,38 +648,33 @@ internal void ProcessTableCellProperties(TableCell cell, RtfStringWriter sb, ref
649648
if (direction.Val == TextDirectionValues.LefToRightTopToBottom ||
650649
direction.Val == TextDirectionValues.LeftToRightTopToBottom2010)
651650
{
652-
// Horizontal text, left to right, top to bottom (default)
653651
sb.Write(@"\cltxlrtb");
654652
}
655-
if (direction.Val == TextDirectionValues.LefttoRightTopToBottomRotated ||
656-
direction.Val == TextDirectionValues.LeftToRightTopToBottomRotated2010)
657-
{
658-
// Vertical text, left to right, top to bottom (seems the same as the default, maybe depends on the font or context)
659-
sb.Write(@"\cltxlrtbv");
660-
}
661653
if (direction.Val == TextDirectionValues.TopToBottomRightToLeft ||
662654
direction.Val == TextDirectionValues.TopToBottomRightToLeft2010)
663655
{
664-
// Vertical text, top to bottom, right to left
665656
sb.Write(@"\cltxtbrl");
666657
}
667-
if (direction.Val == TextDirectionValues.TopToBottomRightToLeftRotated ||
668-
direction.Val == TextDirectionValues.TopToBottomRightToLeftRotated2010)
669-
{
670-
// Vertical text, bottom to top, right to left (seems the same as the default, maybe depends on the font or context)
671-
sb.Write(@"\cltxtbrlv");
672-
}
673658
if (direction.Val == TextDirectionValues.BottomToTopLeftToRight ||
674659
direction.Val == TextDirectionValues.BottomToTopLeftToRight2010)
675660
{
676-
// Vertical text, bottom to top, left to right
677661
sb.Write(@"\cltxbtlr");
678662
}
663+
if (direction.Val == TextDirectionValues.LefttoRightTopToBottomRotated ||
664+
direction.Val == TextDirectionValues.LeftToRightTopToBottomRotated2010)
665+
{
666+
sb.Write(@"\cltxlrtbv");
667+
}
668+
if (direction.Val == TextDirectionValues.TopToBottomRightToLeftRotated ||
669+
direction.Val == TextDirectionValues.TopToBottomRightToLeftRotated2010)
670+
{
671+
sb.Write(@"\cltxtbrlv");
672+
}
679673
if (direction.Val == TextDirectionValues.TopToBottomLeftToRightRotated ||
680674
direction.Val == TextDirectionValues.TopToBottomLeftToRightRotated2010)
681675
{
682-
// Not supported in RTF, fallback to BottomToTopLeftToRight
683-
sb.Write(@"\cltxbtlr");
676+
// Not available in RTF, fallback to TopToBottomRightToLeftRotated.
677+
sb.Write(@"\cltxtbrlv");
684678
}
685679
}
686680

src/DocSharp.Docx/Helpers/OpenXmlHelpers.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,29 @@ public static void RemoveAll<T>(this OpenXmlElement element) where T : OpenXmlEl
6868
}
6969
}
7070

71+
/// <summary>
72+
/// Get or create a child element of the specified type.
73+
/// Useful when a strongly-typed property is not provided by the Open XML SDK.
74+
/// </summary>
75+
/// <typeparam name="T"></typeparam>
76+
/// <param name="element"></param>
77+
public static T EnsureElement<T>(this OpenXmlElement element) where T : OpenXmlElement, new()
78+
{
79+
return element.GetFirstChild<T>() ?? element.AppendChild(new T());
80+
}
81+
82+
/// <summary>
83+
/// Set child element of the specified type.
84+
/// Useful when a strongly-typed property is not provided by the Open XML SDK.
85+
/// </summary>
86+
/// <typeparam name="T"></typeparam>
87+
/// <param name="element"></param>
88+
public static T SetElement<T>(this OpenXmlElement element, T value) where T : OpenXmlElement
89+
{
90+
element.RemoveAll<T>();
91+
return element.AppendChild(value);
92+
}
93+
7194
public static void Clear(this OpenXmlElement element)
7295
{
7396
element.RemoveAllChildren();

0 commit comments

Comments
 (0)