fix/darstellung #1

Merged
rocho merged 8 commits from fix/darstellung into master 2026-08-11 12:52:19 +02:00
Owner
No description provided.
Gegen eine lokale Outline v1.9.2 verifiziert (siehe ../outline-lab).

Datenverlust:
* Ein unbalanciertes (:directive:) (fehlendes :) - von PmWiki harmlos als
  Text gerendert) loeschte alles bis zum naechsten :) irgendwo auf der
  Seite, still und mit Exit-Code 0. Direktiv-Argumente enden jetzt an der
  Zeilengrenze.
* Nicht-Bild-Anhaenge stehen in eigenen Absaetzen. Outlines Markdown-Regel
  ersetzt den ganzen Absatz durch die Datei-Karte ("this makes the
  assumption that the attachment is the only thing in the para") und
  vernichtete dabei Prosa und Bilder daneben.

Anhaenge:
* Layout auf <Gruppe>/attachments/<datei> + ./attachments/<datei> umgestellt.
  Beim gemeinsamen Top-Level-Ordner mit ../ legt Outline einen 0-Byte-Record
  unter der ID an, die im Dokument landet, und die Bytes unter einer anderen
  - jedes Bild war ein kaputter Platzhalter.
* Dateinamen prozent-kodiert (Outline matcht gegen encodeURI).
* Label als "<name> <bytes>", weil Outline Name und Groesse per
  parts.pop() aus dem Linktext liest - sonst Karte ohne Namen.
* Satzpunkt hinter Attach:datei.pdf. gehoert nicht zum Dateinamen.

Darstellung:
* Verschachtelte Nummernlisten: 3 Leerzeichen Einrueckung, sonst wirft
  CommonMark die Verschachtelung weg und nummeriert flach durch.
* >>wikistyle<< ... >><< kollidierte mit Outlines internem <<id>>-Format
  und verschluckte den Text dazwischen in eine Fake-Anhang-URL.
* @@monospace@@, eingerueckte <pre>-Bloecke, [=escaped=], Definitions-
  listen, ->/-<, {$PageVars}, '^sup^'/'_sub_', [--small--].
* Tabellen: ||attr-Zeile wird nicht mehr zur Kopfzeile, ||!caption!||
  erkannt, ohne !-Zellen keine Beforderung von Daten zur Kopfzeile.
* Leerzeilen um Blockkonstrukte, sonst faltet CommonMark Tabellen in den
  Absatz darueber.
* Dokumenttitel aus (:title:) bzw. dem Seitennamen mit Wortabstand.
* TODO-Marker als Blockquote statt HTML-Kommentar - Outline zeigt
  <!-- ... --> als sichtbaren Text.

Sicherheit / Bedienung:
* --exclude-group (Default Site, SiteAdmin, PmWiki) - SiteAdmin.AuthUser
  enthaelt htpasswd-Hashes.
* Seiten mit passwdread/passwdedit werden uebersprungen und gemeldet;
  --include-protected erzwingt sie.
* --overwrite raeumt den Ausgabebaum, sonst ueberleben Geisterdateien.
* wiki.d wird rekursiv gelesen (Per-Group-Unterordner).
* --report kennt jetzt alle Konstrukte, die der Konverter verbiegen kann,
  und faellt nicht mehr auf Prozent-Kodierung in Linkzielen herein.
Gegen Outline v1.9.2 gemessen.

Anhang-Karte:
Die Groesse wird beim Import IMMER auf 0 gesetzt - mit 4105, mit 999 und
ohne Angabe, alle drei landen als "0 Bytes". Aus dem Markdown also nicht
zu retten. Outlines eigene Regel hat aber eine Hintertuer, die vor allem
anderen greift:

    if (href?.includes("display=link")) { return false; }

Nicht-Bild-Anhaenge tragen jetzt &display=link im Ziel und bleiben damit
normale Inline-Links: Label erhalten, keine "0 Bytes"-Karte, und die
Absatz-Isolation aus dem letzten Commit entfaellt - der Satz bleibt am
Stueck. Damit fliegen auch der Groessen-Lookup und die
Interpunktions-Verschiebung wieder raus.

& statt ?: Outline haengt an /api/attachments.redirect?id=<uuid> an, was
hinter dem Pfad stand. Mit ?display=link entstehen zwei ? und der Endpunkt
antwortet 400; mit &display=link ist es eine gueltige Query und die Datei
kommt (HTTP 200, %PDF- verifiziert).

Faellt die Hintertuer in einer kuenftigen Outline-Version weg, muessen
Nicht-Bild-Anhaenge zurueck in eigene Absaetze - sonst kehrt der
Absatzverlust zurueck. Der Test haelt den Vertrag fest.

Domain-Konvertierung (converter/domains.py, --wiki-url):
Absolute URLs auf das alte Wiki werden in PmWiki-Markup zurueckgeschrieben,
damit die bestehenden Link- und Anhang-Phasen sie normal aufloesen - statt
Markdown direkt zu erzeugen und die Gruppen-, Anker- und Kodierungslogik zu
duplizieren.

  /Group/Page  /Group.Page  /Group/Page#anchor  /Group/Page?action=
  /Group/  /?n=Group.Page  /index.php?n=  /pmwiki.php?n=
  /uploads/Group/datei.ext -> Attach:Group/datei.ext

Bare URLs und [[url|text]] getrennt behandelt - ein gemeinsamer Durchgang
haette [[[[Group.Page]]|text]] erzeugt. Fremde Hosts bleiben unberuehrt,
ohne --wiki-url passiert nichts. Satzzeichen am URL-Ende gehoeren zum Satz.
Outline rendert Bilder als eigenen zentrierten Block. Ein Absatz wie
"Schaltbild: ![x](...)." wurde damit dreiteilig dargestellt und der
einzelne Punkt landete als eigene Zeile unter dem Bild.

Ein Rest, der ausschliesslich aus Satzzeichen besteht, wandert jetzt vor
das Bild - bzw. entfaellt, wenn der Text davor schon auf einem Satzzeichen
endet ("Schaltbild:."). Echter Text hinter einem Bild bleibt unangetastet,
der gehoert dort hin.

Im Testimport jetzt null verwaiste Satzzeichen-Zeilen.
Gegen die echten hsmr.cc-Daten entwickelt (1252 Seiten, 31 Gruppen).

Der Anlass: Seiten sind teilweise oeffentlich und teilweise privat. PmWiki
entscheidet zur Renderzeit, wer welchen Teil sieht; ein flacher Export kann
das nicht, also muss es vorher aufgeloest werden - und es geht in beide
Richtungen schief:

  (:if false:)     zeigt PmWiki NIEMANDEM          799x -> verworfen
  (:if auth edit:) nur eingeloggten Mitgliedern    324x -> geschuetzter Export
  (:else:) davon   sahen Nicht-Eingeloggte              -> oeffentlich

Vorher landete beides im oeffentlichen Export: 296 Seiten haetten
Mitglieder-Inhalte offengelegt, dazu 18 Seiten mit PmWiki-Seitenpasswort
(u.a. Main.WebAccounts, Freifunk.Admindoku, Verein.Vorstandstagebuch).

* converter/conditionals.py: 4-wertige Auswertung (KEEP/DROP/MEMBER/UNKNOWN)
  mit Negation durch (:else:). Wichtig: (:if:) hat kein schliessendes Tag -
  eine Region laeuft bis zum naechsten if/else/elseif/ifend, Conditionals
  partitionieren die Seite also sequenziell statt zu verschachteln. Genau
  darum gibt es (:if2:)/(:if3:). 763 der 1252 Seiten haben (:if:) ohne
  jedes (:ifend:); ein Block-Parser haette ganze Abschnitte falsch
  zugeordnet, inklusive der geschuetzten.
* --protected-out schreibt einen zweiten Baum fuer eine Collection mit
  eingeschraenkter Berechtigung. Ohne das Flag wird der Inhalt verworfen und
  gemeldet, aber nie still publiziert.

converter/ptv.py: Page-Text-Variablen (Name: wert -> {$:Name}). Die
Definitionen stehen fast immer in den (:if false:)-Bloecken, werden also aus
dem Rohtext gesammelt, bevor die Bloecke wegfallen - sonst behaelt etwa
(:title Chaostreff {$:StartYear}-...:) das Literal als Dokumenttitel. Ersetzt
wird im Rohmarkup vor den Phasen, wie PmWiki es tut: ein PTV mit '''fett''' und
[[Links]] darin wurde sonst unkonvertiert eingefuegt. Undefiniert = leer.

converter/intermap.py: [[Wikipedia:DIY|Selbstbau]] wird aufgeloest, aus
Site.InterMap plus --intermap scripts/intermap.txt. Dazu echte URI-Schemata
ohne // (tel:, xmpp:, ircs:) als Links statt als InterMap-Praefix.

Weitere Funde aus den echten Daten:
* Doppelpunkt-Direktiven ((:Summary: ...:)) matcht PmWiki mehrzeilig - am
  Live-Wiki geprueft. Die Leerzeichen-Form bleibt einzeilig, dort sitzt das
  Datenverlust-Risiko. 86 -> 3 ueberlebende Direktiven.
* Attach:Gruppe.Seite/datei und Attach:Gruppe./datei adressieren die Gruppe;
  Uploads liegen per Gruppe. 31 -> 0 fehlende Anhaenge.
* [[Attach:datei.jpg"Alt-Text" | Anzeige]] - Titel-Syntax, sonst steckt der
  Text im Dateinamen. Auch mit Leerzeichen im Namen und Leerraum nach [[.
* Ein Durchgang statt zwei fuer Anhaenge: sonst verarbeitet der bare-Pass das
  Label, das der bracketed-Pass gerade erzeugt hat.
* [[Projekte/X | [hsmr]-Programm]] - Klammern im Anzeigetext (26x).
* PmWiki-Maschinenseiten (RecentChanges, GroupHeader, Templates, ...)
  uebersprungen; GroupHeader wird im Kontext anderer Seiten gerendert und ist
  allein nicht aufloesbar.
* Report: Fehlalarme auf Prozent-Kodierung und auf konvertierte Links mit
  Klammern beseitigt, damit echte Funde nicht untergehen.

Ergebnis auf den echten Daten: 868 oeffentliche Seiten, 314 geschuetzte
Dokumente, 1231 Anhaenge, 1 fehlender Anhang (im Wiki geloescht), im Report
1 unkonvertierter Link und 3 Custom-Recipe-Direktiven zur Sichtung.
Beim Import der echten 868 Seiten in die lokale Outline aufgetaucht.

Der Import brach ab: Postgres lehnte "unsupported Unicode escape sequence"
ab. Ursache war ein NUL-Byte aus einem nicht restaurierten Platzhalter.
Profiles.Leisefuxx enthaelt ASCII-Art voller @-Zeichen; daraus wird ein
@@...@@-Span extrahiert, und der umgebende eingerueckte Block schluckt dann
den Marker. Beim Restaurieren des Blocks kam der innere Marker als Literal
zurueck, und ein einzelner Durchgang loeste ihn nie auf - \x00PMDCODE000000
landete im Dokument. _restore_code laeuft jetzt iterativ.

Dazu: C0-Steuerzeichen werden entfernt (Tagebuch.2014-11 enthaelt ein
U+0010 aus der Quelle). In Markdown bedeutungslos, und Outline scheitert
daran.

Upload-Namen (converter/util.py, resolve_attachment):
PmWiki filtert $UploadNameChars nicht nur beim Speichern, sondern auch beim
Bauen des Links - Attach:Grieß.jpg zeigt uploads/FoodHacking/Grie.jpg. Am
Live-Wiki geprueft. Der Konverter nahm die Referenz woertlich und erzeugte
zwei 0-Byte-Attachments in Outline, also genau zwei kaputte Bilder, die im
Wiki funktionieren. Jetzt wird der Name wie in PmWiki bereinigt, das
sichtbare Label behaelt das Original.

Der Report meldete bisher nur gruppenfremde Anhaenge als fehlend; jetzt auch
gruppeneigene - daran waeren die beiden sofort aufgefallen.
Im Testimport auf Infrastruktur.Bananaphone sichtbar geworden.

PmWiki hat die Size-Marker in beiden Formen: [--klein--] und [-klein-],
[++gross++] und [+gross+]. Nur die doppelte war behandelt, die einfache
kommt 59x vor - meist als Bildunterschrift, also gut sichtbar.

Dazu das Muster [[Attach:x.jpg | Beschriftung]] | [-Beschriftung-] (42x):
so haengt das Skin eine Bildunterschrift an. Outline zeigt den Alt-Text
ohnehin unter dem Bild, eine identische Beschriftung dahinter ist also
doppelt und faellt weg; eine abweichende bleibt als Text stehen, nur ohne
das Trennzeichen.
space_wiki_word machte aus 2023-12-27-37c3 den Titel "2023-12-27-37c 3",
weil die Buchstabe-Ziffer-Regel in 37c3 zuschlug. Namen mit Bindestrich oder
fuehrender Ziffer sind keine WikiWords und bleiben jetzt unangetastet;
DingeImGlas -> Dinge Im Glas und ServerGw02 -> Server Gw 02 bleiben.

Betrifft vor allem Events und Overhead, wo fast alle Seitennamen
Datums-Slugs sind.
Beim Testimport der 1252 hsmr.cc-Seiten waren 2242 interne Links tot. Die
Analyse gegen wiki.d:

  1389  nur Gross-/Kleinschreibung   -> behebbar
   729  Seite existiert nicht        -> im Wiki ebenfalls tot
    72  uebersprungen (leer/Filter)
    44  Link ohne Gruppe
     8  Ziel im geschuetzten Baum    -> behebbar

Ursache der 1389: PmWiki normalisiert einen Seitennamen vor dem Nachschlagen
(MakePageName), deshalb erreicht [[~oleander]] die Seite Profiles.Oleander.
Der Konverter hat den Namen woertlich uebernommen. Jetzt loest links.py gegen
ctx["known_pages"] auf - eine Abbildung kleingeschrieben -> kanonischer Name,
die convert.py in einem ersten Durchgang aus wiki.d aufbaut. Ziele, die es
wirklich nicht gibt (Profiles.Towb ist als ,del-<ts> geloescht, snagheenanajad
gab es nie), bleiben unveraendert - PmWiki zeigt dort auch nur einen
"Seite anlegen"-Link.

Die 8 Cross-Baum-Links brauchen zweierlei: --protected-root benennt den
Ordner des geschuetzten Baums (Default INTERN) und wird Links auf
nur-geschuetzte Seiten vorangestellt; ctx["in_protected"] entscheidet, ob
zwei statt einer Ebene hoch gegangen wird. Damit funktionieren Links in
beide Richtungen, wenn beide Baeume in EINEM ZIP importiert werden - Outline
baut seine Dokument-Map pro Import, getrennte Importe koennen einander
grundsaetzlich nicht verlinken.

Der erste Durchgang ist der Preis dafuer: wohin eine Seite kommt, entscheidet
sich erst nach conditionals.split, und das muss bekannt sein, bevor eine
andere Seite darauf verlinkt.
rocho merged commit 07cf89f21b into master 2026-08-11 12:52:19 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
hsmr/pmwiki-migration-tools!1
No description provided.