Skip to content

Commit 3d9b188

Browse files
authored
Merge pull request #403 from Harbour-Enterprises/HAR-8992_sample-doc-formatting
HAR-8992 Get run properties from styles.xml by the styleID
2 parents d529e03 + 04cf084 commit 3d9b188

9 files changed

Lines changed: 52 additions & 16 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/super-editor/src/core/super-converter/v2/importer/annotationImporter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const handleAnnotationNode = (params) => {
1717

1818
const docPartObj = sdtPr?.elements.find((el) => el.name === 'w:docPartObj');
1919
if (docPartObj) {
20-
return handleDocPartObj(nodes, docx, nodeListHandler, insideTrackChange);
20+
return handleDocPartObj({ nodes, docx, nodeListHandler, insideTrackChange });
2121
}
2222

2323
const alias = sdtPr?.elements.find((el) => el.name === 'w:alias');

packages/super-editor/src/core/super-converter/v2/importer/docxImporter.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ const createNodeListHandler = (nodeHandlers) => {
169169
};
170170
};
171171

172-
const nodeListHandlerFn = ({ nodes: elements, docx, insideTrackChange, converter, editor, filename }) => {
172+
const nodeListHandlerFn = ({ nodes: elements, docx, insideTrackChange, converter, editor, filename, parentStyleId }) => {
173173
if (!elements || !elements.length) return [];
174174

175175
const processedElements = [];
@@ -193,7 +193,8 @@ const createNodeListHandler = (nodeHandlers) => {
193193
insideTrackChange,
194194
converter,
195195
editor,
196-
filename
196+
filename,
197+
parentStyleId
197198
});
198199
},
199200
{ nodes: [], consumed: 0 }

