Metainformationen zur Seite
  •  

Dies ist eine alte Version des Dokuments!


Markdown und Co.

Inzwischen (Nov 2022) steht für ich fest, dass ich mit einem Workflow, in dem ich meine Texte in Markdown schreibe und dann als HTML und PDF audgeben kann sehr gut zurecht komme.

Die Grundidee ist, das Schreiben der Inhalte von der endgültigen Formatierung zu trennen. Trotzdem sollen die Formatierungen schon im ASCII-Text (naja, Unicode-Text) erkennbar sein. Weitere Vorteile ergäben sich, wenn man eine Versionsverwaltung wie Git einsetzen würde, da diese zeilenweise Textdateien versioniert. Damit kann man z.B. bei einem Buch, das in einer Markdown-Datei geschrieben wird, jede Änderung nachvollziehen. Dies ist mit einem Textverarbeitungsprogramm (Word, Writer) so nicht möglich. Mein restlicher Workflow ist allerdings Nextcloud-basiert, so dass Git eine zusätzliche und für mich nicht vorteilhafte Verkomplizierung wäre.

Idee

Markdown ist bekanntlich eine vergleichsweise einfache Methode um sofort gut lesbaren strukturierten Text zu schreiben. Ohne Menüs, eine Maus oder Tastatur-Shortcuts zu nutzen kann man Texte mit hierarchischen Überschriften, Fett/Kursivschrift, Tabellen, Zitaten, Links, Fußnoten und Code-Fragmenten schreiben. Es sind bereits einige Bücher sowie viele E-Books in Markdown geschrieben worden.

Praxis

Dienste wie z.B. Github zeigen Markdown-Dateien automatisch als gut aussehendes HTML an. Aber jeder kann selbst Tools einzusetzen, die optisch ansprechende Dokumente in vielen verschiedenen Formaten erzeugen können. Ich ziele derzeit nur auf HTML und daraus erzeugtes PDF (so werden beide mit CSS formatiert). [Man kann aber auch von Pandoc direkt PDF-, odt- oder epub-Dateien erzeugen lassen. Zu den Möglichkeiten siehe hier.]

  • Der Markdown Editor Ghostwriter hilft mir reinen Markdown-Text zu verfassen.
  • Die Konvertierungssoftware Pandoc erzeugt aus einer Markdown-Datei eine HTML-Datei.
  • Den Ausdruck der HTML-Datei in eine PDF-Datei erledigt der Chromium-Browser oder auch Google-Chrome von der Kommandozeile aus.

Pandoc alleine erzeugt eine korrekte, aber nicht so hübsche HTML-Datei. Aber man kann mit der Kommandozeilenoption -H eine zusätzliche Datei in den Header der HTML-Datei einfügen lassen. Damit ist es einfach viele CSS-Styles einzubinden. Am Ende kann man mit -F eine weitere Datei als eine Art Fußzeile einfügen lassen. Dann gibt es noch den Befehl --toc, der ein Inhaltsverzeichnis generiert, das wiederum erst nach eine Formatierung mit obigen Styles gut aussieht.

Chromium/Chrome kann über die Kommandozeile eine HTML-Datei direkt als PDF-Datei „ausdrucken“. Dabei werden Formatierungsanweisungen der HTML-Datei beachtet, z.B. page-break-before, so dass man Kapitel mit einer neuen Seite anfangen lassen kann. Man kann sogar das Aussehen der PDF-Datei komplett anders gestalten, da dabei @media print { … } beachtet wird.

Technisches

Wer ein wenig experimentieren möchte aber auf einer funktionierenden Basis: Hier der aktuelle Stand…

Bash-Datei, die mit dem Namen der md-Datei aufgerufen wird. Dann werden sowohl eine HTML- als auch eine PDF-Datei erzeugt. Pandoc installiert?

md2html
#!/bin/bash
if [[ "$1" == "" ]]
then 
	echo "Dateiname.md als Parameter fehlt" 
	exit
fi
 
rumpf="${1%.*}"
ext="${1##*.}"
echo $rumpf . $ext
[[ "$ext" == @(md|txt|markdown) ]] || (printf "Falsche, oder keine Erweiterung!\nMuss md oder txt sein\n"; exit;)
 
pandoc -s -o "${rumpf}.html" "${1}" --toc --toc-depth=2 -H ~/Pfad/zu/doku.css -A ~/Pfad/zu/footer.txt 
 
firefox "${rumpf}.html" &
 
chromium --headless --disable-gpu  \
    --run-all-compositor-stages-before-draw --print-to-pdf-no-header --no-margins \
    --print-to-pdf=${rumpf}.pdf ${rumpf}.html

footer.txt ist ein HTML-Schnipsel - bei mir im Original mit einem base64-kodierten Bildchen.

footer.txt
<div id="footer" style="text-align:right;">
	Christian Bienmüller <img style="vertical-align:middle;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADEAAAAwCAYAAAC4wJK5AAAABmJLR0QA
        ....
        YOX/NaDH6ejFV/cJagIy6ud4/pL/9S/vYwWvr7yH4Bzfnf1V79bdqpv97/KuM/wdexdIzOCy+fQAAAABJRU5ErkJggg==" alt="Biene" />
</div>

