Example #1
0
        private string?MapPoint(TokenTextPoint point, TiledTextPart part)
        {
            int rowIndex  = point.Y - 1;
            int tileIndex = point.X - 1;

            if (rowIndex >= part.Rows.Count)
            {
                Logger?.LogError($"Location point {point} out of part's rows");
                return(null);
            }

            if (tileIndex >= part.Rows[rowIndex].Tiles.Count)
            {
                Logger?.LogError($"Location point {point} out of part's row tiles");
                return(null);
            }

            if (!part.Rows[rowIndex].Tiles[tileIndex].Data.ContainsKey("id"))
            {
                Logger?.LogError($"Location point {point} maps to tile without id");
                return(null);
            }

            return(part.Rows[rowIndex].Tiles[tileIndex].Data["id"]);
        }
        private static TiledTextPart GetTiledTextPart(int rowCount)
        {
            TiledTextPart part = new TiledTextPart
            {
                ItemId    = Guid.NewGuid().ToString(),
                CreatorId = "zeus",
                UserId    = "zeus"
            };
            char c = 'a';

            for (int y = 0; y < rowCount; y++)
            {
                TextTileRow row = new TextTileRow
                {
                    Y = y + 1
                };
                part.Rows.Add(row);

                for (int x = 0; x < 3; x++)
                {
                    TextTile tile = new TextTile
                    {
                        X = x + 1,
                    };
                    tile.Data[TextTileRow.TEXT_DATA_NAME] = $"{c}{x + 1}";
                    row.Tiles.Add(tile);
                    if (++c > 'z')
                    {
                        c = 'a';
                    }
                }
            }
            return(part);
        }
        /// <summary>
        /// Pick (if possible) the specified count of random locations in the
        /// base text part, each with its corresponding piece of text.
        /// </summary>
        /// <param name="part">The part.</param>
        /// <param name="count">The count.</param>
        /// <returns>A list of tuples where 1=location, 2=base text.</returns>
        private IList <Tuple <string, string> > PickLocAndTexts(
            TiledTextPart part, int count)
        {
            HashSet <Tuple <int, int> >    usedCoords = new HashSet <Tuple <int, int> >();
            List <Tuple <string, string> > results    = new List <Tuple <string, string> >();

            while (count > 0)
            {
                for (int attempt = 0; attempt < 10; attempt++)
                {
                    // pick a row
                    int y = Randomizer.Seed.Next(1, part.Rows.Count + 1);

                    // pick a tile in that line
                    int x = Randomizer.Seed.Next(1, part.Rows[y - 1].Tiles.Count + 1);

                    // select if not already used
                    Tuple <int, int> yx = Tuple.Create(y, x);
                    if (!usedCoords.Contains(yx))
                    {
                        usedCoords.Add(yx);
                        results.Add(Tuple.Create($"{y}.{x}",
                                                 part.Rows[y - 1].Tiles[x - 1]
                                                 .Data[TextTileRow.TEXT_DATA_NAME]));
                        break;
                    }
                }
                count--;
            }
            return(results);
        }
Example #4
0
        public void GetDataPins_NoCitation_Empty()
        {
            TiledTextPart part = GetPart();

            part.Citation = null;

            Assert.Empty(part.GetDataPins());
        }
        public void GetTextAt_3LinesRange_Ok(string location, string expectedText)
        {
            TiledTextPart textPart = GetTiledTextPart(3);
            TiledTextLayerPart <CommentLayerFragment> layerPart = GetPart();

            string text = layerPart.GetTextAt(textPart, location);

            Assert.Equal(expectedText, text);
        }
        public void GetTextAt_InvalidLocation_Null()
        {
            TiledTextPart textPart = GetTiledTextPart(3);
            TiledTextLayerPart <CommentLayerFragment> layerPart = GetPart();

            string text = layerPart.GetTextAt(textPart, "12.3");

            Assert.Null(text);
        }
Example #7
0
        public void GetDataPins_Citation_1()
        {
            TiledTextPart part = GetPart();

            List <DataPin> pins = part.GetDataPins().ToList();

            Assert.Single(pins);

            DataPin pin = pins[0];

            Assert.Equal(part.ItemId, pin.ItemId);
            Assert.Equal(part.Id, pin.PartId);
            Assert.Equal(part.RoleId, pin.RoleId);
            Assert.Equal("citation", pin.Name);
            Assert.Equal("some-citation", pin.Value);
        }
