Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,17 @@ full fledged examples can be found under `example/`
- `restart` <"continuous"|"newPage"|"newSection"> numbering restart strategy. Defaults to `continuous`.
- `numbering` <?[Object]>
- `defaultOrderedListStyleType` <?[String]> default ordered list style type. Defaults to `decimal`.
- `heading` <?[Object]> custom heading styles configuration
- `heading1`-`heading6` <?[Object]> heading style configuration
- `font` <?[String]> font family
- `fontSize` <?[Number]> font size in half-points
- `bold` <?[Boolean]> whether text is bold. Defaults to `true`
- `spacing` <?[Object]> paragraph spacing configuration
- `before` <?[Number]> spacing before heading in twips
- `after` <?[Number]> spacing after heading in twips
- `keepLines` <?[Boolean]> keep lines together. Defaults to `true`
- `keepNext` <?[Boolean]> keep with next paragraph. Defaults to `true`
- `outlineLevel` <?[Number]> outline level (0-5)
- `decodeUnicode` <?[Boolean]> flag to enable unicode decoding of header, body and footer. Defaults to `false`.
- `lang` <?[String]> language localization code for spell checker to work properly. Defaults to `en-US`.
- `direction` <?[String]> text direction for RTL (right-to-left) languages. Set to `'rtl'` for Arabic, Hebrew, etc. Defaults to `'ltr'`.
Expand Down
12 changes: 12 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};
139 changes: 139 additions & 0 deletions example/example-heading-styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/* eslint-disable no-console */
const fs = require('fs');
const HTMLtoDOCX = require('../dist/html-to-docx.umd');

/**
* This example demonstrates the customizable heading styles feature
* introduced in PR #129: https://github.com/TurboDocx/html-to-docx/pull/129
*/

const filePath = './example-heading-styles.docx';

const htmlString = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Customizable Heading Styles Example</title>
</head>
<body>
<h1>Main Title - Custom H1 Style</h1>
<p>This heading uses a custom Arial font at 72pt (36pt in half-points) with extra spacing.</p>

<h2>Section Header - Custom H2 Style</h2>
<p>This heading uses Georgia font at 40pt with custom spacing before and after.</p>

<h3>Subsection - Custom H3 Style</h3>
<p>This heading uses a smaller font size and is not bold (unlike default).</p>

<h4>Detail Section - Default H4 Style</h4>
<p>This heading uses the default styling to show the difference.</p>

<h5>Fine Print Header - Custom H5 Style</h5>
<p>This heading has minimal spacing and a specific outline level.</p>

<h6>Smallest Header - Default H6 Style</h6>
<p>This heading also uses default styling.</p>

<h1>Second Main Title</h1>
<p>All H1 tags will use the same custom style defined in the configuration.</p>

<h2>Another Section</h2>
<p>All H2 tags will use the same custom style.</p>

