Last active
March 13, 2024 00:25
-
-
Save marcusmueller/d65a08b88cd465d1b42439ad1986a920 to your computer and use it in GitHub Desktop.
Justify a text using Python
This file contains 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 | |
# SPDX-License-Identifier: GPL-3.0 | |
# | |
# Title: Justify text | |
# Author: Marcus Müller | |
# Copyright: 2024 | |
# | |
# Usage: justify.py [width [file1] [file2] [file…]] | |
# | |
# if no files are specified, read from standard input | |
# if no width is specified, default to 90 | |
import textwrap | |
import sys | |
import random | |
from typing import TextIO | |
def reflow_file(file_in: [str, TextIO], wrapper: textwrap.TextWrapper): | |
random.seed(42) | |
if type(file_in) is str: | |
file_in = open(file_in, "r", encoding="utf-8") | |
lines = wrapper.wrap(file_in.read()) | |
lines_out = [] | |
for lineno, line in enumerate(lines): | |
if len(line) < wrapper.width and lineno != len(lines) - 1: | |
words = line.split() | |
spaces = len(words) - 1 | |
if spaces > 0: | |
deficit = wrapper.width - len(line) | |
if deficit >= spaces: | |
# we have more deficit than spaces | |
# so add to each word | |
n_add = deficit // spaces | |
words = [word + " " * n_add for word in words] | |
deficit = deficit - n_add * spaces | |
choices = set(random.sample(range(spaces), k=deficit)) | |
words_out = [] | |
for idx, word in enumerate(words): | |
words_out.append(word) | |
if idx in choices: | |
words_out.append("") | |
line = " ".join(words_out) | |
lines_out.append(line) | |
return "\n".join(lines_out) | |
if len(sys.argv) < 2: | |
width = 90 | |
files = [sys.stdin] | |
elif len(sys.argv) < 3: | |
width = int(sys.argv[1]) | |
files = [sys.stdin] | |
else: | |
width = int(sys.argv[1]) | |
files = sys.argv[2:] | |
# set up the Text Wrapper. Add break_on_hyphens=False to the following | |
# arguments should you not want to allow breaking at every "-". | |
wrapper = textwrap.TextWrapper(width=width, tabsize=4) | |
lines = (reflow_file(f, wrapper) for f in files) | |
print("\n".join(lines)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment