TeX 中的壽命線

TeX 中的壽命線

我正在寫一篇關於人類歷史上重要數學家和物理學家的生活的文件(用 plainTeX 編寫)。

現在我有一個問題想要解決。我需要能夠視覺化他們的壽命(以便讀者可以看到誰是同時代人/同時代人)。不幸的是,我不太擅長製作 TeX 的巨集。有人可以給我提示如何做嗎?

具體來說,我想它會這樣工作:

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

這會產生(例如,巴赫和莫札特的實例)

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

主要是,如何實現線路的重新縮放,以便它們適合?

答案1

使用 vanilla TeX 快速破解 plain TeX。首先收集人員數據並計算一些數值(最小年份、最大年份、姓名寬度),然後設定收集的人員數據,最後列印整個時間軸。

\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

通過普通和普通 TeX 的時間線

評論:

  • 我比較喜歡 e-TeX \dimexpr\numexpr如果有的話;他們更舒服。然而,除法是不同的,因為它們 \...expr對結果進行四捨五入。

  • pgf/TikZplain TeX 中也提供了強大的功能。

答案2

這是一個類似的 TeX 解決方案:

\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

在此輸入影像描述

相關內容