Mastodon
2021-11-02T04:00:00+02:00

Browser Lesezeichen in Org-Mode speichern

Lesezeichen sind ein Musterbeispiel für einfache Text-Dateien

Das Problem begann eigentlich schon vor knapp 30 Jahren. Es war sehr einfach im Browser ein Lesezeichen zu einer Seite zu speichern, und genau so einfach war es auch die Seiten danach wieder damit aufzurufen. So sammelten sich im Laufe der Zeit mehr und mehr Lesezeichen an, und wenn dann eine neue Version des Browsers erschien, war es eine mühsame Arbeit die Datei mit den Lesezeichen in das passende Verzeichnis des neuen Browsers zu kopieren.

Immerhin hatten die Hersteller schnell begriffen, dass dies ein Problem war, und boten bald dann eine Möglichkeit an die Lesezeichen automatisiert von einer Vorgängerversion zu übernehmen. Nun arbeiten Menschen aber durchaus mit mehr als einem Browser, und es wurde immer klarer, das es sehr praktisch ist wenn man sowohl auf dem Rechner zu Hause, als auch auf dem Laptop, oder dem Firmen-Rechner die gleichen Lesezeichen zur Verfügung hat.

Damit begann zu erst die Zeit der Online- Lesezeichen Speicherdienste, die über ein Browser-Plugin die Favoriten in ihre Verzeichnisse aufnahmen, später bauten auch alle großen Browserhersteller eine Funktion ein um die Lesezeichen zwischen verschiedenen Browsern zu synchronisieren, was wiederum den Niedergang der Online-Speicherdienste einläutete.

Ich habe damals auch so einen Dienst benutzt, auch weil es praktisch war, seine eigenen Lesezeichen für andere Personen freizugeben. Dennoch sind mir immer wieder Lesezeichen abhanden gekommen, wenn mal das Plugin nicht richtig funktionierte, und Unmengen von Dubletten waren an der Tagesordnung.

So kam es, das ich mich entschied meine Lesezeichen ab jetzt an einem zentralen Ort zu sammeln, der unabhängig von Browser und Internet sein sollte. Seit damals, bis heute ist das eine reine Textdatei, und das Format ist auch nur wenig geändert wurden. Ich habe schon immer den Link gespeichert, und zu Anfang einfach noch ein paar Stichworte dazu geschrieben. Seit einigen Jahren bin ich beim jetzigen Format einem Org-Mode Link inklusive dem Seitentitel, plus einem Zeitstempel, wann ich das Lesezeichen erzeugt habe, angekommen.

Dadurch ist das aufrufen von Seiten ein Kinderspiel. Im Org-Mode von Emacs sind Links einfach anklickbar, und rufen das konfigurierte Programm, also am besten einen Browser, auf.

Das Abspeichern der Links war schon immer eine eigene Baustelle und läuft bei mir mittlerweile in der dritten Fassung

Die Emacs Seite

Auf der Empfängerseite, also in Emacs war die Lösung von Anfang an sehr einfach. Hier gibt es einen Mechanismus der sich Org-Capture nennt. Dieser ist eigentlich dazu gedacht, um neben der normalen Arbeit an einem Text mal eben eine Information zu einem Anruf, oder einem Gespräch mit dem Kollegen, der gerade ins Büro kam festzuhalten. Neben dem normalen Fenster geht ein weiteres Fenster auf, in das man seine Notiz eintragen kann, und diese wird dann an einem festgelegten Ort gespeichert. Dabei lassen sich Templates nutzen, die z.B. bereits Datum und Uhrzeit des Eintrags hinzugefügt haben, noch bevor man los tippt.

Passend zu diesem Mechanismus gibt es das Capture-Protocol. Dadurch wird es möglich Emacs von aussen her aufzurufen, und als Aufrufparameter Informationen mitzugeben, die dann in ein solches Template eingetragen werden, und in die entsprechende Datei eingetragen.

