2025-08-30/31_sphinx_migration#
Datum: 2025‑08‑30 & 31 Författare: Carl & AI‑agent
Sammanfattning: Installerade Sphinx för första gången (appen där du läser detta) - det var för mycket motvind att göra vissa saker med Mkdocs så byte till Sphinx kändes befogat, och kul att testa något nytt - nu visas lekmannakommentarerna bra mycket bättre än tidigare. Se bild nedan för skillnaderna i Mkdocs avseende beskärd visning av högerpanelen - Mkdocs gillar inte att man pillar i det; Spinx är mer medgörligt, och kan passa syftet något bättre på sikt då det har litet fördelar vad gäller generera fram all dokumentation som nedladdningsbar pdf och så vidare.
Skärmklipp: Chrome vs Firefox#
Följande skärmklipp visar rendering i en Chrome‑baserad webbläsare (övre) och en Firefox‑baserad (nedre).
Chrome‑baserad rendering

Firefox‑baserad rendering

Sammanfattad kronologi (snabböversikt)#
2025-08-30 → 2025-08-31: Initial migrering från MkDocs till Sphinx. Bytte tema, implementerade layout för kod+kommentarer och skapade grundläggande Sphinx extensions (inkl. custom
code_comments).2025-08-31:
Dokumenterade tekniska val, mapping‑spec och problem i denna journal (detaljer nedan).
Snabba operationer för att stabilisera navigationen:
Removed generated nested
index/index.rstsom överskuggade vår master‑index.Uppdaterade nav‑konverteringsskriptet så det inte genererar top‑level
index.Flyttade
docs_sphinx/source/app→docs_sphinx/source/_app_backupför att eliminera dubbletter (app/vssrc/app/).Regenererade nav‑stubbar och byggde HTML för att verifiera förändringar.
Senaste åtgärder (kort)#
Uppdaterade
conf.pyför att undvika att copy‑hook skriver över handkuraterade.rst-filer och för att exkludera temporära backup‑mappar från bygget.Lagt till hjälpskript:
scripts/convert_mkdocs_nav_to_sphinx.py— genererartoctree‑stubbar frånmkdocs.yml.scripts/convert_mermaid_fences.py— konverterar fencedmermaidtill Sphinx.. mermaid::direktiv.
Skapade
DOCS_MIGRATION_TODO.mdi repo‑roten med prioriterad fixlista.
Se senare avsnitt för full teknisk detalj och loggutdrag.
Viktiga resultat i denna etapp (executive summary)#
Bytt tema till PyData Sphinx Theme med inbyggd light/dark‑toggle.
Implementerat tvåkolumnslayout: vänster kod, höger Comments – utan horisontell scroll och med radbrytning.
Comments laddas från statiska HTML‑fragment; robust felhantering med tydlig diagnos i UI.
Språkväxling (sv/en) med knappar som följer PyData‑stilen och fungerar i dark mode.
Högerspalt (secondary sidebar) avstängd globalt; comments tar hela högerkolumnen.
Fullbredds‑layout: PyData CSS overrides för
.bd-page-widthoch.bd-article-container.Smalare vänstersidebar, större text i både Comments och kod, större breadcrumbs.
Svenska rubriker i topp och meny: “Roadlake MLOps dokumentation”, “Kubernetes‑manifest”, “Skript”, “Slurm‑konfiguration”, “Slurm‑image”, “Tema‑överskrivningar”.
Egen theme‑toggle borttagen; varningar eliminerade. Pre‑commit grönt (black, isort, flake8, doc8, bandit, pip‑audit).
Tekniska ändringar (detaljer)#
Tema & konfiguration#
Kodexempel från conf.py:
html_theme = "pydata_sphinx_theme"
html_title = "Roadlake MLOps dokumentation"
html_theme_options = {
# Place theme switcher in the navbar
"navbar_end": ["theme-switcher", "navbar-icon-links"],
# Remove the right-hand (secondary) sidebar completely
"secondary_sidebar_items": [],
# Optional: show prev/next buttons
"show_prev_next": True,
}
html_static_path = ["_static"]
html_css_files = ["css/custom.css"]
html_js_files = ["js/comments_loader.js"]
html_theme = "pydata_sphinx_theme",html_title = "Roadlake MLOps dokumentation".html_theme_options = {"navbar_end": ["theme-switcher","navbar-icon-links"], "secondary_sidebar_items": [], "show_prev_next": True}.Svenska meny‑rubriker i
k8s/index.rst,scripts/index.rst,slurm-config/index.rst,slurm-image/index.rst,overrides/index.rst.
Layout & stil#
Full width (CSS overrides) för sida och artikelcontainer.
/* Two-column code/comments layout */
.code-comments-container {
display: flex;
flex-wrap: wrap;
width: 100%;
border-top: 1px solid #e1e4e5;
}
.code-pane {
flex: 1 1 50%;
min-width: 400px;
overflow-x: auto;
}
.comments-pane {
flex: 1 1 50%;
min-width: 400px;
overflow-wrap: anywhere;
}
Vänster sidebar smalare; tvåkolumns‑comments (50/50); radbrytning i code/comments; större breadcrumbs.
Dark‑mode‑kontrast för icke‑aktiv språkknapp.
Direktivet code-with-comments#
Kodexempel från code_comments.py:
import os
from docutils.parsers.rst import Directive
class CodeWithComments(Directive):
"""Include source code with an AI comments pane alongside.
Usage
-----
.. code-with-comments:: path/to/file.py [highlight_language]
:comment-language: sv|en
"""
required_arguments = 1
optional_arguments = 1
has_content = True
option_spec = {
"version": lambda x: x,
"comment-language": lambda x: x,
}
def run(self):
source_file = self.arguments[0]
highlight_language = self.arguments[1] if len(self.arguments) > 1 else "text"
comment_language = self.options.get("comment-language", "sv")
env = self.state.document.settings.env
rst_abs_path = env.doc2path(env.docname)
### 10. Framtida förbättrings-roadmap
- Utveckla integration för full multiversionshantering med automatisk grenvalidering.
- Implementera automatiserade pre-release-byggtester för HTML- och PDF-utdata.
- Utöka dokumentationspipeline med regelbunden säkerhetsskanning av genererat innehåll.
- Integrera kodexempelkontroll via lint-verktyg i CI.
- Lägg till visuell regressionstestning av UI-komponenter (kod/comments-layout).
rst_abs_dir = os.path.dirname(rst_abs_path)
abs_source_path = os.path.normpath(os.path.join(rst_abs_dir, source_file))
normalized_source_path = os.path.relpath(abs_source_path, project_root).replace("\\", "/")
Kodexempel från code_comments.py#
.. code-block:: python :linenos: :emphasize-lines: 7-13
class CodeWithComments(Directive): required_arguments = 1 optional_arguments = 1 has_content = True option_spec = { “version”: lambda x: x, “comment-language”: lambda x: x, }
Path‑upplösning med
env.doc2path(env.docname)+ normalisering relativt projektroten.Graceful fallback i HTML + build‑logg när fil saknas.
Rensat och formatterat enligt flake8/black.
Build, lint och säkerhet#
Alla hooks gröna. Imports flyttade och formattering fixad (E402/E302/BLK100/B007 m.fl.).
Lessons-learned och “Best Practices” görs synliga i navigation, särskilt med fokus på pipeline- och layoutvalidering.
7. API-dokumentation & kodintegration#
Plan för att flytta alla
{::: app.module}/mkdocstrings-snuttar till motsvarande.. automodule::- och.. autoclass::-syntax.Kurering av huvudsidor (Index, Source Overview, Arkitektur mm) för att lyfta alla varför och hur från kodbasen in i documentation-first-presentation.
8. Lessons learned från MkDocs-epoken – så undviker vi regressions#
En väg för hooks: Kopieringslogik (för kommentarer etc) löses alltid på ett ställe — ingen dubblettkörning.
Ingen legacy/vilda artefakter: Tomma kommentarer,
.md.md-filer och gamla kod-wraps filtreras eller tas bort i automationsledet.Manuellt kurerad navigation: Navstruktur byggs medvetet enligt arkitektur och portfolio-hierarki, inte fullauto.
Säkrare och robustare kodinjektion: All kodinjektion/kommentarinjektion sker via tydliga directives och dom-aware layout i stället för wildcard-JS i overrides.
Modern dokumentationspipeline: Docstring/
hl_lines-highlight synkas automatiskt, med “lint” i pre-commit/build pipeline.
9. Plan - nästa steg#
Systematisk migrering av alla wrapper-sidor, API-refs och guides.
Successiv validering så samtliga högre krav på layout, kod+kommentar och navstruktur bibehålls och förbättras.
Portfolio-perfect presentation blir baseline med versionshantering av lessons-learned, driftproblem och designbeslut.
Fortlöpande dokumentation av varje steg i denna journalfil — uppdateras under hela migreringen.
Sammanfattning#
Vi lämnar en hackig, “Javascript-lagad” MkDocs-lösning bakom oss och bygger nu med Sphinx vidare på ett hållbart, rent, och portfölj-anpassat dokumentationssystem där exakt rätt placerad kod/kommentar-layout, nav och lessons-learned är första klassens invånare. All erfarenhet från utvecklingen i MkDocs — från pipeline-problem och artefakt-kaos till lessons-learned och stylingfixar — omvandlas till robusta arbetsmönster på Sphinx-sidan, med mål: noll regressions, maximal instruktionskraft och elegant presentation.
Uppdatering: 2025-08-31#
Kort sammanfattning:
Åtgärd: Fixed copy-hook i
docs_sphinx/source/conf.pyså att den inte längre skriver över existerande Sphinx-källor (inklusiveindex.md). Tidigare beteende gjorde att en kopieradindex.mdfrån MkDocs blev Sphinx master‑dokument och ersatte vår kontrolleradeindex.rst, vilket ledde till att toctree/navigation försvann i byggt HTML.Effekt: Efter denna ändring kommer Sphinx att använda
index.rst(det kontrollerade master‑dokumentet) och navigationen som specificeras där (toctree) återställs när du bygger om dokumentationen.
Åtgärder#
Uppdaterade
conf.pycopy-hook så att existerande filer alltid sparas (“skip existing files”).Lade till/uppdaterade Sphinx index-/sektioner så att MkDocs-navigation kan mappas till Sphinx toctrees utan att vi skriver över handkurerade .rst-sidor.
Variera lokalt
Se till att
myst-parserär installerad i din virtuella miljö:pip install myst-parser.Bygg dokumentationen:
cd docs_sphinx && make htmlellersphinx-build -b html source _build/html.Kontrollera att navigeringen syns: öppna
docs_sphinx/_build/html/index.htmli en webbläsare (ellerhttp://localhost:8008/index.htmlom du serverar_build/html).
Om navigationen fortfarande saknas
Kontrollera om
docs_sphinx/source/index.mdfinns — om så är fallet och du inte vill använda Markdown-versionen, ta bort den (eftersomindex.rstär avsett att vara master). Med nuvarande copy-hook ska index.md dock inte längre ersätta index.rst.Kontrollera
conf.pyförmaster_doc(standard ärindex) ochsource_suffixså att.rstprioriteras eller att myst-parser är korrekt konfigurerad.
Föreslagen komplett migreringsplan (högnivå)
Stabilisera basen
Säkerställ en stabil
conf.pymed följande kärn‑extensions:sphinx.ext.autodoc,sphinx.ext.napoleon,sphinx.ext.intersphinx,sphinx.ext.viewcode,sphinx.ext.todo,myst_parser(valfritt under övergång),sphinx-copybutton,sphinxcontrib-mermaid, och projektets egnacode_comments.Bestäm master‑dokument (
index.rst) och se till att det innehåller en kompletttoctreesom speglar navigationen frånmkdocs.yml.
Automatisk nav‑konvertering
Skriv ett verktyg (
scripts/convert_mkdocs_nav_to_sphinx.py) som läsermkdocs.ymloch genererartoctree-stubbar idocs_sphinx/source(t.ex. genereraindex.rstsamt per‑katalogindex.rstmed toctree).
Inkrementell innehållsmigrering
Behåll Markdown via MyST till en början (så vi snabbt får feature‑parity).
Identifiera MkDocs-specifika Markdown‑features som
pymdownx.snippets/superfencesoch ersätt dem med Sphinx‑ekvivalenter (t.ex... include::för snippets).För sidor som kräver mycket Sphinx‑funktionalitet (automodule, admonitions, mermaid), konvertera till reST där det förenklar underhållet.
API / autogen
Ersätt
mkdocstringsmed Sphinx-autodoc/autosummary/autodoc‑generering. Skapa enapi/-sektion med autosummary‑stubbar som genereras avsphinx-apidoceller ett skript.
Bygg‑pipeline och CI
Lägg till en GitHub Action/job som kör
sphinx-build -b htmlsamtsphinx-build -b linkcheckför att säkra att allt är länkat.
Teman, overrides och assets
Migrera MkDocs overrides (CSS/JS) till Sphinx
_staticoch_templatesoch validera att alla komponenter renderas identiskt.
Decommission MkDocs
När vi har full parity (funktion, navigation, API‑sidor, automatisk generation och CI‑grindarna gröna), planera ett datum för att ta bort
mkdocs.yml, MkDocs-specifika overrides och plugin‑konfiguration.
Nästa konkreta steg jag kan utföra nu (välj ett):
Köra en lokal Sphinx‑build här i miljön och verifiera att navigationen återkommer (jag behöver ditt ok för att köra bygget).
Implementera skriptet
scripts/convert_mkdocs_nav_to_sphinx.pysom genererar toctrees automatiskt.Börja konvertera MkDocs‑specifika Markdown‑funktioner (snippets/superfences) till Sphinx‑inkluderingar.
Mappningar#
MkDocs to Sphinx/Read the Docs Mapping Specification#
Funktion / Arkitektur |
MkDocs-metod/plugin / config |
Sphinx/Read the Docs-lösning |
Caveats / Anpassning |
|---|---|---|---|
Theme & UI |
material theme + custom CSS |
sphinx_rtd_theme + custom CSS ( |
Läs in egna CSS/JS via |
Code comments/AI panel |
Egen JS ( |
Custom extension |
Måste säkerställa att panelen laddar data på rätt plats inom .rst-strukturen |
Kopiera kodblock |
|
Ingen nativ, kan implementeras (JS, custom CSS) eller via sphinx-copybutton |
Installera |
Navigation |
Manuell YAML i |
Automatiskt via katalogstruktur och toctrees i .rst, ev. med |
Underhåll av hierarki flyttas till .rst-filer och |
Sökfunktion |
|
Inbyggt fulltext-sök i Read the Docs-temat (Elasticsearch-backend) |
Mindre konfigurerbart än MkDocs, ingen extra plugin krävs |
Auto-dokumentation (API) |
|
|
Sphinx hanterar NumPy-stil via napoleon, ingen extra omskrivning krävs |
Mermaid-diagram |
Markdown direkt, (Material tolkar mermaid) |
|
Installera |
Admonitions/info block |
|
|
Syntax skiljer sig, ingen plugin krävs |
Snippets/superfences |
|
Sphinx har inbyggd support för code-blocks och kan importera .rst (no snippet plugin) |
Ev. refaktorisera snippet-flöden till Sphinx includes eller inheritance |
Extra Javascript |
|
|
Kontrollera att JS fungerar med Sphinx DOM-struktur och template |
Auto-gen wrapper/docs |
Script |
Script genererar .rst-filer för import i Sphinx |
Se till att alla .rst-filer följer toctree/hierarki-regler för Sphinx |
Språkväxlare/multilang |
Egna struktur eller JS, Material har plugin |
Ingen nativ språkväxlare i Read the Docs, kan använda sphinx-intl eller Serve-translated docs |
Kräver specialkonfig, ev. Docker-build för fler html ouput |
Versionering dev_addr |
|
Inbyggt i RTD, preview via RTD eller lokal |
Ingen direkt motsvarighet för dev_addr, preview via lokal Sphinx build |
Overrides/templates |
|
|
Justera Jinja2 templates vid behov, Material overrides ej kompatibla |
Noteringar#
All auto-dokumentation via docstrings, NumPy-format och Sphinx (med napoleon) är direkt kompatibelt; ingen manuell konvertering behövs.
Eventuell manuell överföring av nav-struktur sker genom
toctree-direktiv eller i_toc.ymlför HTML generering.Anpassningar för comments/AI-panel sker genom att matcha DOM/callouts mellan Material och RTD-template, ev. uppdatering av custom JS/CSS.
Redo för merge för att implementera multiversion#
Beslut: Vi kommer avstå från multiversion-dokumentionsfunktioner just nu.
Description#
Introduces versioned documentation using sphinx-multiversion. This enables the documentation to be built and browsed for multiple codebase versions (branches/tags). This PR includes:
Adding
sphinx-multiversiontodev-requirements.txtUpdating
docs_sphinx/source/conf.pywith appropriate multiversion config and whitelist regexesEnsuring
.. only:: htmland.. smv:: current v1.0present inindex.rstPreparation for GH tag (
v1.0) for full multi-version experience
Instructions#
After merging:
From main, create and push a Git tag:
git tag v1.0 git push origin v1.0
Run the following to build versioned docs:
sphinx-multiversion docs_sphinx/source docs_sphinx/_build
Verify that multiple version dropdown appears in HTML output.
Beslut: avstår från sphinx-multiversion för nu (tillfälligt)#
Efter närmare utredning har vi beslutat att inte fortsätta implementera
sphinx-multiversion i nuläget. Sammanfattning av skälen:
Kompatibilitet:
sphinx-multiversioni dess nuvarande form är inte kompatibel med Sphinx efter version 5 (vi kör nyare Sphinx i vår pipeline), vilket skulle kräva antingen att vi kör en äldre Sphinx eller att vi underhåller en egen fork av extensionen — båda alternativen innebär en hög kostnad i underhåll för en funktion som för oss är “nice-to-have”.Behovsbedömning: Vi förväntar oss mycket sällan behov av att publicera parallella dokumentationsversioner för detta projekt; det är acceptabelt att i de få fall då det behövs bygga separata dokumentationsutgåvor.
Vi lämnar idén som en framtida möjlighet (en template för senare bruk), men prioriterar nu att stabilisera Sphinx‑basen och nå feature parity mot vad vi hade i MkDocs för auto‑genererad API‑dokumentation.
Autogenerad dokumentationsfunktion för att ta över efter mkdocstrings och griffe#
För att få samma (eller bättre) autogenererade API‑sidor som vi tidigare
skapade med mkdocstrings + griffe behöver vi främst säkerställa att
Sphinx kan:
läsa våra utförliga NumPy‑docstrings (done via
sphinx.ext.napoleon),generera modul‑/klass‑sidor automatiskt (via
sphinx-apidocellerautosummary/autodoc), ochpresentera typannoteringar och init‑dokstringar på ett likvärdigt sätt.
Konkreta steg och config‑snippet (lägg i docs_sphinx/source/conf.py):
# Extensions
extensions += [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.autosummary',
'sphinx.ext.viewcode',
'sphinx.ext.intersphinx',
'sphinx_copybutton',
'sphinx_autodoc_typehints',
]
# Autodoc behaviour
autoclass_content = 'both' # include class docstring and __init__
autodoc_default_options = {
'members': True,
'undoc-members': False,
'show-inheritance': True,
}
autosummary_generate = True
autodoc_typehints = 'description'
Exempel‑workflow för att generera API‑sidor:
Kör
sphinx-apidocför att skapa stubbar:
sphinx-apidoc -f -o docs_sphinx/source/api src/app
Bygg dokumentationen och kontrollera
api/‑sektionen:
cd docs_sphinx && sphinx-build -b html source _build/html
Ytterligare förbättringar:
sphinx_autodoc_typehintsellerautodoc_typehintsförbättrar hantering av annoteringar (motsvarar mkdocstringsshow_signature_annotations).autoclass_content = 'both'efterliknar mkdocstringsmerge_init_into_class.viewcodeger länkar till källan (motsvarar mkdocstringsshow_source).
“Source file not found” och nya robusthetskrav#
Bakgrund till regressionen#
Efter “grön” migrering, visade det sig att vissa .rst-sidor med custom .. code-with-comments::-direktivet aldrig laddade själva källkoden – trots att både navigation, toctrees och övriga sidor fungerade. Problemet blev akut när gamla “Source file not found”-fel återuppstod i Sphinx–trots att rätt källa låg på disk där den borde.
Felsökningsåtgärder och metodik#
Genomförde systematisk test av paths: test av absoluta, relativa och kombinatoriska (
../../.., osv) sökvägar i .rst-filer mot verklig filstrukturLade in diagnostic-printar/loggar i
code_comments.py: logg-strängar till Sphinx build-log och synliga “Failed to fetch source…”-injekt i HTML om fil ej fannsSäkerställde att källfiler verkligen existerade (via
ls -lfrån build-root)Provade olika riktningar på referenser: relativt till
docs_sphinx/source, från projektroten, och via symlinksRensade alla legacy
.rstoch templates med för långa underline-tecken och otillåtna directivTog bort alla Sphinx-konfigrations-warnings (t.ex.
display_versioni conf.py)Provade funktionsminimal .rst som bara inkluderar en exempelfil för isolerad test
Vad upptäcktes?#
1. Sphinx’ path-resolution är CWD-beroende, ej robust vs. MkDocs
Paths i standard-Sphinx-directiv hanteras RELATIVT till build-direktivet, men custom-directives måste själva räkna ut detta.
Små fel i directory-djup leder till att source-filer “inte finns” trots korrekt filstruktur.
Round-trip via
scripts/generate_documentation.pykan ha output som ibland tappar rätt “../../”-djup.
2. Vår custom directive och fallback-medveten UX
Funktionaliteten förbättrades med fallback: när fil saknas visas HTML-warn, men bygget kraschar aldrig.
Felet hissas även i “build log”-nivå, vilket tillfredsställer devops och CI.
3. Robusthets lesson learned
Kritiskt i all framtida dokumentationspipeline: all code injection och file fetch ska göras fail-visibly och tyst för både bygget (log) och output (HTML).
Jämfört med MkDocs-material—där wildcard-inklusion ofta slukade error—så explicit fallbacks i Sphinx ger portföljfördel i robusthet och predictability.
Vad återstår?#
Fixa vissa “See also” avsnitt för API-dokumentationen.
Fixa flicker vid öppnande av ny källkodsfil från Src vyn.
Snygga till bildvisning.
Kör om LLM-kommentarerna för att bryta ut mermaid diagram och göra för varje program, och hålla dem separata för det nu inkonsekventa medtagandet i lekmannakommentarrna.
Erfarenheter och best practices från denna regression#
Explicit path-debuggi, undvik implicit CWD: All dokumentationskod (custom directives, scripts) ska alltid logga exakta path som testas mot disk – annars förlorar man snabbt kontrollen vid pipeline-ändringar.
Fail visibly > fail silently: Alla pipeline-lager (Sphinx, .rst, extensions, build-skript) MÅSTE rendera fel synligt, inte bara logga djupt i bygget.
Regressionstestar ALLA paths vid varje build: Alla generationer av .rst eller dynamic includes ska testas i CI mot verklig diskstruktur, och test-strängar ska granskas inför PR-merge.
CI-validering av genererade .rst-filer: Ett dedikerat CI-jobb kör
sphinx-build --warning-is-errorpå alla genererade .rst-filer för att säkerställa att inga varningar eller fel uppstår, samt verifierar att katalogstruktur och innehåll följer definierade riktlinjer.Temawarnings och titles: Sphinx är striktare än MkDocs; ornda genast eventuella lint-warnings kopplat till theme och syntax.
Comments‑pipeline#
comments_loader.js: hämtar/comments/{lang}/{path}.html, ersätter filändelse, visar full URL och instruktion för lokal HTTP‑server vidfile:///.conf.pykopierar comments vidbuild-finishedtillbuild/html/commentsoch loggar viasphinx.util.logging.