summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/dichokey/dichokey.sty
blob: dcf9ff56b61ca092b7e8e032d7480b8956d5b45d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
% Dichokey.sty, first version of 2 january 1998 by Nico Dam.
% This version of 17 dec 1999.
%
% This LaTeX2e style file defines the environment  Key  in which
% dichotomous identification keys can be constructed.
% Numbering of alternatives and indentation are taken of care of
% automatically.
% The key should be STRICTLY dichotomous.
%
% Directions for use:
% The key should be constructed within the environment  Key  . The
% environment has one parameter, that is used as first part of the name
% when a species is keyed out (usually an abbreviation of the genus
% name).
% Within the key, every alternative should begin with the command  \alter
% If a species is keyed out, use the command  \name[option]{name}
% (otherwise just continue with the next alternative).
% The optional argument will be used instead of the parameter provided
% on entering the environment  Key .
%
% To do: provide example file (e.g. rhodocyb.tex)
%
\usepackage{calc}
\usepackage{ifthen}
\def\hang{\hangindent\parindent}
\newcounter{couplet}%          counts current couplet
\newcounter{lastcouplet}%      counts highest couplet number
\newcounter{bincouplet}%       binary counter of couplet availability
\newcounter{binarycounter}%    binary counter of indentation level
\newcounter{indentcounter}%    decimal counter of indentation level
\newcounter{backsteps}%        number of steps to be retreated after a species is keyed out
\newboolean{named}%            true if alternative results in a name
\newsavebox{\gprefix}%         Abbreviation of genus name, parameter for Key
\newlength{\altindent}%        additional indentation of each key level
\setlength{\altindent}{4mm}
\newlength{\keylabelwidth}%    width of label of each key step
\setlength{\keylabelwidth}{2em}%
\newlength{\oldparindent}
\newenvironment{Key}[1]%
  {\setcounter{couplet}{0}%
   \setcounter{lastcouplet}{0}%
   \setcounter{binarycounter}{0}%
   \setcounter{bincouplet}{1}%
   \setcounter{indentcounter}{0}%
   \setboolean{named}{false}%
   \sbox{\gprefix}{\textbf{#1}}%
   \setlength{\oldparindent}{\parindent}%
   \setlength{\hangindent}{0pt}%
   \setlength{\parindent}{0pt}%
  }
  {\par\setlength{\parindent}{\oldparindent}}
%
% The following definition of  name  suppresses dotfill if the species
% name doesn't fit on the current line, but has to occur on its own at
% the line below (made by Sander Stoks).
% Added optional argument to be used instead of \gprefix (Nico Dam).
%
\newcommand{\name}[2][\usebox{\gprefix}]%
 {\setboolean{named}{true}
  \leavevmode
  \unskip\nobreak\hfil
  \penalty 150
  \leaders\hbox{\thinspace.\thinspace}\hskip 12pt plus 1fill
  \vadjust{}\hfil
  \hbox{\textbf{#1}\textbf{\mbox{#2}}}%
  {\parfillskip=0pt\par}}
%
\newcounter{temp}%      temporary storage of counter
\newcounter{delta}%     temporary storage of decrease of counter
\newcommand{\alter}%
  {\par%
   \ifthenelse{\boolean{named}}%
% NAMED = TRUE
     {\setcounter{backsteps}{0}%
      \setcounter{delta}{1}%
      \setcounter{temp}{\value{binarycounter}+1}%
% calculate new couplet number
      \whiledo{\isodd{\value{temp}}}%
         {\addtocounter{backsteps}{1}%
          \setcounter{delta}{\value{delta}*2}%
          \addtocounter{temp}{-1}%
          \setcounter{temp}{\value{temp}/2}%
          \addtocounter{temp}{1}%
         }%
      \addtocounter{binarycounter}{-\value{delta}}%
      \setcounter{couplet}{\value{lastcouplet}-\value{backsteps}}%
% calculate new level of indentation
      \setcounter{backsteps}{0}%
      \setcounter{temp}{\value{indentcounter}+1}
      \whiledo{\isodd{\value{temp}}}%
         {\addtocounter{backsteps}{1}%
          \setcounter{indentcounter}{\value{indentcounter}/2}%
          \setcounter{temp}{\value{indentcounter}+1}
         }%
      \addtocounter{indentcounter}{-1}%
      \addtolength{\parindent}{-\altindent*\value{backsteps}}\hang%
     }%
% NAMED = FALSE
     {\setcounter{binarycounter}{\value{binarycounter}*2+1}%
      \addtocounter{lastcouplet}{1}%
      \setcounter{couplet}{\value{lastcouplet}}%
      \setcounter{indentcounter}{\value{indentcounter}*2+1}%
      \addtolength{\parindent}{\altindent}\hang%
     }%
   \setboolean{named}{false}%
   \hspace*{-\keylabelwidth}\hspace*{-2mm}%
   \parbox[t]{\keylabelwidth}{\hfill{\thecouplet}.}%
   \hspace*{2mm}%
  }
%
\newcommand{\panic}[1]{\addtolength{\parindent}{\altindent*{#1}}}