Skip to content

Commit

Permalink
Extract TagAttributeCollection with TrailingWhitespace property.
Browse files Browse the repository at this point in the history
This also fixes the bug that TrailingWhitespace and ClosingTagTrailingWhitespace are mistakenly using the same field.
  • Loading branch information
CXuesong committed Aug 17, 2017
1 parent 53dfe39 commit a2e7478
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 26 deletions.
30 changes: 7 additions & 23 deletions MwParserFromScratch/Nodes/Inline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,8 @@ public enum TagStyle
/// </summary>
public abstract class TagNode : InlineNode
{
private string _TrailingWhitespace;

private string _ClosingTagTrailingWhitespace;
private TagStyle _TagStyle;

public TagNode() : this(null)
Expand All @@ -495,7 +496,7 @@ public TagNode() : this(null)
public TagNode(string name)
{
Name = name;
Attributes = new NodeCollection<TagAttribute>(this);
Attributes = new TagAttributeCollection(this);
}

/// <summary>
Expand Down Expand Up @@ -524,35 +525,21 @@ public virtual TagStyle TagStyle
}
}

/// <summary>
/// The trailing whitespace for the opening tag, before &gt; or /&gt; .
/// </summary>
/// <exception cref="ArgumentException">The string contains non-white-space characters.</exception>
public string TrailingWhitespace
{
get { return _TrailingWhitespace; }
set
{
Utility.AssertNullOrWhiteSpace(value);
_TrailingWhitespace = value;
}
}

/// <summary>
/// The trailing whitespace for the closing tag.
/// </summary>
/// <exception cref="ArgumentException">The string contains non-white-space characters.</exception>
public string ClosingTagTrailingWhitespace
{
get { return _TrailingWhitespace; }
get { return _ClosingTagTrailingWhitespace; }
set
{
Utility.AssertNullOrWhiteSpace(value);
_TrailingWhitespace = value;
_ClosingTagTrailingWhitespace = value;
}
}

public NodeCollection<TagAttribute> Attributes { get; }
public TagAttributeCollection Attributes { get; }

protected abstract string GetContentString();

Expand All @@ -573,8 +560,7 @@ public override string ToString()
{
var sb = new StringBuilder("<");
sb.Append(Name);
sb.Append(string.Join(null, Attributes));
sb.Append(TrailingWhitespace);
sb.Append(Attributes);
switch (TagStyle)
{
case TagStyle.Normal:
Expand Down Expand Up @@ -641,7 +627,6 @@ protected override Node CloneCore()
Name = Name,
ClosingTagName = ClosingTagName,
Content = Content,
TrailingWhitespace = TrailingWhitespace,
ClosingTagTrailingWhitespace = ClosingTagTrailingWhitespace,
};
n.Attributes.Add(Attributes);
Expand Down Expand Up @@ -721,7 +706,6 @@ protected override Node CloneCore()
Name = Name,
ClosingTagName = ClosingTagName,
Content = Content,
TrailingWhitespace = TrailingWhitespace,
ClosingTagTrailingWhitespace = ClosingTagTrailingWhitespace,
};
n.Attributes.Add(Attributes);
Expand Down
39 changes: 39 additions & 0 deletions MwParserFromScratch/Nodes/TagAttributeCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace MwParserFromScratch.Nodes
{
public class TagAttributeCollection : NodeCollection<TagAttribute>
{
private string _TrailingWhitespace;

internal TagAttributeCollection(Node owner) : base(owner)
{
}

/// <summary>
/// The trailing whitespace after the last tag attribute.
/// </summary>
/// <exception cref="ArgumentException">The string contains non-white-space characters.</exception>
public string TrailingWhitespace
{
get { return _TrailingWhitespace; }
set
{
Utility.AssertNullOrWhiteSpace(value);
_TrailingWhitespace = value;
}
}

/// <inheritdoc />
public override string ToString()
{
var sb = new StringBuilder();
foreach (var attr in this)
sb.Append(attr);
sb.Append(_TrailingWhitespace);
return sb.ToString();
}
}
}
2 changes: 1 addition & 1 deletion MwParserFromScratch/ParserCore.Expandable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ private TagNode ParseTag()
ParseSuccessful(attr);
node.Attributes.Add(attr);
}
node.TrailingWhitespace = ws;
node.Attributes.TrailingWhitespace = ws;
if (rbracket == "/>")
{
node.TagStyle = TagStyle.SelfClosing;
Expand Down
17 changes: 15 additions & 2 deletions UnitTestProject1/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ internal static class Utility
{
private static readonly Dictionary<Type, Func<Node, string>> dumpHandlers = new Dictionary<Type, Func<Node, string>>();

private static readonly WikitextParserOptions DefaultParserOptions = new WikitextParserOptions();

private static void RegisterDumpHandler<T>(Func<T, string> handler) where T : Node
{
dumpHandlers.Add(typeof(T), n => handler((T) n));
Expand Down Expand Up @@ -84,7 +86,7 @@ static Utility()
var sb = new StringBuilder("<");
sb.Append(n.Name);
sb.Append(string.Join(null, n.Attributes.Select(Dump)));
sb.Append(n.TrailingWhitespace);
sb.Append(n.Attributes.TrailingWhitespace);
switch (n.TagStyle)
{
case TagStyle.Normal:
Expand Down Expand Up @@ -147,8 +149,19 @@ public static Wikitext ParseWikitext(string text)
/// 1. Whether the parsed AST can be converted back to the same wikitext as input.
/// 2. Whether the parsed AST is correct.
/// </summary>
public static Wikitext ParseAndAssert(string text, string expectedDump, WikitextParserOptions options = null)
public static Wikitext ParseAndAssert(string text, string expectedDump)
{
return ParseAndAssert(text, expectedDump, DefaultParserOptions);
}

/// <summary>
/// Parses wikitext, and asserts
/// 1. Whether the parsed AST can be converted back to the same wikitext as input.
/// 2. Whether the parsed AST is correct.
/// </summary>
public static Wikitext ParseAndAssert(string text, string expectedDump, WikitextParserOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));
var parser = new WikitextParser {Options = options};
var root = parser.Parse(text);
var parsedText = root.ToString();
Expand Down

0 comments on commit a2e7478

Please sign in to comment.