Skip to content

Commit

Permalink
Refactored code.
Browse files Browse the repository at this point in the history
  • Loading branch information
egonl committed Dec 23, 2017
1 parent a2ef61a commit 6ebc223
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 170 deletions.
14 changes: 8 additions & 6 deletions SharpDocx/CodeBlockBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using SharpDocx.CodeBlocks;
using SharpDocx.Extensions;
using SharpDocx.Models;

Expand Down Expand Up @@ -79,14 +80,14 @@ private void AppendCodeBlocks(CharacterMap map, bool replaceCodeWithPlaceholder)
for (var i = firstCodeBlockIndex; i < CodeBlocks.Count; ++i)
{
// Find out where conditional content ends.
var cb = CodeBlocks[i] as ConditionalCodeBlock;
var cb = CodeBlocks[i] as ConditionalText;
if (cb != null)
{
var bracketLevel = cb.CurlyBracketLevelIncrement;
var bracketLevel = cb.Code.GetCurlyBracketLevelIncrement();

for (var j = i + 1; j < CodeBlocks.Count; ++j)
{
bracketLevel += CodeBlocks[j].CurlyBracketLevelIncrement;
bracketLevel += CodeBlocks[j].Code.GetCurlyBracketLevelIncrement();

if (bracketLevel <= 0)
{
Expand All @@ -113,11 +114,12 @@ private static CodeBlock GetCodeBlock(string code)
{
cb = new Directive(code.Substring(1));
}
else if (code.StartsWith("if(") && CodeBlock.GetCurlyBracketLevelIncrement(code) > 0)
else if (code.Replace(" ", String.Empty).StartsWith("if(") &&
code.GetCurlyBracketLevelIncrement() > 0)
{
cb = new ConditionalCodeBlock(code)
cb = new ConditionalText(code)
{
Condition = CodeBlock.GetExpressionInBrackets(code),
Condition = code.GetExpressionInBrackets(),
};
}
else
Expand Down
36 changes: 36 additions & 0 deletions SharpDocx/CodeBlocks/CodeBlock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using DocumentFormat.OpenXml.Wordprocessing;
using SharpDocx.Extensions;

namespace SharpDocx.CodeBlocks
{
public class CodeBlock
{
public string Code { get; }

public Text Placeholder { get; internal set; }

internal Text StartText { get; set; }

internal Text EndText { get; set; }

public CodeBlock(string code)
{
Code = code;
}

internal void RemoveEmptyParagraphs()
{
var startParagraph = StartText.GetParent<Paragraph>();
if (startParagraph?.Parent != null && !startParagraph.HasText())
{
startParagraph.Remove();
}

var endParagraph = EndText.GetParent<Paragraph>();
if (endParagraph?.Parent != null && !endParagraph.HasText())
{
endParagraph.Remove();
}
}
}
}
18 changes: 18 additions & 0 deletions SharpDocx/CodeBlocks/ConditionalText.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using DocumentFormat.OpenXml.Wordprocessing;

namespace SharpDocx.CodeBlocks
{
/// <summary>
/// ConditionalText is used to conditionally show or hide Word elements.
/// </summary>
public class ConditionalText : CodeBlock
{
public string Condition { get; set; }

public Text EndConditionalPart { get; set; }

public ConditionalText(string code) : base(code)
{
}
}
}
5 changes: 2 additions & 3 deletions SharpDocx/Directive.cs → SharpDocx/CodeBlocks/Directive.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using SharpDocx.Extensions;
using SharpDocx.Models;

namespace SharpDocx
namespace SharpDocx.CodeBlocks
{
public class Directive : CodeBlock
{
Expand All @@ -19,7 +18,7 @@ public Directive(string code) : base(code)

do
{
stringExpression = GetExpressionInApostrophes(code, startIndex);
stringExpression = code.GetExpressionInApostrophes(startIndex);
if (stringExpression != null)
{
// Replace attribute values enclosed in apostrophes with guids to avoid parsing problems later.
Expand Down
16 changes: 8 additions & 8 deletions SharpDocx/DocumentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using SharpDocx.CodeBlocks;
using SharpDocx.Extensions;
using SharpDocx.Models;

namespace SharpDocx
{
public abstract class DocumentBase
{
public string ImageDirectory { get; set; }

public string ViewPath { get; private set; }

protected readonly ElementAppender<Paragraph> ParagraphAppender = new ElementAppender<Paragraph>();

protected readonly ElementAppender<TableRow> RowAppender = new ElementAppender<TableRow>();
Expand All @@ -22,10 +26,6 @@ public abstract class DocumentBase

protected WordprocessingDocument Package;

public string ImageDirectory { get; set; }

public string ViewPath { get; private set; }

protected abstract void InvokeDocumentCode();

protected abstract void SetModel(object model);
Expand Down Expand Up @@ -73,7 +73,7 @@ internal void Init(string viewPath, object model)

protected void Write(object o)
{
string s = ToString(o);
var s = ToString(o);

var lines = s.Split('\n');
if (lines.Length == 1)
Expand All @@ -85,7 +85,7 @@ protected void Write(object o)
CurrentCodeBlock.Placeholder.Text = lines[0];
var lastText = CurrentCodeBlock.Placeholder;

for (int i = 1; i < lines.Length; ++i)
for (var i = 1; i < lines.Length; ++i)
{
var br = lastText.InsertAfterSelf(new Break());
lastText = br.InsertAfterSelf(new Text(lines[i]));
Expand All @@ -105,7 +105,7 @@ protected void Replace(string oldValue, string newValue, int startIndex = 0,

protected void DeleteConditionalContent()
{
var ccb = (ConditionalCodeBlock) CurrentCodeBlock;
var ccb = (ConditionalText) CurrentCodeBlock;
Map.Delete(ccb.Placeholder, ccb.EndConditionalPart);
}

Expand Down
6 changes: 3 additions & 3 deletions SharpDocx/DocumentCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
using System.Text;
using DocumentFormat.OpenXml.Packaging;
using Microsoft.CSharp;
using SharpDocx.Models;
using SharpDocx.CodeBlocks;

namespace SharpDocx
{
Expand Down Expand Up @@ -101,9 +101,9 @@ internal static Assembly Compile(
AddReferencedAssembly(directive, referencedAssemblies);
}
}
else if (cb is ConditionalCodeBlock)
else if (cb is ConditionalText)
{
var ccb = (ConditionalCodeBlock) cb;
var ccb = (ConditionalText) cb;
invokeDocumentCodeBody.Append($" CurrentCodeBlock = CodeBlocks[{i}];{Environment.NewLine}");
invokeDocumentCodeBody.Append($" if (!{ccb.Condition}) {{{Environment.NewLine}");
invokeDocumentCodeBody.Append($" DeleteConditionalContent();{Environment.NewLine}");
Expand Down
2 changes: 1 addition & 1 deletion SharpDocx/ElementAppender.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using DocumentFormat.OpenXml;
using SharpDocx.CodeBlocks;
using SharpDocx.Extensions;
using SharpDocx.Models;

namespace SharpDocx
{
Expand Down
89 changes: 89 additions & 0 deletions SharpDocx/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,94 @@ public static string RemoveRedundantWhitespace(this string s)

return sb.ToString();
}

public static int GetCurlyBracketLevelIncrement(this string s)
{
// Note: since this isn't a proper C# parser, this code won't work properly when there are curly brackets in comments/strings/etc.
var increment = 0;

foreach (var c in s)
{
if (c == '{')
{
++increment;
}
else if (c == '}')
{
--increment;
}
}

return increment;
}

public static string GetExpression(this string s, char startExpression, char endExpression, int startIndex = 0)
{
// Note: same issue as above.
startIndex = s.IndexOf(startExpression, startIndex);
if (startIndex == -1)
{
return null;
}

var expression = new StringBuilder();
var increment = 0;
for (var i = startIndex; i < s.Length; ++i)
{
expression.Append(s[i]);

if (s[i] == startExpression)
{
++increment;
}
else if (s[i] == endExpression)
{
--increment;
}

if (increment == 0)
{
return expression.ToString();
}
}

return null;
}

public static string GetExpressionInBrackets(this string s, int startIndex = 0)
{
return s.GetExpression('(', ')', startIndex);
}

public static string GetExpression(this string s, string startOrEndTag, int startIndex = 0,
bool removeStartAndEndTag = true)
{
// The start/end tag can be escaped with '\'.
s = s.Replace("\\" + startOrEndTag, "b260231509a148aa9d751a5a9d79abd7");

startIndex = s.IndexOf(startOrEndTag, startIndex);
if (startIndex == -1)
{
return null;
}

var endIndex = s.IndexOf(startOrEndTag, startIndex + startOrEndTag.Length);
if (endIndex == -1)
{
return null;
}

s = removeStartAndEndTag
? s.Substring(startIndex + 1, endIndex - startIndex - 1)
: s.Substring(startIndex, endIndex - startIndex + 1);

return s.Replace("b260231509a148aa9d751a5a9d79abd7", "\\" + startOrEndTag);
}

public static string GetExpressionInApostrophes(this string s, int startIndex = 0,
bool removeApostrophes = true)
{
return s.GetExpression("\"", startIndex, removeApostrophes);
}
}
}
Loading

0 comments on commit 6ebc223

Please sign in to comment.