Multipurpose Markdown Maestro Python GUI

👤 Sharing: AI
import tkinter as tk
from tkinter import ttk, filedialog, scrolledtext, messagebox
import markdown
import os
import webbrowser

class MarkdownEditor:
    def __init__(self, master):
        self.master = master
        master.title("Multipurpose Markdown Maestro")
        master.geometry("800x600")

        self.filename = None

        # --- Menu Bar --- #
        self.menubar = tk.Menu(master)
        self.filemenu = tk.Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="New", command=self.new_file)
        self.filemenu.add_command(label="Open", command=self.open_file)
        self.filemenu.add_command(label="Save", command=self.save_file)
        self.filemenu.add_command(label="Save As...", command=self.save_file_as)
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Exit", command=master.quit)
        self.menubar.add_cascade(label="File", menu=self.filemenu)

        self.helpmenu = tk.Menu(self.menubar, tearoff=0)
        self.helpmenu.add_command(label="About", command=self.show_about)
        self.menubar.add_cascade(label="Help", menu=self.helpmenu)

        master.config(menu=self.menubar)

        # --- Paned Window --- #
        self.paned_window = ttk.PanedWindow(master, orient=tk.HORIZONTAL)
        self.paned_window.pack(fill=tk.BOTH, expand=True)

        # --- Markdown Input --- #
        self.markdown_input = scrolledtext.ScrolledText(self.paned_window, wrap=tk.WORD, font=("Arial", 12))
        self.paned_window.add(self.markdown_input)

        # --- HTML Preview --- #
        self.html_preview = scrolledtext.ScrolledText(self.paned_window, wrap=tk.WORD, font=("Arial", 12))
        self.html_preview.config(state=tk.DISABLED)  # Make it read-only
        self.paned_window.add(self.html_preview)

        self.paned_window.sashpos(0, 400)  # Initial sash position

        # --- Buttons Frame --- #
        self.button_frame = ttk.Frame(master)
        self.button_frame.pack(side=tk.BOTTOM, fill=tk.X, padx=5, pady=5)

        self.convert_button = ttk.Button(self.button_frame, text="Convert to HTML", command=self.convert_markdown)
        self.convert_button.pack(side=tk.LEFT, padx=5)

        self.open_in_browser_button = ttk.Button(self.button_frame, text="Open in Browser", command=self.open_in_browser)
        self.open_in_browser_button.pack(side=tk.LEFT, padx=5)

        self.details_button = ttk.Button(self.button_frame, text="Details", command=self.show_details)
        self.details_button.pack(side=tk.RIGHT, padx=5)

        # --- Status Bar --- #
        self.status_bar = tk.Label(master, text="Ready", bd=1, relief=tk.SUNKEN, anchor=tk.W)
        self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)

        # --- Bindings --- #
        self.markdown_input.bind("<KeyRelease>", self.update_preview)

    def new_file(self):
        self.markdown_input.delete("1.0", tk.END)
        self.html_preview.config(state=tk.NORMAL)
        self.html_preview.delete("1.0", tk.END)
        self.html_preview.config(state=tk.DISABLED)
        self.filename = None
        self.status_bar.config(text="New File")

    def open_file(self):
        filetypes = (("Markdown files", "*.md;*.markdown"), ("Text files", "*.txt"), ("All files", "*"))
        self.filename = filedialog.askopenfilename(filetypes=filetypes)
        if self.filename:
            try:
                with open(self.filename, "r", encoding="utf-8") as f:
                    content = f.read()
                    self.markdown_input.delete("1.0", tk.END)
                    self.markdown_input.insert("1.0", content)
                self.update_preview()
                self.status_bar.config(text=f"Opened: {self.filename}")
            except Exception as e:
                messagebox.showerror("Error", f"Could not open file: {e}")

    def save_file(self):
        if self.filename:
            try:
                with open(self.filename, "w", encoding="utf-8") as f:
                    content = self.markdown_input.get("1.0", tk.END)
                    f.write(content)
                self.status_bar.config(text=f"Saved: {self.filename}")
            except Exception as e:
                messagebox.showerror("Error", f"Could not save file: {e}")
        else:
            self.save_file_as()

    def save_file_as(self):
        filetypes = (("Markdown files", "*.md;*.markdown"), ("HTML files", "*.html"), ("Text files", "*.txt"), ("All files", "*"))
        self.filename = filedialog.asksaveasfilename(filetypes=filetypes, defaultextension=".md")
        if self.filename:
            self.save_file()

    def convert_markdown(self):
        self.save_file_as()

    def update_preview(self, event=None):
        markdown_text = self.markdown_input.get("1.0", tk.END)
        html = markdown.markdown(markdown_text)
        self.html_preview.config(state=tk.NORMAL)
        self.html_preview.delete("1.0", tk.END)
        self.html_preview.insert("1.0", html)
        self.html_preview.config(state=tk.DISABLED)

    def open_in_browser(self):
        if self.filename:
            html_content = self.html_preview.get("1.0", tk.END)
            temp_file_path = os.path.join(os.getcwd(), "temp.html")
            with open(temp_file_path, "w", encoding="utf-8") as temp_file:
                temp_file.write(html_content)
            webbrowser.open("file://" + temp_file_path)
        else:
            messagebox.showinfo("Info", "Please save the file first.")

    def show_details(self):
        details_window = tk.Toplevel(self.master)
        details_window.title("Program Details")
        details_text = scrolledtext.ScrolledText(details_window, wrap=tk.WORD, font=("Arial", 12))
        details_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        details_text.insert("1.0", self.get_details())
        details_text.config(state=tk.DISABLED)

    def show_about(self):
        messagebox.showinfo("About", "Multipurpose Markdown Maestro\nVersion 1.0\nA versatile Markdown editor with live preview and HTML conversion.")

    def get_details(self):
        details = """
        Multipurpose Markdown Maestro - Program Details

        This application provides a comprehensive Markdown editing environment with the following features:

        1.  Live Preview: As you type Markdown, the HTML preview updates in real-time.
        2.  File Management: Create, open, save, and save-as Markdown files.
        3.  HTML Conversion: Convert Markdown to HTML with a single click.
        4.  Open in Browser: Preview the generated HTML in your default web browser.
        5.  User-Friendly Interface: Intuitive GUI with a menu bar, status bar, and clearly labeled buttons.
        6.  Customizable:  Adjust the sash position to control the size of the input and preview panes.

        Key Components:

        *   Tkinter: The primary GUI framework.
        *   ttk:  Provides themed widgets for a modern look and feel.
        *   markdown:  The Python Markdown library for converting Markdown to HTML.
        *   scrolledtext:  Used for both the Markdown input and HTML preview areas, providing scrollable text boxes.
        *   webbrowser:  Opens the generated HTML in a web browser.

        Advanced Features & Considerations:

        *   Encoding:  Files are opened and saved using UTF-8 encoding to support a wide range of characters.
        *   Error Handling:  Try-except blocks are used to gracefully handle file I/O errors.
        *   Cross-Platform Compatibility:  Designed to work on Windows, macOS, and Linux.

        Potential Future Enhancements:

        *   Syntax Highlighting:  Add syntax highlighting to the Markdown input for improved readability.
        *   Themes:  Allow users to customize the application's theme.
        *   Export Options:  Support exporting to other formats, such as PDF.
        *   Enhanced Markdown Support:  Implement more advanced Markdown extensions.
        """
        return details


root = tk.Tk()
md_editor = MarkdownEditor(root)
root.mainloop()
👁️ Viewed: 8

Comments