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?

  1. <antragsdatum> und <bearbeitungsdauer_tage> werden vor der Ausführung durch die aktuellen Feldwerte ersetzt.
  2. datetime ist in der Sandbox verfügbar, der Code rechnet Antragstag + 30 Tage.
  3. Der letzte Ausdruck (f"…") wird das Ergebnis – mehr Boilerplate ist nicht nötig.
  4. 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:

  1. SSP-Statistik-qFORM öffnen.
  2. Über das 📁-Symbol die SSP-Datei auswählen.
  3. mjEdit ersetzt <ssp_pfad> durch den gewählten Pfad und führt das QC-Script aus.
  4. 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.

AR-Objekt-Baum: Struktur eines OSCAL-Assessment-Results-Dokuments in mjEdit

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:

  1. Automatische Backups – komprimiert (GZIP), zeitbasiert, beim Öffnen und Speichern
  2. Versions-Archiv – benannte Momentaufnahmen mit Diff-Anzeige und Vorschau

Vor jeder Wiederherstellung wird automatisch ein Backup der aktuellen Datei angelegt.