From 09e156770a3c5850228d0e828bad6adc5709e768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20=C3=9Cste?= Date: Fri, 21 Feb 2025 15:13:04 +0300 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=99=88=20Update=20.gitignore=20to=20i?= =?UTF-8?q?nclude=20macOS=20specific=20files=20and=20directories?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9491a2f..0d68317 100644 --- a/.gitignore +++ b/.gitignore @@ -360,4 +360,42 @@ MigrationBackup/ .ionide/ # Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +FodyWeavers.xsd + +# Created by https://www.toptal.com/developers/gitignore/api/macos +# Edit at https://www.toptal.com/developers/gitignore?templates=macos + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +# End of https://www.toptal.com/developers/gitignore/api/macos \ No newline at end of file From 1ffeda96372d1e7bb11b4422d580886d94c45491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20=C3=9Cste?= Date: Fri, 21 Feb 2025 15:13:18 +0300 Subject: [PATCH 2/4] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Update=20QuestPDF=20pa?= =?UTF-8?q?ckage=20to=20version=202024.7.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HTMLToQPDF/HTMLToQPDF.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTMLToQPDF/HTMLToQPDF.csproj b/HTMLToQPDF/HTMLToQPDF.csproj index d619eea..e800d70 100644 --- a/HTMLToQPDF/HTMLToQPDF.csproj +++ b/HTMLToQPDF/HTMLToQPDF.csproj @@ -26,7 +26,7 @@ - + From 745edaeabffcf1f4988d3022a33c21891b74c400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20=C3=9Cste?= Date: Fri, 21 Feb 2025 15:32:07 +0300 Subject: [PATCH 3/4] =?UTF-8?q?=20=E2=9C=8F=EF=B8=8F=20Fix=20typos=20in=20?= =?UTF-8?q?ParagraphComponent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HTMLToQPDF/Components/ParagraphComponent.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/HTMLToQPDF/Components/ParagraphComponent.cs b/HTMLToQPDF/Components/ParagraphComponent.cs index 9bc0258..cbaa454 100644 --- a/HTMLToQPDF/Components/ParagraphComponent.cs +++ b/HTMLToQPDF/Components/ParagraphComponent.cs @@ -1,4 +1,4 @@ -using HtmlAgilityPack; +using HtmlAgilityPack; using HTMLQuestPDF.Extensions; using HTMLToQPDF.Components; using QuestPDF.Fluent; @@ -17,10 +17,10 @@ public ParagraphComponent(List lineNodes, HTMLComponentsArgs args) this.textStyles = args.TextStyles; } - private HtmlNode? GetParrentBlock(HtmlNode node) + private HtmlNode? GetParentBlock(HtmlNode node) { if (node == null) return null; - return node.IsBlockNode() ? node : GetParrentBlock(node.ParentNode); + return node.IsBlockNode() ? node : GetParentBlock(node.ParentNode); } private HtmlNode? GetListItemNode(HtmlNode node) @@ -31,7 +31,7 @@ public ParagraphComponent(List lineNodes, HTMLComponentsArgs args) public void Compose(IContainer container) { - var listItemNode = GetListItemNode(lineNodes.First()) ?? GetParrentBlock(lineNodes.First()); + var listItemNode = GetListItemNode(lineNodes.First()) ?? GetParentBlock(lineNodes.First()); if (listItemNode == null) return; var numberInList = listItemNode.GetNumberInList(); @@ -96,8 +96,8 @@ private TextSpanAction GetTextSpanAction(HtmlNode node) action(spanAction); if (node.ParentNode != null) { - var parrentAction = GetTextSpanAction(node.ParentNode); - parrentAction(spanAction); + var parentAction = GetTextSpanAction(node.ParentNode); + parentAction(spanAction); } }; } From b992dfd8dbfda9208e220fe1c3ec243c44f178b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sercan=20=C3=9Cste?= Date: Fri, 21 Feb 2025 15:39:48 +0300 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9C=A8=20Add=20Text=20Alignment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HTMLToQPDF/Components/HTMLComponent.cs | 7 +++- HTMLToQPDF/Components/HTMLComponentsArgs.cs | 4 +- HTMLToQPDF/Components/ParagraphComponent.cs | 42 ++++++++++++++++++--- HTMLToQPDF/HTMLDescriptor.cs | 5 +++ README.md | 1 + 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/HTMLToQPDF/Components/HTMLComponent.cs b/HTMLToQPDF/Components/HTMLComponent.cs index 3d386f2..035d0c7 100644 --- a/HTMLToQPDF/Components/HTMLComponent.cs +++ b/HTMLToQPDF/Components/HTMLComponent.cs @@ -46,6 +46,11 @@ internal class HTMLComponent : IComponent { "ol", c => c.PaddingLeft(30) } }; + public Dictionary TextAlignments { get; } = new Dictionary() + { + { "p", TextHorizontalAlignment.Left } + }; + public float ListVerticalPadding { get; set; } = 12; public string HTML { get; set; } = ""; @@ -58,7 +63,7 @@ public void Compose(IContainer container) CreateSeparateBranchesForTextNodes(node); - container.Component(node.GetComponent(new HTMLComponentsArgs(TextStyles, ContainerStyles, ListVerticalPadding, GetImgBySrc))); + container.Component(node.GetComponent(new HTMLComponentsArgs(TextStyles, ContainerStyles, TextAlignments, ListVerticalPadding, GetImgBySrc))); } /// diff --git a/HTMLToQPDF/Components/HTMLComponentsArgs.cs b/HTMLToQPDF/Components/HTMLComponentsArgs.cs index 613d60c..d10140b 100644 --- a/HTMLToQPDF/Components/HTMLComponentsArgs.cs +++ b/HTMLToQPDF/Components/HTMLComponentsArgs.cs @@ -8,13 +8,15 @@ internal class HTMLComponentsArgs { public Dictionary TextStyles { get; } public Dictionary> ContainerStyles { get; } + public Dictionary TextAlignments { get; } public float ListVerticalPadding { get; } public GetImgBySrc GetImgBySrc { get; } - public HTMLComponentsArgs(Dictionary textStyles, Dictionary> containerStyles, float listVerticalPadding, GetImgBySrc getImgBySrc) + public HTMLComponentsArgs(Dictionary textStyles, Dictionary> containerStyles, Dictionary textAlignments, float listVerticalPadding, GetImgBySrc getImgBySrc) { TextStyles = textStyles; ContainerStyles = containerStyles; + TextAlignments = textAlignments; ListVerticalPadding = listVerticalPadding; GetImgBySrc = getImgBySrc; } diff --git a/HTMLToQPDF/Components/ParagraphComponent.cs b/HTMLToQPDF/Components/ParagraphComponent.cs index cbaa454..ff32b82 100644 --- a/HTMLToQPDF/Components/ParagraphComponent.cs +++ b/HTMLToQPDF/Components/ParagraphComponent.cs @@ -1,4 +1,4 @@ -using HtmlAgilityPack; +using HtmlAgilityPack; using HTMLQuestPDF.Extensions; using HTMLToQPDF.Components; using QuestPDF.Fluent; @@ -10,11 +10,13 @@ internal class ParagraphComponent : IComponent { private readonly List lineNodes; private readonly Dictionary textStyles; + private readonly Dictionary textAlignments; public ParagraphComponent(List lineNodes, HTMLComponentsArgs args) { this.lineNodes = lineNodes; this.textStyles = args.TextStyles; + this.textAlignments = args.TextAlignments; } private HtmlNode? GetParentBlock(HtmlNode node) @@ -70,12 +72,12 @@ private Action GetAction(HtmlNode node) if (node.NodeType == HtmlNodeType.Text) { var span = text.Span(node.InnerText); - GetTextSpanAction(node).Invoke(span); + GetTextSpanAction(node).Invoke(span, text); } else if (node.IsBr()) { var span = text.Span("\n"); - GetTextSpanAction(node).Invoke(span); + GetTextSpanAction(node).Invoke(span, text); } else { @@ -88,16 +90,23 @@ private Action GetAction(HtmlNode node) }; } - private TextSpanAction GetTextSpanAction(HtmlNode node) + private Action GetTextSpanAction(HtmlNode node) { - return spanAction => + return (spanAction, text) => { var action = GetTextStyles(node); action(spanAction); + + var alignment = GetTextAlignment(node); + alignment(text); + if (node.ParentNode != null) { var parentAction = GetTextSpanAction(node.ParentNode); - parentAction(spanAction); + parentAction(spanAction, text); + + var parentAlignment = GetTextAlignment(node.ParentNode); + parentAlignment(text); } }; } @@ -111,5 +120,26 @@ public TextStyle GetTextStyle(HtmlNode element) { return textStyles.TryGetValue(element.Name.ToLower(), out TextStyle? style) ? style : TextStyle.Default; } + + public Action GetTextAlignment(HtmlNode element) + { + switch (textAlignments.TryGetValue(element.Name.ToLower(), out TextHorizontalAlignment alignment) ? alignment : TextHorizontalAlignment.Left) + { + case TextHorizontalAlignment.Left: + return block => block.AlignLeft(); + case TextHorizontalAlignment.Center: + return block => block.AlignCenter(); + case TextHorizontalAlignment.Right: + return block => block.AlignRight(); + case TextHorizontalAlignment.Start: + return block => block.AlignStart(); + case TextHorizontalAlignment.End: + return block => block.AlignEnd(); + case TextHorizontalAlignment.Justify: + return block => block.Justify(); + default: + return block => block.AlignLeft(); + } + } } } \ No newline at end of file diff --git a/HTMLToQPDF/HTMLDescriptor.cs b/HTMLToQPDF/HTMLDescriptor.cs index e822c15..8bdcc4b 100644 --- a/HTMLToQPDF/HTMLDescriptor.cs +++ b/HTMLToQPDF/HTMLDescriptor.cs @@ -23,6 +23,11 @@ public void SetTextStyleForHtmlElement(string tagName, TextStyle style) PDFPage.TextStyles[tagName.ToLower()] = style; } + public void SetTextAlignmentForHtmlElement(string tagName, TextHorizontalAlignment alignment) + { + PDFPage.TextAlignments[tagName.ToLower()] = alignment; + } + public void SetContainerStyleForHtmlElement(string tagName, Func style) { PDFPage.ContainerStyles[tagName.ToLower()] = style; diff --git a/README.md b/README.md index 36c0af1..318b36e 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ handler.SetTextStyleForHtmlElement("div", TextStyle.Default.FontColor(Colors.Gre handler.SetTextStyleForHtmlElement("h1", TextStyle.Default.FontColor(Colors.DeepOrange.Accent4).FontSize(32).Bold()); handler.SetContainerStyleForHtmlElement("table", c => c.Background(Colors.Pink.Lighten5)); handler.SetContainerStyleForHtmlElement("ul", c => c.PaddingVertical(10)); +handler.SetTextAlignmentForHtmlElement("p", TextHorizontalAlignment.Justify); ``` You can set the vertical padding size for lists. This padding will not apply to sub-lists: