[FIX] узкие колонки таблиц не растягиваются на всю ширину
This commit is contained in:
@@ -38,6 +38,11 @@ _CAPTION_RE = re.compile(r"^\s*Таблица\s+\d+\s*[—–-]+\s*(.+?)\s*$")
|
|||||||
# узкой колонке LaTeX не может их перенести: строка уезжает за границу колонки
|
# узкой колонке LaTeX не может их перенести: строка уезжает за границу колонки
|
||||||
# и печатается поверх соседней.
|
# и печатается поверх соседней.
|
||||||
_LONG_WORD = 18
|
_LONG_WORD = 18
|
||||||
|
|
||||||
|
# Колонка, где самое длинное значение короче этого, в растягивании не нуждается:
|
||||||
|
# отдав ей равную долю ширины, мы отнимаем место у колонок с текстом, и те
|
||||||
|
# начинают переноситься по одному слову.
|
||||||
|
_NARROW_CELL = 16
|
||||||
_BREAK_AFTER = ":/_.-"
|
_BREAK_AFTER = ":/_.-"
|
||||||
|
|
||||||
_ALIGN_BY_STYLE = {
|
_ALIGN_BY_STYLE = {
|
||||||
@@ -127,8 +132,14 @@ def _tabular(rows: list[list[str]], aligns: list[str]) -> str:
|
|||||||
row.extend([""] * (cols - len(row)))
|
row.extend([""] * (cols - len(row)))
|
||||||
|
|
||||||
spec = list(aligns[:cols]) + ["l"] * max(0, cols - len(aligns))
|
spec = list(aligns[:cols]) + ["l"] * max(0, cols - len(aligns))
|
||||||
stretchable = "l" in spec
|
widths = [max(len(row[i]) for row in rows) for i in range(cols)]
|
||||||
col_spec = "|".join(_STRETCH if col == "l" else col for col in spec)
|
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"
|
env = "tabularx" if stretchable else "tabular"
|
||||||
width = "{\\textwidth}" if stretchable else ""
|
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:
|
def test_table_left_columns_become_stretchable() -> None:
|
||||||
|
"""Растягиваются колонки с текстом; «Сценарий» короткая и остаётся узкой."""
|
||||||
tex = render(WIDE_TABLE_MD)
|
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:
|
def test_table_keeps_center_columns_narrow() -> None:
|
||||||
"""Числовые колонки не должны растягиваться — растягивается только текст."""
|
"""Все колонки короткие: растягивать нечего, таблица идёт по содержимому."""
|
||||||
tex = render(TABLE_MD)
|
tex = body(render(TABLE_MD))
|
||||||
assert "\\begin{tabularx}{\\textwidth}" in tex
|
assert "\\begin{tabular}{|l|c|r|}" in tex
|
||||||
assert tex.count(">{\\raggedright\\arraybackslash}X") == 1
|
assert "\\begin{tabularx}" not in tex
|
||||||
assert f"{{|{_STRETCH}|c|r|}}" in tex
|
|
||||||
|
|
||||||
|
|
||||||
def test_table_without_left_columns_stays_plain_tabular() -> None:
|
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{" in tex
|
||||||
assert "\\textbf\\allowbreak" not 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