Files
md_to_gost/tests/test_paragraph_sizer.py
Igor20264 516abe7b83
Python application / build (push) Has been cancelled
BigUpdate
2026-09-03 10:44:08 +03:00

291 lines
16 KiB
Python

import unittest
import docx
from docx import Document
from md2gost.renderable.paragraph_sizer import Font, ParagraphSizer
from md2gost.renderable.listing import LISTING_OFFSET
from docx.shared import Pt, Mm, Cm
from . import _create_test_document, _EMUS_PER_PX
delta = 10/29
class TestFont(unittest.case.TestCase):
def test_get_text_width(self):
font = Font("Times New Roman", False, False, 14)
self.assertAlmostEqual(37.5, font.get_text_width("hello") / _EMUS_PER_PX, delta=delta)
def test_get_text_width_short(self):
font = Font("Times New Roman", False, False, 14)
self.assertAlmostEqual(15, font.get_text_width("in") / _EMUS_PER_PX, delta=delta)
def test_get_text_width_long(self):
font = Font("Times New Roman", False, False, 14)
self.assertAlmostEqual(245, font.get_text_width("Электроэнцефалографический") / _EMUS_PER_PX, delta=delta)
def test_get_text_width_bold(self):
font = Font("Times New Roman", True, False, 14)
self.assertAlmostEqual(39, font.get_text_width("hello") / _EMUS_PER_PX, delta=delta)
def test_get_text_width_italic(self):
font = Font("Times New Roman", False, True, 14)
self.assertAlmostEqual(37.5, font.get_text_width("hello") / _EMUS_PER_PX, delta=delta)
def test_get_text_width_bold_italic(self):
font = Font("Times New Roman", True, True, 14)
self.assertAlmostEqual(38.5, font.get_text_width("hello") / _EMUS_PER_PX, delta=delta)
def test_get_line_height_times(self):
font = Font("Times New Roman", False, False, 14)
self.assertAlmostEqual(21.4, font.get_line_height() / _EMUS_PER_PX, delta=delta)
def test_get_line_height_times_large(self):
font = Font("Times New Roman", False, False, 50)
self.assertAlmostEqual(77, font.get_line_height() / _EMUS_PER_PX, delta=delta)
def test_get_line_height_calibri(self):
font = Font("Calibri", False, False, 14)
self.assertAlmostEqual(23, font.get_line_height() / _EMUS_PER_PX, delta=delta)
def test_get_line_height_consolas(self):
font = Font("Consolas", False, False, 20)
self.assertAlmostEqual(31, font.get_line_height() / _EMUS_PER_PX, delta=delta)
def test_get_line_height_courier(self):
font = Font("Courier New", False, False, 12)
self.assertAlmostEqual(18.3, font.get_line_height() / _EMUS_PER_PX, delta=delta)
def test_is_mono_courier(self):
font = Font("Courier New", False, False, 12)
self.assertTrue(font.is_mono)
def test_is_mono_times(self):
font = Font("Times New Roman", False, False, 12)
self.assertFalse(font.is_mono)
class TestParagraphSizer(unittest.TestCase):
def setUp(self):
self._document, self._max_height, self._max_width = _create_test_document()
def test_count_lines(self):
paragraph = self._document.add_paragraph()
paragraph.add_run("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam lacinia fringilla lectus, "
"nec euismod odio convallis sed. Nunc ac libero ultricies, condimentum neque et, "
"fermentum urna. Donec feugiat diam sed nulla rutrum, sit amet accumsan odio tempor. Sed "
"bibendum ante at orci faucibus, sed dignissim nisi finibus. Vestibulum luctus eget enim et "
"mattis. In porta convallis ipsum eget dignissim. Ut orci ante, bibendum ut lorem quis, "
"gravida molestie neque. Nulla vitae sapien sed risus gravida elementum non eu lorem. "
"Quisque ac turpis nisl.")
ps = ParagraphSizer(paragraph, None, self._max_width)
self.assertEqual(7, ps.count_lines(paragraph.runs, self._max_width, paragraph.style.font, Cm(1.25)))
def test_count_lines2(self):
paragraph = self._document.add_paragraph()
paragraph.add_run("Ordered lists are useful when you want to present items in a specific order. This is additional text for illustration. Ordered lists are useful when you want to present items in a specific order. This is additional text for illustration. Ordered lists are useful when you want to present items in a specific order. This is additional text for illustration.")
ps = ParagraphSizer(paragraph, None, self._max_width)
self.assertEqual(4, ps.count_lines(paragraph.runs, self._max_width, paragraph.style.font, Cm(1.25)))
def test_count_lines_short_last_line(self):
paragraph = self._document.add_paragraph()
paragraph.add_run("Nam porta urna vel turpis lobortis, nec congue sem suscipit. Mauris ac facilisis metus, "
"non fermentum turpis. Nunc erat ipsum, interdum sit amet odio ut, vulputate feugiat arcu. "
"Donec nec rhoncus metus, nec pharetra mauris. Proin magna arcu, porta vitae eleifend et, "
"scelerisque vel nunc. Ut ut neque sed libero mattis finibus quis eu tortor. Quisque "
"molestie tempus neque rutrum vestibulum. Proin dui odio, tincidunt nec lectus at, "
"mollis tristique diam. Nulla arcu ante, fringilla sit amet pretium venenatis, ultricies a "
"elit. Sed ac velit a dolor interdum sollicitudin. Donec tortor leo, finibus eu nisi id, "
"cursus luctus diam. Vestibulum ex nulla, fringilla pellentesque diam eu, rhoncus suscipit "
"ligula. Mauris vestibulum libero erat, vitae mollis orci ultricies at. Nulla maximus "
"elementum nulla at ultrices. Vestibulum pellentesque vulputate orci, quis finibus")
ps = ParagraphSizer(paragraph, None, self._max_width)
self.assertEqual(11, ps.count_lines(paragraph.runs, self._max_width, paragraph.style.font, Cm(1.25)))
def test_count_lines_short_last_line2(self):
paragraph = self._document.add_paragraph()
paragraph.add_run("OpenAI is a leading artificial intelligence research organization, known for advancements in language models like GPT. Click the link to learn more. Hello world —")
ps = ParagraphSizer(paragraph, None, self._max_width)
self.assertEqual(3, ps.count_lines(paragraph.runs, self._max_width, paragraph.style.font, Cm(1.25)))
def test_count_lines_long_last_line(self):
paragraph = self._document.add_paragraph()
paragraph.add_run("Donec finibus elementum lectus non ultricies. Pellentesque dictum tellus a neque rutrum "
"euismod. Fusce lobortis id est ut bibendum. Integer quis nunc convallis, maximus justo "
"fermentum, vestibulum metus. Nulla fringilla quam in purus laoreet, eu rhoncus risus "
"condimentum. Sed eget odio urna. Integer mi diam, aliquam id rhoncus vitae, lacinia quis "
"augue. Nulla ultrices velit vel urna accumsan, et feugiat nunc fringilla. Praesent feugiat "
"neque ac tellus rutrum congue. Sed congue libero congue, blandit felis ac, "
"lobortis libero. Phasellus eleifend ex vulputate odio mollis dictum.")
ps = ParagraphSizer(paragraph, None, self._max_width)
self.assertEqual(7, ps.count_lines(paragraph.runs, self._max_width, paragraph.style.font, Cm(1.25)))
def test_count_lines_long_last_line2(self):
paragraph = self._document.add_paragraph()
paragraph.add_run('Markdown supports rendering mathematical formulas using LaTeX syntax. This allows you to include complex equations and mathematical notation in your documents.')
ps = ParagraphSizer(paragraph, None, self._max_width)
self.assertEqual(2, ps.count_lines(paragraph.runs, self._max_width, paragraph.style.font, Cm(1.25)))
def test_count_lines_long_last_line3(self):
paragraph = self._document.add_paragraph()
paragraph.add_run("Markdown's LaTeX syntax allows you to easily write fractions and exponents. For instance, you can represent the derivative of a function InlineFormula is not supported with respect to InlineFormula is not supported using the following notation:")
ps = ParagraphSizer(paragraph, None, self._max_width)
self.assertEqual(3, ps.count_lines(paragraph.runs, self._max_width, paragraph.style.font, Cm(1.25)))
def test_count_lines_long_word(self):
paragraph = self._document.add_paragraph()
paragraph.add_run("verylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongword")
ps = ParagraphSizer(paragraph, None, self._max_width)
self.assertEqual(3, ps.count_lines(paragraph.runs, self._max_width, paragraph.style.font, Cm(1.25)))
def test_count_lines_long_word_2(self):
paragraph = self._document.add_paragraph()
paragraph.add_run("someword verylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongwordverylongword")
ps = ParagraphSizer(paragraph, None, self._max_width)
self.assertEqual(4, ps.count_lines(paragraph.runs, self._max_width, paragraph.style.font, Cm(1.25)))
def test_count_lines_courier(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(""" table._cells[0]._element.append(paragraph_rendered_info.docx_element._element)""")
ps = ParagraphSizer(paragraph, None, self._max_width-LISTING_OFFSET)
self.assertEqual(3, ps.count_lines(paragraph.runs, self._max_width-LISTING_OFFSET, paragraph.style.font, 0))
def test_count_lines_courier2(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(
""" continuation_paragraph = Paragraph(self.parent)""")
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(1, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0))
def test_count_lines_courier3(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(
"""ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo""")
ps = ParagraphSizer(paragraph, None, self._max_width - Pt(14))
self.assertEqual(2, ps.count_lines(paragraph.runs, self._max_width - Pt(14), paragraph.style.font, 0))
def test_count_lines_courier4(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(
""" def add_link(self, text: str, url: str, is_bold: bool = None, is_italic: bool = None):""")
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(2, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0))
def test_count_lines_courier5(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(
""" self._docx_paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.EXACTLY""")
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(2, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0))
def test_count_lines_courier6(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(
""" # and "Heading" in previous_rendered.docx_element.style.name\\""")
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(2, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0))
def test_count_lines_courier7(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(
""" run = DocxRun(create_element("w:r"), self._docx_paragraph)""")
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(1, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0, True))
def test_count_lines_courier7(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(
""" # and ((min(2, height_data.lines) - 1) * height_data.line_spacing + 1) * height_data.line_height\\""")
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(2, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0, True))
def test_count_lines_courier8(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(
""" return self._docx_paragraph.paragraph_format.first_line_indent""")
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(2, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0, True))
def test_count_lines_courier9(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(
""" self._docx_paragraph.paragraph_format.first_line_indent = value""")
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(2, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0, True))
def test_count_lines_courier10(self):
paragraph = self._document.add_paragraph(style="Code")
paragraph.add_run(
""" if previous_rendered and isinstance(previous_rendered.docx_element, DocxParagraph) else None,""")
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(3, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0, True))
def test_count_lines_courier_multiple_runs(self):
paragraph = self._document.add_paragraph(style="Code")
for run_text in ['', ' ', 'run', ' ', '=', ' ', 'DocxRun', '(', 'create_element', '(', '"', 'w:r', '"', ')', ',', ' ', 'self', '.', '_docx_paragraph', ')']:
paragraph.add_run(run_text)
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(1, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0, True))
def test_count_lines_courier_multiple_runs2(self):
paragraph = self._document.add_paragraph(style="Code")
for run_text in ['', ' ', '-', '>', ' ', 'Generator', '[', 'RenderedInfo', ' ', '|', ' ', 'Renderable', ',', ' ', 'None', ',', ' ', 'None', ']', ':']:
paragraph.add_run(run_text)
ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
self.assertEqual(1, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0, True))
# def test_count_lines_courier_multiple_runs3(self):
# paragraph = self._document.add_paragraph(style="Code")
# for run_text in ['', ' ', '-', '>', ' ', 'Generator', '[', 'RenderedInfo', ' ', '|', ' ', 'Renderable', ',', ' ', 'None', ',', ' ', 'None', ']', ':']:
# paragraph.add_run(run_text)
#
# ps = ParagraphSizer(paragraph, None, self._max_width - LISTING_OFFSET)
#
# self.assertEqual(3, ps.count_lines(paragraph.runs, self._max_width - LISTING_OFFSET, paragraph.style.font, 0, True))