\section{\ldeen{Kurztutorial}{Short Tutorial}}
\ldeen{Dieses Tutorial begleitet Nora. Nora hält im kommenden Semester erstmals
die Vorlesung "`Betriebssysteme"'.
Die erste Unterrichtseinheit soll über Speicher gehen. Nora will sofort
Speichervirtualisierung behandeln.
Die ist vielleicht etwas optimistisch, aber das soll uns hier nicht aufhalten.

Der Studiengang, in dem der Kurs stattfindet, ist zwar deutschsprachig, aber Nora weiß,
dass viele Gaststudenten teilnehmen werden, die besser Englisch als Deutsch beherrschen.
Daher will sie Folien jeweils in beiden Sprachen vorbereiten.
Außerdem hat sie versprochen, ein kurzes Skript bereitzustellen.
Für die Lehrveranstaltung selbst möchte sie außerdem eine Vortragendenfassung
mit der aktuellen und der nächsten Folie sowie eigenen Anmerkungen verwenden.

Mehrere Dokumentinstanzen für zunächst eine einzige Stunde Lehre:
Nora ahnt bereits, dass getrennte Quelldateien keine besonders gute Idee
wären.}{This tutorial follows Nora.
Next semester, Nora will be teaching
the lecture "`Operating Systems"' for the first time.
The first lesson will cover storage. Nora wants to dive right into storage virtualization.
That might be a bit optimistic, but let's not let that stop us here.

Although the degree program in which the course is offered is German-language, Nora knows
that many visiting students will be attending who are more comfortable with English than with German.
That’s why she wants the slides to be in both languages.
She has also promised to provide a short set of lecture notes.
For the lecture itself she also wants a presenter's version showing the current
and next slide together with her own remarks.

Several document instances for what is initially just a single hour of instruction:
Nora already suspects that having separate source files wouldn’t be
a particularly good idea.}

\ldeen*{Das Tutorial beschreibt nicht jede Möglichkeit von \osglecture. Es zeigt vielmehr
die Dinge, die Nora für ihren ersten kleinen Kurs tatsächlich benötigt.\footnote{%
  Wer lieber sofort in die Details gehen will, kann auch direkt im Abschnitt~@1 weiterlesen.
}%
 Am Ende entstehen aus einem einzelnen Quelldokument einer Lehreinheit Folien,
eine Vortragendenfassung und ein Skript, jeweils in zwei Sprachen.}{The
tutorial does not describe every option in the bundle. Instead, it shows the
things Nora actually needs for her first small course.\footnote{%
  If you'd rather get right into the details, you can continue reading directly in section~@1.
} At the end, one course unit will produce slides, a presenter's version, and
lecture notes, each in two languages.}{\ref{sec:concepts}}

\paragraph{\ldeen{Noras Problem}{Nora's Problem}.}
\ldeen{Nora beginnt so, wie man vermutlich intuitiv ohne \osglecture\ beginnen
würde. Sie legt \File{slides-de.tex} an, füllt es mit Inhalt, kopiert die Datei nach
\File{slides-en.tex} und beginnt mit der Übersetzung. Für das Skript fügt sie
später noch \File{script-de.tex} hinzu. Das funktioniert.
Allerdings fällt kurze Zeit später ein, dass sie bei der Beschreibung des Unterschieds
zwischen \emph{Paging} und \emph{Segmentierung} etwas Wichtiges vergessen hat.
Jedoch klingelt bei der Bearbeitung ihr Telefon, und nach dem Anruf muss Nora überlegen,
in welche der Dateien sie die Korrektur übernommen hat.}{Nora starts off the way one would probably intuitively begin without \osglecture.
She creates \File{slides-de.tex}, copies the file to
\File{slides-en.tex}, and begins the translation. For the script, she
later adds \File{script-de.tex}. That works.
However, shortly afterward, she realizes that she forgot something important in the
description of the difference between \emph{paging} and \emph{segmentation}.
But while she’s editing, her phone rings, and after the call, Nora has to figure out
which of the files she made the correction in.
}

\begin{figure}[htbp]
\centering
\begin{minipage}[t]{.27\linewidth}
  \begin{tcolorbox}[colback=red!3,colframe=red!55!black]
  \centering\File{slides-de.tex}\par\smallskip
  \scriptsize\ldeen{64 Einträge}{64 entries}
  \end{tcolorbox}
\end{minipage}\hfill
\begin{minipage}[t]{.27\linewidth}
  \begin{tcolorbox}[colback=red!3,colframe=red!55!black]
  \centering\File{slides-en.tex}\par\smallskip
  \scriptsize\ldeen{64 Einträge}{64 entries}
  \end{tcolorbox}
\end{minipage}\hfill
\begin{minipage}[t]{.27\linewidth}
  \begin{tcolorbox}[colback=red!3,colframe=red!55!black]
  \centering\File{script-de.tex}\par\smallskip
  \scriptsize\ldeen{63 Einträge?}{63 entries?}
  \end{tcolorbox}
\end{minipage}
\caption{\ldeen{Kopien sind bequem anzulegen und unbequem zu pflegen.}{Copies are easy to create and awkward to maintain.}}
\end{figure}

\ldeen{Nora entscheidet deshalb, \osglecture\ zu nutzen und nur noch eine fachliche
Quelle zu pflegen. Die
Sprachen sollen darin nahe beieinanderstehen; Folien und Skript sollen ebenfalls
aus dieser Quelle entstehen. Genau dies wird im Folgenden eingerichtet.}{Nora therefore
decides to use \osglecture\ and to maintain only one subject-specific
source. The languages should be closely aligned within it; slides and lecture notes should
also be derived from this source. This is exactly what will be set up below.}

\paragraph{\ldeen{Ein Zuhause für den Kurs}{A Home for the Course}.}
\ldeen{Zunächst braucht der Kurs ein Verzeichnis. Nora könnte alle Dateien dort
ablegen. Sie entscheidet sich aber gleich für zwei Unterverzeichnisse: eines für
gemeinsame Angaben und eines für die erste Lehreinheit. Dass die Einheit die
Nummer \code{010} statt \code{001} erhält, erscheint ihr zunächst unnötig
großzügig. Später kann sie dafür eine neue Einheit \code{005-Overview}
dazwischenschieben, ohne alles umzubenennen.
In das Verzeichnis für die erste Lehreinheit kommt die Quelldatei.
Nora legt erst mal eine leere Datei mit dem Namen \File{main.tex} an,
da dies bei \osglecture\ der Standardname für die \LaTeX-Hauptdatei einer
Lehreinheit ist.
}{First, the course needs a directory. Nora could put every file directly into it.
Instead, she immediately
chooses two subdirectories: one for shared settings and one for the first course
unit. Giving the unit the number \code{010} rather than \code{001} initially
seems unnecessarily generous. Later, however, she can insert a new unit named
\code{005-Overview} before it without renaming everything.}

\begin{verbatim}
mkdir -p Noras-os/Include Noras-os/010-Memory
cd Noras-os
touch 010-Memory/main.tex
\end{verbatim}

\ldeen{Noch ist das Ergebnis nicht besonders eindrucksvoll}{The result is not
particularly impressive yet}:
\begin{manualdirtree}
  \dtdir{Noras-os}{\ldeen{Projektwurzel}{project root}}{
    \dtdir{Include}{\ldeen{gemeinsame Angaben}{shared settings}}{}
    \dtdir{010-Memory}{\ldeen{erste Lehreinheit}{first course unit}}{
      \dtfile{main.tex}{}
    }
  }
\end{manualdirtree}

\ldeen{Immerhin ist nun klar, was zum gesamten Kurs und was nur zur Einheit
"`Virtueller Speicher"' gehört.}{At least it is now clear what belongs to the
whole course and what belongs only to the "`Virtual Memory"' unit.}

\paragraph{\ldeen{Nora bestellt Ergebnisse}{Nora Orders Some Outputs}}
\ldeen{Nora hat nun Verzeichnisse, aber noch kein Weg, das aus ihrer einen
Quelle die gewünschten Dokumente erzeugt. Diese Aufgabe übernimmt \OLLM, der
\emph{OSG LaTeX Lecture Maker}. \OLLM\ ist das Buildwerkzeug des Bundles: Es wählt
Dokumenttyp und Sprache, startet den passenden \LaTeX-Lauf und verwaltet die
entstandenen Dateien. Nora wird \OLLM\ deshalb nicht den Inhalt ihrer Vorlesung
erklären, wohl aber, welche Ergebnisse sie erwartet.}{Nora now has directories,
but no way to turn her single source into the documents she wants. This is
the job of \OLLM, the \emph{OSG LaTeX Lecture Maker}. \OLLM\ is the bundle's build
tool: it selects the document type and language, starts the appropriate \LaTeX\
run, and manages the resulting files. Nora will therefore not tell \OLLM\ the
subject matter of her lecture, but she will tell it which outputs she expects.}

\ldeen{Eine konkrete Wahl aus Lehreinheit, Target und Sprache heißt im Folgenden
\emph{Instanziierung}.
Diesen Begriff kennt Nora schon aus der Objektorientierten Programmierung.
Aber anders als dort ist das Ergebnis einer Instanziierung kein Objekt sondern eine
\emph{Dokumentinstanz}.
Die Kombination "`Unterrichtseinheit \code{memory}, Target \code{slides}, Sprache
\code{en}"' erzeugt beispielsweise die englische Folieninstanz dieser Einheit.
Damit ist präzise benannt, was \OLLM\ später bauen soll.}{A specific selection of a teaching unit, target, and language is referred to below as
\emph{instantiation}.
Nora is already familiar with this term from object-oriented programming.
But unlike in that context, the result of an instantiation is not an object but a
\emph{document instance}.
For example, the combination "`Lesson \code{memory}, Target \code{slides}, Language
\code{en}"' generates the English slide instance of this lesson.
This precisely specifies what \OLLM\ is to generate later.}

\ldeen{Nora möchte \OLLM\ am liebsten sofort mit \code{ollm slides} starten.
Das Werkzeug kann jedoch noch nicht wissen, welche Sprachen der Kurs anbietet
oder ob Nora z.\,B.\ überhaupt ein Skript haben möchte. Diese Angaben kommen in ein
Manifest namens \File{ollmconfig.toml} in der Projektwurzel. Man kann es als
Bestellzettel lesen: Nora bestellt zwei Sprachfassungen der Folien und zwei des
Skripts.}{Nora would prefer to start \OLLM\ immediately by typing
\code{ollm slides}. However, the tool cannot yet know which languages the course offers
or whether Nora wants lecture notes at all. This information goes into a
manifest named \File{ollmconfig.toml} in the project root. It can be read as
an order form: Nora orders two language versions of the slides and two of the
lecture notes.}

\begin{verbatim}
schema = 2
bundle_preset = "OSG lecture/1"

[project]
id = "os-in-60"

[targets.defaults]
languages = ["de", "en"]
default_language = "de"
presentation_profile = "ltx-talk"
longform_profile = "book"
document_metadata = "enabled"

[targets.slides]
[targets.screen]
[targets.script]
\end{verbatim}

\ldeen{Nora ist versucht, hier auch Titel, Autorin und Übersetzungen einzutragen.
TOML kann schließlich Text speichern. Sie lässt es dennoch bleiben: Das Manifest
beschreibt die zu erzeugenden Dokumentinstanzen, nicht den Inhalt des Dokuments. Titel und
Sprachabbildung sind \LaTeX-Angelegenheiten und folgen im nächsten Schritt.}{Nora
is tempted to add the title, author, and translations here as well. After all,
TOML can store text. She resists the temptation: the manifest describes the build
matrix, not the document's content. The title and language mapping are \LaTeX\
concerns and follow in the next step.}

\ldeen{Bevor sie weiterschreibt, prüft Nora den Bestellzettel}{Before continuing,
Nora checks the order form}:
\begin{verbatim}
ollm check
\end{verbatim}

\ldeen{Bei ihrem ersten Versuch hatte sie \option{language} statt
\option{languages} geschrieben. \OLLM\ weist den unbekannten Schlüssel zurück.
Das ist Nora lieber als stillschweigend Kursmaterial in der falschen Sprache zu erhalten.
Nachdem sie den Tippfehler korrigiert hat, ist das Manifest gültig.
Auch falls ihre Buildumgebung selbst Probleme bereitet, schließlich erwartet
\osglecture\ eine relativ moderne \LaTeX-Installation, kann \OLLM\ helfen:
\code{ollm doctor} liefert die passendere Diagnose.}{
On her first attempt, she had written \option{language} instead of
\option{languages}. \OLLM\ rejects the unknown key.
Nora prefers that to a course that’s silently in German. After she
corrects the typo, the manifest is valid.
Even if her build environment itself is causing problems,
\code{ollm doctor} provides a more accurate diagnosis.
}

\paragraph{\ldeen{Was für alle Lehreinheiten gilt}{What Applies to Every Unit}.}
\ldeen{Nora möchte ihren Namen und den Kurstitel nicht in jeder späteren Einheit
wiederholen. Sie legt deshalb \File{Include/projectconfig.tex} an. Im Manifest
hat sie für Präsentationen bereits \cls{ltx-talk} und für das Skript die
Standardklasse \cls{book} gewählt. Beide Profile arbeiten mit der neuen
PDF-Verwaltung von \LaTeX; damit kann Nora ihre Dokumente als Tagged PDF
bereitstellen. Das passende Präsentationsthema kann sie unabhängig davon
auswählen.

Die Wahl der Klassen ist eine Projektentscheidung;
die einzelnen Fachtexte in den Lehreinheiten müssen von diesen Klassennamen nichts wissen.
Außerdem lernt Nora, dass Dokumente, die nicht zu den Präsentationen oder Handouts
gehören, in \osglecture\ "`Langformen"' genannt werden. Ihr Skript ist eine solche
Langform.
}{Nora does not want
to repeat her name and the course title in every future unit. She therefore
creates \File{Include/projectconfig.tex}. In the manifest she has already
selected \cls{ltx-talk} for presentations and the standard \cls{book} class
for the lecture notes. Both profiles use \LaTeX's new PDF management, allowing
Nora to provide her documents as Tagged PDF. She can select a suitable
presentation theme independently.

The choice of classes is a project-level decision;
the individual subject-specific texts within the teaching units do not need to be aware of these class names.
In addition, Nora learns that documents that are not part of the presentations or handouts
are called "`long forms"' in \osglecture. Her lecture notes are one such
long form.}

\ldeen*{Sie schreibt in @1}{She writes into @1}{\File{/Include/projectconfig.tex}}

\begin{verbatim}
\title{\ldeen{Betriebssysteme}{Operating Systems}}
\author{Nora Example}

\LectureProjectSetup{
  languages={
    map={de=ngerman,en=british},
    load babel
  }
}
\end{verbatim}

\ldeen{Die Profilwahl steht im Manifest und nicht in
\File{projectconfig.tex}, weil die Basisklasse und ihr Bedarf an
\cs{DocumentMetadata} feststehen müssen, bevor die Klasse überhaupt startet.
Für die frühe PDF-Konfiguration legt Nora deshalb zusätzlich
\File{Include/documentmetadata.tex} an}{The profile selection belongs in the
manifest rather than \File{projectconfig.tex}, because the base class and its
need for \cs{DocumentMetadata} must be known before the class starts. Nora
therefore also creates \File{Include/documentmetadata.tex} for the early PDF
configuration}:

\begin{verbatim}
\DocumentMetadata{
  lang = \OsgLectureRequestedLanguage,
  tagging = on
}
\end{verbatim}

\ldeen{\OLLM\ bindet diese Datei bei allen drei Targets vor
\cs{documentclass} ein. Die sichtbaren Dokumentangaben bleiben dagegen in
\File{projectconfig.tex}.}{\OLLM\ includes this file before
\cs{documentclass} for all three targets. Visible document metadata remains in
\File{projectconfig.tex}.}

\ldeen{Die verbleibende Sprachkonfiguration enthält zwei verschiedene Arten von
Namen. \OLLM\ arbeitet mit den kurzen, portablen Kennungen \code{de} und
\code{en}, wie sie in der Norm ISO 639-1 definiert sind. Das verbreitete
Sprachpaket \pkg{babel} benötigt dagegen die konkreteren Namen \code{ngerman}
und \code{british}. Der Schlüssel \option{languages} reicht dieses Mapping an
\pkg{langselect} weiter und lädt \pkg{babel}. Welche Sprachen das Projekt
überhaupt anbietet, steht bereits im Manifest -- \osglecture\ reicht die Liste
von dort an \pkg{langselect}.}{The remaining language configuration contains
two different kinds of names. \OLLM\ uses the short, portable identifiers
\code{de} and \code{en}. The popular language package \pkg{babel}, by
contrast, needs the more specific names \code{ngerman} and \code{british}. The
\option{languages} key passes this mapping on to \pkg{langselect} and loads
\pkg{babel}. Which languages the project offers at all is already in the
manifest -- \osglecture\ hands that list from there to \pkg{langselect}.}

\paragraph{\ldeen{Endlich etwas Fachliches}{At Last, Some Subject Matter}.}
\ldeen{Nun schreibt Nora \File{010-Memory/main.tex}. Sie beginnt bewusst mit
wenig Inhalt. Ein kleines, erfolgreich gebautes Dokument ist eine angenehmere
Ausgangsbasis als zwanzig Seiten, bei denen eine schließende Klammer fehlt.}{Now
Nora writes \File{010-Memory/main.tex}. She deliberately starts with little
content. A small document that builds successfully is a more pleasant starting
point than twenty pages with a missing closing brace.}

\begin{verbatim}
\documentclass{osglecture}

\begin{document}
\lecture[Memory]{\ldeen{Virtueller Speicher}{Virtual Memory}}{lec:memory}

\begin{frame}
  \frametitle{\ldeen{Warum virtueller Speicher?}{Why virtual memory?}}
  \ldeen{Jeder Prozess sieht einen eigenen Adressraum.}
        {Each process sees a private address space.}
  \Note{\ldeen{Hier an die Analogie mit Zimmernummern erinnern.}
               {Recall the analogy with room numbers here.}}
\end{frame}

\begin{frame}
  \frametitle{\ldeen{Seitentabellen}{Page tables}}
  \ldeen{Eine Seitentabelle ordnet virtuelle Seiten physischen
         Seitenrahmen zu.}
        {A page table maps virtual pages to physical page frames.}
\end{frame}
\end{document}
\end{verbatim}

\ldeen{Der Befehl \cs{lecture} dient Nora dazu, eine Unterrichtseinheit zu beginnen.
Das erste Pflichtargument ist der Titel, das optionale Argument seine Kurzform.}{The
\cs{lecture} command begins a course unit. Its first mandatory argument is the
title, and the optional argument is the short title.}
\ldeen{Das zweite Pflichtargument von \cs{lecture}, hier
\code{lec:memory}, ist das Label der Unterrichtseinheit
Dieses etabliert die Identität der Einheit. Nora darf den sichtbaren
Titel später verbessern und sogar das Verzeichnis umbenennen. Die Identität
sollte sie aber dabei nicht beiläufig ändern; Querverweise und Buildzustand verwenden
 diesen Wert, um die richtige Lehreinheit zu finden.}{The second mandatory argument of \cs{lecture}, here
\code{lec:memory}, is the label of the unit. It constitutes the unit's stable identity.
Nora may improve the visible title later and may even rename the directory.
She should not casually change the identity while doing so; cross-references and build state use this
very value.}

\ldeen{Die \env{frame}-Umgebung kennt Nora schon aus ihrer früheren Arbeit mit \cls{beamer}.
  Sie hat dort zwar häufig den Titel in ein Umgebungsargument geschrieben, aber das darf sie bei \osglecture\ nicht;
  dafür gibt es den Befehl \cs{frametitle}.}{Nora already knows the
\env{frame} environment from her earlier work with \cls{beamer}. She often
put the title in an environment argument there, but \osglecture\ does not
permit that; the \cs{frametitle} command must be used instead.}
\ldeen{Den Befehl \cs{ldeen} kennt Nora noch nicht. Sie findet auch bei einer kurzen Suche mit \code{grep} in ihrem \LaTeX-Verzeichnis kein Paket, das ihn definiert. Dennoch ist Nora intuitiv klar, was er macht: Er stellt die
beiden Sprachvarianten, die Nora bestellt hat, nebeneinander dar.}{Nora has not
seen the \cs{ldeen} command before. Even a quick \code{grep} search of her
\LaTeX\ directory finds no package defining it. Nevertheless, its purpose is
intuitively clear to her: it places the two requested language variants side
by side.}

\ldeen{\cs{Note} enthält dagegen eine Anmerkung für Nora selbst. Sie gehört in
den Frame, auf den sie sich bezieht. Auf den gewöhnlichen Folien und im Skript
erscheint sie nicht; die Vortragendenfassung sammelt sie später auf ihrer
Presenter-Seite.}{\cs{Note}, by contrast, contains a remark for Nora herself.
It belongs inside the frame to which it refers. It does not appear on the
ordinary slides or in the lecture notes; the presenter's version later
collects it on its presenter page.}

\paragraph{\ldeen{Der erste Build}{The First Build}.}
\ldeen{Nora wechselt in die Lehreinheit und versucht aus alter Gewohnheit zuerst
\File{lualatex main.tex}. Das ist zwar ein verständlicher Versuch, umgeht aber
den Bestellzettel: Target und Sprache fehlen. Für einen Serienkurs ist \OLLM\ der
richtige Eingang. Nora baut also zunächst genau das Ergebnis, das sie gerade
sehen möchte}{Nora changes into the course unit and, out of habit, first tries
\File{lualatex main.tex}. This is an understandable attempt, but it bypasses
the order form: the target and language are missing. For a course series, \OLLM\
is the right entry point. Nora therefore first builds exactly the output she
wants to see}:

\begin{verbatim}
cd 010-Memory
ollm build slides --language=de
\end{verbatim}

\ldeen{Das Ergebnis ist eine deutsche Folie. Sie liegt nicht neben
\File{main.tex}; \OLLM\ hält erzeugte Dateien unter
\path{.osglecture/build} von den Quellen getrennt. Nora sucht kurz im falschen
Verzeichnis, findet die Trennung dann aber überzeugend: Ein beschädigter
Buildordner kann entfernt werden, ohne dass dabei Lehrmaterial verschwindet.}{
The result is a German slide. It is not placed next to \File{main.tex}; \OLLM\
keeps generated files below \path{.osglecture/build}, separate from the sources.
Nora briefly looks in the wrong directory, but then finds the separation
convincing: a damaged build directory can be removed without losing teaching
material.}

\ldeen{Die englische Folie ist jetzt fast enttäuschend einfach}{The English slide
is now almost disappointingly easy}:
\begin{verbatim}
ollm build slides --language=en
\end{verbatim}

\ldeen{Nur die gewählte Formulierung ändert sich. Struktur und Formel bleiben dieselben.
Genau das wollte Nora erreichen.}{Only the selected
wording changes. The structure and formula remain the same.
That is precisely what Nora wanted to achieve.}

\paragraph{\ldeen{Eine Fassung für Nora}{A Version for Nora}.}
\ldeen{Für die Lehrveranstaltung baut Nora außerdem das Target
\code{screen}}{For the lecture Nora also builds the \code{screen} target}:

\begin{verbatim}
ollm build screen --language=de
\end{verbatim}

\ldeen{Diese Dokumentinstanz verwendet dieselben Folien, macht jede Seite aber
doppelt so breit. Links liegt die Folie für den Projektor; rechts sieht Nora
die aktuelle und die nächste Folie sowie ihre mit \cs{Note} notierte
Erinnerung. Bei einem erweiterten Desktop kann sie die beiden Hälften auf
Projektor und eigenen Bildschirm verteilen. Die Vortragendenfassung bleibt
damit Teil derselben Quelle, ohne selbst eine Fassung für die Studierenden zu
sein.}{This document instance uses the same slides but makes every page twice
as wide. The slide for the projector is on the left; on the right Nora sees
the current and next slide together with the reminder recorded using
\cs{Note}. With an extended desktop she can distribute the two halves between
the projector and her own screen. The presenter's version thus remains part
of the same source without itself becoming a version for the students.}

\ldeen{Auch diese Instanz wird mit eingeschaltetem Tagging gebaut. Die
zusätzliche Presenter-Seite ist jedoch eine Bedienhilfe für Nora und gehört
nicht zur Lesereihenfolge der eigentlichen Folie.}{This instance is also built
with tagging enabled. The additional presenter page is an aid for Nora,
however, and is not part of the reading order of the slide itself.}

\begin{minipage}{\linewidth}
  \captionsetup{type=figure}
  \centering
  \begin{subcaptiongroup}
    \begin{minipage}[t]{.48\linewidth}
      \fbox{\includegraphics[page=1,width=\linewidth]{tutorial-output-slides.pdf}}
      \caption{\ldeen{Die Folienfassung zeigt jeweils eine Folie.}{The slide
      version shows one slide at a time.}}
    \end{minipage}\hfill
    \begin{minipage}[t]{.48\linewidth}
      \fbox{\includegraphics[page=1,width=\linewidth,
        trim=18mm 176mm 18mm 18mm,clip]{tutorial-output-script.pdf}}
      \caption{\ldeen{Im Skript werden die Inhalte nacheinander gesetzt.}{In
      the lecture notes, the contents are typeset consecutively.}}
    \end{minipage}

    \begin{minipage}[t]{.96\linewidth}
      \fbox{\includegraphics[page=1,width=\linewidth]{tutorial-output-screen.pdf}}
      \caption{\ldeen{Die Vortragendenfassung ergänzt rechts Vorschau und
      Anmerkung.}{The presenter's version adds the preview and remark on the
      right.}}
    \end{minipage}
  \end{subcaptiongroup}
  \caption{\label{fig:tutorial-document-instances}\ldeen{Drei
  Dokumentinstanzen aus derselben Quelle.}{Three document instances from the
  same source.}}
\end{minipage}

\ldeen{Abbildung~\ref{fig:tutorial-document-instances} macht den Unterschied
der drei Targets sichtbar. Die Anmerkung gehört ausschließlich in Noras
Vortragendenfassung; das Skript übernimmt dagegen beide Frames als fortlaufenden
Text.}{Figure~\ref{fig:tutorial-document-instances} shows the difference
between the three targets. The remark belongs exclusively in Nora's presenter
version, while the lecture notes typeset both frames as continuous text.}

\paragraph{\ldeen{Von Stichpunkten zu einem Satz}{From Bullet Points to a Sentence}}
\ldeen{Nora ergänzt zwei weitere Aussagen. Eine gewöhnliche \code{itemize}-Liste
wäre auf der Folie passend. Im Skript möchte sie jedoch keinen Absatz, der nur
aus drei Stichpunkten besteht. Sie könnte dafür zwei Fassungen schreiben, aber
das würde ihr ursprüngliches Problem in kleinerem Maßstab wiederholen. Stattdessen
verwendet sie die \pkg{presitemize}-Umgebung}{Nora adds two more statements. An ordinary
\code{itemize} list would suit the slide. In the lecture notes, however, she
does not want a paragraph consisting only of three bullet points. She could write
two versions, but that would repeat her original problem on a smaller scale.
Instead, she uses \pkg{presitemize}}:

\begin{verbatim}
\begin{frame}
  \frametitle{\ldeen{Warum virtueller Speicher?}{Why virtual memory?}}
  \begin{presitemize}
    \item \ldeen{Jeder Prozess sieht einen eigenen Adressraum}
                {Each process sees a private address space}
    \anditem \ldeen{die Hardware übersetzt virtuelle Adressen}
                   {the hardware translates virtual addresses}
    \thereforeitem \ldeen{Prozesse \finite{sind} voneinander isoliert}
                         {processes \finite{are} isolated}
  \end{presitemize}
\end{frame}
\end{verbatim}

\ldeen{Auf der Folie bleiben dies drei Einträge. In der Langform werden daraus
verbundene Aussagen. Das markierte finite Verb hilft dabei, im deutschen
Nebensatz aus "`Prozesse sind voneinander isoliert"' die Formulierung "`weshalb
Prozesse voneinander isoliert sind"' zu bilden. Nora findet die Markierung etwas
ungewohnt, aber immer noch angenehmer als einen zweiten Absatz, der später
vergessen werden kann.
Und sie ist froh, dass English in dieser Beziehung ein bisschen regelmäßiger ist und
die Verben nicht so herumschubst.
}{On the slide these remain three entries. In the long form
they become connected statements. The marked finite verb helps turn "`Prozesse
sind voneinander isoliert"' into the German subordinate clause "`weshalb Prozesse
voneinander isoliert sind"'. Nora finds the marking slightly unfamiliar, but
still preferable to a second paragraph that might later be forgotten.
And she's glad that English is a little more regular in that regard and doesn't mess
with the verb forms so much.
}

\paragraph{\ldeen{Etwas mehr Platz im Skript}{A Little More Room in the Notes}.}
\ldeen{Für die Folie genügt Nora die knappe Begründung. Im Skript möchte sie
zusätzlich erklären, wo die Abbildung gespeichert wird. Diesmal unterscheidet
sich nicht bloß die Formulierung, sondern der gewünschte Inhalt. Nora ergänzt
deshalb nach dem Frame einen sogenannten \emph{Modusabschnitt}}{The concise explanation is enough
for Nora's slide. In the lecture notes she also wants to explain where the
mapping is stored. This time it is not merely the wording that differs, but the
desired content. Nora therefore adds a so-called \emph{mode section} after the frame}:

\begin{verbatim}
\lecturemode<longform>{
  \ldeen*{Eine Seitentabelle speichert die Abbildung @1.}
        {A page table stores the mapping $v\mapsto @1.}{$v\mapsto p$}
}
\end{verbatim}

\ldeen{Sie hätte auch \code{<script>} schreiben können. Jedoch sagt \code{<longform>}
genauer, was sie meint: Der Absatz passt in jede ausführliche Langform,
nicht nur in den heute konfigurierten Skripttyp. Falls sie später von
\cls{scrbook} zu einem anderen Langformprofil wechselt, muss sie diese Stelle
nicht wiederfinden.}{She could have written \code{<script>}.
\code{<longform>}, however, states her intention more accurately: the paragraph
suits any detailed long form, not merely the script type configured today. If
she later changes from \cls{scrbook} to another long-form profile, she need
not find this passage again.}

\ldeen{Noch längere Erläuterungstexte kann Nora außerhalb der \env{frame}-Umgebung schreiben.
Dann braucht sie für die Langform auch keinen extra Modus: Die dortigen Texte werden bei den Präsentationen ignoriert.}{Nora
can write still longer explanatory passages outside the \env{frame}
environment. She then needs no additional mode for the long form: text there
is ignored in presentations.}

\ldeen{Nun baut Nora das deutsche Skript}{Nora now builds the German lecture
notes}:
\begin{verbatim}
ollm build script --language=de
\end{verbatim}

\ldeen{Beim Vergleich sieht sie erstmals die beiden Dimensionen unabhängig
voneinander: \option{--language} wählt die Sprache, das Target
\code{slides}, \code{screen} oder \code{script} die Dokumentgestalt. Beides verändert die
Ausgabe, aber keines verlangt eine Kopie der Lehreinheit.}{When comparing the
results, she sees the two dimensions independently for the first time:
\option{--language} selects the language, while the \code{slides},
\code{screen}, or \code{script} target selects the document form. Both change the output, but
neither requires a copy of the course unit.}

\paragraph{\ldeen{Hat Nora wirklich an alles gedacht?}{Did Nora Really Think of Everything?}}
\ldeen{Während des Schreibens erzeugt Nora gewöhnlich nur die Dokumentinstanz,
an der sie gerade arbeitet. Das ist schnell, birgt aber eine kleine Gefahr: Eine fehlende
Klammer kann ausschließlich im englischen Zweig stecken; ein nur in Langformen
aktiver Befehl kann auf den Folien unbemerkt bleiben. Vor der Veröffentlichung
lässt Nora daher alle für diese Einheit bestellten Kombinationen bauen}{While
writing, Nora usually creates only the document instance she is currently working on.
This is quick, but carries a small risk: a missing brace may occur only in the
English branch; a command active only in long forms may go unnoticed on the
slides. Before publishing, Nora therefore builds all combinations ordered for
this unit}:

\begin{verbatim}
ollm build --all
\end{verbatim}

\paragraph{\ldeen{Vom Build zur Veröffentlichung}{From Build to Publication}.}
\ldeen{Sechs erfolgreiche Dokumentinstanzen im Buildverzeichnis sind erfreulich,
aber Noras Studierende wissen davon noch nichts. Die beiden
Vortragendenfassungen bleiben bei Nora; Folien und Skripte möchte sie in ein
Verzeichnis \code{release} kopieren, das später etwa von der Lernplattform
oder einem Webserver übernommen werden kann. Sie könnte die Dateien von Hand
kopieren und umbenennen. Nach dem dritten Termin würde sie dabei vermutlich
mindestens einmal die englische Fassung unter dem deutschen Namen ablegen.}{Six
successful document instances in the build directory are gratifying, but
Nora's students still know nothing about them. The two presenter's versions
remain with Nora; she wants to copy the slides and lecture notes to a
\code{release} directory that can later be picked up by a learning platform
or web server. She could copy and rename the files by hand. By the third session,
she would probably have placed the English version under the German name at
least once.}

\ldeen{\OLLM\ trennt deshalb \emph{Bauen} und \emph{Deployment}. Ein Build erzeugt
und prüft eine Dokumentinstanz im internen Buildbereich. Ein Deployment kopiert
eine bereits erfolgreich gebaute Instanz unter einem vereinbarten Namen an
einen Veröffentlichungsort. Es startet selbst keinen neuen \LaTeX-Lauf.}{\OLLM\
therefore separates \emph{building} from \emph{deployment}. A build creates and
checks a document instance in the internal build area. A deployment copies an
already successfully built instance to a publication location under an agreed
name. It does not start another \LaTeX\ run.}

\ldeen{Nora ergänzt am Ende von \File{ollmconfig.toml} zwei Deploymentregeln}{
Nora adds two deployment rules at the end of \File{ollmconfig.toml}}:

\begin{verbatim}
[deployment]
series = "units"

[deployment.types.slides]
paths = ["release/slides"]
filename = "{ordinal}-{unit}-{lang}.pdf"

[deployment.types.script]
paths = ["release/notes"]
filename = "{ordinal}-{unit}-{lang}.pdf"
\end{verbatim}

\ldeen{Die Platzhalter werden für jede Dokumentinstanz gefüllt. Für die aktuelle
Einheit entstehen so beispielsweise \File{010-memory-de.pdf} und
\File{010-memory-en.pdf}. Nora nimmt die Sprache absichtlich in den Namen auf;
ein scheinbar schönerer Name \File{010-memory.pdf} wäre für zwei Sprachfassungen
nicht eindeutig.}{The placeholders are filled for each document instance. For
the current unit this produces, for example, \File{010-memory-de.pdf} and
\File{010-memory-en.pdf}. Nora deliberately includes the language in the file
name; the seemingly prettier \File{010-memory.pdf} would be ambiguous for two
language versions.}

\ldeen{\OLLM\ legt Deploymentverzeichnisse nicht selbst an. Das ist zunächst
überraschend, verhindert aber, dass ein Tippfehler im Manifest unbemerkt einen
zweiten Veröffentlichungsort erzeugt. Nora legt die vereinbarten Verzeichnisse
daher einmalig an und deployt anschließend alle gebauten Instanzen der aktuellen
Einheit}{\OLLM\ does not create deployment directories itself. This is surprising
at first, but prevents a typo in the manifest from silently creating a second
publication location. Nora therefore creates the agreed directories once and
then deploys all built instances of the current unit}:

\begin{verbatim}
mkdir -p ../release/slides ../release/notes
ollm deploy --all
\end{verbatim}

\ldeen{Nora befindet sich noch in \code{010-Memory}; deshalb bezieht sich das
Deployment standardmäßig auf diese Einheit. \OLLM\ kopiert nur vorhandene,
erfolgreich abgeschlossene Builds. Hat Nora nach einer Textänderung noch nicht
neu gebaut, ist \code{deploy} also kein versteckter Ersatz für
\code{build}. Diese Trennung gefällt ihr: Vor dem Kopieren kann sie die
Dokumentinstanzen in Ruhe prüfen.}{Nora is still in \code{010-Memory}; the
deployment therefore applies to this unit by default. \OLLM\ copies only existing,
successfully completed builds. If Nora has changed the text but has not rebuilt
it, \code{deploy} is not a hidden substitute for \code{build}. She likes
this separation: she can inspect the document instances before copying them.}

\ldeen{Beim nächsten Deployment liegt möglicherweise bereits eine ältere Datei
unter demselben Namen im Ziel. Ist sie identisch, bleibt sie unberührt. Ist sie
verschieden, verlangt die voreingestellte Sicherheitsregel eine ausdrückliche
Freigabe mit \option{--overwrite}. Nora sollte diese Option erst verwenden,
nachdem sie sich vergewissert hat, dass sie tatsächlich die veröffentlichte
Fassung ersetzen möchte.}{At the next deployment, an older file may already
exist under the same name at the destination. If it is identical, it remains
untouched. If it differs, the default safety policy requires explicit approval
with \option{--overwrite}. Nora should use this option only after confirming
that she really intends to replace the published version.}

\paragraph{\ldeen{Aus einer Einheit wird eine Serie}{One Unit Becomes a Series}.}
\ldeen{Für die zweite Unterrichtsstunde legt Nora neben \code{010-Memory} das
Verzeichnis \code{020-Processes} an. Dessen \File{main.tex} folgt dem bereits
bekannten Muster. Entscheidend ist nicht die Nummer im Verzeichnisnamen,
sondern die neue logische Unit-ID \code{processes}}{For the second lesson,
Nora creates the directory \code{020-Processes} next to \code{010-Memory}.
Its \File{main.tex} follows the familiar pattern. What matters is not the
number in the directory name, but the new logical unit ID \code{processes}}:

\begin{verbatim}
\documentclass{osglecture}

\begin{document}
\lecture[Processes]{\ldeen{Prozesse}{Processes}}{processes}
\section{\ldeen{Prozessplanung}{Scheduling}}\label{sec:scheduling}

\begin{frame}
  \frametitle{\ldeen{Wer läuft als Nächstes?}{Who Runs Next?}}
  \ldeen{Der Scheduler wählt einen ausführbaren Prozess aus.}
        {The scheduler selects a runnable process.}
\end{frame}
\end{document}
\end{verbatim}

\ldeen{Die beiden Verzeichnisse sind nun nicht bloß zufällige Nachbarn. Das
Manifest und ihre Unit-IDs machen sie zu Einheiten derselben \emph{Serie}.
Damit kann \OLLM\ ihre Dokumentinstanzen gemeinsam auswählen, ihren Zustand
verwalten und Abhängigkeiten zwischen ihnen auflösen. Nora baut beispielsweise
die deutschen Skriptinstanzen der ganzen Serie aus der Projektwurzel}{The two
directories are now more than accidental neighbours. The manifest and their
unit IDs make them units of the same \emph{series}. This allows \OLLM\ to select
their document instances together, manage their state, and resolve dependencies
between them. For example, from the project root Nora builds the German script
instances of the whole series}:

\begin{verbatim}
ollm build script --language=de --scope=series
\end{verbatim}

\ldeen{Der Scope \code{series} bedeutet dabei nicht, dass bereits ein einziges
großes PDF entsteht. Zunächst werden zwei selbstständige Skriptinstanzen gebaut.
Das ist nützlich, weil Nora einzelne Kapitel weiterhin getrennt bereitstellen
kann.}{The \code{series} scope does not mean that a single large PDF is already
created. Initially, two independent script instances are built. This is useful
because Nora can still distribute individual chapters separately.}

\paragraph{\ldeen{Ein Verweis über die Unit-Grenze}{A Reference Across the Unit Boundary}.}
\ldeen{Im Kapitel über Speicher möchte Nora nun auf die spätere Erläuterung der
Prozessplanung verweisen. Ein gewöhnliches \cs{ref} kennt nur Ziele der aktuellen
Dokumentinstanz. Für den serieninternen Verweis nennt Nora deshalb zusätzlich
die logische Ziel-Unit}{In the chapter on memory, Nora now wants to refer to the
later explanation of scheduling. An ordinary \cs{ref} only knows targets in the
current document instance. For the cross-unit reference, Nora therefore also
names the logical target unit}:

\begin{verbatim}
\ldeen*{Mehr dazu in @1.}
        {More on this in @1.}
        {\olautoref[processes]{sec:scheduling}}
\end{verbatim}

\ldeen{Ohne weitere Angaben wählt \cs{olautoref} im Ziel dieselbe Sprache und
denselben Dokumenttyp wie im Ausgangsdokument. Der deutsche Skriptverweis führt
also zum deutschen Skript, der englische Folienverweis zu den englischen Folien.
Soll ein Verweis bewusst etwa von einer Folie in das deutsche Skript führen,
kann Nora die Adresse als
\code{[processes,type=script,lang=de]} schreiben. Seitenverweise über
Dokumentgrenzen vermeidet sie: Die Seitenzahl des anderen PDFs kann sich
unabhängig ändern.}{Without further settings, \cs{olautoref} selects the same
language and document type in the target as in the source document. Thus, the
German script reference leads to the German script, while the English slide
reference leads to the English slides. If a reference is deliberately meant to
lead, for example, from a slide to the German script, Nora can write the address
as \code{[processes,type=script,lang=de]}. She avoids page references across
document boundaries: the page number of the other PDF can change independently.}

\ldeen{Das Ziel muss mindestens einmal erfolgreich gebaut worden sein, damit
\OLLM\ seine Unit-ID und Referenzziele kennt. Nach späteren Änderungen lässt
Nora mit \option{--resolve} die davon abhängigen Instanzen bis zu einem
konsistenten Stand neu bauen}{The target must have been built successfully at
least once so that \OLLM\ knows its unit ID and reference targets. After later
changes, Nora uses \option{--resolve} to rebuild dependent instances until
they reach a consistent state}:

\begin{verbatim}
ollm build script --language=de --scope=series --resolve
\end{verbatim}

\paragraph{\ldeen{Die Kapitel zu einem Gesamtskript verbinden}{Combining the Chapters into Complete Notes}.}
\ldeen{Für das Gesamtskript legt Nora eine dritte Unit an. Sie trägt die Rolle
\code{i} für \emph{Integration} im Verzeichnisnamen und enthält keinen weiteren
Fachtext, sondern nur das Rahmendokument. Die Reihenfolge der
\cs{includeunit}-Befehle bestimmt die Reihenfolge im Ergebnis}{For the complete
lecture notes, Nora creates a third unit. Its directory name carries the role
\code{i} for \emph{integration}, and it contains no further subject matter,
only the wrapper document. The order of the \cs{includeunit} commands determines
the order in the result}:

\begin{verbatim}
mkdir -p 900-i-collection
\end{verbatim}

\ldeen*{In @1 schreibt sie}{She writes in @1}{\File{900-i-collection/main.tex}}:

\begin{verbatim}
\documentclass{osglecture}

\begin{document}
\includeunit{memory}
\includeunit{processes}
\end{document}
\end{verbatim}

\ldeen{\cs{includeunit} fügt nicht die TeX-Quellen ein, sondern die bereits
gebauten Dokumentinstanzen derselben Sprache und desselben Dokumenttyps. So
bleiben die Kapitel einzeln nutzbar, während das Rahmendokument sie zu einem
Gesamtskript verbindet. Nora baut zuerst die Kapitel und anschließend die
eindeutig passende Integrationsunit}{\cs{includeunit} does not include the TeX
sources, but the already built document instances of the same language and
document type. The chapters therefore remain independently usable while the
wrapper combines them into complete lecture notes. Nora first builds the
chapters and then the uniquely matching integration unit}:

\begin{verbatim}
ollm build script --language=de --scope=series --resolve
ollm build script --language=de --scope=collection --resolve
ollm check --scope=series
\end{verbatim}

\ldeen{Der abschließende Check baut nichts neu, sondern meldet unter anderem
fehlende oder veraltete Referenz- und Integrationszustände. Für ein echtes
Projekt würde Nora dieselben Schritte natürlich auch für die englische
Skriptinstanz ausführen. Alle Varianten der Referenzbefehle beschreibt
Abschnitt~\ref{sec:content-command-reference}; die Regeln für Integration  stehen in Abschnitt~\ref{sec:series}, und die
vollständigen Buildoptionen in Abschnitt~\ref{sec:ollm-reference}.}{The final
check does not build anything; among other things, it reports missing or stale
reference and integration state. In a real project, Nora would of course run
the same steps for the English script instance. Section~\ref{sec:content-command-reference}
describes all variants of the reference commands; the rules for integration
are in Section~\ref{sec:series}, and the
complete build options are in Section~\ref{sec:ollm-reference}.}

\ldeen{Damit ist der kleine Kurs natürlich noch nicht fertig. Nora fehlen etwa
weitere Lehreinheiten und vermutlich mehr als zwei Stunden Inhalt. Aber
das Grundmuster steht: Das Manifest beschreibt die gewünschten Ergebnisse, die
Projektkonfiguration enthält gemeinsame Entscheidungen, und jede Lehreinheit
bewahrt den fachlichen Inhalt an einer Stelle. Neue Einheiten kann Nora nun nach
demselben Muster hinzufügen, ohne neue Sprach- oder Dokumentkopien anzulegen.}{
This does not, of course, finish the small course. Nora still lacks further
course units and probably more than two hours of content. But
the basic pattern is in place: the manifest describes the desired outputs, the
project configuration contains shared decisions, and each course unit keeps its
subject matter in one place. Nora can now add new units following the same
pattern without creating new language or document copies.}

\begin{infobox}{\ldeen{Hinweis}{Hint}}\sffamily
\ldeen{Wenn Sie dem Tutorial mit eigenen Dateien folgen, beginnen Sie ebenfalls
mit einer einzigen kleinen Einheit und einer Dokumentinstanz. Erst wenn diese gebaut
wird, ergänzen Sie die zweite Sprache, die Langform und schließlich
\option{--all}. Fehler bleiben so dem Schritt zugeordnet, der sie verursacht
hat.}{If you follow the tutorial with your own files, likewise begin with one
small unit and one document instance. Only once it builds should you add the second
language, the long form, and finally \option{--all}. This keeps errors associated
with the step that introduced them.}
\end{infobox}
