joerglohrerde/docs/wiki-entwurf-nostr-bild-met...

15 KiB

Strukturierte Bild-Metadaten für Markdown-basierte Nostr-Langform-Beiträge

Status: Arbeitsentwurf — eine Praxis-Konvention, (noch) kein NIP. Scope: Eine Inline-Markdown-Konvention zur Bildattribution (Urheber, Lizenz, Quelle, Bearbeitung), die in jedem Markdown-Editor direkt nutzbar ist und sich verlustfrei auf NIP-92-imeta-Tags in kind:30023-Events abbilden lässt. Ziel: Ein einheitliches, menschlich lesbares und maschinell parsbares Attributions-Format für Bilder in Nostr-Langform-Beiträgen. TULLU-BA-konform. Zero-Tool: funktioniert ohne Build-Pipeline. Zero-Loss: bidirektional konvertierbar zu imeta-Tags, sobald Publishing dazukommt.


Warum es das braucht

Markdowns native Bild-Syntax — ![alt](datei.png) — trägt nur zwei Felder: das Ziel und einen Alt-Text. Alles andere, was ein korrekt attribuiertes Bild braucht (Urheber, Lizenz, Link zur Lizenz, Quelle, Bearbeitungen — die TULLU-BA-Regel aus der deutschen Urheberrechtspraxis), hat keinen Platz.

Autor:innen haben heute drei unbefriedigende Optionen:

  1. Attribution als freier Fließtext unter jedem Bild. Gut für Menschen, nicht parsbar.
  2. Inline-HTML-<figure>-Blöcke mit <figcaption>. Bricht Markdown-Lint-Tools, schwer editierbar.
  3. Metadaten weglassen. Risiko stiller Fehlattribution.

NIP-92s imeta-Tag löst die Event-seitige Maschinenlesbarkeit (url, mime, sha256, alt usw. pro Bild). Diese Konvention liefert das fehlende Gegenstück: wie dieselben Informationen bereits im Markdown stehen können — einheitlich, lesbar, parsbar.


Konvention zur Bildattribution

Maximale Beispiel-Darstellung

Rhabarberpflanze mit großen grünen Blättern und roten Stielen in einem Gartenbeet mit Mulch garden rhubarb, Speise-Rhabarber, John Sankey, CC0, beschnitten

Maximale Beispiel-Konstruktion

![alt](imageUrl)
[title](sourceUrl), [author](authorUrl), [licence](licenceUrl), modification

Die Caption-Zeile steht auf der Zeile direkt nach dem Bild (Zeilenumbruch, kein Leerzeichen dazwischen).


Regeln

  1. Reihenfolge der Felder: alt, imageUrl, title, sourceUrl, author, authorUrl, licence, licenceUrl, modification. Die Reihenfolge ist normativ, damit Parser sich darauf verlassen können.
  2. Trenner: Komma + Leerzeichen (, ) zwischen den Caption-Feldern. Einheitlich, kein Mix aus „von", „via", Pipe usw.
  3. Verlinkungen:
    • titlesourceUrl
    • authorauthorUrl
    • licencelicenceUrl
  4. URL-Disziplin: Alle URL-Felder sind absolut (https://…), niemals relativ.
  5. CC0 / Public Domain: sourceUrl darf entfallen. Urheber:in und Lizenz bleiben aus Transparenzgründen empfohlen.
  6. Bearbeitungen: Bei CC-BY-Lizenzen ist die Änderung anzugeben, sobald das Werk verändert wurde (Zuschnitt, Farbe, Skalierung, Kombination usw.). Bei CC0 optional.
  7. Barrierefreiheit: alt ist formal optional, aber für WCAG/BITV-Konformität faktisch Pflicht. Leere eckige Klammern ![] nur bei rein dekorativen Bildern.

(Pflicht-)Felder

Feld Status Bedeutung / Form
licence Pflicht Lizenz-Kurzform (CC0, CC BY, CC BY-SA, ©, …)
licenceUrl Pflicht Kanonische Lizenz-URL, z. B. https://creativecommons.org/publicdomain/zero/1.0/
imageUrl Pflicht Absolute URL zur Bilddatei (sonst nicht renderbar)
sourceUrl Pflicht außer bei CC0 URL zur Quellseite (Link in title)
author Pflicht außer bei CC0 Name der Urheber:in
authorUrl optional Profil-/Homepage-URL der Urheber:in
modification optional (Pflicht bei Bearbeitung von CC-BY-Werken) Freitext zur Bearbeitung
title optional Titel des Werks
alt optional (faktisch Pflicht für Accessibility) Screen-Reader-Beschreibung

Minimale Beispiel-Darstellung

CC0

Minimale Beispiel-Konstruktion

![](imageUrl)
[licence](licenceUrl)

Die harte Mindestanforderung: Bild + Lizenz-Link. Alles andere darf weg, wenn es die Lizenz erlaubt (z. B. CC0).


Zwischenformen

Zwischen Minimum und Maximum sind alle Teilmengen erlaubt, solange die Reihenfolge eingehalten wird und die Pflichtfelder der jeweiligen Lizenz erfüllt sind.

CC0-Eigenbild mit Urheberangabe (empfohlen für Transparenz):

![Hase auf Wiese](cover.jpg)
Comenius-Institut, [CC0](https://creativecommons.org/publicdomain/zero/1.0/)

CC-BY-Fremdbild ohne Titel:

![Schlüssel mit Schild "Ermutigung"](ermutigung.jpg)
[Jörg Lohrer](https://www.flickr.com/photos/empeiria/8553607289/), [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)

Parsing-Regeln (für Tooling)

Die Konvention ist für Menschen geschrieben. Parser haben die Aufgabe, sich daran möglichst anzupassen — nicht umgekehrt. Sonderzeichen, Rollen-Wörter oder sprach-abhängige Marker werden bewusst nicht vorgeschrieben, weil sie den Schreibfluss behindern würden.

Ein Parser erkennt eine Attributions-Caption anhand dieser Merkmale:

  • Position: direkt nach einer Markdown-Bild-Zeile (![alt](imageUrl)), auf der nächsten Zeile ohne Leerzeile dazwischen.
  • Struktur: eine oder mehrere [label](url)-Markdown-Links, getrennt durch , , optional abschließender Freitext-Teil für modification.
  • Feld-Zuordnung nach Position in der Reihenfolge gemäß Regel 1:
    • Erster Link vor einem eventuellen Personennamen-Link = title + sourceUrl
    • Zweiter Link (Personenname) = author + authorUrl
    • Dritter Link (CC-Kürzel) = licence + licenceUrl
    • Alles danach (ohne Klammer-Syntax) = modification

Eindeutige Fälle:

  • Drei Linkstitle/sourceUrl, author/authorUrl, licence/licenceUrl in dieser Reihenfolge. Der letzte Link muss auf ein Lizenz-URL-Pattern matchen.
  • Zwei Links, zweiter matcht Lizenz-Pattern → author/authorUrl + licence/licenceUrl. Ein Titel ohne Autor:in wird konventionell nicht vergeben — das erste [Text](url) ist in zwei-Link-Fällen immer author.
  • Ein Link + unverlinkter Text + Lizenz-Link → unverlinkter Text ist author, Link vor der Lizenz wäre title+sourceUrl.
  • Nur ein Link, matcht Lizenz-Pattern → licence/licenceUrl. Minimal-Form.
  • Unverlinkter String vor der Lizenzauthor (ohne URL).
  • Freitext nach der Lizenzmodification.

Mehrdeutige Fälle (z. B. [Etwas](url), [CC0](url) — Autor oder Titel?):

  • Parser-Empfehlung: LLM-gestützter Parser nimmt Kontext dazu (Bild-Alt-Text, Body-Kontext, Plattform-Muster der URL) und ordnet zu.
  • Reiner Regex-Parser: markiert die Caption als ambigue und eskaliert zur redaktionellen Prüfung (statt zu raten).
  • Schreibende: können Mehrdeutigkeit jederzeit selbst auflösen, indem sie beide Felder setzen ([Titel](url), [Autor](url), [Lizenz](url)). Ein Titel ohne Autor:in ist die Ausnahme; wer Eindeutigkeit braucht, ergänzt die Urheber:in.

Der Parser bricht nie stillschweigend. Eine Caption ist entweder eindeutig geparst, eindeutig Minimal-Form, oder wird als prüfbedürftig markiert — nie still falsch interpretiert.


Abbildung auf das Nostr-Event (imeta, NIP-92)

Jedes Bild im Beitrag wird als eigener imeta-Tag im kind:30023-Event codiert:

["imeta",
  "url <imageUrl>",
  "m <mime>",
  "x <sha256>",
  "alt <alt>",                   wenn nicht leer
  "title <title>",               wenn vorhanden
  "source_url <sourceUrl>",      wenn vorhanden
  "author <author>",             wenn vorhanden; ein Eintrag pro Autor:in
  "author_url <authorUrl>",      wenn vorhanden
  "license <licenceUrl>",        Pflicht
  "modification <modification>"  wenn vorhanden
]

Normativ:

  • url, m, x, license sind Pflicht im imeta.
  • license ist immer die volle URL, nicht die Kurzform (maschinenlesbar, Clients können daraus die Kurzform zur Anzeige ableiten).
  • m (mime) und x (sha256) kommen nicht aus der Caption, sondern werden beim Upload zum Blob-Host (z. B. Blossom) ermittelt.

Erweiterung über NIP-92 hinaus: Die Felder title, source_url, author, author_url, modification sind keine NIP-92-Kernfelder. NIP-92 erlaubt Implementierenden ausdrücklich, zusätzliche Felder einzuführen; Clients ignorieren unbekannte Felder. Diese Konvention nutzt diese Erweiterungsmöglichkeit, um TULLU-BA-Daten direkt beim Bild mitzuführen.


Bidirektionale Abbildung (Markdown ↔ imeta)

Hinweg: Markdown → imeta

  1. Parser findet ![alt](imageUrl) im Body.
  2. Nächste Zeile wird als Caption interpretiert, Felder nach Reihenfolge-Regel extrahiert.
  3. Bild wird hochgeladen (z. B. Blossom), url/mime/sha256 werden aus der Upload-Antwort ergänzt.
  4. imeta-Tag wird aus Caption-Feldern + Upload-Daten gebaut.
  5. Markdown-Body wird angepasst: ursprüngliche imageUrl → Upload-URL. Die Caption-Zeile bleibt erhalten (oder wird entfernt, wenn der Client sie aus imeta rendert — Entscheidung des Publishing-Tools).

Rückweg: imeta → Markdown

  1. Client liest Event, extrahiert pro imeta-Tag die Felder.
  2. Rendert ![alt](url) mit alt aus dem Tag.
  3. Rendert darunter eine Caption-Zeile mit den vorhandenen Feldern in der normativen Reihenfolge aus Regel 1.
  4. license (URL) wird über einen Kurzform-Katalog (siehe Anhang) in eine lesbare Kurzform übersetzt (CC0, CC BY 4.0, …).

Weil die Reihenfolge normativ ist und die Trennzeichen einheitlich, lässt sich beides verlustfrei ineinander übersetzen.


Beispiel: End-to-End

Markdown im Editor

![Rhabarberpflanze mit großen grünen Blättern und roten Stielen in einem Gartenbeet mit Mulch](https://inaturalist-open-data.s3.amazonaws.com/photos/71812633/medium.jpg)
[garden rhubarb, Speise-Rhabarber](https://www.inaturalist.org/photos/71812633), [John Sankey](https://www.inaturalist.org/users/2831535), [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/), beschnitten

Geparst

Feld Wert
alt Rhabarberpflanze mit großen grünen Blättern …
imageUrl https://inaturalist-open-data.s3.amazonaws.com/photos/71812633/medium.jpg
title garden rhubarb, Speise-Rhabarber
sourceUrl https://www.inaturalist.org/photos/71812633
author John Sankey
authorUrl https://www.inaturalist.org/users/2831535
licence CC BY-SA 4.0
licenceUrl https://creativecommons.org/licenses/by-sa/4.0/
modification beschnitten

Als imeta-Tag im kind:30023-Event (nach Blossom-Upload)

["imeta",
  "url https://blossom.example/abc123…def.jpg",
  "m image/jpeg",
  "x abc123…def",
  "alt Rhabarberpflanze mit großen grünen Blättern und roten Stielen in einem Gartenbeet mit Mulch",
  "title garden rhubarb, Speise-Rhabarber",
  "source_url https://www.inaturalist.org/photos/71812633",
  "author John Sankey",
  "author_url https://www.inaturalist.org/users/2831535",
  "license https://creativecommons.org/licenses/by-sa/4.0/",
  "modification beschnitten"
]

Beim Rendern in einem Nostr-Client

Der Client, der dieses imeta versteht, rekonstruiert die Caption nach derselben Konvention:

![Rhabarberpflanze …](https://blossom.example/abc123…def.jpg)
[garden rhubarb, Speise-Rhabarber](https://www.inaturalist.org/photos/71812633), [John Sankey](https://www.inaturalist.org/users/2831535), [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/), beschnitten

Ein Client, der die erweiterten imeta-Felder nicht kennt, zeigt immerhin ![alt](url) korrekt an und ignoriert den Rest — Graceful Degradation.


Anhang: Lizenz-URL → Kurzform-Katalog

Lizenz-URL-Präfix Kurzform
https://creativecommons.org/publicdomain/zero/1.0/ CC0
https://creativecommons.org/publicdomain/mark/1.0/ Public Domain
https://creativecommons.org/licenses/by/4.0/ CC BY 4.0
https://creativecommons.org/licenses/by-sa/4.0/ CC BY-SA 4.0
https://creativecommons.org/licenses/by-nd/4.0/ CC BY-ND 4.0
https://creativecommons.org/licenses/by-nc/4.0/ CC BY-NC 4.0
https://creativecommons.org/licenses/by-nc-sa/4.0/ CC BY-NC-SA 4.0
https://creativecommons.org/licenses/by-nc-nd/4.0/ CC BY-NC-ND 4.0
alles andere Host der URL als Kurzform-Fallback

Locale-Suffixe (/deed.de, /deed.en) werden bei der Kurzform-Auflösung auf die Basis-URL reduziert. Für Versionen (3.0 statt 4.0) wird die Version mit angezeigt.


Offene Fragen an die Community

  1. Reihenfolge normativ oder locker? Die normative Reihenfolge macht den Parser einfach. Eine lockere Variante (Felder an beliebiger Position, Erkennung per URL-Pattern) wäre toleranter, aber fragiler. Empfehlung: normativ. Meinungen?

  2. Mehrere Autor:innen pro Bild. Ein Bild mit Ko-Autorenschaft: [Jane Doe](…) / [John Doe](…)? Oder Komma-getrennt [Jane Doe](…), [John Doe](…)? Letzteres kollidiert mit dem Feld-Trenner. Empfehlung: / als Autor:innen-Trenner innerhalb des author-Slots.

  3. Mehrere Lizenzen pro Bild. CC-Dual-Licensing (z. B. „CC BY-SA oder GFDL") — [CC BY-SA](url) / [GFDL](url) analog zu Autor:innen?

  4. Kanonischer Kurzform-Katalog. Die Tabelle ist praktikabel, aber nicht normativ. Eine Registry von Lizenz-URL-zu-Kurzform-Mappings, referenzierbar an einer Stelle, würde Interop erleichtern.

  5. Sprach-Rollen-Wörter. Diese Konvention verzichtet auf einleitende Wörter wie „Foto:", „Photo:", „Bild:". Das macht sie sprach-agnostisch. Will jemand ein optionales Rollen-Wort erlauben (*Foto: [title](url), …*), damit Attributionen in langen Texten klarer identifizierbar sind?

  6. Repo-Workflow-Ergänzung. Wer Markdown in einem Git-Repo mit Build-Pipeline pflegt, möchte manchmal Metadaten strukturiert im YAML-Frontmatter statt im Body. Ein paralleler YAML-Mapping (gleiche Felder, gleiche Semantik, Array unter images:) kann als Ergänzung leben, wobei die Inline-Markdown-Form die Basis bleibt und beides bidirektional konvertierbar ist.


Referenzen