imported the refcard generating code, as well as the input file for the refcard.
authorFrank Terbeck <ft@grml.org>
Fri, 22 Jun 2007 20:58:17 +0000 (22:58 +0200)
committerFrank Terbeck <ft@grml.org>
Fri, 22 Jun 2007 20:58:17 +0000 (22:58 +0200)
The idea is to generate the LaTeX source for 'grml-zsh-refcard' with this code
and regularly check a new version of it into that repository, so that there is
always a static version of the source for the .pdf-refcard that is on the web.

Makefile [new file with mode: 0644]
genrefcard.pl [new file with mode: 0755]
grml-zsh-refcard.tex.in [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..123bf5a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,8 @@
+ZSHRCS=../grml-etc-core/etc/zsh/zshrc ../grml-etc-core/etc/skel/.zshrc
+
+all: grml-zsh-refcard.tex
+
+grml-zsh-refcard.tex: grml-zsh-refcard.tex.in genrefcard.pl
+       cat $(ZSHRCS) | ./genrefcard.pl > grml-zsh-refcard.tex
+clean:
+       rm -f grml-zsh-refcard.tex
diff --git a/genrefcard.pl b/genrefcard.pl
new file mode 100755 (executable)
index 0000000..daaa877
--- /dev/null
@@ -0,0 +1,422 @@
+#!/usr/bin/perl -w
+use strict;
+#{{{ readme
+### Author: Frank Terbeck <ft@bewatermyfriend.org>
+### GPLv2
+###
+### generate grml zsh refcard.
+### #v#: variables
+### #f#: functions
+### #a#: aliases
+### #k#: keybindings
+### #A#: abbreviations
+### #d#: hasheddirs
+### #o#: other
+###
+### consider these lines in zshrc:
+### #a3# execute \kbd{apt-cache policy}
+### alias acp='apt-cache policy'
+###
+### Now this script will add a new description for 'acp' into
+### the replacement list created by the @@INSERT-aliases-debian@@
+### tag.
+###
+### @@INSERT-aliases-default@@ == @@INSERT-aliases@@
+### @@INSERT-aliases-all@@ will create a sorted list of _all_
+### aliases from all subsections.
+###
+### @@INSERT-other-foobar@@ is special, just does text replaces
+### without any special formatting, useful for:
+### \command{umask @@INSERT-other-umask@@}{...
+### 'other' does not have -default nor -all.
+###
+### you may specify certain subsections like this:
+### #a3#, which will put the input in the into the
+### @@INSERT-aliases-debian@@ tag.
+###
+### See the @secmap array below for section numbers.
+### Yes, this could be done with real names instead of numbers.
+### But names tend to be rather long. I don't want that.
+###
+#}}}
+
+### variables {{{
+my $refin = "./grml-zsh-refcard.tex.in";
+if (defined($ARGV[0]) && $ARGV[0] =~ m!^[^+]!) {
+  $refin = shift;
+}
+my $MAX_INPUT=10000;
+my $verbose = 0;
+if (defined($ARGV[0])) {
+  $verbose = length($ARGV[0]);
+}
+my @secmap = (
+  "default",    #0
+  "system",     #1
+  "user",       #2
+  "debian",     #3
+  "search",     #4
+  "shortcuts",  #5
+  "services"    #6
+);
+my (
+  $i,
+  $ln,
+  $inc,     # global counter for input lines
+  @input,
+  %data,    # HoA
+  %other,   # @@INSERT-other-*@@
+  %splits   # if lists get long, we might need to split them. HoA
+);
+my $splitstring="\\commandlistend\n\\pagebreak\n\\commandlistbegin";
+###}}}
+### subroutines {{{
+sub dumpdata() {
+  my ($key, $entry);
+  if ($verbose < 5) { return; }
+  xprint(5, " --- Data ---\n");
+  foreach $key (sort keys(%other)) {
+    xprint(5, "    \@\@INSERT-other-$key\@\@ -> $other{$key}\n");
+  }
+  foreach $key (sort keys(%data)) {
+    xprint(5, "    \@\@INSERT-$key\@\@ =>\n");
+    foreach $entry (sort @{ $data{$key} }) {
+      xprint(5, "$entry\n");
+    }
+  }
+  foreach $key (sort keys(%splits)) {
+    xprint(5, "    List-Splitting Offset for $key:\n");
+    foreach $entry (@{ $splits{$key} }) {
+      xprint(5, "$entry\n");
+    }
+  }
+  xprint(5, " --- Dump ---\n");
+}
+
+sub xprint {
+  my $level = shift;
+  if ($verbose >= $level) {
+    print STDERR @_;
+  }
+}
+
+sub escape_string($) {
+  my $in = shift;
+  $in =~ s!([\\\{\}\*\&~\$_])!\\$1!g;
+  return($in)
+}
+
+sub demystify_keys($) {
+  # what an ugly hack :-)
+  my $keys = shift;
+  my @tok = split(/(\\e[^\^]|\^.)/, $keys);
+  my ($k, $out);
+
+  $out = '';
+  foreach $k (@tok) {
+    if ($k eq '') { next; }
+    if ($k =~ m!^[^\\\^]!) {
+      $k =~ s!(.)! $1!g;
+    }
+    else {
+      $k =~ s!\\e!ESC-!g;
+      $k =~ s!\^I!TAB!g;
+      $k =~ s!\^[jJmM]!return!g;
+      $k =~ s!\^!CTRL-!g;
+    }
+    $out .= $k;
+  }
+
+  return($out);
+}
+
+sub insert($$$) {
+  my $linenum=shift; my $cat=shift; my $sec=shift;
+  my ($entry, $count);
+  if ($sec eq '') { $sec = 'default'; }
+  if (!defined($data{"$cat-$sec"})) {
+    warn("Unknown insertion tag in line $linenum (\@\@INSERT-$cat-$sec\@\@). IGNORING.\n");
+    return;
+  }
+  xprint(1, "inserting: category($cat) section($sec), line: $linenum\n");
+  $count = 0;
+  foreach $entry (sort @{ $data{"$cat-$sec"} }) {
+    my $is;
+    foreach $is (@{ $splits{"$cat-$sec"} } ) {
+      if ($count == $is) {
+        print("$splitstring\n");
+        last;
+      }
+    }
+    print("$entry\n");
+    $count++;
+  }
+}
+
+sub handle_hashdir($$) {
+  my $sec = shift ; my $desc = shift;
+  my ($dir, $value);
+  if ($sec eq '') { $sec=0; }
+  xprint(1, "Handling hashed dir (section: $secmap[$sec]) in line $ln ($desc)\n");
+  $ln++;
+  while ($ln <= $i) {
+    if ($input[$ln] =~ m!^\s*\#d[0-9]*\#!) {
+      xprint(1, "Ending hashed dir handling in line $ln.\n");
+      $ln++;
+      return;
+    }
+    if ($input[$ln] =~ m!\s*hash\s+-d\s+([^=]+)=(.*)!) {
+      $dir=$1; $value=&escape_string($2);
+      push(@{ $data{"hasheddirs-$secmap[$sec]"} }, "\\command\{$dir\}\{$value\}");
+    }
+    else {
+      warn("Broken hashed dir in line $ln. IGNORING.\n");
+    }
+    $ln++;
+  }
+}
+
+sub handle_abbrev($$) {
+  my $sec = shift ; my $desc = shift;
+  my ($abbrev, $value, $doc);
+  if ($sec eq '') { $sec=0; }
+  xprint(1, "Handling abbreviation (section: $secmap[$sec]) in line $ln ($desc)\n");
+  $ln++;
+  while ($ln <= $i) { # the global $i
+    if ($input[$ln] =~ m!^\s*\#A[0-9]*\#!) {
+      xprint(1, "Ending abbreviation handling in line $ln.\n");
+      $ln++;
+      return;
+    }
+    $doc = '';
+    if ($input[$ln] =~ s!\s+\#d\s*([^#]*)$!!) { $doc = $1; }
+    if ($input[$ln] =~ m!\s*['"]([^"']*)['"]\s\$?['"]([^"']*)['"]!) {
+      $abbrev = $1; $value = &escape_string($2);
+      xprint(2, "ab: $abbrev -> $value ($doc);\n");
+      push(@{ $data{"abbrev-$secmap[$sec]"} }, "\\command\{$abbrev\}\{\\kbd\{$value" . ($doc ne '' ? "\}\\quad $doc" : "\}") . "\}");
+    }
+    else {
+      warn("Broken abbreviation in line $ln. IGNORING.\n");
+    }
+    $ln++;
+  }
+}
+
+sub handle_function($$) {
+  my $sec = shift ; my $desc = shift;
+  if ($sec eq '') { $sec=0; }
+  xprint(1, "Handling function (section: $secmap[$sec]) in line $ln ($desc)\n");
+  $ln++;
+  if ($input[$ln] =~ m!\s*(function)?\s*([^(\s]*)!) {
+    xprint(2, "  - $2()\n");
+    push(@{ $data{"functions-$secmap[$sec]"} }, "\\command\{$2()\}\{$desc\}");
+  }
+  else {
+    warn("Parsing function line $ln ($input[$ln]) failed. IGNORING.\n");
+  }
+}
+
+sub handle_alias($$) {
+  my $sec = shift ; my $desc = shift;
+  my ($alias, $value);
+  if ($sec eq '') { $sec=0; }
+  xprint(1, "Handling alias (section: $secmap[$sec]) in line $ln ($desc)\n");
+  $ln++;
+  if ($input[$ln] =~ m!\s*alias (-[haocC] +)*([^=]*)=["'](.*)["']!) {
+    $alias=$2; $value=&escape_string($3);
+    $desc =~ s!\@a\@!$value!;
+    push(@{ $data{"aliases-$secmap[$sec]"} }, "\\command\{$alias\}\{$desc\}");
+  }
+  else {
+    warn("Parsing alias line $ln ($input[$ln]) failed. IGNORING.\n");
+  }
+}
+
+sub handle_other($$) {
+  my $sec = shift ; my $desc = shift;
+  $desc =~ m!([^\s]+)\s+(.*)!;
+  xprint(1, "Handling 'other' tag in line $ln ($1 -> $2))\n");
+  $other{$1} = $2;
+  $ln++;
+}
+
+sub handle_keybinding($$) {
+  my $sec = shift ; my $desc = shift;
+  my ($kbd, $value);
+  if ($sec eq '') { $sec=0; }
+  xprint(1, "Handling keybinding (section: $secmap[$sec]) in line $ln ($desc)\n");
+  $ln++;
+  if ($input[$ln] =~ m!^.*bindkey\s+[^'"]*(.*)['"]\s+([\w-]*)\#?.*!) {
+    $value=&escape_string($2);
+    $kbd = $1;
+    $kbd =~ s!^["']!!;
+    $kbd =~ s!["']$!!;
+    $kbd=&demystify_keys($kbd);
+    $desc =~ s!\@k\@!$value!;
+   #xprint(0, "!-> DEBUG: kbd: $kbd - value: $value - desc: $desc\n");
+    push(@{ $data{"keybindings-$secmap[$sec]"} }, "\\command\{$kbd\}\{$desc\}");
+  }
+  else {
+    warn("Parsing keybinding line $ln ($input[$ln]) failed. IGNORING.\n");
+  }
+}
+
+sub handle_variable($$) {
+  my $sec = shift ; my $desc = shift;
+  my ($var, $value);
+  if ($sec eq '') { $sec=0; }
+  xprint(1, "Handling variable (section: $secmap[$sec]) in line $ln ($desc)\n");
+  $ln++;
+  if ($input[$ln] =~ m!^.*\s+(\w*)=(.*)$!) {
+    $var = $1 ; $value = $2;
+    $value =~ s!^\$\{\w*:-(.*)\}!$1!;
+    $value =~ s!^['"]!!;
+    $value =~ s!['"]$!!;
+    $value = &escape_string($value);
+    push(@{ $data{"variables-$secmap[$sec]"} }, "\\command\{$var\}\{\\kbd\{$value" . ($desc ne '' ? "\}\\quad $desc" : "\}") . "\}");
+  }
+  else {
+    warn("Parsing variable line $ln ($input[$ln]) failed. IGNORING.\n");
+  }
+}
+
+sub handle_manual($$$) {
+  # this is different than the other handle_*() subs.
+  my $code = shift ; my $key = shift ; my $value = shift;
+  my $sec;
+  xprint(1, "Handling manual entry (code: $code) in line $ln ($key -> $value)\n");
+  $sec = ( (length($code) > 1) ? substr($code, 1) : 0);
+  if    (substr($code, 0, 1) eq 'a') {
+    push(@{ $data{"aliases-$secmap[$sec]"} }, "\\command\{$key\}\{$value\}");
+  }
+  elsif (substr($code, 0, 1) eq 'A') {
+    push(@{ $data{"abbrev-$secmap[$sec]"} }, "\\command\{$key\}\{$value\}");
+  }
+  elsif (substr($code, 0, 1) eq 'd') {
+    push(@{ $data{"hasheddirs-$secmap[$sec]"} }, "\\command\{$key\}\{$value\}");
+  }
+  elsif (substr($code, 0, 1) eq 'f') {
+    push(@{ $data{"functions-$secmap[$sec]"} }, "\\command\{$key\}\{$value\}");
+  }
+  elsif (substr($code, 0, 1) eq 'k') {
+    push(@{ $data{"keybindings-$secmap[$sec]"} }, "\\command\{$key\}\{$value\}");
+  }
+  elsif (substr($code, 0, 1) eq 'o') {
+    push(@{ $data{"other-$secmap[$sec]"} }, "\\command\{$key\}\{$value\}");
+  }
+  elsif (substr($code, 0, 1) eq 'v') {
+    push(@{ $data{"variables-$secmap[$sec]"} }, "\\command\{$key\}\{$value\}");
+  }
+  else {
+    warn("Unknown doc-definition character in manual-line $ln ($1). IGNORING.\n");
+    $ln++;
+  }
+  $ln++;
+}
+
+sub set_option($) {
+  my $optstring = shift;
+  my ($opt, $val);
+  $ln++;
+  if ($optstring =~ m!([a-zA-Z0-9_-]+)\s+(.*)!) {
+    $opt = $1;
+    $val = $2;
+    if ($opt eq 'split') {
+      if ($val =~ m!([a-zA-Z0-9_-]+)\s+(.*)!) {
+        my $what = $1;
+        my $when = $2;
+        xprint(2, "  splitting values (for $what): " . join(' ', split(/,/, $when)) . "\n");
+        @{ $splits{"$what"} } = split(/,/, $when);
+      }
+      else {
+        warn("Parsing split option failed in line $ln. IGNORING.\n");
+      }
+    }
+    else {
+      warn("Unknown option ($opt) in line $ln. IGNORING.\n");
+    }
+  }
+  else {
+    warn("Parsing option in line $ln failed. IGNORING.\n");
+  }
+}
+
+###}}}
+
+### main()
+### {{{ handling stdin
+$i = 0;
+$input[0]='index==linenumber :-)';
+while (<STDIN>) {
+  $i++;
+  if ($i > $MAX_INPUT) {
+    die "Sorry dude, input lines exeeded maximum ($MAX_INPUT)}\n";
+  }
+  chomp;
+  push(@input, $_);
+}
+$ln = 1;
+while ($ln <= $i) {
+  if ($input[$ln] =~ m!^\#\@\#\s*(.*)$!) {
+    &set_option($1);
+    next;
+  }
+  if ($input[$ln] =~ m!^\s*\#([a-zA-Z])([0-9]*)\#\s*(.*)$!) {
+    if    ($1 eq 'a') {
+      &handle_alias($2, $3);
+    }
+    elsif ($1 eq 'A') {
+      &handle_abbrev($2, $3);
+    }
+    elsif ($1 eq 'd') {
+      &handle_hashdir($2, $3);
+    }
+    elsif ($1 eq 'f') {
+      &handle_function($2, $3);
+    }
+    elsif ($1 eq 'k') {
+      &handle_keybinding($2, $3);
+    }
+    elsif ($1 eq 'o') {
+      &handle_other($2, $3);
+    }
+    elsif ($1 eq 'v') {
+      &handle_variable($2, $3);
+    }
+    elsif ($1 eq 'm') {
+      my $arg = $3;
+      $arg =~ m!^\s*([a-zA-Z][0-9]*)\s+(\S+)\s+(.*)!;
+      &handle_manual($1, $2, $3);
+    }
+    else {
+      warn("Unknown doc-definition character in line $ln ($1). IGNORING.\n");
+      $ln++;
+    }
+  }
+  else {
+    $ln++;
+  }
+}
+#}}}
+
+&dumpdata();
+
+open(IN, "<$refin") or die "could not open $refin: $!\n";
+$i=0;
+while (<IN>) { #{{{ output loop
+  $i++;
+  while (m!\@\@INSERT-other-[^@]+\@\@!) {
+    s!\@\@INSERT-other-([^@]+)\@\@!$other{$1}!;
+    xprint(2, "Inserting \@\@INSERT-other-$1\@\@ -> $other{$1}\n");
+  }
+  if (m!^\@\@INSERT-([^-]*)-?(.*)\@\@!) {
+    if ($1 eq '') {
+      die "malformed insertion tag in line $i ($_). ABORT\n";
+    }
+    &insert($i, $1, $2);
+  }
+  else {
+    print;
+  }
+}#}}}
+close(IN);
diff --git a/grml-zsh-refcard.tex.in b/grml-zsh-refcard.tex.in
new file mode 100644 (file)
index 0000000..89ff86c
--- /dev/null
@@ -0,0 +1,435 @@
+\documentclass[8pt,             % 8pt
+               a4paper,         % A4
+               oneside,         % Einseitig
+               DIV20,           % Papiergröße
+             % DIV15,           % Größer
+             % draft,           % Entwurf
+               headsepline,     % Trennlinie oben
+               footsepline,     % -""-       unten
+               smallheadings,   % Kleine Überschriften
+             % pointlessnumbers,% Keine Punkte
+               halfparskip,     % Halbe Zeile Absatz statt Einzug
+               nochapterprefix, % Kein "Kapitel"
+             % bibtotoc         % "Literatur" im TOC  oder
+             % bibtotocnumbered,% -""-, nummeriert
+             % idxtotoc,        % Index im TOC
+               twocolumn
+              ]{scrartcl}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Pakete {{{
+\usepackage[latin1]{inputenc}       % ISO-Umlaute
+\usepackage[T1]{fontenc}            % T1-kodierte Fonts
+\usepackage{ae,aecompl}             % Kodierung für PDF
+%\usepackage{ngerman}                % Deutsche Trennungen,
+                                    % dt. Begriffe
+\usepackage{setspace}               % Single- oder Onehalfspacing
+%\setcounter{tocdepth}{4}            % 4 Hirarchien im Inhaltsv.
+\usepackage{times}                  % Times als Schrift
+\usepackage{amsmath,amssymb,amstext}% Mathematische Symbole
+\usepackage{url}                    % Darstellung von URLs
+\usepackage{calc}
+
+%%% Optional, je nach Dokument
+% \usepackage{listings}             % Quelltext-Listings
+% \usepackage{units}                % Technische Units
+% \usepackage{psfrag}               % Ersetzts PS-Schriften
+% \usepackage{color}                % Farben in LaTeX
+% \usepackage{floatflt}             % Textumflossene Bilder...
+% \usepackage{picins}               % Textumflossene Bilder
+% \usepackage{textcomp}             % Spezielle Zeichen
+% \usepackage[small,compact]{titlesec}             % Überschriften mit wenig Platz
+% \usepackage{gensymb}              % Spezielle Zeichen
+% \usepackage{eurosym}              % Euro-Symbol
+
+%%% Layout
+\usepackage{scrpage2}               % KOMA-Überschriften und -Fußzeilen.
+%%% }}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% PDF {{{
+\newif\ifpdf
+  \ifx\pdfoutput\undefined
+    \pdffalse
+  \else
+    \pdfoutput=1
+    \pdftrue
+  \fi
+
+\ifpdfoutput{
+  \usepackage[pdftex]{graphicx}
+  \DeclareGraphicsExtensions{.pdf}
+  \pdfcompresslevel=9
+  \usepackage[%
+    pdftex=true,
+    backref=true,
+    colorlinks=true,
+    bookmarks=true,
+    breaklinks=true,
+    linktocpage=true,
+    bookmarksopen=false,
+    bookmarksnumbered=false,
+    pdfpagemode=None
+  ]{hyperref}
+}{
+  \usepackage[dvips]{graphicx}
+  \DeclareGraphicsExtensions{.eps}
+  % \usepackage[%
+  %   dvips,
+  %   breaklinks=true,
+  %   colorlinks=false
+  % ]{hyperref}
+}
+%%% }}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Eigene Funktionen {{{
+%%% Beispiel:  \bild{200pt}{foo}{That's a foo\ldots}
+\newcommand{\bild}[3]{
+  \begin{figure}
+    \includegraphics[width=#1, keepaspectratio=true]{#2}
+    \caption{#3}
+    \label{#2}
+  \end{figure}
+}
+
+\newcommand{\kbd}[1]{\texttt{#1}}
+\newcommand{\commandlistbegin}{
+  \vspace{3pt}
+  \begin{tabular}{ll}
+}
+\newcommand{\commandlistend}{
+  \end{tabular}
+}
+\newcommand{\command}[2]{
+  \texttt{#1} & \quad #2 \\
+}
+
+%%% }}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Pagestyle {{{
+  \pagestyle{scrheadings}
+% \pagestyle{fancyhdrs}
+% \pagestyle{empty}
+%%% }}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Seitenkopf- und -Fußzeilen {{{
+ \automark[subsection*]{section} % \left- und \rightmark bekommen Inhalt
+%%% Oben: Links, Mitte, Rechts
+ \ihead[]{{\Huge GRML-Zsh-Refcard}}
+ \chead[]{}
+ \ohead[]{Revision: Die Feb 06 20:11:16 CET 2007}
+ %\ohead[]{Revision: \today}
+%%% Unten: Links, Mitte, Rechts
+ \ifoot[]{\vspace{-3pt}GRML-Zsh-Refcard}
+ \cfoot[]{}
+ \ofoot[]{\vspace{-3pt}\copyright 2005-2007 \href{mailto:julius@grml.org}{Julius Plenz},
+ \href{mailto:mika@grml.org}{Michael Prokop} and
+ \href{mailto:ft@bewatermyfriend.de}{Frank Terbeck}}
+%%% }}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Sonstiges {{{
+% \setlength{\parindent}{17pt}      % Einzug 17pt,
+% \setlength{\parskip}{2pt}         % keine Leerzeilen.
+
+% \textwidth      127mm             % Textbreite
+% \textheight     235mm             % Texthöhe
+% \topmargin     -5mm               % Abstand oben
+% \oddsidemargin  7mm               % Abstand Links, onepage
+
+%\onehalfspacing                    % Zeilenabstand: Bei korrektur,
+ \singlespacing                     % bei Abgabe
+
+% Punkt- und Komma Abstände bei Tausendern/
+% Dezimalzahlen ans deutsche anpassen!
+ \mathcode`,="013B
+ \mathcode`.="613A
+
+ \setlength{\emergencystretch}{2em} % Notfallsstreckung
+%%% }}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\addtolength{\voffset}{10pt}
+\renewcommand{\figurename}{Abb.}
+\begin{document}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Titelseite {{{
+%\pagenumbering{none}                % Für die Titelseite: Keine Seitennummern,
+%\thispagestyle{empty}               % keine Kopf- und Fußzeilen.
+%
+%\begin{center}
+%
+%\end{center}
+%\newpage
+%
+%%% }}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Inhaltsverzeichnis {{{
+  \pagenumbering{arabic}            % Arabische Nummerierung
+% \pagenumbering{roman}             % Kleine, römische Nummerierung
+% \tableofcontents                  % Das Inhaltsverzeichnis
+% \listoffigures                    % Verzeichnis aller Abbildungen
+% \listoftables                     % Verzeichnis aller Tabellen
+% \pagenumbering{arabic}            % ...und wieder Arabisch
+% \newpage
+%%% }}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% we won't be using math mode much, so redefine some of the characters
+% we might want to talk about
+\catcode`\^=12
+\catcode`\_=12
+
+\chardef\\=`\\
+\chardef\{=`\{
+\chardef\}=`\}
+
+\parskip=0pt
+\setlength{\tabcolsep}{0pt}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Inhalt {{{
+
+%Schon in lhead
+%\section{GRML's Zsh-Setup Reference Card}
+
+\subsection*{Configuration files}
+
+\small{Global zsh configuration is located in \textbf{/etc/zsh/zshrc}.  User
+specific settings are defined in \textbf{/etc/skel/.zshrc} (which can be found
+in \kbd{\~}/.zshrc for user grml too). Please notice that some functions/aliases
+are not active by default for user root (referred to as '... for user (grml)'
+below) because of security reasons. Just run 'zshskel' (as user root) to source
+the file /etc/skel/.zshrc. Some aliases/functions also aren't active if the
+appropriate executable isn't present on your system.
+
+/etc/zsh/zshrc: this file can be adjusted according to your needs via using a
+file named /etc/zsh/zshrc.local which is not part of the Debian package
+management. So place all your changes in the file /etc/zsh/zshrc.local.  If you
+don't have write permissions to /etc/zsh/zshrc on your own, copy the file
+/etc/zsh/zshrc to \kbd{\~}/.zshrc.global and it will be sourced by
+\kbd{\~}/.zshrc then.
+
+Write important commands you always need (no matter what's inside zsh's
+history!) to a file named \textbf{\kbd{\~}/.important\_commands}.
+
+Notice that /etc/skel/.zshrc itself is not sourced by zsh but copied to
+\$HOME-directory of your non-root user once. To keep your
+\textbf{\kbd{\~}/.zshrc} in sync with upstream's development just put your
+personal stuff into a file named \textbf{\kbd{\~}/.zshrc.local} and point your
+\kbd{\~}/.zshrc to /etc/skel/.zshrc running 'ln -s /etc/skel/.zshrc
+\kbd{\~}/.zshrc'.}
+
+You can get information regarding configuration files and some environment
+variables to adjust runtime behaviour of grml's zsh running \textbf{zsh-help}.
+
+\subsection*{Using grml's zsh configuration on a non-grml system}
+
+You do not have to use grml/Debian to use grml's zsh configuration.
+Just retrieve and install the configuration files for example running:
+
+\begin{tiny}
+\begin{verbatim}
+wget -O ~/.zshrc      http://hg.grml.org/grml-etc-core/raw-file/tip/etc/skel/.zshrc
+wget -O ~/.zshrc.global http://hg.grml.org/grml-etc-core/raw-file/tip/etc/zsh/zshrc
+\end{verbatim}
+\end{tiny}
+
+\subsection*{Problems?}
+
+Please report any problems you notice using the grml zsh configuration
+to the grml-team. The configuration has been tested on several Linux
+Distribution (Debian, Gentoo, SuSE,...) and non-Linux systems as well
+(FreeBSD, Solaris, AIX,...) but there might be issues anyway. Please
+\href{http://grml.org/bugs/}{report them}!
+
+\subsection*{Settings}
+
+If not already defined, the variables are set to the following
+values:
+
+\commandlistbegin
+@@INSERT-variables@@
+\commandlistend
+
+\commandlistbegin
+\command{umask @@INSERT-other-umask@@}{new files automatically get permissions \kbd{@@INSERT-other-umaskstr@@}}
+\command{umask @@INSERT-other-r_umask@@}{new files for root user \kbd{@@INSERT-other-r_umaskstr@@}}
+\commandlistend
+
+\subsection*{Key Bindings}
+
+Default keybinding mode is Emacs, i.e. you can use Emacs keybinds like
+\kbd{^A {\rm or} ^E} on the command line. You can however also switch
+to vi mode.
+
+\commandlistbegin
+\command{setopt emacs}{Switch to Emacs mode (default)}
+\command{setopt vi}{Switch to vi mode}
+\commandlistend
+
+\subsection*{Keybindings}
+
+The following keybindings document some important keybindings which are not
+defined by zsh's default configuration. Tip: press <tab> twice when completing a
+command you installed which is not yet known to zsh or run 'rehash' manually.
+
+\commandlistbegin
+@@INSERT-keybindings@@
+\commandlistend
+
+\newpage
+
+\subsection*{Terminal Settings}
+
+There are 8 aliases designed to change the font size of the
+XTerm, Aterm\ldots These are:
+\kbd{hide},
+\kbd{tiny},
+\kbd{small},
+\kbd{medium},
+\kbd{default},
+\kbd{large},
+\kbd{huge},
+\kbd{smartfont},
+\kbd{semifont}.
+
+\subsection*{Hashes}
+
+Directory hashes are shortcuts for often used directories. You can
+expand them by typing \kbd{\~{}hash}. Usage example: 'cd \kbd{\~}doc'
+
+\commandlistbegin
+@@INSERT-hasheddirs@@
+\commandlistend
+
+\subsection*{System-Wide Aliases}
+
+\commandlistbegin
+@@INSERT-aliases-system@@
+\commandlistend
+
+\subsection*{Global Functions}
+
+\commandlistbegin
+@@INSERT-functions-system@@
+@@INSERT-functions-services@@
+\commandlistend
+
+\vspace{8pt}
+\subsection*{Debian commands}
+
+Notice: if not executed as root it tries to run the command via sudo if
+necessary.
+
+\commandlistbegin
+@@INSERT-aliases-debian@@
+@@INSERT-functions-debian@@
+\commandlistend
+
+\subsection*{Aliases for user (grml)}
+
+\commandlistbegin
+@@INSERT-aliases-user@@
+\commandlistend
+
+\subsection*{Abbreviation expansion for user (grml)}
+
+As of version 0.9 grml does not enable global aliases anymore.  Instead, a
+feature similiar to vim's 'iab' was added. The default key-sequence to trigger
+the expansion is ',.'.
+
+Example:
+
+\commandlistbegin
+\kbd{co}\begin{Huge},.\end{Huge} \quad expands to: \kbd{./configure \&\& make \&\& sudo make install}
+\commandlistend
+
+The configuration of this feature and its implementation are described in the zshwiki
+<\url{http://zshwiki.org/home/examples/zleiab}>.
+
+\commandlistbegin
+@@INSERT-abbrev@@
+%\vspace{35pt} % temporary hack for alignment of columns/rows
+\commandlistend
+
+\vspace{12pt}
+Most of the normal aliases are also added to this database, so you may expand them
+just like this as well.
+
+%\pagebreak
+
+%% Global Aliases are disabled ATM.
+%\subsection*{Global Aliases}
+%
+%Global Aliases are expanded {\it everywhere} on the command line, not
+%only if they are at the first position. Example: 'cat foo bar C' is the
+%same as running 'cat foo bar | wc -l'.
+%
+%\commandlistbegin
+%\command{BG}{\kbd{\& exit}}
+%\command{C}{\kbd{| wc -l}}
+%\command{G}{\kbd{| grep}}
+%\command{H}{\kbd{| head}}
+%\command{Hl}{\kbd{-{}-help |\& less -r} \quad(display help in pager)}
+%\command{K}{\kbd{| keep}}
+%\command{L}{\kbd{| less}}
+%\command{M}{\kbd{| most}}
+%\command{N}{\kbd{\&>/dev/null} \quad(No Output)}
+%\command{R}{\kbd{| tr A-z N-za-m} \quad(ROT13)}
+%\command{SL}{\kbd{| sort | less}}
+%\command{S}{\kbd{| sort}}
+%\command{T}{\kbd{| tail}}
+%\command{V}{\kbd{| vim -}}
+%\commandlistend
+
+\subsection*{Functions for user (grml)}
+
+\textbf{Searching}
+
+\commandlistbegin
+@@INSERT-functions-search@@
+\commandlistend
+
+\vspace{12pt}
+\textbf{Shortcuts}
+
+\commandlistbegin
+@@INSERT-functions-shortcuts@@
+\commandlistend
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Dieser Trenner muss eingefügt werden, wenn eine Tabelle zu lang ist
+% und daher nicht von LaTeX umbrochen wird.
+%\commandlistend
+%
+%\commandlistbegin
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+%%% }}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Bibliographieverzeichnis {{{
+%\newpage
+%\nocite{*}
+%\bibliographystyle{plaindin}
+%\bibliography{quellen}
+%%% }}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\end{document}
+
+%%% vim:set ai tw=80 fdm=marker:   EOF