commit ede3d39dd5fcb8d88c50437fdeabfd8fcf5c3cbc Author: Jan-Erik Rediger Date: Tue Oct 29 19:27:39 2024 +0100 import texttools, python version diff --git a/texttools.py b/texttools.py new file mode 100755 index 0000000..c784496 --- /dev/null +++ b/texttools.py @@ -0,0 +1,85 @@ +#!/usr/bin/env -S uv run python3 +import tkinter as tk +from tkinter import N, S, E, W, ttk +import textwrap + + +# Complex transforms go here, +# Simple transforms are just lambdas +def _wordcount(s: str): + "Returns a tuple of linecount, wordcount, charcount" + return (len(s.splitlines()), len(s.split()), len(s)) + + +def _markdown_quote(s: str): + "Returns every line prefixed with >" + return "\n".join(["> " + line for line in s.splitlines()]) + +transforms = [ + # Transforms go here, for example + {"name": "One line", "transform": lambda x: " ".join(x.splitlines())} + ,{"name": "Line/Word/Char", "transform": _wordcount} + ,{"name": "Dedent", "transform": textwrap.dedent} + ,{"name": "Markdown Quote", "transform": _markdown_quote} + ] + +class GUI(): + def __init__(self) -> None: + self.root = tk.Tk() + self.active_transform = lambda x: x # start with no transform + self.layout_gui() + + + def layout_gui(self) -> None: + self.mainframe = ttk.Frame(self.root, padding="3 3 12 12") + + self.root.title("Text Tools") + self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) + self.root.columnconfigure(0, weight=1) + self.root.rowconfigure(0, weight=1) + self.content_box = tk.Text(self.mainframe, undo=True) + self.content_box.grid(column=2, row=2) + + self.output_box = tk.Text(self.mainframe, undo=True) + self.output_box.grid(column=2, row=3) + + self.transform_box = tk.Listbox(self.mainframe) + self.transform_box.grid(column=1, row=2, rowspan=2) + for t in transforms: + self.transform_box.insert(tk.END, t["name"]) + + # Keyboard bindings + self.root.bind("", lambda _: self.root.quit()) + self.content_box.bind("", lambda _: self.transform_box.focus()) + + # vvv makes clicking or pressing enter change the transform + self.transform_box.bind("", self.select_transform) + self.transform_box.bind("", self.select_transform) + + # vvv makes anything typed in update the output + self.content_box.bind("", + lambda _: self.root.after(1, self.update)) + + self.content_box.focus() + + def update(self): + content = self.content_box.get('1.0', tk.END) + content = self.active_transform(content) + self.output_box.delete('1.0', tk.END) + self.output_box.insert('1.0', content) + + def select_transform(self, _): + try: + selection = self.transform_box.curselection()[0] + self.active_transform = transforms[selection]["transform"] + self.update() + except (ValueError, IndexError): + pass + +def main(): # Entry point for pyproject.toml + gui = GUI() + gui.root.mainloop() + +if __name__ == "__main__": + main() +