Skip to content

Commit 812e1ac

Browse files
committed
Added Parameters and style attributes
Signed-off-by: Vishal <[email protected]>
1 parent 874210f commit 812e1ac

File tree

6 files changed

+88
-55
lines changed

6 files changed

+88
-55
lines changed

README.md

+12-4
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,18 @@ full fledged examples can be found under `example/`
8484
- `preProcessing` <?[Object]>
8585
- `skipHTMLMinify` <?[Boolean]> flag to skip minification of HTML. Defaults to `false`.
8686
- `hrStyles` <?[Object]>
87-
- `val` <String> The border style (e.g., `single`, `dashed`). Defaults to `single`.
88-
- `sz` <Number> The size of the border. Defaults to `24`.
89-
- `space` <Number> The space around border. Defaults to `1`.
90-
- `color` <String> The color of the border. Defaults to `000000`.
87+
- `height` <Number> The size of the border. Defaults to `24`.
88+
- `width` <Number> The space around border. Defaults to `1`.
89+
- `backgroundColor` <String> The color of the border. Defaults to `000000`.
90+
- `borderOptions` <?[Object]>
91+
- `size` <?[Number]> denotes the border size. Defaults to `0`.
92+
- `val` <?[String]> denotes the style of the borderStyle. Defaults to `solid`.
93+
- `color` <?[String]> determines the border color. Defaults to `000000`.
94+
- `margins` <?[Object]>
95+
- `top` <[Number]> distance between the top of the text margins for the main document and the top of the page for all pages in this section in [TWIP]. Defaults to 1440. Supports equivalent measurement in [pixel], [cm] or [inch].
96+
- `right` <[Number]> distance between the right edge of the page and the right edge of the text extents for this document in [TWIP]. Defaults to 1800. Supports equivalent measurement in [pixel], [cm] or [inch].
97+
- `bottom` <[Number]> distance between the bottom of text margins for the document and the bottom of the page in [TWIP]. Defaults to 1440. Supports equivalent measurement in [pixel], [cm] or [inch].
98+
- `left` <[Number]> distance between the left edge of the page and the left edge of the text extents for this document in [TWIP]. Defaults to 1800. Supports equivalent measurement in [pixel], [cm] or [inch].
9199
- `footerHTMLString` <[String]> clean html string equivalent of footer. Defaults to `<p></p>` if footer flag is `true`.
92100

93101
### Returns

example/example-node.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const htmlString = `<!DOCTYPE html>
1616
<div>
1717
<p>Taken from wikipedia</p>
1818
<p>Taken from wikipedia</p>
19-
<hr style="border: 10px dotted red;" />
19+
<hr style="height:30px;background-color: blue; border: 20px solid; color: blue">
2020
<p>This is a test for hr tag</p>
2121
<hr>
2222
<img

example/example.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const htmlString = `<!DOCTYPE html>
1515
<body>
1616
<div>
1717
<p>Taken from wikipedia</p>
18-
<hr>
18+
<hr style="height:2px;border-width:0;color:gray;background-color:gray">
1919
<p>This is a test for hr tag</p>
2020
<hr>
2121
<img

src/constants.js

+15-4
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,20 @@ const defaultTableBorderAttributeOptions = {
3535
stroke: 'single',
3636
};
3737
const defaultHorizontalRuleOptions = {
38-
val: 'single',
39-
sz: '24',
40-
space: '1',
41-
color: 'FF0000',
38+
height: 0,
39+
width: 100,
40+
backgroundColor: '000000',
41+
borderOptions: {
42+
size: 0,
43+
val: 'solid',
44+
color: '000000',
45+
},
46+
margins: {
47+
top: 0,
48+
right: 0,
49+
bottom: 0,
50+
left: 0,
51+
},
4252
};
4353
const defaultDocumentOptions = {
4454
orientation: defaultOrientation,
@@ -65,6 +75,7 @@ const defaultDocumentOptions = {
6575
},
6676
borderOptions: defaultTableBorderOptions,
6777
},
78+
hrStyles: defaultHorizontalRuleOptions,
6879
pageSize: {
6980
width: landscapeHeight,
7081
height: landscapeWidth,

src/docx-document.js

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class DocxDocument {
160160
this.tableBorders =
161161
(properties.table && properties.table.borderOptions) ||
162162
defaultDocumentOptions.table.borderOptions;
163+
this.horizontalRule = properties.horizontalRule || defaultDocumentOptions.hrStyles;
163164
this.pageNumber = properties.pageNumber || false;
164165
this.skipFirstHeaderFooter = properties.skipFirstHeaderFooter || false;
165166
this.lineNumber = properties.lineNumber ? properties.lineNumberOptions : null;

src/helpers/xml-builder.js

+58-45
Original file line numberDiff line numberDiff line change
@@ -179,43 +179,61 @@ const buildTableRowHeight = (tableRowHeight) =>
179179
.att('@w', 'hRule', 'atLeast')
180180
.up();
181181

182-
const buildHorizontalRule = (element, styles = {}) => {
183-
// Parse inline styles from the element
184-
const inlineStyles = (styleString => {
185-
const styles = {};
186-
if (styleString) {
187-
styleString.split(";").forEach(style => {
188-
const [key, value] = style.split(":").map(s => s.trim());
189-
if (key && value) {
190-
styles[key] = value;
191-
}
192-
});
193-
}
194-
return styles;
195-
})(element && typeof element.getAttribute === 'function' ? element.getAttribute("style") : "");
196-
197-
// Merge inline styles with default styles and additional styles
198-
const mergedStyles = { ...defaultHorizontalRuleOptions, ...styles, ...inlineStyles };
199-
200-
// Use the imported fragment directly
201-
const hrFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele("@w", "p");
202-
const pPr = hrFragment.ele("@w", "pPr");
203-
const pBdr = pPr.ele("@w", "pBdr");
204-
205-
// Define the bottom border properties
206-
pBdr.ele("@w", "bottom", {
207-
"w:val": mergedStyles.val || 'single',
208-
"w:sz": mergedStyles.sz || '4',
209-
"w:space": mergedStyles.space || '1',
210-
"w:color": mergedStyles.color || 'auto'
211-
});
212-
213-
pBdr.up();
214-
pPr.up();
215-
hrFragment.up();
216-
217-
return hrFragment;
218-
};
182+
const buildHorizontalRuleProperties = (attributes) => {
183+
const horizontalRulePropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'pPr');
184+
185+
if (attributes && typeof attributes === 'object') {
186+
const spacingFragment = buildSpacing(
187+
attributes.lineHeight,
188+
attributes.beforeSpacing,
189+
attributes.afterSpacing
190+
);
191+
horizontalRulePropertiesFragment.import(spacingFragment);
192+
193+
const borderFragment = buildBorder(
194+
'bottom',
195+
attributes.borderOptions.size,
196+
attributes.borderOptions.val,
197+
attributes.borderOptions.color
198+
);
199+
horizontalRulePropertiesFragment.import(borderFragment);
200+
201+
const shadingFragment = buildShading(attributes.backgroundColor);
202+
horizontalRulePropertiesFragment.import(shadingFragment);
203+
204+
horizontalRulePropertiesFragment.up();
205+
}
206+
207+
return horizontalRulePropertiesFragment;
208+
};
209+
210+
const buildHorizontalRule = (vNode, attributes, docxDocumentInstance) => {
211+
const options = {
212+
isParagraph: false,
213+
};
214+
215+
const modifiedAttributes = modifiedStyleAttributesBuilder(docxDocumentInstance, vNode, attributes, options);
216+
217+
if (!modifiedAttributes.borderOptions) {
218+
modifiedAttributes.borderOptions = defaultHorizontalRuleOptions.borderOptions;
219+
}
220+
221+
const horizontalRuleFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'hr');
222+
const horizontalRulePropertiesFragment = buildHorizontalRuleProperties(modifiedAttributes);
223+
horizontalRuleFragment.import(horizontalRulePropertiesFragment);
224+
225+
horizontalRuleFragment.ele('w:r')
226+
.ele('@w','rPr')
227+
.ele('@w','shd', { 'w:fill': modifiedAttributes.backgroundColor }).up()
228+
.ele('@w','bdr', { 'w:val': modifiedAttributes.borderOptions.val, 'w:sz': modifiedAttributes.borderOptions.size, 'w:color': modifiedAttributes.borderOptions.color }).up()
229+
.up()
230+
.ele('@w', 't', { 'xml:space': 'preserve' }, ' '.repeat(modifiedAttributes.width))
231+
.up()
232+
.up()
233+
.up();
234+
235+
return horizontalRuleFragment;
236+
};
219237

220238
const buildVerticalAlignment = (verticalAlignment) => {
221239
if (verticalAlignment.toLowerCase() === 'middle') {
@@ -470,11 +488,9 @@ const fixupColumnWidth = (columnWidthString, parentWidth = 0) => {
470488
const fixupMargin = (marginString) => {
471489
if (pointRegex.test(marginString)) {
472490
const matchedParts = marginString.match(pointRegex);
473-
// convert point to half point
474491
return pointToTWIP(matchedParts[1]);
475492
} else if (pixelRegex.test(marginString)) {
476493
const matchedParts = marginString.match(pixelRegex);
477-
// convert pixels to half point
478494
return pixelToTWIP(matchedParts[1]);
479495
} else if (cmRegex.test(marginString)) {
480496
const matchedParts = marginString.match(cmRegex);
@@ -483,22 +499,19 @@ const fixupMargin = (marginString) => {
483499
const matchedParts = marginString.match(inchRegex);
484500
return inchToTWIP(matchedParts[1]);
485501
} else if (percentageRegex.test(marginString)) {
486-
// This requires changes in lot of functions. So, for now, we are returning the percentage value as it is.
487-
// TODO: Revisit this and see how margins in percentages are handled and change in respective functions.
488502
const matchedParts = marginString.match(percentageRegex);
489-
return matchedParts[1]
503+
return matchedParts[1];
490504
}
491505
};
492506

493507
const borderStyleParser = (style) => {
494-
// Accepted OOXML Values for border style: http://officeopenxml.com/WPtableBorders.php
495508
if (['dashed', 'dotted', 'double', 'inset', 'outset', 'none'].includes(style)) {
496509
return style;
497510
} else if (style === 'hidden') {
498511
return 'nil';
499512
}
500-
return 'single'
501-
}
513+
return 'single';
514+
};
502515

503516
const borderSizeParser = (borderSize) => {
504517
if (pointRegex.test(borderSize)) {

0 commit comments

Comments
 (0)