packages/super-editor/src/core/super-converter/v2/importer/listImporter.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,7 @@ function handleListNodes(
187187
nodeAttributes['numId'] = numId;
188188

189189
if (docx) {
190-
const defaultStyleId = attributes['w:rsidRDefault'];
191-
nodeAttributes['spacing'] = getParagraphSpacing(defaultStyleId, item, docx);
190+
nodeAttributes['spacing'] = getParagraphSpacing(item, docx);
192191
}
193192

194193
const newListItem = createListItem(schemaElements, nodeAttributes, []);

packages/super-editor/src/core/super-converter/v2/importer/markImporter.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ export function parseMarks(property, unknownMarks = [], docx = null) {
5050
// Marks with attrs: we need to get their values
5151
if (Object.keys(attributes).length) {
5252
const value = getMarkValue(m.type, attributes, docx);
53+
54+
// If there is no value for mark it can't be applied
55+
if (value === null || value === undefined) return;
56+
5357
newMark.attrs = {};
5458
newMark.attrs[m.property] = value;
5559
}
@@ -159,7 +163,7 @@ function getFontFamilyValue(attributes, docx) {
159163
const typeface = latin.attributes['typeface'];
160164
return typeface;
161165

162-
};
166+
}
163167

164168
function getIndentValue(attributes) {
165169
let value = attributes['w:left'];

packages/super-editor/src/core/super-converter/v2/importer/paragraphNodeImporter.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export const handleParagraphNode = (params) => {
5151
const styleTag = pPr?.elements?.find((el) => el.name === 'w:pStyle');
5252
if (styleTag) {
5353
schemaNode.attrs['styleId'] = styleTag.attributes['w:val'];
54-
};
54+
}
5555

5656
const indent = pPr?.elements?.find((el) => el.name === 'w:ind');
5757
if (indent && indent.attributes) {
@@ -62,7 +62,7 @@ export const handleParagraphNode = (params) => {
6262
if (left) schemaNode.attrs['indent'].left = twipsToPixels(left);
6363
if (right) schemaNode.attrs['indent'].right = twipsToPixels(right);
6464
if (firstLine) schemaNode.attrs['indent'].firstLine = twipsToPixels(firstLine);
65-
};
65+
}
6666

6767
const textIndentVal = left || firstLine || 0;
6868
schemaNode.attrs['textIndent'] = `${twipsToInches(textIndentVal)}in`;
@@ -75,7 +75,7 @@ export const handleParagraphNode = (params) => {
7575

7676
if (docx) {
7777
const defaultStyleId = node.attributes?.['w:rsidRDefault'];
78-
schemaNode.attrs['spacing'] = getParagraphSpacing(defaultStyleId, node, docx);
78+
schemaNode.attrs['spacing'] = getParagraphSpacing(node, docx);
7979
schemaNode.attrs['rsidRDefault'] = defaultStyleId;
8080
}
8181

@@ -92,7 +92,7 @@ export const handleParagraphNode = (params) => {
9292
return { nodes: schemaNode ? [schemaNode] : [], consumed: 1 };
9393
};
9494

95-
export const getParagraphSpacing = (defaultStyleId, node, docx) => {
95+
export const getParagraphSpacing = (node, docx) => {
9696
// Check if we have default paragraph styles to override
9797
const spacing = {
9898
lineSpaceAfter: 0,

packages/super-editor/src/core/super-converter/v2/importer/runNodeImporter.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,48 @@ import { createImportMarks } from './markImporter.js';
55
* @type {import("docxImporter").NodeHandler}
66
*/
77
const handleRunNode = (params) => {
8-
const { nodes, nodeListHandler } = params;
8+
const { nodes, nodeListHandler, parentStyleId, docx } = params;
99
if (nodes.length === 0 || nodes[0].name !== 'w:r') {
1010
return { nodes: [], consumed: 0 };
1111
}
12-
1312
const node = nodes[0];
13+
1414
const childParams = { ...params, nodes: node.elements };
1515
let processedRun = nodeListHandler.handler(childParams)?.filter((n) => n) || [];
1616
const hasRunProperties = node.elements?.some((el) => el.name === 'w:rPr');
17+
const defaultNodeStyles = getMarksFromStyles(docx, parentStyleId);
1718
if (hasRunProperties) {
1819
const { marks = [], attributes = {} } = parseProperties(node);
20+
21+
// Apply fonts from related style definition if there is no marks
22+
const textStyleMark = marks.find(m => m.type === 'textStyle');
23+
const hasFontStyle = textStyleMark && Object.keys(textStyleMark.attrs).length > 0;
24+
if (defaultNodeStyles.marks && !hasFontStyle) {
25+
marks.push(...defaultNodeStyles.marks);
26+
}
27+
1928
if (node.marks) marks.push(...node.marks);
2029
processedRun = processedRun.map((n) => ({ ...n, marks: createImportMarks(marks), attributes }));
30+
} else if (defaultNodeStyles.marks) {
31+
processedRun = processedRun.map((n) => ({ ...n, marks: createImportMarks(defaultNodeStyles.marks) }));
2132
}
2233
return { nodes: processedRun, consumed: 1 };
2334
};
2435

36+
const getMarksFromStyles = (docx, styleId) => {
37+
const styles = docx?.['word/styles.xml'];
38+
if (!styles) {
39+
return {};
40+
}
41+
42+
const styleTags = styles.elements[0].elements.filter((style) => style.name === 'w:style');
43+
const style = styleTags.find((tag) => tag.attributes['w:styleId'] === styleId) || {};
44+
45+
if (!style) return {};
46+
47+
return parseProperties(style, docx);
48+
}
49+
2550
/**
2651
* @type {import("docxImporter").NodeHandlerEntry}
2752
*/

packages/super-editor/src/core/super-converter/v2/importer/standardNodeImporter.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ export const handleStandardNode = (params) => {
4343
// Iterate through the children and build the schemaNode content
4444
// Skip run properties since they are formatting only elements
4545
const content = [];
46+
const parentStyleId = getParentStyleId(node);
4647
if (elements && elements.length) {
4748
const updatedElements = elements.map((el) => {
4849
if (!el.marks) el.marks = [];
4950
el.marks.push(...marks);
5051
return el;
5152
});
52-
53-
const childParams = { ...params, nodes: updatedElements };
53+
54+
const childParams = { ...params, nodes: updatedElements, parentStyleId };
5455
const childContent = nodeListHandler.handler(childParams);
5556
content.push(...childContent);
5657
}
@@ -65,6 +66,12 @@ export const handleStandardNode = (params) => {
6566
return { nodes: [resultNode], consumed: 1 };
6667
};
6768

69+
const getParentStyleId = node => {
70+
const pPr = node.elements?.find((el) => el.name === 'w:pPr');
71+
const styleTag = pPr?.elements?.find((el) => el.name === 'w:pStyle');
72+
return styleTag ? styleTag.attributes['w:val'] : null;
73+
}
74+
6875
/**
6976
* @type {import("docxImporter").NodeHandlerEntry}
7077
*/

packages/super-editor/src/tests/export/export-helpers/export-helpers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { join } from 'path';
22
import { readFile } from 'fs/promises';
3-
import { Editor, getRichTextExtensions } from '@core/Editor.js';
3+
import { Editor } from '@core/Editor.js';
44
import { getRichTextExtensions } from '@harbour-enterprises/super-editor';
55
import { getStarterExtensions } from '@extensions/index.js';
66
import { exportSchemaToJson } from '@converter/exporter';

0 commit comments

Comments
 (0)