Prof. Dr. Detlef Stern

Zettelstore 0.11

Die gute Nachricht für alle Nutzer des Zettelstore: Version 0.11 ist verfügbar. Dies gilt auch für die Bibliothek, um auf den Zettelstore zuzugreifen (a.k.a Zettelstore Client).

Was gibt es an relevanten Änderungen im nun 26. Release?

Viele ist weggefallen, einiges davon angekündigt. Die Repräsentation von Zetteln im sog. ZJSON-Format ist gestrichen. Wer eine strukturierte Repräsentation von den Inhalten eines Zettels benötigt, muss nun das Sexpr-Format verwenden. Dies betrifft im Wesentlichen diejenigen, die auf den Zettelstore über seine API zugegriffen haben, z.B. mit Hilfe des Zettelstore Client.

Bisher wurde der Titel eines Zettels als Zettelmarkuptext interpretiert. D.h. man konnte dort etwas hervorheben, Fußnoten verwenden, auf etwas verweisen. Das machte nur Probleme bei der Generierung. Zum Beispiel werden Zettel bei einer Suche in der Web-Oberfläche über ihren Titel aufgelistet, inkl. Verweis auf den Zettel. Wenn nun ein Titel einen Verweis enthält, dann wird dieser bei der Auflistung ignoriert (und produziert ungültiges HTML). Fußnoten müssen bei der Auflistung unterdrückt werden, sie am Ende der Auflistung darzustellen macht viele weitere Probleme. Also, wer nun entdeckt, dass im Titel „lustige Zeichen“ auftauchen, hat wohl Zettelmarkup im Titel verwendet.

In der Web-Oberfläche werden Verweise auf externe Seiten mit Hilfe eines kleinen Pfeils visualisiert. Dieser konnte über die Konfigurationseinstellung marker-external geändert werden. Da marker-external beliebiges HTML erlaubt, wäre dies ein potentielles Sicherheitsproblem. Außerdem, für das Aussehen ist CSS zuständig. Also habe ich diese Konfigurationseinstellung gelöscht, der Pfeil wird nun mittels CSS erzeugt. Wer diesen ändern möchte: das CSS des Zettelstores ist in einem Zettel gespeichert, der natürlich geändert werden kann.

In einer Anweisung zur Suche gibt es nun die Möglichkeit, mit Hilfe von PICK n (n ist eine positive ganze Zahl) sich aus der Liste der Suchtreffer n zufällige Elemente auszuwählen. Grob entspricht das einem RANDOM LIMIT n, wobei nun aber die Elemente zusätzlich sortiert werden können. RANDOM ist nun nur noch nötig, wenn man alle Suchtreffer zufällig sortieren möchte. Ein RANDOM LIMIT n wird intern auf ein PICK n zurückgeführt. Beide Direktiven können nicht zugleich angegeben werden, PICK n überschreibt ein RANDOM.

Der sog. Zettelkontext ist ein Weg, wie man zu einem bestimmten Zettel andere relevante Zettel auflisten kann. Das geschah bisher über Verknüfungen zwischen Zetteln. Problematisch waren dabei allerdings Zettel, die als Knotenpunkt fungieren. Dadurch wuchs die Auflistung, viele irrelevante Zettel wurden aufgelistet. Seit diesem Release werden Zettel, die als Knotenpunkt fungieren, quasi besteuert. Intern erhalten sie wesentlich höhere Kosten als Zettel mit weniger Verweisen. Gleichzeitig konnte ich mit diesem Kostenmodell relevante Zettel auch über Schlagworte identifizieren. Je mehr Zettel es zu einem Schlagwort gibt, desto teurer sind diese. Im Endeffekt funktioniert dieses Modell in meinem eigenen Zettelstore ganz gut. Auch das Benutzerhandbuch des Zettelstore, das ja selbst ein Zettelstore ist, bestätigt dies. So vermute ich, dass bei allen Nutzern des Zettelstore, bei denen die Zettel einigermaßen verknüpft sind, der Kontext eines Zettels nützliche, weil relevante Zettel auf dem Umfeld anzeigt.

Die größte Änderung ist aktuell nur über eine neue Repräsentation von Zetteln sichtbar, dem SHTML-Format. Das S steht dabei für Symbolischer Ausdruck. Diese SHTML-Format ist dabei eine Vorstufe zum HTML-Format, das insbesondere in der Web-Oberfläche verwendet wird.

In den letzten Monaten habe ich immer mal wieder überprüft, ob das HTML, das der Zettelstore generiert, überhaupt gültiges HTML ist. Im Web-Browser sieht alles soweit in Ordnung aus, aber Web-Browser sind sehr nachsichtig, was ungültiges HTML angeht. Problematischer kann es werden, wenn das generierte HTML nicht vom (graphischen) Web-Browser konsumiert wird, sondern von anderer Software. Diese könnte bei ungültigem HTML aus dem Tritt kommen, zum Beispiel Software, die HTML in Sprache übersetzt.

