2 min read

Markdown to HTML Converter

This utility converts Markdown files (.md) into HTML files using the markdown library. It supports standard Markdown syntax and can optionally wrap the output in a full HTML document structure with CSS support.

Modules Used:

  • markdown: To parse Markdown text and convert it to HTML.
  • argparse: To handle command-line arguments.
  • pathlib: For file path manipulation.

Installation

pip install markdown

The Code

Save this as md_to_html.py.

import markdown
import argparse
from pathlib import Path

def convert_md_to_html(input_file, output_file, full_document=False, css_file=None):
    input_path = Path(input_file)

    if not input_path.exists():
        print(f"Error: Input file '{input_file}' not found.")
        return

    # Read Markdown content
    try:
        text = input_path.read_text(encoding='utf-8')
    except Exception as e:
        print(f"Error reading file: {e}")
        return

    # Convert to HTML
    # 'extra' extension adds support for tables, footnotes, fenced code blocks, etc.
    html_body = markdown.markdown(text, extensions=['extra'])

    final_html = html_body

    # Wrap in full HTML structure if requested
    if full_document:
        css_link = ""
        if css_file:
            css_link = f'<link rel="stylesheet" href="{css_file}">'

        final_html = f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{input_path.stem}</title>
    {css_link}
    <style>
        body {{ font-family: sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; line-height: 1.6; }}
        pre {{ background: <a href='/?search=%23f4f4f4' class='obsidian-tag'>#f4f4f4</a>; padding: 10px; border-radius: 5px; overflow-x: auto; }}
        code {{ background: <a href='/?search=%23f4f4f4' class='obsidian-tag'>#f4f4f4</a>; padding: 2px 5px; border-radius: 3px; }}
        table {{ border-collapse: collapse; width: 100%; }}
        th, td {{ border: 1px solid <a href='/?search=%23ddd' class='obsidian-tag'>#ddd</a>; padding: 8px; }}
        th {{ background-color: <a href='/?search=%23f2f2f2' class='obsidian-tag'>#f2f2f2</a>; }}
    </style>
</head>
<body>
{html_body}
</body>
</html>"""

    # Determine output path
    if output_file:
        out_path = Path(output_file)
    else:
        out_path = input_path.with_suffix('.html')

    # Write to file
    try:
        out_path.write_text(final_html, encoding='utf-8')
        print(f"Successfully converted '{input_file}' to '{out_path}'")
    except Exception as e:
        print(f"Error writing output: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Markdown to HTML Converter")
    parser.add_argument("input", help="Input Markdown file")
    parser.add_argument("-o", "--output", help="Output HTML file (default: same name as input)")
    parser.add_argument("--full", action="store_true", help="Generate a full HTML document (with <head> and <body>)")
    parser.add_argument("--css", help="Path to a CSS file to link (requires --full)")

    args = parser.parse_args()

    convert_md_to_html(args.input, args.output, args.full, args.css)

Usage

# Basic conversion (fragment only)
python md_to_html.py README.md

# Full HTML document with default styling
python md_to_html.py README.md --full

# Full HTML with custom CSS
python md_to_html.py README.md --full --css styles.css

programming/python/python