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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
% This is part of OpTeX project, see http://petr.olsak.net/optex
\_codedecl \maketoc {Macros for maketoc <2020-03-12>} % preloaded in format
\_doc ------------------------------------
\`\_Xtoc` `{<level>}{<type>}{<number>}<title>` (in `.ref` file) reads the
specified data and appends them to the \`\_toclist` as
\^`\_tocline``{<level>}{<type>}{<number>}{<title>}{<gpageno>}{<pageno>}`
where:
\begitems
* `<level>`: 0 reserved, 1: chapter, 2: section, 3: subsection
* `<type>`: the type of the level, i.e. chap, sec, secc
* `<number>`: the number of the chapter/section/subsection in the format 1.2.3
* `<title>`: the title text
* `<gpageno>`: the page number numbered from 1 independently of pagination
* `<pageno>`: the page number used in the pagination
\enditems
The last two parameters are restored from previous
\^`\_Xpage``{<pageno>}{<gpageno>}`, data were saved in the \^`\_currpage` macro.
We read the <title> parameter by \^`\scantoeol` from `.ref` file
because the <title> can include something like \code{`\{`}.
\_cod ------------------------------------
\_def\_toclist{}
\_newifi \_ifischap \_ischapfalse
\_def\_Xtoc#1#2#3{\_ifnum#1=0 \_ischaptrue\_fi
\_addto\_toclist{\_tocline{#1}{#2}{#3}}\_scantoeol\_XtocA}
\_def\_XtocA#1{\_addto\_toclist{{#1}}\_ea\_addto\_ea\_toclist\_ea{\_currpage}}
\_doc ------------------------------------
\`\_tocline``{<level>}{<type>}{<number>}{<title>}{<gpageno>}{<pageno>}` prints
the record to the table of contents. It opens group, reduces `\_leftskip`,
`\_rightskip`, runs the \^`\everytocline` (user can customise the design of TOC
here) and runs `\_tocl:<level> {<number>}{<title>}{<pageno>}` macro.
This macro starts with vertical mode,
inserts one record with given `<level>` and it should end by \^`\_tocpar`
which returns to hrizontal mode. The `\_tocpar`
appends `\_nobreak \_hskip-2\_iindent\_null \_par`. This causes
that the last line of the record is shifted outside the margin given by
`\_rightskip`. A typical record (with long `<title>`) looks like:
\begtt
| |
\llap{<number>} text text text text text
text text text text text
text text .................... <pageno>
\endtt
Margins given by `\leftskip` and `\rightskip` are denoted by `|` in the
examle above.
\nl
\`\tocrefnum` is global counter of all TOC records (used by hyperlinks).
\_cod ------------------------------------
\_newcount \_tocrefnum
\_def\_tocline#1#2#3#4#5#6{%
\_advance\_tocrefnum by1
\_bgroup
\_leftskip=\_iindent \_rightskip=2\_iindent
\_ifischap \_advance\_leftskip by \_iindent \_fi
\_def\_pgn{\_ilink[pg:#5]}%
\_the\_everytocline
\_ifcsname _tocl:#1\_endcsname
\_cs{_tocl:#1}{#3}{\_scantextokens{#4}}{#6}\_par
\_fi
\_egroup
}
\_public \tocrefnum ;
\_doc -----------------------------------
You can re-define default macros for each level of tocline if you want.\nl
Parameters are `{<number>}{<title>}{<pageno>}`.
\_cod -----------------------------------
\_sdef{_tocl:1}#1#2#3{\_nofirst\_bigskip \_bf\_llaptoclink{#1}{#2}\_hfill \_pgn{#3}\_tocpar}
\_sdef{_tocl:2}#1#2#3{\_llaptoclink{#1}{#2}\_tocdotfill \_pgn{#3}\_tocpar}
\_sdef{_tocl:3}#1#2#3{\_advance\_leftskip by\_iindent \_cs{_tocl:2}{#1}{#2}{#3}}
\_doc -----------------------------------
The auxiliary macros are:
\begitems
* \`\_llaptoclink``<text>` does `\_noindent\_llap{<linked text>}`.
* \`\_tocdotfill` creates dots in the TOC.
* \`\_nofirst``\macro` applies the `\macro` only if we don't print the first
record of the TOC.
* \`\_tocpar` finalizes one TOC recors whith rlapped `<pageno>`.
* \`\_pgn``{<pageno>}` creates <pageno> as link to real `<gpage>` saved in `#6`
of \^`\_tocline`. This is temporarily defined in the \^`\_tocline`.
\enditems
\_cod ----------------------------------
\_def\_llaptoclink#1{\_noindent
\_llap{\_ilink[toc:\_the\_tocrefnum]{\_enspace#1\_kern.4em}\_kern.1em}}
\_def\_tocdotfill{\_nobreak\_leaders\_hbox to.8em{\_hss.\_hss}\_hskip 1em plus1fill\_relax}
\_def\_nofirst #1{\_ifnum \_lastpenalty=11333 \_else #1\_fi}
\_def\_tocpar{\_nobreak \_hskip-2\_iindent\_null \_par}
\_doc -----------------------------------
\`\maketoc` prints warning if TOC data is empty, else it creates TOC by
running \^`\_toclist`
\_cod ----------------------------------
\_def\_maketoc{\_par \_ifx\_toclist\_empty
\_opwarning{\_noexpand\maketoc -- data unavailable, TeX me again}\_openref
\_incr\_unresolvedrefs
\_else \_begingroup
\_tocrefnum=0 \_penalty11333
\_the\_regtoc \_toclist
\_endgroup \_fi
}
\_doc -----------------------------------
\`\regmacro` appends its parameters to \`\_regtoc`, \`\_regmark` and
\`\_regoul`. These token lists are used in \^`\maketoc`, \^`\_begoutput` and
\^`\pdfunidef`.
\_cod \_fin -----------------------------
\_newtoks \_regtoc \_newtoks \_regmark \_newtoks \_regoul
\_def\_regmacro #1#2#3{%
\_toksapp\_regtoc{#1}\_toksapp\_regmark{#2}\_toksapp\_regoul{#3}%
}
\_public \maketoc \regmacro ;
\_endcode
2020-04-23 \_tocpar introduced (incompatible change)
2020-04-22 \_pg -> \_pgn (incompatible change)
2020-03-12 introduced
|