From b821f3e3e960741b2f228fa273cd391db12d4847 Mon Sep 17 00:00:00 2001 From: benclawbot Date: Fri, 5 Jun 2026 17:05:48 +0200 Subject: [PATCH] fix(minimax-pdf): accept absolute or fractional col_widths in tables The table renderer in render_body.py treated col_widths as fractions summing to 1.0 and multiplied every value by usable_w. Passing absolute widths (which is what the SKILL.md example at the time appeared to show) silently produced a table that overflowed the page by a factor of 5-6x, clipping the leftmost columns off the page. Auto-detect the format: - If values are in [0, 1] and sum ~= 1.0, treat as fractions (recommended). - Otherwise treat as absolute widths in PDF points, clamp each to usable_w, and scale down proportionally if the total still overflows. - Emit a stderr warning when the fallback path is used so the issue is visible in build logs. Also documents the format in the SKILL.md block-types table. Reproducer: a 3-column table with col_widths: [1.0, 1.5, 4.0] previously rendered as columns of ~4.8in, 7.2in, 21.6in (sum 33.6in vs ~6in usable). After this fix, the same input renders at ~0.6in, 0.9in, 2.4in scaled to fit, with a stderr warning pointing at the recommended fractions format. --- skills/minimax-pdf/SKILL.md | 2 +- skills/minimax-pdf/scripts/render_body.py | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/skills/minimax-pdf/SKILL.md b/skills/minimax-pdf/SKILL.md index 35cfdb94..2022ec62 100644 --- a/skills/minimax-pdf/SKILL.md +++ b/skills/minimax-pdf/SKILL.md @@ -106,7 +106,7 @@ You have creative authority over the accent color. Pick it from the document's s | `bullet` | Unordered list item (• prefix) | `text` | | `numbered` | Ordered list item — counter auto-resets on non-numbered blocks | `text` | | `callout` | Highlighted insight box with accent left bar | `text` | -| `table` | Data table — accent header, alternating row tints | `headers`, `rows`, `col_widths`?, `caption`? | +| `table` | Data table — accent header, alternating row tints | `headers`, `rows`, `col_widths`?, `caption`? | `col_widths` is a list of **fractions summing to 1.0** (e.g. `[0.3, 0.5, 0.2]`). Absolute widths in PDF points are also accepted as a fallback and will be clamped to the page width. | `col_widths` is a list of **fractions summing to 1.0** (e.g. `[0.3, 0.5, 0.2]`). Absolute widths in PDF points are also accepted as a fallback and will be clamped to the page width. | | `image` | Embedded image scaled to column width | `path`/`src`, `caption`? | | `figure` | Image with auto-numbered "Figure N:" caption | `path`/`src`, `caption`? | | `code` | Monospace code block with accent left border | `text`, `language`? | diff --git a/skills/minimax-pdf/scripts/render_body.py b/skills/minimax-pdf/scripts/render_body.py index ef81de86..81331cb1 100644 --- a/skills/minimax-pdf/scripts/render_body.py +++ b/skills/minimax-pdf/scripts/render_body.py @@ -659,9 +659,28 @@ def _add_table(story: list, item: dict, ctx: dict): ] n_cols = len(item["headers"]) - # Optional col_widths as fractions summing to 1.0 + # Optional col_widths. Two formats accepted, auto-detected: + # - Fractions summing to ~1.0 (e.g. [0.3, 0.5, 0.2]) — multiplied by usable_w + # - Absolute widths in PDF points (e.g. [120, 200, 80]) — used as-is, clamped to usable_w if "col_widths" in item and len(item["col_widths"]) == n_cols: - col_w = [usable_w * f for f in item["col_widths"]] + widths = [float(f) for f in item["col_widths"]] + s = sum(widths) + all_unit_or_less = all(0 <= w <= 1.0 for w in widths) + if abs(s - 1.0) < 0.01 and all_unit_or_less: + # Fractions format + col_w = [usable_w * f for f in widths] + else: + # Absolute widths in points — clamp each to fit within usable_w + col_w = [min(w, usable_w) for w in widths] + # If the sum still exceeds usable_w, scale down proportionally + total = sum(col_w) + if total > usable_w: + col_w = [w * (usable_w / total) for w in col_w] + sys.stderr.write( + f"[minimax-pdf] table col_widths on page treating as absolute " + f"points (sum={s:.1f}); fractions summing to 1.0 are recommended. " + f"See references/design.md.\n" + ) else: col_w = [usable_w / n_cols] * n_cols