Skip to content

Instantly share code, notes, and snippets.

@IngoMeyer441
Last active April 22, 2026 23:00
Show Gist options
  • Select an option

  • Save IngoMeyer441/f96e9328bd2ceda10f035bb5a91e5b21 to your computer and use it in GitHub Desktop.

Select an option

Save IngoMeyer441/f96e9328bd2ceda10f035bb5a91e5b21 to your computer and use it in GitHub Desktop.
wrap_rst_table
#!/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