import re import sys import json from datetime import datetime from pathlib import Path def parse_md(txt): """ Implementación mínima con este soporte: párrafos, encabezados, listas, cita, negrita, itálica y enlaces """ # Regex para detectar Markdown header = r"(#+)\s*(.+)" quote = r">\s*(.+)" ulist = r"[\*-]\s+" olist = r"\d\.\s+" bolditalic = r"\*\*\*([^\*]+)\*\*\*" bold = r"\*\*([^\*]+)\*\*" italic = r"\*([^\*]+)\*" link = r"\[([^\[]+)\]\(([^\(]+)\)" emdash = r"---" endash = r"--" dash = r"-" ellipsis = r"\.\.\." # Obtiene los bloques a partir de una cadena de caracteres blocks = map(lambda x: x.strip(), re.split(r"\n\s*\n", txt)) blocks = list(filter(None, blocks)) # Analiza cada bloque for i, block in enumerate(blocks): # Si es encabezado if re.match(header, block): groups = re.match(header, block).groups() tag = "h" + str(len(groups[0])) block = f"<{tag}>{groups[1]}" # Si es cita elif re.match(quote, block): groups = re.match(quote, block).groups() block = f"

{groups[0]}

" # Si es lista no ordenada elif re.match(ulist, block): items = re.sub(r"^" + ulist, "", block) items = re.split(r"\n\s*" + ulist, items) items = "".join(map(lambda x: f"
  • {x}

  • ", items)) block = f"" # Si es lista ordenada elif re.match(olist, block): items = re.sub(r"^" + olist, "", block) items = re.split(r"\n\s*" + olist, items) items = "".join(map(lambda x: f"
  • {x}

  • ", items)) block = f"
      {items}
    " # De lo contrario, se trata como párrafo else: block = f"

    {block}

    " # Limpia y aplica los estilos en línea (negritas, itálicas y enlaces) block = " ".join(block.split()) block = re.sub(bolditalic, r"\1", block) block = re.sub(bold, r"\1", block) block = re.sub(italic, r"\1", block) block = re.sub(link, r'\1', block) block = re.sub(emdash, "—", block) block = re.sub(endash, "–", block) block = re.sub(dash, "-", block) block = re.sub(ellipsis, "⁠…", block) blocks[i] = block # Une los bloques y hace limpiezas html = "\n".join(blocks) html = re.sub(r"\n
    ", "", html) return html root = Path(__file__).parent.parent about = """ Hola, soy perro tuerto. Mi formación académica es en Filosofía, mi profesión es en la edición de publicaciones (libros, fanzines, revistas…) y mi programación se enfoca en el desarrollo de metodologías libres para la publicación. Soy fan de las humanidades, la paleoantropología y las ciencias de la computación, así como soy voluntario en organizaciones sobre edición, *software* y cultura libres, como [Programando LIBREros](https://programando.li/breros), [Miau](https://t.me/miau2018), [Cuates](https://cuates.net/) o [Wikipedia](https://wikimedia.mx/). Doy soporte técnico a la [Academia Mexicana de la Lengua](https://academia.org.mx/) y puedo ayudarte en tus proyectos. **En este espacio comparto enlaces que me parecen chéveres.** """.strip() contact = { "site": "https://perrotuerto.blog", "gitlab": "https://gitlab.com/perrotuerto", "cuates": "https://git.cuates.net/perro", "wikipedia": "https://es.wikipedia.org/wiki/Usuario:Perrotuerto", "github": "https://github.com/perrotuerto", "email": "hi@perrotuerto.blog", } json_file = Path(sys.argv[1]) links = json.loads(json_file.read_text()) data = {"acerca": about, "contacto": contact, "enlaces": links["results"]} index = root / "public" / "index.html" template = (root / "src" / "template.html").read_text() body = "" for key, val in data.items(): if key == "contacto": for name, url in val.items(): template = re.sub(f"#{name.upper()}#", url, template) continue body += f'\n
    ' body += f"\n

    {key.capitalize()}

    " if isinstance(val, str): body += f"\n{parse_md(val)}" else: body += '" body += "\n
    " index.write_text(re.sub("#LINKS#", body, template)) json_file.write_text(json.dumps(data))