--- /dev/null
+#!/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);
--- /dev/null
+\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