Example #8
0
        private static string GetPartTextDescription(TiledTextPart part)
        {
            StringBuilder sb = new();

            // collect head text
            int ya = 0, xa = 0;

            foreach (TextTileRow row in part.Rows)
            {
                ya++;
                xa = 0;
                foreach (TextTile tile in row.Tiles)
                {
                    xa++;
                    if (sb.Length > 0)
                    {
                        sb.Append(' ');
                    }
                    sb.Append(tile.Data[KEY_TEXT]);
                    if (sb.Length >= 40)
                    {
                        goto tail;
                    }
                }
            }
tail:
            // collect tail text
            int i = sb.Length;

            for (int yb = part.Rows.Count; yb >= ya; yb--)
            {
                for (int xb = part.Rows[yb - 1].Tiles.Count;
                     yb == ya? xb > xa : xb > 0;
                     xb--)
                {
                    sb.Insert(i, part.Rows[yb - 1].Tiles[xb - 1].Data[KEY_TEXT]);
                    sb.Insert(i, ' ');
                    if (sb.Length - i >= 40)
                    {
                        sb.Insert(i, "... ");
                        goto end;
                    }
                }
            }
end:
            return(sb.ToString());
        }
        public void Seed_Options_Tag()
        {
            TiledTextPartSeeder seeder = new TiledTextPartSeeder();

            seeder.SetSeedOptions(_seedOptions);

            IPart part = seeder.GetPart(_item, null, _factory);

            Assert.NotNull(part);

            TiledTextPart tp = part as TiledTextPart;

            Assert.NotNull(tp);

            TestHelper.AssertPartMetadata(tp);
            Assert.NotNull(tp.Citation);
            Assert.NotEmpty(tp.Rows);

            for (int y = 1; y <= tp.Rows.Count; y++)
            {
                Assert.Equal(y, tp.Rows[y - 1].Y);
            }
        }
Example #10
0
        public void Part_Is_Serializable()
        {
            TiledTextPart part = GetPart();

            string        json  = TestHelper.SerializePart(part);
            TiledTextPart part2 = TestHelper.DeserializePart <TiledTextPart>(json);

            Assert.Equal(part.Id, part2.Id);
            Assert.Equal(part.TypeId, part2.TypeId);
            Assert.Equal(part.ItemId, part2.ItemId);
            Assert.Equal(part.RoleId, part2.RoleId);
            Assert.Equal(part.CreatorId, part2.CreatorId);
            Assert.Equal(part.UserId, part2.UserId);

            List <TextTileRow> expectedRows = GetRows(3);

            Assert.Equal(expectedRows.Count, part.Rows.Count);
            for (int i = 0; i < expectedRows.Count; i++)
            {
                Assert.Equal(expectedRows[i].Y, part.Rows[i].Y);
                Assert.Equal(expectedRows[i].Tiles.Count, part.Rows[i].Tiles.Count);
                Assert.Equal(expectedRows[i].Data.Count, part.Rows[i].Data.Count);
            }
        }
        /// <summary>
        /// Creates and seeds a new part with its fragments. The fragment
        /// type comes from the part's role ID.
        /// </summary>
        /// <param name="item">The item this part should belong to.</param>
        /// <param name="roleId">The optional part role ID.</param>
        /// <param name="factory">The part seeder factory. This is used
        /// for layer parts, which need to seed a set of fragments.</param>
        /// <returns>A new part.</returns>
        /// <exception cref="ArgumentNullException">item or factory</exception>
        public override IPart GetPart(IItem item, string roleId,
                                      PartSeederFactory factory)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            if (_options == null || _options.MaxFragmentCount < 1)
            {
                return(null);
            }

            // get the base text part; nothing to do if none
            TiledTextPart textPart = item.Parts
                                     .OfType <TiledTextPart>()
                                     .FirstOrDefault();

            if (textPart == null)
            {
                return(null);
            }

            // get the seeder; nothing to do if none
            string          frTypeId = StripColonSuffix(roleId);
            IFragmentSeeder seeder   =
                factory.GetFragmentSeeder("seed." + frTypeId);

            if (seeder == null)
            {
                return(null);
            }

            // get the layer part for the specified fragment type
            Type constructedType = typeof(TiledTextLayerPart <>)
                                   .MakeGenericType(seeder.GetFragmentType());
            IPart part = (IPart)Activator.CreateInstance(constructedType);

            // seed metadata
            SetPartMetadata(part, frTypeId, item);

            // seed by adding fragments
            int count = Randomizer.Seed.Next(1, _options.MaxFragmentCount);
            IList <Tuple <string, string> > locAndTexts =
                PickLocAndTexts(textPart, count);

            // must invoke AddFragment via reflection, as the closed type
            // is known only at runtime
            Type t = part.GetType();

            foreach (var lt in locAndTexts)
            {
                ITextLayerFragment fr = seeder.GetFragment(
                    item, lt.Item1, lt.Item2);
                if (fr != null)
                {
                    t.InvokeMember("AddFragment",
                                   BindingFlags.InvokeMethod,
                                   null,
                                   part,
                                   new[] { fr });
                }
            }

            return(part);
        }