Wer dieses Protokoll nutzen möchte stößt allerdings schnell auf zwei Probleme, die sich allerdings beide lösen lassen:

  • Da es sich um ein neues Protokoll handelt wird dieses vom Betriebssystem behandelt, und muss diesem zunächst mal bekannt gemacht werden. Das bedeutet unter Windows das anlegen von Registry Einträgen, und unter Linux das schreiben (wenn auch sehr kleiner) Konfigurationsdateien. Ohne diese Bekanntgabe passiert absolut nichts. Das Betriebssystem muss wissen, das es jedes mal den Emacsclient aufruft, wenn jemand das org-capture-protocol verwendet.
  • Die Syntax des Aufrufs hat sich im Verlauf der Emacs Versionen einmal geändert, so das es quasi zwei verschiedene Versionen gibt, wie es richtig funktioniert, und auch wenn mittlerweile wohl nur noch Emacs Versionen mit der neuen Syntax in Gebrauch sein sollten, stammen sehr viele Erklärungen im Internet noch aus der Zeit der alten Syntax, die umständlicher, und dazu noch weniger flexibel war. Leider wird fast nirgendwo darauf hingewiesen, dass es mittlerweile eine neuere, bessere Syntax gibt. Selbst Anleitungen, die die neue Syntax zeigen, erwähnen selten, dass es auch mal eine alte Syntax gab, und so geraten Anfänger schnell in die Falle beide Versionen für die Wahrheit zu halten, und sie munter zu mixen, was dann dazu führt, das es überhaupt nicht mehr funktioniert.

Hat man diese beidem Probleme aber einmal erkannt, lässt sich das ganze schnell korrekt konfigurieren (und so schwer ist das dann auch nicht mehr). Ein Tipp: Die aktuelle Syntax findet sich in der Dokumentation, die man sowohl online, als auch innerhalb von in der Hilfe findet.

Die Browser-Seite

Um in Emacs ein Lesezeichen abzuspeichern reicht also ein Aufruf von

emacsclient "org-protocol://capture?template=L&url=%%TAB-URL%%&title=%%TAB-TITLE%%"

Der Browser muss also einfach nur diesen Aufruf hinbekommen, und der Drops ist gelutscht. Leider ist der Aufruf von ausführbaren Programmen von der Platte des Benutzers auch eine riesige Sicherheitslücke, denn wenn ein Angreifer das von einer Internetseite aus tun kann, kann er auch Schadcode dort ausführen. Entsprechend haten die Browser Hersteller keinen einfachen Weg dafür in ihre Browser eingebaut.

Iteration 1

Mein erster Weg damit umzugehen, war es mir einen anderen Browser zuzulegen. Ich hab mir damals Qutebrowser ausgesucht, weil er eine Funktion bot, jede Funktion des Browsers mit einer Tastenkombination zu verbinden. Dazu war noch eine sehr wichtige Funktion eingebaut, mit der man beliebige Programme aufrufen konnte, und der Browser konnte dazu die URL, den Namen der Seite, oder den markierten Text als Aufrufparameter einsteuern. Der Ansatz war also trivial: einfach Ctrl-D mit dem Aufruf eines kleinen Python-Scripts verbunden, das die URL passend formatiert, und dann den Emacsclient aufruft.

Es war ein Traum. … bis zu Debian 10. Dann stellte sich heraus, dass die Versionen von Python, und die von Debian installierten Qt-Bibliotheken für Python unterschiedliche Abhängigkeiten hatten, die sich widersprachen, kurz es knallte an allen Ecken und Enden, und die Lösung wäre es gewesen eine isolierte Python umgebung zu schaffen, mit gepinten Versionen der einzelnen Pakete, und das wollte ich mir dann doch nicht antun.

Es wurde also Zeit für

Iteration 2

Wenn ich den Qutebrowser sowieso nicht mehr nutzen konnte bin ich also wieder zurück zu einem der Standardbrowser gewechselt - Firefox

Hier gab es also wieder das bekannte Problem, dass Firefox nicht besonders gewillt ist externe Programme aufzurufen, und ich habe ein wenig gegrübelt, wie sich das am besten umgehen lässt, ohne die Sicherheit von Firefox auszuhebeln. Die Lösung lieferte dann meine Freundin quasi frei Haus. Wir unterhielten uns eines Tages darüber, das Ihr Arbeitskollege unter Windows sehr virtuos Standard-eMails schreibt, indem er alle wichtigen Textbausteine in einer Software namens Klavier hat, und auf Knopfdruck abrufen kann, verbunden mit der Frage, ob sie das nicht auch irgendwie installieren kann. Nun, für die Software hatte ihr Kollege wohl eine Lizenz gekauft, und das Geld wollte sie nicht ausgeben, aber ich hab eine Software namens AutoHotKey gefunden, die quasi das gleiche kann, und mit der sie seither arbeitet.

Neugierig geworden wollte ich sehen, ob es so etwas auch für Linux gibt (ich hab es nie gebraucht, da Emacs ein paar eingebaute Wege hat mit Textbausteinen zu arbeiten).

Und ich fand ein Programm namens Autokey, und schon die ersten Beispiele, die ich sah zeigten auch, das es auch mit dem Clipboard umgehen kann, und auch externe Programme aufrufen. BINGO!

Von da an ging es ganz schnell. Ich hab Autokey installiert, und CTRL-D mit einen Script belegt das den Cursor in die URL-Zeile setzt, alles markiert, und die URL ins Clipboard kopiert. Mit dieser URL wurde dann mein altes Python-Script aus Iteration 1 aufgerufen, und Voila, die URL landete wieder in meinem Emacs, und damit in der Link-Datei.

Es waren wieder friedliche Zeiten. So einigermaßen.

Denn leider konnte ich so den Seitentitel nicht übernehmen, und musste im Nachgang nochmal ein Skript über meine Links laufen lassen, welches zu jedem Link den Seitetntitel holte, und den Org-Link entsprechend anpasste. Es funktionierte, aber meine Nerd-Seele litt. Ich wollte EINEN EINZIGEN SCHRITT mit EINEM Tastendruck.

Ich begann also die Suche nach

Iteration 3

Ich hab dann angefangen die Firefox AddOns nach Erweiterungen zu durchsuchen, die es irgendwie doch ermöglichen ein externes Skript aus dem Browser zu starten. Die ersten Ergebnisse trieben mir eine Gänsehaut nach der anderen über den Rücken, viele davon verlangten, einen nicht näher beschriebenen Code aus dem Internet zu laden, bei dem der Autor versprach, das er das Problem löst, aber nicht wie, oder ob damit die Browser Sicherheit ausgehebelt wird. Viele dieser Erweiterungen sind mittlerweile aus den AddOns verschwunden, und ich habe mich auch nie getraut, eine davon zu installieren.

Bis ich auf RunWith stieß. Auch hier muss man zwei weitere Dateien auf seinem System installieren, und eventuell war das auch genau der gleiche Mechanismus, wie die anderen AddOns die ich so ignoriert hatte, allerdings machte der Autor zwei entscheidende Dinge anders, als die Pakete, die mir so dubios erschienen. Er zeigte die beiden Dateien ganz offen, und erklärte ihre Funktion Stück für Stück, so dass ich nachvollziehen konnte, wozu ich diese brauche und er stellte ihre Funktion dar, in einen Framework, das sich Native Messaging nennt, und das die von den Browserherstellern bevorzugte sichere Methode ist externe Programme aus einem Browser aufzurufen, und mit Parametern zu versehen. Also exakt das, wonach ich gesucht habe.

URL, Seitentitel und markierter Text gehören auch hier zu den Standard Parametern, die übergeben werden können, aber darüber hinauch auch Bild-URLs oder die Art der Objekts von wo das Skript aufgerufen wurde, denn im Standard enthalten ist auch, das ich beim Klick nur Scripte angezeigt bekomme, die in der jeweiligen Situation sinnvoll sind. Wenn ich also einfach irgendwo auf der Seite dieses AddOn aufrufe bietet es mir an ein Script für ein Lesezeichen auszuführen. Habe ich hingegen einen Teil der Seite markiert, wird zusätzlich ein Script angeboten, das mir den markierten Text als Zitat speichert, und die URL als Quelle darunter schreibt.

Die zentrale Datei der Native Messaging Host ist hier in Python geschrieben, und damit schon mal auf seinen Inhalt überprüfbar. Darüber hinaus beschreibt der Autor auf der Homepage noch sehr schön wie die Schnittstelle aussieht, die ein Skript zur Verfügung stellen muss, um als NM Host fungieren zu können, und welche Aufgaben die einzelnen Teile des Skripts dabei übernehmen. Das ist nicht nur genug um mein Vertrauen zu gewinnen, sondern geradezu vorbildlich.

Ich hoffe daher, dass Iteration 3 damit die letzte Station auf der Reise zur perfekten Bookmark Lösung für mich war. Dabei bleibt wieder einmal eine Erkenntnis zurück. Obwohl alle 3 Iterationen technologisch vollständig unterschiedliche Ansätze waren, konnten alle perfekt mit einer Textdatei arbeiten, und ich möchte mir nicht ausmalen wie es gelaufen wäre, wenn diese auch noch in einem proprietären Dateiformat abgelegt wären.

Dazu kommt noch, das ich diese Textdatei einfach in HTML exportieren kann, und das Ergebnis ist dann unmittelbar die LINKS Seite dieses Blogs, bei der einfach alle privaten Links nicht exportiert wurden.