CodePatternElementPositionLocatorExample.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. using QuestPDF.Elements;
  2. using QuestPDF.Fluent;
  3. using QuestPDF.Helpers;
  4. using QuestPDF.Infrastructure;
  5. namespace QuestPDF.DocumentationExamples.CodePatterns;
  6. public class CodePatternElementPositionLocatorExample
  7. {
  8. [Test]
  9. public void Example()
  10. {
  11. Document
  12. .Create(document =>
  13. {
  14. document.Page(page =>
  15. {
  16. page.ContinuousSize(575);
  17. page.DefaultTextStyle(x => x.FontSize(20));
  18. page.Margin(25);
  19. page.Content()
  20. .Background(Colors.White)
  21. .Row(row =>
  22. {
  23. row.Spacing(25);
  24. row.ConstantItem(0).Dynamic(new DynamicTextSpanPositionCapture());
  25. row.RelativeItem().CapturePosition("container").Text(text =>
  26. {
  27. text.Justify();
  28. var mistakeTextStyle = TextStyle.Default
  29. .FontColor(Colors.Red.Darken3)
  30. .BackgroundColor(Colors.Red.Lighten4)
  31. .Strikethrough()
  32. .DecorationThickness(2);
  33. var correctionTextStyle = TextStyle.Default
  34. .FontColor(Colors.Green.Darken3)
  35. .BackgroundColor(Colors.Green.Lighten4);
  36. text.Span("Proofreading").Bold().Underline().DecorationThickness(2);
  37. text.Span(" technical documentation is a critical quality assurance step that ensures clarity, accuracy, and consistency across all written content. It involves more than just checking for grammar and ");
  38. text.Span("spilling").Style(mistakeTextStyle);
  39. text.Span("spelling").Style(correctionTextStyle);
  40. text.Element(TextInjectedElementAlignment.Middle).CapturePosition("mistake");
  41. text.Span(" errors—it also includes verifying terminology, code syntax, formatting standards, and logical flow. A common best practice is to have the content reviewed by both a subject matter ");
  42. text.Span("export").Style(mistakeTextStyle);
  43. text.Span("expert").Style(correctionTextStyle);
  44. text.Element(TextInjectedElementAlignment.Middle).CapturePosition("mistake");
  45. text.Span(" and a language specialist, ensuring that the material is technically sound while also being accessible to the intended audience.");
  46. });
  47. });
  48. });
  49. })
  50. .GenerateImages(x => "code-pattern-element-position-locator.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
  51. }
  52. public class DynamicTextSpanPositionCapture : IDynamicComponent
  53. {
  54. public DynamicComponentComposeResult Compose(DynamicContext context)
  55. {
  56. var containerLocation = context.GetElementCapturedPositions("container").FirstOrDefault(x => x.PageNumber == context.PageNumber);
  57. var mistakeLocations = context.GetElementCapturedPositions("mistake").Where(x => x.PageNumber == context.PageNumber).ToList();
  58. if (containerLocation == null || mistakeLocations.Count == 0)
  59. {
  60. return new DynamicComponentComposeResult
  61. {
  62. Content = context.CreateElement(_ => { }),
  63. HasMoreContent = false
  64. };
  65. }
  66. var content = context.CreateElement(container =>
  67. {
  68. container.Layers(layers =>
  69. {
  70. layers.PrimaryLayer();
  71. foreach (var mistakeLocation in mistakeLocations)
  72. {
  73. layers
  74. .Layer()
  75. .Unconstrained()
  76. .TranslateY(mistakeLocation.Y - containerLocation.Y)
  77. .TranslateX(-12)
  78. .TranslateY(-12)
  79. .Width(24)
  80. .Svg("Resources/proofreading.svg");
  81. }
  82. });
  83. });
  84. return new DynamicComponentComposeResult
  85. {
  86. Content = content,
  87. HasMoreContent = false
  88. };
  89. }
  90. }
  91. }