public void ContainerNode_ChangeChildrenContent_Works() { var paragraph = new Paragraph(); paragraph.Content.Should().BeEmpty(); paragraph.AddContent(new Strong()); // the only child paragraph.Content.Should().HaveCount(1); var firstChild = paragraph.Content.First(); firstChild.Should().BeOfType <Strong>(); var firstStrongChild = firstChild as Strong; firstStrongChild.Content.Should().BeEmpty(); firstStrongChild.AddTextContent("strong"); firstStrongChild.Content.Should().HaveCount(1); firstStrongChild.Content.First().Should().BeOfType <TextItem>().Subject.Content.Should().Be("strong"); //re-use prev variables, assert paragraph children anew var firstChild1 = paragraph.Content.First(); firstChild1.Should().BeOfType <Strong>(); var firstStrongChild1 = firstChild1 as Strong; firstStrongChild1.Content.Should().HaveCount(1); firstStrongChild1.Content.First().Should().BeOfType <TextItem>().Subject.Content.Should().Be("strong"); }
public void AddContent() { var rtlPara = new Paragraph(0); var ltrPara = new Paragraph(0); rtlPara.AddContent(0, _rtlContent, null); ltrPara.AddContent(0, _ltrContent, null); // words + spaces + inert words > 2 * words Assert.IsTrue(rtlPara.Words.Count > _rtlWords.Length * 2); Assert.IsTrue(ltrPara.Words.Count > _ltrWords.Length * 2); // count special words in paragraph Assert.AreEqual(rtlPara.Words.Count(w => w.Type.HasFlag(WordType.InertChar)), 3); Assert.AreEqual(rtlPara.Words.Count(w => w.Type.HasFlag(WordType.Attached)), 3); Assert.AreEqual(rtlPara.Words.Count(w => w.Type.HasFlag(WordType.Normal)), _rtlWords.Length); Assert.AreEqual(rtlPara.Words.Count(w => w.Type.HasFlag(WordType.Normal) && w.Styles.IsRtl), 14); Assert.AreEqual(rtlPara.Words.Count(w => w.Type.HasFlag(WordType.Normal) && !w.Styles.IsRtl), _rtlWords.Length - 14); Assert.AreEqual(ltrPara.Words.Count(w => w.Type.HasFlag(WordType.InertChar)), 2); Assert.AreEqual(ltrPara.Words.Count(w => w.Type.HasFlag(WordType.Attached)), 2); Assert.AreEqual(ltrPara.Words.Count(w => w.Type.HasFlag(WordType.Normal)), _ltrWords.Length); Assert.AreEqual(ltrPara.Words.Count(w => w.Type.HasFlag(WordType.Normal) && w.Styles.IsRtl), 2); Assert.AreEqual(ltrPara.Words.Count(w => w.Type.HasFlag(WordType.Normal) && !w.Styles.IsRtl), _ltrWords.Length - 2); }
public void RenderTest() { var rtlPara = new Paragraph(0); var ltrPara = new Paragraph(1); rtlPara.AddContent(0, _rtlContent, null); ltrPara.AddContent(0, _ltrContent, null); Assert.IsNotNull(rtlPara.Render()); Assert.IsNotNull(ltrPara.Render()); // paragraph properties calculated in TextViewer BuildPage method Assert.AreEqual(0, ltrPara.Size.Width); Assert.AreEqual(0, ltrPara.Size.Height); Assert.AreEqual(0, ltrPara.Location.X); Assert.AreEqual(0, ltrPara.Location.Y); Assert.AreEqual(0, ltrPara.Lines.Count); }
public void SimilarModifications_ElementsEquality() { var paragOne = new Paragraph(); var paragTwo = new Paragraph(); paragOne.Should().Be(paragTwo); paragOne.AddContent(new Emphasis().AddTextContent("test text content")); paragOne.Should().NotBe(paragTwo); paragTwo.AddContent(new Emphasis().AddTextContent("test text content")); paragOne.Should().Be(paragTwo); paragOne.AddAttribute(new Fb2Attribute(AttributeNames.Id, "testId")); paragOne.Should().NotBe(paragTwo); paragTwo.AddAttribute(new Fb2Attribute(AttributeNames.Id, "testId")); paragOne.Should().Be(paragTwo); }
public void Paragraph_QueryContent_Works() { // setup var paragraph = new Paragraph(); paragraph.AddContent(new Strong().AddTextContent("strong text 1 ")); paragraph.IsEmpty.Should().BeFalse(); paragraph .AddContent( new Emphasis() .AppendTextContent("italic text 1 ") .AddContent( new Strong() .AddTextContent("strong italic text ") .AddContent(new Strikethrough().AddTextContent("bold strikethrough text "))), new Strong().AddTextContent("strong text 2 ")) .AddTextContent("plain text 1"); // verify setup paragraph.Content.Should().HaveCount(4); var firstStrong = paragraph.Content.First() as Strong; firstStrong.Content.Should().HaveCount(1); firstStrong.Content.First().Should().BeOfType <TextItem>(); var firstItalic = paragraph.Content[1] as Emphasis; firstItalic.Content.Should().HaveCount(2); firstItalic.Content.First().Should().BeOfType <TextItem>(); firstItalic.Content[1].Should().BeOfType <Strong>(); var secondStrong = paragraph.Content[2] as Strong; secondStrong.Content.Should().HaveCount(1); secondStrong.Content.First().Should().BeOfType <TextItem>(); var plainText = paragraph.Content.Last() as TextItem; plainText.Content.Should().Be("plain text 1"); // children query example // looking for "Strong" childer - should be 2 var strongChildren = paragraph.GetChildren(ElementNames.Strong); var strongPredicateChildren = paragraph.GetChildren(c => c is Strong); var strongGenericChildren = paragraph.GetChildren <Strong>(); strongChildren.Should().HaveCount(2); strongPredicateChildren.Should().HaveCount(2); strongGenericChildren.Should().HaveCount(2); strongChildren .Should() .BeEquivalentTo(strongPredicateChildren) .And .BeEquivalentTo(strongGenericChildren); // looking for single child var plainTextByName = paragraph.GetFirstChild(ElementNames.FictionText); var plainPredicateText = paragraph.GetFirstChild(p => p is TextItem); var plainGenericText = paragraph.GetFirstChild <TextItem>(); plainTextByName.Should().NotBeNull(); (plainTextByName as Fb2Element).Content.Should().Be("plain text 1"); plainTextByName.Should().Be(plainPredicateText).And.Be(plainGenericText); // and to stress the obvios paragraph.GetFirstChild(c => c is Strong) .Should().BeOfType <Strong>() .Subject.Content.Should().HaveCount(1) .And.Subject.First() .Should().BeOfType <TextItem>() .Subject.Content.Should().Be("strong text 1 "); // okay, descendants queries paragraph .GetFirstDescendant(n => n is Strikethrough) .Should().BeOfType <Strikethrough>() .Subject.Content.Should().HaveCount(1) .And.Subject.First() .Should().BeOfType <TextItem>() .Subject.Content.Should().Be("bold strikethrough text "); paragraph .GetFirstDescendant(ElementNames.Strikethrough) .Should().BeOfType <Strikethrough>() .Subject.Content.Should().HaveCount(1) .And.Subject.First() .Should().BeOfType <TextItem>() .Subject.Content.Should().Be("bold strikethrough text "); paragraph .GetFirstDescendant <Strikethrough>() .Should().BeOfType <Strikethrough>() .Subject.Content.Should().HaveCount(1) .And.Subject.First() .Should().BeOfType <TextItem>() .Subject.Content.Should().Be("bold strikethrough text "); var attemptToGetStrikethroughByName = paragraph.TryGetFirstDescendant(ElementNames.Strikethrough, out var strikethrough); attemptToGetStrikethroughByName.Should().BeTrue(); strikethrough .Should().BeOfType <Strikethrough>() .Subject.Content.Should().HaveCount(1) .And.Subject.First() .Should().BeOfType <TextItem>() .Subject.Content.Should().Be("bold strikethrough text "); var attemptToGetStrikethroughByPredicate = paragraph.TryGetFirstDescendant(n => n is Strikethrough, out var predicateStrikethrough); predicateStrikethrough .Should().BeOfType <Strikethrough>() .Subject.Content.Should().HaveCount(1) .And.Subject.First() .Should().BeOfType <TextItem>() .Subject.Content.Should().Be("bold strikethrough text "); }
private static void ParseInnerHtml(this HtmlNode node, Paragraph parent, TextStyle parentStyle, ref int contentOffset) { var nodeStyle = new TextStyle(parentStyle); nodeStyle.SetDirection(parent.Styles.IsRtl); if (node.Name == "b") { nodeStyle.FontWeight = FontWeights.Bold; } if (node.Name == "img") { var src = node.GetAttributeValue("src", null); if (src != null) { if (src.StartsWith("data:image")) { src = src.Substring(src.IndexOf("base64,") + 8); } nodeStyle.SetImage(src); parent.Words.Add(new ImageWord(contentOffset++, nodeStyle) { Paragraph = parent }); } } if (node.Name == "a") { nodeStyle.HyperRef = node.GetAttributeValue("href", null); } if (node.HasAttributes) { var styles = node.GetAttributeValue("style", null); if (styles != null) { foreach (var entries in styles.Split(';')) { var values = entries.Split(':'); switch (values[0].ToLower().Trim()) { case "vertical-align": nodeStyle.VerticalAlign = (VerticalAlignment)Enum.Parse(typeof(VerticalAlignment), values[1], true); break; case "text-align": parent.Styles.TextAlign = (TextAlignment)Enum.Parse(typeof(TextAlignment), values[1], true); break; case "color": nodeStyle.Foreground = (Brush) new BrushConverter().ConvertFromString(values[1]); break; case "direction": nodeStyle.SetDirection(values[1] == "rtl"); break; case "font-weight": nodeStyle.FontWeight = int.Parse(values[1]) > 500 ? FontWeights.Bold : FontWeights.Normal; break; case "font-size": nodeStyle.FontSize = double.Parse(values[1].Replace("px", "")); break; case "margin-bottom": nodeStyle.MarginBottom = double.Parse(values[1].Replace("px", "")); break; case "margin-top": nodeStyle.MarginTop = double.Parse(values[1].Replace("px", "")); break; case "margin-left": nodeStyle.MarginLeft = double.Parse(values[1].Replace("px", "")); break; case "margin-right": nodeStyle.MarginRight = double.Parse(values[1].Replace("px", "")); break; } } } var dir = node.GetAttributeValue("dir", null); if (dir != null) { nodeStyle.SetDirection(dir == "rtl"); } var w = node.GetAttributeValue("width", null); if (w != null) { parent.Words.Last().Styles.Width = double.Parse(w); } var h = node.GetAttributeValue("height", null); if (h != null) { parent.Words.Last().Styles.Height = double.Parse(h); } } if (node.HasChildNodes) { foreach (var child in node.ChildNodes) { if (child.NodeType == HtmlNodeType.Text) { parent.AddContent(contentOffset, child.InnerText, nodeStyle); contentOffset += child.InnerText.Length; } else { child.ParseInnerHtml(parent, nodeStyle, ref contentOffset); } } } }