Lebensdauerlinien in TeX

Lebensdauerlinien in TeX

Ich schreibe ein Dokument (in PlainTeX) über das Leben bedeutender Mathematiker und Physiker der Menschheitsgeschichte.

Jetzt habe ich ein Problem, das ich angehen möchte. Ich muss in der Lage sein,visualisierenihre Lebensspanne (damit der Leser sehen kann, wer wessen Zeitgenosse/Gleichalte war). Leider bin ich nicht so geschickt darin, TeX-Makros zu erstellen. Kann mir jemand einen Tipp geben, wie das geht?

Konkret stelle ich mir vor, dass es so funktionieren würde:

\person{name}{surname}{year_of_birth}{year_of_death}
\person{name}{surname}{year_of_birth}{year_of_death}
...
\renderpeople

was (zum Beispiel bei Bach und Mozart) ergeben würde

Bach J.S.              |----------------|
Mozart A.                      |-----------------|
...
          |----------|-----------|----------|-----------|---------|
       1750        1800        1850       1900        1950      2000

Vor allem: Wie lässt sich die Skalierung der Linien so implementieren, dass sie passen?

Antwort1

Ein schneller Hack in Plain TeX unter Verwendung von Vanilla TeX. Zuerst werden die Personendaten gesammelt und einige Werte berechnet (minimales Jahr, maximales Jahr, Breite der Namen), dann werden die gesammelten Personendaten festgelegt und schließlich wird die gesamte Zeitleiste gedruckt.

\newdimen\NameWidth
\NameWidth=0pt
\newcount\MinYear
\MinYear=100000
\newcount\MaxYear
\MaxYear=-100000
\newtoks\PersonData
\PersonData={}
\newdimen\ScaleWidth
\newdimen\ScaleUnit
\newcount\TempCount
\newdimen\TickMarkWidth
\TickMarkWidth=.4pt
\newdimen\TickMarkHeight
\TickMarkHeight=8pt
\newdimen\LineWidth
\LineWidth=.4pt
\newdimen\LastYearCorr

\def\person#1#2#3#4{%
  \setbox0=\hbox{\makeperson{#1}{#2}\personsep}%
  \ifdim\wd0>\NameWidth
    \NameWidth=\wd0 %
  \fi
  \ifnum#3<\MinYear
    \MinYear=#3\relax
  \fi
  \ifnum#4>\MaxYear
    \MaxYear=#4\relax
  \fi
  \ifnum#3>#4\relax
    \errmessage{#2 #1 has negative live span, born in #3 and died in #4}%
  \fi
  \PersonData=\expandafter{\the\PersonData
    \DoPerson{#1}{#2}{#3}{#4}%
  }%
}
\def\makeperson#1#2{#1, #2}%
\def\personsep{ }
\def\renderpeople{%
  \par
  \divide\MinYear by 50\relax
  \multiply\MinYear by 50\relax
  \advance\MaxYear by 49\relax 
  \divide\MaxYear by 50\relax  
  \multiply\MaxYear by 50\relax
  \ScaleWidth=\hsize
  \advance\ScaleWidth by -\NameWidth
  \setbox0=\hbox{$\textstyle\the\MaxYear$}%
  \LastYearCorr=.5\wd0 %
  \advance\ScaleWidth by -\LastYearCorr
  \ScaleUnit=\ScaleWidth
  \TempCount=\MaxYear   
  \advance\TempCount by -\MinYear
  \divide\ScaleUnit by \TempCount
  \ScaleWidth=\ScaleUnit
  \multiply\ScaleWidth by \TempCount
  \noindent
  \the\PersonData
  \ScaleLine
  \par
}
\def\DoPerson#1#2#3#4{%
  \hbox to \hsize{%
    \hbox to \NameWidth{%
      \makeperson{#1}{#2}%
      \hfill
      \personsep
    }%
    \hfill
    \hbox to \ScaleWidth{%
      \kern#3\ScaleUnit   
      \kern-\MinYear\ScaleUnit
      \SetTickMark
      \TempCount=#4\relax
      \advance\TempCount by -#3\relax
      \SetLine\TempCount
      \SetTickMark
      \hfill
    }%
    \kern\LastYearCorr
  }%
  \hskip0pt\relax
}
\def\ScaleLine{%
  \hbox to \hsize{%
    \hbox to \NameWidth{\hfill}%
    \hfill
    \hbox to \ScaleWidth{%
      \TempCount=\MinYear 
      \SetTickYearMark    
      \loop
      \ifnum\TempCount<\MaxYear
        \SetLine{50}%
        \advance\TempCount by 50 %
        \SetTickYearMark
      \repeat
    }%
    \kern\LastYearCorr
  }%
  \hskip0pt\relax
}
\def\SetTickYearMark{%
  \hbox to 0pt{%
    \hss
    $\mathsurround=0pt\relax
      \mathop{\vcenter{%
        \hrule width \TickMarkWidth
               height .5\TickMarkHeight
               depth .5\TickMarkHeight 
      }}\limits_{\textstyle\the\TempCount}%
    $%
    \hss
  }%
}   
\def\SetTickMark{%
  \hbox to 0pt{%  
    \hss
    $\mathsurround=0pt\vcenter{%
      \hrule width \TickMarkWidth
             height .5\TickMarkHeight
             depth .5\TickMarkHeight 
    }$%
    \hss
  }%
}   
\def\SetLine#1{%
  $\mathsurround=0pt\vcenter{%
    \hrule width#1\ScaleUnit  
           height.5\LineWidth 
           depth.5\LineWidth  
  }$%
}

\person{Pachelbel}{J.}{1653}{1706}
\person{Bach}{J. S.}{1685}{1750}  
\person{Mozart}{W. A.}{1756}{1791}
\person{Euler}{L.}{1707}{1783}

\renderpeople
\bye

Zeitleisten über einfaches und Standard-TeX

Bemerkungen:

  • Ich würde e-TeX bevorzugen \dimexprund \numexprwenn sie verfügbar sind, sind sie komfortabler. Divisionen sind jedoch anders, da sie \...exprdas Ergebnis runden.

  • Das Leistungsstarke pgf/TikZist auch in reinem TeX verfügbar.

Antwort2

hier ist eine ähnliche TeX-Lösung:

\input pst-grad
\input pstricks-add
\newbox\TBox
\psset{gradbegin=white,gradend=lightgray}
\catcode`\@11\relax

\def\BoxText{\@ifnextchar[\BoxText@i{\BoxText@i[3cm]}}
\def\BoxText@i[#1]#2#3#4{%
  \emergencystretch=3em
  \setbox\TBox\vbox{\hsize #1 #4\par}
  \rput[t](#2){\psframebox[fillstyle=gradient]{\leavevmode\copy\TBox\relax}}%
  \pnode(#2|0,0){A}\pnode(#2){B}
  \ncline{->}{A}{B}%
  \uput*{0.5cm}[-90](A){#3}%
}
\catcode`\@12\relax

\pspicture(0,0.25)(2.5,-10)
\psset{xunit=5}
\psaxes[yAxis=false,Ox=1518]{|->}(0,0)(2.5,-10)% 
\BoxText[4cm]{1.1123,-5.5}{10.2.}{%
Hier muss jetzt irgendetwas hinkommen, was, weiss ich auch nicht genau}
\BoxText{.767,-2}{15.10.}{%
Hier muss jetzt irgendetwas hinkommen, was, weiss ich auch nicht genau}
\endpspicture


\pspicture(0,0.25)(2.5,-10)
\psset{xunit=5cm}
\psaxes[yAxis=false,Ox=1518]{|->}(0,0)(2.5,-10)%
\BoxText{.787,-5}{17.10.}{%
Hier muss jetzt irgendetwas hinkommen, was, weiss ich auch nicht genau}
\pnode(A){A0}
\BoxText{.767,-2}{15.10.}{%
Hier muss jetzt irgendetwas hinkommen, was, weiss ich auch nicht genau}
\uput*{1.2cm}[-90](A0){17.10.}%
\endpspicture

\bye

Bildbeschreibung hier eingeben

verwandte Informationen