Anzeige:
Ergebnis 1 bis 5 von 5

Thema: Maximalwert für Länge bestimmen -- zurückgegebener Wert ist keine Länge?

  1. #1
    Registrierter Benutzer
    Registriert seit
    25.01.2009
    Beiträge
    43

    Maximalwert für Länge bestimmen -- zurückgegebener Wert ist keine Länge?

    Hallo!

    Ich bin gerade dabei, mir eine lco-Datei für scrlttr2 zu basteln. Im Fuß möchte ich mehrere Blöcke (Adresse, Bankverbindung, Telefonnummer/E-Mail/URL) haben, die jeweils aus drei Zeilen bestehen. Die einzelnen Blöcke wollte ich in eine parbox oder auch eine einspaltige Tabelle packen; um deren Breite zu bestimmen, benötige ich die Länge der längsten Zeile im jeweiligen Block.

    Dazu habe ich ein einfaches Makro erstellt, das die einzelnen Zeilen ausmisst und den größten Wert zurückgibt. Im Prinzip funktioniert das auch -- wenn ich das Makro im Textteil aufrufe, wird die Länge der längsten Zeile ausgegeben. Versuche ich allerdings, einer Länge den vom Makro zurückgegebenen Wert zuzuweisen, bricht LaTeX mit folgender Fehlermeldung ab:

    ! Missing number, treated as zero.

    \let
    l.52 ...ength{\test}{\maxwidth{asdf}{ASDF}{asdfg}}

    ?
    Anscheinend wird des Makros Rückgabewert also als Text interpretiert, nicht als Längenangabe. Was mache ich falsch?

    Hier noch das Minimalbeispiel:

    Code:
    \documentclass[version=last,visualize]{scrlttr2}
    
    \usepackage{filecontents}
    
    \begin{filecontents}{minimal.lco}
    \ProvidesFile{minimal.lco}
    \LetterOptionNeedsPapersize{paper=a4}{a4}
    
    \RequirePackage[utf8]{inputenc}
    \RequirePackage[T1]{fontenc}
    \RequirePackage{calc}
    \RequirePackage{printlen}
    \RequirePackage{xifthen}
    
    \@newplength{maxwidth}
    \@newplength{testwidth1}
    \@newplength{testwidth2}
    \newcommand{\maxwidth}[3]{%
            \@setplength{maxwidth}{\widthof{#1}}
            \@setplength{testwidth1}{\widthof{#2}}
            \@setplength{testwidth2}{\widthof{#3}}
    
            \ifthenelse{%
                \lengthtest{\useplength{testwidth1} > \useplength{maxwidth}}
                }
                {\@setplength{maxwidth}{\useplength{testwidth1}}}
                {}
    
            \ifthenelse{%
                \lengthtest{\useplength{testwidth2} > \useplength{maxwidth}}
                }
                {\@setplength{maxwidth}{\useplength{testwidth2}}}
                {}%
    
            \printlength{\useplength{maxwidth}}
    }
    \end{filecontents}
    
    \LoadLetterOption{minimal}
    
    \setlength{\parindent}{0cm}
    
    
    \begin{document}
    
    \begin{letter}{~}
    \opening{}
    
    Länge der längsten Zeile: \maxwidth{asdf}{ASDF}{asdfg}\\[1cm]
    
    \newlength{\test}
    \setlength{\test}{\maxwidth{asdf}{ASDF}{asdfg}}
    
    \fbox{\parbox{\test}{asdf\\ASDF\\asdfg}}
    
    \closing{}
    \end{letter}
    \end{document}
    Beste Grüße!

    Andreas

  2. #2
    Registrierter Benutzer
    Registriert seit
    09.12.2005
    Beiträge
    1.327
    \printlength ist keine Länge, sondern die Ausgabe einer Länge. Wäre es wenigstens eine reine Ziffernfolge gefolgt von einer Maßeinheit, würde es sogar trotzdem funktionieren. Aber \printlength ist nicht vollständig expandierbar und liefert deshalb nichts, was als Länge verwendebar wäre. Ein besserer Name für Deine Anweisung wäre also \printmaxwidth. Ganz ähnlich könntest Du Dir natürlich ein \settomaxwidth definieren, bei dem \printlength durch \setlength{…} ersetzt wird. Allerdings wäre es dann sinnvoller, statt mit Pseudolängen direkt idealer Weise als Parameter übergebene Länge für das Ausmessen zu verwenden, also etwas in der Art
    Code:
    \newcommand*{\settomaxwidth}[4]{%
      \ifthenelse{\withof{#2}>\widthof{#3}}{%
        \ifthenelse{\widtof{#2}>\widthof{#4}}{\settowidth{#1}{#2}}{\settowidth{#1}{#4}}%
      }{%
        \ifthenelse{\widthof{#3}>\widthof{#4}}{\settowidth{#1}{#3}}{\settowidth{#1}{#4}}%
      }%
    }
    ...
    \settomaxwidth{\test}{abcd}{efgH}{IJKLMO}
    Aber: Für eine einspaltige Tabelle musst Du die Länge gar nicht wissen. Da sollte ein
    Code:
    \begin{tabular}{@{}l@{}}
    abcd\\
    efgH\\
    JKLMO\\
    \end{tabular}
    vollkommen genügen. Davon abgesehen gibt es auch noch das Paket varwidth, das eine Art minipage-Umgebung zur Verfügung stellt, die sich selbst an die benötigte Breite anpasst.
    Geändert von klops (15-10-2015 um 11:45 Uhr)

  3. #3
    Registrierter Benutzer
    Registriert seit
    25.01.2009
    Beiträge
    43
    Schönen Dank erstmal, das waren doch recht hilfreiche Anregungen!

    Zitat Zitat von klops Beitrag anzeigen
    \printlength ist keine Länge, sondern die Ausgabe einer Länge. Wäre es wenigstens eine reine Ziffernfolge gefolgt von einer Maßeinheit, würde es sogar trotzdem funktionieren.
    Genau das hatte ich mir auch gedacht -- und im Beispiel (ohne die fehlerhafte Zeile) erhielt ich ja tatsächlich als Ausgabe "31.96996pt"!

    Zitat Zitat von klops Beitrag anzeigen
    Aber \printlength ist nicht vollständig expandierbar und liefert deshalb nichts, was als Länge verwendebar wäre.
    \printlength hatte ich eigentlich eh nur verwendet, weil ich nicht wusste, wie ich das Ergebnis aus dem Makro zurückgeben sollte. Zuerst hatte ich es mit \useplength versucht, war aber eigentlich nicht wirklich überrascht, dass das nicht funktioniert. :-)

    Zitat Zitat von klops Beitrag anzeigen
    Ein besserer Name für Deine Anweisung wäre also \printmaxwidth. Ganz ähnlich könntest Du Dir natürlich ein \settomaxwidth definieren, bei dem \printlength durch \setlength{…} ersetzt wird.
    Das ist natürlich viel eleganter! Ich hatte überhaupt nicht daran gedacht, dass man die Längen auch direkt setzen kann, und war voll auf etwas wie eine Funktion mit Rückgabewert fixiert. :-)

    Zitat Zitat von klops Beitrag anzeigen
    Allerdings wäre es dann sinnvoller, statt mit Pseudolängen direkt idealer Weise als Parameter übergebene Länge für das Ausmessen zu verwenden
    Ich arbeite zwar schon einige Jahre mit LaTeX, das Projekt "Neuer Briefbogen" ist aber meine erste wirkliche Begegnung mit KOMA-Script. Deshalb würde mich jetzt doch einmal interessieren, ob es denn überhaupt sinnvoll ist, eigene Pseudolängen und komavars zu verwenden, oder ob die herkömmliche Methode (\newlength, \newcommand) nicht doch ausreicht. Laut scrguide ist ja mittlerweile der Grund für die Einführung der Pseudolängen -- die beschränkte Registerzahl unter TeX -- durch Verwendung von eTeX nicht mehr gegeben. Umständlich zu handhaben sind die Pseudolängen ja schon, weil man sie immer erst in reale Längen konvertieren muss, wenn man mit ihnen arbeiten will.

    Zitat Zitat von klops Beitrag anzeigen
    Aber: Für eine einspaltige Tabelle musst Du die Länge gar nicht wissen.
    Stimmt. Meistens hatte ich aber doch längere Texte in den Tabellen, so dass ich auch dort parbox-ähnliche Spalten (also solche, in denen Zeilenumbrüche erlaubt sind) verwendet hatte -- und *dafür* ist dann wieder die Breite wichtig.

    Zitat Zitat von klops Beitrag anzeigen
    Davon abgesehen gibt es auch noch das Paket varwidth, das eine Art minipage-Umgebung zur Verfügung stellt, die sich selbst an die benötigte Breite anpasst.
    Das kannte ich noch gar nicht! Damit wird die Datei gleich um einiges kürzer. Allerdings gibt es da noch ein kleines Positionierungsproblem:

    Ich will ja mehrere dieser Blöcke nebeneinander setzen, so dass sie oben bündig sind. Nun verwende ich als Schrift mathpazo, mit "oldstyle figures", also Ziffern mit Unterlänge. Die Blöcke für Adresse und Bankverbindung haben in der letzten Zeile Ziffern, der Block mit den Kontaktmöglichkeiten (Telefon/Mail/URL) nicht. Aufgrund der Unterlängen in der letzten Zeile haben die ersten beiden Blöcke eine etwas größere Höhe als der dritte. Dummerweise wird dieser Block nun zentriert -- er sitzt also tiefer und die Zeilen hier sind nicht mehr bündig mit den Zeilen in den anderen Blöcken. Natürlich könnte ich die Telefonnummer (die ja ebenfalls Ziffern enthält) in die unterste Zeile setzen, aber für mein Empfinden gehört sie ganz nach oben. Einer normalen parbox oder minipage kann man ja einen Positionsparameter mitgeben -- mit "\parbox[t]" würden dann alle Boxen nach oben ausgerichtet sein. Anscheinend ist das aber mit varwidth nicht möglich, oder habe ich da etwas übersehen?

    Beste Grüße

    Andreas

  4. #4
    Registrierter Benutzer
    Registriert seit
    09.12.2005
    Beiträge
    1.327
    Code:
    \documentclass{article}
    \usepackage{varwidth}
    \begin{document}
    \begin{varwidth}[t]{.4\linewidth}
    Hast Du\\
    irgendwie
    \end{varwidth}
    \begin{varwidth}[t]{.4\linewidth}
    Nicht\\
    so\\
    ganz\\
    \"uberblickt.
    \end{varwidth}
    \end{document}
    Unterschiedlich hohe oder tiefe Zeilen kann man übrigens mit einem \strut angleichen:
    Code:
    \documentclass{article}
    \usepackage{varwidth}
    \begin{document}
    \begin{varwidth}{.4\linewidth}
    \strut Das
    \end{varwidth}
    \begin{varwidth}{.4\linewidth}
    geht.\strut
    \end{varwidth}
    \end{document}

  5. #5
    Registrierter Benutzer
    Registriert seit
    25.01.2009
    Beiträge
    43
    Zitat Zitat von klops Beitrag anzeigen
    Code:
    \documentclass{article}
    \usepackage{varwidth}
    \begin{document}
    \begin{varwidth}[t]{.4\linewidth}
    Hast Du\\
    irgendwie
    \end{varwidth}
    \begin{varwidth}[t]{.4\linewidth}
    Nicht\\
    so\\
    ganz\\
    \"uberblickt.
    \end{varwidth}
    \end{document}
    Stimmt -- da habe ich wohl das "(based on minipage)" in der Dokumentation überlesen! In dem Beispiel dort wird der optionale Parameter nicht verwendet, deshalb dachte ich, es gäbe ihn gar nicht. :-)

    Zitat Zitat von klops Beitrag anzeigen
    Unterschiedlich hohe oder tiefe Zeilen kann man übrigens mit einem \strut angleichen:
    Für dieses Problem habe ich hier eine ganz andere Lösung gefunden: Mein verlässlicher Berater in Sachen Typographie hat mich davon überzeugt, dass die "hüpfenden Zahlen" zwar im normalen Text dem Lesefluss förderlich, für den Fußbereich aber nicht geeignet sind. Dort, so meinte er, gehe es um nüchterne Fakten, und die "hüpfenden Zahlen" wären da eher verwirrend, wenn man etwa die Telefonnummer oder gar die lange IBAN abschreiben wolle. Im Fußbereich wechsele ich deshalb jetzt zur Ausgabe von Ziffern in den mathematischen Modus ($123$) -- keine Unterlängen mehr, also auch keine verschieden große Boxen!

    Besten Dank für Deine Hilfe, und ein schönes Wochenende noch!

    Andreas

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •