Skip to content

Commit ddcf7f5

Browse files
Jeremiclaude
andcommitted
feat: add Mermaid diagram support with offline rendering
- Add sphinxcontrib-mermaid extension for flowcharts and diagrams - Configure offline SVG rendering via mmdc for air-gapped builds - Add puppeteer-config.json for Chrome no-sandbox mode (Ubuntu 23.10+) - Update README with mermaid-cli setup instructions and Chrome dependencies - Add concept pages for cycles and registry with mermaid diagrams - Fix privacy wording on index.md homepage - Add sphinx-reredirects extension for URL redirects 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 5118823 commit ddcf7f5

File tree

8 files changed

+1087
-148
lines changed

8 files changed

+1087
-148
lines changed

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,44 @@ Browse the OpenSPP Documentation at https://docs.openspp.org/.
1111

1212
Active development on the OpenSPP Documentation takes place on the branch [`main`](https://github.com/openspp/documentation/).
1313

14+
## Building Documentation
15+
16+
### Quick Start
17+
18+
```bash
19+
git clone https://github.com/OpenSPP/documentation.git
20+
cd documentation
21+
make html # Build HTML docs
22+
make livehtml # Live-reload server at http://localhost:8050
23+
```
24+
25+
### Dependencies
26+
27+
- **Python 3.8+** - For Sphinx and extensions
28+
- **Graphviz** - For graph diagrams: `sudo apt install graphviz`
29+
30+
### Mermaid Diagrams (Optional)
31+
32+
The documentation uses Mermaid for flowcharts and diagrams. By default, diagrams render via CDN JavaScript.
33+
34+
For **offline/air-gapped builds**, install mermaid-cli to pre-render diagrams to SVG:
35+
36+
```bash
37+
# Install Node.js and mermaid-cli
38+
sudo apt install nodejs npm
39+
sudo npm install -g @mermaid-js/mermaid-cli
40+
41+
# Install Chrome dependencies (Ubuntu/Debian)
42+
sudo apt install -y libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
43+
libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 \
44+
libasound2t64 libpango-1.0-0 libpangocairo-1.0-0 libgtk-3-0 libx11-xcb1
45+
46+
# Build with offline mode
47+
MERMAID_OFFLINE=svg make html
48+
```
49+
50+
The build uses `docs/_static/puppeteer-config.json` to configure Chrome with `--no-sandbox` for environments where the sandbox is restricted (e.g., Ubuntu 23.10+ with AppArmor).
51+
1452
## Contribute
1553

1654
- [Contributing to OpenSPP Documentation](https://docs.openspp.org/contributing/index.html)

docs/_static/puppeteer-config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"executablePath": "",
3+
"args": ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"],
4+
"headless": true
5+
}

docs/conf.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,51 @@
158158
"sphinxcontrib.httpexample",
159159
'sphinxcontrib.googleanalytics',
160160
"sphinxcontrib.video",
161-
"sphinxext.opengraph",
162161
"sphinx.ext.viewcode",
163162
"sphinx.ext.autosummary",
164163
"sphinx.ext.graphviz",
165164
"sphinx_tabs.tabs",
166165
"notfound.extension",
166+
"sphinx_reredirects", # URL redirects for documentation restructure
167+
"cel_lexer", # Custom CEL expression syntax highlighting
168+
"sphinxcontrib.mermaid", # Mermaid diagrams (flowcharts, sequence, state)
167169
]
168170

171+
# Mermaid configuration
172+
# For offline/air-gapped builds, set MERMAID_OFFLINE=svg and install mermaid-cli:
173+
# npm install -g @mermaid-js/mermaid-cli
174+
# This will pre-render diagrams to SVG at build time (no JavaScript needed at runtime)
175+
_mermaid_offline = os.environ.get("MERMAID_OFFLINE", "") == "svg"
176+
mermaid_output_format = "svg" if _mermaid_offline else "raw"
177+
# Use puppeteer config for no-sandbox mode (required on Ubuntu 23.10+)
178+
mermaid_cmd = ["mmdc", "--puppeteerConfigFile", os.path.join(os.path.dirname(__file__), "_static/puppeteer-config.json")]
179+
mermaid_include_elk = False # Disable ELK layout to reduce dependencies
180+
mermaid_init_js = "" if _mermaid_offline else "mermaid.initialize({startOnLoad:true});"
181+
182+
# Monkeypatch sphinxcontrib.mermaid to skip JS loading in offline/SVG mode
183+
if _mermaid_offline:
184+
import sphinxcontrib.mermaid
185+
_original_install_js = sphinxcontrib.mermaid.install_js
186+
def _patched_install_js(app, pagename, templatename, context, doctree):
187+
# Skip JS installation entirely when rendering to SVG
188+
if app.config.mermaid_output_format == "svg":
189+
return
190+
return _original_install_js(app, pagename, templatename, context, doctree)
191+
sphinxcontrib.mermaid.install_js = _patched_install_js
192+
193+
# Some optional extensions depend on Pillow. In environments where Pillow cannot
194+
# be imported (for example, Python versions without compatible wheels), build
195+
# the documentation without those extensions.
196+
_pillow_available = True
197+
try:
198+
from PIL import Image # noqa: F401
199+
except Exception as exc: # pragma: no cover - build-environment dependent
200+
_pillow_available = False
201+
_logger.warning("Pillow is not available (%s). Disabling sphinxext.opengraph.", exc)
202+
203+
if _pillow_available:
204+
extensions.append("sphinxext.opengraph")
205+
169206
sphinx_tabs_disable_tab_closing = True
170207
sphinx_tabs_disable_css_loading = True
171208

@@ -218,7 +255,10 @@
218255
"**/README.rst",
219256
]
220257

221-
html_js_files = ["patch_scrollToActive.js", "search_shortcut.js"]
258+
html_js_files = [
259+
"patch_scrollToActive.js",
260+
"search_shortcut.js",
261+
]
222262

223263
html_extra_path = [
224264
"robots.txt",

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Our guiding principles are informed by the Digital Public Goods Standard and the
4141

4242
- **User-centricity**: Our products are designed to be intuitive and pragmatic, recognizing that social protection operates in complex, resource-constrained and rapidly changing contexts.
4343
- **Modularity**: The platform is composed of independent modules which allow for flexibility, scalability, and the interchangeability of components.
44-
- **Privacy and security**: We rigorously uphold privacy and security standards - essential prerequisites for safeguarding Digital Public Goods.
44+
- **Privacy and security**: We embed privacy and security best practices into the platform—protecting beneficiary data by default.
4545
- **Interoperability**: The platform is designed to support system interoperability - critical for the creation of cohesive and efficient digital ecosystems.
4646
- **Inclusivity**: Our products can be customized to suit linguistic and cultural requirements, accessibility, digital literacy, and deployment in remote and less-developed contexts.
4747

0 commit comments

Comments
 (0)