Information Technology Grimoire

Version .0.0.1

IT Notes from various projects because I forget, and hopefully they help you too.

Python3 Python HTML Pretty

Python HTML Pretty

You paste html in one box and it prettifies it in the other.

Install the prereqs

requirements.txt

beautifulsoup4==4.12.2
bs4==0.0.1
soupsieve==2.4.1

Then python -m pip install -r requirements.txt

Main Script

import tkinter as tk
from tkinter import scrolledtext, messagebox, ttk
from bs4 import BeautifulSoup

def prettify_html():
    output_text.config(state=tk.NORMAL)
    try:
        raw_html = input_text.get("1.0", "end-1c")
        soup = BeautifulSoup(raw_html, "html.parser")
        pretty_html = soup.prettify()
        output_text.delete("1.0", tk.END)
        output_text.insert(tk.END, pretty_html)
    except Exception as e:
        messagebox.showerror("Error", str(e))
    output_text.config(state=tk.DISABLED)

def search_text(event=None):
    output_text.tag_remove("highlight", "1.0", tk.END)
    search_query = search_entry.get()
    if not search_query:
        return

    start = "1.0"
    first_occurrence = None
    while True:
        start = output_text.search(search_query, start, stopindex=tk.END, nocase=case_insensitive_var.get())
        if not start:
            break
        if not first_occurrence:
            first_occurrence = start
        end = f"{start}+{len(search_query)}c"
        output_text.tag_add("highlight", start, end)
        start = end

    output_text.tag_config("highlight", background="yellow")
    if first_occurrence:
        output_text.see(first_occurrence)

app = tk.Tk()
app.title("HTML Prettifier")
app.state('zoomed')

# Frames
input_frame = tk.Frame(app)
input_frame.pack(padx=10, pady=5, fill=tk.X, expand=False)

output_frame = tk.Frame(app)
output_frame.pack(padx=10, pady=5, fill=tk.BOTH, expand=True)

search_frame = tk.Frame(app)
search_frame.pack(padx=10, pady=5, fill=tk.X, expand=False)

# Widgets
input_label = tk.Label(input_frame, text="Paste HTML:")
input_label.pack(anchor="w")

input_text = scrolledtext.ScrolledText(input_frame, wrap=tk.WORD, height=3)
input_text.pack(fill=tk.X, expand=False)

output_label = tk.Label(output_frame, text="Prettified HTML:")
output_label.pack(anchor="w")

output_text = scrolledtext.ScrolledText(output_frame, wrap=tk.NONE, state=tk.DISABLED)
output_text.pack(fill=tk.BOTH, expand=True)

# Added a horizontal scrollbar to the output_text
xscrollbar = ttk.Scrollbar(output_frame, orient=tk.HORIZONTAL, command=output_text.xview)
xscrollbar.pack(side=tk.BOTTOM, fill=tk.X)
output_text.config(xscrollcommand=xscrollbar.set)

search_label = tk.Label(search_frame, text="Search:")
search_label.pack(side=tk.LEFT)

search_entry = ttk.Entry(search_frame)
search_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
search_entry.bind("<Return>", search_text)

case_insensitive_var = tk.IntVar()
case_insensitive_cb = ttk.Checkbutton(search_frame, text="Case Insensitive", variable=case_insensitive_var)
case_insensitive_cb.pack(side=tk.LEFT)

search_button = ttk.Button(search_frame, text="Search", command=search_text)
search_button.pack(side=tk.LEFT, padx=10)

prettify_button = ttk.Button(app, text="Prettify!", command=prettify_html)
prettify_button.pack(pady=10)

app.bind("<Control-f>", search_text)
app.mainloop()