diff --git a/.editorconfig b/.editorconfig index ef8aae72..550e3798 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,8 @@ [*.{cs,vb}] +# 2024-02-23: I noticed that Visual studio started to think my source code is written in German 😲 +spelling_languages = en-us + # IDE0049: Simplify Names dotnet_style_predefined_type_for_locals_parameters_members = false:silent @@ -72,6 +75,10 @@ dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion dotnet_style_prefer_compound_assignment = true:suggestion dotnet_style_prefer_simplified_interpolation = true:suggestion dotnet_style_namespace_match_folder = true:suggestion +dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion +dotnet_style_readonly_field = true:suggestion +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_allow_multiple_blank_lines_experimental = true:silent [*.cs] csharp_indent_labels = one_less_than_current @@ -97,4 +104,15 @@ csharp_style_prefer_index_operator = true:suggestion csharp_style_prefer_range_operator = true:suggestion csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion csharp_style_prefer_tuple_swap = true:suggestion -csharp_style_prefer_utf8_string_literals = true:suggestion \ No newline at end of file +csharp_style_prefer_utf8_string_literals = true:suggestion +csharp_space_around_binary_operators = before_and_after +csharp_style_prefer_primary_constructors = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent +csharp_prefer_static_local_function = true:suggestion +csharp_style_prefer_readonly_struct = true:suggestion +csharp_prefer_system_threading_lock = true:suggestion +csharp_prefer_static_anonymous_function = true:suggestion +csharp_style_prefer_readonly_struct_member = true:suggestion \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index a6995fd5..52dff8e9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -49,4 +49,23 @@ *.dbproj text=auto *.sln text=auto eol=crlf +# Some more extensions required for git under Linux +.editorconfig text=auto +.gitattributes text=auto +.gitignore text=auto +LICENSE text=auto +*.config text=auto +*.DotSettings text=auto +*.json text=auto +*.md text=auto +*.nuspec text=auto +*.props text=auto +*.ps1 text=auto +*.restext text=auto +*.settings text=auto +*.txt text=auto +*.xaml text=auto +*.yaml text=auto +*.yml text=auto + *.sh eol=lf diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 26200aec..197f0e43 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -8,7 +8,7 @@ assignees: '' --- If you think there is a bug in PDFsharp then please use the IssueSubmissionTemplate to make the issue replicable. -https://docs.pdfsharp.net/General/IssueReporting.html +https://docs.pdfsharp.net/General/Issue-Reporting.html Thanks. @@ -27,4 +27,4 @@ http://forum.pdfsharp.net/ ## Steps to Reproduce the Behavior We strongly recommend using the IssueSubmissionTemplate to make sure we can replicate the issue. -https://docs.pdfsharp.net/General/IssueReporting.html +https://docs.pdfsharp.net/General/Issue-Reporting.html diff --git a/.gitignore b/.gitignore index 6dab143b..82a21a82 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,7 @@ assets/ TestResults/ localtests/ -.nuget/ .build/ -.testPublish/ *.sln.ide/ _ReSharper.*/ .idea/ @@ -15,39 +13,43 @@ PublishProfiles/ .vs/ .vscode/ .idea/ -bower_components/ -node_modules/ +# bower_components/ +# node_modules/ +zip/ debugSettings.json project.lock.json *.log *.user -*.suo +#*.suo *.cache -*.docstates +#*.docstates +*.zip _ReSharper.* nuget.exe -*net45.csproj -*net451.csproj -*k10.csproj -*.psess +#*net45.csproj +#*net451.csproj +#*k10.csproj +#*.psess *.vsp *.pidb *.userprefs *DS_Store -*.ncrunchsolution -nCrunchTemp*.* -*.*sdf -*.ipch -.settings +#*.ncrunchsolution +#nCrunchTemp*.* +#*.*sdf +#*.ipch +#.settings *.sln.ide node_modules # *launchSettings.json *.orig *.nuget.props *.nuget.targets -/localfeed -oldstate.json -InternalAgentState.json +#/localfeed +#oldstate.json +#InternalAgentState.json /nuget.config *.log -*tempfile.* \ No newline at end of file +#*tempfile.* +launchsettings.json +testEnvironments.json diff --git a/.globalconfig b/.globalconfig new file mode 100644 index 00000000..e0f231a2 --- /dev/null +++ b/.globalconfig @@ -0,0 +1,3 @@ +is_global = true + +dotnet_diagnostic.IDE0290.severity = suggestion diff --git a/LICENSE b/LICENSE index aebf7ae6..03b0a374 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2001-2023 empira Software GmbH, Cologne Area, Germany +Copyright (c) 2001-2026 empira Software GmbH, Troisdorf (Cologne Area), Germany http://docs.pdfsharp.net diff --git a/PdfSharp.sln b/PdfSharp.sln index 948a5c35..b2b46225 100644 --- a/PdfSharp.sln +++ b/PdfSharp.sln @@ -1,13 +1,19 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31912.275 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.11205.157 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{18632E7D-54DF-4933-A8DF-A7ECE8666E9B}" ProjectSection(SolutionItems) = preProject src\Directory.Build.props = src\Directory.Build.props + src\Directory.Build.targets = src\Directory.Build.targets src\Directory.Packages.props = src\Directory.Packages.props src\dotnet-test.Build.props = src\dotnet-test.Build.props + src\Local.Build.props = src\Local.Build.props + src\Local.Build.props---template = src\Local.Build.props---template + src\nuget.config = src\nuget.config + src\PdfSharpBuildConfig.props = src\PdfSharpBuildConfig.props + src\SemVersion.props = src\SemVersion.props EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PDFsharp", "PDFsharp", "{5912CE0D-0DCE-479F-944A-0DFA4CE95A88}" @@ -28,11 +34,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "foundation", "foundation", EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8770F3E1-3FEE-4611-89D4-AF80DFB3B3EA}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "projects", "projects", "{FD3FEC8C-C8C8-47F1-AF08-F77EC937ACFE}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{EF9C1FA7-24B3-438A-BD21-400C1500E164}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{71BD4587-A8B0-4653-A3B2-93578F71ABB7}" + ProjectSection(SolutionItems) = preProject + src\foundation\src\PDFsharp\tests\Directory.Build.props = src\foundation\src\PDFsharp\tests\Directory.Build.props + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Tests", "src\foundation\src\PDFsharp\tests\PdfSharp.Tests\PdfSharp.Tests.csproj", "{0B1C5283-63AC-4B2C-B0B2-D2FFD4BB3BD2}" EndProject @@ -40,8 +47,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{18E75E2F-2 ProjectSection(SolutionItems) = preProject src\foundation\src\PDFsharp\docs\AboutFonts.md = src\foundation\src\PDFsharp\docs\AboutFonts.md src\foundation\src\PDFsharp\docs\AboutImages.md = src\foundation\src\PDFsharp\docs\AboutImages.md + src\foundation\src\PDFsharp\docs\Coding-Issues.md = src\foundation\src\PDFsharp\docs\Coding-Issues.md + src\foundation\src\PDFsharp\docs\GlobalStuff.md = src\foundation\src\PDFsharp\docs\GlobalStuff.md src\foundation\src\PDFsharp\docs\Notebook.md = src\foundation\src\PDFsharp\docs\Notebook.md src\foundation\src\PDFsharp\docs\PortingNotes.md = src\foundation\src\PDFsharp\docs\PortingNotes.md + src\foundation\src\PDFsharp\docs\README.md = src\foundation\src\PDFsharp\docs\README.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{5BB9AA90-46A6-4C3A-BF50-BD122331517B}" @@ -56,6 +66,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D564E33D EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{9EB8E8CC-3BA3-4B0F-B853-5B2443C40015}" + ProjectSection(SolutionItems) = preProject + src\foundation\src\MigraDoc\docs\README.md = src\foundation\src\MigraDoc\docs\README.md + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MigraDoc.Tests", "src\foundation\src\MigraDoc\tests\MigraDoc.Tests\MigraDoc.Tests.csproj", "{CA022FCC-7A23-4759-8789-9FC86C805557}" EndProject @@ -66,8 +79,14 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MigraDoc", "MigraDoc", "{D25A7758-C8D7-473D-B032-D798FECCF08B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{62D00D8A-4171-4103-A5A4-A49212E0F7B3}" + ProjectSection(SolutionItems) = preProject + src\samples\src\PDFsharp\src\README.md = src\samples\src\PDFsharp\src\README.md + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1E84E8EF-D2F3-40A5-BF1B-10DE99894DC3}" + ProjectSection(SolutionItems) = preProject + src\samples\src\MigraDoc\src\README.md = src\samples\src\MigraDoc\src\README.md + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorld,PDFsharp", "src\samples\src\PDFsharp\src\HelloWorld\HelloWorld,PDFsharp.csproj", "{92E59C39-1633-4763-B9A3-3E6FA2593477}" EndProject @@ -103,8 +122,14 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Quality", "src\foundation\src\shared\src\PdfSharp.Quality\PdfSharp.Quality.csproj", "{B0BEB589-A3A7-4412-B045-09621FB1DE25}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Snippets", "src\foundation\src\shared\src\PdfSharp.Snippets\PdfSharp.Snippets.csproj", "{E4D95A70-171A-4027-BFCE-AB2B1907C6C1}" + ProjectSection(ProjectDependencies) = postProject + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} = {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.WPFonts", "src\foundation\src\shared\src\PdfSharp.WPFonts\PdfSharp.WPFonts.csproj", "{034B233F-0745-476A-A3DB-8DDF8FA0EF9C}" + ProjectSection(ProjectDependencies) = postProject + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} = {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "features", "features", "{F6F7E411-5CD0-4507-BF59-70004EDD09DA}" EndProject @@ -113,6 +138,9 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MigraDoc.Features", "src\foundation\src\MigraDoc\features\MigraDoc.Features\MigraDoc.Features.csproj", "{05E1F63A-EC20-4280-86A2-7971691DA964}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Features", "src\foundation\src\PDFsharp\features\PdfSharp.Features\PdfSharp.Features.csproj", "{E42F855D-9A4F-45BE-9950-F20A94169568}" + ProjectSection(ProjectDependencies) = postProject + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} = {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp-wpf", "src\foundation\src\PDFsharp\src\PdfSharp-wpf\PdfSharp-wpf.csproj", "{5BB33F6F-0151-4D8F-8530-249A9C3B9B23}" EndProject @@ -125,12 +153,24 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Quality-gdi", "src\foundation\src\shared\src\PdfSharp.Quality-gdi\PdfSharp.Quality-gdi.csproj", "{B0EE3DF4-34E1-4C69-836E-B8911192D3FE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Snippets-wpf", "src\foundation\src\shared\src\PdfSharp.Snippets-wpf\PdfSharp.Snippets-wpf.csproj", "{8F4002CD-E002-4C61-9E7A-0D78875C4767}" + ProjectSection(ProjectDependencies) = postProject + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} = {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Snippets-gdi", "src\foundation\src\shared\src\PdfSharp.Snippets-gdi\PdfSharp.Snippets-gdi.csproj", "{76959A2A-8113-430B-8272-DD37F17F9305}" + ProjectSection(ProjectDependencies) = postProject + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} = {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PDFsharp.Features-wpf", "src\foundation\src\PDFsharp\features\PDFsharp.Features-wpf\PDFsharp.Features-wpf.csproj", "{E19EF259-4C5F-4967-867C-EF3936B264C4}" + ProjectSection(ProjectDependencies) = postProject + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} = {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PDFsharp.Features-gdi", "src\foundation\src\PDFsharp\features\PDFsharp.Features-gdi\PDFsharp.Features-gdi.csproj", "{ECCE20D4-000F-4D15-87B5-0335C7B3163A}" + ProjectSection(ProjectDependencies) = postProject + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} = {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Charting-wpf", "src\foundation\src\PDFsharp\src\PdfSharp.Charting-wpf\PdfSharp.Charting-wpf.csproj", "{2E3778BB-E153-47C6-AD2C-E69F0B242578}" EndProject @@ -187,11 +227,6 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PDFsharp.NuGet-wpf", "src\foundation\nuget\src\PDFsharp.NuGet-wpf\PDFsharp.NuGet-wpf.csproj", "{4EEE7867-461B-49EC-9450-3973B932A5C8}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{76BA9372-65AE-479C-AEF7-D50E6B486CEF}" - ProjectSection(SolutionItems) = preProject - docs\BoilerplateText.md = docs\BoilerplateText.md - docs\DevNotes.md = docs\DevNotes.md - docs\MakeNewReleaseNotes.md = docs\MakeNewReleaseNotes.md - EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{A1AE894D-9061-44F0-8268-328AC41F403A}" EndProject @@ -207,6 +242,82 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PDFsharp.Features.Runner-gd EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PDFsharp.Features.Runner-wpf", "src\foundation\src\PDFsharp\features\PDFsharp.Features.Runner-wpf\PDFsharp.Features.Runner-wpf.csproj", "{D0CD20C3-C06B-436E-8C88-E5A608C74AB2}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Tests-gdi", "src\foundation\src\PDFsharp\tests\PdfSharp.Tests-gdi\PdfSharp.Tests-gdi.csproj", "{32402A03-34B2-4DA8-8A55-A4E0FCA4C3B2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.tests-wpf", "src\foundation\src\PDFsharp\tests\PdfSharp.tests-wpf\PdfSharp.tests-wpf.csproj", "{AE89ED51-5A8A-4663-ABBE-2D399C8528F4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{E00A1E03-7FB3-4A26-BB33-9BE7AA42CFB7}" + ProjectSection(SolutionItems) = preProject + src\foundation\src\shared\docs\Notebook.md = src\foundation\src\shared\docs\Notebook.md + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfFileViewer", "src\tools\src\PdfFileViewer\PdfFileViewer.csproj", "{6B5BAD8B-F029-452D-A721-0CF5F95DA1DC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.TestHelper-gdi", "src\tools\src\PdfSharp.TestHelper-gdi\PdfSharp.TestHelper-gdi.csproj", "{6E63D5DF-CADA-4AD5-8824-F1FB97185A49}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.TestHelper-wpf", "src\tools\src\PdfSharp.TestHelper-wpf\PdfSharp.TestHelper-wpf.csproj", "{284F0281-F283-4EC3-BD60-DD0CD5A5442F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Fonts", "src\foundation\src\shared\src\PdfSharp.Fonts\PdfSharp.Fonts.csproj", "{9EC27C83-FCD6-44B8-9BC6-9F270DD58C8E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Fonts.TestApp", "src\foundation\src\shared\testapps\PdfSharp.Fonts.TestApp\PdfSharp.Fonts.TestApp.csproj", "{2D32A2B9-CE4E-4F0D-9A76-1578FC3F4776}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Testing", "src\foundation\src\shared\src\PdfSharp.Testing\PdfSharp.Testing.csproj", "{D17FA884-98B9-41E2-AB27-2603F79000F5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dev", "dev", "{BA039CC9-132E-4103-BB47-87C3E3398F82}" + ProjectSection(SolutionItems) = preProject + dev\build-local-nuget-packages-release.ps1 = dev\build-local-nuget-packages-release.ps1 + dev\del-bin-and-obj.ps1 = dev\del-bin-and-obj.ps1 + dev\del-nupkg.ps1 = dev\del-nupkg.ps1 + dev\download-assets.ps1 = dev\download-assets.ps1 + dev\download-fonts.ps1 = dev\download-fonts.ps1 + dev\README.md = dev\README.md + dev\run-tests.ps1 = dev\run-tests.ps1 + dev\update-local-nuget-packages-debug.ps1 = dev\update-local-nuget-packages-debug.ps1 + dev\update-local-nuget-packages-release.ps1 = dev\update-local-nuget-packages-release.ps1 + dev\zip-PDFsharp.ps1 = dev\zip-PDFsharp.ps1 + dev\_update-local-nuget-packages.ps1 = dev\_update-local-nuget-packages.ps1 + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Testing-gdi", "src\foundation\src\shared\src\PdfSharp.Testing-gdi\PdfSharp.Testing-gdi.csproj", "{C7CCB288-8372-41AD-9F65-6224CE0D6358}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Testing-wpf", "src\foundation\src\shared\src\PdfSharp.Testing-wpf\PdfSharp.Testing-wpf.csproj", "{1F9EE0B3-4BA1-4CE4-9301-1735732B61B6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "psf", "psf", "{D2B0EC1F-CF81-4756-B20C-9BB786A151E0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CopyAsLink", "src\tools\src\CopyAsLink\CopyAsLink.csproj", "{60D307AC-D7D6-4AA4-BF9F-DDC6809CBCC7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Shared", "src\foundation\src\shared\src\PdfSharp.Shared\PdfSharp.Shared.csproj", "{8C20115B-AA17-41A7-837D-F5CFD286DFC9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.BarCodes-gdi", "src\foundation\src\PDFsharp\src\PdfSharp.BarCodes-gdi\PdfSharp.BarCodes-gdi.csproj", "{E6E3A838-95C6-462D-84E4-FAFF69DA95C0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.BarCodes-wpf", "src\foundation\src\PDFsharp\src\PdfSharp.BarCodes-wpf\PdfSharp.BarCodes-wpf.csproj", "{4CBBAD35-0D01-4BDD-8BDF-B6022497938E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.BarCodes", "src\foundation\src\PDFsharp\src\PdfSharp.BarCodes\PdfSharp.BarCodes.csproj", "{F4AB506C-AD13-4383-9AF9-48D74085ECC1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharp.Cryptography", "src\foundation\src\PDFsharp\src\PdfSharp.Cryptography\PdfSharp.Cryptography.csproj", "{769ED050-15AF-4EB5-A89F-D7123EE5AA95}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "extensions", "extensions", "{0E0ABA4E-19EE-4D84-8BD7-734AC1BA5AE0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A0D471A6-12D0-4F4E-96BE-32B461547028}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfSharp.Extensions", "src\foundation\src\extensions\src\PdfSharp.Extensions\PdfSharp.Extensions.csproj", "{2D10539B-9BEC-4D75-980B-B1D4FDFEAB8D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfSharp.BuildConfig", "src\foundation\src\shared\src\PdfSharp.BuildConfig\PdfSharp.BuildConfig.csproj", "{7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfSharp.Quality.Ghostscript", "src\foundation\src\shared\src\PdfSharp.Quality.Ghostscript\PdfSharp.Quality.Ghostscript.csproj", "{59171DE5-B6A9-CE9A-7CCA-976878FDAEBD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfSharp.Imaging", "src\foundation\src\shared\src\PdfSharp.Imaging\PdfSharp.Imaging.csproj", "{22EFBF71-31C3-ACEE-ACDB-F2D9C5EAF958}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfSharp.OpenType", "src\foundation\src\shared\src\PdfSharp.OpenType\PdfSharp.OpenType.csproj", "{08CB46DA-52D2-AB40-1E42-A8FC799565F8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PDFsharpGraphics", "PDFsharpGraphics", "{5854C6A1-5FDB-497C-A5DB-74AF372B58BF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfSharp.Fonts.Test", "src\foundation\src\shared\tests\PdfSharp.Fonts.Tests\PdfSharp.Fonts.Test.csproj", "{2F7D4DC3-BD6A-F9B0-D972-02784FEF887D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfSharp.OpenType.Test", "src\foundation\src\shared\tests\PdfSharp.OpenType.Tests\PdfSharp.OpenType.Test.csproj", "{A7A57937-E309-9E58-A3B4-6B268E6933E7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "docs-public", "docs\docs-public.csproj", "{B75C5BBF-4110-E576-C755-66CBF94A4CD9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -429,6 +540,102 @@ Global {D0CD20C3-C06B-436E-8C88-E5A608C74AB2}.Debug|Any CPU.Build.0 = Debug|Any CPU {D0CD20C3-C06B-436E-8C88-E5A608C74AB2}.Release|Any CPU.ActiveCfg = Release|Any CPU {D0CD20C3-C06B-436E-8C88-E5A608C74AB2}.Release|Any CPU.Build.0 = Release|Any CPU + {32402A03-34B2-4DA8-8A55-A4E0FCA4C3B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {32402A03-34B2-4DA8-8A55-A4E0FCA4C3B2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32402A03-34B2-4DA8-8A55-A4E0FCA4C3B2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {32402A03-34B2-4DA8-8A55-A4E0FCA4C3B2}.Release|Any CPU.Build.0 = Release|Any CPU + {AE89ED51-5A8A-4663-ABBE-2D399C8528F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE89ED51-5A8A-4663-ABBE-2D399C8528F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE89ED51-5A8A-4663-ABBE-2D399C8528F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE89ED51-5A8A-4663-ABBE-2D399C8528F4}.Release|Any CPU.Build.0 = Release|Any CPU + {6B5BAD8B-F029-452D-A721-0CF5F95DA1DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B5BAD8B-F029-452D-A721-0CF5F95DA1DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B5BAD8B-F029-452D-A721-0CF5F95DA1DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B5BAD8B-F029-452D-A721-0CF5F95DA1DC}.Release|Any CPU.Build.0 = Release|Any CPU + {6E63D5DF-CADA-4AD5-8824-F1FB97185A49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E63D5DF-CADA-4AD5-8824-F1FB97185A49}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E63D5DF-CADA-4AD5-8824-F1FB97185A49}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E63D5DF-CADA-4AD5-8824-F1FB97185A49}.Release|Any CPU.Build.0 = Release|Any CPU + {284F0281-F283-4EC3-BD60-DD0CD5A5442F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {284F0281-F283-4EC3-BD60-DD0CD5A5442F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {284F0281-F283-4EC3-BD60-DD0CD5A5442F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {284F0281-F283-4EC3-BD60-DD0CD5A5442F}.Release|Any CPU.Build.0 = Release|Any CPU + {9EC27C83-FCD6-44B8-9BC6-9F270DD58C8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9EC27C83-FCD6-44B8-9BC6-9F270DD58C8E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9EC27C83-FCD6-44B8-9BC6-9F270DD58C8E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9EC27C83-FCD6-44B8-9BC6-9F270DD58C8E}.Release|Any CPU.Build.0 = Release|Any CPU + {2D32A2B9-CE4E-4F0D-9A76-1578FC3F4776}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D32A2B9-CE4E-4F0D-9A76-1578FC3F4776}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D32A2B9-CE4E-4F0D-9A76-1578FC3F4776}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D32A2B9-CE4E-4F0D-9A76-1578FC3F4776}.Release|Any CPU.Build.0 = Release|Any CPU + {D17FA884-98B9-41E2-AB27-2603F79000F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D17FA884-98B9-41E2-AB27-2603F79000F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D17FA884-98B9-41E2-AB27-2603F79000F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D17FA884-98B9-41E2-AB27-2603F79000F5}.Release|Any CPU.Build.0 = Release|Any CPU + {C7CCB288-8372-41AD-9F65-6224CE0D6358}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7CCB288-8372-41AD-9F65-6224CE0D6358}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7CCB288-8372-41AD-9F65-6224CE0D6358}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7CCB288-8372-41AD-9F65-6224CE0D6358}.Release|Any CPU.Build.0 = Release|Any CPU + {1F9EE0B3-4BA1-4CE4-9301-1735732B61B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F9EE0B3-4BA1-4CE4-9301-1735732B61B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F9EE0B3-4BA1-4CE4-9301-1735732B61B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F9EE0B3-4BA1-4CE4-9301-1735732B61B6}.Release|Any CPU.Build.0 = Release|Any CPU + {60D307AC-D7D6-4AA4-BF9F-DDC6809CBCC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {60D307AC-D7D6-4AA4-BF9F-DDC6809CBCC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {60D307AC-D7D6-4AA4-BF9F-DDC6809CBCC7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {60D307AC-D7D6-4AA4-BF9F-DDC6809CBCC7}.Release|Any CPU.Build.0 = Release|Any CPU + {8C20115B-AA17-41A7-837D-F5CFD286DFC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C20115B-AA17-41A7-837D-F5CFD286DFC9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C20115B-AA17-41A7-837D-F5CFD286DFC9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C20115B-AA17-41A7-837D-F5CFD286DFC9}.Release|Any CPU.Build.0 = Release|Any CPU + {E6E3A838-95C6-462D-84E4-FAFF69DA95C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6E3A838-95C6-462D-84E4-FAFF69DA95C0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6E3A838-95C6-462D-84E4-FAFF69DA95C0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6E3A838-95C6-462D-84E4-FAFF69DA95C0}.Release|Any CPU.Build.0 = Release|Any CPU + {4CBBAD35-0D01-4BDD-8BDF-B6022497938E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4CBBAD35-0D01-4BDD-8BDF-B6022497938E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4CBBAD35-0D01-4BDD-8BDF-B6022497938E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4CBBAD35-0D01-4BDD-8BDF-B6022497938E}.Release|Any CPU.Build.0 = Release|Any CPU + {F4AB506C-AD13-4383-9AF9-48D74085ECC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F4AB506C-AD13-4383-9AF9-48D74085ECC1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F4AB506C-AD13-4383-9AF9-48D74085ECC1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F4AB506C-AD13-4383-9AF9-48D74085ECC1}.Release|Any CPU.Build.0 = Release|Any CPU + {769ED050-15AF-4EB5-A89F-D7123EE5AA95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {769ED050-15AF-4EB5-A89F-D7123EE5AA95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {769ED050-15AF-4EB5-A89F-D7123EE5AA95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {769ED050-15AF-4EB5-A89F-D7123EE5AA95}.Release|Any CPU.Build.0 = Release|Any CPU + {2D10539B-9BEC-4D75-980B-B1D4FDFEAB8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D10539B-9BEC-4D75-980B-B1D4FDFEAB8D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D10539B-9BEC-4D75-980B-B1D4FDFEAB8D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D10539B-9BEC-4D75-980B-B1D4FDFEAB8D}.Release|Any CPU.Build.0 = Release|Any CPU + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD}.Release|Any CPU.Build.0 = Release|Any CPU + {59171DE5-B6A9-CE9A-7CCA-976878FDAEBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {59171DE5-B6A9-CE9A-7CCA-976878FDAEBD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {59171DE5-B6A9-CE9A-7CCA-976878FDAEBD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {59171DE5-B6A9-CE9A-7CCA-976878FDAEBD}.Release|Any CPU.Build.0 = Release|Any CPU + {22EFBF71-31C3-ACEE-ACDB-F2D9C5EAF958}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {22EFBF71-31C3-ACEE-ACDB-F2D9C5EAF958}.Debug|Any CPU.Build.0 = Debug|Any CPU + {22EFBF71-31C3-ACEE-ACDB-F2D9C5EAF958}.Release|Any CPU.ActiveCfg = Release|Any CPU + {22EFBF71-31C3-ACEE-ACDB-F2D9C5EAF958}.Release|Any CPU.Build.0 = Release|Any CPU + {08CB46DA-52D2-AB40-1E42-A8FC799565F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {08CB46DA-52D2-AB40-1E42-A8FC799565F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {08CB46DA-52D2-AB40-1E42-A8FC799565F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {08CB46DA-52D2-AB40-1E42-A8FC799565F8}.Release|Any CPU.Build.0 = Release|Any CPU + {2F7D4DC3-BD6A-F9B0-D972-02784FEF887D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2F7D4DC3-BD6A-F9B0-D972-02784FEF887D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2F7D4DC3-BD6A-F9B0-D972-02784FEF887D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2F7D4DC3-BD6A-F9B0-D972-02784FEF887D}.Release|Any CPU.Build.0 = Release|Any CPU + {A7A57937-E309-9E58-A3B4-6B268E6933E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7A57937-E309-9E58-A3B4-6B268E6933E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7A57937-E309-9E58-A3B4-6B268E6933E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7A57937-E309-9E58-A3B4-6B268E6933E7}.Release|Any CPU.Build.0 = Release|Any CPU + {B75C5BBF-4110-E576-C755-66CBF94A4CD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B75C5BBF-4110-E576-C755-66CBF94A4CD9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B75C5BBF-4110-E576-C755-66CBF94A4CD9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B75C5BBF-4110-E576-C755-66CBF94A4CD9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -440,7 +647,6 @@ Global {E97F1455-620B-4BF2-B839-08F7AE2FD772} = {E1933982-1D12-497F-B465-67D5E5C74CA1} {0EDABDD2-05D5-43D0-A635-645DD8127201} = {18632E7D-54DF-4933-A8DF-A7ECE8666E9B} {8770F3E1-3FEE-4611-89D4-AF80DFB3B3EA} = {0EDABDD2-05D5-43D0-A635-645DD8127201} - {FD3FEC8C-C8C8-47F1-AF08-F77EC937ACFE} = {18632E7D-54DF-4933-A8DF-A7ECE8666E9B} {EF9C1FA7-24B3-438A-BD21-400C1500E164} = {18632E7D-54DF-4933-A8DF-A7ECE8666E9B} {71BD4587-A8B0-4653-A3B2-93578F71ABB7} = {5912CE0D-0DCE-479F-944A-0DFA4CE95A88} {0B1C5283-63AC-4B2C-B0B2-D2FFD4BB3BD2} = {71BD4587-A8B0-4653-A3B2-93578F71ABB7} @@ -515,6 +721,36 @@ Global {BA04FBE0-6B97-4D21-9561-91F12906A5F9} = {F6F7E411-5CD0-4507-BF59-70004EDD09DA} {380C02B5-94DC-491C-9458-6F5287698C77} = {F6F7E411-5CD0-4507-BF59-70004EDD09DA} {D0CD20C3-C06B-436E-8C88-E5A608C74AB2} = {F6F7E411-5CD0-4507-BF59-70004EDD09DA} + {32402A03-34B2-4DA8-8A55-A4E0FCA4C3B2} = {71BD4587-A8B0-4653-A3B2-93578F71ABB7} + {AE89ED51-5A8A-4663-ABBE-2D399C8528F4} = {71BD4587-A8B0-4653-A3B2-93578F71ABB7} + {E00A1E03-7FB3-4A26-BB33-9BE7AA42CFB7} = {A484FFA0-1C54-4C5C-B46D-6AB5C05AC5AB} + {6B5BAD8B-F029-452D-A721-0CF5F95DA1DC} = {CC13B431-6963-480F-8C21-1F78A220A399} + {6E63D5DF-CADA-4AD5-8824-F1FB97185A49} = {CC13B431-6963-480F-8C21-1F78A220A399} + {284F0281-F283-4EC3-BD60-DD0CD5A5442F} = {CC13B431-6963-480F-8C21-1F78A220A399} + {9EC27C83-FCD6-44B8-9BC6-9F270DD58C8E} = {DE458BB2-5942-4588-A74A-AE9CA86F284C} + {2D32A2B9-CE4E-4F0D-9A76-1578FC3F4776} = {9A382224-6874-4ED3-8DF6-1DD3466A02CE} + {D17FA884-98B9-41E2-AB27-2603F79000F5} = {DE458BB2-5942-4588-A74A-AE9CA86F284C} + {BA039CC9-132E-4103-BB47-87C3E3398F82} = {31FE507C-F342-4DA4-9BE5-B3D2ED93E9CC} + {C7CCB288-8372-41AD-9F65-6224CE0D6358} = {DE458BB2-5942-4588-A74A-AE9CA86F284C} + {1F9EE0B3-4BA1-4CE4-9301-1735732B61B6} = {DE458BB2-5942-4588-A74A-AE9CA86F284C} + {D2B0EC1F-CF81-4756-B20C-9BB786A151E0} = {18E75E2F-2A27-408C-BC02-9B68D7F0817F} + {60D307AC-D7D6-4AA4-BF9F-DDC6809CBCC7} = {CC13B431-6963-480F-8C21-1F78A220A399} + {8C20115B-AA17-41A7-837D-F5CFD286DFC9} = {DE458BB2-5942-4588-A74A-AE9CA86F284C} + {E6E3A838-95C6-462D-84E4-FAFF69DA95C0} = {7C753636-7947-46E0-95E0-135EAA7BFEB3} + {4CBBAD35-0D01-4BDD-8BDF-B6022497938E} = {7C753636-7947-46E0-95E0-135EAA7BFEB3} + {F4AB506C-AD13-4383-9AF9-48D74085ECC1} = {7C753636-7947-46E0-95E0-135EAA7BFEB3} + {769ED050-15AF-4EB5-A89F-D7123EE5AA95} = {7C753636-7947-46E0-95E0-135EAA7BFEB3} + {0E0ABA4E-19EE-4D84-8BD7-734AC1BA5AE0} = {8770F3E1-3FEE-4611-89D4-AF80DFB3B3EA} + {A0D471A6-12D0-4F4E-96BE-32B461547028} = {0E0ABA4E-19EE-4D84-8BD7-734AC1BA5AE0} + {2D10539B-9BEC-4D75-980B-B1D4FDFEAB8D} = {A0D471A6-12D0-4F4E-96BE-32B461547028} + {7680C9FD-3FC5-F4CE-1EE4-5E2DB977FAAD} = {DE458BB2-5942-4588-A74A-AE9CA86F284C} + {59171DE5-B6A9-CE9A-7CCA-976878FDAEBD} = {DE458BB2-5942-4588-A74A-AE9CA86F284C} + {22EFBF71-31C3-ACEE-ACDB-F2D9C5EAF958} = {DE458BB2-5942-4588-A74A-AE9CA86F284C} + {08CB46DA-52D2-AB40-1E42-A8FC799565F8} = {DE458BB2-5942-4588-A74A-AE9CA86F284C} + {5854C6A1-5FDB-497C-A5DB-74AF372B58BF} = {8770F3E1-3FEE-4611-89D4-AF80DFB3B3EA} + {2F7D4DC3-BD6A-F9B0-D972-02784FEF887D} = {A1AE894D-9061-44F0-8268-328AC41F403A} + {A7A57937-E309-9E58-A3B4-6B268E6933E7} = {A1AE894D-9061-44F0-8268-328AC41F403A} + {B75C5BBF-4110-E576-C755-66CBF94A4CD9} = {76BA9372-65AE-479C-AEF7-D50E6B486CEF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D5FF5562-3C79-434B-B951-B84542D01625} diff --git a/PdfSharp.sln.DotSettings b/PdfSharp.sln.DotSettings index 87f689af..d94e93f8 100644 --- a/PdfSharp.sln.DotSettings +++ b/PdfSharp.sln.DotSettings @@ -2,23 +2,49 @@ AES AESV AL + BI + BSD CF + CR + DA + IO IV + MD + OSX + OT SASL + TSA + URI + URL + None + True + BUG + Warning + True + TODO + Edit True ID + True True True True True True True + True True True + True True + True + True True True True + True + True + True True True True @@ -26,24 +52,33 @@ True True True + True True + True True + True + True True True True True True + True True True True True True True + True True + True True True True True True + True True + True True \ No newline at end of file diff --git a/README.md b/README.md index ec904da3..5750fabc 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,18 @@ -# PDFsharp & MigraDoc 6.0 +[![Maintained by PDFsharp Team](https://img.shields.io/badge/Maintained%20by-PDFsharp%20Team-blue?style=flat)](https://www.pdfsharp.com) +[![Commercial Support Available](https://img.shields.io/badge/Commercial%20Support-Available-blue?style=flat)](https://www.pdfsharp.com/Offers) -Version **6.1.0-preview-1** -Published **2023-12-21** +> This project is actively maintained by the PDFsharp Team. +> Professional assistance for production is available upon request. -This is a preview version of the **PDFsharp** project, the main project of PDFsharp & MigraDoc 6.0 with updates for C# 10 and .NET 6.0. +# PDFsharp & MigraDoc 7 -PDFsharp: Copyright (c) 2005-2023 empira Software GmbH, Troisdorf (Cologne Area, Germany) -MigraDoc: Copyright (c) 2001-2023 empira Software GmbH, Troisdorf (Cologne Area, Germany) +Version **7.0.0 Preview 1** +Published **2026-03-24** + +This is a preview version of the **PDFsharp** project, the main project of PDFsharp & MigraDoc 7 with updates for C# 12 and .NET 8, .NET 9, and .NET 10. + +PDFsharp: Copyright (c) 2005-2026 empira Software GmbH, Troisdorf (Cologne Area), Germany +MigraDoc: Copyright (c) 2001-2026 empira Software GmbH, Troisdorf (Cologne Area), Germany Published Open Source under the [MIT License](https://docs.pdfsharp.net/LICENSE.html) For more information see [docs.pdfsharp.net](https://docs.pdfsharp.net/) @@ -15,7 +21,7 @@ For more information see [docs.pdfsharp.net](https://docs.pdfsharp.net/) Project documentation can be found on our DOCS site: . -Note: PowerShell 7 or higher is required to execute the PowerShell scripts that come with PDFsharp. +Note that PowerShell 7 is required to execute the PowerShell scripts that come with PDFsharp. ### Download assets first @@ -23,15 +29,21 @@ Assets like bitmaps, fonts, or PDF files are not part of the repository anymore. You must download them before compiling the solution for the first time. Use `download-assets.ps1` in the `dev` folder to create `assets` folder required for some unit tests and needed by some projects. -Execute `.\dev\download-assets.ps1` +Execute + +```ps +.\dev\download-assets.ps1 +``` ### Build the solution `dotnet build` should build the solution without any warnings or errors. * You need the latest .NET SDK version installed -* If you got an exception from `GitVersion.MsBuild` let us know. - You can set a tag to define a valid version, e.g.: `git tag v6.1.0` to make it work. +* ~~Please note that you need a git repository with at least one commit in order to build the PDFsharp solution. + Without a git repository with at least one commit, you will get an error message from `GitVersion.MsBuild` while building the solution. + You can set a tag to define a valid version, e.g.: `git tag v6.2.0` to make it build with a specific version number. Without tag, version 0.1.0 will be used.~~ + (Is now done automatically by BuildConfig) ### Central package management @@ -62,3 +74,8 @@ Stefan Lange Thomas Hövel Martin Ossendorf Andreas Seifert + +## Libraries used by PDFsharp + +The Core build of PDFsharp uses BigGustave to read PNG images. BigGustave was released into the public domain and does not restrict the MIT license used by PDFsharp. +Link to project repository: https://github.com/EliotJones/BigGustave diff --git a/dev/GetAllPDFs.ps1 b/dev/GetAllPDFs.ps1 new file mode 100644 index 00000000..3029108f --- /dev/null +++ b/dev/GetAllPDFs.ps1 @@ -0,0 +1,41 @@ +# Chat/GPT creates this script for me. That is why comments are German. +# param( +# [Parameter(Mandatory = $true)] +# [string]$SourcePath, + +# [Parameter(Mandatory = $true)] +# [string]$DestinationPath +# ) + +TODO verschieben + +$SourcePath = "D:\repos\emp\PDFsharp.iText\itext.tests" +$DestinationPath = "D:\repos\emp\PDFsharp\assets\private\test-files" + +# Zielverzeichnis erstellen, falls es nicht existiert +if (-not (Test-Path -Path $DestinationPath)) { + New-Item -ItemType Directory -Path $DestinationPath | Out-Null +} + +# Alle PDF-Dateien rekursiv suchen +$files = Get-ChildItem -Path $SourcePath -Recurse -Filter *.pdf + +foreach ($file in $files) { + # Dateiname ermitteln + $destFile = Join-Path $DestinationPath $file.Name + + # Falls Datei schon existiert → eindeutigen Namen erzeugen + if (Test-Path $destFile) { + $baseName = [System.IO.Path]::GetFileNameWithoutExtension($file.Name) + $extension = $file.Extension + $counter = 1 + do { + $newName = "$baseName`_$counter$extension" + $destFile = Join-Path $DestinationPath $newName + $counter++ + } while (Test-Path $destFile) + } + + # Datei kopieren + Copy-Item -Path $file.FullName -Destination $destFile +} diff --git a/dev/README.md b/dev/README.md index 370831f3..af9f5f16 100644 --- a/dev/README.md +++ b/dev/README.md @@ -15,3 +15,9 @@ Builds NuGet packages for release on NuGet.org. ## run-tests Run unit tests on Windows and WSL2. + +## set-en.ps1 +Sets UI language for dotnet build etc. to en-US. + +## zip-PDFsharp.ps1 +Creates a PDFsharp.zip file. diff --git a/dev/_update-local-nuget-packages.ps1 b/dev/_update-local-nuget-packages.ps1 index 00abfa00..7121d72b 100644 --- a/dev/_update-local-nuget-packages.ps1 +++ b/dev/_update-local-nuget-packages.ps1 @@ -1,4 +1,4 @@ -# Updates local nuget packages. +# Updates local nuget packages - implementation #Requires -Version 7 #Requires -PSEdition Core @@ -22,21 +22,70 @@ $b = "`e[94m" $r = "`e[0m" # Set working directory to solution root. -Push-Location $PSScriptRoot -Push-Location .\.. +Push-Location $PSScriptRoot\.. -Write-Host "Copy all `e[93m$($config.ToUpperInvariant())$r NuGet packages to $b$nugetLocal$r." -New-Item -Path $nugetLocal -ItemType directory -Force | Out-Null -$packages = @() -Get-ChildItem -Path . -Filter *.nupkg -Recurse -ErrorAction SilentlyContinue -Force | ForEach-Object { - if ($_.FullName -match "bin\\$config|bin\/$config") { - Copy-Item $_.FullName -Destination ("$nugetLocal\" + $_.Name) - $packages += $_.Name +# Machine local NuGet packages +# Do not copy packages into user profile folder NugetFolder +# if .nuget-local does not exist. +if (Test-Path -Path $nugetLocal) { + # User has a local NuGet directory. +} else { + $nugetLocal = "" +} + +# Project local NuGet packages (if PDFsharp is used as submodule) +# Do not copy packages into .nuget directory if PDFsharp is not used +# as a submodule and therefore .nuget does not exist in project directory. +$nugetProject = "..\..\.nuget" # because of this: YOUR-PROJECT/modules/PDFsharp +if (Test-Path -Path $nugetProject) { + # PDFsharp is a submodule and the outer project has a .nuget directory. + $nugetProject = $nugetProject +} else { + $nugetProject = "" +} + +$hasNugetLocal = $nugetLocal.Length -gt 0 +$hasNugetProject = $nugetProject.Length -gt 0 + +if ($hasNugetLocal -or $hasNugetProject) +{ + if ($hasNugetLocal -and $hasNugetProject) + { + $targetFolders = "$b$nugetLocal$r and $b$nugetProject$r" + } + elseif ($hasNugetLocal) + { + $targetFolders = "$b$nugetLocal$r" } + elseif ($hasNugetProject) + { + $targetFolders = "$b$nugetProject$r" + } + + Write-Output "Copy all `e[93m$($config.ToUpperInvariant())$r NuGet packages to $targetFolders." + # Do not force creation of directory anymore. + # New-Item -Path $nugetLocal -ItemType directory -Force | Out-Null + $packages = @() + Get-ChildItem -Path . -Filter *.nupkg -Recurse -ErrorAction SilentlyContinue -Force | ForEach-Object { + if ($_.FullName -match "bin\\$config|bin\/$config") { + if ($nugetLocal.Length -gt 0) { + Copy-Item $_.FullName -Destination ("$nugetLocal\" + $_.Name) + } + if ($nugetProject.Length -gt 0) { + Copy-Item $_.FullName -Destination ("$nugetProject\" + $_.Name) + } + $packages += $_.Name + } + } + Write-Output " $b$($packages.Count)$r packages copied." } -Write-Host " $b$($packages.Count)$r packages copied." +else +{ + Write-Output "No `e[93m$($config.ToUpperInvariant())$r NuGet packages are copied as there is no .nuget-local and no main module .nuget folder." +} + -Write-Host "Delete all existing old package folders in $b$nuget$r folder." +Write-Output "Delete all existing old package folders in $b$nuget$r folder." $count = 0 $versions = @() $packages | ForEach-Object { @@ -63,10 +112,11 @@ $packages | ForEach-Object { } } } -Write-Host " $b$count$r package $($deleteAllPackageVersions ? '' : 'version ')folders deleted in $b$nuget$r." +Write-Output " $b$count$r package $($deleteAllPackageVersions ? '' : 'version ')folders deleted in $b$nuget$r." if ($packages.Count -gt 0) { - Write-Host " New version number(s) : $b$Versions$r" + # In case you build several times and do not delete the artifacts + # you can have more than one set of NuGet packages + Write-Output " The new version number(s) are: $b$Versions$r" } Pop-Location -Pop-Location diff --git a/dev/build-local-nuget-packages-release.ps1 b/dev/build-local-nuget-packages-release.ps1 index d6eeba5b..7992933c 100644 --- a/dev/build-local-nuget-packages-release.ps1 +++ b/dev/build-local-nuget-packages-release.ps1 @@ -1,4 +1,16 @@ -# Updates local nuget packages. +<# +.SYNOPSIS + Build PDFsharp with config release and updates the local nuget packages. + +.DESCRIPTION + The script deletes all artifacts and builds a PDFsharp release version. + It first builds the PdfSharp.BuildConfig.csproj to ensure that SemVersion.props and + PDFsharpBuildConfig.props are up-to-date before the build process starts. + The created packages are copied to two locations. + The first is the .nuget-local directory in your user profile directory. + The second is the .nuget directory in the root folder of your project in case + you used PDFsharp as a submodule. +#> #Requires -Version 7 #Requires -PSEdition Core @@ -9,31 +21,35 @@ param ( Push-Location $PSScriptRoot -try { - Write-Host "Delete bin and obj " $deleteBinAndObj +try { + # Write-Output "Delete bin and obj " $deleteBinAndObj if ($deleteBinAndObj) { - Write-Host "Deleting BIN and OBJ" - .\del-bin-and-obj.ps1 - Write-Host "Done deleting bin and obj" + Write-Output "Deleting ‘/bin’ and ‘/obj’..." + .\del-bin-and-obj.ps1 | Out-Null + Write-Output "Done." } Push-Location .. try { - Write-Host "Invoking ’dotnet build’" - dotnet build -c release + Write-Output "Invoking ‘dotnet build’ for ‘PdfSharp.BuildConfig.csproj’" + # Generate semver infos and PDFsharp build configuration first. + dotnet build .\src\foundation\src\shared\src\PdfSharp.BuildConfig\PdfSharp.BuildConfig.csproj + Write-Output "Invoking ‘dotnet build’ for PDFsharp solution" + dotnet build --configuration release $build = $LASTEXITCODE - Write-Host "’dotnet build’ has finished" + Write-Output "‘dotnet build’ has finished" } finally { Pop-Location } if ($build -gt 0) { - Write-Host "’dotnet build’ failed with code " $build - throw "’dotnet build’ failed with code " + $build + Write-Error "‘dotnet build’ failed with code " $build + throw "‘dotnet build’ failed with code " + $build } - .\update-local-nuget-packages-release.ps1 + Write-Output "Invoking ‘update-local-nuget-packages-release.ps1’" + .\update-local-nuget-packages-release.ps1 } finally { Pop-Location diff --git a/dev/del-bin-and-obj.ps1 b/dev/del-bin-and-obj.ps1 index 19a70855..fc9c7ec6 100644 --- a/dev/del-bin-and-obj.ps1 +++ b/dev/del-bin-and-obj.ps1 @@ -1,6 +1,17 @@ +# Delete contents of bin and obj folders + #Requires -Version 7 #Requires -PSEdition Core Push-Location $PSScriptRoot\..\ -Get-ChildItem .\ -include bin,obj -Recurse | ForEach-Object ($_) { remove-item $_.fullname -Force -Recurse } +if (Test-Path .\src\SemVersion.props) { + Remove-Item .\src\SemVersion.props + & .\src\foundation\src\shared\src\PdfSharp.BuildConfig\CreateBuildConfiguration.ps1 +} +Write-Output "Deleting..." +Get-ChildItem .\ -include bin,obj -Recurse | +ForEach-Object ($_) { + Remove-Item $_.fullname -Force -Recurse | Out-Null +} +Write-Output "Done." Pop-Location diff --git a/dev/download-assets.ps1 b/dev/download-assets.ps1 index 79be3ff7..f9d5dd8b 100644 --- a/dev/download-assets.ps1 +++ b/dev/download-assets.ps1 @@ -1,10 +1,15 @@ -# Downloads assets +# Downloads assets. + +# This file downloads assets required to compile the PDFsharp/MigraDoc source codes. +# This file runs under PowerShell Core 7.0 or higher. #Requires -Version 7 #Requires -PSEdition Core # Get-ChildItem .\ -include bin,obj -Recurse | ForEach-Object ($_) { remove-item $_.fullname -Force -Recurse } +# Part 1: Download assets from assets.pdfsharp.net + [string[]]$assetList = @( "pdfsharp/pdfsharp.zip" "migradoc/migradoc.zip" @@ -18,26 +23,59 @@ $source = "https://assets.pdfsharp.net/" $destination = "$PSScriptRoot/../assets/" if (test-path -PathType container $destination) { - Remove-Item -LiteralPath $destination -Force -Recurse + Remove-Item -LiteralPath $destination -Force -Recurse | Out-Null } -New-Item -ItemType Directory -Path $destination +New-Item -ItemType Directory -Path $destination | Out-Null +# Download assets version. +$url = $source + ".assets-version" +$dest = $destination + ".assets-version" +Invoke-WebRequest $url -OutFile $dest + +# Download assets files. foreach ($asset in $assetList) { $url = $source + $asset $dest = $destination + $asset $folder = [IO.Path]::GetDirectoryName($dest) - New-Item -ItemType Directory -Path $folder -Force + New-Item -ItemType Directory -Path $folder -Force | Out-Null - $x = Invoke-WebRequest $url -OutFile $dest + Invoke-WebRequest $url -OutFile $dest $idx = $asset.LastIndexOf("/") $assetFolder = $asset.Substring(0, $idx) - $zip = $asset.Substring($idx + 1) - Expand-Archive "$destination/$asset" -DestinationPath "$destination/$assetFolder" -Force - if ($LASTEXITCODE -eq 0) { - Remove-Item "$destination/$asset" - # Not all ZIP files contain compress.ps1. Suppress error messages. - Remove-Item "$destination/$assetFolder/compress.ps1" -ErrorAction Ignore - } + Expand-Archive -Force "$destination/$asset" -DestinationPath "$destination/$assetFolder" + + Remove-Item "$destination/$asset" + # Not all ZIP files contain compress.ps1. Suppress error messages. + Remove-Item "$destination/$assetFolder/compress.ps1" -ErrorAction Ignore } + +# Part 2: Download fonts + +$source = "https://assets.pdfsharp.net/" +$destination = "$PSScriptRoot/../assets/fonts/Noto/Noto_Sans/static/" + +New-Item -ItemType Directory -Path $destination | Out-Null +New-Item -ItemType Directory -Path "$destination/temp/" | Out-Null + +$url = $source + "fonts/Noto/Noto_Sans.zip" +$dest = $destination + +Invoke-WebRequest $url -OutFile "$dest/temp/noto_sans_temp.zip" +Expand-Archive -Force "$destination/temp/noto_sans_temp.zip" -DestinationPath "$destination/temp/" + +# Successfully extracted. Now move the fonts files. +[string[]]$folderList = @( + "NotoSans" + "NotoSans_Condensed" + "NotoSans_ExtraCondensed" + "NotoSans_SemiCondensed" +) + +foreach ($folder in $folderList) { + Copy-Item -Path "$destination/temp/static/$folder/*" -Include "*.ttf" -Destination $dest +} + +# Remove the folder. +Remove-Item "$destination/temp" -Recurse diff --git a/dev/download-fonts.ps1 b/dev/download-fonts.ps1 new file mode 100644 index 00000000..a06636f5 --- /dev/null +++ b/dev/download-fonts.ps1 @@ -0,0 +1,41 @@ +Write-Host "Not in use anymore" +Exit + +# Downloads assets. + +# This file downloads assets required to compile the PDFsharp/MigraDoc source codes. +# This file runs under PowerShell Core 7.0 or higher. + +#Requires -Version 7 +#Requires -PSEdition Core + +# Download fonts +# https://fonts.google.com/download?family=Noto%20Sans%20TC + +$source = "https://fonts.google.com/" +$destination = "$PSScriptRoot/../assets/fonts/Noto/Noto_Sans_TC" + +New-Item -ItemType Directory -Path $destination +# New-Item -ItemType Directory -Path "$destination/temp/" + +$url = $source + "download?family=Noto%20Sans%20TC" +$dest = $destination + +Invoke-WebRequest $url -OutFile "$dest/noto_sans_TC.zip" +Expand-Archive "$destination/noto_sans_TC.zip" -DestinationPath "$destination" -Force + +Remove-Item "$destination//noto_sans_TC.zip" -Recurse +# # Successfully extracted. Now move the fonts files. +# [string[]]$folderList = @( +# "NotoSans" +# "NotoSans_Condensed" +# "NotoSans_ExtraCondensed" +# "NotoSans_SemiCondensed" +# ) + +# foreach ($folder in $folderList) { +# Copy-Item -Path "$destination/temp/static/$folder/*" -Include "*.ttf" -Destination $dest +# } + +# Remove the folder. +# Remove-Item "$destination/temp" -Recurse diff --git a/dev/init-pdfsharp-repository.ps1 b/dev/init-pdfsharp-repository.ps1 new file mode 100644 index 00000000..c950826b --- /dev/null +++ b/dev/init-pdfsharp-repository.ps1 @@ -0,0 +1,21 @@ +# Initialize PDFsharp repository after a fresh git clone. + +#Requires -Version 7 +#Requires -PSEdition Core + +Push-Location $PSScriptRoot/.. + +# Download latest assets. TODO +# ./dev/download-assets.ps1 + ./dev/del-bin-and-obj.ps1 + +# Create correct git version information by producing +# SemVersion.props and SemVersionInformation-generated.cs. +dotnet build .\src\foundation\src\shared\src\PdfSharp.GitVersion\PdfSharp.GitVersion.csproj + +# Build the first time DEBUG and RELEASE +# Compile for testing +dotnet build +dotnet build --configuration release + +Pop-Location diff --git a/dev/run-tests.ps1 b/dev/run-tests.ps1 index 860ded03..5ecbe06e 100644 --- a/dev/run-tests.ps1 +++ b/dev/run-tests.ps1 @@ -1,167 +1,885 @@ -#Requires -Version 7 +<# +.SYNOPSIS + This script runs 'dotnet test' in all available environments for the solution found in the script’s root parent folder. + +.DESCRIPTION + The script builds the solution located in the script’s root parent folder and runs 'dotnet test' for all libraries to test, that are found via its projects. + These tests are run in the following environment, as far as available: Windows with NET8 or NET6, Windows with NET462 and Linux/WSL (NET8 or NET6). + For each environment, libraries not to be run (like WPF in Linux or Linux-targeting DLLs in Windows) are excluded from testing. + The test results are displayed in tables per library / code base comparing the test results in the different environments. + +.PARAMETER Config + Specifies the configuration to build and test the solution ("Debug" or "Release"). "Debug" is the default. + +.PARAMETER Net6 + Specifies whether NET6 shall be tested instead of NET8. $False is the default. + +.PARAMETER SkipBuild + Specifies whether the build of the solution shall be skipped. $False is the default. + +.PARAMETER RunAllTests + Specifies whether to run even the slow tests, whose execution can be managed via PDFsharpTests environment variable. $False is the default. + +.NOTES + Possible test results are: + -------------------------- + + Passed: The test ran successfully. + + Failed: The test has failed. + + Skipped: The test was marked to be skipped (or another circumstance resulting in 'NotExecuted' in the trx file occurred). + + Not implemented: The test result was only found for other environments. Maybe the project is not targeting or the test is not implemented for this environment. + + Not applicable: The test library was not expected to be executed, as it is not intended to be run in this environment or as this environment is not available. + + No trx file: The test library was expected to be executed, but no trx file was found. Maybe an error occurred in this script or in the 'dotnet test' call. + + Calling the script: + ------------------- + + If started in Windows, tests are executed in Windows and WSL: + + > .\dev\run-tests.ps1 + + If started from Windows in WSL, tests are executed in WSL only: + + > wsl -e pwsh -c .\dev\run-tests.ps1 + + If started in Linux / WSL, tests are executed in Linux / WSL only: + + > pwsh -c ./dev/run-tests.ps1 + + Changing the script: + -------------------- + + The master version of this script is maintained in the PDFsharp repository. Copies may be distributed to other repositories. + If changes to the script are needed, implement them in the PDFsharp repository and update all copies of the script in other repositories. +#> + +<# +BUG: Allow to run all tests, including GBE. +#> + +#Requires -Version 7 #Requires -PSEdition Core -# Gets DllInfo objects for all DLLs of the solution to run dotnet test in WSL for. -function GetWslTestDllInfos($solution) { - $dllInfos = GetDllInfos $solution - $testDllInfos = $dllInfos | Where-Object { $_.IsTestDll -eq $true } - $testDllsOutput = $testDllInfos | Select-Object -Property DllFileName, DllFolder +param ( + [Parameter(Mandatory = $false)] [string]$Config = 'Debug', + [Parameter(Mandatory = $false)] [bool]$Net6 = $false, + [Parameter(Mandatory = $false)] [bool]$SkipBuild = $false, + [Parameter(Mandatory = $false)] [bool]$RunAllTests = $false +) - Write-Host - Write-Host "DLLs to test found in `"$solution`"" - Write-Host "(only used to determine DLLs to test in WSL; in Windows dotnet test is run for the solution):" - Write-Host ---------------------------------------- - Write-Host ($testDllsOutput | Format-Table | Out-String) +$script:SystemNameWindows = "Windows" +$script:SystemNameLinux = "Linux" +$script:SystemNameWsl = "WSL" +$script:NetName462 = "net462" +$script:NetName6 = "net6" +$script:NetName8 = "net8" - $wslTestDllInfos = $testDllInfos | Where-Object {$_.DllFileName.EndsWith("-gdi.dll", "OrdinalIgnoreCase") -eq $false -and $_.DllFileName.EndsWith("-wpf.dll", "OrdinalIgnoreCase") -eq $false} - $wslTestDllsOutput = $wslTestDllInfos | Select-Object -Property DllFileName, DllFolder - Write-Host "DLLs to test in WSL found in `"$solution`":" - Write-Host ---------------------------------------- - Write-Host ($wslTestDllsOutput | Format-Table | Out-String) +$script:Solution +$script:TimeStart +$script:ConsoleWidth - return $wslTestDllInfos -} +# Current system information. +$script:SystemNameCurrentLinux +$script:SystemNameHost +$script:RunOnWindowsHost +$script:RunOnLinuxHost +$script:RunOnHostedWsl +$script:EnvironmentForHostedWsl -# Gets DllInfo objects for all DLLs of the solution. -function GetDllInfos($solution) { - $projects = GetSolutionProjects $Solution - $dllInfos = $projects | ForEach-Object {GetDllInfo $_} +# Information about DLLs to test in Windows/Linux. +$script:TestDllInfosWindows +$script:TestDllInfosLinux - return $dllInfos -} -# Creates a DllInfo object for a project. -function GetDllInfo($project) { - $projectFolder = Split-Path -Path $project | Resolve-Path -Relative - $projectName = Split-Path -LeafBase $project +function InitializeScript() +{ + SaveForegroundColor + + $script:Solution = GetSolutionFileName + + $script:Config = (Get-Culture).TextInfo.ToTitleCase($script:Config) - $debugFolder = Join-Path -Path $projectFolder "bin\debug" - $dllFile = Get-ChildItem -Path $debugFolder -Filter "$projectName.dll" -Recurse -ErrorAction SilentlyContinue -Force | Select-Object -first 1 - - if ($dllFile -eq $null) { - Write-Error "Could not finde file `"$debugFolder\**\$projectName.dll`". Maybe Debug Build has not been built." + if ($script:Config -ne "Debug" -and $script:Config -ne "Release") + { + Write-Error "Configuration ($script:Config) is currently not supported. Please pass `"Debug`" or `"Release`" as parameter." + exit } - $dllFolder = $dllFile.Directory.FullName | Resolve-Path -Relative - $dllFileName = $dllFile.Name + Write-Output "" + Write-Output "Started run-tests for solution `"$script:Solution`"." + Write-Output "" - $isTestDll = ContainsTestPlatformDll $dllFolder + $script:TimeStart = Get-Date + $script:ConsoleWidth = $Host.UI.RawUI.WindowSize.Width + if ($script:ConsoleWidth -lt 80) + { + Write-Warning "Low console width recognized ($script:ConsoleWidth)!" + Write-Warning "A width of at least 80 characters is recommended to ensure a good presentation. For lower widths result columns may be omitted." + } + + # Pre-set current system information. + $script:SystemNameCurrentLinux = "none" + $script:SystemNameHost = "unknown" + $script:RunOnWindowsHost = $false + $script:RunOnLinuxHost = $false + $script:RunOnHostedWsl = $false + + # Set current system information. + if ($IsWindows) + { + $script:RunOnWindowsHost = $true + $script:SystemNameHost = $script:SystemNameWindows + + # Check if WSL is installed. + try + { + wslconfig /l | Out-Null + + $script:RunOnHostedWsl = $true + $script:SystemNameCurrentLinux = $script:SystemNameWsl + } + catch + { + #$script:RunOnHostedWsl remains false. + } + } + elseif ($IsLinux) + { + $script:RunOnLinuxHost = $true + + # Check if Linux is WSL. + if (Test-Path "/proc/sys/fs/binfmt_misc/WSLInterop" -PathType Leaf) + { + $script:SystemNameCurrentLinux = $script:SystemNameWsl + } + else + { + $script:SystemNameCurrentLinux = $script:SystemNameLinux + } + $script:SystemNameHost = $script:SystemNameCurrentLinux + } + + # Output current system information. + Write-Output "" + Write-Output "Started script in $script:SystemNameHost." + if ($script:RunOnHostedWsl) + { + Write-Output "Tests will be run on $script:SystemNameHost host and hosted $script:SystemNameCurrentLinux." + } + else + { + Write-Output "Tests will be run on $script:SystemNameHost host only." + } + Write-Output "" + + if ($script:Net6) + { + Write-Output "NET6 Tests will be run instead of NET8." + Write-Output "" + } + + if ($script:SkipBuild) + { + Write-Output "Building solution in $script:Config build will be skipped." + Write-Output "" + } - $info = New-Object -TypeName psobject - $info | Add-Member -MemberType NoteProperty -Name ProjectName -Value $projectName - $info | Add-Member -MemberType NoteProperty -Name ProjectFolder -Value $projectFolder - $info | Add-Member -MemberType NoteProperty -Name DllFileName -Value $dllFileName - $info | Add-Member -MemberType NoteProperty -Name DllFolder -Value $dllFolder - $info | Add-Member -MemberType NoteProperty -Name IsTestDll -Value $isTestDll + if ($script:RunAllTests) + { + $env:PDFsharpTests = "runalltests" + $script:EnvironmentForHostedWsl = "PDFsharpTests=runalltests" + Write-Output "Running all tests of solution." + } + else + { + $env:PDFsharpTests = $null + $script:EnvironmentForHostedWsl = "PDFsharpTests=$null" + Write-Output "Skipping slow tests of solution." + } + Write-Output "" - return $info + CheckNetRuntimes } -# Examines if $path contains "Microsoft.TestPlatform.CommunicationUtilities.dll". -# If so, we can assume that the project DLL in $path contains unit tests to be run. -# This information is useful because starting non test projects in dotnet test may return errors. -function ContainsTestPlatformDll($path) { - $testDlls = Get-ChildItem -Path $path -Filter "Microsoft.TestPlatform.CommunicationUtilities.dll" -Recurse -ErrorAction SilentlyContinue -Force - $result = ($testDlls | measure | Select-Object -ExpandProperty Count) -gt 0 +# Checks the net runtimes for all available environments. +function CheckNetRuntimes() { + # Check net runtime for local machine. + CheckNetRuntime $false - return $result + # Check net runtime for hosted WSL, if needed. + if ($script:RunOnHostedWsl) { + CheckNetRuntime $true + } } -# Gets the projects of a solution. -function GetSolutionProjects($solutionFileName) { - $entries = dotnet sln $solutionFileName list - $projects = $entries | Where-Object {$_.EndsWith(".csproj") -eq $true} - return $projects +# Checks the net runtime for the local machine or WSL. +function CheckNetRuntime($isWsl) +{ + if ($isWsl) { + $runtimes = (wsl -e dotnet --list-runtimes | Out-String) -split "`n" + $wslOrLocal = "WSL" + } + else { + $runtimes = (dotnet --list-runtimes | Out-String) -split "`n" + $wslOrLocal = "the local machine" + } + + if ($script:Net6) { + $netMajorVersion = 6; + } + else { + $netMajorVersion = 8; + } + + $hasRequiredVersion = ($runtimes | Where-Object { $_.StartsWith("Microsoft.NETCore.App $netMajorVersion.") } | Measure-Object | Select-Object -ExpandProperty Count) -gt 0 + + if ($hasRequiredVersion -eq $false) + { + Write-Error "The script is configured to run tests for net$netMajorVersion, but the net$netMajorVersion runtime is not installed on $wslOrLocal." + exit + } } -# Gets the only solution in the current folder. +# Gets the first solution in the current folder. There should be only one. function GetSolutionFileName() { $solutionFile = Get-ChildItem -Filter "*.sln" -Recurse -ErrorAction SilentlyContinue -Force | Select-Object -first 1 $solutionFileName = $solutionFile.Name return $solutionFileName } -function AddTestResultsForEnvironment([ref]$testResults, [ref]$environmentNames, $timeStart, $testResultsFilename, $environmentName) { - AddEnvironment $environmentNames $environmentName - $testResultFiles = GetTestResultFiles $testResultsFilename $environmentName $timeStart +# Builds the Solution. +function BuildSolution() +{ + if ($script:SkipBuild) + { + return + } + + Write-Output "" + Write-Output "Building solution in $script:Config build" + Write-Output ================================================== + Write-Output "" + + dotnet build $script:Solution -c $script:Config + RestoreForegroundColor # The dotnet call may change the foreground color, e. g. when displaying test result exceptions. +} + + +# Loads DllInfo objects for all DLLs of the solution to run dotnet test for and saves the Windows and Linux specific lists. +function LoadTestDllInfos() +{ + Write-Output "" + Write-Output "Analyzing Solution to find test DLLs" + Write-Output ================================================== + Write-Output "" + + $dllInfos = GetDllInfos + + $testDllInfos = $dllInfos | Where-Object { $_.IsTestDll } + + # If Net6 parameter is true, remove net8 DLLs. + if ($script:Net6) + { + $testDllInfos = $testDllInfos | Where-Object ` + { + $_.TargetFramework.Contains("net8") -eq $false + } + } + # If Net6 parameter is false, remove net6 DLLs. + else + { + $testDllInfos = $testDllInfos | Where-Object ` + { + $_.TargetFramework.Contains("net6") -eq $false + } + } + + # Test-HACK: Only include explicit projects. + #$testDllInfos = $testDllInfos | Where-Object {$_.DllFileName.EndsWith("PdfSharp.Tests.dll", "OrdinalIgnoreCase") -or $_.DllFileName.EndsWith("Shared.Tests.dll", "OrdinalIgnoreCase")} - foreach ($testResultFile in $testResultFiles) { - AddTestResultsFromFile $testResults $environmentNames $testResultFile $environmentName + # Set $script:TestDllInfosWindows list if running on Windows host. + if ($script:RunOnWindowsHost) + { + # Exclude Linux target frameworks for Windows. + $script:TestDllInfosWindows = $testDllInfos | Where-Object ` + { + $_.TargetFramework.Contains("linux") -eq $false + } | ForEach-Object { $_.PSObject.Copy() } + + AddEnvironmentName $script:TestDllInfosWindows $script:SystemNameWindows + + OutputTestDlls $script:TestDllInfosWindows $script:SystemNameWindows + } + + # Set $script:TestDllInfosLinux list if running on Linux host or if tests will run in hosted WSL. + if ($script:RunOnLinuxHost -or $script:RunOnHostedWsl) + { + # Exclude WPF and GDI projects and net462 and Windows target frameworks for Linux. + $script:TestDllInfosLinux = $testDllInfos | Where-Object ` + { + $_.DllFileName.EndsWith("-gdi.dll", "OrdinalIgnoreCase") -eq $false -and ` + $_.DllFileName.EndsWith("-wpf.dll", "OrdinalIgnoreCase") -eq $false -and ` + $_.TargetFramework.Contains("net462") -eq $false -and ` + $_.TargetFramework.Contains("windows") -eq $false + } | ForEach-Object { $_.PSObject.Copy() } + + AddEnvironmentName $script:TestDllInfosLinux $script:SystemNameCurrentLinux + + OutputTestDlls $script:TestDllInfosLinux $script:SystemNameCurrentLinux + } +} + +function AddEnvironmentName($testDllInfos, $systemName) +{ + foreach($testDllInfo in $testDllInfos) + { + # Get the environment name and the trx filename by $systemName and the target framework of the $testDllInfo. + $environmentName = GetEnvironmentName $systemName $testDllInfo.TargetFramework + + $testDllInfo | Add-Member -MemberType NoteProperty -Name EnvironmentName -Value $environmentName } } -function AddTestResultsFromFile([ref]$testResults, [ref]$environmentNames, $path, $environmentName) { - $environmentResults = GetTestResults $path $environmentName - $testResults.Value += $environmentResults - AddEnvironment $environmentNames $environmentName +function OutputTestDlls($testDllInfos, $systemName) +{ + $testDllsOutput = $testDllInfos | Select-Object -Property DllFileName, EnvironmentName, DllFolder + + Write-Output "DLLs to test in $systemName found in `"$script:Solution`":" + Write-Output ---------------------------------------- + Write-Output ($testDllsOutput | Format-Table | Out-String) +} + +# Gets DllInfo objects for all DLLs of the solution. +function GetDllInfos() { + $projects = GetSolutionProjects $script:Solution + + $dllInfos = New-Object System.Collections.Generic.List[System.Object] + $exeGenericCodeBases = New-Object System.Collections.Generic.List[System.Object] + + # Add dllInfo for each target framework of each project to $dllInfos. + foreach($project in $projects) + { + $projectFolder = Split-Path -Path $project | Resolve-Path -Relative + $projectName = Split-Path -LeafBase $project + + $binFolder = Join-Path -Path $projectFolder "bin/$script:Config" + + $binFolderExists = Test-Path $binFolder + if ($binFolderExists -eq $false) + { + Write-Error "Missing bin folder `"$binFolder`". Maybe an error occurred while building the solution." + } + + $targetFrameworkPaths = Get-ChildItem -Path $binFolder -Directory + if (($targetFrameworkPaths | Measure-Object | Select-Object -ExpandProperty Count) -eq 0) + { + Write-Error "No target framework folders found in bin folder `"$binFolder`". Maybe an error occurred while building the solution." + } + + foreach($targetFrameworkPath in $targetFrameworkPaths) + { + $targetFrameworkFolder = Split-Path -Leaf $targetFrameworkPath + $targetFramework = $targetFrameworkFolder + + # Get DLL or, if not found, exe file belonging to the project. + $dllFile = Get-ChildItem -Path $targetFrameworkPath -Filter "$projectName.dll" -Recurse -ErrorAction SilentlyContinue -Force + if ($null -ne $dllFile) + { + $isExeFile = $false + } + else + { + $dllFile = Get-ChildItem -Path $targetFrameworkPath -Filter "$projectName.exe" -Recurse -ErrorAction SilentlyContinue -Force + if ($null -ne $dllFile) + { + $isExeFile = $true + } + } + + if ($null -eq $dllFile) + { + Write-Error "Could not find file `"$targetFrameworkPath\**\$projectName.dll`". Maybe an error occurred while building the solution." + } + else + { + $codeBase = $dllFile | Resolve-Path -Relative + $genericCodeBase = GetGenericCodeBase $codeBase + + $dllFolder = Split-Path -Parent $codeBase + $dllFileName = $dllFile.Name + $fileExtension = Split-Path -Extension $dllFileName + + $isTestDll = ContainsTestPlatformDll $dllFolder + + $info = New-Object -TypeName psobject + $info | Add-Member -MemberType NoteProperty -Name ProjectName -Value $projectName # The project name without file extension. + $info | Add-Member -MemberType NoteProperty -Name ProjectFolder -Value $projectFolder # The relative path to the project folder. + $info | Add-Member -MemberType NoteProperty -Name DllFileName -Value $dllFileName # The name of the DLL or exe file with extension. + $info | Add-Member -MemberType NoteProperty -Name DllFolder -Value $dllFolder # The relative path to the folder of the DLL or exe file. + $info | Add-Member -MemberType NoteProperty -Name CodeBase -Value $codeBase # The relative path to DLL or exe file (called CodeBase in trx files). + $info | Add-Member -MemberType NoteProperty -Name GenericCodeBase -Value $genericCodeBase # The relative path to DLL or exe file with wildcarded framework folder name and without extension. + $info | Add-Member -MemberType NoteProperty -Name GenericCodeBaseExtension -Value $fileExtension # The extension of the DLL or exe file. + $info | Add-Member -MemberType NoteProperty -Name TargetFramework -Value $targetFramework # The target framework currently processed by inspecting the according folder in the bin folder. + $info | Add-Member -MemberType NoteProperty -Name IsTestDll -Value $isTestDll # True, if the DLL/exe is recognized as a test library. + + $dllInfos.Add($info) + # For exe files a special treatment is needed below - so add them to $exeGenericCodeBases. + if ($isExeFile) + { + $exeGenericCodeBases.Add($genericCodeBase) + } + } + } + } + + # Replace GenericCodeBase filename extensions with ".dll|exe" for matches containing DLL and exe. + # This way we allow grouping by code base for projects that produce a exe file for one target framework and a DLL file for another one. + foreach ($exeGenericCodeBase in $exeGenericCodeBases) + { + $fileMatches = $dllInfos | Where-Object {$_.GenericCodeBase -eq $exeGenericCodeBase} + $hasDllMatch = ($fileMatches | Where-Object {$_.GenericCodeBaseExtension -eq ".dll"} | Measure-Object | Select-Object -ExpandProperty Count) -gt 0 + + if ($hasDllMatch) + { + foreach ($match in $fileMatches) + { + $match.GenericCodeBaseExtension = ".dll|exe" + } + } + + } + + return $dllInfos +} + +# Gets the projects of the solution. +function GetSolutionProjects() { + $entries = dotnet sln $script:Solution list + $projects = $entries | Where-Object {$_.EndsWith(".csproj")} + return $projects +} + +# Examines if $path contains "xunit.*.dll". +# If so, we can assume that the project DLL in $path contains unit tests to be run. +# This information is needed because starting non test projects in dotnet test may return errors. +function ContainsTestPlatformDll($path) { + $testDlls = Get-ChildItem -Path $path -Filter "xunit.*.dll" -Recurse -ErrorAction SilentlyContinue -Force + $result = ($testDlls | Measure-Object | Select-Object -ExpandProperty Count) -gt 0 + + return $result +} + +# Gets the relative path to DLL or exe file with wildcarded framework folder name and without extension. +function GetGenericCodeBase($codeBase) +{ + $genericCodeBase = $codeBase + + $codeBaseFrameworkPath = Split-Path -Parent $codeBase + $codeBaseBinPath = Split-Path -Parent $codeBaseFrameworkPath + $codeBaseBinFolder = Split-Path -Leaf $codeBaseBinPath + $codeBaseFileNameWithoutExtension = Split-Path -LeafBase $codeBase + + # Wildcard framework folder located in bin folder. + if ($codeBaseBinFolder.EndsWith($script:Config)) + { + $genericCodeBase = Join-Path -Path $codeBaseBinPath "*" $codeBaseFileNameWithoutExtension + } + + return $genericCodeBase } -function AddEnvironment([ref]$environmentNames, $environmentName) { - if ($environmentNames.Value -notcontains $environmentName) { - $environmentNames.Value += $environmentName +# Checks if $checkCodeBase matches $genericCodeBase and $genericCodeBaseExtension +function MatchesGenericCodeBase($checkCodeBase, $genericCodeBase, $genericCodeBaseExtension) +{ + $checkGenericCodeBase = GetGenericCodeBase $checkCodeBase + $checkExtension = Split-Path -Extension $checkCodeBase + + # If generic code bases match... + if ($genericCodeBase -eq $checkGenericCodeBase) + { + # ... and extension too, return true. + if ($genericCodeBaseExtension -eq $checkExtension) + { + return $true + } + + # ... and extension not, check if $genericCodeBaseExtension, which may be ".dll|exe", contains $checkExtension and return the result. + $genericCodeBaseExtensions = $genericCodeBaseExtension -split "|" + $hasMatch = $genericCodeBaseExtensions | Where-Object {$_.TrimStart(".") -eq $checkExtension.TrimStart(".")} + return $hasMatch } + + return $false } -function GetTestResultFiles($testResultsFilename, $environmentName, $timeStart) { - $testResultFiles = Get-ChildItem -Filter $testResultsFilename -Recurse -ErrorAction SilentlyContinue -Force | Where-Object LastWriteTime -gt $timeStart - Write-Host - Write-Host "$environmentName test files:" - if (($testResultFiles | measure).Count -eq 0) { - Write-Host "No test results found." - return $testResultFiles +# Runs dotnet test for all needed DLL/system combinations. +function RunTests() +{ + if ($script:RunOnWindowsHost) + { + RunTestsForSystem $script:TestDllInfosWindows $script:SystemNameWindows $false } - $testResultFiles = ($testResultFiles).FullName | Resolve-Path -Relative + if ($script:RunOnLinuxHost) + { + RunTestsForSystem $script:TestDllInfosLinux $script:SystemNameCurrentLinux $false + } - foreach ($testResultFile in $testResultFiles) { - Write-Host ($testResultFile) + if ($script:RunOnHostedWsl) + { + RunTestsForSystem $script:TestDllInfosLinux $script:SystemNameCurrentLinux $true } +} + +# Runs dotnet test for all needed DLLs for the given $systemName. +function RunTestsForSystem($testDllInfos, $systemName, $isHostedWsl) +{ + Write-Output "" + Write-Output Running tests on $systemName + Write-Output ================================================== + foreach ($testDllInfo in $testDllInfos) + { + # Work with absolute DLL path here to avoid errors. + $testDll = Join-Path $testDllInfo.DllFolder $testDllInfo.DllFileName + $testDllAbsolute = Resolve-Path $testDll + + # For WSL get the corresponding WSL path. + if ($isHostedWsl) + { + # $testDllExecutionPath = wsl wslpath -u $testDllAbsolute + $testDllExecutionPath = WslPath $testDllAbsolute + } + else + { + $testDllExecutionPath = $testDllAbsolute + } - return $testResultFiles + $TestResultsFilename = GetTestResultsFilename $testDllInfo.EnvironmentName + + Write-Output "" + Write-Output ($systemName): dotnet test $testDllInfo.DllFileName ("(" + $testDllInfo.TargetFramework + ")")... + Write-Output ---------------------------------------- + Write-Output "" + + # Change current location to store the trx file in the default "TestResults" folder inside the project folder. + Push-Location $testDllInfo.ProjectFolder + try + { + # Execute dotnet test on the host or hosted system for the DLL in its target framework. + if ($isHostedWsl) + { + wsl -e dotnet test $testDllExecutionPath --environment $script:EnvironmentForHostedWsl -l "trx;LogFileName=./$TestResultsFilename" --framework $testDllInfo.TargetFramework + } + else + { + dotnet test $testDllExecutionPath -l "trx;LogFileName=./$TestResultsFilename" --framework $testDllInfo.TargetFramework + } + RestoreForegroundColor # The dotnet call may change the foreground color, e. g. when displaying test result exceptions. + } + finally + { + Pop-Location + } + } + Write-Output "" + Write-Output "" } -function GetTestResults($path, $environmentName) { - $fileContent = ReadTestResultXml $path +# Gets the name of the environment for the given system and framework. +function GetEnvironmentName($systemName, $targetFramework) +{ + if ($script:Net6 -and $targetFramework.Contains("net6")) + { + $frameworkName = $script:NetName6 + } + elseif ($script:Net6 -eq $false -and $targetFramework.Contains("net8")) + { + $frameworkName = $script:NetName8 + } + elseif ($targetFramework.Contains("net462")) + { + $frameworkName = $script:NetName462 + } + else + { + Write-Error ("Framework `"" + $targetFramework + "`" is not yet supported by test script.") + } + + # HACK: For Linux the frameworkName shall not be shown. + if ($systemName -eq $script:SystemNameCurrentLinux) + { + if ($script:Net6 -and $frameworkName -ne "net6") + { + Write-Error ("For Linux there’s only one column supported (net6) by test script with Net6 parameter set to true.") + } + elseif ($script:Net6 -eq $false -and $frameworkName -ne "net8") + { + Write-Error ("For Linux there’s only one column supported (net8) by test script with Net6 parameter set to false.") + } + return "$systemName" + } + + return "$systemName-$frameworkName" +} - $nameSpace = "http://microsoft.com/schemas/VisualStudio/TeamTest/2010" - $nameSpaceManager = new-object Xml.XmlNamespaceManager $fileContent.NameTable - $nameSpaceManager.AddNamespace("ns", $nameSpace) +# Gets the Windows or Linux DllInfos list according to the environment name. +function GetDllInfosByEnvironmentName($environmentName) +{ + # Get the system specific $dllInfos for this environment. + if ($environmentName.StartsWith($script:SystemNameWindows)) + { + $dllInfos = $script:TestDllInfosWindows + } + elseif ($environmentName.StartsWith($script:SystemNameCurrentLinux)) + { + $dllInfos = $script:TestDllInfosLinux + } + else + { + Write-Error "Could not determine environment system for `"$environmentName`"" + } - $testResults = @() - foreach($unitTestResult in $fileContent.SelectNodes('//ns:UnitTestResult', $nameSpaceManager)) { - $testResult = New-Object -TypeName PsObject + return $dllInfos +} - $testResult | Add-Member -MemberType NoteProperty -Name ExecutionId -Value $unitTestResult.executionId - $testResult | Add-Member -MemberType NoteProperty -Name TestName -Value $unitTestResult.testName - $testResult | Add-Member -MemberType NoteProperty -Name Outcome -Value $unitTestResult.outcome +# Gets the name of the trx file for the given environment. +function GetTestResultsFilename($environmentName) +{ + $TestResultsFilename = "test-$environmentName.trx" + return $TestResultsFilename +} - # Not used: - #$testResult | Add-Member -MemberType NoteProperty -Name Duration -Value $unitTestResult.duration - #$testResult | Add-Member -MemberType NoteProperty -Name Message -Value $unitTestResult.Output.ErrorInfo.Message - #$testResult | Add-Member -MemberType NoteProperty -Name StackTrace -Value $unitTestResult.Output.ErrorInfo.StackTrace - $testResult | Add-Member -MemberType NoteProperty -Name Environment -Value $environmentName +# Loads the trx files and displays the test results. +function LoadAndShowTestResults() +{ + # TODO -ForegroundColor Green # Green color is used to make it the same conspicuity like the given green Format-Table header output. + Write-Output "" + Write-Output "" + Write-Output "TestResults" + Write-Output "==================================================" - $testResults += $testResult + if ($script:Net6) + { + $netNameX = $script:NetName6 + } + else + { + $netNameX = $script:NetName8 } - foreach($testResult in $testResults){ - $testDefinition = $fileContent.SelectNodes("//ns:UnitTest/ns:Execution[@id='" + $testResult.ExecutionId + "']", $nameSpaceManager) + # Environment names to be displayed in separate columns. + $environmentNameWindowsNetX = GetEnvironmentName $script:SystemNameWindows $netNameX + $environmentNameWindowsNet462 = GetEnvironmentName $script:SystemNameWindows $script:NetName462 + $environmentNameLinuxNetX = GetEnvironmentName $script:SystemNameCurrentLinux $netNameX + + $environmentNames = @($environmentNameWindowsNetX, $environmentNameWindowsNet462, $environmentNameLinuxNetX) + + # Get unique GenericCodeBaseinformation for all Windows and Linux test DLLs. + $genericCodeBaseInfos = ($script:TestDllInfosWindows + $script:TestDllInfosLinux) | Select-Object -Property GenericCodeBase, GenericCodeBaseExtension, ProjectFolder -Unique + + + # Define formats for Format-Table + $totalWidth = $script:ConsoleWidth - 2 # Subtract 2 characters of width Format-Table will not use. + + # Define the widths of the result columns + $resultColumnWidth = 17 + $firstResultColumnLeftPadding = 2 # The test column wraps at the first result column with almost no padding. Add a manual left padding for the first result column as there is no way to define column padding. + $firstResultColumnLeftPaddingStr = " " * $firstResultColumnLeftPadding + + # The test column gets the rest of the available width. + $testColumnWidth = $totalWidth - $firstResultColumnLeftPadding - 3 * $resultColumnWidth + + # Cannot generate $formats automatically, as Expression is executed later. + # In a loop generating the formats, all Expressions would get only the last assigned value of the loop variable. + $formats = @( + @{ + Label = "Test" + Expression = { $_.TestName } + Width = $testColumnWidth + }, + @{ + Label = $firstResultColumnLeftPaddingStr + "$environmentNameWindowsNetX" + Expression = { ColorizedCellFormatExpressionResult($firstResultColumnLeftPaddingStr + $_.($environmentNameWindowsNetX)) } + Width = $firstResultColumnLeftPadding + $resultColumnWidth + }, + @{ + Label = "$environmentNameWindowsNet462" + Expression = { ColorizedCellFormatExpressionResult($_.($environmentNameWindowsNet462)) } + Width = $resultColumnWidth + }, + @{ + Label = "$environmentNameLinuxNetX" + Expression = { ColorizedCellFormatExpressionResult($_.($environmentNameLinuxNetX)) } + Width = $resultColumnWidth + } + ) + + + # Load and group all test result. + $allGroupedResults = @() # Collects all results grouped by test names. + + # Use a padding to display CodeBase and the environment’s trx files. + $padValue = (($environmentNames | Select-Object -ExpandProperty Length | Measure-Object -Maximum).Maximum) + + # Loop all GenericCodeBases. For each GenericCodeBase a separate table containing the according test results is outputted. + foreach ($genericCodeBaseInfo in $genericCodeBaseInfos) + { + $genericCodeBase = $genericCodeBaseInfo.GenericCodeBase + + $genericCodeBaseWithExtension = $genericCodeBaseInfo.GenericCodeBase + $genericCodeBaseInfo.GenericCodeBaseExtension + + # TODO -ForegroundColor Green # Green color is used to make it the same conspicuity like the given green Format-Table header output. + Write-Output "" + Write-Output "" + $title = ("CodeBase:").PadRight($padValue + 1, ' ') + Write-Output $title $genericCodeBaseWithExtension + Write-Output "----------------------------------------------------------------------------------------------------" + Write-Output Test files: + + + $codeBaseResults = @() # Collects all results for this GenericCodeBase. + $testResultsFiles = @() # Collects information for the environment specific trx files for this GenericCodeBase. + + # Loop environments to load the according trx file for the code base. + foreach ($environmentName in $environmentNames) + { + $environmentResults = @() # Collects all results for this GenericCodeBase and environment. + + $testResultsFilename = GetTestResultsFilename $environmentName + $testResultsFile = Join-Path -Path $genericCodeBaseInfo.ProjectFolder "TestResults" $testResultsFilename + $testResultsFileExists = Test-Path $testResultsFile + $testResultsFileOutdated = $testResultsFileExists -and (Get-Item $testResultsFile).LastWriteTime -le $script:TimeStart + + $dllInfos = GetDllInfosByEnvironmentName $environmentName + + $referringDllInfos = $dllInfos | Where-Object GenericCodeBase -eq $genericCodeBase; - $codeBase = GetWindowsPath $testDefinition.NextSibling.codeBase | Resolve-Path -Relative + $notTargetingEnvironment = ($referringDllInfos | Where-Object EnvironmentName -eq $environmentName | Measure-Object | Select-Object -ExpandProperty Count) -eq 0 - $testResult | Add-Member -MemberType NoteProperty -Name CodeBase -Value $codeBase + $title = ($environmentName + ":").PadRight($padValue + 1, ' ') + # If the project is not targeting this environment. + if ($notTargetingEnvironment) + { + Write-Output $title Not implemented. + } + # If trx file is not found or outdated, output "No test results found" and continue loop. + elseif ($testResultsFileExists -eq $false -or $testResultsFileOutdated) + { + $testResultsFile = $null + Write-Output $title No test results found. + } + # If trx file is found and from this test run, collect results from the file. + else + { + Write-Output $title $testResultsFile + + # Read trx content. + [xml]$fileContent = Get-Content -Path $testResultsFile + $nameSpace = "http://microsoft.com/schemas/VisualStudio/TeamTest/2010" + $nameSpaceManager = new-object Xml.XmlNamespaceManager $fileContent.NameTable + $nameSpaceManager.AddNamespace("ns", $nameSpace) + + # Get all test definitions from trx file. + $testDefinitions = $fileContent.SelectNodes("//ns:UnitTest/ns:Execution", $nameSpaceManager) + + # Get all unique code bases from test definitions. + $codeBases = $testDefinitions | ForEach-Object { + $value = $_.NextSibling.codeBase + # If started in Windows convert path to Windows path. This way even the results of hosted WSL test get the Windows code bases to provide a uniform output. + if ($script:RunOnWindowsHost) + { + $value = GetWindowsPath $value + } + return $value | Resolve-Path -Relative + } | Select-Object -Unique + + # Check if all code bases in the trx file match the GenericCodeBase the trx file was found for. + foreach ($codeBase in $codeBases) + { + $matchesGenericCodeBase = MatchesGenericCodeBase $codeBase $genericCodeBase $genericCodeBaseInfo.GenericCodeBaseExtension + if ($matchesGenericCodeBase -eq $false) + { + Write-Error "Differing CodeBase found in `"$testResultsFile`": $codeBase" + } + } + + # Add test results from the trx file. + foreach ($unitTestResult in $fileContent.SelectNodes('//ns:UnitTestResult', $nameSpaceManager)) + { + $testResult = New-Object -TypeName PsObject + + $testResult | Add-Member -MemberType NoteProperty -Name ExecutionId -Value $unitTestResult.executionId + $testResult | Add-Member -MemberType NoteProperty -Name TestName -Value $unitTestResult.testName + $testResult | Add-Member -MemberType NoteProperty -Name Outcome -Value $unitTestResult.outcome # The test result. + + # Not used: + #$testResult | Add-Member -MemberType NoteProperty -Name Duration -Value $unitTestResult.duration + #$testResult | Add-Member -MemberType NoteProperty -Name Message -Value $unitTestResult.Output.ErrorInfo.Message + #$testResult | Add-Member -MemberType NoteProperty -Name StackTrace -Value $unitTestResult.Output.ErrorInfo.StackTrace + + $testResult | Add-Member -MemberType NoteProperty -Name Environment -Value $environmentName + + # Save the GenericCodeBase instead of the not generic code base value from the trx file in the test result object to make the test results comparable and groupable. + $testResult | Add-Member -MemberType NoteProperty -Name GenericCodeBase -Value $genericCodeBase + + # Add test result for this environment. + $environmentResults += $testResult + } + } + # Add environment test results for this GenericCodeBase. + $codeBaseResults += $environmentResults + + # Add information for trx file. + $testResultsFileData = New-Object -TypeName PsObject + $testResultsFileData | Add-Member -MemberType NoteProperty -Name Environment -Value $environmentName + $testResultsFileData | Add-Member -MemberType NoteProperty -Name TestResultsFile -Value $testResultsFile + $testResultsFileData | Add-Member -MemberType NoteProperty -Name NotTargetingEnvironment -Value $notTargetingEnvironment + $testResultsFiles += $testResultsFileData + } + + # Group test results for the GenericCodeBase by test name. + $groupedResults = GroupTestResults $codeBaseResults $environmentNames $testResultsFiles $genericCodeBaseInfo.GenericCodeBase + + # Output grouped GenericCodeBase test results. + $groupedResults | Format-Table $formats -Wrap + + # Add grouped test results for this GenericCodeBase. + $allGroupedResults += $groupedResults } - return $testResults + + # Add summary for all grouped test results. + # TODO -ForegroundColor Green # Green color is used to make it the same conspicuity like the given green Format-Table header output. + Write-Output "" + Write-Output "" + Write-Output "" + Write-Output Summary + Write-Output "----------------------------------------------------------------------------------------------------" + + # Create test summary from grouped test results. + $summary = CreateTestSummary $allGroupedResults $environmentNames + + # Change test column header for summary output. + $formats[0].Label = "Total:" + + # Output test results summary. + $summary | Format-Table $formats -Wrap } +# Gets the Windows path according to a WSL path. function GetWindowsPath($path) { - if ($path -match "^/mnt/(?\w)/") { + if ($path -match "^/mnt/(?\w)/") + { #$path = wsl -e wslpath -w $path # Do manual folder conversion as calling wslpath is very very slow. $path = -join($Matches.drive.ToUpper(), ":\", $path.Substring(7).Replace('/', '\')) @@ -169,91 +887,128 @@ function GetWindowsPath($path) { return $path } -function ReadTestResultXml($path) { - Write-Debug "Reading $path and parse as XML" - [xml]$fileContent = Get-Content -Path $path - return $fileContent -} - -function GroupTestResults($testResults, $environmentNames) { - $codeBaseGroups = $testResults | Group-Object CodeBase | Sort-Object Name - - $groupedResults = @() - foreach ($codeBaseGroup in $codeBaseGroups) { - $testNameGroups = $codeBaseGroup.Group | Group-Object TestName | Sort-Object Name - foreach ($testNameGroup in $testNameGroups) { - $groupedResult = New-Object -TypeName PsObject - - $groupedResult | Add-Member -MemberType NoteProperty -Name TestName -Value $testNameGroup.Name - $groupedResult | Add-Member -MemberType NoteProperty -Name CodeBase -Value $codeBaseGroup.Name - foreach ($environmentName in $environmentNames) { - $testResult = $testNameGroup.Group | Where-Object Environment -EQ $environmentName | Select-Object -First 1 - $outcome = $testResult.Outcome - if ($null -eq $outcome) { - $outcome = "Not found" +# Group test results by test name. +function GroupTestResults($testResults, $environmentNames, $testResultsFiles, $genericCodeBase) +{ + $groupedResults = @() # Collects all test results grouped by test name. + + # Group test results by test name. + $testNameGroups = $testResults | Group-Object TestName | Sort-Object Name + + # For each test name... + foreach ($testNameGroup in $testNameGroups) + { + # ...create an object containing the test name... + $groupedResult = New-Object -TypeName PsObject + $groupedResult | Add-Member -MemberType NoteProperty -Name TestName -Value $testNameGroup.Name + + # ...and a member for each environment. + foreach ($environmentName in $environmentNames) + { + $dllInfos = GetDllInfosByEnvironmentName $environmentName + + # If the GenericCodeBase, these test results belong to, is not found in this system $dllInfos, the GenericCodeBase is not applicable for this environment (they where intended not to run). + $isNotApplicable = ($dllInfos | Where-Object GenericCodeBase -eq $genericCodeBase | Measure-Object | Select-Object -ExpandProperty Count) -eq 0 + + # If the GenericCodeBase is not applicable, $outcome shall be "not applicable". + if ($isNotApplicable) + { + # DLL was not included in environment TestDllInfos. + $outcome = "Not applicable" + } + else + { + # Get the test result of this group (test name) for this environment. + $testResult = $testNameGroup.Group | Where-Object Environment -eq $environmentName | Select-Object -First 1 + + # If the GenericCodeBase is applicable, but no test result is found... + if ($null -eq $testResult) + { + $testResultsFile = $testResultsFiles | Where-Object Environment -eq $environmentName | Select-Object -First 1 + $hasTrxFile = $null -ne $testResultsFile.TestResultsFile + + # ...the project may not be targeting the environment or... + if ($testResultsFile.NotTargetingEnvironment) + { + $outcome = "Not implemented" + } + # ...the test is not found in the trx file, so we assume that it’s only implemented for other environments or... + elseif ($hasTrxFile) + { + $outcome = "Not implemented" + } + # ...the trx file is not found, although the project is targeting the environment. Is there an error? + else + { + $outcome = "No trx file" + } + } + # If the GenericCodeBase is applicable, and the test result is found, set $outcome shall be taken from the test result. + else + { + $outcome = $testResult.Outcome + + # For "NotExecuted" "Skipped" shall be returned. Attention: Maybe other circumstances than "Skipped" could result in "NotExecuted" in the trx file. + if ($outcome -eq "NotExecuted") + { + $outcome = "Skipped" + } + elseif ($null -eq $outcome) + { + $outcome = "???" + } } - $groupedResult | Add-Member -MemberType NoteProperty -Name $environmentName -Value $outcome } - $groupedResults += $GroupedResult + # For this environment add the calculated $outcome / test result. + $groupedResult | Add-Member -MemberType NoteProperty -Name $environmentName -Value $outcome } + + $groupedResults += $groupedResult } return $groupedResults } -function AddTestSummary($groupedResults, $environmentNames) { - $groupedResultsWithSummary = @() - foreach ($groupedResult in $groupedResults) { - $groupedResultsWithSummary += $groupedResult - } - - $emptyLine = New-Object -TypeName PsObject - $groupedResultsWithSummary += $emptyLine - - $emptyLine = New-Object -TypeName PsObject - $groupedResultsWithSummary += $emptyLine - - $emptyLine = New-Object -TypeName PsObject - $emptyLine | Add-Member -MemberType NoteProperty -Name TestName -Value "========================================" - foreach ($environmentName in $environmentNames) { - $emptyLine | Add-Member -MemberType NoteProperty -Name $environmentName -Value "==============" - } - $groupedResultsWithSummary += $emptyLine +# Creates a test summary from the grouped test results. +function CreateTestSummary($allGroupedResults, $environmentNames) +{ + $summary = @() $passedLine = New-Object -TypeName PsObject - $passedLine | Add-Member -MemberType NoteProperty -Name TestName -Value " Total:" - foreach ($environmentName in $environmentNames) { - $count = ($groupedResults | Where-Object $environmentName -EQ "Passed" | Measure-Object).Count + foreach ($environmentName in $environmentNames) + { + $count = ($allGroupedResults | Where-Object $environmentName -EQ "Passed" | Measure-Object).Count $passedLine | Add-Member -MemberType NoteProperty -Name $environmentName -Value "Passed: $count" } - $groupedResultsWithSummary += $passedLine + $summary += $passedLine $failedLine = New-Object -TypeName PsObject - foreach ($environmentName in $environmentNames) { - $count = ($groupedResults | Where-Object $environmentName -EQ "Failed" | Measure-Object).Count + foreach ($environmentName in $environmentNames) + { + $count = ($allGroupedResults | Where-Object $environmentName -EQ "Failed" | Measure-Object).Count $failedLine | Add-Member -MemberType NoteProperty -Name $environmentName -Value "Failed: $count" } - $groupedResultsWithSummary += $failedLine + $summary += $failedLine - $notFoundLine = New-Object -TypeName PsObject - foreach ($environmentName in $environmentNames) { - $count = ($groupedResults | Where-Object $environmentName -EQ "Not found" | Measure-Object).Count - $notFoundLine | Add-Member -MemberType NoteProperty -Name $environmentName -Value "Not found: $count" + $notImplementedLine = New-Object -TypeName PsObject + foreach ($environmentName in $environmentNames) + { + $count = ($allGroupedResults | Where-Object $environmentName -EQ "Not implemented" | Measure-Object).Count + $notImplementedLine | Add-Member -MemberType NoteProperty -Name $environmentName -Value "Not impl: $count" } - $groupedResultsWithSummary += $notFoundLine + $summary += $notImplementedLine - return $groupedResultsWithSummary + return $summary } - - -function ColorizedCellFormatExpressionResult($property) { - $isLine = $property -match "[=]" - - $split = $property.Split() +# Gets the expression for Format-Table $format, that formats $value in value-dependent color. +function ColorizedCellFormatExpressionResult($value) +{ + # Try to extract a count integer value from $value. + $split = $value.Split() $count = $null; if ($split.Length -ge 2) { $split2 = $split[$split.Length - 1] @@ -264,127 +1019,94 @@ function ColorizedCellFormatExpressionResult($property) { } # Color codes see https://duffney.io/usingansiescapesequencespowershell/#basic-foreground-background-colors + # Noticeable default value that should not occur. $color = "33" # Orange - if ($isLine -or $count -eq 0) { # Don't change color, if a count of 0 is given. + # White color for "not applicable" and summary lines with a count of 0. + if ($count -eq 0 -or $value.ToLower().Contains("not applicable")) + { $color = "37" # White } - elseif ($property.ToLower().Contains("failed")) { + elseif ($value.ToLower().Contains("failed")) + { $color = "31" # Red } - elseif ($property.ToLower().Contains("passed")) { + elseif ($value.ToLower().Contains("passed")) + { $color = "32" # Green } + # Magic to output $value in the color. $e = [char]27 - "$e[${color}m$($property)${e}[0m" + "$e[${color}m$($value)${e}[0m" } -function SaveForegroundColor() { +function SaveForegroundColor() +{ $script:foregroundColorBackup = $host.UI.RawUI.ForegroundColor } -function RestoreForegroundColor() { +function RestoreForegroundColor() +{ $host.UI.RawUI.ForegroundColor = $script:foregroundColorBackup } -# ***** Main ***** - -$TestResultsFilenameWindows = "test-windows.trx" -$TestResultsFilenameWSL = "test-wsl.trx" - -$TimeStart = Get-Date -#$TimeStart = Get-Date -Year 1900 # Hack for loading all found test result files and not only the ones created in this run. - -# TODO Add try/finally for each Push-Location. -Push-Location $PSScriptRoot -Push-Location .. - -SaveForegroundColor - -Write-Host -$Solution = GetSolutionFileName -Write-Host "Started run-tests for solution `"$Solution`"." - -$wslTestDllInfos = GetWslTestDllInfos $Solution - -Write-Host Running tests under local Windows -Write-Host ================================================== -Write-Host -Write-Host dotnet test $Solution... -Write-Host ---------------------------------------- -Write-Host -dotnet test $Solution --no-build -l "trx;LogFileName=.\$TestResultsFilenameWindows" -RestoreForegroundColor # The dotnet call may change the foreground color, e. g. when displaying test result exceptions. - - -Write-Host -Write-Host Running tests under WSL -Write-Host ================================================== -foreach ($wslTestDllInfo in $wslTestDllInfos) { - $wslTestDll = Join-Path $wslTestDllInfo.DllFolder $wslTestDllInfo.DllFileName - $wslTestDllAbsolute = Resolve-Path $wslTestDll - $wslTestDllLinux = wsl wslpath -u $wslTestDllAbsolute - - Write-Host - Write-Host WSL: dotnet test $wslTestDllInfo.DllFileName... - Write-Host ---------------------------------------- - Write-Host - - # Change current location to get the log file stored in the default "TestResults" folder inside the project folder. - Push-Location $wslTestDllInfo.ProjectFolder - - wsl -e dotnet test $wslTestDllLinux -l "trx;LogFileName=./$TestResultsFilenameWSL" - RestoreForegroundColor # The dotnet call may change the foreground color, e. g. when displaying test result exceptions. - - Pop-Location +<# +.SYNOPSIS +Converts Windows path into a Linux path and vice versa. +.DESCRIPTION +Converts Windows path into a Linux path and vice versa. Uses WSL under the hood, so needs to be installed. +See wslpath docs for more information. +.PARAMETER path +The path to convert. +.PARAMETER conversion +The direction of conversion Windows->Linux by default ('-u'). See wslpath docs for other options. +.EXAMPLE +wslpath $Profile +wslpath $Profile '-w' +#> +function WslPath( + [Parameter(Mandatory)] + [string] + $path, + + [ValidateSet('-u', '-w', '-m')] + $conversion = '-u' +) +{ + wsl 'wslpath' $conversion $path.Replace('\', '\\'); } -# Load and prepare the created TRX test result files. -Write-Host -Write-Host Preparing test results -Write-Host ========================= -Write-Host +# ***** Main ***** -$EnvironmentNameWindows = "Windows" -$EnvironmentNameWSL = "WSL" +Push-Location $PSScriptRoot +try +{ + # Execute script content in the parent folder of the script root. + Push-Location .. + try + { + InitializeScript -$Results = @() -$EnvironmentNames = @() -AddTestResultsForEnvironment ([ref]$Results) ([ref]$EnvironmentNames) $TimeStart $TestResultsFilenameWindows $EnvironmentNameWindows -AddTestResultsForEnvironment ([ref]$Results) ([ref]$EnvironmentNames) $TimeStart $TestResultsFilenameWSL $EnvironmentNameWSL + # Test-HACK for loading all found test result files and not only the ones created in this run. + #$script:TimeStart = Get-Date -Year 1900 -$GroupedResults = GroupTestResults $Results $EnvironmentNames + BuildSolution -$GroupResultsWithSummary = AddTestSummary $GroupedResults $EnvironmentNames + LoadTestDllInfos -Write-Host -Write-Host "TestResults" -ForegroundColor Green -Write-Host "==================================================" -ForegroundColor Green + RunTests -# Cannot generate $formats automatically, as Expression is executed later. -# In a loop generating the formats, all Expressions would get only the last assigned value of the loop variable. -$formats = @( - @{ - Label = "Test" - Expression = { $_.TestName } - Width = 86 - }, - @{ - Label = $EnvironmentNameWindows - Expression = { ColorizedCellFormatExpressionResult($_.Windows) } - Width = 17 - }, - @{ - Label = $EnvironmentNameWSL - Expression = { ColorizedCellFormatExpressionResult($_.WSL) } - Width = 17 + LoadAndShowTestResults } -) - -$GroupResultsWithSummary | Format-Table $formats -Wrap -GroupBy CodeBase - -Pop-Location -Pop-Location + finally + { + Pop-Location + } +} +finally +{ + Pop-Location +} \ No newline at end of file diff --git a/dev/set-en.ps1 b/dev/set-en.ps1 new file mode 100644 index 00000000..c5077ee6 --- /dev/null +++ b/dev/set-en.ps1 @@ -0,0 +1,16 @@ +# Sets UI language for dotnet build to en-US. +#Requires -Version 7 +#Requires -PSEdition Core + +# I want to see English messages on my German Windows dev machine +# when I run e.g. dotnet build. + +# What works: +$env:VSLANG = 1033 +Write-Output "Compiler output language set to en-US." + +# What does not work: +#$env:DOTNET_CLI_UI_LANG = 'en-US' +#$env:PreferredUILang = 'en-US' +#powershell -ExecutionPolicy Bypass -NoExit -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = 'en-US'; [System.Threading.Thread]::CurrentThread.CurrentUICulture = 'en-US';" +#powershell -ExecutionPolicy Bypass -NoExit -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = 'en-US'; [System.Threading.Thread]::CurrentThread.CurrentUICulture = 'en-US';" diff --git a/dev/update-local-nuget-packages-debug.ps1 b/dev/update-local-nuget-packages-debug.ps1 index 3d1bcbfc..c450956c 100644 --- a/dev/update-local-nuget-packages-debug.ps1 +++ b/dev/update-local-nuget-packages-debug.ps1 @@ -1,3 +1,5 @@ +# Update local nuget packages debug build + #Requires -Version 7 #Requires -PSEdition Core diff --git a/dev/update-local-nuget-packages-release.ps1 b/dev/update-local-nuget-packages-release.ps1 index e61ed6a4..e268276b 100644 --- a/dev/update-local-nuget-packages-release.ps1 +++ b/dev/update-local-nuget-packages-release.ps1 @@ -1,3 +1,5 @@ +# Update local nuget packages release build + #Requires -Version 7 #Requires -PSEdition Core diff --git a/dev/zip-PDFsharp.ps1 b/dev/zip-PDFsharp.ps1 new file mode 100644 index 00000000..0e8f414e --- /dev/null +++ b/dev/zip-PDFsharp.ps1 @@ -0,0 +1,38 @@ +# Compresses all files of PDFsharp into a PDFsharp.zip file + +#Requires -Version 7 +#Requires -PSEdition Core + +Push-Location "$PSScriptRoot/.." + +try { + # $root = "$PSScriptRoot/.." + Remove-Item zip -Recurse -Force -ErrorAction SilentlyContinue + Remove-Item PDFsharp.zip -Force -ErrorAction SilentlyContinue + # New-Item -ItemType Directory -Force -Path $Root/PDFsharp.zip + New-Item -ItemType Directory -Force -Path zip + + # I tried an hour or so to do it with Get-Childitem. No way, I finally use robocopy... + # robocopy . $root/zip *.* /dcopy:t /e /xa:h /xd .git /xd "bin" /xd "obj" /xd assets /xd zip + robocopy . zip/PDFsharp *.* /dcopy:t /e /xa:h /xd .git /xd .vs /xd .vscode /xd "bin" /xd "obj" /xd assets /xd zip ` + /xd TestResults /xd localtests ` + /xf debugSettings.json /xf *.user /xf *.userprefs /xf launchsettings.json /xf testEnvironments.json + # robocopy from to *.* /dcopy:t /e /xa:h /xd "System Volume Information" /xd "$RECYCLE*" + + # Delete generated files + Remove-Item zip/PDFsharp/src/SemVersion.props -ErrorAction SilentlyContinue + Remove-Item zip/PDFsharp/src/PdfSharpBuildConfig.props -ErrorAction SilentlyContinue + Remove-Item zip/PDFsharp/src/foundation/src/shared/src/PdfSharp.Shared/Internal/SSemVersionInformation-generated.cs -ErrorAction SilentlyContinue + + # Get-ChildItem zip -Recurse | measure + + Push-Location "zip" + Compress-Archive -Path PDFsharp -DestinationPath ../PDFsharp.zip -CompressionLevel Fastest -Force + Pop-Location + + # Remove-Item $root/zip -Recurse -Force -ErrorAction SilentlyContinue + Remove-Item zip -Recurse -Force -ErrorAction SilentlyContinue +} +finally { + Pop-Location +} diff --git a/docs/BoilerplateText.md b/docs/BoilerplateText.md deleted file mode 100644 index 055e9dbf..00000000 --- a/docs/BoilerplateText.md +++ /dev/null @@ -1,82 +0,0 @@ -# Boilerplate text - -** UNDER CONSTRUCTION ** - -## PDFsharp - -PDFsharp project - PDFsharp -PDFsharp Foundation - PDFsharp library -MigraDoc Foundation - MigraDoc library - - -Source -``` -// PDFsharp - A .NET library for processing PDF -``` - -**Description** -``` -PDFsharp is the Open Source library for creating and modifying PDF documents using .NET. It has an easy-to-use API that allows developers to generate or modify PDF files programmatically. PDFsharp can be used for various applications, including creating reports, invoices, and other types of documents. -``` - - -PDFsharp is a .NET library for creating and manipulating PDF documents. It provides a simple API for generating PDF documents from scratch or modifying existing ones. It can be used in a variety of applications, such as generating invoices, reports, or other types of documents. - - - -Stefan -Describe PDFsharp in 3 sentences -ChatGPT -PDFsharp is a .NET library for creating and manipulating PDF documents. It provides a simple API for generating PDF documents from scratch or modifying existing ones. It can be used in a variety of applications, such as generating invoices, reports, or other types of documents. - -Thomas -Describe PDFsharp in 3 simple sentences. -ChatGPT -PDFsharp is a library for creating and modifying PDF documents using .NET. It has an easy-to-use API that allows developers to generate or modify PDF files programmatically. PDFsharp can be used for various applications, including creating reports, invoices, and other types of documents. - -Stefan -Describe PDFsharp in 3 simple sentences for women. -ChatGPT -PDFsharp is a tool that helps you create and edit PDF documents using .NET. With its simple interface, you can easily generate or modify PDF files for a variety of purposes. Whether you need to create reports, invoices, or other types of documents, PDFsharp can help you get the job done. - -Stefan -Describe PDFsharp in 3 sentences for software developers. -ChatGPT -PDFsharp is a .NET library that provides an easy-to-use API for creating and manipulating PDF documents. It supports a wide range of features such as text, images, graphics, and interactive elements. With PDFsharp, developers can quickly generate or modify PDF files for various purposes in their applications. - - -## MigraDoc - -``` -// MigraDoc - Creating Documents on the Fly -``` - -``` -MigraDoc is a .NET library that allows developers to create documents such as PDF and RTF using a high-level object model. It provides an intuitive API that simplifies the creation of documents, including text formatting, tables, images, and more. MigraDoc is widely used for generating reports, invoices, and other types of documents in various applications. -``` - -Stefan -Describe MigraDoc in 3 simple sentences. -ChatGPT -MigraDoc is a .NET library that allows developers to create documents such as PDF, RTF, and HTML using a high-level object model. It provides an intuitive API that simplifies the creation of documents, including text formatting, tables, images, and more. MigraDoc is widely used for generating reports, invoices, and other types of documents in various applications. - - -**Release notes** - -Note: Do not replicate information from the meta data (like "6.0.0" or "prerelease"). - -PDFsharp: -This is a version of PDFsharp using .NET 6. -The package ’PdfSharp’ can be used on any platform including Windows and Linux. The Target Frameworks are ’net6.0’ and ’netstandard2.0’. -The packages ’PDFsharp-gdi’ and ’PDFsharp-wpf’ can be used under Windows only. The Target Frameworks are ’net6.0-windows’ and ’net472-windows’. -We also publish packages that contain PDFsharp plus MigraDoc. -See the project docs site for further information: -https://docs.pdfsharp.net/history/readme-v6.1.html - - -PDFsharp & MigraDoc: -This is a version of PDFsharp and MigraDoc Foundation using .NET 6. -The package ’PDFsharp-MigraDoc’ can be used on any platform including Windows and Linux. The Target Frameworks are ’net6.0’ and ’netstandard2.0’. -The packages ’PDFsharp-MigraDoc-GDI’ and ’PDFsharp-MigraDoc-WPF’ can be used under Windows only. The Target Frameworks are ’net6.0-windows’ and ’net472-windows’. -See the project docs site for further information: -https://docs.pdfsharp.net/history/readme-v6.1.html diff --git a/docs/DevNotes.md b/docs/DevNotes.md deleted file mode 100644 index faaf8577..00000000 --- a/docs/DevNotes.md +++ /dev/null @@ -1,42 +0,0 @@ -# Developer notes - -## Do this first - -## List of files to be checked before publishing a release - -README.md - -## Comments - -### DELETE yyyy-mm-dd - -Here is code that was replaced by newer code and should be deleted in the future. -But kept here at the moment as reference in case the new code has bugs. - -After the specified date the code can be deleted. - -### KEEP - -Here is older code that is not used anymore but kept here for -documentation or reference purposes and shall not be removed. - -### TODO - -**Here is something to be done __before the project is released__.** - -### BUG - -**Here is a bug that must be fixed before the project is released.** - -### IMPROV - -Here is code that substantially works but has potential for improvements -for better reliability. - -### OBSERVATION - -### EXPERIMENTAL - -### TEST - -Here is code that should be coved by (more) unit tests. diff --git a/docs/MakeNewReleaseNotes.md b/docs/MakeNewReleaseNotes.md deleted file mode 100644 index c8eee157..00000000 --- a/docs/MakeNewReleaseNotes.md +++ /dev/null @@ -1,31 +0,0 @@ -# Files to check - -[README.md](..\README.md) - -* Test on Linux web server - -## Nuget packages - -[PDFsharp.NuGet README.md](..\src\foundation\nuget\src\PDFsharp.NuGet\README.md) -[PDFsharp.NuGet Description.txt](..\src\foundation\nuget\src\PDFsharp.NuGet\Description.txt) -[PDFsharp.NuGet ReleaseNotes.txt](..\src\foundation\nuget\src\PDFsharp.NuGet\ReleaseNotes.txt) - -[PDFsharp.NuGet-gdi README.md](..\src\foundation\nuget\src\PDFsharp.NuGet-gdi\README.md) -[PDFsharp.NuGet-gdi Description.txt](..\src\foundation\nuget\src\PDFsharp.NuGet-gdi\Description.txt) -[PDFsharp.NuGet-gdi ReleaseNotes.txt](..\src\foundation\nuget\src\PDFsharp.NuGet-gdi\ReleaseNotes.txt) - -[PDFsharp.NuGet-wpf README.md](..\src\foundation\nuget\src\PDFsharp.NuGet-wpf\README.md) -[PDFsharp.NuGet-wpf Description.txt](..\src\foundation\nuget\src\PDFsharp.NuGet-wpf\Description.txt) -[PDFsharp.NuGet-wpf ReleaseNotes.txt](..\src\foundation\nuget\src\PDFsharp.NuGet-wpf\ReleaseNotes.txt) - -[MigraDoc.NuGet README.md](..\src\foundation\nuget\src\MigraDoc.NuGet\README.md) -[MigraDoc.NuGet Description.txt](..\src\foundation\nuget\src\MigraDoc.NuGet\Description.txt) -[MigraDoc.NuGet ReleaseNotes.txt](..\src\foundation\nuget\src\MigraDoc.NuGet\ReleaseNotes.txt) - -[MigraDoc.NuGet-gdi README.md](..\src\foundation\nuget\src\MigraDoc.NuGet-gdi\README.md) -[MigraDoc.NuGet-gdi Description.txt](..\src\foundation\nuget\src\MigraDoc.NuGet-gdi\Description.txt) -[MigraDoc.NuGet-gdi ReleaseNotes.txt](..\src\foundation\nuget\src\MigraDoc.NuGet-gdi\ReleaseNotes.txt) - -[MigraDoc.NuGet-wpf README.md](..\src\foundation\nuget\src\MigraDoc.NuGet-wpf\README.md) -[MigraDoc.NuGet-wpf Description.txt](..\src\foundation\nuget\src\MigraDoc.NuGet-wpf\Description.txt) -[MigraDoc.NuGet-wpf ReleaseNotes.txt](..\src\foundation\nuget\src\MigraDoc.NuGet-wpf\ReleaseNotes.txt) diff --git a/docs/MigraDoc/change-log/MD-v6.2.0-log.md b/docs/MigraDoc/change-log/MD-v6.2.0-log.md new file mode 100644 index 00000000..f820fd2c --- /dev/null +++ b/docs/MigraDoc/change-log/MD-v6.2.0-log.md @@ -0,0 +1,36 @@ +# MigraDoc 6.2.0 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **MigraDoc** `History.md`. + +## What’s new in version 6.2 + +### Breaking changes + +**Corrected bug with page orientation** +See *Issues* below. + +### Features + +**MigraDoc Preview user control restored for GDI build** +The MigraDoc Preview user control is again available in the GDI+ build. +MigraDoc Preview samples for GDI and WPF have been added to the samples repository. + +**Color.Parse no longer causes exceptions when invoked with a number value** +If Color.Parse is invoked with a number value, as in `var color = Color.Parse("#f00");`, +it no longer throws a handled exception internally. + +**MigraDoc: No more hard-coded fonts names** +It is now possible to control font names used by MigraDoc for error messages and characters for bullet lists. +PDFsharp 6.2.0 Preview 1 and earlier always used `Courier New` for error messages like Image not found and used hard-coded fonts for bullets. +[Read more](http://docs.pdfsharp.net/link/migradoc-font-resolving-6.2.html) + +### Issues + +**MigraDoc: Infinite loop in renderer** +We fixed a bug that led to an infinite loop in PDF Renderer. + +**Corrected bug with page orientation** +When opening and modifying existing PDF pages, there sometimes were issues due to page rotation and page orientation. +Behavior has changed for page format Ledger and apps supporting Ledger format must be tested and may have to be updated. +Behavior has also changed when you set a new page format or orientation after setting page height and/or page width, including modifying a *Clone()* of the *DefaultPageSetup*. The new method *ResetPageSize* should be called before setting *PageFormat* and *Orientation* for a "cloned" PageSetup. +These are breaking changes. diff --git a/docs/MigraDoc/change-log/MD-v6.2.1-log.md b/docs/MigraDoc/change-log/MD-v6.2.1-log.md new file mode 100644 index 00000000..dfdb779d --- /dev/null +++ b/docs/MigraDoc/change-log/MD-v6.2.1-log.md @@ -0,0 +1,17 @@ +# MigraDoc 6.2.1 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **MigraDoc** `History.md`. + +## What’s new in version 6.2.1 + +### Breaking changes + +*(none)* + +### Features + +The new formatting option of PDFsharp is also useful when generating PDF files from MigraDoc. + +### Issues + +The bug fixes of PDFsharp are also useful when generating PDF files from MigraDoc. diff --git a/docs/MigraDoc/change-log/MD-v6.2.2-log.md b/docs/MigraDoc/change-log/MD-v6.2.2-log.md new file mode 100644 index 00000000..9b62ac2e --- /dev/null +++ b/docs/MigraDoc/change-log/MD-v6.2.2-log.md @@ -0,0 +1,17 @@ +# MigraDoc 6.2.2 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **MigraDoc** `History.md`. + +## What’s new in version 6.2.2 + +### Breaking changes + +*(none)* + +### Features + +*(none)* + +### Issues + +The bug fixes of PDFsharp are also useful when generating PDF files from MigraDoc. diff --git a/docs/MigraDoc/change-log/MD-v6.2.3-log.md b/docs/MigraDoc/change-log/MD-v6.2.3-log.md new file mode 100644 index 00000000..216ec71e --- /dev/null +++ b/docs/MigraDoc/change-log/MD-v6.2.3-log.md @@ -0,0 +1,17 @@ +# MigraDoc 6.2.3 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **MigraDoc** `History.md`. + +## What’s new in version 6.2.3 + +### Breaking changes + +*(none)* + +### Features + +*(none)* + +### Issues + +The bug fixes of PDFsharp are also useful when generating PDF files from MigraDoc. diff --git a/docs/MigraDoc/change-log/MD-v6.2.4-log.md b/docs/MigraDoc/change-log/MD-v6.2.4-log.md new file mode 100644 index 00000000..c0155815 --- /dev/null +++ b/docs/MigraDoc/change-log/MD-v6.2.4-log.md @@ -0,0 +1,27 @@ +# MigraDoc 6.2.4 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **MigraDoc** `History.md`. + +## What’s new in version 6.2.4 + +### Breaking changes + +*(none)* + +### Features + +*(none)* + +### Issues + +**MigraDoc shows filename in PDF if image cannot be found** +If an image cannot be found, MigraDoc renders a placeholder for that image in PDF. +The placeholder now shows the path of the image that cannot be found. + +**Fixed MigraDoc memory leak after rendering PDF** +With MigraDoc 6.2.3, a reference to the MigraDoc Document was kept after rendering PDF. +Only a reference to the last document was kept. +So, when rendering 10 documents, 9 documents were released. +With MigraDoc 6.2.4, the MigraDoc Document is released after rendering. + +The bug fixes of PDFsharp are also useful when generating PDF files from MigraDoc. diff --git a/docs/MigraDoc/change-log/MD-v6.3.0-log.md b/docs/MigraDoc/change-log/MD-v6.3.0-log.md new file mode 100644 index 00000000..01a8aab3 --- /dev/null +++ b/docs/MigraDoc/change-log/MD-v6.3.0-log.md @@ -0,0 +1,19 @@ +# MigraDoc 6.3.0 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **MigraDoc** `History.md`. + +## What’s new in version 6.3 + +**This file is not yet up-to-date.** + +### Breaking changes + +*No changes in this version.* + +### Features + +*No changes in this version.* + +### Issues + +*No changes in this version.* diff --git a/docs/MigraDoc/change-log/MD-v6.4.0-log.md b/docs/MigraDoc/change-log/MD-v6.4.0-log.md new file mode 100644 index 00000000..526fa482 --- /dev/null +++ b/docs/MigraDoc/change-log/MD-v6.4.0-log.md @@ -0,0 +1,20 @@ +# MigraDoc 6.4.0 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **MigraDoc** `History.md`. + +## What’s new in version 6.4 + +**This file is not yet up-to-date.** + +### Breaking changes + +**PdfDate**??? +{according to PDFsharp 6.4.0 change log} + +### Features + +*No changes in this version.* + +### Issues + +*No changes in this version.* diff --git a/docs/MigraDoc/change-log/MD-v7.0.0-preview-log.md b/docs/MigraDoc/change-log/MD-v7.0.0-preview-log.md new file mode 100644 index 00000000..c0737d05 --- /dev/null +++ b/docs/MigraDoc/change-log/MD-v7.0.0-preview-log.md @@ -0,0 +1,23 @@ +# MigraDoc 7.0.0 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **MigraDoc** `History.md`. + +## What’s new in version 7.0 + +**This file is not yet up-to-date.** + +### Breaking changes + +**PdfDate** +PdfDate is now based on DateTimeOffset. See PDFsharp 7.0.0 change log for details. + +**MigraDocRenderingBuildInformation removed** +Use class **SemVersionInformation** or **PdfSharp.Capabilities.Build** to get most of the values. + +### Features + +*No changes in this version.* + +### Issues + +*No changes in this version.* diff --git a/docs/PDFsharp/change-log/PS-v6.2.0-log.md b/docs/PDFsharp/change-log/PS-v6.2.0-log.md new file mode 100644 index 00000000..225fd883 --- /dev/null +++ b/docs/PDFsharp/change-log/PS-v6.2.0-log.md @@ -0,0 +1,88 @@ +# PDFsharp 6.2.0 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **PDFsharp** `History.md`. + +## What’s new in version 6.2 + +### Breaking changes + +**Page orientation now works as expected** +See *Issues* below. + +### Features + +**Improved access to CropBox, ArtBox, BleedBox, TrimBox** +PdfPage now has new properties that make access to those boxes easier. +These are `HasBleedBox`, `BleedBoxReadOnly`, and `EffectiveBleedBoxReadOnly`. +Same applies to ArtBox, CropBox and TrimBox. + +**Loading images: Improved access to buffer of MemoryStream** +LoadImage from MemoryStream now works with a buffer that is not publicly visible. +For better performance, set 'publiclyVisible' to true when creating the MemoryStream. + +**MD5 replaced where possible** +The ImageSelector class needs hash codes for internal use. +We now use SHA1 instead of MD5 because MD5 is not FIPS-compliant and not supported everywhere. +Early PDF encryption uses MD5. So PDFsharp must use MD5 when opening files created with such early encryptions. +And PDFsharp must use MD5 when creating files with such early encryptions. + +**Inefficient reading of object streams** +Reading files with many objects in many object streams now works much faster. + +**Ignore incorrect "/Length" entry on streams close to EOF** +PDFsharp 6.2.0 Preview 1 failed if a PDF contained a stream close to the end of file with an incorrect /Length attribute. +PDFsharp 6.2.0 Preview 2 can correct the /Length attribute even for streams close to the end of the file. + +**ImageSelector improved** +We fixed incorrect handling of identical images with only different masks. + +**Issue with Google Slides** +PDFsharp can now open PDF files created from Google Slides. + +**Size of digital signature may vary without timestamp** +PDFsharp 6.2.0 Preview 1 took into account that the size of digital signatures with timestamp could vary from call to call. +PDFsharp 6.2.0 Preview 2 now takes into account that the size of digital signatures without timestamp can also vary from call to call. + +**Option to read images from non-seekable streams** +PDFsharp is now able to read images from streams that are not seekable. + +### Issues + +**Lexer.ScanNumber and CLexer.ScanNumber** +Based on a bug that crashed PDFsharp if a number in a PDFfile has too many leading zeros, we revised the code of **Lexer.ScanNumber** and **CLexer.ScanNumber**. + +**No more commas allowed in XUnit** +An old hack allowed **XUnit** to be assigned from a string that uses a comma as decimal separator. +This was introduced for languages like German that use a comma instead of a point as decimal separator. +Now you get an exception. Applies also to **XUnitPt**. + +**Bug fixes in PNG reader** +Fixed issues with reading PNG files in Core build. + +**Correct datetime format in XMP meta data** +Time zone was missing. + +**Handle Reverse Solidus without effect correctly** +The reverse solidus was handled incorrectly for invalid combinations of reverse solidus and other characters. + +**Fixes with encrypted PDFs** +Fixes for issues with encrypted PDFs. + +**Improved behavior or better error messages for streams with limited capabilities** +PDFsharp now shows better error messages when trying to read a PDF from streams that cannot seek, cannot report their length, or are otherwise limited. + +**Corrected bug with page orientation** +When opening and modifying existing PDF pages, there sometimes were issues due to page rotation and page orientation. +Behavior has changed for page format Ledger and apps supporting Ledger format must be tested and may have to be updated. +This is a breaking change. + +**BeginContainer issue fixed** +BeginContainer and EndContainer can now be used even in GDI build when drawing on PDF pages. + +**Bug in parsing object referenced** +Lexer now supports white-space within object references. + +**Page orientation now works as expected** +The connection between page Width, Height, PageOrientation, and PageRotation was weird. +It was replaced by a consistent concept. +This is a breaking change. diff --git a/docs/PDFsharp/change-log/PS-v6.2.1-log.md b/docs/PDFsharp/change-log/PS-v6.2.1-log.md new file mode 100644 index 00000000..c40e6171 --- /dev/null +++ b/docs/PDFsharp/change-log/PS-v6.2.1-log.md @@ -0,0 +1,38 @@ +# PDFsharp 6.2.1 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **PDFsharp** `History.md`. + +## What’s new in version 6.2 + +### Breaking changes + +*(none)* + +### Features + +**Formatting options for PDF files** +Using the *Options.Layout* member of the **PdfDocument** class, you can set how PDF files will be generated. +Use **PdfWriterLayout.Verbose** to get readable output. This is the default for Debug builds of PDFsharp. +Use **PdfWriterLayout.Compact** to get small output files. This is the default for Release builds of PDFsharp and should be used for production code. + +### Issues + +**Encrypted hyperlinks are now working** +We fixed a bug that caused PDF file encryption to throw an exception if the PDF file contained certain types of hyperlinks. + +**Character escaping for PDF names** +**PdfName** now correctly includes the curly braces ('{' and '}') in the list of characters to be escaped. + +**Fixed incorrect number formatting** +This bug could lead to incorrectly formatted Outline entries. + +**Fixed exception that occurred for files of size 1030 bytes** +PDFsharp can now open files with a size of 1030 bytes. + +**Arrays in PDF files are now written without line feeds** +When using **PdfWriterLayout.Compact**, arrays in PDF files will be written without line feeds. +The files with line feeds are technically correct, but we were informed that some printer software cannot handle those files correctly. + +**Keep both /A and /Dest entries for outlines in PDF** +According to the PDF Reference 1.7, an /A entry is not permitted if a /Dest entry is present. +PDFsharp 6.2.1 no longer deletes the /A entry if both are present. diff --git a/docs/PDFsharp/change-log/PS-v6.2.2-log.md b/docs/PDFsharp/change-log/PS-v6.2.2-log.md new file mode 100644 index 00000000..5937ddaf --- /dev/null +++ b/docs/PDFsharp/change-log/PS-v6.2.2-log.md @@ -0,0 +1,26 @@ +# PDFsharp 6.2.2 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **PDFsharp** `History.md`. + +## What’s new in version 6.2.2 + +### Breaking changes + +*(none)* + +### Features + +*(none)* + +### Issues + +**Fixed problem with JPEG images from MemoryStreams** +In special cases, JPEG images from a MemoryStream were not handled correctly. GitHub #303 + +**Avoid crash on ID duplicates in an object stream** +PDF files with duplicate IDs in an object stream were not handled correctly. +We consider such files corrupted, but PDFsharp should now handle them correctly. GitHub #296 + +**Fixed problems with signatures in DEBUG build** +The Debug build of PDFsharp adds comments to the generated PDF files. +This caused problems with the Signature field in PDFs, but was fixed now.Github #293 diff --git a/docs/PDFsharp/change-log/PS-v6.2.3-log.md b/docs/PDFsharp/change-log/PS-v6.2.3-log.md new file mode 100644 index 00000000..afd2054f --- /dev/null +++ b/docs/PDFsharp/change-log/PS-v6.2.3-log.md @@ -0,0 +1,23 @@ +# PDFsharp 6.2.3 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **PDFsharp** `History.md`. + +## What’s new in version 6.2.3 + +### Breaking changes + +*(none)* + +### Features + +*(none)* + +### Issues + +**Fixed problem with JPEG images from XImage.FromGdiPlusImage** +JPEG images created from GDI+ images were not handled correctly. GitHub #318 +This API is only available in the GDI+ build of PDFsharp. +It is recommended to avoid the *XImage.FromGdiPlusImage* API and use *XImage.FromFile* or *XImage.FromStream* instead if possible. + +**Avoid exception when reading certain corrupted files** +An incorrectly formatted logging string caused an exception when logging a warning about some corrupted PDF files. GitHub #290 diff --git a/docs/PDFsharp/change-log/PS-v6.2.4-log.md b/docs/PDFsharp/change-log/PS-v6.2.4-log.md new file mode 100644 index 00000000..1e8b7379 --- /dev/null +++ b/docs/PDFsharp/change-log/PS-v6.2.4-log.md @@ -0,0 +1,29 @@ +# PDFsharp 6.2.4 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **PDFsharp** `History.md`. + +## What’s new in version 6.2.4 + +### Breaking changes + +*(none)* + +### Features + +**Optional /Length entry for encryption added always** +The PDF viewer of Edge fails to open some encrypted PDF files if the /Length entry is not present. GitHub #261 +We now always add the /Length entry even in cases where it is optional according to PDF specifications. + +### Issues + +**CArray written without spaces** +When editing a content stream with an array, that CArray will now be saved with spaces. GitHub #300 + +**JPEG issue resolved** +JPEG JFIF files use "byte stuffing" and 0xff bytes may be followed by 0x00 bytes that must be ignored. +PDFsharp 6.2.4 now handles this 0xff 0x00 combination where PDFsharp up to 6.2.3 caused an exception. +GitHub #304, #309, #310 + +**Indirect DecodeParms now handled correctly** +PDFsharp 6.2.3 caused an exception if DecodeParms where specified as an indirect object. GitHub #323 +This indirection is valid, but very unusual. Fixed with 6.2.4. diff --git a/docs/PDFsharp/change-log/PS-v6.3.0-log.md b/docs/PDFsharp/change-log/PS-v6.3.0-log.md new file mode 100644 index 00000000..1b7baa9f --- /dev/null +++ b/docs/PDFsharp/change-log/PS-v6.3.0-log.md @@ -0,0 +1,46 @@ +# PDFsharp 6.3.0 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **PDFsharp** `History.md`. + +## What’s new in version 6.3 + +**This file is not yet up-to-date.** + +### Breaking changes + +**PdfDictionary enumerator** +=> PdfItem? -> PdfItem + +**xxxx** +xxxx. + +### Features + +* PDF object model revised +* + +**PDF/A enhancements** +* PdfAManager + +**File embedding** +* **FileManager** + +**XMP metadata** +* xxx + +**PdfDate** +**PdfDate** now based on **DateTimeOffset** internally and corrects minor issues caused by +differences between .NET and .NET Framework. + +**PdfName** +**PdfName** now based on new class **Name** and fixed some minor issues related to UTF-8 encoding, +escaping delimiter characters, and handling of the empty name. + +**PdfDictionary** +Now implements IEnumerable> and not +IEnumerable> anymore. + +### Issues + +**PdfGraphicsState fixes** +Usually not relevant as the error affected only drawing when starting with transparent strokes and fills. (GitHub #281) diff --git a/docs/PDFsharp/change-log/PS-v6.4.0-log.md b/docs/PDFsharp/change-log/PS-v6.4.0-log.md new file mode 100644 index 00000000..701db4ae --- /dev/null +++ b/docs/PDFsharp/change-log/PS-v6.4.0-log.md @@ -0,0 +1,57 @@ +# PDFsharp 6.4.0 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **PDFsharp** `History.md`. + +## What’s new in version 6.4 + +**This file is not yet up-to-date.** + +### Breaking changes + +**PdfDictionary enumerator** +=> PdfItem? -> PdfItem + +**PdfDate** +* PdfDate is now based on DateTimeOffset +* Value is now nullable in getters +* tostring returns "" if null +* Still trailing ‘'’ if not ‘Z’. +* Change in MigraDoc accordingly + +**PdfRectangle** +* GetRectangle is nullable* + +**minor changes** +* Some PDF annotations lost their default constructor because the constructor now requires a PDF document parameter. + + +### Features + +* PDF object model revised +* + +**PDF/A enhancements** +* PdfAManager + +**File embedding** +* **FileManager** + +**XMP metadata** +* preserve, update + +**PdfDate** +**PdfDate** now based on **DateTimeOffset** internally and corrects minor issues caused by +differences between .NET and .NET Framework. Fix in 6.3.0 + +**PdfName** +**PdfName** now based on new class **Name** and fixed some minor issues related to UTF-8 encoding, +escaping delimiter characters, and handling of the empty name. + +**PdfDictionary** +Now implements IEnumerable> and not +IEnumerable> anymore. + +### Issues + +**PdfGraphicsState fixes** +Usually not relevant as the error affected only drawing when starting with transparent strokes and fills. (GitHub #281) diff --git a/docs/PDFsharp/change-log/PS-v7.0.0-preview-log.md b/docs/PDFsharp/change-log/PS-v7.0.0-preview-log.md new file mode 100644 index 00000000..04ecd057 --- /dev/null +++ b/docs/PDFsharp/change-log/PS-v7.0.0-preview-log.md @@ -0,0 +1,80 @@ +# PDFsharp 7.0.0 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **PDFsharp** `History.md`. + +## What’s new in version 7.0 + +### Breaking changes + +**PdfDictionary enumerator** +Item is no longer nullable, so **PdfItem?** became **PdfItem**. + +**PdfRectangle** changes +**PdfRectangle.Empty** is now obsolete and throws an exception. +Use `new PdfRectangle()` to initialize empty values and to compare if a result of a call is the empty rectangle. + +**MediaBox**, **CropBox**, **BleedBox**, **ArtBox**, **TrimBox** changes +Now obsolete: MediaBoxReadOnly, CropBoxReadOnly, BleedBoxReadOnly, ArtBoxReadOnly, TrimBoxReadOnly. +Use **HasMediaBox**, **HasCropBox**, etc. to check if the boxes have been set. +Use **EffectiveCropBoxReadOnly**, **EffectiveTrimBoxReadOnly**, etc. to get the effective value. + +**PdfDate** +* PdfDate is now based on DateTimeOffset +* Value is now nullable in getters +* ToString returns "" if null +* Still trailing ‘'’ if not ‘Z’ +* Changed in MigraDoc accordingly + +**PdfRectangle** +* GetRectangle is nullable + +**PdfAnnotation** +* Keys were moved from the base class **PdfAnnotation** to the specific class where they belong. + For example, the `/A` key can now be found under `PdfLinkAnnotation.Keys.A`. + Other keys were moved to the **PdfMarkupAnnotation** class. + +**Minor changes** +* Some PDF annotation classes lost their default constructor because the constructor now requires a PDF document parameter. +* Class **PdfRubberStampAnnotation** renamed to **PdfStampAnnotation**. +* Enum **PdfRubberStampAnnotationIcon** renamed to **PdfStampAnnotationIcons**. +* Enum **PdfTextAnnotationIcon** renamed to **PdfTextAnnotationIcons**. + +### Features + +* PDF object model revised. +* PDFsharp is now more forgiving when opening certain non-conforming PDF files. + +**PDF/A enhancements** +* PdfAManager + +**PDF Forms enhancements** +* New classes to support Forms and form elements +* PsX Forms makes using Forms much easier, see https://www.pdfsharp.com/Offers + +**File embedding** +* New **FileManager** + +**PDF Annotations enhancements** +* New classes to support Annotations +* Outlook: PsX Annotations (coming soon) will make using annotations much easier, see https://www.pdfsharp.com/Offers + +**XMP metadata** +* New class MetadataManager +* DocumentMetadataStrategy: KeepExisting, AutoGenerate, UserGenerated, NoMetadata + +**PdfDate** +**PdfDate** now based on **DateTimeOffset** internally and corrects minor issues caused by +differences between .NET and .NET Framework. Fixed in 6.3.0 + +**PdfName** +**PdfName** now based on new class **Name** and fixed some minor issues related to UTF-8 encoding, +escaping delimiter characters, and handling of the empty name. + +**PdfDictionary** +Now implements IEnumerable> and not +IEnumerable> anymore. + +### Issues + +**PdfGraphicsState fixes** +Usually not relevant as the error affected only drawing when starting with transparent strokes and fills. (GitHub #281) diff --git a/docs/PDFsharp/docs/Documentation.md b/docs/PDFsharp/docs/Documentation.md new file mode 100644 index 00000000..c6506086 --- /dev/null +++ b/docs/PDFsharp/docs/Documentation.md @@ -0,0 +1,14 @@ +# Notes to source code documentation + +## PDFsharp PDF classes + +// Reference 2.0: 12.5.2 Annotation dictionaries / Page 467 +// Reference 2.0: xxx / Page xxx + +// Reference 2.0: Table 166 — Entries common to all annotation dictionaries / Page 467 +// Reference 2.0: xxx / Page xxx + +// ReSharper disable InconsistentNaming + +// ReSharper restore InconsistentNaming + diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..1d16cd90 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,7 @@ +# README of PDFsharp/docs + +This folder contains internal technical information for/from the PDFsharp team. +Some texts may be in German. + +`docs-dummy.csproj` is a dummy C# project used for organizing the mark down documents. +It seems Visual Studio has no simple ‘file view project’ type. diff --git a/docs/_READ-THIS-FIRST.md b/docs/_READ-THIS-FIRST.md new file mode 100644 index 00000000..0094a1e9 --- /dev/null +++ b/docs/_READ-THIS-FIRST.md @@ -0,0 +1,6 @@ +# Read this first + +This folder is ***not*** the documentation of PDFsharp. +It contains internal technical information for/from the PDFsharp team. + +You find the documentation of PDFsharp [here](https://docs.pdfsharp.net/). \ No newline at end of file diff --git a/docs/change-log/README.md b/docs/change-log/README.md new file mode 100644 index 00000000..37810f73 --- /dev/null +++ b/docs/change-log/README.md @@ -0,0 +1,66 @@ +# README for logging changes + +## Rules for log files and docs.pdfsharp.net history content + +* There are **3 markdown files** to log the changes for the currently developed version: + * `gn-vX.X.X-log.md` for general changes + * `PS-vX.X.X-log.md` for PDFsharp specific changes + * `MD-vX.X.X-log.md` for MigraDoc specific changes +* All versions shall be sorted descending by date. +* The information about a **version** shall begin with the **heading** `What’s new in version X.x`. +* The information about a **preview version** shall begin with the **subheading** `PDFsharp X.X.X Preview X`. +* A horizontal line shall be included after each version and preview version. + +### Preview versions + +* Only The **log for the general changes** shall list the **preview versions separately** +* The changes of a preview version shall refer to the previous preview version, if existing - otherwise to previous version. +* The **PDFsharp and MigraDoc change logs** shall **not** list the preview versions separately. +All changes of a version (including its preview versions) shall be summarized thematically. +References to the preview version, a change was published with, shall be added to this text (e. g. `(since 6.2.0 PV3`). +* **If a "final" version is going to be released**, its **preview versions shall no longer be listed separately** in the general change log. +The changes shall be summarized like they are in the PDFsharp and MigraDoc change logs. + +### Version content + +#### General change log headings + +* **Breaking changes** + This shall **always** be included. + Explicitely write `There are no breaking changes.` if there are none. +* **General features** (optional) +* **General issues** (optional) +* Furthermore, there are headings for PDFsharp and MigraDoc specific changes. + The text here shall not go in detail and refer to the PDFsharp/MigraDoc specific history, where the change is explained. + * **PDFsharp features** (optional) + * **PDFsharp issues** (optional) + * **MigraDoc features** (optional) + * **MigraDoc issues** (optional) + +#### PDfsharp/MigraDoc change log headings + +* **Features** (optional) +* **Issues** (optional) + +### docs.pdfsharp.net + +* **If a version (or preview version) is released**, the content of the files shall be added to the **3 History.md files** in docs.pdfsharp.net. + Due to the summarization of the preview versions in the change log files, **only the general History.md file shall list preview versions separately, and only for a version, which is currently developed**. +* A horizontal line shall be included after each version. + +## Rules for version readme file + +A version readme file with the name `README-vX.X` shall be published on **docs.pdfsharp.net**. + +### Headings + +* **What’s new** + Shall **refer to the general History.md** published on docs.pdfsharp.net. + There’s **no need to to refer to the PDFsharp/MigraDoc specific Histroy.md**, as the general refers to them at its top. +* **Prerequisites** +* **Breaking changes** + This shall **always** be included. + Explicitely write `There are no breaking changes.` if there are none. + Should be a copy, summary or excerpt of the general History.md breaking changes. + At last, the **general History.md shall be referenced**. +* Perhaps further headings for additional information. \ No newline at end of file diff --git a/docs/change-log/gn-v6.2.0-log.md b/docs/change-log/gn-v6.2.0-log.md new file mode 100644 index 00000000..2624830d --- /dev/null +++ b/docs/change-log/gn-v6.2.0-log.md @@ -0,0 +1,82 @@ +# General 6.2.0 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **general** `History.md`. + +## What’s new in version 6.2 + +### Breaking changes + +**CoreBuildFontResolver removed** +See *General features* below. + +### General features + +**CoreBuildFontResolver removed** +The code was removed from PDFsharp but still exists in the samples repository. +To reactivate the old behavior under Windows, set *UseWindowsFontsUnderWindows* to true. +To reactivate the old behavior under WSL2, set *UseWindowsFontsUnderWsl2* to true. +Note that these settings only have an effect for the Core build. +Also note that these settings only have an effect under Windows or WSL2, respectively. +No fonts will be found under Linux or MacOS, so do not use these properties if you want to develop portable Core applications. + +```cs +GlobalFontSettings.UseWindowsFontsUnderWindows = true; +GlobalFontSettings.UseWindowsFontsUnderWsl2 = true; +``` + +The name is now SubstitutingFontResolver and it can be found in the PDFsharp.Samples repository. + +[Information about font resolving](https://docs.pdfsharp.net/PDFsharp/Topics/Fonts/Font-Resolving.html) + +**UTF-16LE** + +We had recently removed the code that reads UTF-16LE strings because that format was not mentioned in the PDF specs. +We found a PDF file created with Adobe PDF Library 18.0.3 that contains UTF-16 strings with a LE BOM. +PDFsharp now can again read UTF-16 strings with LE BOM. + +**Digital signatures** +PDF documents can now be signed with a digital signature. + +**Multi-colored glyphs** +Multi-colored glyphs like emojis are now supported. + +**.NET Framework 4.6.2** +All assemblies have downgraded .NET Framework references in `` from 4.7.2 to 4.6.2. +`net472` becomes `net462`. + +**.NET 8** +We added .NET 8 (`net8.0`) to ``. + +**PDF/A** +PDF documents can now be PDF/A conforming. We are still working on this feature, so currently there are some limitations. + +**PDFsharp.Shared** +Code that grants friendly access to all PDFsharp Project assemblies lives in this new assembly. + +### General issues + +**Support PDF files with indirect objects in outlines** +PDFsharp 6.2.0 no longer throws exceptions in this case. + +**Support PDF files with whitespace in ASCII85 filtered objects** +PDFsharp 6.2.0 no longer throws exceptions in this case. + +**Support encrypting PDF files with .NET Framework 4.x again** +This did not work with PDFsharp 6.2.0 Preview 2 and Preview 3. + +**Updated NuGet package references to avoid vulnerability warnings** +The warnings came from transitive packages, i.e. packages used by packages that were referenced by PDFsharp. +The vulnerable code was not invoked by PDFsharp. + +**MD5 replaced** +We use the class **MD5Managed** instead of **MD5** from .NET. +One reason is that .NET MD5 cannot be used in a FIPS-compliant environment. +Another reason is that some platforms like Blazor do not support the retired class **MD5** anymore. + +**Cleanup NuGet packages** +MigraDoc packages now depend on PDFsharp NuGet packages instead of including assemblies directly. +All packages now depend on e.g. `Microsoft.Extensions.Logging` instead of including the Microsoft assembly. + +**.restext files removed** +Some assemblies had a subfolder `de` containing German messages. +We removed all `.restext` resources. All messages are now available in US English only. diff --git a/docs/change-log/gn-v6.2.0-preview-log.md b/docs/change-log/gn-v6.2.0-preview-log.md new file mode 100644 index 00000000..c513a61f --- /dev/null +++ b/docs/change-log/gn-v6.2.0-preview-log.md @@ -0,0 +1,199 @@ +# 6.2.0 change log + +This text is copied to `docs.pdfsharp.net`. + +## Version 6.2 + +### PDFsharp 6.2.0 (final release) + +*not yet released* + +### PDFsharp 6.2.0 Preview 3 + +#### General issues + +#### PDFsharp features + +**Improved access to CropBox, ArtBox, BleedBox, TrimBox** +PdfPage now has new properties that make access to those boxes easier. +These are `HasBleedBox`, `BleedBoxReadOnly`, and `EffectiveBleedBoxReadOnly`. +Same applies to ArtBox, CropBox and TrimBox. + +**Loading images: Improved access to buffer of MemoryStream** +LoadImage from MemoryStream now works with a buffer that is not publicly visible. +For better performance, set 'publiclyVisible' to true when creating the MemoryStream. + +#### PDFsharp issues + +**Lexer.ScanNumber and CLexer.ScanNumber** +Based on a bug that crashes PDFsharp if a number in a PDFfile has too many leading zeros, we revised the code of **Lexer.ScanNumber** and **CLexer.ScanNumber**. + +**No more commas allowed in XUnit** +An old hack allows **XUnit** to be assigned from a string that uses a comma as decimal separator. +This was a introduced for languages like German, that use a comma instead of a point as decimal separator. +Now you get an exception. Applies also to **XUnitPt**. + +#### MigraDoc features + +**MigraDoc Preview user control restored for GDI build** +The MigraDoc Preview user control is again available in the GDI+ build. +MigraDoc Preview samples for GDI and WPF have been added to the samples repository. + +**Color.Parse no longer causes exceptions when invoked with a number value** +If Color.Parse is invoked with a number value, as in `var color = Color.Parse("#f00");`, +it no longer throws a handled exception internally. + +#### MigraDoc issues + + +--- + +### PDFsharp 6.2.0 Preview 2 + +#### General features + +**CoreBuildFontResolver removed** +The code was removed from PDFsharp, but still exists in the samples repository. +To reactivate the old behavior under Windows, set *UseWindowsFontsUnderWindows* to true. +To reactivate the old behavior under WSL2, set *UseWindowsFontsUnderWsl2* to true. +Note that these settings only have an effect for the Core build. +Also note that these settings only have an effect under Windows or WSL2, respectively. +No fonts will be found under Linux or MacOS, so do not use these properties if you want to develop portable Core applications. + +```cs +GlobalFontSettings.UseWindowsFontsUnderWindows = true; +GlobalFontSettings.UseWindowsFontsUnderWsl2 = true; +``` + +The name is now SubstitutingFontResolver and it can be found in the PDFsharp.Samples repository. + +[Information about font resolving](https://docs.pdfsharp.net/PDFsharp/Topics/Fonts/Font-Resolving.html) + +**UTF-16LE** + +We have recently removed the code that read UTF-16LE strings because that format was not mentioned in the PDF specs. +We found a PDF file created with Adobe PDF Library 18.0.3 that contains UTF-16 strings with a LE BOM. +PDFsharp now can again read UTF-16 strings with LE BOM. + +#### General issues + +**Updated NuGet package references to avoid vulnerability warnings** +The warnings came from transitive packages, i.e. packages used by packages that were referenced by PDFsharp. +The vulnerable code was not invoked by PDFsharp. + +**MD5 replaced** +We use the class **MD5Managed** instead of **MD5** from .NET. +One reason is that .NET MD5 cannot be used in a FIPS-compliant environment. +Another reason is that some platforms like Blazor do not support the retired class **MD5** anymore. + +#### PDFsharp features + +**MD5 replaced where possible** +The ImageSelector class needs hash codes for internal use. +We now use SHA1 instead of MD5 because MD5 is not FIPS-compliant and not supported everywhere. +Early PDF encryption uses MD5. So PDFsharp must use MD5 when opening files created with such early encryptions. +And PDFsharp must use MD5 when creating files with such early encryptions. + +**Inefficient reading of object streams** +Reading files with many objects in many object streams now works much faster. + +**Ignore incorrect "/Length" entry on streams close to EOF** +PDFsharp 6.2.0 Preview 1 failed if a PDF contained a stream close to the end of file with an incorrect /Length attribute. +PDFsharp 6.2.0 Preview 2 can correct the /Length attribute even for streams close to the end of the file. + +**ImageSelector improved** +We fixed incorrect handling of identical images with only different masks. + +**Issue with Google Slides** +PDFsharp can now open PDF files created from Google Slides. + +**Size of digital signature may vary without timestamp** +PDFsharp 6.2.0 Preview 1 took into account that the size of digital signatures with timestamp could vary from call to call. +PDFsharp 6.2.0 Preview 2 now takes into account that the size of digital signatures without timestamp can also vary from call to call. + +**Option to read images from non-seekable streams** +PDFsharp is now able to read images from streams that are not seekable. + +#### PDFsharp issues + +**Bug fixes in PNG reader** +Fixed issues with reading PNG files in Core build. + +**Correct datetime format in XMP meta data** +Time zone was missing. + +**Handle Reverse Solidus without effect correctly** +The reverse solidus was handled incorrectly for invalid combinations of reverse solidus and other characters. + +**Fixes with encrypted PDFs** +Fixes for issues with encrypted PDFs. + +**Improved behavior or better error messages for streams with limited capabilities** +PDFsharp now shows better error messages when trying to read a PDF from streams that cannot seek, cannot report their length, or are otherwise limited. + +**Corrected bug with page orientation** +When opening and modifying existing PDF pages, there sometimes were issues due to page rotation and page orientation. +Behavior has changed for page format Ledger and apps supporting Ledger format must be tested and may have to be updated. +This is a breaking change. + +**BeginContainer issue fixed** +BeginContainer and EndContainer can now be used even in GDI build when drawing on PDF pages. + +#### MigraDoc features + +**MigraDoc: No more hard-coded fonts names** +It is now possible to control font names used by MigraDoc for error messages and characters for bullet lists. +PDFsharp 6.2.0 Preview 1 and earlier always used `Courier New` for error messages like Image not found and used hard-coded fonts for bullets. + +#### MigraDoc issues + +**MigraDoc: Infinite loop in renderer** +We fixed a bug that led to an infinite loop in PDF Renderer. + +**Corrected bug with page orientation** +When opening and modifying existing PDF pages, there sometimes were issues due to page rotation and page orientation. +Behavior has changed for page format Ledger and apps supporting Ledger format must be tested and may have to be updated. +This is a breaking change. + +--- + +### PDFsharp 6.2.0 Preview 1 + +#### Features + +**Digital signatures** +PDF documents can now be signed with a digital signature. + +**Multi-colored glyphs** +Multi-colored glyphs like emojis are now supported. + +**.NET Framework 4.6.2** +All assemblies have downgraded .NET Framework references in `` from 4.7.2 to 4.6.2. +`net472` becomes `net462`. + +**.NET 8** +We added .NET 8 (`net8.0`) to ``. + +**PDF/A** +PDF documents can now be PDF/A conforming. We are still working on this feature, so currently there are some limitations. + +**PDFsharp.Shared** +Code that grants friendly access to all PDFsharp Project assemblies lives in this new assembly. + +#### Bug fixes + +**Cleanup NuGet packages** +MigraDoc packages now depend on PDFsharp NuGet packages instead of including assemblies directly. +All packages now depend on e.g. `Microsoft.Extensions.Logging` instead of including the Microsoft assembly. + +**.restext files removed** +Some assemblies had a subfolder `de` containing German messages. +We removed all `.restext` resources. All messages are now available in US English only. + +**Bug in parsing object referenced** +Lexer now supports white-space within object references. + +**Page orientation now works as expected** +The connection between page Width, Height, PageOrientation, and PageRotation was weird. +It was replaced by a consistent concept. +This is a breaking change. diff --git a/docs/change-log/gn-v6.2.1-log.md b/docs/change-log/gn-v6.2.1-log.md new file mode 100644 index 00000000..518a8c5e --- /dev/null +++ b/docs/change-log/gn-v6.2.1-log.md @@ -0,0 +1,20 @@ +# General 6.2.1 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **general** `History.md`. + +## What’s new in version 6.2.1 + +### Breaking changes + +*(none)* + +### General features + +The new formatting option of PDFsharp is useful when generating PDF files from PDFsharp or MigraDoc. + +**Automatic download of assets folder** +TODO + +### General issues + +The bug fixes of PDFsharp are useful when generating PDF files from PDFsharp or MigraDoc. diff --git a/docs/change-log/gn-v6.2.2-log.md b/docs/change-log/gn-v6.2.2-log.md new file mode 100644 index 00000000..15466d90 --- /dev/null +++ b/docs/change-log/gn-v6.2.2-log.md @@ -0,0 +1,17 @@ +# General 6.2.2 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **general** `History.md`. + +## What’s new in version 6.2.2 + +### Breaking changes + +*(none)* + +### General features + +*(none)* + +### General issues + +The bug fixes of PDFsharp are useful when generating PDF files from PDFsharp or MigraDoc. diff --git a/docs/change-log/gn-v6.2.3-log.md b/docs/change-log/gn-v6.2.3-log.md new file mode 100644 index 00000000..be892714 --- /dev/null +++ b/docs/change-log/gn-v6.2.3-log.md @@ -0,0 +1,22 @@ +# General 6.2.3 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **general** `History.md`. + +## What’s new in version 6.2.3 + +### Breaking changes + +With version 6.2.3, we added support for .NET 9 and .NET 10. +Version 6.2.3 no longer compiles against .NET 6 which is out of support. +The NuGet packages can still be used for applications that use .NET 6. +Version 6.2.3 was built using Visual Studio 2026. +It still compiles with Visual Studio 2022, provided the .NET 10 SDK is installed, but warnings will be shown. +You can remove .NET 10 from the list of target frameworks if you do not need it. + +### General features + +*(none)* + +### General issues + +The bug fixes of PDFsharp are useful when generating PDF files from PDFsharp or MigraDoc. diff --git a/docs/change-log/gn-v6.2.4-log.md b/docs/change-log/gn-v6.2.4-log.md new file mode 100644 index 00000000..df14f1f0 --- /dev/null +++ b/docs/change-log/gn-v6.2.4-log.md @@ -0,0 +1,18 @@ +# General 6.2.4 change log + +A copy of the text below this line is added to `docs.pdfsharp.net` **general** `History.md`. + +## What’s new in version 6.2.4 + +### Breaking changes + +*(none)* + +### General features + +**Dependency on Microsoft.Extensions.Logging removed** +The new version depends on "Microsoft.Extensions.Logging.Abstractions" instead. GitHub #325 + +### General issues + +The bug fixes of PDFsharp are useful when generating PDF files from PDFsharp or MigraDoc. diff --git a/docs/change-log/gn-v6.3.0-log.md b/docs/change-log/gn-v6.3.0-log.md new file mode 100644 index 00000000..17280c7f --- /dev/null +++ b/docs/change-log/gn-v6.3.0-log.md @@ -0,0 +1,33 @@ +# 6.3.0 change log + +This text is copied to `docs.pdfsharp.net`. + +## What’s new in version 6.3 + +**This file is not yet up-to-date.** + + +### Breaking changes + +* From 6.2 to 6.3 needs a recompile. + +### General features + +* GitVersion build task replaced for better build time. +* Packages for .NET 9. +* 6.4: Implementation for .NET 9 that does not use obsolete APIs. +* DownloadAssets is invoked automatically during building. Requires Internet access. +* 6.4: `PDFsharpBuildFewerFrameworks` build property to speed up development by compiling against .NET 8 only. +* 6.4: `PDFsharpRunSlowTests` build property to include slow unit tests. + +**.NET 9** replaces **.NET 6** +We added .NET 9 (`net9.0`) to ``. +We removed .NET 6 because it is no longer supported by Microsoft. Projects using .NET 6 can still use the current version. + + +#### General issues + +* TODO diff --git a/docs/change-log/gn-v7.0.0-preview-log.md b/docs/change-log/gn-v7.0.0-preview-log.md new file mode 100644 index 00000000..3a2de2e9 --- /dev/null +++ b/docs/change-log/gn-v7.0.0-preview-log.md @@ -0,0 +1,34 @@ +# 7.0.0 change log + +This text is copied to `docs.pdfsharp.net`. + +## What’s new in version 7.0 + +**This file is not yet up-to-date.** + + +### Breaking changes + +* From 6.x to 7.0 needs a recompile. + +### General features + +* GitVersion build task replaced for better build time. +* Packages for .NET 9 and .NET 10. +* 6.4: Implementation for .NET 9 that does not use obsolete APIs. +* DownloadAssets is invoked automatically during building. Requires Internet access. +* 6.4: `PDFsharpBuildFewerFrameworks` build property to speed up development by compiling against .NET 10 only. +* 6.4: `PDFsharpRunSlowTests` build property to include slow unit tests. +* Code review: many classes were refactored to achieve cleaner code with improved maintainability. + +**.NET 9** replaces **.NET 6** +We added .NET 9 (`net9.0`) and .NET 10 to ``. +We removed .NET 6 because it is no longer supported by Microsoft. Projects using .NET 6 can still use the current version. + + +#### General issues + +* TODO diff --git a/docs/coding/DevNotes.md b/docs/coding/DevNotes.md new file mode 100644 index 00000000..4c5f3ae1 --- /dev/null +++ b/docs/coding/DevNotes.md @@ -0,0 +1,116 @@ +# Developer notes + +UNDER CONSTRUCTION + +Just here before being moved to an appropriate place. + +## Temporary tags + +Temporary tags are allowed in develop branch, but must be removed in (final) releases. + +Create a unit test that fails if a temporary tag is in the C# code. + +### TODO + +**Here is something to be done __before the project is finally released__.** + +### BUG + +**Here is definitely wrong code that must be fixed before the project is released.** + +### HACK + +This is a quick fix done during code review, development, finding a bug. + +### REVIEW + +This code must be discussed with another developer who has more knowledge about the issue. + +## General hash tags + +### CHECK_BEFORE_RELEASE + +Check this code here before you finalize the code for a release branch. + +### DELETE yyyy-mm-dd + +Here is code that was replaced by newer code and should be deleted in the future. +But kept here at the moment as reference in case the new code has bugs. + +After the specified date the code should be deleted. + +### KEEP + +Here is older code that is not used anymore but kept here for +documentation or reference purposes and shall not be removed. + +* Type `KEEP`, not `#KEEP`. + +**Example** + +```cs +// KEEP for future reference. +// … +``` + +### IMPROVE + +Here is correct code that substantially works but has potential for improvements +for better reliability. + +**Example** + +```cs +// IMPROVE robustness of the code. +// … +``` + +### OBSERVATION + +### EXPERIMENTAL + +### TEST + +Here is code that should be covered by (more) unit tests. + +## Clean up old code + +Remove all this stuff from existing code. + +* Hack: +* Note: + Write "Note that ..." + Do not delete it in text pasted from the PDF Reference. +* Magic: +* ToDo +* UNDONE +* TODOWPF +* ReviewSTLA +* THHO4STLA +* … (there are other randomly used tags) + +## `#if true` condition + +We often use the following technique to toggle old and new implementations. + +```CS +#if true + «new code» +#else + «old code» +#endif +``` + +>> Define how to treat this code. + +## Contextual hash tags + +A contextual hash tag marks code that was written in connection with a particular feature. + +| Hash tag | Description | +| :---------------- | :----------------------------------------- | +| #PageOrientation | Page size and orientation | +| #PDF-A | Changes for PDF/A | +| #PDF-UA | Code belonging to PDF/UA | +| | | +| | | diff --git a/docs/development/WSL/DevelopmentWithWSL.md b/docs/development/WSL/DevelopmentWithWSL.md new file mode 100644 index 00000000..6d289996 --- /dev/null +++ b/docs/development/WSL/DevelopmentWithWSL.md @@ -0,0 +1,66 @@ +# Development with WSL + +## Setup WSL + +Follow the instructions from Microsoft to set up WSL: +https://learn.microsoft.com/en-us/windows/wsl/install + +## Run and debug projects in WSL + +To run and debug projects, follow the instructions from Microsoft to debug .NET apps in WSL: +https://learn.microsoft.com/en-us/visualstudio/debugger/debug-dotnet-core-in-wsl-2 +It requires you to set up a launchSettings.json in the properties folder of the project, which could look like this: + +```json +{ + "profiles": { + "Windows": { + "commandName": "Project" + }, + "WSL": { + "commandName": "WSL", + "distributionName": "" + } + } +} +``` + +Afterwards, you can choose the profile when starting the project. + +When added for at least one project, Visual Studio may or may not show the WSL launching option for other projects +and add it automatically when choosing WSL. +However, adding the file to a project when needed is recommended. + +You can **copy the launchsettings.template.json** to Properties/launchSettings.json in your project for a quick start. + +## Testing in WSL + +### Run tests in Visual Studio + +To run tests from Visual Studio in your WSL, follow Microsoft’s instructions to enable remote testing: +https://aka.ms/remotetesting +It requires you to set up a testenvironments.json in the root of the solution, which could look like this: + +```json +{ + "version": "1", + "environments": [ + // See https://aka.ms/remotetesting for more details + // about how to configure remote environments. + { + "name": "WSL Ubuntu", + "type": "wsl", + "wslDistribution": "Ubuntu" + } + ] +} +``` + +Afterwards, you can choose the test environment in Test Explorer. + +You can **copy the testenvironments.template.json** to testenvironments.json in the solution root folder for a quick start. + +### Run run-tests script + +With the run-test.ps1 in the dev folder to run all tests in in all available environments, including WSL. +For more information run `help run-tests.ps1`. diff --git a/docs/development/WSL/launchsettings.template.json b/docs/development/WSL/launchsettings.template.json new file mode 100644 index 00000000..2f189c12 --- /dev/null +++ b/docs/development/WSL/launchsettings.template.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "Windows": { + "commandName": "Project" + }, + "WSL": { + "commandName": "WSL", + "distributionName": "" + } + } +} \ No newline at end of file diff --git a/docs/development/WSL/testenvironments.template.json b/docs/development/WSL/testenvironments.template.json new file mode 100644 index 00000000..65570029 --- /dev/null +++ b/docs/development/WSL/testenvironments.template.json @@ -0,0 +1,17 @@ +{ + "version": "1", + "environments": [ + // See https://aka.ms/remotetesting for more details + // about how to configure remote environments. + { + "name": "WSL", + "type": "wsl", + "wslDistribution": "Ubuntu" + }, + //{ + // "name": "Docker dotnet/sdk", + // "type": "docker", + // "dockerImage": "mcr.microsoft.com/dotnet/sdk" + //} + ] +} \ No newline at end of file diff --git a/docs/docs-public.csproj b/docs/docs-public.csproj new file mode 100644 index 00000000..5152857c --- /dev/null +++ b/docs/docs-public.csproj @@ -0,0 +1,9 @@ + + + + + net10.0 + + + diff --git a/src/foundation/src/MigraDoc/tests/MigraDoc.Tests/README.md b/docs/testing/xUnitRunnerSettings.md similarity index 76% rename from src/foundation/src/MigraDoc/tests/MigraDoc.Tests/README.md rename to docs/testing/xUnitRunnerSettings.md index ac566cd8..23e24504 100644 --- a/src/foundation/src/MigraDoc/tests/MigraDoc.Tests/README.md +++ b/docs/testing/xUnitRunnerSettings.md @@ -1,13 +1,8 @@ -# MigraDoc tests - -Tests related to MigraDoc. - -Requirements: -* ... +# xUnit runner settings for test projects ## `xunit.runner.json` -Each test project can have a `xunit.runner.json`, e.g. +Each test project can have an `xunit.runner.json` file, e.g. ```json { diff --git a/gitversion.yml b/gitversion.yml deleted file mode 100644 index c3b00703..00000000 --- a/gitversion.yml +++ /dev/null @@ -1,42 +0,0 @@ -# 23-05-24 -assembly-versioning-scheme: MajorMinorPatch -mode: Mainline -assembly-informational-format: '{NuGetVersion}' -branches: - develop: # Current development - # branch: develop -- is always 'develop' - # version: {6.0.0}-develop.123 -- taken from git tag plus 'develop' plus commit count - regex: ^develop$ - mode: ContinuousDeployment - increment: None - tag: develop - prevent-increment-of-merged-branch-version: false - track-merge-target: true - source-branches: ['feature', 'release'] - release: # Release and preview versions. - # branch: release/6.0.0-preview-3 -- must be same as git tag without leading 'v'. - # version: {6-0-0-preview-3} -- taken from git tag only - regex: ^(release[/-]|master) - # Must not have mode set to be mainline? WTF? - increment: None - tag: '' - prevent-increment-of-merged-branch-version: true - track-merge-target: true - is-release-branch: true - is-mainline: true - source-branches: ['develop', 'release', 'feature'] - feature: # Features and bug fixes. - # branch: feature/my-new-feature -- arbitrary name, e.g. a new preview - # version: {6.0.0}-dev-{my-new-feature}.123 -- taken from git tag plus 'dev-' plus branch name plus commit count - regex: ^(user|feature|fix)[/-] - mode: ContinuousDeployment - increment: None - tag: 'dev-{BranchName}' - prevent-increment-of-merged-branch-version: true - track-merge-target: true - source-branches: ['develop', 'release', 'feature'] - pull-request: - regex: ^(pull|pull\-requests|pr)[/-] - tag: PullRequest - mode: ContinuousDeployment -merge-message-formats: {} diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 00000000..4381b38b --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,5 @@ +# Ignore generated props file +SemVersion.props +Local.Build.props +PdfSharpBuildConfig.props +PdfSharpBuildConfig.targets diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 93e264aa..e253e286 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,36 +1,140 @@ + false true + true enable enable - NU1507 + + + + $(NoWarn);0507;2070;2087 + false + + false + false + false + + + true + + true + + false + + + + false + + + + latest *.ncrunchproject;*.DotSettings + + + + + + + + + + + + net8.0;net9.0;net10.0;netstandard2.0 + net8.0;net9.0;net10.0 + net8.0;net9.0;net10.0;net462 + net8.0;net9.0;net10.0 + net8.0-windows;net9.0-windows;net10.0-windows;net462 + net8.0-windows;net9.0-windows;net10.0-windows + + + + + net8.0;net9.0;net10.0;net472 + net8.0-windows;net9.0-windows;net10.0-windows;net472 + + + net8.0;net9.0;net10.0;netstandard2.0 + net8.0-windows;net9.0-windows;net10.0-windows;net462 + + + + $(DefineConstants);FEWER_FRAMEWORKS + + false + + + .Fewer + + + net10.0 + net10.0 + net10.0 + net10.0 + net10.0-windows + net10.0-windows + + + net10.0 + net10.0 + net10.0-windows + + + net10.0 + net10.0-windows + + + + $(DefineConstants);RUN_SLOW_TESTS + + + + PDFsharp empira Software - © 2023 empira + © 2026 empira Software GmbH + © 2005-2026 empira Software GmbH + © 2001-2026 empira Software GmbH + PDFsharp Team empira Software GmbH + + 1032 + 00240000048000009400000006020000002400005253413100040000010001008794e803e566eccc3c9181f52c4f7044e5442cc2ce3cbba9fc11bc4186ba2e446cd31deea20c1a8f499e978417fad2bc74143a4f8398f7cf5c5c0271b0f7fe907c537cff28b9d582da41289d1dae90168a3da2a5ed1115210a18fdae832479d3e639ca4003286ba8b98dc9144615c040ed838981ac816112df3b5a9e7cab4fbb + + + + + + - false + + + $(SemVer) - - true + + + false - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - \ No newline at end of file + diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets new file mode 100644 index 00000000..76ac5f3e --- /dev/null +++ b/src/Directory.Build.targets @@ -0,0 +1,11 @@ + + + + + + + + $(DefineConstants);USE_LONG_SIZE;TEST_CODExxx;PRESERVE_PARSED_VALUESxxx;PDFSHARP_DEBUGxxx + + + \ No newline at end of file diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 3d29e000..dcb63a2f 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -1,114 +1,44 @@ - 6.0.0 - 6.0.0 - 6.0.0 - 6.0.0 + 10.0.5 + 10.0.5 + 10.0.5 + 10.0.5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + - - - - - - - - + + \ No newline at end of file diff --git a/src/Local.Build.props---template b/src/Local.Build.props---template new file mode 100644 index 00000000..711e64c0 --- /dev/null +++ b/src/Local.Build.props---template @@ -0,0 +1,17 @@ + + + + + + true + + + + + false + + diff --git a/src/StrongnameKey.snk b/src/StrongnameKey.snk new file mode 100644 index 00000000..ce2edba0 Binary files /dev/null and b/src/StrongnameKey.snk differ diff --git a/src/dotnet-test.Build.props b/src/dotnet-test.Build.props index a0e96f7a..00675e9b 100644 --- a/src/dotnet-test.Build.props +++ b/src/dotnet-test.Build.props @@ -1,19 +1,19 @@  - - true - - - - - - - - all - - - all - runtime; build; native; contentfiles; analyzers - - - + + true + + + + + + + + all + + + all + runtime; build; native; contentfiles; analyzers + + + diff --git a/src/foundation/nuget/src/Directory.Build.props b/src/foundation/nuget/src/Directory.Build.props index 5dc9ce07..79d9d34d 100644 --- a/src/foundation/nuget/src/Directory.Build.props +++ b/src/foundation/nuget/src/Directory.Build.props @@ -1,53 +1,62 @@  - - - - - - - - - - @(DescriptionFileContents->'%(Identity)', '%0d') - @(ReleaseNotesFileContents->'%(Identity)', '%0d') - ***** THIS IS A DEBUG BUILD - DO NOT PUBLISH *****%0d - - - https://docs.pdfsharp.net - PDFsharp PDF creation - MigraDoc PDFsharp PDF Document Generation - - - - - - - - - - - - - - $(NuspecProperties);id=$(NuGetId) - $(NuspecProperties);title=$(NuGetTitle) - $(NuspecProperties);config=$(Configuration) - $(NuspecProperties);version=$(PackageVersion) - $(NuspecProperties);description=$(NuGetDescription) - $(NuspecProperties);summary=$(NuGetSummary) - $(NuspecProperties);authors=$(Authors) - $(NuspecProperties);owners=$(Owners) - $(NuspecProperties);projectUrl=$(NuGetProjectUrl) - $(NuspecProperties);copyright=$(Copyright) - $(NuspecProperties);releaseNotes=$(NuGetReleaseNotes) - $(NuspecProperties);tags=$(NuGetTags) - - - - - + + + + + + + + + + @(DescriptionFileContents->'%(Identity)', '%0d') + @(ReleaseNotesFileContents->'%(Identity)', '%0d') + ***** THIS IS A DEBUG BUILD - DO NOT PUBLISH *****%0d + + + https://docs.pdfsharp.net + PDFsharp PDF creation + MigraDoc PDFsharp PDF Document Generation + + + + + + + + + + + + + + -DEBUG + $(NuspecProperties);id=$(NuGetId) + $(NuspecProperties);title=$(NuGetTitle) + $(NuspecProperties);config=$(Configuration) + $(NuspecProperties);version=$(PackageVersion) + $(NuspecProperties);description=$(NuGetDescription) + $(NuspecProperties);summary=$(NuGetSummary) + $(NuspecProperties);authors=$(Authors) + $(NuspecProperties);owners=$(Owners) + $(NuspecProperties);projectUrl=$(NuGetProjectUrl) + $(NuspecProperties);copyright=$(Copyright) + $(NuspecProperties);CopyrightPdfSharp=$(CopyrightPdfSharp) + $(NuspecProperties);CopyrightMigraDoc=$(CopyrightMigraDoc) + $(NuspecProperties);releaseNotes=$(NuGetReleaseNotes) + $(NuspecProperties);tags=$(NuGetTags) + + $(NuspecProperties);NetCore_PackageVersion=$(NetCore_PackageVersion) + $(NuspecProperties);Logging_Abstractions_PackageVersion=$(Logging_Abstractions_PackageVersion) + $(NuspecProperties);Cryptography_PackageVersion=$(Cryptography_PackageVersion) + + $(NuspecProperties);pdfsharpnugetpackagetag=$(PDFsharpNuGetPackageTag) + + + + + diff --git a/src/foundation/nuget/src/Dummy-PDFsharp.NuGet-wpf/Dummy-PDFsharp.NuGet-wpf.csproj b/src/foundation/nuget/src/Dummy-PDFsharp.NuGet-wpf/Dummy-PDFsharp.NuGet-wpf.csproj index ff471541..bcd0a3a9 100644 --- a/src/foundation/nuget/src/Dummy-PDFsharp.NuGet-wpf/Dummy-PDFsharp.NuGet-wpf.csproj +++ b/src/foundation/nuget/src/Dummy-PDFsharp.NuGet-wpf/Dummy-PDFsharp.NuGet-wpf.csproj @@ -1,10 +1,12 @@  - net6.0-windows;net472-windows + $(PDFsharpTargetFrameworks_NuGet_Window) true - + + false + True + ..\..\..\..\StrongnameKey.snk diff --git a/src/foundation/nuget/src/Dummy-PDFsharp.NuGet-wpf/README.md b/src/foundation/nuget/src/Dummy-PDFsharp.NuGet-wpf/README.md index 8c8c0d08..436b3fc5 100644 --- a/src/foundation/nuget/src/Dummy-PDFsharp.NuGet-wpf/README.md +++ b/src/foundation/nuget/src/Dummy-PDFsharp.NuGet-wpf/README.md @@ -14,4 +14,5 @@ According to the docs it should be possible to create NuGet packages without nus all stuff can be set in the csproj file. We still use nuspec because I cannot fix the following issues: * Set the package icon in cssproj so that it is displayed. -* We want a single package for all (e.g.) PDFsharp assemblies. Currently I don't know how to manage that without a nuspec file. +* We want a single package for all (e.g.) PDFsharp assemblies. + Currently I don’t know how to manage that without a nuspec file. diff --git a/src/foundation/nuget/src/MigraDoc.NuGet-gdi/Description.txt b/src/foundation/nuget/src/MigraDoc.NuGet-gdi/Description.txt index 03e61dbb..52986d6f 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet-gdi/Description.txt +++ b/src/foundation/nuget/src/MigraDoc.NuGet-gdi/Description.txt @@ -1,5 +1,9 @@ -MigraDoc is a .NET library that allows developers to create documents such as PDF and RTF using a high-level object model. It provides an intuitive API that simplifies the creation of documents, including text formatting, tables, images, and more. MigraDoc is widely used for generating reports, invoices, and other types of documents in various applications. +MigraDoc is a .NET library that allows developers to create documents such as PDF and RTF using a high-level object model. It provides an intuitive API that simplifies the creation of documents, including text formatting, tables, images, and more. MigraDoc is widely used for generating reports, invoices, and other types of documents in various applications. This package relies on Windows Forms (GDI+) and can be used under Windows only. See https://docs.pdfsharp.net for details. +  +See https://www.pdfsharp.com for professional support offers, premium technical advice, and contract work options. +Choose a support plan that suits your needs. We offer a variety of options, from small projects to large teams, with flexible response times. +Our team provides PDFsharp expert assistance, including implementation, optimization, and tailored solutions. diff --git a/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.Fewer.nuspec b/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.Fewer.nuspec new file mode 100644 index 00000000..c6cde112 --- /dev/null +++ b/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.Fewer.nuspec @@ -0,0 +1,46 @@ + + + + $id$ + $version$ + $description$ + $summary$ + $authors$ + $owners$ + $projectUrl$ + MIT + images\MigraDoc-128x128.png + README.md + false + $releaseNotes$ + $CopyrightMigraDoc$ + $tags$ + + $title$ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.csproj b/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.csproj index 9c7bca2a..1314974d 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.csproj +++ b/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.csproj @@ -1,17 +1,20 @@  - net6.0-windows;net472-windows + $(PDFsharpTargetFrameworks_NuGet_Window) true - true + false + True + ..\..\..\..\StrongnameKey.snk true true - $(MSBuildThisFileDirectory)$(MSBuildProjectName).nuspec + $(MSBuildThisFileDirectory)$(MSBuildProjectName)$(NuGetNuspecTag).nuspec PDFsharp-MigraDoc-GDI + $(NuGetId)-DEBUG PDFsharp plus MigraDoc for Windows Forms apps $(DebugBuildMessage)%0D$(NuGetDescription) Creating Documents on the Fly. diff --git a/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.nuspec b/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.nuspec index c2366247..1dc9c55f 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.nuspec +++ b/src/foundation/nuget/src/MigraDoc.NuGet-gdi/MigraDoc.NuGet-gdi.nuspec @@ -13,32 +13,52 @@ README.md false $releaseNotes$ - $copyright$ + $CopyrightMigraDoc$ $tags$ $title$ - - - + + + + - - - + + + + + + + + + + + + + + - + + + + + + + - + - - + + + + diff --git a/src/foundation/nuget/src/MigraDoc.NuGet-gdi/ReleaseNotes.txt b/src/foundation/nuget/src/MigraDoc.NuGet-gdi/ReleaseNotes.txt index 05c871e1..4616f1fe 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet-gdi/ReleaseNotes.txt +++ b/src/foundation/nuget/src/MigraDoc.NuGet-gdi/ReleaseNotes.txt @@ -1,5 +1,5 @@ -This is a version of PDFsharp and MigraDoc Foundation using .NET 6. -The package ’PDFsharp-MigraDoc’ can be used on any platform including Windows and Linux. The Target Frameworks are ’net6.0’ and ’netstandard2.0’. -The packages ’PDFsharp-MigraDoc-GDI’ and ’PDFsharp-MigraDoc-WPF’ can be used under Windows only. The Target Frameworks are ’net6.0-windows’ and ’net472-windows’. +This is a version of PDFsharp and MigraDoc compatible with .NET 8 and higher. +The package ‘PDFsharp-MigraDoc’ can be used on any platform including Windows and Linux. The Target Frameworks are ‘net8.0’, ‘net9.0’, ‘net10.0’ and ‘netstandard2.0’. +The packages ‘PDFsharp-MigraDoc-GDI’ and ‘PDFsharp-MigraDoc-WPF’ can be used under Windows only. The Target Frameworks are ‘net8.0-windows’, ‘net9.0-windows’, ‘net10.0-windows’ and ‘net462’. See the project docs site for further information: -https://docs.pdfsharp.net/link/readme-v6.1.html +https://docs.pdfsharp.net/link/readme-v7.0.html diff --git a/src/foundation/nuget/src/MigraDoc.NuGet-wpf/Description.txt b/src/foundation/nuget/src/MigraDoc.NuGet-wpf/Description.txt index a24bae03..92f0069a 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet-wpf/Description.txt +++ b/src/foundation/nuget/src/MigraDoc.NuGet-wpf/Description.txt @@ -1,5 +1,9 @@ -MigraDoc is a .NET library that allows developers to create documents such as PDF and RTF using a high-level object model. It provides an intuitive API that simplifies the creation of documents, including text formatting, tables, images, and more. MigraDoc is widely used for generating reports, invoices, and other types of documents in various applications. +MigraDoc is a .NET library that allows developers to create documents such as PDF and RTF using a high-level object model. It provides an intuitive API that simplifies the creation of documents, including text formatting, tables, images, and more. MigraDoc is widely used for generating reports, invoices, and other types of documents in various applications. This package relies on Windows Presentation Foundation (WPF) and can be used under Windows only. See https://docs.pdfsharp.net for details. +  +See https://www.pdfsharp.com for professional support offers, premium technical advice, and contract work options. +Choose a support plan that suits your needs. We offer a variety of options, from small projects to large teams, with flexible response times. +Our team provides PDFsharp expert assistance, including implementation, optimization, and tailored solutions. diff --git a/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.Fewer.nuspec b/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.Fewer.nuspec new file mode 100644 index 00000000..fbc5ba01 --- /dev/null +++ b/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.Fewer.nuspec @@ -0,0 +1,46 @@ + + + + $id$ + $version$ + $description$ + $summary$ + $authors$ + $owners$ + $projectUrl$ + MIT + images\MigraDoc-128x128.png + README.md + false + $releaseNotes$ + $CopyrightMigraDoc$ + $tags$ + + $title$ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.csproj b/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.csproj index 81e67978..7b4dae43 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.csproj +++ b/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.csproj @@ -1,17 +1,20 @@  - net6.0-windows;net472-windows + $(PDFsharpTargetFrameworks_NuGet_Window) true - true + false + True + ..\..\..\..\StrongnameKey.snk true true - $(MSBuildThisFileDirectory)$(MSBuildProjectName).nuspec + $(MSBuildThisFileDirectory)$(MSBuildProjectName)$(NuGetNuspecTag).nuspec PDFsharp-MigraDoc-WPF + $(NuGetId)-DEBUG PDFsharp plus MigraDoc for Windows WPF apps $(DebugBuildMessage)%0D$(NuGetDescription) Creating Documents on the Fly. diff --git a/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.nuspec b/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.nuspec index d1d875ef..01adbf30 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.nuspec +++ b/src/foundation/nuget/src/MigraDoc.NuGet-wpf/MigraDoc.NuGet-wpf.nuspec @@ -13,32 +13,52 @@ README.md false $releaseNotes$ - $copyright$ + $CopyrightMigraDoc$ $tags$ $title$ - - - + + + + - - - + + + + + + + + + + + + + + - + + + + + + + - + - - + + + + diff --git a/src/foundation/nuget/src/MigraDoc.NuGet-wpf/ReleaseNotes.txt b/src/foundation/nuget/src/MigraDoc.NuGet-wpf/ReleaseNotes.txt index 05c871e1..4616f1fe 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet-wpf/ReleaseNotes.txt +++ b/src/foundation/nuget/src/MigraDoc.NuGet-wpf/ReleaseNotes.txt @@ -1,5 +1,5 @@ -This is a version of PDFsharp and MigraDoc Foundation using .NET 6. -The package ’PDFsharp-MigraDoc’ can be used on any platform including Windows and Linux. The Target Frameworks are ’net6.0’ and ’netstandard2.0’. -The packages ’PDFsharp-MigraDoc-GDI’ and ’PDFsharp-MigraDoc-WPF’ can be used under Windows only. The Target Frameworks are ’net6.0-windows’ and ’net472-windows’. +This is a version of PDFsharp and MigraDoc compatible with .NET 8 and higher. +The package ‘PDFsharp-MigraDoc’ can be used on any platform including Windows and Linux. The Target Frameworks are ‘net8.0’, ‘net9.0’, ‘net10.0’ and ‘netstandard2.0’. +The packages ‘PDFsharp-MigraDoc-GDI’ and ‘PDFsharp-MigraDoc-WPF’ can be used under Windows only. The Target Frameworks are ‘net8.0-windows’, ‘net9.0-windows’, ‘net10.0-windows’ and ‘net462’. See the project docs site for further information: -https://docs.pdfsharp.net/link/readme-v6.1.html +https://docs.pdfsharp.net/link/readme-v7.0.html diff --git a/src/foundation/nuget/src/MigraDoc.NuGet/Description.txt b/src/foundation/nuget/src/MigraDoc.NuGet/Description.txt index 0cc42ad4..99d2af4b 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet/Description.txt +++ b/src/foundation/nuget/src/MigraDoc.NuGet/Description.txt @@ -1,5 +1,9 @@ -MigraDoc is a .NET library that allows developers to create documents such as PDF and RTF using a high-level object model. It provides an intuitive API that simplifies the creation of documents, including text formatting, tables, images, and more. MigraDoc is widely used for generating reports, invoices, and other types of documents in various applications. +MigraDoc is a .NET library that allows developers to create documents such as PDF and RTF using a high-level object model. It provides an intuitive API that simplifies the creation of documents, including text formatting, tables, images, and more. MigraDoc is widely used for generating reports, invoices, and other types of documents in various applications. This package does not depend on Windows and can be used on any .NET compatible platform including Linux and macOS. See https://docs.pdfsharp.net for details. +  +See https://www.pdfsharp.com for professional support offers, premium technical advice, and contract work options. +Choose a support plan that suits your needs. We offer a variety of options, from small projects to large teams, with flexible response times. +Our team provides PDFsharp expert assistance, including implementation, optimization, and tailored solutions. diff --git a/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.Fewer.nuspec b/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.Fewer.nuspec new file mode 100644 index 00000000..3f08bda7 --- /dev/null +++ b/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.Fewer.nuspec @@ -0,0 +1,45 @@ + + + + $id$ + $version$ + $description$ + $summary$ + $authors$ + $owners$ + $projectUrl$ + MIT + images\MigraDoc-128x128.png + README.md + false + $releaseNotes$ + $CopyrightMigraDoc$ + $tags$ + + $title$ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.csproj b/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.csproj index b19d7858..b2a3762f 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.csproj +++ b/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.csproj @@ -1,16 +1,19 @@  - net6.0;netstandard2.0 - true + $(PDFsharpTargetFrameworks_NuGet) + false + True + ..\..\..\..\StrongnameKey.snk true true - $(MSBuildThisFileDirectory)$(MSBuildProjectName).nuspec + $(MSBuildThisFileDirectory)$(MSBuildProjectName)$(NuGetNuspecTag).nuspec PDFsharp-MigraDoc + $(NuGetId)-DEBUG PDFsharp plus MigraDoc for Windows and Linux $(DebugBuildMessage)%0D$(NuGetDescription) Creating Documents on the Fly. diff --git a/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.nuspec b/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.nuspec index 7829e2ca..8972a69d 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.nuspec +++ b/src/foundation/nuget/src/MigraDoc.NuGet/MigraDoc.NuGet.nuspec @@ -4,39 +4,57 @@ $id$ $version$ $description$ - $summary$ + $summary$ $authors$ $owners$ - $projectUrl$ + $projectUrl$ MIT images\MigraDoc-128x128.png README.md false $releaseNotes$ - $copyright$ + $CopyrightMigraDoc$ $tags$ $title$ - - - + + + + + + + + + + + + + + - - + + + - + + + + + - - + + + + diff --git a/src/foundation/nuget/src/MigraDoc.NuGet/ReleaseNotes.txt b/src/foundation/nuget/src/MigraDoc.NuGet/ReleaseNotes.txt index 05c871e1..4616f1fe 100644 --- a/src/foundation/nuget/src/MigraDoc.NuGet/ReleaseNotes.txt +++ b/src/foundation/nuget/src/MigraDoc.NuGet/ReleaseNotes.txt @@ -1,5 +1,5 @@ -This is a version of PDFsharp and MigraDoc Foundation using .NET 6. -The package ’PDFsharp-MigraDoc’ can be used on any platform including Windows and Linux. The Target Frameworks are ’net6.0’ and ’netstandard2.0’. -The packages ’PDFsharp-MigraDoc-GDI’ and ’PDFsharp-MigraDoc-WPF’ can be used under Windows only. The Target Frameworks are ’net6.0-windows’ and ’net472-windows’. +This is a version of PDFsharp and MigraDoc compatible with .NET 8 and higher. +The package ‘PDFsharp-MigraDoc’ can be used on any platform including Windows and Linux. The Target Frameworks are ‘net8.0’, ‘net9.0’, ‘net10.0’ and ‘netstandard2.0’. +The packages ‘PDFsharp-MigraDoc-GDI’ and ‘PDFsharp-MigraDoc-WPF’ can be used under Windows only. The Target Frameworks are ‘net8.0-windows’, ‘net9.0-windows’, ‘net10.0-windows’ and ‘net462’. See the project docs site for further information: -https://docs.pdfsharp.net/link/readme-v6.1.html +https://docs.pdfsharp.net/link/readme-v7.0.html diff --git a/src/foundation/nuget/src/PDFsharp.NuGet-gdi/Description.txt b/src/foundation/nuget/src/PDFsharp.NuGet-gdi/Description.txt index 39e800a7..be622cff 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet-gdi/Description.txt +++ b/src/foundation/nuget/src/PDFsharp.NuGet-gdi/Description.txt @@ -1,5 +1,9 @@ -PDFsharp is the Open Source library for creating and modifying PDF documents using .NET. It has an easy-to-use API that allows developers to generate or modify PDF files programmatically. PDFsharp can be used for various applications, including creating reports, invoices, and other types of documents. +PDFsharp is the Open Source library for creating and modifying PDF documents using .NET. It has an easy-to-use API that allows developers to generate or modify PDF files programmatically. PDFsharp can be used for various applications, including creating reports, invoices, and other types of documents. This package relies on Windows Forms (GDI+) and can be used under Windows only. See https://docs.pdfsharp.net for details. +  +See https://www.pdfsharp.com for professional support offers, premium technical advice, and contract work options. +Choose a support plan that suits your needs. We offer a variety of options, from small projects to large teams, with flexible response times. +Our team provides PDFsharp expert assistance, including implementation, optimization, and tailored solutions. diff --git a/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.Fewer.nuspec b/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.Fewer.nuspec new file mode 100644 index 00000000..c98d5d15 --- /dev/null +++ b/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.Fewer.nuspec @@ -0,0 +1,44 @@ + + + + $id$ + $version$ + $description$ + $summary$ + $authors$ + $owners$ + $projectUrl$ + MIT + images\PDFsharp-128x128.png + README.md + false + $releaseNotes$ + $CopyrightPdfSharp$ + $tags$ + + $title$ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.csproj b/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.csproj index 5938e342..85ec6c4e 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.csproj +++ b/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.csproj @@ -1,17 +1,20 @@  - net6.0-windows;net472-windows + $(PDFsharpTargetFrameworks_NuGet_Window) true - true + false + True + ..\..\..\..\StrongnameKey.snk true true - $(MSBuildThisFileDirectory)$(MSBuildProjectName).nuspec + $(MSBuildThisFileDirectory)$(MSBuildProjectName)$(NuGetNuspecTag).nuspec PDFsharp-GDI + $(NuGetId)-DEBUG PDFsharp for Windows Forms apps $(DebugBuildMessage)%0D$(NuGetDescription) A .NET library for processing PDF. @@ -20,7 +23,9 @@ + + diff --git a/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.nuspec b/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.nuspec index 5142aacf..734e4526 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.nuspec +++ b/src/foundation/nuget/src/PDFsharp.NuGet-gdi/PDFsharp.NuGet-gdi.nuspec @@ -13,32 +13,48 @@ README.md false $releaseNotes$ - $copyright$ + $CopyrightPdfSharp$ $tags$ $title$ - - - + + + - - - + + + + + + + + + + + - + + + + + + + - + - - + + + + diff --git a/src/foundation/nuget/src/PDFsharp.NuGet-gdi/ReleaseNotes.txt b/src/foundation/nuget/src/PDFsharp.NuGet-gdi/ReleaseNotes.txt index 3266b560..f7d8d9c8 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet-gdi/ReleaseNotes.txt +++ b/src/foundation/nuget/src/PDFsharp.NuGet-gdi/ReleaseNotes.txt @@ -1,6 +1,6 @@ -This is a version of PDFsharp using .NET 6. -The package ’PdfSharp’ can be used on any platform including Windows and Linux. The Target Frameworks are ’net6.0’ and ’netstandard2.0’. -The packages ’PDFsharp-gdi’ and ’PDFsharp-wpf’ can be used under Windows only. The Target Frameworks are ’net6.0-windows’ and ’net472-windows’. +This is a version of PDFsharp compatible with .NET 8 and higher. +The package ‘PdfSharp’ can be used on any platform including Windows and Linux. The Target Frameworks are ‘net8.0’, ‘net9.0’, ‘net10.0’ and ‘netstandard2.0’. +The packages ‘PDFsharp-gdi’ and ‘PDFsharp-wpf’ can be used under Windows only. The Target Frameworks are ‘net8.0-windows’, ‘net9.0-windows’, ‘net10.0-windows’ and ‘net462’. We also publish packages that contain PDFsharp plus MigraDoc. See the project docs site for further information: -https://docs.pdfsharp.net/link/readme-v6.1.html +https://docs.pdfsharp.net/link/readme-v7.0.html diff --git a/src/foundation/nuget/src/PDFsharp.NuGet-wpf/Description.txt b/src/foundation/nuget/src/PDFsharp.NuGet-wpf/Description.txt index 2627b98f..b82a01aa 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet-wpf/Description.txt +++ b/src/foundation/nuget/src/PDFsharp.NuGet-wpf/Description.txt @@ -1,5 +1,9 @@ -PDFsharp is the Open Source library for creating and modifying PDF documents using .NET. It has an easy-to-use API that allows developers to generate or modify PDF files programmatically. PDFsharp can be used for various applications, including creating reports, invoices, and other types of documents. +PDFsharp is the Open Source library for creating and modifying PDF documents using .NET. It has an easy-to-use API that allows developers to generate or modify PDF files programmatically. PDFsharp can be used for various applications, including creating reports, invoices, and other types of documents. This package relies on Windows Presentation Foundation (WPF) and can be used under Windows only. See https://docs.pdfsharp.net for details. +  +See https://www.pdfsharp.com for professional support offers, premium technical advice, and contract work options. +Choose a support plan that suits your needs. We offer a variety of options, from small projects to large teams, with flexible response times. +Our team provides PDFsharp expert assistance, including implementation, optimization, and tailored solutions. diff --git a/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.Fewer.nuspec b/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.Fewer.nuspec new file mode 100644 index 00000000..1eef4e64 --- /dev/null +++ b/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.Fewer.nuspec @@ -0,0 +1,44 @@ + + + + $id$ + $version$ + $description$ + $summary$ + $authors$ + $owners$ + $projectUrl$ + MIT + images\PDFsharp-128x128.png + README.md + false + $releaseNotes$ + $CopyrightPdfSharp$ + $tags$ + + $title$ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.csproj b/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.csproj index 6f4d9740..5928ff6c 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.csproj +++ b/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.csproj @@ -1,17 +1,20 @@  - net6.0-windows;net472-windows + $(PDFsharpTargetFrameworks_NuGet_Window) true - true + false + True + ..\..\..\..\StrongnameKey.snk true true - $(MSBuildThisFileDirectory)$(MSBuildProjectName).nuspec + $(MSBuildThisFileDirectory)$(MSBuildProjectName)$(NuGetNuspecTag).nuspec PDFsharp-WPF + $(NuGetId)-DEBUG PDFsharp for Windows WPF apps $(DebugBuildMessage)%0D$(NuGetDescription) A .NET library for processing PDF. @@ -20,7 +23,9 @@ + + diff --git a/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.nuspec b/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.nuspec index 6401ecf1..2094e3fb 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.nuspec +++ b/src/foundation/nuget/src/PDFsharp.NuGet-wpf/PDFsharp.NuGet-wpf.nuspec @@ -13,32 +13,48 @@ README.md false $releaseNotes$ - $copyright$ + $CopyrightPdfSharp$ $tags$ $title$ - - - + + + - - - + + + + + + + + + + + - + + + + + + + - + - - + + + + diff --git a/src/foundation/nuget/src/PDFsharp.NuGet-wpf/ReleaseNotes.txt b/src/foundation/nuget/src/PDFsharp.NuGet-wpf/ReleaseNotes.txt index 3266b560..f7d8d9c8 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet-wpf/ReleaseNotes.txt +++ b/src/foundation/nuget/src/PDFsharp.NuGet-wpf/ReleaseNotes.txt @@ -1,6 +1,6 @@ -This is a version of PDFsharp using .NET 6. -The package ’PdfSharp’ can be used on any platform including Windows and Linux. The Target Frameworks are ’net6.0’ and ’netstandard2.0’. -The packages ’PDFsharp-gdi’ and ’PDFsharp-wpf’ can be used under Windows only. The Target Frameworks are ’net6.0-windows’ and ’net472-windows’. +This is a version of PDFsharp compatible with .NET 8 and higher. +The package ‘PdfSharp’ can be used on any platform including Windows and Linux. The Target Frameworks are ‘net8.0’, ‘net9.0’, ‘net10.0’ and ‘netstandard2.0’. +The packages ‘PDFsharp-gdi’ and ‘PDFsharp-wpf’ can be used under Windows only. The Target Frameworks are ‘net8.0-windows’, ‘net9.0-windows’, ‘net10.0-windows’ and ‘net462’. We also publish packages that contain PDFsharp plus MigraDoc. See the project docs site for further information: -https://docs.pdfsharp.net/link/readme-v6.1.html +https://docs.pdfsharp.net/link/readme-v7.0.html diff --git a/src/foundation/nuget/src/PDFsharp.NuGet/Description.txt b/src/foundation/nuget/src/PDFsharp.NuGet/Description.txt index b6b011a5..432a269f 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet/Description.txt +++ b/src/foundation/nuget/src/PDFsharp.NuGet/Description.txt @@ -1,5 +1,9 @@ -PDFsharp is the Open Source library for creating and modifying PDF documents using .NET. It has an easy-to-use API that allows developers to generate or modify PDF files programmatically. PDFsharp can be used for various applications, including creating reports, invoices, and other types of documents. +PDFsharp is the Open Source library for creating and modifying PDF documents using .NET. It has an easy-to-use API that allows developers to generate or modify PDF files programmatically. PDFsharp can be used for various applications, including creating reports, invoices, and other types of documents. This package does not depend on Windows and can be used on any .NET compatible platform including Linux and macOS. See https://docs.pdfsharp.net for details. +  +See https://www.pdfsharp.com for professional support offers, premium technical advice, and contract work options. +Choose a support plan that suits your needs. We offer a variety of options, from small projects to large teams, with flexible response times. +Our team provides PDFsharp expert assistance, including implementation, optimization, and tailored solutions. diff --git a/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.Fewer.nuspec b/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.Fewer.nuspec new file mode 100644 index 00000000..2b2ced3e --- /dev/null +++ b/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.Fewer.nuspec @@ -0,0 +1,50 @@ + + + + $id$ + $version$ + $description$ + $summary$ + $authors$ + $owners$ + $projectUrl$ + MIT + images\PDFsharp-128x128.png + README.md + false + $releaseNotes$ + $CopyrightMigraDoc$ + $tags$ + + $title$ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.csproj b/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.csproj index f1db6367..73410a8b 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.csproj +++ b/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.csproj @@ -1,16 +1,20 @@  - net6.0;netstandard2.0 - true + $(PDFsharpTargetFrameworks_NuGet) + + false + True + ..\..\..\..\StrongnameKey.snk true true - $(MSBuildThisFileDirectory)$(MSBuildProjectName).nuspec + $(MSBuildThisFileDirectory)$(MSBuildProjectName)$(NuGetNuspecTag).nuspec PDFsharp + $(NuGetId)-DEBUG PDFsharp for Windows and Linux $(DebugBuildMessage)%0D$(NuGetDescription) A .NET library for processing PDF. @@ -18,8 +22,10 @@ - + + + diff --git a/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.nuspec b/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.nuspec index 4cf3f7d7..5abe25d7 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.nuspec +++ b/src/foundation/nuget/src/PDFsharp.NuGet/PDFsharp.NuGet.nuspec @@ -13,30 +13,44 @@ README.md false $releaseNotes$ - $copyright$ + $CopyrightPdfSharp$ $tags$ $title$ - - - + + + + + + + + + + + - - + + - + + + + + - - + + + + diff --git a/src/foundation/nuget/src/PDFsharp.NuGet/ReleaseNotes.txt b/src/foundation/nuget/src/PDFsharp.NuGet/ReleaseNotes.txt index 3266b560..f7d8d9c8 100644 --- a/src/foundation/nuget/src/PDFsharp.NuGet/ReleaseNotes.txt +++ b/src/foundation/nuget/src/PDFsharp.NuGet/ReleaseNotes.txt @@ -1,6 +1,6 @@ -This is a version of PDFsharp using .NET 6. -The package ’PdfSharp’ can be used on any platform including Windows and Linux. The Target Frameworks are ’net6.0’ and ’netstandard2.0’. -The packages ’PDFsharp-gdi’ and ’PDFsharp-wpf’ can be used under Windows only. The Target Frameworks are ’net6.0-windows’ and ’net472-windows’. +This is a version of PDFsharp compatible with .NET 8 and higher. +The package ‘PdfSharp’ can be used on any platform including Windows and Linux. The Target Frameworks are ‘net8.0’, ‘net9.0’, ‘net10.0’ and ‘netstandard2.0’. +The packages ‘PDFsharp-gdi’ and ‘PDFsharp-wpf’ can be used under Windows only. The Target Frameworks are ‘net8.0-windows’, ‘net9.0-windows’, ‘net10.0-windows’ and ‘net462’. We also publish packages that contain PDFsharp plus MigraDoc. See the project docs site for further information: -https://docs.pdfsharp.net/link/readme-v6.1.html +https://docs.pdfsharp.net/link/readme-v7.0.html diff --git a/src/foundation/nuget/src/README.md b/src/foundation/nuget/src/README.md index db928446..7dd29443 100644 --- a/src/foundation/nuget/src/README.md +++ b/src/foundation/nuget/src/README.md @@ -4,9 +4,12 @@ This folder contains dummy C# projects for the generation of the PDFsharp and Mi ## Developer notes +* Add dependencies for newly referenced NuGet packages to the nuspec files. + Also libraries, that are part of the shared framework, have to be added for all frameworks. + Otherwise, exceptions may occur at runtime when trying to load the respective library. * The description and release notes are single text files read by MSBUILD and put to the nuspec files. This is done because putting the text directly in XML is very cumbersome. -* The description and release notes should worded such that it is not necessary to revise them on every new release. +* The description and release notes should be worded such that it is not necessary to revise them on every new release. * For inspecting NuGet packages the **NuGet Package Explorer** is a nice app. ## Descriptions @@ -41,10 +44,10 @@ See Project Information for details. ### MigraDoc -MigraDoc Foundation - the Open Source .NET library that easily creates documents based on an object model with paragraphs, tables, styles, etc. and renders them into PDF or RTF. +MigraDoc - the Open Source .NET library that easily creates documents based on an object model with paragraphs, tables, styles, etc. and renders them into PDF or RTF. Text from MigraDoc 1.51: -MigraDoc Foundation - the Open Source .NET library that easily creates documents based on an object model with paragraphs, tables, styles, etc. and renders them into PDF or RTF. +MigraDoc - the Open Source .NET library that easily creates documents based on an object model with paragraphs, tables, styles, etc. and renders them into PDF or RTF. #### MigraDoc Core diff --git a/src/foundation/src/MigraDoc/docs/README.md b/src/foundation/src/MigraDoc/docs/README.md new file mode 100644 index 00000000..e4012614 --- /dev/null +++ b/src/foundation/src/MigraDoc/docs/README.md @@ -0,0 +1,3 @@ +# MigraDoc internal docs + +The docs folder contains internal notes and documentation. \ No newline at end of file diff --git a/src/foundation/src/MigraDoc/features/MigraDoc.Features/MigraDoc.Features.csproj b/src/foundation/src/MigraDoc/features/MigraDoc.Features/MigraDoc.Features.csproj index 41f1d5ad..7d49c23c 100644 --- a/src/foundation/src/MigraDoc/features/MigraDoc.Features/MigraDoc.Features.csproj +++ b/src/foundation/src/MigraDoc/features/MigraDoc.Features/MigraDoc.Features.csproj @@ -1,8 +1,8 @@ - + Exe - net6.0 + $(PDFsharpTargetFrameworks_Exe) diff --git a/src/foundation/src/MigraDoc/features/MigraDoc.Features/Program.cs b/src/foundation/src/MigraDoc/features/MigraDoc.Features/Program.cs index ce28b03e..72b18d98 100644 --- a/src/foundation/src/MigraDoc/features/MigraDoc.Features/Program.cs +++ b/src/foundation/src/MigraDoc/features/MigraDoc.Features/Program.cs @@ -1,10 +1,13 @@ -using System; +// MigraDoc - Creating Documents on the Fly +// See the LICENSE file in the solution root for more information. + +using System; namespace MigraDoc.Features { class Program { - static void Main(string[] args) + static void Main(string[] _) { Console.WriteLine("Hello, World!"); } diff --git a/src/foundation/src/MigraDoc/src/Directory.Build.props b/src/foundation/src/MigraDoc/src/Directory.Build.props index 7197970b..cf05c780 100644 --- a/src/foundation/src/MigraDoc/src/Directory.Build.props +++ b/src/foundation/src/MigraDoc/src/Directory.Build.props @@ -3,6 +3,7 @@ MigraDoc + $(CopyrightMigraDoc) diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/Capabilities.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/Capabilities.cs index a998fa7c..46deb49f 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/Capabilities.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/Capabilities.cs @@ -1,16 +1,16 @@ // PDFsharp - A .NET library for processing PDF +// PDFsharp - A .NET library for processing PDF // See the LICENSE file in the solution root for more information. namespace MigraDoc { - /// - /// UNDER CONSTRUCTION #RENAME Capabilities + /// UNDER CONSTRUCTION - DO NOT USE. /// Capabilities.Fonts.IsAvailable.GlyphToPath /// public static class Capabilities { - // Duplicated from PDFsharp. TODO Unify. + // Duplicated from PDFsharp. /// /// Defines the action to be taken if a requested feature is not available /// in the current build. @@ -82,7 +82,7 @@ public static class BackwardCompatibility /// public static bool DoNotCreateLastSection { get; set; } = false; - // TODO Space before on new page + // TODO_OLD Space before on new page /// /// In RTF a single decimal tabstop in a table is a special case. @@ -117,11 +117,11 @@ public static class Compatibility { /// /// Gets or sets a flag that specifies if the renderer should silently ignore charts if they are not supported. - /// Otherwise an exception will be thrown. + /// Otherwise, an exception will be thrown. /// public static FeatureNotAvailableAction ChartsCannotBeRendered { get; set; } = FeatureNotAvailableAction.DoNothing; - // TODO Barcodes etc. + // Barcodes etc. } } } diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/BookmarkField.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/BookmarkField.cs index d5f2c2ca..7ce6d591 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/BookmarkField.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/BookmarkField.cs @@ -55,7 +55,7 @@ public string Name internal override void Serialize(Serializer serializer) { if (String.IsNullOrEmpty(Values.Name)) - throw new InvalidOperationException(DomSR.MissingObligatoryProperty("Name", "BookmarkField")); + throw new InvalidOperationException(MdDomMsgs.MissingObligatoryProperty(nameof(Name), nameof(BookmarkField)).Message); serializer.Write("\\field(Bookmark)[Name = \"" + Name.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"]"); } @@ -69,7 +69,7 @@ public override bool IsNull() } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/DateField.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/DateField.cs index 1a5ee936..d841d538 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/DateField.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/DateField.cs @@ -48,7 +48,7 @@ internal override void Serialize(Serializer serializer) if (!String.IsNullOrEmpty(Values.Format)) str += "[Format = \"" + Format + "\"]"; else - str += "[]"; //Has to be appended to avoid confusion with '[' in immediately following text. + str += "[]"; // Has to be appended to avoid confusion with '[' in immediately following text. serializer.Write(str); } @@ -62,7 +62,7 @@ public override bool IsNull() } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/InfoField.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/InfoField.cs index 1f0b5dcd..939cab56 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/InfoField.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/InfoField.cs @@ -41,7 +41,7 @@ public string Name if (IsValidName(value)) Values.Name = value; else - throw new ArgumentException(DomSR.InvalidInfoFieldName(value)); + throw new ArgumentException(MdDomMsgs.InvalidInfoFieldName(value).Message); } } @@ -75,14 +75,14 @@ internal override void Serialize(Serializer serializer) { string str = "\\field(Info)"; if (Name == "") - throw new InvalidOperationException(DomSR.MissingObligatoryProperty("Name", "InfoField")); + throw new InvalidOperationException(MdDomMsgs.MissingObligatoryProperty(nameof(Name), nameof(InfoField)).Message); str += "[Name = \"" + Name + "\"]"; serializer.Write(str); } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/NumPagesField.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/NumPagesField.cs index 75f176a9..cbe58cd5 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/NumPagesField.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/NumPagesField.cs @@ -46,7 +46,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/NumericFieldBase.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/NumericFieldBase.cs index fdbbb829..ba61bb26 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/NumericFieldBase.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/NumericFieldBase.cs @@ -16,13 +16,13 @@ public abstract class NumericFieldBase : DocumentObject /// The valid format strings for the supported numeric types. /// protected static readonly string[] ValidFormatStrings = - { + [ "", "ROMAN", "roman", "ALPHABETIC", "alphabetic" - }; + ]; /// /// Initializes a new instance of the NumericFieldBase class. @@ -62,7 +62,7 @@ public string Format if (IsValidFormat(value)) Values.Format = value; else - throw new ArgumentException(DomSR.InvalidFieldFormat(value)); + throw new ArgumentException(MdDomMsgs.InvalidFieldFormat(value).Message); } } diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/PageField.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/PageField.cs index 75974702..d50c2194 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/PageField.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/PageField.cs @@ -40,13 +40,13 @@ internal override void Serialize(Serializer serializer) if (!String.IsNullOrEmpty(Values.Format)) str += "[Format = \"" + Format + "\"]"; else - str += "[]"; //Has to be appended to avoid confusion with '[' in immediately following text. + str += "[]"; // Has to be appended to avoid confusion with '[' in immediately following text. serializer.Write(str); } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/PageRefField.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/PageRefField.cs index 56069034..b4f80da5 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/PageRefField.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/PageRefField.cs @@ -61,7 +61,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/SectionField.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/SectionField.cs index 1e011d9d..45c4cdc9 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/SectionField.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/SectionField.cs @@ -40,13 +40,13 @@ internal override void Serialize(Serializer serializer) if (!String.IsNullOrEmpty(Values.Format)) str += "[Format = \"" + Format + "\"]"; else - str += "[]"; //Has to be appended to avoid confusion with '[' in directly following text. + str += "[]"; // Has to be appended to avoid confusion with '[' in directly following text. serializer.Write(str); } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/SectionPagesField.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/SectionPagesField.cs index 96e7b54a..3e956db3 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/SectionPagesField.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Fields/SectionPagesField.cs @@ -46,7 +46,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlParser.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlParser.cs index 1fa905f1..faa8072b 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlParser.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlParser.cs @@ -1,13 +1,14 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. -#define SECTIONFIX // BUG: Verify changes and clean if checked. - using MigraDoc.DocumentObjectModel.Tables; using MigraDoc.DocumentObjectModel.Shapes; using MigraDoc.DocumentObjectModel.Shapes.Charts; using System.Diagnostics.CodeAnalysis; +// ReSharper disable CommentTypo because of too much token strings in comments +// ReSharper disable GrammarMistakeInComment + namespace MigraDoc.DocumentObjectModel.IO { /// @@ -19,7 +20,7 @@ class DdlParser /// Initializes a new instance of the DdlParser class. /// internal DdlParser(string ddl, DdlReaderErrors? errors) - : this(String.Empty, ddl, errors) + : this("", ddl, errors) { } /// @@ -32,19 +33,19 @@ internal DdlParser(string fileName, string ddl, DdlReaderErrors? errors) } /// - /// Parses the keyword «\document». + /// Parses the keyword «\document». /// internal Document ParseDocument(Document? document) { document ??= new Document(); MoveToCode(); - AssertSymbol(Symbol.Document); + EnsureSymbol(Symbol.Document); ReadCode(); if (Symbol == Symbol.BracketLeft) ParseAttributes(document); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ReadCode(); while (Symbol == Symbol.EmbeddedFile) @@ -57,16 +58,16 @@ internal Document ParseDocument(Document? document) while (Symbol == Symbol.Section) ParseSection(document.Sections); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); - AssertCondition(Symbol == Symbol.Eof, DomMsgID.EndOfFileExpected); + EnsureCondition(Symbol == Symbol.Eof, () => MdDomMsgs.EndOfFileExpected); return document; } /// - /// Parses one of the keywords «\document», «\styles», «\section», «\table», «\textframe», «\chart» - /// and «\paragraph» and returns the corresponding DocumentObject or DocumentObjectCollection. + /// Parses one of the keywords «\document», «\styles», «\section», «\table», «\textframe», «\chart» + /// and «\paragraph» and returns the corresponding DocumentObject or DocumentObjectCollection. /// internal DocumentObject? ParseDocumentObject() { @@ -80,15 +81,15 @@ internal Document ParseDocument(Document? document) break; case Symbol.EmbeddedFile: - obj = ParseEmbeddedFiles(new EmbeddedFiles()); + obj = ParseEmbeddedFiles([] /*new EmbeddedFiles()*/); break; case Symbol.Styles: - obj = ParseStyles(new Styles()); + obj = ParseStyles([] /*new Styles()*/); break; case Symbol.Section: - obj = ParseSection(new Sections()); + obj = ParseSection([] /*new Sections()*/); break; case Symbol.Table: @@ -111,54 +112,54 @@ internal Document ParseDocument(Document? document) break; default: - ThrowParserException(DomMsgID.UnexpectedSymbol); + ThrowParserException(MdDomMsgs.UnexpectedSymbol(Token)); break; } ReadCode(); - AssertCondition(Symbol == Symbol.Eof, DomMsgID.EndOfFileExpected); + EnsureCondition(Symbol == Symbol.Eof, () => MdDomMsgs.EndOfFileExpected); return obj; } /// - /// Parses the keyword «\styles». + /// Parses the keyword «\styles». /// Styles ParseStyles(Styles styles) { MoveToCode(); - AssertSymbol(Symbol.Styles); + EnsureSymbol(Symbol.Styles); ReadCode(); // read '{' - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ReadCode(); // read first style name // An empty \styles block is valid. while (Symbol is Symbol.Identifier or Symbol.StringLiteral) ParseStyleDefinition(styles); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); // read beyond '}' return styles; } /// - /// Parses a style definition block within the keyword «\styles». + /// Parses a style definition block within the keyword «\styles». /// Style? ParseStyleDefinition(Styles styles) { // StyleName [: BaseStyleName] // { - // ... + // … // } Style? style = null; try { - var styleName = _scanner.Token; + var styleName = Token; string? baseStyleName = null; if (Symbol != Symbol.Identifier && Symbol != Symbol.StringLiteral) - ThrowParserException(DomMsgID.StyleNameExpected, styleName); + ThrowParserException(MdDomMsgs.StyleNameExpected(styleName)); ReadCode(); @@ -166,13 +167,13 @@ Styles ParseStyles(Styles styles) { ReadCode(); if (Symbol != Symbol.Identifier && Symbol != Symbol.StringLiteral) - ThrowParserException(DomMsgID.StyleNameExpected, styleName); + ThrowParserException(MdDomMsgs.StyleNameExpected(styleName)); // If baseStyle is not valid, choose InvalidStyleName by default. - baseStyleName = _scanner.Token; + baseStyleName = Token; if (styles.GetIndex(baseStyleName) == -1) { - ReportParserInfo(DdlErrorLevel.Warning, DomMsgID.UseOfUndefinedBaseStyle, baseStyleName); + ReportParserInfo(DdlErrorLevel.Warning, MdDomMsgs.UseOfUndefinedBaseStyle(baseStyleName)); baseStyleName = StyleNames.InvalidStyleName; } @@ -193,14 +194,12 @@ Styles ParseStyles(Styles styles) if (String.IsNullOrEmpty(baseStyleName)) { baseStyleName = StyleNames.InvalidStyleName; - ReportParserInfo(DdlErrorLevel.Warning, DomMsgID.UseOfUndefinedStyle, styleName); + ReportParserInfo(DdlErrorLevel.Warning, MdDomMsgs.UseOfUndefinedStyle(styleName)); } - style = styles.AddStyle(styleName, baseStyleName); } // Parse definition (if any). - if (Symbol == Symbol.BraceLeft) { ParseAttributeBlock(style); @@ -220,21 +219,21 @@ Styles ParseStyles(Styles styles) bool IsHeaderFooter() { var sym = Symbol; - return sym == Symbol.Header || sym == Symbol.Footer || - sym == Symbol.PrimaryHeader || sym == Symbol.PrimaryFooter || - sym == Symbol.EvenPageHeader || sym == Symbol.EvenPageFooter || - sym == Symbol.FirstPageHeader || sym == Symbol.FirstPageFooter; + return sym is Symbol.Header or Symbol.Footer + or Symbol.PrimaryHeader or Symbol.PrimaryFooter + or Symbol.EvenPageHeader or Symbol.EvenPageFooter + or Symbol.FirstPageHeader or Symbol.FirstPageFooter; } /// - /// Parses the keyword «\EmbeddedFiles». + /// Parses the keyword «\EmbeddedFiles». /// EmbeddedFiles ParseEmbeddedFiles(EmbeddedFiles embeddedFiles) { Debug.Assert(embeddedFiles != null); MoveToCode(); - AssertSymbol(Symbol.EmbeddedFile); + EnsureSymbol(Symbol.EmbeddedFile); try { @@ -254,14 +253,14 @@ EmbeddedFiles ParseEmbeddedFiles(EmbeddedFiles embeddedFiles) } /// - /// Parses the keyword «\section». + /// Parses the keyword «\section». /// Section? ParseSection(Sections sections) { Debug.Assert(sections != null); MoveToCode(); - AssertSymbol(Symbol.Section); + EnsureSymbol(Symbol.Section); Section? section = null; try @@ -272,18 +271,22 @@ EmbeddedFiles ParseEmbeddedFiles(EmbeddedFiles embeddedFiles) if (Symbol == Symbol.BracketLeft) ParseAttributes(section); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); -#if SECTIONFIX // DllParser was not able to read directly added paragraph content after headers and footers. This was an old error already existing in MigraDoc 1.51. ReadMoreContent: - if (IsParagraphContent()) // IsParagraphContent() must be checked first, before moving to the next token by ReadCode(). + // If a section contains only one paragraph, the paragraph keyword is omitted in MDDDL and the paragraph content is directly inserted into the section. + // The IsParagraphContent() check has to be made, before moving to the next token by ReadCode(). + if (IsParagraphContent()) { + // Paragraph content was inserted directly into the section. var paragraph = section.Elements.AddParagraph(); ParseParagraphContent(section.Elements, paragraph); + // After paragraph content, there must not be any HeaderFooter or other document elements in the section. } else { - ReadCode(); // Read next token. + // Read next token to check for HeaderFooter or the section’s document elements. + ReadCode(); if (IsHeaderFooter()) { @@ -294,26 +297,8 @@ EmbeddedFiles ParseEmbeddedFiles(EmbeddedFiles embeddedFiles) } ParseDocumentElements(section.Elements, Symbol.Section); } -#else - // Consider the case that the keyword «\paragraph» can be omitted. - if (IsParagraphContent()) - { - var paragraph = section.Elements.AddParagraph(); - ParseParagraphContent(section.Elements, paragraph); - } - else - { - ReadCode(); // read beyond '{' - - // 1st parse headers and footers - while (IsHeaderFooter()) - ParseHeaderFooter(section); - // 2nd parse all other stuff - ParseDocumentElements(section.Elements, Symbol.Section); - } -#endif - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); // read beyond '}' } catch (DdlParserException ex) @@ -324,20 +309,14 @@ EmbeddedFiles ParseEmbeddedFiles(EmbeddedFiles embeddedFiles) return section; } -#if SECTIONFIX - /// - /// Parses the keywords «\header». - /// Doesn't move to next token as paragraph content may follow, which has to be checked before moving to the next token. - /// -#else /// - /// Parses the keywords «\header». + /// Parses the keywords «\header». + /// Doesn’t move to next token as paragraph content may follow, which has to be checked before moving to the next token. /// -#endif void ParseHeaderFooter(Section section) { if (section == null) - throw new ArgumentNullException("section"); + throw new ArgumentNullException(nameof(section)); try { @@ -349,13 +328,13 @@ void ParseHeaderFooter(Section section) // Recall that the styles "Header" resp. "Footer" are used as default if // no other style was given. But this belongs to the rendering process, - // not to the DDL parser. Therefore no code here belongs to that. - HeaderFooter headerFooter = new HeaderFooter(); + // not to the DDL parser. Therefore, no code here belongs to that. + var headerFooter = new HeaderFooter(); ReadCode(); // read '[' or '{' if (Symbol == Symbol.BracketLeft) ParseAttributes(headerFooter); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); if (IsParagraphContent()) { Paragraph paragraph = headerFooter.Elements.AddParagraph(); @@ -366,15 +345,10 @@ void ParseHeaderFooter(Section section) ReadCode(); // parse '{' ParseDocumentElements(headerFooter.Elements, Symbol.HeaderOrFooter); } - AssertSymbol(Symbol.BraceRight); -#if SECTIONFIX - // Removed ReadCode() as a check for paragraph content after headers and footers has to be made before moving to the next token. -#else - ReadCode(); // parse beyond '{' -#endif + EnsureSymbol(Symbol.BraceRight); HeadersFooters headersFooters = isHeader ? section.Headers : section.Footers; - if (hdrFtrSym == Symbol.Header || hdrFtrSym == Symbol.Footer) + if (hdrFtrSym is Symbol.Header or Symbol.Footer) { headersFooters.Primary = headerFooter.Clone(); headersFooters.EvenPage = headerFooter.Clone(); @@ -418,26 +392,25 @@ bool IsParagraphContent() if (_scanner.Char == Chars.BackSlash) { Symbol symbol = _scanner.PeekKeyword(); - switch (symbol) + return symbol switch { - case Symbol.Bold: - case Symbol.Italic: - case Symbol.Underline: - case Symbol.Field: - case Symbol.Font: - case Symbol.FontColor: - case Symbol.FontSize: - case Symbol.Footnote: - case Symbol.Hyperlink: - case Symbol.Symbol: - case Symbol.Chr: - case Symbol.Tab: - case Symbol.LineBreak: - case Symbol.Space: - case Symbol.SoftHyphen: - return true; - } - return false; + Symbol.Bold => true, + Symbol.Italic => true, + Symbol.Underline => true, + Symbol.Field => true, + Symbol.Font => true, + Symbol.FontColor => true, + Symbol.FontSize => true, + Symbol.Footnote => true, + Symbol.Hyperlink => true, + Symbol.Symbol => true, + Symbol.Chr => true, + Symbol.Tab => true, + Symbol.LineBreak => true, + Symbol.Space => true, + Symbol.SoftHyphen => true, + _ => false + }; } return true; } @@ -445,9 +418,11 @@ bool IsParagraphContent() } /// - /// Parses the document elements of a «\paragraph», «\cell» or comparable. + /// Parses the document elements of a «\paragraph», «\cell» or comparable. /// +#pragma warning disable IDE0060 DocumentElements ParseDocumentElements(DocumentElements elements, Symbol context) +#pragma warning restore IDE0060 { // // This is clear: @@ -455,12 +430,12 @@ DocumentElements ParseDocumentElements(DocumentElements elements, Symbol context // All section content will be treated as paragraph content. // // but this is ambiguous: - // \section { \image(...) } + // \section { \image(…) } // It could be an image inside a paragraph or at the section level. // In this case it will be treated as an image on section level. // // If this is not your intention it must be like this: - // \section { \paragraph { \image(...) } } + // \section { \paragraph { \image(…) } } // while (TokenType == TokenType.KeyWord) @@ -496,7 +471,7 @@ DocumentElements ParseDocumentElements(DocumentElements elements, Symbol context break; default: - ThrowParserException(DomMsgID.UnexpectedSymbol, _scanner.Token); + ThrowParserException(MdDomMsgs.UnexpectedSymbol(Token)); break; } } @@ -504,12 +479,12 @@ DocumentElements ParseDocumentElements(DocumentElements elements, Symbol context } /// - /// Parses the keyword «\paragraph». + /// Parses the keyword «\paragraph». /// void ParseParagraph(DocumentElements elements) { MoveToCode(); - AssertSymbol(Symbol.Paragraph); + EnsureSymbol(Symbol.Paragraph); Paragraph paragraph = elements.AddParagraph(); try @@ -522,7 +497,7 @@ void ParseParagraph(DocumentElements elements) if (Symbol == Symbol.BraceLeft) { ParseParagraphContent(elements, paragraph); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); // read beyond '}' } } @@ -557,7 +532,7 @@ void ParseParagraphContent(DocumentElements elements, Paragraph? paragraph) /// Removes the last blank from the text. Used before a tab, a line break or a space will be /// added to the text. /// - void RemoveTrailingBlank(ParagraphElements elements) + static void RemoveTrailingBlank(ParagraphElements elements) { var dom = elements.LastObject; if (dom is Text text) @@ -583,7 +558,7 @@ void ParseFormattedText(ParagraphElements elements, int nestingLevel) switch (Symbol) { case Symbol.Eof: - ThrowParserException(DomMsgID.UnexpectedEndOfFile); + ThrowParserException(MdDomMsgs.UnexpectedEndOfFile); break; case Symbol.EmptyLine: @@ -687,29 +662,29 @@ void ParseFormattedText(ParagraphElements elements, int nestingLevel) break; default: - ThrowParserException(DomMsgID.UnexpectedSymbol, Token); + ThrowParserException(MdDomMsgs.UnexpectedSymbol(Token)); break; } } } /// - /// Parses the keywords «\bold», «\italic», and «\underline». + /// Parses the keywords «\bold», «\italic», and «\underline». /// void ParseBoldItalicEtc(FormattedText formattedText, int nestingLevel) { ReadCode(); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ParseFormattedText(formattedText.Elements, nestingLevel); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); } /// - /// Parses the keyword «\font». + /// Parses the keyword «\font». /// void ParseFont(FormattedText formattedText, int nestingLevel) { - AssertSymbol(Symbol.Font); + EnsureSymbol(Symbol.Font); ReadCode(); if (Symbol == Symbol.ParenLeft) @@ -721,80 +696,80 @@ void ParseFont(FormattedText formattedText, int nestingLevel) if (Symbol == Symbol.BracketLeft) ParseAttributes(formattedText); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ParseFormattedText(formattedText.Elements, nestingLevel); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); } /// - /// Parses code like «("name")». + /// Parses code like «("name")». /// string ParseElementName() { - AssertSymbol(Symbol.ParenLeft); + EnsureSymbol(Symbol.ParenLeft); ReadCode(); if (Symbol != Symbol.StringLiteral) - ThrowParserException(DomMsgID.StringExpected, Token); + ThrowParserException(MdDomMsgs.StringValueExpected(Token)); string name = Token; ReadCode(); - AssertSymbol(Symbol.ParenRight); + EnsureSymbol(Symbol.ParenRight); return name; } /// - /// Parses the keyword «\fontsize». + /// Parses the keyword «\fontsize». /// void ParseFontSize(FormattedText formattedText, int nestingLevel) { - AssertSymbol(Symbol.FontSize); + EnsureSymbol(Symbol.FontSize); ReadCode(); - AssertSymbol(Symbol.ParenLeft); + EnsureSymbol(Symbol.ParenLeft); ReadCode(); - //NYI: Check token for correct Unit format + // NYI: Check token for correct Unit format formattedText.Font.Size = Token; ReadCode(); - AssertSymbol(Symbol.ParenRight); + EnsureSymbol(Symbol.ParenRight); ReadCode(); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ParseFormattedText(formattedText.Elements, nestingLevel); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); } /// - /// Parses the keyword «\fontcolor». + /// Parses the keyword «\fontcolor». /// void ParseFontColor(FormattedText formattedText, int nestingLevel) { - AssertSymbol(Symbol.FontColor); + EnsureSymbol(Symbol.FontColor); ReadCode(); // read '(' - AssertSymbol(Symbol.ParenLeft); + EnsureSymbol(Symbol.ParenLeft); ReadCode(); // read color token Color color = ParseColor(); formattedText.Font.Color = color; - AssertSymbol(Symbol.ParenRight); + EnsureSymbol(Symbol.ParenRight); ReadCode(); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ParseFormattedText(formattedText.Elements, nestingLevel); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); } /// - /// Parses the keyword «\symbol» resp. «\(». + /// Parses the keyword «\symbol» resp. «\(». /// void ParseSymbol(ParagraphElements elements) { - AssertSymbol(Symbol.Symbol); + EnsureSymbol(Symbol.Symbol); ReadCode(); // read '(' - AssertSymbol(Symbol.ParenLeft); + EnsureSymbol(Symbol.ParenLeft); const char ch = (char)0; - SymbolName symtype = 0; + SymbolName symType = 0; int count = 1; ReadCode(); // read name @@ -804,18 +779,18 @@ void ParseSymbol(ParagraphElements elements) { if (Enum.IsDefined(typeof(SymbolName), Token)) { - AssertCondition(IsSymbolType(Token), DomMsgID.InvalidSymbolType, Token); - symtype = (SymbolName)Enum.Parse(typeof(SymbolName), Token, true); + EnsureCondition(IsSymbolType(Token), () => MdDomMsgs.InvalidSymbolType(Token)); + symType = (SymbolName)Enum.Parse(typeof(SymbolName), Token, true); } } catch (Exception ex) { - ThrowParserException(ex, DomMsgID.InvalidEnum, Token); + ThrowParserException(MdDomMsgs.InvalidEnum(Token, nameof(SymbolName)), ex); } } else { - ThrowParserException(DomMsgID.UnexpectedSymbol, Token); + ThrowParserException(MdDomMsgs.UnexpectedSymbol(Token)); } ReadCode(); // read integer or identifier @@ -827,40 +802,40 @@ void ParseSymbol(ParagraphElements elements) ReadCode(); } - AssertSymbol(Symbol.ParenRight); + EnsureSymbol(Symbol.ParenRight); - if (symtype != 0) - elements.AddCharacter(symtype, count); + if (symType != 0) + elements.AddCharacter(symType, count); else elements.AddCharacter(ch, count); } /// - /// Parses the keyword «\chr». + /// Parses the keyword «\chr». /// void ParseChr(ParagraphElements elements) { - AssertSymbol(Symbol.Chr); + EnsureSymbol(Symbol.Chr); ReadCode(); // read '(' - AssertSymbol(Symbol.ParenLeft); + EnsureSymbol(Symbol.ParenLeft); char ch = (char)0; - SymbolName symtype = 0; + SymbolName symType = 0; int count = 1; ReadCode(); // read integer if (TokenType == TokenType.IntegerLiteral) { int val = _scanner.GetTokenValueAsInt(); - if (val >= 1 && val < 256) + if (val is >= 1 and <= 255) ch = (char)val; else - ThrowParserException(DomMsgID.OutOfRange, "1 - 255"); + ThrowParserException(MdDomMsgs.OutOfRange("1 - 255")); } else { - ThrowParserException(DomMsgID.UnexpectedSymbol, Token); + ThrowParserException(MdDomMsgs.UnexpectedSymbol(Token)); } ReadCode(); // read integer or identifier @@ -872,30 +847,32 @@ void ParseChr(ParagraphElements elements) ReadCode(); } - AssertSymbol(Symbol.ParenRight); + EnsureSymbol(Symbol.ParenRight); - if (symtype != 0) - elements.AddCharacter(symtype, count); + if (symType != 0) + elements.AddCharacter(symType, count); else elements.AddCharacter(ch, count); } /// - /// Parses the keyword «\field». + /// Parses the keyword «\field». /// +#pragma warning disable IDE0060 void ParseField(ParagraphElements elements, int nestingLevel) +#pragma warning restore IDE0060 { - AssertSymbol(Symbol.Field); + EnsureSymbol(Symbol.Field); ReadCode(); // read '(' - AssertSymbol(Symbol.ParenLeft); + EnsureSymbol(Symbol.ParenLeft); ReadCode(); // read identifier - AssertSymbol(Symbol.Identifier); + EnsureSymbol(Symbol.Identifier); string fieldType = Token.ToLower(); ReadCode(); // read ')' - AssertSymbol(Symbol.ParenRight); + EnsureSymbol(Symbol.ParenRight); DocumentObject? field = null; switch (fieldType) @@ -908,6 +885,7 @@ void ParseField(ParagraphElements elements, int nestingLevel) field = elements.AddPageField(); break; + // ReSharper disable once StringLiteralTypo case "numpages": field = elements.AddNumPagesField(); break; @@ -916,6 +894,7 @@ void ParseField(ParagraphElements elements, int nestingLevel) field = elements.AddInfoField(0); break; + // ReSharper disable once StringLiteralTypo case "sectionpages": field = elements.AddSectionPagesField(); break; @@ -928,11 +907,12 @@ void ParseField(ParagraphElements elements, int nestingLevel) field = elements.AddBookmark(""); break; + // ReSharper disable once StringLiteralTypo case "pageref": field = elements.AddPageRefField(""); break; } - AssertCondition(field != null, DomMsgID.InvalidFieldType, Token); + EnsureCondition(field != null, () => MdDomMsgs.InvalidFieldType(Token)); if (_scanner.PeekSymbol() == Symbol.BracketLeft) { @@ -942,20 +922,22 @@ void ParseField(ParagraphElements elements, int nestingLevel) } /// - /// Parses the keyword «\footnote». + /// Parses the keyword «\footnote». /// +#pragma warning disable IDE0060 void ParseFootnote(ParagraphElements elements, int nestingLevel) +#pragma warning restore IDE0060 { - AssertSymbol(Symbol.Footnote); + EnsureSymbol(Symbol.Footnote); ReadCode(); - Footnote footnote = elements.AddFootnote(); + var footnote = elements.AddFootnote(); if (Symbol == Symbol.BracketLeft) ParseAttributes(footnote); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); - // The keyword «\paragraph» is typically omitted. + // The keyword «\paragraph» is typically omitted. if (IsParagraphContent()) { Paragraph paragraph = footnote.Elements.AddParagraph(); @@ -966,53 +948,55 @@ void ParseFootnote(ParagraphElements elements, int nestingLevel) ReadCode(); // read beyond '{' ParseDocumentElements(footnote.Elements, Symbol.Footnote); } - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); } /// - /// Parses the keyword «\hyperlink». + /// Parses the keyword «\hyperlink». /// void ParseHyperlink(ParagraphElements elements, int nestingLevel) { - AssertSymbol(Symbol.Hyperlink); + EnsureSymbol(Symbol.Hyperlink); ReadCode(); Hyperlink hyperlink = elements.AddHyperlink(""); - //NYI: Without name and type the hyperlink is senseless, so attributes need to be checked + // NYI: Without name and type the hyperlink is senseless, so attributes need to be checked if (Symbol == Symbol.BracketLeft) ParseAttributes(hyperlink); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ParseFormattedText(hyperlink.Elements, nestingLevel); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); } /// - /// Parses the keyword «\space». + /// Parses the keyword «\space». /// +#pragma warning disable IDE0060 void ParseSpace(ParagraphElements elements, int nestingLevel) +#pragma warning restore IDE0060 { // Samples // \space // \space(5) // \space(em) // \space(em,5) - AssertSymbol(Symbol.Space); + EnsureSymbol(Symbol.Space); Character space = elements.AddSpace(1); - // «\space» can stand alone + // «\space» can stand alone if (_scanner.PeekSymbol() == Symbol.ParenLeft) { ReadCode(); // read '(' - AssertSymbol(Symbol.ParenLeft); + EnsureSymbol(Symbol.ParenLeft); ReadCode(); // read beyond '(' if (Symbol == Symbol.Identifier) { string type = Token; if (!IsSpaceType(type)) - ThrowParserException(DomMsgID.InvalidEnum, type); + ThrowParserException(MdDomMsgs.InvalidEnum(type, nameof(SymbolName))); space.SymbolName = (SymbolName)Enum.Parse(typeof(SymbolName), type, true); @@ -1020,7 +1004,7 @@ void ParseSpace(ParagraphElements elements, int nestingLevel) if (Symbol == Symbol.Comma) { ReadCode(); // read integer - AssertSymbol(Symbol.IntegerLiteral); + EnsureSymbol(Symbol.IntegerLiteral); space.Count = _scanner.GetTokenValueAsInt(); ReadCode(); // read ')' } @@ -1030,7 +1014,7 @@ void ParseSpace(ParagraphElements elements, int nestingLevel) space.Count = _scanner.GetTokenValueAsInt(); ReadCode(); } - AssertSymbol(Symbol.ParenRight); + EnsureSymbol(Symbol.ParenRight); } } @@ -1039,13 +1023,13 @@ void ParseSpace(ParagraphElements elements, int nestingLevel) /// void ParsePageBreak(DocumentElements elements) { - AssertSymbol(Symbol.PageBreak); + EnsureSymbol(Symbol.PageBreak); elements.AddPageBreak(); ReadCode(); } /// - /// Parses the keyword «\table». + /// Parses the keyword «\table». /// void ParseTable(DocumentElements? elements, Table? table) { @@ -1060,24 +1044,24 @@ void ParseTable(DocumentElements? elements, Table? table) } MoveToCode(); - AssertSymbol(Symbol.Table); + EnsureSymbol(Symbol.Table); ReadCode(); - if (_scanner.Symbol == Symbol.BracketLeft) + if (Symbol == Symbol.BracketLeft) ParseAttributes(tbl); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ReadCode(); - // Table must start with «\columns»... - AssertSymbol(Symbol.Columns); + // Table must start with «\columns»... + EnsureSymbol(Symbol.Columns); ParseColumns(tbl); - // ...followed by «\rows». - AssertSymbol(Symbol.Rows); + // ...followed by «\rows». + EnsureSymbol(Symbol.Rows); ParseRows(tbl); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); // read beyond '}' } catch (DdlParserException ex) @@ -1088,7 +1072,7 @@ void ParseTable(DocumentElements? elements, Table? table) } /// - /// Parses the keyword «\columns». + /// Parses the keyword «\columns». /// void ParseColumns(Table table) { @@ -1099,7 +1083,7 @@ void ParseColumns(Table table) if (Symbol == Symbol.BracketLeft) ParseAttributes(table.Columns); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ReadCode(); var loop = true; @@ -1108,7 +1092,7 @@ void ParseColumns(Table table) switch (Symbol) { case Symbol.Eof: - ThrowParserException(DomMsgID.UnexpectedEndOfFile); + ThrowParserException(MdDomMsgs.UnexpectedEndOfFile); break; case Symbol.BraceRight: @@ -1121,14 +1105,14 @@ void ParseColumns(Table table) break; default: - AssertSymbol(Symbol.Column); + EnsureSymbol(Symbol.Column); break; } } } /// - /// Parses the keyword «\column». + /// Parses the keyword «\column». /// void ParseColumn(Column column) { @@ -1143,13 +1127,13 @@ void ParseColumn(Column column) if (Symbol == Symbol.BraceLeft) { ReadCode(); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); } } /// - /// Parses the keyword «\rows». + /// Parses the keyword «\rows». /// void ParseRows(Table table) { @@ -1160,7 +1144,7 @@ void ParseRows(Table table) if (Symbol == Symbol.BracketLeft) ParseAttributes(table.Rows); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ReadCode(); var loop = true; @@ -1169,7 +1153,7 @@ void ParseRows(Table table) switch (Symbol) { case Symbol.Eof: - ThrowParserException(DomMsgID.UnexpectedEndOfFile); + ThrowParserException(MdDomMsgs.UnexpectedEndOfFile); break; case Symbol.BraceRight: @@ -1182,14 +1166,14 @@ void ParseRows(Table table) break; default: - AssertSymbol(Symbol.Row); + EnsureSymbol(Symbol.Row); break; } } } /// - /// Parses the keyword «\row». + /// Parses the keyword «\row». /// void ParseRow(Row row) { @@ -1212,7 +1196,7 @@ void ParseRow(Row row) switch (Symbol) { case Symbol.Eof: - ThrowParserException(DomMsgID.UnexpectedEndOfFile); + ThrowParserException(MdDomMsgs.UnexpectedEndOfFile); break; case Symbol.BraceRight: @@ -1226,7 +1210,7 @@ void ParseRow(Row row) break; default: - ThrowParserException(DomMsgID.UnexpectedSymbol, Token); + ThrowParserException(MdDomMsgs.UnexpectedSymbol(Token)); break; } } @@ -1234,7 +1218,7 @@ void ParseRow(Row row) } /// - /// Parses the keyword «\cell». + /// Parses the keyword «\cell». /// void ParseCell(Cell cell) { @@ -1258,30 +1242,30 @@ void ParseCell(Cell cell) if (Symbol != Symbol.BraceRight) ParseDocumentElements(cell.Elements, Symbol.Cell); } - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); // read '}' } } /// - /// Parses the keyword «\image». + /// Parses the keyword «\image». /// void ParseImage(Image image, bool paragraphContent) { // Future syntax by example // \image("Name") - // \image("Name")[...] - // \image{base64...} //NYI - // \image[...]{base64...} //NYI + // \image("Name")[…] + // \image{base64…} // NYI + // \image[…]{base64…} // NYI Debug.Assert(image != null); try { MoveToCode(); - AssertSymbol(Symbol.Image); + EnsureSymbol(Symbol.Image); ReadCode(); - if (_scanner.Symbol == Symbol.ParenLeft) + if (Symbol == Symbol.ParenLeft) image.Name = ParseElementName(); if (_scanner.PeekSymbol() == Symbol.BracketLeft) @@ -1300,20 +1284,20 @@ void ParseImage(Image image, bool paragraphContent) } /// - /// Parses the keyword «\textframe». + /// Parses the keyword «\textframe». /// void ParseTextFrame(DocumentElements elements) { Debug.Assert(elements != null); - TextFrame textFrame = elements.AddTextFrame(); + var textFrame = elements.AddTextFrame(); try { ReadCode(); - if (_scanner.Symbol == Symbol.BracketLeft) + if (Symbol == Symbol.BracketLeft) ParseAttributes(textFrame); - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); if (IsParagraphContent()) { ParseParagraphContent(textFrame.Elements, null); @@ -1323,7 +1307,7 @@ void ParseTextFrame(DocumentElements elements) ReadCode(); // read '{' ParseDocumentElements(textFrame.Elements, Symbol.TextFrame); } - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); // read beyond '}' } catch (DdlParserException ex) @@ -1344,22 +1328,22 @@ void ParseBarcode(DocumentElements elements) try { ReadCode(); - AssertSymbol(Symbol.ParenLeft, DomMsgID.MissingParenLeft, GetSymbolText(Symbol.Barcode)); + EnsureSymbol(Symbol.ParenLeft, () => MdDomMsgs.MissingParenLeft(GetSymbolText(Symbol.Barcode))); ReadCode(); - AssertSymbol(Symbol.StringLiteral, DomMsgID.UnexpectedSymbol); + EnsureSymbol(Symbol.StringLiteral, () => MdDomMsgs.UnexpectedSymbol(Token)); - Barcode barcode = elements.AddBarcode(); + var barcode = elements.AddBarcode(); barcode.SetValue("Code", Token); ReadCode(); if (Symbol == Symbol.Comma) { ReadCode(); - AssertSymbol(Symbol.Identifier, DomMsgID.IdentifierExpected, Token); + EnsureSymbol(Symbol.Identifier, () => MdDomMsgs.IdentifierExpected(Token)); BarcodeType barcodeType = (BarcodeType)Enum.Parse(typeof(BarcodeType), Token, true); barcode.SetValue("type", barcodeType); ReadCode(); } - AssertSymbol(Symbol.ParenRight, DomMsgID.MissingParenRight, GetSymbolText(Symbol.Barcode)); + EnsureSymbol(Symbol.ParenRight, () => MdDomMsgs.MissingParenRight(GetSymbolText(Symbol.Barcode))); ReadCode(); if (Symbol == Symbol.BracketLeft) @@ -1374,7 +1358,7 @@ void ParseBarcode(DocumentElements elements) } /// - /// Parses the keyword «\chart». + /// Parses the keyword «\chart». /// void ParseChart(DocumentElements elements) { @@ -1388,14 +1372,14 @@ void ParseChart(DocumentElements elements) try { ReadCode(); // read '(' - AssertSymbol(Symbol.ParenLeft, DomMsgID.MissingParenLeft, GetSymbolText(Symbol.Chart)); + EnsureSymbol(Symbol.ParenLeft, () => MdDomMsgs.MissingParenLeft(GetSymbolText(Symbol.Chart))); ReadCode(); // ChartType name - AssertSymbol(Symbol.Identifier, DomMsgID.IdentifierExpected, Token); + EnsureSymbol(Symbol.Identifier, () => MdDomMsgs.IdentifierExpected(Token)); string chartTypeName = Token; ReadCode(); // read ')' - AssertSymbol(Symbol.ParenRight, DomMsgID.MissingParenRight, GetSymbolText(Symbol.Chart)); + EnsureSymbol(Symbol.ParenRight, () => MdDomMsgs.MissingParenRight(GetSymbolText(Symbol.Chart))); try { @@ -1403,16 +1387,16 @@ void ParseChart(DocumentElements elements) } catch (Exception ex) { - ThrowParserException(ex, DomMsgID.UnknownChartType, chartTypeName); + ThrowParserException(MdDomMsgs.UnknownChartType(chartTypeName), ex); } - Chart chart = elements.AddChart(chartType); + var chart = elements.AddChart(chartType); ReadCode(); if (Symbol == Symbol.BracketLeft) ParseAttributes(chart); - AssertSymbol(Symbol.BraceLeft, DomMsgID.MissingBraceLeft, GetSymbolText(Symbol.Chart)); + EnsureSymbol(Symbol.BraceLeft, () => MdDomMsgs.MissingBraceLeft(GetSymbolText(Symbol.Chart))); ReadCode(); // read beyond '{' @@ -1422,7 +1406,7 @@ void ParseChart(DocumentElements elements) switch (Symbol) { case Symbol.Eof: - ThrowParserException(DomMsgID.UnexpectedEndOfFile); + ThrowParserException(MdDomMsgs.UnexpectedEndOfFile); break; case Symbol.BraceRight: @@ -1478,7 +1462,7 @@ void ParseChart(DocumentElements elements) break; default: - ThrowParserException(DomMsgID.UnexpectedSymbol, Token); + ThrowParserException(MdDomMsgs.UnexpectedSymbol(Token)); break; } } @@ -1492,7 +1476,7 @@ void ParseChart(DocumentElements elements) } /// - /// Parses the keyword «\plotarea» inside a chart. + /// Parses the keyword «\plotarea» inside a chart. /// void ParseArea(PlotArea area) { @@ -1523,11 +1507,12 @@ void ParseArea(PlotArea area) break; default: - // Alles ignorieren? Warnung ausgeben? + // Ignore all? Issue warning? + _ = typeof(int); break; } } - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); // read beyond '}' } catch (DdlParserException pe) @@ -1538,8 +1523,8 @@ void ParseArea(PlotArea area) } /// - /// Parses the keywords «\headerarea», «\toparea», «\bottomarea», «\footerarea», - /// «\leftarea» or «\rightarea» inside a chart. + /// Parses the keywords «\headerarea», «\toparea», «\bottomarea», «\footerarea», + /// «\leftarea» or «\rightarea» inside a chart. /// void ParseArea(TextArea area) { @@ -1592,18 +1577,18 @@ void ParseArea(TextArea area) break; case Symbol.Image: - Image image = new Image(); + var image = new Image(); ParseImage(image, false); area.Elements.Add(image); break; default: - ThrowParserException(DomMsgID.UnexpectedSymbol, Token); + ThrowParserException(MdDomMsgs.UnexpectedSymbol(Token)); break; } } } - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); // read beyond '}' } catch (DdlParserException pe) @@ -1614,7 +1599,7 @@ void ParseArea(TextArea area) } /// - /// Parses the keywords «\xaxis», «\yaxis» or «\zaxis» inside a chart. + /// Parses the keywords «\xaxis», «\yaxis» or «\zaxis» inside a chart. /// void ParseAxes(Axis axis, Symbol symbolAxis) { @@ -1639,7 +1624,7 @@ void ParseAxes(Axis axis, Symbol symbolAxis) while (Symbol != Symbol.BraceRight) ReadCode(); - AssertSymbol(Symbol.BraceRight, DomMsgID.MissingBraceRight, GetSymbolText(symbolAxis)); + EnsureSymbol(Symbol.BraceRight, () => MdDomMsgs.MissingBraceRight(GetSymbolText(symbolAxis))); ReadCode(); // read beyond '}' } catch (DdlParserException pe) @@ -1650,7 +1635,7 @@ void ParseAxes(Axis axis, Symbol symbolAxis) } /// - /// Parses the keyword «\series» inside a chart. + /// Parses the keyword «\series» inside a chart. /// void ParseSeries(Series series) { @@ -1664,7 +1649,7 @@ void ParseSeries(Series series) if (Symbol == Symbol.BracketLeft) ParseAttributes(series); - AssertSymbol(Symbol.BraceLeft, DomMsgID.MissingBraceLeft, GetSymbolText(Symbol.Series)); + EnsureSymbol(Symbol.BraceLeft, () => MdDomMsgs.MissingBraceLeft(GetSymbolText(Symbol.Series))); ReadCode(); // read beyond '{' bool fContinue = true; @@ -1674,7 +1659,7 @@ void ParseSeries(Series series) switch (Symbol) { case Symbol.Eof: - ThrowParserException(DomMsgID.UnexpectedEndOfFile); + ThrowParserException(MdDomMsgs.UnexpectedEndOfFile); break; case Symbol.BraceRight: @@ -1687,27 +1672,27 @@ void ParseSeries(Series series) break; case Symbol.Point: - AssertCondition(fFoundComma, DomMsgID.MissingComma); - ParsePoint(series.Add(0.0)); + EnsureCondition(fFoundComma, () => MdDomMsgs.MissingComma); + ParsePoint(series.Add(0)); fFoundComma = false; break; case Symbol.Null: - AssertCondition(fFoundComma, DomMsgID.MissingComma); + EnsureCondition(fFoundComma, () => MdDomMsgs.MissingComma); series.AddBlank(); fFoundComma = false; ReadCode(); break; default: - AssertCondition(fFoundComma, DomMsgID.MissingComma); + EnsureCondition(fFoundComma, () => MdDomMsgs.MissingComma); series.Add(_scanner.GetTokenValueAsReal()); fFoundComma = false; ReadCode(); break; } } - AssertSymbol(Symbol.BraceRight, DomMsgID.MissingBraceRight, GetSymbolText(Symbol.Series)); + EnsureSymbol(Symbol.BraceRight, () => MdDomMsgs.MissingBraceRight(GetSymbolText(Symbol.Series))); ReadCode(); // read beyond '}' } catch (DdlParserException pe) @@ -1718,7 +1703,7 @@ void ParseSeries(Series series) } /// - /// Parses the keyword «\xvalues» inside a chart. + /// Parses the keyword «\xvalues» inside a chart. /// void ParseSeries(XSeries series) { @@ -1728,7 +1713,7 @@ void ParseSeries(XSeries series) try { ReadCode(); - AssertSymbol(Symbol.BraceLeft, DomMsgID.MissingBraceLeft, GetSymbolText(Symbol.Series)); + EnsureSymbol(Symbol.BraceLeft, () => MdDomMsgs.MissingBraceLeft(GetSymbolText(Symbol.Series))); bool fFoundComma = true; bool fContinue = true; @@ -1738,7 +1723,7 @@ void ParseSeries(XSeries series) switch (Symbol) { case Symbol.Eof: - ThrowParserException(DomMsgID.UnexpectedEndOfFile); + ThrowParserException(MdDomMsgs.UnexpectedEndOfFile); break; case Symbol.BraceRight: @@ -1750,7 +1735,7 @@ void ParseSeries(XSeries series) break; case Symbol.Null: - AssertCondition(fFoundComma, DomMsgID.MissingComma); + EnsureCondition(fFoundComma, () => MdDomMsgs.MissingComma); series.AddBlank(); fFoundComma = false; break; @@ -1759,17 +1744,17 @@ void ParseSeries(XSeries series) case Symbol.IntegerLiteral: case Symbol.RealLiteral: case Symbol.HexIntegerLiteral: - AssertCondition(fFoundComma, DomMsgID.MissingComma); + EnsureCondition(fFoundComma, () => MdDomMsgs.MissingComma); series.Add(Token); fFoundComma = false; break; default: - ThrowParserException(DomMsgID.UnexpectedSymbol, Token); + ThrowParserException(MdDomMsgs.UnexpectedSymbol(Token)); break; } } - AssertSymbol(Symbol.BraceRight, DomMsgID.MissingBraceRight, GetSymbolText(Symbol.Series)); + EnsureSymbol(Symbol.BraceRight, () => MdDomMsgs.MissingBraceRight(GetSymbolText(Symbol.Series))); ReadCode(); // read beyond '}' } catch (DdlParserException pe) @@ -1780,7 +1765,7 @@ void ParseSeries(XSeries series) } /// - /// Parses the keyword «\point» inside a series. + /// Parses the keyword «\point» inside a series. /// void ParsePoint(Point point) { @@ -1794,12 +1779,12 @@ void ParsePoint(Point point) if (Symbol == Symbol.BracketLeft) ParseAttributes(point); - AssertSymbol(Symbol.BraceLeft, DomMsgID.MissingBraceLeft, GetSymbolText(Symbol.Point)); + EnsureSymbol(Symbol.BraceLeft, () => MdDomMsgs.MissingBraceLeft(GetSymbolText(Symbol.Point))); ReadCode(); // read beyond '{' point.Value = _scanner.GetTokenValueAsReal(); ReadCode(); // read '}' - AssertSymbol(Symbol.BraceRight, DomMsgID.MissingBraceRight, GetSymbolText(Symbol.Point)); + EnsureSymbol(Symbol.BraceRight, () => MdDomMsgs.MissingBraceRight(GetSymbolText(Symbol.Point))); ReadCode(); // read beyond '}' } catch (DdlParserException pe) @@ -1810,7 +1795,7 @@ void ParsePoint(Point point) } /// - /// Parses the keyword «\legend» inside a textarea. + /// Parses the keyword «\legend» inside a textarea. /// void ParseLegend(Legend legend) { @@ -1842,18 +1827,18 @@ void ParseLegend(Legend legend) } /// - /// Parses an attribute declaration block enclosed in brackets «[…]». If readNextSymbol is + /// Parses an attribute declaration block enclosed in brackets «[…]». If readNextSymbol is /// set to true, the closing bracket will be read. /// void ParseAttributes(DocumentObject element, bool readNextSymbol) { - AssertSymbol(Symbol.BracketLeft); + EnsureSymbol(Symbol.BracketLeft); ReadCode(); // read beyond '[' while (Symbol == Symbol.Identifier) ParseAttributeStatement(element); - AssertSymbol(Symbol.BracketRight); + EnsureSymbol(Symbol.BracketRight); // Do not read ']' when parsing in paragraph content. if (readNextSymbol) @@ -1861,7 +1846,7 @@ void ParseAttributes(DocumentObject element, bool readNextSymbol) } /// - /// Parses an attribute declaration block enclosed in brackets «[…]». + /// Parses an attribute declaration block enclosed in brackets «[…]». /// void ParseAttributes(DocumentObject element) { @@ -1878,26 +1863,22 @@ void ParseAttributeStatement(DocumentObject? doc) // or // sequence of identifiers: xxx.yyy.zzz // - // followed by: «=», «+=», «-=», or «{» + // followed by: «=», «+=», «-=», or «{» // // Parser of rhs depends on the type of the l-value. if (doc == null) - throw new ArgumentNullException("doc"); + throw new ArgumentNullException(nameof(doc)); var valueName = ""; try { - valueName = _scanner.Token; + valueName = Token; ReadCode(); // Resolve path, if it exists. object? val; while (Symbol == Symbol.Dot) { -#if DEBUG_ - if (valueName == "TabStops") - valueName.GetType(); -#endif Debug.Assert(doc != null, "Make ReSharper happy."); val = doc.GetValue(valueName); if (val == null) @@ -1906,19 +1887,14 @@ void ParseAttributeStatement(DocumentObject? doc) val = documentObject.CreateValue(valueName); doc.SetValue(valueName, val); } - AssertCondition(val != null, DomMsgID.InvalidValueName, valueName); + EnsureCondition(val != null, () => MdDomMsgs.InvalidValueName(valueName)); doc = val as DocumentObject; - AssertCondition(doc != null, DomMsgID.SymbolIsNotAnObject, valueName); + EnsureCondition(doc != null, () => MdDomMsgs.SymbolIsNotAnObject(valueName)); ReadCode(); - AssertCondition(Symbol == Symbol.Identifier, DomMsgID.InvalidValueName, _scanner.Token); - valueName = _scanner.Token; - AssertCondition(valueName[0] != '_', DomMsgID.NoAccess, _scanner.Token); - -#if DEBUG_ - if (valueName == "TabStops") - valueName.GetType(); -#endif + EnsureCondition(Symbol == Symbol.Identifier, () => MdDomMsgs.InvalidValueName(Token)); + valueName = Token; + EnsureCondition(valueName[0] != '_', () => MdDomMsgs.NoAccess(Token)); ReadCode(); } @@ -1927,64 +1903,61 @@ void ParseAttributeStatement(DocumentObject? doc) switch (Symbol) { case Symbol.Assign: - //DomValueDescriptor is needed from assignment routine. + // DomValueDescriptor is needed from assignment routine. var pvd = doc.Meta[valueName]; - AssertCondition(pvd != null, DomMsgID.InvalidValueName, valueName); + EnsureCondition(pvd != null, () => MdDomMsgs.InvalidValueName(valueName)); ParseAssign(doc, pvd); break; case Symbol.PlusAssign: case Symbol.MinusAssign: // Hard-coded for TabStops only... - if (!(doc is ParagraphFormat)) - ThrowParserException(DomMsgID.SymbolNotAllowed, _scanner.Token); + if (doc is not ParagraphFormat) + ThrowParserException(MdDomMsgs.SymbolNotAllowed(Token)); if (String.Compare(valueName, "TabStops", StringComparison.OrdinalIgnoreCase) != 0) - ThrowParserException(DomMsgID.InvalidValueForOperation, valueName, _scanner.Token); + ThrowParserException(MdDomMsgs.InvalidValueForOperation(valueName, Token)); ParagraphFormat paragraphFormat = (ParagraphFormat)doc; TabStops tabStops = paragraphFormat.TabStops; - if (true) // HACK in ParseAttributeStatement // BUG THHO4STLA Already existed in 2019. + bool fAddItem = Symbol == Symbol.PlusAssign; + var tabStop = new TabStop(); + + ReadCode(); + + if (Symbol == Symbol.BraceLeft) { - bool fAddItem = Symbol == Symbol.PlusAssign; - TabStop tabStop = new TabStop(); + ParseAttributeBlock(tabStop); + } + else if (Symbol is Symbol.StringLiteral or Symbol.RealLiteral or Symbol.IntegerLiteral) + { + // Special hack for tab stops... + Unit unit = Token; + tabStop.SetValue("Position", unit); ReadCode(); - - if (Symbol == Symbol.BraceLeft) - { - ParseAttributeBlock(tabStop); - } - else if (Symbol == Symbol.StringLiteral || Symbol == Symbol.RealLiteral || Symbol == Symbol.IntegerLiteral) - { - // Special hack for tab stops... - Unit unit = Token; - tabStop.SetValue("Position", unit); - - ReadCode(); - } - else - ThrowParserException(DomMsgID.UnexpectedSymbol, Token); - - if (fAddItem) - tabStops.AddTabStop(tabStop); - else - tabStops.RemoveTabStop(tabStop.Position); } + else + ThrowParserException(MdDomMsgs.UnexpectedSymbol(Token)); + + if (fAddItem) + tabStops.AddTabStop(tabStop); + else + tabStops.RemoveTabStop(tabStop.Position); break; case Symbol.BraceLeft: val = doc.GetValue(valueName); - AssertCondition(val != null, DomMsgID.InvalidValueName, valueName); + EnsureCondition(val != null, () => MdDomMsgs.InvalidValueName(valueName)); if (val is DocumentObject doc2) ParseAttributeBlock(doc2); else - ThrowParserException(DomMsgID.SymbolIsNotAnObject, valueName); + ThrowParserException(MdDomMsgs.SymbolIsNotAnObject(valueName)); break; default: - ThrowParserException(DomMsgID.SymbolNotAllowed, _scanner.Token); + ThrowParserException(MdDomMsgs.SymbolNotAllowed(Token)); return; } } @@ -1993,26 +1966,26 @@ void ParseAttributeStatement(DocumentObject? doc) ReportParserException(ex); AdjustToNextBlock(); } - catch (ArgumentException e) + catch (ArgumentException ex) { - ReportParserException(e, DomMsgID.InvalidAssignment, valueName); + ReportParserException(MdDomMsgs.InvalidAssignment(valueName), ex); } } /// - /// Parses an attribute declaration block enclosed in braces «{…}». + /// Parses an attribute declaration block enclosed in braces «{…}». /// void ParseAttributeBlock(DocumentObject element) { // Technically the same as ParseAttributes - AssertSymbol(Symbol.BraceLeft); + EnsureSymbol(Symbol.BraceLeft); ReadCode(); // move beyond '{' while (Symbol == Symbol.Identifier) ParseAttributeStatement(element); - AssertSymbol(Symbol.BraceRight); + EnsureSymbol(Symbol.BraceRight); ReadCode(); // move beyond '}' } @@ -2033,7 +2006,7 @@ void ParseAssign(DocumentObject dom, ValueDescriptor vd) try { - // BUG ReviewSTLA + // BUG_OLD ReviewSTLA if (valType == typeof(string)) ParseStringAssignment(dom, vd); else if (valType == typeof(int)) @@ -2055,12 +2028,12 @@ void ParseAssign(DocumentObject dom, ValueDescriptor vd) else { AdjustToNextStatement(); - ThrowParserException(DomMsgID.InvalidType, vd.ValueType.Name, vd.ValueName); + ThrowParserException(MdDomMsgs.InvalidType(vd.ValueType.Name, vd.ValueName)); } } catch (Exception ex) { - ReportParserException(ex, DomMsgID.InvalidAssignment, vd.ValueName); + ReportParserException(MdDomMsgs.InvalidAssignment(vd.ValueName), ex); } } @@ -2069,8 +2042,8 @@ void ParseAssign(DocumentObject dom, ValueDescriptor vd) /// void ParseBoolAssignment(DocumentObject dom, ValueDescriptor vd) { - AssertCondition(Symbol == Symbol.True || Symbol == Symbol.False, DomMsgID.BoolExpected, - _scanner.Token); + EnsureCondition(Symbol is Symbol.True or Symbol.False, + () => MdDomMsgs.BoolValueExpected(Token)); dom.SetValue(vd.ValueName, Symbol == Symbol.True); ReadCode(); @@ -2081,10 +2054,10 @@ void ParseBoolAssignment(DocumentObject dom, ValueDescriptor vd) /// void ParseIntegerAssignment(DocumentObject dom, ValueDescriptor vd) { - AssertCondition(Symbol == Symbol.IntegerLiteral || Symbol == Symbol.HexIntegerLiteral || Symbol == Symbol.StringLiteral, - DomMsgID.IntegerExpected, Token); + EnsureCondition(Symbol is Symbol.IntegerLiteral or Symbol.HexIntegerLiteral or Symbol.StringLiteral, + () => MdDomMsgs.IntegerValueExpected(Token)); - int n = Int32.Parse(_scanner.Token, CultureInfo.InvariantCulture); + int n = Int32.Parse(Token, CultureInfo.InvariantCulture); dom.SetValue(vd.ValueName, n); ReadCode(); @@ -2095,10 +2068,10 @@ void ParseIntegerAssignment(DocumentObject dom, ValueDescriptor vd) /// void ParseRealAssignment(DocumentObject dom, ValueDescriptor vd) { - AssertCondition(Symbol == Symbol.RealLiteral || Symbol == Symbol.IntegerLiteral || Symbol == Symbol.StringLiteral, - DomMsgID.RealExpected, _scanner.Token); + EnsureCondition(Symbol is Symbol.RealLiteral or Symbol.IntegerLiteral or Symbol.StringLiteral, + () => MdDomMsgs.RealValueExpected(Token)); - double r = double.Parse(_scanner.Token, CultureInfo.InvariantCulture); + double r = double.Parse(Token, CultureInfo.InvariantCulture); dom.SetValue(vd.ValueName, r); ReadCode(); @@ -2109,8 +2082,8 @@ void ParseRealAssignment(DocumentObject dom, ValueDescriptor vd) /// void ParseUnitAssignment(DocumentObject dom, ValueDescriptor vd) { - AssertCondition(Symbol == Symbol.RealLiteral || Symbol == Symbol.IntegerLiteral || Symbol == Symbol.StringLiteral, - DomMsgID.RealExpected, _scanner.Token); + EnsureCondition(Symbol is Symbol.RealLiteral or Symbol.IntegerLiteral or Symbol.StringLiteral, + () => MdDomMsgs.RealValueExpected(Token)); Unit unit = Token; dom.SetValue(vd.ValueName, unit); @@ -2122,7 +2095,7 @@ void ParseUnitAssignment(DocumentObject dom, ValueDescriptor vd) /// void ParseStringAssignment(DocumentObject dom, ValueDescriptor vd) { - AssertCondition(Symbol == Symbol.StringLiteral, DomMsgID.StringExpected, _scanner.Token); + EnsureCondition(Symbol == Symbol.StringLiteral, () => MdDomMsgs.StringValueExpected(_scanner.Token)); vd.SetValue(dom, Token); //dom.SetValue(vd.ValueName, scanner.Token); @@ -2134,7 +2107,7 @@ void ParseStringAssignment(DocumentObject dom, ValueDescriptor vd) /// void ParseEnumAssignment(DocumentObject dom, ValueDescriptor vd) { - AssertSymbol(Symbol.Identifier, DomMsgID.IdentifierExpected, _scanner.Token); + EnsureSymbol(Symbol.Identifier, () => MdDomMsgs.IdentifierExpected(Token)); try { @@ -2143,7 +2116,7 @@ void ParseEnumAssignment(DocumentObject dom, ValueDescriptor vd) } catch (Exception ex) { - ThrowParserException(ex, DomMsgID.InvalidEnum, _scanner.Token, vd.ValueName); + ThrowParserException(MdDomMsgs.InvalidEnum(Token, vd.ValueName), ex); } ReadCode(); // read next token @@ -2164,7 +2137,7 @@ void ParseValueTypeAssignment(DocumentObject dom, ValueDescriptor vd) } catch (Exception ex) { - ReportParserException(ex, DomMsgID.InvalidAssignment, vd.ValueName); + ReportParserException(MdDomMsgs.InvalidAssignment(vd.ValueName), ex); } } @@ -2192,7 +2165,7 @@ void ParseDocumentObjectAssignment(DocumentObject dom, ValueDescriptor vd) else if (typeof(TabStops) == type) (val as TabStops)?.ClearAll(); else - ThrowParserException(DomMsgID.NullAssignmentNotSupported, vd.ValueName); + ThrowParserException(MdDomMsgs.NullAssignmentNotSupported(vd.ValueName)); ReadCode(); } @@ -2204,7 +2177,7 @@ void ParseDocumentObjectAssignment(DocumentObject dom, ValueDescriptor vd) } catch (Exception ex) { - ReportParserException(ex, DomMsgID.InvalidAssignment, vd.ValueName); + ReportParserException(MdDomMsgs.InvalidAssignment(vd.ValueName), ex); } } @@ -2220,7 +2193,7 @@ void ParseValueAssignment(DocumentObject dom, ValueDescriptor vd) } catch (Exception ex) { - ThrowParserException(ex, DomMsgID.InvalidEnum, _scanner.Token, vd.ValueName); + ThrowParserException(MdDomMsgs.InvalidEnum(Token, vd.ValueName), ex); } ReadCode(); // read next token @@ -2231,14 +2204,14 @@ void ParseValueAssignment(DocumentObject dom, ValueDescriptor vd) /// void ParseColorAssignment(DocumentObject dom, ValueDescriptor vd) { - var val = vd.GetValue(dom, GV.ReadWrite); + var _ = vd.GetValue(dom, GV.ReadWrite); var color = ParseColor(); dom.SetValue(vd.ValueName, color); } /// - /// Parses a color. It can be «green», «123456», «0xFFABCDEF», - /// «RGB(r, g, b)», «CMYK(c, m, y, k)», «CMYK(a, c, m, y, k)», «GRAY(g)», or «"MyColor"». + /// Parses a color. It can be «green», «123456», «0xFFABCDEF», + /// «RGB(r, g, b)», «CMYK(c, m, y, k)», «CMYK(a, c, m, y, k)», «GRAY(g)», or «"MyColor"». /// Color ParseColor() { @@ -2274,12 +2247,12 @@ Color ParseColor() } catch (Exception ex) { - ThrowParserException(ex, DomMsgID.InvalidColor, _scanner.Token); + ThrowParserException(MdDomMsgs.InvalidColor(Token), ex); } break; } } - else if (Symbol == Symbol.IntegerLiteral || Symbol == Symbol.HexIntegerLiteral) + else if (Symbol is Symbol.IntegerLiteral or Symbol.HexIntegerLiteral) { color = new Color(_scanner.GetTokenValueAsUInt()); ReadCode(); // read beyond literal @@ -2289,46 +2262,45 @@ Color ParseColor() throw new NotImplementedException("ParseColor(color-name)"); } else - ThrowParserException(DomMsgID.StringExpected, _scanner.Token); + ThrowParserException(MdDomMsgs.StringValueExpected(Token)); return color; } /// - /// Parses «RGB(r, g, b)». + /// Parses «RGB(r, g, b)». /// // ReSharper disable once InconsistentNaming Color ParseRGB() { - uint r, g, b; ReadCode(); // read '(' - AssertSymbol(Symbol.ParenLeft); + EnsureSymbol(Symbol.ParenLeft); ReadCode(); // read red value - AssertCondition(Symbol == Symbol.IntegerLiteral || Symbol == Symbol.HexIntegerLiteral, - DomMsgID.IntegerExpected, _scanner.Token); - r = _scanner.GetTokenValueAsUInt(); - AssertCondition(r >= 0 && r <= 255, DomMsgID.InvalidRange, "0 - 255"); + EnsureCondition(Symbol is Symbol.IntegerLiteral or Symbol.HexIntegerLiteral, + () => MdDomMsgs.IntegerValueExpected(Token)); + var r = _scanner.GetTokenValueAsUInt(); + EnsureCondition(r is >= 0 and <= 255, () => MdDomMsgs.InvalidRange("0 - 255")); ReadCode(); // read ',' - AssertSymbol(Symbol.Comma); + EnsureSymbol(Symbol.Comma); ReadCode(); // read green value - AssertCondition(Symbol == Symbol.IntegerLiteral || Symbol == Symbol.HexIntegerLiteral, - DomMsgID.IntegerExpected, _scanner.Token); - g = _scanner.GetTokenValueAsUInt(); - AssertCondition(g is >= 0 and <= 255, DomMsgID.InvalidRange, "0 - 255"); + EnsureCondition(Symbol is Symbol.IntegerLiteral or Symbol.HexIntegerLiteral, + () => MdDomMsgs.IntegerValueExpected(Token)); + var g = _scanner.GetTokenValueAsUInt(); + EnsureCondition(g is >= 0 and <= 255, () => MdDomMsgs.InvalidRange("0 - 255")); ReadCode(); // read ',' - AssertSymbol(Symbol.Comma); + EnsureSymbol(Symbol.Comma); ReadCode(); // read blue value - AssertCondition(Symbol == Symbol.IntegerLiteral || Symbol == Symbol.HexIntegerLiteral, - DomMsgID.IntegerExpected, _scanner.Token); - b = _scanner.GetTokenValueAsUInt(); - AssertCondition(b is >= 0 and <= 255, DomMsgID.InvalidRange, "0 - 255"); + EnsureCondition(Symbol is Symbol.IntegerLiteral or Symbol.HexIntegerLiteral, + () => MdDomMsgs.IntegerValueExpected(Token)); + var b = _scanner.GetTokenValueAsUInt(); + EnsureCondition(b is >= 0 and <= 255, () => MdDomMsgs.InvalidRange("0 - 255")); ReadCode(); // read ')' - AssertSymbol(Symbol.ParenRight); + EnsureSymbol(Symbol.ParenRight); ReadCode(); // read next token @@ -2336,45 +2308,46 @@ Color ParseRGB() } /// - /// Parses «CMYK(c, m, y, k)» or «CMYK(a, c, m, y, k)». + /// Parses «CMYK(c, m, y, k)» or «CMYK(a, c, m, y, k)». /// + // ReSharper disable once InconsistentNaming Color ParseCMYK() { ReadCode(); // read '(' - AssertSymbol(Symbol.ParenLeft); + EnsureSymbol(Symbol.ParenLeft); ReadCode(); // read v1 value - AssertCondition(Symbol == Symbol.IntegerLiteral || Symbol == Symbol.RealLiteral, - DomMsgID.NumberExpected, _scanner.Token); + EnsureCondition(Symbol is Symbol.IntegerLiteral or Symbol.RealLiteral, + () => MdDomMsgs.NumberValueExpected(Token)); double v1 = _scanner.GetTokenValueAsReal(); - AssertCondition(v1 >= 0.0f && v1 <= 100.0f, DomMsgID.InvalidRange, "0.0 - 100.0"); + EnsureCondition(v1 is >= 0 and <= 100, () => MdDomMsgs.InvalidRange("0..100")); ReadCode(); // read ',' - AssertSymbol(Symbol.Comma); + EnsureSymbol(Symbol.Comma); ReadCode(); // read v2 value - AssertCondition(Symbol == Symbol.IntegerLiteral || Symbol == Symbol.RealLiteral, - DomMsgID.NumberExpected, _scanner.Token); + EnsureCondition(Symbol is Symbol.IntegerLiteral or Symbol.RealLiteral, + () => MdDomMsgs.NumberValueExpected(Token)); double v2 = _scanner.GetTokenValueAsReal(); - AssertCondition(v2 >= 0.0f && v2 <= 100.0f, DomMsgID.InvalidRange, "0.0 - 100.0"); + EnsureCondition(v2 is >= 0 and <= 100, () => MdDomMsgs.InvalidRange("0..100")); ReadCode(); // read ',' - AssertSymbol(Symbol.Comma); + EnsureSymbol(Symbol.Comma); ReadCode(); // read v3 value - AssertCondition(Symbol == Symbol.IntegerLiteral || Symbol == Symbol.RealLiteral, - DomMsgID.NumberExpected, _scanner.Token); + EnsureCondition(Symbol is Symbol.IntegerLiteral or Symbol.RealLiteral, + () => MdDomMsgs.NumberValueExpected(Token)); double v3 = _scanner.GetTokenValueAsReal(); - AssertCondition(v3 >= 0.0f && v3 <= 100.0f, DomMsgID.InvalidRange, "0.0 - 100.0"); + EnsureCondition(v3 is >= 0 and <= 100, () => MdDomMsgs.InvalidRange("0..100")); ReadCode(); // read ',' - AssertSymbol(Symbol.Comma); + EnsureSymbol(Symbol.Comma); ReadCode(); // read v4 value - AssertCondition(Symbol == Symbol.IntegerLiteral || Symbol == Symbol.RealLiteral, - DomMsgID.NumberExpected, _scanner.Token); + EnsureCondition(Symbol is Symbol.IntegerLiteral or Symbol.RealLiteral, + () => MdDomMsgs.NumberValueExpected(Token)); double v4 = _scanner.GetTokenValueAsReal(); - AssertCondition(v4 >= 0.0f && v4 <= 100.0, DomMsgID.InvalidRange, "0.0 - 100.0"); + EnsureCondition(v4 is >= 0 and <= 100, () => MdDomMsgs.InvalidRange("0..100")); ReadCode(); // read ')' or ',' bool hasAlpha = false; @@ -2383,14 +2356,14 @@ Color ParseCMYK() { hasAlpha = true; ReadCode(); // read v5 value - AssertCondition(Symbol == Symbol.IntegerLiteral || Symbol == Symbol.RealLiteral, - DomMsgID.NumberExpected, _scanner.Token); + EnsureCondition(Symbol is Symbol.IntegerLiteral or Symbol.RealLiteral, + () => MdDomMsgs.NumberValueExpected(Token)); v5 = _scanner.GetTokenValueAsReal(); - AssertCondition(v5 >= 0.0f && v5 <= 100.0, DomMsgID.InvalidRange, "0.0 - 100.0"); + EnsureCondition(v5 is >= 0 and <= 100, () => MdDomMsgs.InvalidRange("0..100")); ReadCode(); // read ')' } - AssertSymbol(Symbol.ParenRight); + EnsureSymbol(Symbol.ParenRight); ReadCode(); // read next token @@ -2401,51 +2374,49 @@ Color ParseCMYK() } else { - a = 100.0; c = v1; m = v2; y = v3; k = v4; + a = 100; c = v1; m = v2; y = v3; k = v4; } return Color.FromCmyk(a, c, m, y, k); } /// - /// Parses «GRAY(g)». + /// Parses «GRAY(g)». /// Color ParseGray() { ReadCode(); // read '(' - AssertSymbol(Symbol.ParenLeft); + EnsureSymbol(Symbol.ParenLeft); ReadCode(); // read gray value - AssertCondition(Symbol == Symbol.IntegerLiteral || Symbol == Symbol.HexIntegerLiteral, - DomMsgID.IntegerExpected, _scanner.Token); + EnsureCondition(Symbol is Symbol.IntegerLiteral or Symbol.HexIntegerLiteral, + () => MdDomMsgs.IntegerValueExpected(Token)); double gray = _scanner.GetTokenValueAsReal(); - AssertCondition(gray >= 0.0f && gray <= 100.0f, DomMsgID.InvalidRange, "0.0 - 100.0"); + EnsureCondition(gray is >= 0 and <= 100, () => MdDomMsgs.InvalidRange("0..100")); ReadCode(); // read ')' - AssertSymbol(Symbol.ParenRight); + EnsureSymbol(Symbol.ParenRight); ReadCode(); // read next token - uint g = (uint)((1 - gray / 100.0) * 255 + 0.5); + uint g = (uint)((1 - gray / 100) * 255 + 0.5); return new Color(0xff000000 + (g << 16) + (g << 8) + g); } /// /// Determines the name/text of the given symbol. /// - string GetSymbolText(Symbol docSym) - { - return KeyWords.NameFromSymbol(docSym); - } + static string GetSymbolText(Symbol docSym) + => KeyWords.NameFromSymbol(docSym); /// /// Returns whether the specified type is a valid SpaceType. /// - bool IsSpaceType(string type) + static bool IsSpaceType(string type) { if (type == null) throw new ArgumentNullException(nameof(type)); if (type == "") - throw new ArgumentException("type"); + throw new ArgumentException("Type is empty.", nameof(type)); if (Enum.IsDefined(typeof(SymbolName), type)) { @@ -2460,19 +2431,18 @@ bool IsSpaceType(string type) return true; } } - return false; } /// /// Returns whether the specified type is a valid enum for \symbol. /// - bool IsSymbolType(string type) + static bool IsSymbolType(string type) { if (type == null) - throw new ArgumentNullException("type"); + throw new ArgumentNullException(nameof(type)); if (type == "") - throw new ArgumentException("type"); + throw new ArgumentException("Type is empty.", nameof(type)); if (Enum.IsDefined(typeof(SymbolName), type)) { @@ -2492,91 +2462,79 @@ bool IsSymbolType(string type) return true; } } - return false; } /// /// If cond is evaluated to false, a DdlParserException with the specified error will be thrown. /// - void AssertCondition( -#if NET6_0_OR_GREATER - [DoesNotReturnIf(false)] -#endif - bool cond, DomMsgID error, params object[] args) + void EnsureCondition([DoesNotReturnIf(false)] bool cond, Func func) { if (!cond) - ThrowParserException(error, args); + ThrowParserException(func()); } /// /// If current symbol is not equal symbol a DdlParserException will be thrown. /// - void AssertSymbol(Symbol symbol) + void EnsureSymbol(Symbol symbol) { if (Symbol != symbol) - ThrowParserException(DomMsgID.SymbolExpected, KeyWords.NameFromSymbol(symbol), Token); + ThrowParserException(MdDomMsgs.SymbolExpected(KeyWords.NameFromSymbol(symbol), Token)); } /// - /// If current symbol is not equal symbol a DdlParserException with the specified message id + /// If current symbol is not equal symbol a DdlParserException with the specified message ID /// will be thrown. /// - void AssertSymbol(Symbol symbol, DomMsgID err) + void EnsureSymbol(Symbol symbol, Func func) { if (Symbol != symbol) - ThrowParserException(err, KeyWords.NameFromSymbol(symbol), Token); + { + var domMsg = func(); + //ThrowParserException(err, KeyWords.NameFromSymbol(symbol), Token); + ThrowParserException(domMsg); + } } - /// - /// If current symbol is not equal symbol a DdlParserException with the specified message id - /// will be thrown. - /// - void AssertSymbol(Symbol symbol, DomMsgID err, params object[] parms) - { - if (Symbol != symbol) - ThrowParserException(err, KeyWords.NameFromSymbol(symbol), parms); - } + ///// + ///// If current symbol is not equal symbol a DdlParserException with the specified message ID + ///// will be thrown. + ///// + //void EnsureSymbol(Symbol symbol, DomMsgID err, params object[] parms) + //{ + // if (Symbol != symbol) + // ThrowParserException(err, KeyWords.NameFromSymbol(symbol), parms); + //} /// /// Creates an ErrorInfo based on the given errorlevel, error and parms and adds it to the ErrorManager2. /// - void ReportParserInfo(DdlErrorLevel level, DomMsgID errorCode, params string[] parms) + void ReportParserInfo(DdlErrorLevel level, MdDomMsg domMsg) { - string message = DomSR.FormatMessage(errorCode, parms); - var error = new DdlReaderError(level, message, (int)errorCode, + var error = new DdlReaderError(level, domMsg, _scanner.DocumentFileName, _scanner.CurrentLine, _scanner.CurrentLinePos); _errors.AddError(error); } - /// - /// Creates an ErrorInfo based on the given error and parms and adds it to the ErrorManager2. - /// - void ReportParserException(DomMsgID error, params string[] parms) - { - ReportParserException(null, error, parms); - } - /// /// Adds the ErrorInfo from the ErrorInfoException2 to the ErrorManager2. /// void ReportParserException(DdlParserException ex) - { - _errors.AddError(ex.Error); - } + => _errors.AddError(ex.Error); /// /// Creates an ErrorInfo based on the given inner exception, error, and parms and adds it to the ErrorManager2. /// - void ReportParserException(Exception? innerException, DomMsgID errorCode, params string[] parms) + void ReportParserException(MdDomMsg domMsg, Exception? innerException = null) { - var message = ""; + var message = domMsg.Message; if (innerException != null) - message = ": " + innerException; + message = " Inner exception: " + innerException; - message += DomSR.FormatMessage(errorCode, parms); - var error = new DdlReaderError(DdlErrorLevel.Error, message, (int)errorCode, + //message += DomSR.FormatMessage(errorCode, parms); + var error = new DdlReaderError(DdlErrorLevel.Error, message, (int)domMsg.Id, _scanner.DocumentFileName, _scanner.CurrentLine, _scanner.CurrentLinePos); _errors.AddError(error); @@ -2586,29 +2544,17 @@ void ReportParserException(Exception? innerException, DomMsgID errorCode, params /// Creates an ErrorInfo based on the DomMsgID and the specified parameters. /// Throws a DdlParserException with that ErrorInfo. /// -#if NET6_0_OR_GREATER [DoesNotReturn] -#endif - void ThrowParserException(DomMsgID errorCode, params object[] parms) + void ThrowParserException(MdDomMsg domMsg, Exception? innerException = null) { - var message = DomSR.FormatMessage(errorCode, parms); - var error = new DdlReaderError(DdlErrorLevel.Error, message, (int)errorCode, - _scanner.DocumentFileName, _scanner.CurrentLine, _scanner.CurrentLinePos); + var message = domMsg.Message; + if (innerException != null) + message = " Inner exception: " + innerException; - throw new DdlParserException(error); - } + var error = new DdlReaderError(DdlErrorLevel.Error, message, (int)domMsg.Id, + _scanner.DocumentFileName, _scanner.CurrentLine, _scanner.CurrentLinePos); - /// - /// Determines the error message based on the DomMsgID and the parameters. - /// Throws a DdlParserException with that error message and the Exception as the inner exception. - /// -#if NET6_0_OR_GREATER - [DoesNotReturn] -#endif - void ThrowParserException(Exception innerException, DomMsgID errorCode, params object[] parms) - { - var message = DomSR.FormatMessage(errorCode, parms); - throw new DdlParserException(message, innerException); + throw new DdlParserException(error, innerException); } /// @@ -2638,7 +2584,7 @@ void AdjustToNextBlock() break; case Symbol.Eof: - ThrowParserException(DomMsgID.UnexpectedEndOfFile); + ThrowParserException(MdDomMsgs.UnexpectedEndOfFile); break; default: @@ -2660,7 +2606,7 @@ void AdjustToNextStatement() switch (Symbol) { case Symbol.Assign: - //read one more symbol + // Read one more symbol. ReadCode(); break; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlParserException.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlParserException.cs index 79bc5b95..9d18e836 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlParserException.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlParserException.cs @@ -4,45 +4,45 @@ namespace MigraDoc.DocumentObjectModel.IO { /// - /// Represents an exception used by the DDL parser. This exception will always be caught inside - /// the DDL parser. + /// Represents an exception issued by the DDL parser. + /// This exception will always be caught inside the DDL parser. /// - class DdlParserException : Exception + sealed class DdlParserException : Exception { - /// - /// Initializes a new instance of the DdlParserException class with the specified message. - /// - public DdlParserException(string message) - : base(message) - { - Error = new DdlReaderError(DdlErrorLevel.Error, message, 0); - } + ///// + ///// Initializes a new instance of the DdlParserException class with the specified message. + ///// + //public DdlParserException(MdDomMsg domMsg) + // : base(domMsg.Message) + //{ + // Error = new DdlReaderError(DdlErrorLevel.Error, domMsg); + //} /// /// Initializes a new instance of the DdlParserException class with the specified message and the /// inner exception. /// - public DdlParserException(string message, Exception innerException) - : base(message, innerException) + public DdlParserException(MdDomMsg domMsg, Exception? innerException = null) + : base(domMsg.Message, innerException) { - Error = new DdlReaderError(DdlErrorLevel.Error, message, 0); + Error = new DdlReaderError(DdlErrorLevel.Error, domMsg); } - /// - /// Initializes a new instance of the DdlParserException class with the specified error level, name, - /// error code and message. - /// - public DdlParserException(DdlErrorLevel level, string message, DomMsgID errorCode) - : base(message) - { - Error = new DdlReaderError(level, message, (int)errorCode); - } + ///// + ///// Initializes a new instance of the DdlParserException class with the specified error level, name, + ///// error code and message. + ///// + //public DdlParserException(DdlErrorLevel level, string message, DomMsgId errorCode) + // : base(message) + //{ + // Error = new DdlReaderError(level, message, (int)errorCode); + //} /// /// Initializes a new instance of the DdlParserException class with the DdlReaderError. /// - public DdlParserException(DdlReaderError error) - : base(error.ErrorMessage) + public DdlParserException(DdlReaderError error, Exception? innerException = null) + : base(error.ErrorMessage, innerException) { Error = error; } diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReader.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReader.cs index 77ec3d7a..fbe203c3 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReader.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReader.cs @@ -126,8 +126,7 @@ public static Document DocumentFromFile(string documentFileName) //, ErrorManage } finally { - if (reader != null) - reader.Close(); + reader?.Close(); } return document; } @@ -164,7 +163,7 @@ public static Document DocumentFromString(string ddl) DocumentObject? domObj; try { - reader = new DdlReader(documentFileName, errors); + reader = new(documentFileName, errors); domObj = reader.ReadObject(); } finally @@ -177,14 +176,15 @@ public static Document DocumentFromString(string ddl) /// /// Reads and returns a domain object from the specified file. /// - public static DocumentObject? ObjectFromFile(string documentFileName) + public static DocumentObject? ObjectFromFile(string documentFileName) => ObjectFromFile(documentFileName, null); /// /// Reads and returns a domain object from the specified DDL string. /// - public static DocumentObject? ObjectFromString(string ddl, DdlReaderErrors? errors) + public static DocumentObject? ObjectFromString(string ddl, DdlReaderErrors? errors = null) { + _ = errors; StringReader? stringReader = null; DocumentObject? domObj; DdlReader? reader = null; @@ -198,18 +198,11 @@ public static Document DocumentFromString(string ddl) finally { stringReader?.Close(); - reader?.Close(); } return domObj; } - /// - /// Reads and returns a domain object from the specified DDL string. - /// - public static DocumentObject? ObjectFromString(string ddl) - => ObjectFromString(ddl, null); - readonly bool _doClose = true; TextReader? _reader; readonly DdlReaderErrors? _errorManager; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReaderError.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReaderError.cs index 66ec31ec..3771169d 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReaderError.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReaderError.cs @@ -6,62 +6,43 @@ namespace MigraDoc.DocumentObjectModel.IO /// /// Represents an error or diagnostic message reported by the DDL reader. /// + // Better name would be DdlReaderProblemDetails. But this class name + // is public. Therefore, we stay with it. public class DdlReaderError { /// /// Initializes a new instance of the DdlReaderError class. /// - public DdlReaderError(DdlErrorLevel errorLevel, string errorMessage, int errorNumber, - string sourceFile, int sourceLine, int sourceColumn) + internal DdlReaderError(DdlErrorLevel level, MdDomMsg domMsg, + string sourceFile = "", int sourceLine = 0, int sourceColumn = 0) { - ErrorLevel = errorLevel; - ErrorMessage = errorMessage; - ErrorNumber = errorNumber; + ErrorLevel = level; + ErrorMessage = domMsg.Message; + ErrorNumber = (int)domMsg.Id; SourceFile = sourceFile; SourceLine = sourceLine; SourceColumn = sourceColumn; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the DdlReaderError class. /// - public DdlReaderError(DdlErrorLevel errorLevel, string errorMessage, int errorNumber) + public DdlReaderError(DdlErrorLevel errorLevel, string errorMessage, int errorNumber, + string sourceFile, int sourceLine, int sourceColumn) { ErrorLevel = errorLevel; ErrorMessage = errorMessage; ErrorNumber = errorNumber; - SourceFile = ""; + SourceFile = sourceFile; + SourceLine = sourceLine; + SourceColumn = sourceColumn; } - // public DdlReaderError(string errorName, DdlReaderError _level, DomMsgID _error, string message, string msg2, - // string DocumentFileName, int CurrentLine, int CurrentLinePos) - // { - // } - // - // public DdlReaderError(string errorName, int _level, string _error, string message, string adf, - // string DocumentFileName, int CurrentLine, int CurrentLinePos) - // { - // } - // - // public DdlReaderError(string errorName, DdlErrorLevel errorInfo , string _error, string message, string adf, - // string DocumentFileName, int CurrentLine, int CurrentLinePos) - // { - // } - // - // public DdlReaderError(string errorName, DdlErrorLevel errorInfo , DomMsgID _error, string message, string adf, - // string DocumentFileName, int CurrentLine, int CurrentLinePos) - // { - // } - - //public const int NoErrorNumber = -1; - /// - /// Returns a String that represents the current DdlReaderError. + /// Returns a string that represents the current DdlReaderError. /// - public override string ToString() - { - return $"[{SourceFile}({SourceLine},{SourceColumn}):] {"xxx"} DDL{ErrorNumber}: {ErrorMessage}"; - } + public override string ToString() + => $"[{SourceFile}({SourceLine},{SourceColumn}):] {"xxx"} DDL{ErrorNumber}: {ErrorMessage}"; /// /// Specifies the severity of this diagnostic. diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReaderErrors.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReaderErrors.cs index aeed3a56..a3409c79 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReaderErrors.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlReaderErrors.cs @@ -36,14 +36,11 @@ public int ErrorCount return count; } } - readonly List _errors = new(); + readonly List _errors = []; /// /// Returns an enumerator that iterates through the error collection. /// - public IEnumerator GetEnumerator() - { - return _errors.GetEnumerator(); - } + public IEnumerator GetEnumerator() => _errors.GetEnumerator(); } } diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlScanner.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlScanner.cs index 298fc54f..3a43d6c5 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlScanner.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlScanner.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. using System.Text; @@ -7,10 +7,10 @@ ddl = | table-element: - \table «attributes»opt { «columns-element» «rows-element» } + \table «attributes»opt { «columns-element» «rows-element» } table-element: - \table «attributes»opt { «columns-element» «rows-element» } + \table «attributes»opt { «columns-element» «rows-element» } */ namespace MigraDoc.DocumentObjectModel.IO @@ -25,20 +25,20 @@ sealed class DdlScanner /// internal DdlScanner(string documentFileName, string ddl, DdlReaderErrors errors) { - _errors = errors; + //_errors = errors; Not (yet?) used. - _documentPath = documentFileName; + DocumentPath = documentFileName; _strDocument = ddl; _ddlLength = _strDocument.Length; _idx = 0; _idxLine = 1; _idxLinePos = 0; - _documentFileName = documentFileName; + DocumentFileName = documentFileName; - _nCurDocumentIndex = _idx; - _nCurDocumentLine = _idxLine; - _nCurDocumentLinePos = _idxLinePos; + //_curDocumentIndex = _idx; Not (yet?) used. + CurrentLine = _idxLine; + CurrentLinePos = _idxLinePos; ScanNextChar(); } @@ -59,62 +59,62 @@ internal DdlScanner(string ddl, DdlReaderErrors errors) /// internal Symbol ReadCode() { - Again: - _symbol = Symbol.None; - _tokenType = TokenType.None; - _token = ""; + Again: + Symbol = Symbol.None; + TokenType = TokenType.None; + Token = ""; MoveToNonWhiteSpace(); SaveCurDocumentPos(); if (_currChar == Chars.Null) { - _symbol = Symbol.Eof; + Symbol = Symbol.Eof; return Symbol.Eof; } if (IsIdentifierChar(_currChar, true)) { // Token is identifier. - _symbol = ScanIdentifier(); - _tokenType = TokenType.Identifier; - // Some keywords do not start with a backslash: true, false, and null. - Symbol sym = KeyWords.SymbolFromName(_token); + Symbol = ScanIdentifier(); + TokenType = TokenType.Identifier; + // Some keywords do not start with a backslash: + // true, false, and null. + var sym = KeyWords.SymbolFromName(Token); if (sym != Symbol.None) { - _symbol = sym; - _tokenType = TokenType.KeyWord; + Symbol = sym; + TokenType = TokenType.KeyWord; } } else if (_currChar == '"') { // Token is string literal. - _token += ScanStringLiteral(); - _symbol = Symbol.StringLiteral; - _tokenType = TokenType.StringLiteral; + Token += ScanStringLiteral(); + Symbol = Symbol.StringLiteral; + TokenType = TokenType.StringLiteral; } - //NYI: else if (IsNumber()) + // NYI: else if (IsNumber()) // symbol = ScanNumber(false); else if (IsDigit(_currChar) || - _currChar == '-' && IsDigit(_nextChar) || - _currChar == '+' && IsDigit(_nextChar)) + _currChar is '-' or '+' && IsDigit(_nextChar)) { // Token is number literal. - _symbol = ScanNumber(false); - _tokenType = _symbol == Symbol.RealLiteral ? TokenType.RealLiteral : TokenType.IntegerLiteral; + Symbol = ScanNumber(false); + TokenType = Symbol == Symbol.RealLiteral ? TokenType.RealLiteral : TokenType.IntegerLiteral; } else if (_currChar == '.' && IsDigit(_nextChar)) { // Token is real literal. - _symbol = ScanNumber(true); - _tokenType = TokenType.RealLiteral; + Symbol = ScanNumber(true); + TokenType = TokenType.RealLiteral; } else if (_currChar == '\\') { // Token is keyword or escaped character. - _token = "\\"; - _symbol = ScanKeyword(); - _tokenType = _symbol != Symbol.None ? TokenType.KeyWord : TokenType.None; + Token = "\\"; + Symbol = ScanKeyword(); + TokenType = Symbol != Symbol.None ? TokenType.KeyWord : TokenType.None; } else if (_currChar == '/' && _nextChar == '/') { @@ -126,16 +126,16 @@ internal Symbol ReadCode() { // Token is verbatim string literal. ScanNextChar(); - _token += ScanVerbatimStringLiteral(); - _symbol = Symbol.StringLiteral; - _tokenType = _symbol != Symbol.None ? TokenType.StringLiteral : TokenType.None; + Token += ScanVerbatimStringLiteral(); + Symbol = Symbol.StringLiteral; + TokenType = Symbol != Symbol.None ? TokenType.StringLiteral : TokenType.None; } else { // Punctuator or syntax error. - _symbol = ScanPunctuator(); + Symbol = ScanPunctuator(); } - return _symbol; + return Symbol; } /// @@ -250,7 +250,7 @@ Symbol PeekPunctuation(int index) // sym = Symbol.Question; // break; - case '¤': + case '¤': sym = Symbol.Currency; //??? used in DDL? break; @@ -311,7 +311,7 @@ internal Symbol PeekSymbol() int idx = _idx - 1; int length = _ddlLength - idx; - // Move to first non whitespace + // Move to first non-white-space char ch = Char.MinValue; while (length > 0) { @@ -337,17 +337,17 @@ internal Symbol ReadText(bool rootLevel) if (_emptyLine) { _emptyLine = false; - _symbol = Symbol.EmptyLine; - _tokenType = TokenType.None; - _token = ""; + Symbol = Symbol.EmptyLine; + TokenType = TokenType.None; + Token = ""; return Symbol.EmptyLine; } // Init for scanning. - _prevSymbol = _symbol; - _symbol = Symbol.None; - _tokenType = TokenType.None; - _token = ""; + _prevSymbol = Symbol; + Symbol = Symbol.None; + TokenType = TokenType.None; + Token = ""; // Save where we are SaveCurDocumentPos(); @@ -355,7 +355,7 @@ internal Symbol ReadText(bool rootLevel) // Check for EOF. if (_currChar == Chars.Null) { - _symbol = Symbol.Eof; + Symbol = Symbol.Eof; return Symbol.Eof; } @@ -372,7 +372,7 @@ internal Symbol ReadText(bool rootLevel) return ReadPlainText(rootLevel); } // Either key word or syntax error. - _token = "\\"; + Token = "\\"; return ScanKeyword(); } @@ -381,14 +381,14 @@ internal Symbol ReadText(bool rootLevel) { case '{': AppendAndScanNextChar(); - _symbol = Symbol.BraceLeft; - _tokenType = TokenType.OperatorOrPunctuator; + Symbol = Symbol.BraceLeft; + TokenType = TokenType.OperatorOrPunctuator; return Symbol.BraceLeft; // Syntax error in any case. case '}': AppendAndScanNextChar(); - _symbol = Symbol.BraceRight; - _tokenType = TokenType.OperatorOrPunctuator; + Symbol = Symbol.BraceRight; + TokenType = TokenType.OperatorOrPunctuator; return Symbol.BraceRight; } @@ -399,10 +399,10 @@ internal Symbol ReadText(bool rootLevel) if (MoveToNextParagraphContentLine(rootLevel)) { // Paragraph continues in next line. Simulate the read of a blank to separate words. - _token = " "; + Token = " "; if (IgnoreLineBreak()) - _token = ""; - _symbol = Symbol.Text; + Token = ""; + Symbol = Symbol.Text; return Symbol.Text; } else @@ -410,15 +410,15 @@ internal Symbol ReadText(bool rootLevel) // Paragraph ends here. Return NewLine or BraceRight. if (_currChar != Chars.BraceRight) { - _symbol = Symbol.EmptyLine; - _tokenType = TokenType.None; //??? + Symbol = Symbol.EmptyLine; + TokenType = TokenType.None; //??? return Symbol.EmptyLine; } else { AppendAndScanNextChar(); - _symbol = Symbol.BraceRight; - _tokenType = TokenType.OperatorOrPunctuator; + Symbol = Symbol.BraceRight; + TokenType = TokenType.OperatorOrPunctuator; return Symbol.BraceRight; } } @@ -427,18 +427,15 @@ internal Symbol ReadText(bool rootLevel) } /// - /// Returns whether the linebreak should be ignored because the previous symbol is already a whitespace. + /// Returns whether the linebreak should be ignored because the previous symbol is already a white-space. /// bool IgnoreLineBreak() { - switch (_prevSymbol) + return _prevSymbol switch { - case Symbol.LineBreak: - case Symbol.Space: - case Symbol.Tab: - return true; - } - return false; + Symbol.LineBreak or Symbol.Space or Symbol.Tab => true, + _ => false + }; } /// @@ -475,6 +472,7 @@ Symbol ReadPlainText(bool rootLevel) loop = false; break; } + continue; } @@ -505,8 +503,8 @@ Symbol ReadPlainText(bool rootLevel) if (MoveToNextParagraphContentLine(rootLevel)) { // Paragraph continues in next line. Add a blank to separate words. - if (!_token.EndsWith(" ", StringComparison.Ordinal)) - _token += ' '; + if (!Token.EndsWith(" ", StringComparison.Ordinal)) + Token += ' '; continue; } else @@ -518,7 +516,7 @@ Symbol ReadPlainText(bool rootLevel) } } - ValidCharacter: + ValidCharacter: // Compress multiple blanks to one if (_currChar == ' ') { @@ -527,6 +525,7 @@ Symbol ReadPlainText(bool rootLevel) ScanNextChar(); continue; } + foundSpace = true; } else @@ -535,8 +534,8 @@ Symbol ReadPlainText(bool rootLevel) AppendAndScanNextChar(); } - _symbol = Symbol.Text; - _tokenType = TokenType.Text; + Symbol = Symbol.Text; + TokenType = TokenType.Text; return Symbol.Text; } @@ -545,9 +544,9 @@ Symbol ReadPlainText(bool rootLevel) /// internal Symbol MoveToCode() { - if (_symbol == Symbol.None || _symbol == Symbol.CR /*|| this .symbol == Symbol.comment*/) + if (Symbol is Symbol.None or Symbol.CR /*|| this .symbol == Symbol.comment*/) ReadCode(); - return _symbol; + return Symbol; } /// @@ -557,7 +556,7 @@ internal Symbol MoveToCode() /// internal bool MoveToParagraphContent() { - Again: + Again: MoveToNonWhiteSpace(); if (_currChar == Chars.Slash && _nextChar == Chars.Slash) { @@ -581,7 +580,7 @@ internal bool MoveToNextParagraphContentLine(bool rootLevel) ScanNextChar(); while (loop) { - // Scan to next EOL and ignore any white space. + // Scan to next EOL and ignore any white-space. MoveToNonWhiteSpaceOrEol(); switch (_currChar) { @@ -590,7 +589,7 @@ internal bool MoveToNextParagraphContentLine(bool rootLevel) break; case Chars.LF: - ScanNextChar(); // read beyond EOL + ScanNextChar(); // Read beyond EOL if (rootLevel) { // At nesting level 0 (root level) a new line ends the paragraph content. @@ -607,7 +606,7 @@ internal bool MoveToNextParagraphContentLine(bool rootLevel) return false; } - //TODO NiSc NYI + // TODO_OLD NiSc NYI //Check.NotImplemented("empty line at non-root level"); } break; @@ -637,9 +636,9 @@ internal bool MoveToNextParagraphContentLine(bool rootLevel) } /// - /// If the current character is not a white space, the function immediately returns it. - /// Otherwise, the DDL cursor is moved forward to the first non-white space or EOF. - /// White spaces are SPACE, HT, VT, CR, and LF.??? + /// If the current character is not a white-space, the function immediately returns it. + /// Otherwise, the DDL cursor is moved forward to the first non-white-space or EOF. + /// White-spaces are SPACE, HT, VT, CR, and LF.??? /// internal char MoveToNonWhiteSpaceOrEol() { @@ -661,9 +660,9 @@ internal char MoveToNonWhiteSpaceOrEol() } /// - /// If the current character is not a white space, the function immediately returns it. - /// Otherwise, the DDL cursor is moved forward to the first non-white space or EOF. - /// White spaces are SPACE, HT, VT, CR, and LF. + /// If the current character is not a white-space, the function immediately returns it. + /// Otherwise, the DDL cursor is moved forward to the first non-white-space or EOF. + /// White-spaces are SPACE, HT, VT, CR, and LF. /// internal char MoveToNonWhiteSpace() { @@ -706,7 +705,7 @@ internal Symbol ScanSingleLineComment() char ch = ScanNextChar(); while (ch != Chars.Null && ch != Chars.LF) { - _token += _currChar; + Token += _currChar; ch = ScanNextChar(); } ScanNextChar(); // read beyond EOL @@ -716,64 +715,57 @@ internal Symbol ScanSingleLineComment() /// /// Gets the current symbol. /// - internal Symbol Symbol => _symbol; + internal Symbol Symbol { get; private set; } = Symbol.None; /// /// Gets the current token type. /// - internal TokenType TokenType => _tokenType; + internal TokenType TokenType { get; private set; } = TokenType.None; /// /// Gets the current token. /// - internal string Token => _token; + internal string Token { get; private set; } = ""; /// /// Interpret current token as integer literal. /// - /// internal int GetTokenValueAsInt() { - if (_symbol == Symbol.IntegerLiteral) - return Int32.Parse(_token, CultureInfo.InvariantCulture); + if (Symbol == Symbol.IntegerLiteral) + return Int32.Parse(Token, CultureInfo.InvariantCulture); - if (_symbol == Symbol.HexIntegerLiteral) + if (Symbol == Symbol.HexIntegerLiteral) { - string number = _token.Substring(2); + string number = Token.Substring(2); return Int32.Parse(number, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture); } - //TODO NiSc Check? - //Check.Assert(false); + Debug.Assert(false, "Should not come here."); return 0; } /// /// Interpret current token as unsigned integer literal. /// - /// internal uint GetTokenValueAsUInt() { - if (_symbol == Symbol.IntegerLiteral) - return UInt32.Parse(_token, CultureInfo.InvariantCulture); + if (Symbol == Symbol.IntegerLiteral) + return UInt32.Parse(Token, CultureInfo.InvariantCulture); - if (_symbol == Symbol.HexIntegerLiteral) + if (Symbol == Symbol.HexIntegerLiteral) { - string number = _token.Substring(2); + string number = Token.Substring(2); return UInt32.Parse(number, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture); } - //TODO NiSc Check. - //Check.Assert(false); + Debug.Assert(false, "Should not come here."); return 0; } /// /// Interpret current token as real literal. /// - /// - internal double GetTokenValueAsReal() - { - return Double.Parse(_token, CultureInfo.InvariantCulture); - } + internal double GetTokenValueAsReal() + => Double.Parse(Token, CultureInfo.InvariantCulture); /// /// Gets the current character or EOF. @@ -797,7 +789,7 @@ internal char ScanNextChar() } else { - SkipChar: + SkipChar: _currChar = _strDocument[_idx++]; _nextChar = _ddlLength <= _idx ? Chars.Null : _strDocument[_idx]; @@ -809,7 +801,7 @@ internal char ScanNextChar() _idxLinePos = 0; break; - // ignore CR + // Ignore CR case Chars.CR: if (_nextChar == Chars.LF) { @@ -824,7 +816,7 @@ internal char ScanNextChar() break; case Chars.LF: - //NYI: Unix uses LF only + // NYI: Unix uses LF only _idxLine++; _idxLinePos = 0; break; @@ -847,7 +839,7 @@ internal void ScanToEol() /// internal char AppendAndScanNextChar() { - _token += _currChar; + Token += _currChar; return ScanNextChar(); } @@ -860,7 +852,7 @@ internal void AppendAndScanToEol() char ch = ScanNextChar(); while (ch != Chars.Null && ch != Chars.CR && ch != Chars.LF) { - _token += _currChar; + Token += _currChar; ch = ScanNextChar(); } } @@ -868,42 +860,30 @@ internal void AppendAndScanToEol() /// /// Is character in '0' ... '9'. /// - internal static bool IsDigit(char ch) - { - return Char.IsDigit(ch); - } + internal static bool IsDigit(char ch) + => Char.IsDigit(ch); /// /// Is character a hexadecimal digit. /// - internal static bool IsHexDigit(char ch) - { - return Char.IsDigit(ch) || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'); - } + internal static bool IsHexDigit(char ch) + => Char.IsDigit(ch) || ch is >= 'A' and <= 'F' || ch is >= 'a' and <= 'f'; /// /// Is character an octal digit. /// internal static bool IsOctDigit(char ch) - { - return Char.IsDigit(ch) && ch < '8'; - } + => Char.IsDigit(ch) && ch < '8'; /// /// Is character an alphabetic letter. /// - internal static bool IsLetter(char ch) - { - return Char.IsLetter(ch); - } + internal static bool IsLetter(char ch) => Char.IsLetter(ch); /// - /// Is character a white space. + /// Is character a white-space. /// - internal static bool IsWhiteSpace(char ch) - { - return Char.IsWhiteSpace(ch); - } + internal static bool IsWhiteSpace(char ch) => Char.IsWhiteSpace(ch); /// /// Is character an identifier character. First character can be letter or underscore, following @@ -920,10 +900,7 @@ internal static bool IsIdentifierChar(char ch, bool firstChar) //IsId..Char /// /// Is character the end of file character. /// - internal static bool IsEof(char ch) - { - return ch == Chars.Null; - } + internal static bool IsEof(char ch) => ch == Chars.Null; //internal bool IsNumber(); //internal bool IsFormat(); @@ -1030,14 +1007,13 @@ internal static bool IsHeaderFooterElement(Symbol symbol) if (IsParagraphElement(symbol)) return true; - // All document elements except pagebreak. + // All document elements except page break. if (IsDocumentElement(symbol)) { if (symbol == Symbol.PageBreak) return false; return true; } - return false; } @@ -1059,22 +1035,22 @@ internal static bool IsFootnoteElement(Symbol symbol) /// /// Gets the current filename of the document. /// - internal string DocumentFileName => _documentFileName; + internal string DocumentFileName { get; } /// /// Gets the current path of the document. /// - internal string DocumentPath => _documentPath; + internal string DocumentPath { get; } /// /// Gets the current scanner line in the document. /// - internal int CurrentLine => _nCurDocumentLine; + internal int CurrentLine { get; private set; } /// /// Gets the current scanner column in the document. /// - internal int CurrentLinePos => _nCurDocumentLinePos; + internal int CurrentLinePos { get; private set; } /// /// Scans an identifier. @@ -1094,7 +1070,7 @@ Symbol ScanIdentifier() Symbol ScanNumber(bool mantissa) { char ch = _currChar; - _token += _currChar; + Token += _currChar; ScanNextChar(); if (!mantissa && ch == '0' && (_currChar == 'x' || _currChar == 'X')) @@ -1122,7 +1098,7 @@ Symbol ScanNumber(bool mantissa) /// Symbol ReadHexNumber() { - _token = "0x"; + Token = "0x"; ScanNextChar(); while (_currChar != Chars.Null) { @@ -1147,17 +1123,17 @@ Symbol ScanKeyword() // \- is a soft hyphen == char(173). if (ch == '-') { - _token += "-"; + Token += "-"; ScanNextChar(); return Symbol.SoftHyphen; } - // \( is a short cut for symbol. + // \( is a shortcut for symbol. if (ch == '(') { - _token += "("; - _symbol = Symbol.Chr; - return Symbol.Chr; // Short cut for \chr( + Token += "("; + Symbol = Symbol.Chr; + return Symbol.Chr; // Shortcut for \chr( } #if false @@ -1169,12 +1145,11 @@ Symbol ScanKeyword() return Symbol.Chr; } #endif - while (!IsEof(ch) && IsIdentifierChar(ch, false)) ch = AppendAndScanNextChar(); - _symbol = KeyWords.SymbolFromName(_token); - return _symbol; + Symbol = KeyWords.SymbolFromName(Token); + return Symbol; } /// @@ -1245,7 +1220,7 @@ Symbol ScanPunctuator() // sym = Symbol.Question; // break; - case '¤': + case '¤': sym = Symbol.Currency; //??? used in DDL? break; @@ -1268,7 +1243,7 @@ Symbol ScanPunctuator() case '+': if (_nextChar == '=') { - _token += _currChar; + Token += _currChar; ScanNextChar(); sym = Symbol.PlusAssign; } @@ -1279,7 +1254,7 @@ Symbol ScanPunctuator() case '-': if (_nextChar == '=') { - _token += _currChar; + Token += _currChar; ScanNextChar(); sym = Symbol.MinusAssign; } @@ -1303,7 +1278,7 @@ Symbol ScanPunctuator() sym = Symbol.Eof; return sym; } - _token += _currChar; + Token += _currChar; ScanNextChar(); return sym; } @@ -1312,7 +1287,6 @@ Symbol ScanPunctuator() ///// ///// Scans string literals used as identifiers. ///// - ///// //protected string ReadRawString() //ScanStringLiteralIdentifier //{ // string str = ""; @@ -1339,7 +1313,7 @@ Symbol ScanPunctuator() //} /// - /// Scans verbatim strings like «@"String with ""quoted"" text"». + /// Scans verbatim strings like «@"String with ""quoted"" text"». /// string ScanVerbatimStringLiteral() { @@ -1358,13 +1332,12 @@ string ScanVerbatimStringLiteral() str += ch; ch = ScanNextChar(); } - ScanNextChar(); return str; } /// - /// Scans regular string literals like «"String with \"escaped\" text"». + /// Scans regular string literals like «"String with \"escaped\" text"». /// string ScanStringLiteral() { @@ -1433,13 +1406,11 @@ string ScanStringLiteral() if (hexNrCount <= 2) str.Append("?????"); //(char)AscULongFromHexString(hexString); else - //throw new DdlParserException(DdlErrorLevel.Error, - // DomSR.GetString(DomMsgID.EscapeSequenceNotAllowed), DomMsgID.EscapeSequenceNotAllowed); throw TH.DdlParserException_EscapeSequenceNotAllowed(str.ToString()); } break; - //NYI: octal numbers + // NYI: octal numbers //case '0': //{ // ScanNextChar(); @@ -1459,14 +1430,10 @@ string ScanStringLiteral() // break; default: - //throw new DdlParserException(DdlErrorLevel.Error, - // DomSR.GetString(DomMsgID.EscapeSequenceNotAllowed), DomMsgID.EscapeSequenceNotAllowed); throw TH.DdlParserException_EscapeSequenceNotAllowed(str.ToString()); } } else if (_currChar is Chars.Null or Chars.CR or Chars.LF) - //throw new DdlParserException(DdlErrorLevel.Error, - // DomSR.GetString(DomMsgID.NewlineInString), DomMsgID.NewlineInString); throw TH.DdlParserException_NewlineInString(); else str.Append(_currChar); @@ -1482,17 +1449,13 @@ string ScanStringLiteral() /// void SaveCurDocumentPos() { - _nCurDocumentIndex = _idx - 1; - _nCurDocumentLine = _idxLine; - _nCurDocumentLinePos = _idxLinePos; + //_curDocumentIndex = _idx - 1; Not (yet?) used. + CurrentLine = _idxLine; + CurrentLinePos = _idxLinePos; } - int _nCurDocumentIndex; - int _nCurDocumentLine; - int _nCurDocumentLinePos; + //int _curDocumentIndex; Not(yet?) used. - readonly string _documentFileName; - readonly string _documentPath; readonly string _strDocument; readonly int _ddlLength; int _idx; @@ -1501,12 +1464,9 @@ void SaveCurDocumentPos() char _currChar; char _nextChar; - string _token = ""; - Symbol _symbol = Symbol.None; Symbol _prevSymbol = Symbol.None; - TokenType _tokenType = TokenType.None; bool _emptyLine; - DdlReaderErrors _errors; + //DdlReaderErrors _errors; Not (yet?) used. } } diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlWriter.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlWriter.cs index 38542c37..1a437ec6 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlWriter.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/DdlWriter.cs @@ -43,17 +43,14 @@ public void Close() { _serializer = null!; - if (_writer != null) - { - _writer.Close(); - _writer = null; - } + _writer?.Close(); + _writer = null; } /// /// Flushes the underlying TextWriter. /// - public void Flush() + public void Flush() => _serializer.Flush(); /// @@ -95,13 +92,13 @@ public void WriteDocument(DocumentObjectCollection documentObjectContainer) /// /// Writes a DocumentObject type object to string. /// - public static string WriteToString(DocumentObject docObject) + public static string WriteToString(DocumentObject docObject) => WriteToString(docObject, 2, 0); /// /// Writes a DocumentObject type object to string. Indent a new block by indent characters. /// - public static string WriteToString(DocumentObject docObject, int indent) + public static string WriteToString(DocumentObject docObject, int indent) => WriteToString(docObject, indent, 0); /// @@ -135,13 +132,13 @@ public static string WriteToString(DocumentObject docObject, int indent, int ini /// /// Writes a DocumentObjectCollection type object to string. /// - public static string WriteToString(DocumentObjectCollection docObjectContainer) + public static string WriteToString(DocumentObjectCollection docObjectContainer) => WriteToString(docObjectContainer, 2, 0); /// /// Writes a DocumentObjectCollection type object to string. Indent a new block by _indent characters. /// - public static string WriteToString(DocumentObjectCollection docObjectContainer, int indent) + public static string WriteToString(DocumentObjectCollection docObjectContainer, int indent) => WriteToString(docObjectContainer, indent, 0); /// @@ -176,13 +173,13 @@ public static string WriteToString(DocumentObjectCollection docObjectContainer, /// /// Writes a document object to a DDL file. /// - public static void WriteToFile(DocumentObject docObject, string filename) + public static void WriteToFile(DocumentObject docObject, string filename) => WriteToFile(docObject, filename, 2, 0); /// /// Writes a document object to a DDL file. Indent a new block by the specified number of characters. /// - public static void WriteToFile(DocumentObject docObject, string filename, int indent) + public static void WriteToFile(DocumentObject docObject, string filename, int indent) => WriteToFile(docObject, filename, indent, 0); /// @@ -209,14 +206,14 @@ public static void WriteToFile(DocumentObject docObject, string filename, int in /// /// Writes a DocumentObjectCollection type object to a DDL file. /// - public static void WriteToFile(DocumentObjectCollection docObjectContainer, string filename) + public static void WriteToFile(DocumentObjectCollection docObjectContainer, string filename) => WriteToFile(docObjectContainer, filename, 2, 0); /// /// Writes a DocumentObjectCollection type object to a DDL file. Indent a new block by /// indent + initialIndent characters. /// - public static void WriteToFile(DocumentObjectCollection docObjectContainer, string filename, int indent) + public static void WriteToFile(DocumentObjectCollection docObjectContainer, string filename, int indent) => WriteToFile(docObjectContainer, filename, indent, 0); /// diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/Symbols.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/Symbols.cs index b839a0a5..38b4e30a 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/Symbols.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/Symbols.cs @@ -174,7 +174,7 @@ internal static Symbol SymbolFromName(string name) Symbol symbol; if (!NameToEnum.TryGetValue(name, out symbol)) { - // Check for case sensitive keywords. Allow first character upper case only. + // Check for case-sensitive keywords. Allow first character upper case only. if (string.Compare(name, "True", StringComparison.OrdinalIgnoreCase) == 0) symbol = Symbol.True; else if (string.Compare(name, "False", StringComparison.OrdinalIgnoreCase) == 0) @@ -190,12 +190,9 @@ internal static Symbol SymbolFromName(string name) /// /// Returns string from Symbol value. /// - internal static string NameFromSymbol(Symbol symbol) - { - return EnumToName[symbol]; - } + internal static string NameFromSymbol(Symbol symbol) => EnumToName[symbol]; - static readonly Dictionary EnumToName = new(); - static readonly Dictionary NameToEnum = new(); + static readonly Dictionary EnumToName = []; + static readonly Dictionary NameToEnum = []; } } diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/enums/Symbol.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/enums/Symbol.cs index 560fb696..e8ebe60e 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/enums/Symbol.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/enums/Symbol.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. namespace MigraDoc.DocumentObjectModel.IO @@ -52,7 +52,7 @@ enum Symbol Percent, // % Dollar, // $ Hash, // # - Currency, // ¤ + Currency, // ¤ //Questionmark, // ? Quotationmark, // " At, // @ diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/enums/TokenType.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/enums/TokenType.cs index faf42a90..8d0f5c06 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/enums/TokenType.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.IO/enums/TokenType.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. namespace MigraDoc.DocumentObjectModel.IO @@ -9,7 +9,7 @@ namespace MigraDoc.DocumentObjectModel.IO enum TokenType { /// - /// White space or comment. + /// White-space or comment. /// None, @@ -19,17 +19,17 @@ enum TokenType Identifier, /// - /// Both «true» and «\bold» are keywords, case sensitive. + /// Both «true» and «\bold» are keywords, case sensitive. /// KeyWord, /// - /// Sample: «42» + /// Sample: «42» /// IntegerLiteral, /// - /// Samples: «42.0», «42.», «.42»,... + /// Samples: «42.0», «42.», «.42»,... /// RealLiteral, @@ -39,12 +39,12 @@ enum TokenType CharacterLiteral, /// - /// Both «"text"» and «@"text with ""quotes"""». + /// Both «"text"» and «@"text with ""quotes"""». /// StringLiteral, /// - /// Samples: «.», «{», «+=»,... + /// Samples: «.», «{», «+=»,... /// OperatorOrPunctuator, diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ErrorHelpers.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ErrorHelpers.cs index d82e9079..cac38922 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ErrorHelpers.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ErrorHelpers.cs @@ -17,7 +17,7 @@ public static string SomeMessage(string someString, int someInt) /// /// // ReSharper disable once InconsistentNaming - static class TH // RENAME TODO + static class TH // #RENAME { #region General Messages @@ -35,17 +35,17 @@ static class TH // RENAME TODO // return FormatMessage(DomMsgID.InvalidInfoFieldName, name); //} - // StyleExpected = The value must be of type MigraDoc.DocumentObjectModel.Style. - public static ArgumentException ArgumentException_StyleExpected(Type type) => - new($"The value is of type '{type.FullName}' but must be of type 'MigraDoc.DocumentObjectModel.Style'."); + /// + /// The specified object must be of type Style. + /// + public static ArgumentException ArgumentException_StyleExpected(Type wrongType) + => new(MdDomMsgs.StyleExpected(wrongType).Message); - // BaseStyleRequired = Base style name must be defined. - public static ArgumentException ArgumentException_UndefinedBaseStyle(string baseStyle) => - new($"Base style name '{baseStyle}' is undefined."); - - //{ - // return FormatMessage(DomMsgID.UndefinedBaseStyle, baseStyle); - //} + /// + /// The base style of style that is not a root style must be defined. + /// + public static ArgumentException ArgumentException_UndefinedBaseStyle(string style) + => new(MdDomMsgs.UndefinedBaseStyle(style).Message); //public static string InvalidValueName(string name) //{ @@ -64,9 +64,9 @@ public static ArgumentException ArgumentException_UndefinedBaseStyle(string base //public static string InvalidEnumValue(T value) where T : unmanaged // struct, Enum //{ - // // ... where T : enum + // // … where T : enum // // -or- - // // ... where T : Enum + // // … where T : Enum // // is not implemented in C# because nobody has done this. // // See Eric Lippert on this topic: http://stackoverflow.com/questions/1331739/enum-type-constraints-in-c-sharp // // UPDATE: Enum constraint comes with C# 7.3, see: https://devblogs.microsoft.com/premier-developer/dissecting-new-generics-constraints-in-c-7-3/ @@ -216,17 +216,17 @@ public static ArgumentException ArgumentException_UndefinedBaseStyle(string base //// FileNotFound, //// NotSupported, - //NewlineInString, + /// + /// A new-line occurs in a string literal. + /// public static DdlParserException DdlParserException_NewlineInString() - => new(DdlErrorLevel.Error, - "Newline in string not allowed.", - DomMsgID.NewlineInString); - - //EscapeSequenceNotAllowed - public static DdlParserException DdlParserException_EscapeSequenceNotAllowed(string s) - => new(DdlErrorLevel.Error, - $"Invalid escape sequence '{s}'.", - DomMsgID.EscapeSequenceNotAllowed); + => new(MdDomMsgs.NewlineInString); + + /// + /// An illegal escape sequence occured. + /// + public static DdlParserException DdlParserException_EscapeSequenceNotAllowed(string token) + => new(MdDomMsgs.EscapeSequenceNotAllowed(token)); //// SymbolsNotAllowedInsideText, //NullAssignmentNotSupported, diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/LogMessages.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/LogMessages.cs index 31db0b11..dd756dd3 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/LogMessages.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/LogMessages.cs @@ -22,13 +22,13 @@ public static partial void ArgbValueIsConsideredEmptyColor( // What to log? - // Image not found (not loadable, not found, ...) + // Image not found (not loadable, not found, …) // Font not found under Linux (use Linux substitution) // Information/Trace-level for e.g. TabStop inheritance, style inheritance // Differences in RTF vs Word (decimal tab) // Performance optimization - // TODO Use logging instead of Console.WriteLine. - // TODO remove all Console.WriteLine calls. + // TODO_OLD Use logging instead of Con/sole.WriteLine. + // TODO_OLD remove all Con/sole.WriteLine calls. } } diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/Logging.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/Logging.cs index fb6428dd..2eb15c37 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/Logging.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/Logging.cs @@ -22,7 +22,7 @@ public static class AppLogEvents // ReSharper disable once IdentifierTypo public static EventId MDDOM = new(AppLogEventIds.MDDOM, "NDDOM"); - // TODO Not yet used. + // TODO_OLD Not yet used. public static EventId FontCreated = new(AppLogEventIds.MDDOM + 0, "Font created"); public static EventId FontFound = new(AppLogEventIds.MDDOM + 1, "Font found"); @@ -35,7 +35,7 @@ public static class AppLogEvents public static EventId Update = new(1002, "Updated"); public static EventId Delete = new(1003, "Deleted"); - // These are also valid EventId instances, as there's + // These are also valid EventId instances, as there’s // an implicit conversion from int to an EventId public const int Details = 3000; public const int Error = 3001; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/Meta.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/Meta.cs index a32854bf..b966d5b3 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/Meta.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/Meta.cs @@ -6,12 +6,12 @@ namespace MigraDoc.DocumentObjectModel.Internals { /// - /// Meta class for document objects. + /// Metaclass for document objects. /// public sealed class Meta { /// - /// Initializes a new instance of the DomMeta class. + /// Initializes a new instance of the Meta class. /// public Meta(Type documentObjectType) { @@ -19,7 +19,7 @@ public Meta(Type documentObjectType) } /// - /// Gets the meta object of the specified document object. + /// Gets the metaobject of the specified document object. /// /// The document object the meta is returned for. public static Meta GetMeta(DocumentObject documentObject) => documentObject.Meta; @@ -29,43 +29,30 @@ public Meta(Type documentObjectType) /// public object? GetValue(DocumentObject dom, string name, GV flags) { -#if NET6_0_OR_GREATER - int dot = name.IndexOf('.', StringComparison.Ordinal); + int dot = name.IndexOf('.'); if (dot == 0) - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); string? trail = null; if (dot > 0) { trail = name[(dot + 1)..]; name = name[..dot]; } -#else - int dot = name.IndexOf(".", StringComparison.Ordinal); - if (dot == 0) - throw new ArgumentException(DomSR.InvalidValueName(name)); - string? trail = null; - if (dot > 0) - { - trail = name.Substring(dot + 1); - name = name.Substring(0, dot); - } -#endif var vd = ValueDescriptors[name]; if (vd == null) - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); var value = vd.GetValue(dom, flags); if (value == null && flags == GV.GetNull) //??? also for GV.ReadOnly? return null; - //REVIEW DaSt: Create object in case of GV.ReadWrite? if (trail != null) { if (value == null || trail == "") - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); if (value is not DocumentObject doc) - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); value = doc.GetValue(trail, flags); } return value; @@ -77,32 +64,23 @@ public Meta(Type documentObjectType) /// public void SetValue(DocumentObject dom, string name, object? val) { -#if NET6_0_OR_GREATER - int dot = name.IndexOf('.', StringComparison.Ordinal); -#else - int dot = name.IndexOf(".", StringComparison.Ordinal); -#endif + int dot = name.IndexOf('.'); if (dot == 0) - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); string? trail = null; if (dot > 0) { -#if NET6_0_OR_GREATER trail = name[(dot + 1)..]; name = name[..dot]; -#else - trail = name.Substring(dot + 1); - name = name.Substring(0, dot); -#endif } var vd = ValueDescriptors[name]; if (vd == null) - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); if (trail != null) { - //REVIEW DaSt: dom.GetValue(name) and call SetValue recursively, - // or dom.GetValue(name.BisVorletzteElement) and then call SetValue? + // REVIEW DaSt: dom.GetValue(name) and call SetValue recursively, + // or dom.GetValue(name.BisVorletzteElement) and then call SetValue? var doc = (DocumentObject?)dom.GetValue(name); if (doc == null) throw new InvalidOperationException($"No value named '{name}' exists."); @@ -117,9 +95,9 @@ public void SetValue(DocumentObject dom, string name, object? val) /// public bool HasValue(string name) { - // BUG: HasValue("a.b") not handled + // BUG_OLD: HasValue("a.b") not handled if (name.Contains('.')) - throw new NotImplementedException($"'{name}' contains a dot."); + throw new NotSupportedException($"'{name}' contains a dot."); return ValueDescriptors.HasName(name); } @@ -131,11 +109,11 @@ public bool HasValue(string name) public void SetNull(DocumentObject dom, string name) { if (name.Contains('.')) - throw new NotImplementedException($"'{name}' contains a dot."); + throw new NotSupportedException($"'{name}' contains a dot."); var vd = ValueDescriptors[name]; if (vd == null) - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); vd.SetNull(dom); } @@ -149,29 +127,19 @@ public void SetNull(DocumentObject dom, string name) if (String.IsNullOrEmpty(name) /*|| name == "this"*/) return IsNull(dom); - //bool isNull = false; -#if NET6_0_OR_GREATER - int dot = name.IndexOf('.', StringComparison.Ordinal); -#else - int dot = name.IndexOf(".", StringComparison.Ordinal); -#endif + int dot = name.IndexOf('.'); if (dot == 0) - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); string? trail = null; if (dot > 0) { -#if NET6_0_OR_GREATER trail = name[(dot + 1)..]; name = name[..dot]; -#else - trail = name.Substring(dot + 1); - name = name.Substring(0, dot); -#endif } var vd = ValueDescriptors[name]; if (vd == null) - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); #if true if (trail == null) @@ -182,9 +150,9 @@ public void SetNull(DocumentObject dom, string name) return true; if (/*value == null || */trail == "") - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); if (value is not DocumentObject doc) - throw new ArgumentException(DomSR.InvalidValueName(name)); + throw new ArgumentException(MdDomMsgs.InvalidValueName(name).Message); return doc.IsNull(trail); #else @@ -254,7 +222,7 @@ public bool IsNull(DocumentObject dom) public ValueDescriptor this[string name] => ValueDescriptors[name]; /// - /// Determines whether this meta object contains a value descriptor with the specified name. + /// Determines whether this metaobject contains a value descriptor with the specified name. /// public bool HasName(string name) => ValueDescriptors.HasName(name); @@ -280,11 +248,6 @@ static void AddValueDescriptors(Meta meta, Type type) foreach (var propInfo in propInfos) { -#if DEBUG_ - string name = propInfo.Name; - if (name == "Font") - name.GetType(); -#endif DVAttribute? attr = null; var dvs = (DVAttribute[])propInfo.GetCustomAttributes(typeof(DVAttribute), false); if (dvs.Length == 1) diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ReferenceTypeDescriptor.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ReferenceTypeDescriptor.cs index 78a93150..131d46c7 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ReferenceTypeDescriptor.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ReferenceTypeDescriptor.cs @@ -13,11 +13,8 @@ class ReferenceTypeDescriptor : ValueDescriptor internal ReferenceTypeDescriptor(string valueName, Type valueType, PropertyInfo propertyInfo, VDFlags flags) : base(valueName, valueType, propertyInfo, flags) { -#if DEBUG_ // Checked in unit tests. // Only String and Object should come here. - if (valueType != typeof(string) && valueType != typeof(object)) - GetType(); -#endif + // Checked in unit tests. } public override object? GetValue(DocumentObject dom, GV flags) diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ValueDescriptor.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ValueDescriptor.cs index c011d9e2..d933bf4a 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ValueDescriptor.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Internals/ValueDescriptor.cs @@ -34,7 +34,6 @@ public object CreateValue() /// /// The document object. /// The GetValue flags. - /// public abstract object? GetValue(DocumentObject doc, GV flags); /// @@ -84,7 +83,7 @@ internal static ValueDescriptor CreateValueDescriptor(PropertyInfo propertyInfo, { // Case: The type of the property is nullable. //ValueStyleInternal |= ValueStyleInternal.Nullable; - //valueType.GetType(); + //_ = typeof(int); } } #endif @@ -137,7 +136,7 @@ internal static ValueDescriptor CreateValueDescriptor(PropertyInfo propertyInfo, protected void EnsureGetValueFlags(GV flags) { if (!Enum.IsDefined(typeof(GV), flags)) - throw new InvalidEnumArgumentException(DomSR.InvalidEnumValue(flags)); + throw new InvalidEnumArgumentException(MdDomMsgs.InvalidEnumValue(flags).Message); } /// diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Resources/Messages.de.restext b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Resources/Messages.de.restext deleted file mode 100644 index c3ac3abf..00000000 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Resources/Messages.de.restext +++ /dev/null @@ -1,71 +0,0 @@ -; ----- German (de) Messages --------------------------------------------------- -; Messages for German language -; that differ from the default messages. -; -; Must be saved with encoding UTF8. Otherwise German umlauts get not processed correctly. -; -; ------------------------------------------------------------------------------ - -StyleExpected = Der übergebene Wert muss vom Typ MigraDoc.DocumentObjectModel.Style sein. -BaseStyleRequired = Es muss eine Basis-Formatvorlage definiert werden. -EmptyBaseStyle = Die Basis-Formatvorlage darf nicht leer sein. -InvalidFieldFormat = '{0}' ist kein gültiges Format für ein numerisches Feld. -InvalidInfoFieldName = Die Eigenschaft 'Name' an 'InfoField' hat den ungültigen Wert '{0}'. -UndefinedBaseStyle = Die Basis-Formatvorlage '{0}' ist nicht definiert. -InvalidUnitValue = '{0}' ist keine gültige Zeichenkette für ein 'Unit'-Objekt. -InvalidUnitType = '{0}' ist eine unbekannte Maßeinheit für ein 'Unit'-Objekt. -InvalidEnumValue = Der Wert '{0:X}' ist für den enum-Type '{1}' nicht gültig. -InvalidEnumForLeftPosition = ShapePosition muss einer der Werte 'Left', 'Center', oder 'Right' sein. -InvalidEnumForTopPosition = ShapePosition muss einer der Werte 'Top', 'Center', oder 'Bottom' sein. -InvalidColorString = Aus der Zeichenkette '{0}' konnte keine Farbe eingelesen werden. -InvalidFontSize = Die Fontgröße '{0}' is außerhalb des erlaubten Bereichs. -InsertNullNotAllowed = In ein Collection-Objekt darf keine null eingefügt werden. -ParentAlreadySet = Wert vom Typ '{0}' muss geklont werden, bevor er an '{1}' gesetzt werden kann. -MissingObligatoryProperty = Obligatorische Eigenschaft '{0}' wurde an '{1}' nicht gesetzt. -InvalidDocumentObjectType = Das übergebene Dokumentobjekt ist in diesem Zusammenhang nicht gültig. - -; ----- DdlReader Messages ------------------------------------------------------------------------ - -;DomMsgID -SymbolExpected = Symbol '{0}' erwartet, '{1}' vorgefunden. -SymbolsExpected = Eines der folgenden Symbole {0} erwartet. -OperatorExpected = Syntaxfehler: Operator '{0}' erwartet. -KeyWordExpected = Schlüsselwort '{1}' - '{0}' erwartet. -EndOfFileExpected = Ende der Datei erwartet. -UnexpectedEndOfFile = Unerwartetes Dateiende. -StyleNameExpected = '{0}' ist kein gültiger Name für eine Formatvorlage. -UnexpectedSymbol = Unerwartetes Symbol '{0}'. -IdentifierExpected = Bezeichner erwartet: '{0}'. -BoolExpected = Boolescher Wert erwartet: '{0}'. -RealExpected = Fließkomma-Wert erwartet: '{0}'. -IntegerExpected = Ganze Zahl erwartet: '{0}'. -StringExpected = Zeichenkette erwartet: '{0}'. -NullExpected = Null erwartet: '{0}'. -NumberExpected = Zahl erwartet: '{0}'. -InvalidEnum = '{0}' '{1}'. -InvalidType = Variablentyp '{0}' wird von '{1}' nicht unterstützt. -InvalidAssignment = Ungültige Zuweisung an '{0}'. -InvalidValueName = '{0}' ist ein ungültiger Wertname. -InvalidRange = Ungültiger Bereich: '{0}'. -InvalidColor = Ungültiger Farbwert: '{0}'. -InvalidFieldType = Ungültiger Feldtyp: '{0}'. -InvalidValueForOperation = Operation '{1}' ist für den Wert '{0}' nicht gültig. -InvalidSymbolType = Ungültiges Symbol '{0}'. -MissingBraceLeft = Öffnende geschweifte Klammer nach '{0}' fehlt. -MissingBraceRight = Schließende geschweifte Klammer nach '{0}' fehlt. -MissingBracketLeft = Öffnende eckige Klammer nach '{0}' fehlt. -MissingBracketRight = Schließende eckige Klammer nach '{0}' fehlt. -MissingParenLeft = Öffnende runde Klammer nach '{0}' fehlt. -MissingParenRight = Schließende runde Klammer nach '{0}' fehlt. -MissingComma = Komma fehlt. -SymbolNotAllowed = Symbol '{0}' ist in diesem Zusammenhang nichterlaubt. -SymbolIsNotAnObject = Symbol '{0}' ist kein Objekt. -UnknownChartType = Unbekannter Diagrammtyp: '{0}' -NoAccess = Zugriff verweigert: '{0}' existiert nur für den internen Gebrauch. -NewlineInString = Zeilenumbruch in Zeichenkette nicht erlaubt. -EscapeSequenceNotAllowed = Ungültige Escapesequenz. -NullAssignmentNotSupported = Zuweisung von 'null' an '{0}' ist nicht erlaubt. -OutOfRange = Der gültige Bereich liegt innerhalb von '{0}'. - -UseOfUndefinedBaseStyle = Die unbekannte Basis-Formatvorlage '{0}' wurde verwendet. -UseOfUndefinedStyle = Die unbekannte Formatvorlage '{0}' wurde verwendet. diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Resources/Messages.restext b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Resources/Messages.restext deleted file mode 100644 index 9ee1942d..00000000 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Resources/Messages.restext +++ /dev/null @@ -1,70 +0,0 @@ -; ----- Default Messages ------------------------------------------------------- -; Each Message will be shown for any language -; that does not override it in its specific .txt-file. -; ------------------------------------------------------------------------------ - -; ----- General Messages -------------------------------------------------------------------------- - -StyleExpected = The value must be of type MigraDoc.DocumentObjectModel.Style. -BaseStyleRequired = Base style name must be defined. -EmptyBaseStyle = Attempt to set empty base style is invalid. -InvalidFieldFormat = '{0}' is not a valid numeric field format. -InvalidInfoFieldName = Property 'Name' of 'InfoField' has invalid value '{0}'. -UndefinedBaseStyle = Base style name '{0}' is undefined. -InvalidUnitValue = String '{0}' is not a valid value for structure 'Unit'. -InvalidUnitType = '{0}' is an unknown unit type. -InvalidEnumValue = The value '{0:X}' is not valid for enum type '{1}'. -InvalidEnumForLeftPosition = ShapePosition must be Left, Center, or Right. -InvalidEnumForTopPosition = ShapePosition must be Top, Center, or Bottom. -InvalidColorString = Color could not be parsed from string '{0}'. -InvalidFontSize = The font size '{0}' is out of range. -InsertNullNotAllowed = Inserting null into a collection is not allowed. -ParentAlreadySet = Value of type '{0}' must be cloned before set into '{1}'. -MissingObligatoryProperty = Obligatory property '{0}' not set in '{1}'. -InvalidDocumentObjectType = The given document object is not valid in this context. - -; ----- DdlReader Messages ------------------------------------------------------------------------ - -;DomMsgID -SymbolExpected = '{0}' expected, found '{1}'. -SymbolsExpected = One of the following symbols {0} is expected. -OperatorExpected = Syntax error: Operator '{0}' is expected. -KeyWordExpected = '{1}' - '{0}' expected. -EndOfFileExpected = End of file expected. -UnexpectedEndOfFile = Unexpected end of file. -StyleNameExpected = Invalid style name '{0}'. -UnexpectedSymbol = Unexpected symbol '{0}'. -IdentifierExpected = Identifier expected: '{0}'. -BoolExpected = Bool expected: '{0}'. -RealExpected = Real expected: '{0}'. -IntegerExpected = Integer expected: '{0}'. -StringExpected = String expected: '{0}'. -NullExpected = Null expected: '{0}'. -NumberExpected = Number expected: '{0}'. -InvalidEnum = '{0}' '{1}'. -InvalidType = Variable type '{0}' not supported by '{1}'. -InvalidAssignment = Invalid assignment to '{0}'. -InvalidValueName = Invalid value name: '{0}'. -InvalidRange = Invalid range: '{0}'. -InvalidColor = Invalid color: '{0}'. -InvalidFieldType = Invalid field type: '{0}'. -InvalidValueForOperation = Operation '{1}' not valid for Value '{0}'. -InvalidSymbolType = Symbol not valid '{0}'. -MissingBraceLeft = Missing left brace after '{0}'. -MissingBraceRight = Missing right brace after '{0}'. -MissingBracketLeft = Missing left bracket after '{0}'. -MissingBracketRight = Missing right bracket after '{0}'. -MissingParenLeft = Missing left parenthesis after '{0}'. -MissingParenRight = Missing right parenthesis after '{0}'. -MissingComma = Missing comma. -SymbolNotAllowed = Symbol '{0}' in this context not allowed. -SymbolIsNotAnObject = Symbol '{0}' is not an object. -UnknownChartType = Unknown chart type: '{0}' -NoAccess = Access denied: '{0}' for internal use only. -NewlineInString = Newline in string not allowed. -EscapeSequenceNotAllowed = Invalid escape sequence. -NullAssignmentNotSupported = Assign 'null' to '{0}' not allowed. -OutOfRange = Valid range only within '{0}'. - -UseOfUndefinedBaseStyle = Use of undefined base style '{0}'. -UseOfUndefinedStyle = Use of undefined style '{0}'. diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Axis.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Axis.cs index 9b2de631..f8bffa3e 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Axis.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Axis.cs @@ -72,7 +72,7 @@ public AxisTitle Title get => Values.Title ??= new AxisTitle(this); set { - SetParent(value); + SetParentOf(value); Values.Title = value; } } @@ -139,7 +139,7 @@ public TickLabels TickLabels get => Values.TickLabels ??= new TickLabels(this); set { - SetParent(value); + SetParentOf(value); Values.TickLabels = value; } } @@ -152,7 +152,7 @@ public LineFormat LineFormat get => Values.LineFormat ??= new LineFormat(this); set { - SetParent(value); + SetParentOf(value); Values.LineFormat = value; } } @@ -165,7 +165,7 @@ public Gridlines MajorGridlines get => Values.MajorGridlines ??= new Gridlines(this); set { - SetParent(value); + SetParentOf(value); Values.MajorGridlines = value; } } @@ -178,7 +178,7 @@ public Gridlines MinorGridlines get => Values.MinorGridlines ??= new Gridlines(this); set { - SetParent(value); + SetParentOf(value); Values.MinorGridlines = value; } } @@ -255,7 +255,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/AxisTitle.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/AxisTitle.cs index 08523a8b..0e730b4b 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/AxisTitle.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/AxisTitle.cs @@ -72,7 +72,7 @@ public Font Font get => Values.Font ??= new Font(this); set { - SetParent(value); + SetParentOf(value); Values.Font = value; } } @@ -133,7 +133,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Chart.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Chart.cs index 4ef5e6b4..b445ba13 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Chart.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Chart.cs @@ -146,7 +146,7 @@ public ParagraphFormat Format get => Values.Format ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Format = value; } } @@ -159,7 +159,7 @@ public Axis XAxis get => Values.XAxis ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.XAxis = value; } } @@ -172,7 +172,7 @@ public Axis YAxis get => Values.YAxis ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.YAxis = value; } } @@ -185,7 +185,7 @@ public Axis ZAxis get => Values.ZAxis ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.ZAxis = value; } } @@ -198,7 +198,7 @@ public SeriesCollection SeriesCollection get => Values.SeriesCollection ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.SeriesCollection = value; } } @@ -211,7 +211,7 @@ public XValues XValues get => Values.XValues ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.XValues = value; } } @@ -224,7 +224,7 @@ public TextArea HeaderArea get => Values.HeaderArea ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.HeaderArea = value; } } @@ -237,7 +237,7 @@ public TextArea BottomArea get => Values.BottomArea ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.BottomArea = value; } } @@ -250,7 +250,7 @@ public TextArea TopArea get => Values.TopArea ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.TopArea = value; } } @@ -263,7 +263,7 @@ public TextArea FooterArea get => Values.FooterArea ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.FooterArea = value; } } @@ -276,7 +276,7 @@ public TextArea LeftArea get => Values.LeftArea ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.LeftArea = value; } } @@ -289,7 +289,7 @@ public TextArea RightArea get => Values.RightArea ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.RightArea = value; } } @@ -302,7 +302,7 @@ public PlotArea PlotArea get => Values.PlotArea ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.PlotArea = value; } } @@ -333,7 +333,7 @@ public DataLabel DataLabel get => Values.DataLabel ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.DataLabel = value; } } @@ -461,7 +461,7 @@ void IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, bool visitChildren) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/ChartObject.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/ChartObject.cs index 1faa20f2..c33844c3 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/ChartObject.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/ChartObject.cs @@ -31,7 +31,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/DataLabel.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/DataLabel.cs index adb16578..8765470e 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/DataLabel.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/DataLabel.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. namespace MigraDoc.DocumentObjectModel.Shapes.Charts @@ -61,14 +61,14 @@ public Font Font get => Values.Font ??= new Font(this); set { - SetParent(value); + SetParentOf(value); Values.Font = value; } } /// /// Gets or sets the Style for the DataLabel. - /// Only the Font-associated part of the Style's ParagraphFormat is used. + /// Only the Font-associated part of the Style’s ParagraphFormat is used. /// public string Style { @@ -116,7 +116,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Gridlines.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Gridlines.cs index 34420d28..37bff0ff 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Gridlines.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Gridlines.cs @@ -52,7 +52,7 @@ public LineFormat LineFormat get => Values.LineFormat ??= new LineFormat(this); set { - SetParent(value); + SetParentOf(value); Values.LineFormat = value; } } @@ -62,9 +62,9 @@ public LineFormat LineFormat /// internal override void Serialize(Serializer serializer) { - var axisObject = Parent as Axis; + var axisObject = Parent as Axis ?? throw new InvalidOperationException("Parent is not of type Axis."); - var pos = serializer.BeginContent(axisObject!.CheckGridlines(this)); // HACK // BUG: What if Parent is not Axis? + var pos = serializer.BeginContent(axisObject.CheckGridlines(this)); Values.LineFormat?.Serialize(serializer); @@ -72,7 +72,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Legend.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Legend.cs index a8dcf6fa..aac866bb 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Legend.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Legend.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. using MigraDoc.DocumentObjectModel.Visitors; @@ -52,7 +52,7 @@ protected override object DeepCopy() } /// - /// Gets or sets the style name of the legend's text. + /// Gets or sets the style name of the legend’s text. /// public string Style { @@ -61,27 +61,27 @@ public string Style } /// - /// Gets the paragraph format of the legend's text. + /// Gets the paragraph format of the legend’s text. /// public ParagraphFormat Format { get => Values.Format ??= new ParagraphFormat(this); set { - SetParent(value); + SetParentOf(value); Values.Format = value; } } /// - /// Gets the line format of the legend's border. + /// Gets the line format of the legend’s border. /// public LineFormat LineFormat { get => Values.LineFormat ??= new LineFormat(this); set { - SetParent(value); + SetParentOf(value); Values.LineFormat = value; } } @@ -114,7 +114,7 @@ public override bool IsNull() } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/PlotArea.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/PlotArea.cs index 75d6407e..4b9127ac 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/PlotArea.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/PlotArea.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. namespace MigraDoc.DocumentObjectModel.Shapes.Charts @@ -50,14 +50,14 @@ protected override object DeepCopy() } /// - /// Gets the line format of the plot area's border. + /// Gets the line format of the plot area’s border. /// public LineFormat LineFormat { get => Values.LineFormat ??= new LineFormat(this); set { - SetParent(value); + SetParentOf(value); Values.LineFormat = value; } } @@ -70,7 +70,7 @@ public FillFormat FillFormat get => Values.FillFormat ??= new FillFormat(this); set { - SetParent(value); + SetParentOf(value); Values.FillFormat = value; } } @@ -142,7 +142,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Point.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Point.cs index 2349bc20..8ba1246a 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Point.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Point.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. namespace MigraDoc.DocumentObjectModel.Shapes.Charts @@ -50,14 +50,14 @@ protected override object DeepCopy() } /// - /// Gets the line format of the data point's border. + /// Gets the line format of the data point’s border. /// public LineFormat LineFormat { get => Values.LineFormat ??= new LineFormat(this); set { - SetParent(value); + SetParentOf(value); Values.LineFormat = value; } } @@ -70,7 +70,7 @@ public FillFormat FillFormat get => Values.FillFormat ??= new FillFormat(this); set { - SetParent(value); + SetParentOf(value); Values.FillFormat = value; } } @@ -112,7 +112,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Series.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Series.cs index 11cfe0fd..ef8c4508 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Series.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/Series.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. namespace MigraDoc.DocumentObjectModel.Shapes.Charts @@ -83,7 +83,7 @@ public SeriesElements Elements get => Values.Elements ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Elements = value; } } @@ -105,7 +105,7 @@ public LineFormat LineFormat get => Values.LineFormat ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.LineFormat = value; } } @@ -118,7 +118,7 @@ public FillFormat FillFormat get => Values.FillFormat ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.FillFormat = value; } } @@ -160,7 +160,7 @@ public Color MarkerBackgroundColor } /// - /// Gets or sets the chart type of the series if it's intended to be different than the global chart type. + /// Gets or sets the chart type of the series if it’s intended to be different than the global chart type. /// public ChartType ChartType { @@ -176,7 +176,7 @@ public DataLabel DataLabel get => Values.DataLabel ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.DataLabel = value; } } @@ -248,7 +248,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/SeriesCollection.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/SeriesCollection.cs index d6bfe77e..edccffd2 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/SeriesCollection.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/SeriesCollection.cs @@ -51,7 +51,7 @@ public Series AddSeries() internal override void Serialize(Serializer serializer) { int count = Count; - for (int index = 0; index < count; ++index) + for (int index = 0; index < count; index++) { var series = this[index]; series?.Serialize(serializer); @@ -59,7 +59,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/SeriesElements.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/SeriesElements.cs index 7acea4a9..4e945b1b 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/SeriesElements.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/SeriesElements.cs @@ -61,7 +61,7 @@ public void Add(params double[] values) internal override void Serialize(Serializer serializer) { int count = Count; - for (int index = 0; index < count; ++index) + for (int index = 0; index < count; index++) { if (this[index] is not Point point) serializer.Write("null, "); @@ -71,7 +71,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/TextArea.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/TextArea.cs index d6b98f24..5c4b0091 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/TextArea.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/TextArea.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. using MigraDoc.DocumentObjectModel.Tables; @@ -169,20 +169,20 @@ public ParagraphFormat Format get => Values.Format ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Format = value; } } /// - /// Gets the line format of the area's border. + /// Gets the line format of the area’s border. /// public LineFormat LineFormat { get => Values.LineFormat ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.LineFormat = value; } } @@ -195,7 +195,7 @@ public FillFormat FillFormat get => Values.FillFormat ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.FillFormat = value; } } @@ -253,7 +253,7 @@ public DocumentElements Elements get => Values.Elements ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Elements = value; } } @@ -306,7 +306,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/TickLabels.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/TickLabels.cs index 35cc0d02..adb2e231 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/TickLabels.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/TickLabels.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. namespace MigraDoc.DocumentObjectModel.Shapes.Charts @@ -54,7 +54,7 @@ public string Style } /// - /// Gets or sets the label's number format. + /// Gets or sets the label’s number format. /// public string Format { @@ -70,7 +70,7 @@ public Font Font get => Values.Font ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Font = value; } } @@ -94,7 +94,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XSeries.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XSeries.cs index 6d70d53d..2d835e2c 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XSeries.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XSeries.cs @@ -14,15 +14,15 @@ public class XSeries : ChartObject public XSeries() { BaseValues = new XSeriesValues(this); - XSeriesElements = new XSeriesElements(); + XSeriesElements = new(); } /// /// The actual value container of the XSeries. /// - protected internal XSeriesElements XSeriesElements // TODO Previous implementation did not have a property? + protected internal XSeriesElements XSeriesElements { - get => Values.XSeriesElements ??= new(); + get => Values.XSeriesElements ??= []; set => Values.XSeriesElements = value; } @@ -38,11 +38,8 @@ protected internal XSeriesElements XSeriesElements // TODO Previous implementati protected override object DeepCopy() { XSeries xSeries = (XSeries)base.DeepCopy(); - //if (xSeries.XSeriesElements != null) - //{ xSeries.XSeriesElements = xSeries.XSeriesElements.Clone(); xSeries.XSeriesElements.Parent = xSeries; - //} return xSeries; } @@ -84,7 +81,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XSeriesElements.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XSeriesElements.cs index 03cc0075..3d3a23b1 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XSeriesElements.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XSeriesElements.cs @@ -63,7 +63,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XValue.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XValue.cs index d62e4bd5..d06593e5 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XValue.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XValue.cs @@ -28,7 +28,7 @@ public XValue(string? value) /// /// The actual value of the XValue. /// - protected internal string? Value // TODO Previous implementation did not have a property? + protected internal string? Value // TODO_OLD Previous implementation did not have a property? { get => Values.Value; set => Values.Value = value; @@ -49,7 +49,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XValues.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XValues.cs index ff0d4300..dd951f62 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XValues.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes.Charts/XValues.cs @@ -51,7 +51,7 @@ public XSeries AddXSeries() internal override void Serialize(Serializer serializer) { int count = Count; - for (int index = 0; index < count; ++index) + for (int index = 0; index < count; index++) { var xSeries = this[index] as XSeries; xSeries?.Serialize(serializer); @@ -59,7 +59,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Barcode.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Barcode.cs index a5b8f7dd..5a19eee2 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Barcode.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Barcode.cs @@ -108,7 +108,7 @@ public double NarrowLineWidth internal override void Serialize(Serializer serializer) { if (String.IsNullOrEmpty(Values.Code)) - throw new InvalidOperationException(DomSR.MissingObligatoryProperty("Name", "BookmarkField")); + throw new InvalidOperationException(MdDomMsgs.MissingObligatoryProperty(nameof(Code), nameof(Barcode)).Message); serializer.WriteLine("\\barcode(\"" + Code + "\")"); @@ -135,7 +135,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/FillFormat.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/FillFormat.cs index 044ad75c..4b7ac6e0 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/FillFormat.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/FillFormat.cs @@ -63,7 +63,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; @@ -89,7 +89,7 @@ internal FillFormatValues(DocumentObject owner) : base(owner) public Color? Color { get => _color; - set => _color = DocumentObjectModel.Color.MakeNullIfEmpty(value); // Contradicts Unit! BUG investigate what is better + set => _color = DocumentObjectModel.Color.MakeNullIfEmpty(value); // Contradicts Unit! BUG_OLD investigate what is better } Color? _color; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Image.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Image.cs index 6c590fcf..e39a1fd6 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Image.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Image.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. namespace MigraDoc.DocumentObjectModel.Shapes @@ -101,19 +101,29 @@ public PictureFormat PictureFormat get => Values.PictureFormat ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.PictureFormat = value; } } /// - /// Gets or sets a user defined resolution for the image in dots per inch. + /// Gets or sets a user-defined resolution for the image in dots per inch. /// public double Resolution { get => Values.Resolution ?? 0.0; set => Values.Resolution = value; } + + /// + /// Gets or sets a flag indicating whether image interpolation is to be performed. + /// Defaults to true. + /// + public bool Interpolate + { + get => Values.Interpolate ?? true; + set => Values.Interpolate = value; + } //#endregion /// @@ -134,18 +144,21 @@ internal override void Serialize(Serializer serializer) serializer.WriteSimpleAttribute("LockAspectRatio", LockAspectRatio); if (Values.Resolution is not null) serializer.WriteSimpleAttribute("Resolution", Resolution); + if (Values.Interpolate is not null) + serializer.WriteSimpleAttribute("Interpolate", Interpolate); + Values.PictureFormat?.Serialize(serializer); serializer.EndAttributes(pos); } /// - /// Gets the concrete image path, taking into account the DOM document's DdlFile and + /// Gets the concrete image path, taking into account the DOM document’s DdlFile and /// ImagePath properties as well as the given working directory (which can be null). /// public string GetFilePath(string workingDir) { - if (Name.StartsWith("base64:", StringComparison.Ordinal)) // The file is stored in the string here, so we don't have to add a path. + if (Name.StartsWith("base64:", StringComparison.Ordinal)) // The file is stored in the string here, so we don’t have to add a path. return Name; string filePath; @@ -153,13 +166,13 @@ public string GetFilePath(string workingDir) if (!String.IsNullOrEmpty(workingDir)) filePath = workingDir; else - filePath = Directory.GetCurrentDirectory() + "\\"; + filePath = Directory.GetCurrentDirectory() + "/"; if (!Document.Values.ImagePath.IsValueNullOrEmpty()) { - string? foundfile = ImageHelper.GetImageName(filePath, Name, Document.ImagePath); - if (foundfile != null) - filePath = foundfile; + string? foundFile = ImageHelper.GetImageName(filePath, Name, Document.ImagePath); + if (foundFile != null) + filePath = foundFile; else filePath = Path.Combine(filePath, Name); } @@ -170,7 +183,7 @@ public string GetFilePath(string workingDir) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; @@ -224,6 +237,12 @@ internal ImageValues(DocumentObject owner) : base(owner) /// See enclosing document object class for documentation of this property. /// public double? Resolution { get; set; } + + /// + /// Gets or sets the internal nullable implementation value of the enclosing document object property. + /// See enclosing document object class for documentation of this property. + /// + public bool? Interpolate { get; set; } } } } diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/LeftPosition.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/LeftPosition.cs index 9e260af3..30ad81aa 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/LeftPosition.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/LeftPosition.cs @@ -13,7 +13,7 @@ public struct LeftPosition : INullableValue /// LeftPosition(Unit value) { - ShapePosition = ShapePosition.Undefined; // BUG + ShapePosition = ShapePosition.Undefined; // BUG_OLD Position = value; } @@ -23,7 +23,7 @@ public struct LeftPosition : INullableValue LeftPosition(ShapePosition value) { if (!(value == ShapePosition.Undefined || IsValid(value))) - throw new ArgumentException(DomSR.InvalidEnumForLeftPosition); + throw new ArgumentException(MdDomMsgs.InvalidEnumForLeftPosition.Message); ShapePosition = value; Position = Unit.Empty; @@ -35,7 +35,7 @@ public struct LeftPosition : INullableValue void SetFromEnum(ShapePosition shapePosition) { if (!IsValid(shapePosition)) - throw new ArgumentException(DomSR.InvalidEnumForLeftPosition); + throw new ArgumentException(MdDomMsgs.InvalidEnumForLeftPosition.Message); ShapePosition = shapePosition; Position = Unit.Empty; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/LineFormat.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/LineFormat.cs index 817b44c5..ba72fc89 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/LineFormat.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/LineFormat.cs @@ -97,7 +97,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/PictureFormat.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/PictureFormat.cs index 1a110bba..f25ccb4b 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/PictureFormat.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/PictureFormat.cs @@ -89,7 +89,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Shape.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Shape.cs index 1f394c17..76a8ec3c 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Shape.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/Shape.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. namespace MigraDoc.DocumentObjectModel.Shapes @@ -58,7 +58,7 @@ public WrapFormat WrapFormat get => Values.WrapFormat ??= new WrapFormat(this); set { - SetParent(value); + SetParentOf(value); Values.WrapFormat = value; } } @@ -100,14 +100,14 @@ public LeftPosition Left } /// - /// Gets the line format of the shape's border. + /// Gets the line format of the shape’s border. /// public LineFormat LineFormat { get => Values.LineFormat ??= new LineFormat(this); set { - SetParent(value); + SetParentOf(value); Values.LineFormat = value; } } @@ -120,7 +120,7 @@ public FillFormat FillFormat get => Values.FillFormat ??= new FillFormat(this); set { - SetParent(value); + SetParentOf(value); Values.FillFormat = value; } } @@ -170,7 +170,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/TextFrame.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/TextFrame.cs index 9213fa36..dbbf5186 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/TextFrame.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/TextFrame.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. using MigraDoc.DocumentObjectModel.Visitors; @@ -109,7 +109,7 @@ public void Add(Image image) => Elements.Add(image); /// - /// Gets or sets the Margin between the text frame's content and its left edge. + /// Gets or sets the Margin between the text frame’s content and its left edge. /// public Unit MarginLeft { @@ -118,7 +118,7 @@ public Unit MarginLeft } /// - /// Gets or sets the Margin between the text frame's content and its right edge. + /// Gets or sets the Margin between the text frame’s content and its right edge. /// public Unit MarginRight { @@ -127,7 +127,7 @@ public Unit MarginRight } /// - /// Gets or sets the Margin between the text frame's content and its top edge. + /// Gets or sets the Margin between the text frame’s content and its top edge. /// public Unit MarginTop { @@ -136,7 +136,7 @@ public Unit MarginTop } /// - /// Gets or sets the Margin between the text frame's content and its bottom edge. + /// Gets or sets the Margin between the text frame’s content and its bottom edge. /// public Unit MarginBottom { @@ -159,7 +159,7 @@ public Unit Margin } /// - /// Gets or sets the text orientation for the text frame's content. + /// Gets or sets the text orientation for the text frame’s content. /// public TextOrientation Orientation { @@ -168,14 +168,14 @@ public TextOrientation Orientation } /// - /// The document elements that build the text frame's content. + /// The document elements that build the text frame’s content. /// public DocumentElements Elements { get => Values.Elements ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Elements = value; } } @@ -221,7 +221,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/TopPosition.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/TopPosition.cs index 739e2530..286f534b 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/TopPosition.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/TopPosition.cs @@ -13,7 +13,7 @@ public struct TopPosition : INullableValue /// TopPosition(Unit value) { - ShapePosition = ShapePosition.Undefined; // BUG? Why not Top? + ShapePosition = ShapePosition.Undefined; // BUG_OLD? Why not Top? Position = value; } @@ -23,7 +23,7 @@ public struct TopPosition : INullableValue TopPosition(ShapePosition value) { if (!(IsValid(value) || value == ShapePosition.Undefined)) - throw new ArgumentException(DomSR.InvalidEnumForTopPosition); + throw new ArgumentException(MdDomMsgs.InvalidEnumForTopPosition.Message); ShapePosition = value; Position = Unit.Empty; @@ -35,7 +35,7 @@ public struct TopPosition : INullableValue void SetFromEnum(ShapePosition shapePosition) { if (!IsValid(shapePosition)) - throw new ArgumentException(DomSR.InvalidEnumForTopPosition); + throw new ArgumentException(MdDomMsgs.InvalidEnumForTopPosition.Message); ShapePosition = shapePosition; Position = Unit.Empty; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/WrapFormat.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/WrapFormat.cs index cd2b52a7..e39c9872 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/WrapFormat.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Shapes/WrapFormat.cs @@ -102,7 +102,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Cell.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Cell.cs index 13d1ada5..ce21f9ca 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Cell.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Cell.cs @@ -84,9 +84,8 @@ internal override void ResetCachedValues() // Lazy execution makes properties slow. Calculate frequently required property values in advance. if (Parent is Cells cells) { - _table = cells.Table; - _row = cells.Row; + _table = cells.Table; } } @@ -155,9 +154,7 @@ public void Add(TextFrame textFrame) /// public Table Table { -#if NET6_0_OR_GREATER [return: MaybeNull] -#endif get { // Set in ResetCachedValues. @@ -171,16 +168,14 @@ public Table Table /// public Column Column { -#if NET6_0_OR_GREATER [return: MaybeNull] -#endif get { if (_clm is not null) return _clm; if (/*_clm == null &&*/ Parent is Cells cells) { - for (int index = 0; index < cells.Count; ++index) + for (int index = 0; index < cells.Count; index++) { //if (cells[index] == this) // _clm = Table.Columns[index]; @@ -197,9 +192,7 @@ public Column Column /// public Row Row { -#if NET6_0_OR_GREATER [return: MaybeNull] -#endif get { // Set in ResetCachedValues. @@ -225,7 +218,7 @@ public ParagraphFormat Format get => Values.Format ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Format = value; } } @@ -247,7 +240,7 @@ public Borders Borders get => Values.Borders ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Borders = value; } } @@ -260,7 +253,7 @@ public Shading Shading get => Values.Shading ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Shading = value; } } @@ -300,7 +293,7 @@ public DocumentElements Elements get => Values.Elements ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Elements = value; } } @@ -365,7 +358,7 @@ void IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, bool visitChildren) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Cells.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Cells.cs index e65080dd..302ed6b7 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Cells.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Cells.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. using System.Diagnostics.CodeAnalysis; @@ -51,9 +51,7 @@ internal override void ResetCachedValues() /// public Table Table { -#if NET6_0_OR_GREATER [return: MaybeNull] -#endif get { if (_table == null && Parent is Row rw) @@ -69,9 +67,7 @@ public Table Table /// public Row Row { -#if NET6_0_OR_GREATER [return: MaybeNull] -#endif get { return _row ??= (Parent as Row)!; } } Row? _row; @@ -96,7 +92,7 @@ public Row Row } /// - /// Resizes this cells' list if necessary. + /// Resizes these cells¹ list if necessary. /// void Resize(int index) { @@ -115,7 +111,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Column.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Column.cs index 86306faa..7d902a82 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Column.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Column.cs @@ -1,4 +1,4 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. using System.Diagnostics.CodeAnalysis; @@ -75,9 +75,7 @@ internal override void ResetCachedValues() /// public Table Table { -#if NET6_0_OR_GREATER [return: MaybeNull] -#endif get { if (_table == null) @@ -101,17 +99,17 @@ public int Index return _idx; if (Values.Index is null && Parent is Columns clms) { - for (int i = 0; i < clms.Count; ++i) + for (int idx = 0; idx < clms.Count; idx++) { - clms[i].Values.Index = i; - clms[i]._idx = i; - clms[i]._hasIdx = true; + clms[idx].Values.Index = idx; + clms[idx]._idx = idx; + clms[idx]._hasIdx = true; } if (_hasIdx) return _idx; } _hasIdx = true; - return _idx = Values.Index ?? throw new InvalidOperationException("Column index was not computed."); // TODO throw correct? Return -1 instead? + return _idx = Values.Index ?? throw new InvalidOperationException("Column index was not computed."); // TODO_OLD throw correct? Return -1 instead? } } int _idx; @@ -120,7 +118,7 @@ public int Index /// /// Gets a cell by its row index. The first cell has index 0. /// - public Cell? this[int index] => Values.Index is not null ? Table.Rows[index][Values.Index.Value] : null; // BUG Doesn't use Index property to guarantee getter loop ran. + public Cell? this[int index] => Values.Index is not null ? Table.Rows[index][Values.Index.Value] : null; // BUG_OLD Doesn’t use Index property to guarantee getter loop ran. /// /// Sets or gets the default style name for all cells of the column. @@ -140,7 +138,7 @@ public ParagraphFormat Format get => Values.Format ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Format = value; } } @@ -180,7 +178,7 @@ public Borders Borders get => Values.Borders ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Borders = value; } } @@ -212,7 +210,7 @@ public Shading Shading get => Values.Shading ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Shading = value; } } @@ -269,7 +267,7 @@ internal override void Serialize(Serializer serializer) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Columns.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Columns.cs index 2f6faf23..f9f5425d 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Columns.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Columns.cs @@ -136,7 +136,7 @@ void IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, bool visitChildren) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Row.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Row.cs index 905af47b..e0417d52 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Row.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Row.cs @@ -39,7 +39,6 @@ internal Row(DocumentObject parent) : base(parent) protected override object DeepCopy() { var row = (Row)base.DeepCopy(); - row.ResetCachedValues(); if (row.Values.Format != null) { row.Values.Format = row.Values.Format.Clone(); @@ -60,6 +59,17 @@ protected override object DeepCopy() row.Values.Cells = row.Values.Cells.Clone(); row.Values.Cells.Parent = row; } + + // Now reset cached values. + + row.ResetCachedValues(); + row.Cells.ResetCachedValues(); + for (var columnIndex = 0; columnIndex < row.Cells.Count; columnIndex++) + { + var cell = row.Cells[columnIndex]; + cell.ResetCachedValues(); + } + return row; } @@ -85,7 +95,16 @@ internal override void ResetCachedValues() if (Parent is Rows rws) { + // All children must update their ancestors. + // Now reset cached values. + Cells.ResetCachedValues(); + // Assign _table before resetting children that may depend on Table of their parent. _table = rws.Table; + for (var columnIndex = 0; columnIndex < Cells.Count; columnIndex++) + { + var cell = Cells[columnIndex]; + cell.ResetCachedValues(); + } } } @@ -94,9 +113,7 @@ internal override void ResetCachedValues() /// public Table Table { -#if NET6_0_OR_GREATER [return: MaybeNull] -#endif get { // Set in ResetCachedValues. @@ -140,7 +157,7 @@ public ParagraphFormat Format get => Values.Format ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Format = value; } } @@ -207,7 +224,7 @@ public Borders Borders get => Values.Borders ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Borders = value; } } @@ -220,7 +237,7 @@ public Shading Shading get => Values.Shading ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Shading = value; } } @@ -243,7 +260,7 @@ public Cells Cells get => Values.Cells ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Cells = value; } } @@ -326,7 +343,7 @@ void IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, bool visitChildren) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Rows.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Rows.cs index f99884fa..ce1a1a7c 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Rows.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Rows.cs @@ -175,7 +175,7 @@ void IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, bool visitChildren) } /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Table.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Table.cs index 5898315e..30f08a83 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Table.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/Table.cs @@ -64,13 +64,29 @@ protected override object DeepCopy() table.Values.Shading = table.Values.Shading.Clone(); table.Values.Shading.Parent = table; } + + // Now reset cached values. + + table.ResetCachedValues(); + for (var rowIndex = 0; rowIndex < table.Rows.Count; rowIndex++) + { + var row = table.Rows[rowIndex]; + row.ResetCachedValues(); + row.Cells.ResetCachedValues(); + for (var columnIndex = 0; columnIndex < row.Cells.Count; columnIndex++) + { + var cell = row.Cells[columnIndex]; + cell.ResetCachedValues(); + } + } + return table; } /// /// Adds a new column to the table. Allowed only before any row was added. /// - public Column AddColumn() + public Column AddColumn() => Columns.AddColumn(); /// @@ -86,7 +102,7 @@ public Column AddColumn(Unit width) /// /// Adds a new row to the table. Allowed only if at least one column was added. /// - public Row AddRow() + public Row AddRow() => Rows.AddRow(); /// @@ -119,7 +135,7 @@ public void SetShading(int clm, int row, int clms, int rows, Color clr) for (int r = row; r <= maxRow; r++) { var currentRow = Rows[r]; - for (int c = clm; c <= maxClm; c++) + for (int c = clm; c <= maxClm; c++) currentRow[c].Shading.Color = clr; } } @@ -224,7 +240,7 @@ public Columns Columns get => Values.Columns ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Columns = value; } } @@ -237,7 +253,7 @@ public Rows Rows get => Values.Rows ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Rows = value; } } @@ -259,7 +275,7 @@ public ParagraphFormat Format get => Values.Format ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Format = value; } } @@ -308,7 +324,7 @@ public Borders Borders get => Values.Borders ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Borders = value; } } @@ -321,7 +337,7 @@ public Shading Shading get => Values.Shading ??= new(this); set { - SetParent(value); + SetParentOf(value); Values.Shading = value; } } @@ -406,7 +422,7 @@ void IVisitable.AcceptVisitor(DocumentObjectVisitor visitor, bool visitChildren) public Cell this[int rwIdx, int clmIdx] => Rows[rwIdx].Cells[clmIdx]; /// - /// Returns the meta object of this instance. + /// Returns the metaobject of this instance. /// internal override Meta Meta => TheMeta; diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/enums/VerticalAlignment.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/enums/VerticalAlignment.cs index c1c0b248..aa2808f8 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/enums/VerticalAlignment.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Tables/enums/VerticalAlignment.cs @@ -1,10 +1,10 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. namespace MigraDoc.DocumentObjectModel.Tables { /// - /// Specifies the vertical alignment of the cell's content. + /// Specifies the vertical alignment of the cell’s content. /// public enum VerticalAlignment { diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/CellComparer.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/CellComparer.cs index 1482aba4..a97aeb0f 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/CellComparer.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/CellComparer.cs @@ -11,45 +11,9 @@ namespace MigraDoc.DocumentObjectModel.Visitors /// public class CellComparer : IComparer { - // AG_HACK - //public int Compare(object lhs, object rhs) - //{ - // if (!(lhs is Cell)) - // throw new ArgumentException(DomSR.CompareJustCells, "lhs"); - - // if (!(rhs is Cell)) - // throw new ArgumentException(DomSR.CompareJustCells, "rhs"); - - // Cell cellLhs = lhs as Cell; - // Cell cellRhs = rhs as Cell; - // int rowCmpr = cellLhs.Row.Index - cellRhs.Row.Index; - // if (rowCmpr != 0) - // return rowCmpr; - - // return cellLhs.Column.Index - cellRhs.Column.Index; - //} - - //int IComparer.Compare(object lhs, object rhs) - //{ - // if (!(lhs is Cell)) - // throw new ArgumentException(DomSR.CompareJustCells, "lhs"); - - // if (!(rhs is Cell)) - // throw new ArgumentException(DomSR.CompareJustCells, "rhs"); - - // Cell cellLhs = lhs as Cell; - // Cell cellRhs = rhs as Cell; - // int rowCmpr = cellLhs.Row.Index - cellRhs.Row.Index; - // if (rowCmpr != 0) - // return rowCmpr; - - // return cellLhs.Column.Index - cellRhs.Column.Index; - //} - /// /// Compares the specified cells. /// - /// public int Compare(Cell? cellLhs, Cell? cellRhs) { if (cellLhs != null && cellRhs != null) @@ -60,7 +24,6 @@ public int Compare(Cell? cellLhs, Cell? cellRhs) return cellLhs.Column.Index - cellRhs.Column.Index; } - throw new NullReferenceException("Cells must not be null for comparison."); } } diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/ElementsExtensions.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/ElementsExtensions.cs index c532a62b..dbcfa7f5 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/ElementsExtensions.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/ElementsExtensions.cs @@ -173,7 +173,6 @@ public static IEnumerable GetElementsRecursively(this DocumentObject docum /// /// The type to be filtered. /// The document objects. - /// public static IEnumerable Filter(this IEnumerable elements) where T : DocumentObject { @@ -185,7 +184,7 @@ public static IEnumerable Filter(this IEnumerable element } /// - /// Gets the text content of the cell's elements as a string. + /// Gets the text content of the cell’s elements as a string. /// /// The cell. /// Text content as string. @@ -195,7 +194,7 @@ public static string GetText(this Cell cell) } /// - /// Gets the text content of the paragraph's elements as a string. + /// Gets the text content of the paragraph’s elements as a string. /// /// The paragraph. /// Text content as string. @@ -205,7 +204,7 @@ public static string GetText(this Paragraph paragraph) } /// - /// Gets the text content of the hyperlinks's elements as a string. + /// Gets the text content of the hyperlinks’s elements as a string. /// /// The hyperlink. /// Text content as string. @@ -362,7 +361,7 @@ public static Unit GetUsedFormatValue(this DocumentObject documentObject, Func

The empty value to return if the value is not assigned or could not be determined. public static T GetUsedFormatValue(this DocumentObject documentObject, Func getValue, Func isEmpty, T emptyValue) { - // Won't work properly inside of tables, as the formats of table columns and rows are not considered as used value. Supplement this when needed. + // Won’t work properly inside of tables, as the formats of table columns and rows are not considered as used value. Supplement this when needed. T result; var format = documentObject.GetFormat(); @@ -391,7 +390,7 @@ public static T GetUsedFormatValue(this DocumentObject documentObject, Func

The empty value to return if the value is not assigned or could not be determined. public static T GetUsedFormatValue(this DocumentObject documentObject, Func getValue, Func isEmpty, T emptyValue) { - // Won't work properly inside of tables, as the formats of table columns and rows are not considered as used value. Supplement this when needed. + // Won’t work properly inside of tables, as the formats of table columns and rows are not considered as used value. Supplement this when needed. T result; var font = documentObject.GetFont(); @@ -440,8 +439,8 @@ public static T GetUsedFormatValue(this DocumentObject documentObject, Func= columns) throw TH.InvalidOperationException_MergeRightTooLarge(rwIdx, clmIdx, mergeRight); - for (int idxMergedRows = 0; idxMergedRows <= mergeDown; ++idxMergedRows) + for (int idxMergedRows = 0; idxMergedRows <= mergeDown; idxMergedRows++) { - for (int idxMergedColumns = 0; idxMergedColumns <= mergeRight; ++idxMergedColumns) + for (int idxMergedColumns = 0; idxMergedColumns <= mergeRight; idxMergedColumns++) { flags[rwIdx + idxMergedRows, clmIdx + idxMergedColumns] = true; } @@ -220,8 +220,7 @@ Borders GetEffectiveBordersInternal(Cell cell, bool considerHeadingRows, int? co if (nbrBrdrs != null && GetEffectiveBorderWidth(nbrBrdrs, BorderType.Left) > GetEffectiveBorderWidth(borders, BorderType.Right)) borders.SetValue("Right", GetBorderFromBorders(nbrBrdrs, BorderType.Left)); } - - + // If considering heading rows and if cellRowIndex is an index a header is been inserted at, override topRowIndex with the last heading row. // This way for rows after a repeated heading row the original last heading row is considered as the top neighbor for top border determination // instead of the last content row on the page before. @@ -237,7 +236,7 @@ Borders GetEffectiveBordersInternal(Cell cell, bool considerHeadingRows, int? co var topNeighbor = GetNeighborTop(cellIdx, topRowIndexOverride); // If not considering heading rows and if the topNeighbor is a heading row, set it to null to ignore it for top border determination. - // This way the first content row's top border doesn't possibly get the bottom border of the original last heading row. + // This way the first content row’s top border doesn’t possibly get the bottom border of the original last heading row. // This behaviour is wanted for RTF only, where all heading rows repetitions are rendered with their border formatting in the RTF application when displaying the // document and where content row movement or insertion in the RTF application must not copy formatting values that actually belong to the original last heading row. if (!considerHeadingRows && topNeighbor?.Row.HeadingFormat == true) @@ -250,7 +249,6 @@ Borders GetEffectiveBordersInternal(Cell cell, bool considerHeadingRows, int? co borders.SetValue("Top", GetBorderFromBorders(nbrBrdrs, BorderType.Bottom)); } - var bottomNeighbor = GetNeighborBottom(cellIdx); if (bottomNeighbor != null && bottomNeighbor.RoundedCorner != RoundedCorner.TopLeft && bottomNeighbor.RoundedCorner != RoundedCorner.TopRight) { @@ -301,7 +299,7 @@ Borders GetEffectiveBordersInternal(Cell cell, bool considerHeadingRows, int? co ///

/// Returns the border of the given borders-object of the specified type (top, bottom, ...). - /// If that border doesn't exist, it returns a new border object that inherits all properties from the given borders object. + /// If that border doesn’t exist, it returns a new border object that inherits all properties from the given borders object. /// static Border GetBorderFromBorders(Borders borders, BorderType type) { @@ -397,7 +395,7 @@ static Unit GetEffectiveBorderWidth(Borders? borders, BorderType type) } /// - /// Gets the specified cell's uppermost neighbor at the specified position. + /// Gets the specified cell’s uppermost neighbor at the specified position. /// [Obsolete("Use GetNeighborTop, GetNeighborBottom, GetNeighborLeft, GetNeighborRight instead.")] Cell? GetNeighbor(int cellIdx, NeighborPosition position) @@ -428,7 +426,7 @@ static Unit GetEffectiveBorderWidth(Borders? borders, BorderType type) if (cell2.Row.Index == cell.Row.Index) return cell2; } - for (int index = cellIdx + 1; index < Count; ++index) + for (int index = cellIdx + 1; index < Count; index++) { var currCell = this[index]; if (IsNeighbor(cell, currCell, position)) @@ -437,7 +435,7 @@ static Unit GetEffectiveBorderWidth(Borders? borders, BorderType type) break; case NeighborPosition.Bottom: - for (int index = cellIdx + 1; index < Count; ++index) + for (int index = cellIdx + 1; index < Count; index++) { var currCell = this[index]; if (IsNeighbor(cell, currCell, position)) @@ -503,7 +501,7 @@ static Unit GetEffectiveBorderWidth(Borders? borders, BorderType type) if (cell2.Row.Index == cell.Row.Index) return cell2; } - for (var index = cellIdx + 2; index < Count; ++index) + for (var index = cellIdx + 2; index < Count; index++) { var currCell = this[index]; if (IsNeighborRight(cell, currCell)) @@ -518,7 +516,7 @@ static Unit GetEffectiveBorderWidth(Borders? borders, BorderType type) if (cell.Row.Index + cell.MergeDown == cell.Table.Rows.Count - 1) return null; - for (var index = cellIdx + 1; index < Count; ++index) + for (var index = cellIdx + 1; index < Count; index++) { var currCell = this[index]; if (IsNeighborBottom(cell, currCell)) @@ -613,7 +611,6 @@ bool IsNeighborTop(Cell cell1, Cell cell2, int? topRowIndexOverride = null) c2CI <= c1CI; } - readonly SortedSet _headerInsertionRowIndices = new(); /// diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/PdfFlattenVisitor.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/PdfFlattenVisitor.cs index 8699a716..2dbe6bb1 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/PdfFlattenVisitor.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/PdfFlattenVisitor.cs @@ -21,7 +21,7 @@ internal override void VisitDocumentElements(DocumentElements elements) #if true // New version without sorted list. int count = elements.Count; - for (int idx = 0; idx < count; ++idx) + for (int idx = 0; idx < count; idx++) { if (elements[idx] is Paragraph paragraph) { @@ -41,7 +41,7 @@ internal override void VisitDocumentElements(DocumentElements elements) #else SortedList splitParaList = new SortedList(); - for (int idx = 0; idx < elements.Count; ++idx) + for (int idx = 0; idx < elements.Count; idx++) { Paragraph paragraph = elements[idx] as Paragraph; if (paragraph != null) @@ -53,7 +53,7 @@ internal override void VisitDocumentElements(DocumentElements elements) } int insertedObjects = 0; - for (int idx = 0; idx < splitParaList.Count; ++idx) + for (int idx = 0; idx < splitParaList.Count; idx++) { int insertPosition = (int)splitParaList.GetKey(idx); Paragraph[] paragraphs = (Paragraph[])splitParaList.GetByIndex(idx); @@ -78,7 +78,7 @@ internal override void VisitDocumentObjectCollection(DocumentObjectCollection el List textIndices = new List(); if (elements is ParagraphElements) { - for (int idx = 0; idx < elements.Count; ++idx) + for (int idx = 0; idx < elements.Count; idx++) { if (elements[idx] is Text) textIndices.Add(idx); @@ -97,7 +97,7 @@ internal override void VisitDocumentObjectCollection(DocumentObjectCollection el for (var chIdx = 0; chIdx < content.Length; chIdx++) { var ch = content[chIdx]; - // TODO Add support for other breaking spaces (en space, em space, &c.). + // TODO_OLD Add support for other breaking spaces (en space, em space, &c.). switch (ch) { case ' ': @@ -117,14 +117,14 @@ internal override void VisitDocumentObjectCollection(DocumentObjectCollection el case '-': // minus. currentString.Append('-'); - // Recognize minus as a sign, if it's the first char of the currently processed string... + // Recognize minus as a sign, if it’s the first char of the currently processed string... bool isSign; if (currentString.Length != 1) isSign = false; else { var nextIdx = chIdx + 1; - // ...and if it's followed by a number... + // ...and if it’s followed by a number... if (nextIdx < content.Length && char.IsNumber(content[nextIdx])) isSign = true; else @@ -190,10 +190,10 @@ internal override void VisitFormattedText(FormattedText formattedText) var document = formattedText.Document; ParagraphFormat? format = null; - var style = document.Styles[formattedText.Values.Style]; // BUG??? We get "null" for "null". + var style = document.Styles[formattedText.Values.Style]; // BUG_OLD??? We get "null" for "null". if (style != null) format = style.Values.ParagraphFormat; - else if (!String.IsNullOrEmpty(formattedText.Values.Style) /*!= ""*/) // BUG??? Treat "null" like empty string. + else if (!String.IsNullOrEmpty(formattedText.Values.Style) /*!= ""*/) // BUG_OLD??? Treat "null" like empty string. format = document.Styles[StyleNames.InvalidStyleName]?.Values.ParagraphFormat ?? throw new InvalidOperationException("Style does not exist."); if (format != null) @@ -201,7 +201,7 @@ internal override void VisitFormattedText(FormattedText formattedText) if (formattedText.Values.Font is null && format.Values.Font is not null) formattedText.Font = format.Values.Font.Clone(); else if (format.Values.Font is not null) - FlattenFont(formattedText.Values.Font!, format.Values.Font); + VisitorBase.FlattenFont(formattedText.Values.Font!, format.Values.Font); } var parentFont = GetParentFont(formattedText); @@ -209,38 +209,37 @@ internal override void VisitFormattedText(FormattedText formattedText) if (formattedText.Values.Font is null && parentFont is not null) formattedText.Font = parentFont.Clone(); else if (parentFont != null) - FlattenFont(formattedText.Values.Font!, parentFont); + VisitorBase.FlattenFont(formattedText.Values.Font!, parentFont); } internal override void VisitHyperlink(Hyperlink hyperlink) { // If NoHyperlinkStyle is set to true, the Hyperlink shall look like the surrounding text without using the Hyperlink Style. - // May be used for text references, e. g. in tables, which shall not be rendered as links. + // May be used for text references, e.g. in tables, which shall not be rendered as links. if (!hyperlink.NoHyperlinkStyle) { - var styleFont = hyperlink.Document.Styles[StyleNames.Hyperlink]!.Font; // BUG ??? "!" + var styleFont = hyperlink.Document.Styles[StyleNames.Hyperlink]!.Font; // BUG_OLD ??? "!" if (hyperlink.Values.Font is null) hyperlink.Font = styleFont.Clone(); else - FlattenFont(hyperlink.Values.Font, styleFont); + VisitorBase.FlattenFont(hyperlink.Values.Font, styleFont); } var parentFont = GetParentFont(hyperlink); if (hyperlink.Values.Font is null && parentFont is not null) hyperlink.Font = parentFont.Clone(); else - FlattenFont(hyperlink.Values.Font!, parentFont!); + VisitorBase.FlattenFont(hyperlink.Values.Font!, parentFont!); } /// /// Get the font for the parent of a given object. /// /// The object to start with. - /// /// Exception that is thrown of the parent object is neither Paragraph nor Hyperlink or FormattedText. protected Font? GetParentFont(DocumentObject obj) { - DocumentObject parentElements = DocumentRelations.GetParent(obj) ?? NRT.ThrowOnNull(); // BUG Throwing on null; + DocumentObject parentElements = DocumentRelations.GetParent(obj) ?? NRT.ThrowOnNull(); // BUG_OLD Throwing on null; DocumentObject? parentObject = DocumentRelations.GetParent(parentElements); Font? parentFont; if (parentObject is Paragraph paragraph) diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/RtfFlattenVisitor.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/RtfFlattenVisitor.cs index 914e0b9f..b5095362 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/RtfFlattenVisitor.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/RtfFlattenVisitor.cs @@ -18,14 +18,14 @@ internal override void VisitFormattedText(FormattedText formattedText) if (style != null) format = style.Values.ParagraphFormat; else if (!String.IsNullOrEmpty(formattedText.Values.Style)) - format = document.Styles[StyleNames.InvalidStyleName]!.Values.ParagraphFormat; // BUG: Clone here? + format = document.Styles[StyleNames.InvalidStyleName]!.Values.ParagraphFormat; // BUG_OLD: Clone here? if (format != null) { if (formattedText.Values.Font is null) - formattedText.Font = format.Values.Font?.Clone() ?? NRT.ThrowOnNull(); // BUG Throwing if format.Values.Font is null + formattedText.Font = format.Values.Font?.Clone() ?? NRT.ThrowOnNull(); // BUG_OLD Throwing if format.Values.Font is null else if (format.Values.Font is not null) - FlattenFont(formattedText.Values.Font, format.Values.Font); + VisitorBase.FlattenFont(formattedText.Values.Font, format.Values.Font); } } @@ -35,7 +35,7 @@ internal override void VisitHyperlink(Hyperlink hyperlink) if (hyperlink.Values.Font is null) hyperlink.Font = styleFont.Clone(); else - FlattenFont(hyperlink.Values.Font, styleFont); + VisitorBase.FlattenFont(hyperlink.Values.Font, styleFont); } } } diff --git a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/VisitorBase.cs b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/VisitorBase.cs index 13a3b654..987686f3 100644 --- a/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/VisitorBase.cs +++ b/src/foundation/src/MigraDoc/src/MigraDoc.DocumentObjectModel/DocumentObjectModel.Visitors/VisitorBase.cs @@ -1,10 +1,13 @@ -// MigraDoc - Creating Documents on the Fly +// MigraDoc - Creating Documents on the Fly // See the LICENSE file in the solution root for more information. using MigraDoc.DocumentObjectModel.Tables; using MigraDoc.DocumentObjectModel.Shapes; using MigraDoc.DocumentObjectModel.Shapes.Charts; +// ReSharper disable ConvertIfStatementToNullCoalescingAssignment +#pragma warning disable IDE0074 // Use compound assignment + namespace MigraDoc.DocumentObjectModel.Visitors { /// @@ -23,9 +26,9 @@ public override void Visit(DocumentObject documentObject) } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenParagraphFormat(ParagraphFormat format, ParagraphFormat? refFormat) + protected static void FlattenParagraphFormat(ParagraphFormat format, ParagraphFormat? refFormat) { if (refFormat != null) { @@ -51,6 +54,7 @@ protected void FlattenParagraphFormat(ParagraphFormat format, ParagraphFormat? r if (values.LineSpacingRule is null) values.LineSpacingRule = refValues.LineSpacingRule; + if (values.LineSpacing is null) values.LineSpacing = refValues.LineSpacing; @@ -79,7 +83,7 @@ protected void FlattenParagraphFormat(ParagraphFormat format, ParagraphFormat? r } } else if (refValues.Font is not null) - FlattenFont(values.Font, refValues.Font); + VisitorBase.FlattenFont(values.Font, refValues.Font); if (values.Shading is null) { @@ -110,9 +114,9 @@ protected void FlattenParagraphFormat(ParagraphFormat format, ParagraphFormat? r } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenListInfo(ListInfo listInfo, ListInfo refListInfo) + protected static void FlattenListInfo(ListInfo listInfo, ListInfo refListInfo) { if (listInfo.Values.ContinuePreviousList is null) listInfo.Values.ContinuePreviousList = refListInfo.Values.ContinuePreviousList; @@ -123,9 +127,9 @@ protected void FlattenListInfo(ListInfo listInfo, ListInfo refListInfo) } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenFont(Font font, Font refFont) // BUG params must be not-nullable + protected static void FlattenFont(Font font, Font refFont) { if (font == null) throw new ArgumentNullException(nameof(font)); @@ -151,9 +155,9 @@ protected void FlattenFont(Font font, Font refFont) // BUG params must be not-n } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenShading(Shading shading, Shading refShading) + protected static void FlattenShading(Shading shading, Shading refShading) { //fClear? if (shading.Values.Visible is null) @@ -163,9 +167,9 @@ protected void FlattenShading(Shading shading, Shading refShading) } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected Border FlattenedBorderFromBorders(Border? border, Borders parentBorders) + protected static Border FlattenedBorderFromBorders(Border? border, Borders parentBorders) { if (border == null) border = new Border(parentBorders); @@ -186,9 +190,9 @@ protected Border FlattenedBorderFromBorders(Border? border, Borders parentBorder } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenBorders(Borders borders, Borders refBorders) + protected static void FlattenBorders(Borders borders, Borders refBorders) { borders.Values.Visible ??= refBorders.Values.Visible; if (borders.Values.Width.IsValueNullOrEmpty()) @@ -232,9 +236,9 @@ protected void FlattenBorders(Borders borders, Borders refBorders) } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenBorder(Border border, Border refBorder) + protected static void FlattenBorder(Border border, Border refBorder) { border.Values.Visible ??= refBorder.Values.Visible; @@ -252,9 +256,9 @@ protected void FlattenBorder(Border border, Border refBorder) } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenTabStops(TabStops tabStops, TabStops refTabStops) + protected static void FlattenTabStops(TabStops tabStops, TabStops refTabStops) { if (!tabStops.TabsCleared) { @@ -267,9 +271,9 @@ protected void FlattenTabStops(TabStops tabStops, TabStops refTabStops) for (int i = 0; i < tabStops.Count; i++) { - TabStop tabStop = tabStops[i]; + var tabStop = tabStops[i]; if (!tabStop.AddTab) - tabStops.RemoveObjectAt(i); + tabStops.RemoveObjectAt(i--); } // The TabStopCollection is complete now. @@ -278,50 +282,96 @@ protected void FlattenTabStops(TabStops tabStops, TabStops refTabStops) } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenPageSetup(PageSetup pageSetup, PageSetup refPageSetup) + protected static void FlattenPageSetup(PageSetup pageSetup, PageSetup refPageSetup) { - if (pageSetup.Values.PageWidth.IsValueNullOrEmpty() && pageSetup.Values.PageHeight is null) + var definesOrientation = pageSetup.Values.Orientation is not null; + + // Inherit orientation now, as the value is needed below. + if (pageSetup.Values.Orientation is null) + pageSetup.Values.Orientation = refPageSetup.Values.Orientation; + + Debug.Assert(pageSetup.Values.Orientation is not null); + + var realizeOrientation = false; // The default is updating the Orientation value due to PageWidth and PageHeight instead of realizing the Orientation. + + // PageWidth and PageHeight are not set. + if (pageSetup.Values.PageWidth.IsValueNullOrEmpty() && pageSetup.Values.PageHeight.IsValueNullOrEmpty()) { + // If all values are null, inherit them from refPageSetup. if (pageSetup.Values.PageFormat is null) { pageSetup.Values.PageWidth = refPageSetup.Values.PageWidth; pageSetup.Values.PageHeight = refPageSetup.Values.PageHeight; pageSetup.Values.PageFormat = refPageSetup.Values.PageFormat; + + // Realize Orientation, if no PageWidth, PageHeight and PageFormat, but Orientation was set for this PageSetup. + if (definesOrientation) + realizeOrientation = true; } + // If only PageFormat is set, calculate PageWidth and PageHeight from PageFormat. else { + // Realize Orientation, if only PageFormat was set for this PageSetup. + realizeOrientation = true; + // Cannot use properties as out parameters, so use local vars. PageSetup.GetPageSize(pageSetup.PageFormat, out Unit width, out Unit height); pageSetup.Values.PageWidth = width; pageSetup.Values.PageHeight = height; } } + // At least PageWidth or PageHeight is set. else { if (pageSetup.Values.PageWidth.IsValueNullOrEmpty()) { + // If only PageHeight is set, inherit PageFormat and PageWidth. if (pageSetup.Values.PageFormat is null) - pageSetup.Values.PageHeight = refPageSetup.Values.PageHeight; + { + pageSetup.Values.PageWidth = refPageSetup.Values.PageWidth; + pageSetup.Values.PageFormat = refPageSetup.Values.PageFormat; + } + // If only PageHeight and PageFormat are set, calculate PageWidth from PageFormat. else { - PageSetup.GetPageSize(pageSetup.PageFormat, out _, out Unit height); - pageSetup.Values.PageHeight = height; + PageSetup.GetPageSize(pageSetup.PageFormat, out Unit width, out Unit height); + // Take PageWidth according to page format orientation, even if Orientation may be updated later due to the final PageWidth and PageHeight. + pageSetup.Values.PageWidth = pageSetup.Orientation == Orientation.Landscape ? height : width; } } else if (pageSetup.Values.PageHeight.IsValueNullOrEmpty()) { + // If only PageWidth is set, inherit PageFormat and PageHeight. if (pageSetup.Values.PageFormat is null) - pageSetup.Values.PageWidth = refPageSetup.Values.PageWidth; + { + pageSetup.Values.PageHeight = refPageSetup.Values.PageHeight; + pageSetup.Values.PageFormat = refPageSetup.Values.PageFormat; + } + // If only PageWidth and PageFormat are set, calculate PageHeight from PageFormat. else { - PageSetup.GetPageSize(pageSetup.PageFormat, out Unit width, out _); - pageSetup.Values.PageWidth = width; + PageSetup.GetPageSize(pageSetup.PageFormat, out Unit width, out Unit height); + // Take PageHeight according to page format orientation, even if Orientation may be updated later due to the final PageWidth and PageHeight. + pageSetup.Values.PageHeight = pageSetup.Orientation == Orientation.Landscape ? width : height; } } } + Debug.Assert(!pageSetup.Values.PageWidth.IsValueNullOrEmpty() || !pageSetup.Values.PageHeight.IsValueNullOrEmpty()); + + // If the page size is newly initialized from PageFormat and/or Orientation only, swap PageWidth and PageHeight due to Orientation, if necessary. + if (realizeOrientation) + RealizeOrientation(pageSetup); + // If the page size is inherited or set by PageWidth and PageHeight, update Orientation due to PageWidth and PageHeight. + // For inherited PageFormat values, PageWidth and PageHeight were already swapped for the source PageSetup, if necessary. + else + UpdateOrientation(pageSetup); + + Debug.Assert((pageSetup.Values.Orientation == Orientation.Portrait && pageSetup.Values.PageWidth <= pageSetup.Values.PageHeight) || + (pageSetup.Values.Orientation == Orientation.Landscape && pageSetup.Values.PageWidth > pageSetup.Values.PageHeight)); + // if (pageSetup.pageWidth.IsNull) // pageSetup.pageWidth = refPageSetup.pageWidth; // if (pageSetup.pageHeight.IsNull) @@ -330,8 +380,6 @@ protected void FlattenPageSetup(PageSetup pageSetup, PageSetup refPageSetup) // pageSetup.pageFormat = refPageSetup.pageFormat; if (pageSetup.Values.SectionStart is null) pageSetup.Values.SectionStart = refPageSetup.Values.SectionStart; - if (pageSetup.Values.Orientation is null) - pageSetup.Values.Orientation = refPageSetup.Values.Orientation; if (pageSetup.Values.TopMargin.IsValueNullOrEmpty()) pageSetup.Values.TopMargin = refPageSetup.Values.TopMargin; if (pageSetup.Values.BottomMargin.IsValueNullOrEmpty()) @@ -355,21 +403,55 @@ protected void FlattenPageSetup(PageSetup pageSetup, PageSetup refPageSetup) } /// - /// Flattens the the specified document object. + /// Realizes the Orientation for PageSetup. + /// This shall be done for PageSetups initialized with PageFormat and or Orientation only. + /// For quadratic pages, Orientation is set to Portrait, as it is Portrait by definition. + /// Otherwise, PageWidth and PageHeight are swapped, if necessary. + /// + static void RealizeOrientation(PageSetup pageSetup) + { + var effectiveOrientation = pageSetup.Orientation; + + // Set quadratic page to Portrait. + if (pageSetup.Values.PageWidth == pageSetup.Values.PageHeight) + pageSetup.Values.Orientation = Orientation.Portrait; + // Otherwise swap PageWidth and PageHeight, if not fitting to effectiveOrientation. + else if ((pageSetup.Values.PageWidth > pageSetup.Values.PageHeight && effectiveOrientation == Orientation.Portrait) || + (pageSetup.Values.PageWidth < pageSetup.Values.PageHeight && effectiveOrientation == Orientation.Landscape)) + (pageSetup.Values.PageWidth, pageSetup.Values.PageHeight) = (pageSetup.Values.PageHeight, pageSetup.Values.PageWidth); + } + + /// + /// Updates the orientation according to a PageSetup’s PageWidth and PageHeight. /// - protected void FlattenHeaderFooter(HeaderFooter headerFooter, bool isHeader) + static void UpdateOrientation(PageSetup pageSetup) + { + // Quadratic page is considered to be Portrait. + pageSetup.Values.Orientation = pageSetup.Values.PageWidth <= pageSetup.Values.PageHeight + ? Orientation.Portrait + : Orientation.Landscape; + } + + /// + /// Flattens the specified document object. + /// +#pragma warning disable IDE0060 + protected static void FlattenHeaderFooter(HeaderFooter headerFooter, bool isHeader) +#pragma warning restore IDE0060 { } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenFillFormat(FillFormat? fillFormat) +#pragma warning disable IDE0060 + protected static void FlattenFillFormat(FillFormat? fillFormat) +#pragma warning restore IDE0060 { } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenLineFormat(LineFormat? lineFormat, LineFormat? refLineFormat) + protected static void FlattenLineFormat(LineFormat? lineFormat, LineFormat? refLineFormat) { if (refLineFormat != null && lineFormat != null) { @@ -379,9 +461,9 @@ protected void FlattenLineFormat(LineFormat? lineFormat, LineFormat? refLineForm } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenAxis(Axis? axis) + protected static void FlattenAxis(Axis? axis) { if (axis == null) return; @@ -390,9 +472,12 @@ protected void FlattenAxis(Axis? axis) { Values = { Width = 0.15 } }; - if (axis.Values.HasMajorGridlines == true && axis.Values.MajorGridlines is not null) + //if (axis.Values.HasMajorGridlines == true && axis.Values.MajorGridlines is not null) + if (axis.Values is { HasMajorGridlines: true, MajorGridlines: not null }) FlattenLineFormat(axis.Values.MajorGridlines.Values.LineFormat, refLineFormat); - if (axis.Values.HasMinorGridlines == true && axis.Values.MinorGridlines is not null) + + //if (axis.Values.HasMinorGridlines == true && axis.Values.MinorGridlines is not null) + if (axis.Values is { HasMinorGridlines: true, MinorGridlines: not null }) FlattenLineFormat(axis.Values.MinorGridlines.Values.LineFormat, refLineFormat); refLineFormat.Values.Width = 0.4; @@ -412,17 +497,21 @@ protected void FlattenAxis(Axis? axis) } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenPlotArea(PlotArea? plotArea) +#pragma warning disable IDE0060 + protected static void FlattenPlotArea(PlotArea? plotArea) +#pragma warning restore IDE0060 { // plotArea can be null. } /// - /// Flattens the the specified document object. + /// Flattens the specified document object. /// - protected void FlattenDataLabel(DataLabel? dataLabel) +#pragma warning disable IDE0060 // Remove unused parameter + protected static void FlattenDataLabel(DataLabel? dataLabel) +#pragma warning restore IDE0060 // Remove unused parameter { } // Chart @@ -487,13 +576,13 @@ internal override void VisitFootnote(Footnote footnote) ParagraphFormat? format; - var style = document.Styles[footnote.Values.Style!]; // BUG??? "!" added. + var style = document.Styles[footnote.Values.Style!]; // BUG_OLD??? "!" added. if (style != null) format = ParagraphFormatFromStyle(style); else { footnote.Style = StyleNames.Footnote; - format = document.Styles[StyleNames.Footnote]!.Values.ParagraphFormat!; // BUG: Check null + format = document.Styles[StyleNames.Footnote]!.Values.ParagraphFormat!; // BUG_OLD: Check null } if (footnote.Values.Format is null) @@ -512,7 +601,7 @@ internal override void VisitParagraph(Paragraph paragraph) ParagraphFormat format; var currentElementHolder = GetDocumentElementHolder(paragraph); - var style = document.Styles[paragraph.Values.Style ?? String.Empty]; + var style = document.Styles[paragraph.Values.Style ?? ""]; if (style != null) format = ParagraphFormatFromStyle(style); @@ -545,12 +634,12 @@ internal override void VisitParagraph(Paragraph paragraph) } else if (currentElementHolder is TextArea area) { - paragraph.Style = area.Style; // BUG ??? + paragraph.Style = area.Style; // BUG_OLD ??? format = area.Values.Format ?? NRT.ThrowOnNull(); } else { - if (!String.IsNullOrEmpty(paragraph.Values.Style)) //StL:BUG see old code + if (!String.IsNullOrEmpty(paragraph.Values.Style)) //StL:BUG_OLD see old code paragraph.Style = StyleNames.InvalidStyleName; else paragraph.Style = StyleNames.Normal; @@ -559,22 +648,19 @@ internal override void VisitParagraph(Paragraph paragraph) if (paragraph.Values.Format == null) { - paragraph.Format = format.Clone(); //StL:BUG see old code + paragraph.Format = format.Clone(); //StL:BUG_OLD see old code paragraph.Format.Parent = paragraph; } else FlattenParagraphFormat(paragraph.Format, format); } + // Section internal override void VisitHeaderFooter(HeaderFooter headerFooter) { var document = headerFooter.Document; - string styleString; - if (headerFooter.IsHeader) - styleString = StyleNames.Header; - else - styleString = StyleNames.Footer; + var styleString = headerFooter.IsHeader ? StyleNames.Header : StyleNames.Footer; ParagraphFormat format; var style = document.Styles[headerFooter.Values.Style]; @@ -707,7 +793,7 @@ internal override void VisitRows(Rows rows) /// Returns a paragraph format object initialized by the given style. /// It differs from style.ParagraphFormat if style is a character style. /// - ParagraphFormat ParagraphFormatFromStyle(Style style) + static ParagraphFormat ParagraphFormatFromStyle(Style style) { if (style.Type == StyleType.Character) { @@ -930,15 +1016,14 @@ internal override void VisitTextArea(TextArea? textArea) if (textArea?.Values.Elements == null) return; - var document = textArea.Document; + _ = textArea.Document; ParagraphFormat parentFormat; if (textArea.Values.Style is not null) { var style = textArea.Document.Styles[textArea.Style]; - if (style == null) - style = textArea.Document.Styles[StyleNames.InvalidStyleName] ?? NRT.ThrowOnNull