diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..fa9d759e
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,209 @@
+# Remove the line below if you want to inherit .editorconfig settings from higher directories
+root = true
+
+# C# files
+[*.cs]
+
+#### Core EditorConfig Options ####
+
+# Indentation and spacing
+indent_size = 4
+indent_style = space
+tab_width = 4
+
+# New line preferences
+end_of_line = crlf
+insert_final_newline = false
+
+#### .NET Coding Conventions ####
+
+# Organize usings
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = false
+file_header_template = unset
+
+# this. and Me. preferences
+dotnet_style_qualification_for_event = false:silent
+dotnet_style_qualification_for_field = false:silent
+dotnet_style_qualification_for_method = false:silent
+dotnet_style_qualification_for_property = false:silent
+
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true:silent
+dotnet_style_predefined_type_for_member_access = true:silent
+
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
+
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
+
+# Expression-level preferences
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_prefer_compound_assignment = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_simplified_interpolation = true:suggestion
+
+# Field preferences
+dotnet_style_readonly_field = true:suggestion
+
+# Parameter preferences
+dotnet_code_quality_unused_parameters = all:suggestion
+
+#### C# Coding Conventions ####
+
+# var preferences
+csharp_style_var_elsewhere = true:silent
+csharp_style_var_for_built_in_types = true:silent
+csharp_style_var_when_type_is_apparent = true:silent
+
+# Expression-bodied members
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+
+# Pattern matching preferences
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_prefer_switch_expression = true:suggestion
+
+# Null-checking preferences
+csharp_style_conditional_delegate_call = true:suggestion
+
+# Modifier preferences
+csharp_prefer_static_local_function = true:suggestion
+csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
+
+# Code-block preferences
+csharp_prefer_braces = true:warning
+csharp_prefer_simple_using_statement = true:suggestion
+
+# Expression-level preferences
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+csharp_style_pattern_local_over_anonymous_function = true:suggestion
+csharp_style_prefer_index_operator = true:suggestion
+csharp_style_prefer_range_operator = true:suggestion
+csharp_style_throw_expression = true:suggestion
+csharp_style_unused_value_assignment_preference = discard_variable:suggestion
+csharp_style_unused_value_expression_statement_preference = discard_variable:silent
+
+# 'using' directive preferences
+csharp_using_directive_placement = outside_namespace:silent
+
+#### C# Formatting Rules ####
+
+# New line preferences
+csharp_new_line_before_catch = true
+csharp_new_line_before_else = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_open_brace = all
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = true
+csharp_indent_labels = one_less_than_current
+csharp_indent_switch_labels = true
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Wrapping preferences
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = true
+
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+# CS1591: Missing XML comment for publicly visible type or member
+dotnet_diagnostic.CS1591.severity = suggestion
+
+
+# IDE0011: Add braces
+dotnet_diagnostic.IDE0011.severity = warning
+csharp_style_prefer_method_group_conversion = true:silent
\ No newline at end of file
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 00000000..7b0e7e65
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,15 @@
+# Lines starting with '#' are comments.
+# Each line is a file pattern followed by one or more owners.
+
+# More details are here: https://help.github.com/articles/about-codeowners/
+
+# The '*' pattern is global owners.
+
+# Order is important. The last matching pattern has the most precedence.
+# The folders are ordered as follows:
+
+# In each subsection folders are ordered first by depth, then alphabetically.
+# This should make it easy to add new rules without breaking existing ones.
+
+# Global rule:
+* @stesee
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..523c45ce
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,47 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "docker"
+ directory: "/"
+ schedule:
+ interval: weekly
+ rebase-strategy: auto
+
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: weekly
+ rebase-strategy: auto
+
+ - package-ecosystem: "npm"
+ directory: "/"
+ schedule:
+ interval: weekly
+ rebase-strategy: auto
+
+ - package-ecosystem: "nuget"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ ignore:
+ - dependency-name: "SixLabors.ImageSharp"
+ versions: ["3.x", "4.x"]
+ - dependency-name: "coverlet.collector"
+ - dependency-name: "Codeuctivity.HtmlRenderer"
+ - dependency-name: "nunit"
+ - dependency-name: "SonarAnalyzer.CSharp"
+ - dependency-name: "AngleSharp"
+ - dependency-name: "Microsoft.NET.Test.Sdk"
+ - dependency-name: "Microsoft.AspNetCore.Mvc.Testing"
+ - dependency-name: "Moq"
+ - dependency-name: "xunit"
+ - dependency-name: "xunit.runner.visualstudio"
+ - dependency-name: "MSTest.TestAdapter"
+ - dependency-name: "MSTest.TestFramework"
+ - dependency-name: "Codeuctivity.ImageSharpCompare"
+ - dependency-name: "NUnit3TestAdapter"
+ - dependency-name: "xunit.runner.console"
\ No newline at end of file
diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml
new file mode 100644
index 00000000..6ebcdab1
--- /dev/null
+++ b/.github/workflows/cla.yml
@@ -0,0 +1,36 @@
+name: "CLA Assistant"
+on:
+ issue_comment:
+ types: [created]
+ pull_request_target:
+ types: [opened, closed, synchronize]
+
+jobs:
+ CLAssistant:
+ runs-on: ubuntu-latest
+ steps:
+ - name: "CLA Assistant"
+ if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
+ # Beta Release
+ uses: cla-assistant/github-action@v2.6.1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # the below token should have repo scope and must be manually added by you in the repository's secret
+ PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
+ with:
+ path-to-signatures: "signatures/version1/cla.json"
+ path-to-document: "https://github.com/Codeuctivity/OpenXmlPowerTools/blob/main/cla.md" # e.g. a CLA or a DCO document
+ # branch should not be protected
+ branch: "cla"
+ allowlist: dependabot[bot],stesee
+
+ #below are the optional inputs - If the optional inputs are not given, then default values will be taken
+ #remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository)
+ #remote-repository-name: enter the remote repository name where the signatures should be stored (Default is storing the signatures in the same repository)
+ #create-file-commit-message: 'For example: Creating file for storing CLA Signatures'
+ #signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo'
+ #custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign'
+ #custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA'
+ #custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.'
+ #lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true)
+ #use-dco-flag: true - If you are using DCO instead of CLA
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
new file mode 100644
index 00000000..5955b1ac
--- /dev/null
+++ b/.github/workflows/dotnet.yml
@@ -0,0 +1,91 @@
+name: .NET build and test
+env:
+ CURRENT_VERSION: 9.0.${{ github.run_number }}
+ LAST_COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ build:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ steps:
+ - uses: actions/checkout@v5
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: 8.0.x
+ - name: Restore dependencies
+ run: dotnet restore
+ - name: Build
+ run: dotnet build --configuration Release --no-restore
+ - name: Test
+ run: dotnet test --no-build --verbosity normal --configuration Release --logger "trx;LogFileName=${{ runner.workspace }}/OpenXmlPowerTools/TestResult/test_results.trx"
+ - name: Publish Unit Test Results
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: TestResult
+ path: "TestResult/**/*"
+
+ deployRelease:
+ if: github.ref == 'refs/heads/release'
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - uses: actions/checkout@v5
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: 8.0.x
+ - name: Restore dependencies
+ run: dotnet restore
+ - name: Build
+ run: dotnet build --configuration Release --no-restore
+ - name: NugetPush
+ env:
+ NUGET_TOKEN_EXISTS: ${{ secrets.NUGET_TOKEN }}
+ if: env.NUGET_TOKEN_EXISTS != ''
+ run: |
+ dotnet nuget push ./OpenXmlPowerTools/bin/Release/*.nupkg --skip-duplicate --api-key ${{secrets.NUGET_TOKEN}} --source https://api.nuget.org/v3/index.json
+ - name: Github Release
+ shell: bash
+ env:
+ GITHUB_TOKEN: ${{ github.TOKEN }}
+ if: env.GITHUB_TOKEN != ''
+ run: |
+ gh release create ${{env.CURRENT_VERSION}} ./OpenXmlPowerTools/bin/Release/*.*nupkg --generate-notes
+
+ deployTest:
+ if: github.ref == 'refs/heads/main'
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - uses: actions/checkout@v5
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: 8.0.x
+ - name: Restore dependencies
+ run: dotnet restore
+ - name: Build
+ run: dotnet build --configuration Release --no-restore
+ - name: NugetPush
+ env:
+ NUGET_TOKEN_EXISTS: ${{ secrets.NUGET_TEST_TOKEN }}
+ if: env.NUGET_TOKEN_EXISTS != ''
+ run: |
+ ls ./OpenXmlPowerTools/bin/Release
+ dotnet nuget push ./OpenXmlPowerTools/bin/Release/*.nupkg --skip-duplicate --api-key ${{secrets.NUGET_TEST_TOKEN}} --source https://apiint.nugettest.org/v3/index.json
+
+ - name: Github Prerelease
+ shell: bash
+ env:
+ GITHUB_TOKEN: ${{ github.TOKEN }}
+ if: env.GITHUB_TOKEN != ''
+ run: |
+ gh release create ${{env.CURRENT_VERSION}} ./OpenXmlPowerTools/bin/Release/*.*nupkg --prerelease --generate-notes
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 00000000..6736c096
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,27 @@
+# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
+#
+# You can adjust the behavior by modifying this file.
+# For more information, see:
+# https://github.com/actions/stale
+name: Mark stale issues and pull requests
+
+on:
+ schedule:
+ - cron: '44 1 * * *'
+
+jobs:
+ stale:
+
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
+
+ steps:
+ - uses: actions/stale@v10
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ stale-issue-message: 'Stale issue message'
+ stale-pr-message: 'Stale pull request message'
+ stale-issue-label: 'no-issue-activity'
+ stale-pr-label: 'no-pr-activity'
diff --git a/.gitignore b/.gitignore
index d66f2aea..1f6ad508 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,5 @@ TestResults/
# JetBrains
.idea/
_ReSharper.Caches/
+
+TestResult/
\ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 00000000..e7a120f8
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,5 @@
+{
+ "recommendations": [
+ "redhat.vscode-yaml"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000..bace6e86
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,27 @@
+{
+ // Use IntelliSense to find out which attributes exist for C# debugging
+ // Use hover for the description of the existing attributes
+ // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": ".NET Launch (console)",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build",
+ // If you have changed target frameworks, make sure to update the program path.
+ "program": "${workspaceFolder}/OpenXmlPowerToolsExamples/DocumentAssembler/bin/Debug/net6.0/DocumentAssembler.dll",
+ "args": [],
+ "cwd": "${workspaceFolder}/OpenXmlPowerToolsExamples/DocumentAssembler",
+ // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
+ "console": "internalConsole",
+ "stopAtEntry": false
+ },
+ {
+ "name": ".NET Attach",
+ "type": "coreclr",
+ "request": "attach",
+ "processId": "${command:pickProcess}"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..20a7d4c1
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,6 @@
+{
+ "cSpell.language": "en",
+ "cSpell.words": [
+ "PPTX"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 00000000..18459304
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,34 @@
+{
+ // See https://go.microsoft.com/fwlink/?LinkId=733558
+ // for the documentation about the tasks.json format
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "build",
+ "command": "dotnet",
+ "type": "shell",
+ "args": [
+ "build",
+ // Ask dotnet build to generate full paths for file names.
+ "/property:GenerateFullPaths=true",
+ // Do not generate summary otherwise it leads to duplicate errors in Problems panel
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "group": "build",
+ "presentation": {
+ "reveal": "silent"
+ },
+ "problemMatcher": "$msCompile"
+ },
+ {
+ "label": "update nuget",
+ "command": "./.vscode/updateNuget.sh",
+ "args": [],
+ "group": "build",
+ "presentation": {
+ "reveal": "always"
+ },
+ "problemMatcher": "$msCompile"
+ }
+ ]
+}
diff --git a/.vscode/updateNuget.sh b/.vscode/updateNuget.sh
new file mode 100755
index 00000000..691c854e
--- /dev/null
+++ b/.vscode/updateNuget.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+regex='PackageReference Include="([^"]*)" Version="([^"]*)"'
+find . -name "*.*proj" | while read proj; do
+ while read line; do
+ if [[ $line =~ $regex ]]; then
+ name="${BASH_REMATCH[1]}"
+ version="${BASH_REMATCH[2]}"
+ if [[ $version != *-* ]]; then
+ dotnet add "$proj" package "$name"
+ fi
+ fi
+ done <"$proj"
+done
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 00000000..45341b2e
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,21 @@
+# Build and Test Instructions
+
+## Prerequisites
+- .NET 8 SDK (`dotnet-sdk-8.0`) must be installed.
+ ```bash
+ apt-get update && apt-get install -y dotnet-sdk-8.0
+ ```
+
+## Build
+From the repository root, run:
+```bash
+dotnet build
+```
+This restores NuGet packages and compiles the library and example projects.
+
+## Test
+Execute the unit tests with:
+```bash
+dotnet test
+```
+The command builds required projects and runs the test suite.
diff --git a/Directory.Build.props b/Directory.Build.props
deleted file mode 100644
index 91ee077a..00000000
--- a/Directory.Build.props
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
- true
-
-
-
- $(MSBuildThisFileDirectory)\rules.ruleset
-
-
diff --git a/Directory.Build.targets b/Directory.Build.targets
deleted file mode 100644
index c1f3257c..00000000
--- a/Directory.Build.targets
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
- All
-
-
-
diff --git a/LICENSE b/LICENSE.md
similarity index 97%
rename from LICENSE
rename to LICENSE.md
index cce6ed6a..06188368 100644
--- a/LICENSE
+++ b/LICENSE.md
@@ -1,4 +1,4 @@
-The MIT License (MIT)
+# The MIT License (MIT)
Copyright (c) Microsoft Corporation
diff --git a/NewDocxDocuments/GenerateNewDocxCmdlet.ps1 b/NewDocxDocuments/GenerateNewDocxCmdlet.ps1
index b3b04b13..4b3bd8b8 100644
--- a/NewDocxDocuments/GenerateNewDocxCmdlet.ps1
+++ b/NewDocxDocuments/GenerateNewDocxCmdlet.ps1
@@ -1,35 +1,24 @@
[environment]::CurrentDirectory = $(Get-Location)
-if (-not $(Test-Path .\GenerateNewDocxCmdlet.ps1))
-{
+if (-not $(Test-Path .\GenerateNewDocxCmdlet.ps1)) {
Throw "You must run this script from within the NewDocxDocuments directory"
}
$dx = "..\Cmdlets\DocxLib.ps1"
-if (Test-Path $dx) { del $dx }
+if (Test-Path $dx) { Remove-Item $dx }
$lineBreak = [System.Environment]::NewLine
[System.Text.StringBuilder]$sbDxl = New-Object -TypeName System.Text.StringBuilder
$copyrightString = @"
-<#***************************************************************************
-
-Copyright (c) Microsoft Corporation 2015.
-
-This code is licensed using the Microsoft Public License (Ms-PL). The text of the license can be found here:
-
-http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx
-
-Published at http://OpenXmlDeveloper.org
-Resource Center and Documentation: http://openxmldeveloper.org/wiki/w/wiki/powertools-for-open-xml.aspx
-
-***************************************************************************#>
+<# Copyright (c) Microsoft. All rights reserved.
+ Licensed under the MIT license. See LICENSE file in the project root for full license information.#>
"@
[void]$sbDxl.Append($copyrightString + $lineBreak)
-dir *.docx | % {
+Get-ChildItem *.docx | ForEach-Object {
$fi = New-Object System.IO.FileInfo $_
[void]$sbDxl.Append("`$SampleDocx$($_.BaseName) =" + $lineBreak)
$b64 = $(ConvertTo-Base64 $_ -PowerShellLiteral)
@@ -42,8 +31,7 @@ $template = [System.IO.File]::ReadAllLines("..\Cmdlets\New-Docx-Template.ps1")
$paramDocs = -1;
$paramDecl = -1;
$paramUse = -1;
-for ($i = 0; $i -lt $template.Length; $i++)
-{
+for ($i = 0; $i -lt $template.Length; $i++) {
$t = $template[$i]
if ($t.Contains("ParameterDocumentation")) { $paramDocs = $i }
if ($t.Contains("ParameterDeclaration")) { $paramDecl = $i }
@@ -51,44 +39,39 @@ for ($i = 0; $i -lt $template.Length; $i++)
}
$ndx = "..\Cmdlets\New-Docx.ps1"
-if (Test-Path $ndx)
-{
+if (Test-Path $ndx) {
Remove-Item $ndx
}
$sbGenNewDocx = New-Object System.Text.StringBuilder;
$template[0..($paramDocs - 1)] | % { [void]$sbGenNewDocx.Append($_ + $lineBreak) }
-dir *.docx | % {
+Get-ChildItem *.docx | ForEach-Object {
$fi = New-Object System.IO.FileInfo $_
[void]$sbGenNewDocx.Append(" .PARAMETER $($fi.BaseName)" + $lineBreak)
$fiDesc = New-Object System.IO.FileInfo $($_.BaseName + ".txt")
- if ($fiDesc.Exists)
- {
- Get-Content $($fiDesc.FullName) | % { [void]$sbGenNewDocx.Append(' ' + $_ + $lineBreak) }
+ if ($fiDesc.Exists) {
+ Get-Content $($fiDesc.FullName) | ForEach-Object { [void]$sbGenNewDocx.Append(' ' + $_ + $lineBreak) }
}
- else
- {
+ else {
$errMessage = "Error: $($fi.BaseName).docx does not have a corresponding $($fi.BaseName).txt"
- Write-Host -ForegroundColor Red $errMessage
+ Write-Error $errMessage
[void]$sbGenNewDocx.Append(' ' + $errMessage + $lineBreak)
}
}
$start = $paramDocs + 1
$end = $paramDecl - 1
-$template[$start..$end] | % { [void]$sbGenNewDocx.Append($_ + $lineBreak) }
-$last = (($(dir *.docx) | measure).Count) - 1
+$template[$start..$end] | ForEach-Object { [void]$sbGenNewDocx.Append($_ + $lineBreak) }
+$last = (($(Get-ChildItem *.docx) | Measure-Object).Count) - 1
$count = 0
-dir *.docx | % {
+Get-ChildItem *.docx | ForEach-Object {
$fi = New-Object System.IO.FileInfo $_
[void]$sbGenNewDocx.Append(' [Parameter(Mandatory=$False)]' + $lineBreak)
[void]$sbGenNewDocx.Append(' [Switch]' + $lineBreak)
- if ($count -ne $last)
- {
+ if ($count -ne $last) {
[void]$sbGenNewDocx.Append(" [bool]`$$($_.BaseName)," + $lineBreak)
}
- else
- {
+ else {
[void]$sbGenNewDocx.Append(" [bool]`$$($_.BaseName)" + $lineBreak)
}
[void]$sbGenNewDocx.Append($lineBreak)
@@ -96,12 +79,12 @@ dir *.docx | % {
}
$start = $paramDecl + 1
$end = $paramUse - 1
-$template[$start..$end] | % { [void]$sbGenNewDocx.Append($_ + $lineBreak) }
-dir *.docx | % {
+$template[$start..$end] | ForEach-Object { [void]$sbGenNewDocx.Append($_ + $lineBreak) }
+Get-ChildItem *.docx | ForEach-Object {
$fi = New-Object System.IO.FileInfo $_
[void]$sbGenNewDocx.Append(" if (`$All -or `$$($fi.BaseName)) { AppendDoc `$srcList `$SampleDocx$($fi.BaseName) `"$($fi.BaseName)`" }" + $lineBreak)
}
$start = $paramUse + 1
-$template[$start..99999] | % { [void]$sbGenNewDocx.Append($_ + $lineBreak) }
+$template[$start..99999] | ForEach-Object { [void]$sbGenNewDocx.Append($_ + $lineBreak) }
Set-Content -Value $sbGenNewDocx.ToString() -Path $ndx -Encoding UTF8
diff --git a/NewPptxPresentations/GenerateNewPptxCmdlet.ps1 b/NewPptxPresentations/GenerateNewPptxCmdlet.ps1
index 2ceb7325..a877aa7b 100644
--- a/NewPptxPresentations/GenerateNewPptxCmdlet.ps1
+++ b/NewPptxPresentations/GenerateNewPptxCmdlet.ps1
@@ -1,35 +1,24 @@
[environment]::CurrentDirectory = $(Get-Location)
-if (-not $(Test-Path .\GenerateNewPptxCmdlet.ps1))
-{
+if (-not $(Test-Path .\GenerateNewPptxCmdlet.ps1)) {
Throw "You must run this script from within the NewPptxPresentations directory"
}
$dx = "..\Cmdlets\PptxLib.ps1"
-if (Test-Path $dx) { del $dx}
+if (Test-Path $dx) { Remove-Item $dx }
$lineBreak = [System.Environment]::NewLine
[System.Text.StringBuilder]$sbDxl = New-Object -TypeName System.Text.StringBuilder
$copyrightString = @"
-<#***************************************************************************
-
-Copyright (c) Microsoft Corporation 2015.
-
-This code is licensed using the Microsoft Public License (Ms-PL). The text of the license can be found here:
-
-http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx
-
-Published at http://OpenXmlDeveloper.org
-Resource Center and Documentation: http://openxmldeveloper.org/wiki/w/wiki/powertools-for-open-xml.aspx
-
-***************************************************************************#>
+<#Copyright (c) Microsoft. All rights reserved.
+Licensed under the MIT license. See LICENSE file in the project root for full license information.#>
"@
[void]$sbDxl.Append($copyrightString + $lineBreak)
-dir *.pptx | % {
+Get-ChildItem *.pptx | ForEach-Object {
$fi = New-Object System.IO.FileInfo $_
[void]$sbDxl.Append("`$SamplePptx$($_.BaseName) =" + $lineBreak)
$b64 = $(ConvertTo-Base64 $_ -PowerShellLiteral)
@@ -42,8 +31,7 @@ $template = [System.IO.File]::ReadAllLines("..\Cmdlets\New-Pptx-Template.ps1")
$paramDocs = -1;
$paramDecl = -1;
$paramUse = -1;
-for ($i = 0; $i -lt $template.Length; $i++)
-{
+for ($i = 0; $i -lt $template.Length; $i++) {
$t = $template[$i]
if ($t.Contains("ParameterDocumentation")) { $paramDocs = $i }
if ($t.Contains("ParameterDeclaration")) { $paramDecl = $i }
@@ -51,44 +39,39 @@ for ($i = 0; $i -lt $template.Length; $i++)
}
$npx = "..\Cmdlets\New-Pptx.ps1"
-if (Test-Path $npx)
-{
+if (Test-Path $npx) {
Remove-Item $npx
}
$sbGenNewPptx = New-Object System.Text.StringBuilder;
-$template[0..($paramDocs - 1)] | % { [void]$sbGenNewPptx.Append($_ + $lineBreak) }
-dir *.pptx | % {
+$template[0..($paramDocs - 1)] | ForEach-Object { [void]$sbGenNewPptx.Append($_ + $lineBreak) }
+Get-ChildItem *.pptx | ForEach-Object {
$fi = New-Object System.IO.FileInfo $_
[void]$sbGenNewPptx.Append(" .PARAMETER $($fi.BaseName)" + $lineBreak)
$fiDesc = New-Object System.IO.FileInfo $($_.BaseName + ".txt")
- if ($fiDesc.Exists)
- {
- Get-Content $($fiDesc.FullName) | % { [void]$sbGenNewPptx.Append(' ' + $_ + $lineBreak) }
+ if ($fiDesc.Exists) {
+ Get-Content $($fiDesc.FullName) | ForEach-Object { [void]$sbGenNewPptx.Append(' ' + $_ + $lineBreak) }
}
- else
- {
+ else {
$errMessage = "Error: $($fi.BaseName).pptx does not have a corresponding $($fi.BaseName).txt"
- Write-Host -ForegroundColor Red $errMessage
+ Write-Error $errMessage
[void]$sbGenNewPptx.Append(' ' + $errMessage + $lineBreak)
}
}
$start = $paramDocs + 1
$end = $paramDecl - 1
-$template[$start..$end] | % { [void]$sbGenNewPptx.Append($_ + $lineBreak) }
-$last = (($(dir *.pptx) | measure).Count) - 1
+$template[$start..$end] | ForEach-Object { [void]$sbGenNewPptx.Append($_ + $lineBreak) }
+$last = (($(Get-ChildItem *.pptx) | Measure-Object).Count) - 1
$count = 0
-dir *.pptx | % {
+Get-ChildItem *.pptx | ForEach-Object {
$fi = New-Object System.IO.FileInfo $_
[void]$sbGenNewPptx.Append(' [Parameter(Mandatory=$False)]' + $lineBreak)
[void]$sbGenNewPptx.Append(' [Switch]' + $lineBreak)
- if ($count -ne $last)
- {
+ if ($count -ne $last) {
[void]$sbGenNewPptx.Append(" [bool]`$$($_.BaseName)," + $lineBreak)
}
- else
- {
+ else {
[void]$sbGenNewPptx.Append(" [bool]`$$($_.BaseName)" + $lineBreak)
}
[void]$sbGenNewPptx.Append($lineBreak)
@@ -96,12 +79,12 @@ dir *.pptx | % {
}
$start = $paramDecl + 1
$end = $paramUse - 1
-$template[$start..$end] | % { [void]$sbGenNewPptx.Append($_ + $lineBreak) }
-dir *.pptx | % {
+$template[$start..$end] | ForEach-Object { [void]$sbGenNewPptx.Append($_ + $lineBreak) }
+Get-ChildItem *.pptx | ForEach-Object {
$fi = New-Object System.IO.FileInfo $_
[void]$sbGenNewPptx.Append(" if (`$All -or `$$($fi.BaseName)) { AppendPresentation `$srcList `$SamplePptx$($fi.BaseName) `"$($fi.BaseName)`" }" + $lineBreak)
}
$start = $paramUse + 1
-$template[$start..99999] | % { [void]$sbGenNewPptx.Append($_ + $lineBreak) }
+$template[$start..99999] | ForEach-Object { [void]$sbGenNewPptx.Append($_ + $lineBreak) }
Set-Content -Value $sbGenNewPptx.ToString() -Path $npx -Encoding UTF8
diff --git a/OpenXmlPowerTools.Tests.OA/HtmlToWmlConverterTests2.cs b/OpenXmlPowerTools.Tests.OA/HtmlToWmlConverterTests2.cs
deleted file mode 100644
index 9ebce63a..00000000
--- a/OpenXmlPowerTools.Tests.OA/HtmlToWmlConverterTests2.cs
+++ /dev/null
@@ -1,558 +0,0 @@
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation 2012-2015.
-
-This code is licensed using the Microsoft Public License (Ms-PL). The text of the license can be found here:
-
-http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx
-
-Published at http://OpenXmlDeveloper.org
-Resource Center and Documentation: http://openxmldeveloper.org/wiki/w/wiki/powertools-for-open-xml.aspx
-
-Developer: Eric White
-Blog: http://www.ericwhite.com
-Twitter: @EricWhiteDev
-Email: eric@ericwhite.com
-
-***************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Validation;
-using OpenXmlPowerTools;
-using Xunit;
-using HtmlAgilityPack;
-using System.Text.RegularExpressions;
-
-/*******************************************************************************************
- * HtmlToWmlConverter expects the HTML to be passed as an XElement, i.e. as XML. While the HTML test files that
- * are included in Open-Xml-PowerTools are able to be read as XML, most HTML is not able to be read as XML.
- * The best solution is to use the HtmlAgilityPack, which can parse HTML and save as XML. The HtmlAgilityPack
- * is licensed under the Ms-PL (same as Open-Xml-PowerTools) so it is convenient to include it in your solution,
- * and thereby you can convert HTML to XML that can be processed by the HtmlToWmlConverter.
- *
- * A convenient way to get the DLL that has been checked out with HtmlToWmlConverter is to clone the repo at
- * https://github.com/EricWhiteDev/HtmlAgilityPack
- *
- * That repo contains only the DLL that has been checked out with HtmlToWmlConverter.
- *
- * Of course, you can also get the HtmlAgilityPack source and compile it to get the DLL. You can find it at
- * http://codeplex.com/HtmlAgilityPack
- *
- * We don't include the HtmlAgilityPack in Open-Xml-PowerTools, to simplify installation. The XUnit tests in
- * this module do not require the HtmlAgilityPack to run.
-*******************************************************************************************/
-
-#if DO_CONVERSION_VIA_WORD
-using Word = Microsoft.Office.Interop.Word;
-#endif
-
-/***************************************************************************************************
- * The XUnit tests in this module are not included in the standard Open-Xml-PowerTools tests because
- * they use either Word automation, the HtmlAgilityPack, or both.
-***************************************************************************************************/
-
-namespace OxPt
-{
- public class HwTests2
- {
- static bool s_ProduceAnnotatedHtml = true;
-
- // PowerShell oneliner that generates InlineData for all files in a directory
- // dir | % { '[InlineData("' + $_.Name + '")]' } | clip
-
- [Theory]
- [InlineData("HW002-Table01.docx")]
- [InlineData("HW002-Table02.docx")]
- [InlineData("HW002-Table03.docx")]
- [InlineData("HW002-Table04.docx")]
- [InlineData("HW002-Table05.docx")]
- [InlineData("HW002-Table06.docx")]
- [InlineData("HW002-Table07.docx")]
- [InlineData("HW002-Table08.docx")]
- [InlineData("HW002-Table09.docx")]
- [InlineData("HW002-Table10.docx")]
- [InlineData("HW002-Table11.docx")]
- [InlineData("HW002-Table12.docx")]
- [InlineData("HW002-Table13.docx")]
- [InlineData("HW002-Table14.docx")]
- [InlineData("HW002-Table15.docx")]
- [InlineData("HW002-Table16.docx")]
- [InlineData("HW002-Table17.docx")]
- [InlineData("HW002-Table18.docx")]
- public void HW002(string name)
- {
- var sourceDocxFi = new FileInfo(Path.Combine(TestUtil.SourceDir.FullName, name));
-
- var sourceCopiedToDestDocxFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-2-Source.docx")));
- var sourceCopiedToDestHtmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-2-Source.html")));
- var destCssFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-3.css")));
- var destDocxFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-4-ConvertedByHtmlToWml.docx")));
- var annotatedHtmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-5-Annotated.txt")));
-
- File.Copy(sourceDocxFi.FullName, sourceCopiedToDestDocxFi.FullName);
-
- WordAutomationUtilities.SaveAsHtmlUsingWord(sourceDocxFi, sourceCopiedToDestHtmlFi);
- XElement html = null;
- int cnt = 0;
- while (true)
- {
- try
- {
- html = HtmlToWmlReadAsXElement.ReadAsXElement(sourceCopiedToDestHtmlFi);
- break;
- }
- catch (XmlException e)
- {
- throw e;
- }
- catch (IOException i)
- {
- if (++cnt == 20)
- throw i;
- System.Threading.Thread.Sleep(50);
- continue;
- }
- }
-
- string usedAuthorCss = HtmlToWmlConverter.CleanUpCss((string)html.Descendants().FirstOrDefault(d => d.Name.LocalName.ToLower() == "style"));
- File.WriteAllText(destCssFi.FullName, usedAuthorCss);
-
- HtmlToWmlConverterSettings settings = HtmlToWmlConverter.GetDefaultSettings();
- // image references in HTML files contain the path to the subdir that contains the images, so base URI is the name of the directory
- // that contains the HTML files
- settings.BaseUriForImages = Path.Combine(TestUtil.TempDir.FullName);
-
- WmlDocument doc = HtmlToWmlConverter.ConvertHtmlToWml(
- defaultCss,
- usedAuthorCss,
- userCss,
- html,
- settings,
- null, // use the default EmptyDocument
- s_ProduceAnnotatedHtml ? annotatedHtmlFi.FullName : null);
-
- Assert.NotNull(doc);
-
- if (doc != null)
- SaveValidateAndFormatMainDocPart(destDocxFi, doc);
-
-#if DO_CONVERSION_VIA_WORD
- var newAltChunkBeforeFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-5-AltChunkBefore.docx")));
- var newAltChunkAfterFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-6-ConvertedViaWord.docx")));
- WordAutomationUtilities.DoConversionViaWord(newAltChunkBeforeFi, newAltChunkAfterFi, html);
-#endif
- }
-
- [Theory]
- [InlineData("T0015.html")]
- public void HW003(string name)
- {
- string testDocPrefix = "HW003_";
- var sourceHtmlFi = new FileInfo(Path.Combine(TestUtil.SourceDir.FullName, name));
-
- var sourceCopiedToDestHtmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, (testDocPrefix + sourceHtmlFi.Name).Replace(".html", "-1-Source.html")));
- var destCssFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, (testDocPrefix + sourceHtmlFi.Name).Replace(".html", "-2.css")));
- var destDocxFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, (testDocPrefix + sourceHtmlFi.Name).Replace(".html", "-3-ConvertedByHtmlToWml.docx")));
- var annotatedHtmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, (testDocPrefix + sourceHtmlFi.Name).Replace(".html", "-4-Annotated.txt")));
-
- File.Copy(sourceHtmlFi.FullName, sourceCopiedToDestHtmlFi.FullName);
- XElement html = HtmlToWmlReadAsXElement.ReadAsXElement(sourceCopiedToDestHtmlFi);
-
- string usedAuthorCss = HtmlToWmlConverter.CleanUpCss((string)html.Descendants().FirstOrDefault(d => d.Name.LocalName.ToLower() == "style"));
- File.WriteAllText(destCssFi.FullName, usedAuthorCss);
-
- HtmlToWmlConverterSettings settings = HtmlToWmlConverter.GetDefaultSettings();
- settings.BaseUriForImages = Path.Combine(TestUtil.TempDir.FullName);
- settings.DefaultBlockContentMargin = "36pt";
-
- WmlDocument doc = HtmlToWmlConverter.ConvertHtmlToWml(defaultCss, usedAuthorCss, userCss, html, settings, null, s_ProduceAnnotatedHtml ? annotatedHtmlFi.FullName : null);
- Assert.NotNull(doc);
- if (doc != null)
- SaveValidateAndFormatMainDocPart(destDocxFi, doc);
- }
-
- [Theory]
- [InlineData("HW010-Symbols01.docx")]
- [InlineData("HW010-Symbols02.docx")]
- [InlineData("HW010-TableWithEmptyRows.docx")]
- [InlineData("HW010-TableWithThreeEmptyRows.docx")]
- [InlineData("HW010-TableWithImage.docx")]
- [InlineData("HW010-SpanWithSingleSpace.docx")]
- [InlineData("HW010-Tab01.docx")]
-
- public void HW010(string name)
- {
- var sourceDocxFi = new FileInfo(Path.Combine(TestUtil.SourceDir.FullName, name));
-
- var sourceCopiedToDestDocxFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-2-Source.docx")));
- var sourceCopiedToDestHtmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-2-Source.html")));
- var destCssFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-3.css")));
- var destDocxFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-4-ConvertedByHtmlToWml.docx")));
- var annotatedHtmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-5-Annotated.txt")));
-
- File.Copy(sourceDocxFi.FullName, sourceCopiedToDestDocxFi.FullName);
-
- SaveAsHtmlUsingHtmlConverter(sourceCopiedToDestDocxFi.FullName, sourceCopiedToDestDocxFi.DirectoryName);
- XElement html = HtmlToWmlReadAsXElement.ReadAsXElement(sourceCopiedToDestHtmlFi);
-
- string usedAuthorCss = HtmlToWmlConverter.CleanUpCss((string)html.Descendants().FirstOrDefault(d => d.Name.LocalName.ToLower() == "style"));
- File.WriteAllText(destCssFi.FullName, usedAuthorCss);
-
- var settingsWmlDocument = new WmlDocument(sourceCopiedToDestDocxFi.FullName);
- HtmlToWmlConverterSettings settings = HtmlToWmlConverter.GetDefaultSettings(settingsWmlDocument);
- // image references in HTML files contain the path to the subdir that contains the images, so base URI is the name of the directory
- // that contains the HTML files
- settings.BaseUriForImages = Path.Combine(TestUtil.TempDir.FullName);
-
- WmlDocument doc = HtmlToWmlConverter.ConvertHtmlToWml(
- defaultCss,
- usedAuthorCss,
- userCss,
- html,
- settings,
- null, // use the default EmptyDocument
- s_ProduceAnnotatedHtml ? annotatedHtmlFi.FullName : null);
-
- Assert.NotNull(doc);
-
- if (doc != null)
- SaveValidateAndFormatMainDocPart(destDocxFi, doc);
-
-#if DO_CONVERSION_VIA_WORD
- var newAltChunkBeforeFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-5-AltChunkBefore.docx")));
- var newAltChunkAfterFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-6-ConvertedViaWord.docx")));
- WordAutomationUtilities.DoConversionViaWord(newAltChunkBeforeFi, newAltChunkAfterFi, html);
-#endif
- }
-
- private static void SaveAsHtmlUsingHtmlConverter(string file, string outputDirectory)
- {
- var fi = new FileInfo(file);
- Console.WriteLine(fi.Name);
- byte[] byteArray = File.ReadAllBytes(fi.FullName);
- using (MemoryStream memoryStream = new MemoryStream())
- {
- memoryStream.Write(byteArray, 0, byteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(memoryStream, true))
- {
- var destFileName = new FileInfo(fi.Name.Replace(".docx", ".html"));
- if (outputDirectory != null && outputDirectory != string.Empty)
- {
- DirectoryInfo di = new DirectoryInfo(outputDirectory);
- if (!di.Exists)
- {
- throw new OpenXmlPowerToolsException("Output directory does not exist");
- }
- destFileName = new FileInfo(Path.Combine(di.FullName, destFileName.Name));
- }
- var imageDirectoryName = destFileName.FullName.Substring(0, destFileName.FullName.Length - 5) + "_files";
- int imageCounter = 0;
-
- var pageTitle = fi.FullName;
- var part = wDoc.CoreFilePropertiesPart;
- if (part != null)
- {
- pageTitle = (string)part.GetXDocument().Descendants(DC.title).FirstOrDefault() ?? fi.FullName;
- }
-
- // TODO: Determine max-width from size of content area.
- HtmlConverterSettings settings = new HtmlConverterSettings()
- {
- AdditionalCss = "body { margin: 1cm auto; max-width: 20cm; padding: 0; }",
- PageTitle = pageTitle,
- FabricateCssClasses = true,
- CssClassPrefix = "pt-",
- RestrictToSupportedLanguages = false,
- RestrictToSupportedNumberingFormats = false,
- ImageHandler = imageInfo =>
- {
- DirectoryInfo localDirInfo = new DirectoryInfo(imageDirectoryName);
- if (!localDirInfo.Exists)
- localDirInfo.Create();
- ++imageCounter;
- string extension = imageInfo.ContentType.Split('/')[1].ToLower();
- ImageFormat imageFormat = null;
- if (extension == "png")
- imageFormat = ImageFormat.Png;
- else if (extension == "gif")
- imageFormat = ImageFormat.Gif;
- else if (extension == "bmp")
- imageFormat = ImageFormat.Bmp;
- else if (extension == "jpeg")
- imageFormat = ImageFormat.Jpeg;
- else if (extension == "tiff")
- {
- // Convert tiff to gif.
- extension = "gif";
- imageFormat = ImageFormat.Gif;
- }
- else if (extension == "x-wmf")
- {
- extension = "wmf";
- imageFormat = ImageFormat.Wmf;
- }
-
- // If the image format isn't one that we expect, ignore it,
- // and don't return markup for the link.
- if (imageFormat == null)
- return null;
-
- string imageFileName = imageDirectoryName + "/image" +
- imageCounter.ToString() + "." + extension;
- try
- {
- imageInfo.Bitmap.Save(imageFileName, imageFormat);
- }
- catch (System.Runtime.InteropServices.ExternalException)
- {
- return null;
- }
- string imageSource = localDirInfo.Name + "/image" +
- imageCounter.ToString() + "." + extension;
-
- XElement img = new XElement(Xhtml.img,
- new XAttribute(NoNamespace.src, imageSource),
- imageInfo.ImgStyleAttribute,
- imageInfo.AltText != null ?
- new XAttribute(NoNamespace.alt, imageInfo.AltText) : null);
- return img;
- }
- };
- XElement htmlElement = HtmlConverter.ConvertToHtml(wDoc, settings);
-
- // Produce HTML document with declaration to tell the browser
- // we are using HTML5.
- var html = new XDocument(
- new XDocumentType("html", null, null, null),
- htmlElement);
-
- // Note: the xhtml returned by ConvertToHtmlTransform contains objects of type
- // XEntity. PtOpenXmlUtil.cs define the XEntity class. See
- // http://blogs.msdn.com/ericwhite/archive/2010/01/21/writing-entity-references-using-linq-to-xml.aspx
- // for detailed explanation.
- //
- // If you further transform the XML tree returned by ConvertToHtmlTransform, you
- // must do it correctly, or entities will not be serialized properly.
-
- var htmlString = html.ToString(SaveOptions.DisableFormatting);
- File.WriteAllText(destFileName.FullName, htmlString, Encoding.UTF8);
- }
- }
- }
-
- private static void SaveValidateAndFormatMainDocPart(FileInfo destDocxFi, WmlDocument doc)
- {
- WmlDocument formattedDoc;
-
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(doc.DocumentByteArray, 0, doc.DocumentByteArray.Length);
- using (WordprocessingDocument document = WordprocessingDocument.Open(ms, true))
- {
- XDocument xDoc = document.MainDocumentPart.GetXDocument();
- document.MainDocumentPart.PutXDocumentWithFormatting();
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(document);
- var errorsString = errors
- .Select(e => e.Description + Environment.NewLine)
- .StringConcatenate();
-
- // Assert that there were no errors in the generated document.
- Assert.Equal("", errorsString);
- }
- formattedDoc = new WmlDocument(destDocxFi.FullName, ms.ToArray());
- }
- formattedDoc.SaveAs(destDocxFi.FullName);
- }
-
-
- /*
- * display property:
- * - inline
- * - block
- * - list-item
- * - inline-block
- * - table
- * - inline-table
- * - table-row-group
- * - table-header-group
- * - table-footer-group
- * - table-row
- * - table-column-group
- * - table-column
- * - table-cell
- * - table-caption
- * - none
- * - inherit
- *
- * position property:
- * - static
- * - relative
- * - absolute
- * - fixed
- * - inherit
- *
- * top, left, bottom, right properties:
- * (only apply if position property is not static)
- */
-
- static string defaultCss =
- @"html, address,
-blockquote,
-body, dd, div,
-dl, dt, fieldset, form,
-frame, frameset,
-h1, h2, h3, h4,
-h5, h6, noframes,
-ol, p, ul, center,
-dir, hr, menu, pre { display: block; unicode-bidi: embed }
-li { display: list-item }
-head { display: none }
-table { display: table }
-tr { display: table-row }
-thead { display: table-header-group }
-tbody { display: table-row-group }
-tfoot { display: table-footer-group }
-col { display: table-column }
-colgroup { display: table-column-group }
-td, th { display: table-cell }
-caption { display: table-caption }
-th { font-weight: bolder; text-align: center }
-caption { text-align: center }
-body { margin: auto; }
-h1 { font-size: 2em; margin: auto; }
-h2 { font-size: 1.5em; margin: auto; }
-h3 { font-size: 1.17em; margin: auto; }
-h4, p,
-blockquote, ul,
-fieldset, form,
-ol, dl, dir,
-menu { margin: auto }
-a { color: blue; }
-h5 { font-size: .83em; margin: auto }
-h6 { font-size: .75em; margin: auto }
-h1, h2, h3, h4,
-h5, h6, b,
-strong { font-weight: bolder }
-blockquote { margin-left: 40px; margin-right: 40px }
-i, cite, em,
-var, address { font-style: italic }
-pre, tt, code,
-kbd, samp { font-family: monospace }
-pre { white-space: pre }
-button, textarea,
-input, select { display: inline-block }
-big { font-size: 1.17em }
-small, sub, sup { font-size: .83em }
-sub { vertical-align: sub }
-sup { vertical-align: super }
-table { border-spacing: 2px; }
-thead, tbody,
-tfoot { vertical-align: middle }
-td, th, tr { vertical-align: inherit }
-s, strike, del { text-decoration: line-through }
-hr { border: 1px inset }
-ol, ul, dir,
-menu, dd { margin-left: 40px }
-ol { list-style-type: decimal }
-ol ul, ul ol,
-ul ul, ol ol { margin-top: 0; margin-bottom: 0 }
-u, ins { text-decoration: underline }
-br:before { content: ""\A""; white-space: pre-line }
-center { text-align: center }
-:link, :visited { text-decoration: underline }
-:focus { outline: thin dotted invert }
-/* Begin bidirectionality settings (do not change) */
-BDO[DIR=""ltr""] { direction: ltr; unicode-bidi: bidi-override }
-BDO[DIR=""rtl""] { direction: rtl; unicode-bidi: bidi-override }
-*[DIR=""ltr""] { direction: ltr; unicode-bidi: embed }
-*[DIR=""rtl""] { direction: rtl; unicode-bidi: embed }
-
-";
-
- // original defaultCss
- // static string defaultCss =
- // @"html, address,
- //blockquote,
- //body, dd, div,
- //dl, dt, fieldset, form,
- //frame, frameset,
- //h1, h2, h3, h4,
- //h5, h6, noframes,
- //ol, p, ul, center,
- //dir, hr, menu, pre { display: block; unicode-bidi: embed }
- //li { display: list-item }
- //head { display: none }
- //table { display: table }
- //tr { display: table-row }
- //thead { display: table-header-group }
- //tbody { display: table-row-group }
- //tfoot { display: table-footer-group }
- //col { display: table-column }
- //colgroup { display: table-column-group }
- //td, th { display: table-cell }
- //caption { display: table-caption }
- //th { font-weight: bolder; text-align: center }
- //caption { text-align: center }
- //body { margin: 8px; }
- //h1 { font-size: 2em; margin: .67em 0em; }
- //h2 { font-size: 1.5em; margin: .75em 0em; }
- //h3 { font-size: 1.17em; margin: .83em 0em; }
- //h4, p,
- //blockquote, ul,
- //fieldset, form,
- //ol, dl, dir,
- //menu { margin: 1.12em 0 }
- //a { color: blue; }
- //h5 { font-size: .83em; margin: 1.5em 0 }
- //h6 { font-size: .75em; margin: 1.67em 0 }
- //h1, h2, h3, h4,
- //h5, h6, b,
- //strong { font-weight: bolder }
- //blockquote { margin-left: 40px; margin-right: 40px }
- //i, cite, em,
- //var, address { font-style: italic }
- //pre, tt, code,
- //kbd, samp { font-family: monospace }
- //pre { white-space: pre }
- //button, textarea,
- //input, select { display: inline-block }
- //big { font-size: 1.17em }
- //small, sub, sup { font-size: .83em }
- //sub { vertical-align: sub }
- //sup { vertical-align: super }
- //table { border-spacing: 2px; }
- //thead, tbody,
- //tfoot { vertical-align: middle }
- //td, th, tr { vertical-align: inherit }
- //s, strike, del { text-decoration: line-through }
- //hr { border: 1px inset }
- //ol, ul, dir,
- //menu, dd { margin-left: 40px }
- //ol { list-style-type: decimal }
- //ol ul, ul ol,
- //ul ul, ol ol { margin-top: 0; margin-bottom: 0 }
- //u, ins { text-decoration: underline }
- //br:before { content: ""\A""; white-space: pre-line }
- //center { text-align: center }
- //:link, :visited { text-decoration: underline }
- //:focus { outline: thin dotted invert }
- ///* Begin bidirectionality settings (do not change) */
- //BDO[DIR=""ltr""] { direction: ltr; unicode-bidi: bidi-override }
- //BDO[DIR=""rtl""] { direction: rtl; unicode-bidi: bidi-override }
- //*[DIR=""ltr""] { direction: ltr; unicode-bidi: embed }
- //*[DIR=""rtl""] { direction: rtl; unicode-bidi: embed }";
-
- static string userCss = @"";
- }
-}
diff --git a/OpenXmlPowerTools.Tests.OA/ListItemRetrieverTests.cs b/OpenXmlPowerTools.Tests.OA/ListItemRetrieverTests.cs
deleted file mode 100644
index a87fffe1..00000000
--- a/OpenXmlPowerTools.Tests.OA/ListItemRetrieverTests.cs
+++ /dev/null
@@ -1,271 +0,0 @@
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation 2012-2015.
-
-This code is licensed using the Microsoft Public License (Ms-PL). The text of the license can be found here:
-
-http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx
-
-Published at http://OpenXmlDeveloper.org
-Resource Center and Documentation: http://openxmldeveloper.org/wiki/w/wiki/powertools-for-open-xml.aspx
-
-Developer: Eric White
-Blog: http://www.ericwhite.com
-Twitter: @EricWhiteDev
-Email: eric@ericwhite.com
-
-***************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml;
-using System.Xml.Linq;
-using HtmlAgilityPack;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Validation;
-using OpenXmlPowerTools;
-using Xunit;
-
-namespace OxPt
-{
- public class LiTests
- {
-
- // PowerShell oneliner that generates InlineData for all files in a directory
- // dir | % { '[InlineData("' + $_.Name + '")]' } | clip
-
- [Theory]
- [InlineData("LIR001-en-US-ordinal.docx")]
- [InlineData("LIR002-en-US-ordinalText.docx")]
- [InlineData("LIR003-en-US-upperLetter.docx")]
- [InlineData("LIR004-en-US-upperRoman.docx")]
- [InlineData("LIR005-fr-FR-cardinalText.docx")]
- [InlineData("LIR006-fr-FR-ordinalText.docx")]
- [InlineData("LIR006-fr-FR-ordinal.docx")]
- // [InlineData("LIR007-ru-RU-ordinalText.docx")] // todo this fails, the code needs updated.
- [InlineData("LIR008-zh-CH-chineseCountingThousand.docx")]
- [InlineData("LIR009-zh-CN-chineseCounting.docx")]
- [InlineData("LIR010-zh-CN-ideographTraditional.docx")]
- [InlineData("LIR011-en-US-00001.docx")]
- [InlineData("LIR012-en-US-0001.docx")]
- [InlineData("LIR013-en-US-001.docx")]
- [InlineData("LIR014-en-US-01.docx")]
- [InlineData("LIR015-en-US-cardinalText.docx")]
- [InlineData("LIR016-en-US-decimal.docx")]
- [InlineData("LIR017-en-US-decimalEnclosedCircle.docx")]
- [InlineData("LIR018-en-US-decimalZero.docx")]
- [InlineData("LIR019-en-US-lowerLetter.docx")]
- [InlineData("LIR020-en-US-lowerRoman.docx")]
- public void LIR001(string file)
- {
- FileInfo lirFile = new FileInfo(Path.Combine(TestUtil.SourceDir.FullName, file));
- WmlDocument wmlDoc = new WmlDocument(lirFile.FullName);
-
- var wordHtmlFile = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, lirFile.Name.Replace(".docx", "-Word.html")));
- WordAutomationUtilities.SaveAsHtmlUsingWord(lirFile, wordHtmlFile);
-
- var ptHtmlFile = ConvertToHtml(lirFile.FullName, TestUtil.TempDir.FullName);
- var fiPtXml = SaveHtmlAsXml(ptHtmlFile);
-
- // read and write to get the BOM on the file
- var wh = File.ReadAllText(wordHtmlFile.FullName, Encoding.Default);
- File.WriteAllText(wordHtmlFile.FullName, wh, Encoding.UTF8);
-
- var wordXml = SaveHtmlAsXml(wordHtmlFile);
- CompareNumbering(fiPtXml, wordXml);
- }
-
- private static void CompareNumbering(FileInfo fiPtXml, FileInfo wordXml)
- {
- char splitChar = '|';
-
- Console.WriteLine("Comparing {0} to {1}", fiPtXml.Name, wordXml.Name);
- var xdWord = XDocument.Load(wordXml.FullName);
- List wordRawParagraphText = xdWord.Descendants("h2").Select(p => p.DescendantNodes().OfType().Select(t => t.Value).Aggregate((s, i) => s + i)).ToList();
- var wordTextToCompare = wordRawParagraphText.Where(p => p.Contains(splitChar.ToString())).Select(p => p.Split(splitChar)[0]).ToList();
-
- var xdPt = XDocument.Load(fiPtXml.FullName);
- XNamespace xhtml = "http://www.w3.org/1999/xhtml";
- List ptRawParagraphText = xdPt.Descendants(xhtml + "h2").Select(p => p.DescendantNodes().OfType().Select(t => t.Value).Aggregate((s, i) => s + i)).ToList();
- var ptTextToCompare = ptRawParagraphText.Where(p => p.Contains(splitChar.ToString())).Select(p => new
- {
- ListItem = p.Split(splitChar)[0],
- ParaText = p.Split(splitChar)[1],
- }).ToList();
-
- if (!wordTextToCompare.Any())
- {
- throw new Exception("Internal error - no items selected");
- }
- if (wordTextToCompare.Count() != ptTextToCompare.Count())
- {
- Assert.True(false);
- //Console.WriteLine("Error, differing line counts");
- //Console.WriteLine("Word line count: {0}", wordTextToCompare.Count());
- //Console.WriteLine("Pt line count: {0}", ptTextToCompare.Count());
- return;
- }
- var zipped = wordTextToCompare.Zip(ptTextToCompare, (w, p) => new
- {
- WordText = w,
- PtText = p.ListItem,
- ParagraphText = p.ParaText,
- });
- var mismatchList = zipped.Where(z =>
- {
- var w = z.WordText.Replace('\n', ' ').Trim();
- var p = z.PtText.Replace('\n', ' ').Trim();
- var match = w == p;
- if (match)
- return false;
- return true;
- }).Select(z => z.ParagraphText).ToList();
- if (mismatchList.Any())
- {
- Assert.True(false);
- //Console.WriteLine("Mismatches: {0}", mismatchList.Count());
- //foreach (var item in mismatchList.Take(20))
- //{
- // Console.WriteLine(item);
- //}
- }
- }
-
- public static FileInfo ConvertToHtml(string file, string outputDirectory)
- {
- var fi = new FileInfo(file);
- byte[] byteArray = File.ReadAllBytes(fi.FullName);
- FileInfo destFileName;
- using (MemoryStream memoryStream = new MemoryStream())
- {
- memoryStream.Write(byteArray, 0, byteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(memoryStream, true))
- {
- destFileName = new FileInfo(fi.Name.Replace(".docx", ".html"));
- if (outputDirectory != null && outputDirectory != string.Empty)
- {
- DirectoryInfo di = new DirectoryInfo(outputDirectory);
- if (!di.Exists)
- {
- throw new OpenXmlPowerToolsException("Output directory does not exist");
- }
- destFileName = new FileInfo(Path.Combine(di.FullName, destFileName.Name));
- }
- var imageDirectoryName = destFileName.FullName.Substring(0, destFileName.FullName.Length - 5) + "_files";
- int imageCounter = 0;
- var pageTitle = (string)wDoc.CoreFilePropertiesPart.GetXDocument().Descendants(DC.title).FirstOrDefault();
- if (pageTitle == null)
- pageTitle = fi.FullName;
-
- HtmlConverterSettings settings = new HtmlConverterSettings()
- {
- PageTitle = pageTitle,
- FabricateCssClasses = true,
- CssClassPrefix = "pt-",
- RestrictToSupportedLanguages = false,
- RestrictToSupportedNumberingFormats = false,
- ImageHandler = imageInfo =>
- {
- DirectoryInfo localDirInfo = new DirectoryInfo(imageDirectoryName);
- if (!localDirInfo.Exists)
- localDirInfo.Create();
- ++imageCounter;
- string extension = imageInfo.ContentType.Split('/')[1].ToLower();
- ImageFormat imageFormat = null;
- if (extension == "png")
- {
- // Convert png to jpeg.
- extension = "gif";
- imageFormat = ImageFormat.Gif;
- }
- else if (extension == "gif")
- imageFormat = ImageFormat.Gif;
- else if (extension == "bmp")
- imageFormat = ImageFormat.Bmp;
- else if (extension == "jpeg")
- imageFormat = ImageFormat.Jpeg;
- else if (extension == "tiff")
- {
- // Convert tiff to gif.
- extension = "gif";
- imageFormat = ImageFormat.Gif;
- }
- else if (extension == "x-wmf")
- {
- extension = "wmf";
- imageFormat = ImageFormat.Wmf;
- }
-
- // If the image format isn't one that we expect, ignore it,
- // and don't return markup for the link.
- if (imageFormat == null)
- return null;
-
- string imageFileName = imageDirectoryName + "/image" +
- imageCounter.ToString() + "." + extension;
- try
- {
- imageInfo.Bitmap.Save(imageFileName, imageFormat);
- }
- catch (System.Runtime.InteropServices.ExternalException)
- {
- return null;
- }
- XElement img = new XElement(Xhtml.img,
- new XAttribute(NoNamespace.src, imageFileName),
- imageInfo.ImgStyleAttribute,
- imageInfo.AltText != null ?
- new XAttribute(NoNamespace.alt, imageInfo.AltText) : null);
- return img;
- }
- };
- XElement html = HtmlConverter.ConvertToHtml(wDoc, settings);
-
- // Note: the xhtml returned by ConvertToHtmlTransform contains objects of type
- // XEntity. PtOpenXmlUtil.cs define the XEntity class. See
- // http://blogs.msdn.com/ericwhite/archive/2010/01/21/writing-entity-references-using-linq-to-xml.aspx
- // for detailed explanation.
- //
- // If you further transform the XML tree returned by ConvertToHtmlTransform, you
- // must do it correctly, or entities will not be serialized properly.
-
- var htmlString = html.ToString(SaveOptions.DisableFormatting);
- File.WriteAllText(destFileName.FullName, htmlString, Encoding.UTF8);
- }
- }
- return destFileName;
- }
-
- public static FileInfo SaveHtmlAsXml(FileInfo htmlFileName)
- {
- string baseName = htmlFileName.Name.Substring(0, htmlFileName.Name.Length - htmlFileName.Extension.Length);
- FileInfo destFile = new FileInfo(Path.Combine(htmlFileName.DirectoryName, baseName + ".xml"));
-
- HtmlDocument hdoc = new HtmlDocument();
- hdoc.Load(htmlFileName.FullName, Encoding.UTF8);
- hdoc.OptionOutputAsXml = true;
- hdoc.Save(destFile.FullName, Encoding.UTF8);
- StringBuilder sb = new StringBuilder(File.ReadAllText(destFile.FullName, Encoding.Default));
- sb.Replace("è", "è");
- sb.Replace("&", "&");
- sb.Replace(" ", "\xA0");
- sb.Replace(""", "\"");
- sb.Replace("<", "~lt;");
- sb.Replace(">", "~gt;");
- sb.Replace("", "~#");
- sb.Replace("&", "&");
- sb.Replace("~lt;", "<");
- sb.Replace("~gt;", ">");
- sb.Replace("~#", "");
- File.WriteAllText(destFile.FullName, sb.ToString(), Encoding.UTF8);
- return destFile;
- }
- }
-
-}
diff --git a/OpenXmlPowerTools.Tests.OA/OpenXmlPowerTools.Tests.OA.csproj b/OpenXmlPowerTools.Tests.OA/OpenXmlPowerTools.Tests.OA.csproj
deleted file mode 100644
index 37303a91..00000000
--- a/OpenXmlPowerTools.Tests.OA/OpenXmlPowerTools.Tests.OA.csproj
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
-
- Debug
- AnyCPU
- {2C50A5AF-E34B-4FC4-983F-F30BB49A57AB}
- Library
- Properties
- OpenXmlPowerTools.Tests.OA
- OpenXmlPowerTools.Tests.OA
- v4.5
- 512
- f5d754ea
-
-
- true
- full
- false
- bin\Debug\
- TRACE;DEBUG;USE_HTMLAGILITYPACK
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- False
- ..\..\Open-Xml-SDK\DocumentFormat.OpenXml\bin\Debug\DocumentFormat.OpenXml.dll
-
-
- False
- ..\..\HtmlAgilityPack\HtmlAgilityPack.dll
-
-
- True
-
-
-
-
-
- ..\..\Open-Xml-SDK\DocumentFormat.OpenXml\bin\Debug\System.IO.Packaging.dll
-
-
-
-
-
-
-
- ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll
- True
-
-
- ..\packages\xunit.assert.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.assert.dll
- True
-
-
- ..\packages\xunit.extensibility.core.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.dll
- True
-
-
-
-
- HtmlConverterTests.cs
-
-
- HtmlToWmlConverterTests.cs
-
-
- HtmlToWmlReadAsXElement.cs
-
-
-
-
-
-
-
-
-
-
-
- {6f957ff3-afcc-4d69-8fbc-71ae21bc45c9}
- OpenXmlPowerTools
-
-
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
-
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests.OA/WordAutomationUtilities.cs b/OpenXmlPowerTools.Tests.OA/WordAutomationUtilities.cs
deleted file mode 100644
index ef154e13..00000000
--- a/OpenXmlPowerTools.Tests.OA/WordAutomationUtilities.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation 2012-2015.
-
-This code is licensed using the Microsoft Public License (Ms-PL). The text of the license can be found here:
-
-http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx
-
-Published at http://OpenXmlDeveloper.org
-Resource Center and Documentation: http://openxmldeveloper.org/wiki/w/wiki/powertools-for-open-xml.aspx
-
-Developer: Eric White
-Blog: http://www.ericwhite.com
-Twitter: @EricWhiteDev
-Email: eric@ericwhite.com
-
-***************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
-using Word = Microsoft.Office.Interop.Word;
-
-namespace OxPt
-{
- public class WordAutomationUtilities
- {
- public static void DoConversionViaWord(FileInfo newAltChunkBeforeFi, FileInfo newAltChunkAfterFi, XElement html)
- {
- var blankAltChunkFi = new DirectoryInfo(Path.Combine(TestUtil.SourceDir.FullName, "Blank-altchunk.docx"));
- File.Copy(blankAltChunkFi.FullName, newAltChunkBeforeFi.FullName);
- using (WordprocessingDocument myDoc = WordprocessingDocument.Open(newAltChunkBeforeFi.FullName, true))
- {
- string altChunkId = "AltChunkId1";
- MainDocumentPart mainPart = myDoc.MainDocumentPart;
- AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
- "application/xhtml+xml", altChunkId);
- using (Stream chunkStream = chunk.GetStream(FileMode.Create, FileAccess.Write))
- using (StreamWriter stringStream = new StreamWriter(chunkStream))
- stringStream.Write(html.ToString());
- XElement altChunk = new XElement(W.altChunk,
- new XAttribute(R.id, altChunkId)
- );
- XDocument mainDocumentXDoc = myDoc.MainDocumentPart.GetXDocument();
- mainDocumentXDoc.Root
- .Element(W.body)
- .AddFirst(altChunk);
- myDoc.MainDocumentPart.PutXDocument();
- }
-
- WordAutomationUtilities.OpenAndSaveAs(newAltChunkBeforeFi.FullName, newAltChunkAfterFi.FullName);
-
- while (true)
- {
- try
- {
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(newAltChunkAfterFi.FullName, true))
- {
- SimplifyMarkupSettings settings2 = new SimplifyMarkupSettings
- {
- RemoveMarkupForDocumentComparison = true,
- };
- MarkupSimplifier.SimplifyMarkup(wDoc, settings2);
- XElement newRoot = (XElement)RemoveDivTransform(wDoc.MainDocumentPart.GetXDocument().Root);
- wDoc.MainDocumentPart.GetXDocument().Root.ReplaceWith(newRoot);
- wDoc.MainDocumentPart.PutXDocumentWithFormatting();
- }
- break;
- }
- catch (IOException)
- {
- System.Threading.Thread.Sleep(50);
- continue;
- }
- }
- }
-
- private static object RemoveDivTransform(XNode node)
- {
- XElement element = node as XElement;
- if (element != null)
- {
- if (element.Name == W.divId)
- return null;
- return new XElement(element.Name,
- element.Attributes(),
- element.Nodes().Select(n => RemoveDivTransform(n)));
- }
- return node;
- }
-
- public static void SaveAsHtmlUsingWord(FileInfo src, FileInfo dest)
- {
- Word.Application app = new Word.Application();
- app.Visible = false;
- try
- {
- Word.Document doc = app.Documents.Open(src.FullName);
- doc.SaveAs2(dest.FullName, Word.WdSaveFormat.wdFormatFilteredHTML);
- }
- catch (System.Runtime.InteropServices.COMException)
- {
- Console.WriteLine("Caught unexpected COM exception.");
- ((Microsoft.Office.Interop.Word._Application)app).Quit();
- Environment.Exit(0);
- }
- ((Microsoft.Office.Interop.Word._Application)app).Quit();
- }
-
- public static void OpenAndSaveAs(string fromFileName, string toFileName)
- {
- Word.Application app = new Word.Application();
- app.Visible = false;
- FileInfo fi = new FileInfo(fromFileName);
- try
- {
- FileInfo ffi = new FileInfo(fromFileName);
- Word.Document doc = app.Documents.Open(ffi.FullName);
- object FileFormat = Word.WdSaveFormat.wdFormatDocument;
- FileInfo tfi = new FileInfo(toFileName);
- object FileName = tfi.FullName;
-
- doc.SaveAs(tfi.FullName, Word.WdSaveFormat.wdFormatDocumentDefault);
- }
- catch (System.Runtime.InteropServices.COMException)
- {
- Console.WriteLine("Caught unexpected COM exception.");
- ((Microsoft.Office.Interop.Word._Application)app).Quit();
- Environment.Exit(0);
- }
- ((Microsoft.Office.Interop.Word._Application)app).Quit();
- }
-
- public static void OpenAndSaveAs(FileInfo src, FileInfo dest)
- {
- Word.Application app = new Word.Application();
- app.Visible = false;
- try
- {
- Word.Document doc = app.Documents.Open(src.FullName);
- doc.SaveAs2(dest.FullName, Word.WdSaveFormat.wdFormatDocument);
- }
- catch (System.Runtime.InteropServices.COMException)
- {
- Console.WriteLine("Caught unexpected COM exception.");
- ((Microsoft.Office.Interop.Word._Application)app).Quit();
- Environment.Exit(0);
- }
- ((Microsoft.Office.Interop.Word._Application)app).Quit();
- }
- }
-}
diff --git a/OpenXmlPowerTools.Tests/ChartUpdaterTests.cs b/OpenXmlPowerTools.Tests/ChartUpdaterTests.cs
index 2a90cfc2..b4107fc9 100644
--- a/OpenXmlPowerTools.Tests/ChartUpdaterTests.cs
+++ b/OpenXmlPowerTools.Tests/ChartUpdaterTests.cs
@@ -1,22 +1,11 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using Codeuctivity.OpenXmlPowerTools;
+using Codeuctivity.OpenXmlPowerTools.Chart;
+using DocumentFormat.OpenXml.Packaging;
using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class CuTests
{
@@ -29,7 +18,6 @@ public class CuTests
[InlineData("CU006-Chart-Cached-Data-06.docx")]
[InlineData("CU007-Chart-Cached-Data-07.docx")]
[InlineData("CU008-Chart-Cached-Data-08.docx")]
-
[InlineData("CU009-Chart-Embedded-Xlsx-01.docx")]
[InlineData("CU010-Chart-Embedded-Xlsx-02.docx")]
[InlineData("CU011-Chart-Embedded-Xlsx-03.docx")]
@@ -39,41 +27,38 @@ public class CuTests
[InlineData("CU015-Chart-Embedded-Xlsx-07.docx")]
[InlineData("CU016-Chart-Embedded-Xlsx-08.docx")]
[InlineData("CU017-Chart-Embedded-Xlsx-10.docx")]
-
[InlineData("CU018-Chart-Cached-Data-41.pptx")]
[InlineData("CU019-Chart-Embedded-Xlsx-41.pptx")]
-
public void CU001(string name)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo templateFile = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var templateFile = new FileInfo(Path.Combine(sourceDir.FullName, name));
if (templateFile.Extension.ToLower() == ".docx")
{
- WmlDocument wmlTemplate = new WmlDocument(templateFile.FullName);
+ var wmlTemplate = new WmlDocument(templateFile.FullName);
var afterUpdatingDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, templateFile.Name.Replace(".docx", "-processed-by-ChartUpdater.docx")));
wmlTemplate.SaveAs(afterUpdatingDocx.FullName);
- using (var wDoc = WordprocessingDocument.Open(afterUpdatingDocx.FullName, true))
+ using var wDoc = WordprocessingDocument.Open(afterUpdatingDocx.FullName, true);
+ var chart1Data = new ChartData
{
- var chart1Data = new ChartData
- {
- SeriesNames = new[] {
+ SeriesNames = new[] {
"Car",
"Truck",
"Van",
"Bike",
"Boat",
},
- CategoryDataType = ChartDataType.String,
- CategoryNames = new[] {
+ CategoryDataType = ChartDataType.String,
+ CategoryNames = new[] {
"Q1",
"Q2",
"Q3",
"Q4",
},
- Values = new double[][] {
+ Values = new double[][] {
new double[] {
100, 310, 220, 450,
},
@@ -90,32 +75,32 @@ public void CU001(string name)
200, 210, 210, 480,
},
},
- };
- ChartUpdater.UpdateChart(wDoc, "Chart1", chart1Data);
+ };
+ ChartUpdater.UpdateChart(wDoc, "Chart1", chart1Data);
- var chart2Data = new ChartData
- {
- SeriesNames = new[] {
+ var chart2Data = new ChartData
+ {
+ SeriesNames = new[] {
"Series"
},
- CategoryDataType = ChartDataType.String,
- CategoryNames = new[] {
+ CategoryDataType = ChartDataType.String,
+ CategoryNames = new[] {
"Cars",
"Trucks",
"Vans",
"Boats",
},
- Values = new double[][] {
+ Values = new double[][] {
new double[] {
320, 112, 64, 80,
},
},
- };
- ChartUpdater.UpdateChart(wDoc, "Chart2", chart2Data);
+ };
+ ChartUpdater.UpdateChart(wDoc, "Chart2", chart2Data);
- var chart3Data = new ChartData
- {
- SeriesNames = new[] {
+ var chart3Data = new ChartData
+ {
+ SeriesNames = new[] {
"X1",
"X2",
"X3",
@@ -123,8 +108,8 @@ public void CU001(string name)
"X5",
"X6",
},
- CategoryDataType = ChartDataType.String,
- CategoryNames = new[] {
+ CategoryDataType = ChartDataType.String,
+ CategoryNames = new[] {
"Y1",
"Y2",
"Y3",
@@ -132,7 +117,7 @@ public void CU001(string name)
"Y5",
"Y6",
},
- Values = new double[][] {
+ Values = new double[][] {
new double[] { 3.0, 2.1, .7, .7, 2.1, 3.0, },
new double[] { 3.0, 2.1, .8, .8, 2.1, 3.0, },
new double[] { 3.0, 2.4, 1.2, 1.2, 2.4, 3.0, },
@@ -140,19 +125,19 @@ public void CU001(string name)
new double[] { 3.0, 2.9, 2.5, 2.5, 2.9, 3.0, },
new double[] { 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, },
},
- };
- ChartUpdater.UpdateChart(wDoc, "Chart3", chart3Data);
+ };
+ ChartUpdater.UpdateChart(wDoc, "Chart3", chart3Data);
- var chart4Data = new ChartData
- {
- SeriesNames = new[] {
+ var chart4Data = new ChartData
+ {
+ SeriesNames = new[] {
"Car",
"Truck",
"Van",
},
- CategoryDataType = ChartDataType.DateTime,
- CategoryFormatCode = 14,
- CategoryNames = new[] {
+ CategoryDataType = ChartDataType.DateTime,
+ CategoryFormatCode = 14,
+ CategoryNames = new[] {
ToExcelInteger(new DateTime(2013, 9, 1)),
ToExcelInteger(new DateTime(2013, 9, 2)),
ToExcelInteger(new DateTime(2013, 9, 3)),
@@ -174,7 +159,7 @@ public void CU001(string name)
ToExcelInteger(new DateTime(2013, 9, 19)),
ToExcelInteger(new DateTime(2013, 9, 20)),
},
- Values = new double[][] {
+ Values = new double[][] {
new double[] {
1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 5, 4, 5, 6, 7, 8, 7, 8, 8, 9,
},
@@ -185,34 +170,32 @@ public void CU001(string name)
2, 3, 3, 3, 3, 2, 2, 2, 3, 2, 3, 3, 4, 4, 4, 3, 4, 5, 5, 4,
},
},
- };
- ChartUpdater.UpdateChart(wDoc, "Chart4", chart4Data);
- }
+ };
+ ChartUpdater.UpdateChart(wDoc, "Chart4", chart4Data);
}
if (templateFile.Extension.ToLower() == ".pptx")
{
- PmlDocument pmlTemplate = new PmlDocument(templateFile.FullName);
+ var pmlTemplate = new PmlDocument(templateFile.FullName);
var afterUpdatingPptx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, templateFile.Name.Replace(".pptx", "-processed-by-ChartUpdater.pptx")));
pmlTemplate.SaveAs(afterUpdatingPptx.FullName);
- using (var pDoc = PresentationDocument.Open(afterUpdatingPptx.FullName, true))
+ using var pDoc = PresentationDocument.Open(afterUpdatingPptx.FullName, true);
+ var chart1Data = new ChartData
{
- var chart1Data = new ChartData
- {
- SeriesNames = new[] {
+ SeriesNames = new[] {
"Car",
"Truck",
"Van",
},
- CategoryDataType = ChartDataType.String,
- CategoryNames = new[] {
+ CategoryDataType = ChartDataType.String,
+ CategoryNames = new[] {
"Q1",
"Q2",
"Q3",
"Q4",
},
- Values = new double[][] {
+ Values = new double[][] {
new double[] {
320, 310, 320, 330,
},
@@ -223,9 +206,8 @@ public void CU001(string name)
180, 200, 220, 230,
},
},
- };
- ChartUpdater.UpdateChart(pDoc, 1, chart1Data);
- }
+ };
+ ChartUpdater.UpdateChart(pDoc, 1, chart1Data);
}
}
@@ -234,6 +216,4 @@ private static string ToExcelInteger(DateTime dateTime)
return dateTime.ToOADate().ToString();
}
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/ColorParserTests.cs b/OpenXmlPowerTools.Tests/ColorParserTests.cs
new file mode 100644
index 00000000..c4cf50bd
--- /dev/null
+++ b/OpenXmlPowerTools.Tests/ColorParserTests.cs
@@ -0,0 +1,56 @@
+using Codeuctivity.OpenXmlPowerTools;
+using SkiaSharp;
+using Xunit;
+
+namespace Codeuctivity.Tests
+{
+ public class ColorParserTests
+ {
+ [Theory]
+ [InlineData("red", 255, 0, 0)]
+ [InlineData("RED", 255, 0, 0)]
+ [InlineData("#00FF00", 0, 255, 0)]
+ [InlineData("#00ff00", 0, 255, 0)]
+ [InlineData("blue", 0, 0, 255)]
+ [InlineData("#0000FF", 0, 0, 255)]
+ [InlineData("#abc", 170, 187, 204)]
+ [InlineData("yellow", 255, 255, 0)]
+ [InlineData("black", 0, 0, 0)]
+ [InlineData("white", 255, 255, 255)]
+ public void ShouldParseColors(string input, byte r, byte g, byte b)
+ {
+ var result = ColorParser.FromName(input);
+ Assert.Equal(r, result.Red);
+ Assert.Equal(g, result.Green);
+ Assert.Equal(b, result.Blue);
+ }
+
+ [Theory]
+ [InlineData("red", true)]
+ [InlineData("#123456", true)]
+ [InlineData("notacolor", false)]
+ [InlineData("", false)]
+ public void ShouldValidateColorNames(string input, bool valid)
+ {
+ Assert.Equal(valid, ColorParser.IsValidName(input));
+ }
+
+ [Fact]
+ public void FromNameShouldThrowOnInvalid()
+ {
+ Assert.Throws(() => ColorParser.FromName("bogus"));
+ }
+
+ [Theory]
+ [InlineData("notacolor")]
+ [InlineData("#GGGGGG")]
+ [InlineData("")]
+ [InlineData(null)]
+ [InlineData(" ")]
+ public void ShouldRejectInvalidColors(string? input)
+ {
+ var success = ColorParser.TryFromName(input, out SKColor _);
+ Assert.False(success);
+ }
+ }
+}
diff --git a/OpenXmlPowerTools.Tests/CssPropertyValueTests.cs b/OpenXmlPowerTools.Tests/CssPropertyValueTests.cs
new file mode 100644
index 00000000..8aaa38e5
--- /dev/null
+++ b/OpenXmlPowerTools.Tests/CssPropertyValueTests.cs
@@ -0,0 +1,45 @@
+using Codeuctivity.OpenXmlPowerTools;
+using SkiaSharp;
+using Xunit;
+
+namespace Codeuctivity.Tests
+{
+ public class CssPropertyValueTests
+ {
+ [Fact]
+ public void ShouldRecognizeNamedColor()
+ {
+ var value = new CssPropertyValue { Type = CssValueType.String, Value = "red" };
+ Assert.True(value.IsColor);
+ var color = value.ToColor();
+ Assert.Equal(SKColors.Red, color);
+ }
+
+ [Fact]
+ public void ShouldRecognizeHexColor()
+ {
+ var value = new CssPropertyValue { Type = CssValueType.Hex, Value = "#0000FF" };
+ Assert.True(value.IsColor);
+ var color = value.ToColor();
+ Assert.Equal(SKColors.Blue, color);
+ }
+
+ [Fact]
+ public void ShouldRejectNonColor()
+ {
+ var value = new CssPropertyValue { Type = CssValueType.String, Value = "1234" };
+ Assert.False(value.IsColor);
+ }
+
+ [Fact]
+ public void ShouldParseHexWithoutHash()
+ {
+ var value = new CssPropertyValue { Type = CssValueType.Hex, Value = "00FF00" };
+ Assert.True(value.IsColor);
+ var color = value.ToColor();
+ Assert.Equal(0u, color.Red);
+ Assert.Equal(255u, color.Green);
+ Assert.Equal(0u, color.Blue);
+ }
+ }
+}
diff --git a/OpenXmlPowerTools.Tests/DocumentAssemblerTests.cs b/OpenXmlPowerTools.Tests/DocumentAssemblerTests.cs
index cf62d2f0..e69616a0 100644
--- a/OpenXmlPowerTools.Tests/DocumentAssemblerTests.cs
+++ b/OpenXmlPowerTools.Tests/DocumentAssemblerTests.cs
@@ -1,24 +1,16 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using Codeuctivity.OpenXmlPowerTools;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Validation;
using System;
using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Validation;
-using OpenXmlPowerTools;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class DaTests
{
@@ -57,11 +49,9 @@ public class DaTests
[InlineData("DA034-HeaderFooter.docx", "DA-Data.xml", false)]
[InlineData("DA035-SchemaErrorInRepeat.docx", "DA-Data.xml", true)]
[InlineData("DA036-SchemaErrorInConditional.docx", "DA-Data.xml", true)]
-
[InlineData("DA100-TemplateDocument.docx", "DA-Data.xml", false)]
[InlineData("DA101-TemplateDocument.docx", "DA-Data.xml", true)]
[InlineData("DA102-TemplateDocument.docx", "DA-Data.xml", true)]
-
[InlineData("DA201-TemplateDocument.docx", "DA-Data.xml", false)]
[InlineData("DA202-TemplateDocument.docx", "DA-DataNotHighValueCust.xml", false)]
[InlineData("DA203-Select-XPathFindsNoData.docx", "DA-Data.xml", true)]
@@ -98,7 +88,6 @@ public class DaTests
[InlineData("DA237-SchemaErrorInRepeat.docx", "DA-Data.xml", true)]
[InlineData("DA238-SchemaErrorInConditional.docx", "DA-Data.xml", true)]
[InlineData("DA239-RunLevelCC-Repeat.docx", "DA-Data.xml", false)]
-
[InlineData("DA250-ConditionalWithRichXPath.docx", "DA250-Address.xml", false)]
[InlineData("DA251-EnhancedTables.docx", "DA-Data.xml", false)]
[InlineData("DA252-Table-With-Sum.docx", "DA-Data.xml", false)]
@@ -116,41 +105,35 @@ public class DaTests
[InlineData("DA264-InvalidRunLevelRepeat.docx", "DA-Data.xml", true)]
[InlineData("DA265-RunLevelRepeatWithWhiteSpaceBefore.docx", "DA-Data.xml", false)]
[InlineData("DA266-RunLevelRepeat-NoData.docx", "DA-Data.xml", true)]
-
public void DA101(string name, string data, bool err)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo templateDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
- FileInfo dataFile = new FileInfo(Path.Combine(sourceDir.FullName, data));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var templateDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var dataFile = new FileInfo(Path.Combine(sourceDir.FullName, data));
- WmlDocument wmlTemplate = new WmlDocument(templateDocx.FullName);
- XElement xmldata = XElement.Load(dataFile.FullName);
+ var wmlTemplate = new WmlDocument(templateDocx.FullName);
+ var xmldata = XElement.Load(dataFile.FullName);
- bool returnedTemplateError;
- WmlDocument afterAssembling = DocumentAssembler.AssembleDocument(wmlTemplate, xmldata, out returnedTemplateError);
+ var afterAssembling = DocumentAssembler.AssembleDocument(wmlTemplate, xmldata, out var returnedTemplateError);
var assembledDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, templateDocx.Name.Replace(".docx", "-processed-by-DocumentAssembler.docx")));
afterAssembling.SaveAs(assembledDocx.FullName);
- using (MemoryStream ms = new MemoryStream())
+ using (var ms = new MemoryStream())
{
ms.Write(afterAssembling.DocumentByteArray, 0, afterAssembling.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
+ using var wDoc = WordprocessingDocument.Open(ms, true);
+ var v = new OpenXmlValidator();
+ var valErrors = v.Validate(wDoc).Where(ve => !s_ExpectedErrors.Contains(ve.Description));
+
+ var sb = new StringBuilder();
+ foreach (var item in valErrors.Select(r => r.Description).OrderBy(t => t).Distinct())
{
- OpenXmlValidator v = new OpenXmlValidator();
- var valErrors = v.Validate(wDoc).Where(ve => !s_ExpectedErrors.Contains(ve.Description));
-
-#if false
- StringBuilder sb = new StringBuilder();
- foreach (var item in valErrors.Select(r => r.Description).OrderBy(t => t).Distinct())
- {
- sb.Append(item).Append(Environment.NewLine);
- }
- string z = sb.ToString();
- Console.WriteLine(z);
-#endif
-
- Assert.Empty(valErrors);
+ sb.Append(item).Append(Environment.NewLine);
}
+ var z = sb.ToString();
+ Console.WriteLine(z);
+
+ Assert.Empty(valErrors);
}
Assert.Equal(err, returnedTemplateError);
@@ -162,8 +145,8 @@ public void DA259(string name, string data, bool err)
{
DA101(name, data, err);
var assembledDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".docx", "-processed-by-DocumentAssembler.docx")));
- WmlDocument afterAssembling = new WmlDocument(assembledDocx.FullName);
- int brCount = afterAssembling.MainDocumentPart
+ var afterAssembling = new WmlDocument(assembledDocx.FullName);
+ var brCount = afterAssembling.MainDocumentPart
.Element(W.body)
.Elements(W.p).ElementAt(1)
.Elements(W.r)
@@ -175,18 +158,17 @@ public void DA259(string name, string data, bool err)
[InlineData("DA024-TrackedRevisions.docx", "DA-Data.xml")]
public void DA102_Throws(string name, string data)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo templateDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
- FileInfo dataFile = new FileInfo(Path.Combine(sourceDir.FullName, data));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var templateDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var dataFile = new FileInfo(Path.Combine(sourceDir.FullName, data));
- WmlDocument wmlTemplate = new WmlDocument(templateDocx.FullName);
- XElement xmldata = XElement.Load(dataFile.FullName);
+ var wmlTemplate = new WmlDocument(templateDocx.FullName);
+ var xmldata = XElement.Load(dataFile.FullName);
- bool returnedTemplateError;
WmlDocument afterAssembling;
Assert.Throws(() =>
{
- afterAssembling = DocumentAssembler.AssembleDocument(wmlTemplate, xmldata, out returnedTemplateError);
+ afterAssembling = DocumentAssembler.AssembleDocument(wmlTemplate, xmldata, out var returnedTemplateError);
});
}
@@ -194,34 +176,31 @@ public void DA102_Throws(string name, string data)
[InlineData("DA025-TemplateDocument.docx", "DA-Data.xml", false)]
public void DA103_UseXmlDocument(string name, string data, bool err)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo templateDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
- FileInfo dataFile = new FileInfo(Path.Combine(sourceDir.FullName, data));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var templateDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var dataFile = new FileInfo(Path.Combine(sourceDir.FullName, data));
- WmlDocument wmlTemplate = new WmlDocument(templateDocx.FullName);
- XmlDocument xmldata = new XmlDocument();
+ var wmlTemplate = new WmlDocument(templateDocx.FullName);
+ var xmldata = new XmlDocument();
xmldata.Load(dataFile.FullName);
- bool returnedTemplateError;
- WmlDocument afterAssembling = DocumentAssembler.AssembleDocument(wmlTemplate, xmldata, out returnedTemplateError);
+ var afterAssembling = DocumentAssembler.AssembleDocument(wmlTemplate, xmldata, out var returnedTemplateError);
var assembledDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, templateDocx.Name.Replace(".docx", "-processed-by-DocumentAssembler.docx")));
afterAssembling.SaveAs(assembledDocx.FullName);
- using (MemoryStream ms = new MemoryStream())
+ using (var ms = new MemoryStream())
{
ms.Write(afterAssembling.DocumentByteArray, 0, afterAssembling.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator v = new OpenXmlValidator();
- var valErrors = v.Validate(wDoc).Where(ve => !s_ExpectedErrors.Contains(ve.Description));
- Assert.Empty(valErrors);
- }
+ using var wDoc = WordprocessingDocument.Open(ms, true);
+ var v = new OpenXmlValidator();
+ var valErrors = v.Validate(wDoc).Where(ve => !s_ExpectedErrors.Contains(ve.Description));
+ Assert.Empty(valErrors);
}
Assert.Equal(err, returnedTemplateError);
}
- private static List s_ExpectedErrors = new List()
+ private static readonly List s_ExpectedErrors = new List()
{
"The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:evenHBand' attribute is not declared.",
"The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:evenVBand' attribute is not declared.",
@@ -239,6 +218,4 @@ public void DA103_UseXmlDocument(string name, string data, bool err)
"The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:oddVBand' attribute is not declared.",
};
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/DocumentBuilderTests.cs b/OpenXmlPowerTools.Tests/DocumentBuilderTests.cs
index 5daacb76..55b69ca9 100644
--- a/OpenXmlPowerTools.Tests/DocumentBuilderTests.cs
+++ b/OpenXmlPowerTools.Tests/DocumentBuilderTests.cs
@@ -1,36 +1,26 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using Codeuctivity.OpenXmlPowerTools;
+using Codeuctivity.OpenXmlPowerTools.DocumentBuilder;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Validation;
using System;
using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Validation;
-using DocumentFormat.OpenXml.Wordprocessing;
-using OpenXmlPowerTools;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class DbTests
{
[Fact]
public void DB001_DocumentBuilderKeepSections()
{
- string name = "DB001-Sections.docx";
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
-
- List sources = null;
- sources = new List()
+ var name = "DB001-Sections.docx";
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sources = new List()
{
new Source(new WmlDocument(sourceDocx.FullName), true),
};
@@ -41,12 +31,10 @@ public void DB001_DocumentBuilderKeepSections()
[Fact]
public void DB002_DocumentBuilderKeepSectionsDiscardHeaders()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB002-Sections-With-Headers.docx"));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB002-Landscape-Section.docx"));
-
- List sources = null;
- sources = new List()
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB002-Sections-With-Headers.docx"));
+ var source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB002-Landscape-Section.docx"));
+ var sources = new List()
{
new Source(new WmlDocument(source1Docx.FullName)) { KeepSections = true },
new Source(new WmlDocument(source2Docx.FullName)) { KeepSections = true, DiscardHeadersAndFootersInKeptSections = true },
@@ -59,12 +47,10 @@ public void DB002_DocumentBuilderKeepSectionsDiscardHeaders()
[Fact]
public void DB003_DocumentBuilderOnlyDefaultHeader()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB003-Only-Default-Header.docx"));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB002-Landscape-Section.docx"));
-
- List sources = null;
- sources = new List()
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB003-Only-Default-Header.docx"));
+ var source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB002-Landscape-Section.docx"));
+ var sources = new List()
{
new Source(new WmlDocument(source1Docx.FullName)) { KeepSections = true },
new Source(new WmlDocument(source2Docx.FullName)) { KeepSections = true, DiscardHeadersAndFootersInKeptSections = true },
@@ -77,12 +63,10 @@ public void DB003_DocumentBuilderOnlyDefaultHeader()
[Fact]
public void DB004_DocumentBuilderNoHeaders()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB004-No-Headers.docx"));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB002-Landscape-Section.docx"));
-
- List sources = null;
- sources = new List()
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB004-No-Headers.docx"));
+ var source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB002-Landscape-Section.docx"));
+ var sources = new List()
{
new Source(new WmlDocument(source1Docx.FullName)) { KeepSections = true },
new Source(new WmlDocument(source2Docx.FullName)) { KeepSections = true, DiscardHeadersAndFootersInKeptSections = true },
@@ -95,12 +79,10 @@ public void DB004_DocumentBuilderNoHeaders()
[Fact]
public void DB005_HeadersWithRefsToImages()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB005-Headers-With-Images.docx"));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB002-Landscape-Section.docx"));
-
- List sources = null;
- sources = new List()
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB005-Headers-With-Images.docx"));
+ var source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, "DB002-Landscape-Section.docx"));
+ var sources = new List()
{
new Source(new WmlDocument(source1Docx.FullName)) { KeepSections = true },
new Source(new WmlDocument(source2Docx.FullName)) { KeepSections = true, DiscardHeadersAndFootersInKeptSections = true },
@@ -113,14 +95,13 @@ public void DB005_HeadersWithRefsToImages()
[Fact]
public void DB006_Example_DocumentBuilder01()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1 = new FileInfo(Path.Combine(sourceDir.FullName, "DB006-Source1.docx"));
- FileInfo source2 = new FileInfo(Path.Combine(sourceDir.FullName, "DB006-Source2.docx"));
- FileInfo source3 = new FileInfo(Path.Combine(sourceDir.FullName, "DB006-Source3.docx"));
- List sources = null;
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source1 = new FileInfo(Path.Combine(sourceDir.FullName, "DB006-Source1.docx"));
+ var source2 = new FileInfo(Path.Combine(sourceDir.FullName, "DB006-Source2.docx"));
+ var source3 = new FileInfo(Path.Combine(sourceDir.FullName, "DB006-Source3.docx"));
// Create new document from 10 paragraphs starting at paragraph 5 of Source1.docx
- sources = new List()
+ var sources = new List()
{
new Source(new WmlDocument(source1.FullName), 5, 10, true),
};
@@ -169,9 +150,9 @@ public void DB006_Example_DocumentBuilder01()
new Source(new WmlDocument(source1.FullName), 0, 5, false),
new Source(new WmlDocument(source2.FullName), 0, 5, true),
};
- WmlDocument wmlOut5 = DocumentBuilder.BuildDocument(sources);
+ var wmlOut5 = DocumentBuilder.BuildDocument(sources);
var out5 = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "DB006-Out5.docx"));
-
+
wmlOut5.SaveAs(out5.FullName); // save it to the file system, but we could just as easily done something
// else with it.
Validate(out5);
@@ -180,14 +161,11 @@ public void DB006_Example_DocumentBuilder01()
[Fact]
public void DB007_Example_DocumentBuilder02_WhitePaper()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo spec = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-Spec.docx"));
- FileInfo whitePaper = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-WhitePaper.docx"));
- FileInfo paperAbstract = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-Abstract.docx"));
- FileInfo authorBio = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-AuthorBiography.docx"));
-
- List sources = null;
- sources = new List()
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var whitePaper = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-WhitePaper.docx"));
+ var paperAbstract = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-Abstract.docx"));
+ var authorBio = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-AuthorBiography.docx"));
+ var sources = new List()
{
new Source(new WmlDocument(whitePaper.FullName), 0, 1, true),
new Source(new WmlDocument(paperAbstract.FullName), false),
@@ -202,12 +180,12 @@ public void DB007_Example_DocumentBuilder02_WhitePaper()
[Fact]
public void DB008_DeleteParasWithGivenStyle()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo notes = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-Notes.docx"));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var notes = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-Notes.docx"));
List sources = null;
// Delete all paragraphs with a specific style.
- using (WordprocessingDocument doc = WordprocessingDocument.Open(notes.FullName, false))
+ using (var doc = WordprocessingDocument.Open(notes.FullName, false))
{
sources = doc
.MainDocumentPart
@@ -253,42 +231,42 @@ public void DB008_DeleteParasWithGivenStyle()
[InlineData("DB009-00160", "DB/HeadersFooters/Src/Watermark-2.docx", "DB/HeadersFooters/Dest/Letter.docx", "Templafy")]
[InlineData("DB009-00170", "DB/HeadersFooters/Src/Disclaimer.docx", "DB/HeadersFooters/Dest/Letter.docx", "Templafy")]
[InlineData("DB009-00180", "DB/HeadersFooters/Src/Footer.docx", "DB/HeadersFooters/Dest/Letter.docx", "Templafy")]
-
public void DB009_ImportIntoHeadersFooters(string testId, string src, string dest, string insertId)
{
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Load the source document
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocxFi = new FileInfo(Path.Combine(sourceDir.FullName, src));
- WmlDocument wmlSourceDocument = new WmlDocument(sourceDocxFi.FullName);
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDocxFi = new FileInfo(Path.Combine(sourceDir.FullName, src));
+ var wmlSourceDocument = new WmlDocument(sourceDocxFi.FullName);
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Load the dest document
- FileInfo destDocxFi = new FileInfo(Path.Combine(sourceDir.FullName, dest));
- WmlDocument wmlDestDocument = new WmlDocument(destDocxFi.FullName);
+ var destDocxFi = new FileInfo(Path.Combine(sourceDir.FullName, dest));
+ var wmlDestDocument = new WmlDocument(destDocxFi.FullName);
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create the dir for the test
var rootTempDir = TestUtil.TempDir;
var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
if (thisTestTempDir.Exists)
+ {
Assert.True(false, "Duplicate test id: " + testId);
+ }
else
+ {
thisTestTempDir.Create();
+ }
+
var tempDirFullName = thisTestTempDir.FullName;
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copy src DOCX to temp directory, for ease of review
while (true)
{
try
{
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
var sourceDocxCopiedToDestFileName = new FileInfo(Path.Combine(tempDirFullName, sourceDocxFi.Name));
if (!sourceDocxCopiedToDestFileName.Exists)
+ {
wmlSourceDocument.SaveAs(sourceDocxCopiedToDestFileName.FullName);
- //////////////////////////////////////////////////
+ }
break;
}
catch (IOException)
@@ -297,18 +275,17 @@ public void DB009_ImportIntoHeadersFooters(string testId, string src, string des
}
}
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copy dest DOCX to temp directory, for ease of review
while (true)
{
try
{
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
var destDocxCopiedToDestFileName = new FileInfo(Path.Combine(tempDirFullName, destDocxFi.Name));
if (!destDocxCopiedToDestFileName.Exists)
+ {
wmlDestDocument.SaveAs(destDocxCopiedToDestFileName.FullName);
- //////////////////////////////////////////////////
+ }
break;
}
catch (IOException)
@@ -317,7 +294,7 @@ public void DB009_ImportIntoHeadersFooters(string testId, string src, string des
}
}
- List sources = new List()
+ var sources = new List()
{
new Source(wmlDestDocument),
new Source(wmlSourceDocument, insertId),
@@ -328,138 +305,6 @@ public void DB009_ImportIntoHeadersFooters(string testId, string src, string des
Validate(outFi);
}
-#if false
- [Theory]
- [InlineData("DB999-00010", "DBTEMP/03DE57384B87AA6C2A3BDE87DDDD7F880DC55E.docx", true)]
- [InlineData("DB999-00020", "DBTEMP/0D3DEB27ED036116466BED616B2056CDD2783A.docx", false)]
- [InlineData("DB999-00030", "DBTEMP/421628B3F4B03B123CA8EDDA5009E449F5F47D.docx", false)]
- [InlineData("DB999-00040", "DBTEMP/58D4E8661C7F44FE33392B89B0A3CB0AF1684F.docx", false)]
- [InlineData("DB999-00050", "DBTEMP/67EBCA627D6D584CAB3EB1DF2E4C3982023DEE.docx", true)]
- [InlineData("DB999-00060", "DBTEMP/A529643E2FC3E2C682FA86DEE0A1B3064DCEE0.docx", false)]
- [InlineData("DB999-00070", "DBTEMP/E794032F0422B440D3C564F0E09E395519127D.docx", false)]
- [InlineData("DB999-00080", "DBTEMP/1FF1ADF30B24978E9449754459C743D3BC67ED.docx", false)]
- [InlineData("DB999-00090", "DBTEMP/5E685927DA2FECB88DE9CAF0BECEC88BC118A7.docx", false)]
- [InlineData("DB999-00100", "DBTEMP/6427BCF5C18B55D627B95F3E14924050628C5B.docx", false)]
- [InlineData("DB999-00110", "DBTEMP/91691E0D3AB89E9927A2BAC5D385BB6277648F.docx", false)]
- [InlineData("DB999-00120", "DBTEMP/9533BC5710190EA01DA86D29CD06880395C4AF.docx", false)]
- [InlineData("DB999-00130", "DBTEMP/E9CD8C556AA52CA7D31DADB51A201EEF580AA8.docx", false)]
- [InlineData("DB999-00140", "DBTEMP/21D3CE149C30B791F9A8BE092828E1469A9047.docx", false)]
- [InlineData("DB999-00150", "DBTEMP/AC0CB8CE43A7ECAE995BB542D4FB1060FB835B.docx", false)]
- [InlineData("DB999-00160", "DBTEMP/C61F69B52EC8B0E2C784C932B26F3C613AE671.docx", false)]
- [InlineData("DB999-00170", "DBTEMP/1DF04A9130B3EF858ACA6837A706A429904973.dotm", false)]
- [InlineData("DB999-00180", "DBTEMP/6E9F26B708DE6076B2C731B97AAA5288D839AB.docm", false)]
- [InlineData("DB999-00190", "DBTEMP/A6649726EA0BD7545932DDD51403D83E4D5917.docx", false)]
- [InlineData("DB999-00200", "DBTEMP/C8AE8AD0A73F24B7CFCFD11918B337CF2B90C9.docx", false)]
- [InlineData("DB999-00210", "DBTEMP/BC46A7FBB212EFD10878A39D91AE3ECAADDAB0.docx", false)]
- [InlineData("DB999-00220", "DBTEMP/B6F0E938B508676B322C47F3E0E29C8D786DB2.docm", false)]
- [InlineData("DB999-00230", "DBTEMP/D4D8694A51DECA243AF748B3232BE565EEE19D.docx", false)]
- [InlineData("DB999-00240", "DBTEMP/F20B3CE72BF635462E22BA3CA81CA9D57F6FEB.docx", false)]
- [InlineData("DB999-00250", "DBTEMP/74ED106FF88C1B195D97C466E00BECCB636A03.docx", false)]
- [InlineData("DB999-00260", "DBTEMP/4421A4B7B6ECC2813070309AA2D86C4BCA4AEF.docx", false)]
- [InlineData("DB999-00270", "DBTEMP/BC7D91B993807518F3D430B7C6592AFD6BD91C.docx", false)]
- [InlineData("DB999-00280", "DBTEMP/3006E76FE65E8A25A91ED204EEBEE6D6D62A44.docx", false)]
- [InlineData("DB999-00290", "DBTEMP/6254B74778BFFCD1799F4F2B3B01C2025AABB2.docx", false)]
- [InlineData("DB999-00300", "DBTEMP/5AD0A0BD99676B268D8E7C1F69238FB9B6149E.docx", false)]
- [InlineData("DB999-00310", "DBTEMP/2D58495ECCF30ED9507B707C689CA9C9D4B049.docx", false)]
-
- public void DB999_DocumentBuilder(string testId, string src, bool shouldThrow)
- {
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Load the source document
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocxFi = new FileInfo(Path.Combine(sourceDir.FullName, src));
- WmlDocument wmlSourceDocument = new WmlDocument(sourceDocxFi.FullName);
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Create the dir for the test
- var rootTempDir = TestUtil.TempDir;
- var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
- if (thisTestTempDir.Exists)
- Assert.True(false, "Duplicate test id: " + testId);
- else
- thisTestTempDir.Create();
- var tempDirFullName = thisTestTempDir.FullName;
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Copy src DOCX to temp directory, for ease of review
-
- while (true)
- {
- try
- {
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
- var sourceDocxCopiedToDestFileName = new FileInfo(Path.Combine(tempDirFullName, sourceDocxFi.Name));
- if (!sourceDocxCopiedToDestFileName.Exists)
- wmlSourceDocument.SaveAs(sourceDocxCopiedToDestFileName.FullName);
- //////////////////////////////////////////////////
- break;
- }
- catch (IOException)
- {
- System.Threading.Thread.Sleep(50);
- }
- }
-
- List expectedErrors;
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(wmlSourceDocument.DocumentByteArray, 0, wmlSourceDocument.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, false))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- expectedErrors = validator.Validate(wDoc)
- .Select(e => e.Description)
- .Distinct()
- .ToList();
- }
- }
- foreach (var item in s_ExpectedErrors)
- expectedErrors.Add(item);
-
- List sources = new List()
- {
- new Source(wmlSourceDocument, true),
- };
-
- var outFi = new FileInfo(Path.Combine(tempDirFullName, "Output.docx"));
-
- if (shouldThrow)
- {
- Assert.Throws(() => DocumentBuilder.BuildDocument(sources, outFi.FullName));
- }
- else
- {
- var outWml = DocumentBuilder.BuildDocument(sources);
- outWml.SaveAs(outFi.FullName);
-
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(outWml.DocumentByteArray, 0, outWml.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, false))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e =>
- {
- var str = e.Description;
- foreach (var ee in expectedErrors)
- {
- if (str.Contains(ee))
- return false;
- }
- return true;
- });
- if (errors.Count() != 0)
- {
- var message = errors.Select(e => e.Description + Environment.NewLine).StringConcatenate();
- Assert.True(false, message);
- }
- }
- }
-
- }
- }
-#endif
-
private class DocumentInfo
{
public int DocumentNumber;
@@ -470,11 +315,11 @@ private class DocumentInfo
[Fact]
public void DB009_ShredDocument()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo spec = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-Spec.docx"));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var spec = new FileInfo(Path.Combine(sourceDir.FullName, "DB007-Spec.docx"));
// Shred a document into multiple parts for each section
List documentList;
- using (WordprocessingDocument doc = WordprocessingDocument.Open(spec.FullName, false))
+ using (var doc = WordprocessingDocument.Open(spec.FullName, false))
{
var sectionCounts = doc
.MainDocumentPart
@@ -498,10 +343,10 @@ public void DB009_ShredDocument()
Paragraph = p,
Index = i,
});
- var zipped = PtExtensions.PtZip(beforeZipped, sectionCounts, (pi, sc) => new
+ var zipped = beforeZipped.PtZip(sectionCounts, (pi, sc) => new
{
- Paragraph = pi.Paragraph,
- Index = pi.Index,
+ pi.Paragraph,
+ pi.Index,
SectionIndex = sc,
});
documentList = zipped
@@ -516,9 +361,9 @@ public void DB009_ShredDocument()
}
foreach (var doc in documentList)
{
- string fileName = String.Format("DB009-Section{0:000}.docx", doc.DocumentNumber);
+ var fileName = string.Format("DB009-Section{0:000}.docx", doc.DocumentNumber);
var fiSection = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, fileName));
- List documentSource = new List {
+ var documentSource = new List {
new Source(new WmlDocument(spec.FullName), doc.Start, doc.Count, true)
};
DocumentBuilder.BuildDocument(documentSource, fiSection.FullName);
@@ -526,14 +371,14 @@ public void DB009_ShredDocument()
}
// Re-assemble the parts into a single document.
- List sources = TestUtil.TempDir
+ var sources = TestUtil.TempDir
.GetFiles("DB009-Section*.docx")
.Select(d => new Source(new WmlDocument(d.FullName), true))
.ToList();
var fiReassembled = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "DB009-Reassembled.docx"));
DocumentBuilder.BuildDocument(sources, fiReassembled.FullName);
- using (WordprocessingDocument doc = WordprocessingDocument.Open(fiReassembled.FullName, true))
+ using (var doc = WordprocessingDocument.Open(fiReassembled.FullName, true))
{
ReferenceAdder.AddToc(doc, "/w:document/w:body/w:p[1]",
@"TOC \o '1-3' \h \z \u", null, null);
@@ -541,33 +386,32 @@ public void DB009_ShredDocument()
Validate(fiReassembled);
}
-
[Fact]
public void DB010_InsertUsingInsertId()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo front = new FileInfo(Path.Combine(sourceDir.FullName, "DB010-FrontMatter.docx"));
- FileInfo insert01 = new FileInfo(Path.Combine(sourceDir.FullName, "DB010-Insert-01.docx"));
- FileInfo insert02 = new FileInfo(Path.Combine(sourceDir.FullName, "DB010-Insert-02.docx"));
- FileInfo template = new FileInfo(Path.Combine(sourceDir.FullName, "DB010-Template.docx"));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var front = new FileInfo(Path.Combine(sourceDir.FullName, "DB010-FrontMatter.docx"));
+ var insert01 = new FileInfo(Path.Combine(sourceDir.FullName, "DB010-Insert-01.docx"));
+ var insert02 = new FileInfo(Path.Combine(sourceDir.FullName, "DB010-Insert-02.docx"));
+ var template = new FileInfo(Path.Combine(sourceDir.FullName, "DB010-Template.docx"));
- WmlDocument doc1 = new WmlDocument(template.FullName);
- using (MemoryStream mem = new MemoryStream())
+ var doc1 = new WmlDocument(template.FullName);
+ using (var mem = new MemoryStream())
{
mem.Write(doc1.DocumentByteArray, 0, doc1.DocumentByteArray.Length);
- using (WordprocessingDocument doc = WordprocessingDocument.Open(mem, true))
+ using (var doc = WordprocessingDocument.Open(mem, true))
{
- XDocument xDoc = doc.MainDocumentPart.GetXDocument();
- XElement frontMatterPara = xDoc.Root.Descendants(W.txbxContent).Elements(W.p).FirstOrDefault();
+ var xDoc = doc.MainDocumentPart.GetXDocument();
+ var frontMatterPara = xDoc.Root.Descendants(W.txbxContent).Elements(W.p).FirstOrDefault();
frontMatterPara.ReplaceWith(
new XElement(PtOpenXml.Insert,
new XAttribute("Id", "Front")));
- XElement tbl = xDoc.Root.Element(W.body).Elements(W.tbl).FirstOrDefault();
- XElement firstCell = tbl.Descendants(W.tr).First().Descendants(W.p).First();
+ var tbl = xDoc.Root.Element(W.body).Elements(W.tbl).FirstOrDefault();
+ var firstCell = tbl.Descendants(W.tr).First().Descendants(W.p).First();
firstCell.ReplaceWith(
new XElement(PtOpenXml.Insert,
new XAttribute("Id", "Liz")));
- XElement secondCell = tbl.Descendants(W.tr).Skip(1).First().Descendants(W.p).First();
+ var secondCell = tbl.Descendants(W.tr).Skip(1).First().Descendants(W.p).First();
secondCell.ReplaceWith(
new XElement(PtOpenXml.Insert,
new XAttribute("Id", "Eric")));
@@ -576,7 +420,7 @@ public void DB010_InsertUsingInsertId()
doc1.DocumentByteArray = mem.ToArray();
}
- List sources = new List()
+ var sources = new List()
{
new Source(doc1, true),
new Source(new WmlDocument(insert01.FullName), "Liz"),
@@ -592,12 +436,10 @@ public void DB010_InsertUsingInsertId()
public void DB011_BodyAndHeaderWithShapes()
{
// Both of theses documents have a shape with a DocProperties ID of 1.
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1 = new FileInfo(Path.Combine(sourceDir.FullName, "DB011-Header-With-Shape.docx"));
- FileInfo source2 = new FileInfo(Path.Combine(sourceDir.FullName, "DB011-Body-With-Shape.docx"));
- List sources = null;
-
- sources = new List()
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source1 = new FileInfo(Path.Combine(sourceDir.FullName, "DB011-Header-With-Shape.docx"));
+ var source2 = new FileInfo(Path.Combine(sourceDir.FullName, "DB011-Body-With-Shape.docx"));
+ var sources = new List()
{
new Source(new WmlDocument(source1.FullName)),
new Source(new WmlDocument(source2.FullName)),
@@ -610,17 +452,14 @@ public void DB011_BodyAndHeaderWithShapes()
ValidateUniqueDocPrIds(processedDestDocx);
}
-
[Fact]
public void DB012_NumberingsWithSameAbstractNumbering()
{
// This document has three numbering definitions that use the same abstract numbering definition.
- string name = "DB012-Lists-With-Different-Numberings.docx";
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
-
- List sources = null;
- sources = new List()
+ var name = "DB012-Lists-With-Different-Numberings.docx";
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sources = new List()
{
new Source(new WmlDocument(sourceDocx.FullName)),
};
@@ -628,11 +467,9 @@ public void DB012_NumberingsWithSameAbstractNumbering()
sourceDocx.Name.Replace(".docx", "-processed-by-DocumentBuilder.docx")));
DocumentBuilder.BuildDocument(sources, processedDestDocx.FullName);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(processedDestDocx.FullName, false))
- {
- var numberingRoot = wDoc.MainDocumentPart.NumberingDefinitionsPart.GetXDocument().Root;
- Assert.Equal(3, numberingRoot.Elements(W.num).Count());
- }
+ using var wDoc = WordprocessingDocument.Open(processedDestDocx.FullName, false);
+ var numberingRoot = wDoc.MainDocumentPart.NumberingDefinitionsPart.GetXDocument().Root;
+ Assert.Equal(3, numberingRoot.Elements(W.num).Count());
}
[Fact]
@@ -640,10 +477,10 @@ public void DB013a_LocalizedStyleIds_Heading()
{
// Each of these documents have changed the font color of the Heading 1 style, one to red, the other to green.
// One of the documents were created with English as the Word display language, the other with Danish as the language.
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1 =
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source1 =
new FileInfo(Path.Combine(sourceDir.FullName, "DB013a-Red-Heading1-English.docx"));
- FileInfo source2 = new FileInfo(Path.Combine(sourceDir.FullName,
+ var source2 = new FileInfo(Path.Combine(sourceDir.FullName,
"DB013a-Green-Heading1-Danish.docx"));
List sources = null;
@@ -656,17 +493,15 @@ public void DB013a_LocalizedStyleIds_Heading()
new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "DB013a-Colored-Heading1.docx"));
DocumentBuilder.BuildDocument(sources, processedDestDocx.FullName);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(processedDestDocx.FullName, false))
- {
- var styles = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument().Root.Elements(W.style).ToArray();
- Assert.Equal(1, styles.Count(s => s.Element(W.name).Attribute(W.val).Value == "heading 1"));
+ using var wDoc = WordprocessingDocument.Open(processedDestDocx.FullName, false);
+ var styles = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument().Root.Elements(W.style).ToArray();
+ Assert.Equal(1, styles.Count(s => s.Element(W.name).Attribute(W.val).Value == "heading 1"));
- var styleIds = new HashSet(styles.Select(s => s.Attribute(W.styleId).Value));
- var paragraphStylesIds = new HashSet(wDoc.MainDocumentPart.GetXDocument()
- .Descendants(W.pStyle)
- .Select(p => p.Attribute(W.val).Value));
- Assert.Subset(styleIds, paragraphStylesIds);
- }
+ var styleIds = new HashSet(styles.Select(s => s.Attribute(W.styleId).Value));
+ var paragraphStylesIds = new HashSet(wDoc.MainDocumentPart.GetXDocument()
+ .Descendants(W.pStyle)
+ .Select(p => p.Attribute(W.val).Value));
+ Assert.Subset(styleIds, paragraphStylesIds);
}
[Fact]
@@ -674,10 +509,10 @@ public void DB013b_LocalizedStyleIds_List()
{
// Each of these documents have changed the font color of the List Paragraph style, one to orange, the other to blue.
// One of the documents were created with English as the Word display language, the other with Danish as the language.
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1 =
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source1 =
new FileInfo(Path.Combine(sourceDir.FullName, "DB013b-Orange-List-Danish.docx"));
- FileInfo source2 = new FileInfo(Path.Combine(sourceDir.FullName,
+ var source2 = new FileInfo(Path.Combine(sourceDir.FullName,
"DB013b-Blue-List-English.docx"));
List sources = null;
@@ -690,27 +525,23 @@ public void DB013b_LocalizedStyleIds_List()
new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "DB013b-Colored-List.docx"));
DocumentBuilder.BuildDocument(sources, processedDestDocx.FullName);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(processedDestDocx.FullName, false))
- {
- var styles = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument().Root.Elements(W.style).ToArray();
- Assert.Equal(1, styles.Count(s => s.Element(W.name).Attribute(W.val).Value == "List Paragraph"));
+ using var wDoc = WordprocessingDocument.Open(processedDestDocx.FullName, false);
+ var styles = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument().Root.Elements(W.style).ToArray();
+ Assert.Equal(1, styles.Count(s => s.Element(W.name).Attribute(W.val).Value == "List Paragraph"));
- var styleIds = new HashSet(styles.Select(s => s.Attribute(W.styleId).Value));
- var paragraphStylesIds = new HashSet(wDoc.MainDocumentPart.GetXDocument()
- .Descendants(W.pStyle)
- .Select(p => p.Attribute(W.val).Value));
- Assert.Subset(styleIds, paragraphStylesIds);
- }
+ var styleIds = new HashSet(styles.Select(s => s.Attribute(W.styleId).Value));
+ var paragraphStylesIds = new HashSet(wDoc.MainDocumentPart.GetXDocument()
+ .Descendants(W.pStyle)
+ .Select(p => p.Attribute(W.val).Value));
+ Assert.Subset(styleIds, paragraphStylesIds);
}
[Fact]
public void DB014_KeepWebExtensions()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source = new FileInfo(Path.Combine(sourceDir.FullName, "DB014-WebExtensions.docx"));
- List sources = null;
-
- sources = new List()
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source = new FileInfo(Path.Combine(sourceDir.FullName, "DB014-WebExtensions.docx"));
+ var sources = new List()
{
new Source(new WmlDocument(source.FullName)),
};
@@ -718,22 +549,18 @@ public void DB014_KeepWebExtensions()
DocumentBuilder.BuildDocument(sources, processedDestDocx.FullName);
Validate(processedDestDocx);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(processedDestDocx.FullName, false))
- {
- Assert.NotNull(wDoc.WebExTaskpanesPart);
- Assert.Equal(2, wDoc.WebExTaskpanesPart.Taskpanes.ChildElements.Count);
- Assert.Equal(2, wDoc.WebExTaskpanesPart.WebExtensionParts.Count());
- }
+ using var wDoc = WordprocessingDocument.Open(processedDestDocx.FullName, false);
+ Assert.NotNull(wDoc.WebExTaskpanesPart);
+ Assert.Equal(2, wDoc.WebExTaskpanesPart.Taskpanes.ChildElements.Count);
+ Assert.Equal(2, wDoc.WebExTaskpanesPart.WebExtensionParts.Count());
}
[Fact]
public void DB015_LatentStyles()
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source = new FileInfo(Path.Combine(sourceDir.FullName, "DB015-LatentStyles.docx"));
- List sources = null;
-
- sources = new List()
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source = new FileInfo(Path.Combine(sourceDir.FullName, "DB015-LatentStyles.docx"));
+ var sources = new List()
{
new Source(new WmlDocument(source.FullName)),
};
@@ -752,12 +579,10 @@ public void DB015_LatentStyles()
[Fact]
public void DB0016_DocDefaultStyles()
{
- string name = "DB0016-DocDefaultStyles.docx";
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
-
- List sources = null;
- sources = new List()
+ var name = "DB0016-DocDefaultStyles.docx";
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sources = new List()
{
new Source(new WmlDocument(sourceDocx.FullName), true),
};
@@ -765,11 +590,26 @@ public void DB0016_DocDefaultStyles()
sourceDocx.Name.Replace(".docx", "-processed-by-DocumentBuilder.docx")));
DocumentBuilder.BuildDocument(sources, processedDestDocx.FullName);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(processedDestDocx.FullName, true))
+ using var wDoc = WordprocessingDocument.Open(processedDestDocx.FullName, true);
+ var styles = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument().Root.Elements(W.docDefaults).ToArray();
+ Assert.Single(styles);
+ }
+
+ [Fact]
+ public void DB017_ApplyHeaderAndFooterToAllDocs()
+ {
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var source1 = new FileInfo(Path.Combine(sourceDir.FullName, "DB017-ApplyHeaderAndFooterToAllDocs-Portrait-TwoColumns.docx"));
+ var source2 = new FileInfo(Path.Combine(sourceDir.FullName, "DB017-ApplyHeaderAndFooterToAllDocs-Landscape-SingleColumn.docx"));
+
+ var sources = new List()
{
- var styles = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument().Root.Elements(W.docDefaults).ToArray();
- Assert.Single(styles);
- }
+ new Source(new WmlDocument(source1.FullName)){KeepSections = true},
+ new Source(new WmlDocument(source2.FullName)){KeepSections = true, DiscardHeadersAndFootersInKeptSections = true},
+ };
+
+ var processedDestDocx = new FileInfo(Path.Combine(Path.Combine(TestUtil.TempDir.FullName), "DB017-ApplyHeaderAndFooterToAllDocs.docx"));
+ DocumentBuilder.BuildDocument(sources, processedDestDocx.FullName);
}
[Theory]
@@ -785,20 +625,18 @@ public void DB0016_DocDefaultStyles()
[InlineData("DB100-00100", "DB/GlossaryDocuments/FooterContent-built.docx", "DB/GlossaryDocuments/BaseDocument.docx,0,4", "DB/GlossaryDocuments/FooterContent.docx", "DB/GlossaryDocuments/BaseDocument.docx,4", null, null, null)]
[InlineData("DB100-00110", "DB/GlossaryDocuments/HeaderContent-built.docx", "DB/GlossaryDocuments/BaseDocument.docx,0,4", "DB/GlossaryDocuments/HeaderContent.docx", "DB/GlossaryDocuments/BaseDocument.docx,4", null, null, null)]
[InlineData("DB100-00200", null, "DB/GlossaryDocuments/BaseDocument.docx", "DB/GlossaryDocuments/CellLevelContentControl.docx", "DB/GlossaryDocuments/NestedContentControl.docx", null, null, null)]
-
public void WithGlossaryDocuments(string testId, string baseline, string src1, string src2, string src3, string src4, string src5, string src6)
{
var rawSources = new string[] { src1, src2, src3, src4, src5, src6, };
var sourcesStr = rawSources.Where(s => s != null).ToArray();
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Load the source documents
- List sources = sourcesStr.Select(s =>
+ var sources = sourcesStr.Select(s =>
{
var spl = s.Split(',');
if (spl.Length == 1)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
var sourceFi = new FileInfo(Path.Combine(sourceDir.FullName, s));
var wmlSource = new WmlDocument(sourceFi.FullName);
return new Source(wmlSource);
@@ -806,7 +644,7 @@ public void WithGlossaryDocuments(string testId, string baseline, string src1, s
else if (spl.Length == 2)
{
var start = int.Parse(spl[1]);
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
var sourceFi = new FileInfo(Path.Combine(sourceDir.FullName, spl[0]));
return new Source(sourceFi.FullName, start, true);
}
@@ -814,24 +652,27 @@ public void WithGlossaryDocuments(string testId, string baseline, string src1, s
{
var start = int.Parse(spl[1]);
var count = int.Parse(spl[2]);
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
var sourceFi = new FileInfo(Path.Combine(sourceDir.FullName, spl[0]));
return new Source(sourceFi.FullName, start, count, true);
}
})
.ToList();
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create the dir for the test
var rootTempDir = TestUtil.TempDir;
var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
if (thisTestTempDir.Exists)
+ {
Assert.True(false, "Duplicate test id: " + testId);
+ }
else
+ {
thisTestTempDir.Create();
+ }
+
var tempDirFullName = thisTestTempDir.FullName;
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copy sources to temp directory, for ease of review
foreach (var item in sources)
@@ -839,51 +680,50 @@ public void WithGlossaryDocuments(string testId, string baseline, string src1, s
var fi = new FileInfo(item.WmlDocument.FileName);
var sourceCopiedToDestFi = new FileInfo(Path.Combine(tempDirFullName, fi.Name));
if (!sourceCopiedToDestFi.Exists)
+ {
File.Copy(item.WmlDocument.FileName, sourceCopiedToDestFi.FullName);
+ }
}
if (baseline != null)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
var baselineFi = new FileInfo(Path.Combine(sourceDir.FullName, baseline));
var baselineCopiedToDestFileName = new FileInfo(Path.Combine(tempDirFullName, baselineFi.Name));
File.Copy(baselineFi.FullName, baselineCopiedToDestFileName.FullName);
}
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Use DocumentBuilder to build the destination document
var outFi = new FileInfo(Path.Combine(tempDirFullName, "Output.docx"));
- DocumentBuilderSettings settings = new DocumentBuilderSettings();
+ var settings = new DocumentBuilderSettings();
DocumentBuilder.BuildDocument(sources, outFi.FullName, settings);
Validate(outFi);
}
private void Validate(FileInfo fi)
{
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(fi.FullName, true))
+ using var wDoc = WordprocessingDocument.Open(fi.FullName, true);
+ var v = new OpenXmlValidator();
+ var errors = v.Validate(wDoc).Where(ve =>
{
- OpenXmlValidator v = new OpenXmlValidator();
- var errors = v.Validate(wDoc).Where(ve =>
- {
- var found = s_ExpectedErrors.Any(xe => ve.Description.Contains(xe));
- return !found;
- });
+ var found = s_ExpectedErrors.Any(xe => ve.Description.Contains(xe));
+ return !found;
+ });
- if (errors.Count() != 0)
+ if (errors.Any())
+ {
+ var sb = new StringBuilder();
+ foreach (var item in errors)
{
- StringBuilder sb = new StringBuilder();
- foreach (var item in errors)
- {
- sb.Append(item.Description).Append(Environment.NewLine);
- }
- var s = sb.ToString();
- Assert.True(false, s);
+ sb.Append(item.Description).Append(Environment.NewLine);
}
+ var s = sb.ToString();
+ Assert.True(false, s);
}
}
- private static List s_ExpectedErrors = new List()
+ private static readonly List s_ExpectedErrors = new List()
{
"The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:evenHBand' attribute is not declared.",
"The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:evenVBand' attribute is not declared.",
@@ -916,25 +756,44 @@ private void Validate(FileInfo fi)
private void ValidateUniqueDocPrIds(FileInfo fi)
{
- using (WordprocessingDocument doc = WordprocessingDocument.Open(fi.FullName, false))
+ using var doc = WordprocessingDocument.Open(fi.FullName, false);
+ var docPrIds = new HashSet();
+ foreach (var item in doc.MainDocumentPart.GetXDocument().Descendants(WP.docPr))
+ {
+ Assert.True(docPrIds.Add(item.Attribute(NoNamespace.id).Value));
+ }
+
+ foreach (var header in doc.MainDocumentPart.HeaderParts)
{
- var docPrIds = new HashSet();
- foreach (var item in doc.MainDocumentPart.GetXDocument().Descendants(WP.docPr))
- Assert.True(docPrIds.Add(item.Attribute(NoNamespace.id).Value));
- foreach (var header in doc.MainDocumentPart.HeaderParts)
foreach (var item in header.GetXDocument().Descendants(WP.docPr))
+ {
Assert.True(docPrIds.Add(item.Attribute(NoNamespace.id).Value));
- foreach (var footer in doc.MainDocumentPart.FooterParts)
+ }
+ }
+
+ foreach (var footer in doc.MainDocumentPart.FooterParts)
+ {
foreach (var item in footer.GetXDocument().Descendants(WP.docPr))
+ {
Assert.True(docPrIds.Add(item.Attribute(NoNamespace.id).Value));
- if (doc.MainDocumentPart.FootnotesPart != null)
- foreach (var item in doc.MainDocumentPart.FootnotesPart.GetXDocument().Descendants(WP.docPr))
- Assert.True(docPrIds.Add(item.Attribute(NoNamespace.id).Value));
- if (doc.MainDocumentPart.EndnotesPart != null)
- foreach (var item in doc.MainDocumentPart.EndnotesPart.GetXDocument().Descendants(WP.docPr))
- Assert.True(docPrIds.Add(item.Attribute(NoNamespace.id).Value));
+ }
+ }
+
+ if (doc.MainDocumentPart.FootnotesPart != null)
+ {
+ foreach (var item in doc.MainDocumentPart.FootnotesPart.GetXDocument().Descendants(WP.docPr))
+ {
+ Assert.True(docPrIds.Add(item.Attribute(NoNamespace.id).Value));
+ }
+ }
+
+ if (doc.MainDocumentPart.EndnotesPart != null)
+ {
+ foreach (var item in doc.MainDocumentPart.EndnotesPart.GetXDocument().Descendants(WP.docPr))
+ {
+ Assert.True(docPrIds.Add(item.Attribute(NoNamespace.id).Value));
+ }
}
}
}
-}
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/FormattingAssemblerTests.cs b/OpenXmlPowerTools.Tests/FormattingAssemblerTests.cs
index 2ce730b1..4980dcbf 100644
--- a/OpenXmlPowerTools.Tests/FormattingAssemblerTests.cs
+++ b/OpenXmlPowerTools.Tests/FormattingAssemblerTests.cs
@@ -1,24 +1,14 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using Codeuctivity.OpenXmlPowerTools;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Validation;
using System;
using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Validation;
-using DocumentFormat.OpenXml.Wordprocessing;
-using OpenXmlPowerTools;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class FaTests
{
@@ -47,38 +37,41 @@ public class FaTests
[InlineData("FA001-00220", "FA/RevTracking/022-TablePropertiesChange.docx")]
[InlineData("FA001-00230", "FA/RevTracking/023-CellPropertiesChange.docx")]
[InlineData("FA001-00240", "FA/RevTracking/024-RowPropertiesChange.docx")]
-
public void FA001_DocumentsWithRevTracking(string testId, string src)
{
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Load the source document
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocxFi = new FileInfo(Path.Combine(sourceDir.FullName, src));
- WmlDocument wmlSourceDocument = new WmlDocument(sourceDocxFi.FullName);
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDocxFi = new FileInfo(Path.Combine(sourceDir.FullName, src));
+ var wmlSourceDocument = new WmlDocument(sourceDocxFi.FullName);
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create the dir for the test
var rootTempDir = TestUtil.TempDir;
var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
if (thisTestTempDir.Exists)
+ {
Assert.True(false, "Duplicate test id: " + testId);
+ }
else
+ {
thisTestTempDir.Create();
+ }
+
var tempDirFullName = thisTestTempDir.FullName;
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copy src DOCX to temp directory, for ease of review
var sourceDocxCopiedToDestFileName = new FileInfo(Path.Combine(tempDirFullName, sourceDocxFi.Name));
if (!sourceDocxCopiedToDestFileName.Exists)
+ {
wmlSourceDocument.SaveAs(sourceDocxCopiedToDestFileName.FullName);
+ }
var sourceDocxAcceptedCopiedToDestFileName = new FileInfo(Path.Combine(tempDirFullName, sourceDocxFi.Name.ToLower().Replace(".docx", "-accepted.docx")));
var wmlSourceAccepted = RevisionProcessor.AcceptRevisions(wmlSourceDocument);
wmlSourceAccepted.SaveAs(sourceDocxAcceptedCopiedToDestFileName.FullName);
var outFi = new FileInfo(Path.Combine(tempDirFullName, "Output.docx"));
- FormattingAssemblerSettings settings = new FormattingAssemblerSettings();
+ var settings = new FormattingAssemblerSettings();
var assembledWml = FormattingAssembler.AssembleFormatting(wmlSourceDocument, settings);
assembledWml.SaveAs(outFi.FullName);
@@ -91,29 +84,27 @@ public void FA001_DocumentsWithRevTracking(string testId, string src)
private void Validate(FileInfo fi)
{
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(fi.FullName, true))
+ using var wDoc = WordprocessingDocument.Open(fi.FullName, true);
+ var v = new OpenXmlValidator();
+ var errors = v.Validate(wDoc).Where(ve =>
{
- OpenXmlValidator v = new OpenXmlValidator();
- var errors = v.Validate(wDoc).Where(ve =>
- {
- var found = s_ExpectedErrors.Any(xe => ve.Description.Contains(xe));
- return !found;
- });
+ var found = s_ExpectedErrors.Any(xe => ve.Description.Contains(xe));
+ return !found;
+ });
- if (errors.Count() != 0)
+ if (errors.Any())
+ {
+ var sb = new StringBuilder();
+ foreach (var item in errors)
{
- StringBuilder sb = new StringBuilder();
- foreach (var item in errors)
- {
- sb.Append(item.Description).Append(Environment.NewLine);
- }
- var s = sb.ToString();
- Assert.True(false, s);
+ sb.Append(item.Description).Append(Environment.NewLine);
}
+ var s = sb.ToString();
+ Assert.True(false, s);
}
}
- private static List s_ExpectedErrors = new List()
+ private static readonly List s_ExpectedErrors = new List()
{
"The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:evenHBand' attribute is not declared.",
"The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:evenVBand' attribute is not declared.",
@@ -146,5 +137,4 @@ private void Validate(FileInfo fi)
"The element has invalid child element 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:del'.",
};
}
-}
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/HtmlConverterTests.cs b/OpenXmlPowerTools.Tests/HtmlConverterTests.cs
deleted file mode 100644
index 9bdb2165..00000000
--- a/OpenXmlPowerTools.Tests/HtmlConverterTests.cs
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-#define COPY_FILES_FOR_DEBUGGING
-
-// DO_CONVERSION_VIA_WORD is defined in the project OpenXmlPowerTools.Tests.OA.csproj, but not in the OpenXmlPowerTools.Tests.csproj
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
-using Xunit;
-
-#if DO_CONVERSION_VIA_WORD
-using Word = Microsoft.Office.Interop.Word;
-#endif
-
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
-{
- public class HcTests
- {
- public static bool s_CopySourceFiles = true;
- public static bool s_CopyFormattingAssembledDocx = true;
- public static bool s_ConvertUsingWord = true;
-
- // PowerShell oneliner that generates InlineData for all files in a directory
- // dir | % { '[InlineData("' + $_.Name + '")]' } | clip
-
- [Theory]
- [InlineData("HC001-5DayTourPlanTemplate.docx")]
- [InlineData("HC002-Hebrew-01.docx")]
- [InlineData("HC003-Hebrew-02.docx")]
- [InlineData("HC004-ResumeTemplate.docx")]
- [InlineData("HC005-TaskPlanTemplate.docx")]
- [InlineData("HC006-Test-01.docx")]
- [InlineData("HC007-Test-02.docx")]
- [InlineData("HC008-Test-03.docx")]
- [InlineData("HC009-Test-04.docx")]
- [InlineData("HC010-Test-05.docx")]
- [InlineData("HC011-Test-06.docx")]
- [InlineData("HC012-Test-07.docx")]
- [InlineData("HC013-Test-08.docx")]
- [InlineData("HC014-RTL-Table-01.docx")]
- [InlineData("HC015-Vertical-Spacing-atLeast.docx")]
- [InlineData("HC016-Horizontal-Spacing-firstLine.docx")]
- [InlineData("HC017-Vertical-Alignment-Cell-01.docx")]
- [InlineData("HC018-Vertical-Alignment-Para-01.docx")]
- [InlineData("HC019-Hidden-Run.docx")]
- [InlineData("HC020-Small-Caps.docx")]
- [InlineData("HC021-Symbols.docx")]
- [InlineData("HC022-Table-Of-Contents.docx")]
- [InlineData("HC023-Hyperlink.docx")]
- [InlineData("HC024-Tabs-01.docx")]
- [InlineData("HC025-Tabs-02.docx")]
- [InlineData("HC026-Tabs-03.docx")]
- [InlineData("HC027-Tabs-04.docx")]
- [InlineData("HC028-No-Break-Hyphen.docx")]
- [InlineData("HC029-Table-Merged-Cells.docx")]
- [InlineData("HC030-Content-Controls.docx")]
- [InlineData("HC031-Complicated-Document.docx")]
- [InlineData("HC032-Named-Color.docx")]
- [InlineData("HC033-Run-With-Border.docx")]
- [InlineData("HC034-Run-With-Position.docx")]
- [InlineData("HC035-Strike-Through.docx")]
- [InlineData("HC036-Super-Script.docx")]
- [InlineData("HC037-Sub-Script.docx")]
- [InlineData("HC038-Conflicting-Border-Weight.docx")]
- [InlineData("HC039-Bold.docx")]
- [InlineData("HC040-Hyperlink-Fieldcode-01.docx")]
- [InlineData("HC041-Hyperlink-Fieldcode-02.docx")]
- [InlineData("HC042-Image-Png.docx")]
- [InlineData("HC043-Chart.docx")]
- [InlineData("HC044-Embedded-Workbook.docx")]
- [InlineData("HC045-Italic.docx")]
- [InlineData("HC046-BoldAndItalic.docx")]
- [InlineData("HC047-No-Section.docx")]
- [InlineData("HC048-Excerpt.docx")]
- [InlineData("HC049-Borders.docx")]
- [InlineData("HC050-Shaded-Text-01.docx")]
- [InlineData("HC051-Shaded-Text-02.docx")]
- [InlineData("HC060-Image-with-Hyperlink.docx")]
- [InlineData("HC061-Hyperlink-in-Field.docx")]
-
- public void HC001(string name)
- {
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
-
-#if COPY_FILES_FOR_DEBUGGING
- var sourceCopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-1-Source.docx")));
- if (!sourceCopiedToDestDocx.Exists)
- File.Copy(sourceDocx.FullName, sourceCopiedToDestDocx.FullName);
-
- var assembledFormattingDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-2-FormattingAssembled.docx")));
- if (!assembledFormattingDestDocx.Exists)
- CopyFormattingAssembledDocx(sourceDocx, assembledFormattingDestDocx);
-#endif
-
- var oxPtConvertedDestHtml = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-3-OxPt.html")));
- ConvertToHtml(sourceDocx, oxPtConvertedDestHtml);
-
-#if DO_CONVERSION_VIA_WORD
- var wordConvertedDocHtml = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-4-Word.html")));
- ConvertToHtmlUsingWord(sourceDocx, wordConvertedDocHtml);
-#endif
-
- }
-
- [Theory]
- [InlineData("HC006-Test-01.docx")]
- public void HC002_NoCssClasses(string name)
- {
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
-
- var oxPtConvertedDestHtml = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-5-OxPt-No-CSS-Classes.html")));
- ConvertToHtmlNoCssClasses(sourceDocx, oxPtConvertedDestHtml);
- }
-
- private static void CopyFormattingAssembledDocx(FileInfo source, FileInfo dest)
- {
- var ba = File.ReadAllBytes(source.FullName);
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(ba, 0, ba.Length);
- using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(ms, true))
- {
-
- RevisionAccepter.AcceptRevisions(wordDoc);
- SimplifyMarkupSettings simplifyMarkupSettings = new SimplifyMarkupSettings
- {
- RemoveComments = true,
- RemoveContentControls = true,
- RemoveEndAndFootNotes = true,
- RemoveFieldCodes = false,
- RemoveLastRenderedPageBreak = true,
- RemovePermissions = true,
- RemoveProof = true,
- RemoveRsidInfo = true,
- RemoveSmartTags = true,
- RemoveSoftHyphens = true,
- RemoveGoBackBookmark = true,
- ReplaceTabsWithSpaces = false,
- };
- MarkupSimplifier.SimplifyMarkup(wordDoc, simplifyMarkupSettings);
-
- FormattingAssemblerSettings formattingAssemblerSettings = new FormattingAssemblerSettings
- {
- RemoveStyleNamesFromParagraphAndRunProperties = false,
- ClearStyles = false,
- RestrictToSupportedLanguages = false,
- RestrictToSupportedNumberingFormats = false,
- CreateHtmlConverterAnnotationAttributes = true,
- OrderElementsPerStandard = false,
- ListItemRetrieverSettings =
- new ListItemRetrieverSettings()
- {
- ListItemTextImplementations = ListItemRetrieverSettings.DefaultListItemTextImplementations,
- },
- };
-
- FormattingAssembler.AssembleFormatting(wordDoc, formattingAssemblerSettings);
- }
- var newBa = ms.ToArray();
- File.WriteAllBytes(dest.FullName, newBa);
- }
- }
-
- private static void ConvertToHtml(FileInfo sourceDocx, FileInfo destFileName)
- {
- byte[] byteArray = File.ReadAllBytes(sourceDocx.FullName);
- using (MemoryStream memoryStream = new MemoryStream())
- {
- memoryStream.Write(byteArray, 0, byteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(memoryStream, true))
- {
- var outputDirectory = destFileName.Directory;
- destFileName = new FileInfo(Path.Combine(outputDirectory.FullName, destFileName.Name));
- var imageDirectoryName = destFileName.FullName.Substring(0, destFileName.FullName.Length - 5) + "_files";
- int imageCounter = 0;
- var pageTitle = (string)wDoc.CoreFilePropertiesPart.GetXDocument().Descendants(DC.title).FirstOrDefault();
- if (pageTitle == null)
- pageTitle = sourceDocx.FullName;
-
- WmlToHtmlConverterSettings settings = new WmlToHtmlConverterSettings()
- {
- PageTitle = pageTitle,
- FabricateCssClasses = true,
- CssClassPrefix = "pt-",
- RestrictToSupportedLanguages = false,
- RestrictToSupportedNumberingFormats = false,
- ImageHandler = imageInfo =>
- {
- DirectoryInfo localDirInfo = new DirectoryInfo(imageDirectoryName);
- if (!localDirInfo.Exists)
- localDirInfo.Create();
- ++imageCounter;
- string extension = imageInfo.ContentType.Split('/')[1].ToLower();
- ImageFormat imageFormat = null;
- if (extension == "png")
- {
- // Convert png to jpeg.
- extension = "gif";
- imageFormat = ImageFormat.Gif;
- }
- else if (extension == "gif")
- imageFormat = ImageFormat.Gif;
- else if (extension == "bmp")
- imageFormat = ImageFormat.Bmp;
- else if (extension == "jpeg")
- imageFormat = ImageFormat.Jpeg;
- else if (extension == "tiff")
- {
- // Convert tiff to gif.
- extension = "gif";
- imageFormat = ImageFormat.Gif;
- }
- else if (extension == "x-wmf")
- {
- extension = "wmf";
- imageFormat = ImageFormat.Wmf;
- }
-
- // If the image format isn't one that we expect, ignore it,
- // and don't return markup for the link.
- if (imageFormat == null)
- return null;
-
- string imageFileName = imageDirectoryName + "/image" +
- imageCounter.ToString() + "." + extension;
- try
- {
- imageInfo.Bitmap.Save(imageFileName, imageFormat);
- }
- catch (System.Runtime.InteropServices.ExternalException)
- {
- return null;
- }
- XElement img = new XElement(Xhtml.img,
- new XAttribute(NoNamespace.src, imageFileName),
- imageInfo.ImgStyleAttribute,
- imageInfo.AltText != null ?
- new XAttribute(NoNamespace.alt, imageInfo.AltText) : null);
- return img;
- }
- };
- XElement html = WmlToHtmlConverter.ConvertToHtml(wDoc, settings);
-
- // Note: the xhtml returned by ConvertToHtmlTransform contains objects of type
- // XEntity. PtOpenXmlUtil.cs define the XEntity class. See
- // http://blogs.msdn.com/ericwhite/archive/2010/01/21/writing-entity-references-using-linq-to-xml.aspx
- // for detailed explanation.
- //
- // If you further transform the XML tree returned by ConvertToHtmlTransform, you
- // must do it correctly, or entities will not be serialized properly.
-
- var htmlString = html.ToString(SaveOptions.DisableFormatting);
- File.WriteAllText(destFileName.FullName, htmlString, Encoding.UTF8);
- }
- }
- }
-
- private static void ConvertToHtmlNoCssClasses(FileInfo sourceDocx, FileInfo destFileName)
- {
- byte[] byteArray = File.ReadAllBytes(sourceDocx.FullName);
- using (MemoryStream memoryStream = new MemoryStream())
- {
- memoryStream.Write(byteArray, 0, byteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(memoryStream, true))
- {
- var outputDirectory = destFileName.Directory;
- destFileName = new FileInfo(Path.Combine(outputDirectory.FullName, destFileName.Name));
- var imageDirectoryName = destFileName.FullName.Substring(0, destFileName.FullName.Length - 5) + "_files";
- int imageCounter = 0;
- var pageTitle = (string)wDoc.CoreFilePropertiesPart.GetXDocument().Descendants(DC.title).FirstOrDefault();
- if (pageTitle == null)
- pageTitle = sourceDocx.FullName;
-
- WmlToHtmlConverterSettings settings = new WmlToHtmlConverterSettings()
- {
- PageTitle = pageTitle,
- FabricateCssClasses = false,
- RestrictToSupportedLanguages = false,
- RestrictToSupportedNumberingFormats = false,
- ImageHandler = imageInfo =>
- {
- DirectoryInfo localDirInfo = new DirectoryInfo(imageDirectoryName);
- if (!localDirInfo.Exists)
- localDirInfo.Create();
- ++imageCounter;
- string extension = imageInfo.ContentType.Split('/')[1].ToLower();
- ImageFormat imageFormat = null;
- if (extension == "png")
- {
- // Convert png to jpeg.
- extension = "gif";
- imageFormat = ImageFormat.Gif;
- }
- else if (extension == "gif")
- imageFormat = ImageFormat.Gif;
- else if (extension == "bmp")
- imageFormat = ImageFormat.Bmp;
- else if (extension == "jpeg")
- imageFormat = ImageFormat.Jpeg;
- else if (extension == "tiff")
- {
- // Convert tiff to gif.
- extension = "gif";
- imageFormat = ImageFormat.Gif;
- }
- else if (extension == "x-wmf")
- {
- extension = "wmf";
- imageFormat = ImageFormat.Wmf;
- }
-
- // If the image format isn't one that we expect, ignore it,
- // and don't return markup for the link.
- if (imageFormat == null)
- return null;
-
- string imageFileName = imageDirectoryName + "/image" +
- imageCounter.ToString() + "." + extension;
- try
- {
- imageInfo.Bitmap.Save(imageFileName, imageFormat);
- }
- catch (System.Runtime.InteropServices.ExternalException)
- {
- return null;
- }
- XElement img = new XElement(Xhtml.img,
- new XAttribute(NoNamespace.src, imageFileName),
- imageInfo.ImgStyleAttribute,
- imageInfo.AltText != null ?
- new XAttribute(NoNamespace.alt, imageInfo.AltText) : null);
- return img;
- }
- };
- XElement html = WmlToHtmlConverter.ConvertToHtml(wDoc, settings);
-
- // Note: the xhtml returned by ConvertToHtmlTransform contains objects of type
- // XEntity. PtOpenXmlUtil.cs define the XEntity class. See
- // http://blogs.msdn.com/ericwhite/archive/2010/01/21/writing-entity-references-using-linq-to-xml.aspx
- // for detailed explanation.
- //
- // If you further transform the XML tree returned by ConvertToHtmlTransform, you
- // must do it correctly, or entities will not be serialized properly.
-
- var htmlString = html.ToString(SaveOptions.DisableFormatting);
- File.WriteAllText(destFileName.FullName, htmlString, Encoding.UTF8);
- }
- }
- }
-
-#if DO_CONVERSION_VIA_WORD
- public static void ConvertToHtmlUsingWord(FileInfo sourceFileName, FileInfo destFileName)
- {
- Word.Application app = new Word.Application();
- app.Visible = false;
- try
- {
- Word.Document doc = app.Documents.Open(sourceFileName.FullName);
- doc.SaveAs2(destFileName.FullName, Word.WdSaveFormat.wdFormatFilteredHTML);
- }
- catch (System.Runtime.InteropServices.COMException)
- {
- Console.WriteLine("Caught unexpected COM exception.");
- ((Microsoft.Office.Interop.Word._Application)app).Quit();
- Environment.Exit(0);
- }
- ((Microsoft.Office.Interop.Word._Application)app).Quit();
- }
-#endif
- }
-}
-
-#endif
diff --git a/OpenXmlPowerTools.Tests/HtmlToWmlConverterTests.cs b/OpenXmlPowerTools.Tests/HtmlToWmlConverterTests.cs
index 3bec4ffe..56630fba 100644
--- a/OpenXmlPowerTools.Tests/HtmlToWmlConverterTests.cs
+++ b/OpenXmlPowerTools.Tests/HtmlToWmlConverterTests.cs
@@ -1,21 +1,10 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using Codeuctivity.OpenXmlPowerTools;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Validation;
using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
using System.IO;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Validation;
-using OpenXmlPowerTools;
using Xunit;
-using System.Text.RegularExpressions;
/*******************************************************************************************
* HtmlToWmlConverter expects the HTML to be passed as an XElement, i.e. as XML. While the HTML test files that
@@ -23,30 +12,24 @@
* The best solution is to use the HtmlAgilityPack, which can parse HTML and save as XML. The HtmlAgilityPack
* is licensed under the Ms-PL (same as Open-Xml-PowerTools) so it is convenient to include it in your solution,
* and thereby you can convert HTML to XML that can be processed by the HtmlToWmlConverter.
- *
+ *
* A convenient way to get the DLL that has been checked out with HtmlToWmlConverter is to clone the repo at
* https://github.com/EricWhiteDev/HtmlAgilityPack
- *
+ *
* That repo contains only the DLL that has been checked out with HtmlToWmlConverter.
- *
+ *
* Of course, you can also get the HtmlAgilityPack source and compile it to get the DLL. You can find it at
* http://codeplex.com/HtmlAgilityPack
- *
+ *
* We don't include the HtmlAgilityPack in Open-Xml-PowerTools, to simplify installation. The XUnit tests in
* this module do not require the HtmlAgilityPack to run.
*******************************************************************************************/
-#if DO_CONVERSION_VIA_WORD
-using Word = Microsoft.Office.Interop.Word;
-#endif
-
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class HwTests
{
- static bool s_ProduceAnnotatedHtml = true;
+ private static readonly bool s_ProduceAnnotatedHtml = true;
// PowerShell oneliner that generates InlineData for all files in a directory
// dir | % { '[InlineData("' + $_.Name + '")]' } | clip
@@ -282,108 +265,26 @@ public class HwTests
[InlineData("T1830.html")]
[InlineData("T1840.html")]
[InlineData("T1850.html")]
-
public void HW001(string name)
{
-#if false
- string[] cssFilter = new[] {
- "text-indent",
- "margin-left",
- "margin-right",
- "padding-left",
- "padding-right",
- };
-#else
- string[] cssFilter = null;
-#endif
-
-#if false
- string[] htmlFilter = new[] {
- "img",
- };
-#else
- string[] htmlFilter = null;
-#endif
-
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
var sourceHtmlFi = new FileInfo(Path.Combine(sourceDir.FullName, name));
var sourceImageDi = new DirectoryInfo(Path.Combine(sourceDir.FullName, sourceHtmlFi.Name.Replace(".html", "_files")));
-
- var destImageDi = new DirectoryInfo(Path.Combine(TestUtil.TempDir.FullName, sourceImageDi.Name));
- var sourceCopiedToDestHtmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceHtmlFi.Name.Replace(".html", "-1-Source.html")));
var destCssFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceHtmlFi.Name.Replace(".html", "-2.css")));
var destDocxFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceHtmlFi.Name.Replace(".html", "-3-ConvertedByHtmlToWml.docx")));
var annotatedHtmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceHtmlFi.Name.Replace(".html", "-4-Annotated.txt")));
- if (!sourceCopiedToDestHtmlFi.Exists)
- File.Copy(sourceHtmlFi.FullName, sourceCopiedToDestHtmlFi.FullName);
- XElement html = HtmlToWmlReadAsXElement.ReadAsXElement(sourceCopiedToDestHtmlFi);
-
- string htmlString = html.ToString();
- if (htmlFilter != null && htmlFilter.Any())
- {
- bool found = false;
- foreach (var item in htmlFilter)
- {
- if (htmlString.Contains(item))
- {
- found = true;
- break;
- }
- }
- if (!found)
- {
- sourceCopiedToDestHtmlFi.Delete();
- return;
- }
- }
-
- string usedAuthorCss = HtmlToWmlConverter.CleanUpCss((string)html.Descendants().FirstOrDefault(d => d.Name.LocalName.ToLower() == "style"));
+ var html = HtmlToWmlReadAsXElement.ReadAsXElement(sourceHtmlFi);
+ var usedAuthorCss = HtmlToWmlConverter.CleanUpCss((string)html.Descendants().FirstOrDefault(d => d.Name.LocalName.ToLower() == "style"));
File.WriteAllText(destCssFi.FullName, usedAuthorCss);
- if (cssFilter != null && cssFilter.Any())
- {
- bool found = false;
- foreach (var item in cssFilter)
- {
- if (usedAuthorCss.Contains(item))
- {
- found = true;
- break;
- }
- }
- if (!found)
- {
- sourceCopiedToDestHtmlFi.Delete();
- destCssFi.Delete();
- return;
- }
- }
-
- if (sourceImageDi.Exists)
- {
- destImageDi.Create();
- foreach (var file in sourceImageDi.GetFiles())
- {
- File.Copy(file.FullName, destImageDi.FullName + "/" + file.Name);
- }
- }
-
- HtmlToWmlConverterSettings settings = HtmlToWmlConverter.GetDefaultSettings();
- // image references in HTML files contain the path to the subdir that contains the images, so base URI is the name of the directory
- // that contains the HTML files
- settings.BaseUriForImages = Path.Combine(TestUtil.TempDir.FullName);
+ var settings = HtmlToWmlConverter.GetDefaultSettings();
+ // image references in HTML files contain the path to the subdir that contains the images, so base URI is the name of the directory that contains the HTML files
+ settings.BaseUriForImages = sourceDir.FullName;
- WmlDocument doc = HtmlToWmlConverter.ConvertHtmlToWml(defaultCss, usedAuthorCss, userCss, html, settings, null, s_ProduceAnnotatedHtml ? annotatedHtmlFi.FullName : null);
+ var doc = HtmlToWmlConverter.ConvertHtmlToWml(defaultCss, usedAuthorCss, userCss, html, settings, null, s_ProduceAnnotatedHtml ? annotatedHtmlFi.FullName : null);
Assert.NotNull(doc);
- if (doc != null)
- SaveValidateAndFormatMainDocPart(destDocxFi, doc);
-
-#if DO_CONVERSION_VIA_WORD
- var newAltChunkBeforeFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".html", "-5-AltChunkBefore.docx")));
- var newAltChunkAfterFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, name.Replace(".html", "-6-ConvertedViaWord.docx")));
- WordAutomationUtilities.DoConversionViaWord(newAltChunkBeforeFi, newAltChunkAfterFi, html);
-#endif
+ SaveValidateAndFormatMainDocPart(destDocxFi, doc);
}
[Theory]
@@ -391,8 +292,7 @@ public void HW001(string name)
[InlineData("E0020.html")]
public void HW004(string name)
{
-
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
var sourceHtmlFi = new FileInfo(Path.Combine(sourceDir.FullName, name));
var sourceImageDi = new DirectoryInfo(Path.Combine(sourceDir.FullName, sourceHtmlFi.Name.Replace(".html", "_files")));
@@ -403,12 +303,12 @@ public void HW004(string name)
var annotatedHtmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceHtmlFi.Name.Replace(".html", "-4-Annotated.txt")));
File.Copy(sourceHtmlFi.FullName, sourceCopiedToDestHtmlFi.FullName);
- XElement html = HtmlToWmlReadAsXElement.ReadAsXElement(sourceCopiedToDestHtmlFi);
+ var html = HtmlToWmlReadAsXElement.ReadAsXElement(sourceCopiedToDestHtmlFi);
- string usedAuthorCss = HtmlToWmlConverter.CleanUpCss((string)html.Descendants().FirstOrDefault(d => d.Name.LocalName.ToLower() == "style"));
+ var usedAuthorCss = HtmlToWmlConverter.CleanUpCss((string)html.Descendants().FirstOrDefault(d => d.Name.LocalName.ToLower() == "style"));
File.WriteAllText(destCssFi.FullName, usedAuthorCss);
- HtmlToWmlConverterSettings settings = HtmlToWmlConverter.GetDefaultSettings();
+ var settings = HtmlToWmlConverter.GetDefaultSettings();
settings.BaseUriForImages = Path.Combine(TestUtil.TempDir.FullName);
Assert.Throws(() => HtmlToWmlConverter.ConvertHtmlToWml(defaultCss, usedAuthorCss, userCss, html, settings, null, s_ProduceAnnotatedHtml ? annotatedHtmlFi.FullName : null));
@@ -418,29 +318,31 @@ private static void SaveValidateAndFormatMainDocPart(FileInfo destDocxFi, WmlDoc
{
WmlDocument formattedDoc;
+ if (File.Exists(destDocxFi.FullName))
+ {
+ File.Delete(destDocxFi.FullName);
+ }
+
doc.SaveAs(destDocxFi.FullName);
- using (MemoryStream ms = new MemoryStream())
+ using (var ms = new MemoryStream())
{
ms.Write(doc.DocumentByteArray, 0, doc.DocumentByteArray.Length);
- using (WordprocessingDocument document = WordprocessingDocument.Open(ms, true))
+ using (var document = WordprocessingDocument.Open(ms, true))
{
- XDocument xDoc = document.MainDocumentPart.GetXDocument();
+ var xDoc = document.MainDocumentPart.GetXDocument();
document.MainDocumentPart.PutXDocumentWithFormatting();
- OpenXmlValidator validator = new OpenXmlValidator();
+ var validator = new OpenXmlValidator();
var errors = validator.Validate(document);
- var errorsString = errors
- .Select(e => e.Description + Environment.NewLine)
- .StringConcatenate();
+ var errorsString = errors.Select(e => e.Description + Environment.NewLine).StringConcatenate();
- // Assert that there were no errors in the generated document.
- Assert.Equal("", errorsString);
+ Assert.True(errorsString.Length == 0, $"Error in {destDocxFi.FullName}\n{errorsString}");
}
formattedDoc = new WmlDocument(destDocxFi.FullName, ms.ToArray());
}
formattedDoc.SaveAs(destDocxFi.FullName);
}
- static string defaultCss =
+ private const string defaultCss =
@"html, address,
blockquote,
body, dd, div,
@@ -514,8 +416,6 @@ private static void SaveValidateAndFormatMainDocPart(FileInfo destDocxFi, WmlDoc
";
- static string userCss = @"";
+ private const string userCss = @"";
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/HtmlToWmlReadAsXElement.cs b/OpenXmlPowerTools.Tests/HtmlToWmlReadAsXElement.cs
index 99998d4f..8defdb03 100644
--- a/OpenXmlPowerTools.Tests/HtmlToWmlReadAsXElement.cs
+++ b/OpenXmlPowerTools.Tests/HtmlToWmlReadAsXElement.cs
@@ -1,15 +1,7 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
+using System.IO;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
-using OpenXmlPowerTools;
/*******************************************************************************************
* HtmlToWmlConverter expects the HTML to be passed as an XElement, i.e. as XML. While the HTML test files that
@@ -17,30 +9,30 @@
* The best solution is to use the HtmlAgilityPack, which can parse HTML and save as XML. The HtmlAgilityPack
* is licensed under the Ms-PL (same as Open-Xml-PowerTools) so it is convenient to include it in your solution,
* and thereby you can convert HTML to XML that can be processed by the HtmlToWmlConverter.
- *
+ *
* A convenient way to get the DLL that has been checked out with HtmlToWmlConverter is to clone the repo at
* https://github.com/EricWhiteDev/HtmlAgilityPack
- *
+ *
* That repo contains only the DLL that has been checked out with HtmlToWmlConverter.
- *
+ *
* Of course, you can also get the HtmlAgilityPack source and compile it to get the DLL. You can find it at
* http://codeplex.com/HtmlAgilityPack
- *
+ *
* We don't include the HtmlAgilityPack in Open-Xml-PowerTools, to simplify installation. The XUnit tests in
* this module do not require the HtmlAgilityPack to run.
-*******************************************************************************************/
+*******************************************************************************************/
#if USE_HTMLAGILITYPACK
using HtmlAgilityPack;
#endif
-namespace OpenXmlPowerTools
+namespace Codeuctivity.Tests
{
public class HtmlToWmlReadAsXElement
{
public static XElement ReadAsXElement(FileInfo sourceHtmlFi)
{
- string htmlString = File.ReadAllText(sourceHtmlFi.FullName);
+ var htmlString = File.ReadAllText(sourceHtmlFi.FullName);
XElement html = null;
try
{
@@ -68,9 +60,9 @@ public static XElement ReadAsXElement(FileInfo sourceHtmlFi)
html = XElement.Parse(sb.ToString());
}
#else
- catch (XmlException e)
+ catch (XmlException)
{
- throw e;
+ throw;
}
#endif
html = (XElement)ConvertToNoNamespace(html);
@@ -79,8 +71,7 @@ public static XElement ReadAsXElement(FileInfo sourceHtmlFi)
private static object ConvertToNoNamespace(XNode node)
{
- XElement element = node as XElement;
- if (element != null)
+ if (node is XElement element)
{
return new XElement(element.Name.LocalName,
element.Attributes().Where(a => !a.IsNamespaceDeclaration),
@@ -89,4 +80,4 @@ private static object ConvertToNoNamespace(XNode node)
return node;
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/ImageHandlerTests.cs b/OpenXmlPowerTools.Tests/ImageHandlerTests.cs
new file mode 100644
index 00000000..4e8b3d8d
--- /dev/null
+++ b/OpenXmlPowerTools.Tests/ImageHandlerTests.cs
@@ -0,0 +1,93 @@
+using System.IO;
+using System.Xml.Linq;
+using Codeuctivity.OpenXmlPowerTools;
+using Codeuctivity.OpenXmlPowerTools.OpenXMLWordprocessingMLToHtmlConverter;
+using SkiaSharp;
+using Xunit;
+
+namespace Codeuctivity.Tests
+{
+ public class ImageHandlerTests
+ {
+ [Theory]
+ [InlineData(SKEncodedImageFormat.Png, "image/png")]
+ [InlineData(SKEncodedImageFormat.Jpeg, "image/jpeg")]
+ [InlineData(SKEncodedImageFormat.Webp, "image/webp")]
+ public void ShouldTransformImagesToDataUri(SKEncodedImageFormat format, string mime)
+ {
+ using var surface = SKSurface.Create(new SKImageInfo(10, 10));
+ surface.Canvas.Clear(SKColors.Red);
+ using var image = surface.Snapshot();
+ using var ms = new MemoryStream();
+ using (var data = image.Encode(format, 100))
+ {
+ data.SaveTo(ms);
+ }
+ ms.Position = 0;
+ var info = new ImageInfo { Image = ms, AltText = "alt", ImgStyleAttribute = new XAttribute(NoNamespace.style, "width:10px") };
+ var handler = new ImageHandler();
+ var result = handler.TransformImage(info);
+ var srcAttr = result.Attribute(NoNamespace.src);
+ Assert.NotNull(srcAttr);
+ Assert.StartsWith($"data:{mime};base64,", srcAttr.Value);
+ Assert.Equal("width:10px", result.Attribute(NoNamespace.style)?.Value);
+ }
+
+ [Fact]
+ public void ShouldTransformGifToDataUri()
+ {
+ var gif = System.Convert.FromBase64String("R0lGODlhAQABAPAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==");
+ using var ms = new MemoryStream(gif);
+ var info = new ImageInfo { Image = ms };
+ var handler = new ImageHandler();
+ var result = handler.TransformImage(info);
+ var srcAttr = result.Attribute(NoNamespace.src);
+ Assert.NotNull(srcAttr);
+ Assert.StartsWith("data:image/gif;base64,", srcAttr.Value);
+ }
+
+ [Fact]
+ public void ShouldThrowOnInvalidImage()
+ {
+ using var ms = new MemoryStream(new byte[] { 1, 2, 3, 4 });
+ var handler = new ImageHandler();
+ Assert.ThrowsAny(() => handler.TransformImage(new ImageInfo { Image = ms }));
+ }
+
+ [Fact]
+ public void ShouldIncludeAltText()
+ {
+ using var surface = SKSurface.Create(new SKImageInfo(5, 5));
+ surface.Canvas.Clear(SKColors.Blue);
+ using var image = surface.Snapshot();
+ using var ms = new MemoryStream();
+ using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
+ {
+ data.SaveTo(ms);
+ }
+ ms.Position = 0;
+ var info = new ImageInfo { Image = ms, AltText = "demo" };
+ var handler = new ImageHandler();
+ var result = handler.TransformImage(info);
+ Assert.Equal("demo", result.Attribute(NoNamespace.alt)?.Value);
+ }
+
+ [Fact]
+ public void ShouldOmitAltTextWhenNotProvided()
+ {
+ using var surface = SKSurface.Create(new SKImageInfo(5, 5));
+ surface.Canvas.Clear(SKColors.Blue);
+ using var image = surface.Snapshot();
+ using var ms = new MemoryStream();
+ using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
+ {
+ data.SaveTo(ms);
+ }
+ ms.Position = 0;
+ var info = new ImageInfo { Image = ms };
+ var handler = new ImageHandler();
+ var result = handler.TransformImage(info);
+ Assert.Null(result.Attribute(NoNamespace.alt));
+ }
+ }
+}
diff --git a/OpenXmlPowerTools.Tests/MarkupSimplifierTests.cs b/OpenXmlPowerTools.Tests/MarkupSimplifierTests.cs
index c5f6bc79..5bc7ab7b 100644
--- a/OpenXmlPowerTools.Tests/MarkupSimplifierTests.cs
+++ b/OpenXmlPowerTools.Tests/MarkupSimplifierTests.cs
@@ -1,22 +1,19 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using Codeuctivity.OpenXmlPowerTools;
+using DocumentFormat.OpenXml;
+using DocumentFormat.OpenXml.Packaging;
using System.IO;
using System.Linq;
using System.Xml.Linq;
-using DocumentFormat.OpenXml;
-using DocumentFormat.OpenXml.Packaging;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OpenXmlPowerTools.Tests
+namespace Codeuctivity.Tests
{
public class MarkupSimplifierTests
{
private const WordprocessingDocumentType DocumentType = WordprocessingDocumentType.Document;
private const string SmartTagDocumentTextValue = "The countries include Algeria, Botswana, and Sri Lanka.";
+
private const string SmartTagDocumentXmlString =
@"
@@ -86,56 +83,52 @@ public class MarkupSimplifierTests
[Fact]
public void CanRemoveSmartTags()
{
- XDocument partDocument = XDocument.Parse(SmartTagDocumentXmlString);
+ var partDocument = XDocument.Parse(SmartTagDocumentXmlString);
Assert.True(partDocument.Descendants(W.smartTag).Any());
- using (var stream = new MemoryStream())
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, DocumentType))
- {
- MainDocumentPart part = wordDocument.AddMainDocumentPart();
- part.PutXDocument(partDocument);
+ using var stream = new MemoryStream();
+ using var wordDocument = WordprocessingDocument.Create(stream, DocumentType);
+ var part = wordDocument.AddMainDocumentPart();
+ part.PutXDocument(partDocument);
- var settings = new SimplifyMarkupSettings { RemoveSmartTags = true };
- MarkupSimplifier.SimplifyMarkup(wordDocument, settings);
+ var settings = new SimplifyMarkupSettings { RemoveSmartTags = true };
+ MarkupSimplifier.SimplifyMarkup(wordDocument, settings);
- partDocument = part.GetXDocument();
- XElement t = partDocument.Descendants(W.t).First();
+ partDocument = part.GetXDocument();
+ var t = partDocument.Descendants(W.t).First();
- Assert.False(partDocument.Descendants(W.smartTag).Any());
- Assert.Equal(SmartTagDocumentTextValue, t.Value);
- }
+ Assert.False(partDocument.Descendants(W.smartTag).Any());
+ Assert.Equal(SmartTagDocumentTextValue, t.Value);
}
[Fact]
public void CanRemoveContentControls()
{
- XDocument partDocument = XDocument.Parse(SdtDocumentXmlString);
+ var partDocument = XDocument.Parse(SdtDocumentXmlString);
Assert.True(partDocument.Descendants(W.sdt).Any());
- using (var stream = new MemoryStream())
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, DocumentType))
- {
- MainDocumentPart part = wordDocument.AddMainDocumentPart();
- part.PutXDocument(partDocument);
+ using var stream = new MemoryStream();
+ using var wordDocument = WordprocessingDocument.Create(stream, DocumentType);
+ var part = wordDocument.AddMainDocumentPart();
+ part.PutXDocument(partDocument);
- var settings = new SimplifyMarkupSettings { RemoveContentControls = true };
- MarkupSimplifier.SimplifyMarkup(wordDocument, settings);
+ var settings = new SimplifyMarkupSettings { RemoveContentControls = true };
+ MarkupSimplifier.SimplifyMarkup(wordDocument, settings);
- partDocument = part.GetXDocument();
- XElement element = partDocument
- .Descendants(W.body)
- .Descendants()
- .First();
+ partDocument = part.GetXDocument();
+ var element = partDocument
+ .Descendants(W.body)
+ .Descendants()
+ .First();
- Assert.False(partDocument.Descendants(W.sdt).Any());
- Assert.Equal(W.p, element.Name);
- }
+ Assert.False(partDocument.Descendants(W.sdt).Any());
+ Assert.Equal(W.p, element.Name);
}
[Fact]
public void CanRemoveGoBackBookmarks()
{
- XDocument partDocument = XDocument.Parse(GoBackBookmarkDocumentXmlString);
+ var partDocument = XDocument.Parse(GoBackBookmarkDocumentXmlString);
Assert.Contains(partDocument
.Descendants(W.bookmarkStart)
, e => e.Attribute(W.name).Value == "_GoBack" && e.Attribute(W.id).Value == "0");
@@ -143,21 +136,17 @@ public void CanRemoveGoBackBookmarks()
.Descendants(W.bookmarkEnd)
, e => e.Attribute(W.id).Value == "0");
- using (var stream = new MemoryStream())
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, DocumentType))
- {
- MainDocumentPart part = wordDocument.AddMainDocumentPart();
- part.PutXDocument(partDocument);
+ using var stream = new MemoryStream();
+ using var wordDocument = WordprocessingDocument.Create(stream, DocumentType);
+ var part = wordDocument.AddMainDocumentPart();
+ part.PutXDocument(partDocument);
- var settings = new SimplifyMarkupSettings { RemoveGoBackBookmark = true };
- MarkupSimplifier.SimplifyMarkup(wordDocument, settings);
+ var settings = new SimplifyMarkupSettings { RemoveGoBackBookmark = true };
+ MarkupSimplifier.SimplifyMarkup(wordDocument, settings);
- partDocument = part.GetXDocument();
- Assert.False(partDocument.Descendants(W.bookmarkStart).Any());
- Assert.False(partDocument.Descendants(W.bookmarkEnd).Any());
- }
+ partDocument = part.GetXDocument();
+ Assert.False(partDocument.Descendants(W.bookmarkStart).Any());
+ Assert.False(partDocument.Descendants(W.bookmarkEnd).Any());
}
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/MetricsGetterTests.cs b/OpenXmlPowerTools.Tests/MetricsGetterTests.cs
index dffcd14f..e450bc23 100644
--- a/OpenXmlPowerTools.Tests/MetricsGetterTests.cs
+++ b/OpenXmlPowerTools.Tests/MetricsGetterTests.cs
@@ -1,19 +1,9 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
+using Codeuctivity.OpenXmlPowerTools;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using System.Xml.Linq;
-using OpenXmlPowerTools;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class MgTests
{
@@ -28,10 +18,10 @@ public class MgTests
[InlineData("DA006-SelectTestValue-NoData.docx")]
public void MG001(string name)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo fi = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var fi = new FileInfo(Path.Combine(sourceDir.FullName, name));
- MetricsGetterSettings settings = new MetricsGetterSettings()
+ var settings = new MetricsGetterSettings()
{
IncludeTextInContentControls = false,
IncludeXlsxTableCellData = false,
@@ -43,23 +33,21 @@ public void MG001(string name)
XElement metrics = null;
if (Util.IsWordprocessingML(extension))
{
- WmlDocument wmlDocument = new WmlDocument(fi.FullName);
+ var wmlDocument = new WmlDocument(fi.FullName);
metrics = MetricsGetter.GetDocxMetrics(wmlDocument, settings);
}
else if (Util.IsSpreadsheetML(extension))
{
- SmlDocument smlDocument = new SmlDocument(fi.FullName);
+ var smlDocument = new SmlDocument(fi.FullName);
metrics = MetricsGetter.GetXlsxMetrics(smlDocument, settings);
}
else if (Util.IsPresentationML(extension))
{
- PmlDocument pmlDocument = new PmlDocument(fi.FullName);
+ var pmlDocument = new PmlDocument(fi.FullName);
metrics = MetricsGetter.GetPptxMetrics(pmlDocument, settings);
}
Assert.NotNull(metrics);
}
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/OpenXMLWordprocessingMLToHtmlConverter/AllowedDiffInfo.cs b/OpenXmlPowerTools.Tests/OpenXMLWordprocessingMLToHtmlConverter/AllowedDiffInfo.cs
new file mode 100644
index 00000000..59411961
--- /dev/null
+++ b/OpenXmlPowerTools.Tests/OpenXMLWordprocessingMLToHtmlConverter/AllowedDiffInfo.cs
@@ -0,0 +1,16 @@
+namespace Codeuctivity.Tests.OpenXMLWordProcessingMLToHtmlConverter
+{
+ internal class AllowedDiffInfo
+ {
+ public bool DiffFileExists;
+ public string NewDiffImageFileName;
+ public string[] ExistingDiffImageFilename;
+
+ public AllowedDiffInfo(bool diffFileExists, string newDiffImageFileName, string[] matchingFiles)
+ {
+ DiffFileExists = diffFileExists;
+ NewDiffImageFileName = newDiffImageFileName;
+ ExistingDiffImageFilename = matchingFiles;
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/OpenXMLWordprocessingMLToHtmlConverter/WmlToHtmlConverterHandlerTests.cs b/OpenXmlPowerTools.Tests/OpenXMLWordprocessingMLToHtmlConverter/WmlToHtmlConverterHandlerTests.cs
new file mode 100644
index 00000000..fa78d8b5
--- /dev/null
+++ b/OpenXmlPowerTools.Tests/OpenXMLWordprocessingMLToHtmlConverter/WmlToHtmlConverterHandlerTests.cs
@@ -0,0 +1,129 @@
+using Codeuctivity.OpenXmlPowerTools;
+using Codeuctivity.OpenXmlPowerTools.OpenXMLWordprocessingMLToHtmlConverter;
+using Codeuctivity.SkiaSharpCompare;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using Xunit;
+
+namespace Codeuctivity.Tests.OpenXMLWordProcessingMLToHtmlConverter
+{
+ public class WmlToHtmlConverterHandlerTests
+ {
+ private const string minimalPng = "iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAMSURBVBhXY0ACDAwAAA4AAXqxuTAAAAAASUVORK5CYII=";
+ private const string minimalBmp = "Qk1CAAAAAAAAADoAAAAoAAAAAgAAAAIAAAABAAQAAAAAAAAAAAAiLgAAIi4AAAEAAAABAAAAAAAA/wAAAAAAAAAA";
+ private const string minimalJpg = "/9j/4AAQSkZJRgABAQEBLAEsAAD/4QBoRXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAAExAAIAAAARAAAATgAAAAAABJPfAAAD6AAEk98AAAPocGFpbnQubmV0IDQuMi4xNAAA/9sAQwACAQEBAQECAQEBAgICAgIEAwICAgIFBAQDBAYFBgYGBQYGBgcJCAYHCQcGBggLCAkKCgoKCgYICwwLCgwJCgoK/9sAQwECAgICAgIFAwMFCgcGBwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK/8AAEQgAAgACAwEhAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A/n/ooA//2Q==";
+
+ [Fact]
+ public void ShouldTranslateWithWordprocessingTextDummyHandler()
+ {
+ var expected = "someValue";
+ Dictionary fontFamily = default!;
+ var wordprocessingTextDummyHandler = new TextDummyHandler();
+
+ var actual = wordprocessingTextDummyHandler.TransformText(expected, fontFamily);
+
+ Assert.Equal(expected, actual);
+ }
+
+ [Theory]
+ [InlineData("png", minimalPng)]
+ [InlineData("bmp", minimalBmp)]
+ [InlineData("jpeg", minimalJpg)]
+ public void ShouldTranslateWithDefaultImageHandler(string imageType, string minimalImage)
+ {
+ var expectedStart = $"
";
+ var binaryBitmap = Convert.FromBase64String(minimalImage);
+
+ using var expectedImage = new MemoryStream(binaryBitmap);
+
+ var imageInfo = new ImageInfo
+ {
+ Image = expectedImage
+ };
+
+ var defaultImageHandler = new ImageHandler();
+
+ var actual = defaultImageHandler.TransformImage(imageInfo).ToString();
+
+ Assert.StartsWith(expectedStart, actual);
+ Assert.EndsWith(expectedEnd, actual);
+
+ var actualBase64Part = actual.Substring(expectedStart.Length, actual.Length - expectedEnd.Length - expectedStart.Length);
+ var binaryActualBitmap = Convert.FromBase64String(actualBase64Part);
+ using var actualImage = new MemoryStream(binaryActualBitmap);
+
+ expectedImage.Position = 0;
+ actualImage.Position = 0;
+
+ Assert.True(Compare.ImagesAreEqual(expectedImage, actualImage, transparencyOptions: TransparencyOptions.CompareAlphaChannel));
+ }
+
+ [Fact]
+ public void ShouldTranslateSymbolsToUnicodeWithDefaultSymbolHandler()
+ {
+ Dictionary fontFamily = default!;
+ var defaultSymbolHandler = new SymbolHandler();
+
+ var element = new XElement("symbol", new XAttribute(W._char, "A"));
+
+ var actual = defaultSymbolHandler.TransformSymbol(element, fontFamily);
+
+ Assert.Equal("
", actual.ToString());
+ }
+
+ [Fact]
+ public void ShouldTranslatePageBreaksWithBreakHandler()
+ {
+ var breakHandler = new BreakHandler();
+
+ var element = new XElement("br");
+
+ var actual = breakHandler.TransformBreak(element);
+
+ Assert.Equal(3, actual.Count());
+ Assert.Equal("
", actual.ElementAt(0).ToString());
+ Assert.Equal("", actual.ElementAt(1).ToString());
+ Assert.Null(actual.ElementAt(2));
+ }
+
+ [Fact]
+ public void ShouldTranslateFontInRunSymbolWithFontHandler()
+ {
+ var fontHandler = new FontHandler();
+
+ var element = new XElement("run", new XElement(W.sym, new XAttribute(W.font, "SomeSymbolFont")), new XAttribute(PtOpenXml.FontName, "SomeRunFont"));
+
+ var actual = fontHandler.TranslateRunStyleFont(element);
+
+ Assert.Equal("SomeSymbolFont", actual);
+ }
+
+ [Fact]
+ public void ShouldTranslateFontInRunWithFontHandler()
+ {
+ var fontHandler = new FontHandler();
+
+ var element = new XElement("run", new XAttribute(PtOpenXml.FontName, "SomeRunFont"));
+
+ var actual = fontHandler.TranslateRunStyleFont(element);
+
+ Assert.Equal("SomeRunFont", actual);
+ }
+
+ [Fact]
+ public void ShouldTranslateFontInParagraphWithFontHandler()
+ {
+ var fontHandler = new FontHandler();
+
+ var element = new XElement("run", new XAttribute(PtOpenXml.FontName, "SomeRunFont"));
+
+ var actual = fontHandler.TranslateParagraphStyleFont(element);
+
+ Assert.Equal("SomeRunFont", actual);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/OpenXMLWordprocessingMLToHtmlConverter/WmlToHtmlConverterTests.cs b/OpenXmlPowerTools.Tests/OpenXMLWordprocessingMLToHtmlConverter/WmlToHtmlConverterTests.cs
new file mode 100644
index 00000000..3329b53c
--- /dev/null
+++ b/OpenXmlPowerTools.Tests/OpenXMLWordprocessingMLToHtmlConverter/WmlToHtmlConverterTests.cs
@@ -0,0 +1,293 @@
+using Codeuctivity.HtmlRenderer;
+using Codeuctivity.OpenXmlPowerTools.OpenXMLWordprocessingMLToHtmlConverter;
+using Codeuctivity.SkiaSharpCompare;
+using DocumentFormat.OpenXml.Packaging;
+using PuppeteerSharp;
+using SkiaSharp;
+using System;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using Xunit;
+
+namespace Codeuctivity.Tests.OpenXMLWordProcessingMLToHtmlConverter
+{
+ public class WmlToHtmlConverterTests
+ {
+ // PowerShell one liner that generates InlineData for all files in a directory
+ // dir | % { '[InlineData("' + $_.Name + '")]' } | clip
+
+ [Theory]
+ [InlineData("HC001-5DayTourPlanTemplate.docx", 0, false)]
+ [InlineData("HC002-Hebrew-01.docx", 0, true)]
+ [InlineData("HC003-Hebrew-02.docx", 0, true)]
+ [InlineData("HC004-ResumeTemplate.docx", 0, false)]
+ [InlineData("HC005-TaskPlanTemplate.docx", 0, false)]
+ [InlineData("HC006-Test-01.docx", 0, true)]
+ [InlineData("HC007-Test-02.docx", 0, true)]
+ [InlineData("HC008-Test-03.docx", 0, false)]
+ [InlineData("HC009-Test-04.docx", 0, true)]
+ [InlineData("HC010-Test-05.docx", 0, true)]
+ [InlineData("HC011-Test-06.docx", 0, false)]
+ [InlineData("HC012-Test-07.docx", 0, true)]
+ [InlineData("HC013-Test-08.docx", 0, false)]
+ [InlineData("HC014-RTL-Table-01.docx", 0, true)]
+ [InlineData("HC015-Vertical-Spacing-atLeast.docx", 0, false)]
+ [InlineData("HC016-Horizontal-Spacing-firstLine.docx", 0, false)]
+ [InlineData("HC017-Vertical-Alignment-Cell-01.docx", 0, false)]
+ [InlineData("HC018-Vertical-Alignment-Para-01.docx", 0, false)]
+ [InlineData("HC019-Hidden-Run.docx", 0, false)]
+ [InlineData("HC020-Small-Caps.docx", 0, false)]
+ [InlineData("HC021-Symbols.docx", 0, false)]
+ [InlineData("HC022-Table-Of-Contents.docx", 0, false)]
+ [InlineData("HC023-Hyperlink.docx", 0, false)]
+ [InlineData("HC024-Tabs-01.docx", 0, false)]
+ [InlineData("HC025-Tabs-02.docx", 0, false)]
+ [InlineData("HC026-Tabs-03.docx", 0, false)]
+ [InlineData("HC027-Tabs-04.docx", 0, false)]
+ [InlineData("HC028-No-Break-Hyphen.docx", 0, false)]
+ [InlineData("HC029-Table-Merged-Cells.docx", 0, false)]
+ [InlineData("HC030-Content-Controls.docx", 0, false)]
+ [InlineData("HC031-Complicated-Document.docx", 0, true)]
+ [InlineData("HC032-Named-Color.docx", 0, false)]
+ [InlineData("HC033-Run-With-Border.docx", 0, false)]
+ [InlineData("HC034-Run-With-Position.docx", 0, false)]
+ [InlineData("HC035-Strike-Through.docx", 0, false)]
+ [InlineData("HC036-Super-Script.docx", 0, false)]
+ [InlineData("HC037-Sub-Script.docx", 0, false)]
+ [InlineData("HC038-Conflicting-Border-Weight.docx", 0, false)]
+ [InlineData("HC039-Bold.docx", 0, false)]
+ [InlineData("HC040-Hyperlink-Fieldcode-01.docx", 0, false)]
+ [InlineData("HC041-Hyperlink-Fieldcode-02.docx", 0, false)]
+ [InlineData("HC042-Image-Png.docx", 0, false)]
+ [InlineData("HC043-Chart.docx", 0, false)]
+ [InlineData("HC044-Embedded-Workbook.docx", 0, false)]
+ [InlineData("HC045-Italic.docx", 0, false)]
+ [InlineData("HC046-BoldAndItalic.docx", 0, false)]
+ [InlineData("HC047-No-Section.docx", 0, false)]
+ [InlineData("HC048-Excerpt.docx", 0, true)]
+ [InlineData("HC049-Borders.docx", 0, false)]
+ [InlineData("HC050-Shaded-Text-01.docx", 0, false)]
+ [InlineData("HC051-Shaded-Text-02.docx", 0, false)]
+ [InlineData("HC052-SmartArt.docx", 0, false)]
+ [InlineData("HC053-Headings.docx", 0, false)]
+ [InlineData("HC055-GoogleDocsExport.docx", 0, false)]
+ [InlineData("HC060-Image-with-Hyperlink.docx", 0, false)]
+ [InlineData("HC061-Hyperlink-in-Field.docx", 0, false)]
+ [InlineData("Tabs.docx", 0, false)]
+ public async Task HC001(string name, int expectedPixelNoise, bool imageSizeMayDiffer)
+ {
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var settings = new WmlToHtmlConverterSettings(sourceDocx.FullName);
+
+ var oxPtConvertedDestHtml = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-3-OxPt.html")));
+ await ConvertToHtml(sourceDocx, oxPtConvertedDestHtml, settings, expectedPixelNoise, imageSizeMayDiffer);
+ }
+
+ [Theory]
+ [InlineData("HC006-Test-01.docx", 0)]
+ public async Task HC002_NoCssClasses(string name, int expectedPixelNoise)
+ {
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var settings = new WmlToHtmlConverterSettings(sourceDocx.FullName, new ImageHandler(), new TextDummyHandler(), new SymbolHandler(), new BreakHandler(), new FontHandler(), false);
+
+ var oxPtConvertedDestHtml = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-5-OxPt-No-CSS-Classes.html")));
+ await ConvertToHtml(sourceDocx, oxPtConvertedDestHtml, settings, expectedPixelNoise, true);
+ }
+
+ [Theory]
+ [InlineData("HC023-Hyperlink.docx", "href=\"http://example.com/#anchor\"")]
+ [InlineData("HC003-Hebrew-02.docx", " allowedPixelErrorCount;
+
+ if (!pixelErrorCountAboveExpectedWithDiff)
+ {
+ return;
+ }
+ resultWithAllowedDiffPixelErrorCount = Math.Min(resultWithAllowedDiffPixelErrorCount, resultWithAllowedDiff.PixelErrorCount);
+ }
+
+ SaveToGithubActionsPickupTestresultsDirectory(actualFullPath, expectFullPath, allowedDiffInfo.NewDiffImageFileName);
+ Assert.Fail($"Expected PixelErrorCount beyond {allowedPixelErrorCount} but was {resultWithAllowedDiffPixelErrorCount}\nExpected {expectFullPath}\ndiffers to actual {actualFullPath}\n diff is {allowedDiffInfo.NewDiffImageFileName}\n");
+ }
+
+ var result = Compare.CalcDiff(actualFullPath, expectFullPath, resizeOption, transparencyOptions: TransparencyOptions.CompareAlphaChannel);
+
+ var pixelErrorCountAboveExpected = result.PixelErrorCount > allowedPixelErrorCount;
+ if (pixelErrorCountAboveExpected)
+ {
+ SaveToGithubActionsPickupTestresultsDirectory(actualFullPath, expectFullPath, allowedDiffInfo.NewDiffImageFileName);
+
+ Assert.Fail($"Expected PixelErrorCount less or equal {allowedPixelErrorCount} but was {result.PixelErrorCount}\nExpected {expectFullPath}\ndiffers to actual {actualFullPath}\n Diff is {allowedDiffInfo.NewDiffImageFileName} \nReplace {actualFullPath} with the new value or store the diff as {allowedDiffInfo.ExistingDiffImageFilename.First()}.");
+ }
+ }
+ catch (System.Exception ex) when (!(ex is Xunit.Sdk.FailException))
+ {
+ SaveToGithubActionsPickupTestresultsDirectory(actualFullPath, expectFullPath, allowedDiffInfo.NewDiffImageFileName);
+ }
+ }
+
+ private static AllowedDiffInfo CalcAllowedDiffInfo(string actualFullPath, string expectFullPath, int allowedPixelErrorCount, bool imageSizeMayDiffer)
+ {
+ var osSpecificDiffFileSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "linux" : "win";
+ var newDiffImageFileName = $"{Path.GetFileName(expectFullPath)}.diff.{osSpecificDiffFileSuffix}{DateTime.Now:yyyyMMddHHmmss}.png";
+
+ var directoryPath = Path.GetDirectoryName(expectFullPath);
+ var fileNamePattern = $"{Path.GetFileName(expectFullPath)}.diff.{osSpecificDiffFileSuffix}*.png";
+ var matchingFiles = Directory.GetFiles(directoryPath, fileNamePattern);
+
+ return new AllowedDiffInfo(matchingFiles.Length > 0, newDiffImageFileName, matchingFiles);
+ }
+
+ private static void SaveToGithubActionsPickupTestresultsDirectory(string actualFullPath, string expectFullPath, string newDiffImageFileName)
+ {
+ var fileName = Path.GetFileName(actualFullPath);
+ var expectFullDirectory = Path.GetDirectoryName(expectFullPath);
+ var expectFullDirectoryFullPath = Path.GetFullPath(expectFullDirectory);
+
+ var testResultDirectoryActual = Path.Combine(expectFullDirectoryFullPath, "../TestResult/Actual");
+ var testResultDirectoryExpected = Path.Combine(expectFullDirectoryFullPath, "../TestResult/Expected");
+ var testResultDirectoryDiff = Path.Combine(expectFullDirectoryFullPath, "../TestResult/Diff");
+ CreateDirectory(Path.Combine(expectFullDirectoryFullPath, "../TestResult"));
+ CreateDirectory(testResultDirectoryActual);
+ CreateDirectory(testResultDirectoryExpected);
+ CreateDirectory(testResultDirectoryDiff);
+
+ File.Copy(actualFullPath, Path.Combine(testResultDirectoryActual, fileName), true);
+ File.Copy(expectFullPath, Path.Combine(testResultDirectoryExpected, fileName), true);
+ var newDiffImageFullPath = Path.GetFullPath(newDiffImageFileName);
+ var destFileName = Path.Combine(testResultDirectoryDiff, Path.GetFileName(newDiffImageFullPath));
+ File.Copy(newDiffImageFullPath, destFileName, true);
+
+ static void CreateDirectory(string testResultDirectory)
+ {
+ if (!Directory.Exists(testResultDirectory))
+ {
+ Directory.CreateDirectory(testResultDirectory);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/OpenXmlPowerTools.Tests.csproj b/OpenXmlPowerTools.Tests/OpenXmlPowerTools.Tests.csproj
index 6bb94044..9b8f7ac4 100644
--- a/OpenXmlPowerTools.Tests/OpenXmlPowerTools.Tests.csproj
+++ b/OpenXmlPowerTools.Tests/OpenXmlPowerTools.Tests.csproj
@@ -1,30 +1,31 @@
- net452;net461;netcoreapp2.0
- true
- true
- true
+ 8.0
+ net8.0
+ true
-
-
-
-
-
-
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
-
-
-
-
-
-
-
-
-
diff --git a/OpenXmlPowerTools.Tests/OpenXmlRegexTests.cs b/OpenXmlPowerTools.Tests/OpenXmlRegexTests.cs
index 1921db11..334277b4 100644
--- a/OpenXmlPowerTools.Tests/OpenXmlRegexTests.cs
+++ b/OpenXmlPowerTools.Tests/OpenXmlRegexTests.cs
@@ -1,18 +1,13 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System.Collections.Generic;
+using Codeuctivity.OpenXmlPowerTools;
+using DocumentFormat.OpenXml;
+using DocumentFormat.OpenXml.Packaging;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
-using DocumentFormat.OpenXml;
-using DocumentFormat.OpenXml.Packaging;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OpenXmlPowerTools.Tests
+namespace Codeuctivity.Tests
{
public class OpenXmlRegexTests
{
@@ -220,167 +215,155 @@ private static string InnerDelText(XContainer e)
[Fact]
public void CanReplaceTextWithQuotationMarks()
{
- XDocument partDocument = XDocument.Parse(QuotationMarksDocumentXmlString);
- XElement p = partDocument.Descendants(W.p).First();
- string innerText = InnerText(p);
+ var partDocument = XDocument.Parse(QuotationMarksDocumentXmlString);
+ var p = partDocument.Descendants(W.p).First();
+ var innerText = InnerText(p);
Assert.Equal(
"Text can be enclosed in “normal double quotes” and in «double angle quotation marks».",
innerText);
- using (var stream = new MemoryStream())
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, DocumentType))
- {
- MainDocumentPart part = wordDocument.AddMainDocumentPart();
- part.PutXDocument(partDocument);
-
- IEnumerable content = partDocument.Descendants(W.p);
- var regex = new Regex(string.Format("{0}(?{1}){2}", LeftDoubleQuotationMarks, Words,
- RightDoubleQuotationMarks));
- int count = OpenXmlRegex.Replace(content, regex, "‘changed ${words}’", null);
-
- p = partDocument.Descendants(W.p).First();
- innerText = InnerText(p);
-
- Assert.Equal(2, count);
- Assert.Equal(
- "Text can be enclosed in ‘changed normal double quotes’ and in ‘changed double angle quotation marks’.",
- innerText);
- }
+ using var stream = new MemoryStream();
+ using var wordDocument = WordprocessingDocument.Create(stream, DocumentType);
+ var part = wordDocument.AddMainDocumentPart();
+ part.PutXDocument(partDocument);
+
+ var content = partDocument.Descendants(W.p);
+ var regex = new Regex(string.Format("{0}(?{1}){2}", LeftDoubleQuotationMarks, Words,
+ RightDoubleQuotationMarks));
+ var count = OpenXmlRegex.Replace(content, regex, "‘changed ${words}’", null);
+
+ p = partDocument.Descendants(W.p).First();
+ innerText = InnerText(p);
+
+ Assert.Equal(2, count);
+ Assert.Equal(
+ "Text can be enclosed in ‘changed normal double quotes’ and in ‘changed double angle quotation marks’.",
+ innerText);
}
[Fact]
public void CanReplaceTextWithQuotationMarksAndAddTrackedChangesWhenReplacing()
{
- XDocument partDocument = XDocument.Parse(QuotationMarksDocumentXmlString);
- XElement p = partDocument.Descendants(W.p).First();
- string innerText = InnerText(p);
+ var partDocument = XDocument.Parse(QuotationMarksDocumentXmlString);
+ var p = partDocument.Descendants(W.p).First();
+ var innerText = InnerText(p);
Assert.Equal(
"Text can be enclosed in “normal double quotes” and in «double angle quotation marks».",
innerText);
- using (var stream = new MemoryStream())
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, DocumentType))
- {
- MainDocumentPart part = wordDocument.AddMainDocumentPart();
- part.PutXDocument(partDocument);
+ using var stream = new MemoryStream();
+ using var wordDocument = WordprocessingDocument.Create(stream, DocumentType);
+ var part = wordDocument.AddMainDocumentPart();
+ part.PutXDocument(partDocument);
- IEnumerable content = partDocument.Descendants(W.p);
- var regex = new Regex(string.Format("{0}(?{1}){2}", LeftDoubleQuotationMarks, Words,
- RightDoubleQuotationMarks));
- int count = OpenXmlRegex.Replace(content, regex, "‘changed ${words}’", null, true, "John Doe");
+ var content = partDocument.Descendants(W.p);
+ var regex = new Regex(string.Format("{0}(?{1}){2}", LeftDoubleQuotationMarks, Words,
+ RightDoubleQuotationMarks));
+ var count = OpenXmlRegex.Replace(content, regex, "‘changed ${words}’", null, true, "John Doe");
- p = partDocument.Descendants(W.p).First();
- innerText = InnerText(p);
+ p = partDocument.Descendants(W.p).First();
+ innerText = InnerText(p);
- Assert.Equal(2, count);
- Assert.Equal(
- "Text can be enclosed in ‘changed normal double quotes’ and in ‘changed double angle quotation marks’.",
- innerText);
+ Assert.Equal(2, count);
+ Assert.Equal(
+ "Text can be enclosed in ‘changed normal double quotes’ and in ‘changed double angle quotation marks’.",
+ innerText);
- Assert.Contains(p.Elements(W.ins), e => InnerText(e) == "‘changed normal double quotes’");
- Assert.Contains(p.Elements(W.ins), e => InnerText(e) == "‘changed double angle quotation marks’");
+ Assert.Contains(p.Elements(W.ins), e => InnerText(e) == "‘changed normal double quotes’");
+ Assert.Contains(p.Elements(W.ins), e => InnerText(e) == "‘changed double angle quotation marks’");
- Assert.Contains(p.Elements(W.del), e => InnerDelText(e) == "“normal double quotes”");
- Assert.Contains(p.Elements(W.del), e => InnerDelText(e) == "«double angle quotation marks»");
- }
+ Assert.Contains(p.Elements(W.del), e => InnerDelText(e) == "“normal double quotes”");
+ Assert.Contains(p.Elements(W.del), e => InnerDelText(e) == "«double angle quotation marks»");
}
[Fact]
public void CanReplaceTextWithQuotationMarksAndTrackedChanges()
{
- XDocument partDocument = XDocument.Parse(QuotationMarksAndTrackedChangesDocumentXmlString);
- XElement p = partDocument.Descendants(W.p).First();
- string innerText = InnerText(p);
+ var partDocument = XDocument.Parse(QuotationMarksAndTrackedChangesDocumentXmlString);
+ var p = partDocument.Descendants(W.p).First();
+ var innerText = InnerText(p);
Assert.Equal(
"Text can be enclosed in “normal double quotes” and in «double angle quotation marks».",
innerText);
- using (var stream = new MemoryStream())
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, DocumentType))
- {
- MainDocumentPart part = wordDocument.AddMainDocumentPart();
- part.PutXDocument(partDocument);
+ using var stream = new MemoryStream();
+ using var wordDocument = WordprocessingDocument.Create(stream, DocumentType);
+ var part = wordDocument.AddMainDocumentPart();
+ part.PutXDocument(partDocument);
- IEnumerable content = partDocument.Descendants(W.p);
- var regex = new Regex(string.Format("{0}(?{1}){2}", LeftDoubleQuotationMarks, Words,
- RightDoubleQuotationMarks));
- int count = OpenXmlRegex.Replace(content, regex, "‘changed ${words}’", null, true, "John Doe");
+ var content = partDocument.Descendants(W.p);
+ var regex = new Regex(string.Format("{0}(?{1}){2}", LeftDoubleQuotationMarks, Words,
+ RightDoubleQuotationMarks));
+ var count = OpenXmlRegex.Replace(content, regex, "‘changed ${words}’", null, true, "John Doe");
- p = partDocument.Descendants(W.p).First();
- innerText = InnerText(p);
+ p = partDocument.Descendants(W.p).First();
+ innerText = InnerText(p);
- Assert.Equal(2, count);
- Assert.Equal(
- "Text can be enclosed in ‘changed normal double quotes’ and in ‘changed double angle quotation marks’.",
- innerText);
+ Assert.Equal(2, count);
+ Assert.Equal(
+ "Text can be enclosed in ‘changed normal double quotes’ and in ‘changed double angle quotation marks’.",
+ innerText);
- Assert.Contains(p.Elements(W.ins), e => InnerText(e) == "‘changed normal double quotes’");
- Assert.Contains(p.Elements(W.ins), e => InnerText(e) == "‘changed double angle quotation marks’");
- }
+ Assert.Contains(p.Elements(W.ins), e => InnerText(e) == "‘changed normal double quotes’");
+ Assert.Contains(p.Elements(W.ins), e => InnerText(e) == "‘changed double angle quotation marks’");
}
[Fact]
public void CanReplaceTextWithSymbolsAndTrackedChanges()
{
- XDocument partDocument = XDocument.Parse(SymbolsAndTrackedChangesDocumentXmlString);
- XElement p = partDocument.Descendants(W.p).First();
- string innerText = InnerText(p);
+ var partDocument = XDocument.Parse(SymbolsAndTrackedChangesDocumentXmlString);
+ var p = partDocument.Descendants(W.p).First();
+ var innerText = InnerText(p);
Assert.Equal("We can also use symbols such as \uF021 or \uF028.", innerText);
- using (var stream = new MemoryStream())
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, DocumentType))
- {
- MainDocumentPart part = wordDocument.AddMainDocumentPart();
- part.PutXDocument(partDocument);
+ using var stream = new MemoryStream();
+ using var wordDocument = WordprocessingDocument.Create(stream, DocumentType);
+ var part = wordDocument.AddMainDocumentPart();
+ part.PutXDocument(partDocument);
- IEnumerable content = partDocument.Descendants(W.p);
- var regex = new Regex(@"[\uF021]");
- int count = OpenXmlRegex.Replace(content, regex, "\uF028", null, true, "John Doe");
+ var content = partDocument.Descendants(W.p);
+ var regex = new Regex(@"[\uF021]");
+ var count = OpenXmlRegex.Replace(content, regex, "\uF028", null, true, "John Doe");
- p = partDocument.Descendants(W.p).First();
- innerText = InnerText(p);
+ p = partDocument.Descendants(W.p).First();
+ innerText = InnerText(p);
- Assert.Equal(1, count);
- Assert.Equal("We can also use symbols such as \uF028 or \uF028.", innerText);
+ Assert.Equal(1, count);
+ Assert.Equal("We can also use symbols such as \uF028 or \uF028.", innerText);
- Assert.Contains(p.Descendants(W.ins), ins => ins.Descendants(W.sym).Any(
- sym => sym.Attribute(W.font).Value == "Wingdings" &&
- sym.Attribute(W._char).Value == "F028"));
- }
+ Assert.Contains(p.Descendants(W.ins), ins => ins.Descendants(W.sym).Any(
+ sym => sym.Attribute(W.font).Value == "Wingdings" &&
+ sym.Attribute(W._char).Value == "F028"));
}
[Fact]
public void CanReplaceTextWithFields()
{
- XDocument partDocument = XDocument.Parse(FieldsDocumentXmlString);
- XElement p = partDocument.Descendants(W.p).Last();
- string innerText = InnerText(p);
+ var partDocument = XDocument.Parse(FieldsDocumentXmlString);
+ var p = partDocument.Descendants(W.p).Last();
+ var innerText = InnerText(p);
Assert.Equal("As stated in Article {__1} and this Section {__1.1}, this is described in Schedule C (Performance Framework).",
innerText);
- using (var stream = new MemoryStream())
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, DocumentType))
- {
- MainDocumentPart part = wordDocument.AddMainDocumentPart();
- part.PutXDocument(partDocument);
+ using var stream = new MemoryStream();
+ using var wordDocument = WordprocessingDocument.Create(stream, DocumentType);
+ var part = wordDocument.AddMainDocumentPart();
+ part.PutXDocument(partDocument);
- IEnumerable content = partDocument.Descendants(W.p);
- var regex = new Regex(@"Schedule C \(Performance Framework\)");
- int count = OpenXmlRegex.Replace(content, regex, "Exhibit 4", null, true, "John Doe");
+ var content = partDocument.Descendants(W.p);
+ var regex = new Regex(@"Schedule C \(Performance Framework\)");
+ var count = OpenXmlRegex.Replace(content, regex, "Exhibit 4", null, true, "John Doe");
- p = partDocument.Descendants(W.p).Last();
- innerText = InnerText(p);
+ p = partDocument.Descendants(W.p).Last();
+ innerText = InnerText(p);
- Assert.Equal(1, count);
- Assert.Equal("As stated in Article {__1} and this Section {__1.1}, this is described in Exhibit 4.", innerText);
- }
+ Assert.Equal(1, count);
+ Assert.Equal("As stated in Article {__1} and this Section {__1.1}, this is described in Exhibit 4.", innerText);
}
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/PowerToolsBlockExtensionsTests.cs b/OpenXmlPowerTools.Tests/PowerToolsBlockExtensionsTests.cs
index fccb6d73..b107aafe 100644
--- a/OpenXmlPowerTools.Tests/PowerToolsBlockExtensionsTests.cs
+++ b/OpenXmlPowerTools.Tests/PowerToolsBlockExtensionsTests.cs
@@ -1,136 +1,121 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System.Collections.Generic;
+using Codeuctivity.OpenXmlPowerTools;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Wordprocessing;
using System.IO;
using System.Linq;
using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Wordprocessing;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OpenXmlPowerTools.Tests
+namespace Codeuctivity.Tests
{
public class PowerToolsBlockExtensionsTests : TestsBase
{
[Fact]
public void MustBeginPowerToolsBlockToUsePowerTools()
{
- using (var stream = new MemoryStream())
- {
- CreateEmptyWordprocessingDocument(stream);
-
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(stream, true))
- {
- MainDocumentPart part = wordDocument.MainDocumentPart;
-
- // Add a first paragraph through the SDK.
- Body body = part.Document.Body;
- body.AppendChild(new Paragraph(new Run(new Text("First"))));
-
- // This demonstrates the usage of the BeginPowerToolsBlock method to
- // demarcate blocks or regions of code where the PowerTools are used
- // in between usages of the strongly typed classes.
- wordDocument.BeginPowerToolsBlock();
-
- // Get content through the PowerTools. We will see the one paragraph added
- // by using the strongly typed SDK classes.
- XDocument content = part.GetXDocument();
- List paragraphElements = content.Descendants(W.p).ToList();
- Assert.Single(paragraphElements);
- Assert.Equal("First", paragraphElements[0].Value);
-
- // This demonstrates the usage of the EndPowerToolsBlock method to
- // demarcate blocks or regions of code where the PowerTools are used
- // in between usages of the strongly typed classes.
- wordDocument.EndPowerToolsBlock();
-
- // Add a second paragraph through the SDK in the exact same way as above.
- body = part.Document.Body;
- body.AppendChild(new Paragraph(new Run(new Text("Second"))));
- part.Document.Save();
-
- // Get content through the PowerTools in the exact same way as above,
- // noting that we have not used the BeginPowerToolsBlock method to
- // mark the beginning of the next PowerTools Block.
- // What we will see in this case is that we still only get the first
- // paragraph. This is caused by the GetXDocument method using the cached
- // XDocument, i.e., the annotation, rather reading the part's stream again.
- content = part.GetXDocument();
- paragraphElements = content.Descendants(W.p).ToList();
- Assert.Single(paragraphElements);
- Assert.Equal("First", paragraphElements[0].Value);
-
- // To make the GetXDocument read the parts' streams, we need to begin
- // the next PowerTools Block. This will remove the annotations from the
- // parts and make the PowerTools read the part's stream instead of
- // using the outdated annotation.
- wordDocument.BeginPowerToolsBlock();
-
- // Get content through the PowerTools in the exact same way as above.
- // We should now see both paragraphs.
- content = part.GetXDocument();
- paragraphElements = content.Descendants(W.p).ToList();
- Assert.Equal(2, paragraphElements.Count);
- Assert.Equal("First", paragraphElements[0].Value);
- Assert.Equal("Second", paragraphElements[1].Value);
- }
- }
+ using var stream = new MemoryStream();
+ CreateEmptyWordprocessingDocument(stream);
+
+ using var wordDocument = WordprocessingDocument.Open(stream, true);
+ var part = wordDocument.MainDocumentPart;
+
+ // Add a first paragraph through the SDK.
+ var body = part.Document.Body;
+ body.AppendChild(new Paragraph(new Run(new Text("First"))));
+
+ // This demonstrates the usage of the BeginPowerToolsBlock method to
+ // demarcate blocks or regions of code where the PowerTools are used
+ // in between usages of the strongly typed classes.
+ wordDocument.BeginPowerToolsBlock();
+
+ // Get content through the PowerTools. We will see the one paragraph added
+ // by using the strongly typed SDK classes.
+ var content = part.GetXDocument();
+ var paragraphElements = content.Descendants(W.p).ToList();
+ Assert.Single(paragraphElements);
+ Assert.Equal("First", paragraphElements[0].Value);
+
+ // This demonstrates the usage of the EndPowerToolsBlock method to
+ // demarcate blocks or regions of code where the PowerTools are used
+ // in between usages of the strongly typed classes.
+ wordDocument.EndPowerToolsBlock();
+
+ // Add a second paragraph through the SDK in the exact same way as above.
+ body = part.Document.Body;
+ body.AppendChild(new Paragraph(new Run(new Text("Second"))));
+ part.Document.Save();
+
+ // Get content through the PowerTools in the exact same way as above,
+ // noting that we have not used the BeginPowerToolsBlock method to
+ // mark the beginning of the next PowerTools Block.
+ // What we will see in this case is that we still only get the first
+ // paragraph. This is caused by the GetXDocument method using the cached
+ // XDocument, i.e., the annotation, rather reading the part's stream again.
+ content = part.GetXDocument();
+ paragraphElements = content.Descendants(W.p).ToList();
+ Assert.Single(paragraphElements);
+ Assert.Equal("First", paragraphElements[0].Value);
+
+ // To make the GetXDocument read the parts' streams, we need to begin
+ // the next PowerTools Block. This will remove the annotations from the
+ // parts and make the PowerTools read the part's stream instead of
+ // using the outdated annotation.
+ wordDocument.BeginPowerToolsBlock();
+
+ // Get content through the PowerTools in the exact same way as above.
+ // We should now see both paragraphs.
+ content = part.GetXDocument();
+ paragraphElements = content.Descendants(W.p).ToList();
+ Assert.Equal(2, paragraphElements.Count);
+ Assert.Equal("First", paragraphElements[0].Value);
+ Assert.Equal("Second", paragraphElements[1].Value);
}
[Fact]
public void MustEndPowerToolsBlockToUseStronglyTypedClasses()
{
- using (var stream = new MemoryStream())
- {
- CreateEmptyWordprocessingDocument(stream);
-
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(stream, true))
- {
- MainDocumentPart part = wordDocument.MainDocumentPart;
-
- // Add a paragraph through the SDK.
- Body body = part.Document.Body;
- body.AppendChild(new Paragraph(new Run(new Text("Added through SDK"))));
-
- // Begin the PowerTools Block, which saves any changes made through the strongly
- // typed SDK classes to the parts of the WordprocessingDocument.
- // In this case, this could also be done by invoking the Save method on the
- // WordprocessingDocument, which will save all parts that had changes, or by
- // invoking part.RootElement.Save() for the one part that was changed.
- wordDocument.BeginPowerToolsBlock();
-
- // Add a paragraph through the PowerTools.
- XDocument content = part.GetXDocument();
- XElement bodyElement = content.Descendants(W.body).First();
- bodyElement.Add(new XElement(W.p, new XElement(W.r, new XElement(W.t, "Added through PowerTools"))));
- part.PutXDocument();
-
- // Get the part's content through the SDK. However, we will only see what we
- // added through the SDK, not what we added through the PowerTools functionality.
- body = part.Document.Body;
- List paragraphs = body.Elements().ToList();
- Assert.Single(paragraphs);
- Assert.Equal("Added through SDK", paragraphs[0].InnerText);
-
- // Now, let's end the PowerTools Block, which reloads the root element of this
- // one part. Reloading those root elements this way is fine if you know exactly
- // which parts had their content changed by the Open XML PowerTools.
- wordDocument.EndPowerToolsBlock();
-
- // Get the part's content through the SDK. Having reloaded the root element,
- // we should now see both paragraphs.
- body = part.Document.Body;
- paragraphs = body.Elements().ToList();
- Assert.Equal(2, paragraphs.Count);
- Assert.Equal("Added through SDK", paragraphs[0].InnerText);
- Assert.Equal("Added through PowerTools", paragraphs[1].InnerText);
- }
- }
+ using var stream = new MemoryStream();
+ CreateEmptyWordprocessingDocument(stream);
+
+ using var wordDocument = WordprocessingDocument.Open(stream, true);
+ var part = wordDocument.MainDocumentPart;
+
+ // Add a paragraph through the SDK.
+ var body = part.Document.Body;
+ body.AppendChild(new Paragraph(new Run(new Text("Added through SDK"))));
+
+ // Begin the PowerTools Block, which saves any changes made through the strongly
+ // typed SDK classes to the parts of the WordprocessingDocument.
+ // In this case, this could also be done by invoking the Save method on the
+ // WordprocessingDocument, which will save all parts that had changes, or by
+ // invoking part.RootElement.Save() for the one part that was changed.
+ wordDocument.BeginPowerToolsBlock();
+
+ // Add a paragraph through the PowerTools.
+ var content = part.GetXDocument();
+ var bodyElement = content.Descendants(W.body).First();
+ bodyElement.Add(new XElement(W.p, new XElement(W.r, new XElement(W.t, "Added through PowerTools"))));
+ part.PutXDocument();
+
+ // Get the part's content through the SDK. However, we will only see what we
+ // added through the SDK, not what we added through the PowerTools functionality.
+ body = part.Document.Body;
+ var paragraphs = body.Elements().ToList();
+ Assert.Single(paragraphs);
+ Assert.Equal("Added through SDK", paragraphs[0].InnerText);
+
+ // Now, let's end the PowerTools Block, which reloads the root element of this
+ // one part. Reloading those root elements this way is fine if you know exactly
+ // which parts had their content changed by the Open XML PowerTools.
+ wordDocument.EndPowerToolsBlock();
+
+ // Get the part's content through the SDK. Having reloaded the root element,
+ // we should now see both paragraphs.
+ body = part.Document.Body;
+ paragraphs = body.Elements().ToList();
+ Assert.Equal(2, paragraphs.Count);
+ Assert.Equal("Added through SDK", paragraphs[0].InnerText);
+ Assert.Equal("Added through PowerTools", paragraphs[1].InnerText);
}
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/PowerToolsBlockTests.cs b/OpenXmlPowerTools.Tests/PowerToolsBlockTests.cs
index 12b4a89d..955bf41a 100644
--- a/OpenXmlPowerTools.Tests/PowerToolsBlockTests.cs
+++ b/OpenXmlPowerTools.Tests/PowerToolsBlockTests.cs
@@ -1,61 +1,52 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using Codeuctivity.OpenXmlPowerTools;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Wordprocessing;
using System;
-using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Wordprocessing;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OpenXmlPowerTools.Tests
+namespace Codeuctivity.Tests
{
public class PowerToolsBlockTests : TestsBase
{
[Fact]
public void CanUsePowerToolsBlockToDemarcateApis()
{
- using (var stream = new MemoryStream())
- {
- CreateEmptyWordprocessingDocument(stream);
-
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(stream, true))
- {
- MainDocumentPart part = wordDocument.MainDocumentPart;
-
- // Add a paragraph through the SDK.
- Body body = part.Document.Body;
- body.AppendChild(new Paragraph(new Run(new Text("Added through SDK"))));
+ using var stream = new MemoryStream();
+ CreateEmptyWordprocessingDocument(stream);
- // This demonstrates the use of the PowerToolsBlock in a using statement to
- // demarcate the intermittent use of the PowerTools.
- using (new PowerToolsBlock(wordDocument))
- {
- // Assert that we can see the paragraph added through the strongly typed classes.
- XDocument content = part.GetXDocument();
- List paragraphElements = content.Descendants(W.p).ToList();
- Assert.Single(paragraphElements);
- Assert.Equal("Added through SDK", paragraphElements[0].Value);
+ using var wordDocument = WordprocessingDocument.Open(stream, true);
+ var part = wordDocument.MainDocumentPart;
- // Add a paragraph through the PowerTools.
- XElement bodyElement = content.Descendants(W.body).First();
- bodyElement.Add(new XElement(W.p, new XElement(W.r, new XElement(W.t, "Added through PowerTools"))));
- part.PutXDocument();
- }
+ // Add a paragraph through the SDK.
+ var body = part.Document.Body;
+ body.AppendChild(new Paragraph(new Run(new Text("Added through SDK"))));
- // Get the part's content through the SDK. Having used the PowerToolsBlock,
- // we should see both paragraphs.
- body = part.Document.Body;
- List paragraphs = body.Elements().ToList();
- Assert.Equal(2, paragraphs.Count);
- Assert.Equal("Added through SDK", paragraphs[0].InnerText);
- Assert.Equal("Added through PowerTools", paragraphs[1].InnerText);
- }
+ // This demonstrates the use of the PowerToolsBlock in a using statement to
+ // demarcate the intermittent use of the PowerTools.
+ using (new PowerToolsBlock(wordDocument))
+ {
+ // Assert that we can see the paragraph added through the strongly typed classes.
+ var content = part.GetXDocument();
+ var paragraphElements = content.Descendants(W.p).ToList();
+ Assert.Single(paragraphElements);
+ Assert.Equal("Added through SDK", paragraphElements[0].Value);
+
+ // Add a paragraph through the PowerTools.
+ var bodyElement = content.Descendants(W.body).First();
+ bodyElement.Add(new XElement(W.p, new XElement(W.r, new XElement(W.t, "Added through PowerTools"))));
+ part.PutXDocument();
}
+
+ // Get the part's content through the SDK. Having used the PowerToolsBlock,
+ // we should see both paragraphs.
+ body = part.Document.Body;
+ var paragraphs = body.Elements().ToList();
+ Assert.Equal(2, paragraphs.Count);
+ Assert.Equal("Added through SDK", paragraphs[0].InnerText);
+ Assert.Equal("Added through PowerTools", paragraphs[1].InnerText);
}
[Fact]
@@ -64,6 +55,4 @@ public void ConstructorThrowsWhenPassingNull()
Assert.Throws(() => new PowerToolsBlock(null));
}
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/PresentationBuilderTests.cs b/OpenXmlPowerTools.Tests/PresentationBuilderTests.cs
deleted file mode 100644
index 95a0dc6b..00000000
--- a/OpenXmlPowerTools.Tests/PresentationBuilderTests.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Validation;
-using OpenXmlPowerTools;
-using Xunit;
-
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
-{
- public class PbTests
- {
- [Fact]
- public void PB001_Formatting()
- {
- string name1 = "PB001-Input1.pptx";
- string name2 = "PB001-Input2.pptx";
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Pptx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Pptx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- List sources = null;
- sources = new List()
- {
- new SlideSource(new PmlDocument(source1Pptx.FullName), 1, true),
- new SlideSource(new PmlDocument(source2Pptx.FullName), 0, true),
- };
- var processedDestPptx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "PB001-Formatting.pptx"));
- PresentationBuilder.BuildPresentation(sources, processedDestPptx.FullName);
- }
-
- [Fact]
- public void PB002_Formatting()
- {
- string name2 = "PB001-Input2.pptx";
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source2Pptx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- List sources = null;
- sources = new List()
- {
- new SlideSource(new PmlDocument(source2Pptx.FullName), 0, true),
- };
- var processedDestPptx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "PB002-Formatting.pptx"));
- PresentationBuilder.BuildPresentation(sources, processedDestPptx.FullName);
- }
-
- [Fact]
- public void PB003_Formatting()
- {
- string name1 = "PB001-Input1.pptx";
- string name2 = "PB001-Input3.pptx";
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Pptx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Pptx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- List sources = null;
- sources = new List()
- {
- new SlideSource(new PmlDocument(source1Pptx.FullName), 1, true),
- new SlideSource(new PmlDocument(source2Pptx.FullName), 0, true),
- };
- var processedDestPptx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "PB003-Formatting.pptx"));
- PresentationBuilder.BuildPresentation(sources, processedDestPptx.FullName);
- }
-
- [Fact]
- public void PB004_Formatting()
- {
- string name1 = "PB001-Input1.pptx";
- string name2 = "PB001-Input3.pptx";
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Pptx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Pptx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- List sources = null;
- sources = new List()
- {
- new SlideSource(new PmlDocument(source2Pptx.FullName), 0, true),
- new SlideSource(new PmlDocument(source1Pptx.FullName), 1, true),
- };
- var processedDestPptx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "PB004-Formatting.pptx"));
- PresentationBuilder.BuildPresentation(sources, processedDestPptx.FullName);
- }
-
- [Fact]
- public void PB005_Formatting()
- {
- string name1 = "PB001-Input1.pptx";
- string name2 = "PB001-Input3.pptx";
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Pptx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Pptx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- List sources = null;
- sources = new List()
- {
- new SlideSource(new PmlDocument(source2Pptx.FullName), 0, 0, true),
- new SlideSource(new PmlDocument(source1Pptx.FullName), 1, true),
- new SlideSource(new PmlDocument(source2Pptx.FullName), 0, true),
- };
- var processedDestPptx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "PB005-Formatting.pptx"));
- PresentationBuilder.BuildPresentation(sources, processedDestPptx.FullName);
- }
-
-#if NETCOREAPP2_0
- [Fact(Skip="Bug in netcore 2.0 : https://github.com/OfficeDev/Open-Xml-PowerTools/pull/238#issuecomment-412375570")]
-#else
- [Fact]
-#endif
- public void PB006_VideoFormats()
- {
- // This presentation contains videos with content types video/mp4, video/quicktime, video/unknown, video/x-ms-asf, and video/x-msvideo.
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourcePptx = new FileInfo(Path.Combine(sourceDir.FullName, "PP006-Videos.pptx"));
-
- var oldMediaDataContentTypes = GetMediaDataContentTypes(sourcePptx);
-
- List sources = null;
- sources = new List()
- {
- new SlideSource(new PmlDocument(sourcePptx.FullName), true),
- };
- var processedDestPptx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "PB006-Videos.pptx"));
- PresentationBuilder.BuildPresentation(sources, processedDestPptx.FullName);
-
- var newMediaDataContentTypes = GetMediaDataContentTypes(processedDestPptx);
-
- Assert.Equal(oldMediaDataContentTypes, newMediaDataContentTypes);
- }
-
- private static string[] GetMediaDataContentTypes(FileInfo fi)
- {
- using (PresentationDocument ptDoc = PresentationDocument.Open(fi.FullName, false))
- {
- return ptDoc.PresentationPart.SlideParts.SelectMany(
- p => p.DataPartReferenceRelationships.Select(d => d.DataPart.ContentType))
- .Distinct()
- .OrderBy(m => m)
- .ToArray();
- }
- }
- }
-}
-
-#endif
diff --git a/OpenXmlPowerTools.Tests/PtUtilTests.cs b/OpenXmlPowerTools.Tests/PtUtilTests.cs
index 4515e5d9..7b209f93 100644
--- a/OpenXmlPowerTools.Tests/PtUtilTests.cs
+++ b/OpenXmlPowerTools.Tests/PtUtilTests.cs
@@ -1,22 +1,8 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
+using Codeuctivity.OpenXmlPowerTools;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class PtUtilTests
{
@@ -24,8 +10,8 @@ public class PtUtilTests
[InlineData("PU/PU001-Test001.mht")]
public void PU001(string name)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceMht = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceMht = new FileInfo(Path.Combine(sourceDir.FullName, name));
var src = File.ReadAllText(sourceMht.FullName);
var p = MhtParser.Parse(src);
Assert.True(p.ContentType != null);
@@ -33,8 +19,5 @@ public void PU001(string name)
Assert.True(p.Parts.Length != 0);
Assert.DoesNotContain(p.Parts, part => part.ContentType == null || part.ContentLocation == null);
}
-
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/RevisionAccepterTests.cs b/OpenXmlPowerTools.Tests/RevisionAccepterTests.cs
index 2797e478..c98a3934 100644
--- a/OpenXmlPowerTools.Tests/RevisionAccepterTests.cs
+++ b/OpenXmlPowerTools.Tests/RevisionAccepterTests.cs
@@ -1,41 +1,23 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
+using Codeuctivity.OpenXmlPowerTools;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class RaTests
{
[Theory]
[InlineData("RA001-Tracked-Revisions-01.docx")]
[InlineData("RA001-Tracked-Revisions-02.docx")]
-
public void RA001(string name)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
- WmlDocument notAccepted = new WmlDocument(sourceDocx.FullName);
- WmlDocument afterAccepting = RevisionAccepter.AcceptRevisions(notAccepted);
+ var notAccepted = new WmlDocument(sourceDocx.FullName);
+ var afterAccepting = RevisionAccepter.AcceptRevisions(notAccepted);
var processedDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-processed-by-RevisionAccepter.docx")));
afterAccepting.SaveAs(processedDestDocx.FullName);
}
-
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/RevisionProcessorTests.cs b/OpenXmlPowerTools.Tests/RevisionProcessorTests.cs
index 88730fb2..f4b92234 100644
--- a/OpenXmlPowerTools.Tests/RevisionProcessorTests.cs
+++ b/OpenXmlPowerTools.Tests/RevisionProcessorTests.cs
@@ -1,34 +1,13 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using Codeuctivity.OpenXmlPowerTools;
using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class RpTests
{
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // perf settings
- public static bool m_CopySourceFilesToTempDir = true;
- public static bool m_OpenTempDirInExplorer = false;
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
[Theory]
- //[InlineData("RP/RP001-Tracked-Revisions-01.docx")]
- //[InlineData("RP/RP001-Tracked-Revisions-02.docx")]
[InlineData("RP/RP002-Deleted-Text.docx")]
[InlineData("RP/RP003-Inserted-Text.docx")]
[InlineData("RP/RP004-Deleted-Text-in-CC.docx")]
@@ -81,14 +60,14 @@ public class RpTests
[InlineData("RP/RP052-Deleted-Para-Mark.docx")]
public void RP001(string name)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
var sourceFi = new FileInfo(Path.Combine(sourceDir.FullName, name));
var baselineAcceptedFi = new FileInfo(Path.Combine(sourceDir.FullName, name.Replace(".docx", "-Accepted.docx")));
var baselineRejectedFi = new FileInfo(Path.Combine(sourceDir.FullName, name.Replace(".docx", "-Rejected.docx")));
- WmlDocument sourceWml = new WmlDocument(sourceFi.FullName);
- WmlDocument afterRejectingWml = RevisionProcessor.RejectRevisions(sourceWml);
- WmlDocument afterAcceptingWml = RevisionProcessor.AcceptRevisions(sourceWml);
+ var sourceWml = new WmlDocument(sourceFi.FullName);
+ var afterRejectingWml = RevisionProcessor.RejectRevisions(sourceWml);
+ var afterAcceptingWml = RevisionProcessor.AcceptRevisions(sourceWml);
var processedAcceptedFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceFi.Name.Replace(".docx", "-Accepted.docx")));
afterAcceptingWml.SaveAs(processedAcceptedFi.FullName);
@@ -96,45 +75,24 @@ public void RP001(string name)
var processedRejectedFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceFi.Name.Replace(".docx", "-Rejected.docx")));
afterRejectingWml.SaveAs(processedRejectedFi.FullName);
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Copy source files to temp dir
- if (m_CopySourceFilesToTempDir)
- {
- while (true)
- {
- try
- {
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
- var sourceDocxCopiedToDestFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceFi.Name));
- if (!sourceDocxCopiedToDestFi.Exists)
- sourceWml.SaveAs(sourceDocxCopiedToDestFi.FullName);
- //////////////////////////////////////////////////
- break;
- }
- catch (IOException)
- {
- System.Threading.Thread.Sleep(50);
- }
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// create batch file to copy properly processed documents to the TestFiles directory.
while (true)
{
try
{
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
var batchFileName = "Copy-Gen-Files-To-TestFiles.bat";
var batchFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, batchFileName));
var batch = "";
batch += "copy " + processedAcceptedFi.FullName + " " + baselineAcceptedFi.FullName + Environment.NewLine;
batch += "copy " + processedRejectedFi.FullName + " " + baselineRejectedFi.FullName + Environment.NewLine;
if (batchFi.Exists)
+ {
File.AppendAllText(batchFi.FullName, batch);
+ }
else
+ {
File.WriteAllText(batchFi.FullName, batch);
- //////////////////////////////////////////////////
+ }
break;
}
catch (IOException)
@@ -142,69 +100,6 @@ public void RP001(string name)
System.Threading.Thread.Sleep(50);
}
}
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Open Windows Explorer
- if (m_OpenTempDirInExplorer)
- {
- while (true)
- {
- try
- {
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
- var semaphorFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "z_ExplorerOpenedSemaphore.txt"));
- if (!semaphorFi.Exists)
- {
- File.WriteAllText(semaphorFi.FullName, "");
- TestUtil.Explorer(TestUtil.TempDir);
- }
- //////////////////////////////////////////////////
- break;
- }
- catch (IOException)
- {
- System.Threading.Thread.Sleep(50);
- }
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Use WmlComparer to see if accepted baseline is same as processed
- if (baselineAcceptedFi.Exists)
- {
- var baselineAcceptedWml = new WmlDocument(baselineAcceptedFi.FullName);
- WmlComparerSettings wmlComparerSettings = new WmlComparerSettings();
- WmlDocument result = WmlComparer.Compare(baselineAcceptedWml, afterAcceptingWml, wmlComparerSettings);
- var revisions = WmlComparer.GetRevisions(result, wmlComparerSettings);
- if (revisions.Any())
- {
- Assert.True(false, "Regression Error: Accepted baseline document did not match processed document");
- }
- }
- else
- {
- Assert.True(false, "No Accepted baseline document");
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Use WmlComparer to see if rejected baseline is same as processed
- if (baselineRejectedFi.Exists)
- {
- var baselineRejectedWml = new WmlDocument(baselineRejectedFi.FullName);
- WmlComparerSettings wmlComparerSettings = new WmlComparerSettings();
- WmlDocument result = WmlComparer.Compare(baselineRejectedWml, afterRejectingWml, wmlComparerSettings);
- var revisions = WmlComparer.GetRevisions(result, wmlComparerSettings);
- if (revisions.Any())
- {
- Assert.True(false, "Regression Error: Rejected baseline document did not match processed document");
- }
- }
- else
- {
- Assert.True(false, "No Rejected baseline document");
- }
}
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/SmlCellFormatterTests.cs b/OpenXmlPowerTools.Tests/SmlCellFormatterTests.cs
index 0c215625..abc3026a 100644
--- a/OpenXmlPowerTools.Tests/SmlCellFormatterTests.cs
+++ b/OpenXmlPowerTools.Tests/SmlCellFormatterTests.cs
@@ -1,22 +1,10 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
+using Codeuctivity.OpenXmlPowerTools;
+using DocumentFormat.OpenXml.Packaging;
using System.IO;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class CfTests
{
@@ -82,11 +70,9 @@ public class CfTests
[InlineData("mm:ss.0", "42344.295445092591", "05:26:456", null)]
[InlineData("##0.0E+0", "100.0", "100.0E+0", null)]
[InlineData("##0.0E+0", "543.210", "543.2E+0", null)]
-
public void CF001(string formatCode, string value, string expected, string expectedColor)
{
- string color;
- string r = SmlCellFormatter.FormatCell(formatCode, value, out color);
+ var r = SmlCellFormatter.FormatCell(formatCode, value, out var color);
Assert.Equal(expected, r);
Assert.Equal(expectedColor, color);
}
@@ -116,38 +102,29 @@ public void CF001(string formatCode, string value, string expected, string expec
[InlineData("SH151-Custom-Cell-Format-Currency.xlsx", "Sheet1", "H1:H1", "£ 123.45", null)]
[InlineData("SH151-Custom-Cell-Format-Currency.xlsx", "Sheet1", "H2:H2", "-£ 123.45", "Red")]
[InlineData("SH151-Custom-Cell-Format-Currency.xlsx", "Sheet1", "H3:H3", "£ -", null)]
-
[InlineData("SH152-Custom-Cell-Format.xlsx", "Sheet1", "A1:A1", "1,234,567.0000", null)]
[InlineData("SH152-Custom-Cell-Format.xlsx", "Sheet1", "B1:B1", "This is the value: abc", null)]
-
[InlineData("SH201-Cell-C1-Without-R-Attr.xlsx", "Sheet1", "C1:C1", "3", null)]
[InlineData("SH202-Cell-C1-D1-Without-R-Attr.xlsx", "Sheet1", "C1:C1", "3", null)]
[InlineData("SH203-Cell-C1-D1-E1-Without-R-Attr.xlsx", "Sheet1", "C1:C1", "3", null)]
[InlineData("SH204-Cell-A1-B1-C1-Without-R-Attr.xlsx", "Sheet1", "A1:A1", "1", null)]
-
public void CF002(string name, string sheetName, string range, string expected, string expectedColor)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
var sourceCopiedToDestXlsx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceXlsx.Name.Replace(".xlsx", "-1-Source.xlsx")));
if (!sourceCopiedToDestXlsx.Exists)
- File.Copy(sourceXlsx.FullName, sourceCopiedToDestXlsx.FullName);
-
- var dataTemplateFileNameSuffix = string.Format("-2-Generated-XmlData-{0}.xml", range.Replace(":", ""));
- var dataXmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceXlsx.Name.Replace(".xlsx", dataTemplateFileNameSuffix)));
- using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(sourceXlsx.FullName, true))
{
- var rangeXml = SmlDataRetriever.RetrieveRange(sDoc, sheetName, range);
- string displayValue = (string)rangeXml.Descendants("DisplayValue").FirstOrDefault();
- string displayColor = (string)rangeXml.Descendants("DisplayColor").FirstOrDefault();
- Assert.Equal(expected, displayValue);
- Assert.Equal(expectedColor, displayColor);
+ File.Copy(sourceXlsx.FullName, sourceCopiedToDestXlsx.FullName);
}
- }
-
+ using var sDoc = SpreadsheetDocument.Open(sourceCopiedToDestXlsx.FullName, true);
+ var rangeXml = SmlDataRetriever.RetrieveRange(sDoc, sheetName, range);
+ var displayValue = (string)rangeXml.Descendants("DisplayValue").FirstOrDefault();
+ var displayColor = (string)rangeXml.Descendants("DisplayColor").FirstOrDefault();
+ Assert.Equal(expected, displayValue);
+ Assert.Equal(expectedColor, displayColor);
+ }
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/SmlToHtmlConverterTests.cs b/OpenXmlPowerTools.Tests/SmlToHtmlConverterTests.cs
index a0ad0393..5cb0b5ea 100644
--- a/OpenXmlPowerTools.Tests/SmlToHtmlConverterTests.cs
+++ b/OpenXmlPowerTools.Tests/SmlToHtmlConverterTests.cs
@@ -1,22 +1,9 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
+using Codeuctivity.OpenXmlPowerTools;
using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
+using System.IO;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class ShTests
{
@@ -54,24 +41,23 @@ public class ShTests
[InlineData("SH129-FmtNumId-20.xlsx", "Sheet1")]
[InlineData("SH130-FmtNumId-21.xlsx", "Sheet1")]
[InlineData("SH131-FmtNumId-22.xlsx", "Sheet1")]
-
public void SH005_ConvertSheet(string name, string sheetName)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
var sourceCopiedToDestXlsx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceXlsx.Name.Replace(".xlsx", "-1-Source.xlsx")));
if (!sourceCopiedToDestXlsx.Exists)
+ {
File.Copy(sourceXlsx.FullName, sourceCopiedToDestXlsx.FullName);
+ }
var dataTemplateFileNameSuffix = "-2-Generated-XmlData-Entire-Sheet.xml";
- var dataXmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceXlsx.Name.Replace(".xlsx", dataTemplateFileNameSuffix)));
- using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(sourceXlsx.FullName, true))
- {
- var settings = new SmlToHtmlConverterSettings();
- var rangeXml = SmlDataRetriever.RetrieveSheet(sDoc, sheetName);
- rangeXml.Save(dataXmlFi.FullName);
- }
+ var dataXmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceCopiedToDestXlsx.Name.Replace(".xlsx", dataTemplateFileNameSuffix)));
+ using var sDoc = SpreadsheetDocument.Open(sourceCopiedToDestXlsx.FullName, true);
+ var settings = new SmlToHtmlConverterSettings();
+ var rangeXml = SmlDataRetriever.RetrieveSheet(sDoc, sheetName);
+ rangeXml.Save(dataXmlFi.FullName);
}
[Theory]
@@ -113,26 +99,24 @@ public void SH005_ConvertSheet(string name, string sheetName)
[InlineData("SH129-FmtNumId-20.xlsx", "Sheet1", "A1:A10")]
[InlineData("SH130-FmtNumId-21.xlsx", "Sheet1", "A1:A10")]
[InlineData("SH131-FmtNumId-22.xlsx", "Sheet1", "A1:A10")]
-
public void SH004_ConvertRange(string name, string sheetName, string range)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
var sourceCopiedToDestXlsx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceXlsx.Name.Replace(".xlsx", "-1-Source.xlsx")));
if (!sourceCopiedToDestXlsx.Exists)
+ {
File.Copy(sourceXlsx.FullName, sourceCopiedToDestXlsx.FullName);
+ }
var dataTemplateFileNameSuffix = string.Format("-2-Generated-XmlData-{0}.xml", range.Replace(":", ""));
- var dataXmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceXlsx.Name.Replace(".xlsx", dataTemplateFileNameSuffix)));
- using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(sourceXlsx.FullName, true))
- {
- var settings = new SmlToHtmlConverterSettings();
- var rangeXml = SmlDataRetriever.RetrieveRange(sDoc, sheetName, range);
- rangeXml.Save(dataXmlFi.FullName);
- }
+ var dataXmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceCopiedToDestXlsx.Name.Replace(".xlsx", dataTemplateFileNameSuffix)));
+ using var sDoc = SpreadsheetDocument.Open(sourceCopiedToDestXlsx.FullName, true);
+ var settings = new SmlToHtmlConverterSettings();
+ var rangeXml = SmlDataRetriever.RetrieveRange(sDoc, sheetName, range);
+ rangeXml.Save(dataXmlFi.FullName);
}
-
[Theory]
[InlineData("SH001-Table.xlsx", "MyTable")]
@@ -144,36 +128,33 @@ public void SH004_ConvertRange(string name, string sheetName, string range)
[InlineData("SH007-One-Cell-Table.xlsx", "Table1")]
[InlineData("SH008-Table-With-Tall-Row.xlsx", "Table1")]
[InlineData("SH009-Table-With-Wide-Column.xlsx", "Table1")]
-
public void SH003_ConvertTable(string name, string tableName)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
var sourceCopiedToDestXlsx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceXlsx.Name.Replace(".xlsx", "-1-Source.xlsx")));
if (!sourceCopiedToDestXlsx.Exists)
- File.Copy(sourceXlsx.FullName, sourceCopiedToDestXlsx.FullName);
-
- var dataXmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceXlsx.Name.Replace(".xlsx", "-2-Generated-XmlData.xml")));
- using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(sourceXlsx.FullName, true))
{
- var settings = new SmlToHtmlConverterSettings();
- var rangeXml = SmlDataRetriever.RetrieveTable(sDoc, tableName);
- rangeXml.Save(dataXmlFi.FullName);
+ File.Copy(sourceXlsx.FullName, sourceCopiedToDestXlsx.FullName);
}
+
+ var dataXmlFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceCopiedToDestXlsx.Name.Replace(".xlsx", "-2-Generated-XmlData.xml")));
+ using var sDoc = SpreadsheetDocument.Open(sourceCopiedToDestXlsx.FullName, true);
+ var settings = new SmlToHtmlConverterSettings();
+ var rangeXml = SmlDataRetriever.RetrieveTable(sDoc, tableName);
+ rangeXml.Save(dataXmlFi.FullName);
}
[Theory]
[InlineData("Spreadsheet.xlsx", 2)]
public void SH002_SheetNames(string name, int numberOfSheets)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
- using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(sourceXlsx.FullName, true))
- {
- var sheetNames = SmlDataRetriever.SheetNames(sDoc);
- Assert.Equal(numberOfSheets, sheetNames.Length);
- }
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ using var sDoc = SpreadsheetDocument.Open(sourceXlsx.FullName, false);
+ var sheetNames = SmlDataRetriever.SheetNames(sDoc);
+ Assert.Equal(numberOfSheets, sheetNames.Length);
}
[Theory]
@@ -181,15 +162,11 @@ public void SH002_SheetNames(string name, int numberOfSheets)
[InlineData("SH002-TwoTablesTwoSheets.xlsx", 2)]
public void SH001_TableNames(string name, int numberOfTables)
{
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
- using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(sourceXlsx.FullName, true))
- {
- var table = SmlDataRetriever.TableNames(sDoc);
- Assert.Equal(numberOfTables, table.Length);
- }
+ var sourceDir = new DirectoryInfo("../../../../TestFiles/");
+ var sourceXlsx = new FileInfo(Path.Combine(sourceDir.FullName, name));
+ using var sDoc = SpreadsheetDocument.Open(sourceXlsx.FullName, false);
+ var table = SmlDataRetriever.TableNames(sDoc);
+ Assert.Equal(numberOfTables, table.Length);
}
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/SpreadsheetWriterTests.cs b/OpenXmlPowerTools.Tests/SpreadsheetWriterTests.cs
index 5deccaa2..e17ae745 100644
--- a/OpenXmlPowerTools.Tests/SpreadsheetWriterTests.cs
+++ b/OpenXmlPowerTools.Tests/SpreadsheetWriterTests.cs
@@ -1,92 +1,83 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using Codeuctivity.OpenXmlPowerTools;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Validation;
using System;
using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Validation;
-using Sw = OpenXmlPowerTools;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
+namespace Codeuctivity.Tests
{
public class SwTests
{
[Fact]
public void SW001_Simple()
{
- Sw.WorkbookDfn wb = new Sw.WorkbookDfn
+ var wb = new WorkbookDfn
{
- Worksheets = new Sw.WorksheetDfn[]
+ Worksheets = new WorksheetDfn[]
{
- new Sw.WorksheetDfn
+ new WorksheetDfn
{
Name = "MyFirstSheet",
TableName = "NamesAndRates",
- ColumnHeadings = new Sw.CellDfn[]
+ ColumnHeadings = new CellDfn[]
{
- new Sw.CellDfn
+ new CellDfn
{
Value = "Name",
Bold = true,
},
- new Sw.CellDfn
+ new CellDfn
{
Value = "Age",
Bold = true,
- HorizontalCellAlignment = Sw.HorizontalCellAlignment.Left,
+ HorizontalCellAlignment = HorizontalCellAlignment.Left,
},
- new Sw.CellDfn
+ new CellDfn
{
Value = "Rate",
Bold = true,
- HorizontalCellAlignment = Sw.HorizontalCellAlignment.Left,
+ HorizontalCellAlignment = HorizontalCellAlignment.Left,
}
},
- Rows = new Sw.RowDfn[]
+ Rows = new RowDfn[]
{
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "Eric",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
Value = 50,
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
Value = (decimal)45.00,
FormatCode = "0.00",
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "Bob",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
Value = 42,
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
Value = (decimal)78.00,
FormatCode = "0.00",
},
@@ -96,207 +87,235 @@ public void SW001_Simple()
}
}
};
- var outXlsx = new FileInfo(Path.Combine(Sw.TestUtil.TempDir.FullName, "SW001-Simple.xlsx"));
- Sw.SpreadsheetWriter.Write(outXlsx.FullName, wb);
+ var outXlsx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "SW001-Simple.xlsx"));
+ SpreadsheetWriter.Write(outXlsx.FullName, wb);
Validate(outXlsx);
}
+ // Breaks with DocumentFormat.OpenXml 2.12 but works till 2.11.3
[Fact]
public void SW002_AllDataTypes()
{
- Sw.WorkbookDfn wb = new Sw.WorkbookDfn
+ var wb = new WorkbookDfn
{
- Worksheets = new Sw.WorksheetDfn[]
+ Worksheets = new WorksheetDfn[]
{
- new Sw.WorksheetDfn
+ new WorksheetDfn
{
Name = "MyFirstSheet",
- ColumnHeadings = new Sw.CellDfn[]
+ ColumnHeadings = new CellDfn[]
{
- new Sw.CellDfn
+ new CellDfn
{
Value = "DataType",
Bold = true,
},
- new Sw.CellDfn
+ new CellDfn
{
Value = "Value",
Bold = true,
- HorizontalCellAlignment = Sw.HorizontalCellAlignment.Right,
+ HorizontalCellAlignment = HorizontalCellAlignment.Right,
},
},
- Rows = new Sw.RowDfn[]
+ Rows = new RowDfn[]
{
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "Boolean",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Boolean,
+ new CellDfn {
+ CellDataType = CellDataType.Boolean,
Value = true,
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "Boolean",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Boolean,
+ new CellDfn {
+ CellDataType = CellDataType.Boolean,
Value = false,
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "String",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "A String",
- HorizontalCellAlignment = Sw.HorizontalCellAlignment.Right,
+ HorizontalCellAlignment = HorizontalCellAlignment.Right,
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "int",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
- Value = (int)100,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
+ Value = 100,
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "int?",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
- Value = (int?)100,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
+ Value = 100,
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "int? (is null)",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
Value = null,
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "uint",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
- Value = (uint)101,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
+ Value = 101,
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "long",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
- Value = Int64.MaxValue,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
+ Value = long.MaxValue,
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "float",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
Value = (float)123.45,
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "double",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
- Value = (double)123.45,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
+ Value = 123.45,
},
}
},
- new Sw.RowDfn
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.String,
+ new CellDfn {
+ CellDataType = CellDataType.String,
Value = "decimal",
},
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Number,
+ new CellDfn {
+ CellDataType = CellDataType.Number,
Value = (decimal)123.45,
},
}
},
- new Sw.RowDfn
+ new RowDfn
+ {
+ Cells = new CellDfn[]
+ {
+ new CellDfn {
+ CellDataType = CellDataType.String,
+ Value = "date (t:str)",
+ },
+ new CellDfn {
+ Value = new DateTime(2012, 1, 8).ToOADate(),
+ FormatCode= "mm-dd-yy",
+ Bold = true,
+ },
+ }
+ },
+ new RowDfn
{
- Cells = new Sw.CellDfn[]
+ Cells = new CellDfn[]
{
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Date,
- Value = new DateTime(2012, 1, 8),
- FormatCode = "mm-dd-yy",
- },
- new Sw.CellDfn {
- CellDataType = Sw.CellDataType.Date,
- Value = new DateTime(2012, 1, 9),
- FormatCode = "mm-dd-yy",
+ new CellDfn {
+ CellDataType = CellDataType.String,
+ Value = "date (t:str)",
+ },
+ new CellDfn {
+ Value = new DateTime(2012, 1, 9).ToOADate(),
+ FormatCode= "mm-dd-yy",
Bold = true,
- HorizontalCellAlignment = Sw.HorizontalCellAlignment.Center,
+ HorizontalCellAlignment = HorizontalCellAlignment.Center,
+ },
+ }
+ },
+ new RowDfn
+ {
+ Cells = new CellDfn[]
+ {
+ new CellDfn {
+ CellDataType = CellDataType.String,
+ Value = "date (t:d)",
+ },
+ new CellDfn {
+ CellDataType = CellDataType.Date,
+ Value = new DateTime(2012, 1, 11).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff"),
},
}
},
@@ -304,43 +323,36 @@ public void SW002_AllDataTypes()
}
}
};
- var outXlsx = new FileInfo(Path.Combine(Sw.TestUtil.TempDir.FullName, "SW002-DataTypes.xlsx"));
- Sw.SpreadsheetWriter.Write(outXlsx.FullName, wb);
+ var outXlsx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "SW002-DataTypes.xlsx"));
+ SpreadsheetWriter.Write(outXlsx.FullName, wb);
Validate(outXlsx);
}
private void Validate(FileInfo fi)
{
- using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(fi.FullName, true))
- {
- OpenXmlValidator v = new OpenXmlValidator();
- var errors = v.Validate(sDoc).Where(ve => !s_ExpectedErrors.Contains(ve.Description));
+ using var sDoc = SpreadsheetDocument.Open(fi.FullName, true);
+ var v = new OpenXmlValidator();
+ var errors = v.Validate(sDoc).Where(ve => !s_ExpectedErrors.Contains(ve.Description));
-#if false
- // if a test fails validation post-processing, then can use this code to determine the SDK
- // validation error(s).
+ // if a test fails validation post-processing, then can use this code to determine the SDK validation error(s).
- if (errors.Count() != 0)
+ if (errors.Any())
+ {
+ var sb = new StringBuilder();
+ foreach (var item in errors)
{
- StringBuilder sb = new StringBuilder();
- foreach (var item in errors)
- {
- sb.Append(item.Description).Append(Environment.NewLine);
- }
- var s = sb.ToString();
- Console.WriteLine(s);
+ sb.Append(item.Description).Append(Environment.NewLine);
}
-#endif
-
- Assert.Empty(errors);
+ var s = sb.ToString();
+ Console.WriteLine(s);
}
+
+ Assert.Empty(errors);
}
- private static List s_ExpectedErrors = new List()
+ private static readonly List s_ExpectedErrors = new List()
{
"The attribute 't' has invalid value 'd'. The Enumeration constraint failed.",
};
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/StronglyTypedBlockTests.cs b/OpenXmlPowerTools.Tests/StronglyTypedBlockTests.cs
index ac0c5715..18edaba4 100644
--- a/OpenXmlPowerTools.Tests/StronglyTypedBlockTests.cs
+++ b/OpenXmlPowerTools.Tests/StronglyTypedBlockTests.cs
@@ -1,60 +1,51 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using Codeuctivity.OpenXmlPowerTools;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Wordprocessing;
using System;
-using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Wordprocessing;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OpenXmlPowerTools.Tests
+namespace Codeuctivity.Tests
{
public class StronglyTypedBlockTests : TestsBase
{
[Fact]
public void CanUseStronglyTypedBlockToDemarcateApis()
{
- using (var stream = new MemoryStream())
- {
- CreateEmptyWordprocessingDocument(stream);
-
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(stream, true))
- {
- MainDocumentPart part = wordDocument.MainDocumentPart;
-
- // Add a paragraph through the PowerTools.
- XDocument content = part.GetXDocument();
- XElement bodyElement = content.Descendants(W.body).First();
- bodyElement.Add(new XElement(W.p, new XElement(W.r, new XElement(W.t, "Added through PowerTools"))));
- part.PutXDocument();
+ using var stream = new MemoryStream();
+ CreateEmptyWordprocessingDocument(stream);
- // This demonstrates the use of the StronglyTypedBlock in a using statement to
- // demarcate the intermittent use of the strongly typed classes.
- using (new StronglyTypedBlock(wordDocument))
- {
- // Assert that we can see the paragraph added through the PowerTools.
- Body body = part.Document.Body;
- List paragraphs = body.Elements().ToList();
- Assert.Single(paragraphs);
- Assert.Equal("Added through PowerTools", paragraphs[0].InnerText);
+ using var wordDocument = WordprocessingDocument.Open(stream, true);
+ var part = wordDocument.MainDocumentPart;
- // Add a paragraph through the SDK.
- body.AppendChild(new Paragraph(new Run(new Text("Added through SDK"))));
- }
+ // Add a paragraph through the PowerTools.
+ var content = part.GetXDocument();
+ var bodyElement = content.Descendants(W.body).First();
+ bodyElement.Add(new XElement(W.p, new XElement(W.r, new XElement(W.t, "Added through PowerTools"))));
+ part.PutXDocument();
- // Assert that we can see the paragraphs added through the PowerTools and the SDK.
- content = part.GetXDocument();
- List paragraphElements = content.Descendants(W.p).ToList();
- Assert.Equal(2, paragraphElements.Count);
- Assert.Equal("Added through PowerTools", paragraphElements[0].Value);
- Assert.Equal("Added through SDK", paragraphElements[1].Value);
- }
+ // This demonstrates the use of the StronglyTypedBlock in a using statement to
+ // demarcate the intermittent use of the strongly typed classes.
+ using (new StronglyTypedBlock(wordDocument))
+ {
+ // Assert that we can see the paragraph added through the PowerTools.
+ var body = part.Document.Body;
+ var paragraphs = body.Elements().ToList();
+ Assert.Single(paragraphs);
+ Assert.Equal("Added through PowerTools", paragraphs[0].InnerText);
+
+ // Add a paragraph through the SDK.
+ body.AppendChild(new Paragraph(new Run(new Text("Added through SDK"))));
}
+
+ // Assert that we can see the paragraphs added through the PowerTools and the SDK.
+ content = part.GetXDocument();
+ var paragraphElements = content.Descendants(W.p).ToList();
+ Assert.Equal(2, paragraphElements.Count);
+ Assert.Equal("Added through PowerTools", paragraphElements[0].Value);
+ Assert.Equal("Added through SDK", paragraphElements[1].Value);
}
[Fact]
@@ -63,6 +54,4 @@ public void ConstructorThrowsWhenPassingNull()
Assert.Throws(() => new StronglyTypedBlock(null));
}
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/TestUtil.cs b/OpenXmlPowerTools.Tests/TestUtil.cs
new file mode 100644
index 00000000..4ef92264
--- /dev/null
+++ b/OpenXmlPowerTools.Tests/TestUtil.cs
@@ -0,0 +1,22 @@
+using System;
+using System.IO;
+
+namespace Codeuctivity.Tests
+{
+ public class TestUtil
+ {
+ static TestUtil()
+ {
+ var now = DateTime.Now;
+ var tempDirName = $"Test-{now.Year - 2000:00}-{now.Month:00}-{now.Day:00}-{now.Hour:00}{now.Minute:00}{now.Second:00}-{Guid.NewGuid()}";
+ var tempDir = new DirectoryInfo(Path.Combine(Path.GetTempPath(), tempDirName));
+ tempDir.Create();
+ TempDir = tempDir;
+ }
+
+ ///
+ /// Lookin into /tmp or %temp% for test output
+ ///
+ public static DirectoryInfo TempDir { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/TestsBase.cs b/OpenXmlPowerTools.Tests/TestsBase.cs
index a5df4f51..03c62f91 100644
--- a/OpenXmlPowerTools.Tests/TestsBase.cs
+++ b/OpenXmlPowerTools.Tests/TestsBase.cs
@@ -1,12 +1,9 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System.IO;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
+using System.IO;
-namespace OpenXmlPowerTools.Tests
+namespace Codeuctivity.Tests
{
///
/// Base class for unit tests providing utility methods.
@@ -17,11 +14,9 @@ public class TestsBase
protected static void CreateEmptyWordprocessingDocument(Stream stream)
{
- using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, DocumentType))
- {
- MainDocumentPart part = wordDocument.AddMainDocumentPart();
- part.Document = new Document(new Body());
- }
+ using var wordDocument = WordprocessingDocument.Create(stream, DocumentType);
+ var part = wordDocument.AddMainDocumentPart();
+ part.Document = new Document(new Body());
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/UnicodeMapperTests.cs b/OpenXmlPowerTools.Tests/UnicodeMapperTests.cs
index 562a6682..b54e8f69 100644
--- a/OpenXmlPowerTools.Tests/UnicodeMapperTests.cs
+++ b/OpenXmlPowerTools.Tests/UnicodeMapperTests.cs
@@ -1,27 +1,9 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation 2016.
-
-This code is licensed using the Microsoft Public License (Ms-PL). The text of the license can be found here:
-
-http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx
-
-Developer: Thomas Barnekow
-Email: thomas@barnekow.info
-
-***************************************************************************/
-
-using System.Collections.Generic;
+using Codeuctivity.OpenXmlPowerTools;
using System.Linq;
using System.Xml.Linq;
using Xunit;
-#if !ELIDE_XUNIT_TESTS
-
-namespace OpenXmlPowerTools.Tests
+namespace Codeuctivity.Tests
{
public class UnicodeMapperTests
{
@@ -63,7 +45,7 @@ public void CanCreateRunChildElementsFromSpecialCharacters()
Assert.Equal(W.softHyphen, UnicodeMapper.CharToRunChild(UnicodeMapper.SoftHyphen).Name);
Assert.Equal(W.tab, UnicodeMapper.CharToRunChild(UnicodeMapper.HorizontalTabulation).Name);
- XElement element = UnicodeMapper.CharToRunChild(UnicodeMapper.FormFeed);
+ var element = UnicodeMapper.CharToRunChild(UnicodeMapper.FormFeed);
Assert.Equal(W.br, element.Name);
Assert.Equal("page", element.Attribute(W.type).Value);
@@ -76,8 +58,8 @@ public void CanCreateCoalescedRuns()
const string textString = "This is only text.";
const string mixedString = "First\tSecond\tThird";
- List textRuns = UnicodeMapper.StringToCoalescedRunList(textString, null);
- List mixedRuns = UnicodeMapper.StringToCoalescedRunList(mixedString, null);
+ var textRuns = UnicodeMapper.StringToCoalescedRunList(textString, null);
+ var mixedRuns = UnicodeMapper.StringToCoalescedRunList(mixedString, null);
Assert.Single(textRuns);
Assert.Equal(5, mixedRuns.Count);
@@ -93,26 +75,26 @@ public void CanMapSymbols()
var sym1 = new XElement(W.sym,
new XAttribute(W.font, "Wingdings"),
new XAttribute(W._char, "F028"));
- char charFromSym1 = UnicodeMapper.SymToChar(sym1);
- XElement symFromChar1 = UnicodeMapper.CharToRunChild(charFromSym1);
+ var charFromSym1 = UnicodeMapper.SymToChar(sym1);
+ var symFromChar1 = UnicodeMapper.CharToRunChild(charFromSym1);
var sym2 = new XElement(W.sym,
new XAttribute(W._char, "F028"),
new XAttribute(W.font, "Wingdings"));
- char charFromSym2 = UnicodeMapper.SymToChar(sym2);
+ var charFromSym2 = UnicodeMapper.SymToChar(sym2);
var sym3 = new XElement(W.sym,
new XAttribute(XNamespace.Xmlns + "w", W.w),
new XAttribute(W.font, "Wingdings"),
new XAttribute(W._char, "F028"));
- char charFromSym3 = UnicodeMapper.SymToChar(sym3);
+ var charFromSym3 = UnicodeMapper.SymToChar(sym3);
var sym4 = new XElement(W.sym,
new XAttribute(XNamespace.Xmlns + "w", W.w),
new XAttribute(W.font, "Webdings"),
new XAttribute(W._char, "F028"));
- char charFromSym4 = UnicodeMapper.SymToChar(sym4);
- XElement symFromChar4 = UnicodeMapper.CharToRunChild(charFromSym4);
+ var charFromSym4 = UnicodeMapper.SymToChar(sym4);
+ var symFromChar4 = UnicodeMapper.CharToRunChild(charFromSym4);
Assert.Equal(charFromSym1, charFromSym2);
Assert.Equal(charFromSym1, charFromSym3);
@@ -128,13 +110,13 @@ public void CanMapSymbols()
[Fact]
public void CanStringifySymbols()
{
- char charFromSym1 = UnicodeMapper.SymToChar("Wingdings", '\uF028');
- char charFromSym2 = UnicodeMapper.SymToChar("Wingdings", 0xF028);
- char charFromSym3 = UnicodeMapper.SymToChar("Wingdings", "F028");
+ var charFromSym1 = UnicodeMapper.SymToChar("Wingdings", '\uF028');
+ var charFromSym2 = UnicodeMapper.SymToChar("Wingdings", 0xF028);
+ var charFromSym3 = UnicodeMapper.SymToChar("Wingdings", "F028");
- XElement symFromChar1 = UnicodeMapper.CharToRunChild(charFromSym1);
- XElement symFromChar2 = UnicodeMapper.CharToRunChild(charFromSym2);
- XElement symFromChar3 = UnicodeMapper.CharToRunChild(charFromSym3);
+ var symFromChar1 = UnicodeMapper.CharToRunChild(charFromSym1);
+ var symFromChar2 = UnicodeMapper.CharToRunChild(charFromSym2);
+ var symFromChar3 = UnicodeMapper.CharToRunChild(charFromSym3);
Assert.Equal(charFromSym1, charFromSym2);
Assert.Equal(charFromSym1, charFromSym3);
@@ -143,6 +125,4 @@ public void CanStringifySymbols()
Assert.Equal(symFromChar1.ToString(SaveOptions.None), symFromChar3.ToString(SaveOptions.None));
}
}
-}
-
-#endif
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools.Tests/WmlComparerTests.cs b/OpenXmlPowerTools.Tests/WmlComparerTests.cs
deleted file mode 100644
index a882b422..00000000
--- a/OpenXmlPowerTools.Tests/WmlComparerTests.cs
+++ /dev/null
@@ -1,1114 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Validation;
-using OpenXmlPowerTools;
-using Xunit;
-using System.Diagnostics;
-
-/****************************************************************************************************************/
-// Large tests have been commented out below. If and when there is an effort to improve performance for WmlComparer,
-// then uncomment. Performance isn't bad, but certainly is possible to improve.
-/****************************************************************************************************************/
-
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
-{
- public class WcTests
- {
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- public static bool s_OpenWord = false;
- public static bool m_OpenTempDirInExplorer = false;
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- [Theory]
- [InlineData("RC-0010", "RC/RC001-Before.docx",
- @"
-
- RC/RC001-After1.docx
- LightYellow
- From Bob
-
-
- RC/RC001-After2.docx
- LightPink
- From Fred
-
- ")]
- [InlineData("RC-0020", "RC/RC002-Image.docx",
- @"
-
- RC/RC002-Image-After1.docx
- LightBlue
- From Bob
-
- ")]
- [InlineData("RC-0030", "RC/RC002-Image-After1.docx",
- @"
-
- RC/RC002-Image.docx
- LightBlue
- From Bob
-
- ")]
- [InlineData("RC-0040", "WC/WC027-Twenty-Paras-Before.docx",
- @"
-
- WC/WC027-Twenty-Paras-After-1.docx
- LightBlue
- From Bob
-
- ")]
- [InlineData("RC-0050", "WC/WC027-Twenty-Paras-Before.docx",
- @"
-
- WC/WC027-Twenty-Paras-After-3.docx
- LightBlue
- From Bob
-
- ")]
- [InlineData("RC-0060", "RC/RC003-Multi-Paras.docx",
- @"
-
- RC/RC003-Multi-Paras-After.docx
- LightBlue
- From Bob
-
- ")]
- [InlineData("RC-0070", "RC/RC004-Before.docx",
- @"
-
- RC/RC004-After1.docx
- LightYellow
- From Bob
-
-
- RC/RC004-After2.docx
- LightPink
- From Fred
-
- ")]
- [InlineData("RC-0080", "RC/RC005-Before.docx",
- @"
-
- RC/RC005-After1.docx
- LightYellow
- From Bob
-
- ")]
- [InlineData("RC-0090", "RC/RC006-Before.docx",
- @"
-
- RC/RC006-After1.docx
- LightYellow
- From Bob
-
- ")]
- [InlineData("RC-0100", "RC/RC007-Endnotes-Before.docx",
- @"
-
- RC/RC007-Endnotes-After.docx
- LightYellow
- From Bob
-
- ")]
-
- public void WC001_Consolidate(string testId, string originalName, string revisedDocumentsXml)
- {
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo originalDocx = new FileInfo(Path.Combine(sourceDir.FullName, originalName));
-
- var rootTempDir = TestUtil.TempDir;
- var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
- if (thisTestTempDir.Exists)
- Assert.True(false, "Duplicate test id: " + testId);
- else
- thisTestTempDir.Create();
-
- var originalCopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, originalDocx.Name));
- if (!originalCopiedToDestDocx.Exists)
- {
- var wml1 = new WmlDocument(originalDocx.FullName);
- var wml2 = WordprocessingMLUtil.BreakLinkToTemplate(wml1);
- wml2.SaveAs(originalCopiedToDestDocx.FullName);
- }
-
- var revisedDocumentsXElement = XElement.Parse(revisedDocumentsXml);
- var revisedDocumentsArray = revisedDocumentsXElement
- .Elements()
- .Select(z =>
- {
- FileInfo revisedDocx = new FileInfo(Path.Combine(sourceDir.FullName, z.Element("DocName").Value));
- var revisedCopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, revisedDocx.Name));
- var wml1 = new WmlDocument(revisedDocx.FullName);
- var wml2 = WordprocessingMLUtil.BreakLinkToTemplate(wml1);
- wml2.SaveAs(revisedCopiedToDestDocx.FullName);
- return new WmlRevisedDocumentInfo()
- {
- RevisedDocument = new WmlDocument(revisedCopiedToDestDocx.FullName),
- Color = ColorParser.FromName(z.Element("Color")?.Value),
- Revisor = z.Element("Revisor")?.Value,
- };
- })
- .ToList();
-
- var consolidatedDocxName = originalCopiedToDestDocx.Name.Replace(".docx", "-Consolidated.docx");
- var consolidatedDocumentFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, consolidatedDocxName));
-
- WmlDocument source1Wml = new WmlDocument(originalCopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- settings.DebugTempFileDi = thisTestTempDir;
- WmlDocument consolidatedWml = WmlComparer.Consolidate(
- source1Wml,
- revisedDocumentsArray,
- settings);
- var wml3 = WordprocessingMLUtil.BreakLinkToTemplate(consolidatedWml);
- wml3.SaveAs(consolidatedDocumentFi.FullName);
-
- var validationErrors = "";
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(consolidatedWml.DocumentByteArray, 0, consolidatedWml.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() > 0)
- {
-
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
-#if true
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
-#else
- sb.Append(" \"" + err.Description + "\"," + Environment.NewLine);
-#endif
- }
- validationErrors = sb.ToString();
- }
- }
- }
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, consolidatedDocumentFi);
- WordRunner.RunWord(wordExe, originalCopiedToDestDocx);
-
- var revisedList = revisedDocumentsXElement
- .Elements()
- .Select(z =>
- {
- FileInfo revisedDocx = new FileInfo(Path.Combine(sourceDir.FullName, z.Element("DocName").Value));
- var revisedCopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, revisedDocx.Name));
- return revisedCopiedToDestDocx;
- })
- .ToList();
- foreach (var item in revisedList)
- WordRunner.RunWord(wordExe, item);
- }
-
- /************************************************************************************************************************/
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Open Windows Explorer
- if (m_OpenTempDirInExplorer)
- {
- while (true)
- {
- try
- {
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
- var semaphorFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "z_ExplorerOpenedSemaphore.txt"));
- if (!semaphorFi.Exists)
- {
- File.WriteAllText(semaphorFi.FullName, "");
- TestUtil.Explorer(thisTestTempDir);
- }
- //////////////////////////////////////////////////
- break;
- }
- catch (IOException)
- {
- System.Threading.Thread.Sleep(50);
- }
- }
- }
-
- if (validationErrors != "")
- Assert.True(false, validationErrors);
- }
-
- [Theory]
- [InlineData("WCB-1000", "CA/CA001-Plain.docx", "CA/CA001-Plain-Mod.docx")]
- [InlineData("WCB-1010", "WC/WC001-Digits.docx", "WC/WC001-Digits-Mod.docx")]
- [InlineData("WCB-1020", "WC/WC001-Digits.docx", "WC/WC001-Digits-Deleted-Paragraph.docx")]
- [InlineData("WCB-1030", "WC/WC001-Digits-Deleted-Paragraph.docx", "WC/WC001-Digits.docx")]
- [InlineData("WCB-1040", "WC/WC002-Unmodified.docx", "WC/WC002-DiffInMiddle.docx")]
- [InlineData("WCB-1050", "WC/WC002-Unmodified.docx", "WC/WC002-DiffAtBeginning.docx")]
- [InlineData("WCB-1060", "WC/WC002-Unmodified.docx", "WC/WC002-DeleteAtBeginning.docx")]
- [InlineData("WCB-1070", "WC/WC002-Unmodified.docx", "WC/WC002-InsertAtBeginning.docx")]
- [InlineData("WCB-1080", "WC/WC002-Unmodified.docx", "WC/WC002-InsertAtEnd.docx")]
- [InlineData("WCB-1090", "WC/WC002-Unmodified.docx", "WC/WC002-DeleteAtEnd.docx")]
- [InlineData("WCB-1100", "WC/WC002-Unmodified.docx", "WC/WC002-DeleteInMiddle.docx")]
- [InlineData("WCB-1110", "WC/WC002-Unmodified.docx", "WC/WC002-InsertInMiddle.docx")]
- [InlineData("WCB-1120", "WC/WC002-DeleteInMiddle.docx", "WC/WC002-Unmodified.docx")]
- //[InlineData("WCB-1130", "WC/WC004-Large.docx", "WC/WC004-Large-Mod.docx")]
- [InlineData("WCB-1140", "WC/WC006-Table.docx", "WC/WC006-Table-Delete-Row.docx")]
- [InlineData("WCB-1150", "WC/WC006-Table-Delete-Row.docx", "WC/WC006-Table.docx")]
- [InlineData("WCB-1160", "WC/WC006-Table.docx", "WC/WC006-Table-Delete-Contests-of-Row.docx")]
- [InlineData("WCB-1170", "WC/WC007-Unmodified.docx", "WC/WC007-Longest-At-End.docx")]
- [InlineData("WCB-1180", "WC/WC007-Unmodified.docx", "WC/WC007-Deleted-at-Beginning-of-Para.docx")]
- [InlineData("WCB-1190", "WC/WC007-Unmodified.docx", "WC/WC007-Moved-into-Table.docx")]
- [InlineData("WCB-1200", "WC/WC009-Table-Unmodified.docx", "WC/WC009-Table-Cell-1-1-Mod.docx")]
- [InlineData("WCB-1210", "WC/WC010-Para-Before-Table-Unmodified.docx", "WC/WC010-Para-Before-Table-Mod.docx")]
- [InlineData("WCB-1220", "WC/WC011-Before.docx", "WC/WC011-After.docx")]
- [InlineData("WCB-1230", "WC/WC012-Math-Before.docx", "WC/WC012-Math-After.docx")]
- [InlineData("WCB-1240", "WC/WC013-Image-Before.docx", "WC/WC013-Image-After.docx")]
- [InlineData("WCB-1250", "WC/WC013-Image-Before.docx", "WC/WC013-Image-After2.docx")]
- [InlineData("WCB-1260", "WC/WC013-Image-Before2.docx", "WC/WC013-Image-After2.docx")]
- [InlineData("WCB-1270", "WC/WC014-SmartArt-Before.docx", "WC/WC014-SmartArt-After.docx")]
- [InlineData("WCB-1280", "WC/WC014-SmartArt-With-Image-Before.docx", "WC/WC014-SmartArt-With-Image-After.docx")]
- [InlineData("WCB-1290", "WC/WC014-SmartArt-With-Image-Before.docx", "WC/WC014-SmartArt-With-Image-Deleted-After.docx")]
- [InlineData("WCB-1300", "WC/WC014-SmartArt-With-Image-Before.docx", "WC/WC014-SmartArt-With-Image-Deleted-After2.docx")]
- [InlineData("WCB-1310", "WC/WC015-Three-Paragraphs.docx", "WC/WC015-Three-Paragraphs-After.docx")]
- [InlineData("WCB-1320", "WC/WC016-Para-Image-Para.docx", "WC/WC016-Para-Image-Para-w-Deleted-Image.docx")]
- [InlineData("WCB-1330", "WC/WC017-Image.docx", "WC/WC017-Image-After.docx")]
- [InlineData("WCB-1340", "WC/WC018-Field-Simple-Before.docx", "WC/WC018-Field-Simple-After-1.docx")]
- [InlineData("WCB-1350", "WC/WC018-Field-Simple-Before.docx", "WC/WC018-Field-Simple-After-2.docx")]
- [InlineData("WCB-1360", "WC/WC019-Hyperlink-Before.docx", "WC/WC019-Hyperlink-After-1.docx")]
- [InlineData("WCB-1370", "WC/WC019-Hyperlink-Before.docx", "WC/WC019-Hyperlink-After-2.docx")]
- [InlineData("WCB-1380", "WC/WC020-FootNote-Before.docx", "WC/WC020-FootNote-After-1.docx")]
- [InlineData("WCB-1390", "WC/WC020-FootNote-Before.docx", "WC/WC020-FootNote-After-2.docx")]
- [InlineData("WCB-1400", "WC/WC021-Math-Before-1.docx", "WC/WC021-Math-After-1.docx")]
- [InlineData("WCB-1410", "WC/WC021-Math-Before-2.docx", "WC/WC021-Math-After-2.docx")]
- [InlineData("WCB-1420", "WC/WC022-Image-Math-Para-Before.docx", "WC/WC022-Image-Math-Para-After.docx")]
- [InlineData("WCB-1430", "WC/WC023-Table-4-Row-Image-Before.docx", "WC/WC023-Table-4-Row-Image-After-Delete-1-Row.docx")]
- [InlineData("WCB-1440", "WC/WC024-Table-Before.docx", "WC/WC024-Table-After.docx")]
- [InlineData("WCB-1450", "WC/WC024-Table-Before.docx", "WC/WC024-Table-After2.docx")]
- [InlineData("WCB-1460", "WC/WC025-Simple-Table-Before.docx", "WC/WC025-Simple-Table-After.docx")]
- [InlineData("WCB-1470", "WC/WC026-Long-Table-Before.docx", "WC/WC026-Long-Table-After-1.docx")]
- [InlineData("WCB-1480", "WC/WC027-Twenty-Paras-Before.docx", "WC/WC027-Twenty-Paras-After-1.docx")]
- [InlineData("WCB-1490", "WC/WC027-Twenty-Paras-After-1.docx", "WC/WC027-Twenty-Paras-Before.docx")]
- [InlineData("WCB-1500", "WC/WC027-Twenty-Paras-Before.docx", "WC/WC027-Twenty-Paras-After-2.docx")]
- [InlineData("WCB-1510", "WC/WC030-Image-Math-Before.docx", "WC/WC030-Image-Math-After.docx")]
- [InlineData("WCB-1520", "WC/WC031-Two-Maths-Before.docx", "WC/WC031-Two-Maths-After.docx")]
- [InlineData("WCB-1530", "WC/WC032-Para-with-Para-Props.docx", "WC/WC032-Para-with-Para-Props-After.docx")]
- [InlineData("WCB-1540", "WC/WC033-Merged-Cells-Before.docx", "WC/WC033-Merged-Cells-After1.docx")]
- [InlineData("WCB-1550", "WC/WC033-Merged-Cells-Before.docx", "WC/WC033-Merged-Cells-After2.docx")]
- [InlineData("WCB-1560", "WC/WC034-Footnotes-Before.docx", "WC/WC034-Footnotes-After1.docx")]
- [InlineData("WCB-1570", "WC/WC034-Footnotes-Before.docx", "WC/WC034-Footnotes-After2.docx")]
- [InlineData("WCB-1580", "WC/WC034-Footnotes-Before.docx", "WC/WC034-Footnotes-After3.docx")]
- [InlineData("WCB-1590", "WC/WC034-Footnotes-After3.docx", "WC/WC034-Footnotes-Before.docx")]
- [InlineData("WCB-1600", "WC/WC035-Footnote-Before.docx", "WC/WC035-Footnote-After.docx")]
- [InlineData("WCB-1610", "WC/WC035-Footnote-After.docx", "WC/WC035-Footnote-Before.docx")]
- [InlineData("WCB-1620", "WC/WC036-Footnote-With-Table-Before.docx", "WC/WC036-Footnote-With-Table-After.docx")]
- [InlineData("WCB-1630", "WC/WC036-Footnote-With-Table-After.docx", "WC/WC036-Footnote-With-Table-Before.docx")]
- [InlineData("WCB-1640", "WC/WC034-Endnotes-Before.docx", "WC/WC034-Endnotes-After1.docx")]
- [InlineData("WCB-1650", "WC/WC034-Endnotes-Before.docx", "WC/WC034-Endnotes-After2.docx")]
- [InlineData("WCB-1660", "WC/WC034-Endnotes-Before.docx", "WC/WC034-Endnotes-After3.docx")]
- [InlineData("WCB-1670", "WC/WC034-Endnotes-After3.docx", "WC/WC034-Endnotes-Before.docx")]
- [InlineData("WCB-1680", "WC/WC035-Endnote-Before.docx", "WC/WC035-Endnote-After.docx")]
- [InlineData("WCB-1690", "WC/WC035-Endnote-After.docx", "WC/WC035-Endnote-Before.docx")]
- [InlineData("WCB-1700", "WC/WC036-Endnote-With-Table-Before.docx", "WC/WC036-Endnote-With-Table-After.docx")]
- [InlineData("WCB-1710", "WC/WC036-Endnote-With-Table-After.docx", "WC/WC036-Endnote-With-Table-Before.docx")]
- [InlineData("WCB-1720", "WC/WC038-Document-With-BR-Before.docx", "WC/WC038-Document-With-BR-After.docx")]
- [InlineData("WCB-1730", "RC/RC001-Before.docx", "RC/RC001-After1.docx")]
- [InlineData("WCB-1740", "RC/RC002-Image.docx", "RC/RC002-Image-After1.docx")]
- //[InlineData("WCB-1000", "", "")]
- //[InlineData("WCB-1000", "", "")]
- //[InlineData("WCB-1000", "", "")]
- //[InlineData("WCB-1000", "", "")]
- //[InlineData("WCB-1000", "", "")]
- //[InlineData("WCB-1000", "", "")]
- //[InlineData("WCB-1000", "", "")]
-
-
- public void WC002_Consolidate_Bulk_Test(string testId, string name1, string name2)
- {
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var rootTempDir = TestUtil.TempDir;
- var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
- if (thisTestTempDir.Exists)
- Assert.True(false, "Duplicate test id: " + testId);
- else
- thisTestTempDir.Create();
-
- var source1CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name));
- var source2CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name));
- if (!source1CopiedToDestDocx.Exists)
- {
- var wml1 = new WmlDocument(source1Docx.FullName);
- var wml2 = WordprocessingMLUtil.BreakLinkToTemplate(wml1);
- wml2.SaveAs(source1CopiedToDestDocx.FullName);
- }
- if (!source2CopiedToDestDocx.Exists)
- {
- var wml1 = new WmlDocument(source2Docx.FullName);
- var wml2 = WordprocessingMLUtil.BreakLinkToTemplate(wml1);
- wml2.SaveAs(source2CopiedToDestDocx.FullName);
- }
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo source1DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocxForWord = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name.Replace(".docx", "-For-Word.docx")));
- var source2CopiedToDestDocxForWord = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name.Replace(".docx", "-For-Word.docx")));
- if (!source1CopiedToDestDocxForWord.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocxForWord.FullName);
- if (!source2CopiedToDestDocxForWord.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocxForWord.FullName);
-
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- var path = new DirectoryInfo(@"C:\Users\Eric\Documents\WindowsPowerShellModules\Open-Xml-PowerTools\TestFiles");
- WordRunner.RunWord(wordExe, source2CopiedToDestDocxForWord);
- WordRunner.RunWord(wordExe, source1CopiedToDestDocxForWord);
- }
-
- /************************************************************************************************************************/
-
- var before = source1CopiedToDestDocx.Name.Replace(".docx", "");
- var after = source2CopiedToDestDocx.Name.Replace(".docx", "");
- var docxWithRevisionsFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, before + "-COMPARE-" + after + ".docx"));
- var docxConsolidatedFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, before + "-CONSOLIDATED-" + after + ".docx"));
-
- WmlDocument source1Wml = new WmlDocument(source1CopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(source2CopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
- WordprocessingMLUtil.BreakLinkToTemplate(comparedWml).SaveAs(docxWithRevisionsFi.FullName);
-
- List revisedDocInfo = new List()
- {
- new WmlRevisedDocumentInfo()
- {
- RevisedDocument = source2Wml,
- Color = Color.LightBlue,
- Revisor = "Revised by Eric White",
- }
- };
- WmlDocument consolidatedWml = WmlComparer.Consolidate(
- source1Wml,
- revisedDocInfo,
- settings);
- WordprocessingMLUtil.BreakLinkToTemplate(consolidatedWml).SaveAs(docxConsolidatedFi.FullName);
-
- string validationErrors = "";
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(consolidatedWml.DocumentByteArray, 0, consolidatedWml.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() > 0)
- {
-
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
-#if true
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
-#else
- sb.Append(" \"" + err.Description + "\"," + Environment.NewLine);
-#endif
- }
- validationErrors = sb.ToString();
- }
- }
- }
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, docxConsolidatedFi);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Open Windows Explorer
- if (m_OpenTempDirInExplorer)
- {
- while (true)
- {
- try
- {
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
- var semaphorFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "z_ExplorerOpenedSemaphore.txt"));
- if (!semaphorFi.Exists)
- {
- File.WriteAllText(semaphorFi.FullName, "");
- TestUtil.Explorer(thisTestTempDir);
- }
- //////////////////////////////////////////////////
- break;
- }
- catch (IOException)
- {
- System.Threading.Thread.Sleep(50);
- }
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- if (validationErrors != "")
- Assert.True(false, validationErrors);
- }
-
- [Theory]
- [InlineData("WC-1000", "CA/CA001-Plain.docx", "CA/CA001-Plain-Mod.docx", 1)]
- [InlineData("WC-1010", "WC/WC001-Digits.docx", "WC/WC001-Digits-Mod.docx", 4)]
- [InlineData("WC-1020", "WC/WC001-Digits.docx", "WC/WC001-Digits-Deleted-Paragraph.docx", 1)]
- [InlineData("WC-1030", "WC/WC001-Digits-Deleted-Paragraph.docx", "WC/WC001-Digits.docx", 1)]
- [InlineData("WC-1040", "WC/WC002-Unmodified.docx", "WC/WC002-DiffInMiddle.docx", 2)]
- [InlineData("WC-1050", "WC/WC002-Unmodified.docx", "WC/WC002-DiffAtBeginning.docx", 2)]
- [InlineData("WC-1060", "WC/WC002-Unmodified.docx", "WC/WC002-DeleteAtBeginning.docx", 1)]
- [InlineData("WC-1070", "WC/WC002-Unmodified.docx", "WC/WC002-InsertAtBeginning.docx", 1)]
- [InlineData("WC-1080", "WC/WC002-Unmodified.docx", "WC/WC002-InsertAtEnd.docx", 1)]
- [InlineData("WC-1090", "WC/WC002-Unmodified.docx", "WC/WC002-DeleteAtEnd.docx", 1)]
- [InlineData("WC-1100", "WC/WC002-Unmodified.docx", "WC/WC002-DeleteInMiddle.docx", 1)]
- [InlineData("WC-1110", "WC/WC002-Unmodified.docx", "WC/WC002-InsertInMiddle.docx", 1)]
- [InlineData("WC-1120", "WC/WC002-DeleteInMiddle.docx", "WC/WC002-Unmodified.docx", 1)]
- //[InlineData("WC-1130", "WC/WC004-Large.docx", "WC/WC004-Large-Mod.docx", 2)]
- [InlineData("WC-1140", "WC/WC006-Table.docx", "WC/WC006-Table-Delete-Row.docx", 1)]
- [InlineData("WC-1150", "WC/WC006-Table-Delete-Row.docx", "WC/WC006-Table.docx", 1)]
- [InlineData("WC-1160", "WC/WC006-Table.docx", "WC/WC006-Table-Delete-Contests-of-Row.docx", 2)]
- [InlineData("WC-1170", "WC/WC007-Unmodified.docx", "WC/WC007-Longest-At-End.docx", 2)]
- [InlineData("WC-1180", "WC/WC007-Unmodified.docx", "WC/WC007-Deleted-at-Beginning-of-Para.docx", 1)]
- [InlineData("WC-1190", "WC/WC007-Unmodified.docx", "WC/WC007-Moved-into-Table.docx", 2)]
- [InlineData("WC-1200", "WC/WC009-Table-Unmodified.docx", "WC/WC009-Table-Cell-1-1-Mod.docx", 1)]
- [InlineData("WC-1210", "WC/WC010-Para-Before-Table-Unmodified.docx", "WC/WC010-Para-Before-Table-Mod.docx", 3)]
- [InlineData("WC-1220", "WC/WC011-Before.docx", "WC/WC011-After.docx", 2)]
- [InlineData("WC-1230", "WC/WC012-Math-Before.docx", "WC/WC012-Math-After.docx", 2)]
- [InlineData("WC-1240", "WC/WC013-Image-Before.docx", "WC/WC013-Image-After.docx", 2)]
- [InlineData("WC-1250", "WC/WC013-Image-Before.docx", "WC/WC013-Image-After2.docx", 2)]
- [InlineData("WC-1260", "WC/WC013-Image-Before2.docx", "WC/WC013-Image-After2.docx", 2)]
- [InlineData("WC-1270", "WC/WC014-SmartArt-Before.docx", "WC/WC014-SmartArt-After.docx", 2)]
- [InlineData("WC-1280", "WC/WC014-SmartArt-With-Image-Before.docx", "WC/WC014-SmartArt-With-Image-After.docx", 2)]
- [InlineData("WC-1310", "WC/WC014-SmartArt-With-Image-Before.docx", "WC/WC014-SmartArt-With-Image-Deleted-After.docx", 3)]
- [InlineData("WC-1320", "WC/WC014-SmartArt-With-Image-Before.docx", "WC/WC014-SmartArt-With-Image-Deleted-After2.docx", 1)]
- [InlineData("WC-1330", "WC/WC015-Three-Paragraphs.docx", "WC/WC015-Three-Paragraphs-After.docx", 3)]
- [InlineData("WC-1340", "WC/WC016-Para-Image-Para.docx", "WC/WC016-Para-Image-Para-w-Deleted-Image.docx", 1)]
- [InlineData("WC-1350", "WC/WC017-Image.docx", "WC/WC017-Image-After.docx", 3)]
- [InlineData("WC-1360", "WC/WC018-Field-Simple-Before.docx", "WC/WC018-Field-Simple-After-1.docx", 2)]
- [InlineData("WC-1370", "WC/WC018-Field-Simple-Before.docx", "WC/WC018-Field-Simple-After-2.docx", 3)]
- [InlineData("WC-1380", "WC/WC019-Hyperlink-Before.docx", "WC/WC019-Hyperlink-After-1.docx", 3)]
- [InlineData("WC-1390", "WC/WC019-Hyperlink-Before.docx", "WC/WC019-Hyperlink-After-2.docx", 5)]
- [InlineData("WC-1400", "WC/WC020-FootNote-Before.docx", "WC/WC020-FootNote-After-1.docx", 3)]
- [InlineData("WC-1410", "WC/WC020-FootNote-Before.docx", "WC/WC020-FootNote-After-2.docx", 5)]
- [InlineData("WC-1420", "WC/WC021-Math-Before-1.docx", "WC/WC021-Math-After-1.docx", 9)]
- [InlineData("WC-1430", "WC/WC021-Math-Before-2.docx", "WC/WC021-Math-After-2.docx", 6)]
- [InlineData("WC-1440", "WC/WC022-Image-Math-Para-Before.docx", "WC/WC022-Image-Math-Para-After.docx", 10)]
- [InlineData("WC-1450", "WC/WC023-Table-4-Row-Image-Before.docx", "WC/WC023-Table-4-Row-Image-After-Delete-1-Row.docx", 7)]
- [InlineData("WC-1460", "WC/WC024-Table-Before.docx", "WC/WC024-Table-After.docx", 1)]
- [InlineData("WC-1470", "WC/WC024-Table-Before.docx", "WC/WC024-Table-After2.docx", 7)]
- [InlineData("WC-1480", "WC/WC025-Simple-Table-Before.docx", "WC/WC025-Simple-Table-After.docx", 4)]
- [InlineData("WC-1500", "WC/WC026-Long-Table-Before.docx", "WC/WC026-Long-Table-After-1.docx", 2)]
- [InlineData("WC-1510", "WC/WC027-Twenty-Paras-Before.docx", "WC/WC027-Twenty-Paras-After-1.docx", 2)]
- [InlineData("WC-1520", "WC/WC027-Twenty-Paras-After-1.docx", "WC/WC027-Twenty-Paras-Before.docx", 2)]
- [InlineData("WC-1530", "WC/WC027-Twenty-Paras-Before.docx", "WC/WC027-Twenty-Paras-After-2.docx", 4)]
- [InlineData("WC-1540", "WC/WC030-Image-Math-Before.docx", "WC/WC030-Image-Math-After.docx", 2)]
- [InlineData("WC-1550", "WC/WC031-Two-Maths-Before.docx", "WC/WC031-Two-Maths-After.docx", 4)]
- [InlineData("WC-1560", "WC/WC032-Para-with-Para-Props.docx", "WC/WC032-Para-with-Para-Props-After.docx", 3)]
- [InlineData("WC-1570", "WC/WC033-Merged-Cells-Before.docx", "WC/WC033-Merged-Cells-After1.docx", 2)]
- [InlineData("WC-1580", "WC/WC033-Merged-Cells-Before.docx", "WC/WC033-Merged-Cells-After2.docx", 4)]
- [InlineData("WC-1600", "WC/WC034-Footnotes-Before.docx", "WC/WC034-Footnotes-After1.docx", 1)]
- [InlineData("WC-1610", "WC/WC034-Footnotes-Before.docx", "WC/WC034-Footnotes-After2.docx", 4)]
- [InlineData("WC-1620", "WC/WC034-Footnotes-Before.docx", "WC/WC034-Footnotes-After3.docx", 3)]
- [InlineData("WC-1630", "WC/WC034-Footnotes-After3.docx", "WC/WC034-Footnotes-Before.docx", 3)]
- [InlineData("WC-1640", "WC/WC035-Footnote-Before.docx", "WC/WC035-Footnote-After.docx", 2)]
- [InlineData("WC-1650", "WC/WC035-Footnote-After.docx", "WC/WC035-Footnote-Before.docx", 2)]
- [InlineData("WC-1660", "WC/WC036-Footnote-With-Table-Before.docx", "WC/WC036-Footnote-With-Table-After.docx", 5)]
- [InlineData("WC-1670", "WC/WC036-Footnote-With-Table-After.docx", "WC/WC036-Footnote-With-Table-Before.docx", 5)]
- [InlineData("WC-1680", "WC/WC034-Endnotes-Before.docx", "WC/WC034-Endnotes-After1.docx", 1)]
- [InlineData("WC-1700", "WC/WC034-Endnotes-Before.docx", "WC/WC034-Endnotes-After2.docx", 4)]
- [InlineData("WC-1710", "WC/WC034-Endnotes-Before.docx", "WC/WC034-Endnotes-After3.docx", 7)]
- [InlineData("WC-1720", "WC/WC034-Endnotes-After3.docx", "WC/WC034-Endnotes-Before.docx", 7)]
- [InlineData("WC-1730", "WC/WC035-Endnote-Before.docx", "WC/WC035-Endnote-After.docx", 2)]
- [InlineData("WC-1740", "WC/WC035-Endnote-After.docx", "WC/WC035-Endnote-Before.docx", 2)]
- [InlineData("WC-1750", "WC/WC036-Endnote-With-Table-Before.docx", "WC/WC036-Endnote-With-Table-After.docx", 6)]
- [InlineData("WC-1760", "WC/WC036-Endnote-With-Table-After.docx", "WC/WC036-Endnote-With-Table-Before.docx", 6)]
- [InlineData("WC-1770", "WC/WC037-Textbox-Before.docx", "WC/WC037-Textbox-After1.docx", 2)]
- [InlineData("WC-1780", "WC/WC038-Document-With-BR-Before.docx", "WC/WC038-Document-With-BR-After.docx", 2)]
- [InlineData("WC-1800", "RC/RC001-Before.docx", "RC/RC001-After1.docx", 2)]
- [InlineData("WC-1810", "RC/RC002-Image.docx", "RC/RC002-Image-After1.docx", 1)]
- [InlineData("WC-1820", "WC/WC039-Break-In-Row.docx", "WC/WC039-Break-In-Row-After1.docx", 1)]
- [InlineData("WC-1830", "WC/WC041-Table-5.docx", "WC/WC041-Table-5-Mod.docx", 2)]
- [InlineData("WC-1840", "WC/WC042-Table-5.docx", "WC/WC042-Table-5-Mod.docx", 2)]
- [InlineData("WC-1850", "WC/WC043-Nested-Table.docx", "WC/WC043-Nested-Table-Mod.docx", 2)]
- [InlineData("WC-1860", "WC/WC044-Text-Box.docx", "WC/WC044-Text-Box-Mod.docx", 2)]
- [InlineData("WC-1870", "WC/WC045-Text-Box.docx", "WC/WC045-Text-Box-Mod.docx", 2)]
- [InlineData("WC-1880", "WC/WC046-Two-Text-Box.docx", "WC/WC046-Two-Text-Box-Mod.docx", 2)]
- [InlineData("WC-1890", "WC/WC047-Two-Text-Box.docx", "WC/WC047-Two-Text-Box-Mod.docx", 2)]
- [InlineData("WC-1900", "WC/WC048-Text-Box-in-Cell.docx", "WC/WC048-Text-Box-in-Cell-Mod.docx", 6)]
- [InlineData("WC-1910", "WC/WC049-Text-Box-in-Cell.docx", "WC/WC049-Text-Box-in-Cell-Mod.docx", 5)]
- [InlineData("WC-1920", "WC/WC050-Table-in-Text-Box.docx", "WC/WC050-Table-in-Text-Box-Mod.docx", 8)]
- [InlineData("WC-1930", "WC/WC051-Table-in-Text-Box.docx", "WC/WC051-Table-in-Text-Box-Mod.docx", 9)]
- [InlineData("WC-1940", "WC/WC052-SmartArt-Same.docx", "WC/WC052-SmartArt-Same-Mod.docx", 2)]
- [InlineData("WC-1950", "WC/WC053-Text-in-Cell.docx", "WC/WC053-Text-in-Cell-Mod.docx", 2)]
- [InlineData("WC-1960", "WC/WC054-Text-in-Cell.docx", "WC/WC054-Text-in-Cell-Mod.docx", 0)]
- [InlineData("WC-1970", "WC/WC055-French.docx", "WC/WC055-French-Mod.docx", 0)]
- [InlineData("WC-1980", "WC/WC056-French.docx", "WC/WC056-French-Mod.docx", 0)]
- [InlineData("WC-1990", "WC/WC057-Table-Merged-Cell.docx", "WC/WC057-Table-Merged-Cell-Mod.docx", 4)]
- [InlineData("WC-2000", "WC/WC058-Table-Merged-Cell.docx", "WC/WC058-Table-Merged-Cell-Mod.docx", 6)]
- [InlineData("WC-2010", "WC/WC059-Footnote.docx", "WC/WC059-Footnote-Mod.docx", 5)]
- [InlineData("WC-2020", "WC/WC060-Endnote.docx", "WC/WC060-Endnote-Mod.docx", 3)]
- [InlineData("WC-2030", "WC/WC061-Style-Added.docx", "WC/WC061-Style-Added-Mod.docx", 1)]
- [InlineData("WC-2040", "WC/WC062-New-Char-Style-Added.docx", "WC/WC062-New-Char-Style-Added-Mod.docx", 2)]
- [InlineData("WC-2050", "WC/WC063-Footnote.docx", "WC/WC063-Footnote-Mod.docx", 1)]
- [InlineData("WC-2060", "WC/WC063-Footnote-Mod.docx", "WC/WC063-Footnote.docx", 1)]
- [InlineData("WC-2070", "WC/WC064-Footnote.docx", "WC/WC064-Footnote-Mod.docx", 0)]
- [InlineData("WC-2080", "WC/WC065-Textbox.docx", "WC/WC065-Textbox-Mod.docx", 2)]
- [InlineData("WC-2090", "WC/WC066-Textbox-Before-Ins.docx", "WC/WC066-Textbox-Before-Ins-Mod.docx", 1)]
- [InlineData("WC-2092", "WC/WC066-Textbox-Before-Ins-Mod.docx", "WC/WC066-Textbox-Before-Ins.docx", 1)]
- [InlineData("WC-2100", "WC/WC067-Textbox-Image.docx", "WC/WC067-Textbox-Image-Mod.docx", 2)]
- //[InlineData("WC-1000", "", "", 0)]
- //[InlineData("WC-1000", "", "", 0)]
- //[InlineData("WC-1000", "", "", 0)]
- //[InlineData("WC-1000", "", "", 0)]
- //[InlineData("WC-1000", "", "", 0)]
- //[InlineData("WC-1000", "", "", 0)]
-
- public void WC003_Compare(string testId, string name1, string name2, int revisionCount)
- {
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var rootTempDir = TestUtil.TempDir;
- var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
- if (thisTestTempDir.Exists)
- Assert.True(false, "Duplicate test id???");
- else
- thisTestTempDir.Create();
-
- var source1CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name));
- var source2CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name));
- File.Copy(source1Docx.FullName, source1CopiedToDestDocx.FullName);
- File.Copy(source2Docx.FullName, source2CopiedToDestDocx.FullName);
-
- var before = source1CopiedToDestDocx.Name.Replace(".docx", "");
- var after = source2CopiedToDestDocx.Name.Replace(".docx", "");
- //var baselineDocxWithRevisionsFi = new FileInfo(Path.Combine(source1Docx.DirectoryName, before + "-COMPARE-" + after + ".docx"));
- var docxWithRevisionsFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, before + "-COMPARE-" + after + ".docx"));
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo source1DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocxForWord = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name.Replace(".docx", "-For-Word.docx")));
- var source2CopiedToDestDocxForWord = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name.Replace(".docx", "-For-Word.docx")));
- File.Copy(source1Docx.FullName, source1CopiedToDestDocxForWord.FullName);
- File.Copy(source2Docx.FullName, source2CopiedToDestDocxForWord.FullName);
-
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- var path = new DirectoryInfo(@"C:\Users\Eric\Documents\WindowsPowerShellModules\Open-Xml-PowerTools\TestFiles");
- WordRunner.RunWord(wordExe, source2CopiedToDestDocxForWord);
- WordRunner.RunWord(wordExe, source1CopiedToDestDocxForWord);
- }
-
- /************************************************************************************************************************/
-
- WmlDocument source1Wml = new WmlDocument(source1CopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(source2CopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- settings.DebugTempFileDi = thisTestTempDir;
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
- comparedWml.SaveAs(docxWithRevisionsFi.FullName);
-
-#if false
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // create batch file to copy newly generated ContentTypeXml and NarrDoc to the TestFiles directory.
- while (true)
- {
- try
- {
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
- var batchFileName = "Copy-Gen-Files-To-TestFiles.bat";
- var batchFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, batchFileName));
- var batch = "";
- batch += "copy " + docxWithRevisionsFi.FullName + " " + source1Docx.DirectoryName + Environment.NewLine;
- if (batchFi.Exists)
- File.AppendAllText(batchFi.FullName, batch);
- else
- File.WriteAllText(batchFi.FullName, batch);
- //////////////////////////////////////////////////
- break;
- }
- catch (IOException)
- {
- System.Threading.Thread.Sleep(50);
- }
- }
-#endif
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // validate generated document
- var validationErrors = "";
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(comparedWml.DocumentByteArray, 0, comparedWml.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() > 0)
- {
-
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
-#if true
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
-#else
- sb.Append(" \"" + err.Description + "\"," + Environment.NewLine);
-#endif
- }
- validationErrors = sb.ToString();
- }
- }
- }
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, docxWithRevisionsFi);
- }
-
- /************************************************************************************************************************/
-
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Open Windows Explorer
- if (m_OpenTempDirInExplorer)
- {
- while (true)
- {
- try
- {
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
- var semaphorFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "z_ExplorerOpenedSemaphore.txt"));
- if (!semaphorFi.Exists)
- {
- File.WriteAllText(semaphorFi.FullName, "");
- TestUtil.Explorer(thisTestTempDir);
- }
- //////////////////////////////////////////////////
- break;
- }
- catch (IOException)
- {
- System.Threading.Thread.Sleep(50);
- }
- }
- }
-
- if (validationErrors != "")
- {
- Assert.True(false, validationErrors);
- }
-
- WmlComparerSettings settings2 = new WmlComparerSettings();
-
- WmlDocument revisionWml = new WmlDocument(docxWithRevisionsFi.FullName);
- var revisions = WmlComparer.GetRevisions(revisionWml, settings);
- Assert.Equal(revisionCount, revisions.Count());
-
- var afterRejectingWml = RevisionProcessor.RejectRevisions(revisionWml);
-
- var WRITE_TEMP_FILES = true;
-
- if (WRITE_TEMP_FILES)
- {
- var afterRejectingFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, "AfterRejecting.docx"));
- afterRejectingWml.SaveAs(afterRejectingFi.FullName);
- }
-
- WmlDocument afterRejectingComparedWml = WmlComparer.Compare(source1Wml, afterRejectingWml, settings);
- var sanityCheck1 = WmlComparer.GetRevisions(afterRejectingComparedWml, settings);
-
- if (WRITE_TEMP_FILES)
- {
- var afterRejectingComparedFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, "AfterRejectingCompared.docx"));
- afterRejectingComparedWml.SaveAs(afterRejectingComparedFi.FullName);
- }
-
- var afterAcceptingWml = RevisionProcessor.AcceptRevisions(revisionWml);
-
- if (WRITE_TEMP_FILES)
- {
- var afterAcceptingFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, "AfterAccepting.docx"));
- afterAcceptingWml.SaveAs(afterAcceptingFi.FullName);
- }
-
- WmlDocument afterAcceptingComparedWml = WmlComparer.Compare(source2Wml, afterAcceptingWml, settings);
- var sanityCheck2 = WmlComparer.GetRevisions(afterAcceptingComparedWml, settings);
-
- if (WRITE_TEMP_FILES)
- {
- var afterAcceptingComparedFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, "AfterAcceptingCompared.docx"));
- afterAcceptingComparedWml.SaveAs(afterAcceptingComparedFi.FullName);
- }
-
- if (sanityCheck1.Count() != 0)
- Assert.True(false, "Sanity Check #1 failed");
- if (sanityCheck2.Count() != 0)
- Assert.True(false, "Sanity Check #2 failed");
- }
-
-#if false
- [Theory]
- [InlineData("WC/WC037-Textbox-Before.docx", "WC/WC037-Textbox-After1.docx", 2)]
-
- public void WC003_Throws(string name1, string name2, int revisionCount)
- {
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source1Docx.Name));
- var source2CopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source2Docx.Name));
- if (!source1CopiedToDestDocx.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocx.FullName);
- if (!source2CopiedToDestDocx.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocx.FullName);
-
- WmlDocument source1Wml = new WmlDocument(source1CopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(source2CopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- Assert.Throws(() =>
- {
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
- });
- }
-#endif
-
- [Theory]
- [InlineData("WCS-1000", "WC/WC001-Digits.docx")]
- [InlineData("WCS-1010", "WC/WC001-Digits-Deleted-Paragraph.docx")]
- [InlineData("WCS-1020", "WC/WC001-Digits-Mod.docx")]
- [InlineData("WCS-1030", "WC/WC002-DeleteAtBeginning.docx")]
- [InlineData("WCS-1040", "WC/WC002-DeleteAtEnd.docx")]
- [InlineData("WCS-1050", "WC/WC002-DeleteInMiddle.docx")]
- [InlineData("WCS-1060", "WC/WC002-DiffAtBeginning.docx")]
- [InlineData("WCS-1070", "WC/WC002-DiffInMiddle.docx")]
- [InlineData("WCS-1080", "WC/WC002-InsertAtBeginning.docx")]
- [InlineData("WCS-1090", "WC/WC002-InsertAtEnd.docx")]
- [InlineData("WCS-1100", "WC/WC002-InsertInMiddle.docx")]
- [InlineData("WCS-1110", "WC/WC002-Unmodified.docx")]
- //[InlineData("WCS-1120", "WC/WC004-Large.docx")]
- //[InlineData("WCS-1130", "WC/WC004-Large-Mod.docx")]
- [InlineData("WCS-1140", "WC/WC006-Table.docx")]
- [InlineData("WCS-1150", "WC/WC006-Table-Delete-Contests-of-Row.docx")]
- [InlineData("WCS-1160", "WC/WC006-Table-Delete-Row.docx")]
- [InlineData("WCS-1170", "WC/WC007-Deleted-at-Beginning-of-Para.docx")]
- [InlineData("WCS-1180", "WC/WC007-Longest-At-End.docx")]
- [InlineData("WCS-1190", "WC/WC007-Moved-into-Table.docx")]
- [InlineData("WCS-1200", "WC/WC007-Unmodified.docx")]
- [InlineData("WCS-1210", "WC/WC009-Table-Cell-1-1-Mod.docx")]
- [InlineData("WCS-1220", "WC/WC009-Table-Unmodified.docx")]
- [InlineData("WCS-1230", "WC/WC010-Para-Before-Table-Mod.docx")]
- [InlineData("WCS-1240", "WC/WC010-Para-Before-Table-Unmodified.docx")]
- [InlineData("WCS-1250", "WC/WC011-After.docx")]
- [InlineData("WCS-1260", "WC/WC011-Before.docx")]
- [InlineData("WCS-1270", "WC/WC012-Math-After.docx")]
- [InlineData("WCS-1280", "WC/WC012-Math-Before.docx")]
- [InlineData("WCS-1290", "WC/WC013-Image-After.docx")]
- [InlineData("WCS-1300", "WC/WC013-Image-After2.docx")]
- [InlineData("WCS-1310", "WC/WC013-Image-Before.docx")]
- [InlineData("WCS-1320", "WC/WC013-Image-Before2.docx")]
- [InlineData("WCS-1330", "WC/WC014-SmartArt-After.docx")]
- [InlineData("WCS-1340", "WC/WC014-SmartArt-Before.docx")]
- [InlineData("WCS-1350", "WC/WC014-SmartArt-With-Image-After.docx")]
- [InlineData("WCS-1360", "WC/WC014-SmartArt-With-Image-Before.docx")]
- [InlineData("WCS-1370", "WC/WC014-SmartArt-With-Image-Deleted-After.docx")]
- [InlineData("WCS-1380", "WC/WC014-SmartArt-With-Image-Deleted-After2.docx")]
- [InlineData("WCS-1390", "WC/WC015-Three-Paragraphs.docx")]
- [InlineData("WCS-1400", "WC/WC015-Three-Paragraphs-After.docx")]
- [InlineData("WCS-1410", "WC/WC016-Para-Image-Para.docx")]
- [InlineData("WCS-1420", "WC/WC016-Para-Image-Para-w-Deleted-Image.docx")]
- [InlineData("WCS-1430", "WC/WC017-Image.docx")]
- [InlineData("WCS-1440", "WC/WC017-Image-After.docx")]
- [InlineData("WCS-1450", "WC/WC018-Field-Simple-After-1.docx")]
- [InlineData("WCS-1460", "WC/WC018-Field-Simple-After-2.docx")]
- [InlineData("WCS-1470", "WC/WC018-Field-Simple-Before.docx")]
- [InlineData("WCS-1480", "WC/WC019-Hyperlink-After-1.docx")]
- [InlineData("WCS-1490", "WC/WC019-Hyperlink-After-2.docx")]
- [InlineData("WCS-1500", "WC/WC019-Hyperlink-Before.docx")]
- [InlineData("WCS-1510", "WC/WC020-FootNote-After-1.docx")]
- [InlineData("WCS-1520", "WC/WC020-FootNote-After-2.docx")]
- [InlineData("WCS-1530", "WC/WC020-FootNote-Before.docx")]
- [InlineData("WCS-1540", "WC/WC021-Math-After-1.docx")]
- [InlineData("WCS-1550", "WC/WC021-Math-Before-1.docx")]
- [InlineData("WCS-1560", "WC/WC022-Image-Math-Para-After.docx")]
- [InlineData("WCS-1570", "WC/WC022-Image-Math-Para-Before.docx")]
- //[InlineData("WCS-1580", "", "")]
- //[InlineData("WCS-1590", "", "")]
- //[InlineData("WCS-1600", "", "")]
- //[InlineData("WCS-1610", "", "")]
-
- public void WC004_Compare_To_Self(string testId, string name)
- {
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
-
- var rootTempDir = TestUtil.TempDir;
- var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
- if (thisTestTempDir.Exists)
- Assert.True(false, "Duplicate test id???");
- else
- thisTestTempDir.Create();
-
- var sourceCopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, sourceDocx.Name.Replace(".docx", "-Source.docx")));
- if (!sourceCopiedToDestDocx.Exists)
- File.Copy(sourceDocx.FullName, sourceCopiedToDestDocx.FullName);
-
- var before = sourceCopiedToDestDocx.Name.Replace(".docx", "");
- var docxComparedFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, before + "-COMPARE" + ".docx"));
- var docxCompared2Fi = new FileInfo(Path.Combine(thisTestTempDir.FullName, before + "-COMPARE2" + ".docx"));
-
- WmlDocument source1Wml = new WmlDocument(sourceCopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(sourceCopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
-
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
- comparedWml.SaveAs(docxComparedFi.FullName);
- ValidateDocument(comparedWml);
-
- WmlDocument comparedWml2 = WmlComparer.Compare(comparedWml, source1Wml, settings);
- comparedWml2.SaveAs(docxCompared2Fi.FullName);
- ValidateDocument(comparedWml2);
- }
-
- [Theory]
- [InlineData("WCI-1000", "WC/WC040-Case-Before.docx", "WC/WC040-Case-After.docx", 2)]
-
- public void WC005_Compare_CaseInsensitive(string testId, string name1, string name2, int revisionCount)
- {
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var rootTempDir = TestUtil.TempDir;
- var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
- if (thisTestTempDir.Exists)
- Assert.True(false, "Duplicate test id???");
- else
- thisTestTempDir.Create();
-
- var source1CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name));
- var source2CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name));
- if (!source1CopiedToDestDocx.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocx.FullName);
- if (!source2CopiedToDestDocx.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocx.FullName);
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo source1DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocxForWord = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name.Replace(".docx", "-For-Word.docx")));
- var source2CopiedToDestDocxForWord = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name.Replace(".docx", "-For-Word.docx")));
- if (!source1CopiedToDestDocxForWord.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocxForWord.FullName);
- if (!source2CopiedToDestDocxForWord.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocxForWord.FullName);
-
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- var path = new DirectoryInfo(@"C:\Users\Eric\Documents\WindowsPowerShellModules\Open-Xml-PowerTools\TestFiles");
- WordRunner.RunWord(wordExe, source2CopiedToDestDocxForWord);
- WordRunner.RunWord(wordExe, source1CopiedToDestDocxForWord);
- }
-
- /************************************************************************************************************************/
-
- var before = source1CopiedToDestDocx.Name.Replace(".docx", "");
- var after = source2CopiedToDestDocx.Name.Replace(".docx", "");
- var docxWithRevisionsFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, before + "-COMPARE-" + after + ".docx"));
-
- WmlDocument source1Wml = new WmlDocument(source1CopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(source2CopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- settings.CaseInsensitive = true;
- settings.CultureInfo = System.Globalization.CultureInfo.CurrentCulture;
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
- comparedWml.SaveAs(docxWithRevisionsFi.FullName);
-
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(comparedWml.DocumentByteArray, 0, comparedWml.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() > 0)
- {
-
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
-#if true
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
-#else
- sb.Append(" \"" + err.Description + "\"," + Environment.NewLine);
-#endif
- }
- var sbs = sb.ToString();
- Assert.Equal("", sbs);
- }
- }
- }
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, docxWithRevisionsFi);
- }
-
- /************************************************************************************************************************/
-
- WmlDocument revisionWml = new WmlDocument(docxWithRevisionsFi.FullName);
- var revisions = WmlComparer.GetRevisions(revisionWml, settings);
- Assert.Equal(revisionCount, revisions.Count());
- }
-
- private static void ValidateDocument(WmlDocument wmlToValidate)
- {
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(wmlToValidate.DocumentByteArray, 0, wmlToValidate.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() != 0)
- {
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
-#if true
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
-#else
- sb.Append(" \"" + err.Description + "\"," + Environment.NewLine);
-#endif
-
- }
- var sbs = sb.ToString();
- Assert.Equal("", sbs);
- }
- }
- }
- }
-
- public static string[] ExpectedErrors = new string[] {
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:firstRow' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:lastRow' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:firstColumn' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:lastColumn' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:noHBand' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:noVBand' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:allStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:customStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:latentStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:stylesInUse' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:headingStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:numberingStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:tableStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:directFormattingOnRuns' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:directFormattingOnParagraphs' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:directFormattingOnNumbering' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:directFormattingOnTables' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:clearFormatting' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:top3HeadingStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:visibleStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:alternateStyleNames' attribute is not declared.",
- "The attribute 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:val' has invalid value '0'. The MinInclusive constraint failed. The value must be greater than or equal to 1.",
- "The attribute 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:val' has invalid value '0'. The MinInclusive constraint failed. The value must be greater than or equal to 2.",
- "The 'urn:schemas-microsoft-com:office:office:gfxdata' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:fill' attribute is invalid - The value '0' is not valid according to any of the memberTypes of the union.",
- };
-
- }
-
- public class WordRunner
- {
- public static void RunWord(FileInfo executablePath, FileInfo docxPath)
- {
- if (executablePath.Exists)
- {
- using (Process proc = new Process())
- {
- proc.StartInfo.FileName = executablePath.FullName;
- proc.StartInfo.Arguments = docxPath.FullName;
- proc.StartInfo.WorkingDirectory = docxPath.DirectoryName;
- proc.StartInfo.UseShellExecute = false;
- proc.StartInfo.RedirectStandardOutput = true;
- proc.StartInfo.RedirectStandardError = true;
- proc.Start();
- }
- }
- else
- {
- throw new ArgumentException("Invalid executable path.", "executablePath");
- }
- }
- }
-}
-
-#endif
diff --git a/OpenXmlPowerTools.Tests/WmlComparerTests2.cs b/OpenXmlPowerTools.Tests/WmlComparerTests2.cs
deleted file mode 100644
index 69ad2a52..00000000
--- a/OpenXmlPowerTools.Tests/WmlComparerTests2.cs
+++ /dev/null
@@ -1,988 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using DocumentFormat.OpenXml.Validation;
-using OpenXmlPowerTools;
-using Xunit;
-using System.Diagnostics;
-
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
-{
- public class WcTests2
- {
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- public static bool m_OpenWord = false;
- public static bool m_OpenTempDirInExplorer = false;
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- [Theory]
- [InlineData("CZ-1000", "CZ/CZ001-Plain.docx", "CZ/CZ001-Plain-Mod.docx", 1)]
- [InlineData("CZ-1010", "CZ/CZ002-Multi-Paragraphs.docx", "CZ/CZ002-Multi-Paragraphs-Mod.docx", 1)]
- [InlineData("CZ-1020", "CZ/CZ003-Multi-Paragraphs.docx", "CZ/CZ003-Multi-Paragraphs-Mod.docx", 1)]
- [InlineData("CZ-1030", "CZ/CZ004-Multi-Paragraphs-in-Cell.docx", "CZ/CZ004-Multi-Paragraphs-in-Cell-Mod.docx", 1)]
- public void CZ001_CompareTrackedInPrev(string testId, string name1, string name2, int revisionCount)
- {
- // TODO: Do we need to keep the revision count parameter?
- Assert.Equal(1, revisionCount);
-
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var rootTempDir = TestUtil.TempDir;
- var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
- if (thisTestTempDir.Exists)
- Assert.True(false, "Duplicate test id???");
- else
- thisTestTempDir.Create();
- var source1CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name));
- var source2CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name));
- File.Copy(source1Docx.FullName, source1CopiedToDestDocx.FullName);
- File.Copy(source2Docx.FullName, source2CopiedToDestDocx.FullName);
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- if (m_OpenWord)
- {
- FileInfo source1DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocxForWord = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name.Replace(".docx", "-For-Word.docx")));
- var source2CopiedToDestDocxForWord = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name.Replace(".docx", "-For-Word.docx")));
- if (!source1CopiedToDestDocxForWord.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocxForWord.FullName);
- if (!source2CopiedToDestDocxForWord.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocxForWord.FullName);
-
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, source2CopiedToDestDocxForWord);
- WordRunner.RunWord(wordExe, source1CopiedToDestDocxForWord);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- var before = source1CopiedToDestDocx.Name.Replace(".docx", "");
- var after = source2CopiedToDestDocx.Name.Replace(".docx", "");
- var docxWithRevisionsFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, before + "-COMPARE-" + after + ".docx"));
-
- WmlDocument source1Wml = new WmlDocument(source1CopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(source2CopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- settings.DebugTempFileDi = thisTestTempDir;
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
-
- ///////////////////////////
- comparedWml.SaveAs(docxWithRevisionsFi.FullName);
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(comparedWml.DocumentByteArray, 0, comparedWml.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() > 0)
- {
-
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
- }
- var sbs = sb.ToString();
- if (sbs != "")
- Assert.True(false, sbs.ToString());
- }
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- if (m_OpenWord)
- {
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, docxWithRevisionsFi);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Open Windows Explorer
- if (m_OpenTempDirInExplorer)
- {
- while (true)
- {
- try
- {
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
- var semaphorFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "z_ExplorerOpenedSemaphore.txt"));
- if (!semaphorFi.Exists)
- {
- File.WriteAllText(semaphorFi.FullName, "");
- TestUtil.Explorer(thisTestTempDir);
- }
- //////////////////////////////////////////////////
- break;
- }
- catch (IOException)
- {
- System.Threading.Thread.Sleep(50);
- }
- }
- }
-#if false
- WmlDocument revisionWml = new WmlDocument(docxWithRevisionsFi.FullName);
- var revisions = WmlComparer.GetRevisions(revisionWml, settings);
- Assert.Equal(revisionCount, revisions.Count());
-#endif
- }
-
-#if false
- [Theory]
- [InlineData("CZ-2000", "CA001-Plain.docx", "CA001-Plain-Mod.docx", 1)]
- [InlineData("CZ-2010", "WC001-Digits.docx", "WC001-Digits-Mod.docx", 4)]
- [InlineData("CZ-2020", "WC001-Digits.docx", "WC001-Digits-Deleted-Paragraph.docx", 1)]
- [InlineData("CZ-2030", "WC001-Digits-Deleted-Paragraph.docx", "WC001-Digits.docx", 1)]
- [InlineData("CZ-2040", "WC002-Unmodified.docx", "WC002-DiffInMiddle.docx", 2)]
- [InlineData("CZ-2050", "WC002-Unmodified.docx", "WC002-DiffAtBeginning.docx", 2)]
- [InlineData("CZ-2060", "WC002-Unmodified.docx", "WC002-DeleteAtBeginning.docx", 1)]
- [InlineData("CZ-2070", "WC002-Unmodified.docx", "WC002-InsertAtBeginning.docx", 1)]
- [InlineData("CZ-2080", "WC002-Unmodified.docx", "WC002-InsertAtEnd.docx", 1)]
- [InlineData("CZ-2080", "WC002-Unmodified.docx", "WC002-DeleteAtEnd.docx", 1)]
- [InlineData("CZ-2100", "WC002-Unmodified.docx", "WC002-DeleteInMiddle.docx", 1)]
- [InlineData("CZ-2110", "WC002-Unmodified.docx", "WC002-InsertInMiddle.docx", 1)]
- [InlineData("CZ-2120", "WC002-DeleteInMiddle.docx", "WC002-Unmodified.docx", 1)]
- //[InlineData("CZ-2130", "WC004-Large.docx", "WC004-Large-Mod.docx", 2)]
- [InlineData("CZ-2140", "WC006-Table.docx", "WC006-Table-Delete-Row.docx", 1)]
- [InlineData("CZ-2150", "WC006-Table-Delete-Row.docx", "WC006-Table.docx", 1)]
- [InlineData("CZ-2160", "WC006-Table.docx", "WC006-Table-Delete-Contests-of-Row.docx", 2)]
- [InlineData("CZ-2170", "WC007-Unmodified.docx", "WC007-Longest-At-End.docx", 2)]
- [InlineData("CZ-2180", "WC007-Unmodified.docx", "WC007-Deleted-at-Beginning-of-Para.docx", 2)]
- [InlineData("CZ-2200", "WC007-Unmodified.docx", "WC007-Moved-into-Table.docx", 2)]
- [InlineData("CZ-2210", "WC009-Table-Unmodified.docx", "WC009-Table-Cell-1-1-Mod.docx", 1)]
- [InlineData("CZ-2220", "WC010-Para-Before-Table-Unmodified.docx", "WC010-Para-Before-Table-Mod.docx", 3)]
- [InlineData("CZ-2230", "WC011-Before.docx", "WC011-After.docx", 2)]
- [InlineData("CZ-2240", "WC012-Math-Before.docx", "WC012-Math-After.docx", 2)]
- [InlineData("CZ-2250", "WC013-Image-Before.docx", "WC013-Image-After.docx", 2)]
- [InlineData("CZ-2260", "WC013-Image-Before.docx", "WC013-Image-After2.docx", 2)]
- [InlineData("CZ-2270", "WC013-Image-Before2.docx", "WC013-Image-After2.docx", 2)]
- [InlineData("CZ-2280", "WC014-SmartArt-Before.docx", "WC014-SmartArt-After.docx", 2)]
- [InlineData("CZ-2300", "WC014-SmartArt-With-Image-Before.docx", "WC014-SmartArt-With-Image-After.docx", 2)]
- [InlineData("CZ-2310", "WC014-SmartArt-With-Image-Before.docx", "WC014-SmartArt-With-Image-Deleted-After.docx", 3)]
- [InlineData("CZ-2320", "WC014-SmartArt-With-Image-Before.docx", "WC014-SmartArt-With-Image-Deleted-After2.docx", 1)]
- [InlineData("CZ-2330", "WC015-Three-Paragraphs.docx", "WC015-Three-Paragraphs-After.docx", 3)]
- [InlineData("CZ-2340", "WC016-Para-Image-Para.docx", "WC016-Para-Image-Para-w-Deleted-Image.docx", 1)]
- [InlineData("CZ-2350", "WC017-Image.docx", "WC017-Image-After.docx", 3)]
- [InlineData("CZ-2360", "WC018-Field-Simple-Before.docx", "WC018-Field-Simple-After-1.docx", 2)]
- [InlineData("CZ-2370", "WC018-Field-Simple-Before.docx", "WC018-Field-Simple-After-2.docx", 3)]
- [InlineData("CZ-2380", "WC019-Hyperlink-Before.docx", "WC019-Hyperlink-After-1.docx", 3)]
- [InlineData("CZ-2400", "WC019-Hyperlink-Before.docx", "WC019-Hyperlink-After-2.docx", 5)]
- [InlineData("CZ-2410", "WC020-FootNote-Before.docx", "WC020-FootNote-After-1.docx", 3)]
- [InlineData("CZ-2420", "WC020-FootNote-Before.docx", "WC020-FootNote-After-2.docx", 5)]
- [InlineData("CZ-2430", "WC021-Math-Before-1.docx", "WC021-Math-After-1.docx", 9)]
- [InlineData("CZ-2440", "WC021-Math-Before-2.docx", "WC021-Math-After-2.docx", 6)]
- [InlineData("CZ-2450", "WC022-Image-Math-Para-Before.docx", "WC022-Image-Math-Para-After.docx", 22)]
- [InlineData("CZ-2460", "WC023-Table-4-Row-Image-Before.docx", "WC023-Table-4-Row-Image-After-Delete-1-Row.docx", 9)]
- [InlineData("CZ-2470", "WC024-Table-Before.docx", "WC024-Table-After.docx", 1)]
- [InlineData("CZ-2480", "WC024-Table-Before.docx", "WC024-Table-After2.docx", 7)]
- [InlineData("CZ-2500", "WC025-Simple-Table-Before.docx", "WC025-Simple-Table-After.docx", 4)]
- [InlineData("CZ-2510", "WC026-Long-Table-Before.docx", "WC026-Long-Table-After-1.docx", 2)]
- [InlineData("CZ-2520", "WC027-Twenty-Paras-Before.docx", "WC027-Twenty-Paras-After-1.docx", 2)]
- [InlineData("CZ-2530", "WC027-Twenty-Paras-After-1.docx", "WC027-Twenty-Paras-Before.docx", 2)]
- [InlineData("CZ-2540", "WC027-Twenty-Paras-Before.docx", "WC027-Twenty-Paras-After-2.docx", 4)]
- [InlineData("CZ-2550", "WC030-Image-Math-Before.docx", "WC030-Image-Math-After.docx", 2)]
- [InlineData("CZ-2560", "WC031-Two-Maths-Before.docx", "WC031-Two-Maths-After.docx", 4)]
- [InlineData("CZ-2570", "WC032-Para-with-Para-Props.docx", "WC032-Para-with-Para-Props-After.docx", 3)]
- [InlineData("CZ-2580", "WC033-Merged-Cells-Before.docx", "WC033-Merged-Cells-After1.docx", 2)]
- [InlineData("CZ-2600", "WC033-Merged-Cells-Before.docx", "WC033-Merged-Cells-After2.docx", 4)]
- [InlineData("CZ-2610", "WC034-Footnotes-Before.docx", "WC034-Footnotes-After1.docx", 1)]
- [InlineData("CZ-2620", "WC034-Footnotes-Before.docx", "WC034-Footnotes-After2.docx", 6)]
- [InlineData("CZ-2630", "WC034-Footnotes-Before.docx", "WC034-Footnotes-After3.docx", 3)]
- [InlineData("CZ-2640", "WC034-Footnotes-After3.docx", "WC034-Footnotes-Before.docx", 3)]
- [InlineData("CZ-2650", "WC035-Footnote-Before.docx", "WC035-Footnote-After.docx", 2)]
- [InlineData("CZ-2660", "WC035-Footnote-After.docx", "WC035-Footnote-Before.docx", 2)]
- [InlineData("CZ-2670", "WC036-Footnote-With-Table-Before.docx", "WC036-Footnote-With-Table-After.docx", 5)]
- [InlineData("CZ-2680", "WC036-Footnote-With-Table-After.docx", "WC036-Footnote-With-Table-Before.docx", 5)]
- [InlineData("CZ-2700", "WC034-Endnotes-Before.docx", "WC034-Endnotes-After1.docx", 1)]
- [InlineData("CZ-2710", "WC034-Endnotes-Before.docx", "WC034-Endnotes-After2.docx", 6)]
- [InlineData("CZ-2720", "WC034-Endnotes-Before.docx", "WC034-Endnotes-After3.docx", 8)]
- [InlineData("CZ-2730", "WC034-Endnotes-After3.docx", "WC034-Endnotes-Before.docx", 8)]
- [InlineData("CZ-2740", "WC035-Endnote-Before.docx", "WC035-Endnote-After.docx", 2)]
- [InlineData("CZ-2750", "WC035-Endnote-After.docx", "WC035-Endnote-Before.docx", 2)]
- [InlineData("CZ-2760", "WC036-Endnote-With-Table-Before.docx", "WC036-Endnote-With-Table-After.docx", 6)]
- [InlineData("CZ-2770", "WC036-Endnote-With-Table-After.docx", "WC036-Endnote-With-Table-Before.docx", 6)]
- [InlineData("CZ-2780", "WC038-Document-With-BR-Before.docx", "WC038-Document-With-BR-After.docx", 2)]
- [InlineData("CZ-2790", "RC001-Before.docx", "RC001-After1.docx", 2)]
- [InlineData("CZ-2800", "RC002-Image.docx", "RC002-Image-After1.docx", 1)]
- [InlineData("CZ-2810", "WC039-Break-In-Row.docx", "WC039-Break-In-Row-After1.docx", 1)]
- //[InlineData("CZ-2820", "", "", 0)]
- //[InlineData("CZ-2830", "", "", 0)]
- //[InlineData("CZ-2840", "", "", 0)]
- //[InlineData("CZ-2850", "", "", 0)]
- //[InlineData("CZ-2860", "", "", 0)]
- //[InlineData("CZ-2870", "", "", 0)]
- //[InlineData("CZ-2880", "", "", 0)]
- //[InlineData("CZ-2890", "", "", 0)]
- public void CZ002_Compare(string testId, string name1, string name2, int revisionCount)
- {
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var rootTempDir = TestUtil.TempDir;
- var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId));
- if (!thisTestTempDir.Exists)
- thisTestTempDir.Create();
- var source1CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name));
- var source2CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name));
- if (!source1CopiedToDestDocx.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocx.FullName);
- if (!source2CopiedToDestDocx.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocx.FullName);
-
- /************************************************************************************************************************/
-
- if (m_OpenWord)
- {
- FileInfo source1DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocxForWord = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name.Replace(".docx", "-For-Word.docx")));
- var source2CopiedToDestDocxForWord = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name.Replace(".docx", "-For-Word.docx")));
- if (!source1CopiedToDestDocxForWord.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocxForWord.FullName);
- if (!source2CopiedToDestDocxForWord.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocxForWord.FullName);
-
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, source2CopiedToDestDocxForWord);
- WordRunner.RunWord(wordExe, source1CopiedToDestDocxForWord);
- }
-
- /************************************************************************************************************************/
-
- var before = source1CopiedToDestDocx.Name.Replace(".docx", "");
- var after = source2CopiedToDestDocx.Name.Replace(".docx", "");
- var docxWithRevisionsFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, before + "-COMPARE-" + after + ".docx"));
-
- WmlDocument source1Wml = new WmlDocument(source1CopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(source2CopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- settings.DebugTempFileDi = TestUtil.TempDir;
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
- comparedWml.SaveAs(docxWithRevisionsFi.FullName);
-
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(comparedWml.DocumentByteArray, 0, comparedWml.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() > 0)
- {
-
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
- }
- var sbs = sb.ToString();
- if (sbs != "")
- Assert.True(false, sbs.ToString());
- }
- }
- }
-
- /************************************************************************************************************************/
-
- if (m_OpenWord)
- {
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, docxWithRevisionsFi);
- }
-
- /************************************************************************************************************************/
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Open Windows Explorer
- if (m_OpenTempDirInExplorer)
- {
- while (true)
- {
- try
- {
- ////////// CODE TO REPEAT UNTIL SUCCESS //////////
- var semaphorFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "z_ExplorerOpenedSemaphore.txt"));
- if (!semaphorFi.Exists)
- {
- File.WriteAllText(semaphorFi.FullName, "");
- TestUtil.Explorer(thisTestTempDir);
- }
- //////////////////////////////////////////////////
- break;
- }
- catch (IOException)
- {
- System.Threading.Thread.Sleep(50);
- }
- }
- }
-#if false
- WmlDocument revisionWml = new WmlDocument(docxWithRevisionsFi.FullName);
- var revisions = WmlComparer.GetRevisions(revisionWml, settings);
- Assert.Equal(revisionCount, revisions.Count());
-#endif
- }
-#endif
-
-#if false
- [Theory]
- [InlineData("RC001-Before.docx",
- @"
-
- RC001-After1.docx
- LightYellow
- From Bob
-
-
- RC001-After2.docx
- LightPink
- From Fred
-
- ")]
- [InlineData("RC002-Image.docx",
- @"
-
- RC002-Image-After1.docx
- LightBlue
- From Bob
-
- ")]
- [InlineData("RC002-Image-After1.docx",
- @"
-
- RC002-Image.docx
- LightBlue
- From Bob
-
- ")]
- [InlineData("WC027-Twenty-Paras-Before.docx",
- @"
-
- WC027-Twenty-Paras-After-1.docx
- LightBlue
- From Bob
-
- ")]
- [InlineData("WC027-Twenty-Paras-Before.docx",
- @"
-
- WC027-Twenty-Paras-After-3.docx
- LightBlue
- From Bob
-
- ")]
- [InlineData("RC003-Multi-Paras.docx",
- @"
-
- RC003-Multi-Paras-After.docx
- LightBlue
- From Bob
-
- ")]
- [InlineData("RC004-Before.docx",
- @"
-
- RC004-After1.docx
- LightYellow
- From Bob
-
-
- RC004-After2.docx
- LightPink
- From Fred
-
- ")]
-
- public void WC001_Consolidate(string originalName, string revisedDocumentsXml)
- {
- FileInfo originalDocx = new FileInfo(Path.Combine(sourceDir.FullName, originalName));
-
- var originalCopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, originalDocx.Name));
- if (!originalCopiedToDestDocx.Exists)
- File.Copy(originalDocx.FullName, originalCopiedToDestDocx.FullName);
-
- var revisedDocumentsXElement = XElement.Parse(revisedDocumentsXml);
- var revisedDocumentsArray = revisedDocumentsXElement
- .Elements()
- .Select(z =>
- {
- FileInfo revisedDocx = new FileInfo(Path.Combine(sourceDir.FullName, z.Element("DocName").Value));
- var revisedCopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, revisedDocx.Name));
- if (!revisedCopiedToDestDocx.Exists)
- File.Copy(revisedDocx.FullName, revisedCopiedToDestDocx.FullName);
- return new WmlRevisedDocumentInfo()
- {
- RevisedDocument = new WmlDocument(revisedCopiedToDestDocx.FullName),
- Color = ColorParser.FromName(z.Element("Color").Value),
- Revisor = z.Element("Revisor").Value,
- };
- })
- .ToList();
-
- var consolidatedDocxName = originalCopiedToDestDocx.Name.Replace(".docx", "-Consolidated.docx");
- var consolidatedDocumentFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, consolidatedDocxName));
-
- WmlDocument source1Wml = new WmlDocument(originalCopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- WmlDocument consolidatedWml = WmlComparer.Consolidate(
- source1Wml,
- revisedDocumentsArray,
- settings);
- consolidatedWml.SaveAs(consolidatedDocumentFi.FullName);
-
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(consolidatedWml.DocumentByteArray, 0, consolidatedWml.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() > 0)
- {
-
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
-#if true
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
-#else
- sb.Append(" \"" + err.Description + "\"," + Environment.NewLine);
-#endif
- }
- var sbs = sb.ToString();
- Assert.Equal("", sbs);
- }
- }
- }
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, consolidatedDocumentFi);
- }
-
- /************************************************************************************************************************/
- }
-
- [Theory]
- [InlineData("CA001-Plain.docx", "CA001-Plain-Mod.docx")]
- [InlineData("WC001-Digits.docx", "WC001-Digits-Mod.docx")]
- [InlineData("WC001-Digits.docx", "WC001-Digits-Deleted-Paragraph.docx")]
- [InlineData("WC001-Digits-Deleted-Paragraph.docx", "WC001-Digits.docx")]
- [InlineData("WC002-Unmodified.docx", "WC002-DiffInMiddle.docx")]
- [InlineData("WC002-Unmodified.docx", "WC002-DiffAtBeginning.docx")]
- [InlineData("WC002-Unmodified.docx", "WC002-DeleteAtBeginning.docx")]
- [InlineData("WC002-Unmodified.docx", "WC002-InsertAtBeginning.docx")]
- [InlineData("WC002-Unmodified.docx", "WC002-InsertAtEnd.docx")]
- [InlineData("WC002-Unmodified.docx", "WC002-DeleteAtEnd.docx")]
- [InlineData("WC002-Unmodified.docx", "WC002-DeleteInMiddle.docx")]
- [InlineData("WC002-Unmodified.docx", "WC002-InsertInMiddle.docx")]
- [InlineData("WC002-DeleteInMiddle.docx", "WC002-Unmodified.docx")]
- //[InlineData("WC004-Large.docx", "WC004-Large-Mod.docx")]
- [InlineData("WC006-Table.docx", "WC006-Table-Delete-Row.docx")]
- [InlineData("WC006-Table-Delete-Row.docx", "WC006-Table.docx")]
- [InlineData("WC006-Table.docx", "WC006-Table-Delete-Contests-of-Row.docx")]
- [InlineData("WC007-Unmodified.docx", "WC007-Longest-At-End.docx")]
- [InlineData("WC007-Unmodified.docx", "WC007-Deleted-at-Beginning-of-Para.docx")]
- [InlineData("WC007-Unmodified.docx", "WC007-Moved-into-Table.docx")]
- [InlineData("WC009-Table-Unmodified.docx", "WC009-Table-Cell-1-1-Mod.docx")]
- [InlineData("WC010-Para-Before-Table-Unmodified.docx", "WC010-Para-Before-Table-Mod.docx")]
- [InlineData("WC011-Before.docx", "WC011-After.docx")]
- [InlineData("WC012-Math-Before.docx", "WC012-Math-After.docx")]
- [InlineData("WC013-Image-Before.docx", "WC013-Image-After.docx")]
- [InlineData("WC013-Image-Before.docx", "WC013-Image-After2.docx")]
- [InlineData("WC013-Image-Before2.docx", "WC013-Image-After2.docx")]
- [InlineData("WC014-SmartArt-Before.docx", "WC014-SmartArt-After.docx")]
- [InlineData("WC014-SmartArt-With-Image-Before.docx", "WC014-SmartArt-With-Image-After.docx")]
- [InlineData("WC014-SmartArt-With-Image-Before.docx", "WC014-SmartArt-With-Image-Deleted-After.docx")]
- [InlineData("WC014-SmartArt-With-Image-Before.docx", "WC014-SmartArt-With-Image-Deleted-After2.docx")]
- [InlineData("WC015-Three-Paragraphs.docx", "WC015-Three-Paragraphs-After.docx")]
- [InlineData("WC016-Para-Image-Para.docx", "WC016-Para-Image-Para-w-Deleted-Image.docx")]
- [InlineData("WC017-Image.docx", "WC017-Image-After.docx")]
- [InlineData("WC018-Field-Simple-Before.docx", "WC018-Field-Simple-After-1.docx")]
- [InlineData("WC018-Field-Simple-Before.docx", "WC018-Field-Simple-After-2.docx")]
- [InlineData("WC019-Hyperlink-Before.docx", "WC019-Hyperlink-After-1.docx")]
- [InlineData("WC019-Hyperlink-Before.docx", "WC019-Hyperlink-After-2.docx")]
- [InlineData("WC020-FootNote-Before.docx", "WC020-FootNote-After-1.docx")]
- [InlineData("WC020-FootNote-Before.docx", "WC020-FootNote-After-2.docx")]
- [InlineData("WC021-Math-Before-1.docx", "WC021-Math-After-1.docx")]
- [InlineData("WC021-Math-Before-2.docx", "WC021-Math-After-2.docx")]
- [InlineData("WC022-Image-Math-Para-Before.docx", "WC022-Image-Math-Para-After.docx")]
- [InlineData("WC023-Table-4-Row-Image-Before.docx", "WC023-Table-4-Row-Image-After-Delete-1-Row.docx")]
- [InlineData("WC024-Table-Before.docx", "WC024-Table-After.docx")]
- [InlineData("WC024-Table-Before.docx", "WC024-Table-After2.docx")]
- [InlineData("WC025-Simple-Table-Before.docx", "WC025-Simple-Table-After.docx")]
- [InlineData("WC026-Long-Table-Before.docx", "WC026-Long-Table-After-1.docx")]
- [InlineData("WC027-Twenty-Paras-Before.docx", "WC027-Twenty-Paras-After-1.docx")]
- [InlineData("WC027-Twenty-Paras-After-1.docx", "WC027-Twenty-Paras-Before.docx")]
- [InlineData("WC027-Twenty-Paras-Before.docx", "WC027-Twenty-Paras-After-2.docx")]
- [InlineData("WC030-Image-Math-Before.docx", "WC030-Image-Math-After.docx")]
- [InlineData("WC031-Two-Maths-Before.docx", "WC031-Two-Maths-After.docx")]
- [InlineData("WC032-Para-with-Para-Props.docx", "WC032-Para-with-Para-Props-After.docx")]
- [InlineData("WC033-Merged-Cells-Before.docx", "WC033-Merged-Cells-After1.docx")]
- [InlineData("WC033-Merged-Cells-Before.docx", "WC033-Merged-Cells-After2.docx")]
- [InlineData("WC034-Footnotes-Before.docx", "WC034-Footnotes-After1.docx")]
- [InlineData("WC034-Footnotes-Before.docx", "WC034-Footnotes-After2.docx")]
- [InlineData("WC034-Footnotes-Before.docx", "WC034-Footnotes-After3.docx")]
- [InlineData("WC034-Footnotes-After3.docx", "WC034-Footnotes-Before.docx")]
- [InlineData("WC035-Footnote-Before.docx", "WC035-Footnote-After.docx")]
- [InlineData("WC035-Footnote-After.docx", "WC035-Footnote-Before.docx")]
- [InlineData("WC036-Footnote-With-Table-Before.docx", "WC036-Footnote-With-Table-After.docx")]
- [InlineData("WC036-Footnote-With-Table-After.docx", "WC036-Footnote-With-Table-Before.docx")]
- [InlineData("WC034-Endnotes-Before.docx", "WC034-Endnotes-After1.docx")]
- [InlineData("WC034-Endnotes-Before.docx", "WC034-Endnotes-After2.docx")]
- [InlineData("WC034-Endnotes-Before.docx", "WC034-Endnotes-After3.docx")]
- [InlineData("WC034-Endnotes-After3.docx", "WC034-Endnotes-Before.docx")]
- [InlineData("WC035-Endnote-Before.docx", "WC035-Endnote-After.docx")]
- [InlineData("WC035-Endnote-After.docx", "WC035-Endnote-Before.docx")]
- [InlineData("WC036-Endnote-With-Table-Before.docx", "WC036-Endnote-With-Table-After.docx")]
- [InlineData("WC036-Endnote-With-Table-After.docx", "WC036-Endnote-With-Table-Before.docx")]
- [InlineData("WC038-Document-With-BR-Before.docx", "WC038-Document-With-BR-After.docx")]
- [InlineData("RC001-Before.docx", "RC001-After1.docx")]
- [InlineData("RC002-Image.docx", "RC002-Image-After1.docx")]
- //[InlineData("", "")]
- //[InlineData("", "")]
- //[InlineData("", "")]
- //[InlineData("", "")]
- //[InlineData("", "")]
- //[InlineData("", "")]
- //[InlineData("", "")]
- //[InlineData("", "")]
- //[InlineData("", "")]
-
-
- public void WC002_Consolidate_Bulk_Test(string name1, string name2)
- {
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source1Docx.Name));
- var source2CopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source2Docx.Name));
- if (!source1CopiedToDestDocx.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocx.FullName);
- if (!source2CopiedToDestDocx.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocx.FullName);
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo source1DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocxForWord = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source1Docx.Name.Replace(".docx", "-For-Word.docx")));
- var source2CopiedToDestDocxForWord = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source2Docx.Name.Replace(".docx", "-For-Word.docx")));
- if (!source1CopiedToDestDocxForWord.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocxForWord.FullName);
- if (!source2CopiedToDestDocxForWord.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocxForWord.FullName);
-
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- var path = new DirectoryInfo(@"C:\Users\Eric\Documents\WindowsPowerShellModules\Open-Xml-PowerTools\TestFiles");
- WordRunner.RunWord(wordExe, source2CopiedToDestDocxForWord);
- WordRunner.RunWord(wordExe, source1CopiedToDestDocxForWord);
- }
-
- /************************************************************************************************************************/
-
- var before = source1CopiedToDestDocx.Name.Replace(".docx", "");
- var after = source2CopiedToDestDocx.Name.Replace(".docx", "");
- var docxWithRevisionsFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, before + "-COMPARE-" + after + ".docx"));
- var docxConsolidatedFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, before + "-CONSOLIDATED-" + after + ".docx"));
-
- WmlDocument source1Wml = new WmlDocument(source1CopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(source2CopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
- comparedWml.SaveAs(docxWithRevisionsFi.FullName);
-
- List revisedDocInfo = new List()
- {
- new WmlRevisedDocumentInfo()
- {
- RevisedDocument = source2Wml,
- Color = Color.LightBlue,
- Revisor = "Revised by Eric White",
- }
- };
- WmlDocument consolidatedWml = WmlComparer.Consolidate(
- source1Wml,
- revisedDocInfo,
- settings);
- consolidatedWml.SaveAs(docxConsolidatedFi.FullName);
-
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(consolidatedWml.DocumentByteArray, 0, consolidatedWml.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() > 0)
- {
-
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
-#if true
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
-#else
- sb.Append(" \"" + err.Description + "\"," + Environment.NewLine);
-#endif
- }
- var sbs = sb.ToString();
- Assert.Equal("", sbs);
- }
- }
- }
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, docxConsolidatedFi);
- }
-
- /************************************************************************************************************************/
- }
-#endif
-
-#if false
- [Theory]
- [InlineData("WC037-Textbox-Before.docx", "WC037-Textbox-After1.docx", 2)]
-
- public void WC003_Throws(string name1, string name2, int revisionCount)
- {
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source1Docx.Name));
- var source2CopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source2Docx.Name));
- if (!source1CopiedToDestDocx.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocx.FullName);
- if (!source2CopiedToDestDocx.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocx.FullName);
-
- WmlDocument source1Wml = new WmlDocument(source1CopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(source2CopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- Assert.Throws(() =>
- {
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
- });
- }
-
- [Theory]
- [InlineData("WC001-Digits.docx")]
- [InlineData("WC001-Digits-Deleted-Paragraph.docx")]
- [InlineData("WC001-Digits-Mod.docx")]
- [InlineData("WC002-DeleteAtBeginning.docx")]
- [InlineData("WC002-DeleteAtEnd.docx")]
- [InlineData("WC002-DeleteInMiddle.docx")]
- [InlineData("WC002-DiffAtBeginning.docx")]
- [InlineData("WC002-DiffInMiddle.docx")]
- [InlineData("WC002-InsertAtBeginning.docx")]
- [InlineData("WC002-InsertAtEnd.docx")]
- [InlineData("WC002-InsertInMiddle.docx")]
- [InlineData("WC002-Unmodified.docx")]
- //[InlineData("WC004-Large.docx")]
- //[InlineData("WC004-Large-Mod.docx")]
- [InlineData("WC006-Table.docx")]
- [InlineData("WC006-Table-Delete-Contests-of-Row.docx")]
- [InlineData("WC006-Table-Delete-Row.docx")]
- [InlineData("WC007-Deleted-at-Beginning-of-Para.docx")]
- [InlineData("WC007-Longest-At-End.docx")]
- [InlineData("WC007-Moved-into-Table.docx")]
- [InlineData("WC007-Unmodified.docx")]
- [InlineData("WC009-Table-Cell-1-1-Mod.docx")]
- [InlineData("WC009-Table-Unmodified.docx")]
- [InlineData("WC010-Para-Before-Table-Mod.docx")]
- [InlineData("WC010-Para-Before-Table-Unmodified.docx")]
- [InlineData("WC011-After.docx")]
- [InlineData("WC011-Before.docx")]
- [InlineData("WC012-Math-After.docx")]
- [InlineData("WC012-Math-Before.docx")]
- [InlineData("WC013-Image-After.docx")]
- [InlineData("WC013-Image-After2.docx")]
- [InlineData("WC013-Image-Before.docx")]
- [InlineData("WC013-Image-Before2.docx")]
- [InlineData("WC014-SmartArt-After.docx")]
- [InlineData("WC014-SmartArt-Before.docx")]
- [InlineData("WC014-SmartArt-With-Image-After.docx")]
- [InlineData("WC014-SmartArt-With-Image-Before.docx")]
- [InlineData("WC014-SmartArt-With-Image-Deleted-After.docx")]
- [InlineData("WC014-SmartArt-With-Image-Deleted-After2.docx")]
- [InlineData("WC015-Three-Paragraphs.docx")]
- [InlineData("WC015-Three-Paragraphs-After.docx")]
- [InlineData("WC016-Para-Image-Para.docx")]
- [InlineData("WC016-Para-Image-Para-w-Deleted-Image.docx")]
- [InlineData("WC017-Image.docx")]
- [InlineData("WC017-Image-After.docx")]
- [InlineData("WC018-Field-Simple-After-1.docx")]
- [InlineData("WC018-Field-Simple-After-2.docx")]
- [InlineData("WC018-Field-Simple-Before.docx")]
- [InlineData("WC019-Hyperlink-After-1.docx")]
- [InlineData("WC019-Hyperlink-After-2.docx")]
- [InlineData("WC019-Hyperlink-Before.docx")]
- [InlineData("WC020-FootNote-After-1.docx")]
- [InlineData("WC020-FootNote-After-2.docx")]
- [InlineData("WC020-FootNote-Before.docx")]
- [InlineData("WC021-Math-After-1.docx")]
- [InlineData("WC021-Math-Before-1.docx")]
- [InlineData("WC022-Image-Math-Para-After.docx")]
- [InlineData("WC022-Image-Math-Para-Before.docx")]
- //[InlineData("", "")]
- //[InlineData("", "")]
- //[InlineData("", "")]
- //[InlineData("", "")]
-
- public void WC004_Compare_To_Self(string name)
- {
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
-
- var sourceCopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-Source.docx")));
- if (!sourceCopiedToDestDocx.Exists)
- File.Copy(sourceDocx.FullName, sourceCopiedToDestDocx.FullName);
-
- var before = sourceCopiedToDestDocx.Name.Replace(".docx", "");
- var docxComparedFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, before + "-COMPARE" + ".docx"));
- var docxCompared2Fi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, before + "-COMPARE2" + ".docx"));
-
- WmlDocument source1Wml = new WmlDocument(sourceCopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(sourceCopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
-
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
- comparedWml.SaveAs(docxComparedFi.FullName);
- ValidateDocument(comparedWml);
-
- WmlDocument comparedWml2 = WmlComparer.Compare(comparedWml, source1Wml, settings);
- comparedWml2.SaveAs(docxCompared2Fi.FullName);
- ValidateDocument(comparedWml2);
- }
-
- [Theory]
- [InlineData("WC040-Case-Before.docx", "WC040-Case-After.docx", 2)]
- //[InlineData("", "", 0)]
- //[InlineData("", "", 0)]
- //[InlineData("", "", 0)]
- //[InlineData("", "", 0)]
- //[InlineData("", "", 0)]
- //[InlineData("", "", 0)]
- //[InlineData("", "", 0)]
- //[InlineData("", "", 0)]
-
- public void WC005_Compare_CaseInsensitive(string name1, string name2, int revisionCount)
- {
- FileInfo source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source1Docx.Name));
- var source2CopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source2Docx.Name));
- if (!source1CopiedToDestDocx.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocx.FullName);
- if (!source2CopiedToDestDocx.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocx.FullName);
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo source1DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name1));
- FileInfo source2DocxForWord = new FileInfo(Path.Combine(sourceDir.FullName, name2));
-
- var source1CopiedToDestDocxForWord = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source1Docx.Name.Replace(".docx", "-For-Word.docx")));
- var source2CopiedToDestDocxForWord = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, source2Docx.Name.Replace(".docx", "-For-Word.docx")));
- if (!source1CopiedToDestDocxForWord.Exists)
- File.Copy(source1Docx.FullName, source1CopiedToDestDocxForWord.FullName);
- if (!source2CopiedToDestDocxForWord.Exists)
- File.Copy(source2Docx.FullName, source2CopiedToDestDocxForWord.FullName);
-
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- var path = new DirectoryInfo(@"C:\Users\Eric\Documents\WindowsPowerShellModules\Open-Xml-PowerTools\TestFiles");
- WordRunner.RunWord(wordExe, source2CopiedToDestDocxForWord);
- WordRunner.RunWord(wordExe, source1CopiedToDestDocxForWord);
- }
-
- /************************************************************************************************************************/
-
- var before = source1CopiedToDestDocx.Name.Replace(".docx", "");
- var after = source2CopiedToDestDocx.Name.Replace(".docx", "");
- var docxWithRevisionsFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, before + "-COMPARE-" + after + ".docx"));
-
- WmlDocument source1Wml = new WmlDocument(source1CopiedToDestDocx.FullName);
- WmlDocument source2Wml = new WmlDocument(source2CopiedToDestDocx.FullName);
- WmlComparerSettings settings = new WmlComparerSettings();
- settings.CaseInsensitive = true;
- settings.CultureInfo = System.Globalization.CultureInfo.CurrentCulture;
- WmlDocument comparedWml = WmlComparer.Compare(source1Wml, source2Wml, settings);
- comparedWml.SaveAs(docxWithRevisionsFi.FullName);
-
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(comparedWml.DocumentByteArray, 0, comparedWml.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() > 0)
- {
-
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
- }
- var sbs = sb.ToString();
- Assert.Equal("", sbs);
- }
- }
- }
-
- /************************************************************************************************************************/
-
- if (s_OpenWord)
- {
- FileInfo wordExe = new FileInfo(@"C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE");
- WordRunner.RunWord(wordExe, docxWithRevisionsFi);
- }
-
- /************************************************************************************************************************/
-
- WmlDocument revisionWml = new WmlDocument(docxWithRevisionsFi.FullName);
- var revisions = WmlComparer.GetRevisions(revisionWml, settings);
- Assert.Equal(revisionCount, revisions.Count());
- }
-#endif
-
- private static void ValidateDocument(WmlDocument wmlToValidate)
- {
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(wmlToValidate.DocumentByteArray, 0, wmlToValidate.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- OpenXmlValidator validator = new OpenXmlValidator();
- var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description));
- if (errors.Count() != 0)
- {
- var ind = " ";
- var sb = new StringBuilder();
- foreach (var err in errors)
- {
- sb.Append("Error" + Environment.NewLine);
- sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine);
- sb.Append(ind + "Description: " + err.Description + Environment.NewLine);
- sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine);
- sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine);
- }
- var sbs = sb.ToString();
- Assert.Equal("", sbs);
- }
- }
- }
- }
-
- public static string[] ExpectedErrors = new string[] {
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:firstRow' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:lastRow' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:firstColumn' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:lastColumn' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:noHBand' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:noVBand' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:allStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:customStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:latentStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:stylesInUse' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:headingStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:numberingStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:tableStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:directFormattingOnRuns' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:directFormattingOnParagraphs' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:directFormattingOnNumbering' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:directFormattingOnTables' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:clearFormatting' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:top3HeadingStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:visibleStyles' attribute is not declared.",
- "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:alternateStyleNames' attribute is not declared.",
- "The attribute 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:val' has invalid value '0'. The MinInclusive constraint failed. The value must be greater than or equal to 1.",
- "The attribute 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:val' has invalid value '0'. The MinInclusive constraint failed. The value must be greater than or equal to 2.",
- };
-
- }
-#if false
- public class WordRunner
- {
- public static void RunWord(FileInfo executablePath, FileInfo docxPath)
- {
- if (executablePath.Exists)
- {
- using (Process proc = new Process())
- {
- proc.StartInfo.FileName = executablePath.FullName;
- proc.StartInfo.Arguments = docxPath.FullName;
- proc.StartInfo.WorkingDirectory = docxPath.DirectoryName;
- proc.StartInfo.UseShellExecute = false;
- proc.StartInfo.RedirectStandardOutput = true;
- proc.StartInfo.RedirectStandardError = true;
- proc.Start();
- }
- }
- else
- {
- throw new ArgumentException("Invalid executable path.", "executablePath");
- }
- }
- }
-#endif
-}
-
-#endif
diff --git a/OpenXmlPowerTools.Tests/WmlContentAtomListTests.cs b/OpenXmlPowerTools.Tests/WmlContentAtomListTests.cs
deleted file mode 100644
index 889f9bb0..00000000
--- a/OpenXmlPowerTools.Tests/WmlContentAtomListTests.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-#define COPY_FILES_FOR_DEBUGGING
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
-using Xunit;
-
-#if !ELIDE_XUNIT_TESTS
-
-namespace OxPt
-{
- public class CaTests
- {
- /*
- * This test was removed because it depends on the Coalesce method, which is only ever used
- * by this test.
- *
- [Theory]
- [InlineData("CA/CA001-Plain.docx", 60)]
- [InlineData("CA/CA002-Bookmark.docx", 7)]
- [InlineData("CA/CA003-Numbered-List.docx", 8)]
- [InlineData("CA/CA004-TwoParas.docx", 88)]
- [InlineData("CA/CA005-Table.docx", 27)]
- [InlineData("CA/CA006-ContentControl.docx", 60)]
- [InlineData("CA/CA007-DayLong.docx", 10)]
- [InlineData("CA/CA008-Footnote-Reference.docx", 23)]
- [InlineData("CA/CA010-Delete-Run.docx", 16)]
- [InlineData("CA/CA011-Insert-Run.docx", 16)]
- [InlineData("CA/CA012-fldSimple.docx", 10)]
- [InlineData("CA/CA013-Lots-of-Stuff.docx", 168)]
- [InlineData("CA/CA014-Complex-Table.docx", 193)]
- [InlineData("WC/WC024-Table-Before.docx", 24)]
- [InlineData("WC/WC024-Table-After2.docx", 18)]
- //[InlineData("", 0)]
- //[InlineData("", 0)]
- //[InlineData("", 0)]
- //[InlineData("", 0)]
-
- public void CA001_ContentAtoms(string name, int contentAtomCount)
- {
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
-
- var thisGuid = Guid.NewGuid().ToString().Replace("-", "");
- var sourceCopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", string.Format("-{0}-1-Source.docx", thisGuid))));
- if (!sourceCopiedToDestDocx.Exists)
- File.Copy(sourceDocx.FullName, sourceCopiedToDestDocx.FullName);
-
- var coalescedDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", string.Format("-{0}-2-Coalesced.docx", thisGuid))));
- if (!coalescedDocx.Exists)
- File.Copy(sourceDocx.FullName, coalescedDocx.FullName);
-
- var contentAtomDataFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", string.Format("-{0}-3-ContentAtomData.txt", thisGuid))));
-
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(coalescedDocx.FullName, true))
- {
- var contentParent = wDoc.MainDocumentPart.GetXDocument().Root.Element(W.body);
- var settings = new WmlComparerSettings();
- ComparisonUnitAtom[] contentAtomList = WmlComparer.CreateComparisonUnitAtomList(wDoc.MainDocumentPart, contentParent, settings);
- StringBuilder sb = new StringBuilder();
- var part = wDoc.MainDocumentPart;
-
- sb.AppendFormat("Part: {0}", part.Uri.ToString());
- sb.Append(Environment.NewLine);
- sb.Append(ComparisonUnit.ComparisonUnitListToString(contentAtomList.ToArray()) + Environment.NewLine);
- sb.Append(Environment.NewLine);
-
- XDocument newMainXDoc = WmlComparer.Coalesce(contentAtomList);
- var partXDoc = wDoc.MainDocumentPart.GetXDocument();
- partXDoc.Root.ReplaceWith(newMainXDoc.Root);
- wDoc.MainDocumentPart.PutXDocument();
-
- File.WriteAllText(contentAtomDataFi.FullName, sb.ToString());
-
- Assert.Equal(contentAtomCount, contentAtomList.Count());
- }
- }
- */
-
- [Theory]
- [InlineData("HC009-Test-04.docx")]
- public void CA002_Annotations(string name)
- {
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
-
-#if COPY_FILES_FOR_DEBUGGING
- var sourceCopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-1-Source.docx")));
- if (!sourceCopiedToDestDocx.Exists)
- File.Copy(sourceDocx.FullName, sourceCopiedToDestDocx.FullName);
-
- var annotatedDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", "-2-Annotated.docx")));
- if (!annotatedDocx.Exists)
- File.Copy(sourceDocx.FullName, annotatedDocx.FullName);
-
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(annotatedDocx.FullName, true))
- {
- var contentParent = wDoc.MainDocumentPart.GetXDocument().Root.Element(W.body);
- var settings = new WmlComparerSettings();
- WmlComparer.CreateComparisonUnitAtomList(wDoc.MainDocumentPart, contentParent, settings);
- }
-#endif
- }
-
- [Theory]
- [InlineData("CA/CA009-altChunk.docx")]
- //[InlineData("")]
- //[InlineData("")]
- //[InlineData("")]
-
- public void CA003_ContentAtoms_Throws(string name)
- {
- DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/");
- FileInfo sourceDocx = new FileInfo(Path.Combine(sourceDir.FullName, name));
- var thisGuid = Guid.NewGuid().ToString().Replace("-", "");
- var sourceCopiedToDestDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", string.Format("-{0}-1-Source.docx", thisGuid))));
- if (!sourceCopiedToDestDocx.Exists)
- File.Copy(sourceDocx.FullName, sourceCopiedToDestDocx.FullName);
-
- var coalescedDocx = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", string.Format("-{0}-2-Coalesced.docx", thisGuid))));
- if (!coalescedDocx.Exists)
- File.Copy(sourceDocx.FullName, coalescedDocx.FullName);
-
- var contentAtomDataFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceDocx.Name.Replace(".docx", string.Format("-{0}-3-ContentAtomData.txt", thisGuid))));
-
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(coalescedDocx.FullName, true))
- {
- Assert.Throws(() =>
- {
- var contentParent = wDoc.MainDocumentPart.GetXDocument().Root.Element(W.body);
- var settings = new WmlComparerSettings();
- WmlComparer.CreateComparisonUnitAtomList(wDoc.MainDocumentPart, contentParent, settings);
- });
- }
- }
- }
-}
-
-#endif
diff --git a/OpenXmlPowerTools.sln b/OpenXmlPowerTools.sln
index 806dc01e..57fdb2bd 100644
--- a/OpenXmlPowerTools.sln
+++ b/OpenXmlPowerTools.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.27130.2036
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenXmlPowerTools", "OpenXmlPowerTools\OpenXmlPowerTools.csproj", "{6F957FF3-AFCC-4D69-8FBC-71AE21BC45C9}"
EndProject
@@ -25,18 +25,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlConverter01", "OpenXmlP
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ListItemRetriever01", "OpenXmlPowerToolsExamples\ListItemRetriever01\ListItemRetriever01.csproj", "{04935FA6-E48B-496F-8D6A-41A59232303D}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarkupSimplifierApp", "OpenXmlPowerToolsExamples\MarkupSimplifierApp\MarkupSimplifierApp.csproj", "{0CCE83BA-8B8B-4B98-8846-B62A61FDF170}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MetricsGetter01", "OpenXmlPowerToolsExamples\MetricsGetter01\MetricsGetter01.csproj", "{ED37372C-DFBF-4720-BD4B-CE1415961038}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenXmlRegex01", "OpenXmlPowerToolsExamples\OpenXmlRegex01\OpenXmlRegex01.csproj", "{4330D46F-6703-4BA2-844D-177F722C0820}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PivotTables01", "OpenXmlPowerToolsExamples\PivotTables01\PivotTables01.csproj", "{6785A554-BBBB-480C-8E4D-9FE90DD91A46}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PresentationBuilder01", "OpenXmlPowerToolsExamples\PresentationBuilder01\PresentationBuilder01.csproj", "{A4128935-B707-4D56-B924-27910EC92664}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PresentationBuilder02", "OpenXmlPowerToolsExamples\PresentationBuilder02\PresentationBuilder02.csproj", "{495060B4-BD80-4B18-AC44-4680F0D6D5DB}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReferenceAdder01", "OpenXmlPowerToolsExamples\ReferenceAdder01\ReferenceAdder01.csproj", "{211F05D3-F8EE-497F-9DE9-AFFA0A72140D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RevisionAccepter01", "OpenXmlPowerToolsExamples\RevisionAccepter01\RevisionAccepter01.csproj", "{84823BA5-B860-4CAF-885E-981D7F121830}"
@@ -69,22 +63,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WmlToHtmlConverter02", "Ope
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SmlDataRetriever01", "OpenXmlPowerToolsExamples\SmlDataRetriever01\SmlDataRetriever01.csproj", "{DCE8EC51-1E58-49A0-82CF-5BE269FA0A9D}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WmlComparer01", "OpenXmlPowerToolsExamples\WmlComparer01\WmlComparer01.csproj", "{C9CAA69C-575A-442E-9D8A-69C53B39D72C}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WmlComparer02", "OpenXmlPowerToolsExamples\WmlComparer02\WmlComparer02.csproj", "{3D1C46E1-7A9E-4A4B-8D95-68613603DEDF}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{A83D6B58-6D38-46AF-8C20-5CFC170A1063}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9AFB8C96-1E6E-483E-9882-75D2483E7076}"
ProjectSection(SolutionItems) = preProject
- Directory.Build.props = Directory.Build.props
- Directory.Build.targets = Directory.Build.targets
- LICENSE.txt = LICENSE.txt
+ .editorconfig = .editorconfig
+ .github\workflows\cla.yml = .github\workflows\cla.yml
+ .github\dependabot.yml = .github\dependabot.yml
+ .github\workflows\dotnet.yml = .github\workflows\dotnet.yml
+ LICENSE.md = LICENSE.md
README.md = README.md
- rules.ruleset = rules.ruleset
- stylecop.json = stylecop.json
+ .github\workflows\stale.yml = .github\workflows\stale.yml
EndProjectSection
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarkupSimplifierApp", "OpenXmlPowerToolsExamples\MarkupSimplifierApp\MarkupSimplifierApp.csproj", "{6731E031-9C81-48FB-97A7-0E945993BCE2}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -135,10 +128,6 @@ Global
{04935FA6-E48B-496F-8D6A-41A59232303D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04935FA6-E48B-496F-8D6A-41A59232303D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04935FA6-E48B-496F-8D6A-41A59232303D}.Release|Any CPU.Build.0 = Release|Any CPU
- {0CCE83BA-8B8B-4B98-8846-B62A61FDF170}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0CCE83BA-8B8B-4B98-8846-B62A61FDF170}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0CCE83BA-8B8B-4B98-8846-B62A61FDF170}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0CCE83BA-8B8B-4B98-8846-B62A61FDF170}.Release|Any CPU.Build.0 = Release|Any CPU
{ED37372C-DFBF-4720-BD4B-CE1415961038}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED37372C-DFBF-4720-BD4B-CE1415961038}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED37372C-DFBF-4720-BD4B-CE1415961038}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -151,14 +140,6 @@ Global
{6785A554-BBBB-480C-8E4D-9FE90DD91A46}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6785A554-BBBB-480C-8E4D-9FE90DD91A46}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6785A554-BBBB-480C-8E4D-9FE90DD91A46}.Release|Any CPU.Build.0 = Release|Any CPU
- {A4128935-B707-4D56-B924-27910EC92664}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A4128935-B707-4D56-B924-27910EC92664}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A4128935-B707-4D56-B924-27910EC92664}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A4128935-B707-4D56-B924-27910EC92664}.Release|Any CPU.Build.0 = Release|Any CPU
- {495060B4-BD80-4B18-AC44-4680F0D6D5DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {495060B4-BD80-4B18-AC44-4680F0D6D5DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {495060B4-BD80-4B18-AC44-4680F0D6D5DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {495060B4-BD80-4B18-AC44-4680F0D6D5DB}.Release|Any CPU.Build.0 = Release|Any CPU
{211F05D3-F8EE-497F-9DE9-AFFA0A72140D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{211F05D3-F8EE-497F-9DE9-AFFA0A72140D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{211F05D3-F8EE-497F-9DE9-AFFA0A72140D}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -223,14 +204,10 @@ Global
{DCE8EC51-1E58-49A0-82CF-5BE269FA0A9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCE8EC51-1E58-49A0-82CF-5BE269FA0A9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCE8EC51-1E58-49A0-82CF-5BE269FA0A9D}.Release|Any CPU.Build.0 = Release|Any CPU
- {C9CAA69C-575A-442E-9D8A-69C53B39D72C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C9CAA69C-575A-442E-9D8A-69C53B39D72C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C9CAA69C-575A-442E-9D8A-69C53B39D72C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C9CAA69C-575A-442E-9D8A-69C53B39D72C}.Release|Any CPU.Build.0 = Release|Any CPU
- {3D1C46E1-7A9E-4A4B-8D95-68613603DEDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3D1C46E1-7A9E-4A4B-8D95-68613603DEDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3D1C46E1-7A9E-4A4B-8D95-68613603DEDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3D1C46E1-7A9E-4A4B-8D95-68613603DEDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6731E031-9C81-48FB-97A7-0E945993BCE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6731E031-9C81-48FB-97A7-0E945993BCE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6731E031-9C81-48FB-97A7-0E945993BCE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6731E031-9C81-48FB-97A7-0E945993BCE2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -246,12 +223,9 @@ Global
{618B95DB-3A70-4DC8-BD87-00F636F72453} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
{BC9E7408-508D-482D-8602-96E76ACBB5EA} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
{04935FA6-E48B-496F-8D6A-41A59232303D} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
- {0CCE83BA-8B8B-4B98-8846-B62A61FDF170} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
{ED37372C-DFBF-4720-BD4B-CE1415961038} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
{4330D46F-6703-4BA2-844D-177F722C0820} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
{6785A554-BBBB-480C-8E4D-9FE90DD91A46} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
- {A4128935-B707-4D56-B924-27910EC92664} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
- {495060B4-BD80-4B18-AC44-4680F0D6D5DB} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
{211F05D3-F8EE-497F-9DE9-AFFA0A72140D} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
{84823BA5-B860-4CAF-885E-981D7F121830} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
{5CA29B44-C4A5-4310-9429-553F0BC9FC1D} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
@@ -267,8 +241,7 @@ Global
{396D9209-0D9A-4E61-9471-04C71F6CA6B9} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
{D4078011-2611-46A7-8A30-55E4AB8FA786} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
{DCE8EC51-1E58-49A0-82CF-5BE269FA0A9D} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
- {C9CAA69C-575A-442E-9D8A-69C53B39D72C} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
- {3D1C46E1-7A9E-4A4B-8D95-68613603DEDF} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
+ {6731E031-9C81-48FB-97A7-0E945993BCE2} = {A83D6B58-6D38-46AF-8C20-5CFC170A1063}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E623EFF5-2CA4-4FA0-B3AB-53F921DA212E}
diff --git a/OpenXmlPowerTools/Chart/ChartData.cs b/OpenXmlPowerTools/Chart/ChartData.cs
new file mode 100644
index 00000000..9908475d
--- /dev/null
+++ b/OpenXmlPowerTools/Chart/ChartData.cs
@@ -0,0 +1,13 @@
+namespace Codeuctivity.OpenXmlPowerTools.Chart
+{
+ public class ChartData
+ {
+ public string[] SeriesNames { get; set; }
+
+ public ChartDataType CategoryDataType { get; set; }
+ public int CategoryFormatCode { get; set; }
+ public string[] CategoryNames { get; set; }
+
+ public double[][] Values { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools/Chart/ChartDataType.cs b/OpenXmlPowerTools/Chart/ChartDataType.cs
new file mode 100644
index 00000000..32c6de53
--- /dev/null
+++ b/OpenXmlPowerTools/Chart/ChartDataType.cs
@@ -0,0 +1,9 @@
+namespace Codeuctivity.OpenXmlPowerTools.Chart
+{
+ public enum ChartDataType
+ {
+ Number,
+ String,
+ DateTime,
+ }
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools/ChartUpdater.cs b/OpenXmlPowerTools/Chart/ChartUpdater.cs
similarity index 75%
rename from OpenXmlPowerTools/ChartUpdater.cs
rename to OpenXmlPowerTools/Chart/ChartUpdater.cs
index 79b0f74b..2d6c7842 100644
--- a/OpenXmlPowerTools/ChartUpdater.cs
+++ b/OpenXmlPowerTools/Chart/ChartUpdater.cs
@@ -1,65 +1,11 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using DocumentFormat.OpenXml.Packaging;
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
-using System.Text;
using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
-namespace OpenXmlPowerTools
+namespace Codeuctivity.OpenXmlPowerTools.Chart
{
- public enum ChartDataType
- {
- Number,
- String,
- DateTime,
- }
-
- // Format Codes
- // 0 - general
- // 1 - 0
- // 2 - 0.00
- // 3 - #,##0
- // 4 - #,##0.00
- // 9 - 0%
- // 10 - 0.00%
- // 11 - 0.00E+00
- // 12 - # ?/?
- // 13 - # ??/??
- // 14 - mm-dd-yy
- // 15 - d-mmm-yy
- // 16 - d-mmm
- // 17 - mmm-yy
- // 18 - h:mm AM/PM
- // 19 - h:mm:ss AM/PM
- // 20 - h:mm
- // 21 - h:mm:ss
- // 22 - m/d/yy h:mm
- // 37 - #,##0 ;(#,##0)
- // 38 - #,##0 ;[Red](#,##0)
- // 39 - #,##0.00;(#,##0.00)
- // 40 - #,##0.00;[Red](#,##0.00)
- // 45 - mm:ss
- // 46 - [h]:mm:ss
- // 47 - mmss.0
- // 48 - ##0.0E+0
- // 49 - @
-
- public class ChartData
- {
- public string[] SeriesNames;
-
- public ChartDataType CategoryDataType;
- public int CategoryFormatCode;
- public string[] CategoryNames;
-
- public double[][] Values;
- }
-
public class ChartUpdater
{
public static bool UpdateChart(WordprocessingDocument wDoc, string contentControlTag, ChartData chartData)
@@ -73,7 +19,7 @@ public static bool UpdateChart(WordprocessingDocument wDoc, string contentContro
var chartRid = (string)cc.Descendants(C.chart).Attributes(R.id).FirstOrDefault();
if (chartRid != null)
{
- ChartPart chartPart = (ChartPart)mainDocumentPart.GetPartById(chartRid);
+ var chartPart = (ChartPart)mainDocumentPart.GetPartById(chartRid);
UpdateChart(chartPart, chartData);
var newContent = cc.Elements(W.sdtContent).Elements().Select(e => new XElement(e));
cc.ReplaceWith(newContent);
@@ -84,20 +30,47 @@ public static bool UpdateChart(WordprocessingDocument wDoc, string contentContro
return false;
}
+ public static bool UpdateChart(PresentationDocument pDoc, int slideNumber, ChartData chartData)
+ {
+ var presentationPart = pDoc.PresentationPart;
+ var pXDoc = presentationPart.GetXDocument();
+ var sldIdElement = pXDoc.Root.Elements(P.sldIdLst).Elements(P.sldId).Skip(slideNumber - 1).FirstOrDefault();
+ if (sldIdElement != null)
+ {
+ var rId = (string)sldIdElement.Attribute(R.id);
+ var slidePart = presentationPart.GetPartById(rId);
+ var sXDoc = slidePart.GetXDocument();
+ var chartRid = (string)sXDoc.Descendants(C.chart).Attributes(R.id).FirstOrDefault();
+ if (chartRid != null)
+ {
+ var chartPart = (ChartPart)slidePart.GetPartById(chartRid);
+ UpdateChart(chartPart, chartData);
+ return true;
+ }
+ return true;
+ }
+ return false;
+ }
+
public static void UpdateChart(ChartPart chartPart, ChartData chartData)
{
if (chartData.Values.Length != chartData.SeriesNames.Length)
+ {
throw new ArgumentException("Invalid chart data");
+ }
+
foreach (var ser in chartData.Values)
{
if (ser.Length != chartData.CategoryNames.Length)
+ {
throw new ArgumentException("Invalid chart data");
+ }
}
UpdateSeries(chartPart, chartData);
}
- private static Dictionary FormatCodes = new Dictionary()
+ private static readonly Dictionary FormatCodes = new Dictionary()
{
{ 0, "general" },
{ 1, "0" },
@@ -133,34 +106,41 @@ private static void UpdateSeries(ChartPart chartPart, ChartData chartData)
{
UpdateEmbeddedWorkbook(chartPart, chartData);
- XDocument cpXDoc = chartPart.GetXDocument();
- XElement root = cpXDoc.Root;
+ var cpXDoc = chartPart.GetXDocument();
+ var root = cpXDoc.Root;
var firstSeries = root.Descendants(C.ser).FirstOrDefault();
var numRef = firstSeries.Elements(C.val).Elements(C.numRef).FirstOrDefault();
- string sheetName = null;
+ string? sheetName = null;
var f = (string)firstSeries.Descendants(C.f).FirstOrDefault();
if (f != null)
+ {
sheetName = f.Split('!')[0];
+ }
// remove all but first series
- XName chartType = firstSeries.Parent.Name;
+ var chartType = firstSeries.Parent.Name;
firstSeries.Parent.Elements(C.ser).Skip(1).Remove();
var newSetOfSeries = chartData.SeriesNames
- .Select((string sn, int si) =>
+ .Select((sn, si) =>
{
- XElement cat = null;
+ XElement? cat = null;
var oldCat = firstSeries.Elements(C.cat).FirstOrDefault();
if (oldCat == null)
+ {
throw new OpenXmlPowerToolsException("Invalid chart markup");
+ }
var catHasFormula = oldCat.Descendants(C.f).Any();
if (catHasFormula)
{
- XElement newFormula = null;
+ XElement? newFormula = null;
if (sheetName != null)
+ {
newFormula = new XElement(C.f, string.Format("{0}!$A$2:$A${1}", sheetName, chartData.CategoryNames.Length + 1));
+ }
+
if (chartData.CategoryDataType == ChartDataType.String)
{
cat = new XElement(C.cat,
@@ -223,7 +203,7 @@ private static void UpdateSeries(ChartPart chartPart, ChartData chartData)
}
}
- XElement newCval = null;
+ XElement? newCval = null;
if (sheetName == null)
{
@@ -257,12 +237,15 @@ private static void UpdateSeries(ChartPart chartPart, ChartData chartData)
}
var serHasFormula = firstSeries.Descendants(C.f).Any();
- XElement tx = null;
+ XElement? tx = null;
if (serHasFormula)
{
- XElement newFormula = null;
+ XElement? newFormula = null;
if (sheetName != null)
+ {
newFormula = new XElement(C.f, string.Format("{0}!${1}$1", sheetName, SpreadsheetMLUtil.IntToColumnId(si + 1)));
+ }
+
tx = new XElement(C.tx,
new XElement(C.strRef,
newFormula,
@@ -278,7 +261,7 @@ private static void UpdateSeries(ChartPart chartPart, ChartData chartData)
new XElement(C.v, chartData.SeriesNames[si]));
}
- XElement newSer = null;
+ XElement? newSer = null;
if (chartType == C.area3DChart || chartType == C.areaChart)
{
@@ -373,9 +356,11 @@ private static void UpdateSeries(ChartPart chartPart, ChartData chartData)
}
if (newSer == null)
+ {
throw new OpenXmlPowerToolsException("Unsupported chart type");
+ }
- int accentNumber = (si % 6) + 1;
+ var accentNumber = si % 6 + 1;
newSer = (XElement)UpdateAccentTransform(newSer, accentNumber);
return newSer;
});
@@ -385,120 +370,133 @@ private static void UpdateSeries(ChartPart chartPart, ChartData chartData)
private static void UpdateEmbeddedWorkbook(ChartPart chartPart, ChartData chartData)
{
- XDocument cpXDoc = chartPart.GetXDocument();
- XElement root = cpXDoc.Root;
+ var cpXDoc = chartPart.GetXDocument();
+ var root = cpXDoc.Root;
var firstSeries = root.Descendants(C.ser).FirstOrDefault();
if (firstSeries == null)
+ {
return;
+ }
+
var firstFormula = (string)firstSeries.Descendants(C.f).FirstOrDefault();
if (firstFormula == null)
+ {
return;
+ }
+
var sheet = firstFormula.Split('!')[0];
var embeddedSpreadsheetRid = (string)root.Descendants(C.externalData).Attributes(R.id).FirstOrDefault();
if (embeddedSpreadsheetRid == null)
+ {
return;
+ }
+
var embeddedSpreadsheet = chartPart.GetPartById(embeddedSpreadsheetRid);
if (embeddedSpreadsheet != null)
{
- using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(embeddedSpreadsheet.GetStream(), true))
+ using var sDoc = SpreadsheetDocument.Open(embeddedSpreadsheet.GetStream(), true);
+ var workbookPart = sDoc.WorkbookPart;
+ var wbRoot = workbookPart.GetXDocument().Root;
+ var sheetRid = (string)wbRoot
+ .Elements(S.sheets)
+ .Elements(S.sheet)
+ .Where(s => (string)s.Attribute("name") == sheet)
+ .Attributes(R.id)
+ .FirstOrDefault();
+ if (sheetRid != null)
{
- var workbookPart = sDoc.WorkbookPart;
- var wbRoot = workbookPart.GetXDocument().Root;
- var sheetRid = (string)wbRoot
- .Elements(S.sheets)
- .Elements(S.sheet)
- .Where(s => (string)s.Attribute("name") == sheet)
- .Attributes(R.id)
- .FirstOrDefault();
- if (sheetRid != null)
+ var sheetPart = workbookPart.GetPartById(sheetRid);
+ var xdSheet = sheetPart.GetXDocument();
+ var sheetData = xdSheet.Descendants(S.sheetData).FirstOrDefault();
+
+ var stylePart = workbookPart.WorkbookStylesPart;
+ var xdStyle = stylePart.GetXDocument();
+
+ var categoryStyleId = 0;
+ if (chartData.CategoryFormatCode != 0)
{
- var sheetPart = workbookPart.GetPartById(sheetRid);
- var xdSheet = sheetPart.GetXDocument();
- var sheetData = xdSheet.Descendants(S.sheetData).FirstOrDefault();
-
- var stylePart = workbookPart.WorkbookStylesPart;
- var xdStyle = stylePart.GetXDocument();
-
- int categoryStyleId = 0;
- if (chartData.CategoryFormatCode != 0)
- categoryStyleId = AddDxfToDxfs(xdSheet, xdStyle, chartData.CategoryFormatCode);
- stylePart.PutXDocument();
-
- var firstRow = new XElement(S.row,
- new XAttribute("r", "1"),
- new XAttribute("spans", string.Format("1:{0}", chartData.SeriesNames.Length + 1)),
- new [] { new XElement(S.c,
+ categoryStyleId = AddDxfToDxfs(xdSheet, xdStyle, chartData.CategoryFormatCode);
+ }
+
+ stylePart.PutXDocument();
+
+ var firstRow = new XElement(S.row,
+ new XAttribute("r", "1"),
+ new XAttribute("spans", string.Format("1:{0}", chartData.SeriesNames.Length + 1)),
+ new[] { new XElement(S.c,
new XAttribute("r", "A1"),
new XAttribute("t", "str"),
new XElement(S.v,
new XAttribute(XNamespace.Xml + "space", "preserve"),
" "))}
- .Concat(
- chartData.SeriesNames
- .Select((sn, i) => new XElement(S.c,
- new XAttribute("r", RowColToString(0, i + 1)),
- new XAttribute("t", "str"),
- new XElement(S.v, sn)))));
- var otherRows = chartData
- .CategoryNames
- .Select((cn, r) =>
- {
- var row = new XElement(S.row,
- new XAttribute("r", r + 2),
- new XAttribute("spans", string.Format("1:{0}", chartData.SeriesNames.Length + 1)),
- new[] {
+ .Concat(
+ chartData.SeriesNames
+ .Select((sn, i) => new XElement(S.c,
+ new XAttribute("r", RowColToString(0, i + 1)),
+ new XAttribute("t", "str"),
+ new XElement(S.v, sn)))));
+ var otherRows = chartData
+ .CategoryNames
+ .Select((cn, r) =>
+ {
+ var row = new XElement(S.row,
+ new XAttribute("r", r + 2),
+ new XAttribute("spans", string.Format("1:{0}", chartData.SeriesNames.Length + 1)),
+ new[] {
new XElement(S.c,
new XAttribute("r", RowColToString(r + 1, 0)),
categoryStyleId != 0 ? new XAttribute("s", categoryStyleId) : null,
chartData.CategoryDataType == ChartDataType.String ? new XAttribute("t", "str") : null,
new XElement(S.v, cn))
- }.Concat(
- Enumerable.Range(0, chartData.Values.Length)
- .Select((c, ci) =>
- {
- var cell = new XElement(S.c,
- new XAttribute("r", RowColToString(r + 1, ci + 1)),
- new XElement(S.v, chartData.Values[ci][r]));
- return cell;
- })));
- return row;
- });
- var allRows = new[] {
+ }.Concat(
+ Enumerable.Range(0, chartData.Values.Length)
+ .Select((c, ci) =>
+ {
+ var cell = new XElement(S.c,
+ new XAttribute("r", RowColToString(r + 1, ci + 1)),
+ new XElement(S.v, chartData.Values[ci][r]));
+ return cell;
+ })));
+ return row;
+ });
+ var allRows = new[] {
firstRow
}.Concat(otherRows);
- var newSheetData = new XElement(S.sheetData,
- allRows);
- sheetData.ReplaceWith(newSheetData);
- sheetPart.PutXDocument();
-
- var tablePartRid = (string)xdSheet
- .Root
- .Elements(S.tableParts)
- .Elements(S.tablePart)
- .Attributes(R.id)
- .FirstOrDefault();
- if (tablePartRid != null)
- {
- var partTable = sheetPart.GetPartById(tablePartRid);
- var xdTablePart = partTable.GetXDocument();
- var xaRef = xdTablePart.Root.Attribute("ref");
- xaRef.Value = string.Format("A1:{0}", RowColToString(chartData.CategoryNames.Length - 1, chartData.SeriesNames.Length));
- var xeNewTableColumns = new XElement(S.tableColumns,
- new XAttribute("count", chartData.SeriesNames.Count() + 1),
- new[] {
+ var newSheetData = new XElement(S.sheetData,
+ allRows);
+ sheetData.ReplaceWith(newSheetData);
+ sheetPart.PutXDocument();
+
+ var tablePartRid = (string)xdSheet
+ .Root
+ .Elements(S.tableParts)
+ .Elements(S.tablePart)
+ .Attributes(R.id)
+ .FirstOrDefault();
+ if (tablePartRid != null)
+ {
+ var partTable = sheetPart.GetPartById(tablePartRid);
+ var xdTablePart = partTable.GetXDocument();
+ var xaRef = xdTablePart.Root.Attribute("ref");
+ xaRef.Value = string.Format("A1:{0}", RowColToString(chartData.CategoryNames.Length - 1, chartData.SeriesNames.Length));
+ var xeNewTableColumns = new XElement(S.tableColumns,
+ new XAttribute("count", chartData.SeriesNames.Length + 1),
+ new[] {
new XElement(S.tableColumn,
new XAttribute("id", 1),
new XAttribute("name", " "))
- }.Concat(
- chartData.SeriesNames.Select((cn, ci) =>
- new XElement(S.tableColumn,
- new XAttribute("id", ci + 2),
- new XAttribute("name", cn)))));
- var xeExistingTableColumns = xdTablePart.Root.Element(S.tableColumns);
- if (xeExistingTableColumns != null)
- xeExistingTableColumns.ReplaceWith(xeNewTableColumns);
- partTable.PutXDocument();
+ }.Concat(
+ chartData.SeriesNames.Select((cn, ci) =>
+ new XElement(S.tableColumn,
+ new XAttribute("id", ci + 2),
+ new XAttribute("name", cn)))));
+ var xeExistingTableColumns = xdTablePart.Root.Element(S.tableColumns);
+ if (xeExistingTableColumns != null)
+ {
+ xeExistingTableColumns.ReplaceWith(xeNewTableColumns);
}
+
+ partTable.PutXDocument();
}
}
}
@@ -541,7 +539,9 @@ private static int AddDxfToDxfs(XDocument xdSheet, XDocument xdStyle, int format
}
}
if (cellXfs == null)
+ {
throw new OpenXmlPowerToolsException("Internal error");
+ }
var cnt = (int)cellXfs.Attribute("count");
cnt++;
@@ -564,11 +564,12 @@ private static string RowColToString(int row, int col)
private static object UpdateAccentTransform(XNode node, int accentNumber)
{
- XElement element = node as XElement;
- if (element != null)
+ if (node is XElement element)
{
if (element.Name == A.schemeClr && (string)element.Attribute("val") == "accent1")
+ {
return new XElement(A.schemeClr, new XAttribute("val", "accent" + accentNumber));
+ }
return new XElement(element.Name,
element.Attributes(),
@@ -576,27 +577,5 @@ private static object UpdateAccentTransform(XNode node, int accentNumber)
}
return node;
}
-
- public static bool UpdateChart(PresentationDocument pDoc, int slideNumber, ChartData chartData)
- {
- var presentationPart = pDoc.PresentationPart;
- var pXDoc = presentationPart.GetXDocument();
- var sldIdElement = pXDoc.Root.Elements(P.sldIdLst).Elements(P.sldId).Skip(slideNumber - 1).FirstOrDefault();
- if (sldIdElement != null)
- {
- var rId = (string)sldIdElement.Attribute(R.id);
- var slidePart = presentationPart.GetPartById(rId);
- var sXDoc = slidePart.GetXDocument();
- var chartRid = (string)sXDoc.Descendants(C.chart).Attributes(R.id).FirstOrDefault();
- if (chartRid != null)
- {
- ChartPart chartPart = (ChartPart)slidePart.GetPartById(chartRid);
- UpdateChart(chartPart, chartData);
- return true;
- }
- return true;
- }
- return false;
- }
}
}
\ No newline at end of file
diff --git a/OpenXmlPowerTools/ColorParser.cs b/OpenXmlPowerTools/ColorParser.cs
index 7539e9fd..993abb4f 100644
--- a/OpenXmlPowerTools/ColorParser.cs
+++ b/OpenXmlPowerTools/ColorParser.cs
@@ -1,29 +1,37 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using SkiaSharp;
+using System;
using System.Drawing;
-namespace OpenXmlPowerTools
+namespace Codeuctivity.OpenXmlPowerTools
{
public static class ColorParser
{
- public static Color FromName(string name)
+ public static SKColor FromName(string name)
{
- return Color.FromName(name);
+ if (!TryFromName(name, out var color))
+ {
+ throw new ArgumentException("Invalid color name", nameof(name));
+ }
+ return color;
}
- public static bool TryFromName(string name, out Color color)
+ public static bool TryFromName(string? name, out SKColor color)
{
- try
+ if (string.IsNullOrWhiteSpace(name))
{
- color = Color.FromName(name);
+ color = default;
+ return false;
+ }
- return color.IsNamedColor;
+ try
+ {
+ var drawingColor = ColorTranslator.FromHtml(name);
+ color = new SKColor(drawingColor.R, drawingColor.G, drawingColor.B, drawingColor.A);
+ return true;
}
catch
{
- color = default(Color);
-
+ color = default;
return false;
}
}
diff --git a/OpenXmlPowerTools/DocumentAssembler.cs b/OpenXmlPowerTools/DocumentAssembler/DocumentAssembler.cs
similarity index 82%
rename from OpenXmlPowerTools/DocumentAssembler.cs
rename to OpenXmlPowerTools/DocumentAssembler/DocumentAssembler.cs
index f4d9673e..c838e7bf 100644
--- a/OpenXmlPowerTools/DocumentAssembler.cs
+++ b/OpenXmlPowerTools/DocumentAssembler/DocumentAssembler.cs
@@ -1,57 +1,51 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
+using DocumentFormat.OpenXml.Packaging;
using System;
+using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
-using System.Xml.XPath;
using System.Xml.Schema;
-using DocumentFormat.OpenXml.Office.CustomUI;
-using DocumentFormat.OpenXml.Packaging;
-using OpenXmlPowerTools;
-using System.Collections;
+using System.Xml.XPath;
-namespace OpenXmlPowerTools
+namespace Codeuctivity.OpenXmlPowerTools
{
- public class DocumentAssembler
+ public partial class DocumentAssembler
{
public static WmlDocument AssembleDocument(WmlDocument templateDoc, XmlDocument data, out bool templateError)
{
- XDocument xDoc = data.GetXDocument();
+ var xDoc = data.GetXDocument();
return AssembleDocument(templateDoc, xDoc.Root, out templateError);
}
public static WmlDocument AssembleDocument(WmlDocument templateDoc, XElement data, out bool templateError)
{
- byte[] byteArray = templateDoc.DocumentByteArray;
- using (MemoryStream mem = new MemoryStream())
+ var byteArray = templateDoc.DocumentByteArray;
+ using var mem = new MemoryStream();
+ mem.Write(byteArray, 0, byteArray.Length);
+ using (var wordDoc = WordprocessingDocument.Open(mem, true))
{
- mem.Write(byteArray, 0, (int)byteArray.Length);
- using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(mem, true))
+ if (RevisionAccepter.HasTrackedRevisions(wordDoc))
{
- if (RevisionAccepter.HasTrackedRevisions(wordDoc))
- throw new OpenXmlPowerToolsException("Invalid DocumentAssembler template - contains tracked revisions");
+ throw new OpenXmlPowerToolsException("Invalid DocumentAssembler template - contains tracked revisions");
+ }
- var te = new TemplateError();
- foreach (var part in wordDoc.ContentParts())
- {
- ProcessTemplatePart(data, te, part);
- }
- templateError = te.HasError;
+ var te = new TemplateError();
+ foreach (var part in wordDoc.ContentParts())
+ {
+ ProcessTemplatePart(data, te, part);
}
- WmlDocument assembledDocument = new WmlDocument("TempFileName.docx", mem.ToArray());
- return assembledDocument;
+ templateError = te.HasError;
}
+ var assembledDocument = new WmlDocument("TempFileName.docx", mem.ToArray());
+ return assembledDocument;
}
private static void ProcessTemplatePart(XElement data, TemplateError te, OpenXmlPart part)
{
- XDocument xDoc = part.GetXDocument();
+ var xDoc = part.GetXDocument();
var xDocRoot = RemoveGoBackBookmarks(xDoc.Root);
@@ -72,14 +66,14 @@ private static void ProcessTemplatePart(XElement data, TemplateError te, OpenXml
ProcessOrphanEndRepeatEndConditional(xDocRoot, te);
// do the actual content replacement
- xDocRoot = (XElement)ContentReplacementTransform(xDocRoot, data, te);
+ xDocRoot = ContentReplacementTransform(xDocRoot, data, te) as XElement;
xDoc.Elements().First().ReplaceWith(xDocRoot);
part.PutXDocument();
return;
}
- private static XName[] s_MetaToForceToBlock = new XName[] {
+ private static readonly XName[] s_MetaToForceToBlock = new XName[] {
PA.Conditional,
PA.EndConditional,
PA.Repeat,
@@ -89,20 +83,19 @@ private static void ProcessTemplatePart(XElement data, TemplateError te, OpenXml
private static object ForceBlockLevelAsAppropriate(XNode node, TemplateError te)
{
- XElement element = node as XElement;
- if (element != null)
+ if (node is XElement element)
{
if (element.Name == W.p)
{
var childMeta = element.Elements().Where(n => s_MetaToForceToBlock.Contains(n.Name)).ToList();
- if (childMeta.Count() == 1)
+ if (childMeta.Count == 1)
{
var child = childMeta.First();
var otherTextInParagraph = element.Elements(W.r).Elements(W.t).Select(t => (string)t).StringConcatenate().Trim();
if (otherTextInParagraph != "")
{
var newPara = new XElement(element);
- var newMeta = newPara.Elements().Where(n => s_MetaToForceToBlock.Contains(n.Name)).First();
+ var newMeta = newPara.Elements().First(n => s_MetaToForceToBlock.Contains(n.Name));
newMeta.ReplaceWith(CreateRunErrorMessage("Error: Unmatched metadata can't be in paragraph with other text", te));
return newPara;
}
@@ -114,13 +107,19 @@ private static object ForceBlockLevelAsAppropriate(XNode node, TemplateError te)
child.Elements()));
return meta;
}
- var count = childMeta.Count();
+ var count = childMeta.Count;
if (count % 2 == 0)
{
if (childMeta.Where(c => c.Name == PA.Repeat).Count() != childMeta.Where(c => c.Name == PA.EndRepeat).Count())
+ {
return CreateContextErrorMessage(element, "Error: Mismatch Repeat / EndRepeat at run level", te);
+ }
+
if (childMeta.Where(c => c.Name == PA.Conditional).Count() != childMeta.Where(c => c.Name == PA.EndConditional).Count())
+ {
return CreateContextErrorMessage(element, "Error: Mismatch Conditional / EndConditional at run level", te);
+ }
+
return new XElement(element.Name,
element.Attributes(),
element.Nodes().Select(n => ForceBlockLevelAsAppropriate(n, te)));
@@ -158,7 +157,10 @@ private static XElement RemoveGoBackBookmarks(XElement xElement)
{
var bm = cloneXDoc.DescendantsAndSelf(W.bookmarkStart).FirstOrDefault(b => (string)b.Attribute(W.name) == "_GoBack");
if (bm == null)
+ {
break;
+ }
+
var id = (string)bm.Attribute(W.id);
var endBm = cloneXDoc.DescendantsAndSelf(W.bookmarkEnd).FirstOrDefault(b => (string)b.Attribute(W.id) == id);
bm.Remove();
@@ -171,8 +173,7 @@ private static XElement RemoveGoBackBookmarks(XElement xElement)
// the content control, which contains the paragraph content of the cell.
private static object NormalizeContentControlsInCells(XNode node)
{
- XElement element = node as XElement;
- if (element != null)
+ if (node is XElement element)
{
if (element.Name == W.sdt && element.Parent.Name == W.tr)
{
@@ -200,7 +201,7 @@ private static void NormalizeTablesRepeatAndConditional(XElement xDoc, TemplateE
var tables = xDoc.Descendants(PA.Table).ToList();
foreach (var table in tables)
{
- var followingElement = table.ElementsAfterSelf().Where(e => e.Name == W.tbl || e.Name == W.p).FirstOrDefault();
+ var followingElement = table.ElementsAfterSelf().FirstOrDefault(e => e.Name == W.tbl || e.Name == W.p);
if (followingElement == null || followingElement.Name != W.tbl)
{
table.ReplaceWith(CreateParaErrorMessage("Table metadata is not immediately followed by a table", te));
@@ -213,8 +214,8 @@ private static void NormalizeTablesRepeatAndConditional(XElement xDoc, TemplateE
table.Add(followingElement);
}
- int repeatDepth = 0;
- int conditionalDepth = 0;
+ var repeatDepth = 0;
+ var conditionalDepth = 0;
foreach (var metadata in xDoc.Descendants().Where(d =>
d.Name == PA.Repeat ||
d.Name == PA.Conditional ||
@@ -249,17 +250,25 @@ private static void NormalizeTablesRepeatAndConditional(XElement xDoc, TemplateE
while (true)
{
- bool didReplace = false;
+ var didReplace = false;
foreach (var metadata in xDoc.Descendants().Where(d => (d.Name == PA.Repeat || d.Name == PA.Conditional) && d.Attribute(PA.Depth) != null).ToList())
{
var depth = (int)metadata.Attribute(PA.Depth);
- XName matchingEndName = null;
+ XName? matchingEndName = null;
if (metadata.Name == PA.Repeat)
+ {
matchingEndName = PA.EndRepeat;
+ }
else if (metadata.Name == PA.Conditional)
+ {
matchingEndName = PA.EndConditional;
+ }
+
if (matchingEndName == null)
+ {
throw new OpenXmlPowerToolsException("Internal error");
+ }
+
var matchingEnd = metadata.ElementsAfterSelf(matchingEndName).FirstOrDefault(end => { return (int)end.Attribute(PA.Depth) == depth; });
if (matchingEnd == null)
{
@@ -269,7 +278,10 @@ private static void NormalizeTablesRepeatAndConditional(XElement xDoc, TemplateE
metadata.RemoveNodes();
var contentBetween = metadata.ElementsAfterSelf().TakeWhile(after => after != matchingEnd).ToList();
foreach (var item in contentBetween)
+ {
item.Remove();
+ }
+
contentBetween = contentBetween.Where(n => n.Name != W.bookmarkStart && n.Name != W.bookmarkEnd).ToList();
metadata.Add(contentBetween);
metadata.Attributes(PA.Depth).Remove();
@@ -278,11 +290,13 @@ private static void NormalizeTablesRepeatAndConditional(XElement xDoc, TemplateE
break;
}
if (!didReplace)
+ {
break;
+ }
}
}
- private static List s_AliasList = new List()
+ private static readonly List s_AliasList = new List()
{
"Content",
"Table",
@@ -294,8 +308,7 @@ private static void NormalizeTablesRepeatAndConditional(XElement xDoc, TemplateE
private static object TransformToMetadata(XNode node, XElement data, TemplateError te)
{
- XElement element = node as XElement;
- if (element != null)
+ if (node is XElement element)
{
if (element.Name == W.sdt)
{
@@ -312,19 +325,26 @@ private static object TransformToMetadata(XNode node, XElement data, TemplateErr
.Replace('”', '"');
if (ccContents.StartsWith("<"))
{
- XElement xml = TransformXmlTextToMetadata(te, ccContents);
+ var xml = TransformXmlTextToMetadata(te, ccContents);
if (xml.Name == W.p || xml.Name == W.r) // this means there was an error processing the XML.
{
if (element.Parent.Name == W.p)
+ {
return xml.Elements(W.r);
+ }
+
return xml;
}
if (alias != null && xml.Name.LocalName != alias)
{
if (element.Parent.Name == W.p)
+ {
return CreateRunErrorMessage("Error: Content control alias does not match metadata element name", te);
+ }
else
+ {
return CreateParaErrorMessage("Error: Content control alias does not match metadata element name", te);
+ }
}
xml.Add(element.Elements(W.sdtContent).Elements());
return xml;
@@ -345,22 +365,25 @@ private static object TransformToMetadata(XNode node, XElement data, TemplateErr
.Select(t => (string)t)
.StringConcatenate()
.Trim();
- int occurances = paraContents.Select((c, i) => paraContents.Substring(i)).Count(sub => sub.StartsWith("<#"));
+ var occurances = paraContents.Select((c, i) => paraContents.Substring(i)).Count(sub => sub.StartsWith("<#"));
if (paraContents.StartsWith("<#") && paraContents.EndsWith("#>") && occurances == 1)
{
var xmlText = paraContents.Substring(2, paraContents.Length - 4).Trim();
- XElement xml = TransformXmlTextToMetadata(te, xmlText);
+ var xml = TransformXmlTextToMetadata(te, xmlText);
if (xml.Name == W.p || xml.Name == W.r)
+ {
return xml;
+ }
+
xml.Add(element);
return xml;
}
if (paraContents.Contains("<#"))
{
- List runReplacementInfo = new List();
+ var runReplacementInfo = new List();
var thisGuid = Guid.NewGuid().ToString();
var r = new Regex("<#.*?#>");
- XElement xml = null;
+ XElement? xml = null;
OpenXmlRegex.Replace(new[] { element }, r, thisGuid, (para, match) =>
{
var matchString = match.Value.Trim();
@@ -371,7 +394,7 @@ private static object TransformToMetadata(XNode node, XElement data, TemplateErr
}
catch (XmlException e)
{
- RunReplacementInfo rri = new RunReplacementInfo()
+ var rri = new RunReplacementInfo()
{
Xml = null,
XmlExceptionMessage = "XmlException: " + e.Message,
@@ -380,10 +403,10 @@ private static object TransformToMetadata(XNode node, XElement data, TemplateErr
runReplacementInfo.Add(rri);
return true;
}
- string schemaError = ValidatePerSchema(xml);
+ var schemaError = ValidatePerSchema(xml);
if (schemaError != null)
{
- RunReplacementInfo rri = new RunReplacementInfo()
+ var rri = new RunReplacementInfo()
{
Xml = null,
XmlExceptionMessage = null,
@@ -392,7 +415,7 @@ private static object TransformToMetadata(XNode node, XElement data, TemplateErr
runReplacementInfo.Add(rri);
return true;
}
- RunReplacementInfo rri2 = new RunReplacementInfo()
+ var rri2 = new RunReplacementInfo()
{
Xml = xml,
XmlExceptionMessage = null,
@@ -407,11 +430,18 @@ private static object TransformToMetadata(XNode node, XElement data, TemplateErr
{
var runToReplace = newPara.Descendants(W.r).FirstOrDefault(rn => rn.Value == thisGuid && rn.Parent.Name != PA.Content);
if (runToReplace == null)
+ {
throw new OpenXmlPowerToolsException("Internal error");
+ }
+
if (rri.XmlExceptionMessage != null)
+ {
runToReplace.ReplaceWith(CreateRunErrorMessage(rri.XmlExceptionMessage, te));
+ }
else if (rri.SchemaValidationMessage != null)
+ {
runToReplace.ReplaceWith(CreateRunErrorMessage(rri.SchemaValidationMessage, te));
+ }
else
{
var newXml = new XElement(rri.Xml);
@@ -442,20 +472,23 @@ private static XElement TransformXmlTextToMetadata(TemplateError te, string xmlT
{
return CreateParaErrorMessage("XmlException: " + e.Message, te);
}
- string schemaError = ValidatePerSchema(xml);
+ var schemaError = ValidatePerSchema(xml);
if (schemaError != null)
+ {
return CreateParaErrorMessage("Schema Validation Error: " + schemaError, te);
+ }
+
return xml;
}
private class RunReplacementInfo
{
- public XElement Xml;
- public string XmlExceptionMessage;
- public string SchemaValidationMessage;
+ public XElement? Xml;
+ public string? XmlExceptionMessage;
+ public string? SchemaValidationMessage;
}
- private static string ValidatePerSchema(XElement element)
+ private static string? ValidatePerSchema(XElement element)
{
if (s_PASchemaSets == null)
{
@@ -539,7 +572,7 @@ private static string ValidatePerSchema(XElement element)
foreach (var item in s_PASchemaSets)
{
var itemPAss = item.Value;
- XmlSchemaSet schemas = new XmlSchemaSet();
+ var schemas = new XmlSchemaSet();
schemas.Add("", XmlReader.Create(new StringReader(itemPAss.XsdMarkup)));
itemPAss.SchemaSet = schemas;
}
@@ -549,60 +582,37 @@ private static string ValidatePerSchema(XElement element)
return string.Format("Invalid XML: {0} is not a valid element", element.Name.LocalName);
}
var paSchemaSet = s_PASchemaSets[element.Name];
- XDocument d = new XDocument(element);
- string message = null;
+ var d = new XDocument(element);
+ string? message = null;
d.Validate(paSchemaSet.SchemaSet, (sender, e) =>
{
if (message == null)
+ {
message = e.Message;
+ }
}, true);
if (message != null)
+ {
return message;
- return null;
- }
-
- private class PA
- {
- public static XName Content = "Content";
- public static XName Table = "Table";
- public static XName Repeat = "Repeat";
- public static XName EndRepeat = "EndRepeat";
- public static XName Conditional = "Conditional";
- public static XName EndConditional = "EndConditional";
-
- public static XName Select = "Select";
- public static XName Optional = "Optional";
- public static XName Match = "Match";
- public static XName NotMatch = "NotMatch";
- public static XName Depth = "Depth";
- }
+ }
- private class PASchemaSet
- {
- public string XsdMarkup;
- public XmlSchemaSet SchemaSet;
+ return null;
}
- private static Dictionary s_PASchemaSets = null;
+ private static Dictionary s_PASchemaSets;
- private class TemplateError
+ private static object? ContentReplacementTransform(XNode node, XElement data, TemplateError templateError)
{
- public bool HasError = false;
- }
-
- static object ContentReplacementTransform(XNode node, XElement data, TemplateError templateError)
- {
- XElement element = node as XElement;
- if (element != null)
+ if (node is XElement element)
{
if (element.Name == PA.Content)
{
- XElement para = element.Descendants(W.p).FirstOrDefault();
- XElement run = element.Descendants(W.r).FirstOrDefault();
+ var para = element.Descendants(W.p).FirstOrDefault();
+ var run = element.Descendants(W.r).FirstOrDefault();
- var xPath = (string) element.Attribute(PA.Select);
- var optionalString = (string) element.Attribute(PA.Optional);
- bool optional = (optionalString != null && optionalString.ToLower() == "true");
+ var xPath = (string)element.Attribute(PA.Select);
+ var optionalString = (string)element.Attribute(PA.Optional);
+ var optional = (optionalString != null && optionalString.ToLower() == "true");
string newValue;
try
@@ -616,9 +626,8 @@ static object ContentReplacementTransform(XNode node, XElement data, TemplateErr
if (para != null)
{
-
- XElement p = new XElement(W.p, para.Elements(W.pPr));
- foreach(string line in newValue.Split('\n'))
+ var p = new XElement(W.p, para.Elements(W.pPr));
+ foreach (var line in newValue.Split('\n'))
{
p.Add(new XElement(W.r,
para.Elements(W.r).Elements(W.rPr).FirstOrDefault(),
@@ -629,8 +638,8 @@ static object ContentReplacementTransform(XNode node, XElement data, TemplateErr
}
else
{
- List list = new List();
- foreach(string line in newValue.Split('\n'))
+ var list = new List();
+ foreach (var line in newValue.Split('\n'))
{
list.Add(new XElement(W.r,
run.Elements().Where(e => e.Name != W.t),
@@ -642,9 +651,9 @@ static object ContentReplacementTransform(XNode node, XElement data, TemplateErr
}
if (element.Name == PA.Repeat)
{
- string selector = (string)element.Attribute(PA.Select);
+ var selector = (string)element.Attribute(PA.Select);
var optionalString = (string)element.Attribute(PA.Optional);
- bool optional = (optionalString != null && optionalString.ToLower() == "true");
+ var optional = (optionalString != null && optionalString.ToLower() == "true");
IEnumerable repeatingData;
try
@@ -660,11 +669,6 @@ static object ContentReplacementTransform(XNode node, XElement data, TemplateErr
if (optional)
{
return null;
- //XElement para = element.Descendants(W.p).FirstOrDefault();
- //if (para != null)
- // return new XElement(W.p, new XElement(W.r));
- //else
- // return new XElement(W.r);
}
return CreateContextErrorMessage(element, "Repeat: Select returned no data", templateError);
}
@@ -690,10 +694,13 @@ static object ContentReplacementTransform(XNode node, XElement data, TemplateErr
{
return CreateContextErrorMessage(element, "XPathException: " + e.Message, templateError);
}
- if (tableData.Count() == 0)
+ if (!tableData.Any())
+ {
return CreateContextErrorMessage(element, "Table Select returned no data", templateError);
- XElement table = element.Element(W.tbl);
- XElement protoRow = table.Elements(W.tr).Skip(1).FirstOrDefault();
+ }
+
+ var table = element.Element(W.tbl);
+ var protoRow = table.Elements(W.tr).Skip(1).FirstOrDefault();
var footerRowsBeforeTransform = table
.Elements(W.tr)
.Skip(2)
@@ -702,10 +709,13 @@ static object ContentReplacementTransform(XNode node, XElement data, TemplateErr
.Select(x => ContentReplacementTransform(x, data, templateError))
.ToList();
if (protoRow == null)
+ {
return CreateContextErrorMessage(element, string.Format("Table does not contain a prototype row"), templateError);
+ }
+
protoRow.Descendants(W.bookmarkStart).Remove();
protoRow.Descendants(W.bookmarkEnd).Remove();
- XElement newTable = new XElement(W.tbl,
+ var newTable = new XElement(W.tbl,
table.Elements().Where(e => e.Name != W.tr),
table.Elements(W.tr).FirstOrDefault(),
tableData.Select(d =>
@@ -714,17 +724,17 @@ static object ContentReplacementTransform(XNode node, XElement data, TemplateErr
protoRow.Elements(W.tc)
.Select(tc =>
{
- XElement paragraph = tc.Elements(W.p).FirstOrDefault();
- XElement cellRun = paragraph.Elements(W.r).FirstOrDefault();
- string xPath = paragraph.Value;
- string newValue = null;
+ var paragraph = tc.Elements(W.p).FirstOrDefault();
+ var cellRun = paragraph.Elements(W.r).FirstOrDefault();
+ var xPath = paragraph.Value;
+ string? newValue = null;
try
{
newValue = EvaluateXPathToString(d, xPath, false);
}
catch (XPathException e)
{
- XElement errorCell = new XElement(W.tc,
+ var errorCell = new XElement(W.tc,
tc.Elements().Where(z => z.Name != W.p),
new XElement(W.p,
paragraph.Element(W.pPr),
@@ -732,7 +742,7 @@ static object ContentReplacementTransform(XNode node, XElement data, TemplateErr
return errorCell;
}
- XElement newCell = new XElement(W.tc,
+ var newCell = new XElement(W.tc,
tc.Elements().Where(z => z.Name != W.p),
new XElement(W.p,
paragraph.Element(W.pPr),
@@ -747,26 +757,31 @@ static object ContentReplacementTransform(XNode node, XElement data, TemplateErr
}
if (element.Name == PA.Conditional)
{
- string xPath = (string)element.Attribute(PA.Select);
+ var xPath = (string)element.Attribute(PA.Select);
var match = (string)element.Attribute(PA.Match);
var notMatch = (string)element.Attribute(PA.NotMatch);
if (match == null && notMatch == null)
+ {
return CreateContextErrorMessage(element, "Conditional: Must specify either Match or NotMatch", templateError);
+ }
+
if (match != null && notMatch != null)
+ {
return CreateContextErrorMessage(element, "Conditional: Cannot specify both Match and NotMatch", templateError);
+ }
+
+ string? testValue = null;
- string testValue = null;
-
try
{
testValue = EvaluateXPathToString(data, xPath, false);
}
- catch (XPathException e)
+ catch (XPathException e)
{
return CreateContextErrorMessage(element, e.Message, templateError);
}
-
+
if ((match != null && testValue == match) || (notMatch != null && testValue != notMatch))
{
var content = element.Elements().Select(e => ContentReplacementTransform(e, data, templateError));
@@ -783,13 +798,16 @@ static object ContentReplacementTransform(XNode node, XElement data, TemplateErr
private static object CreateContextErrorMessage(XElement element, string errorMessage, TemplateError templateError)
{
- XElement para = element.Descendants(W.p).FirstOrDefault();
- XElement run = element.Descendants(W.r).FirstOrDefault();
+ var para = element.Descendants(W.p).FirstOrDefault();
var errorRun = CreateRunErrorMessage(errorMessage, templateError);
if (para != null)
+ {
return new XElement(W.p, errorRun);
+ }
else
+ {
return errorRun;
+ }
}
private static XElement CreateRunErrorMessage(string errorMessage, TemplateError templateError)
@@ -815,14 +833,17 @@ private static XElement CreateParaErrorMessage(string errorMessage, TemplateErro
return errorPara;
}
- private static string EvaluateXPathToString(XElement element, string xPath, bool optional )
+ private static string EvaluateXPathToString(XElement element, string xPath, bool optional)
{
object xPathSelectResult;
try
{
//support some cells in the table may not have an xpath expression.
- if (String.IsNullOrWhiteSpace(xPath)) return String.Empty;
-
+ if (string.IsNullOrWhiteSpace(xPath))
+ {
+ return string.Empty;
+ }
+
xPathSelectResult = element.XPathEvaluate(xPath);
}
catch (XPathException e)
@@ -832,10 +853,14 @@ private static string EvaluateXPathToString(XElement element, string xPath, bool
if ((xPathSelectResult is IEnumerable) && !(xPathSelectResult is string))
{
- var selectedData = ((IEnumerable) xPathSelectResult).Cast();
+ var selectedData = ((IEnumerable)xPathSelectResult).Cast();
if (!selectedData.Any())
{
- if (optional) return string.Empty;
+ if (optional)
+ {
+ return string.Empty;
+ }
+
throw new XPathException(string.Format("XPath expression ({0}) returned no results", xPath));
}
if (selectedData.Count() > 1)
@@ -843,15 +868,20 @@ private static string EvaluateXPathToString(XElement element, string xPath, bool
throw new XPathException(string.Format("XPath expression ({0}) returned more than one node", xPath));
}
- XObject selectedDatum = selectedData.First();
-
- if (selectedDatum is XElement) return ((XElement) selectedDatum).Value;
+ var selectedDatum = selectedData.First();
- if (selectedDatum is XAttribute) return ((XAttribute) selectedDatum).Value;
+ if (selectedDatum is XElement element1)
+ {
+ return element1.Value;
+ }
+
+ if (selectedDatum is XAttribute)
+ {
+ return ((XAttribute)selectedDatum).Value;
+ }
}
return xPathSelectResult.ToString();
-
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools/DocumentAssembler/PA.cs b/OpenXmlPowerTools/DocumentAssembler/PA.cs
new file mode 100644
index 00000000..a4482288
--- /dev/null
+++ b/OpenXmlPowerTools/DocumentAssembler/PA.cs
@@ -0,0 +1,22 @@
+using System.Xml.Linq;
+
+namespace Codeuctivity.OpenXmlPowerTools
+{
+ public partial class DocumentAssembler
+ {
+ private static class PA
+ {
+ public static readonly XName Content = "Content";
+ public static readonly XName Table = "Table";
+ public static readonly XName Repeat = "Repeat";
+ public static readonly XName EndRepeat = "EndRepeat";
+ public static readonly XName Conditional = "Conditional";
+ public static readonly XName EndConditional = "EndConditional";
+ public static readonly XName Select = "Select";
+ public static readonly XName Optional = "Optional";
+ public static readonly XName Match = "Match";
+ public static readonly XName NotMatch = "NotMatch";
+ public static readonly XName Depth = "Depth";
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools/DocumentAssembler/PASchemaSet.cs b/OpenXmlPowerTools/DocumentAssembler/PASchemaSet.cs
new file mode 100644
index 00000000..f0fa1209
--- /dev/null
+++ b/OpenXmlPowerTools/DocumentAssembler/PASchemaSet.cs
@@ -0,0 +1,13 @@
+using System.Xml.Schema;
+
+namespace Codeuctivity.OpenXmlPowerTools
+{
+ public partial class DocumentAssembler
+ {
+ private class PASchemaSet
+ {
+ public string XsdMarkup;
+ public XmlSchemaSet SchemaSet;
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools/DocumentAssembler/TemplateError.cs b/OpenXmlPowerTools/DocumentAssembler/TemplateError.cs
new file mode 100644
index 00000000..e533ddfb
--- /dev/null
+++ b/OpenXmlPowerTools/DocumentAssembler/TemplateError.cs
@@ -0,0 +1,10 @@
+namespace Codeuctivity.OpenXmlPowerTools
+{
+ public partial class DocumentAssembler
+ {
+ private class TemplateError
+ {
+ public bool HasError;
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenXmlPowerTools/DocumentBuilder.cs b/OpenXmlPowerTools/DocumentBuilder/DocumentBuilder.cs
similarity index 73%
rename from OpenXmlPowerTools/DocumentBuilder.cs
rename to OpenXmlPowerTools/DocumentBuilder/DocumentBuilder.cs
index 18114cc6..b2bbd452 100644
--- a/OpenXmlPowerTools/DocumentBuilder.cs
+++ b/OpenXmlPowerTools/DocumentBuilder/DocumentBuilder.cs
@@ -1,220 +1,66 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-#define TestForUnsupportedDocuments
+#define TestForUnsupportedDocuments
#define MergeStylesWithSameNames
+using Codeuctivity.OpenXmlPowerTools.Exceptions;
+using DocumentFormat.OpenXml.Packaging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
-using DocumentFormat.OpenXml.Packaging;
-namespace OpenXmlPowerTools
+namespace Codeuctivity.OpenXmlPowerTools.DocumentBuilder
{
- public partial class WmlDocument : OpenXmlPowerToolsDocument
- {
- public IEnumerable SplitOnSections()
- {
- return DocumentBuilder.SplitOnSections(this);
- }
- }
-
- public class Source
- {
- public WmlDocument WmlDocument { get; set; }
- public int Start { get; set; }
- public int Count { get; set; }
- public bool KeepSections { get; set; }
- public bool DiscardHeadersAndFootersInKeptSections { get; set; }
- public string InsertId { get; set; }
-
- public Source(string fileName)
- {
- WmlDocument = new WmlDocument(fileName);
- Start = 0;
- Count = Int32.MaxValue;
- KeepSections = false;
- InsertId = null;
- }
-
- public Source(WmlDocument source)
- {
- WmlDocument = source;
- Start = 0;
- Count = Int32.MaxValue;
- KeepSections = false;
- InsertId = null;
- }
-
- public Source(string fileName, bool keepSections)
- {
- WmlDocument = new WmlDocument(fileName);
- Start = 0;
- Count = Int32.MaxValue;
- KeepSections = keepSections;
- InsertId = null;
- }
-
- public Source(WmlDocument source, bool keepSections)
- {
- WmlDocument = source;
- Start = 0;
- Count = Int32.MaxValue;
- KeepSections = keepSections;
- InsertId = null;
- }
-
- public Source(string fileName, string insertId)
- {
- WmlDocument = new WmlDocument(fileName);
- Start = 0;
- Count = Int32.MaxValue;
- KeepSections = false;
- InsertId = insertId;
- }
-
- public Source(WmlDocument source, string insertId)
- {
- WmlDocument = source;
- Start = 0;
- Count = Int32.MaxValue;
- KeepSections = false;
- InsertId = insertId;
- }
-
- public Source(string fileName, int start, bool keepSections)
- {
- WmlDocument = new WmlDocument(fileName);
- Start = start;
- Count = Int32.MaxValue;
- KeepSections = keepSections;
- InsertId = null;
- }
-
- public Source(WmlDocument source, int start, bool keepSections)
- {
- WmlDocument = source;
- Start = start;
- Count = Int32.MaxValue;
- KeepSections = keepSections;
- InsertId = null;
- }
-
- public Source(string fileName, int start, string insertId)
- {
- WmlDocument = new WmlDocument(fileName);
- Start = start;
- Count = Int32.MaxValue;
- KeepSections = false;
- InsertId = insertId;
- }
-
- public Source(WmlDocument source, int start, string insertId)
- {
- WmlDocument = source;
- Start = start;
- Count = Int32.MaxValue;
- KeepSections = false;
- InsertId = insertId;
- }
-
- public Source(string fileName, int start, int count, bool keepSections)
- {
- WmlDocument = new WmlDocument(fileName);
- Start = start;
- Count = count;
- KeepSections = keepSections;
- InsertId = null;
- }
-
- public Source(WmlDocument source, int start, int count, bool keepSections)
- {
- WmlDocument = source;
- Start = start;
- Count = count;
- KeepSections = keepSections;
- InsertId = null;
- }
-
- public Source(string fileName, int start, int count, string insertId)
- {
- WmlDocument = new WmlDocument(fileName);
- Start = start;
- Count = count;
- KeepSections = false;
- InsertId = insertId;
- }
-
- public Source(WmlDocument source, int start, int count, string insertId)
- {
- WmlDocument = source;
- Start = start;
- Count = count;
- KeepSections = false;
- InsertId = insertId;
- }
- }
-
public class DocumentBuilderSettings
{
- public HashSet CustomXmlGuidList = null;
- public bool NormalizeStyleIds = false;
+ public HashSet CustomXmlGuidList { get; set; }
+ public bool NormalizeStyleIds { get; set; }
}
public static class DocumentBuilder
{
public static void BuildDocument(List sources, string fileName)
{
- using (OpenXmlMemoryStreamDocument streamDoc = OpenXmlMemoryStreamDocument.CreateWordprocessingDocument())
+ using var streamDoc = OpenXmlMemoryStreamDocument.CreateWordprocessingDocument();
+ using (var output = streamDoc.GetWordprocessingDocument())
{
- using (WordprocessingDocument output = streamDoc.GetWordprocessingDocument())
- {
- BuildDocument(sources, output, new DocumentBuilderSettings());
- output.Close();
- }
- streamDoc.GetModifiedDocument().SaveAs(fileName);
+ BuildDocument(sources, output, new DocumentBuilderSettings());
+ output.Dispose();
}
+ streamDoc.GetModifiedDocument().SaveAs(fileName);
}
public static void BuildDocument(List sources, string fileName, DocumentBuilderSettings settings)
{
- using (OpenXmlMemoryStreamDocument streamDoc = OpenXmlMemoryStreamDocument.CreateWordprocessingDocument())
+ using var streamDoc = OpenXmlMemoryStreamDocument.CreateWordprocessingDocument();
+ using (var output = streamDoc.GetWordprocessingDocument())
{
- using (WordprocessingDocument output = streamDoc.GetWordprocessingDocument())
- {
- BuildDocument(sources, output, settings);
- output.Close();
- }
- streamDoc.GetModifiedDocument().SaveAs(fileName);
+ BuildDocument(sources, output, settings);
+ output.Dispose();
}
+ streamDoc.GetModifiedDocument().SaveAs(fileName);
}
public static WmlDocument BuildDocument(List sources)
{
- using (OpenXmlMemoryStreamDocument streamDoc = OpenXmlMemoryStreamDocument.CreateWordprocessingDocument())
+ using var streamDoc = OpenXmlMemoryStreamDocument.CreateWordprocessingDocument();
+ using (var output = streamDoc.GetWordprocessingDocument())
{
- using (WordprocessingDocument output = streamDoc.GetWordprocessingDocument())
- {
- BuildDocument(sources, output, new DocumentBuilderSettings());
- output.Close();
- }
- return streamDoc.GetModifiedWmlDocument();
+ BuildDocument(sources, output, new DocumentBuilderSettings());
+ output.Dispose();
}
+ return streamDoc.GetModifiedWmlDocument();
}
public static WmlDocument BuildDocument(List sources, DocumentBuilderSettings settings)
{
- using (OpenXmlMemoryStreamDocument streamDoc = OpenXmlMemoryStreamDocument.CreateWordprocessingDocument())
+ using var streamDoc = OpenXmlMemoryStreamDocument.CreateWordprocessingDocument();
+ using (var output = streamDoc.GetWordprocessingDocument())
{
- using (WordprocessingDocument output = streamDoc.GetWordprocessingDocument())
- {
- BuildDocument(sources, output, settings);
- output.Close();
- }
- return streamDoc.GetModifiedWmlDocument();
+ BuildDocument(sources, output, settings);
+ output.Dispose();
}
+ return streamDoc.GetModifiedWmlDocument();
}
private struct TempSource
@@ -231,7 +77,7 @@ private class Atbi
private class Atbid
{
- public XElement BlockLevelContent;
+ public XElement? BlockLevelContent;
public int Index;
public int Div;
}
@@ -243,106 +89,101 @@ private class Atbid
public static IEnumerable SplitOnSections(WmlDocument doc)
{
List tempSourceList;
- using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(doc))
- using (WordprocessingDocument document = streamDoc.GetWordprocessingDocument())
- {
- XDocument mainDocument = document.MainDocumentPart.GetXDocument();
- var divs = mainDocument
- .Root
- .Element(W.body)
- .Elements()
- .Select((p, i) => new Atbi
+ using var streamDoc = new OpenXmlMemoryStreamDocument(doc);
+ using var document = streamDoc.GetWordprocessingDocument();
+ var mainDocument = document.MainDocumentPart.GetXDocument();
+ var divs = mainDocument
+ .Root
+ .Element(W.body)
+ .Elements()
+ .Select((p, i) => new Atbi
+ {
+ BlockLevelContent = p,
+ Index = i,
+ })
+ .Rollup(new Atbid
+ {
+ BlockLevelContent = null,
+ Index = -1,
+ Div = 0,
+ },
+ (b, p) =>
{
- BlockLevelContent = p,
- Index = i,
- })
- .Rollup(new Atbid
- {
- BlockLevelContent = (XElement)null,
- Index = -1,
- Div = 0,
- },
- (b, p) =>
- {
- XElement elementBefore = b.BlockLevelContent
- .SiblingsBeforeSelfReverseDocumentOrder()
- .FirstOrDefault();
- if (elementBefore != null && elementBefore.Descendants(W.sectPr).Any())
- return new Atbid
- {
- BlockLevelContent = b.BlockLevelContent,
- Index = b.Index,
- Div = p.Div + 1,
- };
+ var elementBefore = b.BlockLevelContent
+ .SiblingsBeforeSelfReverseDocumentOrder()
+ .FirstOrDefault();
+ if (elementBefore != null && elementBefore.Descendants(W.sectPr).Any())
+ {
return new Atbid
{
BlockLevelContent = b.BlockLevelContent,
Index = b.Index,
- Div = p.Div,
+ Div = p.Div + 1,
};
- });
- var groups = divs
- .GroupAdjacent(b => b.Div);
- tempSourceList = groups
- .Select(g => new TempSource
- {
- Start = g.First().Index,
- Count = g.Count(),
- })
- .ToList();
- foreach (var ts in tempSourceList)
+ }
+
+ return new Atbid
+ {
+ BlockLevelContent = b.BlockLevelContent,
+ Index = b.Index,
+ Div = p.Div,
+ };
+ });
+ var groups = divs
+ .GroupAdjacent(b => b.Div);
+ tempSourceList = groups
+ .Select(g => new TempSource
{
- List sources = new List()
+ Start = g.First().Index,
+ Count = g.Count(),
+ })
+ .ToList();
+ foreach (var ts in tempSourceList)
+ {
+ var sources = new List()
{
new Source(doc, ts.Start, ts.Count, true)
};
- WmlDocument newDoc = DocumentBuilder.BuildDocument(sources);
- newDoc = AdjustSectionBreak(newDoc);
- yield return newDoc;
- }
+ var newDoc = BuildDocument(sources);
+ newDoc = AdjustSectionBreak(newDoc);
+ yield return newDoc;
}
}
private static WmlDocument AdjustSectionBreak(WmlDocument doc)
{
- using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(doc))
+ using var streamDoc = new OpenXmlMemoryStreamDocument(doc);
+ using (var document = streamDoc.GetWordprocessingDocument())
{
- using (WordprocessingDocument document = streamDoc.GetWordprocessingDocument())
+ var mainXDoc = document.MainDocumentPart.GetXDocument();
+ var lastElement = mainXDoc.Root.Element(W.body).Elements().LastOrDefault();
+ if (lastElement != null && lastElement.Name != W.sectPr && lastElement.Descendants(W.sectPr).Any())
{
- XDocument mainXDoc = document.MainDocumentPart.GetXDocument();
- XElement lastElement = mainXDoc.Root
- .Element(W.body)
- .Elements()
- .LastOrDefault();
- if (lastElement != null)
+ mainXDoc.Root.Element(W.body).Add(lastElement.Descendants(W.sectPr).First());
+ lastElement.Descendants(W.sectPr).Remove();
+ if (!lastElement.Elements().Any(e => e.Name != W.pPr))
{
- if (lastElement.Name != W.sectPr &&
- lastElement.Descendants(W.sectPr).Any())
- {
- mainXDoc.Root.Element(W.body).Add(lastElement.Descendants(W.sectPr).First());
- lastElement.Descendants(W.sectPr).Remove();
- if (!lastElement.Elements()
- .Where(e => e.Name != W.pPr)
- .Any())
- lastElement.Remove();
- document.MainDocumentPart.PutXDocument();
- }
+ lastElement.Remove();
}
+
+ document.MainDocumentPart.PutXDocument();
}
- return streamDoc.GetModifiedWmlDocument();
}
+ return streamDoc.GetModifiedWmlDocument();
}
private static void BuildDocument(List sources, WordprocessingDocument output, DocumentBuilderSettings settings)
{
- WmlDocument wmlGlossaryDocument = CoalesceGlossaryDocumentParts(sources, settings);
+ var wmlGlossaryDocument = CoalesceGlossaryDocumentParts(sources);
if (RelationshipMarkup == null)
+ {
InitRelationshipMarkup();
+ }
// This list is used to eliminate duplicate images
- List images = new List();
- XDocument mainPart = output.MainDocumentPart.GetXDocument();
+ var images = new List();
+ var mainPart = output.MainDocumentPart.GetXDocument();
mainPart.Declaration.Standalone = Yes;
mainPart.Declaration.Encoding = Utf8;
mainPart.Root.ReplaceWith(
@@ -352,17 +193,19 @@ private static void BuildDocument(List sources, WordprocessingDocument o
{
// the following function makes sure that for a given style name, the same style ID is used for all documents.
if (settings != null && settings.NormalizeStyleIds)
+ {
sources = NormalizeStyleNamesAndIds(sources);
+ }
- using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(sources[0].WmlDocument))
- using (WordprocessingDocument doc = streamDoc.GetWordprocessingDocument())
+ using (var streamDoc = new OpenXmlMemoryStreamDocument(sources[0].WmlDocument))
+ using (var doc = streamDoc.GetWordprocessingDocument())
{
CopyStartingParts(doc, output, images);
CopySpecifiedCustomXmlParts(doc, output, settings);
}
- int sourceNum2 = 0;
- foreach (Source source in sources)
+ var sourceNum2 = 0;
+ foreach (var source in sources)
{
if (source.InsertId != null)
{
@@ -374,111 +217,122 @@ modify AppendDocument so that it can take a part.
are there any PtOpenXml.Insert elements in any of them?
if so, then open and process all.
#endif
- bool foundInMainDocPart = false;
- XDocument mainXDoc = output.MainDocumentPart.GetXDocument();
+ var foundInMainDocPart = false;
+ var mainXDoc = output.MainDocumentPart.GetXDocument();
if (mainXDoc.Descendants(PtOpenXml.Insert).Any(d => (string)d.Attribute(PtOpenXml.Id) == source.InsertId))
+ {
foundInMainDocPart = true;
+ }
+
if (foundInMainDocPart)
{
- using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(source.WmlDocument))
- using (WordprocessingDocument doc = streamDoc.GetWordprocessingDocument())
- {
+ using var streamDoc = new OpenXmlMemoryStreamDocument(source.WmlDocument);
+ using var doc = streamDoc.GetWordprocessingDocument();
#if TestForUnsupportedDocuments
- // throws exceptions if a document contains unsupported content
- TestForUnsupportedDocument(doc, sources.IndexOf(source));
+ // throws exceptions if a document contains unsupported content
+ TestForUnsupportedDocument(doc, sources.IndexOf(source));
#endif
- if (foundInMainDocPart)
+ if (foundInMainDocPart)
+ {
+ if (source.KeepSections && source.DiscardHeadersAndFootersInKeptSections)
+ {
+ RemoveHeadersAndFootersFromSections(doc);
+ }
+ else if (source.KeepSections)
{
- if (source.KeepSections && source.DiscardHeadersAndFootersInKeptSections)
- RemoveHeadersAndFootersFromSections(doc);
- else if (source.KeepSections)
- ProcessSectionsForLinkToPreviousHeadersAndFooters(doc);
-
- List contents = doc.MainDocumentPart.GetXDocument()
- .Root
- .Element(W.body)
- .Elements()
- .Skip(source.Start)
- .Take(source.Count)
- .ToList();
-
- try
+ ProcessSectionsForLinkToPreviousHeadersAndFooters(doc);
+ }
+
+ var contents = doc.MainDocumentPart.GetXDocument()
+ .Root
+ .Element(W.body)
+ .Elements()
+ .Skip(source.Start)
+ .Take(source.Count)
+ .ToList();
+
+ try
+ {
+ AppendDocument(doc, output, contents, source.KeepSections, source.InsertId, images);
+ }
+ catch (DocumentBuilderInternalException dbie)
+ {
+ if (dbie.Message.Contains("{0}"))
{
- AppendDocument(doc, output, contents, source.KeepSections, source.InsertId, images);
- }
- catch (DocumentBuilderInternalException dbie)
- {
- if (dbie.Message.Contains("{0}"))
- throw new DocumentBuilderException(string.Format(dbie.Message, sourceNum2));
- else
- throw dbie;
+ throw new DocumentBuilderException(string.Format(dbie.Message, sourceNum2), dbie);
}
+ throw;
}
}
}
else
+ {
break;
+ }
}
}
else
{
- using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(source.WmlDocument))
- using (WordprocessingDocument doc = streamDoc.GetWordprocessingDocument())
- {
+ using var streamDoc = new OpenXmlMemoryStreamDocument(source.WmlDocument);
+ using var doc = streamDoc.GetWordprocessingDocument();
#if TestForUnsupportedDocuments
- // throws exceptions if a document contains unsupported content
- TestForUnsupportedDocument(doc, sources.IndexOf(source));
+ // throws exceptions if a document contains unsupported content
+ TestForUnsupportedDocument(doc, sources.IndexOf(source));
#endif
- if (source.KeepSections && source.DiscardHeadersAndFootersInKeptSections)
- RemoveHeadersAndFootersFromSections(doc);
- else if (source.KeepSections)
- ProcessSectionsForLinkToPreviousHeadersAndFooters(doc);
+ if (source.KeepSections && source.DiscardHeadersAndFootersInKeptSections)
+ {
+ RemoveHeadersAndFootersFromSections(doc);
+ }
+ else if (source.KeepSections)
+ {
+ ProcessSectionsForLinkToPreviousHeadersAndFooters(doc);
+ }
- var body = doc.MainDocumentPart.GetXDocument()
- .Root
- .Element(W.body);
-
- if (body == null)
- throw new DocumentBuilderException(
- String.Format("Source {0} is unsupported document - contains no body element in the correct namespace", sourceNum2));
-
- List contents = body
- .Elements()
- .Skip(source.Start)
- .Take(source.Count)
- .ToList();
- try
- {
- AppendDocument(doc, output, contents, source.KeepSections, null, images);
- }
- catch (DocumentBuilderInternalException dbie)
+ var body = doc.MainDocumentPart.GetXDocument()
+ .Root
+ .Element(W.body);
+
+ if (body == null)
+ {
+ throw new DocumentBuilderException(
+ string.Format("Source {0} is unsupported document - contains no body element in the correct namespace", sourceNum2));
+ }
+
+ var contents = body
+ .Elements()
+ .Skip(source.Start)
+ .Take(source.Count)
+ .ToList();
+ try
+ {
+ AppendDocument(doc, output, contents, source.KeepSections, null, images);
+ }
+ catch (DocumentBuilderInternalException dbie)
+ {
+ if (dbie.Message.Contains("{0}"))
{
- if (dbie.Message.Contains("{0}"))
- throw new DocumentBuilderException(string.Format(dbie.Message, sourceNum2));
- else
- throw dbie;
+ throw new DocumentBuilderException(string.Format(dbie.Message, sourceNum2), dbie);
}
+ throw;
}
}
++sourceNum2;
}
if (!sources.Any(s => s.KeepSections))
{
- using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(sources[0].WmlDocument))
- using (WordprocessingDocument doc = streamDoc.GetWordprocessingDocument())
- {
- var body = doc.MainDocumentPart.GetXDocument().Root.Element(W.body);
+ using var streamDoc = new OpenXmlMemoryStreamDocument(sources[0].WmlDocument);
+ using var doc = streamDoc.GetWordprocessingDocument();
+ var body = doc.MainDocumentPart.GetXDocument().Root.Element(W.body);
- if (body != null && body.Elements().Any())
- {
- var sectPr = doc.MainDocumentPart.GetXDocument().Root.Elements(W.body)
- .Elements().LastOrDefault();
- if (sectPr != null && sectPr.Name == W.sectPr)
- {
- AddSectionAndDependencies(doc, output, sectPr, images);
- output.MainDocumentPart.GetXDocument().Root.Element(W.body).Add(sectPr);
- }
- }
+ if (body != null && body.Elements().Any())
+ {
+ var sectPr = doc.MainDocumentPart.GetXDocument().Root.Elements(W.body)
+ .Elements().LastOrDefault();
+ if (sectPr != null && sectPr.Name == W.sectPr)
+ {
+ AddSectionAndDependencies(doc, output, sectPr, images);
+ output.MainDocumentPart.GetXDocument().Root.Element(W.body).Add(sectPr);
+ }
}
}
else
@@ -490,7 +344,7 @@ are there any PtOpenXml.Insert elements in any of them?
var mxd = output.MainDocumentPart.GetXDocument();
var sections = mxd.Descendants(W.sectPr).Reverse().ToList();
- CachedHeaderFooter[] cachedHeaderFooter = new[]
+ var cachedHeaderFooter = new[]
{
new CachedHeaderFooter() { Ref = W.headerReference, Type = "first" },
new CachedHeaderFooter() { Ref = W.headerReference, Type = "even" },
@@ -500,7 +354,7 @@ are there any PtOpenXml.Insert elements in any of them?
new CachedHeaderFooter() { Ref = W.footerReference, Type = "default" },
};
- bool firstSection = true;
+ var firstSection = true;
foreach (var sect in sections)
{
if (firstSection)
@@ -509,7 +363,9 @@ are there any PtOpenXml.Insert elements in any of them?
{
var referenceElement = sect.Elements(hf.Ref).FirstOrDefault(z => (string)z.Attribute(W.type) == hf.Type);
if (referenceElement != null)
+ {
hf.CachedPartRid = (string)referenceElement.Attribute(R.id);
+ }
}
firstSection = false;
continue;
@@ -523,13 +379,12 @@ are there any PtOpenXml.Insert elements in any of them?
CopyOrCacheHeaderOrFooter(output, cachedHeaderFooter, sect, W.footerReference, "even");
CopyOrCacheHeaderOrFooter(output, cachedHeaderFooter, sect, W.footerReference, "default");
}
-
}
}
// Now can process PtOpenXml:Insert elements in headers / footers
- int sourceNum = 0;
- foreach (Source source in sources)
+ var sourceNum = 0;
+ foreach (var source in sources)
{
if (source.InsertId != null)
{
@@ -541,86 +396,99 @@ this uses an overload of AppendDocument that takes a part.
are there any PtOpenXml.Insert elements in any of them?
if so, then open and process all.
#endif
- bool foundInHeadersFooters = false;
+ var foundInHeadersFooters = false;
if (output.MainDocumentPart.HeaderParts.Any(hp =>
{
var hpXDoc = hp.GetXDocument();
return hpXDoc.Descendants(PtOpenXml.Insert).Any(d => (string)d.Attribute(PtOpenXml.Id) == source.InsertId);
}))
+ {
foundInHeadersFooters = true;
+ }
+
if (output.MainDocumentPart.FooterParts.Any(fp =>
{
var hpXDoc = fp.GetXDocument();
return hpXDoc.Descendants(PtOpenXml.Insert).Any(d => (string)d.Attribute(PtOpenXml.Id) == source.InsertId);
}))
+ {
foundInHeadersFooters = true;
+ }
if (foundInHeadersFooters)
{
- using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(source.WmlDocument))
- using (WordprocessingDocument doc = streamDoc.GetWordprocessingDocument())
- {
+ using var streamDoc = new OpenXmlMemoryStreamDocument(source.WmlDocument);
+ using var doc = streamDoc.GetWordprocessingDocument();
#if TestForUnsupportedDocuments
- // throws exceptions if a document contains unsupported content
- TestForUnsupportedDocument(doc, sources.IndexOf(source));
+ // throws exceptions if a document contains unsupported content
+ TestForUnsupportedDocument(doc, sources.IndexOf(source));
#endif
- var partList = output.MainDocumentPart.HeaderParts.Cast().Concat(output.MainDocumentPart.FooterParts.Cast()).ToList();
- foreach (var part in partList)
+ var partList = output.MainDocumentPart.HeaderParts.Cast().Concat(output.MainDocumentPart.FooterParts.Cast()).ToList();
+ foreach (var part in partList)
+ {
+ var partXDoc = part.GetXDocument();
+ if (!partXDoc.Descendants(PtOpenXml.Insert).Any(d => (string)d.Attribute(PtOpenXml.Id) == source.InsertId))
{
- var partXDoc = part.GetXDocument();
- if (!partXDoc.Descendants(PtOpenXml.Insert).Any(d => (string)d.Attribute(PtOpenXml.Id) == source.InsertId))
- continue;
- List contents = doc.MainDocumentPart.GetXDocument()
- .Root
- .Element(W.body)
- .Elements()
- .Skip(source.Start)
- .Take(source.Count)
- .ToList();
-
- try
- {
- AppendDocument(doc, output, part, contents, source.KeepSections, source.InsertId, images);
- }
- catch (DocumentBuilderInternalException dbie)
+ continue;
+ }
+
+ var contents = doc.MainDocumentPart.GetXDocument()
+ .Root
+ .Element(W.body)
+ .Elements()
+ .Skip(source.Start)
+ .Take(source.Count)
+ .ToList();
+
+ try
+ {
+ AppendDocument(doc, output, part, contents, source.InsertId, images);
+ }
+ catch (DocumentBuilderInternalException dbie)
+ {
+ if (dbie.Message.Contains("{0}"))
{
- if (dbie.Message.Contains("{0}"))
- throw new DocumentBuilderException(string.Format(dbie.Message, sourceNum));
- else
- throw dbie;
+ throw new DocumentBuilderException(string.Format(dbie.Message, sourceNum), dbie);
}
+ throw;
}
}
}
else
+ {
break;
+ }
}
}
++sourceNum;
}
if (sources.Any(s => s.KeepSections) && !output.MainDocumentPart.GetXDocument().Root.Descendants(W.sectPr).Any())
{
- using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(sources[0].WmlDocument))
- using (WordprocessingDocument doc = streamDoc.GetWordprocessingDocument())
+ using var streamDoc = new OpenXmlMemoryStreamDocument(sources[0].WmlDocument);
+ using var doc = streamDoc.GetWordprocessingDocument();
+ var sectPr = doc.MainDocumentPart.GetXDocument().Root.Element(W.body)
+ .Elements().LastOrDefault();
+ if (sectPr != null && sectPr.Name == W.sectPr)
{
- var sectPr = doc.MainDocumentPart.GetXDocument().Root.Element(W.body)
- .Elements().LastOrDefault();
- if (sectPr != null && sectPr.Name == W.sectPr)
- {
- AddSectionAndDependencies(doc, output, sectPr, images);
- output.MainDocumentPart.GetXDocument().Root.Element(W.body).Add(sectPr);
- }
+ AddSectionAndDependencies(doc, output, sectPr, images);
+ output.MainDocumentPart.GetXDocument().Root.Element(W.body).Add(sectPr);
}
}
AdjustDocPrIds(output);
}
if (wmlGlossaryDocument != null)
+ {
WriteGlossaryDocumentPart(wmlGlossaryDocument, output, images);
+ }
foreach (var part in output.GetAllParts())
+ {
if (part.Annotation() != null)
+ {
part.PutXDocument();
+ }
+ }
}
// there are two scenarios that need to be handled
@@ -632,9 +500,9 @@ are there any PtOpenXml.Insert elements in any of them?
// - mark the document as changed, and change it in the sources.
private static List NormalizeStyleNamesAndIds(List sources)
{
- Dictionary styleNameMap = new Dictionary();
- HashSet styleIds = new HashSet();
- List newSources = new List();
+ var styleNameMap = new Dictionary();
+ var styleIds = new HashSet();
+ var newSources = new List();
foreach (var src in sources)
{
@@ -646,13 +514,13 @@ private static List NormalizeStyleNamesAndIds(List sources)
private static Source AddAndRectify(Source src, Dictionary styleNameMap, HashSet styleIds)
{
- bool modified = false;
- using (MemoryStream ms = new MemoryStream())
+ var modified = false;
+ using (var ms = new MemoryStream())
{
ms.Write(src.WmlDocument.DocumentByteArray, 0, src.WmlDocument.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
+ using (var wDoc = WordprocessingDocument.Open(ms, true))
{
- Dictionary correctionList = new Dictionary();
+ var correctionList = new Dictionary();
var thisStyleNameMap = GetStyleNameMap(wDoc);
foreach (var pair in thisStyleNameMap)
{
@@ -669,7 +537,7 @@ private static Source AddAndRectify(Source src, Dictionary style
while (true)
{
var newStyleId = GenStyleIdFromStyleName(styleName);
- if (! styleIds.Contains(newStyleId))
+ if (!styleIds.Contains(newStyleId))
{
correctionList.Add(styleId, newStyleId);
styleNameMap.Add(styleName, newStyleId);
@@ -690,7 +558,10 @@ private static Source AddAndRectify(Source src, Dictionary style
{
// if the id is the same as the existing ID, then nothing to do
if (styleNameMap[styleName] == styleId)
+ {
continue;
+ }
+
correctionList.Add(styleId, styleNameMap[styleName]);
}
}
@@ -703,9 +574,11 @@ private static Source AddAndRectify(Source src, Dictionary style
if (modified)
{
var newWmlDocument = new WmlDocument(src.WmlDocument.FileName, ms.ToArray());
- var newSrc = new Source(newWmlDocument, src.Start, src.Count, src.KeepSections);
- newSrc.DiscardHeadersAndFootersInKeptSections = src.DiscardHeadersAndFootersInKeptSections;
- newSrc.InsertId = src.InsertId;
+ var newSrc = new Source(newWmlDocument, src.Start, src.Count, src.KeepSections)
+ {
+ DiscardHeadersAndFootersInKeptSections = src.DiscardHeadersAndFootersInKeptSections,
+ InsertId = src.InsertId
+ };
return newSrc;
}
}
@@ -770,22 +643,41 @@ private static void AdjustStyleIdsForDocument(WordprocessingDocument wDoc, Dicti
// update styles part
UpdateStyleIdsForStylePart(wDoc.MainDocumentPart.StyleDefinitionsPart, correctionList);
if (wDoc.MainDocumentPart.StylesWithEffectsPart != null)
+ {
UpdateStyleIdsForStylePart(wDoc.MainDocumentPart.StylesWithEffectsPart, correctionList);
+ }
// update content parts
UpdateStyleIdsForContentPart(wDoc.MainDocumentPart, correctionList);
foreach (var part in wDoc.MainDocumentPart.HeaderParts)
+ {
UpdateStyleIdsForContentPart(part, correctionList);
+ }
+
foreach (var part in wDoc.MainDocumentPart.FooterParts)
+ {
UpdateStyleIdsForContentPart(part, correctionList);
+ }
+
if (wDoc.MainDocumentPart.FootnotesPart != null)
+ {
UpdateStyleIdsForContentPart(wDoc.MainDocumentPart.FootnotesPart, correctionList);
+ }
+
if (wDoc.MainDocumentPart.EndnotesPart != null)
+ {
UpdateStyleIdsForContentPart(wDoc.MainDocumentPart.EndnotesPart, correctionList);
+ }
+
if (wDoc.MainDocumentPart.WordprocessingCommentsPart != null)
+ {
UpdateStyleIdsForContentPart(wDoc.MainDocumentPart.WordprocessingCommentsPart, correctionList);
+ }
+
if (wDoc.MainDocumentPart.WordprocessingCommentsExPart != null)
+ {
UpdateStyleIdsForContentPart(wDoc.MainDocumentPart.WordprocessingCommentsExPart, correctionList);
+ }
// update numbering part
UpdateStyleIdsForNumberingPart(wDoc.MainDocumentPart.NumberingDefinitionsPart, correctionList);
@@ -825,11 +717,19 @@ private static void UpdateStyleIdsForNumberingPart(OpenXmlPart part, Dictionary<
foreach (var item in numAttributeChangeList)
{
foreach (var att in item.PStyleAttributesToChange)
+ {
att.Value = item.NewId;
+ }
+
foreach (var att in item.NumStyleLinkAttributesToChange)
+ {
att.Value = item.NewId;
+ }
+
foreach (var att in item.StyleLinkAttributesToChange)
+ {
att.Value = item.NewId;
+ }
}
part.PutXDocument();
}
@@ -881,13 +781,24 @@ private static void UpdateStyleIdsForStylePart(OpenXmlPart part, Dictionary images)
{
- using (MemoryStream ms = new MemoryStream())
- {
- ms.Write(wmlGlossaryDocument.DocumentByteArray, 0, wmlGlossaryDocument.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- var fromXDoc = wDoc.MainDocumentPart.GetXDocument();
-
- var outputGlossaryDocumentPart = output.MainDocumentPart.AddNewPart();
- var newXDoc = new XDocument(
- new XDeclaration(OnePointZero, Utf8, Yes),
- new XElement(W.glossaryDocument,
- NamespaceAttributes,
- new XElement(W.docParts,
- fromXDoc.Descendants(W.docPart))));
- outputGlossaryDocumentPart.PutXDocument(newXDoc);
-
- CopyGlossaryDocumentPartsToGD(wDoc, output, fromXDoc.Root.Descendants(W.docPart), images);
- CopyRelatedPartsForContentParts(wDoc.MainDocumentPart, outputGlossaryDocumentPart, new[] { fromXDoc.Root }, images);
- }
- }
+ using var ms = new MemoryStream();
+ ms.Write(wmlGlossaryDocument.DocumentByteArray, 0, wmlGlossaryDocument.DocumentByteArray.Length);
+ using var wDoc = WordprocessingDocument.Open(ms, true);
+ var fromXDoc = wDoc.MainDocumentPart.GetXDocument();
+
+ var outputGlossaryDocumentPart = output.MainDocumentPart.AddNewPart();
+ var newXDoc = new XDocument(
+ new XDeclaration(OnePointZero, Utf8, Yes),
+ new XElement(W.glossaryDocument,
+ NamespaceAttributes,
+ new XElement(W.docParts,
+ fromXDoc.Descendants(W.docPart))));
+ outputGlossaryDocumentPart.PutXDocument(newXDoc);
+
+ CopyGlossaryDocumentPartsToGD(wDoc, output, fromXDoc.Root.Descendants(W.docPart), images);
+ CopyRelatedPartsForContentParts(wDoc.MainDocumentPart, outputGlossaryDocumentPart, new[] { fromXDoc.Root }, images);
}
- private static WmlDocument CoalesceGlossaryDocumentParts(IEnumerable sources, DocumentBuilderSettings settings)
+ private static WmlDocument? CoalesceGlossaryDocumentParts(IEnumerable sources)
{
- List allGlossaryDocuments = sources
- .Select(s => DocumentBuilder.ExtractGlossaryDocument(s.WmlDocument))
+ var allGlossaryDocuments = sources
+ .Select(s => ExtractGlossaryDocument(s.WmlDocument))
.Where(s => s != null)
.Select(s => new Source(s))
.ToList();
if (!allGlossaryDocuments.Any())
+ {
return null;
+ }
- WmlDocument coalescedRaw = DocumentBuilder.BuildDocument(allGlossaryDocuments);
+ var coalescedRaw = BuildDocument(allGlossaryDocuments);
// now need to do some fix up
- using (MemoryStream ms = new MemoryStream())
+ using var ms = new MemoryStream();
+ ms.Write(coalescedRaw.DocumentByteArray, 0, coalescedRaw.DocumentByteArray.Length);
+ using (var wDoc = WordprocessingDocument.Open(ms, true))
{
- ms.Write(coalescedRaw.DocumentByteArray, 0, coalescedRaw.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
- {
- var mainXDoc = wDoc.MainDocumentPart.GetXDocument();
+ var mainXDoc = wDoc.MainDocumentPart.GetXDocument();
- var newBody = new XElement(W.body,
- new XElement(W.docParts,
- mainXDoc.Root.Element(W.body).Elements(W.docParts).Elements(W.docPart)));
+ var newBody = new XElement(W.body,
+ new XElement(W.docParts,
+ mainXDoc.Root.Element(W.body).Elements(W.docParts).Elements(W.docPart)));
- mainXDoc.Root.Element(W.body).ReplaceWith(newBody);
+ mainXDoc.Root.Element(W.body).ReplaceWith(newBody);
- wDoc.MainDocumentPart.PutXDocument();
- }
+ wDoc.MainDocumentPart.PutXDocument();
+ }
- WmlDocument coalescedGlossaryDocument = new WmlDocument("Coalesced.docx", ms.ToArray());
+ var coalescedGlossaryDocument = new WmlDocument("Coalesced.docx", ms.ToArray());
- return coalescedGlossaryDocument;
- }
+ return coalescedGlossaryDocument;
}
private static void InitRelationshipMarkup()
@@ -1085,18 +1000,19 @@ private static void InitRelationshipMarkup()
private static void CopySpecifiedCustomXmlParts(WordprocessingDocument sourceDocument, WordprocessingDocument output, DocumentBuilderSettings settings)
{
if (settings.CustomXmlGuidList == null || !settings.CustomXmlGuidList.Any())
+ {
return;
+ }
- foreach (CustomXmlPart customXmlPart in sourceDocument.MainDocumentPart.CustomXmlParts)
+ foreach (var customXmlPart in sourceDocument.MainDocumentPart.CustomXmlParts)
{
- OpenXmlPart propertyPart = customXmlPart
+ var propertyPart = customXmlPart
.Parts
.Select(p => p.OpenXmlPart)
- .Where(p => p.ContentType == "application/vnd.openxmlformats-officedocument.customXmlProperties+xml")
- .FirstOrDefault();
+.FirstOrDefault(p => p.ContentType == "application/vnd.openxmlformats-officedocument.customXmlProperties+xml");
if (propertyPart != null)
{
- XDocument propertyPartDoc = propertyPart.GetXDocument();
+ var propertyPartDoc = propertyPart.GetXDocument();
#if false
At various locations in Open-Xml-PowerTools, you will find examples of Open XML markup that is associated with code associated with
querying or generating that markup. This is an example of the Custom XML Properties part.
@@ -1111,11 +1027,11 @@ querying or generating that markup. This is an example of the Custom XML Proper
itemID = itemID.Trim('{', '}');
if (settings.CustomXmlGuidList.Contains(itemID))
{
- CustomXmlPart newPart = output.MainDocumentPart.AddCustomXmlPart(customXmlPart.ContentType);
+ var newPart = output.MainDocumentPart.AddCustomXmlPart(customXmlPart.ContentType);
newPart.GetXDocument().Add(customXmlPart.GetXDocument().Root);
- foreach (OpenXmlPart propPart in customXmlPart.Parts.Select(p => p.OpenXmlPart))
+ foreach (var propPart in customXmlPart.Parts.Select(p => p.OpenXmlPart))
{
- CustomXmlPropertiesPart newPropPart = newPart.AddNewPart();
+ var newPropPart = newPart.AddNewPart();
newPropPart.GetXDocument().Add(propPart.GetXDocument().Root);
}
}
@@ -1145,7 +1061,7 @@ private class CachedHeaderFooter
private static void ProcessSectionsForLinkToPreviousHeadersAndFooters(WordprocessingDocument doc)
{
- CachedHeaderFooter[] cachedHeaderFooter = new[]
+ var cachedHeaderFooter = new[]
{
new CachedHeaderFooter() { Ref = W.headerReference, Type = "first" },
new CachedHeaderFooter() { Ref = W.headerReference, Type = "even" },
@@ -1172,42 +1088,64 @@ private static void ProcessSectionsForLinkToPreviousHeadersAndFooters(Wordproces
if (headerEven == null)
{
if (headerDefault != null)
- AddReferenceToExistingHeaderOrFooter(doc.MainDocumentPart, sect, (string)headerDefault.Attribute(R.id), W.headerReference, "even");
+ {
+ AddReferenceToExistingHeaderOrFooter(sect, (string)headerDefault.Attribute(R.id), W.headerReference, "even");
+ }
else
+ {
InitEmptyHeaderOrFooter(doc.MainDocumentPart, sect, W.headerReference, "even");
+ }
}
if (headerFirst == null)
{
if (headerDefault != null)
- AddReferenceToExistingHeaderOrFooter(doc.MainDocumentPart, sect, (string)headerDefault.Attribute(R.id), W.headerReference, "first");
+ {
+ AddReferenceToExistingHeaderOrFooter(sect, (string)headerDefault.Attribute(R.id), W.headerReference, "first");
+ }
else
+ {
InitEmptyHeaderOrFooter(doc.MainDocumentPart, sect, W.headerReference, "first");
+ }
}
if (footerEven == null)
{
if (footerDefault != null)
- AddReferenceToExistingHeaderOrFooter(doc.MainDocumentPart, sect, (string)footerDefault.Attribute(R.id), W.footerReference, "even");
+ {
+ AddReferenceToExistingHeaderOrFooter(sect, (string)footerDefault.Attribute(R.id), W.footerReference, "even");
+ }
else
+ {
InitEmptyHeaderOrFooter(doc.MainDocumentPart, sect, W.footerReference, "even");
+ }
}
if (footerFirst == null)
{
if (footerDefault != null)
- AddReferenceToExistingHeaderOrFooter(doc.MainDocumentPart, sect, (string)footerDefault.Attribute(R.id), W.footerReference, "first");
+ {
+ AddReferenceToExistingHeaderOrFooter(sect, (string)footerDefault.Attribute(R.id), W.footerReference, "first");
+ }
else
+ {
InitEmptyHeaderOrFooter(doc.MainDocumentPart, sect, W.footerReference, "first");
+ }
}
foreach (var hf in cachedHeaderFooter)
{
if (sect.Elements(hf.Ref).FirstOrDefault(z => (string)z.Attribute(W.type) == hf.Type) == null)
+ {
InitEmptyHeaderOrFooter(doc.MainDocumentPart, sect, hf.Ref, hf.Type);
+ }
+
var reference = sect.Elements(hf.Ref).FirstOrDefault(z => (string)z.Attribute(W.type) == hf.Type);
if (reference == null)
+ {
throw new OpenXmlPowerToolsException("Internal error");
+ }
+
hf.CachedPartRid = (string)reference.Attribute(R.id);
}
firstSection = false;
@@ -1231,8 +1169,11 @@ private static void CopyOrCacheHeaderOrFooter(WordprocessingDocument doc, Cached
var referenceElement = FindReference(sect, referenceXName, type);
if (referenceElement == null)
{
- var cachedPartRid = cachedHeaderFooter.FirstOrDefault(z => z.Ref == referenceXName && z.Type == type).CachedPartRid;
- AddReferenceToExistingHeaderOrFooter(doc.MainDocumentPart, sect, cachedPartRid, referenceXName, type);
+ var cachedPartRid = cachedHeaderFooter.FirstOrDefault(z => z.Ref == referenceXName && z.Type == type)?.CachedPartRid;
+ if (cachedPartRid != null)
+ {
+ AddReferenceToExistingHeaderOrFooter(sect, cachedPartRid, referenceXName, type);
+ }
}
else
{
@@ -1249,7 +1190,7 @@ private static XElement FindReference(XElement sect, XName reference, string typ
});
}
- private static void AddReferenceToExistingHeaderOrFooter(MainDocumentPart mainDocPart, XElement sect, string rId, XName reference, string toType)
+ private static void AddReferenceToExistingHeaderOrFooter(XElement sect, string rId, XName reference, string toType)
{
if (reference == W.headerReference)
{
@@ -1269,7 +1210,7 @@ private static void AddReferenceToExistingHeaderOrFooter(MainDocumentPart mainDo
private static void InitEmptyHeaderOrFooter(MainDocumentPart mainDocPart, XElement sect, XName referenceXName, string toType)
{
- XDocument xDoc = null;
+ XDocument xDoc;
if (referenceXName == W.headerReference)
{
xDoc = XDocument.Parse(
@@ -1347,43 +1288,57 @@ private static void InitEmptyHeaderOrFooter(MainDocumentPart mainDocPart, XEleme
private static void TestPartForUnsupportedContent(OpenXmlPart part, int sourceNumber)
{
- XNamespace[] obsoleteNamespaces = new[]
+ var obsoleteNamespaces = new[]
{
XNamespace.Get("http://schemas.microsoft.com/office/word/2007/5/30/wordml"),
XNamespace.Get("http://schemas.microsoft.com/office/word/2008/9/16/wordprocessingDrawing"),
XNamespace.Get("http://schemas.microsoft.com/office/word/2009/2/wordml"),
};
- XDocument xDoc = part.GetXDocument();
- XElement invalidElement = xDoc.Descendants()
+ var xDoc = part.GetXDocument();
+ var invalidElement = xDoc.Descendants()
.FirstOrDefault(d =>
{
- bool b = d.Name == W.subDoc ||
+ var b = d.Name == W.subDoc ||
d.Name == W.control ||
d.Name == W.altChunk ||
d.Name.LocalName == "contentPart" ||
obsoleteNamespaces.Contains(d.Name.Namespace);
- bool b2 = b ||
+ var b2 = b ||
d.Attributes().Any(a => obsoleteNamespaces.Contains(a.Name.Namespace));
return b2;
});
if (invalidElement != null)
{
if (invalidElement.Name == W.subDoc)
- throw new DocumentBuilderException(String.Format("Source {0} is unsupported document - contains sub document",
+ {
+ throw new DocumentBuilderException(string.Format("Source {0} is unsupported document - contains sub document",
sourceNumber));
+ }
+
if (invalidElement.Name == W.control)
- throw new DocumentBuilderException(String.Format("Source {0} is unsupported document - contains ActiveX controls",
+ {
+ throw new DocumentBuilderException(string.Format("Source {0} is unsupported document - contains ActiveX controls",
sourceNumber));
+ }
+
if (invalidElement.Name == W.altChunk)
- throw new DocumentBuilderException(String.Format("Source {0} is unsupported document - contains altChunk",
+ {
+ throw new DocumentBuilderException(string.Format("Source {0} is unsupported document - contains altChunk",
sourceNumber));
+ }
+
if (invalidElement.Name.LocalName == "contentPart")
- throw new DocumentBuilderException(String.Format("Source {0} is unsupported document - contains contentPart content",
+ {
+ throw new DocumentBuilderException(string.Format("Source {0} is unsupported document - contains contentPart content",
sourceNumber));
+ }
+
if (obsoleteNamespaces.Contains(invalidElement.Name.Namespace) ||
invalidElement.Attributes().Any(a => obsoleteNamespaces.Contains(a.Name.Namespace)))
- throw new DocumentBuilderException(String.Format("Source {0} is unsupported document - contains obsolete namespace",
+ {
+ throw new DocumentBuilderException(string.Format("Source {0} is unsupported document - contains obsolete namespace",
sourceNumber));
+ }
}
}
@@ -1398,67 +1353,88 @@ private static void TestPartForUnsupportedContent(OpenXmlPart part, int sourceNu
private static void TestForUnsupportedDocument(WordprocessingDocument doc, int sourceNumber)
{
if (doc.MainDocumentPart.GetXDocument().Root == null)
+ {
throw new DocumentBuilderException(string.Format("Source {0} is an invalid document - MainDocumentPart contains no content.", sourceNumber));
+ }
- if ((string)doc.MainDocumentPart.GetXDocument().Root.Name.NamespaceName == "http://purl.oclc.org/ooxml/wordprocessingml/main")
+ if (doc.MainDocumentPart.GetXDocument().Root.Name.NamespaceName == "http://purl.oclc.org/ooxml/wordprocessingml/main")
+ {
throw new DocumentBuilderException(string.Format("Source {0} is saved in strict mode, not supported", sourceNumber));
+ }
// note: if ever want to support section changes, need to address the code that rationalizes headers and footers, propagating to sections that inherit headers/footers from prev section
foreach (var d in doc.MainDocumentPart.GetXDocument().Descendants())
{
if (d.Name == W.sectPrChange)
+ {
throw new DocumentBuilderException(string.Format("Source {0} contains section changes (w:sectPrChange), not supported", sourceNumber));
-
- // note: if ever want to support Open-Xml-PowerTools attributes, need to make sure that all attributes are propagated in all cases
- //if (d.Name.Namespace == PtOpenXml.ptOpenXml ||
- // d.Name.Namespace == PtOpenXml.pt)
- // throw new DocumentBuilderException(string.Format("Source {0} contains Open-Xml-PowerTools markup, not supported", sourceNumber));
- //if (d.Attributes().Any(a => a.Name.Namespace == PtOpenXml.ptOpenXml || a.Name.Namespace == PtOpenXml.pt))
- // throw new DocumentBuilderException(string.Format("Source {0} contains Open-Xml-PowerTools markup, not supported", sourceNumber));
+ }
}
TestPartForUnsupportedContent(doc.MainDocumentPart, sourceNumber);
foreach (var hdr in doc.MainDocumentPart.HeaderParts)
+ {
TestPartForUnsupportedContent(hdr, sourceNumber);
+ }
+
foreach (var ftr in doc.MainDocumentPart.FooterParts)
+ {
TestPartForUnsupportedContent(ftr, sourceNumber);
+ }
+
if (doc.MainDocumentPart.FootnotesPart != null)
+ {
TestPartForUnsupportedContent(doc.MainDocumentPart.FootnotesPart, sourceNumber);
+ }
+
if (doc.MainDocumentPart.EndnotesPart != null)
+ {
TestPartForUnsupportedContent(doc.MainDocumentPart.EndnotesPart, sourceNumber);
+ }
if (doc.MainDocumentPart.DocumentSettingsPart != null &&
doc.MainDocumentPart.DocumentSettingsPart.GetXDocument().Descendants().Any(d => d.Name == W.src ||
d.Name == W.recipientData || d.Name == W.mailMerge))
- throw new DocumentBuilderException(String.Format("Source {0} is unsupported document - contains Mail Merge content",
+ {
+ throw new DocumentBuilderException(string.Format("Source {0} is unsupported document - contains Mail Merge content",
sourceNumber));
+ }
+
if (doc.MainDocumentPart.WebSettingsPart != null &&
doc.MainDocumentPart.WebSettingsPart.GetXDocument().Descendants().Any(d => d.Name == W.frameset))
- throw new DocumentBuilderException(String.Format("Source {0} is unsupported document - contains a frameset", sourceNumber));
+ {
+ throw new DocumentBuilderException(string.Format("Source {0} is unsupported document - contains a frameset", sourceNumber));
+ }
+
var numberingElements = doc.MainDocumentPart
.GetXDocument()
.Descendants(W.numPr)
.Where(n =>
{
- bool zeroId = (int?)n.Attribute(W.id) == 0;
- bool hasChildInsId = n.Elements(W.ins).Any();
+ var zeroId = (int?)n.Attribute(W.id) == 0;
+ var hasChildInsId = n.Elements(W.ins).Any();
if (zeroId || hasChildInsId)
+ {
return false;
+ }
+
return true;
})
.ToList();
if (numberingElements.Any() &&
doc.MainDocumentPart.NumberingDefinitionsPart == null)
- throw new DocumentBuilderException(String.Format(
+ {
+ throw new DocumentBuilderException(string.Format(
"Source {0} is invalid document - contains numbering markup but no numbering part", sourceNumber));
+ }
}
private static void FixUpSectionProperties(WordprocessingDocument newDocument)
{
- XDocument mainDocumentXDoc = newDocument.MainDocumentPart.GetXDocument();
+ var mainDocumentXDoc = newDocument.MainDocumentPart.GetXDocument();
mainDocumentXDoc.Declaration.Standalone = Yes;
mainDocumentXDoc.Declaration.Encoding = Utf8;
- XElement body = mainDocumentXDoc.Root.Element(W.body);
+ var body = mainDocumentXDoc.Root.Element(W.body);
var sectionPropertiesToMove = body
.Elements()
.Take(body.Elements().Count() - 1)
@@ -1468,11 +1444,16 @@ private static void FixUpSectionProperties(WordprocessingDocument newDocument)
{
var p = s.SiblingsBeforeSelfReverseDocumentOrder().First();
if (p.Element(W.pPr) == null)
+ {
p.AddFirst(new XElement(W.pPr));
+ }
+
p.Element(W.pPr).Add(s);
}
foreach (var s in sectionPropertiesToMove)
+ {
s.Remove();
+ }
}
private static void AddSectionAndDependencies(WordprocessingDocument sourceDocument, WordprocessingDocument newDocument,
@@ -1481,8 +1462,8 @@ private static void AddSectionAndDependencies(WordprocessingDocument sourceDocum
var headerReferences = sectionMarkup.Elements(W.headerReference);
foreach (var headerReference in headerReferences)
{
- string oldRid = headerReference.Attribute(R.id).Value;
- HeaderPart oldHeaderPart = null;
+ var oldRid = headerReference.Attribute(R.id).Value;
+ HeaderPart? oldHeaderPart = null;
try
{
oldHeaderPart = (HeaderPart)sourceDocument.MainDocumentPart.GetPartById(oldRid);
@@ -1492,11 +1473,14 @@ private static void AddSectionAndDependencies(WordprocessingDocument sourceDocum
var message = string.Format("ArgumentOutOfRangeException, attempting to get header rId={0}", oldRid);
throw new OpenXmlPowerToolsException(message);
}
- XDocument oldHeaderXDoc = oldHeaderPart.GetXDocument();
+ var oldHeaderXDoc = oldHeaderPart.GetXDocument();
if (oldHeaderXDoc != null && oldHeaderXDoc.Root != null)
+ {
CopyNumbering(sourceDocument, newDocument, new[] { oldHeaderXDoc.Root }, images);
- HeaderPart newHeaderPart = newDocument.MainDocumentPart.AddNewPart();
- XDocument newHeaderXDoc = newHeaderPart.GetXDocument();
+ }
+
+ var newHeaderPart = newDocument.MainDocumentPart.AddNewPart();
+ var newHeaderXDoc = newHeaderPart.GetXDocument();
newHeaderXDoc.Declaration.Standalone = Yes;
newHeaderXDoc.Declaration.Encoding = Utf8;
newHeaderXDoc.Add(oldHeaderXDoc.Root);
@@ -1508,17 +1492,22 @@ private static void AddSectionAndDependencies(WordprocessingDocument sourceDocum
var footerReferences = sectionMarkup.Elements(W.footerReference);
foreach (var footerReference in footerReferences)
{
- string oldRid = footerReference.Attribute(R.id).Value;
+ var oldRid = footerReference.Attribute(R.id).Value;
var oldFooterPart2 = sourceDocument.MainDocumentPart.GetPartById(oldRid);
if (!(oldFooterPart2 is FooterPart))
+ {
throw new DocumentBuilderException("Invalid document - invalid footer part.");
+ }
- FooterPart oldFooterPart = (FooterPart)oldFooterPart2;
- XDocument oldFooterXDoc = oldFooterPart.GetXDocument();
+ var oldFooterPart = (FooterPart)oldFooterPart2;
+ var oldFooterXDoc = oldFooterPart.GetXDocument();
if (oldFooterXDoc != null && oldFooterXDoc.Root != null)
+ {
CopyNumbering(sourceDocument, newDocument, new[] { oldFooterXDoc.Root }, images);
- FooterPart newFooterPart = newDocument.MainDocumentPart.AddNewPart();
- XDocument newFooterXDoc = newFooterPart.GetXDocument();
+ }
+
+ var newFooterPart = newDocument.MainDocumentPart.AddNewPart();
+ var newFooterXDoc = newFooterPart.GetXDocument();
newFooterXDoc.Declaration.Standalone = Yes;
newFooterXDoc.Declaration.Encoding = Utf8;
newFooterXDoc.Add(oldFooterXDoc.Root);
@@ -1534,9 +1523,11 @@ private static void MergeStyles(WordprocessingDocument sourceDocument, Wordproce
var newIds = new Dictionary();
#endif
if (fromStyles.Root == null)
+ {
return;
+ }
- foreach (XElement style in fromStyles.Root.Elements(W.style))
+ foreach (var style in fromStyles.Root.Elements(W.style))
{
var fromId = (string)style.Attribute(W.styleId);
var fromName = (string)style.Elements(W.name).Attributes(W.val).FirstOrDefault();
@@ -1550,47 +1541,41 @@ private static void MergeStyles(WordprocessingDocument sourceDocument, Wordproce
{
#if MergeStylesWithSameNames
var linkElement = style.Element(W.link);
- string linkedId;
- if (linkElement != null && newIds.TryGetValue(linkElement.Attribute(W.val).Value, out linkedId))
+ if (linkElement != null && newIds.TryGetValue(linkElement.Attribute(W.val).Value, out var linkedId))
{
var linkedStyle = toStyles.Root.Elements(W.style)
.First(o => o.Attribute(W.styleId).Value == linkedId);
if (linkedStyle.Element(W.link) != null)
+ {
newIds.Add(fromId, linkedStyle.Element(W.link).Attribute(W.val).Value);
+ }
+
continue;
}
- //string name = (string)style.Elements(W.name).Attributes(W.val).FirstOrDefault();
- //var namedStyle = toStyles
- // .Root
- // .Elements(W.style)
- // .Where(st => st.Element(W.name) != null)
- // .FirstOrDefault(o => (string)o.Element(W.name).Attribute(W.val) == name);
- //if (namedStyle != null)
- //{
- // if (! newIds.ContainsKey(fromId))
- // newIds.Add(fromId, namedStyle.Attribute(W.styleId).Value);
- // continue;
- //}
#endif
- int number = 1;
- int abstractNumber = 0;
- XDocument oldNumbering = null;
- XDocument newNumbering = null;
- foreach (XElement numReference in style.Descendants(W.numPr))
+ var number = 1;
+ var abstractNumber = 0;
+ XDocument? oldNumbering = null;
+ XDocument? newNumbering = null;
+ foreach (var numReference in style.Descendants(W.numPr))
{
- XElement idElement = numReference.Descendants(W.numId).FirstOrDefault();
+ var idElement = numReference.Descendants(W.numId).FirstOrDefault();
if (idElement != null)
{
if (oldNumbering == null)
{
if (sourceDocument.MainDocumentPart.NumberingDefinitionsPart != null)
+ {
oldNumbering = sourceDocument.MainDocumentPart.NumberingDefinitionsPart.GetXDocument();
+ }
else
{
- oldNumbering = new XDocument();
- oldNumbering.Declaration = new XDeclaration(OnePointZero, Utf8, Yes);
+ oldNumbering = new XDocument
+ {
+ Declaration = new XDeclaration(OnePointZero, Utf8, Yes)
+ };
oldNumbering.Add(new XElement(W.numbering, NamespaceAttributes));
}
}
@@ -1606,13 +1591,18 @@ private static void MergeStyles(WordprocessingDocument sourceDocument, Wordproce
.Elements(W.num)
.Select(f => (int)f.Attribute(W.numId));
if (numIds.Any())
+ {
number = numIds.Max() + 1;
+ }
+
numIds = newNumbering
.Root
.Elements(W.abstractNum)
.Select(f => (int)f.Attribute(W.abstractNumId));
if (numIds.Any())
+ {
abstractNumber = numIds.Max() + 1;
+ }
}
else
{
@@ -1623,17 +1613,16 @@ private static void MergeStyles(WordprocessingDocument sourceDocument, Wordproce
newNumbering.Add(new XElement(W.numbering, NamespaceAttributes));
}
}
- string numId = idElement.Attribute(W.val).Value;
+ var numId = idElement.Attribute(W.val).Value;
if (numId != "0")
{
- XElement element = oldNumbering
+ var element = oldNumbering
.Descendants()
.Elements(W.num)
- .Where(p => ((string)p.Attribute(W.numId)) == numId)
- .FirstOrDefault();
+.FirstOrDefault(p => (string)p.Attribute(W.numId) == numId);
// Copy abstract numbering element, if necessary (use matching NSID)
- string abstractNumId = string.Empty;
+ var abstractNumId = string.Empty;
if (element != null)
{
abstractNumId = element
@@ -1642,71 +1631,80 @@ private static void MergeStyles(WordprocessingDocument sourceDocument, Wordproce
.Attribute(W.val)
.Value;
- XElement abstractElement = oldNumbering
+ var abstractElement = oldNumbering
.Descendants()
.Elements(W.abstractNum)
- .Where(p => ((string)p.Attribute(W.abstractNumId)) == abstractNumId)
- .FirstOrDefault();
- string abstractNSID = string.Empty;
+.FirstOrDefault(p => (string)p.Attribute(W.abstractNumId) == abstractNumId);
+ var abstractNSID = string.Empty;
if (abstractElement != null)
{
- XElement nsidElement = abstractElement
+ var nsidElement = abstractElement
.Element(W.nsid);
abstractNSID = null;
if (nsidElement != null)
+ {
abstractNSID = (string)nsidElement
.Attribute(W.val);
+ }
- XElement newAbstractElement = newNumbering
+ var newAbstractElement = newNumbering
.Descendants()
.Elements(W.abstractNum)
.Where(e => e.Annotation() == null)
- .Where(p =>
+.FirstOrDefault(p =>
{
var thisNsidElement = p.Element(W.nsid);
if (thisNsidElement == null)
+ {
return false;
+ }
+
return (string)thisNsidElement.Attribute(W.val) == abstractNSID;
- })
- .FirstOrDefault();
+ });
if (newAbstractElement == null)
{
newAbstractElement = new XElement(abstractElement);
newAbstractElement.Attribute(W.abstractNumId).Value = abstractNumber.ToString();
abstractNumber++;
if (newNumbering.Root.Elements(W.abstractNum).Any())
+ {
newNumbering.Root.Elements(W.abstractNum).Last().AddAfterSelf(newAbstractElement);
+ }
else
+ {
newNumbering.Root.Add(newAbstractElement);
+ }
- foreach (XElement pictId in newAbstractElement.Descendants(W.lvlPicBulletId))
+ foreach (var pictId in newAbstractElement.Descendants(W.lvlPicBulletId))
{
- string bulletId = (string)pictId.Attribute(W.val);
- XElement numPicBullet = oldNumbering
+ var bulletId = (string)pictId.Attribute(W.val);
+ var numPicBullet = oldNumbering
.Descendants(W.numPicBullet)
.FirstOrDefault(d => (string)d.Attribute(W.numPicBulletId) == bulletId);
- int maxNumPicBulletId = new int[] { -1 }.Concat(
+ var maxNumPicBulletId = new int[] { -1 }.Concat(
newNumbering.Descendants(W.numPicBullet)
.Attributes(W.numPicBulletId)
.Select(a => (int)a))
.Max() + 1;
- XElement newNumPicBullet = new XElement(numPicBullet);
+ var newNumPicBullet = new XElement(numPicBullet);
newNumPicBullet.Attribute(W.numPicBulletId).Value = maxNumPicBulletId.ToString();
pictId.Attribute(W.val).Value = maxNumPicBulletId.ToString();
newNumbering.Root.AddFirst(newNumPicBullet);
}
}
- string newAbstractId = newAbstractElement.Attribute(W.abstractNumId).Value;
+ var newAbstractId = newAbstractElement.Attribute(W.abstractNumId).Value;
// Copy numbering element, if necessary (use matching element with no overrides)
- XElement newElement = null;
+ XElement? newElement = null;
if (!element.Elements(W.lvlOverride).Any())
+ {
newElement = newNumbering
.Descendants()
.Elements(W.num)
- .Where(p => !p.Elements(W.lvlOverride).Any() &&
- ((string)p.Elements(W.abstractNumId).First().Attribute(W.val)) == newAbstractId)
- .FirstOrDefault();
+.FirstOrDefault(p => !p.Elements(W.lvlOverride).Any() &&
+ (string)p.Elements(W.abstractNumId).First().Attribute(W.val) == newAbstractId);
+ }
+
if (newElement == null)
{
newElement = new XElement(element);
@@ -1734,10 +1732,9 @@ private static void MergeStyles(WordprocessingDocument sourceDocument, Wordproce
else
{
var toId = (string)toStyle.Attribute(W.styleId);
- if (fromId != toId)
+ if (fromId != toId && !newIds.ContainsKey(fromId))
{
- if (! newIds.ContainsKey(fromId))
- newIds.Add(fromId, toId);
+ newIds.Add(fromId, toId);
}
}
}
@@ -1754,9 +1751,7 @@ private static void MergeStyles(WordprocessingDocument sourceDocument, Wordproce
}
foreach (var item in newContent.DescendantsAndSelf()
- .Where(d => d.Name == W.pStyle ||
- d.Name == W.rStyle ||
- d.Name == W.tblStyle))
+ .Where(d => d.Name == W.pStyle || d.Name == W.rStyle || d.Name == W.tblStyle))
{
ConvertToNewId(item, newIds);
}
@@ -1781,7 +1776,9 @@ private static void MergeLatentStyles(XDocument fromStyles, XDocument toStyles)
{
var fromLatentStyles = fromStyles.Descendants(W.latentStyles).FirstOrDefault();
if (fromLatentStyles == null)
+ {
return;
+ }
var toLatentStyles = toStyles.Descendants(W.latentStyles).FirstOrDefault();
if (toLatentStyles == null)
@@ -1798,26 +1795,39 @@ private static void MergeLatentStyles(XDocument fromStyles, XDocument toStyles)
.Elements(W.style)
.FirstOrDefault();
if (firstStyle == null)
+ {
toStyles.Root.Add(newLatentStylesElement);
+ }
else
+ {
firstStyle.AddBeforeSelf(newLatentStylesElement);
+ }
}
else
+ {
globalDefaults.AddAfterSelf(newLatentStylesElement);
+ }
}
toLatentStyles = toStyles.Descendants(W.latentStyles).FirstOrDefault();
if (toLatentStyles == null)
+ {
throw new OpenXmlPowerToolsException("Internal error");
+ }
var toStylesHash = new HashSet();
foreach (var lse in toLatentStyles.Elements(W.lsdException))
+ {
toStylesHash.Add((string)lse.Attribute(W.name));
+ }
foreach (var fls in fromLatentStyles.Elements(W.lsdException))
{
var name = (string)fls.Attribute(W.name);
if (toStylesHash.Contains(name))
+ {
continue;
+ }
+
toLatentStyles.Add(fls);
toStylesHash.Add(name);
}
@@ -1839,14 +1849,16 @@ private static void MergeDocDefaultStyles(XDocument xDocument, XDocument newXDoc
}
#if MergeStylesWithSameNames
+
private static void ConvertToNewId(XElement element, Dictionary newIds)
{
if (element == null)
+ {
return;
+ }
var valueAttribute = element.Attribute(W.val);
- string newId;
- if (newIds.TryGetValue(valueAttribute.Value, out newId))
+ if (newIds.TryGetValue(valueAttribute.Value, out var newId))
{
valueAttribute.Value = newId;
}
@@ -1871,19 +1883,21 @@ private static void ConvertNumberingPartToNewIds(XDocument newNumbering, Diction
ConvertToNewId(item, newIds);
}
}
+
#endif
private static void MergeFontTables(XDocument fromFontTable, XDocument toFontTable)
{
- foreach (XElement font in fromFontTable.Root.Elements(W.font))
+ foreach (var font in fromFontTable.Root.Elements(W.font))
{
- string name = font.Attribute(W.name).Value;
- if (toFontTable
+ var name = font.Attribute(W.name).Value;
+ if (!toFontTable
.Root
.Elements(W.font)
- .Where(o => o.Attribute(W.name).Value == name)
- .Count() == 0)
+.Any(o => o.Attribute(W.name).Value == name))
+ {
toFontTable.Root.Add(new XElement(font));
+ }
}
}
@@ -1893,18 +1907,18 @@ private static void CopyStylesAndFonts(WordprocessingDocument sourceDocument, Wo
// Copy all styles to the new document
if (sourceDocument.MainDocumentPart.StyleDefinitionsPart != null)
{
- XDocument oldStyles = sourceDocument.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
+ var oldStyles = sourceDocument.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
if (newDocument.MainDocumentPart.StyleDefinitionsPart == null)
{
newDocument.MainDocumentPart.AddNewPart();
- XDocument newStyles = newDocument.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
+ var newStyles = newDocument.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
newStyles.Declaration.Standalone = Yes;
newStyles.Declaration.Encoding = Utf8;
newStyles.Add(oldStyles.Root);
}
else
{
- XDocument newStyles = newDocument.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
+ var newStyles = newDocument.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
MergeStyles(sourceDocument, newDocument, oldStyles, newStyles, newContent);
MergeLatentStyles(oldStyles, newStyles);
}
@@ -1913,18 +1927,18 @@ private static void CopyStylesAndFonts(WordprocessingDocument sourceDocument, Wo
// Copy all styles with effects to the new document
if (sourceDocument.MainDocumentPart.StylesWithEffectsPart != null)
{
- XDocument oldStyles = sourceDocument.MainDocumentPart.StylesWithEffectsPart.GetXDocument();
+ var oldStyles = sourceDocument.MainDocumentPart.StylesWithEffectsPart.GetXDocument();
if (newDocument.MainDocumentPart.StylesWithEffectsPart == null)
{
newDocument.MainDocumentPart.AddNewPart();
- XDocument newStyles = newDocument.MainDocumentPart.StylesWithEffectsPart.GetXDocument();
+ var newStyles = newDocument.MainDocumentPart.StylesWithEffectsPart.GetXDocument();
newStyles.Declaration.Standalone = Yes;
newStyles.Declaration.Encoding = Utf8;
newStyles.Add(oldStyles.Root);
}
else
{
- XDocument newStyles = newDocument.MainDocumentPart.StylesWithEffectsPart.GetXDocument();
+ var newStyles = newDocument.MainDocumentPart.StylesWithEffectsPart.GetXDocument();
MergeStyles(sourceDocument, newDocument, oldStyles, newStyles, newContent);
MergeLatentStyles(oldStyles, newStyles);
}
@@ -1933,18 +1947,18 @@ private static void CopyStylesAndFonts(WordprocessingDocument sourceDocument, Wo
// Copy fontTable to the new document
if (sourceDocument.MainDocumentPart.FontTablePart != null)
{
- XDocument oldFontTable = sourceDocument.MainDocumentPart.FontTablePart.GetXDocument();
+ var oldFontTable = sourceDocument.MainDocumentPart.FontTablePart.GetXDocument();
if (newDocument.MainDocumentPart.FontTablePart == null)
{
newDocument.MainDocumentPart.AddNewPart();
- XDocument newFontTable = newDocument.MainDocumentPart.FontTablePart.GetXDocument();
+ var newFontTable = newDocument.MainDocumentPart.FontTablePart.GetXDocument();
newFontTable.Declaration.Standalone = Yes;
newFontTable.Declaration.Encoding = Utf8;
newFontTable.Add(oldFontTable.Root);
}
else
{
- XDocument newFontTable = newDocument.MainDocumentPart.FontTablePart.GetXDocument();
+ var newFontTable = newDocument.MainDocumentPart.FontTablePart.GetXDocument();
MergeFontTables(oldFontTable, newFontTable);
}
}
@@ -1953,14 +1967,17 @@ private static void CopyStylesAndFonts(WordprocessingDocument sourceDocument, Wo
private static void CopyComments(WordprocessingDocument sourceDocument, WordprocessingDocument newDocument,
IEnumerable newContent, List images)
{
- Dictionary commentIdMap = new Dictionary();
- int number = 0;
- XDocument oldComments = null;
- XDocument newComments = null;
- foreach (XElement comment in newContent.DescendantsAndSelf(W.commentReference))
+ var commentIdMap = new Dictionary();
+ var number = 0;
+ XDocument? oldComments = null;
+ XDocument? newComments = null;
+ foreach (var comment in newContent.DescendantsAndSelf(W.commentReference))
{
if (oldComments == null)
+ {
oldComments = sourceDocument.MainDocumentPart.WordprocessingCommentsPart.GetXDocument();
+ }
+
if (newComments == null)
{
if (newDocument.MainDocumentPart.WordprocessingCommentsPart != null)
@@ -1970,7 +1987,9 @@ private static void CopyComments(WordprocessingDocument sourceDocument, Wordproc
newComments.Declaration.Encoding = Utf8;
var ids = newComments.Root.Elements(W.comment).Select(f => (int)f.Attribute(W.id));
if (ids.Any())
+ {
number = ids.Max() + 1;
+ }
}
else
{
@@ -1981,26 +2000,36 @@ private static void CopyComments(WordprocessingDocument sourceDocument, Wordproc
newComments.Add(new XElement(W.comments, NamespaceAttributes));
}
}
- int id;
- if (!int.TryParse((string)comment.Attribute(W.id), out id))
+ if (!int.TryParse((string)comment.Attribute(W.id), out var id))
+ {
throw new DocumentBuilderException("Invalid document - invalid comment id");
- XElement element = oldComments
+ }
+
+ var element = oldComments
.Descendants()
.Elements(W.comment)
- .Where(p => {
- int thisId;
- if (! int.TryParse((string)p.Attribute(W.id), out thisId))
+.FirstOrDefault(p =>
+ {
+ if (!int.TryParse((string)p.Attribute(W.id), out var thisId))
+ {
throw new DocumentBuilderException("Invalid document - invalid comment id");
+ }
+
return thisId == id;
- })
- .FirstOrDefault();
+ });
if (element == null)
+ {
throw new DocumentBuilderException("Invalid document - comment reference without associated comment in comments part");
- XElement newElement = new XElement(element);
+ }
+
+ var newElement = new XElement(element);
newElement.Attribute(W.id).Value = number.ToString();
newComments.Root.Add(newElement);
- if (! commentIdMap.ContainsKey(id))
+ if (!commentIdMap.ContainsKey(id))
+ {
commentIdMap.Add(id, number);
+ }
+
number++;
}
foreach (var item in newContent.DescendantsAndSelf()
@@ -2010,7 +2039,9 @@ private static void CopyComments(WordprocessingDocument sourceDocument, Wordproc
.ToList())
{
if (commentIdMap.ContainsKey((int)item.Attribute(W.id)))
+ {
item.Attribute(W.id).Value = commentIdMap[(int)item.Attribute(W.id)].ToString();
+ }
}
if (sourceDocument.MainDocumentPart.WordprocessingCommentsPart != null &&
newDocument.MainDocumentPart.WordprocessingCommentsPart != null)
@@ -2025,56 +2056,76 @@ private static void CopyComments(WordprocessingDocument sourceDocument, Wordproc
}
}
- private static void AdjustUniqueIds(WordprocessingDocument sourceDocument,
- WordprocessingDocument newDocument, IEnumerable newContent)
+ private static void AdjustUniqueIds(WordprocessingDocument newDocument, IEnumerable newContent)
{
// adjust bookmark unique ids
- int maxId = 0;
+ var maxId = 0;
if (newDocument.MainDocumentPart.GetXDocument().Descendants(W.bookmarkStart).Any())
+ {
maxId = newDocument.MainDocumentPart.GetXDocument().Descendants(W.bookmarkStart)
.Select(d => (int)d.Attribute(W.id)).Max();
- Dictionary bookmarkIdMap = new Dictionary();
+ }
+
+ var bookmarkIdMap = new Dictionary();
foreach (var item in newContent.DescendantsAndSelf().Where(bm => bm.Name == W.bookmarkStart ||
bm.Name == W.bookmarkEnd))
{
- int id;
- if (!int.TryParse((string)item.Attribute(W.id), out id))
+ if (!int.TryParse((string)item.Attribute(W.id), out var id))
+ {
throw new DocumentBuilderException("Invalid document - invalid value for bookmark ID");
+ }
+
if (!bookmarkIdMap.ContainsKey(id))
+ {
bookmarkIdMap.Add(id, ++maxId);
+ }
}
foreach (var bookmarkElement in newContent.DescendantsAndSelf().Where(e => e.Name == W.bookmarkStart ||
e.Name == W.bookmarkEnd))
+ {
bookmarkElement.Attribute(W.id).Value = bookmarkIdMap[(int)bookmarkElement.Attribute(W.id)].ToString();
-
- // adjust shape unique ids
- // This doesn't work because OLEObjects refer to shapes by ID.
- // Punting on this, because sooner or later, this will be a non-issue.
- //foreach (var item in newContent.DescendantsAndSelf(VML.shape))
- //{
- // Guid g = Guid.NewGuid();
- // string s = "R" + g.ToString().Replace("-", "");
- // item.Attribute(NoNamespace.id).Value = s;
- //}
+ }
}
private static void AdjustDocPrIds(WordprocessingDocument newDocument)
{
- int docPrId = 0;
+ var docPrId = 0;
foreach (var item in newDocument.MainDocumentPart.GetXDocument().Descendants(WP.docPr))
+ {
item.Attribute(NoNamespace.id).Value = (++docPrId).ToString();
+ }
+
foreach (var header in newDocument.MainDocumentPart.HeaderParts)
+ {
foreach (var item in header.GetXDocument().Descendants(WP.docPr))
+ {
item.Attribute(NoNamespace.id).Value = (++docPrId).ToString();
+ }
+ }
+
foreach (var footer in newDocument.MainDocumentPart.FooterParts)
+ {
foreach (var item in footer.GetXDocument().Descendants(WP.docPr))
+ {
item.Attribute(NoNamespace.id).Value = (++docPrId).ToString();
+ }
+ }
+
if (newDocument.MainDocumentPart.FootnotesPart != null)
+ {
foreach (var item in newDocument.MainDocumentPart.FootnotesPart.GetXDocument().Descendants(WP.docPr))
+ {
item.Attribute(NoNamespace.id).Value = (++docPrId).ToString();
+ }
+ }
+
if (newDocument.MainDocumentPart.EndnotesPart != null)
+ {
foreach (var item in newDocument.MainDocumentPart.EndnotesPart.GetXDocument().Descendants(WP.docPr))
+ {
item.Attribute(NoNamespace.id).Value = (++docPrId).ToString();
+ }
+ }
}
// This probably doesn't need to be done, except that the Open XML SDK will not validate
@@ -2086,11 +2137,13 @@ private static void RemoveGfxdata(IEnumerable newContent)
private static object InsertTransform(XNode node, List newContent)
{
- XElement element = node as XElement;
- if (element != null)
+ if (node is XElement element)
{
if (element.Annotation() != null)
+ {
return newContent;
+ }
+
return new XElement(element.Name,
element.Attributes(),
element.Nodes().Select(n => InsertTransform(n, newContent)));
@@ -2098,7 +2151,8 @@ private static object InsertTransform(XNode node, List newContent)
return node;
}
- private class ReplaceSemaphore { }
+ private class ReplaceSemaphore
+ { }
// Rules for sections
// - if KeepSections for all documents in the source collection are false, then it takes the section
@@ -2109,7 +2163,7 @@ private class ReplaceSemaphore { }
// - if you specify true for any document, and there are no sections for any paragraphs, then no
// sections are copied.
private static void AppendDocument(WordprocessingDocument sourceDocument, WordprocessingDocument newDocument,
- List newContent, bool keepSection, string insertId, List images)
+ List newContent, bool keepSection, string? insertId, List images)
{
FixRanges(sourceDocument.MainDocumentPart.GetXDocument(), newContent);
AddRelationships(sourceDocument.MainDocumentPart, newDocument.MainDocumentPart, newContent);
@@ -2117,45 +2171,59 @@ private static void AppendDocument(WordprocessingDocument sourceDocument, Wordpr
newContent, images);
// Append contents
- XDocument newMainXDoc = newDocument.MainDocumentPart.GetXDocument();
+ var newMainXDoc = newDocument.MainDocumentPart.GetXDocument();
newMainXDoc.Declaration.Standalone = Yes;
newMainXDoc.Declaration.Encoding = Utf8;
- if (keepSection == false)
+ if (!keepSection)
{
- List adjustedContents = newContent.Where(e => e.Name != W.sectPr).ToList();
+ var adjustedContents = newContent.Where(e => e.Name != W.sectPr).ToList();
adjustedContents.DescendantsAndSelf(W.sectPr).Remove();
newContent = adjustedContents;
}
var listOfSectionProps = newContent.DescendantsAndSelf(W.sectPr).ToList();
foreach (var sectPr in listOfSectionProps)
+ {
AddSectionAndDependencies(sourceDocument, newDocument, sectPr, images);
+ }
+
CopyStylesAndFonts(sourceDocument, newDocument, newContent);
CopyNumbering(sourceDocument, newDocument, newContent, images);
CopyComments(sourceDocument, newDocument, newContent, images);
CopyFootnotes(sourceDocument, newDocument, newContent, images);
CopyEndnotes(sourceDocument, newDocument, newContent, images);
- AdjustUniqueIds(sourceDocument, newDocument, newContent);
+ AdjustUniqueIds(newDocument, newContent);
RemoveGfxdata(newContent);
CopyCustomXmlPartsForDataBoundContentControls(sourceDocument, newDocument, newContent);
CopyWebExtensions(sourceDocument, newDocument);
if (insertId != null)
{
- XElement insertElementToReplace = newMainXDoc
+ var insertElementToReplace = newMainXDoc
.Descendants(PtOpenXml.Insert)
.FirstOrDefault(i => (string)i.Attribute(PtOpenXml.Id) == insertId);
if (insertElementToReplace != null)
+ {
insertElementToReplace.AddAnnotation(new ReplaceSemaphore());
+ }
+
newMainXDoc.Element(W.document).ReplaceWith((XElement)InsertTransform(newMainXDoc.Root, newContent));
}
else
+ {
newMainXDoc.Root.Element(W.body).Add(newContent);
+ }
if (newMainXDoc.Descendants().Any(d =>
{
if (d.Name.Namespace == PtOpenXml.pt || d.Name.Namespace == PtOpenXml.ptOpenXml)
+ {
return true;
+ }
+
if (d.Attributes().Any(att => att.Name.Namespace == PtOpenXml.pt || att.Name.Namespace == PtOpenXml.ptOpenXml))
+ {
return true;
+ }
+
return false;
}))
{
@@ -2201,13 +2269,12 @@ private static void AddToIgnorable(XElement root, string v)
}
}
- /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// New method to support new functionality
private static void AppendDocument(WordprocessingDocument sourceDocument, WordprocessingDocument newDocument, OpenXmlPart part,
- List newContent, bool keepSection, string insertId, List images)
+ List newContent, string insertId, List images)
{
// Append contents
- XDocument partXDoc = part.GetXDocument();
+ var partXDoc = part.GetXDocument();
partXDoc.Declaration.Standalone = Yes;
partXDoc.Declaration.Encoding = Utf8;
@@ -2217,69 +2284,78 @@ private static void AppendDocument(WordprocessingDocument sourceDocument, Wordpr
newContent, images);
// never keep sections for content to be inserted into a header/footer
- List adjustedContents = newContent.Where(e => e.Name != W.sectPr).ToList();
+ var adjustedContents = newContent.Where(e => e.Name != W.sectPr).ToList();
adjustedContents.DescendantsAndSelf(W.sectPr).Remove();
newContent = adjustedContents;
CopyNumbering(sourceDocument, newDocument, newContent, images);
CopyComments(sourceDocument, newDocument, newContent, images);
- AdjustUniqueIds(sourceDocument, newDocument, newContent);
+ AdjustUniqueIds(newDocument, newContent);
RemoveGfxdata(newContent);
if (insertId == null)
+ {
throw new OpenXmlPowerToolsException("Internal error");
+ }
- XElement insertElementToReplace = partXDoc
+ var insertElementToReplace = partXDoc
.Descendants(PtOpenXml.Insert)
.FirstOrDefault(i => (string)i.Attribute(PtOpenXml.Id) == insertId);
if (insertElementToReplace != null)
+ {
insertElementToReplace.AddAnnotation(new ReplaceSemaphore());
+ }
+
partXDoc.Elements().First().ReplaceWith((XElement)InsertTransform(partXDoc.Root, newContent));
}
- /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- public static WmlDocument ExtractGlossaryDocument(WmlDocument wmlGlossaryDocument)
+ public static WmlDocument? ExtractGlossaryDocument(WmlDocument wmlGlossaryDocument)
{
if (RelationshipMarkup == null)
+ {
InitRelationshipMarkup();
+ }
- using (MemoryStream ms = new MemoryStream())
+ using var ms = new MemoryStream();
+ ms.Write(wmlGlossaryDocument.DocumentByteArray, 0, wmlGlossaryDocument.DocumentByteArray.Length);
+ using var wDoc = WordprocessingDocument.Open(ms, false);
+ if (wDoc.MainDocumentPart.GlossaryDocumentPart == null)
{
- ms.Write(wmlGlossaryDocument.DocumentByteArray, 0, wmlGlossaryDocument.DocumentByteArray.Length);
- using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, false))
- {
- if (wDoc.MainDocumentPart.GlossaryDocumentPart == null)
- return null;
-
- var fromXd = wDoc.MainDocumentPart.GlossaryDocumentPart.GetXDocument();
- if (fromXd.Root == null)
- return null;
+ return null;
+ }
- using (MemoryStream outMs = new MemoryStream())
- {
- using (WordprocessingDocument outWDoc = WordprocessingDocument.Create(outMs, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
- {
- List images = new List();
+ var fromXd = wDoc.MainDocumentPart.GlossaryDocumentPart.GetXDocument();
+ if (fromXd.Root == null)
+ {
+ return null;
+ }
- MainDocumentPart mdp = outWDoc.AddMainDocumentPart();
- var mdpXd = mdp.GetXDocument();
- XElement root = new XElement(W.document);
- if (mdpXd.Root == null)
- mdpXd.Add(root);
- else
- mdpXd.Root.ReplaceWith(root);
- root.Add(new XElement(W.body,
- fromXd.Root.Elements(W.docParts)));
- mdp.PutXDocument();
+ using var outMs = new MemoryStream();
+ using (var outWDoc = WordprocessingDocument.Create(outMs, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
+ {
+ var images = new List