Browse Source

Element renaming + custom text format

MarcinZiabek 3 years ago
parent
commit
68df390d0e

+ 28 - 0
QuestPDF.ReportSample/Helpers.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Concurrent;
 using System.IO;
 using SkiaSharp;
 
@@ -24,5 +25,32 @@ namespace QuestPDF.ReportSample
                 Latitude = Helpers.Random.NextDouble() * 180f - 90f
             };
         }
+
+        private static readonly ConcurrentDictionary<int, string> RomanNumeralCache = new ConcurrentDictionary<int, string>();
+
+        public static string FormatAsRomanNumeral(this int number)
+        {
+            if (number < 0 || number > 3999) 
+                throw new ArgumentOutOfRangeException("Number should be in range from 1 to 3999");
+            
+            return RomanNumeralCache.GetOrAdd(number, x =>
+            {
+                if (x >= 1000) return "M" + FormatAsRomanNumeral(x - 1000);
+                if (x >= 900) return "CM" + FormatAsRomanNumeral(x - 900); 
+                if (x >= 500) return "D" + FormatAsRomanNumeral(x - 500);
+                if (x >= 400) return "CD" + FormatAsRomanNumeral(x - 400);
+                if (x >= 100) return "C" + FormatAsRomanNumeral(x - 100);            
+                if (x >= 90) return "XC" + FormatAsRomanNumeral(x - 90);
+                if (x >= 50) return "L" + FormatAsRomanNumeral(x - 50);
+                if (x >= 40) return "XL" + FormatAsRomanNumeral(x - 40);
+                if (x >= 10) return "X" + FormatAsRomanNumeral(x - 10);
+                if (x >= 9) return "IX" + FormatAsRomanNumeral(x - 9);
+                if (x >= 5) return "V" + FormatAsRomanNumeral(x - 5);
+                if (x >= 4) return "IV" + FormatAsRomanNumeral(x - 4);
+                if (x >= 1) return "I" + FormatAsRomanNumeral(x - 1);
+                
+                return string.Empty;  
+            });
+        }
     }
 }

+ 2 - 2
QuestPDF.ReportSample/Layouts/StandardReport.cs

@@ -39,9 +39,9 @@ namespace QuestPDF.ReportSample.Layouts
                     
                     page.Footer().AlignCenter().Text(text =>
                     {
-                        text.CurrentPageNumber();
+                        text.CurrentPageNumber(format: x => x?.FormatAsRomanNumeral() ?? "-----");
                         text.Span(" / ");
-                        text.TotalPages();
+                        text.TotalPages(format: x => x?.FormatAsRomanNumeral() ?? "-----");
                     });
                 });
         }

+ 3 - 3
QuestPDF.ReportSample/Layouts/TableOfContentsTemplate.cs

@@ -47,14 +47,14 @@ namespace QuestPDF.ReportSample.Layouts
                     row.RelativeItem().Text(locationName);
                     row.ConstantItem(150).AlignRight().Text(text =>
                     {
-                        text.BeginPageNumberOfLocation(locationName);
+                        text.BeginPageNumberOfSection(locationName);
                         text.Span(" - ");
-                        text.EndPageNumberOfLocation(locationName);
+                        text.EndPageNumberOfSection(locationName);
 
                         var lengthStyle = TextStyle.Default.Color(Colors.Grey.Medium);
                         
                         text.Span(" (", lengthStyle);
-                        text.PageLengthOfLocation(locationName, x => x == 1 ? "1 page long" : $"{x} pages long", lengthStyle);
+                        text.TotalPagesWithinSection(locationName, lengthStyle, x => x == 1 ? "1 page long" : $"{x} pages long");
                         text.Span(")", lengthStyle);
                     });
                 });

+ 1 - 1
QuestPDF.UnitTests/ExternalLinkTests.cs

@@ -8,7 +8,7 @@ namespace QuestPDF.UnitTests
     public class ExternalLinkTests
     {
         [Test]
-        public void Measure() => SimpleContainerTests.Measure<ExternalLink>();
+        public void Measure() => SimpleContainerTests.Measure<Hyperlink>();
         
         // TODO: consider tests for the Draw method
     }

+ 1 - 1
QuestPDF.UnitTests/InternalLinkTests.cs

@@ -8,7 +8,7 @@ namespace QuestPDF.UnitTests
     public class InternalLinkTests
     {
         [Test]
-        public void Measure() => SimpleContainerTests.Measure<InternalLink>();
+        public void Measure() => SimpleContainerTests.Measure<SectionLink>();
         
         // TODO: consider tests for the Draw method
     }

