summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/maketoc.opm
blob: 6ab711657ec6b1d5fc6a3f05311bc0ea12393ab7 (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
112
113
114
115
116
117
118
119
%% 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>}{<text>}` (in `.ref` file) reads the 
   specified data and saves it to the `\_toclist` as:

   \begtt
   \_tocline{<level>}{<type>}{<number>}{<text>}{<gpageno>}{<pageno>}
   where:
   <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
   <text>:    the title text
   <gpageno>: the page number numbered from 1 independently of pagination 
   <pageno>:  the page number used in the pagination
   \endtt

   The last two parameters are restored from previous
   `\_Xpage{<pageno>}{<gpageno>}`, data are saved in the `\_currpage` macro.
   \_cod ------------------------------------

\_def\_toclist{} 
\_newifi \_ifischap \_ischapfalse

\def\_Xtoc#1#2#3#4{\_ifnum#1=0 \_ischaptrue\_fi 
   \_addto\_toclist{\_tocline{#1}{#2}{#3}{#4}}
   \_ea\_addto\_ea\_toclist\_ea{\_currpage}%
}

   \_doc ------------------------------------
   `\_tocline{<level>}{<type>}{<number>}{<text>}{<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>}{<text>}{<page>}` macro. 
   This macro starts with vertical mode,
   inserts one record with given <level> and ends in horizontal mode. Then
   `\_tocline` 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 <text>) 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. 
   \_cod ------------------------------------

\def\_tocline#1#2#3#4#5#6{%
   \_advance\_tocrefnum by1
   \_bgroup
      \_leftskip=\_iindent \_rightskip=2\_iindent
      \_ifischap \_advance\_leftskip by \_iindent \_fi
      \_def\_pg{\_ilink[pg:#5]}%
      \_the\_everytocline
      \_ifcsname _tocl:#1\_endcsname 
         \_cs{_tocl:#1}{#3}{#4}{#6}\_nobreak \_hskip-2\_iindent\_null \_par
      \_fi
   \_egroup
}

   \_doc -----------------------------------
   You can re-define default macros for each level of tocline if you want:
   \_cod -----------------------------------

\_sdef{_tocl:1}#1#2#3{\_nofirst\_bigskip \_bf\_llaptoclink{#1}{#2}\_hfill \_pg{#3}}
\_sdef{_tocl:2}#1#2#3{\_llaptoclink{#1}{#2}\_tocdotfill \_pg{#3}}
\_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.
   * `\_pg{<pageno>}` creates <pageno> as link to real <gpage> saved in `#6`
     of `\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}

   \_doc -----------------------------------
   `\maketoc` prints warning if TOC data is empty, lse it creates TOC by
   running `\_toclist` 
   \_cod ----------------------------------

\_def\_maketoc{\_par \_ifx\_toclist\_empty
      \_opwarning{\_noexpand\maketoc -- data unavailable, TeX me again}\_openref
   \_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