Created
March 7, 2025 16:38
-
-
Save kallookoo/47fa5c7755e26e652712e6b5be3093a6 to your computer and use it in GitHub Desktop.
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 python3 | |
import re | |
import argparse | |
import shutil | |
from pathlib import Path | |
def split_escaped(s, delimiter): | |
"""Split a string by a delimiter, ignoring escaped delimiters.""" | |
parts = [] | |
current = [] | |
escape = False | |
for char in s: | |
if char == '\\' and not escape: | |
escape = True | |
elif char == delimiter and not escape: | |
parts.append(''.join(current).strip()) | |
current = [] | |
else: | |
current.append(char) | |
escape = False | |
parts.append(''.join(current).strip()) | |
return parts | |
def format_table(table): | |
lines = table.strip().split('\n') | |
headers = split_escaped(lines[0], '|')[1:-1] | |
separators = split_escaped(lines[1], '|')[1:-1] | |
rows = [split_escaped(line, '|')[1:-1] for line in lines[2:]] | |
# Calculate the maximum width for each column | |
col_widths = [max(len(cell) for cell in col) for col in zip(headers, *rows)] | |
# Create a format string for each row | |
row_format = '| ' + ' | '.join(f'{{:<{width}}}' for width in col_widths) + ' |' | |
# Format the headers, separators, and rows | |
formatted_table = [ | |
row_format.format(*headers), | |
row_format.format(*['-' * width for width in col_widths]) | |
] | |
for row in rows: | |
formatted_table.append(row_format.format(*row)) | |
return '\n'.join(formatted_table) + '\n' | |
def format_markdown_tables(markdown_file, backup): | |
markdown_file = Path(markdown_file) | |
if not markdown_file.is_file(): | |
raise FileNotFoundError(f"The file '{markdown_file}' does not exist.") | |
if backup: | |
backup_file = markdown_file.with_suffix('.bak') | |
shutil.copy(markdown_file, backup_file) # Create a backup | |
if not backup_file.is_file(): | |
raise IOError(f"Failed to create backup at '{backup_file}'.") | |
with markdown_file.open('r') as file: | |
content = file.read() | |
# Find all tables in the markdown file | |
tables = re.findall(r'(\|.*?\|\n\|.*?\|\n(?:\|.*?\|\n)+)', content, re.DOTALL) | |
# Format each table | |
formatted_tables = [format_table(table) for table in tables] | |
# Replace the old tables with the formatted tables | |
for old_table, new_table in zip(tables, formatted_tables): | |
content = content.replace(old_table, new_table) | |
with markdown_file.open('w') as file: | |
file.write(content) | |
def main(): | |
parser = argparse.ArgumentParser(description='Format markdown tables in a file.') | |
parser.add_argument('markdown_file', type=str, help='Path to the markdown file') | |
parser.add_argument('--backup', action='store_true', help='Create a backup of the file before formatting') | |
args = parser.parse_args() | |
try: | |
format_markdown_tables(args.markdown_file, args.backup) | |
print(f'Tables in {args.markdown_file} have been formatted.') | |
if args.backup: | |
print(f'Backup created at {args.markdown_file}.bak') | |
except Exception as e: | |
print(f"An error occurred: {e}") | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment