Download-Size

download-size.html

Zu einer Downloaddatei wird die Dateigröße ermittelt und für eine humane Darstellung aufbereitet.

Zuerst muss der Name der Downloaddatei mitsamt deren Zugriffspfad ermittelt werden.

   {{- $finfo := path.Join .File.Dir .Params.file | os.Stat -}}
   {{- $fsize := $finfo.Size -}}

Wir machen uns zu Nutze, dass die Markdown-Datei (.md) mit der Beschreibung im Dateibaum gleich “daneben” steht. Beide Dateien haben daher den gleichen Zugriffspfad, .File.Dir gibt uns den bekannt. .Params.file steht für den Dateinamen der Downloaddatei wie er im Frontmatter angegeben ist. Für das Zusammenfügen der beiden Bestandteile wird path.Join bemüht. Mittels des ‘pipe’-Operators | wird der zusammengefügte Pfad mit Dateiname zur Downloaddatei an os.Stat weitergereicht. Dieses os.Stat holt die Datei-Info der angegebenen Datei vom Betriebssystem und weist die Datei-Info an $finfo zu. Die Dateigröße ($finfo.Size) wird dann an $fsize zugewiesen.

Die Dateigröße ist generell in Bytes angegeben. Große Zahlen sind aber für den Leser eher schwer zu erfassen. Außerdem kommt es ab einigen Kilobyte (kB) nicht mehr auf eine exakte Angabe an. Die Dateigröße wird daher für eine angenehme Darstellung aufbereitet. Dazu sind zwei Pfade zu behandeln: Einer für den Zahlenwert und einer für die Einheit. Beides ginge auch in einem Aufwasch, aber damit gibt es ein Häkchen, das später bei der eigentlichen Darstellung erst auffiele.

   {{- $fsize_unit := "Bytes" -}}
   {{- $scratch1 := newScratch -}}

   {{-      if gt $fsize 104857600}}
      {{- printf "%.0f" (div $fsize 1048576.0) | $scratch1.Set "fsize_txt" -}}
      {{- $fsize_unit = "MB" -}}
   {{- else if gt $fsize 10485760}}
      {{- printf "%.1f" (div $fsize 1048576.0) | $scratch1.Set "fsize_txt" -}}
      {{- $fsize_unit = "MB" -}}
   {{- else if gt $fsize 1048576}}
      {{ printf "%.2f" (div $fsize 1048576.0) | $scratch1.Set "fsize_txt" -}}
      {{ $fsize_unit = "MB" -}}
   {{- else if gt $fsize 102400 -}}
      {{- printf "%.0f" (div $fsize 1024.0) | $scratch1.Set "fsize_txt" -}}
      {{- $fsize_unit = "kB" -}}
   {{- else if gt $fsize 10240 -}}
      {{- printf "%.1f" (div $fsize 1024.0) | $scratch1.Set "fsize_txt" -}}
      {{- $fsize_unit = "kB" -}}
   {{- else if gt $fsize 1024 -}}
      {{- printf "%.2f" (div $fsize 1024.0) | $scratch1.Set "fsize_txt" -}}
      {{- $fsize_unit = "kB" -}}
   {{- else -}}
      {{- printf "%d" $fsize | $scratch1.Set "fsize_txt" -}}
      {{- $fsize_unit = "Bytes" -}}
   {{- end -}}

$fsize_unit := "Bytes" erhält als die Einheit der Dateigröße zunächst “Bytes”. Für den Zahlenwert wird ein “Notizzettel” angelegt: $scratch1 := newScratch. Nun wird der Reihe nach, beginnend mit einem sehr großen Wert, geprüft, ob die Dateigröße diesen (willkürlich) gewählten Wert überschreitet. Falls nicht, kommt der nächstniedrigere Wert an die Reihe. Trifft ein Vergleich if gt $fsize xxxx (if $fsize > xxxx) zu, wird die Dateigröße durch einen Teiler skaliert (div $fsize 1024.0 entspricht $fsize / 1024.0). Dabei sorgt die angehängte ‘.0’ dafür, dass das Ergebnis als Fließkommazahl erscheint. Diese Fließkommazahl wird nun per printf "%._f"in einen String umgewandelt. Dabei bestimmt die Zahl anstelle des Platzhalters die Anzahl der Nachkommastellen in der Anzeige; "%.2f"erzwingt zwei Nachkommastellen. Das Ergebnis des printf wird per | zum “Notizzettel” weitergereicht und per $scratch1.Set zur späteren Verwendung aufbewahrt. Die kaufmännische Rundung erledigt das printf übrigens gleich mit. Aus 12.73 wird so 12.7 und aus 12.77 wird 12.8.

Trifft keiner der Vergleiche zu, wird die Dateigröße direkt als Integerwert und mit der Einheit ‘Bytes’ angegeben. In diesem Fall ist nichts zu runden.

Passend zum Teiler wird die Einheit auf ‘MB’, ‘kB’ oder ‘Bytes’ umgestellt und in $fsize_unit abgelegt.

Nun wird noch das Ergebnis zurückgeliefert.

   {{- $scratch1.Get "fsize_txt" -}} {{- $fsize_unit -}}

Der Zahlenwert wird per $scratch1.Get "fsize_txt" hervorgelockt.   ist ein spezielles Leerzeichen, das nicht durch einen Zeilenumbruch ersetzt werden darf. $fsize_unit gibt noch die Einheit der Dateigröße dazu.

Insgesamt kommt da sowas wie 12.7 kB heraus. Wegen des &nbsp ist die Einheit untrennbar mit der Zahl verbunden und beide Teile werden immer gemeinsam in einer Zeile stehen, obwohl ein normgerechter Abstand dazwischen eingehalten wird.

Leider hat sich herausgestellt, dass das   nicht durch Hugos printf erzeugt werden kann und deswegen ist die getrennte Behandlung von Zahl und Einheit bis hierher erforderlich.

Die errechnete und aufbereitete Dateigröße wird durch die letzte Zeile {{- $scratch1.Get "fsize_txt" -}} {{- $fsize_unit -}} an der Stelle erscheinen, wo das Partial ‘aufgerufen’ wird. {{- sowie -}} unterdrücken jeglichen Whitespace.

   ( {{- partial "download-size.html" . -}} )

wird im fertigen HTML-Code dann z. B. durch

   (12.7 kB)

ersetzt.

Der beschriebene Code sollte dem tatsächlichen Inhalt von /layouts/partials/download-size.html entsprechen. Eventuell ergeben sich marginale Abweichungen, weil einer der Grenzwerte verändert wurde ohne die hiesige Doku anzupassen. Das ist dann halt so und es gilt immer der ‘produktive’ Wert.

Stand: 25. Oktober 2019