nixos_config/home/conf/xonsh/kittycatsay.py
2025-09-20 09:36:21 +02:00

95 lines
No EOL
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import sys
DEFAULT_CAT = r""" |、
(˚ˎ 。7 {{HBAR}}{{HBAR}}
|、˜〵
じしˍ,)"""
BOXES = {
"rounded": {
"hbar": "",
"vbar": "",
"corner_tl": "",
"corner_tr": "",
"corner_bl": "",
"corner_br": "",
"joiner": "",
}
}
def main():
parser = False
args = False
isatty = sys.stdin.isatty()
message = ""
if not isatty:
message = sys.stdin.read().strip()
if len(sys.argv) > 1:
import argparse
parser = argparse.ArgumentParser(description="Display a message in a speech bubble next to a kittycat.")
parser.add_argument("--box", type=str, choices=BOXES.keys(), default="rounded", help="The style of the speech bubble.")
parser.add_argument("-W", type=int, default=0, help="The maximum width of the message before wrapping. Defaults to terminal width minus kittycat width.")
parser.add_argument("-f", "--file", type=str, default="./kittycats/default.cat", help="The path to the kittycat file to use.")
if isatty:
parser.add_argument("message", type=str, help="The message to display.")
args = parser.parse_args()
message = args.message
else:
args = parser.parse_args()
if len(message) == 0:
message = [
"Meow.",
"We still don't support multi-line input.",
"Try a pipe why don't you?",
"Wi wi wi wi.",
"Weh weh weh.",
][int((int.from_bytes(open("/dev/urandom", "rb").read(1), "big") / 256) * 5)]
kittycat = DEFAULT_CAT
box_style = "rounded"
wrapping = 0
if args:
if os.path.isfile(args.file):
kittycat = open(args.file).read()
box_style = args.box
wrapping = args.W
outcat = get_kittycat(kittycat, message, BOXES[box_style], wrap=wrapping)
print(outcat)
def get_kittycat(cat: str, msg: str, box: dict[str, str], wrap = 0):
for kw in box.keys():
cat = cat.replace(r"{{" + kw.upper() + r"}}", box[kw])
cat_lines = cat.splitlines()
cat_width = max(len(line) for line in cat_lines)
max_msg_height = len(cat_lines) - 2
max_msg_width = os.get_terminal_size()[0] - cat_width - 2
if not wrap < max_msg_width:
raise ValueError("Wrap width exceeds maximum message width")
wrap = wrap if wrap else max_msg_width
msg = msg.replace("\n", " ")
msg_lines = []
msg_words = msg.split(" ")
while msg_words:
line = ""
while msg_words and len(line) + len(msg_words[0]) + 1 <= wrap:
line += (msg_words.pop(0) + " ")
msg_lines.append(line.rstrip())
if len(msg_lines) > max_msg_height:
raise ValueError(f"Message exceeds maximum height of {max_msg_height} given {wrap} character wrap")
longest_msg_line = max(len(line) for line in msg_lines)
msg_lines = [line.ljust(longest_msg_line) for line in msg_lines]
msg_lines = [box["joiner"] + " " + msg_lines.pop(0) + " " + box["vbar"]] + [box["vbar"] + " " + line + " " + box["vbar"] for line in msg_lines]
top_bar = box["corner_tl"] + box["hbar"] * (longest_msg_line + 2) + box["corner_tr"]
bottom_bar = box["corner_bl"] + box["hbar"] * (longest_msg_line + 2) + box["corner_br"]
msg_lines = [top_bar, *msg_lines, bottom_bar]
outcat_lines = []
for i, line in enumerate(cat_lines):
box_line = ""
if i < len(msg_lines):
box_line = msg_lines[i]
outcat_lines.append(line + box_line)
return "\n".join(outcat_lines)
if __name__ == "__main__":
main()