diff --git a/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/FormattedTextExtensions.cs b/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/FormattedTextExtensions.cs
new file mode 100644
index 0000000..9186104
--- /dev/null
+++ b/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/FormattedTextExtensions.cs
@@ -0,0 +1,116 @@
+using System.Linq;
+using System.Text;
+
+namespace YetAnotherPacketParser.Compiler
+{
+ internal static class FormattedTextExtensions
+ {
+ public static void WriteFormattedText(this FormattedText node, StringBuilder builder)
+ {
+ Verify.IsNotNull(node, nameof(node));
+
+ if (!node.Segments.Any())
+ {
+ return;
+ }
+
+ bool previousBolded = false;
+ bool previousItalic = false;
+ bool previousUnderlined = false;
+ bool previousSubscript = false;
+ bool previousSuperscript = false;
+
+ foreach (FormattedTextSegment segment in node.Segments)
+ {
+ // Close tags before opening new ones
+ if (previousSuperscript && !segment.IsSuperscript)
+ {
+ builder.Append("");
+ previousSuperscript = false;
+ }
+
+ if (previousSubscript && !segment.IsSubscript)
+ {
+ builder.Append("");
+ previousSubscript = false;
+ }
+
+ if (previousItalic && !segment.Italic)
+ {
+ builder.Append("");
+ previousItalic = false;
+ }
+
+ if (previousUnderlined && !segment.Underlined)
+ {
+ builder.Append("");
+ previousUnderlined = false;
+ }
+
+ if (previousBolded ^ segment.Bolded)
+ {
+ builder.Append(segment.Bolded ? "" : "");
+ previousBolded = segment.Bolded;
+ }
+
+ if (!previousBolded && segment.Bolded)
+ {
+ builder.Append("");
+ previousBolded = true;
+ }
+
+ if (!previousUnderlined && segment.Underlined)
+ {
+ builder.Append("");
+ previousUnderlined = true;
+ }
+
+ if (!previousItalic && segment.Italic)
+ {
+ builder.Append("");
+ previousItalic = true;
+ }
+
+ if (!previousSubscript && segment.IsSubscript)
+ {
+ builder.Append("");
+ previousSubscript = true;
+ }
+
+ if (!previousSuperscript && segment.IsSuperscript)
+ {
+ builder.Append("");
+ previousSuperscript = true;
+ }
+
+ builder.Append(segment.Text);
+ }
+
+ // Close any remaining tags
+ if (previousBolded)
+ {
+ builder.Append("");
+ }
+
+ if (previousUnderlined)
+ {
+ builder.Append("");
+ }
+
+ if (previousItalic)
+ {
+ builder.Append("");
+ }
+
+ if (previousSubscript)
+ {
+ builder.Append("");
+ }
+
+ if (previousSuperscript)
+ {
+ builder.Append("");
+ }
+ }
+ }
+}
diff --git a/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Html/HtmlCompiler.cs b/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Html/HtmlCompiler.cs
index 0d94050..0d8d42f 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Html/HtmlCompiler.cs
+++ b/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Html/HtmlCompiler.cs
@@ -1,5 +1,4 @@
using System.Diagnostics;
-using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YetAnotherPacketParser.Ast;
@@ -63,7 +62,7 @@ private static void WriteBonus(BonusNode bonus, StringBuilder builder)
builder.Append("
");
builder.Append(bonus.Number);
builder.Append(". ");
- WriteFormattedText(bonus.Leadin, builder);
+ bonus.Leadin.WriteFormattedText(builder);
builder.Append("
");
foreach (BonusPartNode bonusPart in bonus.Parts)
{
@@ -91,66 +90,11 @@ private static void WriteBonusPart(BonusPartNode bonusPart, StringBuilder builde
private static void WriteQuestion(QuestionNode node, StringBuilder builder)
{
- WriteFormattedText(node.Question, builder);
+ node.Question.WriteFormattedText(builder);
builder.AppendLine("
");
builder.Append("ANSWER: ");
- WriteFormattedText(node.Answer, builder);
+ node.Answer.WriteFormattedText(builder);
builder.AppendLine("
");
}
-
- // TODO: move this somewhere where it can be tested, or merge with JsonCompiler (different tags needed)
- // Would lose some efficiency that way, since we'd recreate a StringBuilder each time
- private static void WriteFormattedText(FormattedText node, StringBuilder builder)
- {
- Verify.IsNotNull(node, nameof(node));
-
- if (!node.Segments.Any())
- {
- return;
- }
-
- bool previousBolded = false;
- bool previousItalic = false;
- bool previousUnderlined = false;
-
- foreach (FormattedTextSegment segment in node.Segments)
- {
- if (previousBolded ^ segment.Bolded)
- {
- builder.Append(segment.Bolded ? "" : "");
- previousBolded = segment.Bolded;
- }
-
- if (previousUnderlined ^ segment.Underlined)
- {
- builder.Append(segment.Underlined ? "" : "");
- previousUnderlined = segment.Underlined;
- }
-
- if (previousItalic ^ segment.Italic)
- {
- builder.Append(segment.Italic ? "" : "");
- previousItalic = segment.Italic;
- }
-
- builder.Append(segment.Text);
- }
-
- // Close any remaining tags
- if (previousBolded)
- {
- builder.Append("");
- }
-
- if (previousUnderlined)
- {
- builder.Append("");
- }
-
- if (previousItalic)
- {
- builder.Append("");
- }
- }
}
}
diff --git a/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Json/JsonBonusNode.cs b/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Json/JsonBonusNode.cs
index edb372b..109f581 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Json/JsonBonusNode.cs
+++ b/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Json/JsonBonusNode.cs
@@ -43,18 +43,18 @@ public JsonBonusNode(BonusNode bonusNode, bool omitSanitizedFields)
public string? Leadin_sanitized { get; }
- public string? Metadata { get; }
+ public ICollection Parts { get; }
+
+ public ICollection? Parts_sanitized { get; }
public ICollection Answers { get; }
public ICollection? Answers_sanitized { get; }
- public ICollection Parts { get; }
-
- public ICollection? Parts_sanitized { get; }
-
public ICollection Values { get; }
public ICollection? DifficultyModifiers { get; }
+
+ public string? Metadata { get; }
}
}
diff --git a/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Json/JsonTextFormatter.cs b/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Json/JsonTextFormatter.cs
index 4ee7905..e1f82b8 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Json/JsonTextFormatter.cs
+++ b/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/Json/JsonTextFormatter.cs
@@ -8,55 +8,8 @@ internal static class JsonTextFormatter
internal static string ToStringWithTags(FormattedText node)
{
Verify.IsNotNull(node, nameof(node));
-
- if (!node.Segments.Any())
- {
- return string.Empty;
- }
-
- bool previousBolded = false;
- bool previousItalic = false;
- bool previousUnderlined = false;
-
StringBuilder builder = new StringBuilder();
- foreach (FormattedTextSegment segment in node.Segments)
- {
- if (previousBolded ^ segment.Bolded)
- {
- builder.Append(segment.Bolded ? "" : "");
- previousBolded = segment.Bolded;
- }
-
- if (previousUnderlined ^ segment.Underlined)
- {
- builder.Append(segment.Underlined ? "" : "");
- previousUnderlined = segment.Underlined;
- }
-
- if (previousItalic ^ segment.Italic)
- {
- builder.Append(segment.Italic ? "" : "");
- previousItalic = segment.Italic;
- }
-
- builder.Append(segment.Text);
- }
-
- // Close any remaining tags
- if (previousBolded)
- {
- builder.Append("");
- }
-
- if (previousUnderlined)
- {
- builder.Append("");
- }
-
- if (previousItalic)
- {
- builder.Append("");
- }
+ node.WriteFormattedText(builder);
return builder.ToString();
}
diff --git a/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/SanitizeHtmlTransformer.cs b/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/SanitizeHtmlTransformer.cs
index c03be5d..cd16776 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/SanitizeHtmlTransformer.cs
+++ b/YetAnotherPacketParser/YetAnotherPacketParser/Compiler/SanitizeHtmlTransformer.cs
@@ -135,7 +135,9 @@ private FormattedText SanitizeFormattedTexts(FormattedText rawFormattedTexts)
sanitizedText,
rawSegment.Italic,
rawSegment.Bolded,
- rawSegment.Underlined);
+ rawSegment.Underlined,
+ rawSegment.IsSubscript,
+ rawSegment.IsSuperscript);
sanitizedFormattedTexts.Add(sanitizedFormattedText);
}
diff --git a/YetAnotherPacketParser/YetAnotherPacketParser/FormattedText.cs b/YetAnotherPacketParser/YetAnotherPacketParser/FormattedText.cs
index 86d4447..25d77b8 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParser/FormattedText.cs
+++ b/YetAnotherPacketParser/YetAnotherPacketParser/FormattedText.cs
@@ -29,7 +29,12 @@ public FormattedText Substring(int startIndex)
{
string substringText = segment.Text.Substring(startIndex - index);
segments.Add(new FormattedTextSegment(
- substringText, segment.Italic, segment.Bolded, segment.Underlined));
+ substringText,
+ segment.Italic,
+ segment.Bolded,
+ segment.Underlined,
+ segment.IsSubscript,
+ segment.IsSuperscript));
}
else if (index >= startIndex)
{
diff --git a/YetAnotherPacketParser/YetAnotherPacketParser/FormattedTextSegment.cs b/YetAnotherPacketParser/YetAnotherPacketParser/FormattedTextSegment.cs
index e530135..2bdc303 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParser/FormattedTextSegment.cs
+++ b/YetAnotherPacketParser/YetAnotherPacketParser/FormattedTextSegment.cs
@@ -4,12 +4,20 @@ namespace YetAnotherPacketParser
{
internal class FormattedTextSegment
{
- public FormattedTextSegment(string text, bool italic = false, bool bolded = false, bool underlined = false)
+ public FormattedTextSegment(
+ string text,
+ bool italic = false,
+ bool bolded = false,
+ bool underlined = false,
+ bool isSubscript = false,
+ bool isSuperscript = false)
{
this.Text = text ?? throw new ArgumentNullException(nameof(text));
this.Italic = italic;
this.Bolded = bolded;
this.Underlined = underlined;
+ this.IsSubscript = isSubscript;
+ this.IsSuperscript = isSuperscript;
}
public string Text { get; }
@@ -20,12 +28,18 @@ public FormattedTextSegment(string text, bool italic = false, bool bolded = fals
public bool Underlined { get; }
+ public bool IsSubscript { get; }
+
+ public bool IsSuperscript { get; }
+
public override string ToString()
{
string boldedString = this.Bolded ? "bolded, " : string.Empty;
string italicString = this.Italic ? "italic, " : string.Empty;
string underlinedString = this.Underlined ? "underlined, " : string.Empty;
- string propertiesString = $"{boldedString}{italicString}{underlinedString}".Trim();
+ string subscriptString = this.IsSubscript ? "subscript, " : string.Empty;
+ string superscriptString = this.IsSuperscript ? "superscript, " : string.Empty;
+ string propertiesString = $"{boldedString}{italicString}{underlinedString}{subscriptString}{superscriptString}".Trim();
return $"({propertiesString}) {this.Text}";
}
@@ -39,7 +53,9 @@ public override bool Equals(object? obj)
return this.Text == other.Text &&
this.Bolded == other.Bolded &&
this.Italic == other.Italic &&
- this.Underlined == other.Underlined;
+ this.Underlined == other.Underlined &&
+ this.IsSubscript == other.IsSubscript &&
+ this.IsSuperscript == other.IsSuperscript;
}
public override int GetHashCode()
@@ -47,7 +63,9 @@ public override int GetHashCode()
return (this.Text?.GetHashCode(StringComparison.Ordinal) ?? 0) ^
this.Bolded.GetHashCode() ^
(this.Italic.GetHashCode() << 1) ^
- (this.Underlined.GetHashCode() << 2);
+ (this.Underlined.GetHashCode() << 2) ^
+ (this.IsSubscript.GetHashCode() << 3) ^
+ (this.IsSuperscript.GetHashCode() << 4);
}
}
}
diff --git a/YetAnotherPacketParser/YetAnotherPacketParser/Lexer/DocxLexer.cs b/YetAnotherPacketParser/YetAnotherPacketParser/Lexer/DocxLexer.cs
index f57ef4e..d586717 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParser/Lexer/DocxLexer.cs
+++ b/YetAnotherPacketParser/YetAnotherPacketParser/Lexer/DocxLexer.cs
@@ -143,6 +143,8 @@ private static List GetLinesFromTextBlockLines(IEnumerable
bool bolded = false;
bool italic = false;
bool underlined = false;
+ bool subscripted = false;
+ bool superscripted = false;
List lines = new List();
foreach (TextBlockLine textBlockLine in textBlockLines)
@@ -156,20 +158,31 @@ private static List GetLinesFromTextBlockLines(IEnumerable
bool blockBolded = false;
bool blockItalic = false;
bool blockUnderlined = false;
+ bool blockSubscripted = false;
+ bool blockSuperscripted = false;
if (textBlock.Properties != null)
{
+ string? verticalTextAlignmentVal = textBlock.Properties.VerticalTextAlignment?.Val?.ToString();
+
blockBolded = textBlock.Properties.Bold != null;
blockItalic = textBlock.Properties.Italic != null;
blockUnderlined = textBlock.Properties.Underline != null;
+ blockSubscripted = verticalTextAlignmentVal == "subscript";
+ blockSuperscripted = verticalTextAlignmentVal == "superscript";
}
- if (blockBolded != bolded || blockItalic != italic || blockUnderlined != underlined)
+ if (blockBolded != bolded ||
+ blockItalic != italic ||
+ blockUnderlined != underlined ||
+ blockSubscripted != subscripted ||
+ blockSuperscripted != superscripted)
{
// Formatting has changed. This means the last segment finished. Add it if it has anything.
if (currentSegment.Length > 0)
{
formattedTextSegments.Add(
- new FormattedTextSegment(currentSegment.ToString(), italic, bolded, underlined));
+ new FormattedTextSegment(
+ currentSegment.ToString(), italic, bolded, underlined, subscripted, superscripted));
currentSegment.Clear();
}
@@ -177,6 +190,8 @@ private static List GetLinesFromTextBlockLines(IEnumerable
bolded = blockBolded;
italic = blockItalic;
underlined = blockUnderlined;
+ subscripted = blockSubscripted;
+ superscripted = blockSuperscripted;
}
currentSegment.Append(textBlock.Text);
@@ -195,7 +210,8 @@ private static List GetLinesFromTextBlockLines(IEnumerable
// Add the remainder of the line
if (currentSegment.Length > 0)
{
- formattedTextSegments.Add(new FormattedTextSegment(currentSegment.ToString(), italic, bolded, underlined));
+ formattedTextSegments.Add(new FormattedTextSegment(
+ currentSegment.ToString(), italic, bolded, underlined, subscripted, superscripted));
currentSegment.Clear();
}
diff --git a/YetAnotherPacketParser/YetAnotherPacketParser/Lexer/HtmlLexer.cs b/YetAnotherPacketParser/YetAnotherPacketParser/Lexer/HtmlLexer.cs
index 630c92f..7929eee 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParser/Lexer/HtmlLexer.cs
+++ b/YetAnotherPacketParser/YetAnotherPacketParser/Lexer/HtmlLexer.cs
@@ -66,7 +66,9 @@ private static IList GetTextLines(IHtmlElement body)
paragraph.TextContent,
previousFormatting.Italic,
previousFormatting.Bolded,
- previousFormatting.Underlined)
+ previousFormatting.Underlined,
+ previousFormatting.Subscripted,
+ previousFormatting.Superscripted)
}));
}
@@ -141,14 +143,20 @@ private static IResult> ClassifyLines(IList fo
if (!node.HasChildNodes && !string.IsNullOrEmpty(node.TextContent))
{
segments.Add(new FormattedTextSegment(
- node.TextContent, formatting.Italic, formatting.Bolded, formatting.Underlined));
+ node.TextContent,
+ formatting.Italic,
+ formatting.Bolded,
+ formatting.Underlined,
+ formatting.Subscripted,
+ formatting.Superscripted));
return;
}
bool isElement = node.NodeType == NodeType.Element;
IElement? element = node as Element;
- // Need to change formatting if it's B/REQ, U, or I/EM. For other ones, just call GetString on the child.
+ // Need to change formatting if it's B/REQ, U, I/EM, SUB, or SUP. For other ones, just call GetString on
+ // the child.
if (isElement && element != null)
{
if (segments.Count > 0 && (element.TagName == "P" || element.TagName == "BR"))
@@ -197,6 +205,12 @@ private static void UpdateFormatting(Formatting formatting, IElement element, bo
case "U":
formatting.Underlined = value;
break;
+ case "SUB":
+ formatting.Subscripted = value;
+ break;
+ case "SUP":
+ formatting.Superscripted = value;
+ break;
default:
break;
}
@@ -208,6 +222,10 @@ private class Formatting
public bool Italic { get; set; }
public bool Underlined { get; set; }
+
+ public bool Superscripted { get; set; }
+
+ public bool Subscripted { get; set; }
}
}
}
diff --git a/YetAnotherPacketParser/YetAnotherPacketParser/YetAnotherPacketParser.csproj b/YetAnotherPacketParser/YetAnotherPacketParser/YetAnotherPacketParser.csproj
index 8063818..f163125 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParser/YetAnotherPacketParser.csproj
+++ b/YetAnotherPacketParser/YetAnotherPacketParser/YetAnotherPacketParser.csproj
@@ -17,9 +17,9 @@
quizbowl packetparser quizbowlpacketparser
https://github.com/alopezlago/YetAnotherPacketParser
LICENSE.txt
- 1.1.1.0
- 1.1.1.0
- 1.1.1.0
+ 1.2.0.0
+ 1.2.0.0
+ 1.2.0.0
true
Recommended
All
diff --git a/YetAnotherPacketParser/YetAnotherPacketParserCommandLine/YetAnotherPacketParserCommandLine.csproj b/YetAnotherPacketParser/YetAnotherPacketParserCommandLine/YetAnotherPacketParserCommandLine.csproj
index 81e9567..cb24eca 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParserCommandLine/YetAnotherPacketParserCommandLine.csproj
+++ b/YetAnotherPacketParser/YetAnotherPacketParserCommandLine/YetAnotherPacketParserCommandLine.csproj
@@ -9,9 +9,9 @@
(c) 2020 Alejandro Lopez-Lago
Yet Another Packet Parser parses quiz bowl packets and translates them to different formats
YAPP
- 1.1.1.0
- 1.1.1.0
- 1.1.1.0
+ 1.2.0.0
+ 1.2.0.0
+ 1.2.0.0
true
Recommended
All
diff --git a/YetAnotherPacketParser/YetAnotherPacketParserTests/FormattedTextTests.cs b/YetAnotherPacketParser/YetAnotherPacketParserTests/FormattedTextTests.cs
new file mode 100644
index 0000000..bbae6ca
--- /dev/null
+++ b/YetAnotherPacketParser/YetAnotherPacketParserTests/FormattedTextTests.cs
@@ -0,0 +1,37 @@
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using YetAnotherPacketParser;
+using YetAnotherPacketParser.Compiler;
+
+namespace YetAnotherPacketParserTests
+{
+ [TestClass]
+ public class FormattedTextTests
+ {
+ [TestMethod]
+ public void TestFormat()
+ {
+ FormattedTextSegment[] segments = new FormattedTextSegment[]
+ {
+ new FormattedTextSegment("First"),
+ new FormattedTextSegment("Second", italic: true),
+ new FormattedTextSegment("Third", italic: true, bolded: true),
+ new FormattedTextSegment("Fourth", italic: true, bolded: true, underlined: true),
+ new FormattedTextSegment("Fifth", italic: true, bolded: true, underlined: true, isSubscript: true),
+ new FormattedTextSegment("Sixth", italic: true, bolded: true, underlined: true, isSuperscript: true),
+ new FormattedTextSegment("Seventh", italic: true, bolded: true, underlined: true),
+ new FormattedTextSegment("Eighth", italic: true, bolded: true),
+ new FormattedTextSegment("Ninth", italic: true),
+ new FormattedTextSegment("Tenth"),
+ };
+
+ FormattedText text = new FormattedText(segments);
+ StringBuilder builder = new StringBuilder();
+ text.WriteFormattedText(builder);
+
+ Assert.AreEqual(
+ "FirstSecondThirdFourthFifthSixthSeventhEighthNinthTenth",
+ builder.ToString());
+ }
+ }
+}
diff --git a/YetAnotherPacketParser/YetAnotherPacketParserTests/HtmlLexerTests.cs b/YetAnotherPacketParser/YetAnotherPacketParserTests/HtmlLexerTests.cs
index e14a76d..779dcfb 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParserTests/HtmlLexerTests.cs
+++ b/YetAnotherPacketParser/YetAnotherPacketParserTests/HtmlLexerTests.cs
@@ -18,7 +18,7 @@ public async Task ParseHtml()
const string htmlPacket = @"
- 1. This is a tossup. Underline and italics.
+ 1. This is a tossup. Underline and italics. H20 and x2.
ANSWER: Tossup Answer
@@ -76,6 +76,10 @@ public async Task ParseHtml()
new FormattedTextSegment("Underline", underlined: true),
new FormattedTextSegment(" and "),
new FormattedTextSegment("italics", italic: true),
+ new FormattedTextSegment(". H"),
+ new FormattedTextSegment("2", isSubscript: true),
+ new FormattedTextSegment("0 and x"),
+ new FormattedTextSegment("2", isSuperscript: true),
new FormattedTextSegment(".\n ")
};
CollectionAssert.AreEqual(
diff --git a/YetAnotherPacketParser/YetAnotherPacketParserTests/JsonCompilerTests.cs b/YetAnotherPacketParser/YetAnotherPacketParserTests/JsonCompilerTests.cs
index b0b663d..eec41f0 100644
--- a/YetAnotherPacketParser/YetAnotherPacketParserTests/JsonCompilerTests.cs
+++ b/YetAnotherPacketParser/YetAnotherPacketParserTests/JsonCompilerTests.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using YetAnotherPacketParser;
using YetAnotherPacketParser.Ast;