Besteht in LaTeX die Möglichkeit, Größenwerte von Befehlen berechnen zu lassen, statt unmittelbar anzugeben? Ein einfaches Beispiel:

Öffne in Overleaf
\newcommand{\laenge}{2mm}

\setlength{\parindent}{2 * \laenge} % Multiplikation mit 2

\RedeclareSectionCommand[tocnumwidth=\laenge+3mm]{chapter} % Addition mit 3 mm

gefragt 24 Apr, 03:36

rix's gravatar image

rix
39021220
Akzeptiert: 94%

bearbeitet 27 Apr, 01:48

1

Bitte wirf uns nicht nur Codeschnipsel vor, sondern mach immer ein vollständiges Minimalbeispiel. Damit können wir dann direkt arbeiten. Je näher das Beispiel an der tatsächlich beabsichtigen Anwendung ist, desto zielführender kann auch die Antwort sein.

(25 Apr, 01:59) saputello

Die Angabe eines Faktors zu einem Längenregister ist immer möglich:

Öffne in Overleaf
\newlength{\laenge}
\setlength{\laenge}{2mm}
\setlength{\parindent}{2\laenge}

Dabei ist \laenge quasi die Maßeinheit und 2 der Wert in dieser Maßeinheit. Bei Befehlen ist dies im Gegensatz zu Registern nicht möglich. Sowohl pdflatex, lualatex und xelatex beinhalten aber außerdem auch die e-TeX-Erweiterungen. Bei den gängigen, freien TeX-Distributionen MiKTeX und TeX Live gilt das auch für latex. Damit sind Ausdrücke mit Hilfe von \dimexpr oder \glueexpr möglich:

Öffne in Overleaf
\documentclass[12pt]{article}
\newcommand{\laenge}{2mm}
\begin{document}
\setlength{\parskip}{\glueexpr \laenge * 2 + 10pt plus 1pt minus 1pt\relax}
Der Absatzabstand ist nun: \the\parskip
\end{document}

Der Absatzabstand ist nun: 21.38107pt plus 1.0pt minus 1.0pt

Ersetzt man in diesem Beispiel \parskip durch \parindent erhält man übrigens als Ergebnis nur den Wert 21.38107pt ohne Leim (glue). Das liegt daran, dass \parindent nur ein (spezielles) Längenregister (dimen) ist, während \parskip eine dehn- und schrumpfbare Länge (skip) ist. Zu diesem Unterschied und dem zwischen Registern und Befehlen sei auf ausführliche LaTeX-Einführungen, TeX by Topic und The TeXbook verwiesen.

Natürlich kann man \glueexpr, \dimexpr und \numexpr nicht nur innerhalb von \setlength verwenden. Sie sind überall dort einsetzbar, wie man auch skips, dimens oder counter oder deren Werte verwenden kann, also beispielsweise auch:

Öffne in Overleaf
\documentclass[12pt]{scrbook}
\newcommand{\laenge}{2mm}
\RedeclareSectionCommand[tocnumwidth=\dimexpr\laenge+30mm\relax]{chapter} % Addition mit 30 mm
\begin{document}
\tableofcontents
\chapter{Test}
\end{document}

Der Inhaltsverzeichniseintrag mit großem Abstand zwischen Nummer und Text.

wobei hier als Besonderheit hinzu kommt, dass der Optionenparser von KOMA-Script für tocnumwidth (bzw. numwidth in \DeclareTOCStyleEntry) explizit auch Ausdrücke erlaubt.

Näheres zu \numexpr, \dimexpr und \glueexpr ist dem e-TeX-Manual zu entnehmen (bitte unbedingt nachlesen!!!).

Bei Verwendung von \dimexpr innerhalb von \newcommand muss man beachten, dass dies wie Makros oder Längen auch, erst zum Zeitpunkt der Verwendung ausgewertet wird. Dagegen wird der Ausdruck bei Verwendung in \setlength unmittelbar ausgewertet. Das ist ein genereller Unterschied zwischen \newcommand (und Makros) zu \setlength (und Längenregistern) und hat nichts mit \dimexpr selbst zu tun.

Nur zur Vollständigkeit sei auch noch auf das Paket calc hingewiesen, das diverse LaTeX-Befehle wie \setlength, \addtolength aber auch \rule, \makebox, \parbox etc. so erweitert, dass Berechnungen in den Längenargumenten möglich sind:

Öffne in Overleaf
\documentclass[12pt]{article}
\usepackage{calc}
\newcommand{\laenge}{2mm}
\begin{document}
\setlength{\parskip}{\laenge * 2 + 10pt plus 1pt minus 1pt}
Der Absatzabstand ist nun: \the\parskip
\end{document}

Allerdings findet dabei die Zerlegung der Ausdrücke in TeX statt, was wesentlich langsamer ist als die Verarbeitung mit den e-TeX-Primitiven \dimexpr, \glueexpr und \numexpr. Außerdem verändert das Paket nur die Befehle, die es kennt und hat beispielsweise keinen Einfluss darauf, was KOMA-Script als Wert für eine Option erlaubt.

Darüber hinaus gibt es Berechnungsmöglichkeiten auch in LaTeX3. So bietet beispielsweise l3skip mit \dim_eval:n die Möglichkeit, Ausdrücke zu berechnen. Damit verlassen wir dann aber die normale LaTeX-Syntax. expl3 beschreibt eher die Implementierungsebene für neue Benutzeranweisungen (also das, was Paketautoren verwenden können oder sollten) und ist weniger dazu gedacht, vom Benutzer direkt verwendet zu werden.

Permanenter link

beantwortet 24 Apr, 04:29

Ijon%20Tichy's gravatar image

Ijon Tichy
7.2k1919

bearbeitet 25 Apr, 02:22

Vielen Dank! Ich hatte aber eher an soetwas gedacht wie \newcommand{\laenge}{(2mm * 7) + \wasanderes}; oder innerhalb von Einstellungen: \RedeclareSectionCommand[tocnumwidth=\laenge+3mm]{chapter}

(25 Apr, 01:34) rix

@rix: Wenn Du die Antwort von Ijon verstanden hast, dann sollte Dir klar werden, dass man seine Antwort darauf unmittelbar anwenden und beispielsweise \newcommand*{\laenge}{\dimexpr (2mm * 7) + \wasanderes\relax} schreiben kann, sofern \wasanderes ebenfalls zu einer Länger expandiert (falls es glue enthalten kann, sollte man stattdessen \glueexpr verwenden).

(25 Apr, 01:56) saputello

@Ijon Tichy: Nochmal ganz herzlichen Dank für die Mühe und überarbeitete Erläuterung; genau, was ich gesucht habe.

(27 Apr, 01:38) rix
Deine Antwort auf die Frage (nicht auf andere Antworten)
Knebel-Vorschau

Folge dieser Frage

Per E-Mail:

Wenn Du Dich anmeldest, kannst Du Updates hier abonnieren

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs füge einfach zwei Leerzeichen an die Stelle ein, an der die neue Zeile sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Zugeordnete Themen:

×50
×7
×6
×5
×3

Frage gestellt: 24 Apr, 03:36

Frage wurde angeschaut: 150 Mal

Zuletzt aktualisiert: 27 Apr, 01:48