Created
June 23, 2026 15:58
-
-
Save hzxie/d2ebdbb5938f3d33ed13f2fc21f7bed9 to your computer and use it in GitHub Desktop.
Clean up WordPress-exported Markdown for Hugo (strip leftover HTML, fix images / code blocks / LaTeX)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import logging | |
| import re | |
| import sys | |
| UPLOADS_URLS = ( | |
| "https://static.infinitescript.com/wordpress/wp-content/uploads", | |
| "https://infinitescript.com/wordpress/wp-content/uploads", | |
| ) | |
| with open(sys.argv[1]) as fp: | |
| markdown = fp.read() | |
| for url in UPLOADS_URLS: | |
| markdown = markdown.replace(url, "") | |
| markdown = markdown.replace(" {}", "") | |
| markdown = markdown.replace(" ", " ") | |
| markdown = markdown.replace("<", "<") | |
| # url -> slug | |
| attr_url = re.search(r"url: \/[0-9]{4}\/[0-9]{2}\/[A-Za-z0-9\-]+", markdown) | |
| assert attr_url is not None, "post URL not found in front matter" | |
| attr_url = attr_url.group() | |
| attr_slug = attr_url[attr_url.rfind("/") + 1 :] | |
| markdown = markdown.replace(f"{attr_url}/", f"slug: {attr_slug}") | |
| # Tailing comments after heading | |
| markdown = re.sub(r" \{[#A-Za-z0-9\-]*\.wp-block-heading\}", "", markdown) | |
| # <a> | |
| hyperlinks = re.findall( | |
| r"<a [A-Za-z0-9= :#&_\"\/\.\-\?]+>[A-Za-z0-9@:_ \-\.\(\)\+]+</a>", markdown | |
| ) | |
| for hl in hyperlinks: | |
| href = re.search(r"href=\"[A-Za-z0-9= :#&_\/\.\-\?]+\"", hl).group() | |
| text = re.search(r">[A-Za-z0-9@:_ \-\.\(\)\+]+</a>", hl).group() | |
| markdown = markdown.replace(hl, f"[{text[1:-4]}]({href[6:-1]})") | |
| # <figure> | |
| figures = re.findall(r"<figure [A-Za-z0-9= :#&_\"\/\.\-\?]+>", markdown) | |
| markdown = markdown.replace("</figure>", "") | |
| for f in figures: | |
| markdown = markdown.replace(f, "") | |
| # Partial converted image | |
| md_images = re.findall(r"\[<img [A-Za-z0-9= ,:#&_\(\)\"\/\.\-\?]+>\]", markdown) | |
| for mi in md_images: | |
| img_src = re.search(r"src=\"[A-Za-z0-9_\/\-\.]+\"", mi).group() | |
| img_alt = img_src[img_src.rfind("/") + 1 : img_src.rfind(".")] | |
| markdown = markdown.replace(mi, f"![{img_alt}]") | |
| # <img> | |
| images = re.findall(r"<img [A-Za-z0-9= ,:#&_\(\)\"\/\.\-\?]+>", markdown) | |
| for i in images: | |
| img_src = re.search(r"src=\"[A-Za-z0-9\/\-\.]+\"", i).group() | |
| img_alt = img_src[img_src.rfind("/") + 1 : img_src.rfind(".")] | |
| markdown = markdown.replace(i, f"") | |
| # <pre> | |
| codes = re.findall(r"<pre [A-Za-z0-9:;= \"\-]+>", markdown) | |
| markdown = markdown.replace("</pre>", "\n```") | |
| for c in codes: | |
| language = re.search(r"language=\"[A-Za-z]+\"", c) | |
| if language is None: | |
| language = "plain" | |
| logging.warning(f"Unknown language: {c}") | |
| else: | |
| language = language.group()[10:-1] | |
| language = "plain" if language in ["generic", "raw"] else language | |
| markdown = markdown.replace(c, f"```{language}\n") | |
| # LaTeX | |
| markdown = markdown.replace(r"\displaystyle", "") | |
| latex = re.findall( | |
| r"<span class='MathJax_Preview'>[A-Za-z0-9&!_^=,;<> \[\]\|\\\(\)\{\}\+\-\*\/\.]+</span>", | |
| markdown, | |
| ) | |
| for l in latex: | |
| equation = l[32:-9] | |
| markdown = markdown.replace(l, f"${equation.strip()}$") | |
| # Dump | |
| with open(sys.argv[1], "w") as fp: | |
| fp.write(markdown) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment