Fix duplicate critical affix import fragments
This commit is contained in:
Binary file not shown.
@@ -1,3 +1,5 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
using RolemasterDb.App.Data;
|
using RolemasterDb.App.Data;
|
||||||
@@ -115,6 +117,25 @@ public sealed class StandardCriticalTableParserIntegrationTests
|
|||||||
Assert.Contains(expectedSnippet, result.DescriptionText, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains(expectedSnippet, result.DescriptionText, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Arcane_aether_c_31_has_single_bleed_effect()
|
||||||
|
{
|
||||||
|
var entry = LoadManifest().Tables.Single(item => string.Equals(item.Slug, "arcane-aether", StringComparison.Ordinal));
|
||||||
|
var parseResult = await LoadParseResultAsync(entry);
|
||||||
|
var result = parseResult.Table.Results.Single(item =>
|
||||||
|
item.GroupKey is null &&
|
||||||
|
string.Equals(item.RollBandLabel, "31-40", StringComparison.Ordinal) &&
|
||||||
|
string.Equals(item.ColumnKey, "C", StringComparison.Ordinal));
|
||||||
|
|
||||||
|
var bleedEffects = result.Effects
|
||||||
|
.Where(effect => effect.EffectCode == CriticalEffectCodes.BleedPerRound)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
Assert.Equal("+15H – ∑ – ∫", result.RawAffixText);
|
||||||
|
Assert.Single(bleedEffects);
|
||||||
|
Assert.Equal(1, bleedEffects.Single().PerRound);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Slash_boundary_repair_keeps_56_60_a_prose_first()
|
public async Task Slash_boundary_repair_keeps_56_60_a_prose_first()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ internal static class CriticalTableParserSupport
|
|||||||
|
|
||||||
var document = XDocument.Load(xmlReader);
|
var document = XDocument.Load(xmlReader);
|
||||||
|
|
||||||
return document.Descendants("page")
|
var fragments = document.Descendants("page")
|
||||||
.SelectMany(page =>
|
.SelectMany(page =>
|
||||||
{
|
{
|
||||||
var pageNumber = int.Parse(page.Attribute("number")?.Value ?? "1");
|
var pageNumber = int.Parse(page.Attribute("number")?.Value ?? "1");
|
||||||
@@ -45,6 +45,8 @@ internal static class CriticalTableParserSupport
|
|||||||
.Where(item => !string.IsNullOrWhiteSpace(item.Text));
|
.Where(item => !string.IsNullOrWhiteSpace(item.Text));
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
return RemoveRedundantContainedFragments(fragments);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<XmlTextFragment> FindRowLabelFragments(
|
internal static List<XmlTextFragment> FindRowLabelFragments(
|
||||||
@@ -263,6 +265,56 @@ internal static class CriticalTableParserSupport
|
|||||||
.Replace('’', '\'')
|
.Replace('’', '\'')
|
||||||
.Trim();
|
.Trim();
|
||||||
|
|
||||||
|
private static List<XmlTextFragment> RemoveRedundantContainedFragments(IReadOnlyList<XmlTextFragment> fragments)
|
||||||
|
{
|
||||||
|
var redundant = new HashSet<XmlTextFragment>();
|
||||||
|
|
||||||
|
foreach (var group in fragments.GroupBy(item => (item.PageNumber, item.Top, item.Height)))
|
||||||
|
{
|
||||||
|
var ordered = group
|
||||||
|
.OrderByDescending(item => item.Width)
|
||||||
|
.ThenBy(item => item.Left)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
for (var index = 0; index < ordered.Count; index++)
|
||||||
|
{
|
||||||
|
var container = ordered[index];
|
||||||
|
if (container.Text.Length <= 1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var candidateIndex = index + 1; candidateIndex < ordered.Count; candidateIndex++)
|
||||||
|
{
|
||||||
|
var candidate = ordered[candidateIndex];
|
||||||
|
if (candidate.Width > container.Width ||
|
||||||
|
!container.Text.Contains(candidate.Text, StringComparison.Ordinal) ||
|
||||||
|
!IsHorizontallyContained(candidate, container))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
redundant.Add(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragments
|
||||||
|
.Where(item => !redundant.Contains(item))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsHorizontallyContained(XmlTextFragment candidate, XmlTextFragment container)
|
||||||
|
{
|
||||||
|
const int containmentTolerance = 1;
|
||||||
|
|
||||||
|
var candidateRight = candidate.Left + candidate.Width;
|
||||||
|
var containerRight = container.Left + container.Width;
|
||||||
|
|
||||||
|
return candidate.Left >= container.Left - containmentTolerance &&
|
||||||
|
candidateRight <= containerRight + containmentTolerance;
|
||||||
|
}
|
||||||
|
|
||||||
internal static string? NormalizeConditionKey(string conditionText)
|
internal static string? NormalizeConditionKey(string conditionText)
|
||||||
{
|
{
|
||||||
var normalized = CollapseWhitespace(conditionText)
|
var normalized = CollapseWhitespace(conditionText)
|
||||||
|
|||||||
Reference in New Issue
Block a user