% This is part of the OpTeX project, see http://petr.olsak.net/optex \_codedecl \maketoc {Macros for maketoc <2021-07-18>} % preloaded in format \_doc ------------------------------------ \`\_Xtoc` `{}{}{}{}` (in `.ref` file) reads given data and appends them to the \`\_toclist` as \^`\_tocline``{<level>}{<type>}{<number>}{<o-title>}{<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 * `<o-title>`: outlines title, if differs from `<title>`. * `<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#4{\_ifnum#1=0 \_ischaptrue\_fi \_addto\_toclist{\_tocline{#1}{#2}{#3}{#4}}\_scantoeol\_XtocA} \_def\_XtocA#1{\_addto\_toclist{{#1}}\_ea\_addto\_ea\_toclist\_ea{\_currpage}} \_doc ------------------------------------ \`\_tocline``{<level>}{<type>}{<number>}{<o-title>}{<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 horizontal 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 this: \begtt \catcode`\<=13 | | \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 the global counter of all TOC records (used by hyperlinks). \_cod ------------------------------------ \_newcount \_tocrefnum \_def\_tocline#1#2#3#4#5#6#7{% \_advance\_tocrefnum by1 \_bgroup \_leftskip=\_iindent \_rightskip=2\_iindent \_ifischap \_advance\_leftskip by \_iindent \_fi \_def\_pgn##1{\_ilink[pg:#6]{\_numprint{##1}}}% \_the\_everytocline \_ifcsname _tocl:#1\_endcsname \_cs{_tocl:#1}{#3}{\_scantextokens{#5}}{#7}\_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}\_nobreak\_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\_numprint{#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 ----------------------------------- If you want a special formating of TOC with adding more special lines (no generated as titles from `\chap`, `\sec`, `\secc`), you can define `\addtotoc{<level>}{<type>}{<number>}{<o-title>}{<title>}` macro: \begtt \def\addtotoc#1#2#3#4#5{% \incr\_tocrefnum \_dest[toc:\_the\_tocrefnum]% \_ewref\_Xtoc{{#1}{#2}{#3}{#4}#5}% } \endtt and you can declare special lines (or something else) as an unused level (10 in the following example): \begtt \sdef{_tocl:10}#1#2#3{\medskip\hbox{\Blue #2}\medskip} \endtt Now, users can add a blue line into TOC by \begtt \catcode`\<=13 \addtotoc{10}{blue-line}{}{\relax}{<blue text to be added in the TOC>} \endtt anywhere in the document. Note that `\relax` in the fourth parameter means that outline will be not generated. And second parameter `blue-line` is only a comment (unused in macros). \`\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 2021-07-18 _tocl:1, \nobreak added, bug fixed 2021-02-09 \thisoutline implemented 2020-04-23 \_tocpar introduced (incompatible change) 2020-04-22 \_pg -> \_pgn (incompatible change) 2020-03-12 introduced