/// <summary> /// Maps the specified location to 1 or 2 (for ranges) IDs. /// </summary> /// <param name="location">The location.</param> /// <param name="item">The parent item. The tiled text part will be /// searched among its parts.</param> /// <returns>Tuple where 1=first or single ID, 2=second ID or null /// when there is a single ID only; null if text part not found.</returns> /// <exception cref="ArgumentNullException">location or item</exception> public Tuple <string, string?>?Map(string location, IItem item) { if (location == null) { throw new ArgumentNullException(nameof(location)); } if (item == null) { throw new ArgumentNullException(nameof(item)); } // find the tiled text part TiledTextPart?part = item.Parts.Find(p => p.TypeId == _tiledTextPartTypeId) as TiledTextPart; if (part == null) { Logger?.LogError($"No tiled text part for item {item}"); return(null); } // parse and map location TokenTextLocation loc = TokenTextLocation.Parse(location); string? a = MapPoint(loc.A, part); if (a == null) { return(null); } if (loc.IsRange) { string?b = MapPoint(loc.B, part); if (b == null) { return(null); } return(Tuple.Create(a !, (string?)b)); } else { return(Tuple.Create(a, (string?)null)); } }
private static bool PartHasOverlaps( TiledTextLayerPart <ApparatusLayerFragment> part) { List <TokenTextLocation> locs = (from fr in part.Fragments select TokenTextLocation.Parse(fr.Location)) .ToList(); for (int i = 0; i < locs.Count; i++) { for (int j = i + 1; j < locs.Count; j++) { if (locs[i].Overlaps(locs[j])) { return(true); } } } return(false); }
private void AddFragmentToPart(ApparatusLayerFragment fr, TiledTextLayerPart <ApparatusLayerFragment> part, string originalLoc) { int count = part.Fragments.Count; // bypass part's add so that even overlapping fragments are added; // we will then move them all at once later, when splitting part TokenTextLocation loc = TokenTextLocation.Parse(fr.Location); if (part.Fragments.Any(f => TokenTextLocation.Parse(f.Location) .Overlaps(loc))) { Logger?.LogInformation( $"Overlap for new fragment at {fr.Location}" + $" (original {originalLoc}): " + string.Join("; ", fr.Entries)); } part.Fragments.Add(fr); }
/// <summary> /// Gets the text at the specified location from the specified /// base text part. /// </summary> /// <param name="baseTextPart">The base text part to get text from.</param> /// <param name="location">The location.</param> /// <returns>The text, or null if location is invalid.</returns> /// <exception cref="ArgumentNullException">baseTextPart or location /// </exception> public override string GetTextAt(IPart baseTextPart, string location) { if (baseTextPart == null) { throw new ArgumentNullException(nameof(baseTextPart)); } if (location == null) { throw new ArgumentNullException(nameof(location)); } if (!(baseTextPart is TiledTextPart textPart)) { return(null); } // parse TokenTextLocation loc = TokenTextLocation.Parse(location); int aRowIndex = loc.A.Y - 1; if (aRowIndex < 0 || aRowIndex >= textPart.Rows.Count) { return(null); } List <TextTile> tiles; // range if (loc.IsRange) { // tokens range StringBuilder sb = new StringBuilder(); int bRowIndex = loc.B.Y - 1; if (bRowIndex < aRowIndex || bRowIndex >= textPart.Rows.Count) { return(null); } int aTileIndex = loc.A.X - 1; int bTileIndex = loc.B.X - 1; // corner case: same row for A-B if (aRowIndex == bRowIndex) { // defensive if (bTileIndex < aTileIndex) { return(null); } tiles = textPart.Rows[aRowIndex].Tiles; if (aTileIndex < 0 || aTileIndex >= tiles.Count) { return(null); } return(string.Join(" ", from t in tiles .Skip(aTileIndex) .Take(bTileIndex + 1 - aTileIndex) select GetTileText(t))); } // first row // A.X tiles = textPart.Rows[aRowIndex].Tiles; if (aTileIndex < 0 || aTileIndex >= tiles.Count) { return(null); } sb.Append(string.Join(" ", from t in tiles.Skip(aTileIndex) select GetTileText(t))); // mid-rows for (int i = aRowIndex + 1; i < bRowIndex; i++) { sb.AppendLine(); sb.Append(string.Join(" ", from t in textPart.Rows[i].Tiles select GetTileText(t))); } // last row sb.AppendLine(); tiles = textPart.Rows[bRowIndex].Tiles; if (bTileIndex < 0 || bTileIndex >= tiles.Count) { return(null); } sb.Append(string.Join(" ", from t in tiles.Take(bTileIndex + 1) select GetTileText(t))); return(sb.ToString()); } // single tile // X int tokenIndex = loc.A.X - 1; tiles = textPart.Rows[aRowIndex].Tiles; return(tokenIndex < 0 || tokenIndex >= tiles.Count ? null : GetTileText(tiles[tokenIndex])); }
/// <summary> /// Gets the text at the specified location from the specified /// base text part. /// </summary> /// <param name="baseTextPart">The base text part to get text from.</param> /// <param name="location">The location.</param> /// <returns>The text, or null if location is invalid.</returns> /// <exception cref="ArgumentNullException">baseTextPart or location /// </exception> public override string GetTextAt(IPart baseTextPart, string location) { if (baseTextPart == null) { throw new ArgumentNullException(nameof(baseTextPart)); } if (location == null) { throw new ArgumentNullException(nameof(location)); } if (!(baseTextPart is TokenTextPart textPart)) { return(null); } // parse TokenTextLocation loc = TokenTextLocation.Parse(location); string[] tokens; int aLineIndex = loc.A.Y - 1; if (aLineIndex < 0 || aLineIndex >= textPart.Lines.Count) { return(null); } // range if (loc.IsRange) { // tokens range StringBuilder sb = new StringBuilder(); int bLineIndex = loc.B.Y - 1; if (bLineIndex < aLineIndex || bLineIndex >= textPart.Lines.Count) { return(null); } int aTokenIndex = loc.A.X - 1; int bTokenIndex = loc.B.X - 1; // corner case: same line for A-B if (aLineIndex == bLineIndex) { // defensive if (bTokenIndex < aTokenIndex) { return(null); } tokens = textPart.Lines[aLineIndex].GetTokens(); if (aTokenIndex < 0 || aTokenIndex >= tokens.Length) { return(null); } return(string.Join(" ", tokens.Skip(aTokenIndex).Take(bTokenIndex + 1 - aTokenIndex))); } // first line // A.X tokens = textPart.Lines[aLineIndex].GetTokens(); if (aTokenIndex < 0 || aTokenIndex >= tokens.Length) { return(null); } sb.Append(string.Join(" ", tokens.Skip(aTokenIndex))); // mid-lines for (int i = aLineIndex + 1; i < bLineIndex; i++) { sb.AppendLine(); sb.Append(textPart.Lines[i].Text); } // last line sb.AppendLine(); tokens = textPart.Lines[bLineIndex].GetTokens(); if (bTokenIndex < 0 || bTokenIndex >= tokens.Length) { return(null); } sb.Append(string.Join(" ", tokens.Take(bTokenIndex + 1))); return(sb.ToString()); } // single token // X int tokenIndex = loc.A.X - 1; tokens = textPart.Lines[aLineIndex].GetTokens(); return(tokenIndex < 0 || tokenIndex >= tokens.Length ? null : tokens[tokenIndex]); }