python -m http.server 8080
startet einen Web-Server im aktuellen Verzeichnis. Unter der Adresse http://localhost:8080/
bzw. http://127.0.0.1:8080/
kann man den Webserver aufrufen. Er liefert alle Dateien im aktuellen Verzeichnis aus.
SVGs haben einige Vorteile bei der Textgestaltung: In Inkscape kann man mit Alt+< die Buchstaben in einem Text näher zusammenrücken (mit Alt+> weiter auseinander). Einzelne Buchstaben zurechten des Cursors kann man mit Alt+Links bzw. Alt+Rechts hin-und-herrücken (auch Alt+Hoch und Alt+Nieder geht).
Indem man den Text in einen Path umwandelt, wird er darstellbar unabhängig von installierten Fonts. Man kann ihn dann aber nicht mehr editieren. Immerhin erzeugt Inkscape ein Attribut namens ‘aria-label’, das den ursprünglichen Text enthält.
Ich würde gerne SVG in großem Umfang für das Web einsetzen.
Frage: Gibt es eine Möglichkeit, das Inkcape-SVG optimal für das Web zu kompilieren?
Inkscape (Version 1.2) hat einen HTML-5-Canvas-Export. Der liefert aber Müll und ist sowieso sinnlos, da das SVG ja SVG bleiben soll und nicht in JavaScript umgewandelt.
Besser ist die Möglichkeit, das SVG mit ‘Save as Optimized SVG’ abzuspeichern, es gibt dafür ein Dialogfenster mit etlichen Optionen. Dieser Export beruht auf dem Programm: Scour - An SVG Scrubber (https://github.com/scour-project/scour
). Funktioniert bei mir nicht, da das Plugin nicht installiert ist. Mit pip install scour
kann man aber eine Stand-Alone-Version installieren.
Weitere beliebte SVG-Optimier-Tools sind SVGO (https://github.com/svg/svgo
) und svgcleaner (https://github.com/RazrFalcon/svgcleaner
).
svgcleaner ist seit 2019 in Entwicklungsstasis, SVGO wird 2023 noch weiterentwickelt.
svgcleaner hat gute Dokumentation: https://github.com/RazrFalcon/svgcleaner/blob/master/docs/svgcleaner.adoc
.
Batik (https://xmlgraphics.apache.org/batik
) ist ein Java-SVG-Tool und eine Bibliothek.
java -jar batik-ttf2svg.jar -autorange "some-font.ttf" -o "some-font.svg
kann einen ttf-Font in einen SVG-Font umwandeln, vielleicht nützlich.
https://github.com/vercel/satori
kann HTML und CSS in SVG umwandeln.
https://github.com/rossmoody/svg-gobbler
ist ein Browser-Addon, das SVGs auf Websiten findet und runterladen kann.
https://github.com/shrhdk/text-to-svg
ist eine Javascript-Bibliothek, die einen Text in SVG umwandelt. Das ist aber nicht genau das, was ich will. Ich will ein Tool, das ein SVG mit Text in ein SVG ohne Text aber mit Paths umwandelt. Das hier wandelt reinen Text in einen SVG-Pfad um. (zu installieren mit npm install --save text-to-svg
)
https://github.com/paulzi/svg-text-to-path
ist vielleicht das Richtige. Ebenfalls eine Node.js-Bibliothek. npm install -g svg-text-to-path
hat die Installation von 81 Paketen getriggert. Kann von der Commandline aus benutzt werden. Aber gefährlich: Wenn svg-text-to-path in.svg
ohne output-file-option -o out.svg
oder Pipe-Redirect (das funktioniert auch) aufgerufen wird, ersetzt es das Input-File!
https://github.com/javedblch/svg-text-to-vector
ist auch eine Node.js-Bibliothek, die SVGs erzeugt.
https://github.com/caesarsol/svg-text-to-path
ist eine Alternative dazu in Ruby, dessen Installation zu kompliziert ist für jemanden, der Ruby noch nie benutzt hat.
https://macsvg.org/
ist eine Open-Source-Mac-App zum Erstellen von SVGs. Es ist ärgerlich, dass es bei mir nicht läuft. Die aktuelle Version 1.2 läuft ab Mac OS 10.14, 1.1.5 ab Mac OS 10.11, ebenso die älteste Version 1.0.0.
https://github.com/donbright/font_to_svg
ist eine C++-Header-only-Bibliothek, mit der man einzelne Buchstaben in ein SVG umwandeln kann.
https://fontlibrary.org/
ist eine interessante Font-Webseite (https://fonts.google.com/
gibt es auch noch).
Am besten ist wahrscheinlich, Inkscape selbst als Commandline-Tool zu benutzen. Das geht.
Die Option “-T” bzw. “–export-text-to-path” sollte das Gewünschte vollbringen.
z.B. inkscape -T -o out.svg test.svg
oder
inkscape -T -o - test.svg | svgcleaner -c - >clean.svg
funktioniert gut.
inkscape -T -o - test.svg | scour --remove-metadata | svgcleaner -c - --remove-declarations=no --remove-nonsvg-attributes=no >clean.svg
beläßt den Text im aria-label auch in der cleanen Version und ebenso eine XML-Präambel, die nötig ist, damit das SVG tel quel direkt in den HTML-Quelltext eingefügt werden kann.
So könnte man eine private Website mit SVGs als Posts erstellen.
Weiters bräuchte man einen Website-Generator (Static-Site-Generator).
Auf Macports gibt es unter diesem Stichwort: blades, cobalt.rs, hugo, kiln, rb-webgen, stog, zola.
https://getblades.org/
hat plugins, in die man vielleicht die SVG-Verarbeitung stecken kann.
https://cobalt-org.github.io
scheint gut für ‘Normalo’-Blogs.
https://gohugo.io/
Hugo ist so modern, dass es auf Waterfox Classic sehr unzureichend dargestellt wird.
https://kiln.adnano.co/
kann Gemini-Sites erstellen.
https://webgen.gettalong.org/
(rb-webgen) braucht Ruby.
https://www.good-eris.net/stog/
braucht OCaml, für Oldschool-‘Normalo’-Blogs.
https://www.getzola.org
Macports hat die aktuelle Version von März 2023.
https://getpelican.com/
pelican ist ein Static-Site-Generator-Pythonmodul mit vielen Plugins
https://github.com/pelican-plugins
.
https://jamstack.org/generators/
Liste von Static-Site-Generatoren. Viele davon sind in Javascript geschrieben. Sie haben Namen wie Next.js, Gatsby, Jekyll, Nuxt, Docusaurus, Hexo, Slate, GitBook, Astro, Docsify, VuePress, MkDocs, UmiJS, Eleventy, SvelteKit, mdBook, React Static, fresh, Gridea, Gridsome, Metalsmith, Sapper.js, Middleman, Brunch, Vitepress, Publii, Sphinx, Harp, Expose, Publish, Assemble, Lektor, Wintersmith, Cactus, DocFX, Phenomic, Bookdown, Docpad, HubPress, R Markdown, Hakyll, Scully, Nikola, Saber, Elder.js, Nanoc, Jigsaw, markdown-styles, Octopress …
Punch, JBake, Cryogen, InkPaper, Franklin, thumbsup, Ruhoh, Poet, Gor, Pretzel, Plenti, Couscous, Frog, Cabin, Blacksmith, Cuttlebelle, Primo, Coleslaw, Orchid …
https://github.com/Jack000/Expose
ist ein Shellscript, mit dem man einen Ordner mit Bildern publizieren kann. Man kann damit sogar ein Polygon innerhalb eines Fotos definieren, in das Text gefüllt werden kann.
Vielleicht könnte man das hacken, so dass es auch mit SVGs läuft.
https://github.com/cfenollosa/bashblog
ist ein weiterer Static-Site-Generator, der nur aus einem Shellscript besteht.
https://docs.racket-lang.org/pollen/index.html
zum Webbucherstellen mit Racket (https://practicaltypography.com/
, https://beautifulracket.com/
), von einem Typografen.
Zuerst probeweise Pelikan. Gefällt mir supergut. Zur Webseitenerstellung mit pelican-quickstart
wird auf der Kommandozeile eine Reihe von Fragen präsentiert, die leicht zu beantworten sind und gute Defaults haben. Sogar die Zeitzone hat pelican richtig erraten. Die Struktur eines leeren Webseitenprojekts sieht so aus:
testsite
content
[leer]
Makefile
output
[leer]
pelicanconf.py
publishconf.py
tasks.py
make help
, im Verzeichnis ‘testsite’ ausgeführt, listet folgende Optionen auf:
make html (re)generate the web site
make clean remove the generated files
make regenerate regenerate files upon modification
make publish generate using production settings
make serve [PORT=8000] serve site at http://localhost:8000
make serve-global [SERVER=0.0.0.0] serve (as root) to "0.0.0.0":80
make devserver [PORT=8000] serve and regenerate together
make devserver-global regenerate and serve on 0.0.0.0
Der Unterschied zwischen make html, make regenerate und make publish ist mir noch unklar. Posts kommen jedenfalls als Markdown (.md)-Dateien unter einem beliebigen Dateinamen nach “content”. Die Metadaten müssen in der Post mitgeteilt werden.
Title: mein erster Post
Date: 2023-06-07 14:30
Category: Allgemeines
Mit dem Befehl pelican -r -l
, das ist kurz für pelican --autoreload --listen
, wird die Seite auf localhost:8000 gehostet, wenn sich was ändert, wird automatisch neugeneriert. Das ergibt eine Seite mit Oldschool-Bloglook (das Default-Thema ist laut der Seite selber von 2009), aber das kann man bestimmt ändern.
Das Editieren von der Blogpost in content führte aber zu einer exception:
There are 2 original (not translated) items with slug "mein-erster-post":
/Users/Shared/Dev/Javascript/Test/testsite/content/mein_erster~.md
/Users/Shared/Dev/Javascript/Test/testsite/content/mein_erster.md
Anscheinend, weil der Editor kurzzeitig ein Backup gemacht hat. Daher schlug das automatische Re-laden fehl. O.k. kann passieren. Wenn man die Category löscht, wird der Post automatisch mit ‘misc’ getagt. Wenn man auch noch das Datum löscht, wird der ganze Post verschluckt. Dann heisst es: This site currently has no content.
Mit make publish
lädt man die Seite auf den entfernten Server (den man gemietet hat oder der umsonst ist) hoch. Das geschieht mit “rsync” und “ssh”.
Bedenklich ist, dass man die Werbefusszeile: ‘Proudly powered by Pelican, which takes great advantage of Python.’ nicht in der lokalen Config löschen kann. Hoffentlich muss man dazu den Pelican nicht forken.
Ich probiere noch Zola (né Gutenberg) https://www.getzola.org/, falls Pelican sich als zu schwierig im Umgang herausstellt. Gut ist, dass Macports die aktuelle Version bereithält. Gut ist auch, dass Macports gleich die binäre Version herunterlädt, da Rust, die Sprache, in der Zola geschrieben ist, berüchtigt dafür ist, wie lange die Compilierung dauert.
Bei Zola ist die config eine “.toml”-Datei, während sie bei Pelican ein Python-Script ist. Die Directory-Struktur ist viel involvierter als bei Pelican. Das sieht weniger gut aus. Da gibt es einen ‘sass’-Ordner und getrennt davon einen ‘templates’-Ordner und zusätzlich noch einen ‘themes’-Ordner. Im templates-Ordner sind Dateien wie base.html, blog-page.html, blog.html und index.html drin. Der Unterschied zwischen sass, templates und themes scheint sehr klein, alles dient der Formatierung, warum kann man den ganzen Kram nicht in einen Ordner in 1 oder 2 Dateien ablegen? Es reicht nicht, wie bei pelican, die eigentlichen Blog-Posts einfach in den content-Folder zu werfen, nein, da muss ein ‘blog’-Unterordner her, mit einem Unterstrich-Index-Markdown-File und dann erst darf man Blogposts schreiben.
zola init
initialisiert eine neue Webseite. Ausser ‘init’ gibt es noch ‘zola build’, ‘zola serve’, ‘zola check’, ‘zola completion’ und ‘zola help’. Das scheint vernünftig, ausser ‘zola completion’, was völlig obskur ist und auch obskur bleibt, wenn man ‘zola help completion’ aufruft:
$ zola help completion
Generate shell completion
Usage: zola completion <SHELL>
Arguments:
<SHELL> Shell to generate completion for [possible values: bash, elvish, fish, powershell, zsh]
Dies ist keine Hilfe. Selbst die Dokumentation von zola kennt den Befehl ‘completion’ nicht:
https://www.getzola.org/documentation/getting-started/cli-usage/
Da heisst es: Zola only has 4 commands: init, build, serve and check.
Es wird nicht besser: Genauso wie bei pelican-quickstart
bekommt man Fragen präsentiert, aber gleich die zweite ist völlig unklar:
Do you want to enable Sass compilation? [Y/n]: Was ist Sass compilation? Default ist Yes. Ist das gut? Sass ist Css, nur etwas einfacher. Die dritte Frage ist auch blöd: Do you want to enable syntax highlighting? [y/N]: Welche Syntax wird wo und wann gehighlighted? Die Blog-Posts oder irgendwelche Konfigurationsfiles, oder was? Ich bin dazu geneigt, ‘Yes’ zu nehmen, obwohl ‘No’ der Default ist, nur um zu sehen, was das ist. Do you want to build a search index of the content? [y/N]: hilfreich wäre zu wissen, ob das später noch möglich ist (hoffentlich ja).
zola serve
startet den Server auf http://127.0.0.1:1111
.
Schön ist, dass die leere Webseite keinen Werbespam wie bei pelican enthält. Ausserdem ist sie moderner (also asketischer). Die Gerüst-Webseiten-Indexseite muss man manuell in templates/base.html erstellen. Dies soll in den Body der Base.html:
<body>
<section class="section">
<div class="container">
{% block content %} {% endblock %}
</div>
</section>
</body>
Jetzt noch templates/index.html erstellen. Und wieder kommen Meta-Anweisungen an den Seitengenerator in Form von in ‘{%’ und ‘%}’ eingeschlossenen Blöcken zu Anwendung.
{% extends "base.html" %}
{% block content %}
<h1 class="title">
Das ist mein Blog.
</h1>
{% endblock content %}
Jetzt kann das leere Blog dargestellt werden. Und es gibt noch mehr komische Syntaxdinge. Folgendes Zeug muss in Unterstrich-index-md in ein neues Verzeichnis (das neue Verzeichnis ist nötig, damit eine neue Sektion entstehen kann):
+++
title = "List of blog posts"
sort_by = "date"
template = "blog.html"
page_template = "blog-page.html"
+++
Die ‘+++’ sind verpflichtend. Die Syntax ist “toml” (https://github.com/toml-lang/toml
), aber die Datei muss eine “Markdown”-Dateiendung haben.
Gut ist immerhin, dass ‘Assets’ nicht in noch einem anderen Verzeichnis abgelegt werden müssen, sondern neben den Markdown-Dateien in den Sektionsabschnitten, die dann in Html-Seiten umgewandelt werden, existieren können. Der Abschnitt innerhalb der ‘+++’-Zeichen im _index.md-File ist als TOML-Front matter bekannt. Wenn man statt ‘+++
’ ‘---
’ benutzt, kann man YAML-front matter verwenden.
Mir kommt vor, der Unterschied zwischen Pelican und Zola ist in etwa analog des Unterschiedes zwischen den Programmiersprachen, in denen die beiden Programme geschrieben sind, Pelican ist Python und Zola Rust.
Also, ich würde gerne eine Probe aufs Exempel machen. Und eine Page auf Codeberg erstellen.
Man muss ein Repositorium mit dem Namen ‘pages’ erstellen. Super kompliziert.
Unter https://mondo20.codeberg.page/
ist endlich etwas sichtbar.
Ich kann gar nicht erklären, wie kompliziert das war.
Ich bin unschlüssig. Vielleicht komme ich ohne Seitengenerator aus. Jedenfalls habe ich nach zwei Tagen Rumfummelns eine hübsche selbstgemachte Blogseite erstellen können.
Seitengeneratoren, die sich weigern, meine Posts zu veröffentlichen, weil ich kein Datum angeben will. Git (git, das Kommandozeilenprogramm, nicht github) will meine email-Adresse haben. Hier fängt der Digitalhorror an.
Ich denke, ich muss meinen eigenen Workflow entwickeln.
Dies ist der Workflow, den ich mir zugelegt habe.
Die zu veröffentlichenden Seiten sind in einem Unterverzeichnis von “codeberg”. Ich starte zuerst einen Webserver mit python -m http.server 8080
im Verzeichnis “codeberg”.
Die Entwürfe sind in txt-Files im Filesystem verstreut.
$ cd /Users/Shared/Dev/Javascript/Test/codeberg/pages
$ multimarkdown -f /Users/Shared/Dev/Javascript/Test/Web-Development.txt > my.html
Der Entwurfs-Text, dem Markdown-Elemente hinzugefügt worden sind (hauptsächlich Backticks (`) für Code und Überschriften mit “-------
” unterstrichen), wird durch multimarkdown
in eine HTML-Seite umgewandelt und in “my.html” gespeichert. In einem Webbrowser geöffnet fallen Fehler leichter auf.
Im Terminal-Fenster kann man mühelos mit der Pfeil-Nach-Oben-Taste den letzten Befehl wiederholen und nochmal ausführen.
Aus my.html copy-paste ich die Passagen, die ich veröffentlichen will, in index.html. Dies ist die finale Website. Nun kann der Schriftsteller weiter daran herumfeilen, oder er kann sie veröffentlichen. Je mehr man indes an dem Text arbeitet, desto mehr entfernt er sich vom Entwurf.
Parallel zur Arbeit am Text fummle ich in main.css
an der Formatierung herum.
Wirklich veröffentlicht wird die Webseite mit “git”.
git config -l
git config -l --global
git config -l --local
git log
git status
Das sind Git-Befehle, die über den Status Auskunft geben. Es gibt einige Dinge, die man hier ändern kann, z.B. mit git config --global user.name "anon"
den globalen Usernamen und die email-Adresse mit git config --global user.email "anon@example.com"
.
Das Verzeichnis ‘pages’ ist bereits mit git init
als Repositorium initialisiert worden. Leider war das Weitere nicht so einfach und es wird auf Codeberg in den Docs (https://docs.codeberg.org/
) auch nicht gut erklärt.
git remote add origin https://codeberg.org/mondo20/pages
verbindet das lokale Ropositorium mit dem entfernten Repositorium in Berlin. git add index.html
fügt die Website zum Repositorium hinzu, so dass Änderungen getrackt werden können. git add main.css
fügt das Stylesheet hinzu, für jede weitere Datei, die hochgeladen werden soll, muss man das ebenfalls machen. “my.html”, das nur Entwürfe für die eigentlichen Webseite enthält, habe ich nicht zum Git-Repositorium hinzugefügt, es erscheint dann bei git status
rot unter ‘untracked files’.
Der nächste Schritt ist ‘commit’: git commit -am "test"
verpflichtet die Änderungen in den Stamm. Ein Kommentar (hier “test”) ist vorgeschrieben.
Nun kann man die Seite “wirklich wirklich” hochladen mit
git push
Ich glaube, beim erstenmal fragt git
nach dem Passwort für codeberg und dann speichert es das Passwort in einen Schlüsselbund ab. Jedenfalls musste ich das Passwort nicht wieder eingeben.
Mit git diff head
und git diff origin/main
kann man sehen, was sich im Vergleich zur committeten bzw. publizierten Version geändert hat, bevor man eine neue Version hochlädt.