[FIX] узкие колонки таблиц не растягиваются на всю ширину
This commit is contained in:
@@ -38,6 +38,11 @@ _CAPTION_RE = re.compile(r"^\s*Таблица\s+\d+\s*[—–-]+\s*(.+?)\s*$")
|
||||
# узкой колонке LaTeX не может их перенести: строка уезжает за границу колонки
|
||||
# и печатается поверх соседней.
|
||||
_LONG_WORD = 18
|
||||
|
||||
# Колонка, где самое длинное значение короче этого, в растягивании не нуждается:
|
||||
# отдав ей равную долю ширины, мы отнимаем место у колонок с текстом, и те
|
||||
# начинают переноситься по одному слову.
|
||||
_NARROW_CELL = 16
|
||||
_BREAK_AFTER = ":/_.-"
|
||||
|
||||
_ALIGN_BY_STYLE = {
|
||||
@@ -127,8 +132,14 @@ def _tabular(rows: list[list[str]], aligns: list[str]) -> str:
|
||||
row.extend([""] * (cols - len(row)))
|
||||
|
||||
spec = list(aligns[:cols]) + ["l"] * max(0, cols - len(aligns))
|
||||
stretchable = "l" in spec
|
||||
col_spec = "|".join(_STRETCH if col == "l" else col for col in spec)
|
||||
widths = [max(len(row[i]) for row in rows) for i in range(cols)]
|
||||
stretch = [
|
||||
align == "l" and width >= _NARROW_CELL for align, width in zip(spec, widths)
|
||||
]
|
||||
stretchable = any(stretch)
|
||||
col_spec = "|".join(
|
||||
_STRETCH if is_wide else col for col, is_wide in zip(spec, stretch)
|
||||
)
|
||||
|
||||
env = "tabularx" if stretchable else "tabular"
|
||||
width = "{\\textwidth}" if stretchable else ""
|
||||
|
||||
+26
-6
@@ -394,16 +394,16 @@ def test_wide_table_uses_tabularx_so_it_fits_the_page() -> None:
|
||||
|
||||
|
||||
def test_table_left_columns_become_stretchable() -> None:
|
||||
"""Растягиваются колонки с текстом; «Сценарий» короткая и остаётся узкой."""
|
||||
tex = render(WIDE_TABLE_MD)
|
||||
assert tex.count(">{\\raggedright\\arraybackslash}X") == 3
|
||||
assert tex.count(">{\\raggedright\\arraybackslash}X") == 2
|
||||
|
||||
|
||||
def test_table_keeps_center_columns_narrow() -> None:
|
||||
"""Числовые колонки не должны растягиваться — растягивается только текст."""
|
||||
tex = render(TABLE_MD)
|
||||
assert "\\begin{tabularx}{\\textwidth}" in tex
|
||||
assert tex.count(">{\\raggedright\\arraybackslash}X") == 1
|
||||
assert f"{{|{_STRETCH}|c|r|}}" in tex
|
||||
"""Все колонки короткие: растягивать нечего, таблица идёт по содержимому."""
|
||||
tex = body(render(TABLE_MD))
|
||||
assert "\\begin{tabular}{|l|c|r|}" in tex
|
||||
assert "\\begin{tabularx}" not in tex
|
||||
|
||||
|
||||
def test_table_without_left_columns_stays_plain_tabular() -> None:
|
||||
@@ -440,3 +440,23 @@ def test_break_points_do_not_touch_latex_commands() -> None:
|
||||
)
|
||||
assert "\\textbf{" in tex
|
||||
assert "\\textbf\\allowbreak" not in tex
|
||||
|
||||
|
||||
MIXED_WIDTH_TABLE_MD = (
|
||||
"| Сценарий | Что делает |\n"
|
||||
"| :--- | :--- |\n"
|
||||
"| build.yml | Собирает образ Docker целиком и публикует его в реестр |\n"
|
||||
"| test.yml | Собирает проект через CMake и прогоняет набор тестов |\n"
|
||||
)
|
||||
|
||||
|
||||
def test_narrow_column_is_not_stretched() -> None:
|
||||
"""Колонка из коротких значений не должна занимать половину ширины."""
|
||||
tex = body(render(MIXED_WIDTH_TABLE_MD))
|
||||
assert f"{{|l|{_STRETCH}|}}" in tex
|
||||
|
||||
|
||||
def test_all_short_columns_stay_plain_tabular() -> None:
|
||||
tex = body(render("| a | b |\n| :--- | :--- |\n| ping | сервер |\n"))
|
||||
assert "\\begin{tabular}{|l|l|}" in tex
|
||||
assert "\\begin{tabularx}" not in tex
|
||||
|
||||
Reference in New Issue
Block a user