Browse Source

Refactor SemanticHeader methods to remove title parameter and update header text dynamically

Marcin Ziąbek 3 months ago
parent
commit
f4c9f9aa33

+ 3 - 3
Source/QuestPDF.DocumentationExamples/SemanticExamples.cs

@@ -85,7 +85,7 @@ public class SemanticExamples
                                         
                                         column.Item()
                                             .PaddingBottom(8)
-                                            .SemanticHeader1(category1.Category)
+                                            .SemanticHeader1()
                                             .Text(category1.Category)
                                             .FontSize(24)
                                             .FontColor(Colors.Blue.Darken4)
@@ -102,7 +102,7 @@ public class SemanticExamples
                                                     
                                                     column.Item()
                                                         .PaddingBottom(8)
-                                                        .SemanticHeader2(category2.Category)
+                                                        .SemanticHeader2()
                                                         .Text(category2.Category)
                                                         .FontSize(20)
                                                         .FontColor(Colors.Blue.Darken2)
@@ -119,7 +119,7 @@ public class SemanticExamples
                                                                 
                                                                 column.Item()
                                                                     .PaddingBottom(8)
-                                                                    .SemanticHeader3(category3.Category)
+                                                                    .SemanticHeader3()
                                                                     .Text(category3.Category)
                                                                     .FontSize(16)
                                                                     .FontColor(Colors.Blue.Medium)

+ 30 - 0
Source/QuestPDF/Elements/SemanticTag.cs

@@ -17,6 +17,9 @@ internal class SemanticTag : ContainerElement
 
     internal override void Draw(Size availableSpace)
     {
+        if (TagType is "H" or "H1" or "H2" or "H3" or "H4" or "H5" or "H6")
+            UpdateHeaderText();
+        
         if (SemanticTreeNode == null)
         {
             var id = SemanticTreeManager.GetNextNodeId();
@@ -37,4 +40,31 @@ internal class SemanticTag : ContainerElement
         Child?.Draw(availableSpace);
         SemanticTreeManager.PopStack();
     }
+
+    private void UpdateHeaderText()
+    {
+        if (!string.IsNullOrWhiteSpace(Alt))
+            return;
+        
+        var builder = new StringBuilder();
+        Traverse(builder, Child);
+        Alt = builder.ToString();
+        
+        static void Traverse(StringBuilder builder, Element element)
+        {
+            if (element is TextBlock textBlock)
+            {
+                builder.Append(textBlock.Text).Append(' ');
+            }
+            else if (element is ContainerElement container)
+            {
+                Traverse(builder, container);
+            }
+            else
+            {
+                foreach (var child in element.GetChildren())
+                    Traverse(builder, child);
+            }
+        }
+    }
 }

+ 18 - 23
Source/QuestPDF/Fluent/SemanticExtensions.cs

@@ -118,79 +118,74 @@ public static class SemanticExtensions
     #region Headers
     
     /// <summary>
-    /// A label for a subdivision of a document's content. It should be the first child of the division that it heads.
+    /// A label for a subdivision of a document's content.
+    /// It should be the first child of the division that it heads.
     /// </summary>
-    public static IContainer SemanticHeader(this IContainer container, string title)
+    public static IContainer SemanticHeader(this IContainer container)
     {
-        if (string.IsNullOrWhiteSpace(title))
-            throw new ArgumentException("Title cannot be null or empty.", nameof(title));
-
-        return container.SemanticTag("H", title);
+        return container.SemanticTag("H");
     }
     
-    private static IContainer SemanticHeader(this IContainer container, string title, int level)
+    private static IContainer SemanticHeader(this IContainer container, int level)
     {
-        if (string.IsNullOrWhiteSpace(title))
-            throw new ArgumentException("Title cannot be null or empty.", nameof(title));
-        
         if (level < 1 || level > 6)
             throw new ArgumentOutOfRangeException(nameof(level), "Header level must be between 1 and 6.");
 
-        return container.SemanticTag($"H{level}", title);
+        return container.SemanticTag($"H{level}");
     }
     
     /// <summary>
     /// A label for a subdivision of a document's content. It should be the first child of the division that it heads.
     /// A level 1 header - the highest level of heading.
     /// </summary>
-    public static IContainer SemanticHeader1(this IContainer container, string title)
+    public static IContainer SemanticHeader1(this IContainer container)
     {
-        return container.SemanticHeader(title, 1);
+        return container.SemanticHeader(1);
     }
     
     /// <summary>
     /// A label for a subdivision of a document's content. It should be the first child of the division that it heads.
     /// A level 2 header.
     /// </summary>
-    public static IContainer SemanticHeader2(this IContainer container, string title)
+    public static IContainer SemanticHeader2(this IContainer container)
     {
-        return container.SemanticHeader(title, 2);
+        return container.SemanticHeader(2);
     }
     
     /// <summary>
     /// A label for a subdivision of a document's content. It should be the first child of the division that it heads.
     /// A level 3 header.
     /// </summary>
-    public static IContainer SemanticHeader3(this IContainer container, string title)
+    public static IContainer SemanticHeader3(this IContainer container)
     {
-        return container.SemanticHeader(title, 3);
+        return container.SemanticHeader(3);
     }
     
     /// <summary>
     /// A label for a subdivision of a document's content. It should be the first child of the division that it heads.
     /// A level 4 header.
     /// </summary>
-    public static IContainer SemanticHeader4(this IContainer container, string title)
+    public static IContainer SemanticHeader4(this IContainer container)
     {
-        return container.SemanticHeader(title, 4);
+        return container.SemanticHeader(4);
     }
     
     /// <summary>
     /// A label for a subdivision of a document's content. It should be the first child of the division that it heads.
     /// A level 5 header.
     /// </summary>
-    public static IContainer SemanticHeader5(this IContainer container, string title)
+    public static IContainer SemanticHeader5(this IContainer container)
     {
-        return container.SemanticHeader(title, 5);
+        return container.SemanticHeader(5);
     }
     
     /// <summary>
     /// A label for a subdivision of a document's content. It should be the first child of the division that it heads.
     /// A level 6 header - the lowest level of heading.
     /// </summary>
-    public static IContainer SemanticHeader6(this IContainer container, string title)
+    public static IContainer SemanticHeader6(this IContainer container)
     {
-        return container.SemanticHeader(title, 6);
+        return container.SemanticHeader(6);
     }
     
     #endregion