Markdown to Word Converter with Python and Pandoc

Jul 14, 2023 | Uncategorized | 0 comments

Home 9 Uncategorized 9 Markdown to Word Converter with Python and Pandoc

I’m lazy. Like every lazy person, I can dedicate a lot of time and effort to something that will allow me to stay lazy (a little counter-intuitive – I know). So what is the problem now? I like to use markdown language for all my notes, plans, documents, etc. It’s super simple and provides a nice and clear structure.

I use a highly customized open-source editor called Obsidian (I highly recommend it to everyone!) to produce all my work. It’s simple, it’s fast and I can export my Markdown docs as nicely looking PDFs with absolutely zero effort.

Today I stumbled on a “problem” ๐Ÿ™‚ I can’t include a PDF and need to send my formatted doc in an email from Outlook…
Outlook doesn’t like Markdown, and I can’t use rendered doc because it screws up the formatting.
Let’s use Python to convert it then…

I assume you have Python already installed, we need to get a couple of libraries to make our life easier:

  1. PyQt5 for creating GUI.
  2. markdown for converting markdown to HTML.
  3. pypandoc to convert HTML to Word (.docx).
Bash
pip install PyQt5
pip install markdown
pip install pypandoc

Here is a simple GUI application that does the job:

Python
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QTextEdit, QFileDialog
import markdown
import pypandoc

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Markdown to Word Converter')
        
        layout = QVBoxLayout()
        self.setLayout(layout)
        
        self.textEdit = QTextEdit()
        layout.addWidget(self.textEdit)

        self.button = QPushButton('Convert to Word')
        layout.addWidget(self.button)
        
        self.button.clicked.connect(self.convert_to_word)

    def convert_to_word(self):
        markdown_text = self.textEdit.toPlainText()
        html = markdown.markdown(markdown_text)
        
        filename, _ = QFileDialog.getSaveFileName(self, 'Save File', '', 'Word Document (*.docx)')
        if filename:
            pypandoc.convert_text(html, 'docx', format='html', outputfile=filename)

def main():
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

This script creates a simple GUI (Graphical User Interface) with a text edit area and a button. You can paste your markdown code into the text area, then click the ‘Convert to Word’ button to convert it to a Word file. A file dialog will appear for you to select the location and name of the Word file.

Please note that this is a very basic script and may not cover all edge cases or possible issues. You might want to enhance it according to your specific requirements, add an option to convert from .md file directly to .docx, etc.

If your Word doc looks like HTML code instead of a nicely formatted Word, you probably don’t have Pandoc installed. Pandoc is not the same as pypandoc Python library! You still need the tool (it’s very powerful so if you do a lot of file conversions and manipulations, I recommend you learn how to use Pandoc’s command line.

You can install it from here: https://pandoc.org/installing.html. If you’re on macOS, you can install it easily with Homebrew by running:
brew install pandoc
On Linux, you can use the package manager for your distribution.
On Windows, you can download the installer from the Pandoc website. Remember to restart your terminal window after you install it ๐Ÿ˜‰

If you’ve done everything right, you should see this window:

Yet again, laziness is the drive behind cool things ๐Ÿ˜‰
Paste your markdown code, click “Convert to Word” and save the docx file.

Join The FFF Newsletter

Future Flow Forecast

Future Flow Forecast

Joinย the number one AI newsletter and learn how to be at the forefront of the latest discoveries. This is your "dotcom bubble" chance!

You have Successfully Subscribed!