Run properties in Paragraph properties
See original GitHub issueThis is probably a feature request.
Use Case / Problem I want 2 tables stacked on top of each other, but with no space in between. Impossible right? Word merges stacked tables and the only way to split them is by putting a paragraph in between. So, the trick is to make the paragraph as short as possible. Why? Because I want the 2nd table to be on a new page. So the paragraph must be at the end of the first table/page or at the beginning of the 2nd table/page. If the former, you don’t want the paragraph to wrap to a new page if the table takes up almost all vertical space. If the latter, you don’t want extra dead space above your table on the 2nd page.
Solution To make a paragraph take up as little space as possible, give it a font size of 0.5pts. Note that MSWord doesn’t allow you to go lower than 1pt, but the XML supports 0.5pts and Word respects it and will preserve it when resaving the doc.
docx.js Limitation But while I can make an empty paragraph with 1pt font size in MSWord, I can’t in docx.js. When I try, Word doesn’t like it and falls back to the default 10pt font size. I compared the XML generated by docx.js with the XML generated by Word and discovered the difference.
This is Word:
<w:p>
<w:pPr>
<w:rPr>
<w:sz w:val="2" />
<w:szCs w:val="2" />
</w:rPr>
</w:pPr>
</w:p>
This is docx.js:
<w:p>
<w:r>
<w:rPr>
<w:sz w:val="1" />
<w:szCs w:val="1" />
</w:rPr>
</w:r>
</w:p>
The difference is subtle. But notice the “rPr” nested inside of “pPr” in the Word example. While the docx.js example nests “rPr” inside of a “r”. This is because docx.js forced me to create an empty TextRun object and apply the font size to it. But Word doesn’t create a TextRun at all. It appears to be defining default TextRun properties in the paragraph properties. As far as I can tell, docx.js doesn’t allow me to pass the font size to paragraph properties at all.
Workaround Until this is supported, I have resorted to adding text to the TextRun and setting the font color to “white”. But, being able to add default run properties at the paragraph level would be nice for a number of reasons, so I decided to bring this feature to your attention.
Issue Analytics
- State:
- Created 3 years ago
- Comments:16 (5 by maintainers)
Top GitHub Comments
@dolanmiu Honestly, it confused me too. But after playing with your XML file, I realized that quote doesn’t say HOW “The text is then formatted accordingly”. After all, it is true in practice. Let’s say you have an empty paragraph formatted with a font size of 50pt. Any text you type into that paragraph will inherit the formatting. But the mechanics behind that apparently involve copying the formatting from the paragraph to the run. That’s what MS Word does, and docx.js can do the same thing. Also, in MS Word, you can then highlight the text and change the font size to 10pt (make sure you highlight the text and not the whole paragraph when changing the font size). After saving, you will see in the XML that the paragraph still has a font size of 50pt, but the run now has a font size of 10pt. This is an example of the “except for possible direct text formatting” in the spec. When it comes to docx.js, that just means the formatting defined at the run level overrides formatting defined at the paragraph level as you merge formatting in the serialized XML it produces for the runs’ properties.
@dolanmiu First of all, thanks for your effort on this. I am more than happy to assist with my analysis. So I played with it a bit. Looks like your XML correctly conforms to the spec. But you will only notice the 50pt font size for EMPTY paragraphs. Your paragraph is not empty. MS Word will COPY the paragraph run properties to any runs it adds to the paragraph. For example, if you open a blank document, set the font size to 50pt, type some text, and save it then you will get XML that looks like this:
MS Word copied the properties from the paragraph run properties to the new run’s properties. docx.js can do the same thing. When creating a new paragraph, merge the paragraph run properties with the properties (if any) of each run added as a child. Allow any properties set on the run to override properties set on the paragraph.
In short, your branch works as-is and will solve my problem since I’m working with an empty paragraph. But if you want your changes to work intuitively with non-empty paragraphs, then you can add the merge logic.
Make sense?