mjEdit organisiert die Arbeit in einem Multi-Tab-System. Jeder Tab ist auf einen bestimmten Arbeitsbereich spezialisiert und arbeitet nahtlos mit den anderen zusammen.
Text-Tab — Der JSON-Editor
Das Herzstück von mjEdit: ein vollwertiger JSON-Editor mit Syntax-Highlighting, Echtzeit-Validierung, Klammer-Matching und intelligenter Auto-Reparatur.
Performance-Modi für große Dateien
| Dateigröße | Verhalten |
|---|---|
| < 100 KB | Vollständiges Highlighting + Rechtschreibprüfung + alle Features |
| 100 KB – 200 KB | Vereinfachtes Highlighting (nur Keys/Klammern), keine Rechtschreibprüfung |
| > 1 MB | Kein Highlighting, Lazy-Loading (erste 10.000 Zeilen) |
Form-Tab — qFORM-Formularsystem & QC-Scripts
Der Form-Tab verwandelt JSON-Daten automatisch in bearbeitbare Formulare. Das proprietäre qFORM-Format kombiniert strukturierte Dateneingabe mit eingebetteten Python-Scripts (QC-Scripts) in einer RestrictedPython-Sandbox.
Automatische Widget-Erkennung
| Feldtyp | Widget | JSON-Erkennung |
|---|---|---|
| Verschachteltes Objekt | QGroupBox | Wert ist {} (Dict) |
| Array/Liste | QGroupBox (orange) | Wert ist [] (Array) |
| QC-Script | QTextEdit (readonly) | Wert beginnt mit "QC", >10 Zeichen |
| Checkbox | QCheckBox | Wert ist true oder false |
| Dropdown | QComboBox | Wert beginnt mit |, ≥2 Pipes |
| Dateipfad | QLineEdit + 📁 | Wert enthält Pfad-Muster |
| Datum | QLineEdit + DATUM | Datum-Keyword im Key oder Datumsformat |
| Text (Standard) | AutoResizeTextEdit | Alles andere |
QC-Script-Syntax in Kürze
QC-Scripts werden in Stringfeldern der qFORM-Datei eingebettet, in eine RestrictedPython-Sandbox kompiliert und beim Rendern ausgeführt. Das letzte Ausdrucksergebnis ersetzt den Code-Block im Formular.
| Element | Bedeutung |
|---|---|
@( … )@ |
Markiert einen QC-Code-Block (auch mehrfach im selben Feld erlaubt) |
<feldname> |
Platzhalter – wird vor der Ausführung durch den Wert eines qFORM-Feldes ersetzt (Punkt-Notation für verschachtelte Pfade möglich) |
json_data |
Die gesamte qFORM-Datei als Dict – z. B. wenn eine OSCAL-Datei direkt im Form-Tab geöffnet ist |
| Erlaubte Module | datetime, json, math, re, time, socket, urllib, optional requests (kein direkter Datei-Zugriff) |
Beispiel 1 — Einsteiger: Abholtermin für einen neuen Reisepass
Eine Behörden-qFORM erfasst den Antragstag und berechnet daraus automatisch den frühesten Abholtermin (klassisch: Antragsdatum + 30 Tage).
{
"Reisepass-Antrag": {
"antragsdatum": "DATUM 06.05.2026",
"bearbeitungsdauer_tage": 30,
"abholtermin": "QC: berechneter Termin: @(\nfrom datetime import datetime, timedelta\nantrag = datetime.strptime('<antragsdatum>', '%d.%m.%Y')\nabholung = antrag + timedelta(days=int('<bearbeitungsdauer_tage>'))\nf'{abholung.strftime(\"%A, %d.%m.%Y\")} (frühestens)'\n)@"
}
}
So gerendert wird das QC-Feld z. B. als:
berechneter Termin: Freitag, 05.06.2026 (frühestens)
Was passiert hier?
<antragsdatum>und<bearbeitungsdauer_tage>werden vor der Ausführung durch die aktuellen Feldwerte ersetzt.datetimeist in der Sandbox verfügbar, der Code rechnetAntragstag + 30 Tage.- Der letzte Ausdruck (
f"…") wird das Ergebnis – mehr Boilerplate ist nicht nötig. - Sobald der Sachbearbeiter
antragsdatumändert, aktualisiert mjEdit die Anzeige automatisch.
Beispiel 2 — Fortgeschritten: SSP-Implementierungsstand zählen
Eine reine OSCAL-SSP-Datei enthält kein QC-Feld. Es gibt aber die Möglichkeit, Daten über ein temporäres QC-Feld auszuwerten und OSCAL-Datein mit qFORM sinnvoll zu kombinieren – entweder direkt im Form-Tab oder über eine eigenständige qFORM mit Datei-Picker (siehe weiter unten).:
Variante A — SSP direkt im Form-Tab öffnen
Wenn Sie eine OSCAL-SSP-JSON in mjEdit öffnen und im Form-Tab anzeigen, ist die SSP selbst json_data. Ein temporär in einem freien Beschreibungsfeld eingefügter QC-Block kann das gesamte Dokument auswerten – nützlich für Stichprobenstatistiken während eines Reviews:
@(
reqs = json_data.get('system-security-plan', {}).get('control-implementation', {}).get('implemented-requirements', [])
implementiert = sum(
1 for r in reqs
for s in r.get('statements', [])
for bc in s.get('by-components', [])
if bc.get('implementation-status', {}).get('state') == 'implemented'
)
total = len(reqs)
f"Implementiert: {implementiert} von {total} Anforderungen ({(implementiert/total*100 if total else 0):.1f} %)"
)@
Vorteil: Kein zusätzliches Tooling, sofort einsetzbar. Nachteil: Der QC-Block muss vor dem Speichern wieder entfernt werden, wenn das Dokument schemavalide bleiben soll.
Variante B — Eigene „SSP-Statistik"-qFORM mit Datei-Picker
Die saubere Variante ist eine eigenständige qFORM, die einen Dateipfad auf eine SSP-Datei aufnimmt und per urllib einliest. Der Dateipfad-Widget (📁-Button) ist von qFORM nativ unterstützt; das QC-Script greift via <ssp_pfad> auf den Wert zu:
{
"SSP-Statistik": {
"ssp_pfad": "C:/oscal/ssp_acme.json",
"report": "QC-Bericht: @(\nimport urllib.request, json\nfrom urllib.parse import urljoin\nfrom pathlib import PurePath\nuri = 'file:///' + str(PurePath('<ssp_pfad>')).replace('\\\\','/')\nwith urllib.request.urlopen(uri) as f:\n ssp = json.load(f)\nreqs = ssp.get('system-security-plan', {}).get('control-implementation', {}).get('implemented-requirements', [])\nimpl = sum(1 for r in reqs for s in r.get('statements', []) for bc in s.get('by-components', []) if bc.get('implementation-status', {}).get('state') == 'implemented')\nf'{impl} von {len(reqs)} Controls implementiert'\n)@"
}
}
Schritte für den Anwender:
- SSP-Statistik-qFORM öffnen.
- Über das 📁-Symbol die SSP-Datei auswählen.
- mjEdit ersetzt
<ssp_pfad>durch den gewählten Pfad und führt das QC-Script aus. - Das Ergebnis erscheint live im Formular – jeder Pfadwechsel löst eine Neuberechnung aus.
Vorteil: Wiederverwendbar, die SSP-Datei selbst bleibt unverändert, das QC-Script kann beliebig komplexe Auswertungen liefern (Ampel pro Control-Familie, fehlende Komponenten, POA&M-Bezüge usw.).
Markdown-Tab — Dokumentation und Berichte
Vollwertiger Markdown-Editor mit Live-Preview im Split-View, GitHub Flavored Markdown, Auto-Formatierung über mdformat und PDF-/HTML-Export.
Erweitertes Task-Listen-System
| Element | Syntax | Beispiel |
|---|---|---|
| Checkbox | - [ ] / - [x] |
- [x] Server konfiguriert |
| Priorität | Schlüsselwörter | kritisch, wichtig, hoch |
| Status | Schlüsselwörter | in arbeit, pausiert, vollständig |
| Zuweisung | @Person |
@Mueller |
| Datum | 📅 YYYY-MM-DD |
📅 2026-04-30 |
| Tags | #Tag |
#sicherheit #patch |
| OSCAL-Links | &OSCAL|...|... |
Direktlink zu OSCAL-Controls |
| POA&M-Referenzen | &POAM|...|... |
Direktlink zu Maßnahmen |
PDF-Tab — Viewer, Annotator und Schwärzungswerkzeug
PDF-Dokumente werden direkt in mjEdit angezeigt – mit Multi-Tab-Unterstützung, Annotationen, Text-Suche und sicherer Schwärzung.
- Zoom 25 % – 400 %, Fit-to-Width / Fit-to-Height
- Highlighter, Notizen, Freihand-Zeichnung, Formen, Text-Einfügung
- Sichere Schwärzung mit Unicode-Block (■): Inhalte werden tatsächlich entfernt, nicht nur überdeckt
- PDF mit allen Annotationen als neue Datei speichern
Browser-Tab — Integrierter Webbrowser
Vollwertiger Chromium-basierter Browser direkt in mjEdit – mit zweistufigem Lesezeichen-System.
Globale vs. private Lesezeichen
| Eigenschaft | Globale Lesezeichen | Private Lesezeichen |
|---|---|---|
| Zweck | Team-Ressourcen, geteilte Referenzen | Persönliche Sammlung |
| Speicherort | data/global-browser-bookmarks/ |
config/ |
| Hinzufügen | Dialog mit Titel, Tags, Kürzel | Ein Klick – kein Dialog |
| Team-Sharing | Über Git teilbar | Nur lokal |
Webseiten als OSCAL-Back-Matter-Resource speichern
Jede angezeigte Webseite kann per Rechtsklick als Back-Matter-Resource in ein geöffnetes OSCAL-Dokument eingefügt werden – ein Klick statt Copy-Paste zwischen Anwendungen.
OSCAL-Tabs (Plugin) — Spezialisierte Editoren
Die OSCAL-Tabs werden automatisch geöffnet, wenn mjEdit eine OSCAL-Datei erkennt. Für jeden der 8 OSCAL-Dokumenttypen steht ein maßgeschneiderter Editor bereit – siehe OSCAL-Integration.
Datei-Tree-View — Zentrales Cockpit
- Lazy-Loading für große Verzeichnisse (1.000+ Dateien)
- Farbige Datei-Icons pro Endung (konfigurierbar)
- Echtzeit-Filter, case-insensitiv und rekursiv
- Kontextmenü mit Aktionen je nach Dateityp
- Backup-Indikator zeigt vorhandene Sicherungen
- Multi-Selektion für Batch-Operationen
- „Öffnen als Text" umgeht das automatische OSCAL-Routing
Backup- und Versionierungskonzept
mjEdit bietet ein zweistufiges Sicherheitsnetz:
- Automatische Backups – komprimiert (GZIP), zeitbasiert, beim Öffnen und Speichern
- Versions-Archiv – benannte Momentaufnahmen mit Diff-Anzeige und Vorschau
Vor jeder Wiederherstellung wird automatisch ein Backup der aktuellen Datei angelegt.