Skip to content

Commit

Permalink
Added support for using native .drawio files within .md files
Browse files Browse the repository at this point in the history
  • Loading branch information
aldelucaizs committed Feb 25, 2025
1 parent 1532a8a commit d5bd91c
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 18 deletions.
73 changes: 56 additions & 17 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
# Use Python 3.9 as the base image
FROM python:3.9-slim
FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive
ENV DRAWIO_VERSION=26.0.9

# Set the working directory
WORKDIR /app

# Install system dependencies for WeasyPrint
# Install system dependencies for WeasyPrint and Draw.io
RUN apt-get update && \
apt-get install -y \
apt-get install -y --no-install-recommends \
build-essential \
libpango1.0-0 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libcairo2 \
libgdk-pixbuf2.0-0 \
libffi-dev \
shared-mime-info \
libjpeg62-turbo \
libjpeg-turbo8 \
libpng-dev \
libxml2-dev \
libxslt1-dev \
Expand All @@ -27,20 +30,32 @@ RUN apt-get update && \
plantuml \
wget \
unzip \
xvfb \
dbus \
dbus-x11 \
libgtk-3-0 \
libxtst6 \
libnss3 \
libasound2t64 \
libxss1 \
libgbm1 \
ca-certificates \
libnotify4 \
xdg-utils \
libsecret-1-0 \
graphviz \
&& apt-get clean

# Detect architecture and install the correct version of Pandoc
RUN apt-get update && apt-get install -y wget && apt-get clean && \
wget https://github.com/jgm/pandoc/releases/download/2.5/pandoc-2.5-linux.tar.gz && \
tar xvfz pandoc-2.5-linux.tar.gz && \
mv pandoc-2.5/bin/pandoc /usr/local/bin/ && \
mv pandoc-2.5/bin/pandoc-citeproc /usr/local/bin/ && \
rm -rf pandoc-2.5 pandoc-2.5-linux.tar.gz;
# Install Python and pip
RUN apt-get update && apt-get install -y python3 python3-pip python3-venv && apt-get clean

# Create a virtual environment
RUN python3 -m venv /venv

# Install MkDocs and the specified plugins and extensions
RUN pip install --no-cache-dir mkdocs==1.2.4 \
# Activate the virtual environment and install dependencies
RUN /venv/bin/pip install --no-cache-dir mkdocs==1.2.4 \
mkdocs-izsam-search==0.1.8 \
mkdocs-bionformatic-izsam-theme==1.0.4 \
mkdocs-bionformatic-izsam-theme==1.0.5 \
mkdocs-izsam-video==1.0.3 \
mkdocs-redirects==1.2.0 \
mkdocs-izsam-mermaid-to-images==1.0.8 \
Expand All @@ -52,14 +67,38 @@ RUN pip install --no-cache-dir mkdocs==1.2.4 \
qrcode==7.3.1 \
weasyprint==62.3

# Ensure the virtual environment is activated when running commands
ENV PATH="/venv/bin:$PATH"

# Copy the bin folder (including sh directory) into the Docker image
COPY . /app

RUN pip install -e /app/plugins/custom
# Install custom plugins
RUN /venv/bin/pip install -e /app/plugins/custom

# Set the working directory back to /app
WORKDIR /app

# Detect architecture and install the correct version of Pandoc
RUN apt-get update && \
apt-get install -y wget && \
apt-get clean && \
wget https://github.com/jgm/pandoc/releases/download/2.5/pandoc-2.5-linux.tar.gz && \
tar xvfz pandoc-2.5-linux.tar.gz && \
mv pandoc-2.5/bin/pandoc /usr/local/bin/ && \
mv pandoc-2.5/bin/pandoc-citeproc /usr/local/bin/ && \
rm -rf pandoc-2.5 pandoc-2.5-linux.tar.gz

# Install draw.io
RUN wget -q https://github.com/jgraph/drawio-desktop/releases/download/v${DRAWIO_VERSION}/drawio-amd64-${DRAWIO_VERSION}.deb && \
dpkg -i drawio-amd64-${DRAWIO_VERSION}.deb || apt-get -f install -y && \
rm -f drawio-amd64-${DRAWIO_VERSION}.deb

# Copy draw.io conversion script
COPY bin/sh/drawio-converter.sh /usr/local/bin/drawio-converter
# Ensure it is executable
RUN chmod +x /usr/local/bin/drawio-converter

# Ensure the entrypoint.sh file has the correct permissions to be executed
RUN chmod +x /app/entrypoint.sh

Expand Down
14 changes: 14 additions & 0 deletions bin/sh/drawio-converter.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

# Start dbus if not already running
if [ ! -e /var/run/dbus/pid ]; then
mkdir -p /var/run/dbus
dbus-daemon --system --fork
fi

if [ "$1" = "-x" ] && [ "$2" = "-f" ] && [ -n "$3" ] && [ "$4" = "-o" ] && [ -n "$5" ] && [ -n "$6" ]; then
dbus-run-session -- xvfb-run drawio --no-sandbox -x -f "$3" -o "$5" "$6" --disable-gpu
exit $?
else
dbus-run-session -- xvfb-run drawio --no-sandbox "$@"
fi
5 changes: 5 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,9 @@ if [ "$1" = "build" ]; then
echo "#####################################################################"
else
exec "$@"
fi

# Ensure draw.io script is executable
if [ ! -x /usr/local/bin/drawio-converter ]; then
chmod +x /usr/local/bin/drawio-converter
fi
26 changes: 26 additions & 0 deletions plugins/init/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@

The `main.py` file collect all macros available to be used inside Mkdocs file (docs, themes, configuration). Available macros:

### def drawio_export(drawio_file, alt="drawio diagram", fmt=None)

Convert a .drawio file to an image (SVG/PNG/etc.) via drawio-converter CLI.

#### Args

* `drawio_file (str)`: The path to the .drawio file.
* `alt (str)`: The alt text for the image. Defaults to "drawio diagram".
* `fmt (str, optional)`: The format of the output image (e.g., "svg", "png"). Defaults to the value specified in the MkDocs configuration (`extra.drawio_output_format`). If not specified in the configuration, defaults to "svg".

#### Returns

```html
<img src="{relative_out_path}" class="drawio" alt="{alt}" />
```

#### How to use

To be used inside `.md` files with the following syntax:

```markdown
{{ drawio_export("diagram.drawio") }}
{{ drawio_export("diagram.drawio", "some alt text") }}
{{ drawio_export("diagram.drawio", "some alt text", "png") }}
```

### def button(text, link)

Generates HTML code for a button that opens a link in a new window.
Expand Down
69 changes: 68 additions & 1 deletion plugins/init/main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,75 @@
import markdown
import os
import markdown
import shutil
import subprocess
from pathlib import Path

def define_env(env):

@env.macro
def drawio_export(drawio_file, alt="drawio diagram", fmt=None):
"""
Convert a .drawio file to an image (SVG/PNG/etc.) via drawio-converter CLI.
This macro uses an extra configuration parameter in mkdocs.yml:
extra:
drawio_output_format: svg
or in your PDF config:
extra:
drawio_output_format: png
Usage:
{{ drawio_export("diagram.drawio") }}
{{ drawio_export("diagram.drawio", "some alt text") }}
{{ drawio_export("diagram.drawio", "some alt text", "png") }}
"""
if not env.page:
return f"Error: No page context for {drawio_file}"

# Read default format from mkdocs config, fallback to 'svg' if not found
config_default_format = env.conf.get("extra", {}).get("drawio_output_format", "svg")

# If caller didn't supply a format, use the config default
if fmt is None:
fmt = config_default_format

# If neither the config nor the caller supplied a format, use 'svg' as the default
if fmt is None:
fmt = "svg"

# Directory of the .md file being processed
page_dir = Path(env.page.file.abs_src_path).parent

# Full path to the .drawio file
src_path = page_dir / drawio_file
if not src_path.is_file():
return f"Error: {drawio_file} not found at {src_path}"

# Output directory under site_dir relative to the current page
output_dir = Path(env.conf['site_dir']) / Path(env.page.url).parent / 'drawio'
output_dir.mkdir(parents=True, exist_ok=True)
final_out_path = output_dir / (src_path.stem + f".{fmt}")

# Run drawio-converter
try:
result = subprocess.run([
"drawio-converter",
"-x", # export
"-f", fmt, # format
"-o", str(final_out_path),
str(src_path)
], check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as e:
return f"Error: Conversion failed for {drawio_file}. {e}"

# Verify output actually got created
if not final_out_path.exists():
return f"Error: {final_out_path.name} was not created."

# Return relative path from the page's directory
relative_out_path = final_out_path.relative_to(Path(env.conf['site_dir']) / Path(env.page.url).parent)
return f'<img src="{relative_out_path}" class="drawio" alt="{alt}" />'

@env.macro
def button(text, link):
"""
Expand Down

0 comments on commit d5bd91c

Please sign in to comment.