Last active
April 22, 2026 23:00
-
-
Save IngoMeyer441/f96e9328bd2ceda10f035bb5a91e5b21 to your computer and use it in GitHub Desktop.
wrap_rst_table
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| import sys | |
| import textwrap | |
| WRAP_WIDTH = 120 | |
| def split_line(line): | |
| stripped = line.lstrip() | |
| prefix_len = len(line) - len(stripped) | |
| core = stripped.rstrip() | |
| suffix_len = len(stripped) - len(core) | |
| prefix = line[:prefix_len] | |
| suffix = stripped[len(core) :] | |
| return prefix, core, suffix | |
| def parse_row_block(block): | |
| rows = [line.strip()[1:-1].split("|") for line in block] | |
| num_cols = len(rows[0]) | |
| cols = [[] for _ in range(num_cols)] | |
| for row in rows: | |
| for col, cell in zip(cols, row): | |
| col.append(cell.rstrip()) | |
| return [" ".join(c.strip() for c in col if c.strip()) for col in cols] | |
| def wrap_cells(cells, col_widths): | |
| wrapped = [] | |
| for col_width, cell in zip(col_widths, cells): | |
| width = col_width - 2 | |
| lines = textwrap.wrap(cell, width=width, break_long_words=True, break_on_hyphens=False) or [""] | |
| wrapped.append(lines) | |
| max_lines = max(len(c) for c in wrapped) | |
| for col in wrapped: | |
| col += [""] * (max_lines - len(col)) | |
| return wrapped | |
| def format_row(wrapped_cols, col_widths, prefix="", suffix=""): | |
| lines = [] | |
| height = len(wrapped_cols[0]) | |
| for i in range(height): | |
| parts = [] | |
| for col_width, col in zip(col_widths, wrapped_cols): | |
| content = col[i] | |
| parts.append(" " + content.ljust(col_width - 1)) | |
| lines.append(prefix + "|" + "|".join(parts) + "|" + suffix) | |
| return lines | |
| def compute_last_col_width(col_widths, target_width): | |
| borders = len(col_widths) + 1 | |
| other = sum(col_widths[:-1]) | |
| return max(5, target_width - (other + borders)) | |
| def split_fragment_blocks(lines): | |
| blocks = [] | |
| current = [] | |
| for line in lines: | |
| stripped_line = line.strip() | |
| if stripped_line.startswith("+"): | |
| if current: | |
| blocks.append(current) | |
| current = [] | |
| blocks.append(line) # keep separator | |
| elif stripped_line.startswith("|"): | |
| current.append(stripped_line) | |
| if current: | |
| blocks.append(current) | |
| return blocks | |
| def reformat_fragment(lines, wrap_width): | |
| first_line = next(l for l in lines if "|" in l) | |
| prefix, core, suffix = split_line(first_line) | |
| parts = core[1:-1].split("|") | |
| col_widths = [len(p) for p in parts] | |
| col_widths[-1] = compute_last_col_width(col_widths, wrap_width) | |
| blocks = split_fragment_blocks(lines) | |
| output = [] | |
| for block in blocks: | |
| if isinstance(block, str): | |
| output.append(block) | |
| else: | |
| cells = parse_row_block(block) | |
| wrapped = wrap_cells(cells, col_widths) | |
| output.extend(format_row(wrapped, col_widths, prefix, suffix)) | |
| return output | |
| def reformat_table(table_text, wrap_width): | |
| lines = table_text.strip("\n").splitlines() | |
| return "\n".join(reformat_fragment(lines, wrap_width)) | |
| def main(): | |
| print(reformat_table(sys.stdin.read(), wrap_width=WRAP_WIDTH)) | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment