[Home^][4stack>][b16>][Gforth>][bigFORTH>][Wiki Forth*]

[CMSv][Steueranweisungenv][Komfortv]

Wiki Forth

Wiki Forth (WF) ist ein kleines CMS (Content Management System) in Forth. Der Name kommt daher, dass WF eine Spache benutzt, die denen der verschiedenen Wikis ähnlich sieht, also weitgehend normaler Text mit ein paar Steuerzeichen eingestreut. Bis auf ein paar historische Reste ist meine ganze Homepage in WF geschrieben. Die aktuelle Version von WF erzeugt W3C-konformes XHTML mit CSS. Es gibt zwar Browser, die das nicht so richtig können und trotzdem versuchen (Netzkappe 4 und Internet Exploder), die Seiten sind aber auch ohne CSS noch lesbar.


Was ist ein CMS?

Ein CMS soll die Verwaltung von Web-Seiten erleichtern. Gerade wenn die Seiten etwas umfangreicher sind, und öfter hier und da etwas geändert wird, ist das sinnvoll. Natürlich sollen Inhalt und Form voneinander getrennt sein. Bei der Eingabe konzentriert man sich auf den Inhalt; die Seiten werden dann entsprechend dem gewählten Stil umgesetzt.

Zudem sollte ein CMS noch Verwaltungsfunktionen anbieten, etwa tote Links erkennen (innerhalb des verwalteten Bereichs), und andere automatisch generierbare Informationen zur Verfügung stellen. Eine sehr wichtige Funktion ist für mich z.B. die Größe einer verlinkten Datei anzugeben.


Die Steueranweisungen

Die Steueranweisungen teilen sich in drei Gruppen auf:

Globale Informationen

Die globalen Informationen sind als Forth-Befehle am Anfang der Seite zu finden. Eine Seite wie diese enthält zumindest einige minimale Informationen über den Maintainer und dessen E-Mail-Adresse, das erste Dokumentdatum und das zugehörige Style-Sheet.

maintainer Bernd Paysan <bernd.paysan@gmx.de>
created 11apr2004
css "wf.css"

Hat die Seite ein Menü, stellt man es hier zusammen. Menüs sind Links, enthalten also einen Text und eine Datei, getrennt durch das Pipe-Symbol |. Aus dem Text kann man ein Icon generieren lassen.

up-toc Home|index.html
top-toc 4stack|4stack.html
top-toc b16|b16.html
top-toc Gforth|gforth.html
top-toc bigFORTH|bigforth.html
this-toc Wiki Forth|wf.html
sub-toc CMS|wf.html#CMS
sub-toc Steueranweisungen|wf.html#ST

Die Icons generiert am besten der Gimp. Alle Icons werden im Unterverzeichnis navigate abgespeichert. Dort wird auch eine Gimp-Batch-Datei erzeugt (nav.scm), der nur noch das (gimp-quit 0) als letzte Zeile fehlt. Den Gimp ruft also auf mit

echo '(gimp-quit 0)' >>navigate/nav.scm
gimp -i --batch '(load "navigate/nav.scm")'

auf. Als Basis für die Generierung des Navigationsbuttons dient die Datei navigation.scm - die muss man in das scripts-Verzeichnis vom Gimp kopieren. Als leeren Button verwendet die eine Datei button.jpg, deren Pfad in navigation.scm drin steht. Als Font wird der Blippo-Font aus dem Freefont-Packet verwendet. Man kann natürlich auch einen der vielen bereits vorhandenen Button-Funktionen im Gimp nehmen, aber Gimp-Programmierung ist jetzt ein anderes Thema.

Die eigentliche Seite wird mit dem Wort wf eingeleitet. Dem folgt die erzeugte HTML-Datei und der Seitentitel. wf scannt die Eingangsdatei, bis es auf einen einzeln stehenden Punkt trifft; hier endet die Seite.

wf wf.html "Wiki Forth"

Struktur des Dokuments

Die Steueranweisungen für die Grobstruktur orientieren sich am Emacs-Outline-Mode. Überschriften beginnen mit ein, zwei oder drei Sternen (h1 bis h3 in HTML). Jedem Element kann man ein Label zuordnen, indem man && label in die Zeile davor stellt. Horizonale Leisten erzeugt man mit ---. Untermenüs mit -- label, hier werden die Sub-Menüs wieder erzeugt, und das aktuelle markiert.

Natürlich kann man auch Listen anlegen. << startet eine Liste, >> beendet sie. Ob die Liste mit Punkten oder Nummern markiert wird, entscheidet das Startzeichen: - für Punkte, + für Nummern. Die Zeichen ? und : sind für descriptive Listen reserviert, wobei ? einen Titel einleitet, und : die eingerückte Erklärung.

Wenn die Struktur über mehr als einen Absatz gehen soll, hängt man an's Startzeichen noch zwei << dran, und beendet das Ganze mit >>. Dabei sind natürlich wieder Unterstrukturen erlaubt.

Unformatierten ASCII-Text (für Listings) bindet man mit :code .. :endcode ein, oder mit :code-file datei gleich eine ganze Datei.

Implementiert werden werden diese Wörter alle in einer Wordlist namens longtags. Interpretiert werden sie, wenn sie am Anfang eines Absatzes stehen. Steht kein verwertbares Wort am Anfang eines Absatzes, wird er als ganz normaler Absatz gesetzt:

: section-par ( -- )  >in off
    bl sword longtags search-wordlist
    IF    execute
    ELSE  source nip IF  >in off s" p" par  THEN  THEN ;
: parse-section ( -- )  end-sec off
    BEGIN  refill  WHILE
	section-par end-sec @ UNTIL  THEN ;

Inline-Elemente

Innerhalb des Texts will man natürlich auch noch Variationen verwenden. Etwa fette oder hervorgehobene Texte. Oder Schreibmaschinenschrift. Natürlich auch noch [html]Links oder Bilder. Oder [html]Bilder im Link.

Diese Tags bestehen aus einzelnen Buchstaben am Anfang eines Wortes. * steht für fett, _ für unterstrichen, und # für Schreibmaschinenschrift. Wer einen dieser reservierten Buchstaben braucht, kann sie in eine Tilde ~ einfassen.

Bilder haben folgende Syntax: {Text|URL}. Links sind fast gleich aufgebaut: [Text|URL], allerdings darf der Text auch Bilder enthalten. Ein paar Sonderzeichen direkt nach dem | werden in Optionen umgesetzt.

Link-Optionen

Links werden normalerweise automatisch mit einem Icon versehen. Icons kann man für ganze URLS vergeben, oder für bestimmte Suffixe. Bei der Suche nach dem Icon wird die URL stückweise nach . durchsucht, und der Rest als Dateiname im Unterverzeichnis icons mit angehängtem .* gesucht. Das gefundene Icon (GIF, PNG oder JPEG) wird dann vor den eigentlichen Link-Text gesetzt. Wer das verhindern will, setzt als Options-Zeichen ein \.

Längere Dateien (für Downloads) sollte man immer mit der Größe versehen. Dafür ist die Link-Option % vorgesehen. Die hängt die Größe der Datei in Kilobytes (oder Megabytes, wenn's mehr als 2 sind) hinter den Link (in Klammern). Natürlich kann man beide Link-Optionen gleichzeitig verwenden, die Reihenfolge spielt dann keine Rolle.

Ich signiere Software-Downloads. Auch hier gibt es einen Automatismus: Wenn es zum Link eine zugehörige .sig-Datei gibt, wird der Link auf diese Datei automatisch eingebunden.

Bilder-Optionen

Hier gibt es mehr Optionen, und die Reihenfolge spielt auch eine Rolle. Zunächst einmal kann man Bilder ausrichten.

l, <
Bild wird links ausgerichtet (class "left", genaues bestimmt das Style-Sheet).
r, >
Bild wird rechts ausgerichtet (class "right")
c, =
Bild wird zentriert (class "center")
~
Bild wird zentriert (class "middle")

Normalerweise bekommen Bilder in Links immer einen Rahmen. Will man das verhindern (oder einen schmaleren Namen verwenden), muss man das natürlich auch deklarieren.

-
Bild bekommt gar keinen Rahmen (class border0)
+
Bild bekommt einen Rahmen der Größe 1 (class border1)

Allen Bildern wird automatisch die Größe mitgegeben, damit der Browser die Seiten schon komplett rendern kann, bevor die Bilder geladen sind.

Tabellen

Tabellen sind ein Thema für sich, schließlich erlaubt HTML sehr viel mit Tabellen anzustellen. Zur Zeit sind nur die wichtigsten Features implementiert. Die Formatierung lehnt sich dabei an LaTeX an.

Zunächst fangen Tabellen mit <| Format [Border] an. Die Format-Zeichen gelten für die jeweilige Spalte der Tabelle, und bedeuten folgendes:

l, < left alignment
r, > left alignment
c, = left alignment

Zeilen innerhalb der Tabelle sind eingerahmt, je nach Bedeutung:

+| .. |+ Zeile enthält table headers (Kopfzeilen)
-| .. |- Zeile enthält normale Tabelleneinträge
=| .. |= Zeile beginnt mit einer Kopfzeile, normale Tabelleneinträge folgen

Einträge, die über mehrere Spalten gehen, benötigen eine eigene Formatanweisung. Diese beginnt mit / für Zellen, die mehrere Zeilen überspannen, \ für mehrere Spalten. Die folgende optionale Ziffer gibt die Zahl der Zeilen oder Spalten an (Default ist eine Zeile/Spalte). Danach kann noch ein Formatzeichen kommen (siehe oben). Es ist möglich, beide Formatanweisungen zu verwenden, wobei zuerst / und dann \ kommen muss.

Das kann man natürlich nur an einem Beispiel zeigen. Eine einfache Tabelle sieht etwa so aus:

<| clrr 1
+| Menge | Artikel | Preis | Summe |+
-| 3     | Äpfel   | 0,30  |  0,90 |-
-| 1     | Banane  | 0,50  |  0,50 |-
=| \3l Gesamtpreis         |  1,40 |=
|>
Menge Artikel Preis Summe
3 Äpfel 0,30 0,90
1 Banane 0,50 0,50
Gesamtpreis 1,40

Eine komplexe Tabelle zeigt alle Möglichkeiten:

<| rccl 2
+| /3 1 | 2 |\2c 40  |+
-| /3\2c center | 6  |-
-|                8  |-
-| /2 9 |         1  |-
=| \2r 12   |/r   4  |=
-| 1    | 2 | 3 | 40 |-
-| 1234 | 1243 | 1234 | 1234 |-
|>

gibt

1 2 40
center 6
8
9 1
12 4
1 2 3 40
1234 1243 1234 1234

Man muss bei solchen komplexen Tabellen natürlich immer die ausgelassenen Tabellen im Kopf behalten.


Komfortfunktionen

Neben der eigentlichen Texteingabe braucht ein CMS natürlich noch mehr Komfort.

Autoreplaces

So sollen vielleicht bestimmte Schlüsselwörter immer als Link erscheinen (wie bei einem Wiki). Dazu gibt es autoreplaces. Diese Wörter werden zu Links expandiert, wann immer sie im Text auftauchen. Beispiel:

autoreplace ForthGesellschaft [Forth Gesellschaft|http://www.forth-ev.de/]

ersetzt jedes Vorkommen von "ForthGesellschaft" durch den entsprechenden Link [html]Forth Gesellschaft .

Datenbank

Man kann sich natürlich noch komplexere Einträge vorstellen als einfache Links. Das braucht sowas wie eine einfache Datenbank. Zugriff hat man auf den Eintrag über das Schlüsselwort, eingefügt wird ein Text, der sich aus den einzelnen Feldern zusammensetzt. Ich verwende diese Datenbank an zwei Stellen: Für meine Changelog-Einträge in bigFORTH, und für Projektmitarbeiter auf den Intranetseiten in der Arbeit (die Mitarbeiter haben immer dieselben Daten, die man natürlich nicht für jedes Projekt nochmal eingeben will). Hier will ich nur die Changelog-Datenbank erklären. So ein Eintrag sieht etwa so aus:

change: 01sep2003
Version: 2.0.11
minos: 1.0.0
text: fixes a few bugs, like FORTH-WORDLIST being commented out, and
problems with read only filesystems (like Knoppix). Also fixed OpenGL
bindings, created a new setup script for Inno Setup 3.x, and a windows
distribution. Fixed Makefile and configure process so that the windows
version can be compiled from source with #./configure; make# when
cygwin is installed. Bumped up MINOS version to 1.0.0 (there are
little further changes to expect).
.

Das Datum dient dabei als Schlüsselwort. Der Code dazu ist auch nicht so schwer. Zunächst einmal definiert man sich die Tabelle (aus Text-Feldern und Absätzen), die Ausgabe-Prozedur ist ein deferred Word, weil sie natürlich erst später definiert werden kann:

Defer .log
' .log 4 table: change:
field: version:
field: minos:
par: text:

Das war noch einfach. Die Tabelle besteht aus vier Feldern mit den Namen change:, version:, minos: und text:. Beim Aufruf wird .log ausgeführt. Was soll da passieren? Es sollen die Versionen mit dem Wort ?rev ausgegeben werden, und der Text als solcher (ohne besondere Methode; die Datenbank weiß, wie man Paragraphen ausgibt). db-par scannt durch den Text bis es an eine Punkt am Zeilenanfang ankommt. Variablen stehen in %, werden sie nicht mit der Standardmethode ausgegeben, muss der gewünschte Forth-Code mit | abgetrennt werden (es ist auch mehr als ein Befehl erlaubt).

: .rev ( addr u -- ) s" b" tagged ;
: ?rev ( addr u -- ) dup 0= IF  2drop  EXIT  THEN  .rev ;
: .entry-rest ( addr -- ) 
    db-par The version %version:|?rev% from %change:|?rev% %text:% 
. ;
: .entry-par ( addr -- )
  LT -<< .entry-rest LT >> ;

' .entry-par is .log

Als Besonderheit gibt .last noch den zuletzt definierten Changelog-Eintrag etwas anders formatiert aus:

: .last ( -- ) last-entry @
    db-par Current version is bigFORTH %version:|.rev%, Minos beta 
%minos:|.rev%, from %change:|.rev%.
. last-entry @ .entry-rest ;

Created 11apr2004. Last modified: 25nov2015 by MailBernd Paysan