Procesar Markdown con Python: Convertir, Analizar y Generar
Markdown es el formato de escritura más popular para documentación técnica, READMEs y blogs. Python ofrece varias librerías para convertir Markdown a HTML, PDF y otros formatos.
Instalación
pip install markdown mistune python-markdown2 weasyprint
Markdown a HTML con markdown
import markdown
# Conversión básica
texto_md = """
# Título Principal
Este es un párrafo con **negrita** e *itálica*.
## Lista de características
- Fácil de aprender
- Compatible con muchos editores
- Exportable a múltiples formatos
```python
print("Hola mundo")
"""
html = markdown.markdown(texto_md, extensions=["fenced_code", "tables", "toc"]) print(html)
Guardar en archivo
with open("documento.html", "w", encoding="utf-8") as f: f.write(f"
{html}") print("HTML generado: documento.html")
## Extensiones de Markdown
```python
import markdown
def md_a_html_completo(md_path, html_path, titulo="Documento"):
with open(md_path, encoding="utf-8") as f:
contenido = f.read()
md = markdown.Markdown(extensions=[
"fenced_code", # Bloques de código con ```
"codehilite", # Resaltado de sintaxis
"tables", # Tablas tipo GFM
"toc", # Tabla de contenidos
"meta", # Metadatos YAML al inicio
"nl2br", # Saltos de línea como <br>
"footnotes", # Notas al pie
])
cuerpo = md.convert(contenido)
toc = md.toc # Tabla de contenidos HTML
html = f"""<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>{titulo}</title>
<style>
body {{ font-family: Georgia, serif; max-width: 800px; margin: 0 auto; padding: 2em; }}
pre {{ background: #f4f4f4; padding: 1em; border-radius: 4px; overflow-x: auto; }}
code {{ font-family: monospace; }}
table {{ border-collapse: collapse; width: 100%; }}
th, td {{ border: 1px solid #ddd; padding: 8px; }}
</style>
</head>
<body>
<nav>{toc}</nav>
{cuerpo}
</body>
</html>"""
with open(html_path, "w", encoding="utf-8") as f:
f.write(html)
print(f"HTML generado: {html_path}")
md_a_html_completo("README.md", "README.html", "Documentación del Proyecto")
Markdown a PDF
import markdown
from weasyprint import HTML
def md_a_pdf(md_path, pdf_path):
with open(md_path, encoding="utf-8") as f:
contenido = f.read()
html_body = markdown.markdown(contenido, extensions=["tables", "fenced_code", "toc"])
html_full = f"""
<html><head>
<meta charset="utf-8">
<style>
body {{ font-family: Arial, sans-serif; font-size: 12pt; }}
pre {{ background: #f0f0f0; padding: 8px; font-size: 10pt; }}
h1 {{ color: #333; border-bottom: 2px solid #333; }}
h2 {{ color: #555; }}
table {{ border-collapse: collapse; }}
td, th {{ border: 1px solid #ccc; padding: 6px; }}
</style></head>
<body>{html_body}</body></html>
"""
HTML(string=html_full).write_pdf(pdf_path)
print(f"PDF generado: {pdf_path}")
md_a_pdf("documento.md", "documento.pdf")
Extraer Headings y Estructura
import re
def extraer_estructura(md_path):
with open(md_path, encoding="utf-8") as f:
lineas = f.readlines()
estructura = []
for linea in lineas:
m = re.match(r'^(#{1,6})\s+(.+)', linea)
if m:
nivel = len(m.group(1))
titulo = m.group(2).strip()
estructura.append((nivel, titulo))
print(" " * (nivel-1) + f"H{nivel}: {titulo}")
return estructura
extraer_estructura("documentacion.md")
Convertir Directorio de Markdown a HTML
import markdown
from pathlib import Path
def convertir_directorio_md(carpeta_entrada, carpeta_salida):
Path(carpeta_salida).mkdir(exist_ok=True)
md_files = list(Path(carpeta_entrada).rglob("*.md"))
for i, md_file in enumerate(md_files, 1):
with open(md_file, encoding="utf-8") as f:
html = markdown.markdown(f.read(), extensions=["tables", "fenced_code"])
html_file = Path(carpeta_salida) / (md_file.stem + ".html")
with open(html_file, "w", encoding="utf-8") as f:
f.write(f"<html><body>{html}</body></html>")
print(f" [{i}/{len(md_files)}] {md_file.name} -> {html_file.name}")
print(f"Convertidos {len(md_files)} archivos")
convertir_directorio_md("docs/", "docs_html/")
Recurso Adicional
Para convertir archivos Markdown a PDF, HTML o DOCX sin instalar nada, usa KaijuConverter — gratis y sin registro.
Conversiones relacionadas
Conversiones de documento que siguen este tema: