Push to Publish 2

Nachdem ich vor Kurzem einen euphorischen Eintrag über mein automatisiertes Update dieses Blogs via Travis-CI und GitHub pages geschrieben habe, bin ich jetzt auf eine einfachere Lösung gestoßen.

Alles unter einem Dach bei Netlify Netlify Logo

Es gibt einen einfachen Buildservice, der zwar nicht so flexibel ist wie Travis-CI, aber für dieses Blog ausreicht. Netlify baut die Seite also bei jedem Push in ein beobachtetes GitHub Repository. Nach Konfiguration des DNS und einem weiteren Knopfdruck ist die Seite mit einem SSL Zertifikat von Let’s Encrypt ausgestattet und erreichbar. Also Bonus kann man selbst HTTP-Header bestimmen über eine _headers Datei:

/*
    Strict-Transport-Security: max-age=31536000; includeSubDomains

Also kann man HTTP/2 Server Push ausprobieren, ohne einen Server betreiben zu müssen.

png2vp9

Konvertiere einen Ordner voller .png in ein zur Web-Wiedergabe geeignetes VP9, das von allen wichtigen Browsern unterstützt wird.

ffmpeg -f image2 -pattern_type glob -i "img*.png" -c:v libvpx-vp9 -pass 1  \
    -b:v 1000K -threads 1 -speed 4 -tile-columns 0 -frame-parallel 0 \
    -auto-alt-ref 1 -lag-in-frames 25 -g 9999 -aq-mode 0 -an -f null -


ffmpeg -f image2 -pattern_type glob -i "img*.png" -c:v libvpx-vp9 -pass 2 \
    -b:v 1000K -threads 1 -speed 0 -tile-columns 0 -frame-parallel 0 \
    -auto-alt-ref 1 -lag-in-frames 25 -g 9999 -aq-mode 0 -c:a libopus -b:a 64k \
    -f webm video.webm

Für maximale Kompatibilität kann als Fallback noch ein MP4 erstellt werden.

ffmpeg -an -f image2 -pattern_type glob -i "img*.png" -vcodec libx264 \
    -pix_fmt yuv420p -profile:v baseline -level 3 video.mp4

Einbettung erfolgt mit:

<video>
  <source src="path/to/video.webm" type="video/webm; codecs=vp9,vorbis">
  <source src="path/to/video.mp4" type="video/mp4">
</video>

make

Als Obi-Wan zu Luke gesagt hat

This is the weapon of a Jedi Knight. Not as clumsy or random as a blaster; an elegant weapon for a more civilized age.

Obi-Wan Kenobi (1977)

Meinte er vermutlich make. (Fun Fact: make wurde auch 1977 veröffentlicht.)

Mit wenigen Zeilen im Makefile kann man nicht nur sein \(\LaTeX\) Projekt kompilieren, sondern auch alle Plots neu zeichnen, die sich geändert haben. Für unser Beispiel gehen wir davon aus, dass zum Plotten Gnuplot mit dem epslatex Terminal genutzt wird und folgende Verzeichnisstruktur des Projektes vorliegt.

.
+-- data
|   + datafile1.dat
|   + datafile2.dat
+-- images
|   +-- img1.svg
|   +-- img2.tex
+-- plots
|   +-- style.gps
|   +-- plot1.gp
|   +-- plot2.gp
+-- myDocument.tex
+-- chapter1.tex
+-- chapter2.tex
+-- lit.bib

Dann kümmert sich das folgende Makefile darum, dass die Daten für die Plots heruntergeladen werden, alle Plots, TikZ und .svg parallel zu .pdf gerendert werden und sobald das geschehen ist, das Dokument kompiliert wird.

DOCUMENT = myDocument

# get all image files from their directories
PLOTS := $(wildcard plots/*.gp)
TIKZ := $(wildcard images/*.tex)
SVG := $(wildcard images/*.svg)

# we want the images to be pdf
PLOTS := $(PLOTS:%.gp=%.pdf)
SVG := $(SVG:%.svg=%.pdf)
TIKZ := $(TIKZ:%.tex=%.pdf)

IMAGES := $(PLOTS) $(SVG) $(TIKZ)

# get all tex files
TEX := $(wildcard *.tex)
BIBFILE := lit.bib

all: $(DOKUMENT).pdf

# we need chapters, images and the bib file to create our document
# also recompile, whenever one of those changes
$(DOCUMENT).pdf: $(TEX) $(IMAGES) $(BIBFILE)
$(DOCUMENT).pdf: %.pdf: %.tex
    pdflatex -interaction=batchmode $* > /dev/null
    biber $* > /dev/null
    pdflatex -interaction=batchmode $* > /dev/null
    pdflatex -interaction=batchmode $* > /dev/null

# gnuplot generates texfiles from the .gp files
# make sure to regenerate all tex files, if the style
# or the data changes
%.tex: %.gp plots/style.gps | data
    cd $(<D) && gnuplot $(<F) > /dev/null 2>&1

# use this rule to convert .svg to pdf
$(SVG): %.pdf: %.svg
    cd $(<D) && inkscape -z -A $(*F).pdf -h 1080 $(<F)

# use this rule only to generate .pdf from the "image type" .tex files
$(TIKZ) $(PLOTS): %.pdf: %.tex
    cd $(<D) && pdflatex -interaction=batchmode $(<F) > /dev/null
    rm -f $*.{log,aux} $*-inc.eps $*-inc-eps-converted-to.pdf

# rule to extract data from its archive
data: %: %.tar.xz
    tar -xf $<

# rule to download the archive with the data
%.tar.xz:
    wget -nv https://some.domain.tld/where/your/data/is/$@

clean: proper
    rm -rf data
    rm -f $(DOCUMENT).pdf

# delete temporary files
proper:
    rm -f data.tar.xz
    rm -f $(PLOTS) $(PLOTS:.pdf=.eps) *-inc.eps *-inc-eps-converted-to.pdf $(PLOTS:.pdf=.tex) plots/fit.log $(TIKZ) $(SVG)
    rm -f {$(DOCUMENT)}.{log,aux,bbl,blg,toc,out,lof,lot,snm,nav,tec,glg,glo,gls,xdy,acn,acr,alg,bcf,run.xml}

Dazu baut make einen gerichteten azyklischen Graphen (DAG) aus den Abhängigkeiten auf und führt die Dinge, deren Abhängigkeiten erfüllt sind, parallel aus.

Das grundlegende Element einer Makefile sind die Rules, die generell so aufgebaut sind

targets : prerequisites
<tab> recipe

Dabei gibt die erste Zeile die Abhängigkeiten welche prerequisites bestehen müssen, um durch Ausführung des recipe die targets zu erstellen.

Die Nützlichkeit von make wird zu großen Teilen durch automatische Variablen (zB. $*) oder Pattern Rules (%.pdf) hergestellt. Dazu verweise ich allerdings lieber auf die offizielle Dokumentation.