Browse Source

Merge branch 'main' into feat-semantic-structure

Marcin Ziąbek 1 week ago
parent
commit
d2130af7d9

+ 0 - 1
Source/QuestPDF/Drawing/DocumentGenerator.cs

@@ -110,7 +110,6 @@ namespace QuestPDF.Drawing
                 return;
                 return;
             }
             }
             
             
-            // TODO: handle Header nesting values
             var semanticTreeManager = CreateSemanticTreeManager(settings);
             var semanticTreeManager = CreateSemanticTreeManager(settings);
             var useOriginalImages = canvas is ImageDocumentCanvas;
             var useOriginalImages = canvas is ImageDocumentCanvas;
             var content = ConfigureContent(document, settings, semanticTreeManager, useOriginalImages);
             var content = ConfigureContent(document, settings, semanticTreeManager, useOriginalImages);

+ 1 - 6
Source/QuestPDF/Elements/Line.cs

@@ -6,18 +6,13 @@ using QuestPDF.Skia;
 
 
 namespace QuestPDF.Elements
 namespace QuestPDF.Elements
 {
 {
-    public interface ILine
-    {
-        
-    }
-    
     internal enum LineType
     internal enum LineType
     {
     {
         Vertical,
         Vertical,
         Horizontal
         Horizontal
     }
     }
 
 
-    internal sealed class Line : Element, ILine, IStateful
+    internal sealed class Line : Element, IStateful
     {
     {
         public LineType Type { get; set; } = LineType.Vertical;
         public LineType Type { get; set; } = LineType.Vertical;
         public Color Color { get; set; } = Colors.Black;
         public Color Color { get; set; } = Colors.Black;

+ 5 - 0
Source/QuestPDF/Fluent/ColumnExtensions.cs

@@ -9,6 +9,11 @@ namespace QuestPDF.Fluent
     {
     {
         internal Column Column { get; } = new();
         internal Column Column { get; } = new();
 
 
+        internal ColumnDescriptor()
+        {
+            
+        }
+
         /// <summary>
         /// <summary>
         /// Adjusts vertical spacing between items.
         /// Adjusts vertical spacing between items.
         /// </summary>
         /// </summary>

+ 5 - 0
Source/QuestPDF/Fluent/DecorationExtensions.cs

@@ -9,6 +9,11 @@ namespace QuestPDF.Fluent
     public sealed class DecorationDescriptor
     public sealed class DecorationDescriptor
     {
     {
         internal Decoration Decoration { get; } = new Decoration();
         internal Decoration Decoration { get; } = new Decoration();
+
+        internal DecorationDescriptor()
+        {
+            
+        }
         
         
         /// <summary>
         /// <summary>
         /// Returns a container for the section positioned before (above) the primary main content.
         /// Returns a container for the section positioned before (above) the primary main content.

+ 9 - 0
Source/QuestPDF/Fluent/ElementExtensions.cs

@@ -285,6 +285,9 @@ namespace QuestPDF.Fluent
         /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="param.url"]/*' />
         /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="param.url"]/*' />
         public static IContainer Hyperlink(this IContainer element, string url)
         public static IContainer Hyperlink(this IContainer element, string url)
         {
         {
+            if (string.IsNullOrWhiteSpace(url))
+                throw new ArgumentException("The URL cannot be null or whitespace.", nameof(url));
+            
             return element.Element(new Hyperlink
             return element.Element(new Hyperlink
             {
             {
                 Url = url
                 Url = url
@@ -310,6 +313,9 @@ namespace QuestPDF.Fluent
         /// <param name="sectionName">An internal text key representing the section. It should be unique and won't appear in the final document.</param>
         /// <param name="sectionName">An internal text key representing the section. It should be unique and won't appear in the final document.</param>
         public static IContainer Section(this IContainer element, string sectionName)
         public static IContainer Section(this IContainer element, string sectionName)
         {
         {
+            if (string.IsNullOrWhiteSpace(sectionName))
+                throw new ArgumentException("The section name cannot be null or whitespace.", nameof(sectionName));
+            
             return element
             return element
                 .DebugPointer(DebugPointerType.Section, sectionName)
                 .DebugPointer(DebugPointerType.Section, sectionName)
                 .Element(new Section
                 .Element(new Section
@@ -332,6 +338,9 @@ namespace QuestPDF.Fluent
         /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="param.sectionName"]/*' />
         /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="param.sectionName"]/*' />
         public static IContainer SectionLink(this IContainer element, string sectionName)
         public static IContainer SectionLink(this IContainer element, string sectionName)
         {
         {
+            if (string.IsNullOrWhiteSpace(sectionName))
+                throw new ArgumentException("The section name cannot be null or whitespace.", nameof(sectionName));
+            
             return element.Element(new SectionLink
             return element.Element(new SectionLink
             {
             {
                 SectionName = sectionName
                 SectionName = sectionName

+ 5 - 0
Source/QuestPDF/Fluent/GridExtensions.cs

@@ -8,6 +8,11 @@ namespace QuestPDF.Fluent
     public sealed class GridDescriptor
     public sealed class GridDescriptor
     {
     {
         internal Grid Grid { get; } = new Grid();
         internal Grid Grid { get; } = new Grid();
+
+        internal GridDescriptor()
+        {
+            
+        }
         
         
         public void Spacing(float value, Unit unit = Unit.Point)
         public void Spacing(float value, Unit unit = Unit.Point)
         {
         {

+ 5 - 0
Source/QuestPDF/Fluent/InlinedExtensions.cs

@@ -7,6 +7,11 @@ namespace QuestPDF.Fluent
     public sealed class InlinedDescriptor
     public sealed class InlinedDescriptor
     {
     {
         internal Inlined Inlined { get; } = new Inlined();
         internal Inlined Inlined { get; } = new Inlined();
+
+        internal InlinedDescriptor()
+        {
+            
+        }
         
         
         #region Spacing
         #region Spacing
         
         

+ 5 - 0
Source/QuestPDF/Fluent/LayerExtensions.cs

@@ -9,6 +9,11 @@ namespace QuestPDF.Fluent
     public sealed class LayersDescriptor
     public sealed class LayersDescriptor
     {
     {
         internal Layers Layers { get; } = new Layers();
         internal Layers Layers { get; } = new Layers();
+
+        internal LayersDescriptor()
+        {
+            
+        }
         
         
         private IContainer Layer(bool isPrimary)
         private IContainer Layer(bool isPrimary)
         {
         {

+ 54 - 47
Source/QuestPDF/Fluent/LineExtensions.cs

@@ -1,62 +1,27 @@
 using System;
 using System;
 using System.Linq;
 using System.Linq;
 using QuestPDF.Elements;
 using QuestPDF.Elements;
-using QuestPDF.Helpers;
 using QuestPDF.Infrastructure;
 using QuestPDF.Infrastructure;
 
 
 namespace QuestPDF.Fluent
 namespace QuestPDF.Fluent
 {
 {
-    public static class LineExtensions
+    public class LineDescriptor
     {
     {
-        private static ILine Line(this IContainer element, LineType type, float thickness)
-        {
-            if (thickness < 0)
-                throw new ArgumentOutOfRangeException(nameof(thickness), "The Line thickness cannot be negative.");
-            
-            var line = new Line
-            {
-                Thickness = thickness,
-                Type = type
-            };
+        internal Line Line { get; } = new Line();
 
 
-            element.Element(line);
-            return line;
-        }
-        
-        /// <summary>
-        /// Renders a vertical line with a specified thickness.
-        /// <a href="https://www.questpdf.com/api-reference/line.html">Learn more</a>
-        /// </summary>
-        /// <remarks>
-        /// The line is not just a visual element; it occupies actual space within the document.
-        /// </remarks>
-        /// <returns>A descriptor to modify line attributes.</returns>
-        public static ILine LineVertical(this IContainer element, float thickness, Unit unit = Unit.Point)
-        {
-            return element.Line(LineType.Vertical, thickness.ToPoints(unit));
-        }
-        
-        /// <summary>
-        /// Renders a horizontal line with a specified thickness.
-        /// <a href="https://www.questpdf.com/api-reference/line.html">Learn more</a>
-        /// </summary>
-        /// <remarks>
-        /// The line is not just a visual element; it occupies actual space within the document.
-        /// </remarks>
-        /// <returns>A descriptor to modify line attributes.</returns>
-        public static ILine LineHorizontal(this IContainer element, float thickness, Unit unit = Unit.Point)
+        internal LineDescriptor()
         {
         {
-            return element.Line(LineType.Horizontal, thickness.ToPoints(unit));
+            
         }
         }
         
         
         /// <summary>
         /// <summary>
         /// Specifies the color for the line.
         /// Specifies the color for the line.
         /// </summary>
         /// </summary>
         /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="colorParam"]/*' />
         /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="colorParam"]/*' />
-        public static ILine LineColor(this ILine descriptor, Color color)
+        public LineDescriptor LineColor(Color color)
         {
         {
-            (descriptor as Line).Color = color;
-            return descriptor;
+            Line.Color = color;
+            return this;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -64,7 +29,7 @@ namespace QuestPDF.Fluent
         /// For example, a pattern of [2, 3] creates a dash of 2 units followed by a gap of 3 units.
         /// For example, a pattern of [2, 3] creates a dash of 2 units followed by a gap of 3 units.
         /// </summary>
         /// </summary>
         /// <param name="dashPattern">The length of this array must be even.</param>
         /// <param name="dashPattern">The length of this array must be even.</param>
-        public static ILine LineDashPattern(this ILine descriptor, float[] dashPattern, Unit unit = Unit.Point)
+        public LineDescriptor LineDashPattern(float[] dashPattern, Unit unit = Unit.Point)
         {
         {
             if (dashPattern == null)
             if (dashPattern == null)
                 throw new ArgumentNullException(nameof(dashPattern), "The dash pattern cannot be null.");
                 throw new ArgumentNullException(nameof(dashPattern), "The dash pattern cannot be null.");
@@ -75,14 +40,14 @@ namespace QuestPDF.Fluent
             if (dashPattern.Length % 2 != 0)
             if (dashPattern.Length % 2 != 0)
                 throw new ArgumentException("The dash pattern must contain an even number of elements.", nameof(dashPattern));
                 throw new ArgumentException("The dash pattern must contain an even number of elements.", nameof(dashPattern));
             
             
-            (descriptor as Line).DashPattern = dashPattern.Select(x => x.ToPoints(unit)).ToArray();
-            return descriptor;
+            Line.DashPattern = dashPattern.Select(x => x.ToPoints(unit)).ToArray();
+            return this;
         }
         }
 
 
         /// <summary>
         /// <summary>
         /// Applies a linear gradient to a line using the specified colors.
         /// Applies a linear gradient to a line using the specified colors.
         /// </summary>
         /// </summary>
-        public static ILine LineGradient(this ILine descriptor, Color[] colors)
+        public LineDescriptor LineGradient(Color[] colors)
         {
         {
             if (colors == null)
             if (colors == null)
                 throw new ArgumentNullException(nameof(colors), "The gradient colors cannot be null.");
                 throw new ArgumentNullException(nameof(colors), "The gradient colors cannot be null.");
@@ -90,8 +55,50 @@ namespace QuestPDF.Fluent
             if (colors.Length == 0)
             if (colors.Length == 0)
                 throw new ArgumentException("The gradient colors cannot be empty.", nameof(colors));
                 throw new ArgumentException("The gradient colors cannot be empty.", nameof(colors));
 
 
-            (descriptor as Line).GradientColors = colors;
+            Line.GradientColors = colors;
+            return this;
+        }
+    }
+    
+    public static class LineExtensions
+    {
+        private static LineDescriptor Line(this IContainer element, LineType type, float thickness)
+        {
+            if (thickness < 0)
+                throw new ArgumentOutOfRangeException(nameof(thickness), "The Line thickness cannot be negative.");
+            
+            var descriptor = new LineDescriptor();
+            descriptor.Line.Thickness = thickness;
+            descriptor.Line.Type = type;
+            
+            element.Element(descriptor.Line);
             return descriptor;
             return descriptor;
         }
         }
+        
+        /// <summary>
+        /// Renders a vertical line with a specified thickness.
+        /// <a href="https://www.questpdf.com/api-reference/line.html">Learn more</a>
+        /// </summary>
+        /// <remarks>
+        /// The line is not just a visual element; it occupies actual space within the document.
+        /// </remarks>
+        /// <returns>A descriptor to modify line attributes.</returns>
+        public static LineDescriptor LineVertical(this IContainer element, float thickness, Unit unit = Unit.Point)
+        {
+            return element.Line(LineType.Vertical, thickness.ToPoints(unit));
+        }
+        
+        /// <summary>
+        /// Renders a horizontal line with a specified thickness.
+        /// <a href="https://www.questpdf.com/api-reference/line.html">Learn more</a>
+        /// </summary>
+        /// <remarks>
+        /// The line is not just a visual element; it occupies actual space within the document.
+        /// </remarks>
+        /// <returns>A descriptor to modify line attributes.</returns>
+        public static LineDescriptor LineHorizontal(this IContainer element, float thickness, Unit unit = Unit.Point)
+        {
+            return element.Line(LineType.Horizontal, thickness.ToPoints(unit));
+        }
     }
     }
 }
 }

+ 5 - 0
Source/QuestPDF/Fluent/MultiColumnExtensions.cs

@@ -9,6 +9,11 @@ namespace QuestPDF.Fluent;
 public sealed class MultiColumnDescriptor
 public sealed class MultiColumnDescriptor
 {
 {
     internal MultiColumn MultiColumn { get; } = new MultiColumn();
     internal MultiColumn MultiColumn { get; } = new MultiColumn();
+
+    internal MultiColumnDescriptor()
+    {
+        
+    }
         
         
     /// <summary>
     /// <summary>
     /// Configures the horizontal spacing between adjacent columns in the layout.
     /// Configures the horizontal spacing between adjacent columns in the layout.

+ 5 - 0
Source/QuestPDF/Fluent/PageExtensions.cs

@@ -12,6 +12,11 @@ namespace QuestPDF.Fluent
     {
     {
         internal Page Page { get; } = new Page();
         internal Page Page { get; } = new Page();
 
 
+        internal PageDescriptor()
+        {
+            
+        }
+        
         #region Size
         #region Size
         
         
         /// <summary>
         /// <summary>

+ 5 - 0
Source/QuestPDF/Fluent/RowExtensions.cs

@@ -10,6 +10,11 @@ namespace QuestPDF.Fluent
     {
     {
         internal Row Row { get; } = new();
         internal Row Row { get; } = new();
 
 
+        internal RowDescriptor()
+        {
+            
+        }
+        
         /// <summary>
         /// <summary>
         /// Adjusts horizontal spacing between items.
         /// Adjusts horizontal spacing between items.
         /// </summary>
         /// </summary>

+ 10 - 0
Source/QuestPDF/Fluent/TableExtensions.cs

@@ -12,6 +12,11 @@ namespace QuestPDF.Fluent
     {
     {
         internal List<TableColumnDefinition> Columns { get; } = new();
         internal List<TableColumnDefinition> Columns { get; } = new();
         
         
+        internal TableColumnsDefinitionDescriptor()
+        {
+            
+        }
+        
         /// <summary>
         /// <summary>
         /// Defines a column of constant size that occupies the specified horizontal space.
         /// Defines a column of constant size that occupies the specified horizontal space.
         /// </summary>
         /// </summary>
@@ -76,6 +81,11 @@ namespace QuestPDF.Fluent
         private Table ContentTable { get; } = new();
         private Table ContentTable { get; } = new();
         private Table FooterTable { get; } = new();
         private Table FooterTable { get; } = new();
 
 
+        internal TableDescriptor()
+        {
+            
+        }
+        
         /// <summary>
         /// <summary>
         /// Specifies the order and size of the table columns.
         /// Specifies the order and size of the table columns.
         /// <a href="https://www.questpdf.com/api-reference/table/basics.html#columns-definition">Learn more</a>
         /// <a href="https://www.questpdf.com/api-reference/table/basics.html#columns-definition">Learn more</a>

+ 9 - 5
Source/QuestPDF/Fluent/TextExtensions.cs

@@ -6,7 +6,6 @@ using QuestPDF.Elements;
 using QuestPDF.Elements.Text;
 using QuestPDF.Elements.Text;
 using QuestPDF.Elements.Text.Items;
 using QuestPDF.Elements.Text.Items;
 using QuestPDF.Infrastructure;
 using QuestPDF.Infrastructure;
-using static System.String;
 
 
 namespace QuestPDF.Fluent
 namespace QuestPDF.Fluent
 {
 {
@@ -149,6 +148,11 @@ namespace QuestPDF.Fluent
         private TextStyle? DefaultStyle { get; set; }
         private TextStyle? DefaultStyle { get; set; }
 
 
         internal const string DefaultLineClampEllipsis = "…";
         internal const string DefaultLineClampEllipsis = "…";
+
+        internal TextDescriptor()
+        {
+            
+        }
         
         
         /// <summary>
         /// <summary>
         /// Applies a consistent text style for the whole content within this <see cref="TextExtensions.Text">Text</see> element.
         /// Applies a consistent text style for the whole content within this <see cref="TextExtensions.Text">Text</see> element.
@@ -355,8 +359,8 @@ namespace QuestPDF.Fluent
         /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="text.returns.spanDescriptor"]/*' />
         /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="text.returns.spanDescriptor"]/*' />
         public TextSpanDescriptor SectionLink(string? text, string sectionName)
         public TextSpanDescriptor SectionLink(string? text, string sectionName)
         {
         {
-            if (IsNullOrEmpty(sectionName))
-                throw new ArgumentException("Section name cannot be null or empty", nameof(sectionName));
+            if (string.IsNullOrWhiteSpace(sectionName))
+                throw new ArgumentException("Section name cannot be null or whitespace.", nameof(sectionName));
 
 
             if (text == null)
             if (text == null)
                 return new TextSpanDescriptor(new TextBlockSpan());
                 return new TextSpanDescriptor(new TextBlockSpan());
@@ -385,8 +389,8 @@ namespace QuestPDF.Fluent
         /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="text.returns.spanDescriptor"]/*' />
         /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="text.returns.spanDescriptor"]/*' />
         public TextSpanDescriptor Hyperlink(string? text, string url)
         public TextSpanDescriptor Hyperlink(string? text, string url)
         {
         {
-            if (IsNullOrEmpty(url))
-                throw new ArgumentException("Url cannot be null or empty", nameof(url));
+            if (string.IsNullOrWhiteSpace(url))
+                throw new ArgumentException("Url cannot be null or whitespace.", nameof(url));
 
 
             if (text == null)
             if (text == null)
                 return new TextSpanDescriptor(new TextBlockSpan());
                 return new TextSpanDescriptor(new TextBlockSpan());

+ 1 - 1
Source/QuestPDF/Resources/ReleaseNotes.txt

@@ -33,4 +33,4 @@
 - Simplified the Fluent API.
 - Simplified the Fluent API.
 - Made minor semantic adjustments.
 - Made minor semantic adjustments.
 - Added a conformance test suite based on the Mustang project (for ZUGFeRD).
 - Added a conformance test suite based on the Mustang project (for ZUGFeRD).
-- Performed code refactoring and cleanup.
+- Performed code refactoring and cleanup.