Immer wieder habe ich ungültiges HTML gefunden, immer wieder die jeweiligen Stellen korrigiert. Schwierigkeiten macht nicht das eigentliche HTML, mit dem Dokumente struktuiert werden (also den sog. Tags), sondern Attributwerte, Inhalte des <script>-Tags, u.s.w. Je nach Inhaltstyp gelten unterschiedliche Regelungen. Wenn man immer wieder Fehler macht, dann kann man Software schreiben oder nutzen, damit diese Fehler vermieden werden. Sonst würden wir noch in Assembler programmieren.

Bisher generiert der Zettelstore HTML auf zwei Arten. Hauptsächlich in der Umwandlung der inneren Zettelstruktur in HTML wird das HTML in den jeweiligen internen Funktionen zusammengestellt. Dabei wird der HTML-Code als unstrukturierte Zeichenkette aufgefasst. Um den HTML-Code für die Seiten der Web-Oberfläche zu erzeugen, verwende ich sog. Templates. Ein Template ist im Wesentlichen HTML-Code mit Platzhaltern an den Stellen, an denen etwas variabel sein muss. Der Zettelstore ist in der Programmiersprache Go, dass über eine recht gute Template-Bibliothek verfügt. Da aber Templates auch Zettel sein sollen, wäre man dan daran gebunden, den Zettelstore in Go zu implementieren. Deshalb wird Mustache verwendet, für das es viele Implementierung in so gut wie allen Programmiersprachen gibt.

Der Post Producing HTML using string templates has always been the wrong solution gab mir den Anstoss zu einer nachhaltigen Änderung. Der Post beschreibt gut, warum Templates, die nur auf Zeichenketten basieren und die Struktur von HTML nicht kennen, prinzipielle Nachteile besitzen. Das gilt besonders für Mustache, in Teilen auch für Go-Templates. Viel besser ist es, auch aus Sicherheitsgründen, die innere Struktur von HTML zu berücksichtigen. Die Idee von SXML sprach mich auch deshalb an, weil der Zettelstore sowieso symbolische Ausdrücke mit Hilfe des Sexpr-Formats unterstützt.

So habe ich ein weiteres Projekt gestartet: SxHTML. Man erstellt zunächst spezielle symbolische Ausdrücke, die dann von dieser Bibliothek in HTML umgewandelt werden. Das SxHTML-Format ist also nichts weiter als die innere Struktur eines zu generierenden HTML-Formats.

Innerhalb des Zettelstore wird für die HTML-Darstellung ein Zettel erst einmal ins Sexpr-Format konvertiert, von dort aus ins SHTML-Format und dann ins HTML-Format. Da alles intern passiert, wird kein Text generiert und im nächsten Schritt gelesen. Intern sind das nur unterschiedliche Datenstrukturen, die jeweils einem Zweck genügen.

Aktuell werden nur die Zettelinhalte nach SHTML und dann nach HTML überführt. In den nächsten Releases werden die Mustache-Templates durch symbolische Ausdrücke ersetzt. LISP-Sprachen bieten dazu den Template-Mechanismus mit Namen Quasi-Quotierung. Die Mustache-Bibliothek benötige ich dann nicht mehr, die entsprechenden Zettel erhalten entweder andere Inhalte, eben die symbolischen Template-Ausdrücke, oder es gibt neue Zettel und die bestehenden werden perspektivisch gelöscht.

Womit ich schon beim Ausblick bin.

Die API nutzt an einigen Stellen noch das JSON-Format. In kommenden Releases wird dies ebenfalls durch symbolische Ausdrücke ersetzt. Damit werden dann die Bibliotheken zur Verarbeitung von JSON-Daten ebenfalls nicht mehr benötigt werden. Dieser Umstieg wird aber noch etwas dauern, wie auch obige Umstellung auf symbolische Template-Ausdrücke.

Jemand auf Mastodon meinte, dass perspektivisch der ganze Zettelstore, also auch die Software selbst, dann mit Hilfe einer LISP-Sprache implementiert werden können, analog Emacs. Nun, da wird der Mond noch häufig die Erde umkreisen. Ein Schritt nach dem anderen. Aber wenn das den Entwurfszielen des Zettelstore dient, warum nicht?

Für das Release 0.12 werde ich das Sexpr-Format dokumentieren. Zettel erhalten ein Metadatum, mit dem man das Ablaufdatum des Zettels angeben kann. Dies ist mindestens in meinem Kontext relevant, denn mein Zettelstore enthält Vorlesungsunterlagen und Notizen zu Abschlussarbeiten. Gerade die personenbezogenen Daten sollte nach der Ablauffrist gelöscht werden. Ansonsten habe ich wieder einige interne Optimierungen geplant. Mal sehen, ob davon eine so umfangreich wie die Einführung des SHTML-Formats wird. Die Ideen für die Client-Software (Zettel Mail, Zettel Presenter, Zettel Publisher) sind nicht vom Tisch.

Aber vielleicht kommt noch eine Anregung aus dem Kreis der Nutzer oder Interessierten dazu …

Update 2023-05-31: Die Bibliothek SxHTML ist umgezogen.