@nguyenphp/antigravity-marketing 1.0.18 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -78
- package/package.json +4 -3
- package/templates/.agent/skills/marketing-report-expert/SKILL.md +70 -0
- package/templates/.agent/skills/minimax-docx/LICENSE +21 -0
- package/templates/.agent/skills/minimax-docx/SKILL.md +274 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/academic_styles.xml +250 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/corporate_styles.xml +284 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/default_styles.xml +449 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/aesthetic-rules.xsd +470 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/business-rules.xsd +130 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/common-types.xsd +159 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/wml-subset.xsd +589 -0
- package/templates/.agent/skills/minimax-docx/references/cjk_typography.md +357 -0
- package/templates/.agent/skills/minimax-docx/references/cjk_university_template_guide.md +184 -0
- package/templates/.agent/skills/minimax-docx/references/comments_guide.md +191 -0
- package/templates/.agent/skills/minimax-docx/references/design_good_bad_examples.md +829 -0
- package/templates/.agent/skills/minimax-docx/references/design_principles.md +819 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_element_order.md +308 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part1.md +4061 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part2.md +2820 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part3.md +3381 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_namespaces.md +82 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_units.md +72 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_a_create.md +284 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_b_edit_content.md +295 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_c_apply_template.md +456 -0
- package/templates/.agent/skills/minimax-docx/references/track_changes_guide.md +200 -0
- package/templates/.agent/skills/minimax-docx/references/troubleshooting.md +506 -0
- package/templates/.agent/skills/minimax-docx/references/typography_guide.md +294 -0
- package/templates/.agent/skills/minimax-docx/references/xsd_validation_guide.md +158 -0
- package/templates/.agent/skills/minimax-docx/scripts/doc_to_docx.sh +40 -0
- package/templates/.agent/skills/minimax-docx/scripts/docx_preview.sh +37 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/MiniMaxAIDocx.Cli.csproj +19 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/Program.cs +18 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/AnalyzeCommand.cs +147 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ApplyTemplateCommand.cs +322 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/CreateCommand.cs +324 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/DiffCommand.cs +155 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/EditContentCommand.cs +487 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/FixOrderCommand.cs +108 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/MergeRunsCommand.cs +122 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ValidateCommand.cs +107 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/MiniMaxAIDocx.Core.csproj +15 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/CommentSynchronizer.cs +169 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/ElementOrder.cs +80 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/NamespaceConstants.cs +42 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/RunMerger.cs +81 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/StyleAnalyzer.cs +81 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/TrackChangesHelper.cs +99 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/UnitConverter.cs +23 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples.cs +1832 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch1.cs +910 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch2.cs +999 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch3.cs +1048 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch4.cs +1038 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/CharacterFormattingSamples.cs +1020 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/DocumentCreationSamples.cs +1121 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FieldAndTocSamples.cs +624 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FootnoteAndCommentSamples.cs +675 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/HeaderFooterSamples.cs +838 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ImageSamples.cs +917 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ListAndNumberingSamples.cs +826 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ParagraphFormattingSamples.cs +1199 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/StyleSystemSamples.cs +1487 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TableSamples.cs +1163 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TrackChangesSamples.cs +595 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/CjkHelper.cs +39 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/FontDefaults.cs +24 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/PageSizes.cs +20 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/BusinessRuleValidator.cs +224 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/GateCheckValidator.cs +148 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/ValidationResult.cs +23 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/XsdValidator.cs +69 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.slnx +4 -0
- package/templates/.agent/skills/minimax-docx/scripts/env_check.sh +196 -0
- package/templates/.agent/skills/minimax-docx/scripts/setup.ps1 +274 -0
- package/templates/.agent/skills/minimax-docx/scripts/setup.sh +504 -0
- package/templates/.agent/skills/minimax-multimodal-toolkit/SKILL.md +359 -0
- package/templates/.agent/skills/minimax-pdf/README.md +222 -0
- package/templates/.agent/skills/minimax-pdf/SKILL.md +201 -0
- package/templates/.agent/skills/minimax-pdf/design/design.md +381 -0
- package/templates/.agent/skills/minimax-pdf/scripts/cover.py +1579 -0
- package/templates/.agent/skills/minimax-pdf/scripts/fill_inspect.py +200 -0
- package/templates/.agent/skills/minimax-pdf/scripts/fill_write.py +242 -0
- package/templates/.agent/skills/minimax-pdf/scripts/make.sh +491 -0
- package/templates/.agent/skills/minimax-pdf/scripts/merge.py +112 -0
- package/templates/.agent/skills/minimax-pdf/scripts/palette.py +559 -0
- package/templates/.agent/skills/minimax-pdf/scripts/reformat_parse.py +374 -0
- package/templates/.agent/skills/minimax-pdf/scripts/render_body.py +1055 -0
- package/templates/.agent/skills/minimax-pdf/scripts/render_cover.cjs +111 -0
- package/templates/.agent/skills/minimax-xlsx/SKILL.md +138 -0
- package/templates/.agent/skills/minimax-xlsx/references/create.md +691 -0
- package/templates/.agent/skills/minimax-xlsx/references/edit.md +684 -0
- package/templates/.agent/skills/minimax-xlsx/references/fix.md +37 -0
- package/templates/.agent/skills/minimax-xlsx/references/format.md +768 -0
- package/templates/.agent/skills/minimax-xlsx/references/ooxml-cheatsheet.md +231 -0
- package/templates/.agent/skills/minimax-xlsx/references/read-analyze.md +97 -0
- package/templates/.agent/skills/minimax-xlsx/references/validate.md +772 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/formula_check.py +422 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/libreoffice_recalc.py +248 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/shared_strings_builder.py +163 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/style_audit.py +575 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_add_column.py +395 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_insert_row.py +274 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_pack.py +87 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_reader.py +362 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_shift_rows.py +396 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_unpack.py +130 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/[Content_Types].xml +9 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/_rels/.rels +6 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/_rels/workbook.xml.rels +19 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/sharedStrings.xml +33 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/styles.xml +160 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/workbook.xml +30 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/worksheets/sheet1.xml +70 -0
- package/templates/.agent/skills/pptx-generator/SKILL.md +249 -0
- package/templates/.agent/skills/pptx-generator/references/design-system.md +392 -0
- package/templates/.agent/skills/pptx-generator/references/editing.md +162 -0
- package/templates/.agent/skills/pptx-generator/references/pitfalls.md +112 -0
- package/templates/.agent/skills/pptx-generator/references/pptxgenjs.md +420 -0
- package/templates/.agent/skills/pptx-generator/references/slide-types.md +413 -0
- package/templates/.agent/skills/tutorial-video-expert/SKILL.md +88 -0
- package/templates/.agent/skills/ui-ux-pro-max/SKILL.md +170 -585
- package/templates/.agent/skills/vision-analysis/SKILL.md +174 -0
- package/templates/.agent/workflows/analyze.md +3 -0
- package/templates/.agent/workflows/brand-report.md +44 -0
- package/templates/.agent/workflows/report.md +49 -0
- package/templates/.agent/agents/backend-specialist.md +0 -263
- package/templates/.agent/agents/database-architect.md +0 -226
- package/templates/.agent/agents/debugger.md +0 -225
- package/templates/.agent/agents/devops-engineer.md +0 -242
- package/templates/.agent/agents/frontend-specialist.md +0 -527
- package/templates/.agent/agents/game-developer.md +0 -162
- package/templates/.agent/agents/mobile-developer.md +0 -377
- package/templates/.agent/agents/penetration-tester.md +0 -188
- package/templates/.agent/agents/security-auditor.md +0 -170
- package/templates/.agent/agents/test-engineer.md +0 -158
- package/templates/.agent/skills/api-patterns/SKILL.md +0 -81
- package/templates/.agent/skills/api-patterns/api-style.md +0 -42
- package/templates/.agent/skills/api-patterns/auth.md +0 -24
- package/templates/.agent/skills/api-patterns/documentation.md +0 -26
- package/templates/.agent/skills/api-patterns/graphql.md +0 -41
- package/templates/.agent/skills/api-patterns/rate-limiting.md +0 -31
- package/templates/.agent/skills/api-patterns/response.md +0 -37
- package/templates/.agent/skills/api-patterns/rest.md +0 -40
- package/templates/.agent/skills/api-patterns/scripts/api_validator.py +0 -211
- package/templates/.agent/skills/api-patterns/security-testing.md +0 -122
- package/templates/.agent/skills/api-patterns/trpc.md +0 -41
- package/templates/.agent/skills/api-patterns/versioning.md +0 -22
- package/templates/.agent/skills/app-builder/SKILL.md +0 -75
- package/templates/.agent/skills/app-builder/agent-coordination.md +0 -71
- package/templates/.agent/skills/app-builder/feature-building.md +0 -53
- package/templates/.agent/skills/app-builder/project-detection.md +0 -34
- package/templates/.agent/skills/app-builder/scaffolding.md +0 -118
- package/templates/.agent/skills/app-builder/tech-stack.md +0 -40
- package/templates/.agent/skills/app-builder/templates/SKILL.md +0 -39
- package/templates/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -76
- package/templates/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -92
- package/templates/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -88
- package/templates/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -88
- package/templates/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +0 -83
- package/templates/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -90
- package/templates/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -90
- package/templates/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -82
- package/templates/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -100
- package/templates/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -106
- package/templates/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -101
- package/templates/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -83
- package/templates/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -93
- package/templates/.agent/skills/architecture/SKILL.md +0 -55
- package/templates/.agent/skills/architecture/context-discovery.md +0 -43
- package/templates/.agent/skills/architecture/examples.md +0 -94
- package/templates/.agent/skills/architecture/pattern-selection.md +0 -68
- package/templates/.agent/skills/architecture/patterns-reference.md +0 -50
- package/templates/.agent/skills/architecture/trade-off-analysis.md +0 -77
- package/templates/.agent/skills/bash-linux/SKILL.md +0 -199
- package/templates/.agent/skills/behavioral-modes/SKILL.md +0 -242
- package/templates/.agent/skills/clean-code/SKILL.md +0 -201
- package/templates/.agent/skills/code-review-checklist/SKILL.md +0 -109
- package/templates/.agent/skills/database-design/SKILL.md +0 -52
- package/templates/.agent/skills/database-design/database-selection.md +0 -43
- package/templates/.agent/skills/database-design/indexing.md +0 -39
- package/templates/.agent/skills/database-design/migrations.md +0 -48
- package/templates/.agent/skills/database-design/optimization.md +0 -36
- package/templates/.agent/skills/database-design/orm-selection.md +0 -30
- package/templates/.agent/skills/database-design/schema-design.md +0 -56
- package/templates/.agent/skills/database-design/scripts/schema_validator.py +0 -172
- package/templates/.agent/skills/deployment-procedures/SKILL.md +0 -241
- package/templates/.agent/skills/docker-expert/SKILL.md +0 -409
- package/templates/.agent/skills/game-development/2d-games/SKILL.md +0 -119
- package/templates/.agent/skills/game-development/3d-games/SKILL.md +0 -135
- package/templates/.agent/skills/game-development/SKILL.md +0 -167
- package/templates/.agent/skills/game-development/game-art/SKILL.md +0 -185
- package/templates/.agent/skills/game-development/game-audio/SKILL.md +0 -190
- package/templates/.agent/skills/game-development/game-design/SKILL.md +0 -129
- package/templates/.agent/skills/game-development/mobile-games/SKILL.md +0 -108
- package/templates/.agent/skills/game-development/multiplayer/SKILL.md +0 -132
- package/templates/.agent/skills/game-development/pc-games/SKILL.md +0 -144
- package/templates/.agent/skills/game-development/vr-ar/SKILL.md +0 -123
- package/templates/.agent/skills/game-development/web-games/SKILL.md +0 -150
- package/templates/.agent/skills/lint-and-validate/SKILL.md +0 -45
- package/templates/.agent/skills/lint-and-validate/scripts/lint_runner.py +0 -172
- package/templates/.agent/skills/lint-and-validate/scripts/type_coverage.py +0 -173
- package/templates/.agent/skills/mcp-builder/SKILL.md +0 -176
- package/templates/.agent/skills/nestjs-expert/SKILL.md +0 -552
- package/templates/.agent/skills/nextjs-best-practices/SKILL.md +0 -203
- package/templates/.agent/skills/nodejs-best-practices/SKILL.md +0 -333
- package/templates/.agent/skills/parallel-agents/SKILL.md +0 -175
- package/templates/.agent/skills/performance-profiling/SKILL.md +0 -143
- package/templates/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +0 -76
- package/templates/.agent/skills/powershell-windows/SKILL.md +0 -167
- package/templates/.agent/skills/prisma-expert/SKILL.md +0 -355
- package/templates/.agent/skills/python-patterns/SKILL.md +0 -441
- package/templates/.agent/skills/react-patterns/SKILL.md +0 -198
- package/templates/.agent/skills/red-team-tactics/SKILL.md +0 -199
- package/templates/.agent/skills/server-management/SKILL.md +0 -161
- package/templates/.agent/skills/systematic-debugging/SKILL.md +0 -109
- package/templates/.agent/skills/tdd-workflow/SKILL.md +0 -149
- package/templates/.agent/skills/testing-patterns/SKILL.md +0 -178
- package/templates/.agent/skills/testing-patterns/scripts/test_runner.py +0 -219
- package/templates/.agent/skills/typescript-expert/SKILL.md +0 -429
- package/templates/.agent/skills/vue-expert/SKILL.md +0 -374
- package/templates/.agent/skills/vulnerability-scanner/SKILL.md +0 -276
- package/templates/.agent/skills/vulnerability-scanner/checklists.md +0 -121
- package/templates/.agent/skills/vulnerability-scanner/scripts/security_scan.py +0 -458
- package/templates/.agent/skills/webapp-testing/SKILL.md +0 -187
- package/templates/.agent/skills/webapp-testing/scripts/playwright_runner.py +0 -173
- package/templates/.agent/workflows/debug.md +0 -103
- package/templates/.agent/workflows/deploy.md +0 -176
- package/templates/.agent/workflows/enhance.md +0 -63
- package/templates/.agent/workflows/test.md +0 -144
|
@@ -0,0 +1,1199 @@
|
|
|
1
|
+
using DocumentFormat.OpenXml;
|
|
2
|
+
using DocumentFormat.OpenXml.Wordprocessing;
|
|
3
|
+
|
|
4
|
+
namespace MiniMaxAIDocx.Core.Samples;
|
|
5
|
+
|
|
6
|
+
/// <summary>
|
|
7
|
+
/// Exhaustive reference for every ParagraphProperties (w:pPr) child element in OpenXML.
|
|
8
|
+
/// Each method demonstrates one formatting category with full XML doc comments,
|
|
9
|
+
/// unit explanations, and gotchas. All code compiles against DocumentFormat.OpenXml 3.5.1.
|
|
10
|
+
/// </summary>
|
|
11
|
+
public static class ParagraphFormattingSamples
|
|
12
|
+
{
|
|
13
|
+
// ──────────────────────────────────────────────────────────────────
|
|
14
|
+
// 1. Justification / Alignment (w:jc)
|
|
15
|
+
// ──────────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
/// <summary>
|
|
18
|
+
/// Sets paragraph horizontal alignment (justification).
|
|
19
|
+
/// <para>
|
|
20
|
+
/// <b>All JustificationValues:</b>
|
|
21
|
+
/// <list type="bullet">
|
|
22
|
+
/// <item><b>Left</b> — Left-aligned (default for LTR documents). Ragged right edge.</item>
|
|
23
|
+
/// <item><b>Center</b> — Centered text.</item>
|
|
24
|
+
/// <item><b>Right</b> — Right-aligned. Ragged left edge.</item>
|
|
25
|
+
/// <item><b>Both</b> — Justified: text stretches to fill the full line width.
|
|
26
|
+
/// The last line is left-aligned. Word adjusts inter-word spacing.</item>
|
|
27
|
+
/// <item><b>Distribute</b> — Like justify, but also stretches the last line.
|
|
28
|
+
/// Word adjusts both inter-word AND inter-character spacing. Used in CJK typography.</item>
|
|
29
|
+
/// <item><b>ThaiDistribute</b> — Special distribute mode for Thai script,
|
|
30
|
+
/// which has unique spacing rules around vowel marks and tone marks.</item>
|
|
31
|
+
/// </list>
|
|
32
|
+
/// </para>
|
|
33
|
+
/// <para>
|
|
34
|
+
/// <b>Gotcha:</b> In RTL paragraphs (w:bidi), "Left" actually means the START edge
|
|
35
|
+
/// (right side in RTL) and "Right" means the END edge. Use Start/End values if
|
|
36
|
+
/// you need direction-independent alignment (not all renderers support them).
|
|
37
|
+
/// </para>
|
|
38
|
+
/// </summary>
|
|
39
|
+
public static void ApplyJustification(Paragraph para)
|
|
40
|
+
{
|
|
41
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
42
|
+
|
|
43
|
+
// Left-aligned (default for Western text)
|
|
44
|
+
pPr.Justification = new Justification { Val = JustificationValues.Left };
|
|
45
|
+
|
|
46
|
+
// Center-aligned
|
|
47
|
+
// pPr.Justification = new Justification { Val = JustificationValues.Center };
|
|
48
|
+
|
|
49
|
+
// Right-aligned
|
|
50
|
+
// pPr.Justification = new Justification { Val = JustificationValues.Right };
|
|
51
|
+
|
|
52
|
+
// Justified (both edges flush, last line left-aligned)
|
|
53
|
+
// pPr.Justification = new Justification { Val = JustificationValues.Both };
|
|
54
|
+
|
|
55
|
+
// Distribute (all lines justified including last, with inter-character spacing)
|
|
56
|
+
// pPr.Justification = new Justification { Val = JustificationValues.Distribute };
|
|
57
|
+
|
|
58
|
+
// Thai distribute (specialized Thai script distribution)
|
|
59
|
+
// pPr.Justification = new Justification { Val = JustificationValues.ThaiDistribute };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ──────────────────────────────────────────────────────────────────
|
|
63
|
+
// 2. Indentation (w:ind)
|
|
64
|
+
// ──────────────────────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
/// <summary>
|
|
67
|
+
/// Sets paragraph indentation: left, right, first-line, and hanging.
|
|
68
|
+
/// <para>
|
|
69
|
+
/// <b>Units:</b> All values are in <b>DXA</b> (twentieths of a point).
|
|
70
|
+
/// 1 inch = 1440 DXA, 1 cm ≈ 567 DXA, 1 pt = 20 DXA.
|
|
71
|
+
/// </para>
|
|
72
|
+
/// <para>
|
|
73
|
+
/// <b>Properties:</b>
|
|
74
|
+
/// <list type="bullet">
|
|
75
|
+
/// <item><b>Left</b> — Left indent for the entire paragraph (shifts all lines right).</item>
|
|
76
|
+
/// <item><b>Right</b> — Right indent (shifts the right boundary left).</item>
|
|
77
|
+
/// <item><b>FirstLine</b> — Additional indent for the FIRST line only (added to Left).
|
|
78
|
+
/// 720 DXA = 0.5 inch first-line indent.</item>
|
|
79
|
+
/// <item><b>Hanging</b> — The first line hangs LEFT of the paragraph body.
|
|
80
|
+
/// Used for numbered/bulleted lists. Mutually exclusive with FirstLine.</item>
|
|
81
|
+
/// </list>
|
|
82
|
+
/// </para>
|
|
83
|
+
/// <para>
|
|
84
|
+
/// <b>CJK character units:</b>
|
|
85
|
+
/// <list type="bullet">
|
|
86
|
+
/// <item><b>FirstLineChars</b> — First-line indent in hundredths of a character width.
|
|
87
|
+
/// 200 = 2 character widths. Takes precedence over FirstLine when set.</item>
|
|
88
|
+
/// <item><b>LeftChars</b> — Left indent in hundredths of a character width.</item>
|
|
89
|
+
/// <item><b>RightChars</b> — Right indent in hundredths of a character width.</item>
|
|
90
|
+
/// <item><b>HangingChars</b> — Hanging indent in hundredths of a character width.</item>
|
|
91
|
+
/// </list>
|
|
92
|
+
/// </para>
|
|
93
|
+
/// <para>
|
|
94
|
+
/// <b>Gotcha:</b> FirstLine and Hanging are mutually exclusive. If both are set,
|
|
95
|
+
/// behavior is undefined. Setting one should clear the other.
|
|
96
|
+
/// </para>
|
|
97
|
+
/// <para>
|
|
98
|
+
/// <b>Gotcha:</b> When using character-based units (FirstLineChars, etc.),
|
|
99
|
+
/// the corresponding DXA value (FirstLine, etc.) should also be set as a fallback
|
|
100
|
+
/// for renderers that do not support character-based indentation.
|
|
101
|
+
/// </para>
|
|
102
|
+
/// </summary>
|
|
103
|
+
public static void ApplyIndentation(Paragraph para)
|
|
104
|
+
{
|
|
105
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
106
|
+
|
|
107
|
+
// Standard indentation in DXA
|
|
108
|
+
pPr.Indentation = new Indentation
|
|
109
|
+
{
|
|
110
|
+
Left = "720", // 0.5 inch left indent (720 DXA)
|
|
111
|
+
Right = "360", // 0.25 inch right indent (360 DXA)
|
|
112
|
+
FirstLine = "720" // 0.5 inch first-line indent (720 DXA)
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Hanging indent (commonly used with bullets/numbering)
|
|
116
|
+
// pPr.Indentation = new Indentation
|
|
117
|
+
// {
|
|
118
|
+
// Left = "720", // Overall paragraph indent
|
|
119
|
+
// Hanging = "360" // First line hangs back 0.25 inch
|
|
120
|
+
// // Effective first line position: 720 - 360 = 360 DXA from margin
|
|
121
|
+
// };
|
|
122
|
+
|
|
123
|
+
// CJK character-based indent
|
|
124
|
+
// pPr.Indentation = new Indentation
|
|
125
|
+
// {
|
|
126
|
+
// FirstLineChars = 200, // 2 character widths (200 hundredths)
|
|
127
|
+
// FirstLine = "480" // DXA fallback (approx 2 chars at ~10.5pt SimSun)
|
|
128
|
+
// };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ──────────────────────────────────────────────────────────────────
|
|
132
|
+
// 3. Line Spacing (w:spacing — line, lineRule)
|
|
133
|
+
// ──────────────────────────────────────────────────────────────────
|
|
134
|
+
|
|
135
|
+
/// <summary>
|
|
136
|
+
/// Sets the spacing between lines within a paragraph.
|
|
137
|
+
/// <para>
|
|
138
|
+
/// <b>LineRule values and their Line units:</b>
|
|
139
|
+
/// <list type="bullet">
|
|
140
|
+
/// <item><b>Auto</b> — Line is in <b>240ths of a line</b> (proportional).
|
|
141
|
+
/// 240 = single spacing (1.0), 276 = 1.15 (Word default), 360 = 1.5, 480 = 2.0.
|
|
142
|
+
/// Formula: value = desiredMultiplier * 240.</item>
|
|
143
|
+
/// <item><b>Exact</b> — Line is in <b>DXA</b> (twentieths of a point).
|
|
144
|
+
/// The line height is fixed at exactly this value. Text may be clipped if too tall.
|
|
145
|
+
/// Example: 240 DXA = 12pt exact line height.</item>
|
|
146
|
+
/// <item><b>AtLeast</b> — Line is in <b>DXA</b>. The line height is at least this
|
|
147
|
+
/// value, but can grow larger to accommodate tall content (images, large fonts).
|
|
148
|
+
/// Example: 240 DXA = at least 12pt.</item>
|
|
149
|
+
/// </list>
|
|
150
|
+
/// </para>
|
|
151
|
+
/// <para>
|
|
152
|
+
/// <b>Gotcha:</b> The unit of "Line" changes depending on LineRule!
|
|
153
|
+
/// Auto = 240ths of a line, Exact/AtLeast = DXA (twips). This is a very common
|
|
154
|
+
/// source of bugs. If you set Line="360" with LineRule=Auto, you get 1.5x spacing.
|
|
155
|
+
/// If you set Line="360" with LineRule=Exact, you get 18pt fixed height.
|
|
156
|
+
/// </para>
|
|
157
|
+
/// <para>
|
|
158
|
+
/// <b>Gotcha:</b> If LineRule is omitted, it defaults to Auto.
|
|
159
|
+
/// </para>
|
|
160
|
+
/// </summary>
|
|
161
|
+
public static void ApplyLineSpacing(Paragraph para)
|
|
162
|
+
{
|
|
163
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
164
|
+
|
|
165
|
+
// Single spacing (1.0x) — Auto mode, 240/240 = 1.0
|
|
166
|
+
// pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
167
|
+
// {
|
|
168
|
+
// Line = "240",
|
|
169
|
+
// LineRule = LineSpacingRuleValues.Auto
|
|
170
|
+
// };
|
|
171
|
+
|
|
172
|
+
// 1.15x spacing (Word's default) — Auto mode, 276/240 = 1.15
|
|
173
|
+
pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
174
|
+
{
|
|
175
|
+
Line = "276",
|
|
176
|
+
LineRule = LineSpacingRuleValues.Auto
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// 1.5x spacing — Auto mode, 360/240 = 1.5
|
|
180
|
+
// pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
181
|
+
// {
|
|
182
|
+
// Line = "360",
|
|
183
|
+
// LineRule = LineSpacingRuleValues.Auto
|
|
184
|
+
// };
|
|
185
|
+
|
|
186
|
+
// Double spacing (2.0x) — Auto mode, 480/240 = 2.0
|
|
187
|
+
// pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
188
|
+
// {
|
|
189
|
+
// Line = "480",
|
|
190
|
+
// LineRule = LineSpacingRuleValues.Auto
|
|
191
|
+
// };
|
|
192
|
+
|
|
193
|
+
// Exact 14pt line height — no growing for tall content
|
|
194
|
+
// pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
195
|
+
// {
|
|
196
|
+
// Line = "280", // 14pt × 20 DXA/pt = 280 DXA
|
|
197
|
+
// LineRule = LineSpacingRuleValues.Exact
|
|
198
|
+
// };
|
|
199
|
+
|
|
200
|
+
// At-least 12pt — minimum height, can grow
|
|
201
|
+
// pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
202
|
+
// {
|
|
203
|
+
// Line = "240", // 12pt × 20 = 240 DXA
|
|
204
|
+
// LineRule = LineSpacingRuleValues.AtLeast
|
|
205
|
+
// };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// ──────────────────────────────────────────────────────────────────
|
|
209
|
+
// 4. Paragraph Spacing — Before/After (w:spacing — before, after)
|
|
210
|
+
// ──────────────────────────────────────────────────────────────────
|
|
211
|
+
|
|
212
|
+
/// <summary>
|
|
213
|
+
/// Sets the space before and after a paragraph.
|
|
214
|
+
/// <para>
|
|
215
|
+
/// <b>Unit:</b> Before and After are in <b>DXA</b> (twentieths of a point).
|
|
216
|
+
/// 1pt = 20 DXA. Common values: 0 DXA = 0pt, 120 DXA = 6pt, 200 DXA = 10pt,
|
|
217
|
+
/// 240 DXA = 12pt.
|
|
218
|
+
/// </para>
|
|
219
|
+
/// <para>
|
|
220
|
+
/// <b>CJK line units:</b>
|
|
221
|
+
/// <list type="bullet">
|
|
222
|
+
/// <item><b>BeforeLines</b> — Space before in hundredths of a line.
|
|
223
|
+
/// 100 = 1 line of space. Takes precedence over Before when set.</item>
|
|
224
|
+
/// <item><b>AfterLines</b> — Space after in hundredths of a line.</item>
|
|
225
|
+
/// </list>
|
|
226
|
+
/// </para>
|
|
227
|
+
/// <para>
|
|
228
|
+
/// <b>Gotcha:</b> Paragraph spacing collapses: when two paragraphs are adjacent,
|
|
229
|
+
/// the space between them is the LARGER of paragraph1.After and paragraph2.Before,
|
|
230
|
+
/// NOT the sum. This is standard Word behavior.
|
|
231
|
+
/// </para>
|
|
232
|
+
/// <para>
|
|
233
|
+
/// <b>Gotcha:</b> <see cref="ApplyContextualSpacing"/> can suppress spacing between
|
|
234
|
+
/// paragraphs of the same style, overriding Before/After.
|
|
235
|
+
/// </para>
|
|
236
|
+
/// <para>
|
|
237
|
+
/// <b>BeforeAutoSpacing / AfterAutoSpacing:</b> When set to true, Word auto-calculates
|
|
238
|
+
/// the spacing (typically 14pt for HTML-imported paragraphs). Overrides Before/After.
|
|
239
|
+
/// </para>
|
|
240
|
+
/// </summary>
|
|
241
|
+
public static void ApplyParagraphSpacing(Paragraph para)
|
|
242
|
+
{
|
|
243
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
244
|
+
|
|
245
|
+
// 6pt before, 10pt after (typical body text spacing)
|
|
246
|
+
pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
247
|
+
{
|
|
248
|
+
Before = "120", // 6pt × 20 = 120 DXA
|
|
249
|
+
After = "200" // 10pt × 20 = 200 DXA
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// Combined with line spacing
|
|
253
|
+
// pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
254
|
+
// {
|
|
255
|
+
// Before = "240", // 12pt before
|
|
256
|
+
// After = "120", // 6pt after
|
|
257
|
+
// Line = "276", // 1.15x line spacing
|
|
258
|
+
// LineRule = LineSpacingRuleValues.Auto
|
|
259
|
+
// };
|
|
260
|
+
|
|
261
|
+
// CJK line-based spacing
|
|
262
|
+
// pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
263
|
+
// {
|
|
264
|
+
// BeforeLines = 50, // 0.5 line before
|
|
265
|
+
// AfterLines = 100, // 1 line after
|
|
266
|
+
// Before = "120", // DXA fallback
|
|
267
|
+
// After = "240" // DXA fallback
|
|
268
|
+
// };
|
|
269
|
+
|
|
270
|
+
// Auto spacing (used in HTML imports)
|
|
271
|
+
// pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
272
|
+
// {
|
|
273
|
+
// BeforeAutoSpacing = true, // Word decides (typically 14pt)
|
|
274
|
+
// AfterAutoSpacing = true
|
|
275
|
+
// };
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ──────────────────────────────────────────────────────────────────
|
|
279
|
+
// 5. Pagination Control (w:keepNext, w:keepLines, w:widowControl,
|
|
280
|
+
// w:pageBreakBefore)
|
|
281
|
+
// ──────────────────────────────────────────────────────────────────
|
|
282
|
+
|
|
283
|
+
/// <summary>
|
|
284
|
+
/// Controls how a paragraph interacts with page breaks.
|
|
285
|
+
/// <para>
|
|
286
|
+
/// <b>Properties:</b>
|
|
287
|
+
/// <list type="bullet">
|
|
288
|
+
/// <item><b>KeepNext</b> — Keeps this paragraph on the same page as the NEXT paragraph.
|
|
289
|
+
/// Essential for headings (so a heading is never orphaned at the bottom of a page
|
|
290
|
+
/// while its body text starts on the next page).</item>
|
|
291
|
+
/// <item><b>KeepLines</b> — Prevents a page break within this paragraph.
|
|
292
|
+
/// All lines of the paragraph stay on the same page. If it doesn't fit, the entire
|
|
293
|
+
/// paragraph moves to the next page.</item>
|
|
294
|
+
/// <item><b>WidowControl</b> — Prevents widows (a single last line of a paragraph at
|
|
295
|
+
/// the top of a page) and orphans (a single first line at the bottom of a page).
|
|
296
|
+
/// Default is ON. Set Val=false to allow widows/orphans.</item>
|
|
297
|
+
/// <item><b>PageBreakBefore</b> — Forces a page break immediately before this paragraph.
|
|
298
|
+
/// Used for chapter headings and section starts.</item>
|
|
299
|
+
/// </list>
|
|
300
|
+
/// </para>
|
|
301
|
+
/// <para>
|
|
302
|
+
/// <b>Gotcha:</b> These properties can cause unexpected pagination behavior.
|
|
303
|
+
/// A chain of KeepNext paragraphs can push an entire group to the next page.
|
|
304
|
+
/// KeepLines on a very long paragraph can cause a full blank page.
|
|
305
|
+
/// </para>
|
|
306
|
+
/// </summary>
|
|
307
|
+
public static void ApplyKeepTogether(Paragraph para)
|
|
308
|
+
{
|
|
309
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
310
|
+
|
|
311
|
+
// Keep with next paragraph (typical for headings)
|
|
312
|
+
pPr.KeepNext = new KeepNext();
|
|
313
|
+
|
|
314
|
+
// Keep all lines of this paragraph together
|
|
315
|
+
pPr.KeepLines = new KeepLines();
|
|
316
|
+
|
|
317
|
+
// Widow/orphan control (on by default, explicitly setting here)
|
|
318
|
+
pPr.WidowControl = new WidowControl();
|
|
319
|
+
|
|
320
|
+
// Force page break before this paragraph
|
|
321
|
+
// pPr.PageBreakBefore = new PageBreakBefore();
|
|
322
|
+
|
|
323
|
+
// Disable widow/orphan control (allow widows/orphans)
|
|
324
|
+
// pPr.WidowControl = new WidowControl { Val = false };
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// ──────────────────────────────────────────────────────────────────
|
|
328
|
+
// 6. Outline Level (w:outlineLvl)
|
|
329
|
+
// ──────────────────────────────────────────────────────────────────
|
|
330
|
+
|
|
331
|
+
/// <summary>
|
|
332
|
+
/// Sets the outline level for Table of Contents (TOC) integration
|
|
333
|
+
/// and Navigation Pane display.
|
|
334
|
+
/// <para>
|
|
335
|
+
/// <b>Values:</b> 0–8 (where 0 = top-level heading, 8 = deepest level).
|
|
336
|
+
/// Level 9 (BodyTextLevel) means "body text" (not included in TOC).
|
|
337
|
+
/// </para>
|
|
338
|
+
/// <para>
|
|
339
|
+
/// <b>Relationship to heading styles:</b> Word's built-in Heading 1 through Heading 9
|
|
340
|
+
/// styles have outlineLvl 0–8 respectively. You can assign an outline level to ANY
|
|
341
|
+
/// paragraph style, making it appear in the TOC without using a Heading style.
|
|
342
|
+
/// </para>
|
|
343
|
+
/// <para>
|
|
344
|
+
/// <b>Gotcha:</b> If you set outlineLvl directly on paragraphs (not in a style),
|
|
345
|
+
/// each paragraph needs the property. It is more maintainable to define a style
|
|
346
|
+
/// with the outline level and apply the style.
|
|
347
|
+
/// </para>
|
|
348
|
+
/// </summary>
|
|
349
|
+
public static void ApplyOutlineLevel(Paragraph para)
|
|
350
|
+
{
|
|
351
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
352
|
+
|
|
353
|
+
// Level 0 = equivalent to Heading 1 in TOC
|
|
354
|
+
pPr.OutlineLevel = new OutlineLevel { Val = 0 };
|
|
355
|
+
|
|
356
|
+
// Level 1 = Heading 2 equivalent
|
|
357
|
+
// pPr.OutlineLevel = new OutlineLevel { Val = 1 };
|
|
358
|
+
|
|
359
|
+
// Level 2 = Heading 3 equivalent
|
|
360
|
+
// pPr.OutlineLevel = new OutlineLevel { Val = 2 };
|
|
361
|
+
|
|
362
|
+
// Body text (explicitly not in TOC)
|
|
363
|
+
// pPr.OutlineLevel = new OutlineLevel { Val = 9 };
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// ──────────────────────────────────────────────────────────────────
|
|
367
|
+
// 7. Paragraph Borders (w:pBdr)
|
|
368
|
+
// ──────────────────────────────────────────────────────────────────
|
|
369
|
+
|
|
370
|
+
/// <summary>
|
|
371
|
+
/// Applies borders to a paragraph (top, bottom, left, right, between, bar).
|
|
372
|
+
/// <para>
|
|
373
|
+
/// <b>Border properties:</b>
|
|
374
|
+
/// <list type="bullet">
|
|
375
|
+
/// <item><b>Val</b> — Border style. Common values: Single, Double, Dotted, Dashed,
|
|
376
|
+
/// DotDash, DotDotDash, Triple, ThickThinSmallGap, ThinThickSmallGap,
|
|
377
|
+
/// ThickThinMediumGap, ThinThickMediumGap, ThickThinLargeGap, ThinThickLargeGap,
|
|
378
|
+
/// Wave, DoubleWave, DashSmallGap, DashDotStroked, ThreeDEmboss, ThreeDEngrave,
|
|
379
|
+
/// Outset, Inset, None, Nil.</item>
|
|
380
|
+
/// <item><b>Size</b> — Width in eighths of a point. 4 = 0.5pt, 8 = 1pt, 12 = 1.5pt.
|
|
381
|
+
/// Range: 2–96.</item>
|
|
382
|
+
/// <item><b>Space</b> — Distance from text to border in points. Range: 0–31.</item>
|
|
383
|
+
/// <item><b>Color</b> — Hex RGB color (e.g., "000000") or "auto".</item>
|
|
384
|
+
/// </list>
|
|
385
|
+
/// </para>
|
|
386
|
+
/// <para>
|
|
387
|
+
/// <b>Between border:</b> Renders between consecutive paragraphs that BOTH have the
|
|
388
|
+
/// "between" border set. This is how Word creates a visually grouped block of bordered
|
|
389
|
+
/// paragraphs without doubling up borders between them.
|
|
390
|
+
/// </para>
|
|
391
|
+
/// <para>
|
|
392
|
+
/// <b>Bar border:</b> A vertical line at the start edge of the paragraph (left for LTR,
|
|
393
|
+
/// right for RTL). Not the same as the left border — the bar appears in the margin area.
|
|
394
|
+
/// </para>
|
|
395
|
+
/// </summary>
|
|
396
|
+
public static void ApplyParagraphBorders(Paragraph para)
|
|
397
|
+
{
|
|
398
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
399
|
+
|
|
400
|
+
pPr.ParagraphBorders = new ParagraphBorders(
|
|
401
|
+
// Top border
|
|
402
|
+
new TopBorder
|
|
403
|
+
{
|
|
404
|
+
Val = BorderValues.Single,
|
|
405
|
+
Size = 4, // 0.5pt
|
|
406
|
+
Space = 1, // 1pt from text
|
|
407
|
+
Color = "000000"
|
|
408
|
+
},
|
|
409
|
+
// Bottom border
|
|
410
|
+
new BottomBorder
|
|
411
|
+
{
|
|
412
|
+
Val = BorderValues.Single,
|
|
413
|
+
Size = 4,
|
|
414
|
+
Space = 1,
|
|
415
|
+
Color = "000000"
|
|
416
|
+
},
|
|
417
|
+
// Left border
|
|
418
|
+
new LeftBorder
|
|
419
|
+
{
|
|
420
|
+
Val = BorderValues.Single,
|
|
421
|
+
Size = 4,
|
|
422
|
+
Space = 4, // 4pt from text
|
|
423
|
+
Color = "000000"
|
|
424
|
+
},
|
|
425
|
+
// Right border
|
|
426
|
+
new RightBorder
|
|
427
|
+
{
|
|
428
|
+
Val = BorderValues.Single,
|
|
429
|
+
Size = 4,
|
|
430
|
+
Space = 4,
|
|
431
|
+
Color = "000000"
|
|
432
|
+
}
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
// Add "between" border for consecutive bordered paragraphs
|
|
436
|
+
// pPr.ParagraphBorders.AppendChild(new BetweenBorder
|
|
437
|
+
// {
|
|
438
|
+
// Val = BorderValues.Single,
|
|
439
|
+
// Size = 4,
|
|
440
|
+
// Space = 1,
|
|
441
|
+
// Color = "000000"
|
|
442
|
+
// });
|
|
443
|
+
|
|
444
|
+
// Add "bar" border (vertical bar in the margin)
|
|
445
|
+
// pPr.ParagraphBorders.AppendChild(new BarBorder
|
|
446
|
+
// {
|
|
447
|
+
// Val = BorderValues.Single,
|
|
448
|
+
// Size = 4,
|
|
449
|
+
// Space = 0,
|
|
450
|
+
// Color = "FF0000" // Red bar
|
|
451
|
+
// });
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// ──────────────────────────────────────────────────────────────────
|
|
455
|
+
// 8. Paragraph Shading (w:shd)
|
|
456
|
+
// ──────────────────────────────────────────────────────────────────
|
|
457
|
+
|
|
458
|
+
/// <summary>
|
|
459
|
+
/// Applies a background color or pattern to the entire paragraph.
|
|
460
|
+
/// <para>
|
|
461
|
+
/// <b>Properties:</b>
|
|
462
|
+
/// <list type="bullet">
|
|
463
|
+
/// <item><b>Val</b> — Shading pattern. Use <c>ShadingPatternValues.Clear</c> for a
|
|
464
|
+
/// solid background (most common). Other patterns: HorizontalStripe, VerticalStripe,
|
|
465
|
+
/// ReverseDiagonalStripe, DiagonalStripe, DiagonalCross, HorizontalCross,
|
|
466
|
+
/// ThinHorizontalStripe, ThinVerticalStripe, Percent5 through Percent95, etc.</item>
|
|
467
|
+
/// <item><b>Fill</b> — Background color as hex RGB (e.g., "FFFF00"). "auto" = no fill.</item>
|
|
468
|
+
/// <item><b>Color</b> — Foreground/pattern color. Only visible with non-Clear patterns.
|
|
469
|
+
/// "auto" = automatic.</item>
|
|
470
|
+
/// </list>
|
|
471
|
+
/// </para>
|
|
472
|
+
/// <para>
|
|
473
|
+
/// <b>Theme-based shading:</b> Use ThemeFill, ThemeFillTint, ThemeFillShade for
|
|
474
|
+
/// theme-aware background colors. The Fill attribute serves as a fallback.
|
|
475
|
+
/// </para>
|
|
476
|
+
/// </summary>
|
|
477
|
+
public static void ApplyParagraphShading(Paragraph para)
|
|
478
|
+
{
|
|
479
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
480
|
+
|
|
481
|
+
// Solid light yellow background
|
|
482
|
+
pPr.Shading = new Shading
|
|
483
|
+
{
|
|
484
|
+
Val = ShadingPatternValues.Clear, // Solid fill
|
|
485
|
+
Fill = "FFFFCC", // Light yellow
|
|
486
|
+
Color = "auto"
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
// Theme-based background
|
|
490
|
+
// pPr.Shading = new Shading
|
|
491
|
+
// {
|
|
492
|
+
// Val = ShadingPatternValues.Clear,
|
|
493
|
+
// Fill = "D9E2F3", // Hex fallback
|
|
494
|
+
// ThemeFill = ThemeColorValues.Accent1,
|
|
495
|
+
// ThemeFillTint = "33" // Light tint
|
|
496
|
+
// };
|
|
497
|
+
|
|
498
|
+
// Patterned shading (rare, but valid)
|
|
499
|
+
// pPr.Shading = new Shading
|
|
500
|
+
// {
|
|
501
|
+
// Val = ShadingPatternValues.Percent10, // 10% dot pattern
|
|
502
|
+
// Fill = "FFFFFF", // White background
|
|
503
|
+
// Color = "000000" // Black dots
|
|
504
|
+
// };
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// ──────────────────────────────────────────────────────────────────
|
|
508
|
+
// 9. Tab Stops (w:tabs)
|
|
509
|
+
// ──────────────────────────────────────────────────────────────────
|
|
510
|
+
|
|
511
|
+
/// <summary>
|
|
512
|
+
/// Defines custom tab stops with alignment and leader characters.
|
|
513
|
+
/// <para>
|
|
514
|
+
/// <b>Tab alignment values:</b>
|
|
515
|
+
/// <list type="bullet">
|
|
516
|
+
/// <item><b>Left</b> — Text starts at the tab position (default).</item>
|
|
517
|
+
/// <item><b>Center</b> — Text is centered on the tab position.</item>
|
|
518
|
+
/// <item><b>Right</b> — Text ends at the tab position (text flows leftward).</item>
|
|
519
|
+
/// <item><b>Decimal</b> — Aligns on the decimal point (for numbers like 1,234.56).</item>
|
|
520
|
+
/// <item><b>Bar</b> — Draws a vertical bar at the tab position (text is not affected).</item>
|
|
521
|
+
/// <item><b>Clear</b> — Clears an inherited tab stop at this position.</item>
|
|
522
|
+
/// <item><b>Number</b> — Tab position for list numbering.</item>
|
|
523
|
+
/// </list>
|
|
524
|
+
/// </para>
|
|
525
|
+
/// <para>
|
|
526
|
+
/// <b>Tab leader values:</b> The character that fills the space before the tab stop.
|
|
527
|
+
/// <list type="bullet">
|
|
528
|
+
/// <item><b>None</b> — Blank space (default).</item>
|
|
529
|
+
/// <item><b>Dot</b> — Dots (. . . . . .) — common in TOC.</item>
|
|
530
|
+
/// <item><b>Hyphen</b> — Hyphens (- - - - -).</item>
|
|
531
|
+
/// <item><b>Underscore</b> — Continuous underline (__________).</item>
|
|
532
|
+
/// <item><b>Heavy</b> — Thick underline.</item>
|
|
533
|
+
/// <item><b>MiddleDot</b> — Middle dots (· · · · ·).</item>
|
|
534
|
+
/// </list>
|
|
535
|
+
/// </para>
|
|
536
|
+
/// <para>
|
|
537
|
+
/// <b>Position unit:</b> Tab stop position is in <b>DXA</b> (twentieths of a point).
|
|
538
|
+
/// 1440 DXA = 1 inch, 720 DXA = 0.5 inch.
|
|
539
|
+
/// </para>
|
|
540
|
+
/// <para>
|
|
541
|
+
/// <b>Gotcha:</b> Tab stops are cumulative with style-defined tabs unless you use
|
|
542
|
+
/// a Clear tab to remove an inherited one. Order tab stops by position.
|
|
543
|
+
/// </para>
|
|
544
|
+
/// </summary>
|
|
545
|
+
public static void ApplyTabStops(Paragraph para)
|
|
546
|
+
{
|
|
547
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
548
|
+
|
|
549
|
+
pPr.Tabs = new Tabs(
|
|
550
|
+
// Left tab at 1 inch
|
|
551
|
+
new TabStop
|
|
552
|
+
{
|
|
553
|
+
Val = TabStopValues.Left,
|
|
554
|
+
Position = 1440 // 1 inch = 1440 DXA
|
|
555
|
+
},
|
|
556
|
+
// Center tab at 3 inches
|
|
557
|
+
new TabStop
|
|
558
|
+
{
|
|
559
|
+
Val = TabStopValues.Center,
|
|
560
|
+
Position = 4320 // 3 inches = 4320 DXA
|
|
561
|
+
},
|
|
562
|
+
// Right tab at 6 inches with dot leader (TOC style)
|
|
563
|
+
new TabStop
|
|
564
|
+
{
|
|
565
|
+
Val = TabStopValues.Right,
|
|
566
|
+
Position = 8640, // 6 inches = 8640 DXA
|
|
567
|
+
Leader = TabStopLeaderCharValues.Dot
|
|
568
|
+
},
|
|
569
|
+
// Decimal tab at 4 inches (for aligning numbers)
|
|
570
|
+
new TabStop
|
|
571
|
+
{
|
|
572
|
+
Val = TabStopValues.Decimal,
|
|
573
|
+
Position = 5760 // 4 inches = 5760 DXA
|
|
574
|
+
}
|
|
575
|
+
);
|
|
576
|
+
|
|
577
|
+
// Clear an inherited tab stop at 2 inches
|
|
578
|
+
// pPr.Tabs.AppendChild(new TabStop
|
|
579
|
+
// {
|
|
580
|
+
// Val = TabStopValues.Clear,
|
|
581
|
+
// Position = 2880
|
|
582
|
+
// });
|
|
583
|
+
|
|
584
|
+
// Bar tab at 0.5 inch (draws a vertical line, does not move text)
|
|
585
|
+
// pPr.Tabs.AppendChild(new TabStop
|
|
586
|
+
// {
|
|
587
|
+
// Val = TabStopValues.Bar,
|
|
588
|
+
// Position = 720
|
|
589
|
+
// });
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// ──────────────────────────────────────────────────────────────────
|
|
593
|
+
// 10. Numbering / List (w:numPr)
|
|
594
|
+
// ──────────────────────────────────────────────────────────────────
|
|
595
|
+
|
|
596
|
+
/// <summary>
|
|
597
|
+
/// Associates a paragraph with a numbering definition (bulleted or numbered list).
|
|
598
|
+
/// <para>
|
|
599
|
+
/// <b>NumberingId (w:numId):</b> References a numbering definition instance
|
|
600
|
+
/// in the numbering.xml part (NumberingDefinitionsPart). This ID links to an
|
|
601
|
+
/// AbstractNum that defines the list format.
|
|
602
|
+
/// </para>
|
|
603
|
+
/// <para>
|
|
604
|
+
/// <b>NumberingLevelReference (w:ilvl):</b> The nesting level (0-based).
|
|
605
|
+
/// 0 = top-level item, 1 = first sub-level, etc. Maximum depth: 8 (9 levels total).
|
|
606
|
+
/// </para>
|
|
607
|
+
/// <para>
|
|
608
|
+
/// <b>Gotcha:</b> The numbering definition must exist in numbering.xml.
|
|
609
|
+
/// Creating a paragraph with numPr that references a non-existent numId will cause
|
|
610
|
+
/// Word to show an error or ignore the numbering.
|
|
611
|
+
/// </para>
|
|
612
|
+
/// <para>
|
|
613
|
+
/// <b>Gotcha:</b> To remove numbering from a paragraph that inherits it from a style,
|
|
614
|
+
/// set NumberingId to 0: <c>new NumberingId { Val = 0 }</c>
|
|
615
|
+
/// </para>
|
|
616
|
+
/// <para>
|
|
617
|
+
/// <b>NumberingChange:</b> For tracked changes, wrap numPr changes in a
|
|
618
|
+
/// NumberingChange element to record the revision.
|
|
619
|
+
/// </para>
|
|
620
|
+
/// </summary>
|
|
621
|
+
public static void ApplyNumbering(Paragraph para)
|
|
622
|
+
{
|
|
623
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
624
|
+
|
|
625
|
+
// Associate with numbering definition #1, level 0 (top-level)
|
|
626
|
+
pPr.NumberingProperties = new NumberingProperties
|
|
627
|
+
{
|
|
628
|
+
NumberingLevelReference = new NumberingLevelReference { Val = 0 },
|
|
629
|
+
NumberingId = new NumberingId { Val = 1 }
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
// Sub-level item (indented bullet/number)
|
|
633
|
+
// pPr.NumberingProperties = new NumberingProperties
|
|
634
|
+
// {
|
|
635
|
+
// NumberingLevelReference = new NumberingLevelReference { Val = 1 },
|
|
636
|
+
// NumberingId = new NumberingId { Val = 1 }
|
|
637
|
+
// };
|
|
638
|
+
|
|
639
|
+
// Remove numbering inherited from style
|
|
640
|
+
// pPr.NumberingProperties = new NumberingProperties
|
|
641
|
+
// {
|
|
642
|
+
// NumberingId = new NumberingId { Val = 0 } // 0 = no numbering
|
|
643
|
+
// };
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// ──────────────────────────────────────────────────────────────────
|
|
647
|
+
// 11. Bidirectional (w:bidi, w:textDirection)
|
|
648
|
+
// ──────────────────────────────────────────────────────────────────
|
|
649
|
+
|
|
650
|
+
/// <summary>
|
|
651
|
+
/// Sets the paragraph as right-to-left (for Arabic/Hebrew text).
|
|
652
|
+
/// <para>
|
|
653
|
+
/// <b>BiDi (w:bidi):</b> When set, the paragraph direction is right-to-left.
|
|
654
|
+
/// This affects: text flow direction, default alignment (right becomes default),
|
|
655
|
+
/// indentation sides (left/right swap meaning), tab stop behavior.
|
|
656
|
+
/// </para>
|
|
657
|
+
/// <para>
|
|
658
|
+
/// <b>TextDirection (w:textDirection):</b> Controls text flow direction within
|
|
659
|
+
/// the paragraph's text area. Values include LrTb (left-to-right, top-to-bottom,
|
|
660
|
+
/// default), TbRl (top-to-bottom, right-to-left — vertical CJK), BtLr
|
|
661
|
+
/// (bottom-to-top, left-to-right — rotated).
|
|
662
|
+
/// </para>
|
|
663
|
+
/// <para>
|
|
664
|
+
/// <b>Gotcha:</b> For RTL paragraphs, also set Justification to Right
|
|
665
|
+
/// (which visually aligns to the RIGHT = start edge in RTL context).
|
|
666
|
+
/// </para>
|
|
667
|
+
/// </summary>
|
|
668
|
+
public static void ApplyBidirectional(Paragraph para)
|
|
669
|
+
{
|
|
670
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
671
|
+
|
|
672
|
+
// Set paragraph as right-to-left
|
|
673
|
+
pPr.BiDi = new BiDi();
|
|
674
|
+
|
|
675
|
+
// Also set right-alignment (the "start" edge for RTL)
|
|
676
|
+
pPr.Justification = new Justification { Val = JustificationValues.Right };
|
|
677
|
+
|
|
678
|
+
// Text direction for vertical CJK layout
|
|
679
|
+
// pPr.TextDirection = new TextDirection
|
|
680
|
+
// {
|
|
681
|
+
// Val = TextDirectionValues.TopToBottomRightToLeft // Vertical CJK
|
|
682
|
+
// };
|
|
683
|
+
|
|
684
|
+
// Text direction for rotated layout
|
|
685
|
+
// pPr.TextDirection = new TextDirection
|
|
686
|
+
// {
|
|
687
|
+
// Val = TextDirectionValues.BottomToTopLeftToRight // 90° rotation
|
|
688
|
+
// };
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// ──────────────────────────────────────────────────────────────────
|
|
692
|
+
// 12. Contextual Spacing (w:contextualSpacing)
|
|
693
|
+
// ──────────────────────────────────────────────────────────────────
|
|
694
|
+
|
|
695
|
+
/// <summary>
|
|
696
|
+
/// Suppresses Before/After spacing between consecutive paragraphs that
|
|
697
|
+
/// share the same paragraph style.
|
|
698
|
+
/// <para>
|
|
699
|
+
/// <b>Use case:</b> List items. When multiple "List Paragraph" items follow each other,
|
|
700
|
+
/// contextual spacing removes the gap between them while preserving spacing when
|
|
701
|
+
/// the list meets a different style (e.g., body text).
|
|
702
|
+
/// </para>
|
|
703
|
+
/// <para>
|
|
704
|
+
/// <b>How it works:</b> When two adjacent paragraphs have the same ParagraphStyleId
|
|
705
|
+
/// AND both have ContextualSpacing set, the Before spacing of the second paragraph
|
|
706
|
+
/// and the After spacing of the first paragraph are suppressed (set to 0).
|
|
707
|
+
/// </para>
|
|
708
|
+
/// <para>
|
|
709
|
+
/// <b>Gotcha:</b> Both paragraphs must have the same style AND contextual spacing
|
|
710
|
+
/// enabled. If only one has it, the spacing is NOT suppressed.
|
|
711
|
+
/// </para>
|
|
712
|
+
/// </summary>
|
|
713
|
+
public static void ApplyContextualSpacing(Paragraph para)
|
|
714
|
+
{
|
|
715
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
716
|
+
|
|
717
|
+
pPr.ContextualSpacing = new ContextualSpacing();
|
|
718
|
+
|
|
719
|
+
// Disable (override a style that enables it):
|
|
720
|
+
// pPr.ContextualSpacing = new ContextualSpacing { Val = false };
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// ──────────────────────────────────────────────────────────────────
|
|
724
|
+
// 13. Mirror Indents (w:mirrorIndents)
|
|
725
|
+
// ──────────────────────────────────────────────────────────────────
|
|
726
|
+
|
|
727
|
+
/// <summary>
|
|
728
|
+
/// Swaps left and right indentation on even/odd pages for book-style layouts.
|
|
729
|
+
/// <para>
|
|
730
|
+
/// <b>Use case:</b> In bound documents (books, reports), you want wider inner margins
|
|
731
|
+
/// (the binding side). On odd pages the binding is on the left; on even pages it's
|
|
732
|
+
/// on the right. MirrorIndents makes "Left" become "Inside" and "Right" become "Outside".
|
|
733
|
+
/// </para>
|
|
734
|
+
/// <para>
|
|
735
|
+
/// <b>Gotcha:</b> This property works in conjunction with the section's mirror margins
|
|
736
|
+
/// setting (w:mirrorMargins in sectPr). If the section does not have mirror margins
|
|
737
|
+
/// enabled, this property has limited effect.
|
|
738
|
+
/// </para>
|
|
739
|
+
/// </summary>
|
|
740
|
+
public static void ApplyMirrorIndents(Paragraph para)
|
|
741
|
+
{
|
|
742
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
743
|
+
|
|
744
|
+
pPr.MirrorIndents = new MirrorIndents();
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// ──────────────────────────────────────────────────────────────────
|
|
748
|
+
// 14. Snap to Grid (w:snapToGrid)
|
|
749
|
+
// ──────────────────────────────────────────────────────────────────
|
|
750
|
+
|
|
751
|
+
/// <summary>
|
|
752
|
+
/// Controls whether paragraph text aligns to the document grid.
|
|
753
|
+
/// <para>
|
|
754
|
+
/// <b>Document grid:</b> Defined in the section properties (w:docGrid), the grid
|
|
755
|
+
/// specifies a fixed layout for character and line placement. This is primarily
|
|
756
|
+
/// used in CJK documents where characters should align to a uniform grid.
|
|
757
|
+
/// </para>
|
|
758
|
+
/// <para>
|
|
759
|
+
/// <b>Val = true (default):</b> Text snaps to the grid positions, ensuring uniform
|
|
760
|
+
/// character spacing and line heights across the page.
|
|
761
|
+
/// </para>
|
|
762
|
+
/// <para>
|
|
763
|
+
/// <b>Val = false:</b> Text ignores the document grid. Useful for paragraphs
|
|
764
|
+
/// that contain only Western text in a CJK document, where grid alignment
|
|
765
|
+
/// would create too much spacing.
|
|
766
|
+
/// </para>
|
|
767
|
+
/// </summary>
|
|
768
|
+
public static void ApplySnapToGrid(Paragraph para)
|
|
769
|
+
{
|
|
770
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
771
|
+
|
|
772
|
+
// Disable grid snapping for this paragraph
|
|
773
|
+
pPr.SnapToGrid = new SnapToGrid { Val = false };
|
|
774
|
+
|
|
775
|
+
// Re-enable (explicit, same as default)
|
|
776
|
+
// pPr.SnapToGrid = new SnapToGrid { Val = true };
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
// ──────────────────────────────────────────────────────────────────
|
|
780
|
+
// 15. Suppress Auto-Hyphenation (w:suppressAutoHyphens)
|
|
781
|
+
// ──────────────────────────────────────────────────────────────────
|
|
782
|
+
|
|
783
|
+
/// <summary>
|
|
784
|
+
/// Disables automatic hyphenation for this paragraph.
|
|
785
|
+
/// <para>
|
|
786
|
+
/// <b>Background:</b> When document-level auto-hyphenation is enabled
|
|
787
|
+
/// (in document settings), Word breaks long words at line endings with hyphens.
|
|
788
|
+
/// This property overrides that for specific paragraphs.
|
|
789
|
+
/// </para>
|
|
790
|
+
/// <para>
|
|
791
|
+
/// <b>Use case:</b> Disable hyphenation for headings, proper nouns, code blocks,
|
|
792
|
+
/// or any text where breaking words would be inappropriate.
|
|
793
|
+
/// </para>
|
|
794
|
+
/// </summary>
|
|
795
|
+
public static void ApplySuppressAutoHyphens(Paragraph para)
|
|
796
|
+
{
|
|
797
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
798
|
+
|
|
799
|
+
pPr.SuppressAutoHyphens = new SuppressAutoHyphens();
|
|
800
|
+
|
|
801
|
+
// Re-enable auto-hyphenation (override style that suppresses):
|
|
802
|
+
// pPr.SuppressAutoHyphens = new SuppressAutoHyphens { Val = false };
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
// ──────────────────────────────────────────────────────────────────
|
|
806
|
+
// 16. Paragraph Style (w:pStyle)
|
|
807
|
+
// ──────────────────────────────────────────────────────────────────
|
|
808
|
+
|
|
809
|
+
/// <summary>
|
|
810
|
+
/// Applies a named paragraph style.
|
|
811
|
+
/// <para>
|
|
812
|
+
/// <b>Val:</b> The style ID (not the display name). Built-in style IDs include:
|
|
813
|
+
/// "Normal", "Heading1" through "Heading9", "Title", "Subtitle",
|
|
814
|
+
/// "ListParagraph", "NoSpacing", "Quote", "IntenseQuote",
|
|
815
|
+
/// "TOCHeading", "TOC1" through "TOC9", "Header", "Footer",
|
|
816
|
+
/// "FootnoteText", "EndnoteText", "Caption", "Bibliography", etc.
|
|
817
|
+
/// </para>
|
|
818
|
+
/// <para>
|
|
819
|
+
/// <b>Gotcha:</b> Style IDs are locale-independent (always English) even in
|
|
820
|
+
/// non-English installations of Word. The display name is localized, but the
|
|
821
|
+
/// ID stays the same. "Heading1" is always "Heading1" regardless of language.
|
|
822
|
+
/// </para>
|
|
823
|
+
/// <para>
|
|
824
|
+
/// <b>Gotcha:</b> Custom styles use whatever ID was assigned at creation time.
|
|
825
|
+
/// The ID may contain spaces or special characters. Always verify the actual
|
|
826
|
+
/// style ID in styles.xml rather than guessing from the display name.
|
|
827
|
+
/// </para>
|
|
828
|
+
/// <para>
|
|
829
|
+
/// <b>Gotcha:</b> If the referenced style does not exist in styles.xml, Word
|
|
830
|
+
/// falls back to the "Normal" style silently.
|
|
831
|
+
/// </para>
|
|
832
|
+
/// </summary>
|
|
833
|
+
public static void ApplyParagraphStyle(Paragraph para)
|
|
834
|
+
{
|
|
835
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
836
|
+
|
|
837
|
+
// Apply Heading 1 style
|
|
838
|
+
pPr.ParagraphStyleId = new ParagraphStyleId { Val = "Heading1" };
|
|
839
|
+
|
|
840
|
+
// Other common built-in style IDs:
|
|
841
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "Normal" };
|
|
842
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "Heading2" };
|
|
843
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "Title" };
|
|
844
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "Subtitle" };
|
|
845
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "ListParagraph" };
|
|
846
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "NoSpacing" };
|
|
847
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "Quote" };
|
|
848
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "TOC1" };
|
|
849
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "Header" };
|
|
850
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "Footer" };
|
|
851
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "FootnoteText" };
|
|
852
|
+
// pPr.ParagraphStyleId = new ParagraphStyleId { Val = "Caption" };
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// ──────────────────────────────────────────────────────────────────
|
|
856
|
+
// 17. Frame Properties (w:framePr) — positioned paragraph
|
|
857
|
+
// ──────────────────────────────────────────────────────────────────
|
|
858
|
+
|
|
859
|
+
/// <summary>
|
|
860
|
+
/// Makes a paragraph into a positioned text frame (an anchored box of text).
|
|
861
|
+
/// <para>
|
|
862
|
+
/// <b>Use case:</b> Drop caps, pull quotes, sidebar text, positioned labels.
|
|
863
|
+
/// FrameProperties turns a paragraph into a floating frame that can be positioned
|
|
864
|
+
/// relative to the page, margin, or text.
|
|
865
|
+
/// </para>
|
|
866
|
+
/// <para>
|
|
867
|
+
/// <b>Properties:</b>
|
|
868
|
+
/// <list type="bullet">
|
|
869
|
+
/// <item><b>Width (w)</b> — Frame width in DXA. 0 = auto (fit content).</item>
|
|
870
|
+
/// <item><b>Height (h)</b> — Frame height in DXA. 0 = auto.</item>
|
|
871
|
+
/// <item><b>HeightRule (hRule)</b> — Auto, AtLeast, or Exact.</item>
|
|
872
|
+
/// <item><b>HorizontalPosition (x)</b> — Horizontal offset in DXA.</item>
|
|
873
|
+
/// <item><b>VerticalPosition (y)</b> — Vertical offset in DXA.</item>
|
|
874
|
+
/// <item><b>HorizontalSpace (hSpace)</b> — Horizontal clearance in DXA.</item>
|
|
875
|
+
/// <item><b>VerticalSpace (vSpace)</b> — Vertical clearance in DXA.</item>
|
|
876
|
+
/// <item><b>Anchor</b> — Vertical anchor: Text, Margin, or Page.</item>
|
|
877
|
+
/// <item><b>AnchorLock</b> — Prevents repositioning in Word UI.</item>
|
|
878
|
+
/// <item><b>DropCap</b> — DropCapLocationValues: None, Drop, Margin.</item>
|
|
879
|
+
/// <item><b>Lines</b> — Number of lines for a drop cap (typically 2–4).</item>
|
|
880
|
+
/// <item><b>Wrap</b> — Text wrapping: Auto, NotBeside, Around, Tight, Through, None.</item>
|
|
881
|
+
/// </list>
|
|
882
|
+
/// </para>
|
|
883
|
+
/// <para>
|
|
884
|
+
/// <b>Gotcha:</b> Frame properties are a legacy positioning mechanism. For modern
|
|
885
|
+
/// documents, consider using DrawingML text boxes instead. However, framePr is still
|
|
886
|
+
/// the standard way to create drop caps in OOXML.
|
|
887
|
+
/// </para>
|
|
888
|
+
/// </summary>
|
|
889
|
+
public static void ApplyFrameProperties(Paragraph para)
|
|
890
|
+
{
|
|
891
|
+
var pPr = para.GetOrCreateParagraphProperties();
|
|
892
|
+
|
|
893
|
+
// Drop cap: 3-line dropped initial capital
|
|
894
|
+
pPr.FrameProperties = new FrameProperties
|
|
895
|
+
{
|
|
896
|
+
DropCap = DropCapLocationValues.Drop,
|
|
897
|
+
Lines = 3, // Span 3 lines of body text
|
|
898
|
+
HorizontalSpace = "72", // 72 DXA = ~3.6pt clearance
|
|
899
|
+
Wrap = TextWrappingValues.Around // Body text wraps around
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
// Positioned frame (floating text box)
|
|
903
|
+
// pPr.FrameProperties = new FrameProperties
|
|
904
|
+
// {
|
|
905
|
+
// Width = "2880", // 2 inches wide
|
|
906
|
+
// Height = "1440", // 1 inch tall
|
|
907
|
+
// HeightRule = HeightRuleValues.AtLeast,
|
|
908
|
+
// X = "4320", // 3 inches from anchor
|
|
909
|
+
// Y = "1440", // 1 inch from anchor
|
|
910
|
+
// HorizontalSpace = "144", // 0.1 inch horizontal clearance
|
|
911
|
+
// VerticalSpace = "72", // ~3.6pt vertical clearance
|
|
912
|
+
// VerticalAnchor = VerticalAnchorValues.Text,
|
|
913
|
+
// Wrap = TextWrappingValues.Around,
|
|
914
|
+
// AnchorLock = true
|
|
915
|
+
// };
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// ──────────────────────────────────────────────────────────────────
|
|
919
|
+
// 18. Fully Formatted Paragraph (combining multiple properties)
|
|
920
|
+
// ──────────────────────────────────────────────────────────────────
|
|
921
|
+
|
|
922
|
+
/// <summary>
|
|
923
|
+
/// Creates a fully formatted paragraph combining multiple paragraph properties.
|
|
924
|
+
/// Demonstrates the correct construction order and element nesting.
|
|
925
|
+
/// <para>
|
|
926
|
+
/// <b>Structure:</b>
|
|
927
|
+
/// <c><w:p><w:pPr>...</w:pPr><w:r>...</w:r></w:p></c>
|
|
928
|
+
/// </para>
|
|
929
|
+
/// <para>
|
|
930
|
+
/// <b>Key principle:</b> ParagraphProperties must be the FIRST child of the paragraph.
|
|
931
|
+
/// Runs, hyperlinks, and other content follow after.
|
|
932
|
+
/// </para>
|
|
933
|
+
/// </summary>
|
|
934
|
+
public static Paragraph CreateFullyFormattedParagraph()
|
|
935
|
+
{
|
|
936
|
+
// Build ParagraphProperties first
|
|
937
|
+
var pPr = new ParagraphProperties();
|
|
938
|
+
|
|
939
|
+
// 1. Style (must be first child per schema)
|
|
940
|
+
pPr.ParagraphStyleId = new ParagraphStyleId { Val = "Heading1" };
|
|
941
|
+
|
|
942
|
+
// 2. Pagination
|
|
943
|
+
pPr.KeepNext = new KeepNext();
|
|
944
|
+
pPr.KeepLines = new KeepLines();
|
|
945
|
+
|
|
946
|
+
// 3. Page break
|
|
947
|
+
// pPr.PageBreakBefore = new PageBreakBefore();
|
|
948
|
+
|
|
949
|
+
// 4. Widow/orphan control
|
|
950
|
+
pPr.WidowControl = new WidowControl();
|
|
951
|
+
|
|
952
|
+
// 5. Numbering
|
|
953
|
+
// pPr.NumberingProperties = new NumberingProperties
|
|
954
|
+
// {
|
|
955
|
+
// NumberingLevelReference = new NumberingLevelReference { Val = 0 },
|
|
956
|
+
// NumberingId = new NumberingId { Val = 1 }
|
|
957
|
+
// };
|
|
958
|
+
|
|
959
|
+
// 6. Borders
|
|
960
|
+
pPr.ParagraphBorders = new ParagraphBorders(
|
|
961
|
+
new BottomBorder
|
|
962
|
+
{
|
|
963
|
+
Val = BorderValues.Single,
|
|
964
|
+
Size = 8,
|
|
965
|
+
Space = 4,
|
|
966
|
+
Color = "4472C4"
|
|
967
|
+
}
|
|
968
|
+
);
|
|
969
|
+
|
|
970
|
+
// 7. Shading
|
|
971
|
+
pPr.Shading = new Shading
|
|
972
|
+
{
|
|
973
|
+
Val = ShadingPatternValues.Clear,
|
|
974
|
+
Fill = "F2F2F2"
|
|
975
|
+
};
|
|
976
|
+
|
|
977
|
+
// 8. Tab stops
|
|
978
|
+
pPr.Tabs = new Tabs(
|
|
979
|
+
new TabStop
|
|
980
|
+
{
|
|
981
|
+
Val = TabStopValues.Right,
|
|
982
|
+
Position = 9360, // Right margin tab
|
|
983
|
+
Leader = TabStopLeaderCharValues.Dot
|
|
984
|
+
}
|
|
985
|
+
);
|
|
986
|
+
|
|
987
|
+
// 9. Suppress hyphenation
|
|
988
|
+
pPr.SuppressAutoHyphens = new SuppressAutoHyphens();
|
|
989
|
+
|
|
990
|
+
// 10. Spacing (before/after + line spacing)
|
|
991
|
+
pPr.SpacingBetweenLines = new SpacingBetweenLines
|
|
992
|
+
{
|
|
993
|
+
Before = "240", // 12pt before
|
|
994
|
+
After = "120", // 6pt after
|
|
995
|
+
Line = "276", // 1.15x line spacing
|
|
996
|
+
LineRule = LineSpacingRuleValues.Auto
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
// 11. Indentation
|
|
1000
|
+
pPr.Indentation = new Indentation
|
|
1001
|
+
{
|
|
1002
|
+
Left = "360", // 0.25 inch left indent
|
|
1003
|
+
FirstLine = "0" // No additional first-line indent
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
// 12. Justification
|
|
1007
|
+
pPr.Justification = new Justification { Val = JustificationValues.Both };
|
|
1008
|
+
|
|
1009
|
+
// 13. Outline level (for TOC)
|
|
1010
|
+
pPr.OutlineLevel = new OutlineLevel { Val = 0 };
|
|
1011
|
+
|
|
1012
|
+
// 14. Paragraph-level run properties (default formatting for runs in this para)
|
|
1013
|
+
// This sets the DEFAULT run formatting — individual runs can override.
|
|
1014
|
+
pPr.ParagraphMarkRunProperties = new ParagraphMarkRunProperties(
|
|
1015
|
+
new RunFonts { Ascii = "Georgia", HighAnsi = "Georgia" },
|
|
1016
|
+
new Bold(),
|
|
1017
|
+
new FontSize { Val = "28" }, // 14pt
|
|
1018
|
+
new Color { Val = "2F5496" }
|
|
1019
|
+
);
|
|
1020
|
+
|
|
1021
|
+
// Build the paragraph
|
|
1022
|
+
var para = new Paragraph();
|
|
1023
|
+
para.ParagraphProperties = pPr;
|
|
1024
|
+
|
|
1025
|
+
// Add a run with text
|
|
1026
|
+
var run = new Run(
|
|
1027
|
+
new RunProperties(
|
|
1028
|
+
new RunFonts { Ascii = "Georgia", HighAnsi = "Georgia" },
|
|
1029
|
+
new Bold(),
|
|
1030
|
+
new FontSize { Val = "28" },
|
|
1031
|
+
new Color { Val = "2F5496" }
|
|
1032
|
+
),
|
|
1033
|
+
new Text("Chapter 1: Introduction") { Space = SpaceProcessingModeValues.Preserve }
|
|
1034
|
+
);
|
|
1035
|
+
para.AppendChild(run);
|
|
1036
|
+
|
|
1037
|
+
return para;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
// ──────────────────────────────────────────────────────────────────
|
|
1041
|
+
// 19. BuildParagraphProperties helper — recommended property order
|
|
1042
|
+
// ──────────────────────────────────────────────────────────────────
|
|
1043
|
+
|
|
1044
|
+
/// <summary>
|
|
1045
|
+
/// Helper that constructs ParagraphProperties with elements in the correct schema order.
|
|
1046
|
+
/// <para>
|
|
1047
|
+
/// <b>OOXML schema order for w:pPr children (ISO 29500-1, section 17.3.1.26):</b>
|
|
1048
|
+
/// <list type="number">
|
|
1049
|
+
/// <item>w:pStyle — Paragraph style reference</item>
|
|
1050
|
+
/// <item>w:keepNext — Keep with next paragraph</item>
|
|
1051
|
+
/// <item>w:keepLines — Keep lines together</item>
|
|
1052
|
+
/// <item>w:pageBreakBefore — Page break before</item>
|
|
1053
|
+
/// <item>w:framePr — Frame/text-box properties</item>
|
|
1054
|
+
/// <item>w:widowControl — Widow/orphan control</item>
|
|
1055
|
+
/// <item>w:numPr — Numbering properties</item>
|
|
1056
|
+
/// <item>w:suppressLineNumbers — Suppress line numbers</item>
|
|
1057
|
+
/// <item>w:pBdr — Paragraph borders</item>
|
|
1058
|
+
/// <item>w:shd — Shading</item>
|
|
1059
|
+
/// <item>w:tabs — Tab stops</item>
|
|
1060
|
+
/// <item>w:suppressAutoHyphens — Suppress auto-hyphenation</item>
|
|
1061
|
+
/// <item>w:kinsoku — CJK line-breaking rules</item>
|
|
1062
|
+
/// <item>w:wordWrap — Allow word-level wrapping (CJK)</item>
|
|
1063
|
+
/// <item>w:overflowPunct — Allow overflow punctuation (CJK)</item>
|
|
1064
|
+
/// <item>w:topLinePunct — Top-line punctuation compression (CJK)</item>
|
|
1065
|
+
/// <item>w:autoSpaceDE — Auto-space between CJK and Western text</item>
|
|
1066
|
+
/// <item>w:autoSpaceDN — Auto-space between CJK text and numbers</item>
|
|
1067
|
+
/// <item>w:bidi — Bidirectional (RTL paragraph)</item>
|
|
1068
|
+
/// <item>w:adjustRightInd — Auto-adjust right indent for grid</item>
|
|
1069
|
+
/// <item>w:snapToGrid — Snap to document grid</item>
|
|
1070
|
+
/// <item>w:spacing — Line and paragraph spacing</item>
|
|
1071
|
+
/// <item>w:ind — Indentation</item>
|
|
1072
|
+
/// <item>w:contextualSpacing — Contextual spacing</item>
|
|
1073
|
+
/// <item>w:mirrorIndents — Mirror indents for odd/even pages</item>
|
|
1074
|
+
/// <item>w:suppressOverlap — Suppress frame overlap</item>
|
|
1075
|
+
/// <item>w:jc — Justification (alignment)</item>
|
|
1076
|
+
/// <item>w:textDirection — Text direction</item>
|
|
1077
|
+
/// <item>w:textAlignment — Text vertical alignment within line</item>
|
|
1078
|
+
/// <item>w:textboxTightWrap — Text box tight wrap</item>
|
|
1079
|
+
/// <item>w:outlineLvl — Outline level</item>
|
|
1080
|
+
/// <item>w:divId — HTML div ID</item>
|
|
1081
|
+
/// <item>w:cnfStyle — Conditional formatting style</item>
|
|
1082
|
+
/// <item>w:rPr — Paragraph mark run properties</item>
|
|
1083
|
+
/// <item>w:sectPr — Section properties (last pPr in section)</item>
|
|
1084
|
+
/// <item>w:pPrChange — Revision tracking for paragraph properties</item>
|
|
1085
|
+
/// </list>
|
|
1086
|
+
/// </para>
|
|
1087
|
+
/// <para>
|
|
1088
|
+
/// <b>Gotcha:</b> Like RunProperties, when using strongly-typed SDK properties
|
|
1089
|
+
/// (e.g., <c>pPr.Justification = new Justification { ... }</c>), the SDK handles
|
|
1090
|
+
/// serialization order automatically. If using <c>AppendChild()</c>, you must
|
|
1091
|
+
/// maintain the schema order yourself.
|
|
1092
|
+
/// </para>
|
|
1093
|
+
/// </summary>
|
|
1094
|
+
/// <param name="styleId">Paragraph style ID. Null to skip.</param>
|
|
1095
|
+
/// <param name="justification">Alignment. Null to skip.</param>
|
|
1096
|
+
/// <param name="spacingBeforePt">Space before in points. Null to skip.</param>
|
|
1097
|
+
/// <param name="spacingAfterPt">Space after in points. Null to skip.</param>
|
|
1098
|
+
/// <param name="lineSpacingMultiplier">Line spacing multiplier (e.g., 1.0, 1.15, 1.5, 2.0).
|
|
1099
|
+
/// Null to skip. Only applies Auto line rule.</param>
|
|
1100
|
+
/// <param name="leftIndentDxa">Left indent in DXA. Null to skip.</param>
|
|
1101
|
+
/// <param name="firstLineIndentDxa">First line indent in DXA. Null to skip.
|
|
1102
|
+
/// Use negative value for hanging indent (will be set as Hanging).</param>
|
|
1103
|
+
/// <returns>A well-ordered ParagraphProperties element.</returns>
|
|
1104
|
+
public static ParagraphProperties BuildParagraphProperties(
|
|
1105
|
+
string? styleId = null,
|
|
1106
|
+
JustificationValues? justification = null,
|
|
1107
|
+
double? spacingBeforePt = null,
|
|
1108
|
+
double? spacingAfterPt = null,
|
|
1109
|
+
double? lineSpacingMultiplier = null,
|
|
1110
|
+
int? leftIndentDxa = null,
|
|
1111
|
+
int? firstLineIndentDxa = null)
|
|
1112
|
+
{
|
|
1113
|
+
var pPr = new ParagraphProperties();
|
|
1114
|
+
|
|
1115
|
+
// Style reference (schema position 1)
|
|
1116
|
+
if (styleId is not null)
|
|
1117
|
+
{
|
|
1118
|
+
pPr.ParagraphStyleId = new ParagraphStyleId { Val = styleId };
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
// Spacing (schema position 22) — combines para spacing and line spacing
|
|
1122
|
+
if (spacingBeforePt is not null || spacingAfterPt is not null || lineSpacingMultiplier is not null)
|
|
1123
|
+
{
|
|
1124
|
+
var spacing = new SpacingBetweenLines();
|
|
1125
|
+
|
|
1126
|
+
if (spacingBeforePt is not null)
|
|
1127
|
+
{
|
|
1128
|
+
// Points to DXA: 1pt = 20 DXA
|
|
1129
|
+
spacing.Before = ((int)(spacingBeforePt.Value * 20)).ToString();
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
if (spacingAfterPt is not null)
|
|
1133
|
+
{
|
|
1134
|
+
spacing.After = ((int)(spacingAfterPt.Value * 20)).ToString();
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
if (lineSpacingMultiplier is not null)
|
|
1138
|
+
{
|
|
1139
|
+
// Auto mode: multiplier × 240 = value
|
|
1140
|
+
spacing.Line = ((int)(lineSpacingMultiplier.Value * 240)).ToString();
|
|
1141
|
+
spacing.LineRule = LineSpacingRuleValues.Auto;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
pPr.SpacingBetweenLines = spacing;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
// Indentation (schema position 23)
|
|
1148
|
+
if (leftIndentDxa is not null || firstLineIndentDxa is not null)
|
|
1149
|
+
{
|
|
1150
|
+
var ind = new Indentation();
|
|
1151
|
+
|
|
1152
|
+
if (leftIndentDxa is not null)
|
|
1153
|
+
{
|
|
1154
|
+
ind.Left = leftIndentDxa.Value.ToString();
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
if (firstLineIndentDxa is not null)
|
|
1158
|
+
{
|
|
1159
|
+
if (firstLineIndentDxa.Value >= 0)
|
|
1160
|
+
{
|
|
1161
|
+
ind.FirstLine = firstLineIndentDxa.Value.ToString();
|
|
1162
|
+
}
|
|
1163
|
+
else
|
|
1164
|
+
{
|
|
1165
|
+
// Negative value → hanging indent (positive DXA stored in Hanging)
|
|
1166
|
+
ind.Hanging = Math.Abs(firstLineIndentDxa.Value).ToString();
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
pPr.Indentation = ind;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
// Justification (schema position 26)
|
|
1174
|
+
if (justification is not null)
|
|
1175
|
+
{
|
|
1176
|
+
pPr.Justification = new Justification { Val = justification };
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
return pPr;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
// ──────────────────────────────────────────────────────────────────
|
|
1183
|
+
// Internal helper: get or create ParagraphProperties
|
|
1184
|
+
// ──────────────────────────────────────────────────────────────────
|
|
1185
|
+
|
|
1186
|
+
/// <summary>
|
|
1187
|
+
/// Gets the existing ParagraphProperties or creates and attaches a new one.
|
|
1188
|
+
/// Ensures ParagraphProperties is always the first child of the paragraph.
|
|
1189
|
+
/// </summary>
|
|
1190
|
+
private static ParagraphProperties GetOrCreateParagraphProperties(this Paragraph para)
|
|
1191
|
+
{
|
|
1192
|
+
if (para.ParagraphProperties is not null)
|
|
1193
|
+
return para.ParagraphProperties;
|
|
1194
|
+
|
|
1195
|
+
var pPr = new ParagraphProperties();
|
|
1196
|
+
para.ParagraphProperties = pPr;
|
|
1197
|
+
return pPr;
|
|
1198
|
+
}
|
|
1199
|
+
}
|