diff --git a/packtools/sps/formats/pdf/pipeline/docx.py b/packtools/sps/formats/pdf/pipeline/docx.py index c7a9824a1..3975bfdb2 100644 --- a/packtools/sps/formats/pdf/pipeline/docx.py +++ b/packtools/sps/formats/pdf/pipeline/docx.py @@ -459,6 +459,11 @@ def docx_references_pipe( for reference in references: paragraph = docx.add_paragraph(reference) paragraph.style = docx.styles[paragraph_style_name] + # SCL Paragraph Reference has no line_spacing of its own and uses + # the same font size as body text, so a reference that wraps to + # multiple lines rendered with the same loose spacing as a body + # paragraph, with no visual distinction between entries. + paragraph.paragraph_format.line_spacing = 1.0 def docx_acknowledgments_pipe(docx, acknowledgment_title, acknowledgement_paragraphs, paragraph_section_style_name='SCL Section Title'): """ diff --git a/packtools/sps/formats/pdf/renderer/docx/figure.py b/packtools/sps/formats/pdf/renderer/docx/figure.py index b6455d9d5..0b491734d 100644 --- a/packtools/sps/formats/pdf/renderer/docx/figure.py +++ b/packtools/sps/formats/pdf/renderer/docx/figure.py @@ -298,6 +298,12 @@ def _add_caption(docx, figure_data, header_style_name): r_cap = p.add_run(figure_data['caption']) r_cap.bold = False + # Single line spacing regardless of whether the named style resolves: + # SCL Table Heading has no line_spacing of its own, so a multi-line + # caption would otherwise fall back to the same loose spacing as body + # text (only the smaller caption font made it look tighter). + p.paragraph_format.line_spacing = 1.0 + try: p.style = docx.styles[header_style_name] except KeyError: diff --git a/packtools/sps/formats/pdf/renderer/docx/table.py b/packtools/sps/formats/pdf/renderer/docx/table.py index 2992e9721..a549b80cb 100644 --- a/packtools/sps/formats/pdf/renderer/docx/table.py +++ b/packtools/sps/formats/pdf/renderer/docx/table.py @@ -177,13 +177,19 @@ def _add_caption_paragraph(docx, table_data, header_style_name): if table_data.get('title'): r = p.add_run(table_data['title']) r.bold = False - + + # Single line spacing regardless of whether the named style resolves: + # SCL Table Heading has no line_spacing of its own, so a multi-line + # caption would otherwise fall back to the same loose spacing as body + # text (only the smaller caption font made it look tighter). + p.paragraph_format.line_spacing = 1.0 + try: p.style = docx.styles[header_style_name] p.paragraph_format.keep_with_next = True except Exception: pass - + return p def _add_table_foot_paragraphs(docx, table_data): diff --git a/tests/sps/formats/pdf/pipeline/test_docx.py b/tests/sps/formats/pdf/pipeline/test_docx.py index 3dc799d66..faa57d28f 100644 --- a/tests/sps/formats/pdf/pipeline/test_docx.py +++ b/tests/sps/formats/pdf/pipeline/test_docx.py @@ -259,8 +259,19 @@ class TestDocxBodyPipe(unittest.TestCase): class TestDocxReferencesPipe(unittest.TestCase): - # TODO - ... + """ + Regression: SCL Paragraph Reference uses the same font size as body + text and has no line_spacing of its own, so a reference wrapping to + multiple lines rendered with the same loose spacing as a body + paragraph. Line spacing is now set explicitly on each reference + paragraph. + """ + + def test_reference_has_single_line_spacing(self): + docx = _docx_with_layout_styles() + docx_pipe.docx_references_pipe(docx, references=['Author A. Title B. Journal C. 2020.']) + para = docx.paragraphs[-1] + self.assertEqual(para.paragraph_format.line_spacing, 1.0) class TestDocxAcknowledgmentsPipe(unittest.TestCase): diff --git a/tests/sps/formats/pdf/renderer/docx/test_figure.py b/tests/sps/formats/pdf/renderer/docx/test_figure.py index 636cb4f25..f3fc9b814 100644 --- a/tests/sps/formats/pdf/renderer/docx/test_figure.py +++ b/tests/sps/formats/pdf/renderer/docx/test_figure.py @@ -7,6 +7,7 @@ from PIL import Image from packtools.sps.formats.pdf.renderer.docx.figure import ( + _add_caption, _infer_image_dpi, _natural_width_capped, add_figure, @@ -15,6 +16,30 @@ from packtools.sps.formats.pdf import enum as pdf_enum +class TestAddCaption(unittest.TestCase): + """ + Regression: the caption paragraph's own style (SCL Table Heading) has no + line_spacing, so it fell back to the same loose spacing as body text - + only the smaller caption font size made it look somewhat tighter. Line + spacing is now set explicitly, independent of whether the named style + resolves. + """ + + def test_caption_has_single_line_spacing(self): + docx = Document() + docx.add_paragraph() + _add_caption(docx, {'label': 'Figure 1', 'caption': 'A caption'}, 'SCL Table Heading') + p = docx.paragraphs[-1] + self.assertEqual(p.paragraph_format.line_spacing, 1.0) + + def test_line_spacing_set_even_when_named_style_is_missing(self): + docx = Document() + docx.add_paragraph() + _add_caption(docx, {'label': 'Figure 1', 'caption': 'A caption'}, 'Does Not Exist') + p = docx.paragraphs[-1] + self.assertEqual(p.paragraph_format.line_spacing, 1.0) + + class TestDecideFigureLayoutUnits(unittest.TestCase): """ Regression test for a units bug: single_col_width degrades from a Cm diff --git a/tests/sps/formats/pdf/renderer/docx/test_table.py b/tests/sps/formats/pdf/renderer/docx/test_table.py index 2807b1937..f5e035c1f 100644 --- a/tests/sps/formats/pdf/renderer/docx/test_table.py +++ b/tests/sps/formats/pdf/renderer/docx/test_table.py @@ -3,7 +3,7 @@ from docx import Document from docx.shared import Cm -from packtools.sps.formats.pdf.renderer.docx.table import _compute_table_width, add_table +from packtools.sps.formats.pdf.renderer.docx.table import _compute_table_width, _add_caption_paragraph, add_table from packtools.sps.formats.pdf import enum as pdf_enum @@ -49,6 +49,30 @@ def test_single_column_layout_override_ignores_column_count(self): self.assertEqual(layout, pdf_enum.SINGLE_COLUMN_PAGE_LABEL) +class TestAddCaptionParagraph(unittest.TestCase): + """ + Regression: the caption paragraph's own style (SCL Table Heading) has no + line_spacing, so it fell back to the same loose spacing as body text - + only the smaller caption font size made it look somewhat tighter. Line + spacing is now set explicitly, independent of whether the named style + resolves. + """ + + def test_caption_has_single_line_spacing(self): + docx = Document() + p = _add_caption_paragraph( + docx, {'label': 'Table 1', 'title': 'A caption'}, 'SCL Table Heading' + ) + self.assertEqual(p.paragraph_format.line_spacing, 1.0) + + def test_line_spacing_set_even_when_named_style_is_missing(self): + docx = Document() + p = _add_caption_paragraph( + docx, {'label': 'Table 1', 'title': 'A caption'}, 'Does Not Exist' + ) + self.assertEqual(p.paragraph_format.line_spacing, 1.0) + + class TestAddTableFoot(unittest.TestCase): """ Regression tests: notes extracted into table_data['foot']