+ 1 - 1
QuestPDF.UnitTests/InternalLocationTests.cs

@@ -8,7 +8,7 @@ namespace QuestPDF.UnitTests
     public class InternalLocationTests
     {
         [Test]
-        public void Measure() => SimpleContainerTests.Measure<InternalLink>();
+        public void Measure() => SimpleContainerTests.Measure<SectionLink>();
         
         // TODO: consider tests for the Draw method
     }

+ 4 - 4
QuestPDF.UnitTests/TestEngine/MockCanvas.cs

@@ -20,9 +20,9 @@ namespace QuestPDF.UnitTests.TestEngine
         public void DrawRectangle(Position vector, Size size, string color) => DrawRectFunc(vector, size, color);
         public void DrawText(string text, Position position, TextStyle style) => DrawTextFunc(text, position, style);
         public void DrawImage(SKImage image, Position position, Size size) => DrawImageFunc(image, position, size);
-        
-        public void DrawExternalLink(string url, Size size) => throw new NotImplementedException();
-        public void DrawLocationLink(string locationName, Size size) => throw new NotImplementedException();
-        public void DrawLocation(string locationName) => throw new NotImplementedException();
+
+        public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
+        public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();
+        public void DrawSection(string sectionName) => throw new NotImplementedException();
     }
 }

+ 3 - 3
QuestPDF.UnitTests/TestEngine/OperationRecordingCanvas.cs

@@ -18,8 +18,8 @@ namespace QuestPDF.UnitTests.TestEngine
         public void DrawText(string text, Position position, TextStyle style) => Operations.Add(new CanvasDrawTextOperation(text, position, style));
         public void DrawImage(SKImage image, Position position, Size size) => Operations.Add(new CanvasDrawImageOperation(position, size));
         
-        public void DrawExternalLink(string url, Size size) => throw new NotImplementedException();
-        public void DrawLocationLink(string locationName, Size size) => throw new NotImplementedException();
-        public void DrawLocation(string locationName) => throw new NotImplementedException();
+        public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
+        public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();
+        public void DrawSection(string sectionName) => throw new NotImplementedException();
     }
 }

+ 3 - 3
QuestPDF/Drawing/FreeCanvas.cs

@@ -51,17 +51,17 @@ namespace QuestPDF.Drawing
             
         }
 
-        public void DrawExternalLink(string url, Size size)
+        public void DrawHyperlink(string url, Size size)
         {
            
         }
 
-        public void DrawLocationLink(string locationName, Size size)
+        public void DrawSectionLink(string sectionName, Size size)
         {
             
         }
 
-        public void DrawLocation(string locationName)
+        public void DrawSection(string sectionName)
         {
             
         }

+ 5 - 5
QuestPDF/Drawing/SkiaCanvasBase.cs

@@ -37,19 +37,19 @@ namespace QuestPDF.Drawing
             Canvas.DrawImage(image, new SKRect(vector.X, vector.Y, size.Width, size.Height));
         }
 
-        public void DrawExternalLink(string url, Size size)
+        public void DrawHyperlink(string url, Size size)
         {
             Canvas.DrawUrlAnnotation(new SKRect(0, 0, size.Width, size.Height), url);
         }
         
-        public void DrawLocationLink(string locationName, Size size)
+        public void DrawSectionLink(string sectionName, Size size)
         {
-            Canvas.DrawLinkDestinationAnnotation(new SKRect(0, 0, size.Width, size.Height), locationName);
+            Canvas.DrawLinkDestinationAnnotation(new SKRect(0, 0, size.Width, size.Height), sectionName);
         }
 
-        public void DrawLocation(string locationName)
+        public void DrawSection(string sectionName)
         {
-            Canvas.DrawNamedDestinationAnnotation(new SKPoint(0, 0), locationName);
+            Canvas.DrawNamedDestinationAnnotation(new SKPoint(0, 0), sectionName);
         }
 
         public void Rotate(float angle)

+ 2 - 2
QuestPDF/Elements/ExternalLink.cs → QuestPDF/Elements/Hyperlink.cs