<h3>More Subsections</h3>
<p>Demonstrating consistent styling across multiple headings of the same level.</p>
</body>
</html>`;

(async () => {
console.log('🎨 Creating DOCX with customizable heading styles...\n');

// Define custom heading styles
const customHeadingOptions = {
heading1: {
font: 'Arial',
fontSize: 72, // 36pt in Word (OOXML uses half-points: 72 / 2 = 36pt)
bold: true,
spacing: {
before: 600, // Spacing in twips (1/20 of a point)
after: 200,
},
keepLines: true,
keepNext: true,
outlineLevel: 0,
},
heading2: {
font: 'Georgia',
fontSize: 40, // 20pt in Word (40 / 2 = 20pt)
bold: true,
spacing: {
before: 400,
after: 150,
},
keepLines: true,
keepNext: true,
outlineLevel: 1,
},
heading3: {
font: 'Calibri',
fontSize: 26, // 13pt in Word (26 / 2 = 13pt)
bold: false, // Not bold (different from default)
spacing: {
before: 240,
after: 100,
},
keepLines: true,
keepNext: true,
outlineLevel: 2,
},
// heading4, heading5, heading6 will use default styles
heading5: {
font: 'Times New Roman',
fontSize: 20, // 10pt in Word (20 / 2 = 10pt)
bold: true,
spacing: {
before: 120,
after: 60,
},
keepLines: false, // Allow splits
keepNext: false,
outlineLevel: 4,
},
};

console.log('📋 Custom Heading Configuration:');
console.log(' H1: Arial, 36pt, bold, extra spacing');
console.log(' H2: Georgia, 20pt, bold, custom spacing');
console.log(' H3: Calibri, 13pt, NOT bold, custom spacing');
console.log(' H4: (using defaults)');
console.log(' H5: Times New Roman, 10pt, bold, minimal spacing');
console.log(' H6: (using defaults)\n');

try {
const fileBuffer = await HTMLtoDOCX(htmlString, null, {
heading: customHeadingOptions,
title: 'Customizable Heading Styles Demo',
subject: 'Demonstrating PR #129 - Customizable Heading Styles',
creator: 'TurboDocx Example',
description: 'This document showcases the customizable heading styles feature',
});

fs.writeFile(filePath, fileBuffer, (error) => {
if (error) {
console.log('❌ Docx file creation failed');
console.error(error);
return;
}
console.log('✅ Docx file created successfully: ' + filePath);
console.log('\n📖 Open the file to see:');
console.log(' • Custom fonts for different heading levels');
console.log(' • Custom font sizes');
console.log(' • Custom spacing before/after headings');
console.log(' • H3 without bold (customized)');
console.log(' • H4 and H6 with default styles (for comparison)');
});
} catch (error) {
console.log('❌ Error generating document');
console.error(error);
}
})();
61 changes: 60 additions & 1 deletion example/typescript/typescript-example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,66 @@ async function generateDocuments() {
);

await saveDocxFile(rtlTestResult, "typescript-rtl-test.docx", "RTL Test");


// Customizable Heading Styles test (PR #129)
const headingStylesHtml = `
<h1>Custom Heading Styles Demo</h1>
<p>This demonstrates the customizable heading styles feature from PR #129.</p>
<h2>Custom Styled Section</h2>
<p>All headings in this document use custom fonts, sizes, and spacing.</p>
<h3>Subsection Header</h3>
<p>Notice the different styling for each heading level.</p>
`;

const headingStylesResult = await HTMLtoDOCX(
headingStylesHtml,
null,
{
title: "Custom Heading Styles Test",
creator: "TypeScript Heading Styles Test",
heading: {
heading1: {
font: "Arial",
fontSize: 72, // 36pt in Word (OOXML uses half-points: 72 / 2 = 36pt)
bold: true,
spacing: {
before: 600,
after: 200
},
keepLines: true,
keepNext: true,
outlineLevel: 0
},
heading2: {
font: "Georgia",
fontSize: 40, // 20pt in Word (40 / 2 = 20pt)
bold: true,
spacing: {
before: 400,
after: 150
},
keepLines: true,
keepNext: true,
outlineLevel: 1
},
heading3: {
font: "Calibri",
fontSize: 26, // 13pt in Word (26 / 2 = 13pt)
bold: false, // Not bold
spacing: {
before: 240,
after: 100
},
keepLines: true,
keepNext: true,
outlineLevel: 2
}
}
}
);

await saveDocxFile(headingStylesResult, "typescript-heading-styles-test.docx", "Heading Styles Test");

} catch (error) {
console.error("Error generating documents:", error);
}
Expand Down
25 changes: 25 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,30 @@ declare namespace HTMLtoDOCX {
restart: "continuous" | "newPage" | "newSection";
}

interface HeadingSpacing {
before?: number;
after?: number;
}

interface HeadingStyle {
font?: string;
fontSize?: number;
bold?: boolean;
spacing?: HeadingSpacing;
keepLines?: boolean;
keepNext?: boolean;
outlineLevel?: number;
}

interface HeadingConfig {
heading1?: HeadingStyle;
heading2?: HeadingStyle;
heading3?: HeadingStyle;
heading4?: HeadingStyle;
heading5?: HeadingStyle;
heading6?: HeadingStyle;
}

interface DocumentOptions {
orientation?: "portrait" | "landscape";
pageSize?: PageSize;
Expand Down Expand Up @@ -64,6 +88,7 @@ declare namespace HTMLtoDOCX {
numbering?: {
defaultOrderedListStyleType?: string;
};
heading?: HeadingConfig;
decodeUnicode?: boolean;
lang?: string;
direction?: "ltr" | "rtl";
Expand Down
17 changes: 17 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module.exports = {
testEnvironment: 'node',
testMatch: ['**/tests/**/*.test.js'],
collectCoverageFrom: [
'src/**/*.js',
'!src/**/*.test.js',
'!**/node_modules/**',
],
coverageDirectory: 'coverage',
coverageReporters: ['text', 'lcov', 'html'],
verbose: true,
transform: {
'^.+\\.js$': 'babel-jest',
},
moduleFileExtensions: ['js', 'json'],
testTimeout: 10000,
};
Loading