Skip to content

Commit

Permalink
realign-spaces: align lines composed of fields separated by blankspaces
Browse files Browse the repository at this point in the history
  • Loading branch information
hydrargyrum committed Feb 13, 2025
1 parent 3363567 commit b664072
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ This repository hosts various small personal tools.
- [`r2w_plugins`](r2w_plugins): 2 rest2web plugins
- [`radiodump`](radiodump): circular buffer and dump to file
- [`random-line`](random-line): take a random line from stdin
- [`realign-spaces`](realign-spaces): align lines composed of fields separated by blankspaces
- [`realign-text-table`](realign-text-table): takes a malformed ASCII-drawn table and redraw borders properly
- [`gitlab-delete-your-comments.py`](redacting/gitlab-delete-your-comments.py): delete your own gitlab comments on issues/MRs/etc.
- [`matrix-redact-room.py`](redacting/matrix-redact-room.py): redact messages in a Matrix room of all users or a specific user (resumable)
Expand Down
74 changes: 74 additions & 0 deletions realign-spaces/realign-spaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: WTFPL

import argparse
import locale
import os
from pathlib import Path
import signal
import sys
import shlex
import shutil
import tempfile

__version__ = "0.1.0"


def process(args, splitfunc, quotefunc):
data = []
width = []
for line in args.file:
data.append([quotefunc(part) for part in splitfunc(line)])

linewidth = [len(part) for part in data[-1]]
width.extend([0] * (len(data[-1]) - len(width)))
for n, partwidth in enumerate(linewidth):
width[n] = max(width[n], partwidth)

outfile = sys.stdout
if args.inplace:
outfile = tempfile.NamedTemporaryFile("w+", encoding="utf8", dir=Path(args.file.name).parent)

for lineparts in data:
line = " ".join(f"{part:{width[n]}s}" for n, part in enumerate(lineparts))
line = line.strip()
print(line, file=outfile)

if args.inplace:
# we want to copy permissions etc. but still mark file as modified now
shutil.copystat(args.file.name, outfile.name)
os.utime(outfile.name)
os.replace(outfile.name, args.file.name)


def main():
locale.setlocale(locale.LC_ALL, "")

signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGPIPE, signal.SIG_DFL)

parser = argparse.ArgumentParser()
parser.add_argument(
"file", type=argparse.FileType(mode="r"), nargs="?", default=sys.stdin,
)
parser.add_argument("--version", action="version", version=__version__)
parser.add_argument(
"--shell-split", action="store_true",
)
parser.add_argument(
"-i", "--inplace", action="store_true",
)
args = parser.parse_args()

if args.file is sys.stdin:
args.inplace = False

with args.file:
if args.shell_split:
process(args, shlex.split, shlex.quote)
else:
process(args, str.split, str)


if __name__ == "__main__":
main()
62 changes: 62 additions & 0 deletions realign-spaces/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/sh -eu
# SPDX-License-Identifier: WTFPL
# shellcheck enable=

cd "$(dirname "$0")"

got=$(mktemp realign-spaces.XXXXXX)
trap 'rm "$got"' EXIT


init () {
./realign-spaces.py "$@" > "$got"
}

check () {
diff -u - "$got"
}


# basic test
init <<- EOF
a bbb
aaaa b
c
EOF

check <<- EOF
a bbb
aaaa b
c
EOF

# shell split
init --shell-split <<- EOF
'a b' bbb
aaa b
c
EOF

check <<- EOF
'a b' bbb
aaa b
c
EOF

# -i
cat > "$got" <<- EOF
a bbb
aaa b
c
EOF
# set a weird mode to check umask does not affect it
chmod 623 "$got"
./realign-spaces.py -i "$got"

check <<- EOF
a bbb
aaa b
c
EOF
# check our mode was preserved
ls -l "$got" | grep -q rw--w--wx

0 comments on commit b664072

Please sign in to comment.