A “non-sciency” LaTeX book

One of my “customers” wanted a book that didn’t look so “sciency” (i.e., less like LaTeX). So here are a few tweaks to match their expectations.

Chapters should have letters as references with the prefix “Teil”:

\renewcommand{\thechapter}{Teil \Alph{chapter}}

Sections have the letter, a hyphen and the number:

\renewcommand*{\thesection}{\Alph{chapter}-\arabic{section}} 

Figures have no numbers, only the caption text below (using the package caption):

\usepackage{caption}
\captionsetup[figure]{labelformat=empty,textfont=footnotesize}
\renewcommand{\thefigure}{}

The first line of a paragraph is not indented. To compensate, the space between paragraphs is bigger:

\setlength\parindent{0pt}
\addtolength\parskip{4pt}

The header line of a page contains no section, but only the name of the chapter (using the package scrlayer-scrpage):

\usepackage{scrlayer-scrpage}
\clearpairofpagestyles % empty default header/footer markings
\automark[chapter]{chapter} % only chapter as mark
\ihead{\headmark} % inner margin has name of chapter
\ohead{\pagemark} % outer margin has page number

Compact lists in LaTeX

New environments that take up a lot less space than the original ones:

\newcommand{\backskip}{\vspace{-0.4\baselineskip}}
\newenvironment{compactitemize} % compact itemize list
{\backskip\begin{itemize}\itemsep0pt\parskip0pt}
{\end{itemize}\backskip}
\newenvironment{compactdescription} % compact description list
{\backskip\begin{itemize}\itemsep0pt\parskip0pt}
{\end{itemize}\backskip}
\newenvironment{compactenumerate} % compact enumerate list
{\backskip\begin{enumerate}\itemsep0pt\parskip0pt}
{\end{enumerate}\backskip}

A numbered environment for example sentences

I want an environment for example sentences where sentences are numbered and can be referenced. This is common in publications in the area of linguistics and there are a few packages that do the trick. But here is my own.

First, we need a counter that provides the number for the sentence:

\newcounter{mySentence}

We reset sentence counter for each chapter:

\@addtoreset{mySentence}{chapter}

We print the sentence number as (chapter.sentence):

\renewcommand*{\themySentence}{(\thechapter.\arabic{mySentence})}

Then we define an environment for one example sentence, where the number will be printed in the beginning of the line and then the sentence follows:

\newcommand{\backskip}{\vspace{-0.4\baselineskip}}
\newenvironment{examplesentence}
{% start env
\backskip%
\stepcounter{mySentence}%
\begin{enumerate} \small%
\renewcommand{\theenumi}{\thechapter.\arabic{mySentence}}%
\renewcommand{\labelenumi}{\themySentence}%
\itemsep0pt \parskip0pt%
\item
}
{% end env
\end{enumerate}
\backskip
}

Next is an environment for more than one example sentence. Here the sentence number will be printed in the beginning of the line and the individual sentences get an a., b., c., in front of them:

\newenvironment{examplesentences}
{% start env
\begin{examplesentence}%
\begin{enumerate} \itemsep0pt \parskip0pt%
\renewcommand{\theenumii}{\alph{enumii}}%
\renewcommand{\labelenumii}{\alph{enumii}.}%
}
{% end env
\end{enumerate}
\end{examplesentence}
}

Distribute updates from server to pool computers (hacky way)

This is the crowning achievement of my days at the MINT computer pool. Sadly, by the time I write this post, it will all be deleted. So here it is, archived for posterity.

The setting is a typical computer pool setting. 24 computers and one server. All computers load their home directories from the server (see here). Otherwise, each computer is totally independent. The idea is now, that updates to the pool computers can also be distributed from the server. So that I don’t have to sit down at each computer and execute a script which is a real pain. Again, a really common problem and many solutions exist – but I made my own, hacky, one.

Setting up the server side of things is easy. Basically, we create a few folders and put one shell script in the home of a special user called admin. There is a folder /home/admin/poolsetup/script into which we put a script poolupdate.sh. You can get the script from my wkutils github repository. This script goes through all files in another folder, /home/admin/poolsetup/updates, and executes any scripts it finds in there. It redirects the outputs of the execution into a log file in the folder /home/admin/poolsetup/logs. We can use this file to check what happened. And the update script uses the log file to avoid executing scripts twice. If a log file for a given script exists, we don’t execute the script again.

Because the home directories are loaded from the server, each pool computer will have access to files in the home directory of admin. We don’t have to do any copying to distribute the update script to the pool computers and any changes to the script will take effect right away.

So here are the commands for the server setup – basically just create the necessary folder structure with the correct permissions and put the update script there:

mkdir /home/admin/poolsetup/script
mkdir /home/admin/poolsetup/updates
mkdir /home/admin/poolsetup/logs
chmod o+rx /home/admin/poolsetup/script
chmod o+rx /home/admin/poolsetup/updates
chmod o+rwx /home/admin/poolsetup/logs
wget https://github.com/Kaffeedrache/wkutils/blob/master/admin/poolupdate.sh
mv poolupdate.sh /home/admin/poolsetup/script
chmod o+rx /home/admin/poolsetup/script/poolupdate.sh

On client side, we only have to make the computer execute the update script on a regular basis. We use cron and therefor call crontab which manages the cron jobs:

crontab -e

In the editor, we add these two lines:

00 17 * * 5 bash /home/admin/poolsetup/script/poolupdate.sh
@reboot bash -c "while [[ ! -d /home/admin/ ]] ; do sleep 5; done" ; bash /home/admin/poolsetup/script/poolupdate.sh

The first line will execute the update script every Friday at 5 PM. The second line will execute the script at every system start. We need the ugly loop with the sleep to ensure that the home directories have been mounted, before trying to access them.

So how does making an update work now? Write a script that does what you want to do. Put this script into the folder /home/admin/poolsetup/updates. When a pool computer starts up, it will execute the script. After that, look into the log folder and read the corresponding log to see what has happened. When all computers execute the update, usually you need to read only one log file and then check if all other log files have the same size. Done!

Access a server with an SSH key

Install ssh on the server:

apt-get install openssh-server

Generate a key pair (files id_rsa and id_rsa.pub) with a passphrase:

ssh-keygen

Edit the ssh configuration file:

vi /etc/ssh/sshd_config

In the file, make the following settings:

   PasswordAuthentication no
   PermitRootLogin without-password
   RSAAuthentication yes
   PubkeyAuthentication yes

Add the public key as an authorized key for root that can be used for login:

cat id_rsa.pub >> /root/.ssh/authorized_keys

That’s all for the server!

Now for the client. Copy the key pair into the folder ~/.ssh. Now you should be able to connect with:

ssh -i ~/.ssh/id_rsa root@server