Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 25 additions & 46 deletions MariGold.OpenXHTML/DocxElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ internal abstract class DocxElement
protected const string whiteSpace = " ";
protected readonly IOpenXmlContext context;
internal EventHandler<ParagraphEventArgs> ParagraphCreated;
protected static readonly Regex newLineRegex = new Regex(@"(?:\n|\r\n)", RegexOptions.Compiled);
protected static readonly Regex whitespaceRegex = new Regex(@"[\r\n ]+", RegexOptions.Compiled);

protected void RunCreated(DocxNode node, Run run)
{
Expand Down Expand Up @@ -142,21 +144,29 @@ protected void ProcessBlockElement(DocxNode node, ref Paragraph paragraph, Dicti

protected void ProcessParagraph(DocxNode child, DocxNode node, DocxNode paragraphNode, ref Paragraph paragraph)
{
if (!IsEmptyText(child, out string text))
if (TryGetText(child, out string text))
{
if (paragraph == null)
if (paragraph == null && !IsEmptyText(text))
{
paragraph = node.Parent.AppendChild(new Paragraph());
OnParagraphCreated(paragraphNode, paragraph);
}

Run run = paragraph.AppendChild(new Run(new Text()
if (paragraph != null)
{
Text = ClearHtml(text),
Space = SpaceProcessingModeValues.Preserve
}));
if (child.Previous != null && child.Previous.InnerHtml.EndsWith(whiteSpace))
{
text = text.TrimStart();
}

Run run = paragraph.AppendChild(new Run(new Text()
{
Text = ClearHtml(text),
Space = SpaceProcessingModeValues.Preserve
}));

RunCreated(node, run);
RunCreated(node, run);
}
}
}

Expand Down Expand Up @@ -216,67 +226,36 @@ internal string ClearHtml(string html)
{
return string.Empty;
}

html = WebUtility.HtmlDecode(html);
html = html.Replace("&nbsp;", whiteSpace);
html = html.Replace("&amp;", "&");

Regex regex = new Regex(Environment.NewLine + "\\s+");
Match match = regex.Match(html);
html = whitespaceRegex.Replace(html, " ");

while (match.Success)
{
//match.Length - 1 for leave a single space. Otherwise the sentences will collide.
html = html.Remove(match.Index, match.Length - 1);
match = regex.Match(html);
}

html = html.Replace(Environment.NewLine, string.Empty);
html = WebUtility.HtmlDecode(html);

return html;
}

internal bool IsEmptyText(string html)
{
if (string.IsNullOrEmpty(html))
{
return true;
}

html = html.Replace(Environment.NewLine, string.Empty);

if (string.IsNullOrEmpty(html.Trim()))
{
return true;
}

return false;
return string.IsNullOrEmpty(html.Trim());
}

internal bool IsEmptyText(DocxNode node, out string text)
internal bool TryGetText(DocxNode node, out string text)
{
text = string.Empty;

if (string.IsNullOrEmpty(node.InnerHtml))
{
return true;
}

text = node.InnerHtml.Replace(Environment.NewLine, string.Empty);
text = node.InnerHtml;

if (!string.IsNullOrEmpty(text.Trim()))
{
return false;
return true;
}
else if (!string.IsNullOrEmpty(text) &&
node.Previous != null && !node.Previous.IsText && !node.Previous.InnerHtml.EndsWith(whiteSpace) &&
node.Next != null && !node.Next.IsText && !node.Next.InnerHtml.StartsWith(whiteSpace))
{
text = whiteSpace;
return false;
return true;
}

return true;
return false;
}

