Mermaid | Displaying diagrams as images on a blog
def convert_mermaid_to_image(mermaid_code):
ensure_directory_exists(mermaid_output_directory)
mermaid_hash = sha256(mermaid_code.encode()).hexdigest()
image_path = os.path.join(mermaid_output_directory, f"{mermaid_hash}.png")
if not os.path.exists(image_path):
try:
process = subprocess.run([
"mmdc", "-i", "-", "-o", image_path, "-s", "10"
], input=mermaid_code, text=True, check=True)
except subprocess.CalledProcessError as e:
print(f"Error converting mermaid diagram: {e}")
return None
return image_path
New issue: we need to know what/when to run this one
2 - Where to edit?
Fortunately, convert_notebooks.py already exists and runs whenever the site is made. The following code checks each notebook for a cell beginning with “~~~mermaid”, indicating mermaid code.
for cell in notebook.cells:
if cell.cell_type == "markdown" and cell.source.startswith("~~~mermaid"):
mermaid_code = cell.source.replace("~~~mermaid", "").replace("~~~", "").strip()
image_path = convert_mermaid_to_image(mermaid_code)
3 - Displaying the image
Ok. Now we have the image of the mermaid code saved, we just need a way to display it. We can’t modify the notebook, since the mermaid code of that will need to be edited in the future. Thankfully, we have the MD files which we can modify. Easiest way is simply replacing the cell content with the path to the image, and letting the rest of the already existing convert functions to the rest of the job.
if image_path:
cell.source = f""
4 - Final Code
Putting it all together, it looks like below (with the addition of a call to process_mermaid in the main convert function):
def ensure_directory_exists(path):
os.makedirs(os.path.dirname(path), exist_ok=True)
def convert_mermaid_to_image(mermaid_code):
ensure_directory_exists(mermaid_output_directory)
mermaid_hash = sha256(mermaid_code.encode()).hexdigest()
image_path = os.path.join(mermaid_output_directory, f"{mermaid_hash}.png")
if not os.path.exists(image_path):
try:
process = subprocess.run([
"mmdc", "-i", "-", "-o", image_path, "-s", "10"
], input=mermaid_code, text=True, check=True)
except subprocess.CalledProcessError as e:
print(f"Error converting mermaid diagram: {e}")
return None
return image_path
def process_mermaid_cells(notebook):
for cell in notebook.cells:
if cell.cell_type == "markdown" and cell.source.startswith("~~~mermaid"):
mermaid_code = cell.source.replace("~~~mermaid", "").replace("~~~", "").strip()
image_path = convert_mermaid_to_image(mermaid_code)
if image_path:
cell.source = f""
A flowchart is below. Created in mermaid of course.