Mein großer Wunsch für die Zukunft des Internets ist mehr Eigenständigkeit. In den letzten Jahren hat sich das Internet zu wenigen zentralen Spielorten verändert,

Struktur der Dateien

1. Idee: Untergliederung in Abschnitte

Type(1): Markdown | Plain | HTML | Razor | Hidden | Twitter | Facebook
Share-With(*): friends, jon, public
Reference(?): https://twitter.com/datenkanal/status/1128979313636913152 | https://www.facebook.com/events/2349550201778089/
Source(*): (Quellenangabe) https://
Hidden-Source(*): (Quellenangabe, wird aber nicht ausgegeben)
Anchor(?): HTML-Anker in der Ausgabe
Tag(*): tagX
Tags(*): tag1, tag2
Creation-Date(1): 2019-05-18T11:19+02:00
Author(+): …
Licence(1): CC-by-sa | /legal.html
Summary(?): Zusammenfassung für <meta type=description>

Content of this section
#####
Type: Hidden
Share-With: dies hat keine Bedeutung
Reference: Not used

Dieser Text wird nicht ausgegeben und kann für Notizen genutzt werden
#####
Type: Twitter
Reference: https://twitter.com/datenkanal/status/1128979313636913152

$TEXT
<blockquote class="twitter-tweet" data-lang="de">
  <p lang="de" dir="ltr">Wie immer könnt Ihr Euch auch während der Sendung im Matrix-Raum
    <a href="https://t.co/4pODta98zk">https://t.co/4pODta98zk</a> an der Sendung
    beteiligen.</p>&mdash; Datenkanal (@datenkanal)
    <a href="https://twitter.com/datenkanal/status/1128979313636913152?ref_src=twsrc%5Etfw"
    >16. Mai 2019</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

2. Idee:

Dokument besteht aus optionalem Kopfteil und Rumpf. Der Kopf ist zeilenweise wie bei E-Mails in eine Liste von Feldern geteilt.

Type(1): Markdown | Plain
Base(?): name of an outer frame for this body
Param(*): user: Option<User>
Param(*): content: Document = FnOnce(Context) -> Result<(), Error>
Prelude:
  fn helper() {
    let a = 7;
  }
Share-With(*): friends, jon, public
Tag(*): tag with space or other special characters
Tags(*): tag1 tag2
Creation-Date(1): 2019-05-18T11:19+02:00
Author(+): …
Licence(1): CC-by-sa | /legal.html
Summary(?): Zusammenfassung für <meta type=description>

This is *the* body. <me@example.org>

@twitter("https://twitter.com/datenkanal/status/1128979313636913152")

@facebook("…")

@ref("https://zeit.de/")

@@ => @
@[a-zA-Z0-9:_.&]+

expressions:
@(…) => ….to_html(ctx)?;
@abc => abc.to_html(ctx)?;

call:
@content() => content(ctx)?;
@ctx.func() => ctx.func()?;

code:
@{…} plain code => …
@// and @/* */
@if … { } else { }
@for … {
@while … {
@loop {
@let …;

Block:
code
@// @/* */
@{…
}$

@…;$

@…{$
}$

expression:
@[a-z…]$
@(…
)$

call:
@…(…)$

Generierter Code:

fn page(ctx) -> Result<(), Error> {
    // prelude
    fn helper() {
      let a = 7;
    }

    let body = |ctx| {
        ctx.set_source("file", byte_offset, line);
        ctx.write_literal("This is ")?;
        ctx.write_emph("the")?;
        ctx.write_literal(" body. ")?;
        ctx.write_url("me@example.org")?;
        ctx.end_paragraph()?;

        ctx.set_source("file", byte_offset, line);
        twitter(ctx, "…")?;

        Ok(())
    };

    base(ctx, body)
}

fn base(ctx, body) {
}

fn begin_paragraph(self) -> Result<(), Error> {
    if !self.in_paragraph {
        self.in_paragraph = true;
        self.write("<p>")?;
    }

    Ok((())
}

fn end_paragraph(self) -> Result<(), Error> {
    if self.in_paragraph {
        self.in_paragraph = false;
        self.write("</p>")?;
    }

    Ok((())
}

fn write_literal(self, txt) -> Result<(), Error> {
    self.begin_paragraph()?;
    self.write(txt)
}

fn twitter(ctx, text, id) -> Result<(), Error> {
    self.end_paragraph()?;
    if id.is_empty() {
        ctx.db.register_tweet(text, ctx.file(), ctx.offset());
    } else {
        self.write(r#"<blockquote class="twitter-tweet" data-lang="de"><p>"#)?;
        …
        self.write("<a href=\"https://twitter.com/>")?;
        self.write(id)?; // => datenkanal/status/1128979313636913152
        self.write(">")?;
        self.write(tweet_date)?;
        self.write("</a></blockquote>")?;
        if !ctx.FOO("twitter-widget-loaded") {
            self.write(r#"<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>"#)?;
        }
    }
}