Skip to content

Commit

Permalink
Merge pull request #21 from alopezlago/alopezlago/public_0_2_2_0
Browse files Browse the repository at this point in the history
v 0.2.2 - support difficulty markings
  • Loading branch information
alopezlago committed Jul 7, 2021
2 parents d6c1474 + d60269f commit 4ca4e35
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ namespace YetAnotherPacketParser.Ast
{
public class BonusPartNode
{
public BonusPartNode(QuestionNode question, int value)
public BonusPartNode(QuestionNode question, int value, char? difficultyModifier)
{
this.Question = question ?? throw new ArgumentNullException(nameof(question));
this.Value = value;
this.DifficultyModifier = difficultyModifier;
}

public QuestionNode Question { get; }

public int Value { get; }

public char? DifficultyModifier { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ private static void WriteBonusPart(BonusPartNode bonusPart, StringBuilder builde
{
builder.Append('[');
builder.Append(bonusPart.Value);
builder.Append(bonusPart.DifficultyModifier);
builder.Append("] ");
WriteQuestion(bonusPart.Question, builder);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using YetAnotherPacketParser.Ast;

namespace YetAnotherPacketParser.Compiler.Json
Expand All @@ -16,13 +17,18 @@ public JsonBonusNode(BonusNode bonusNode)
this.Parts = new List<string>();
this.Parts_sanitized = new List<string>();
this.Values = new List<int>();

this.DifficultModifiers = partNodes.Any(node => node.DifficultyModifier.HasValue) ? new List<char?>() : null;

foreach (BonusPartNode partNode in partNodes)
{
this.Answers.Add(JsonTextFormatter.ToStringWithTags(partNode.Question.Answer));
this.Answers_sanitized.Add(JsonTextFormatter.ToStringWithoutTags(partNode.Question.Answer));
this.Parts.Add(JsonTextFormatter.ToStringWithTags(partNode.Question.Question));
this.Parts_sanitized.Add(JsonTextFormatter.ToStringWithoutTags(partNode.Question.Question));
this.Values.Add(partNode.Value);

this.DifficultModifiers?.Add(partNode.DifficultyModifier);
}
}

Expand All @@ -39,5 +45,7 @@ public JsonBonusNode(BonusNode bonusNode)
public ICollection<string> Parts_sanitized { get; }

public ICollection<int> Values { get; }

public ICollection<char?>? DifficultModifiers { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public async Task<string> CompileAsync(PacketNode packet)
{
AllowTrailingCommas = true,
PropertyNamingPolicy = new PascalCaseJsonNamingPolicy(),
WriteIndented = this.Options.PrettyPrint
WriteIndented = this.Options.PrettyPrint,
IgnoreNullValues = true
};

// TODO: If we decide to host this directly in an ASP.Net context, remove ConfigureAwait calls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private BonusNode SanitizeBonus(BonusNode node)
private BonusPartNode SanitizeBonusPart(BonusPartNode node)
{
QuestionNode sanitizedQuestion = this.SanitizeQuestion(node.Question);
return new BonusPartNode(sanitizedQuestion, node.Value);
return new BonusPartNode(sanitizedQuestion, node.Value, node.DifficultyModifier);
}

private QuestionNode SanitizeQuestion(QuestionNode node)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
{
public class BonusPartLine : ILine
{
public BonusPartLine(FormattedText text, int value)
public BonusPartLine(FormattedText text, int value, char? difficultyModifier)
{
this.Text = text;
this.Value = value;
this.DifficultyModifier = difficultyModifier;
}

public LineType Type => LineType.BonusPart;
Expand All @@ -14,6 +15,8 @@ public BonusPartLine(FormattedText text, int value)

public int Value { get; }

public char? DifficultyModifier { get; }

public override string ToString()
{
return Strings.BonusPart(this.Value, this.Text.ToString());
Expand Down
26 changes: 20 additions & 6 deletions YetAnotherPacketParser/YetAnotherPacketParser/Lexer/DocxLexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ public class DocxLexer : ILexer

// Include spaces after the start tag so we get all of the spaces in a match, and we can avoid having to trim
// them manually.
private static readonly Regex AnswerRegEx = new Regex("^\\s*ANS(WER)?\\s*(:|\\.)\\s*", RegexOptions.IgnoreCase);
private static readonly Regex AnswerRegEx = new Regex(
"^\\s*ANS(WER)?\\s*(:|\\.)\\s*", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex QuestionDigitRegEx = new Regex(
"^\\s*(\\d+|tb|tie(breaker)?)\\s*\\.\\s*", RegexOptions.IgnoreCase);
private static readonly Regex BonusPartValueRegex = new Regex("^\\s*\\[\\s*(\\d)+\\s*\\]\\s*");
"^\\s*(\\d+|tb|tie(breaker)?)\\s*\\.\\s*", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex BonusPartValueRegex = new Regex(
"^\\s*\\[\\s*(\\d)+\\s*[ehm]?\\s*\\]\\s*", RegexOptions.Compiled);

/// <summary>
/// Gets the lines from the .docx file, with metadata indicating what type of line it is.
Expand Down Expand Up @@ -241,10 +243,10 @@ private static List<ILine> GetLinesFromTextBlockLines(IEnumerable<TextBlockLine>
{
line = new AnswerLine(formattedText.Substring(matchValue.Length));
}
else if (TextStartsWithBonsuPart(unformattedText, out matchValue, out int? partValue) &&
else if (TextStartsWithBonsuPart(unformattedText, out matchValue, out int? partValue, out char? difficultyModifier) &&
partValue != null)
{
line = new BonusPartLine(formattedText.Substring(matchValue.Length), partValue.Value);
line = new BonusPartLine(formattedText.Substring(matchValue.Length), partValue.Value, difficultyModifier);
}
else
{
Expand Down Expand Up @@ -292,9 +294,11 @@ private static bool TextStartsWithAnswer(string text, out string matchValue)
return true;
}

private static bool TextStartsWithBonsuPart(string text, out string matchValue, out int? partValue)
private static bool TextStartsWithBonsuPart(
string text, out string matchValue, out int? partValue, out char? difficultyModifier)
{
partValue = null;
difficultyModifier = null;
Match match = BonusPartValueRegex.Match(text);
if (!match.Success)
{
Expand All @@ -307,6 +311,16 @@ private static bool TextStartsWithBonsuPart(string text, out string matchValue,
.Replace("[", string.Empty, StringComparison.Ordinal)
.Replace("]", string.Empty, StringComparison.Ordinal)
.Trim();


// If there's a difficulty modifier at the last character, include it. It's optional.
char lastLetter = partValueText[^1];
if (char.IsLetter(lastLetter))
{
difficultyModifier = lastLetter;
partValueText = partValueText.Substring(0, partValueText.Length - 1);
}

if (!int.TryParse(partValueText, out int value))
{
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ private static IResult<BonusPartNode> ParseBonusPart(LinesEnumerator lines, int
return new FailureResult<BonusPartNode>(questionResult.ErrorMessages);
}

return new SuccessResult<BonusPartNode>(new BonusPartNode(questionResult.Value, partValue));
return new SuccessResult<BonusPartNode>(
new BonusPartNode(questionResult.Value, partValue, bonusPartLine.DifficultyModifier));
}

private static IResult<QuestionNode> ParseQuestion(LinesEnumerator lines, string context)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
Expand All @@ -17,15 +17,15 @@
<PackageTags>quizbowl packetparser quizbowlpacketparser</PackageTags>
<PackageProjectUrl>https://github.com/alopezlago/YetAnotherPacketParser</PackageProjectUrl>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<AssemblyVersion>0.2.1.0</AssemblyVersion>
<FileVersion>0.2.1.0</FileVersion>
<Version>0.2.1.0</Version>
<AssemblyVersion>0.2.2.0</AssemblyVersion>
<FileVersion>0.2.2.0</FileVersion>
<Version>0.2.2.0</Version>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.12.1" />
<PackageReference Include="HtmlSanitizer" Version="5.0.376" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.2">
<PackageReference Include="HtmlSanitizer" Version="5.0.404" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,32 @@ public void BonusWithNoBonusPartsFails()
Assert.AreEqual(1, packetResult.ErrorMessages.Count());
}

[TestMethod]
public void BonusPartWithDifficultyModifierSucceeds()
{
const char modifier = 'h';
ILine[] lines = new ILine[]
{
CreateQuestionLine(1, "Tossup"),
CreateAnswerLine("Answer"),
CreateQuestionLine(1, "Bonus leadin"),
CreatePartLine("Bonus part that is", 10, modifier),
CreateAnswerLine("The answer")
};

LinesParser parser = new LinesParser();
IResult<PacketNode> packetResult = parser.Parse(lines);
Assert.IsTrue(packetResult.Success);
Assert.IsNotNull(packetResult.Value.Bonuses);
Assert.AreEqual(1, packetResult.Value.Bonuses?.Count(), "Unexpected number of bonuses");

BonusNode bonus = packetResult.Value.Bonuses.First();
Assert.AreEqual(1, bonus.Parts.Count(), "Unexpected number of parts");

BonusPartNode bonusPart = bonus.Parts.First();
Assert.AreEqual(modifier, bonusPart.DifficultyModifier);
}

[TestMethod]
public void TossupWithNoAnswerFails()
{
Expand Down Expand Up @@ -414,9 +440,9 @@ private static FormattedText CreateFormattedText(string text)
return new FormattedText(new FormattedTextSegment[] { new FormattedTextSegment(text) });
}

private static BonusPartLine CreatePartLine(string text, int partValue)
private static BonusPartLine CreatePartLine(string text, int partValue, char? difficultyModifier = null)
{
return new BonusPartLine(CreateFormattedText(text), partValue);
return new BonusPartLine(CreateFormattedText(text), partValue, difficultyModifier);
}

private static NumberedQuestionLine CreateQuestionLine(int number, string text)
Expand Down

0 comments on commit 4ca4e35

Please sign in to comment.