@@ -3,7 +3,7 @@ using QuestPDF.Infrastructure;
 
 namespace QuestPDF.Elements
 {
-    internal class ExternalLink : ContainerElement
+    internal class Hyperlink : ContainerElement
     {
         public string Url { get; set; } = "https://www.questpdf.com";
         
@@ -14,7 +14,7 @@ namespace QuestPDF.Elements
             if (targetSize.Type == SpacePlanType.Wrap)
                 return;
 
-            Canvas.DrawExternalLink(Url, targetSize);
+            Canvas.DrawHyperlink(Url, targetSize);
             base.Draw(availableSpace);
         }
     }

+ 3 - 3
QuestPDF/Elements/InternalLocation.cs → QuestPDF/Elements/Section.cs

@@ -2,7 +2,7 @@
 
 namespace QuestPDF.Elements
 {
-    internal class InternalLocation : ContainerElement, IStateResettable
+    internal class Section : ContainerElement, IStateResettable
     {
         public string LocationName { get; set; }
         private bool IsRendered { get; set; }
@@ -16,11 +16,11 @@ namespace QuestPDF.Elements
         {
             if (!IsRendered)
             {
-                Canvas.DrawLocation(LocationName);
+                Canvas.DrawSection(LocationName);
                 IsRendered = true;
             }
             
-            PageContext.SetLocationPage(LocationName);
+            PageContext.SetSectionPage(LocationName);
             base.Draw(availableSpace);
         }
     }

+ 3 - 3
QuestPDF/Elements/InternalLink.cs → QuestPDF/Elements/SectionLink.cs

@@ -3,9 +3,9 @@ using QuestPDF.Infrastructure;
 
 namespace QuestPDF.Elements
 {
-    internal class InternalLink : ContainerElement
+    internal class SectionLink : ContainerElement
     {
-        public string LocationName { get; set; }
+        public string SectionName { get; set; }
         
         internal override void Draw(Size availableSpace)
         {
@@ -14,7 +14,7 @@ namespace QuestPDF.Elements
             if (targetSize.Type == SpacePlanType.Wrap)
                 return;
 
-            Canvas.DrawLocationLink(LocationName, targetSize);
+            Canvas.DrawSectionLink(SectionName, targetSize);
             base.Draw(availableSpace);
         }
     }

+ 2 - 2
QuestPDF/Elements/Text/Items/TextBlockExternalLink.cs → QuestPDF/Elements/Text/Items/TextBlockHyperlink.cs

@@ -3,7 +3,7 @@ using QuestPDF.Infrastructure;
 
 namespace QuestPDF.Elements.Text.Items
 {
-    internal class TextBlockExternalLink : TextBlockSpan
+    internal class TextBlockHyperlink : TextBlockSpan
     {
         public string Url { get; set; }
         
@@ -15,7 +15,7 @@ namespace QuestPDF.Elements.Text.Items
         public override void Draw(TextDrawingRequest request)
         {
             request.Canvas.Translate(new Position(0, request.TotalAscent));
-            request.Canvas.DrawExternalLink(Url, new Size(request.TextSize.Width, request.TextSize.Height));
+            request.Canvas.DrawHyperlink(Url, new Size(request.TextSize.Width, request.TextSize.Height));
             request.Canvas.Translate(new Position(0, -request.TotalAscent));
             
             base.Draw(request);

+ 3 - 3
QuestPDF/Elements/Text/Items/TextBlockInternalLink.cs → QuestPDF/Elements/Text/Items/TextBlockSectionlLink.cs

@@ -3,9 +3,9 @@ using QuestPDF.Infrastructure;
 
 namespace QuestPDF.Elements.Text.Items
 {
-    internal class TextBlockInternalLink : TextBlockSpan
+    internal class TextBlockSectionlLink : TextBlockSpan
     {
-        public string LocationName { get; set; }
+        public string SectionName { get; set; }
         
         public override TextMeasurementResult? Measure(TextMeasurementRequest request)
         {
@@ -15,7 +15,7 @@ namespace QuestPDF.Elements.Text.Items
         public override void Draw(TextDrawingRequest request)
         {
             request.Canvas.Translate(new Position(0, request.TotalAscent));
-            request.Canvas.DrawLocationLink(LocationName, new Size(request.TextSize.Width, request.TextSize.Height));
+            request.Canvas.DrawSectionLink(SectionName, new Size(request.TextSize.Width, request.TextSize.Height));
             request.Canvas.Translate(new Position(0, -request.TotalAscent));
             
             base.Draw(request);

+ 24 - 6
QuestPDF/Fluent/ElementExtensions.cs

@@ -60,7 +60,7 @@ namespace QuestPDF.Fluent
 
         public static void Placeholder(this IContainer element, string? text = null)
         {
-            element.Component(new Elements.Placeholder
+            element.Component(new Placeholder
             {
                 Text = text ?? string.Empty
             });
@@ -99,27 +99,45 @@ namespace QuestPDF.Fluent
             return element.Element(new Container());
         }
         
+        [Obsolete("This element has been renamed since version 2022.3. Please use the Hyperlink method.")]
         public static IContainer ExternalLink(this IContainer element, string url)
         {
-            return element.Element(new ExternalLink
+            return element.Hyperlink(url);
+        }
+        
+        public static IContainer Hyperlink(this IContainer element, string url)
+        {
+            return element.Element(new Hyperlink
             {
                 Url = url
             });
         }
         
+        [Obsolete("This element has been renamed since version 2022.3. Please use the Section method.")]
         public static IContainer Location(this IContainer element, string locationName)
         {
-            return element.Element(new InternalLocation
+            return element.Section(locationName);
+        }
+        
+        public static IContainer Section(this IContainer element, string sectionName)
+        {
+            return element.Element(new Section
             {
-                LocationName = locationName
+                LocationName = sectionName
             });
         }
         
+        [Obsolete("This element has been renamed since version 2022.3. Please use the SectionLink method.")]
         public static IContainer InternalLink(this IContainer element, string locationName)
         {
-            return element.Element(new InternalLink
+            return element.SectionLink(locationName);
+        }
+        
+        public static IContainer SectionLink(this IContainer element, string sectionName)
+        {
+            return element.Element(new SectionLink
             {
-                LocationName = locationName
+                SectionName = sectionName
             });
         }
         

+ 39 - 33
QuestPDF/Fluent/TextExtensions.cs

@@ -90,81 +90,81 @@ namespace QuestPDF.Fluent
             Span(Environment.NewLine);
         }
 
-        private void PageNumber(Func<IPageContext, string> source, TextStyle? style = null)
+        private static Func<int?, string> DefaultTextFormat = x => (x ?? 123).ToString();
+        
+        private void PageNumber(Func<IPageContext, int?> pageNumber, TextStyle? style, Func<int?, string>? format)
         {
             style ??= TextStyle.Default;
+            format ??= DefaultTextFormat;
             
             AddItemToLastTextBlock(new TextBlockPageNumber()
             {
-                Source = source,
+                Source = context => format(pageNumber(context)),
                 Style = style
             });
         }
-        
-        public void CurrentPageNumber(Func<int?, string> format, TextStyle? style = null)
-        {
-            PageNumber(context => format(context.CurrentPage), style);
-        }
-        
-        public void CurrentPageNumber(TextStyle? style = null)
-        {
-            CurrentPageNumber(x => x.ToString(), style);
-        }
 
-        public void TotalPages(Func<int?, string> format, TextStyle? style = null)
+        public void CurrentPageNumber(TextStyle? style = null, Func<int?, string>? format = null)
         {
-            PageNumber(context => format(context.GetLocation(PageContext.DocumentLocation)?.Length), style);
+            PageNumber(x => x.CurrentPage, style, format);
         }
         
-        public void TotalPages(TextStyle? style = null)
+        public void TotalPages(TextStyle? style = null, Func<int?, string>? format = null)
         {
-            TotalPages(x => x.ToString(), style);
+            PageNumber(x => x.GetLocation(PageContext.DocumentLocation)?.Length, style, format);
         }
-        
+
+        [Obsolete("This element has been renamed since version 2022.3. Please use the BeginPageNumberOfSection method.")]
         public void PageNumberOfLocation(string locationName, TextStyle? style = null)
         {
-            BeginPageNumberOfLocation(locationName);
+            BeginPageNumberOfSection(locationName);
         }
         
-        public void BeginPageNumberOfLocation(string locationName, TextStyle? style = null)
+        public void BeginPageNumberOfSection(string locationName, TextStyle? style = null, Func<int?, string>? format = null)
         {
-            PageNumber(context => (context.GetLocation(locationName)?.PageStart ?? 123).ToString(), style);
+            PageNumber(x => x.GetLocation(locationName)?.PageStart, style, format);
         }
         
-        public void EndPageNumberOfLocation(string locationName, TextStyle? style = null)
+        public void EndPageNumberOfSection(string locationName, TextStyle? style = null, Func<int?, string>? format = null)
         {
-            PageNumber(context => (context.GetLocation(locationName)?.PageEnd ?? 123).ToString(), style);
+            PageNumber(x => x.GetLocation(locationName)?.PageEnd, style, format);
         }
         
-        public void PageNumberWithinLocation(string locationName, Func<int?, string> format, TextStyle? style = null)
+        public void PageNumberWithinSection(string locationName, TextStyle? style = null, Func<int?, string>? format = null)
         {
-            PageNumber(context => format(context.CurrentPage + 1 - context.GetLocation(locationName)?.PageEnd), style);
+            PageNumber(x => x.CurrentPage + 1 - x.GetLocation(locationName)?.PageEnd, style, format);
         }
         
-        public void PageLengthOfLocation(string locationName, Func<int?, string> format, TextStyle? style = null)
+        public void TotalPagesWithinSection(string locationName, TextStyle? style = null, Func<int?, string>? format = null)
         {
-            PageNumber(context => format(context.GetLocation(locationName)?.Length), style);
+            PageNumber(x => x.GetLocation(locationName)?.Length, style, format);
         }
         
-        public void InternalLocation(string? text, string locationName, TextStyle? style = null)
+        public void SectionLink(string? text, string sectionName, TextStyle? style = null)
         {
             if (IsNullOrEmpty(text))
                 return;
             
-            if (IsNullOrEmpty(locationName))
-                throw new ArgumentException(nameof(locationName));
+            if (IsNullOrEmpty(sectionName))
+                throw new ArgumentException(nameof(sectionName));
 
             style ??= TextStyle.Default;
             
-            AddItemToLastTextBlock(new TextBlockInternalLink
+            AddItemToLastTextBlock(new TextBlockSectionlLink
             {
                 Style = style,
                 Text = text,
-                LocationName = locationName
+                SectionName = sectionName
             });
         }
         
-        public void ExternalLocation(string? text, string url, TextStyle? style = null)
+        [Obsolete("This element has been renamed since version 2022.3. Please use the SectionLink method.")]
+        public void InternalLocation(string? text, string locationName, TextStyle? style = null)
+        {
+            SectionLink(text, locationName, style);
+        }
+        
+        public void Hyperlink(string? text, string url, TextStyle? style = null)
         {
             if (IsNullOrEmpty(text))
                 return;
@@ -174,7 +174,7 @@ namespace QuestPDF.Fluent
             
             style ??= TextStyle.Default;
             
-            AddItemToLastTextBlock(new TextBlockExternalLink
+            AddItemToLastTextBlock(new TextBlockHyperlink
             {
                 Style = style,
                 Text = text,
@@ -182,6 +182,12 @@ namespace QuestPDF.Fluent
             });
         }
         
+        [Obsolete("This element has been renamed since version 2022.3. Please use the Hyperlink method.")]
+        public void ExternalLocation(string? text, string url, TextStyle? style = null)
+        {
+            Hyperlink(text, url, style);
+        }
+        
         public IContainer Element()
         {
             var container = new Container();

+ 3 - 3
QuestPDF/Infrastructure/ICanvas.cs

@@ -10,9 +10,9 @@ namespace QuestPDF.Infrastructure
         void DrawText(string text, Position position, TextStyle style);
         void DrawImage(SKImage image, Position position, Size size);
 
-        void DrawExternalLink(string url, Size size);
-        void DrawLocationLink(string locationName, Size size);
-        void DrawLocation(string locationName);
+        void DrawHyperlink(string url, Size size);
+        void DrawSectionLink(string sectionName, Size size);
+        void DrawSection(string sectionName);
         
         void Rotate(float angle);
         void Scale(float scaleX, float scaleY);

+ 1 - 1
QuestPDF/Infrastructure/IPageContext.cs

@@ -13,7 +13,7 @@ namespace QuestPDF.Infrastructure
     internal interface IPageContext
     {
         int CurrentPage { get; }
-        void SetLocationPage(string name);
+        void SetSectionPage(string name);
         DocumentLocation? GetLocation(string name);
     }
 }

+ 2 - 2
QuestPDF/Infrastructure/PageContext.cs

@@ -14,10 +14,10 @@ namespace QuestPDF.Infrastructure
         internal void SetPageNumber(int number)
         {
             CurrentPage = number;
-            SetLocationPage(DocumentLocation);
+            SetSectionPage(DocumentLocation);
         }
         
-        public void SetLocationPage(string name)
+        public void SetSectionPage(string name)
         {
             var location = GetLocation(name);