Example #12
0
        /// <summary>
        /// Creates and seeds a new part.
        /// </summary>
        /// <param name="item">The item this part should belong to.</param>
        /// <param name="roleId">The optional part role ID.</param>
        /// <param name="factory">The part seeder factory. This is used
        /// for layer parts, which need to seed a set of fragments.</param>
        /// <returns>A new part.</returns>
        /// <exception cref="ArgumentNullException">item or factory</exception>
        public override IPart GetPart(IItem item, string roleId,
                                      PartSeederFactory factory)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            TiledTextPart part = new TiledTextPart();

            SetPartMetadata(part, roleId, item);

            // citation
            part.Citation = Randomizer.Seed.Next(1, 100)
                            .ToString(CultureInfo.InvariantCulture);

            // from 2 to 10 rows
            var    faker = new Faker();
            string text  = faker.Lorem.Sentences(
                Randomizer.Seed.Next(2, 11));
            int y = 1;

            foreach (string line in text.Split('\n'))
            {
                // row
                TextTileRow row = new TextTileRow
                {
                    Y = y++,
                };
                // row's data
                for (int i = 0; i < Randomizer.Seed.Next(0, 4); i++)
                {
                    row.Data[$"d{(char)(i + 97)}"] = faker.Lorem.Word();
                }

                // add tiles in row
                int x = 1;
                foreach (string token in line.Trim().Split(' '))
                {
                    TextTile tile = new TextTile
                    {
                        X = x++,
                    };
                    // text
                    tile.Data[TextTileRow.TEXT_DATA_NAME] = token;
                    // other data
                    for (int i = 0; i < Randomizer.Seed.Next(0, 11); i++)
                    {
                        tile.Data[$"d{(char)(i + 97)}"] = faker.Lorem.Word();
                    }
                    row.Tiles.Add(tile);
                }

                part.Rows.Add(row);
            }

            return(part);
        }
Example #13
0
        /// <summary>
        /// Imports the partition into a Cadmus item.
        /// </summary>
        /// <param name="div">The document's div element containing the partition,
        /// or a part of it.</param>
        /// <param name="rowElements">The rows elements, i.e. the children elements
        /// of the partition representing tiled text rows (either <c>l</c> or
        /// <c>p</c> elements).</param>
        /// <returns>The item.</returns>
        private IItem ImportPartition(XElement div,
                                      IList <XElement> rowElements)
        {
            _partitionNr++;

            // build citation
            string cit = XmlHelper.GetBreakPointCitation(_partitionNr,
                                                         div.Elements().FirstOrDefault(IsLOrP),
                                                         _docId);

            // item
            var  nBounds = GetPartitionNBoundaries(rowElements);
            Item item    = new Item
            {
                Title = cit,
                //Description = (nBounds != null ?
                //    $"{nBounds.Item1}-{nBounds.Item2} " : "") +
                //    GetDescriptionText(div.Value.Trim()),
                FacetId   = _facetId,
                GroupId   = _docId,
                CreatorId = _userId,
                UserId    = UserId
            };

            // text part
            TiledTextPart part = new TiledTextPart
            {
                ItemId    = item.Id,
                Citation  = cit,
                CreatorId = item.CreatorId,
                UserId    = item.UserId,
                RoleId    = PartBase.BASE_TEXT_ROLE_ID
            };

            item.Parts.Add(part);

            int y      = 1;
            int wordNr = 1;

            foreach (XElement rowElement in rowElements)
            {
                // row
                TextTileRow row = new TextTileRow
                {
                    Y = y++
                };
                row.Data["_name"] = rowElement.Name.LocalName;

                // row's attributes
                foreach (XAttribute attr in rowElement.Attributes())
                {
                    string key = GetKeyFromAttrName(attr.Name);
                    row.Data[key] = attr.Value;
                }

                // tiles
                if (rowElement.Elements(XmlHelper.TEI + "w").Any())
                {
                    AddTiles(rowElement.Elements(XmlHelper.TEI + "w"), row);
                }
                else
                {
                    int divNr = div.ElementsBeforeSelf(div.Name).Count() + 1;
                    row.Data["_split"] = "1";
                    var wordAndIds = from w in rowElement.Value.Split(' ')
                                     select Tuple.Create(
                        w,
                        $"d{divNr:000}w{wordNr++}");

                    AddTiles(wordAndIds, row);
                }

                part.Rows.Add(row);
            }

            item.Description = (nBounds != null ?
                                $"{nBounds.Item1}-{nBounds.Item2} " : "")
                               + GetPartTextDescription(part);

            item.SortKey = _sortKeyBuilder.BuildKey(item, null);
            int i = item.SortKey.IndexOf(' ', item.SortKey.IndexOf(' ') + 1);

            item.SortKey = item.SortKey.Substring(0, i);

            return(item);
        }