-
-
Notifications
You must be signed in to change notification settings - Fork 32
Customizable heading styles #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add heading configuration options to document options with support for: - Custom font family, font size, and formatting for headings 1-6 - Configurable paragraph spacing before and after headings - Keep lines and keep next paragraph options - Outline level configuration for document structure - Merge user heading config with default settings
- Extract defaultHeadingOptions constant to reduce duplication - Fix headingOptions parameter default value consistency - Simplify styles generation with single utility function - Add TypeScript definitions for heading configuration - Fix spacing logic to use !== undefined checks
- Replace 6 repetitive generateHeadingStyleXML calls with Object.entries + map approach - Improve code maintainability by dynamically iterating over heading configurations - Ensure proper ordering with localeCompare sort - Maintain identical functionality while reducing code duplication
- Add XML escape utility to prevent injection attacks in font names - Fix TypeScript type definitions by removing null types from HeadingStyle - Add outlineLevel validation to ensure values are within 0-5 range - Improve fontSize handling to prevent zero or negative values - Extract escapeXml function to utils module for better code organization
Signed-off-by: Kushal <kushalkumargupta4@gmail.com>
Signed-off-by: Kushal <kushalkumargupta4@gmail.com>
This commit expands the scope of PR #129 by adding a complete test suite to ensure reliability and prevent regressions. While this increases the changeset, it provides critical validation of the feature. Added: - 66 comprehensive unit and integration tests - Jest testing framework with Babel transpilation - Tests for XML escaping security (13 tests) - Tests for heading styles generation (30 tests) - End-to-end integration tests (23 tests) Test Coverage: - XML injection prevention and security - Input validation and edge cases - Deep merge configuration behavior - Font size and outline level clamping - Spacing configuration handling - Boolean properties (bold, keepLines, keepNext) - End-to-end document generation - Compatibility with other document options All tests validate critical issues identified in PR #116 feedback: - Code duplication fix verification - XML injection prevention - Font size validation - Spacing null safety - Deep merge correctness - Outline level validation The test suite ensures the feature works correctly and provides confidence for future changes. All 66 tests are passing. Commands: npm run test:unit - Run unit tests npm run test:all - Run all tests (unit + integration) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Fix the order of keepNext and keepLines elements in the pPr section to comply with the OOXML schema specification (ECMA-376). According to the schema, the correct order within w:pPr is: 1. keepNext 2. keepLines 3. spacing 4. outlineLvl The previous implementation had keepLines before keepNext, which violates the schema sequence requirements. While most OOXML parsers are lenient, following the correct order ensures maximum compatibility. All 66 tests still pass after this fix. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add example/example-heading-styles.js demonstrating heading customization - Add heading styles test section to TypeScript example - Add test:headings npm script for running heading styles example - Update test:all to include heading styles example - Clarify font size comments: OOXML uses half-points (72) while Word UI displays points (36pt) Related to PR #129
|
@DemoMacro thank you for your contributions they are truly appreciated! We added you to the contirbutors list and will be merging and deploying shortly. @K-Kumar-01 I took this as an opportunity to start with the unit tests and will integrate this into a CI. I added a few more test cases |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to change expected.toBeDefined to be explicit and check the zip file
Rework of #116.
Cherry picked the commits @DemoMacro
Summary
This PR introduces customizable heading styles (H1-H6) for DOCX documents, allowing users to configure font family, font size, bold formatting, paragraph spacing, and outline levels. This is a rework of PR #116 with cherry-picked commits.
Changes:
Overview
This feature adds significant flexibility to heading customization by:
headingconfiguration object to document optionsDetailed Review
✅ Strengths
1. Security Improvements (src/utils/xml-escape.js)
&,<,>,",'2. Code Quality Refactoring (src/schemas/styles.js)
Object.entries()+map()approach3. Type Safety (index.d.ts)
HeadingConfig,HeadingStyle,HeadingSpacing?modifiers4. Validation & Safety (src/schemas/styles.js:32)
Math.max(0, Math.min(5, heading.outlineLevel || 0))> 0to prevent invalid values5. Documentation (README.md)
1. Critical: Undefined Spacing Before (src/schemas/styles.js:29)
Problem: If
heading.spacingexists butheading.spacing.beforeisundefined, this will outputw:before="undefined"in the XML, which is invalid.Fix Needed:
2. Potential Issue: String Comparison (src/schemas/styles.js:35)
Problem:
headingNumberis extracted as a string from'Heading1', soheadingNumber >= 3is a string comparison, which works but is not semantically correct.Suggestion:
3. Empty XML Elements (src/schemas/styles.js:47-52)
When optional properties are not set, empty paragraph properties (
<w:pPr>) or run properties (<w:rPr>) sections are still generated. While this doesn't break DOCX files, it adds unnecessary bloat.Suggestion: Conditionally render these sections only if they contain content.
4. Missing Font Validation
The
escapeXmlfunction is used for fonts, but there's no validation that the font string is reasonable (e.g., not excessively long, no control characters).Suggestion: Add basic validation before escaping:
5. Inconsistent Merging Strategy (src/schemas/styles.js:68)
This shallow merge means if a user provides
{ heading1: { fontSize: 50 } }, it will completely overridedefaultHeadingOptions.heading1rather than merging properties. Users lose default values forbold,spacing,keepLines, etc.Critical Fix Needed:
📋 Minor Observations
defaultHeadingOptionsto constants file🧪 Testing Recommendations
The PR should include tests for:
undefined,null, empty strings, negative numbers🔒 Security Assessment
Good:
Consider:
Recommendations
Must Fix (Blocking)
Should Fix (High Priority)
headingNumberstring to integer for proper numeric comparisonNice to Have
Verdict
Status:⚠️ CHANGES REQUESTED
This PR adds valuable functionality and demonstrates good code quality practices (refactoring, security, TypeScript support). However, there are two critical bugs that need to be fixed before merging:
spacing.beforeissue will produce invalid XMLOnce these issues are resolved, this will be an excellent addition to the library.
Files Changed
Reviewed by: Claude Code
Review Date: 2025-10-06