doku.css enthält alle Formatierungen und, da sie 1:1 in den Header geschrieben wird, auch die Zeilen <style> und </style».

doku.css
<style type="text/css">
    body {
        margin: auto;
        padding-right: 1em;
        padding-left: 1em;
        max-width: 44em; 
        border-left: 1px solid black;
        border-right: 1px solid black;
        font-family: "Liberation Sans", Verdana, Arial, sans-serif;
        font-size: 100%;
        line-height: 140%;
        color: #333; 
    }
    pre {
        border: 1px dotted gray;
        background-color: #ececec;
        color: #1111111;
        padding: 0.5em;
    }
    blockquote {
        border-left: 4px solid #4d94ff;
        padding-left: 6px;
        margin: 10px 20px 10px 10px;
    }
    code {
        font-family: "Source Code Pro", "Liberation Mono", monospace;
        background-color: #ececec;
 
    }
    a { color: #005ce6}
    .footnote-ref {text-decoration: none; font-weight:bold;}
 
    h1 a, h2 a, h3 a, h4 a, h5 a { 
        text-decoration: none;
        color: #005ce6; 
    }
    h1, h2, h3, h4, h5 { font-family: "Liberation Sans", Verdana, Arial, sans-serif;
                         font-weight: bold;
                         color: #4d94ff; }
 
    h1, h2, h3 { 
            border-bottom: 1px dotted black;
    }
    h1 {
        font-size: 130%;
        counter-reset: h2counter;
    }
 
    h1:not(:first-of-type) {
        page-break-before: always;
    }
 
    h2 {
        font-size: 115%; 
    }
 
    h3 {
        font-size: 105%; }
 
    h4 {
        font-size: 95%;
        font-style: italic; }
 
    h5 {
        font-size: 90%;
        font-style: italic; }
 
    h1.title {
        font-size: 200%;
        font-weight: bold;
        padding-top: 0.2em;
        padding-bottom: 0.2em;
        text-align: left;
        border: none; }
 
    dt code {
        font-weight: bold;   }
 
    dd p {
        margin-top: 0;   }
 
    footer, #footer {
        padding-top: 1em;
        font-size: 70%;
        color: gray;
        text-align: center; }
 
    table {
        font-family: "Liberation Sans", Verdana, Arial, sans-serif;
        border-collapse: collapse;
        width: 100%;  }
 
    td, th {
        border: 1px solid #ddd;
        padding: 8px;
    }
 
    td:first-child {
        font-weight: bold; font-size:90%;}
 
    tr:nth-child(even){
        background-color: #f2f2f2;}
 
    tr:hover {background-color: #ddd;}
 
    th {
        padding-top: 12px;
        padding-bottom: 12px;
        text-align: left;
        background-color: #4d94ff;
        font-weight: bold;
        color: white;  } 
 
    .footnotes li {
        font-style: italic;
        font-size:80%;    }
    /* Formatierung des Table Of Contents */
    #TOC { 
        float: right;
        max-width: 35%; 
        font-size:80%;
        margin-left: 6px;
        padding-left: 6px;
        padding-right: 4px;
        background-color: #e6f0ff;
        border: 1px solid grey;
    }
    #TOC::before { 
        font-weight: bold;
        content: " Inhalt und Links" ;
    }
    #TOC ul { 
        margin: 0em;
        padding: 0em;
        padding-left: 1.5em; 
    }
    #TOC a,
    #TOC a:visited {
        text-decoration: none;
    }
 
/* ==========================================================================
   Print styles. Zum Drucken im Browser und für PDF-Export relevant
   ========================================================================== */
 
@media print {
    body { 
        font-size: 90%;
        max-width:100%;
        border: 0;
    }
 
    *,
    *::before,
    *::after {
        /* background: #fff !important; */
        /* color: #000 !important; */
        /* Black prints faster */
        box-shadow: none !important;
        text-shadow: none !important;
    }
    h1, h2 { color:  #404040; }
    h3, h4, h5 { color: grey; }
 
    th { background: grey;}
 
    a,
    a:visited {
        color: grey;
        text-decoration: underline;
    }
    /* Inhaltsverzeichnis */
    /* -> besteht nur aus Links, müssen aber daher nicht so formatiert sein */
    #TOC a,
    #TOC a:visited {
        color: black;
        text-decoration: none;
    }
    /* ohne Farbe hellstgrau */
    #TOC {
        background-color: #e8e8e8;
    }
 
    /* Print the URL of most links */
    a[href]::after {
        content: " (" attr(href) ")";
        font-size: 80%;
    }
    /* Don't print internal links or links that use the `javascript:` pseudo protocol */
    a[href^="#"]::after,
    a[href^="javascript:"]::after {
        content: "";
    }
 
    abbr[title]::after {
        content: " (" attr(title) ")"; 
    }
 
    pre {
        white-space: pre-wrap !important;
        border: 1px solid #999;
        page-break-inside: avoid;
    }
 
    blockquote {
        border-left: 4px solid grey;
        padding-left: 6px;
    }
 
    tr,
    img {
        page-break-inside: avoid;
    }
 
    h2, h3, h4 {
        page-break-after: avoid;
    }
} /* ENDE der Printstyles */
 
</style>