%% This is part of the OpTeX project, see http://petr.olsak.net/optex \_codedecl \chap {Titles, chapters, sections, subsections <2024-01-19>} % preloaded in format \_doc --------------------------- We are using scaled fonts for titles \`\_titfont`, \`\_chapfont`, \`\_secfont` and \`\_seccfont`. They are scaled from main fonts size of the document, which is declared by first `\typosize[/]` command. \_cod --------------------------- \_def \_titfont {\_scalemain\_typoscale[\_magstep4/\_magstep5]\_boldify} \_def \_chapfont {\_scalemain\_typoscale[\_magstep3/\_magstep3]\_boldify} \_def \_secfont {\_scalemain\_typoscale[\_magstep2/\_magstep2]\_boldify} \_def \_seccfont {\_scalemain\_typoscale[\_magstep1/\_magstep1]\_boldify} \_doc --------------------------- The \`\tit` macro is defined using \^`\scantoeol` and \`\_printtit`. It means that the parameter is separated by end of line and inline verbatim is allowed. The same principle is used in the \^`\chap`, \^`\sec`, and \^`\secc` macros. \_cod --------------------------- \_def\_printtit #1{\_vglue\_titskip {\_leftskip=0pt plus1fill \_rightskip=\_leftskip % centering \_titfont \_noindent \_scantextokens{#1}\_par}% \_nobreak\_bigskip } \_def\_tit{\_scantoeol\_printtit} \_sdef{_eol:tit}{\_printtit} % enables \bracedparam\tit{title} \_public \tit ; \_doc --------------------------- You can re-define \`\_printchap`, \`\_printsec` or \`\_printsecc` macros if another design of section titles is needed. These macros get the `` text in its parameter. The common recommendations for these macros are: \begitems * Use \^`\_abovetitle``{<penaltyA>}{<skipA>}` and \^`\_belowtitle``{<skipB>}` for inserting vertical material above and below the section title. The arguments of these macros are normally used, i.\,e.\ \^`\_abovetitle` inserts `<penaltyA><skipA>` and \^`\_belowtitle` inserts `<skipB>`. But there is an exception: if \^`\_belowtitle``{<skipB>}` is immediately followed by \^`\_abovetitle``{<penaltyA>}{<skipA>}` (for example section title is immediately followed by subsection title), then only `<skipA>` is generated, i.\,e.\ `<skipB><penaltyA><skipA>` is reduced only to `<skipA>`. The reason for such behavior: we don't want to duplicate vertical skip and we don't want to use the negative penalty in such cases. Moreover, \^`\_abovetitle``{<penaltyA>}{<skipA>}` takes previous whatever vertical skip (other than from `\_belowtitle`) and generates only greater from this pair of skips. It means that `<whatever-skip><penaltyA><skipA>` is transformed to `<penaltyA>`max(`<whatever-skip><skipA>`). The reason for such behavior: we don't want to duplicate vertical skips (from `\_belowlistskip`, for example) above the title. * Use \^`\_printrefnum``[<pre>@<post>]` in horizontal mode. It prints `<pre><ref-num><post>`. The `<ref-num>` is \^`\_thechapnum` or \^`\_thesecnum` or \^`\_theseccnum` depending on what type o title is processed. If \^`\nonum` prefix is used then \^`\_printrefnum` prints nothing. The macro \^`\_printrefnum` does more work: it creates destination of hyperlinks (if \^`\hyperlinks``{}{}` is used) and saves references from the label (if \^`\label``[<label>]` precedes) and saves references for the table of contents (if \^`\maketoc` is used). * Use \^`\nbpar` for closing the paragraph for printing title. This command inserts `\_nobreak` between each line of such paragraph, so the title cannot be broken into more pages. * You can use \^`\_firstnoindent` in order to the first paragraph after the title is not indented. \enditems \_cod --------------------------- \_def\_printchap #1{\_vfill\_supereject \_prevdepth=0pt \_vglue\_medskipamount % shifted by topkip+\medskipamount {\_chapfont \_noindent \_mtext{chap} \_printrefnum[@]\_par \_nobreak\_smallskip \_noindent \_raggedright #1\_nbpar}\_mark{}% \_nobreak \_belowtitle{\_bigskip}% \_firstnoindent } \_def\_printsec#1{\_par \_abovetitle{\_penalty-151}\_bigskip {\_secfont \_noindent \_raggedright \_printrefnum[@\_quad]#1\_nbpar}\_insertmark{#1}% \_nobreak \_belowtitle{\_medskip}% \_firstnoindent } \_def\_printsecc#1{\_par \_abovetitle{\_penalty-101}{\_medskip\_smallskip} {\_seccfont \_noindent \_raggedright \_printrefnum[@\_quad]#1\_nbpar}% \_nobreak \_belowtitle{\_medskip}% \_firstnoindent } \_doc -------------------------- The \`\_sectionlevel` is the level of the printed section: \begitems * `\_sectionlevel=0` -- reserved for parts of the book (unused by default) * `\_sectionlevel=1` -- chapters (used in `\chap`) * `\_sectionlevel=2` -- sections (used in `\sec`) * `\_sectionlevel=3` -- subsections (used in `\secc`) * `\_sectionlevel=4` -- subsubsections (unused by default, see the \ulink[http://petr.olsak.net/optex/optex-tricks.html\#seccc]{\OpTeX/ trick 0033}) \enditems \_cod -------------------------- \_newcount\_sectionlevel \_def \_secinfo {\_ifcase \_sectionlevel part\_or chap\_or sec\_or secc\_or seccc\_fi } \_doc -------------------------- The \`\_chapx` initializes counters used in chapters, the \`\_secx` initializes counters in sections and \`\_seccx` initializes counters in subsections. If you have more types of numbered objects in your document then you can declare appropriate counters and do `\addto\_chapx{\yourcounter=0 }` for example. If you have another concept of numbering objects used in your document, you can re-define these macros. All settings here are global because it is used by `{\_globaldefs=1 \_chapx}`. Default concept: Tables, figures, and display maths are numbered from one in each section -- subsections don't reset these counters. Footnotes declared by \^`\fnotenumchapters` are numbered in each chapter from one. The `\_the*` macros \`\_thechapnum`, \`\_thesecnum`, \`\_theseccnum`, \`\_thetnum`, \`\_thefnum` and \`\_thednum` include the format of numbers used when the object is printing. If chapter is never used in the document then `\_chapnum=0` and \`\_othe``\_chapnum.` expands to empty. Sections have numbers <num> and subsections <num>.<num>. On the other hand, if chapter is used in the document then `\_chapnum>0` and sections have numbers` <num>.<num>` and subsections have numbers `<num>.<num>.<num>`. \_cod -------------------------- \_newcount \_chapnum % chapters \_newcount \_secnum % sections \_newcount \_seccnum % subsections \_newcount \_tnum % table numbers \_newcount \_fnum % figure numbers \_newcount \_dnum % numbered display maths \_def \_chapx {\_secx \_secnum=0 \_lfnotenum=0 } \_def \_secx {\_seccx \_seccnum=0 \_tnum=0 \_fnum=0 \_dnum=0 \_resetABCDE } \_def \_seccx {} \_def \_thechapnum {\_the\_chapnum} \_def \_thesecnum {\_othe\_chapnum.\_the\_secnum} \_def \_theseccnum {\_othe\_chapnum.\_the\_secnum.\_the\_seccnum} \_def \_thetnum {\_othe\_chapnum.\_othe\_secnum.\_the\_tnum} \_def \_thefnum {\_othe\_chapnum.\_othe\_secnum.\_the\_fnum} \_def \_thednum {(\_the\_dnum)} \_def\_othe #1.{\_ifnum#1>0 \_the#1.\_fi} \_doc ---------------------------- The \`\notoc` and \`\nonum` prefixes are implemented by internal \`\_ifnotoc` and \`\_ifnonum`. They are reset after each chapter/section/subsection by the \`\_resetnonumnotoc` macro. \_cod ---------------------------- \_newifi \_ifnotoc \_notocfalse \_def\_notoc {\_global\_notoctrue} \_newifi \_ifnonum \_nonumfalse \_def\_nonum {\_global\_nonumtrue} \_def \_resetnonumnotoc{\_global\_notocfalse \_global\_nonumfalse} \_public \notoc \nonum ; \_doc ---------------------------- The \`\chap`, \`\sec`, and \`\secc` macros are implemented here. The \`\_inchap`, \`\_insec` and \`\_insecc` macros do the real work, First, we read the optional parameter `[<label>]`, if it exists. The `\chap`, `\sec` and `\secc` macro reads its parameter using \^`\scantoeol`. This causes that they cannot be used inside other macros. Use \^`\_inchap`, \^`\_insec`, and \^`\_insecc` macros directly in such case. \_cod ---------------------------- \_optdef\_chap[]{\_trylabel \_scantoeol\_inchap} \_optdef\_sec []{\_trylabel \_scantoeol\_insec} \_optdef\_secc[]{\_trylabel \_scantoeol\_insecc} \_def\_trylabel{\_istoksempty\_opt\_iffalse \_label[\_the\_opt]\_fi} \_sdef{_eol:chap}{\_inchap} % enebles \bracedparam\chap{title} \_sdef{_eol:sec}{\_insec} % enables \bracedparam\sec{title} \_sdef{_eol:secc}{\_insecc} % enables \bracedparam\secc{title} \_def\_inchap #1{\_par \_sectionlevel=1 \_def \_savedtitle {#1}% saved to .ref file \_ifnonum \_else {\_globaldefs=1 \_incr\_chapnum \_chapx}\_fi \_edef \_therefnum {\_ifnonum \_space \_else \_thechapnum \_fi}% \_printchap{\_scantextokens{#1}}% \_resetnonumnotoc } \_def\_insec #1{\_par \_sectionlevel=2 \_def \_savedtitle {#1}% saved to .ref file \_ifnonum \_else {\_globaldefs=1 \_incr\_secnum \_secx}\_fi \_edef \_therefnum {\_ifnonum \_space \_else \_thesecnum \_fi}% \_printsec{\_scantextokens{#1}}% \_resetnonumnotoc } \_def\_insecc #1{\_par \_sectionlevel=3 \_def \_savedtitle {#1}% saved to .ref file \_ifnonum \_else {\_globaldefs=1 \_incr\_seccnum \_seccx}\_fi \_edef \_therefnum {\_ifnonum \_space \_else \_theseccnum \_fi}% \_printsecc{\_scantextokens{#1}}% \_resetnonumnotoc } \_public \chap \sec \secc ; \_doc ---------------------------- The \`\_printrefnum``[<pre>@<post>]` macro is used in `\_print*` macros. Note that the `<tite-text>` is `\detokenize`d before `\_wref`, so the problem of \"fragile macros" from old \LaTeX/ never occurs. This fourth parameter is not delimited by `{...}` but by end of line. This gives possibility to have unbalanced braces in inline verbatim in titles. \_cod ---------------------------- \_def \_printrefnum [#1@#2]{\_leavevmode % we must be in horizontal mode \_ifnonum \_else #1\_numprint\_therefnum #2\_fi \_wlabel \_therefnum % references, if `\label[<label>]` is declared \_ifnotoc \_else \_incr \_tocrefnum \_dest[toc:\_the\_tocrefnum]% \_ewref\_Xtoc{{\_the\_sectionlevel}{\_secinfo}% {\_therefnum}{\_theoutline}\_detokenize\_ea{\_savedtitle}}% \_fi \_gdef\_theoutline{}% } \_doc ----------------------------- \`\thisoutline``{<text>}` saves text to the \`\_theoutline` macro. \^`\_printrefnum` uses it and removes it. \_cod ----------------------------- \_def\_theoutline{} \_def\_thisoutline#1{\_gdef\_theoutline{#1}} \_public \thisoutline ; \_doc ----------------------------- The \`\_abovetitle``{<penaltyA>}{<skipA>}` and \`\_belowtitle``{<skipB>}` pair communicates using a special penalty 11333 in vertical mode. The `\_belowtitle` puts the vertical skip (its value is saved in `\_savedtitleskip`) followed by this special penalty. The `\_abovetitle` reads `\lastpenalty` and if it has this special value then it removes the skip used before and doesn't use the parameter. The `\abovetitle` creates `<skipA>` only if whatever previous skip is less or equal than `<skipA>`. We must save `<whatever-skip>`, remove it, create `<penaltyA>` (if `\_belowtitle` does not precede) and create <whatever-skip> or `<skipA>` depending on what is greater. The amount of `<skipA>` is measured using `\setbox0=\vbox`. \_cod ----------------------------- \_newskip \_savedtitleskip \_newskip \_savedlastskip \_def\_abovetitle #1#2{\_savedlastskip=\_lastskip % <whatever-skip> \_ifdim\_lastskip>\_zo \_vskip-\_lastskip \_fi \_ifnum\_lastpenalty=11333 \_vskip-\_savedtitleskip \_else #1\_fi \_ifdim\_savedlastskip>\_zo \_setbox0=\_vbox{#2\_global\_tmpdim=\_lastskip}% \_else \_tmpdim=\_maxdimen \_fi \_ifdim\_savedlastskip>\_tmpdim \vskip\_savedlastskip \_else #2\_fi } \_def\_belowtitle #1{#1\_global\_savedtitleskip=\_lastskip \_penalty11333 } \_doc ----------------------------- \`\nbpar` sets `\interlinepenaty` value. \`\nl` is \"new line" in the text (or titles), but space in toc or headlines or outlines. \_cod ----------------------------- \_def\_nbpar{{\_interlinepenalty=10000\_endgraf}} \_protected\_def\_nl{\_unskip\_hfil\_break} \_regmacro {\_def\_nl{\_unskip\_space}} {\_def\_nl{\_unskip\_space}} {\_def\_nl{ }} \_regmacro {\_def\nl{\_unskip\_space}} {\_def\nl{\_unskip\_space}} {\_def\nl{ }} \_public \nbpar \nl ; \_doc ----------------------------- \`\_firstnoindent` puts a material to `\everypar` in order to next paragraph will be without indentation. It is useful after titles. If you dislike this feature then you can say `\let\_firtnoindent=\relax`. The \`\_wipeepar` removes the material from `\everypar`. \_cod ----------------------------- \_def \_firstnoindent {\_global\_everypar={\_wipeepar \_setbox7=\_lastbox}} \_def \_wipeepar {\_global\_everypar={}} \_doc ----------------------------- The `\mark` (for running heads) is used in `\_printsection` only. We suppose that chapters will be printed after `\vfil\break`, so users can implement chapter titles for running headers directly by macros, no `\mark` mechanism is needed. But sections need `\mark`s. And they can be mixed with chapter's running heads, of course. The \`\_insertmark``{<title text>}` saves `\mark` in the format `{<title-num>} {<title-text>}`, so it can be printed \"as is" in `\headline` (see the space between them), or you can define a formating macro with two parameters for processing these data, if you need it. \_cod ----------------------------- \_def\_insertmark#1{\_mark{{\_ifnonum\_else\_therefnum\_fi} {\_unexpanded{#1}}}} \_doc ----------------------------- \OpTeX/ sets `\headline={}` by default, so no running headings are printed. You can activate the running headings by following code, for example. See also \ulink[https://github.com/olsak/OpTeX/issues/100]{issue 100}. \begtt \addto\_chapx {\globaldefs=0 \vfil\break % headline of previous chapter is printed \xdef\_runningchap {\_thechapnum: \unexpanded\_ea{\_savedtitle}}} \def \formathead #1#2{\isempty{#1}\iffalse #1: #2\fi} \headline = {% \ifodd \pageno \hfil \ea\formathead\firstmark{}{}% \else \ifx\_runningchap\_undefined \else Chapter \_runningchap \fi \hfil \fi } \endtt The \`\secl``<number> <title-text><eol>` should be used for various levels of sections (for example, when converting from Markdown to \OpTeX/). `\secl1` is `\chap`, `\secl2` is `\sec`, `\secl3` is `\secc` and all more levels (for <number>$>3$) are printed by the common \`\_seclp` macro. It declares only a simple design. If there is a requirement to use such more levels then the book designer can define something different here.\nl The variant `\_eol:secl` is defined to enable \^`\bracedparam``\secl<number> {<title-text>}`. \_cod ----------------------------- \_def\_secl{\_let\_secle=\_ea \_afterassignment\_secla \_sectionlevel=} \_sdef{_eol:secl}{\_def\_secle{\_ea\_bracedparam\_ea}\_afterassignment\_secla \_sectionlevel=} \_def\_secla{\_ifcase\_sectionlevel \_or \_secle\_chap \_or \_secle\_sec \_or \_secle\_secc \_else \_ea \_seclp\_fi} \_eoldef\_seclp#1{\_par \_ifnum\_lastpenalty=0 \_removelastskip\_medskip\_fi \_noindent{\_bf #1}\_vadjust{\_nobreak}\_nl\_ignorepars} \_def\_ignorepars{\_isnextchar\_par{\_ignoresecond\_ignorepars}{}} \_public \secl ; \_doc ----------------------------- The \`\caption``/<letter>` increases `\_<letter>num` counter, edefines \`\_thecapnum` as `\_the<letter>num` and defines \`\_thecaptitle` as language-dependent word using \^`\_mtext`, declares default format by \^`\_captionformat``{<letter>}` and runs the `\_everycaption<letter>` tokens register. The two groups opened by `\caption` are finalized by first `\_par` from an empty line or from `\vskip`, `\cskip` or from `\endinsert`. If a \code{\}} occurs first then `\_par` from `\aftergroup` is processed. The `\_printcaption<letter>` is called, it starts with printing of the caption.\nl The \`\cskip` macro inserts nonbreakable vertical space between the caption and the object. \_cod ----------------------------- \_def\_caption/#1{\_def\_tmpa{#1}\_nospaceafter \_capA} \_optdef\_capA []{\_trylabel \_incaption} \_def\_incaption {\_bgroup \_ifcsname _\_tmpa num\_endcsname \_ea\_incr \_csname _\_tmpa num\_endcsname \_else \_opwarning{Unknown caption /\_tmpa}\_fi \_edef\_thecapnum {\_csname _the\_tmpa num\_endcsname}% \_edef\_thecaptitle{\_mtext{\_tmpa}}% \_ea\_captionformat\_ea{\_tmpa}% \_ea\_the \_csname _everycaption\_tmpa\_endcsname \_def\_par{\_ifhmode\_nbpar\_egroup\_egroup\_fi}% \_ifx\par\_endgraf \_let\par=\_par \_fi \_bgroup \_aftergroup\_par \_cs{_printcaption\_tmpa}% } \_def \_cskip {\_par\_nobreak\_medskip} % space between caption and the object \_public \caption \cskip ; \_doc ----------------------------- The \`\_printcaptiont` and \`\_printcaptionf` macros start in vertical mode. They switch to horizontal mode and use `\_wlabel\_thecapnum` (in order to make reference and hyperlink destination). They can use: \begitems * \^`\_thecaptitle` ... expands to the word Table or Figure (depending on the current language). * \^`\_thecapnum` ... expands to `\the<letter>num` (caption number). \enditems The macro \^`\_printcaptiont` (or `f`) is processed inside group and the `\_par` can be run after this group. If you want to re-define formating parameters for `\_par`, do this in the macro \^`\_captionformat`. The \`\_captionsep` inserts a separator between auto-generated caption number and the following caption text. Default separator is `\_enspace` but if the caption text starts with dot or colon, then the space is not inserted. A user can wite `\caption/t: My table` and \"{\bf Table 1.1:} My table" is printed. You can re-define the \^`\_captionsep` macro if you want to use another separator. \_cod ----------------------------- \_def \_printcaptiont {% \_noindent \_wlabel\_thecapnum {\_bf\_thecaptitle~\_thecapnum}% \_futurelet\_next\_captionsep } \_def\_captionsep{\_ifx\_next.\_ea\_bfnext \_else\_ifx\_next:\_ea\_ea\_ea\_bfnext \_else \_enspace \_fi\_fi} \_def\_bfnext#1{{\_bf#1}} \_let \_printcaptionf = \_printcaptiont % caption of figures = caption of tables \_doc ----------------------------- If you want to declare a new type of `\caption` with independent counter, you can use following lines, where `\caption/a` for Algorithms are declared: \begtt \let\_printcaptiona = \_printcaptionf \let\_everycaptiona = \_everycaptionf \newcount\_anum \addto\_secx {\_anum=0 } \def\_theanum {\_othe\_chapnum.\_the\_secnum.\_the\_anum} \sdef{_mt:a:en}{Algorithm} \sdef{_mt:a:cs}{Algoritmus} % + your language... \endtt The format of the \^`\caption` text is given by the \`\_captionformat``{<caption-letter>}` macro. The default format for `t` and `f` is a paragraph in block narrower by `\_iindent` and with the last line is centered. This setting is done by the \`\_narrowlastlinecentered` macro. \_cod ----------------------------- \_def\_captionformat#1{\_narrowlastlinecentered\_iindent} \_def\_narrowlastlinecentered#1{% \_leftskip=#1plus1fil \_rightskip=#1plus-1fil \_parfillskip=0pt plus2fil\_relax } \_doc ----------------------------- \`\eqmark` is processed in display mode (we add `\eqno` primitive) or in internal mode when `\eqaligno` is used (we don't add `\eqno`). \_cod ----------------------------- \_optdef\_eqmark []{\_trylabel \_ineqmark} \_def\_ineqmark{\_incr\_dnum \_ifinner\_else\_eqno \_fi \_wlabel\_thednum \_hbox{\_numprint\_thednum}% } \_public \eqmark ; \_doc ----------------------------- The \`\numberedpar` `<letter>{<name>}` is implemented here. \_cod ----------------------------- \_newcount\_counterA \_newcount\_counterB \_newcount\_counterC \_newcount\_counterD \_newcount\_counterE \_def\_resetABCDE {\_counterA=0 \_counterB=0 \_counterC=0 \_counterD=0 \_counterE=0 } \_def \_theAnum {\_othe\_chapnum.\_othe\_secnum.\_the\_counterA} \_def \_theBnum {\_othe\_chapnum.\_othe\_secnum.\_the\_counterB} \_def \_theCnum {\_othe\_chapnum.\_othe\_secnum.\_the\_counterC} \_def \_theDnum {\_othe\_chapnum.\_othe\_secnum.\_the\_counterD} \_def \_theEnum {\_othe\_chapnum.\_othe\_secnum.\_the\_counterE} \_def\_numberedpar#1#2{\_ea \_incr \_csname _counter#1\_endcsname \_def\_tmpa{#1}\_def\_tmpb{#2}\_numberedparparam} \_optdef\_numberedparparam[]{% \_ea \_printnumberedpar \_csname _the\_tmpa num\_ea\_endcsname\_ea{\_tmpb}} \_public \numberedpar ; \_doc ----------------------------- The \`\_printnumberedpar` `\theXnum {<name>}` opens numbered paragraph and prints it. The optional parameter is in `\_the\_opt`. You can re-define it if you need another design. `\_printnumberedpar` needs not to be re-defined if you only want to print Theorems in italic and to insert vertical skips (for example). You can do this by the following code: \begtt \def\theorem {\medskip\bgroup\it \numberedpar A{Theorem}} \def\endtheorem {\par\egroup\medskip} \theorem Let $M$ be... \endtheorem \endtt \_cod ----------------------------- \_def \_printnumberedpar #1#2{\_par \_noindent\_wlabel #1% {\_bf #2 \_numprint{#1}\_istoksempty\_opt\_iffalse \_space \_the\_opt \_fi.}\_space \_ignorespaces } \_endcode % ------------------------------------- 2024-01-19 \bracedparam\secl enalbed 2024-01-18 \tit, \chap, \sec, \secc: added cooperation with new \bracedparam 2023-05-02 \_numprint used 2022-10-19 More robust \caption (two opened groups, \_printcaption introduced) 2022-08-02 Penalties in \_printsec, \_printsecc changed 2022-07-11 \_printchap: \_prevdepth=0pt added, see issue 100 2021-03-03 \_captionsep introduced, \_othe used in \_thetnum, \_thefnum. 2021-02-09 \thisoutline implemented 2021-01-26 \_nl: \unskip added 2021-01-11 \secl introduced 2021-01-05 \_thednum printed in text mode in its both occurences. 2020-04-28 \_secfonts etc: \_boldify is last. 2020-04-22 \_chapx, \_secx, \_seccx rewritten 2020-03-14 introduced