internal abstract bool CanConvert(DocxNode node);
Expand Down
22 changes: 15 additions & 7 deletions MariGold.OpenXHTML/Elements/DocxBody.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,29 @@ private void ProcessBody(DocxNode node, ref Paragraph paragraph, Dictionary<stri
{
if (node.IsText)
{
if (!IsEmptyText(node, out string text))
if (TryGetText(node, out string text))
{
if (paragraph == null)
if (paragraph == null && !IsEmptyText(text))
{
paragraph = body.AppendChild(new Paragraph());
OnParagraphCreated(node, paragraph);
}

Run run = paragraph.AppendChild(new Run(new Text()
if (paragraph != null)
{
Text = ClearHtml(text),
Space = SpaceProcessingModeValues.Preserve
}));
if (node.Previous != null && node.Previous.InnerHtml.EndsWith(whiteSpace))
{
text = text.TrimStart();
}

RunCreated(node, run);
Run run = paragraph.AppendChild(new Run(new Text()
{
Text = ClearHtml(text),
Space = SpaceProcessingModeValues.Preserve
}));

RunCreated(node, run);
}
}
}
else
Expand Down
8 changes: 5 additions & 3 deletions MariGold.OpenXHTML/Elements/DocxBr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ internal override void Process(DocxNode node, ref Paragraph paragraph, Dictionar
paragraph = node.Parent.AppendChild(new Paragraph());
OnParagraphCreated(node.ParagraphNode, paragraph);
}

Run run = paragraph.AppendChild(new Run(new Break()));
RunCreated(node, run);
else
{
Run run = paragraph.AppendChild(new Run(new Break()));
RunCreated(node, run);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion MariGold.OpenXHTML/Elements/DocxDiv.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal override void Process(DocxNode node, ref Paragraph paragraph, Dictionar
return;
}

//Div creates it's own new paragraph. So old paragraph ends here and creats another one after this div
//Div creates it's own new paragraph. So old paragraph ends here and creates another one after this div
//if there any text!
paragraph = null;
Paragraph divParagraph = null;
Expand Down
16 changes: 15 additions & 1 deletion MariGold.OpenXHTML/Elements/DocxHeading.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
internal sealed class DocxHeading : DocxElement
{
private Regex isValid;
private int number;

private int GetHeaderNumber(DocxNode node)
{
Expand Down Expand Up @@ -64,7 +65,7 @@ private void ApplyStyle(DocxNode node)

if (string.IsNullOrEmpty(fontSizeValue))
{
string headingFontSize = CalculateFontSize(GetHeaderNumber(node));
string headingFontSize = CalculateFontSize(number);
string inheritedStyle = node.ExtractInheritedStyleValue(DocxFontStyle.fontSize);

if (!string.IsNullOrEmpty(inheritedStyle))
Expand All @@ -88,6 +89,16 @@ private void ApplyStyle(DocxNode node)
node.SetExtentedStyle(DocxFontStyle.fontWeight, fontWeightValue);
}

private void OnHeadingParagraphCreated(object sender, ParagraphEventArgs args)
{
if (args.Paragraph.ParagraphProperties == null)
{
args.Paragraph.ParagraphProperties = new ParagraphProperties();
}

args.Paragraph.ParagraphProperties.Append(new ParagraphStyleId() { Val = $"Heading{number}" });
}

internal DocxHeading(IOpenXmlContext context)
: base(context)
{
Expand All @@ -108,8 +119,11 @@ internal override void Process(DocxNode node, ref Paragraph paragraph, Dictionar

paragraph = null;
Paragraph headerParagraph = null;
number = GetHeaderNumber(node);
ApplyStyle(node);

ParagraphCreated = OnHeadingParagraphCreated;

ProcessBlockElement(node, ref headerParagraph, properties);
}
}
Expand Down
21 changes: 14 additions & 7 deletions MariGold.OpenXHTML/Elements/DocxHr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
{
using System;
using System.Collections.Generic;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml.Vml;
using DocumentFormat.OpenXml.Vml.Office;
using DocumentFormat.OpenXml.Wordprocessing;

internal sealed class DocxHr : DocxElement
{
Expand Down Expand Up @@ -32,12 +34,17 @@ internal override void Process(DocxNode node, ref Paragraph paragraph, Dictionar
{
hrParagraph.ParagraphProperties = new ParagraphProperties();
}

ParagraphBorders paragraphBorders = new ParagraphBorders();
DocxBorder.ApplyDefaultBorder<TopBorder>(paragraphBorders);
hrParagraph.ParagraphProperties.Append(paragraphBorders);

Run run = hrParagraph.AppendChild(new Run(new Text()));

var rectangle = new Rectangle();
rectangle.Style = "width:0;height:1.5pt";
rectangle.Horizontal = true;
rectangle.HorizontalStandard = true;
rectangle.FillColor = "#a0a0a0";
rectangle.Stroked = false;
rectangle.HorizontalAlignment = HorizontalRuleAlignmentValues.Center;
var picture = new Picture(rectangle);

Run run = hrParagraph.AppendChild(new Run(picture));
RunCreated(node, run);
}
}
Expand Down
2 changes: 1 addition & 1 deletion MariGold.OpenXHTML/Elements/DocxOL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ private void DefineLevel(NumberFormatValues numberFormat, int levelIndex)
Level level = new Level() { LevelIndex = gLevelId };
StartNumberingValue startNumberingValue = new StartNumberingValue() { Val = 1 };
NumberingFormat numberingFormat = new NumberingFormat() { Val = numberFormat };
LevelText levelText = new LevelText() { Val = $"%{gLevelId + 1})" }; //Later we need a provison to configure this text.
LevelText levelText = new LevelText() { Val = $"%{gLevelId + 1}." }; //Later we need a provison to configure this text.
LevelJustification levelJustification = new LevelJustification() { Val = LevelJustificationValues.Left };

PreviousParagraphProperties previousParagraphProperties = new PreviousParagraphProperties();
Expand Down
5 changes: 3 additions & 2 deletions MariGold.OpenXHTML/Elements/DocxUL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private void InitNumberDefinitions(int levelIndex)
Level level = new Level() { LevelIndex = levelIndex };
StartNumberingValue startNumberingValue = new StartNumberingValue() { Val = 1 };
NumberingFormat numberingFormat = new NumberingFormat() { Val = NumberFormatValues.Bullet };
LevelText levelText = new LevelText() { Val = "·" };
LevelText levelText = new LevelText() { Val = "" };
LevelJustification levelJustification = new LevelJustification() { Val = LevelJustificationValues.Left };

PreviousParagraphProperties previousParagraphProperties = new PreviousParagraphProperties();
Expand All @@ -122,7 +122,8 @@ private void InitNumberDefinitions(int levelIndex)
{
Hint = FontTypeHintValues.Default,
Ascii = "Symbol",
HighAnsi = "Symbol"
HighAnsi = "Symbol",
ComplexScript = "Symbol"
};

numberingSymbolRunProperties.Append(runFonts);
Expand Down
2 changes: 1 addition & 1 deletion MariGold.OpenXHTML/IOpenXmlContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

internal interface IOpenXmlContext
internal interface IOpenXmlContext : IDisposable
{
string ImagePath{ get; set; }
string BaseURL{ get; set; }
Expand Down
50 changes: 43 additions & 7 deletions MariGold.OpenXHTML/OpenXmlContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,39 @@ private void SaveNumberDefinitions()
}
}

private void SaveStyleDefinitions()
{
if (mainPart.StyleDefinitionsPart is null)
{
_ = mainPart.AddNewPart<StyleDefinitionsPart>("styleDefinitionsPart");
}

var styles = new Styles();

// Hyperlink
var hyperlink = new Style { StyleId = "Hyperlink", Type = StyleValues.Character };
hyperlink.StyleName = new StyleName { Val = "Hyperlink" };
hyperlink.UnhideWhenUsed = new UnhideWhenUsed();
if (hyperlink.StyleRunProperties is null)
{
hyperlink.StyleRunProperties = new StyleRunProperties();
}
hyperlink.StyleRunProperties.Append(new Color { Val = "0563C1", ThemeColor = ThemeColorValues.Hyperlink });
hyperlink.StyleRunProperties.Append(new Underline { Val = UnderlineValues.Single });
styles.Append(hyperlink);

// Headings
for (int i = 1; i <= 6; i++)
{
var heading = new Style { StyleId = $"Heading{i}", Type = StyleValues.Paragraph };
heading.StyleName = new StyleName { Val = $"heading {i}" };
heading.LinkedStyle = new LinkedStyle { Val = $"Heading{i}Char" };
styles.Append(heading);
}

mainPart.StyleDefinitionsPart.Styles = styles;
}

internal OpenXmlContext(WordprocessingDocument document)
{
this.document = document;
Expand Down Expand Up @@ -203,14 +236,9 @@ public Int16 ListNumberId
public void Save()
{
SaveNumberDefinitions();
SaveStyleDefinitions();

Document.Save();

document.Close();
document.Dispose();

document = null;
mainPart = null;
document.Save();
}

public DocxElement Convert(DocxNode node)
Expand Down Expand Up @@ -276,5 +304,13 @@ public IDocxInterchanger GetInterchanger()
{
return new DocxInterchanger();
}

public void Dispose()
{
document.Dispose();

document = null;
mainPart = null;
}
}
}
Loading