Skip to content

Commit 8f79647

Browse files
committed
paragraph indentation
1 parent 9fb030f commit 8f79647

3 files changed

Lines changed: 95 additions & 15 deletions

File tree

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

Lines changed: 72 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,23 +58,29 @@ export const handleParagraphNode = (params) => {
5858
if (styleTag) {
5959
schemaNode.attrs['styleId'] = styleTag.attributes['w:val'];
6060
}
61+
62+
if (docx) {
63+
const indent = getParagraphIndent(node, docx, schemaNode.attrs['styleId']);
6164

62-
const indent = pPr?.elements?.find((el) => el.name === 'w:ind');
63-
if (indent && indent.attributes) {
64-
const { 'w:left': left, 'w:right': right, 'w:firstLine': firstLine, 'w:hanging': hanging } = indent?.attributes;
65-
66-
if (schemaNode.attrs) {
67-
if (!schemaNode.attrs.indent) schemaNode.attrs.indent = {};
68-
if (left) schemaNode.attrs['indent'].left = twipsToPixels(left);
69-
if (right) schemaNode.attrs['indent'].right = twipsToPixels(right);
70-
if (firstLine) schemaNode.attrs['indent'].firstLine = twipsToPixels(firstLine);
71-
if (hanging) schemaNode.attrs['indent'].hanging = twipsToPixels(hanging);
65+
if (!schemaNode.attrs.indent) {
66+
schemaNode.attrs.indent = {};
7267
}
7368

74-
const textIndentValue = left - parseInt(hanging || 0) || 0;
75-
if (textIndentValue) {
76-
schemaNode.attrs['textIndent'] = `${twipsToInches(textIndentValue)}in`;
77-
}
69+
if (indent.left) {
70+
schemaNode.attrs.indent.left = indent.left;
71+
}
72+
if (indent.right) {
73+
schemaNode.attrs.indent.right = indent.right;
74+
}
75+
if (indent.firstLine) {
76+
schemaNode.attrs.indent.firstLine = indent.firstLine;
77+
}
78+
if (indent.hanging) {
79+
schemaNode.attrs.indent.hanging = indent.hanging;
80+
}
81+
if (indent.textIndent) {
82+
schemaNode.attrs.textIndent = `${indent.textIndent}in`;
83+
}
7884
}
7985

8086
const justify = pPr?.elements?.find((el) => el.name === 'w:jc');
@@ -111,6 +117,48 @@ export const handleParagraphNode = (params) => {
111117
return { nodes: schemaNode ? [schemaNode] : [], consumed: 1 };
112118
};
113119

120+
export const getParagraphIndent = (node, docx, styleId = '') => {
121+
const indent = {
122+
left: 0,
123+
right: 0,
124+
firstLine: 0,
125+
hanging: 0,
126+
textIndent: 0,
127+
};
128+
129+
const { indent: pDefaultIndent = {} } = getDefaultParagraphStyle(docx, styleId);
130+
131+
const pPr = node.elements?.find((el) => el.name === 'w:pPr');
132+
const inLineIndentTag = pPr?.elements?.find((el) => el.name === 'w:ind');
133+
const inLineIndent = inLineIndentTag?.attributes || {};
134+
135+
const leftIndent = inLineIndent?.['w:left'] || pDefaultIndent?.['w:left'];
136+
const rightIndent = inLineIndent?.['w:right'] || pDefaultIndent?.['w:right'];
137+
const firstLine = inLineIndent?.['w:firstLine'] || pDefaultIndent?.['w:firstLine'];
138+
const hanging = inLineIndent?.['w:hanging'] || pDefaultIndent?.['w:hanging'];
139+
140+
if (leftIndent) {
141+
indent.left = twipsToPixels(leftIndent);
142+
}
143+
if (rightIndent) {
144+
indent.right = twipsToPixels(rightIndent);
145+
}
146+
if (firstLine) {
147+
indent.firstLine = twipsToPixels(firstLine);
148+
}
149+
if (hanging) {
150+
indent.hanging = twipsToPixels(hanging);
151+
}
152+
153+
const textIndentValue = leftIndent - parseInt(hanging || 0) || 0;
154+
155+
if (textIndentValue) {
156+
indent.textIndent = twipsToInches(textIndentValue);
157+
}
158+
159+
return indent;
160+
};
161+
114162
export const getParagraphSpacing = (node, docx, styleId = '', marks = []) => {
115163
// Check if we have default paragraph styles to override
116164
const spacing = {
@@ -168,27 +216,36 @@ const getDefaultParagraphStyle = (docx, styleId = '') => {
168216
const pDefault = defaults.elements.find((el) => el.name === 'w:pPrDefault');
169217
const pPrDefault = pDefault?.elements?.find((el) => el.name === 'w:pPr');
170218
const pPrDefaultSpacingTag = pPrDefault?.elements?.find((el) => el.name === 'w:spacing') || {};
219+
const pPrDefaultIndentTag = pPrDefault?.elements?.find((el) => el.name === 'w:ind') || {};
171220

172221
// Paragraph 'Normal' styles
173222
const stylesNormal = styles.elements[0].elements?.find((el) => el.name === 'w:style' && el.attributes['w:styleId'] === 'Normal');
174223
const pPrNormal = stylesNormal?.elements?.find((el) => el.name === 'w:pPr');
175224
const pPrNormalSpacingTag = pPrNormal?.elements?.find((el) => el.name === 'w:spacing') || {};
225+
const pPrNormalIndentTag = pPrNormal?.elements?.find((el) => el.name === 'w:ind') || {};
176226

177227
// Styles based on styleId
178228
let pPrStyleIdSpacingTag = {};
229+
let pPrStyleIdIndentTag = {};
179230
if (styleId) {
180231
const stylesById = styles.elements[0].elements?.find((el) => el.name === 'w:style' && el.attributes['w:styleId'] === styleId);
181232
const pPrById = stylesById?.elements?.find((el) => el.name === 'w:pPr');
182233
pPrStyleIdSpacingTag = pPrById?.elements?.find((el) => el.name === 'w:spacing') || {};
234+
pPrStyleIdIndentTag = pPrById?.elements?.find((el) => el.name === 'w:ind') || {};
183235
}
184236

185237
const { attributes: pPrDefaultSpacingAttr } = pPrDefaultSpacingTag;
186238
const { attributes: pPrNormalSpacingAttr } = pPrNormalSpacingTag;
187239
const { attributes: pPrByIdSpacingAttr } = pPrStyleIdSpacingTag;
188240

241+
const { attributes: pPrDefaultIndentAttr } = pPrDefaultIndentTag;
242+
const { attributes: pPrNormalIndentAttr } = pPrNormalIndentTag;
243+
const { attributes: pPrByIdIndentAttr } = pPrStyleIdIndentTag;
244+
189245
return {
190246
spacing: pPrByIdSpacingAttr || pPrDefaultSpacingAttr || pPrNormalSpacingAttr,
191-
}
247+
indent: pPrByIdIndentAttr || pPrDefaultIndentAttr || pPrNormalIndentAttr,
248+
};
192249
};
193250

194251
/**
Binary file not shown.

packages/super-editor/src/tests/import/paragraphNodeImporter.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,26 @@ describe('paragraph tests to check spacing', () => {
251251
expect(node.attrs.textIndent).toBe('1.81in');
252252
});
253253
});
254+
255+
describe('paragraph tests to check indentation', () => {
256+
257+
it('correctly gets indents from paragraph Normal styles', async () => {
258+
const dataName = 'paragraph_indent_normal_styles.docx';
259+
const docx = await getTestDataByFileName(dataName);
260+
const documentXml = docx['word/document.xml'];
261+
262+
const doc = documentXml.elements[0];
263+
const body = doc.elements[0];
264+
const content = body.elements;
265+
266+
const { nodes } = handleParagraphNode({ nodes: [content[0]], docx, nodeListHandler: defaultNodeListHandler() });
267+
268+
const node = nodes[0];
269+
expect(node.type).toBe('paragraph');
270+
271+
const { attrs } = node;
272+
const { indent } = attrs;
273+
274+
expect(indent.firstLine).toBe(29);
275+
});
276+
});

0 commit comments

Comments
 (0)