markdown_editor.py
# Importsfrom tkinter import *import ctypesimport re# Increas Dots Per inch so it looks sharperctypes.windll.shcore.SetProcessDpiAwareness(True)# Setuproot = Tk()root.title('Markdown Editor')root.geometry('1000x600')# Setting the Font globalyroot.option_add('*Font', 'Courier 15')def changes(event=None): display['state'] = NORMAL # Clear the Display Area display.delete(1.0, END) # Insert the content of the Edit Area into the Display Area text = editor.get('1.0', END) # Save Raw Text for later textRaw = text # Remove Unwanted Characters text = ''.join(text.split('#')) text = ''.join(text.split('*')) display.insert(1.0, text) # Loop through each replacement, unpacking it fully for pattern, name, fontData, colorData, offset in replacements: # Get the location indices of the given pattern locations = search_re(pattern, textRaw, offset) print(f'{name} at {locations}') # Add tags where the search_re function found the pattern for start, end in locations: display.tag_add(name, start, end) # Configure the tag to use the specified font and color # to this every time to delete the previous tags display.tag_config(name, font=fontData, foreground=colorData) display['state'] = DISABLEDdef search_re(pattern, text, offset): matches = [] text = text.splitlines() for i, line in enumerate(text): for match in re.finditer(pattern, line): matches.append( (f"{i + 1}.{match.start()}", f"{i + 1}.{match.end() - offset}") ) return matches# Convert an RGB tuple to a HEX string using the % Operator# 02 means print 2 characters# x means hexadecimaldef rgbToHex(rgb): return "#%02x%02x%02x" % rgb# Style SetupeditorBackground = rgbToHex((40, 40, 40))editorTextColor = rgbToHex((230, 230, 230))displayBackground = rgbToHex((60, 60, 60))displayTextColor = rgbToHex((200, 200, 200))caretColor = rgbToHex((255, 255, 255))# Width of the Textareas in characterswidth = 10# FontseditorfontName = 'Courier'displayFontName = 'Calibri'# Font SizesnormalSize = 15h1Size = 40h2Size = 30h3Size = 20# font Colorsh1Color = rgbToHex((240, 240, 240))h2Color = rgbToHex((200, 200, 200))h3Color = rgbToHex((160, 160, 160))# Replacements tell us were to insert tags with the font and colors givenreplacements = [ [ '^#[a-zA-Z\s\d\?\!\.]+$', 'Header 1', f'{displayFontName} {h1Size}', h1Color, 0 ], [ '^##[a-zA-Z\s\d\?\!\.]+$', 'Header 2', f'{displayFontName} {h2Size}', h2Color, 0 ], [ '^###[a-zA-Z\s\d\?\!\.]+$', 'Header 3', f'{displayFontName} {h3Size}', h3Color, 0 ], [ '\*.+?\*', 'Bold', f'{displayFontName} {normalSize} bold', displayTextColor, 2 ],]# Making the Editor Areaeditor = Text( root, height=5, width=width, bg=editorBackground, fg=editorTextColor, border=30, relief=FLAT, insertbackground=caretColor)editor.pack(expand=1, fill=BOTH, side=LEFT)# Bind <KeyReleas> so every change is registerededitor.bind('<KeyRelease>', changes)editor.focus_set()# Insert a starting texteditor.insert(INSERT, """#Heading 1##Heading 2###Heading 3 This is a *bold* move!- Markdown Editor -""")# Making the Display Areadisplay = Text( root, height=5, width=width, bg=displayBackground, fg=displayTextColor, border=30, relief=FLAT, font=f"{displayFontName} {normalSize}",)display.pack(expand=1, fill=BOTH, side=LEFT)# Disable the Display Area so the user cant write in it# We will have to toggle it so we can insert textdisplay['state'] = DISABLED# Starting the Applicationchanges()root.mainloop()