% \iffalse % % Copyright (C) 2024, 2025 by Ch. L. Spiel % % This work may be distributed and/or modified under the conditions % of the LaTeX Project Public License, either version 1.3c of this % license or (at your option) any later version. The latest version % of this license is in % https://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of LaTeX % version 2003/12/01 or later. % % \fi % % \iffalse %<*driver> \documentclass{ltxdoc} \tracingonline=0 \EnableCrossrefs \CodelineIndex \RecordChanges \PassOptionsToClass{a4paper}{article} \PassOptionsToPackage{hyperfootnotes=false}{hyperref} \PassOptionsToPackage{dvipsnames}{xcolor} \usepackage{amsmath} \usepackage{amssymb} \usepackage{array} \usepackage{booktabs} \usepackage{caption} \usepackage{dtk-logos} \usepackage{enumitem} \usepackage{etoolbox}%--\tracingpatches \usepackage{fancyhdr} \usepackage[LGR,T1]{fontenc} \usepackage{hypdoc} \usepackage{hyphenat} \usepackage[shrink=10, stretch=10, verbose=true]{microtype} \usepackage{multirow} \usepackage{needspace} \usepackage[section]{placeins} \usepackage{ragged2e} \usepackage{setspace} \usepackage{sidecap} \usepackage{tabularx} \usepackage[most]{tcolorbox} \usepackage[nobottomtitles*]{titlesec}\renewcommand*{\bottomtitlespace}{.2\textheight} \usepackage[debug, raise*=.05em, uppercaselabelitemadjustments={.25pt, 1pt, -.875pt, .25pt}, lowercaselabelitemadjustments={-.75pt, 0pt, -2pt, -.75pt}]{typog} \usepackage{xcolor} \usepackage[default, lining, proportional, regular, semibold]{sourceserifpro} \usepackage[lining, proportional, regular, semibold]{sourcesanspro} \usepackage[lining, regular]{sourcecodepro} \usepackage[scaled=1.08, uprightscript, xcharter]{newtxmath} \setbaselineskip{12.5pt} \makeatletter \def\@get@fontclan#1-#2\@nil{#1} \newcommand*{\fontclan}{\expandafter\@get@fontclan\f@family\@nil} \makeatother \DeclareRobustCommand{\proportionalliningfigures}{\fontfamily{\fontclan-LF}\selectfont} \DeclareRobustCommand{\proportionaloldstylefigures}{\fontfamily{\fontclan-OsF}\selectfont} \DeclareRobustCommand{\tabularliningfigures}{\fontfamily{\fontclan-TLF}\selectfont} \DeclareRobustCommand{\tabularoldstylefigures}{\fontfamily{\fontclan-TOsF}\selectfont} \DeclareRobustCommand{\textdenominator}[1]{{\fontfamily{\fontclan-Dnom}\selectfont #1}} \DeclareRobustCommand{\textinferior}[1]{{\fontfamily{\fontclan-Inf}\selectfont #1}} \DeclareRobustCommand{\textnumerator}[1]{{\fontfamily{\fontclan-Numr}\selectfont #1}} \DeclareRobustCommand{\textsuperior}[1]{{\fontfamily{\fontclan-Sup}\selectfont #1}} \newcommand*{\nativetextfraction}[2] {\mbox{\textnumerator{#1}\textfractionsolidus\textdenominator{#2}}} \makeatletter \renewcommand*{\@makefnmark}{\hbox{\sf\textsuperior{\@thefnmark}}} \newenvironment*{tabfigures} {\edef\rmdefault{\fontclan-T\sourceserifpro@figurestyle}\rm\ignorespaces} {\ignorespacesafterend} \makeatother \DeclareRobustCommand{\elseries}{\fontseries{el}\selectfont} \DeclareTextFontCommand{\textel}{\elseries} \DeclareRobustCommand{\lseries}{\fontseries{l}\selectfont} \DeclareTextFontCommand{\textl}{\lseries} %%--\DeclareRobustCommand{\mdseries}{\fontseries{m}\selectfont} %%--\DeclareTextFontCommand{\textmd}{\mdseries} \DeclareRobustCommand{\sbseries}{\fontseries{sb}\selectfont} \DeclareTextFontCommand{\textsb}{\sbseries} \DeclareRobustCommand{\bseries}{\fontseries{b}\selectfont} \DeclareTextFontCommand{\textb}{\bseries} \DeclareRobustCommand{\ebseries}{\fontseries{eb}\selectfont} \DeclareTextFontCommand{\texteb}{\ebseries} \DeclareRobustCommand{\ubseries}{\fontseries{k}\selectfont} \DeclareTextFontCommand{\textub}{\ubseries} \usepackage{cleveref} \expandafter\GetFileInfo\expandafter{\jobname.sty} \def\aspdfdate#1/#2/#3\relax{D:#1#2#3} \edef\pdffiledate{\expandafter\aspdfdate\filedate\relax} \hypersetup{ citecolor = blue, colorlinks = true, linkcolor = blue, linktocpage = true, pdfauthor={Dr. Christoph L. Spiel}, pdfcreationdate={\pdffiledate}, pdfkeywords={LaTeX, typography, ligature, italic-correction, paragraph justification, baselineskip, sloppy, ragged}, pdflang=en-US, pdfsubject={Typographic fine-tuning for LaTeX}, pdftitle={Package typog \fileversion}, raiselinks = false, urlcolor = [rgb]{0, 0, .5}% = navy } \newlength{\sectiontocindent} \newlength{\sectionnumberwidth} \newlength{\subsectiontocindent} \newlength{\subsectionnumberwidth} \newlength{\subsubsectiontocindent} \newlength{\subsubsectionnumberwidth} \setlength{\sectiontocindent}{0pt} \setlength{\sectionnumberwidth}{40pt} \setlength{\subsectiontocindent}{40pt} \setlength{\subsectionnumberwidth}{25pt} \setlength{\subsubsectiontocindent}{65pt} \setlength{\subsubsectionnumberwidth}{30pt} \makeatletter \renewcommand*{\l@section}[2] {\ifnum \c@tocdepth >\z@ \addpenalty\@secpenalty \addvspace{1.0em \@plus\p@}% \setlength{\@tempdima}{\sectionnumberwidth}% \begingroup \def\numberline##1{\hb@xt@\@tempdima{% \tt\lseries \fontsize{44}{0}\selectfont \microtypecontext{kerning=drop-left-sidebearing}% \iffalse\raisebox{-30pt}[0pt][0pt]{\rule{0.1pt}{40pt}}\fi \textcolor{customred3}{##1}% \hfil}}% \parindent \z@ \rightskip \@pnumwidth \parfillskip -\@pnumwidth \leavevmode \advance\leftskip\@tempdima \hskip -\leftskip \bfseries \iffalse \nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2\kern-\p@\kern\p@}% \else {\sffamily\large #1}\quad {#2}\hfil\hbox{} \fi \par \endgroup \fi} \renewcommand*{\@dottedtocline}[5] {\ifnum #1>\c@tocdepth \else \vskip \z@ \@plus.2\p@ \begingroup \leftskip #2\relax \rightskip \@tocrmarg \parfillskip -\rightskip \parindent #2\relax\@afterindenttrue \interlinepenalty\@M \leavevmode \@tempdima #3\relax \advance\leftskip \@tempdima \null\nobreak \hskip -\leftskip {#4}\nobreak \iffalse \leaders\hbox{$\m@th \mkern \@dotsep mu\hbox{.}\mkern \@dotsep mu$}\hfill \nobreak\hb@xt@\@pnumwidth{\hfil\normalfont \normalcolor #5\kern-\p@\kern\p@}% \else \hbox{\quad\normalfont\bfseries #5}\nobreak\hfill\hbox{}% \fi \par \endgroup \fi} \renewcommand*{\l@subsection}{\@dottedtocline{2}{\subsectiontocindent}{\subsectionnumberwidth}} \renewcommand*{\l@subsubsection}{\@dottedtocline{3}{\subsubsectiontocindent}{\subsubsectionnumberwidth}} \newrobustcmd*{\tocsquashedsubsections} {\def\l@subsection{\@dottedtocline{2}{0pt}{\subsectionnumberwidth}}% \def\l@subsubsection{\@dottedtocline{3}{0pt}{\subsubsectionnumberwidth}}} \makeatother \Crefname{figure}{Figure}{Figures} \crefname{figure}{Fig.}{Figs.} \Crefname{page}{Page}{Pages} \crefname{page}{p.}{p.} \Crefname{section}{Section}{Sections} \crefname{section}{Sec.}{Secs.} \Crefname{table}{Table}{Tables} \crefname{table}{Tab.}{Tabs.} \DeclareCaptionJustification{centerlastjustification}{\justify\fussy\lastlinecenteredpar} \DeclareCaptionJustification{smoothraggedjustification}% {\renewcommand*{\smoothraggedrightgenerator}{quintuplet}% \setlength{\smoothraggedrightragwidth}{1em}% \smoothraggedrightpar\relax} \DeclareCaptionJustification{relaxedjustification}{\justify\slightlysloppy} \newcommand*{\floatcaptionwidth}{.79\textwidth} \captionsetup[figure]{font=small, justification=centerlastjustification, labelfont=sc, width=\floatcaptionwidth} \captionsetup[table]{font=small, justification=centerlastjustification, labelfont=sc, width=\floatcaptionwidth} \captionsetup[SCfigure]{font=small, justification=relaxedjustification, labelfont=sc} \captionsetup[SCtable]{font=small, justification=relaxedjustification, labelfont=sc} \newsavebox{\listlabelbox} \sbox{\listlabelbox}{---} \SetEnumitemKey{noindent}{ label={---}, labelwidth=\wd\listlabelbox, leftmargin=! } \SetEnumitemKey{nestedinspecialsection}{ leftmargin=10pt } \SetEnumitemKey{notopsep}{ after=\vskip.8em plus .2em minus .4em, partopsep=0pt, topsep=0pt } \newlength{\marginindicatorsep} \setlength{\marginindicatorsep}{10pt} \newcommand*{\marginalizesectionnumber}[1] {\makebox[0pt][r]{#1\hspace{\marginindicatorsep}}} \fancypagestyle{pagenumberonly}{ \fancyhf{} \fancyhead[L]{} \fancyhead[R]{\thepage} } \fancypagestyle{fancy}{ \fancyhf{} \fancyhead[L]{\rightmark} \fancyhead[R]{\thepage} } \newcommand*{\letterspacedsmallcaps}[1]{\textsc{\textls[20]{#1}}} \newcommand*{\resetfancyhead} {\fancyhead[L]{\textsf{\letterspacedsmallcaps{\nouppercase\rightmark}}}} \renewcommand*{\headrulewidth}{0pt} \renewcommand*{\sectionmark}[1] {\def\truesectionname{#1}% \markright{\textsf{\marginalizesectionnumber{\thesection}% \letterspacedsmallcaps{#1}}}} \renewcommand*{\subsectionmark}[1] {\markright{\textsf{\marginalizesectionnumber{\thesubsection}% \letterspacedsmallcaps{\truesectionname:\enspace}#1}}} \titleformat{\section}[hang] {\sffamily\Large\bfseries}{\marginalizesectionnumber{\thesection}}{0pt}{} \titleformat{\subsection}[hang] {\sffamily\large\bfseries}{\marginalizesectionnumber{\thesubsection}}{0pt}{} \titleformat{\subsubsection}[hang] {\sffamily\normalsize\bfseries}{\marginalizesectionnumber{\thesubsubsection}}{0pt}{} \titleformat{\paragraph}[runin] {\sffamily\normalsize\bfseries}{\theparagraph}{1em}{} \def\footnoterule{\vfill}% push footnotes to the bottom of the page \makeatletter \renewcommand*{\@makefntext}[1] {\noindent \llap{\let\@textsuperscript=\relax% use "normal" figures for the footnote numbers \let\textsuperior=\relax \@makefnmark \hspace{\marginindicatorsep}}% separate the footnote number and the body #1} \makeatother \pretocmd{\DescribeEnv}{\needspace{25pt}}{\relax}{\PrependingFailed} \pretocmd{\DescribeMacro}{\needspace{25pt}}{\relax}{\PrependingFailed} \setlength{\skip\footins}{25pt} \setlength{\overfullrule}{0pt} \renewcommand*{\sidecaptionsep}{25pt} \renewcommand*{\abstractname}{{\sffamily Abstract}} \newrobustcmd*{\acronym}[1]{\mbox{\scshape\MakeLowercase{#1}}} \newcommand*{\aliasfor}[2]{$\rightarrow$ #1} \newcommand*{\application}[1]{\mbox{\sffamily #1}} \renewcommand*{\arraystretch}{1.12} \newcommand*{\backwardincompatiblechange} {\textcolor{customred3}{\sffamily\scshape\bfseries [Backward Incompatible Change]}} \newcommand*{\bibauthor}[1]{\mbox{\textsc{#1}}} \newcommand*{\bibtitle}[1]{\textit{#1}} \newcommand*{\biburl}[1]{\url{#1}} \newcommand*{\bottomstrut}{\rule[-.5em]{0pt}{0pt}} \newenvironment*{codeexample*} {\vspace{.5\smallskipamount} \par \ttfamily \begin{tabbing}} {\end{tabbing} \par \vspace{.5\smallskipamount}} \newenvironment*{codeexample} {\vspace{.5\smallskipamount} \par \centering \begin{minipage}{\linewidth} \ttfamily \begin{tabbing}} {\end{tabbing} \end{minipage} \par \vspace{.5\smallskipamount}} \makeatletter \newcommand*{\citenum}[1]{\@nameuse{b@#1}} \makeatother \renewcommand*{\code}[1]{\texttt{#1}} \newcommand*{\codelineindicator}{\mbox{\small$\mathscr{l}$}} \newrobustcmd*{\command}[1]{\mbox{\textbf{#1}}} \newcommand*{\detoxindex}[1]{\index{\detokenize{#1}}} \newcommand*{\doublequotes}[1]{``#1''} \newcommand*{\dumpmacro}[1]{\texttt{\detokenize\expandafter{#1}\unskip}} \renewcommand*{\eTeX}{\mbox{\textepsilon-\kern-.075em\TeX}} \newcommand*{\filesystem}[1]{\mbox{\textit{#1\/}}} \newcommand*{\filledrectangle}[2]{\rule{#1}{#2}} \newcommand*{\filledsquare}[1]{\filledrectangle{#1}{#1}} \newcommand*{\foreignphrase}[1]{\textsl{#1}} \makeatletter \newcommand*{\formatdimen}{\@ifstar{\@typog@rem@pt}{\@typog@strip@pt}} \newcommand*{\@typog@rem@pt}[1]{\dimen0=\dimexpr#1\relax\strip@pt\dimen0\,pt} \newcommand*{\@typog@strip@pt}[1]{\expandafter\strip@pt#1\relax\,pt} \makeatother \newcommand*{\formatskip}[3]{#1\genfrac{}{}{0pt}{}{{+}#2}{{-}#3}} \makeatletter \renewcommand*{\fps@figure}{htbp} \renewcommand*{\fps@table}{htbp} \makeatother \apptocmd{\GlossaryParms} {\RaggedRight\normalsize} {\relax} {\AppendingFailed} \let\oldhdclindex=\hdclindex \renewcommand*{\hdclindex}[2] {\ifstrequal{#2}{code} {\oldhdclindex{#1}{codeidx}} {\oldhdclindex{#1}{#2}}} \let\oldhdpindex=\hdpindex \renewcommand*{\hdpindex}[2]{\textbf{\oldhdpindex{#1}{#2}}} \newcommand*{\hollowrectangle}[2] {\setlength{\fboxrule}{.5pt}% \setlength{\fboxsep}{0pt}% \framebox{\rule{#1}{0pt}\rule{0pt}{#2}}} \newcommand*{\hollowsquare}[1]{\hollowrectangle{#1}{#1}} \NewMarkClass{IndexGroup} \newcommand*{\indexgroup}[1]{\InsertMark{IndexGroup}{#1}#1} \apptocmd{\IndexParms} {\RaggedRight\small} {\relax} {\AppendingFailed} \makeatletter \IndexPrologue{\section*{Index}% \markboth{\sf\letterspacedsmallcaps{Index}}{\sf\letterspacedsmallcaps{Index}}% \begin{whittyquote} Es ist schon alles gesagt, \\ nur noch nicht von allen. \\ \capitalemdash*~\propername{Karl Valentin} \end{whittyquote} Numbers written in italic style refer to definitions; numbers in regular style refer to pages where an entry is used. \ifx\special@index\HD@codeline@wrindex References to code lines are prefixed with~\singlequotes{\codelineindicator}. Again, italic style refers to definitions and regular style to lines where the code is used. \fi} \newcommand*{\linenumberdecoration} {\ifx\special@index\HD@codeline@wrindex \codelineindicator \fi} \makeatother \newcommand*{\indexpackageoption}[1] {\detoxindex{package option>#1=\code{#1}|userman}% \detoxindex{#1=\code{#1}~(option)|userman}% \ignorespaces} \newcommand*{\indexpackageoptiondefinition}[1] {\detoxindex{package option>#1=\code{#1}|usermandef}% \detoxindex{#1=\code{#1}~(option)|usermandef}% \ignorespaces} \newcommand*{\leftmarker}{\rule{.2em}{.1pt}\rule{.1pt}{.667em}} \newcommand*{\rightmarker}{\rule{.1pt}{.667em}\rule{.2em}{.1pt}} \newcommand*{\indicatewidth}[1]{\mbox{\leftmarker #1\rightmarker}} \newcommand*{\logmacro}[1] {\ifdef{#1} {\message{^^JDump of macro \string#1 follows.^^J} \message{\detokenize\expandafter{#1}} \message{^^JEnd macro dump.^^J}} {\message{^^JMacro \string#1 is not defined.^^J}}} \newcommand*{\marginnoteformat} {\resetbaselineskip \sffamily \footnotesize \nofontexpansion \slightlysloppy[1] \loosespacing[1] \setlength{\smoothraggedrightragwidth}{1em}% \def\smoothraggedrightgenerator{quintuplet}% \smoothraggedrightpar} \newcommand*{\marginnote}[1]{\marginpar{\marginnoteformat #1}} \addtolength{\marginparpush}{3pt} \addtolength{\marginparsep}{25pt} \addtolength{\marginparwidth}{-25pt} \newcommand*{\shiftedmarginnote}[1] {\marginpar{\moveleft \leftmargin \hbox{\parbox{\dimexpr\marginparwidth - \marginparsep} {\marginnoteformat #1}}}} \newenvironment*{widebody} {\begin{list}{}{\leftmargin=-\marginparwidth \listparindent=\parindent \parsep=\parskip \rightmargin=0pt \topsep=0pt} \item\relax} {\end{list}} \newcommand*{\microtyperequiredmarker} {\mbox{\normalfont\packagename{microtype}~required}} \newlength{\emreference} \AtBeginDocument{\setlength{\emreference}{\fontdimen6\font}} \newrobustcmd*{\milliem}[1] {\ifdim #1=0pt 0\,pt% \else \nativetextfraction{\the\numexpr\dimexpr (#1) * 1000 / \emreference}{1000}\:em% \fi} \newrobustcmd*{\milliemglue}[1] {\nativetextfraction{\the\numexpr\dimexpr (#1) * 1000 / \emreference}{1000}\:em% \ifdim\gluestretch #1>0pt \space plus~\relax \nativetextfraction{\the\numexpr\gluestretch\glueexpr (#1) * 1000 / \emreference}{1000}\:em% \fi \ifdim\glueshrink #1>0pt \space minus~\relax \nativetextfraction{\the\numexpr\glueshrink\glueexpr (#1) * 1000 / \emreference}{1000}\:em% \fi} \let\originalmulticols=\multicols \let\endoriginalmulticols=\endmulticols \RenewDocumentEnvironment{multicols}{m o o} {\ifnum #1=1 \IfNoValueTF{#2}{\relax}{#2}% \else \IfNoValueTF{#2} {\originalmulticols{#1}} {\originalmulticols{#1}[#2]}% \fi} {\ifnum #1=1 \relax \else \endoriginalmulticols \fi} \newcommand*{\needtocspace}[1][3] {\addtocontents{toc}{\protect\needspace{#1\baselineskip}}} \let\newpagetofixtoc=\newpage \newcommand*{\packagename}[1]{\mbox{\textsf{#1}}} \newcommand*{\programname}[1]{\mbox{\textbf{#1}}} \newcommand*{\propername}[1]{\mbox{\textsc{#1}}} \newcommand*{\quarterspace}{\hspace{.25em}} \NewDocumentCommand{\sample}{s m} {\setbox0=\hbox{#2}% H: 6.19849pt, /: 7.49817 \mbox{\raisebox{\dimexpr -.15em - \dp0}{\tiny$\llcorner$}% \kern-.15em\copy0\kern-.15em \raisebox{\ifdim\ht0>.7em \ifx#1\BooleanTrue .4em \else \dimexpr\ht0 - .1em \fi \else .4em \fi} {\tiny$\urcorner$}}} \newcommand*{\samplestar}{\sample{\raisebox{-.25em}[0pt][0pt]{*}}} \newcommand*{\sectionfinish}[1][0] {\ifnum#1=0% \relax \else \vfill \begingroup \centering \textcolor{\markercolor} {\ifcase#1% 0 \relax \or % 1 \filledsquare{5pt}\enspace\filledsquare{5pt}% \or % 2 \filledsquare{4pt}\enspace\filledsquare{4pt}\enspace\filledsquare{4pt}% \or % 3 $\bullet\enspace\bullet\enspace\bullet$% \or % 4 \large \textasteriskcentered\enspace\textasteriskcentered\enspace\textasteriskcentered \fi}% \par \endgroup \vfill \fi} \newcommand*{\sinceversion}[1]{% modeled after \NewIn of "doc.dtx" \leavevmode \marginpar{\RaggedLeft\textcolor{\markercolor}{\sf\scshape\proportionaloldstylefigures #1}}% \ignorespaces } \newcommand*{\singlequotes}[1]{\mbox{`#1'}} \newcommand*{\specialsectionheading}[1]{\textcolor{\markercolor}{\textit{\textbf{#1}}}} \definecolor{customred1}{rgb}{.890, .282, .282}%-- https://paletton.com/ \definecolor{customred2}{rgb}{.831, .110, .110} \definecolor{customred3}{rgb}{.686, .043, .043} \definecolor{customred4}{rgb}{.569, .000, .000} \definecolor{customred5}{rgb}{.420, .000, .000} \newcommand*{\markercolor}{customred4} \newcommand*{\specialsectionmarker}{\color{\markercolor}\filledsquare{5pt}} \newcommand*{\specialsectionbegin} {\llap{\raisebox{1pt}{\specialsectionmarker}% \hspace{\marginindicatorsep}}} \newcommand*{\specialsectionend} {\ifmmode \specialsectionmarker \else \leavevmode \unskip \penalty9999\mbox{}\nobreak \hfill \quad \mbox{\specialsectionmarker}% \fi} \newtoggle{printspecialsectionmarker} \NewDocumentEnvironment{specialsection}{m m} {\Needspace{4\baselineskip}% \toggletrue{printspecialsectionmarker}% \begin{list} {\specialsectionheading{#1\ifblank{#2}{}{\textup{\space---\space#2}}}} {\itemindent=0pt \labelwidth=10pt \leftmargin=15pt \listparindent=15pt \parsep=0pt \topsep=\medskipamount} \newcommand*{\specialsectionendhere} {\specialsectionend \global\togglefalse{printspecialsectionmarker}} \phantomsection \item \nointerlineskip \leavevmode\par \noindent} {\iftoggle{printspecialsectionmarker}{\specialsectionend}{\relax}% \end{list}} \newenvironment*{caution}[1][]{\begin{specialsection}{Caution}{#1}}{\end{specialsection}} \newenvironment*{example}[1][]{\begin{specialsection}{Example}{#1}}{\end{specialsection}} \newenvironment*{futuredirection}[1][] {\begin{specialsection}{Anticipated Changes \textit{\&} Possible Extensions}{#1}\small} {\end{specialsection}} \newenvironment*{important}[1][]{\begin{specialsection}{Important}{#1}}{\end{specialsection}} \newenvironment*{note}[1][]{\begin{specialsection}{Note}{#1}}{\end{specialsection}} \newenvironment*{notes}[1][]{\begin{specialsection}{Notes}{#1}}{\end{specialsection}} \newenvironment*{tip}[1][]{\begin{specialsection}{Tip}{#1}}{\end{specialsection}} \newenvironment*{tips}[1][]{\begin{specialsection}{Tips}{#1}}{\end{specialsection}} \newenvironment*{usecase}[1][]{\begin{specialsection}{Use Case}{#1}\small}{\end{specialsection}} \newenvironment*{usecases}[1][]{\begin{specialsection}{Use Cases}{#1}\small}{\end{specialsection}} \newcommand*{\specialcodesectionheading}[1]{\textcolor{\markercolor}{\textbf{\textit{#1}}}} \newenvironment*{specialcodesection}[1] {\Needspace{4\baselineskip}% \begin{tcolorbox}[blanker, borderline west={3pt}{0pt}{\markercolor}, breakable, left=15pt] \sf\typogsetupsf \begin{list} {\specialcodesectionheading{#1}} {\itemindent=0pt \labelwidth=20pt \leftmargin=25pt \listparindent=15pt \parsep=0pt \topsep=\medskipamount} \item \nointerlineskip \leavevmode\par \slightlysloppy[2] \noindent} {\end{list} \end{tcolorbox}} \newenvironment*{anticipatedchange} {\begin{specialcodesection}{Anticipated Change}} {\end{specialcodesection}} \newenvironment*{implementationnote} {\begin{specialcodesection}{Implementation Note}} {\end{specialcodesection}} \newenvironment*{knownbug} {\begin{specialcodesection}{Known Bug}} {\end{specialcodesection}} \newenvironment*{suspendshortverb} {\DeleteShortVerb{\|}} {\MakeShortVerb{\|}} \definecolor{cold-silver}{cmyk}{.08, 0, 0, .18} \newenvironment*{synopsis} {\begin{tcolorbox}[boxrule=.25pt, colback=cold-silver]% \phantomsection} {\end{tcolorbox}} \newenvironment*{tablenotes} {\medskip \centering \small \begin{minipage}{\floatcaptionwidth}} {\end{minipage}} \newcommand*{\tablenotemark}[1]{\smash{\textsuperscript{#1}}} \newcommand*{\tablenotesymbol}[1]{% Bringhurst's "traditional order" (p69) from 1 to 6 \ifcase#1\relax #1% 0 \or \textasteriskcentered% 1 \or \textdagger% 2 \or \textdaggerdbl% 3 \or \textsection% 4 \or \textbardbl% 5 \or \textsection% 6 \or \textasteriskcentered\textasteriskcentered%7 \or \textdagger\textdagger%8 \or \textdaggerdbl\textdaggerdbl%9 \else #1 \fi } \newcommand*{\termparbox}[1]{\parbox[t]{\linewidth}{#1\bottomstrut}} \renewcommand*{\textepsilon} {{\fontencoding{LGR}% \fontfamily{artemisia}% use true Greek font that pairs well with Source Serif \fontsize{1.083\fontdimen6\font}{1.2\fontdimen6\font}% scale up to match Source Serif \selectfont\char101}} \newcommand*{\thousandsseparator}{\mbox{,}} \ExplSyntaxOn \newcommand*{\titlecase}[1]{\text_titlecase:n {#1}} \ExplSyntaxOff \newcommand*{\toccontinuesonnextpage} {\addtocontents{toc}{\par \bigskip \hfill\textit{Table of Contents continued on next page.}\par \protect\clearpage}} \newcommand*{\topstrut}{\rule{0pt}{1.3em}} \newlength{\ttellipsisgap} \setlength{\ttellipsisgap}{0.4em} \newcommand*{\ttdots} {\setbox0=\hbox{.}% \wd0=0pt% \copy0\kern\ttellipsisgap \copy0\kern\ttellipsisgap \box0\kern\ttellipsisgap} \newcommand*{\typogsetuprm} {\typogsetup{raise*=.025em, raisecapitalguillemets=.05em, raiseguillemets=.03333em, raisefiguredash=.05em}} \newcommand*{\typogsetupsf} {\typogsetup{raise*=.06667em, raiseguillemets=.05em}} \newcommand*{\unmarkedfntext}[1] {{\def\thefootnote{}\footnote{#1}% \addtocounter{footnote}{-1}}} \newcommand*{\userman}[1]{\textbf{\hyperpage{#1}}}%-- https://github.com/ho-tex/hypdoc/issues/11 \newcommand*{\usermandef}[1]{\textbf{\itshape\hyperpage{#1}}} \newcommand*{\visualpar}{~\textcolor{\markercolor}{\P}\linebreak[1]\enspace} \newenvironment*{whittyquote} {\begin{flushright} \sf\typogsetupsf} {\end{flushright}} \newenvironment*{widecodeexample} {\begin{widebody} \flushright \begin{minipage}{\textwidth} \ttfamily \begin{tabbing}} {\end{tabbing} \end{minipage} \end{widebody}} \NewDocElement[macrolike = true, idxtype = dim., idxgroup = dimensions, printtype = \textit{dimen}] {LaTeXDimen}{ldimen} \pretocmd{\DescribeLaTeXDimen}{\needspace{25pt}}{\relax}{\PrependingFailed} \NewDocElement[macrolike = false, idxtype = enumitem-key, idxgroup = enumitem-keys, printtype = \textit{enumitem key}] {EnumItemKey}{enumitemkey} \pretocmd{\DescribeEnumItemKey}{\needspace{25pt}}{\relax}{\PrependingFailed} \NewDocElement[macrolike = true, idxtype = skip, idxgroup = dimensions, printtype = \textit{skip}] {LaTeXSkip}{lskip} \pretocmd{\DescribeLaTeXSkip}{\needspace{25pt}}{\relax}{\PrependingFailed} \NewDocElement[macrolike = true, idxtype = counter, idxgroup = \protect\TeX{} counters, printtype = \textit{counter}] {TeXCounter}{tcounter} \pretocmd{\DescribeTeXCounter}{\needspace{25pt}}{\relax}{\PrependingFailed} \NewMarkClass{QuickReference} \newdimen\qrcolumnwidth \newcommand*{\qrcolumns}{2} \newcommand*{\qrlistparam}{\itemindent=-\leftmargin \itemsep=5pt plus 2pt minus 1pt} \newcommand*{\qrtightspacing}{1} \SetTracking[context = quickreference]{encoding = *, family = {rm*, sf*}}{0} \newenvironment*{quickreference} {\NewDocumentCommand{\heading}{s m} {\IfBooleanF{##1} {\pagebreak[3]% \medskip \needspace{2\baselineskip}}% {\sffamily\bfseries\large ##2}} \newcommand*{\sigbrk} {\discretionary{\hbox{\raise .025em \hbox{$\triangleright$}}} {\hbox{\raise .025em \hbox{$\triangleleft$}}} {}} \newcommand*{\horizontalcolumnseparator} {\rule{\dimexpr \qrcolumnwidth * (\qrcolumns - 1) + \columnsep * (\qrcolumns - 2)}{.5pt}}% \newcommand*{\suspendseparator} {\noindent\horizontalcolumnseparator\rule{.5pt}{7pt}} \newcommand*{\resumeseparator} {\hfill\rule[-6.5pt]{.5pt}{7pt}\horizontalcolumnseparator} \setlength{\columnsep}{25pt}% \setbaselineskippercentage{120}% \NewDocumentEnvironment{qritem}{m m O{}} {\item \vtietop[2] \hyperref[##1]{\textnormal{##2}}##3\relax \edef\qrpageref{\pageref{##1}}% \InsertMark{QuickReference}{##2}% \leavevmode \linebreak \ignorespaces} {\leavevmode \unskip \penalty9999\hbox{}\nobreak \hfill\quad \mbox{\footnotesize\textbf{\qrpageref}}}% \newcommand*{\suspendmulticols} {\end{list}% \end{tightspacing}% \end{microtypecontext}% \end{multicols}% \suspendseparator \begin{microtypecontext}{tracking=quickreference}% \begin{tightspacing}[\qrtightspacing]% \begin{list}{}{\qrlistparam}}% \newcommand*{\resumemulticols} {\end{list}% \end{tightspacing}% \end{microtypecontext}% \resumeseparator \begin{multicols}{\qrcolumns} \raggedcolumns \RaggedRight \begin{microtypecontext}{tracking=quickreference}% \begin{tightspacing}[\qrtightspacing]% \begin{list}{}{\qrlistparam}}% \begin{multicols}{\qrcolumns} \global\qrcolumnwidth=\columnwidth \raggedcolumns \RaggedRight \begin{microtypecontext}{tracking=quickreference}% \begin{tightspacing}[\qrtightspacing]% \begin{list}{}{\qrlistparam}} {\end{list}% \end{tightspacing}% \end{microtypecontext}% \end{multicols}} \makeatletter \newcommand*{\ps@fancyqr} {\def\@oddhead{\begingroup \sf \kern-\marginparwidth {\letterspacedsmallcaps{Quick Reference}}\hfill \textnormal{\FirstMark{QuickReference}}\enspace\capitalemdash*\enspace \textnormal{\LastMark{QuickReference}}% \endgroup \hfill \thepage} \let\@evenhead=\@oddhead} \makeatother \newenvironment{mybibliography} {\begin{RaggedRight}% \def\MakeUppercase##1{\sf\letterspacedsmallcaps{##1}}% \begin{thebibliography}{88}} {\end{thebibliography}% \end{RaggedRight}} \iffalse %% Linearize document and make it more palpable for pdftotext(1). \OnlyDescription \let\oldcode=\code \renewcommand*{\code}[1]{\mbox{\oldcode{#1}}} \let\oldcs=\cs \renewcommand*{\cs}[1]{\mbox{\oldcs{#1}}} \renewcommand*{\footnote}[2][]{\space({#2})\space} \renewcommand*{\footnotetext}[2][]{\space({#2})\space} \let\fuzzy=\sloppy \renewcommand*{\LaTeXe}{LaTeX~2~epsilon} \renewcommand*{\LaTeXIII}{LaTeX~3} \renewcommand*{\LaTeX}{LaTeX} \renewcommand*{\LuaLaTeX}{LUA~LaTeX} \renewcommand*{\LuaTeX}{LUA~TeX} \renewcommand*{\MP}{Meta~Post} \renewcommand*{\marginpar}[1]{\space({#1})\space} \renewcommand*{\moveleft}[2]{#2} \let\oldpagestyle=\pagestyle \renewcommand*{\pagestyle}[1]{\oldpagestyle{plain}} \renewcommand*{\pdfLaTeX}{PDF~LaTeX} \renewcommand*{\pdfTeX}{PDF~TeX} \renewcommand*{\sample}[1]{\mbox{`#1'}} \let\scshape=\relax \let\sf=\relax \let\sffamily=\relax \renewcommand*{\slightlysloppy}[1][]{} \renewenvironment{slightlysloppypar}{}{} \renewenvironment{smoothraggedrightpar}[1][]{}{} \renewenvironment{smoothraggedright}[1][]{}{} \renewcommand*{\marginnote}[1]{#1} \renewcommand*{\shiftedmarginnote}[1]{#1} \renewcommand*{\TeX}{TeX} \renewcommand*{\textsc}[1]{#1} \RenewDocumentEnvironment{multicols}{m o o}{}{} \lefthyphenmin=62 \righthyphenmin=62 \overfullrule=0pt \AtBeginDocument{\sloppy} \fi \hyphenation{% https://hyphenateit.com/en-us Double-guillemet-left Double-guillemet-right Double-quotes Single-guillemet-left Single-guillemet-right Single-quotes adj-demerits allow-break babel-hyphenation base-line-skip break-penalty breakable-display capital-hyphen capital-inverted-exclamation-mark capital-inverted-question-mark capital-times cite-dash club-penalties cref-range-conjunction display-break display-widow-penalties double-guillemet-right double-hyphen-demerits double-quotes ex-hyphen-penalty figure-dash guille-met guille-mets inter-display-line-penalty inter-text kerned-hyphen last-line-centered last-line-centered-par last-line-fit last-line-fit-par last-line-ragged-left last-line-ragged-left-par left-spaced-endash loose-ness loose-spacing lower-case-adjust-label-items lower-case-label-item-adjustments make-at-letter make-at-other mar-gin-al math-italic-correction micro-type narrow-space narrow-space-scale narrow-space-strength number-dash par-box par-indent parfillskip pdf-string-def-Disable-Commands post-display-penalty pre-display-penalty raise-capital-guillemets raise-capital-hyphen raise-capital-times raise-inverted-marks raise-number-dash right-spaced-endash Set-Extra-Kerning set-baseline-skip set-baseline-skip-percentage set-font-expand set-font-shrink set-font-stretch set-leading set-leading-percentage short-inter-text shrink-limits single-guillemet-left single-guillemet-right single-quotes slash-kern slightly-sloppy slightly-sloppy-par sloppy-par smooth-ragged-right-fuzz-factor smooth-ragged-right-generator smooth-ragged-right-left-skip smooth-ragged-right-par smooth-ragged-right-par-indent smooth-ragged-right-rag-width smooth-ragged-right-shape-quintuplet smooth-ragged-right-shape-septuplet smooth-ragged-right-shape-triplet space-skip spaced-capital-emdash spaced-capital-endash spaced-dash spaced-emdash spaced-endash stretch-limits text-exclam-down text-italic-correction text-question-down tight-spacing tracing-boxes tracing-para-graphs tracking-tt-spacing typog-get typog-setup upper-case-adjust-label-items upper-case-label-item-adjustments vtie-bot vtie-bot-disp vtie-bot-disp-par vtie-bot-disp-top-par vtie-bot-par vtie-top vtie-top-par wide-space wide-space-scale wide-space-strength widow-penalties } \begin{document} \typogsetuprm \uppercaseadjustlabelitems{*} \DocInput{typog.dtx} \end{document} % %<*index-style> actual '=' delim_0 "\\nobreak\\enspace" delim_1 "\\nobreak\\enspace" delim_2 "\\nobreak\\enspace" delim_r "\\nohyperpage{\\figuredash*}" heading_prefix "\\pagebreak[3]\\smallskip\n\n{\\sffamily\\bfseries\\large\\indexgroup " heading_suffix "}\\nopagebreak\n" headings_flag 1 level '>' line_max 65536 quote '!' % %<*changes-style> actual '=' delim_0 "\\nobreak\\enspace" delim_1 "\\nobreak\\enspace" delim_2 "\\nobreak\\enspace" heading_prefix "\\pagebreak[3]\\smallskip\n\n{\\sffamily\\bfseries\\large " heading_suffix "}\\nopagebreak\n" headings_flag 0 item_x1 "\\efill\n\\subitem " item_x2 "\\ " keyword "\\glossaryentry" level '>' line_max 65536 postamble "\n\\end{theglossary}\n" preamble "\\begin{theglossary}\n \\makeatletter\\scan@allowedfalse" quote '!' % % \fi % % % \DoNotIndex{\,} % \DoNotIndex{\\} % \DoNotIndex{\addtocounter,\addtolength,\advance,\aftergroup,\allowdisplaybreaks,\arabic,\arraystretch} % \DoNotIndex{\AfterEndPreamble,\AfterPreamble,\AtBeginDocument,\autotransfer} % \DoNotIndex{\baselineskip,\begin,\begingroup,\booltrue,\box} % \DoNotIndex{\c,\char,\clist,\clubpenalties,\clubpenalty,\count,\cs,\csname} % \DoNotIndex{\DeclareRobustCommand,\def,\define@choicekey,\define@key,\detokenize} % \DoNotIndex{\dim,\dimen,\dimexpr,\discretionary,\displaywidowpenalties,\displaywidowpenalty,\dp} % \DoNotIndex{\edef,\else,\emergencystretch,\empty,\end,\endcsname,\endgroup} % \DoNotIndex{\endlastlineflushrightpar} % \DoNotIndex{\endlastlineraggedleftpar} % \DoNotIndex{\endnofontexpand,\endnofontexpansion} % \DoNotIndex{\endsmoothraggedrightshapequintuplet} % \DoNotIndex{\endsmoothraggedrightshapeseptuplet} % \DoNotIndex{\endsmoothraggedrightshapetriplet} % \DoNotIndex{\endtypoginspect} % \DoNotIndex{\exhyphenpenalty,\expandafter,\ExplSyntaxOff,\ExplSyntaxOn} % \DoNotIndex{\fi,\finalhyphendemerits,\font,\fontdimen,\forcsvlist,\fp,\fpeval,\fussy,\futurelet} % \DoNotIndex{\gdef,\global,\glueexpr,\@gobble} % \DoNotIndex{\guillemotleft,\guillemotright,\guilsinglleft,\guilsinglright} % \DoNotIndex{\hbadness,\hbox,\hfuzz,\hskip,\hspace,\ht} % \DoNotIndex{\ignorespaces,\ignorespacesafterend} % \DoNotIndex{\if,\ifblank,\ifbool,\IfBooleanT,\IfBooleanTF,\ifcase,\ifdefined,\ifdim,\iffalse,\ifmmode} % \DoNotIndex{\ifMT@expansion,\@ifnextchar,\IfNoValueF,\IfNoValueTF,\ifnum,\ifodd,\ifstrequal} % \DoNotIndex{\iftypog@microtype@loadedfalse} % \DoNotIndex{\iftypog@microtype@preloadedfalse} % \DoNotIndex{\ifvmode,\ifx,\ignorespaces,\inputlineno,\int,\interlinepenalty,\itemize} % \DoNotIndex{\jobname} % \DoNotIndex{\kern} % \DoNotIndex{\l,\labelitemi,\labelitemii,\labelitemiii,\labelitemiv} % \DoNotIndex{\lastlinefit,\lastlineflushrightpar,\lastlineraggedleftpar,\lastskip} % \DoNotIndex{\lefthyphenmin,\leftmargin,\leftskip,\let,\letcs} % \DoNotIndex{\linepenalty,\linewidth,\@listdepth,\loop,\looseness,\lsstyle} % \DoNotIndex{\@M,\m@th,\mathbin,\mathord,\maxdimen,\mbox,\message,\microtypecontext,\microtypesetup} % \DoNotIndex{\@minus,\mkern,\m@ne,\mspace,\MT@letterspace@,\MT@MT,\muexpr} % \DoNotIndex{\@ne,\NeedsTeXFormat,\newbool,\NewDocumentCommand,\NewDocumentEnvironment} % \DoNotIndex{\newcommand,\newenvironment} % \DoNotIndex{\newcounter,\newdimen,\newif,\newlength,\newline,\newmuskip} % \DoNotIndex{\nobreak,\nofontexpand,\nofontexpansion,\nr,\numexpr} % \DoNotIndex{\or,\optarg} % \DoNotIndex{\p@,\PackageError,\PackageWarning,\PackageWarningNoLine} % \DoNotIndex{\par,\parfillskip,\parindent,\parshape,\patchcmd,\pdf@strcmp} % \DoNotIndex{\pdfstringdefDisableCommands} % \DoNotIndex{\penalty,\@plus,\PopPostHook,\postdisplaypenalty,\predisplaypenalty,\prg} % \DoNotIndex{\pretolerance,\protected,\ProvidesPackage,\PushPostHook} % \DoNotIndex{\raisebox,\refstepcounter,\relax,\RenewExpandableDocumentCommand,\repeat,\RequirePackage} % \DoNotIndex{\righthyphenmin,\rightskip,\rlap,\romannumeral,\rule} % \DoNotIndex{\seq,\setbox,\setcounter,\SetEnumitemKey,\SetExpansion,\setkeys,\setlength,\setstretch} % \DoNotIndex{\showboxbreadth,\showboxdepth,\skip,\sloppy} % \DoNotIndex{\smoothraggedrightpar} % \DoNotIndex{\smoothraggedrightshapequintuplet} % \DoNotIndex{\smoothraggedrightshapeseptuplet} % \DoNotIndex{\smoothraggedrightshapetriplet} % \DoNotIndex{\space,\spaceskip,\stepcounter,\str,\@strength,\string} % \DoNotIndex{\textemdash,\textendash,\textexclamdown,\textquestiondown} % \DoNotIndex{\textsf,\textsl,\texttimes,\textwidth,\the,\times,\tl} % \DoNotIndex{\token,\tolerance,\tracingnone,\tracingpages,\tracingparagraphs} % \DoNotIndex{\typeout,\typog,\typogadjuststairsfor,\typoginspect,\typoglogo} % \DoNotIndex{\unhbox,\unless,\unskip} % \DoNotIndex{\val,\value,\vbadness,\vfuzz} % \DoNotIndex{\wd,\widowpenalties,\widowpenalty} % \DoNotIndex{\z@,\z@skip} % % % \changes{v0.1}{2024-3-7}{Initial version.} % % % \pagenumbering{roman} % % \title{\vspace{-30pt}% % {\sffamily\elseries\fontsize{84}{0}\selectfont % \textls[-30]{\typoglogo}} \\[30pt] % \large A \LaTeX{} Package for Micro-Typographic Enhancements} % \author{Ch.~L.~Spiel\footnote{\quarterspace\texttt{cspiel@users.sourceforge.org}}} % \date{\fileversion\qquad \filedate} % \maketitle % \thispagestyle{empty} % % \begin{abstract} % \begin{lastlinecenteredpar} % \hyphenpenalty=5000\noindent % The \packagename{typog} package provides macros and environments to improve % micro-typographic quality. It enables fine-tuning of hyphenation, spacing, font % adjustments, and alignment. Features include control over \TeX's paragraph % justification, customizable spacing, font characteristic adjustments, and specialized % environments for precise paragraph layout and alignment. % \end{lastlinecenteredpar} % \end{abstract} % % % \iffalse %<*title> prologues := 3; truecorners := 1; linecap := butt; string roman_font; roman_font := "pplr8r"; % URW Palladio L - Roman string italic_font; italic_font := "pplri8r"; % URW Palladio L - Italic picture dash_dotted; dash_dotted := dashpattern(on 3 off 3 on 0 off 3); u := 280; font_scale := 20; pair loc[]; loc[1] := .2[origin, (u, 0)]; loc[2] := .5[origin, (u, 0)]; loc[3] := .8[origin, (u, 0)]; pair slant_vector; slant_vector := (63, 150); pair raise_vector[]; raise_vector[0] := (0, 44); raise_vector[1] := (0, 61); raise_vector[2] := (0, 54); raise_vector[3] := (0, 71); picture letter_V; letter_V := thelabel.top("V" infont roman_font scaled font_scale, loc[1]); picture normal_hyphen; normal_hyphen := thelabel.top("-" infont roman_font scaled font_scale, loc[2] + raise_vector[0]); picture raised_hyphen; raised_hyphen := thelabel.top("-" infont roman_font scaled font_scale, loc[2] + raise_vector[1]); picture letter_A; letter_A := thelabel.top("A" infont roman_font scaled font_scale, loc[3]); beginfig(1); draw letter_V; draw normal_hyphen withcolor .9 white; draw raised_hyphen; draw letter_A; pickup pencircle scaled .4pt; draw (loc[1] -- loc[1] + slant_vector) shifted (7, 0) dashed evenly; draw (loc[1] -- loc[1] + slant_vector) shifted (27, 0) dashed evenly; draw (loc[1] -- loc[1] + slant_vector) shifted (80, 0) dashed evenly; draw (loc[3] -- loc[3] + slant_vector) shifted (-68, 0) dashed evenly; draw .35[origin, (u, 0)] + raise_vector[2] -- .8[origin, (u, 0)] + raise_vector[2] dashed dash_dotted withcolor .6white; draw .35[origin, (u, 0)] + raise_vector[3] -- .8[origin, (u, 0)] + raise_vector[3] dashed dash_dotted; endfig; end % % \fi % % \vfill % % \begin{center} % \includegraphics{title-1.eps} % \end{center} % % \vfill % % \begin{lastlinecenteredpar} % \footnotesize % \noindent % This package is copyright \textcopyright~2024, 2025 Ch.~L.~Spiel. It may be distributed % and\kernedslash*or modified under the conditions of the % \href{https://www.latex-project.org/lppl.txt}{\LaTeX{} Project Public License} % \acronym{(LPPL)}, either version~1.3c of this license or\leftspacedendash at your % option\rightspacedendash any later version. This work has the \acronym{LPPL} maintenance % status \doublequotes{author-maintained}. % \end{lastlinecenteredpar} % % % \clearpage % \pagestyle{pagenumberonly} % % \unmarkedfntext{The font sample on the title page was generated with the help of \MP{} using % \doublequotes{\acronym{URW}~Palladio}.% % \detoxindex{font>typeface>URW Palladio=\acronym{URW} Palladio|userman}} % % \begin{nofontexpansion} % \begin{nocharprotrusion} % \tableofcontents % \end{nocharprotrusion} % \end{nofontexpansion} % % \addtocontents{toc}{% % \protect\begin{whittyquote} % Hoffentlich wird es nicht so schlimm, wie es schon ist! \\ % \capitalemdash*~\propername{Karl Valentin} % \protect\end{whittyquote}\par} % % \vspace{\fill} % % \begin{nofontexpansion} % \begin{nocharprotrusion} % \listoftables % \end{nocharprotrusion} % \end{nofontexpansion} % % \vspace{\fill} % % % \clearpage % \pagestyle{fancy} % \phantomsection % \addcontentsline{toc}{section}{\protect\numberline{}Quick Reference} % \addtocontents{toc}{\medskip} % \section*{Quick Reference} % \markboth{\sf\letterspacedsmallcaps{Quick Reference}}{\sf\letterspacedsmallcaps{Quick Reference}} % \index{quick reference|(userman} % % This is an alphabetically sorted list of all user macros and environments defined by % package~\packagename{typog} along with the page numbers of their descriptions. % \marginnote{In the multi-column parts of the Quick Reference, we reduce the line spacing from % 125\% to 120\% with % \hyperref[syn:setbaselineskippercentage]{\cs{set\-base\-line\-skip\-per\-cent\-age}}, and the % inter-word spacing by 1.25\% with \hyperref[syn:tightspacing]{\code{tightspacing}}. List % \cs{item}s get tied with \hyperref[syn:vtietop]{\cs{vtietop}}.}\relax % A list of all \hyperref[sec:package-options]{package options} can be found on % pages~\pageref{sec:package-options} to~\pageref{secend:package-options}. The % \hyperref[sec:index]{Index} on pages~\pageref{sec:index} to~\pageref{secend:index} may % provide some more detailed insights. % % If a line break occurs between the macro and its arguments or between any of the arguments, % we indicate the break with a triangle at the end of the initial line and at the beginning of % the following line. % % \bigskip % % \begin{widebody} % \begin{quickreference} % \item\relax % \hspace{\leftmargin}\heading*{A} % \qritem{syn:Adjustedlabelitem}{\cs{Adjustedlabelitemi}} % Typeset an uppercase-adjusted \cs{label\-itemi}. % \endqritem % % \qritem{syn:adjustedlabelitem}{\cs{adjustedlabelitemi}} % Typeset a lowercase-adjusted \cs{label\-itemi}. % \endqritem % % \qritem{syn:Adjustedlabelitem}{\cs{Adjustedlabelitemii}} % Typeset an uppercase-adjusted \cs{label\-itemii}. % \endqritem % % \qritem{syn:adjustedlabelitem}{\cs{adjustedlabelitemii}} % Typeset a lowercase-adjusted \cs{label\-itemii}. % \endqritem % % \qritem{syn:Adjustedlabelitem}{\cs{Adjustedlabelitemiii}} % Typeset an uppercase-adjusted \cs{label\-itemiii}. % \endqritem % % \qritem{syn:adjustedlabelitem}{\cs{adjustedlabelitemiii}} % Typeset a lowercase-adjusted \cs{label\-itemiii}. % \endqritem % % \qritem{syn:Adjustedlabelitem}{\cs{Adjustedlabelitemiv}} % Typeset an uppercase-adjusted \cs{label\-itemiv}. % \endqritem % % \qritem{syn:adjustedlabelitem}{\cs{adjustedlabelitemiv}} % Typeset a height-adjusted \cs{label\-itemiv}. % \endqritem % % \qritem{syn:allowhyphenation}{\cs{allow\-hyphenation}} % (Re-)enable automatic hyphenation. % \endqritem % % \heading{B} % \qritem{syn:breakabledisplay}{\code{breakable\-display}}[\sigbrk\oarg{level}] % Adjust the penalty associated with \cs{allowdisplaybreaks}. % \endqritem % % \qritem{syn:breakpoint}{\cs{breakpoint*}} % Insert an empty discretionary. % \endqritem % % \qritem{syn:breakpoint}{\cs{breakpoint}} % Insert an empty discretionary and re-enable automatic hyphenation. % \endqritem % % \heading{C} % \qritem{syn:capitaldash}{\cs{capitaldash*}} % Alias for \cs{capitalendash*}. % \endqritem % % \qritem{syn:capitaldash}{\cs{capitaldash}} % Alias for \cs{capitalendash}. % \endqritem % % \qritem{syn:capitalemdash}{\cs{capitalemdash*}} % Typeset a vertically adjusted \cs{textemdash}. % \endqritem % % \qritem{syn:capitalemdash}{\cs{capitalemdash}} % Typeset a vertically adjusted \cs{textemdash} that is breakable. % \endqritem % % \qritem{syn:capitalendash}{\cs{capitalendash*}} % Typeset a vertically adjusted \cs{textendash}. % \endqritem % % \qritem{syn:capitalendash}{\cs{capitalendash}} % Typeset a vertically adjusted \cs{textendash} that is breakable. % \endqritem % % \qritem{syn:capitalhyphen}{\cs{capitalhyphen*}} % Typeset a vertically adjusted hyphen character. % \endqritem % % \qritem{syn:capitalhyphen}{\cs{capitalhyphen}} % Typeset a vertically adjusted hyphen character that is breakable. % \endqritem % % \qritem{syn:capitalinvertedexclamationmark}{\cs{capital\-inverted\-exclamation\-mark}} % [\sigbrk\marg{number}] % Typeset an inverted (\singlequotes{upside-down}) exclamation mark that is level with % the baseline. % \endqritem % % \qritem{syn:capitalinvertedquestionmark}{\cs{capital\-inverted\-question\-mark}} % [\sigbrk\marg{number}] % Typeset an inverted (\singlequotes{upside-down}) question mark that is level with the % baseline. % \endqritem % % \qritem{syn:capitaltimes}{\cs{capitaltimes}} % Typeset a vertically adjusted \cs{texttimes}. % \endqritem % % \qritem{syn:covernextindentpar}{\code{cover\-next\-indent\-par}}[\sigbrk\oarg{dim}] % Extend the last line of a paragraph. % \endqritem % % \heading{D} % \qritem{syn:Doubleguillemetleft}{\cs{Double\-guillemet\-left}} % Typeset left double guillemets vertically adjusted for uppercase. % \endqritem % % \qritem{syn:Doubleguillemetright}{\cs{Double\-guillemet\-right}} % Typeset right double guillemets vertically adjusted for uppercase. % \endqritem % % \qritem{syn:doubleguillemetleft}{\cs{double\-guillemet\-left}} % Typeset left double guillemets vertically adjusted for lowercase. % \endqritem % % \qritem{syn:doubleguillemetright}{\cs{double\-guillemet\-right}} % Typeset right double guillemets vertically adjusted for lowercase. % \endqritem % % \heading{F} % \qritem{syn:figuredash}{\cs{figuredash*}} % Typeset a \cs{textendash} vertically adjusted for figures (numerals). % \endqritem % % \qritem{syn:figuredash}{\cs{figuredash}} % Typeset a breakable \cs{textendash} vertically adjusted for figures (numerals). % \endqritem % % \qritem{syn:fontsizeinfo}{\cs{fontsize\-info}}[\sigbrk\marg{csname}] % Store the current em-heigh and \cs{baselineskip} in a pair of macros. % \endqritem % % \heading{H} % \qritem{syn:hyphenmin}{\code{hyphenmin}}[\sigbrk\oarg{left-min}\sigbrk\marg{right-min}] % Set the values of \cs{lefthyphenmin} and \cs{righthyphenmin}. % \endqritem % % \heading{I} % \qritem{syn:itcorr}{\cs{itcorr*}}[\sigbrk\marg{strength}] % Apply italic correction in the form of a \cs{kern} scaled by % \code{textitaliccorrection}. % \endqritem % % \qritem{syn:itcorr}{\cs{itcorr}}[\sigbrk\marg{strength}] % Apply italic correction in the form of a \cs{kern} scaled by % \cs{fontdim1} or \code{textitaliccorrection}. % \endqritem % % \heading{K} % \qritem{syn:kernedhyphen}{\cs{kernedhyphen*}} % [\sigbrk\oarg{raise}\sigbrk\marg{left-kern}\sigbrk\marg{right-kern}] % Typeset an unbreakable hyphen and apply kerning to its left and right. % \endqritem % % \qritem{syn:kernedhyphen}{\cs{kernedhyphen}} % [\sigbrk\oarg{raise}\sigbrk\marg{left-kern}\sigbrk\marg{right-kern}] % Typeset a breakable hyphen and apply kerning to its left and right. % \endqritem % % \qritem{syn:kernedslash}{\cs{kernedslash*}} % Typeset an unbreakable forward slash and apply kerning to both its left and right % sides. % \endqritem % % \qritem{syn:kernedslash}{\cs{kernedslash}} % Typeset a breakable forward slash and apply kerning to both its left and right sides. % \endqritem % % \heading{L} % \qritem{syn:lastlinecenteredpar}{\code{last\-line\-centered\-par}} % Center the last lines of a paragraph. % \endqritem % % \qritem{syn:lastlinefitpar}{\code{last\-line\-fit\-par}} % Match the spacing of last line and next-to-last line. % \endqritem % % \qritem{syn:lastlineflushrightpar}{\code{last\-line\-flush\-right\-par}} % Alias for \code{lastlineraggedleftpar}. % \endqritem % % \qritem{syn:lastlineraggedleftpar}{\code{last\-line\-ragged\-left\-par}} % Align the last line of paragraph flush right. % \endqritem % % \qritem{syn:leftkernedhyphen}{\cs{left\-kerned\-hyphen*}} % [\sigbrk\oarg{raise}\sigbrk\marg{left-kern}] % Typeset a hyphen and apply kerning to its left-hand side. % \endqritem % % \qritem{syn:leftkernedhyphen}{\cs{left\-kerned\-hyphen}} % [\sigbrk\oarg{raise}\sigbrk\marg{left-kern}] % Typeset a hyphen, apply kerning to its left-hand side, and insert a breakpoint after % it. % \endqritem % % \qritem{syn:spacedendash}{\cs{left\-spaced\-dash*}}[\sigbrk\oarg{raise}] % Alias for \cs{left\-spaced\-endash*}. % % \qritem{syn:spacedemdash}{\cs{left\-spaced\-dash}}[\sigbrk\oarg{raise}] % Alias for \cs{left\-spaced\-emdash}. % % \qritem{syn:spacedemdash}{\cs{left\-spaced\-emdash*}}[\sigbrk\oarg{raise}] % Typeset an em-dash with some space around it. Prohibit line breaks before and after % it. % % \qritem{syn:spacedemdash}{\cs{left\-spaced\-emdash}}[\sigbrk\oarg{raise}] % Typeset an em-dash with some space around it. Allow line breaks at its left-hand side. % % \qritem{syn:spacedendash}{\cs{left\-spaced\-endash*}}[\sigbrk\oarg{raise}] % Typeset an en-dash with some space around it. Prohibit line breaks before and after % it. % % \qritem{syn:spacedendash}{\cs{left\-spaced\-endash}}[\sigbrk\oarg{raise}] % Typeset an en-dash with some space around it. Allow line breaks at its left-hand side. % % \qritem{syn:loosespacing}{\code{loose\-spacing}}[\sigbrk\oarg{level}] % Increase the width of the space character. % \endqritem % % \qritem{syn:lowercaseadjustlabelitems}{\cs{lowercase\-adjust\-label\-items}} % [\sigbrk\marg{levels}] % Activate the lowercase height-adjustment values inside \code{itemize}~environments. % \endqritem % % \heading{N} % \qritem{syn:narrowspace}{\cs{narrowspace*}} % Typeset a narrow space whose width depends on \cs{fontdimen7}. % \endqritem % % \qritem{syn:narrowspace}{\cs{narrowspace}} % Typeset a narrow space whose width depends on \cs{fontdimen7} or \cs{fontdimen2}. % \endqritem % % \qritem{syn:noadjustlabelitems}{\cs{no\-adjust\-label\-items}} % [\sigbrk\marg{levels}] % Deactivate height-adjustment of label items. % \endqritem % % \qritem{syn:nocharprotrusion}{\code{nocharprotrusion}} % Deactivate character protrusion. % \endqritem % % \qritem{syn:nofontexpansion}{\code{nofontexpand}} % Alias for \code{nofontexpansion}. % \endqritem % % \qritem{syn:nofontexpansion}{\code{nofontexpansion}} % Deactivate font expansion. % \endqritem % % \qritem{syn:nolig}{\cs{nolig*}}[\oarg{kerning}] % Break a ligature. % \endqritem % % \qritem{syn:nolig}{\cs{nolig}}[\oarg{kerning}] % Break a ligature and introduce a hyphenation opportunity. % \endqritem % % \heading{O} % \qritem{syn:openlastlinepar}{\code{openlastlinepar}}[\sigbrk\oarg{dim}] % Open a paragraph's last line if it is almost full or completely filled. % \endqritem % % \heading{P} % \qritem{syn:prolongpar}{\code{prolongpar}} % Increase the \cs{looseness} of a paragraph. % \endqritem % % \heading{R} % \qritem{syn:resetbaselineskip}{\cs{reset\-baseline\-skip}} % Reset \cs{baselineskip} to its original value. % \endqritem % % \qritem{syn:rightkernedhyphen}{\cs{right\-kerned\-hyphen*}} % [\sigbrk\oarg{raise}\sigbrk\marg{right-kern}] % Typeset a hyphen and apply kerning to its right-hand side. % \endqritem % % \qritem{syn:rightkernedhyphen}{\cs{right\-kerned\-hyphen}} % [\sigbrk\oarg{raise}\sigbrk\marg{right-kern}] % Typeset a hyphen, apply kerning to its right-hand side, and insert a breakpoint after % it. % \endqritem % % \qritem{syn:spacedendash}{\cs{right\-spaced\-dash*}}[\sigbrk\oarg{raise}] % Alias for \cs{right\-spaced\-endash*}. % % \qritem{syn:spacedendash}{\cs{right\-spaced\-dash}}[\sigbrk\oarg{raise}] % Alias for \cs{right\-spaced\-endash}. % % \qritem{syn:spacedemdash}{\cs{right\-spaced\-emdash*}}[\sigbrk\oarg{raise}] % Typeset an em-dash with some space around it. Prohibit line breaks before and after % it. % % \qritem{syn:spacedemdash}{\cs{right\-spaced\-emdash}}[\sigbrk\oarg{raise}] % Typeset an em-dash with some space around it. Allow line breaks at its right-hand % side. % % \qritem{syn:spacedendash}{\cs{right\-spaced\-endash*}}[\sigbrk\oarg{raise}] % Typeset an en-dash with some space around it. Prohibit line breaks before and after % it. % % \qritem{syn:spacedendash}{\cs{right\-spaced\-endash}}[\sigbrk\oarg{raise}] % Typeset an en-dash with some space around it. Allow line breaks at its right-hand % side. % % \heading{S} % \qritem{syn:setbaselineskippercentage}{\cs{set\-baseline\-skip\-percentage}} % [\sigbrk\marg{percentage}] % Set \cs{baselineskip} as a percentage relative to the point size of the font. % \endqritem % % \qritem{syn:setbaselineskip}{\cs{set\-baseline\-skip}}[\sigbrk\marg{baselineskip}] % Set \cs{baselineskip} using an absolute length. % \endqritem % % \qritem{syn:setfontexpand}{\code{setfontexpand}}[\sigbrk\oarg{level}] % Simultaneously set font stretch and shrink limits. % \endqritem % % \qritem{syn:setfontshrink}{\code{setfontshrink}}[\sigbrk\oarg{level}] % Set font shrink limits. % \endqritem % % \qritem{syn:setfontstretch}{\code{setfontstretch}}[\sigbrk\oarg{level}] % Set font stretch limits. % \endqritem % % \qritem{syn:setfonttracking}{\code{setfonttracking}}[\sigbrk\marg{delta}] % Override the default tracking for all fonts. % \endqritem % % \qritem{syn:setleadingpercentage}{\cs{set\-leading\-percentage}} % [\sigbrk\marg{percentage}] % Set \cs{baselineskip} as a percentage using the leading. % \endqritem % % \qritem{syn:setleading}{\cs{setleading}}[\sigbrk\marg{leading}] % Set \cs{baselineskip} using the leading. % \endqritem % % \qritem{syn:shortenpar}{\code{shortenpar}} % Decrease the \cs{looseness} of a paragraph. % \endqritem % % \qritem{syn:Singleguillemetleft}{\cs{Single\-guillemet\-left}} % Typeset left single guillemets vertically adjusted for uppercase. % \endqritem % % \qritem{syn:Singleguillemetright}{\cs{Single\-guillemet\-right}} % Typeset right single guillemets vertically adjusted for uppercase. % \endqritem % % \qritem{syn:singleguillemetleft}{\cs{single\-guillemet\-left}} % Typeset left single guillemets vertically adjusted for lowercase. % \endqritem % % \qritem{syn:singleguillemetright}{\cs{single\-guillemet\-right}} % Typeset right single guillemets vertically adjusted for lowercase. % \endqritem % % \qritem{syn:slightlysloppypar}{\code{slightly\-sloppy\-par}}[\sigbrk\oarg{sloppiness}] % Format a paragraph with given sloppiness. % \endqritem % % \qritem{syn:slightlysloppy}{\cs{slightlysloppy}}[\sigbrk\oarg{sloppiness}] % Format using the given sloppiness. % \endqritem % % \qritem{syn:smoothraggedright}{\code{smoothraggedright}}[{[\meta{option}\dots]}] % Format with one of the three smooth-ragged-right generators. % \endqritem % % \qritem{syn:smoothraggedrightfuzzfactor}{\cs{smooth\-ragged\-right\-fuzz\-factor}}[\marg{factor}] % Relative amount of glue in smooth-ragged-right typeset lines. % \endqritem % % \qritem{syn:smoothraggedrightgenerator}{\cs{smooth\-ragged\-right\-generator}}[\marg{generator}] % Name of the basis environment (\singlequotes{generator}) used in the environments % \code{smooth\-ragged\-right} and \code{smooth\-ragged\-right\-par}. % \endqritem % % \qritem{syn:smoothraggedrightleftskip}{\cs{smooth\-ragged\-right\-left\-skip}} % Value for \code{leftskip} that \code{smooth\-ragged\-right} and % \code{smooth\-ragged\-right\-par} pass to the smooth-ragged-right generator. % \endqritem % % \qritem{syn:smoothraggedrightpar}{\code{smoothraggedrightpar}}[{[\meta{option}\dots]}] % Format a paragraph using one of the three smooth-ragged-right generators. % \endqritem % % \qritem{syn:smoothraggedrightparindent}{\cs{smooth\-ragged\-right\-par\-indent}} % Value for \code{parindent} that \code{smooth\-ragged\-right} and % \code{smooth\-ragged\-right\-par} pass to the smooth-ragged-right generator. % \endqritem % % \qritem{syn:smoothraggedrightragwidth}{\cs{smooth\-ragged\-right\-rag\-width}} % Value for the width of the smooth-ragged-right margin in environments % \code{smooth\-ragged\-right} and \code{smooth\-ragged\-right\-par}. % \endqritem % % % \suspendmulticols % % % \qritem{syn:smoothraggedrightshapequintuplet}{\code{smoothraggedrightshapequintuplet}} % [{[\meta{option}\dots]}\marg{width1}\dots\marg{width5}] % Prescribe five line lengths for formatting paragraphs. % \endqritem % % \qritem{syn:smoothraggedrightshapeseptuplet}{\code{smoothraggedrightshapeseptuplet}} % [{[\meta{option}\dots]}\marg{width1}\dots\marg{width7}] % Prescribe seven line lengths for formatting paragraphs. % \endqritem % % \qritem{syn:smoothraggedrightshapetriplet}{\code{smoothraggedrightshapetriplet}} % [{[\meta{option}\dots]}\marg{width1}\marg{width2}\marg{width3}] % Prescribe three line lengths for formatting paragraphs. % \endqritem % % % \resumemulticols % % % \qritem{syn:spacedcapitalemdash}{\cs{spacedcapitalemdash*}} % Typeset a height-adjusted em-dash with some space around it. Prohibit line breaks % before and after the dash. % \endqritem % % \qritem{syn:spacedcapitalemdash}{\cs{spacedcapitalemdash}} % Typeset a height-adjusted em-dash with some space around it. % \endqritem % % \qritem{syn:spacedcapitalendash}{\cs{spacedcapitalendash*}} % Typeset a height-adjusted en-dash with some space around it. Prohibit line breaks % before and after the dash. % \endqritem % % \qritem{syn:spacedcapitalendash}{\cs{spacedcapitalendash}} % Typeset a height-adjusted em-dash with some space around it. % \endqritem % % \qritem{syn:spacedendash}{\cs{spaceddash*}}[\oarg{raise}] % Alias for \cs{rightspacedendash*}. % \endqritem % % \qritem{syn:spacedendash}{\cs{spaceddash}}[\oarg{raise}] % Alias for \cs{rightspacedendash}. % \endqritem % % \qritem{syn:spacedemdash}{\cs{spacedemdash*}}[\oarg{raise}] % Alias for \cs{rightspacedemdash*}. % \endqritem % % \qritem{syn:spacedemdash}{\cs{spacedemdash}}[\oarg{raise}] % Alias for \cs{rightspacedemdash}. % \endqritem % % \qritem{syn:spacedendash}{\cs{spacedendash*}}[\oarg{raise}] % Alias for \cs{rightspacedendash*}. % \endqritem % % \qritem{syn:spacedendash}{\cs{spacedendash}}[\oarg{raise}] % Alias for \cs{rightspacedendash}. % \endqritem % % \qritem{syn:splicevtietop}{\cs{splicevtietop}}[\sigbrk\marg{lines}] % Inside of a \code{list}-like environment, fuse the first lines. % \endqritem % % \heading{T} % \qritem{syn:tightspacing}{\code{tightspacing}}[\sigbrk\oarg{level}] % Decrease the width of the space character. % \endqritem % % \qritem{syn:typogadjuststairs}{\cs{typog\-adjust\-stairs}} % [\sigbrk\oarg{factor}\sigbrk\marg{step}\sigbrk\marg{count}\sigbrk\marg{sample}] % Generate \singlequotes{stairs} of vertically shifted label items. % \endqritem % % \qritem{syn:typogfontsize}{\cs{typogfontsize}} % The default font's quad size. % \endqritem % % \qritem{syn:typoggetnth}{\cs{typoggetnth}} % [\sigbrk\marg{dest}\sigbrk\marg{key}\sigbrk\marg{index}] % Retrieve single item of a \packagename{typog} compound configuration value. % \endqritem % % \qritem{syn:typogget}{\cs{typogget}}[\sigbrk\marg{key}] % Retrieve a \packagename{typog} configuration value. % \endqritem % % \qritem{syn:typoginspectpar}{\code{typoginspectpar}}[\sigbrk\oarg{option}\sigbrk\marg{id}] % Turn on tracing of paragraphs and pages for a paragraph. % \endqritem % % \qritem{syn:typoginspect}{\code{typoginspect}}[\sigbrk\oarg{option}\sigbrk\marg{id}] % Turn on tracing of paragraphs and pages. % \endqritem % % \qritem{syn:typoglowercaseadjustcheck}{\cs{typog\-lowercase\-adjust\-check}} % [\sigbrk\oarg{factor}\sigbrk\marg{sample}] % Typeset all four label items adjusted for lowercase with an indicator line. % \endqritem % % \qritem{syn:typogsetup}{\code{typogsetup}}[\sigbrk\marg{keys}] % Configure package \packagename{typog}. % \endqritem % % \qritem{syn:typoguppercaseadjustcheck}{\cs{typog\-uppercase\-adjust\-check}} % [\sigbrk\oarg{factor}\sigbrk\marg{sample}] % Typeset all four label items adjusted for uppercase with an indicator line. % \endqritem % % \heading{U} % \qritem{syn:uppercaseadjustlabelitems}{\cs{uppercase\-adjust\-label\-items}} % [\sigbrk\marg{levels}] % Activate the uppercase height-adjustment values inside \code{itemize}~environments. % \endqritem % % \heading{V} % \qritem{syn:vtiebotdisptoppar}{\code{vtie\-bot\-disp\-top\-par}} % [\sigbrk\oarg{num-before-lines}\sigbrk\oarg{num-after-lines}] % Fuse a display with its preceding and following lines. % \endqritem % % \qritem{syn:vtiebotdisp}{\code{vtiebotdisp}}[\sigbrk\oarg{num-lines}] % Fuse a display with its preceding lines. % \endqritem % % \qritem{syn:vtiebotpar}{\code{vtiebotpar}}[\sigbrk\oarg{num-lines}] % Fuse the final lines of a paragraph. % \endqritem % % \qritem{syn:vtiebot}{\cs{vtiebot}}[\sigbrk\oarg{num-lines}] % Fuse final lines. % \endqritem % % \qritem{syn:vtietoppar}{\code{vtietoppar}}[\sigbrk\oarg{num-lines}] % Fuse the first lines of a paragraph. % \endqritem % % \qritem{syn:vtietop}{\code{vtietop}}[\sigbrk\oarg{num-lines}] % Fuse first lines. % \endqritem % % \qritem{syn:vtietop}{\cs{vtietop}}[\sigbrk\oarg{num-lines}] % Fuse first lines. % \endqritem % % \heading{W} % \qritem{syn:widespace}{\cs{widespace*}} % Typeset a wide space whose width depends on \cs{fontdimen7}. % \endqritem % % \qritem{syn:widespace}{\cs{widespace}} % Typeset a wide space whose width depends on \cs{fontdimen7} or \cs{fontdimen2}. % \endqritem % \end{quickreference} % \sectionfinish % \end{widebody} % \index{quick reference|)userman} % % % \clearpage % \pagestyle{fancy} % \pagenumbering{arabic} % \section{Introduction}\label{sec:introduction} % % \begin{whittyquote} % \doublequotes{Good typography} is the minimum acceptable solution; \\ % \doublequotes{fine typography} is what we aspire to. \\ % \capitalemdash*~\propername{Ilene Strizver} % \end{whittyquote} % % \noindent % \LaTeX{} is the beginning of good typesetting\spacedemdash not the end. This package % provides some tools for even better looking documents. When applied correctly, its effects % appear subtle and inconspicuous. However, it's a long ball game. % % % \subsection{Overview}\label{sec:overview} % % The primary focus of \packagename{typog} are micro-typographic improvements, where it tries % to hit it out of the ballpark in terms of typographic polish. % % \Cref{sec:setup} presents how to reconfigure package~\packagename{typog} after it has been % loaded and how to access its configuration values for introspection or inclusion in the % user's own code. \Cref{sec:information} addresses the need for more information in the % typesetting process whether during the draft phase or in the final printed % manuscript.\marginnote{Throughout the whole document we indicate actual uses of the package's % macros and environments in the margin. All these notes are examples themselves, as they are % typeset using \hyperref[syn:slightlysloppy]{\code{slightlysloppy}}, % \hyperref[syn:loosespacing]{\code{loosespacing}}, and % \hyperref[syn:smoothraggedrightpar]{\code{smoothraggedrightpar}}.\visualpar The title page % has already demonstrated the effect of % \hyperref[syn:lastlinecenteredpar]{\code{lastlinecenteredpar}} in justified paragraphs for % the abstract and the copyright notice.} \Cref{sec:latex-hyphenation} expands the hyphenation % facilities of \LaTeX. \Cref{sec:break-ligatures,sec:manual-italic-correction} treat the % breaking of ligatures and the manual application of italic correction\spacedemdash in a % generalized way. \Cref{sec:extra-kerning} introduces macros to kern or space some % punctuation signs. \Cref{sec:raise-characters} deals with vertically positioning glyphs in a % more visually pleasing manner. \Cref{sec:adjust-label-items} also deals with vertical % alignment and explains how to height-adjust the labels in |itemize|~lists to perfection, % whether the items are followed by uppercase or by lowercase letters. % \Cref{sec:align-last-line,sec:fill-last-line} discuss much-needed macros for better control % of the last line of a paragraph. \Cref{sec:spacing-control} covers the manipulation of % paragraph spacing. \Cref{sec:microtype-frontend} details the \packagename{microtype} % front end: font tracking~(\ref{sec:tracking-control}), font % expansion~(\ref{sec:font-expansion-control}), and character % protrusion~(\ref{sec:protrusion}). In \cref{sec:sloppy-paragraphs}, we address some % shortcomings of spacing control with a replacement for the macro~\cs{sloppy} and the related % environment~\code{sloppypar}. \Cref{sec:vtie-paragraph} presents several specialized % functions to avoid club or widow lines in a paragraph. As a simple extension of displayed % mathematical equations, we define a breakable variant in \cref{sec:breakable-display}. % \Cref{sec:setspace-frontend} introduces the \packagename{setspace} front end. In the last % part, \cref{sec:smooth-ragged}, we introduce a novel way of generating ragged paragraphs, % which is still experimental. % % % \subsection{Prerequisites}\label{sec:packageprerequisites} % % Package \packagename{typog} requires \eTeX; it relies on the \LaTeXIII{}~interface. Parts of % it are based on packages \packagename{microtype}~\cite{package:microtype} and % \packagename{setspace}~\cite{package:setspace}. However, if the functionality is not used, % \packagename{typog} can be used without \packagename{microtype}. The same holds true for the % \packagename{setspace} front end. % % The package was tested with % \programname{pdfTeX}~3.141592653\capitalhyphen*2.6\capitalhyphen*1.40.24 from the TeX~Live % distribution of~2022, as shipped by % \href{https://packages.debian.org/search?keywords=texlive}{Debian}. % % % \sectionfinish % \clearpage % \section{Package Options}\label{sec:package-options} % \index{package option|(usermandef} % % The \packagename{typog} package is loaded as usual via \cs{usepackage}. It can be configured % during loading with package \meta{OPTIONs} or later on with % \hyperref[syn:typogsetup]{\code{typogsetup}}, as described in \cref{sec:setup}. Since % \packagename{typog} provides front ends to packages~\packagename{microtype} and % \packagename{setspace}, we mention them in the synopsis; they are \emph{not} automatically % loaded by \packagename{typog}. % % \begin{synopsis} % \begin{tabbing} % |\usepackage[|\,\ttdots|]{microtype}| % \=\texttt{\%\space}\textit{Only required for macros and} \\ % \>\texttt{\%\space}\textit{environments in \cref{sec:microtype-frontend}.} \\ % \\[-.5em] % |\usepackage[|\,\ttdots|]{setspace}| % \=\texttt{\%\space}\textit{Only required for macros in \cref{sec:setspace-frontend}.} \\ % \\[-.5em] % |\usepackage[|\meta{OPTION}\ttdots|]{typog}| % \end{tabbing} % \end{synopsis} % % The package \meta{OPTIONs} also serve as configuration \meta{key}s unless noted otherwise. % This means, they can be set with \hyperref[syn:typogsetup]{\code{typogsetup}} and their % values can be retrieved with \hyperref[syn:typogget]{\cs{typogget}}. Options that rely on % package~\packagename{microtype} are indicated with \doublequotes{\microtyperequiredmarker}. % % \begin{typogsetup}{} % \begin{description} % [before={\let\oldmakelabel=\makelabel % \renewcommand{\makelabel}[1] % {\oldmakelabel{\termparbox{##1}}\phantomsection}}, % font=\normalfont, % style=nextline, % vtietop] % \item[|breakpenalty=|\meta{penalty}]\label{item:breakpenalty} % \indexpackageoptiondefinition{breakpenalty} % \shiftedmarginnote{This subsection is typeset with all \packagename{typog}~parameters % reset to their defaults by wrapping it in a % \hyperref[syn:typogsetup]{\code{typogsetup}}~environment with an empty argument.} % Penalty for a line break at various points. Default value: % \the\typogget{breakpenalty}, initialized by the current \cs{exhyphenpenalty}: % \the\exhyphenpenalty. % % \item[|debug|, |nodebug|]\label{item:debug} % \indexpackageoptiondefinition{debug} % \indexpackageoptiondefinition{nodebug} % Write some package-specific debug information to the \filesystem{log}~file. Opposite: % |nodebug|. The default is not to record debug information. % % These two options cannot be used with \hyperref[syn:typogsetup]{\code{typogsetup}} or % \hyperref[syn:typogget]{\cs{typogget}}. % % \item[|emdashspace|=\meta{glue}]\label{item:emdashspace} % \indexpackageoptiondefinition{emdashspace} % \sinceversion{Since v0.5} % Set the horizontal skip that is inserted before and after the em-dash in % macros~\hyperref[syn:spacedemdash]{\cs{spacedemdash}} and % \hyperref[syn:spacedcapitalemdash]{\cs{spacedcapitalemdash}} to \meta{glue}. Default % value: \milliemglue{\typogget{emdashspace}}. % % \item[|endashspace|=\meta{glue}]\label{item:endashspace} % \indexpackageoptiondefinition{endashspace} % \sinceversion{Since v0.5} % Set the horizontal skip that is inserted before and after the en-dash in % macros~\hyperref[syn:spacedendash]{\cs{spacedendash}} and % \hyperref[syn:spacedcapitalendash]{\cs{spacedcapitalendash}} to \meta{glue}. Default % value: \milliemglue{\typogget{endashspace}}. % % \item[|ligaturekern=|\meta{dim}]\label{item:ligaturekern} % \indexpackageoptiondefinition{ligaturekern} % Set \meta{dim} of the kern that is inserted to split a ligature in % macro~\hyperref[syn:nolig]{\cs{nolig}}. See \cref{sec:break-ligatures}. Default % value: \milliem{\typogget{ligaturekern}}. % % \item[|lowercaselabelitemadjustments=\{|\meta{dim-1}, \dots, \meta{dim-4}|\}|]% % \label{item:lowercaselabelitemadjustments} % \indexpackageoptiondefinition{lowercase\-labelitem\-adjustments} % \sinceversion{Since v0.4} % Vertical shifts \meta{dim-N} to apply to \cs{labelitem}\meta{N}, where \meta{N}= 1, 2, 3, % or~4 is the nesting level of the |itemize|~list. Empty list elements are ignored. The % special value~\samplestar{} instructs \packagename{typog} to preserve \meta{dim-N} at % that position. The adjustments apply to the lowercase setting % (\hyperref[syn:lowercaseadjustlabelitems]{\code{\string\lowercaseadjustlabelitems}}). % See \cref{sec:adjust-label-items} (in particular subsection~\singlequotes{Setup} and % \cref{tab:labelitemadjustvalues} on \cpageref{tab:labelitemadjustvalues}) and also % configuration option % \hyperref[item:uppercaselabelitemadjustments]{\code{uppercaseadjustlabelitem}}. % % All four lengths default to \formatdimen*{0pt}. % % \begin{important} % \slightlysloppy % \noindent % Configuring \code{lowercaselabelitemadjustments} (or % \code{uppercaselabelitemadjustments}) does \emph{not} activate the correction % mechanism. Use one of the macros \code{\string\lowercaseadjustlabelitems} or % \code{\string\uppercaseadjustlabelitems} for that purpose. % \end{important} % % \item[|lowerslash=|\meta{dim}]\label{item:lowerslash} % \indexpackageoptiondefinition{lowerslash} % \sinceversion{Since v0.5} % Lower the slash typeset by \hyperref[syn:kernedslash]{\cs{kernedslash}}. Positive % lengths~\meta{dim} \emph{lower} the glyph, negative ones raise it. This is the opposite % \singlequotes{direction} of \cs{raisebox}. See \cref{sec:slash-with-kern}. Default % value: \milliem{\typogget{lowerslash}}. % % \item[|mathitaliccorrection=|\meta{dim}]\label{item:mathitaliccorrection} % \indexpackageoptiondefinition{mathitaliccorrection} % \sinceversion{Renamed in v0.5} % Italic correction in math mode. See \cref{sec:manual-italic-correction} and also the % complementary configuration % option~\hyperref[item:textitaliccorrection]{|textitaliccorrection|}. Default % value: \the\typogget{mathitaliccorrection}.\!\footnote{Note that 1\,mu is % \nativetextfraction{1}{18}\,em of the mathematical font's~em.} % % \item[|raise*=|\meta{dim}]\label{item:raise} % \indexpackageoptiondefinition{raise*} % Set the length by which selected characters (dash, hyphen, times, and number dash) are % raised. Default value: \formatdimen*{0pt}.\shiftedmarginnote{We access all the (default) % configuration values with \hyperref[syn:typogget]{\cs{typogget}}.} % % Only the raise amounts for guillemets and inverted marks are unaffected by this option. % % This option neither can be used with \hyperref[syn:typogsetup]{\code{typogsetup}} nor % with \hyperref[syn:typogget]{\cs{typogget}}; however, the specific options influenced by % it can. % % \item[|raisecapitaldash=|\meta{dim}]\label{item:raisecapitaldash} % \indexpackageoptiondefinition{raisecapitaldash} % Set the length that the \cs{textendash} is raised in % \hyperref[syn:capitaldash]{\cs{capitaldash}}. See \cref{sec:capital-dash}. Default % value: \milliem{\the\typogget{raisecapitaldash}}. % % \item[|raisecapitalguillemets=|\meta{dim}]\label{item:raisecapitalguillemets} % \indexpackageoptiondefinition{raisecapitalguillemets} % Set the length that single and double guillemets are raised in the uppercase versions of % the guillemet macros. See \cref{sec:guillemets}. Default % value: \milliem{\the\typogget{raisecapitalguillemets}}. % % \item[|raisecapitalhyphen=|\meta{dim}]\label{item:raisecapitalhyphen} % \indexpackageoptiondefinition{raisecapitalhyphen} % Set the length that the hyphen character~\sample{-} is raised in % \hyperref[syn:capitalhyphen]{\cs{capitalhyphen}}. See \cref{sec:capital-hyphen}. % Default value: \milliem{\the\typogget{raisecapitalhyphen}}. % % \item[|raisecapitaltimes=|\meta{dim}]\label{item:raisecapitaltimes} % \indexpackageoptiondefinition{raisecapitaltimes} % Set the length that the multiplication symbol~\sample{\texttimes} is raised in % \hyperref[syn:capitaltimes]{\cs{capitaltimes}}. See \cref{sec:mult-sign}. Default % value: \milliem{\the\typogget{raisecapitaltimes}}. % % \item[|raisefiguredash=|\meta{dim}]\label{item:raisefiguredash} % \indexpackageoptiondefinition{raisefiguredash} % Set the length that the \cs{textendash} is raised in % \hyperref[syn:figuredash]{\cs{figuredash}}. See \cref{sec:number-dash}. Default % value: \milliem{\the\typogget{raisefiguredash}}. % % \item[|raiseguillemets=|\meta{dim}]\label{item:raiseguillemets} % \indexpackageoptiondefinition{raiseguillemets} % Set the length that single and double guillemets are raised in the lowercase versions of % the guillemet macros. See \cref{sec:guillemets}. Default % value: \milliem{\the\typogget{raiseguillemets}}. % % \item[|raiseinvertedmarks=\{|\meta{dim-1}, \meta{dim-2}, \meta{dim-3}|\}|]\label{item:raiseinvertedmarks} % \indexpackageoptiondefinition{raiseinvertedmarks} % \sinceversion{Since v0.5} % Set the lengths by which the macros % \hyperref[syn:capitalinvertedexclamationmark]{\cs{capitalinvertedexclamationmark}} and % \hyperref[syn:capitalinvertedquestionmark]{\cs{capitalinvertedquestionmark}} raise their % associated inverted exclamation marks and inverted question marks. Each dimension % corresponds to the optional indices of the macros. See \cref{sec:inverted-marks}. % % A \meta{dim-N} of \formatdimen*{0pt} means to \doublequotes{auto level} the mark; if a % \mbox{(quasi-)}\breakpoint zero manual correction is desired, use, for example, 1\,sp. % Empty list elements are ignored. The special value~\samplestar{} instructs % \packagename{typog} to preserve \meta{dim-N} at that position. Default values: % \typoggetnth{\dimen0}{raiseinvertedmarks}{1}\milliem{\the\dimen0}, % \typoggetnth{\dimen0}{raiseinvertedmarks}{2}\milliem{\the\dimen0}, % \typoggetnth{\dimen0}{raiseinvertedmarks}{3}\milliem{\the\dimen0}. % % \item[|shrinklimits=\{|\meta{limit-1}, \meta{limit-2}, \meta{limit-3}|\}|\quad\microtyperequiredmarker\label{item:shrinklimits} \\ % |stretchlimits=\{|\meta{limit-1}, \meta{limit-2}, \meta{limit-3}|\}|\quad\microtyperequiredmarker]\label{item:stretchlimits} % \indexpackageoptiondefinition{shrinklimits} % \indexpackageoptiondefinition{stretchlimits} % Set the three limits, given in \nativetextfraction{1}{1000}\,em, of shrinkability and % stretchability for the levels. They are used in % \hyperref[syn:setfontshrink]{\code{setfontshrink}} (|shrinklimits| only), % \hyperref[syn:setfontstretch]{\code{setfontstretch}} (|stretchlimits| only), and % \hyperref[syn:setfontexpand]{\code{setfontexpand}} (both sets). See % \cref{sec:font-expansion-control}. % % New \meta{limit-\#} values replace old ones. If one or more limits of the triple should % remain unchanged pass a \samplestar{} instead of a number. % % \makeatletter % Defaults for |shrinklimits| are \mbox{\typog@default@shrink@i, \typog@default@shrink@ii, % \typog@default@shrink@iii} and those for |stretchlimits| are % \mbox{\typog@default@stretch@i, \typog@default@stretch@ii, \typog@default@stretch@iii}. % \makeatother % % Both options can be used when loading the package and in the document preamble, but % \emph{not} in the document body. % % \item[|slashkern=|\meta{dim}]\label{item:slashkern} % \indexpackageoptiondefinition{slashkern} % Set the size of the kerns before and after \hyperref[syn:kernedslash]{\cs{kernedslash}}. % See \cref{sec:slash-with-kern}. Default value: \milliem{\typogget{slashkern}}. % % \item[|textitaliccorrection=|\meta{dim}]\label{item:textitaliccorrection} % \indexpackageoptiondefinition{textitaliccorrection} % \sinceversion{Renamed in v0.5} % Italic correction fallback value; used if \cs{fontdimen1} is zero. See % \cref{sec:manual-italic-correction} on manual italic correction and also the % complementary configuration % option~\hyperref[item:mathitaliccorrection]{|mathitaliccorrection|}. Default value: % \milliem{\typogget{textitaliccorrection}}. % % \item[|trackingttspacing=|\code{\{\meta{outer-spacing}\}}\quad\microtyperequiredmarker]\label{item:trackingttspacing} % \indexpackageoptiondefinition{trackingttspacing} % Set the outer spacing of all typewriter fonts when used in the % \code{settracking}~environment as described in \cref{sec:tracking-control}. % % The argument \meta{outer-spacing} gets passed to \packagename{microtype}'s % \cs{SetTracking} option~\code{outer spacing}~\cite[Sec.~5.3]{package:microtype}. If the % argument contains commas, enclose the whole argument in curly braces. Default argument % value: \mbox{\typogget{trackingttspacing}}. % % The option can be used when loading the package and in the document preamble, but % \emph{not} in the document body. % % By default, this option is unset. % % \item[|uppercaselabelitemadjustments=\{|\meta{dim-1}, \dots, \meta{dim-4}|\}|]% % \label{item:uppercaselabelitemadjustments} % \indexpackageoptiondefinition{uppercase\-labelitem\-adjustments} % \sinceversion{Since v0.4} % Vertical shifts \meta{dim-N} to apply to \cs{labelitem}\meta{N}, where \meta{N}=1, 2, 3, % or~4 is the nesting level of the |itemize|~list. Empty list elements are ignored. The % special value~\samplestar{} instructs \packagename{typog} to preserve \meta{dim-N} at % that position. The adjustments apply to the uppercase setting % (\hyperref[syn:uppercaseadjustlabelitems]{\code{\string\uppercaseadjustlabelitems}}). % See \cref{sec:adjust-label-items} (in particular subsection~\singlequotes{Setup} and % \cref{tab:labelitemadjustvalues} on \cpageref{tab:labelitemadjustvalues}) and also % configuration option % \hyperref[item:lowercaselabelitemadjustments]{\code{lowercaseadjustlabelitem}}. % % All four lengths default to \formatdimen*{0pt}. % % \begin{important} % \slightlysloppy % \noindent % Configuring \code{uppercaselabelitemadjustments} (or % \code{lowercaselabelitemadjustments}) does \emph{not} activate the correction % mechanism. Use one of the macros % \hyperref[syn:uppercaseadjustlabelitems]{\cs{uppercaseadjustlabelitems}} or % \hyperref[syn:lowercaseadjustlabelitems]{\cs{lowercaseadjustlabelitems}} for that % purpose.\label{secend:package-options} % \end{important} % \end{description} % \end{typogsetup} % \index{package option|)usermandef} % % % \sectionfinish % \clearpage % \section{Macros and Environments}\label{sec:macros-and-envs} % % \begin{whittyquote} % Easy things should be easy, and \\ % hard things should be possible. \\ % \capitalemdash*~\propername{Larry Wall} % \end{whittyquote} % % \noindent % This is the \doublequotes{User Manual}~section of the documentation, where we describe all % user-relevant macros and environments that are defined in package~\packagename{typog}. % % We follow the naming convention that every environment whose name ends with % \mbox{\code{\ttdots}\:\code{par}} issues a \cs{par} at its end. Environments with different % name suffixes never close with~\cs{par}. % % % \subsection{Setup and Reconfiguration}\label{sec:setup} % % \DescribeEnv{typogsetup} % Configure\index{configuration|userman}\index{setup|userman} the package with the given % \meta{keys}. An empty argument of \code{typogsetup} resets all \meta{keys} to their default % values. % % \begin{synopsis}\label{syn:typogsetup} % \cs{begin}|{typogsetup}|\marg{keys} % \ttdots{} % \cs{end}|{typogsetup}| % \end{synopsis} % % The package can be (re-)configured\index{reconfigure|userman} at any point with % \cs{typogsetup}\marg{keys}, or\leftspacedendash for localized changes\rightspacedendash as % % \begin{codeexample} % 12\=\kill % \cs{begin}|{typogsetup}|\marg{keys} \\ % \> \ttdots \\ % \cs{end}|{typogsetup}| % \end{codeexample} % % \noindent % where \meta{keys} have the same format as the package options described in % \cref{sec:package-options}. % % \begin{tip} % Use \code{\string\PassOptionsToPackage\{\meta{keys}\}\{typog\}} to pass \meta{keys} to % \packagename{typog} before loading it and \code{\string\typogsetup\{\meta{keys}\}} after % \code{\string\usepackage\{typog\}}. % \end{tip} % % \begin{usecases} % \cs{typogsetup} can substitute configuring the package at load time or serve as an % addition.\visualpar Using the |typogsetup|~environment allows to fine-tune the parameters % for a specific use, e.\,g., display-sized text.\visualpar It even is conceivable that a % well-established \packagename{typog}-configuration could be attached to font-changing % macros like \cs{rm}, \cs{sf}, or~\cs{tt}. % \end{usecases} % % % \noindent % \DescribeMacro{\typogget} % Sometimes the user needs to access configuration values of package~\packagename{typog}. This % can be done in a safe way without resorting to code that is bracketed by \cs{makeatletter} % and \cs{makeatother} using of the following macro. % % \begin{synopsis}\label{syn:typogget} % \cs{typogget}\marg{key} % \end{synopsis} % % Retrieve the configuration value that is associated with~\meta{key}. For a list of available % \meta{key}s see~\cref{sec:package-options}. % % \begin{usecase} % Raise glyphs by the same amount as configured with \packagename{typog}. % % \begin{codeexample} % 12\=\kill % \cs{newcommand*}\{\cs{seesubst}\} \\ % \> \{\cs{raisebox}\= \{\cs{typogget}\{raisecapitalguillemets\}\}\% \\ % \> \> \{\cs{rightarrowhead}\}\} \\ % \cs{renewcommand*}\{\cs{labelitemi}\} \\ % \> \{\cs{raisebox}\= \{\cs{typogget}\{raisecapitaldash\}\}\{\cs{cdot}\}\} % \end{codeexample} % % The latter only is useful inside of an \code{itemize}~environment of course. Compare with % the solution in \cref{sec:adjust-label-items} offered by \packagename{typog} since v0.4. % \end{usecase} % % \DescribeMacro{\typoggetnth} % \sinceversion{Since v0.4} % If a configuration item is associated with a list of values as % \hyperref[item:lowercaselabelitemadjustments]{\code{lowercaselabelitemadjustments}}, % \hyperref[item:shrinklimits]{\code{shrinklimits}}, % \hyperref[item:stretchlimits]{\code{stretchlimits}}, % \hyperref[item:trackingttspacing]{\code{trackingttspacing}}, and % \hyperref[item:uppercaselabelitemadjustments]{\code{uppercaselabelitemadjustments}} are, it % may be convenient to fetch a particular list element of it. % % \begin{synopsis}\label{syn:typoggetnth} % \cs{typoggetnth}\marg{csname}\marg{key}\marg{index} \\ % \cs{typoggetnth}\marg{dimen-register}\marg{key}\marg{index} % \end{synopsis} % % Retrieve the configuration value\spacedemdash which is a comma-separated list\spacedemdash % that is associated with~\meta{key} and store the item having position~\meta{index} in % \meta{dimen-register} or the parameter-less, global macro~\meta{csname}. The destination % \meta{dimen-register} may be predefined like, e.\,g., \cs{dimen0} or user-defined. % Dimensions can also be stored in a macro by using the \meta{csname}~form of \cs{typoggetnth} % but not vice versa. % % Index into the list either from left to right with positive indices starting at~\(1\) up to % the length of the list, or from right to left with negative indices starting at~\(-1\) down % to the negative length. % % \begin{important} % Macro~\cs{typoggetnth} \emph{only} works with \meta{key}s that are associated with a list % of values. % \end{important} % % % \subsection{Information}\label{sec:information} % \index{information|userman} % % \begin{whittyquote} % Never forget: The visual output counts; \\ % it must always be checked, [\dots\itcorr{-4}]. \\ % \marginnote{The em-dash at then end of the quote is height-adjusted with % \hyperref[syn:capitalemdash]{\cs{capitalemdash*}}.}% % \capitalemdash*~\propername{Udo Wermuth}~\cite{wermuth:2017a} % \end{whittyquote} % % \noindent % We define some functions for inspecting the typesetting process. % % % \subsubsection{Font Information}\label{sec:font-information} % \index{font>information|userman} % % \DescribeMacro{\fontsizeinfo} % Capture the font~size\footnote{We use \cs{fontdimen6}, the em-height as the font % size.}\index{font>size|userman} and line~spacing\footnote{The line~spacing simply is % \cs{baselineskip}.}\index{line spacing|userman} at the point where \cs{fontsizeinfo} \emph{is % called} in macro~\meta{csname}. Both dimensions are measured in points~(pt) and the results % are rounded to tenths. % % \begin{synopsis}\label{syn:fontsizeinfo} % \cs{fontsizeinfo}\marg{csname} % \end{synopsis} % % The call to \cs{fontsizeinfo} defines a pair of macros to access the stored values. The % unstarred version~\cs{csname} expands to the lengths including their units (i.\,e.,~pt), the % starred version~\cs{csname*} omits the units. The separating slash is % \hyperref[syn:kernedslash]{\cs{kernedslash}}, which is introduced in % \cref{sec:slash-with-kern}. % % \begin{note} % The \cs{baselineskip} can contain a rubber (stretch/shrink) component; however, % \cs{fontsizeinfo} will not display these parts. % \end{note} % % \begin{usecases} % Colophon.\visualpar Font test pages. % \end{usecases} % % % \subsubsection{Paragraph- and Page-Breaking Trace}\label{sec:paragraph-and-pagebraking-trace} % % \DescribeEnv{typoginspect} % \DescribeEnv{typoginspectpar} % The environments |typoginspect| and |typoginspectpar| turn on the tracing of paragraphs and % pages; optionally they display the parbox' contents. These environments help users identify % typographic issues quantitatively without getting distracted by unrelated information in the % trace or the \filesystem{log}-file. % % \begin{synopsis} % \label{syn:typoginspect} % \label{syn:typoginspectpar} % \cs{begin}|{typoginspect}|\oarg{option}\marg{id} % \ttdots{} % \cs{end}|{typoginspect}| \\[\smallskipamount] % \cs{begin}|{typoginspectpar}|\oarg{option}\marg{id} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{typoginspectpar}| % \end{synopsis} % % The \meta{id} is an arbitrary string that identifies the results in the % \filesystem{log}~file. If the mandatory argument is empty, \packagename{typog} constructs a % unique value. % % % \paragraph{Option} % % \begin{description}[style=nextline] % \item[|tracingboxes|{[}=\meta{size}{]}] % Specify the maximum box breadth and box depth reported in the log. If \meta{size} is % omitted the maximum values are assumed; this is similar to the \cs{tracingboxes} % macro~\cite[p.~312]{abrahams:2020}. % \end{description} % % \begin{caution} % The end-of-trace marker sometimes gets placed too early and the trace seems truncated. % \LaTeX{} reliably logs the requested trace information, but the write operations for trace % data and \cs{immediate}\cs{write} which is used to print the end-tag are not synchronized. % The workaround in such a situation is to enclose more text in the % \code{typoginspect}~environment (respecting the nesting of other environments of course). % \end{caution} % % % \paragraph{\LaTeX{} \filesystem{log}-file and trace.} % The trace data in the \filesystem{log}-file is bracketed by \acronym{XML}-tags. % % \begin{widecodeexample} % \\ % ~~\ttdots \\ % % \end{widecodeexample} % % \noindent % where the \meta{id} is the user-supplied, unique\footnote{It has turned out advantageous to % use unique \meta{id}s. However, \meta{id}s are \emph{not required} to be distinct.} % identifier of the group, \meta{jobname} is the value of \cs{jobname}, \meta{line-number} % records the \cs{inputlineno} of the \cs{begin}~of the group, and \meta{page-number} gets % replaced with the current value of the page counter. % % \begin{itemize}[noindent] % \item Any text tool can be used to extract the tags. \propername{Emacs} users will find the % function~\mbox{\code{(\href{https://www.gnu.org/software/emacs/manual/html_node/emacs/Other-Repeating-Search.html}{occur} % \meta{regexp})}} to be useful.\shiftedmarginnote{This \code{itemize} list demonstrates % vertically adjusted label items (\cref{sec:adjust-label-items}).} % % \item As long as the tags are not nested \programname{sed} or \programname{perl} % extract the information gathered by~|typoginspect|, for example: % % \begin{codeexample} % sed \= -ne '/\#p' \\ % \> < jobname.log % \end{codeexample} % % or % % \begin{codeexample} % perl \= -ne '\= \$a=0 if /<\textbackslash/typog-inspect>/; \textbackslash \\ % \>\> print \$\_ if \$a; \textbackslash \\ % \>\> \$a=1 if / < jobname.log % \end{codeexample} % % \item The companion program~\programname{typog-grep} is tailored to extract the information % marked up by |typoginspect| and~|typoginspectpar|, even if the environments are nested. % % The complete manual page of \programname{typog-grep} is reproduced in % \Cref{app:typog-grep}. % \end{itemize} % % \begin{tips} % \begin{itemize}[nestedinspecialsection, notopsep] % \item It may be necessary to run whatever \LaTeX~engine with a larger log-file line length, % to prevent wrapped lines. With short lines the wannabe \acronym{XML} opening tags can % get wrapped and thus become unrecognizable to dumb postprocessors. To avoid wrapped % lines, prepend % % \begin{codeexample} % /usr/bin/env max\_print\_line=2147483647 % \end{codeexample} % % to the command-line. The value~\(2147483647 = 2^{31} - 1\) effectively disables all line % wrapping by \LaTeX. % % As both \command{pdflatex} and \command{lualatex} support changing their configuration on % a by-call basis with option~\code{-cnf-line=\meta{STRING}} an alternative to the above % example is to add % % \begin{codeexample} % -cnf-line=max\_print\_line=2147483647 % \end{codeexample} % % to the command-line. % % \item If more trace information is needed just add \cs{tracing\ttdots} calls right after % \code{\string\begin\{typoginspect\}} % or~\code{\string\begin\{typoginspectpar\}}. % % \item As the overhead of \cs{typoginspect} is relatively low, hairy parts of a document can % permanently be furnished with them, for example, the Index. % % \item Any labeled part can treat their ids to \meta{id}. Think of \cs{caption}s or any % theorem-like environment and their associated, unique \cs{label}s.\specialsectionendhere % \end{itemize} % \end{tips} % % % \phantomsection % \paragraph{Investigating the badness of a paragraph.}\label{sec:investigating-paragraph-badness} % \index{paragraph>badness|userman} % % It is generally unnecessary to determine the \emph{exact} classification of a paragraph's % badness~\cite[p.~97n]{knuth:1986}, though the curious user can switch on logging of % \TeX's~line-break information with % \cs{tracingparagraphs}|=1|\footnote{Reference~\citenum{wermuth:2016} provides an % exceptionally detailed discussion of the output of \cs{tracingparagraphs}.} or simply use % the \hyperref[syn:typoginspect]{typoginspect}~environment and check the suffixes % % \begingroup % \centering % |@@|\meta{breakpoint-number} |line| \meta{line-number}|.|\meta{suffix} % \par % \endgroup % % \noindent % of each line in the paragraph, where for \meta{suffix} the following mapping % holds~\cite[p.~99]{knuth:1986}: % \begin{equation*} % 0 \mapsto \text{very loose},\quad % 1 \mapsto \text{loose},\quad % 2 \mapsto \text{decent, and}\quad % 3 \mapsto \text{tight}. % \end{equation*} % % \begin{example} % \let\oldsample=\sample % \renewcommand*{\sample}[1]{\oldsample{\texttt{#1}}} % \par\medskip % \noindent % |@@17: line 15.1- t=142289 s=93.58414 a=2.86073 -> @@16| % % \begin{enumerate}[noitemsep] % \item The feasible breakpoint~\sample{@@} number~17 in the paragraph leads to % \item \sample{line}~15, which is the loose~\sample{.1} last~\sample{-} line of the % paragraph. % \item Up to this breakpoint the paragraph has picked up total demerits~\sample{t} % of~142289. % \item\index{lastlinefit=\verb!*+\lastlinefit+|userman} % The following two values only show up if\/ \(\cs{lastlinefit} \not= 0\): % \begin{enumerate}[beginpenalty=10000, nosep] % \item The shortfall~\sample{s} and % \item glue~\sample{a} or~\sample{g}.\!\footnote{The author is unaware of any descriptions % of \sample{s}, \sample{a}, or~\sample{g} and the interested reader is referred to the % source code, e.\,g., \filesystem{pdftex.web}; search for \code{print("\textvisiblespace % s=")}. In the weaved documentation the first relevant section is~\S1851.} % \end{enumerate} % \item The best\footnote{\singlequotes{Best} means the minimum-demerits path in the graph of % the feasible breakpoints, which has been constructed for the paragraph.} way to get % here, i.\,e., |@@17| is via~\sample{->} breakpoint~\sample{@@}~16.\specialsectionendhere % \end{enumerate} % \end{example} % % \begin{note} % When package~\packagename{microtype}'s font expansion jumps in the reports on % \doublequotes{Loose \textbackslash hbox (badness~\dots)} and \doublequotes{Tight % \textbackslash hbox (badness~\dots)} \shiftedmarginnote{All of our guillemets were raised % by \milliem{\the\typogget{raiseguillemets}}.} contain the amount of shrinking or expansion % as parenthesized values (units are thousandths of the current font's~em) like, e.\,g., % % \begin{codeexample} % \textbackslash T1/erewhon-LF/m/n/9/@/@ (-13) \ttdots % \end{codeexample} % % or % % \begin{codeexample} % \textbackslash T1/erewhon-LF/m/n/9/@/@/10ls (+7) \ttdots % \end{codeexample} % % An \sample{ls} appended to the font name specification indicates that % \packagename{microtype}'s letter~spacing is active and changed the tracking by that many % thousands on an em as indicated before~\sample{ls}. % \end{note} % % % \phantomsection % \paragraph{Investigating page-breaks.} % \index{page break|userman} % % Use \code{\cs{tracingpages}=1} or the \hyperref[syn:typoginspect]{typoginspect}~environment % to switch on tracing of \TeX's page-break % information~\cite[p.~112n]{knuth:1986}.\!\footnote{See also the discussion of the \TeX~output % routines by \propername{Solomon}~\cite{solomon:1990}.} % % The first time vertical material enters a new page, \TeX{} logs % % \begingroup\tt % \centering % \%\% goal height=\meta{text-height}, max depth=\meta{max-depth} \\ % \par % \endgroup % % \noindent % where \meta{text-height} is the total height \TeX{} wants to achieve and~\meta{max-depth} is % the maximum depth of the hbox in the last line of the page is allowed to have without % considering \meta{text-height} to be exceeded. For example: % % \begingroup\tt % \centering % \%\% goal height=598.0, max depth=5.0 \\ % \par % \endgroup % % For every vertical breakpoint \TeX{} records % % \begingroup\tt % \centering % \% t=\meta{total-height} g=\meta{goal-height} b=\meta{badness} p=\meta{penalty} c=\meta{cost} % \par % \endgroup % % Here, \meta{total-height} and \meta{goal-height} are the current total height of the page and % the current goal height to achieve with respect to this vertical breakpoint. % % The value of \meta{penalty} and \meta{cost} can be infinite, which would be indicated with an % asterisk~\sample{\texttt{*}} instead of a numerical value. The best vertical breakpoint % found so far on the current page is indicated by a trailing sharp-sign~\sample{\texttt{\#}}. % % \begin{example} % \let\oldsample=\sample % \renewcommand*{\sample}[1]{\oldsample{\texttt{#1}}} % \begin{widecodeexample} % \% t=351.3 plus 11.0 minus 1.0 g=553.9 b=10000 p=-300 c=100000\# % \end{widecodeexample} % % \begin{enumerate}[noitemsep, notopsep] % \item At this vertical breakpoint the total page height~\sample{t} is 351.3\,pt. We have % picked up glue with 11\,pt~stretchability and~1\,pt~shrinkability along the way. % % \item The current goal height~\sample{g} is 553.9\,pt. If the initial goal height was % 598\,pt we can deduce that some space for other vertical material was subtracted. % % \item The badness~\sample{b} of this vertical break is horrendous which is expected for the % first lines on a page since breaks so early are rightfully considered infinitely bad. % % \item The penalty~\sample{p} at this point actually is a bonus. % % \item As the badness is 10000 the cost for a break is calculated % to~100000.\specialsectionendhere % \end{enumerate} % \end{example} % % % \subsection{Hyphenation}\label{sec:latex-hyphenation} % \index{hyphenation|userman} % % \TeX's and thus \LaTeX's hyphenation algorithm is highly sophisticated, yet the document % author sometimes lacks convenient macros to solve seemingly trivial typographic tasks. For % example, to hyphenate a compound~word connected by a hyphen. % % \DescribeMacro{\allowhyphenation} % \TeX{} inhibits breaks of the component words by default. The following macro rectifies the % problem. % % \begin{synopsis}\label{syn:allowhyphenation} % \cs{allowhyphenation} % \end{synopsis} % % Macro~\cs{allowhyphenation}\index{hyphenation>re-enable automatic|userman} re-enables % automatic hyphenation after \TeX{} has turned it off, e.\,g.~in a hyphenated compound. % % The admittedly simple rules for when \TeX{} auto-hyphenates and when it does not give rise to % so many different, yet interesting cases that we devote \cref{tab:hyphens-and-hyphenations} % to them. % \begingroup % \let\textfrac=\nativetextfraction % The seemingly special cases shown there are not that uncommon, e.\,g., consider % \singlequotes{\mbox{spin-\textfrac{1}{2}}} which is coded as |\mbox{spin-\textfrac{1}{2}}|. % A line break between the text and the fraction would garble the term. % \endgroup % % \begin{usecases} % \begin{itemize}[notopsep] % \item All examples from the bottom of \cref{tab:hyphens-and-hyphenations} on % \cpageref{tab:hyphens-and-hyphenations}. % % \item Establish additional hyphenation opportunities if these have been canceled by % bricolage that is necessary for parenthesized German compounds like, e.\,g., % \foreignphrase{\doublequotes{(Linear\mbox{-})\hskip0pt Impulsvektor}}, % \foreignphrase{\doublequotes{(Links\mbox{-})\hskip0ptKonjugation}}, or % \foreignphrase{\doublequotes{(Unter\mbox{-})\hskip0pt Gruppe}}. All of these can be % fixed by blunting the hyphen with \code{\cs{mbox}} and inserting a breakpoint with % \code{\cs{hskip}} (or, as horizontal glue carries a penalty of zero, with % \hyperref[syn:breakpoint]{\code{\cs{breakpoint}}}, which is associated with % \code{\cs{breakpenalty}}), like % % \begin{codeexample} % (Linear\cs{mbox\{-\}})\cs{hskip0pt} Impulsvektor % \end{codeexample} % % where \foreignphrase{\doublequotes{Linear}} won't get hyphenated. % Macro~\code{\cs{allowhyphenation}} rectifies this situation: % % \begin{codeexample} % (Linear\cs{allowhyphenation}\cs{mbox}\{-\})\cs{hskip0pt} Impulsvektor % \end{codeexample} % % Typographically the last code example raises the same concerns as does \code{\cs{hyp}}, % this is, whether the hyphenation opportunities % (here:\narrowspace\foreignphrase{Li-ne-ar}),\marginnote{A % \hyperref[syn:narrowspace]{\code{\cs{narrowspace}}} compensates the visual gap between % the colon and the italic \singlequotes{L}.} if chosen, distract from the constuction of % the compound that already contains a hyphen. % % \item Mend line breaks of index-entries in a narrow index: % % \begin{codeexample} % Halbgruppe, Transformations\cs{allowhyphenation}\cs{mbox}\{-\}\cs{,}-\nolig*-\nolig*- % \end{codeexample} % % The first part, \singlequotes{Transformations} is allowed to be hyphenated, but a break % after the hyphen is prohibited as it results in a prowling em-dash at the beginning of % the next line. % % \item Re-enable hyphenation when a macro decays into a \cs{hbox}: % % \begin{codeexample} % Einselement\cs{allowhyphenation}\cs{rlap}\{,\}\cs{footnote}\{\ttdots\} % \end{codeexample} % % where \cs{rlap} is equivalent to something like % \code{\cs{makebox}[0pt]\{\#1\cs{hss}\}}. % % \item Use \cs{allowhyphenation} to turn on hyphenation of the first word of a paragraph as, % e.\,g., in a narrow index or a \cs{marginpar}: % % \begin{codeexample} % \cs{marginpar}\{\cs{allowhyphenation} Kontakttransformationen\} % \end{codeexample} % % A common trick to sweet-talk \TeX{} into hyphenating the first word of a paragraph is to % put \cs{hskip0pt} in front of it. % % \item Enable automatic hyphenation in the rare but weird cases when \TeX{} does not % hyphenate a word that is hyphenatable despite the result is an overfull % box.\!\footnote{The author of \packagename{typog} has no idea, why this happens, but he % has been successful in fixing the problems with code like \code{(\cs{allowhyphenation} % \mbox{Superpositionsprinzip})} or \code{(\cs{allowhyphenation} % \mbox{Superauswahlregel})}. Elucidation by a \TeX-savant is highly % welcome.}\specialsectionendhere % \end{itemize} % \end{usecases} % % \begin{table}\small % \centering % \caption[Hyphens and automatic hyphenation] % {\TeX{} offers plenty of possibilities to hyphenate a compound.\visualpar We use % the sample \singlequotes{hyphenated-compound} to show various code examples and % the results that they produce. The parts are automatically hyphenated like this: % \singlequotes{hyphenated}~\(\rightarrow\) \singlequotes{hy-phen-ated} and % \singlequotes{compound}~\(\rightarrow\) \singlequotes{com-pound}.} % \label{tab:hyphens-and-hyphenations} % % \begin{nofontexpansion} % \newcommand*{\zbox}[1] % {\hfuzz=\maxdimen % \overfullrule=0pt % \raisebox{\normalbaselineskip}{\parbox[t]{0pt}{\hspace{0pt}#1}}} % % \sbox{\listlabelbox}{hyphenated-compound} % \begin{tabularx}{\linewidth}{@{}p{12em}l>{\fussy\RaggedRight}X@{}} % \toprule % \LaTeX-Code & \makebox[\wd\listlabelbox][l]{Result} & Note \\ % \midrule % \code{hyphenated-compound} & % \zbox{hyphenated-compound} & % Most frequently used code; the hyphen~\sample{\code{-}} expands to % \code{\cs{discretionary}\mbox{\{-\}\{\}\{-\}}} rendering the parts unbreakable \\ % % \code{hyphenated\cs{mbox}\{-\}\%}\newline % \code{compound} & % \zbox{hyphenated\mbox{-}compound} & % Suppress hyphenation with the \cs{mbox} in the compound \\ % % \code{\cs{mbox}\{hyphenated-\%}\newline % \code{compound\}} & % \zbox{\mbox{hyphenated-compound}} & % Avoid line break and thus hyphenation \\ % % \midrule % % \code{hyphenated\cs{hyp}}\newline % \code{compound} & % \zbox{hyphenated\hyp compound} & % Macro~\cs{hyp} defined in package % \packagename{hyphenat}~\cite{package:hyphenat} \\ % % \addlinespace % \midrule % % \code{hyphenated\%}\newline % \cs{allowhyphenation}\code{-\%}\newline % \code{compound} & % \zbox{hyphenated\allowhyphenation-compound} & % Macro~\cs{allowhyphenation} of package~\packagename{typog}; only unblock % hyphenation of the first part \\ % % \code{hyphenated-\%}\newline % \cs{allowhyphenation}\newline % \code{compound} & % \zbox{hyphenated-\allowhyphenation compound} & % Macro~\cs{allowhyphenation} of package~\packagename{typog}; only unblock % hyphenation of the second part \\ % % \code{hyphenated\%}\newline % \cs{allowhyphenation}\newline % \cs{mbox}\code{\{-\}\%}\newline % \code{compound} & % \zbox{hyphenated\allowhyphenation\mbox{-}compound} & % Macro~\cs{allowhyphenation} of package~\packagename{typog}; hyphenate first % part and keep the original hyphen unbreakable \\ % % \code{hyphenated\%}\newline % \cs{allowhyphenation}\code{-\%}\newline % \cs{allowhyphenation}\newline % \code{compound} & % \zbox{hyphenated\allowhyphenation-\allowhyphenation compound} & % Macro~\cs{allowhyphenation} of package~\packagename{typog}; hyphenate both % parts, similar to \cs{hyp} shown above \\ % % \addlinespace % \bottomrule % \end{tabularx} % \end{nofontexpansion} % \end{table} % % \noindent % Whenever using \cs{-}, the short-hand form of \cs{discretionary\{-\}\{\}\{\}}, authors % writing in a foreign language should reconsider whether it really beats \cs{hyphenation} or % \cs{babelhyphenation}\footnote{\cs{babelhyphenation} is the multi-lingual extension of \TeX's % \cs{hyphenation} and it is defined in package~\packagename{babel}~\cite{package:babel}.} in % the particular situation. However, sometimes \cs{-} actually \emph{is} the way to go. % % Let us assume we mark up proper names with % % \begin{codeexample} % \cs{DeclareRobustCommand}*\= \{\cs{propername}\}[1] \\ % \> \{\cs{mbox}\{\cs{textsc}\{\#1\}\}\} % \end{codeexample} % % \noindent % and we want to have breakable \foreignphrase{\doublequotes{\propername{Abel}sche Gruppe}} or % \foreignphrase{\doublequotes{\propername{Euklid}ischer Vektorraum}} without dropping the % markup. To that end we define commands that insert a hyphenation point at the right place: % % \begin{codeexample} % \cs{newcommand*}\= \{\cs{abelsche}\} \\ % \> \{\cs{propername}\{Abel\}\cs{-}sche\} \\ % \cs{newcommand*}\> \{\cs{euklidischer}\} \\ % \> \{\cs{propername}\{Euklid\}i\cs{-}scher\} % \end{codeexample} % % \noindent % which are impossible to encode with \cs{hyphenation} or~\cs{babelhyphenation} as these expect % only letters and dashes as their arguments with spaces separating the words. % % \index{hyphenation>first word|userman} % \index{hyphenation>hskip=\cs{hskip}|userman} % \TeX{} never hyphenates the initial word in a paragraph even with \cs{allowhyphenation}. % Start the paragraph with \cs{hskip~0pt} to enable hyphenation even for the first word. % % \begin{tip}[Typewriter Fonts] % Sometimes it is desired to get a breakable typewriter font. \LaTeX{} suppresses any % hyphenation for fonts in \cs{ttfamily} by un-defining their \cs{hyphenchar}s. If these are % reassigned, the usual line breaking and hyphenation occurs again. % % So, a fictitious macro `\cs{code}' to typeset short pieces of code could look like this: % % \begin{codeexample} % \cs{newcommand*}\= \{\cs{code}\}[1] \\ % \> \{\{\= \cs{ttfamily} \\ % \> \> \cs{hyphenchar}\cs{font}=`\cs{-}\cs{relax} \#1\}\}\specialsectionendhere % \end{codeexample} % \end{tip} % % \DescribeMacro{\breakpoint} % \DescribeMacro{\breakpoint*} % The empty discretionary construct~\cite[p.~95]{knuth:1986}, \cs{discretionary\{\}\{\}\{\}}, % is helpful. It deserves its own macro\spacedemdash with a descriptive name. % % \begin{synopsis}\label{syn:breakpoint} % \cs{breakpoint}\qquad \cs{breakpoint*} % \end{synopsis} % % \index{hyphenation>empty discretionary|userman} % The starred form inserts an empty discretionary, which disables automatic hyphenation. The % unstarred form inserts an empty discretionary and immediately re-enables automatic % hyphenation. % % The difference between \cs{breakpoint} and the \LaTeX{} macro~\cs{allowbreak} is not only % that the former has a starred form, but the penalty associated with \cs{breakpoint} is the % current\footnote{At this point in the document % \code{\string\exhyphenpenalty=\the\exhyphenpenalty} holds.} \cs{exhyphenpenalty}, whereas % \cs{allowbreak} statically assigns a zero~penalty. % % \begin{usecase} % Prefixes that end in a hyphen inside of a pair of parenthesis: % % \begin{codeexample} % \cs{mbox}\{(pre-)\}\cs{breakpoint*} \cs{propername}\{Hilbert\} space\specialsectionendhere % \end{codeexample} % \end{usecase} % % \DescribeEnv{hyphenmin} % \sinceversion{Since v0.3} % Set the values of \cs{lefthyphenmin} and \cs{righthyphenmin} confined to an environment. % % \begin{synopsis}\label{syn:hyphenmin} % \cs{begin}|{hyphenmin}|\oarg{left-hyphen-minimum}\marg{hyphen-minimum} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{hyphenmin}| % \end{synopsis} % % Without optional argument |hyphenmin| sets both \cs{lefthyphenmin} and \cs{righthyphenmin} to % \meta{hyphen-minimum}. When called with an optional argument it sets \cs{lefthyphenmin} to % \meta{left-hyphen-minimum} and \cs{righthyphenmin} to \meta{hyphen-minimum}.\!\footnote{The % current values for \cs{lefthyphenmin} and \cs{righthyphenmin} in this document % are~\the\lefthyphenmin{} and~\the\righthyphenmin.} % % \begin{usecase} % If the hyphen minimums were \emph{increased} e.\,g.~in the preamble: Reduce the hyphen % minimum in the index or other multi-column environments with narrow lines to regain % hyphenation possibilities.\visualpar Use a large \meta{hyphen-minimum} to disable % hyphenation.\label{secend:latex-hyphenation} % \end{usecase} % % % \newpagetofixtoc % \subsection{Disable\kernedslash Break Ligatures}\label{sec:break-ligatures} % \index{ligature|userman} % % \DescribeMacro{\nolig*} % Break a ligature without introducing a hyphenation opportunity. % % \begin{synopsis}\label{syn:nolig-star} % \cs{nolig*}\oarg{kerning} % \end{synopsis} % % \indexpackageoption{ligaturekern} % Inserting \cs{nolig*} disables a ligature at the given point by a kern. Set the size of the % kern\index{kerning>ligature|userman} with \hyperref[item:ligaturekern]{\code{ligaturekern}} or % override this value with \meta{kerning} as thousandths of the current font's~em. % % \begin{usecases} % \cs{nolig*} can be useful in headings, where additional hyphenation points are % unwelcome.\visualpar In fonts with an overly rich set of ligatures \cs{nolig*} offers a % straightforward means to suppress unwanted ligatures at non-hyphenatable % positions.\visualpar Rectify the appearance of a pseudo ligature, i.\,e., two adjacent % characters that look like a ligature, but actually are not. % \end{usecases} % % \noindent % \DescribeMacro{\nolig} % Break a ligature and introduce a hyphenation opportunity. % % \begin{synopsis}\label{syn:nolig} % \cs{nolig}\oarg{kerning} % \end{synopsis} % % \indexpackageoption{breakpenalty} % Inserting \cs{nolig} disables a ligature at the given point as \cs{nolig*} does \emph{and} % introduces a hyphenation opportunity with % penalty~\hyperref[item:breakpenalty]{|breakpenalty|}. % % \begin{important}[\packagename{hyperref} bookmarks] % If a \cs{nolig}\leftspacedendash whether starred or un-starred\rightspacedendash occurs % in an argument that is processed with % package~\packagename{hyperref}\index{hyperref=\packagename{hyperref} (package)|userman} % for inclusion into the document's % \acronym{PDF}-bookmarks\index{PDF=\acronym{PDF}|userman}\index{bookmark|userman} an % additional argument is necessary to parse the macro. This argument either is \cs{relax} % or~the empty group~\sample*{\{\kern.1em\}}. % % \begin{synopsis} % \begin{tabbing} % \cs{nolig*}\oarg{kerning}\cs{relax}\qquad\= \cs{nolig}\oarg{kerning}\cs{relax} \\ % \cs{nolig*}\oarg{kerning}\code{\{\}}\> \cs{nolig}\oarg{kerning}\code{\{\}} % \end{tabbing} % \end{synopsis} % % The prototypical places where this processing-for-\acronym{PDF}-bookmarks happens are the % sectioning macros, e.\,g., \cs{chapter}, \cs{section}, \cs{subsection},~etc. % % \LaTeX{} will trip with \doublequotes{Undefined control sequence} on % \cs{typog@\-missing@\-argument} if the extra argument is not passed. % % Alternatively use \cs{texorpdfstring}~\cite[Sec.~4.1.2, p.~22]{package:hyperref}. % \end{important} % % \begin{usecases} % \cs{nolig} can be used with just about any ligature that needs to be split into its parts. % It also has proven beneficial in separating pairs of characters that are kerned too % tightly, e.\,g., the \singlequotes{ij}, as in \singlequotes{bijection}, which is % particularly distractive here, for it occurs at the boundary of two syllables. % \end{usecases} % % % \newpagetofixtoc % \subsection{Manual Italic Correction}\label{sec:manual-italic-correction}\label{italic correction} % % \DescribeMacro{\itcorr} % \DescribeMacro{\itcorr*} % The italic correction offered by \TeX{} or \LaTeX{} sometimes needs manual adjustment. % % \begin{synopsis}\label{syn:itcorr} % \cs{itcorr}\marg{strength}\qquad \cs{itcorr*}\marg{strength} % \end{synopsis} % % In text mode, macro~\cs{itcorr} inserts a kern whose width is proportional to \cs{fontdim1}, % which is the font's italic correction. % \indexpackageoption{textitaliccorrection} % If \cs{fontdim1} happens to be zero (e.\,g.~for an upright font), \cs{itcorr} uses the value % set with \hyperref[item:textitaliccorrection]{\code{textitaliccorrection}} instead of % \cs{fontdim1}. The starred version always uses % \hyperref[item:textitaliccorrection]{\code{textitaliccorrection}}. % \indexpackageoption{mathitaliccorrection} % In math mode macro~\cs{itcorr} uses the value set with % \hyperref[item:mathitaliccorrection]{\code{mathitaliccorrection}}\footnote{Separate % adjustments may be desirable if the math font's italic have markedly different slants.} in % both the starred and the unstarred form. % % Typical slant angles of serif italic fonts range from 8\textdegree{} to~18\textdegree{} and % thus values for |textitaliccorrection| from .14 to~.32. Note: \meta{strength} can be % negative, and fractional \meta{strength}s are allowed. % % \begin{usecases} % Stronger or weaker correction than |\/|.\visualpar Correct a non-slanted or non-italicized % font.\visualpar Negative correction at the left-hand side\footnote{Groff has the machinery % for left-italic-correction. Its font-metrics files support per glyph % left-italic-correction values and users can access them conveniently via~\sample*{\cs{,}}.} % of italic, i.\,e., compensate \doublequotes{shift-to-the-right effect} of % italic.\visualpar Positive correction at the left-hand side of italic, e.\,g., an % opening parenthesis or square bracket followed by an % italic~\sample{\itshape\itcorr{8}f\itcorr{7}} (before:~8, after:~7) or % \sample{\itshape\itcorr{4}y\itcorr{1}} (before:~4, after:~1) reaching far to the left below % the baseline. % \end{usecases} % % % \paragraph{The \meta{strength} parameter explained.} % % \TeX{} records the slant angle~\(\alpha\) of a font in \cs{fontdim1} as \(\mbox{1\,pt} \times % \sin\alpha\). Rephrased the formula means: \emph{How much horizontal space is required for a % letter slanted with ~\(\alpha\) that is 1\,pt high?} Thus, \cs{itcorr}\marg{strength} % calculates % \begin{displaymath} % \meta{strength} \times \mbox{1\,pt} \times \sin\alpha. % \end{displaymath} % % A well-chosen \meta{strength} should be the absolute minimum value which avoids that the % glyphs typeset in italic collide with other\leftspacedendash usually % non-italic\rightspacedendash letters or symbols unless this disturbs the consistency of the % overall tracking. % % Correction of the right-hand side and \mbox{\(\alpha > 0\)}: A reasonable first guess of % \meta{strength} is the highest point where the rightmost part of the letter would touch a % rule angled at \(\alpha\) with respect to the baseline. The correction of the left-hand side % and \mbox{\(\alpha > 0\)} considers the lowest \singlequotes{touching} point below the % baseline on the left-hand side of the letter. Negative values of \(\alpha\) exchange the % reference points. % % \iffalse %<*slantangle> prologues := 3; truecorners := 1; linecap := butt; input TEX; TEXPRE("%&latex" & char(10) & "\documentclass{article}\begin{document}"); TEXPOST("\end{document}"); string roman_font; roman_font := "pplr8r"; % URW Palladio L - Roman string italic_font; italic_font := "pplri8r"; % URW Palladio L - Italic u := 360; font_scale := 10; pair loc[]; loc[1] := .2[origin, (u, 0)]; loc[2] := .5[origin, (u, 0)]; loc[3] := .8[origin, (u, 0)]; picture letter_H; letter_H := thelabel.top("H" infont italic_font scaled font_scale, loc[1]); picture letter_L; letter_L := thelabel.top("L" infont italic_font scaled font_scale, loc[2]); picture letter_a; letter_a := thelabel.top("a" infont italic_font scaled font_scale, loc[3]); path slant_angle; slant_angle := lrcorner letter_H + (14, 0) -- lrcorner letter_H + (-6, 0) -- urcorner letter_H + (3.5, 0); pair base_point; base_point := (xpart point 2 of slant_angle, ypart point 0 of slant_angle) ; pair angle_label; angle_label := point 2 of slant_angle + (0, -12); beginfig(1); draw letter_H; draw slant_angle; draw point 2 of slant_angle -- base_point dashed evenly; draw point 1 of slant_angle -- base_point withpen pencircle scaled 2pt; label.rt(TEX("$\alpha$"), angle_label); draw letter_L; draw slant_angle shifted (xpart lrcorner letter_L - xpart lrcorner letter_H + 2, 0); draw letter_a; draw slant_angle shifted (xpart lrcorner letter_a - xpart lrcorner letter_H - 3, 0); endfig; end % % \fi % % \Cref{fig:slant-angle} shows how \meta{strength} and \(\alpha\) are related. Moreover, it % demonstrates how intricate italic correction is. % % \begin{figure} % \centering % \includegraphics{slant-angle-1.mps} % \caption[Some letters of an italic font.] % {Some letters of an italic font. We use the capital~\sample{H} to measure the % angle~\(\alpha\) between the plumb-line (drawn dashed) and a tangent to the % rightmost parts of the glyph. The length of the plumb-line is proportional to % \meta{strength} and the short, thick part of the baseline symbolizes the resulting % italic correction.\visualpar The middle example, the capital~\sample{L}, shares % \(\alpha\) with \sample{H} but obviously needs a far smaller \meta{strength} or % even no correction at all.\visualpar The \sample{a} at the right-hand side is an % example of why \TeX{} allows to assign an italic~correction to each individual % character of a font. Not only features the lowercase~\sample{a} a % larger~\(\alpha\)\leftspacedendash despite being a member of the same % font\rightspacedendash but its serif adds as much to the width as the slanted % stem.\label{fig:slant-angle}} % \vspace{-3\baselineskip} % \llap{\parbox{\marginparwidth} % {\marginnoteformat % We center the last lines of each figure and table caption using % \hyperref[syn:lastlinecenteredpar]{\code{lastlinecenteredpar}}.} % \hspace*{\marginparsep}} % \end{figure} % % % \newpagetofixtoc % \subsection{Apply Extra Kerning or Spacing}\label{sec:extra-kerning} % \index{kerning>extra|userman} % \index{extra spacing|userman} % % Package \packagename{typog} provides two sets of macros to kern some of the punctuation % symbols. One is for forward slashes the other, more extensive one, for hyphens and dashes. % % % \subsubsection{Slash}\label{sec:slash-with-kern} % \index{kerning>forward slash|userman} % % \DescribeMacro{\kernedslash} % \DescribeMacro{\kernedslash*} % Macro~\cs{kernedslash} expands to a forward slash~(\sample{\itcorr{3}\char`/}) with some % extra space around it. % % \begin{synopsis}\label{syn:kernedslash} % \cs{kernedslash}\qquad \cs{kernedslash*} % \end{synopsis} % % \indexpackageoption{breakpenalty} % The starred form is unbreakable, the non-starred version introduces a break point with % penalty~\hyperref[item:breakpenalty]{|breakpenalty|} after the slash. % \indexpackageoption{slashkern} % Configure the kerning around the slash with~\hyperref[item:slashkern]{|slashkern|}. % % \sinceversion{Option \code{lowerslash} introduced in v0.5} % \indexpackageoption{lowerslash} % The kerned slash can typset lowered (or raised), with the offset from the baseline configured % using \hyperref[item:lowerslash]{|lowerslash|}. % % \begin{tip} % Define specialized macros for slashes surrounded by lowercase letters or small~caps if they % are needed often or require a specific value for \code{slashkern}. % % \begin{codeexample} % \cs{newcommand*}\= \{\cs{lowercasekernedslash}\} \\ % \> \{\=\cs{begin}\{typogsetup\}\{\=lowerslash=.1em, \\ % \> \> \>slashkern=.02em\} \\ % \> \> ~~\cs{kernedslash} \\ % \> \> \cs{end}\{typogsetup\}\} % \end{codeexample} % % Generic solutions could build upon \cs{fontdimen5} and \cs{fontdimen6} (see % \cref{tab:fontdimen} on \cpageref{tab:fontdimen}) or measure the height and depth of the % slash-glyph (abstracted in \cs{typog@forwardslash}) and compare it to e.\,g.~the height of % selected lowercase characters. % \end{tip} % % If the word following the slash should not be hyphenated append \cs{nobreak} after % \cs{kernedslash*}. % % \begin{usecases} % \cs{kernedslash} improves the appearance of pairs of years typeset in lining numerals: % \meta{year\textsubscript{1}}/\meta{year\textsubscript{2}}.\visualpar The macro has proven % helpful in many cases where the right hand side of the slash starts with a capital as, for % example, \meta{city}/\meta{state-code} (\acronym{US}-specific) or % \meta{anything}/\meta{noun} (any language that capitalizes \meta{noun}).\visualpar Use % option~\code{lowerslash} to adjust the slash to surrounding lowercase letters.\visualpar % Correct a too high raising slash of a font % (e.\,g.~Cochineal\detoxindex{font>typeface>Cochineal|userman}) with % option~\code{lowerslash}. % \end{usecases} % % % \subsubsection{Hyphen}\label{sec:hyphen-with-kern} % \index{kerning>hyphen|userman} % % \DescribeMacro{\kernedhyphen} % \DescribeMacro{\kernedhyphen*} % Macros \cs{kernedhyphen*} and \cs{kernedhyphen} expand to a hyphen~(\sample{-}) with given % kerning to its left and to its right. % % \begin{synopsis}\label{syn:kernedhyphen} % \cs{kernedhyphen}\oarg{raise}\marg{left-kerning}\marg{right-kerning} \\ % \cs{kernedhyphen*}\oarg{raise}\marg{left-kerning}\marg{right-kerning} % \end{synopsis} % % Typeset an unbreakable hyphen with \cs{kernedhyphen*} or a breakable hyphen (like \cs{hyp} of % package \packagename{hyphenat}~\cite{package:hyphenat}) with \cs{kernedhyphen} and apply some % kerning to left and to the right of it. The values \meta{left-kerning} and % \meta{right-kerning} are multiplied with one thousandth of the current font's~em to get the % size of the kern. % % The optional argument~\meta{raise}, also given in \nativetextfraction{1}{1000}\,em, allows to % adjust the height of the hyphen similar to the macros described in % \cref{sec:raise-characters}. % \indexpackageoption{raisecapitalhyphen} % In text mode, the special argument~\sample{|*|} for \meta{raise} applies the current value of % \hyperref[item:raisecapitalhyphen]{\code{raisecapitalhyphen}}. The default for \meta{raise} % is zero. % % \DescribeMacro{\leftkernedhyphen} % \DescribeMacro{\leftkernedhyphen*} % \DescribeMacro{\rightkernedhyphen} % \DescribeMacro{\rightkernedhyphen*} % We also define specialized versions for kerning on the left-hand side or the right-hand side % only. These macros work like their two-argument counterparts and set the opposite kerning to % zero. % % \begin{synopsis}\label{syn:leftkernedhyphen}\label{syn:rightkernedhyphen} % \cs{leftkernedhyphen}\oarg{raise}\marg{left-kerning} \\ % \cs{leftkernedhyphen*}\oarg{raise}\marg{left-kerning} \\[\smallskipamount] % \cs{rightkernedhyphen}\oarg{raise}\marg{right-kerning} \\ % \cs{rightkernedhyphen*}\oarg{raise}\marg{right-kerning} % \end{synopsis} % % \begin{usecases} % Composites in the form \meta{math}-\meta{noun} in languages where nouns are % capitalized.\visualpar Composites where one or both sides of the hyphen are typeset in % different fonts, like, \meta{small-caps}-\meta{roman}. % \end{usecases} % % % \newpagetofixtoc % \subsubsection{En-Dash and Em-Dash}\label{sec:spaced-dashes} % % The macros introduced in this subsection allow for fine-tuning of the whitespace before and % after en-dashes and em-dashes. Each macro set is designed for a specific use. The spaced % en-dash macros are intended to be used where an en-dash is surrounded by normal spaces: % % \begin{center} % \meta{WORD}\code{\textvisiblespace}\textendash\code{\textvisiblespace}\meta{WORD}. % \end{center} % % \noindent % \skip1=\glueexpr\fontdimen2\font plus \fontdimen3\font minus \fontdimen4\font\relax % Typographic improvement may come from reducing the width of the space around the en-dash with % relative to the normal space.\!\footnote{The current font's space width is % \milliemglue{\skip1} compared to \packagename{typog}s % \hyperref[item:endashspace]{\code{endashspace}} width of % \milliemglue{\typogget{endashspace}}.} On the other hand, the em-dash macros assume that % there is no space between the \meta{WORD}s and the em-dash: % % \begin{center} % \meta{WORD}\textemdash\meta{WORD}. % \end{center} % % \noindent % The spaced em-dash macros add some (hairline) space between the em-dash and the \meta{WORD}s, % which helps prevent the em-dash from visually colliding with adjacent words.\!\footnote{Some % fonts offer dashes with no side bearings to facilitate drawing horizontal lines by abutting % these dashes.} % % \paragraph{Line Breaking Around Dashes.} % Package \packagename{typog} offers spaced en- and em-dashes with breakpoints either on the % left-hand side or the right-hand side (or none for any of the starred versions) and this is % reflected in the macro names by \code{left} and \code{right}. All spaced dashes apply equal % amounts of space on both sides of the dash; \singlequotes{left} and \singlequotes{right} % refer to the breakpoints. % % A single dash is used\leftspacedendash among many other cases\rightspacedendash % \marginnote{The insertion, \doublequotes{among~\dots}, is separated by spaced en-dashes.} to % indicate a pause (e.\,g.~announcing an action to be continued), instead of a comma, or even % instead of a period. The typographic rules favor either no line break at all or a break at % the right-hand side~\cite[6.82]{chicago-manual-of-style:2017} of the dash, which also is % \TeX's default. % % Dashes are often used for appositions or explanatory phrases, as in the first sentence above. % In this instance there exist two camps: one emphasizes the insertion and thus couples the % lead-in and lead-out dashes to it (see \cref{item:emphasize-insertion} % below)~\cite[p.~173]{forssman-de-jong:2008}. The other avoids a dash at the beginning of a % line at the cost of severing it from the insertion % (\cref{item:avoid-dash-at-beginning-of-line}). We demonstrate the alternatives with % en-dashes. % % \begin{enumerate} % \item\label{item:emphasize-insertion} % One rule set prefers insertions to be preceded and followed by dashes. The elementary way % to solve this is to say % % \begin{codeexample} % before\textvisiblespace -\nolig*-\textasciitilde insertion\textasciitilde-\nolig*-\textvisiblespace after % \end{codeexample} % % For this solution \packagename{typog} offers \cs{leftspacedendash} and % \cs{rightspacedendash}: % % \begin{codeexample} % before\cs{leftspacedendash} \\ % insertion\cs{rightspacedendash} after % \end{codeexample} % % \item\label{item:avoid-dash-at-beginning-of-line} % Another school insists to avoid dashes at the start of lines. Now the straightforward % solution looks like this: % % \begin{codeexample} % before\textasciitilde-\nolig*-\textvisiblespace insertion\textasciitilde-\nolig*-\textvisiblespace after % \end{codeexample} % % For this scenario both dashes behave like \cs{rightspacedendash} and the alias % \cs{spacedendash} comes in handy: % % \begin{codeexample} % before\cs{spacedendash} \\ % insertion\cs{spacedendash} after % \end{codeexample} % \end{enumerate} % % \index{spaced character>en-dash|userman} % \DescribeMacro{\leftspacedendash} % \DescribeMacro{\leftspaceddash} % \DescribeMacro{\leftspacedendash*} % \DescribeMacro{\leftspaceddash*} % \DescribeMacro{\rightspacedendash} % \DescribeMacro{\rightspaceddash} % \DescribeMacro{\spacedendash} % \DescribeMacro{\spaceddash} % \DescribeMacro{\rightspacedendash*} % \DescribeMacro{\rightspaceddash*} % \DescribeMacro{\spacedendash*} % \DescribeMacro{\spaceddash*} % \sinceversion{All since v0.5} % The four macros \cs{leftspacedendash}, \cs{leftspacedendash*}, \cs{right\-spaced\-endash}, % and \cs{rightspacedendash*} all expand to an en-dash~\sample{--} that is surrounded by % whitespace. They differ in the ways they handle line breaking before or after the en-dash. % % \begin{synopsis}\label{syn:spacedendash} % \begin{tabbing} % \cs{rightspacedendash*}\oarg{raise}\qquad \= \kill % \cs{leftspacedendash}\oarg{raise} \> \cs{leftspaceddash} (alias) \\ % \cs{leftspacedendash*}\oarg{raise} \> \cs{leftspaceddash*} (alias) \\[\smallskipamount] % \cs{rightspacedendash}\oarg{raise} \> \cs{rightspaceddash} (alias) \\ % \> \cs{spacedendash} (alias) \\ % \> \cs{spaceddash} (alias) \\ % \cs{rightspacedendash*}\oarg{raise} % \> \cs{spacedendash*} (alias) \\ % \> \cs{spaceddash*} (alias) % \end{tabbing} % \end{synopsis} % % Typeset an unbreakable en-dash with any of the starred variants. The unstarred % \cs{left\ttdots}\itcorr*{3}-macros have breakpoints at their left-hand sides and the % \cs{right\ttdots}\itcorr*{3}-macros breakpoints at their right-hand sides. % % Configure the size of the space before and after the dash with % option~\hyperref[item:endashspace]{\code{endashspace}}. % % The optional argument~\meta{raise} allows adjusting the height of the en-dash above the % baseline just as the macros in \cref{sec:raise-characters}; it is meant for one-off % solutions. If an en-dash is needed that is both raised and spaced prefer % macro~\hyperref[syn:spacedcapitalendash]{\cs{spacedcapitalendash}}. % % % \begin{important}[\packagename{hyperref} bookmarks]\label{imp:hyperref-bookmarks-spacedendash}\relax % If any of \cs{leftspacedendash}, \cs{rightspacedendash}, \cs{spacedendash}, % \cs{spaceddash}, or \cs{spacedemdash} (see below)\spacedemdash whether starred or % un-starred\spacedemdash occur in an argument that is processed with % package~\packagename{hyperref}\index{hyperref=\packagename{hyperref} (package)|userman} for % inclusion into the document's % \acronym{PDF}-bookmarks\index{PDF=\acronym{PDF}|userman}\index{bookmark|userman} an % additional argument is necessary to parse the macro. This argument either is \cs{relax} % or~the empty group~\sample*{\{\kern.1em\}}. % % We showcase the modifications of the plain calls for macro~\cs{spaceddash}. They apply to % all macros that generate spaced en- and em-dashes. % % \begin{synopsis} % \begin{tabbing} % \cs{spaceddash*}\oarg{raise}\cs{relax}\qquad\= \cs{spaceddash}\oarg{raise}\cs{relax} \\ % \cs{spaceddash*}\oarg{raise}\code{\{\}}\> \cs{spaceddash}\oarg{raise}\code{\{\}} % \end{tabbing} % \end{synopsis} % % The prototypical places where this processing for \acronym{PDF}~bookmarks happens are the % sectioning macros, e.\,g., \cs{chapter}, \cs{section}, \cs{subsection},~etc. % % \LaTeX{} will trip with \doublequotes{Undefined control sequence} on % \cs{typog@\-missing@\-argument} if the extra argument is not passed. % % Alternatively use \cs{texorpdfstring}~\cite[Sec.~4.1.2, p.~22]{package:hyperref}. % \end{important} % % \DescribeMacro{\swapendashskip} % \sinceversion{Since v0.5} % If a \cs{rightspacedendash} is immediately followed by another punctuation mark as, e.\,g., a % comma, the space at the right-hand side of the en-dash is ill-placed. It either should by % removed by following the macro with an \cs{unskip} or \cs{swapendashskip}. Furthermore, % \cs{rightspacedendash} should be made unbreakable. % % \begin{synopsis}\label{syn:swapendashskip} % \cs{swapendashskip}\marg{arg} % \end{synopsis} % % Use \cs{swapendashskip}\marg{arg}, where \meta{arg} typically is a punctuation mark, to % remove the right-hand space of any spaced en-dash macro and put exactly that amount of space % on the right-hand side of \meta{arg}. \Cref{tab:swapendashskip} compares the effects on the % spacing. % % \begin{table} % \centering % \caption[Comparison of \cs{rightspacedendash}-comma combinations] % {Comparison of uncorrected and corrected \cs{right\-spaced\-endash}-comma % combinations for a space width of \nativetextfraction{1}{3}\:em and a % (exaggerated) \hyperref[item:endashspace]{\code{endashspace}} of % \nativetextfraction{1}{2}\:em. We have added \doublequotes{book struts} to the % left and to the right of the results to indicate the width of the output.} % \label{tab:swapendashskip} % % \begin{typogsetup}{endashspace=.5em} % \begin{tabular}{@{}ll@{}} % \toprule % Code & Result \\ % \midrule % \code{\cs{rightspacedendash*},\cs{space}} & % \indicatewidth{\rightspacedendash*,\hspace*{.3333em}} \\ % \code{\cs{rightspacedendash*}\cs{unskip},\cs{space}} & % \indicatewidth{\rightspacedendash*\unskip,\hspace*{.3333em}} \\ % \code{\cs{rightspacedendash*}\cs{swapendashskip},} & % \indicatewidth{\rightspacedendash*\swapendashskip,} \\ % \bottomrule % \end{tabular} % \end{typogsetup} % \end{table} % % \index{spaced character>em-dash|userman} % \DescribeMacro{\leftspacedemdash} % \DescribeMacro{\leftspacedemdash*} % \DescribeMacro{\rightspacedemdash} % \DescribeMacro{\rightspacedemdash*} % \DescribeMacro{\spacedemdash} % \DescribeMacro{\spacedemdash*} % \sinceversion{All since v0.5} % The four macros \cs{leftspacedemdash}, \cs{leftspacedemdash*}, \cs{right\-spaced\-emdash}, % and \cs{rightspacedemdash*} all expand to an em-dash~\sample{---} that is surrounded by % whitespace. They differ in the ways they handle line breaking before or after the em-dash. % % Let us pick up the alternatives explained in the section on en-dashes and adapt them to % em-dashes. Note that by joining words with em-dashes \TeX{} \emph{turns off} automatic % hyphenation, which usually is the right thing to do to avoid confusion with dashes and % hyphens. The spaced em-dash macros duplicate this behavior. % % \begin{enumerate} % \item Tie the em-dashes to the insertion. % % \begin{codeexample} % before\cs{breakpoint}\cs{mbox}\{-\nolig*-\nolig*-\} \\ % insertion-\nolig*-\nolig*-after % \end{codeexample} % % Macro \hyperref[syn:breakpoint]{\cs{breakpoint}} was introduced in % \Cref{sec:latex-hyphenation}. % % \begin{codeexample} % before\cs{leftspacedemdash} \\ % insertion\cs{rightspacedemdash} after % \end{codeexample} % % \item By default \TeX{} inserts breakpoints after em-dashes. So that we can just write % % \begin{codeexample} % before-\nolig*-\nolig*-insertion-\nolig*-\nolig*-after % \end{codeexample} % % The spaced solution with package~\packagename{typog} looks like this: % % \begin{codeexample} % before\cs{spacedemdash} \\ % insertion\cs{spacedemdash} after % \end{codeexample} % \end{enumerate} % % \begin{synopsis}\label{syn:spacedemdash} % \begin{tabbing} % \cs{rightspacedemdash*}\oarg{raise}\qquad \= \kill % \cs{leftspacedemdash}\oarg{raise} \> \cs{leftspaceddash} (alias) \\ % \cs{leftspacedemdash*}\oarg{raise} \> \cs{leftspaceddash*} (alias) \\[\smallskipamount] % \cs{rightspacedemdash}\oarg{raise} \> \cs{rightspaceddash} (alias) \\ % \> \cs{spacedemdash} (alias) \\ % \cs{rightspacedemdash*}\oarg{raise} % \> \cs{spacedemdash*} (alias) % \end{tabbing} % \end{synopsis} % % Typeset an unbreakable em-dash with any of the starred variants. The unstarred % \cs{left\ttdots}\itcorr*{3}-macros have breakpoints at their left-hand sides and the % \cs{right\ttdots}\itcorr*{3}-macros breakpoints at their right-hand sides. % % The size of the space before and after the dash is configured with % option~\hyperref[item:emdashspace]{\code{emdashspace}}. % % The optional argument~\meta{raise} allows adjusting the height of the em-dash above the % baseline just as the macros in \cref{sec:raise-characters}; it is meant for one-off % solutions. If an em-dash is needed that is both raised and spaced prefer % macro~\hyperref[syn:spacedcapitalemdash]{\cs{spacedcapitalemdash}}. % % The same \hyperref[imp:hyperref-bookmarks-spacedendash]{\emph{Important} note} on hyperref % bookmarks holds for \cs{spacedemdash} as for \cs{spacedendash}. % % \begin{note} % Alternatively use package \packagename{microtype} to achieve a similar effect. % Macro~\cs{SetExtraKerning}~\cite[Sec.~5.4]{package:microtype} allows modifying the % side-bearings of any glyph. % \end{note} % % \begin{tip}\label{tip:textemdash-textendash}\relax % \index{textemdash=\verb!*+\textemdash+|userman}\relax % \index{textendash=\verb!*+\textendash+|userman}\relax % The macros rely on \cs{textemdash} and \cs{textendash} to typeset em-dashes and en-dashes. % If different glyphs are desired redefine them (preferably locally). % % \noindent % Example with the fictitious macro~\cs{fancydash}: % % \begin{codeexample} % \cs{let}\cs{origspacedemdash}=\cs{spacedemdash} \\ % \cs{renewcommand*}\=\{\cs{spacedemdash}\} \\ % \>\{\cs{begingroup} \\ % \>~\cs{typogsetup}\{emdashspace=.2pt\}\% \\ % \>~\cs{let}\cs{textemdash}=\cs{fancydash} \\ % \>~\cs{origspacedemdash} \\ % \>~\cs{endgroup}\}\specialsectionendhere % \end{codeexample} % \end{tip} % % % \subsection{Raise Selected Characters}\label{sec:raise-characters} % \index{raised character|userman} % % Usually all hyphens and dashes of a font are designed to join lowercase letters. This holds % also true for most of our \cs{labelitem}\meta{N} markers, bullets, stars, and even fancy % dingbats. If these hyphens and dashes connect uppercase letters (or lining numerals) they % sometimes appear to low; they disrespect the glyphs' symmetry axis. A similar situation % arises if |itemize|~list markers precede an uppercase letter, a lining numeral, or a big % mathematical operator. % % We introduce a set of macros for the most common cases that typeset these characters at a % user definable, adjusted height above the baseline. Readers familiar with % \mbox{OpenType} fonts will be reminded of the \code{case}~feature. Users can base their own % definitions of raised characters on their associated dimensions.\!\footnote{Also compare with % Ex.~12 in reference~\citenum{wermuth:2023} for an attempt to automate vertical alignment.} % % \begin{caution} % The height adjustment disables a font's built-in kerning. % \end{caution} % % \noindent % General note for all raised hyphen-like macros: Prefer the starred version if applied in % front of any punctuation. % % % \subsubsection{Capital Hyphen}\label{sec:capital-hyphen} % \index{raised character>hyphen|userman} % % \DescribeMacro{\capitalhyphen} % \DescribeMacro{\capitalhyphen*} % In many fonts the height of the hyphen character~\sample{-} above the baseline is optimized % for lowercase letters. In languages that capitalize their nouns as, e.\,g., German, this may % be too low for compounds involving capitals. % % \begin{synopsis}\label{syn:capitalhyphen} % \cs{capitalhyphen}\qquad \cs{capitalhyphen*} % \end{synopsis} % % \indexpackageoption{breakpenalty} % The unstarred version introduces a hyphenation opportunity right after the hyphen character % (with penalty~\hyperref[item:breakpenalty]{|breakpenalty|}) whereas the starred version does % not. The actual amount the hyphen gets raised in \cs{capitalhyphen} is determined by % \hyperref[item:raisecapitalhyphen]{|raisecapitalhyphen|}. % % \begin{usecases} % In languages that capitalize their nouns, the typical use-case is between an % \meta{ab\-bre\-vi\-a\-tion} and a \meta{noun} when \meta{ab\-bre\-vi\-a\-tion} is a string % of uppercase letters. The same holds true for a connection of an uppercase variable in % mathematical mode and a \meta{noun} starting with a capital letter.\visualpar Abbreviated % compound first names (e.\,g., A.\capitalhyphen* M.~Legendre) can be joined with the starred % version.\visualpar Also, the starred form is suited for \acronym{ISO~8601}-formatted dates % if they are composed with lining-style numerals. % \end{usecases} % % % \newpagetofixtoc % \subsubsection{Capital En-Dash and Capital Em-Dash}\label{sec:capital-dash} % \index{raised character>en-dash|userman} % % \DescribeMacro{\capitalendash} % \DescribeMacro{\capitalendash*} % \DescribeMacro{\capitaldash} % \DescribeMacro{\capitaldash*} % The situation of the en-dash~\sample{--} is almost identical to the one of the hyphen % character~\sample{-} described in the previous section or the number dash to be introduced in % the next section. % % \begin{synopsis}\label{syn:capitalendash}\label{syn:capitaldash} % \begin{tabbing} % \cs{capitalendash}\qquad\= \cs{capitaldash} (alias) \\ % \cs{capitalendash*} \> \cs{capitaldash*} (alias) % \end{tabbing} % \end{synopsis} % % \indexpackageoption{breakpenalty} % The unstarred version introduces a hyphenation opportunity right after the dash (with % penalty~\hyperref[item:breakpenalty]{|breakpenalty|}) whereas the starred version does not. % \indexpackageoption{raisecapitaldash} % The actual amount the hyphen gets raised in \cs{capitaldash} is determined by % \hyperref[item:raisecapitaldash]{|raisecapitaldash|}. % % \begin{usecases} % Letter ranges as used in the title of an index.\visualpar Any mixed letter-digit ranges % (of capital letters and lining-style numerals) as in e.\,g., Sec.~B\capitaldash* 2. % \end{usecases} % % \index{raised character>em-dash|userman} % \noindent % \DescribeMacro{\capitalemdash} % \DescribeMacro{\capitalemdash*} % For completeness we also introduce a raised em-dash~\sample{---}. It behaves just like its % en-dash sibling. % % \begin{synopsis}\label{syn:capitalemdash} % \cs{capitalemdash}\qquad \cs{capitalemdash*} % \end{synopsis} % % \begin{usecases} % Item symbols in \code{itemized} lists if the item text starts with an uppercase % letter.\visualpar Theorem headings, like, e.\,g., \mbox{Definition 6.2 \capitalemdash{} % \textsc{Lie} Algebra}. % \end{usecases} % % \DescribeMacro{\leftspacedcapitalendash} % \DescribeMacro{\leftspacedcapitaldash} % \DescribeMacro{\leftspacedcapitalendash*} % \DescribeMacro{\leftspacedcapitaldash*} % \DescribeMacro{\rightspacedcapitalendash} % \DescribeMacro{\rightspacedcapitaldash} % \DescribeMacro{\rightspacedcapitalendash*} % \DescribeMacro{\rightspacedcapitaldash*} % \sinceversion{All since v0.5} % Combine raising a en-dash and adding some extra space around it. % % \begin{list}{}{\leftmargin=15pt \rightmargin=-30pt}\item % \begin{synopsis}\label{syn:spacedcapitalendash} % \begin{tabbing} % \cs{rightspacedcapitalendash*}\qquad \= \kill % \cs{leftspacedcapitalendash} \> \cs{leftspacedcapitaldash} (alias) \\ % \cs{leftspacedcapitalendash*} \> \cs{leftspacedcapitaldash*} (alias) \\[\smallskipamount] % \cs{rightspacedcapitalendash} \> \cs{rightspacedcapitaldash} (alias) \\ % \> \cs{spacedcapitalendash} (alias) \\ % \> \cs{spacedcapitaldash} (alias) \\ % \cs{rightspacedcapitalendash*} % \> \cs{spacedcapitalendash*} (alias) \\ % \> \cs{spacedcapitaldash*} (alias) % \end{tabbing} % \end{synopsis} % \end{list} % % These macros unite the features of \hyperref[syn:capitalendash]{\cs{capitalendash}} with % those of \hyperref[syn:spacedendash]{\cs{spacedendash}} as described in % \cref{sec:spaced-dashes}. % % \DescribeMacro{\leftspacedcapitalemdash} % \DescribeMacro{\leftspacedcapitalemdash*} % \DescribeMacro{\rightspacedcapitalemdash} % \DescribeMacro{\rightspacedcapitalemdash*} % \DescribeMacro{\spacedcapitalemdash} % \DescribeMacro{\spacedcapitalemdash*} % \sinceversion{All since v0.5} % Combine raising a em-dash and adding some extra space around it. % % \begin{list}{}{\leftmargin=15pt \rightmargin=-30pt}\item % \begin{synopsis}\label{syn:spacedcapitalemdash} % \begin{tabbing} % \cs{rightspacedcapitalemdash*}\qquad \= \kill % \cs{leftspacedcapitalemdash} \\ % \cs{leftspacedcapitalemdash*} \\[\smallskipamount] % \cs{rightspacedcapitalemdash} % \> \cs{spacedcapitalemdash} (alias) \\ % \cs{rightspacedcapitalemdash*} % \> \cs{spacedcapitalemdash*} (alias) % \end{tabbing} % \end{synopsis} % \end{list} % % These macros unite the features of \hyperref[syn:capitalemdash]{\cs{capitalemdash}} with % those of \hyperref[syn:spacedemdash]{\cs{spacedemdash}} as described in % \cref{sec:spaced-dashes}. % % \begin{tip} % \index{textemdash=\verb!*+\textemdash+|userman}\relax % \index{textendash=\verb!*+\textendash+|userman}\relax % The macros rely on \cs{textemdash} and \cs{textendash} to typeset em-dashes and en-dashes. % If different glyphs are desired redefine them (preferably locally). % % See the \hyperref[tip:textemdash-textendash]{tip} on \cpageref{tip:textemdash-textendash} % for a code example. % \end{tip} % % % \subsubsection{Number Dash (Figure Dash)}\label{sec:number-dash} % \index{raised character>number dash|userman} % % \DescribeMacro{\figuredash} % \DescribeMacro{\figuredash*} % The en-dash often gets used as separator for numerical ranges. In most fonts it has the % correct height above baseline for oldstyle numerals, % e.\,g.~\oldstylenums{12}--\oldstylenums{34}--\oldstylenums{56}--\oldstylenums{78}, but with % lining numerals\leftspacedendash depending on the font\rightspacedendash it may look like % it suffers from \doublequotes{broken suspenders}: % 12\textendash34\textendash56\textendash78.\marginnote{\cs{figuredash} yields % 12\figuredash34\figuredash56\figuredash78 for sans-serif and {\rm % 12\figuredash34\figuredash56\figuredash78} for the roman typeface.} The situation is similar % to \cs{capitaldash} and \cs{capitalhyphen} discussed in % \cref{sec:capital-hyphen,sec:capital-dash}. % % \begin{synopsis}\label{syn:figuredash} % \cs{figuredash}\qquad \cs{figuredash*} % \end{synopsis} % % \indexpackageoption{breakpenalty} % The unstarred version introduces a hyphenation opportunity right after the en-dash with % penalty~\hyperref[item:breakpenalty]{|breakpenalty|} whereas the starred version does not. % \indexpackageoption{raisefiguredash} % The actual amount the en-dash gets raised in \cs{figuredash} is determined by % \hyperref[item:raisefiguredash]{|raisefiguredash|}. % % Values of .05\,em to .1\,em are typical for fonts that need this kind of correction % and~.1\,em is a good starting point. \Cref{tab:raisefiguredash} summarizes some findings. % % \begin{table} % \centering % \caption[Suggested raise amounts for \cs{figuredash}]% % {Suggested values for raising \cs{figuredash}, which actually is an en-dash, % between lining numerals of some selected fonts in multiples of~1\,em.} % \label{tab:raisefiguredash} % % \newcommand*{\fbbmark}{\tablenotemark{\tablenotesymbol{1}}} % % \begin{tabfigures} % \begin{tabularx}{\linewidth}{@{}>{\RaggedRight}Xl@{}} % \toprule % Font & Raise \\ % \midrule % Alegreya\detoxindex{font>typeface>Alegreya|userman}, Arvo\detoxindex{font>typeface>Arvo|userman}, % Bitter\detoxindex{font>typeface>Bitter|userman}, Clara\detoxindex{font>typeface>Clara|userman}, % \acronym{EB}~Garamond\detoxindex{font>typeface>EB Garamond=\acronym{EB} Garamond|userman}, % Gentium\detoxindex{font>typeface>Gentium|userman}, % Ibarra Real Nova\detoxindex{font>typeface>Ibarra Real Nova|userman}, % \acronym{Inria}~Serif\detoxindex{font>typeface>Inria Serif=\acronym{Inria} Serif|userman}, % Libertine\detoxindex{font>typeface>Libertine|userman}, % Libertinus\detoxindex{font>typeface>Libertinus Serif|userman}, % Merriweather\detoxindex{font>typeface>Merriweather|userman}, % \acronym{PT}~Serif\detoxindex{font>typeface>PT Serif=\acronym{PT} Serif|userman}, % Roboto Slab\detoxindex{font>typeface>Roboto Slab|userman}, % Spectral\detoxindex{font>typeface>Spectral|userman}, % \acronym{STIX}\detoxindex{font>typeface>STIX=\acronym{STIX}|userman}, and many more & % .0 \\ % Charis \acronym{SIL}\detoxindex{font>typeface>Charis SIL=Charis \acronym{SIL}|userman}, % fbb\fbbmark\detoxindex{font>typeface>fbb|userman}\!, % Source Serif Pro\detoxindex{font>typeface>Source Serif Pro|userman} & % .05 \\ % Libre Baskerville\detoxindex{font>typeface>Libre Baskerville|userman}, % Crimson Pro\detoxindex{font>typeface>Crimson Pro|userman}, % Erewhon\detoxindex{font>typeface>Erewhon|userman}, % Droid Serif\detoxindex{font>typeface>Droid Serif|userman} & % .0667 \\ % \acronym{GFS}~Artemisia\detoxindex{font>typeface>GFS Artemisia=\acronym{GFS} Artemisia|userman}, % Libre Caslon\detoxindex{font>typeface>Libre Caslon|userman}, % Coelacanth\detoxindex{font>typeface>Coelacanth|userman}, % Crimson Pro\detoxindex{font>typeface>Crimson Pro|userman}, % Crimson Text\detoxindex{font>typeface>Crimson Text|userman}, % \TeX{} Gyre~Pagella\detoxindex{font>typeface>TeX Gyre Pagella=\TeX{} Gyre Pagella|userman}, % Quattrocento\detoxindex{font>typeface>Quattrocento|userman}, % \acronym{TX}~Fonts\detoxindex{font>typeface>TX Fonts=\acronym{TX} Fonts|userman}, % \acronym{ADF}~Venturis\detoxindex{font>typeface>ADF Venturis=\acronym{ADF} Venturis|userman}, % and many more & % .1 \\ % \bottomrule % \end{tabularx} % \end{tabfigures} % % \begin{tablenotes} % \renewcommand*{\tablenotemark}[1]{#1}% % \fbbmark\enspace Free Bembo. % \end{tablenotes} % \end{table} % % Other macros may be redefined with \cs{figuredash} for a consistent appearance of the copy, % like, for example, \cs{citedash} (package~\packagename{cite}~\cite{package:cite}), or % \cs{crefrangeconjunction} (package~\packagename{cleveref}~\cite{package:cleveref}). % % \begin{usecase} % The key customers of \cs{figuredash} are the |PAGES|~entries of bibliography % databases.\visualpar In an index generated with \command{makeindex} the range % delimiter~\code{delim\_r} is a candidate for \cs{figuredash*}. % \end{usecase} % % % \newpagetofixtoc % \subsubsection[Multiplication Sign]% % {Multiplication Sign -- Times~\sample{\texttimes}}\label{sec:mult-sign} % \index{raised character>multiplication sign|userman} % % \DescribeMacro{\capitaltimes} % The \cs{capitaltimes}~macro is a variation of the % \hyperref[syn:capitalhyphen]{\cs{capitalhyphen}}~theme. % % \begin{synopsis}\label{syn:capitaltimes} % \cs{capitaltimes} % \end{synopsis} % % \indexpackageoption{raisecapitaltimes} % In text mode, it expands to an appropriately raised \cs{texttimes}, and in math~mode to a % raised \cs{times} binary~operator, where % \hyperref[item:raisecapitaltimes]{|raisecapitaltimes|} determines the amount of % upward-shifting applied; it never inserts any break points. % % \begin{usecase} % Prime use are two- or higher-dimensional shape specifications with lining numerals or % uppercase letters in mathematical mode as, for example, matrix or tensor sizes. % \end{usecase} % % % \subsubsection{Guillemets}\label{sec:guillemets} % \index{raised character>guillemets|userman} % % Another possible typographic problem this package addresses is that both % sets\leftspacedendash\marginnote{The sentence uses % \hyperref[syn:spacedendash]{\cs{left\-spaced\-endash}} and % \hyperref[syn:spacedendash]{\cs{right\-spaced\-endash}}.} single and double % quotes\rightspacedendash of guillemets may suffer from a too small distance to the baseline. % % For the implementation \packagename{typog} relies on the T1\footnote{Font % encoding~T1\detoxindex{font>encoding|userman} can be forced via % \cs{usepackage}|[T1]\{fontenc\}| in the document preamble.}~font encoding not on % package~\packagename{babel}. % % % \paragraph{Lowercase Versions.} % % \DescribeMacro{\singleguillemetleft} % \DescribeMacro{\singleguillemetright} % \DescribeMacro{\doubleguillemetleft} % \DescribeMacro{\doubleguillemetright} % \begin{synopsis} % \label{syn:singleguillemetleft} % \label{syn:singleguillemetright} % \label{syn:doubleguillemetleft} % \label{syn:doubleguillemetright} % \begin{tabbing} % \cs{singleguillemetleft}\qquad\= \cs{singleguillemetright} \\ % \cs{doubleguillemetleft}\> \cs{doubleguillemetright} % \end{tabbing} % \end{synopsis} % % \noindent % For consistency and easy accessibility we define height-adjusted left and right single % guillemets as \cs{singleguillemetleft} and \cs{singleguillemetright}; double guillemets are % available with \cs{doubleguillemetleft} and \cs{doubleguillemetright}. % \indexpackageoption{raiseguillemets} % Their heights above the baseline are collectively adjusted with % \hyperref[item:raiseguillemets]{|raiseguillemets|}. % % % \paragraph{Uppercase Versions.} % % \DescribeMacro{\Singleguillemetleft} % \DescribeMacro{\Singleguillemetright} % \DescribeMacro{\Doubleguillemetleft} % \DescribeMacro{\Doubleguillemetright} % \begin{synopsis} % \label{syn:Singleguillemetleft} % \label{syn:Singleguillemetright} % \label{syn:Doubleguillemetleft} % \label{syn:Doubleguillemetright} % \begin{tabbing} % \cs{Singleguillemetleft}\qquad\= \cs{Singleguillemetright} \\ % \cs{Doubleguillemetleft}\> \cs{Doubleguillemetright} % \end{tabbing} % \end{synopsis} % % \noindent % The companion set of single, double, left, and right quotes corrected for uppercase letters % or lining numerals is \cs{Singleguillemetleft} and \cs{Singleguillemetright} and % \cs{Doubleguillemetleft} and \cs{doubleguillemetright}. Mnemonic: These macros start with an % uppercase letter. % \indexpackageoption{raisecapitalguillemets} % Their height above the baseline is adjusted with % \hyperref[item:raisecapitalguillemets]{|raisecapitalguillemets|}. Values of .025\,em to % .075\,em are typical for fonts that need this kind of correction. \Cref{tab:raiseguillemets} % summarizes some findings. % % \begin{table} % \centering % \caption[Suggested raise amounts for guillemets]% % {Suggested values for raising guillemets of some selected fonts in multiples % of~1\,em.} % \label{tab:raiseguillemets} % % \begin{tabfigures} % \def~{\hphantom{0}} % \begin{tabular}{@{}>{\RaggedRight}p{.5\textwidth}cc@{}} % \toprule % Font & Uppercase & Lowercase \\ % \midrule % \acronym{EB} Garamond\detoxindex{font>typeface>EB Garamond=\acronym{EB} Garamond|userman}, % Libertinus\index{font>typeface>Libertinus Serif|userman}, % Merriweather\index{font>typeface>Merriweather|userman}, and many more & % .05~~ & .0~~~ \\ % Gentium\index{font>typeface>Gentium|userman} & % .05~~ & .025~ \\ % \acronym{GFS} Artemisia\detoxindex{font>typeface>GFS Artemisia=\acronym{GFS} Artemisia|userman}, % \acronym{GFS} Didot\detoxindex{font>typeface>GFS Didot=\acronym{GFS} Didot|userman} & % .0625 & .05~~ \\ % Charis \acronym{SIL}\detoxindex{font>typeface>Charis SIL=Charis \acronym{SIL}|userman} & % .0667 & .0333 \\ % \acronym{ADF} Baskervald\index{font>typeface>ADF Baskervald=\acronym{ADF} Baskervald|userman} & % .0667 & .04~~ \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \end{table} % % \begin{tip} % Define shorthand macros that simplify the application of guillemets, like, e.\,g., % % \begin{codeexample} % \cs{newcommand*}\= \{\= \cs{singlequotes}\}[1] \\ % \> \{\cs{singleguillemetright} \#1\% \\ % \> \> \cs{singleguillemetleft}\} \\ % \cs{let}\cs{sq}=\cs{singlequotes} % \end{codeexample} % % \noindent % and similar definitions for \cs{Singlequotes}, \cs{doublequotes}, and \cs{Doublequotes}. % % Users working according to the French typesetting conventions will want to add extra % spacing between the guillemets and the macro argument already in these macros. % \end{tip} % % \noindent % Whether the guillemets must be height-adjusted for lowercase letters depends on the font. % Careful judgment at various magnifications with a variety of samples is necessary. % % % \paragraph{Interaction with package~\packagename{csquotes}.} % \index{csquotes=\packagename{csquotes} (package)|userman} % % The users of package~\packagename{csquotes} % can hook up the guillemets as defined by \packagename{typog} % with \cs{DeclareQuoteStyle}: % % \begin{codeexample} % 12\=\kill % \cs{DeclareQuoteStyle}\{typog-guillemets\} \\ % \> \{\cs{doubleguillemetright}\}\%\qquad\= opening outer mark \\ % \> \{\cs{doubleguillemetleft}\}\% \> closing outer mark \\ % \> \{\cs{singleguillemetright}\}\% \> opening inner mark \\ % \> \{\cs{singleguillemetleft}\}\% \> closing inner mark % \end{codeexample} % % \noindent % As always, the influence of package~\packagename{babel} on \packagename{csquotes} has to be % put into consideration. See Sec.~8 of the \packagename{csquotes}~manual for a description of % its configuration possibilities. % % \begin{usecase} % All-capital words as for example acronyms put in guillemets that are raised somewhat almost % always look better, whether using the French typographic convention (guillemets pointing % outward plus some extra kerning) or the other way round (guillemets pointing inward). % \end{usecase} % % \begin{futuredirection} % A correction in the other direction, i.\,e., lowering certain characters may also be % desirable, to visually align them to the surrounding copy. Parentheses and in particular % square brackets around all-lowercase text come into mind. % \end{futuredirection} % % % \subsubsection[Inverted Marks] % {Inverted Exclamation Mark and % Inverted Question Mark}\label{sec:inverted-marks} % \index{inverted>exclamation mark|userman} % \index{inverted>question mark|userman} % \index{raised character>inverted exclamation mark|userman} % \index{raised character>inverted question mark|userman} % % The Spanish (Castilian, Asturian, etc.) language requires exclamatory sentences and questions % to be followed by exclamation marks and question marks and recommends that they are preceded % by inverted (or \singlequotes{upside-down}) versions of these punctuation characters. % % Usually the horizontally-mirrored versions' designs follow that of the lowercase letters. In % particular the inverted marks exhibit descenders (see left-hand side of % \cref{fig:inverted-marks}). For all-uppercase or all-smallcaps phrases, e.\,g.~in headlines % the descending parts of these marks disturb the tight block structure and it may be % preferable to have inverted marks that align with the baseline. % % \hangindent=3\parindent % \hangafter=-3 % \noindent % \DescribeMacro{\capitalinvertedexclamationmark} % \DescribeMacro{\capitalinvertedquestionmark} % \sinceversion{Both since v0.5} % The macros \cs{capitalinvertedexclamationmark} and \cs{capitalinvertedquestionmark} % simultaneously provide bottom-aligned inverted marks for up to three different sets of % exclamation marks or question marks, e.\,g., for uppercase, med-caps, and small-caps % text\footnote{The small exclamation and question marks even made it into Unicode.} or just % for some stylistic alternatives offered by particularly well equipped fonts. % % \begin{synopsis} % \label{syn:capitalinvertedexclamationmark} % \label{syn:capitalinvertedquestionmark} % \cs{capitalinvertedexclamationmark}\marg{number} \\ % \cs{capitalinvertedquestionmark}\marg{number} % \end{synopsis} % % Typeset inverted exclamation marks and inverted question mark. Select the appropriate mark % and the associated raise-amount with \meta{number}=1, 2, or~3. We sketch the result of the % automated correction process in \Cref{fig:inverted-marks}. % % \iffalse %<*invertedmarks> prologues := 3; bboxmargin := 0;% Extremely important setting: otherwise all our bboxes are too loose! linecap := butt; truecorners := 1; string roman_font; roman_font := "pplr8r"; % URW Palladio L - Roman font_scale := 5; picture letter_a; letter_a := thelabel("a" infont roman_font scaled font_scale, origin); path bbox_a; bbox_a := bbox letter_a; ex_height := ypart (ulcorner bbox_a - llcorner bbox_a); show ex_height; picture letter_g; letter_g := thelabel("g" infont roman_font scaled font_scale, origin); path bbox_g; bbox_g := bbox letter_g; descender_height := ypart (ulcorner bbox_g - llcorner bbox_g) - ex_height; show descender_height; string inverted_exclamation_mark_char; inverted_exclamation_mark_char := char(161); string inverted_question_mark_char; inverted_question_mark_char := char(191); picture font_sample; font_sample := thelabel(("g" & inverted_exclamation_mark_char & "jk" & inverted_question_mark_char & "y " & inverted_exclamation_mark_char & " E! " & inverted_question_mark_char & " Q?") infont roman_font scaled font_scale, origin); path bbox_sample; bbox_sample := bbox font_sample; %% The locations of shifted_inverted_exclamation_mark and %% shifted_inverted_question_mark are 100% pure fudge! picture shifted_inverted_exclamation_mark; shifted_inverted_exclamation_mark := thelabel(inverted_exclamation_mark_char infont roman_font scaled font_scale, font_scale * (2.6, 1.333)); picture shifted_inverted_question_mark; shifted_inverted_question_mark := thelabel(inverted_question_mark_char infont roman_font scaled font_scale, font_scale * (20.6, 1.333)); beginfig(1); draw font_sample; draw shifted_inverted_exclamation_mark withcolor .8 white; draw shifted_inverted_question_mark withcolor .8 white; draw (xpart (llcorner bbox_sample), ypart (llcorner bbox_sample) + descender_height) -- (xpart (lrcorner bbox_sample), ypart (lrcorner bbox_sample) + descender_height) withpen pencircle scaled .3333pt; draw (llcorner bbox_sample) -- (lrcorner bbox_sample) dashed evenly withpen pencircle scaled .25pt; draw (xpart (llcorner bbox_sample), ypart (llcorner bbox_sample) + descender_height + ex_height) -- (xpart (lrcorner bbox_sample), ypart (lrcorner bbox_sample) + descender_height + ex_height) dashed evenly withpen pencircle scaled .25pt; endfig; end % % \fi % % \begin{figure} % \centering % \includegraphics{inverted-marks-1.mps} % \caption[Inverted exclamation and question marks] % {The left-hand sample shows the inverted exclamation marks and question marks % wedged between some lowercase letters. The baseline is drawn with a solid lineand % the ex-height as well as the descender depth are indicated with dashed % lines.\visualpar On the right hand side we display the same marks in conjunction % with capital letters. The gray glyphs demonstrate the result of shifting them up % such that they exactly touch the baseline, which mimics the auto-raise mode % described in the text.\visualpar The sample font once again is % \acronym{URW}~Palladio% % \detoxindex{font>typeface>URW Palladio=\acronym{URW} Palladio|userman}.% % \label{fig:inverted-marks}} % \end{figure} % % \indexpackageoption{raiseinvertedmarks} % Inverted exclamation and inverted question marks by the same \meta{number} are raised by the % same amount which is configurable with % option~\hyperref[item:raiseinvertedmarks]{\code{raiseinvertedmarks}}, where \meta{number} % corresponds to the dimension at position~\meta{number}. If the dimension is equal to % \formatdimen*{0pt} the marks are auto-raised as shown in \cref{fig:inverted-marks}. This may % amount to different lengths for the inverted exclamation mark and inverted question mark even % at the same \meta{number}. A nonzero dimension raises the marks by exactly that length. To % get a near-zero length use e.\,g.~1\,sp. % % \begin{tip} % \index{itcorr=\verb!*+\itcorr+|userman}\relax % The letters \sample{\itcorr{-2}V}, \sample{\itcorr{-2}W}, and \sample{\itcorr{-1}Y} % following an inverted question mark may need some manual kerning as well as % \sample{\itcorr{3}J} following an inverted exclamation mark. % Macro~\hyperref[syn:itcorr]{\cs{itcorr}} (\cpageref{syn:itcorr}) offers a solution that is % almost portable across font changes and a \meta{strength} of \textminus1 is a good starting % point. % \end{tip} % % The user-side macros \cs{capitalinvertedexclamationmark}\marg{number} and % \cs{capitalinvertedquestionmark}\marg{number} call the parameter-less, internal macros % % \begin{synopsis} % \cs{typog@inverted@exclamationmark@}\meta{roman-numeral} \\ % \cs{typog@inverted@questionmark@}\meta{roman-numeral} % \end{synopsis} % % \index{textexclamdown=\verb!*+\textexclamdown+|userman} % \index{textquestiondown=\verb!*+\textquestiondown+|userman} % \noindent % where \meta{roman-numeral}=\code{i}, \code{ii}, and~\code{iii} correpspond to % \meta{number}=1, 2, and~3. Their defaults are \cs{textexclamdown} and \cs{textquestiondown} % for all three numbers. Users can redefine the internal macros to hook up special fonts or % characters. % % % \subsection[Vertically Adjust Label Items] % {Vertically Adjust Label Items of % Environment \code{itemize}}\label{sec:adjust-label-items} % \index{label items|userman} % % \begin{whittyquote} % Perfection of planned layout \\ % is achieved only by institutions \\ % on the point of collapse. \\ % \capitalemdash*~\propername{Cyril Northcote Parkinson} % \end{whittyquote} % % \noindent % The symbols that \LaTeX{} uses to distinguish the items of |itemize|~lists do not always % align well in the vertical direction with the following text. Sometimes the label is too % low, especially if followed by an uppercase (initial) letter. In rare occasions the label is % placed too far above the baseline. If any label has been taken from a math-font vertical % alignment with the text font is almost purely accidental.\!\footnote{The exception being % mathematics typeset as text via package~\packagename{mathastext}~\cite{package:mathastext}.} % % \hangindent=2\parindent % \hangafter=-3 % \noindent % \DescribeMacro{\uppercaseadjustlabelitems} % \DescribeMacro{\lowercaseadjustlabelitems} % \DescribeMacro{\noadjustlabelitems} % \sinceversion{All three since v0.5} % Package~\packagename{typog} lets the user vertically align the \code{itemize}~labels for % subsequent uppercase or lowercase letters, where the designations~\singlequotes{uppercase} % and \singlequotes{lowercase} are just names for two four-tuples of lengths (technically: % |dimen|s) to shift the labels up or down. % % \begin{synopsis} % \label{syn:lowercaseadjustlabelitems} % \label{syn:noadjustlabelitems} % \label{syn:uppercaseadjustlabelitems} % \cs{uppercaseadjustlabelitems}\marg{levels-to-adjust} \\ % \cs{lowercaseadjustlabelitems}\marg{levels-to-adjust} \\ % \cs{noadjustlabelitems}\marg{levels-to-adjust} % \end{synopsis} % % \indexpackageoption{lowercase\-labelitem\-adjustments} % \indexpackageoption{uppercase\-labelitem\-adjustments} % Apply uppercase adjustment, lowercase adjustment or no adjustment to the labels in % |itemize|~environments at the \meta{levels-to-adjust}. The adjustment values themselves, % this is the vertical shifts are configured with % options~\hyperref[item:uppercaselabelitemadjustments]{\code{uppercaselabelitemadjustments}} % and~\hyperref[item:lowercaselabelitemadjustments]{\code{lowercaselabelitemadjustments}}. % They are doubly font dependent: on the one hand the font where the label itself comes from % and on the other hand the font of the copy. % % The argument \meta{levels-to-adjust} is a\leftspacedendash possibly empty\rightspacedendash % comma separated list of the levels the adjustments are to be applied to. The levels % themselves are given as \emph{decimal} numbers, this is, 1, 2, 3, 4 or the special % value~\samplestar{} which stands for all four levels. An empty argument list also has a % special meaning. Used within any \code{itemize}~environment it automatically applies the % adjustment to exactly this level. % % \begin{example} % \begin{typogsetup}{uppercaselabelitemadjustments={.1em}} % With the flexible syntax the following settings are possible. % % \renewcommand*{\labelitemi}{{\small$\rhd$}}% % \begin{itemize}\uppercaseadjustlabelitems{} % \item Correct all |itemize| labels for uppercase letters. % % \begin{codeexample} % \cs{uppercaseadjustlabelitems}\{*\} % \end{codeexample} % % \item Adjust nesting levels~1, 2, and~3 for uppercase letters and level~4 for lowercase. % % \begin{codeexample} % \cs{lowercaseadjustlabelitems}\{4\} \\ % \cs{uppercaseadjustlabelitems}\{2,3,1\} % \end{codeexample} % % \item Within an |itemize|~environment just turn off any correction for this level whatever % it may be. % % \begin{codeexample} % \cs{begin}\{itemize\} \\ % \cs{noadjustlabelitems}\{\} \\ % \cs{item} \ttdots \\ % \cs{end}\{itemize\} % \end{codeexample} % % \item Override \cs{labelitemi} with a right-pointing triangle and adjust its vertical % position inside of a \code{typogsetup}~environment. % % \begin{codeexample} % \cs{begin}\=\{typogsetup\} \\ % \>\{uppercaselabelitemadjustments=\{.1em\}\} \\ % 12\=34567890 \kill % \>\cs{renewcommand*}\{\cs{labelitemi}\}\{\{\cs{small}\$\cs{rhd}\$\}\} \\ % \>\cs{begin}\{itemize\} \\ % \>\cs{uppercaseadjustlabelitems}\{\} \\ % \>\cs{item} \ttdots \\ % \>\cs{end}\{itemize\} \\ % \cs{end}\{typogsetup\} % \end{codeexample} % \end{itemize} % % The observant reader will have noticed that the itemized list in this example uses this % code. % \end{typogsetup} % \end{example} % % % \paragraph{Setup.} % % To assist the user in finding the desired adjustments of the labels of \packagename{typog} % provides macros that help setting up % \hyperref[item:lowercaselabelitemadjustments]{\code{lowercaselabelitemadjustments}} and % \hyperref[item:uppercaselabelitemadjustments]{\code{uppercaselabelitemadjustments}}. Their % intended uses are in the draft phase of a document or in non-printed sections of the text. % % The macros assume a \singlequotes{correct} height that they derive from the measured height % of a sample text scaled by a user-defined factor, which defaults % to~\nativetextfraction{1}{2}.\!\footnote{The default factor of~\nativetextfraction{1}{2} % hearkens back to \propername{Strizver's} suggestion that \doublequotes{[b]ullets should be % centered on either the cap~height or x-height of the neighboring % text,~[\dots].}~\cite[p.~220]{strizver:2014}.} The then correct height gets indicated by a % thin horizontal line parallel to the baseline. Thus, at sufficiently high magnifications it % is possible to judge whether a label gets typeset too high or too low with respect to this % reference line. % % \begin{note} % The macros use the actual height of a given sample~text. So, a lowercase~sample should not % contain any letters with ascenders. % % Swashes whether upper- or lowercase always need special attention. % \end{note} % % \DescribeMacro{\Adjustedlabelitemi} % \DescribeMacro{\Adjustedlabelitemii} % \DescribeMacro{\Adjustedlabelitemiii} % \DescribeMacro{\Adjustedlabelitemiv} % \DescribeMacro{\adjustedlabelitemi} % \DescribeMacro{\adjustedlabelitemii} % \DescribeMacro{\adjustedlabelitemiii} % \DescribeMacro{\adjustedlabelitemiv} % \sinceversion{All eight since v0.5} % Sometimes uppercase-adjusted or lowercase-adjusted label items are needed outside of % \code{itemize}~environments. % % \begin{synopsis}\label{syn:Adjustedlabelitem}\label{syn:adjustedlabelitem} % \begin{tabular}{@{}l@{\hspace{2em}}l@{}} % \cs{Adjustedlabelitemi} & \cs{adjustedlabelitemi} \\ % \cs{Adjustedlabelitemii} & \cs{adjustedlabelitemii} \\ % \cs{Adjustedlabelitemiii} & \cs{adjustedlabelitemiii} \\ % \cs{Adjustedlabelitemiv} & \cs{adjustedlabelitemiv} % \end{tabular} % \end{synopsis} % % Typeset label items that are height-adjusted according to % \hyperref[item:uppercaselabelitemadjustments]{\code{uppercaselabelitemadjustments}} or % \hyperref[item:lowercaselabelitemadjustments]{\code{lowercaselabelitemadjustments}} either % for uppercase (macros starting with a capital~\sample{A}) or lowercase (macros starting with % a small~\sample{a}). These macros can be used anywhere. They are \emph{not} controlled by % \hyperref[syn:uppercaseadjustlabelitems]{\cs{uppercaseadjustlabelitems}}, % \hyperref[syn:lowercaseadjustlabelitems]{\cs{lowercaseadjustlabelitems}}, nor % \hyperref[syn:noadjustlabelitems]{\cs{noadjustlabelitems}}. % % \begin{usecases} % Free, user-defined lists.\visualpar % Injection of \packagename{typog}'s height-adjustment functionality in other packages as, % for example, \packagename{tasks}~\cite{package:tasks}. % \end{usecases} % % \DescribeMacro{\typogadjuststairs} % \sinceversion{Since v0.5} % To get a quick overview how the four \code{itemize}~labels align vertically % \cs{typogadjuststairs} draws them at user-defined steps, typically % \nativetextfraction{1}{4}\,pt, \nativetextfraction{1}{3}\,pt, or % \nativetextfraction{1}{2}\,pt. It ignores any existing adjustments and in that way can be % utilized as a first configuration step or, for a small \meta{step-size} and a high % \meta{number-of-steps}, for an easy refinement. % % \begin{synopsis} % \begin{tabbing} % \label{syn:typogadjuststairs} % \cs{typogadjuststairs}\=[\meta{scale-factor}=.5] \\ % \>\marg{step-size}\marg{number-of-steps} \\ % \>\marg{sample} % \end{tabbing} % \end{synopsis} % % Generate stairs of \meta{number-of-steps} vertically shifted label items; use the next odd % number, if \meta{number-of-steps} is even. Draw a reference hairline at \meta{scale-factor} % times the height of \meta{sample}, where \meta{scale-factor} defaults to~.5. The stairs % start at a vertical shift of % \begin{gather*} % -\frac{\text{\meta{number-of-steps}} - 1}{2} \times \text{\meta{step-size}} \\ % \intertext{and repeat up to} % \frac{\text{\meta{number-of-steps}} - 1}{2} \times \text{\meta{step-size}}. % \end{gather*} % % The central step\leftspacedendash which is always surrounded by a bit more % space\rightspacedendash shows the neutral, uncorrected alignment, this is, 0\,pt. % \cs{typogadjuststairs} never prints the contents of \meta{sample}. % % \begin{example} % Play ball! % % \begin{center} % \typogadjuststairs{.25pt}{11}{ABC} % \end{center} % % This is the result of \code{\string\typogadjuststairs\{.25pt\}\{11\}\{ABC\}} with the % document's definitions of \cs{labelitem}\meta{N}. The middle (6\textsuperscript{th}) % label~item in each line is the uncorrected one. % \end{example} % % \hangindent=2\parindent % \hangafter=-3 % \noindent % \DescribeMacro{\typoguppercaseadjustcheck} % \DescribeMacro{\typoglowercaseadjustcheck} % \sinceversion{Both since v0.5} % For a quick and easy check how the four label items vertically align \emph{as configured} use % \code{\string\typoguppercaseadjustcheck} and \code{\string\typoglowercaseadjustcheck}. % Experienced users with a keen eye for type can apply these macros even in the initial setup. % An accurate determination of \code{uppercaselabelitemadjustments} and % \code{lowercaselabelitemadjustments} is preferably done at a high magnification (e.\,g., % 400\% to 600\% on a 100\,dpi screen) with a representative sample of initial letters. % % \begin{synopsis} % \label{syn:typoguppercaseadjustcheck} % \label{syn:typoglowercaseadjustcheck} % \cs{typoguppercaseadjustcheck}[\meta{scale-factor}=.5]\marg{sample} \\ % \cs{typoglowercaseadjustcheck}[\meta{scale-factor}=.5]\marg{sample} % \end{synopsis} % % Typeset all four label items adjusted for uppercase or for lowercase with an indicator line % at \meta{scale-factor} times the \meta{sample}'s actual height. The default % \meta{scale-factor} is~.5. Both macros refer to the currently configured values for the % uppercase or lowercase adjustments but they are independent of any settings done with % \cs{uppercaseadjustlabelitems}, \cs{lowercaseadjustlabelitems}, or \cs{noadjustlabelitems}. % Again, \meta{sample} does not get printed. % % \begin{example} % Uppercase check with \code{\string\typoguppercaseadjustcheck\{ABCXYZ\}}: % % \centering % ABGH\typoguppercaseadjustcheck{ABCXYZ}QWYZ,\enspace % 0123\typoguppercaseadjustcheck{ABCXYZ}4567 % % \justifying % \noindent % and similarly for lowercase: \code{\string\typoglowercaseadjustcheck\{acexyz\}}: % % \centering % ace\typoglowercaseadjustcheck{acexyz}mno,\enspace % bdf\typoglowercaseadjustcheck{acexyz}gjy,\enspace % {\proportionaloldstylefigures 0123\typoglowercaseadjustcheck{acexyz}4567,} % % \justifying % \noindent % where we have bracketed the macro calls with selected uppercase and lowercase letters, or % suitable figures. % \end{example} % % In \Cref{tab:labelitemadjustvalues} on \cpageref{tab:labelitemadjustvalues} we collected some % suggestions for adjustment values in the \emph{default} case when the label items are not % redefined by the user and expand like % % \begin{center} % \def\arraystretch{1} % \begin{tabular}{@{}l@{\enspace\(\vdash\)\enspace}l@{}} % \cs{labelitemi} & \dumpmacro{\labelitemi}, \\ % \cs{labelitemii} & \dumpmacro{\labelitemii}, \\ % \cs{labelitemiii} & \dumpmacro{\labelitemiii}, and \\ % \cs{labelitemiv} & \dumpmacro{\labelitemiv}. % \end{tabular} % \end{center} % % \noindent % They display as \sample{\labelitemi}, \sample{\labelitemii}, \sample{\labelitemiii}, and % \sample{\labelitemiv}. % % \begin{table} % \centering % \caption[Label item adjustment suggestions]% % {Some suggested values for the vertical adjustments of label items. The table % assumes that the default definitions (of class~\packagename{article}) for % \cs{labelitem}\meta{N} are in effect. The \code{itemize}-list levels~\code{i}, % \code{ii}, \code{iii}, and~\code{iv} are referred to with \(N = 1, 2, 3, 4\). All % lengths are given as printer points~(pt) and relate to a document font size of % \formatdimen*{10pt}.} % \label{tab:labelitemadjustvalues} % % \newcommand*{\etbbmark}{\tablenotemark{\tablenotesymbol{1}}} % \newcommand*{\xchartermark}{\tablenotemark{\tablenotesymbol{2}}} % \newcommand*{\kpmark}{\tablenotemark{\tablenotesymbol{3}}} % \newcommand*{\palladiomark}{\tablenotemark{\tablenotesymbol{4}}} % \newcommand*{\utopiamark}{\tablenotemark{\tablenotesymbol{5}}} % % \begin{tabfigures} % \def~{\hphantom{0}} % \def\mc#1{#1~~~} % \noindent % \makebox[0pt]{% % \begin{tabular}{@{}l*{4}{r}@{\qquad}*{4}{r}@{}} % \toprule % Font Name & % \multicolumn{4}{c}{Uppercase Adjustments} & \multicolumn{4}{c@{}}{Lowercase Adjustments} \\ % {} & % \mc{1} & \mc{2} & \mc{3} & \mc{4} & % \mc{1} & \mc{2} & \mc{3} & \mc{4} \\ % \midrule % \acronym{ADF} Accanthis\detoxindex{font>typeface>ADF Venturis=\acronym{ADF} Accanthis|userman} & % 1.0~~ & .75~ & 1.125 & 1.125 & % .0~~ & \textminus.25~ & \textminus.125 & .0~~ \\ % \acronym{ADF} Venturis\detoxindex{font>typeface>ADF Venturis=\acronym{ADF} Venturis|userman} & % .75~ & .5~~ & .75~ & .875 & % \textminus.125 & \textminus.25~ & \textminus.125 & \textminus.125 \\ % Aleo\detoxindex{font>typeface>Aleo|userman} & % 1.25~ & 1.0~~ & 1.25~ & 1.25~ & % .0~~ & \textminus.25~ & .0~~ & .125 \\ % Charis \acronym{SIL}\detoxindex{font>typeface>Charis SIL=Charis \acronym{SIL}|userman} & % 1.0~~ & 1.0~~ & 1.0~~ & 1.125 & % .0~~ & \textminus.25~ & .0~~ & .125 \\ % \acronym{CM} Roman\detoxindex{font>typeface>CM Roman=\acronym{CM} Roman|userman} & % 1.0~~ & .75~ & 1.0~~ & 1.0~~ & % \textminus.25~ & \textminus.5~~ & \textminus.25~ & \textminus.25~ \\ % Domitian\detoxindex{font>typeface>Domitian|userman} & % 1.0~~ & .75~ & 1.0~~ & 1.0~~ & % .0~~ & \textminus.25~ & \textminus.25~ & .0~~ \\ % Cochineal\detoxindex{font>typeface>Cochineal|userman} & % .75~ & .75~ & .75~ & .75~ & % \textminus.25~ & \textminus.5~~ & \textminus.25~ & \textminus.25~ \\ % \acronym{EB} Garamond\detoxindex{font>typeface>EB Garamond=\acronym{EB} Garamond|userman} & % 1.0~~ & .75~ & .75~ & 1.0~~ & % \textminus.25~ & \textminus.5~~ & \textminus.25~ & \textminus.25~ \\ % etbb\etbbmark\detoxindex{font>typeface>etbb|userman} & % 1.0~~ & .75~ & 1.0~~ & 1.0~~ & % \textminus.25~ & \textminus.5~~ & \textminus.25~ & \textminus.25~ \\ % Extended Charter\xchartermark\detoxindex{font>typeface>Extended Charter|userman} & % 1.0~~ & .75~ & 1.0~~ & 1.0~~ & % .0~~ & \textminus.25~ & .0~~ & .0~~ \\ % Gentium Plus\detoxindex{font>typeface>Gentium Plus|userman} & % .75~ & .5~~ & .75~ & .75~ & % \textminus.25~ & \textminus.5~~ & \textminus.25~ & .0~~ \\ % \acronym{GFS} Bodoni\detoxindex{font>typeface>GFS Bodoni=\acronym{GFS} Bodoni|userman} & % 1.0~~ & .75~ & 1.0~~ & 1.0~~ & % .0~~ & \textminus.25~ & \textminus.125 & .0~~ \\ % \acronym{GFS} Didot\detoxindex{font>typeface>GFS Didot=\acronym{GFS} Didot|userman} & % 1.25~ & 1.0~~ & 1.25~ & 1.25~ & % .0~~ & .0~~ & .0~~ & .0~~ \\ % \acronym{IBM} Plex Serif\detoxindex{font>typeface>IBM Plex Serif=\acronym{IBM} Plex Serif|userman} & % 1.125 & 1.0~~ & 1.125 & 1.25~ & % .25~ & .25~ & .25~ & .25~ \\ % \acronym{KP} Serif\itcorr{8}\kpmark\detoxindex{font>typeface>KP Serif=\acronym{KP} Serif|userman} & % 1.0~~ & .75~ & 1.0~~ & 1.0~~ & % \textminus.25~ & \textminus.5~~ & \textminus.25~ & \textminus.25~ \\ % Libertinus Serif\detoxindex{font>typeface>Libertinus Serif|userman} & % .75~ & .5~~ & .75~ & .875 & % \textminus.25~ & \textminus.5~~ & \textminus.25~ & \textminus.25~ \\ % \acronym{ML} Modern\detoxindex{font>typeface>ML Modern=\acronym{ML} Modern|userman} & % 1.~~~ & .75~ & 1.0~~ & 1.0~~ & % \textminus.25~ & \textminus.5~~ & \textminus.25~ & \textminus.25~ \\ % Source Serif Pro\detoxindex{font>typeface>Source Serif Pro|userman} & % 1.0~~ & .75~ & 1.0~~ & 1.0~~ & % .0~~ & \textminus.25~ & .0~~ & .0~~ \\ % Spectral\detoxindex{font>typeface>Spectral|userman} & % 1.0~~ & .75~ & .75~ & 1.0~~ & % .0~~ & \textminus.25~ & \textminus.25~ & .0~~ \\ % \acronym{STIX}\detoxindex{font>typeface>STIX=\acronym{STIX}|userman} & % 1.0~~ & .75~ & 1.0~~ & 1.0~~ & % \textminus.25~ & \textminus.5~~ & \textminus.25~ & .0~~ \\ % \acronym{URW} Palladio\palladiomark\detoxindex{font>typeface>URW Palladio=\acronym{URW} Palladio|userman} & % 1.0~~ & .75~ & 1.0~~ & 1.0~~ & % .0~~ & .0~~ & .0~~ & .0~~ \\ % Utopia\itcorr{2}\utopiamark\detoxindex{font>typeface>Utopia|userman} & % .75~ & .5~~ & .75~ & .75~ & % \textminus.25~ & \textminus.5~~ & \textminus.25~ & \textminus.25~ \\ % \bottomrule % \end{tabular}} % \end{tabfigures} % % \begin{tablenotes} % \renewcommand*{\tablenotemark}[1]{#1}% % \etbbmark\enspace % \propername{Edward Tufte}'s Bembo in package~\packagename{ETbb}. Note the two initial % capital letters in the filename. % % \xchartermark\enspace % Found in package \packagename{XCharter}. Again note the two initial capitals in the % filename. % % \kpmark\enspace % In package \packagename{kpfonts}. % % \palladiomark\enspace % Contained in package~\packagename{mathpazo}. % % \utopiamark\enspace % Utopia is available through package~\packagename{fourier} or % package~\packagename{mathdesign}. For the latter pass option~\code{adobe-utopia} to the % package. % \end{tablenotes} % % \begin{note} % Depending on the font packages loaded (and on their load order) the three % macros~\cs{text\-endash}, \cs{text\-asterisk\-centered}, \cs{text\-period\-centered} may % be redefined and thus expand to different glyphs which need different adjustment values % than the ones mentioned in \Cref{tab:labelitemadjustvalues}. To ensure a set of % correction values works use % macros~\hyperref[syn:typoguppercaseadjustcheck]{\cs{typog\-upper\-case\-adjust\-check}} % or \hyperref[syn:typoglowercaseadjustcheck]{\cs{typog\-lower\-case\-adjust\-check}} % inside of the target document. % \end{note} % \end{table} % % % \subsection[Align Last Line] % {Align Last Line of a Paragraph}\label{sec:align-last-line} % \index{paragraph>align last line|userman} % % The usual algorithms of \LaTeX{} typeset the last line of a paragraph flush with the left % margin unless |center|, |raggedleft| or |Centering|, |FlushRight| % (package~\packagename{ragged2e}~\cite{package:ragged2e}) are in effect. For an instructive % discussion consult Ch.~17, \doublequotes{Paragraph End}, of reference~\citenum{eijkhout:2007}. % The following environments adjust the last lines of paragraphs in different ways. % % \DescribeEnv{lastlineraggedleftpar} % \DescribeEnv{lastlineflushrightpar} % The environment \code{lastlineraggedleftpar}\index{paragraph>align last line>flush right|userman} % adjusts the various skips such that the last lines of the paragraphs gets typeset flush with % the right margin. % % \begin{synopsis}\label{syn:lastlineraggedleftpar}\label{syn:lastlineflushrightpar} % \cs{begin}|{lastlineraggedleftpar}| \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{lastlineraggedleftpar}| \\[\smallskipamount] % |lastlineflushrightpar|~(alias) % \end{synopsis} % % The name |lastlineflushrightpar| is an alias for~\code{lastlineraggedleftpar}. % % \DescribeEnv{lastlinecenteredpar} % Center\index{paragraph>align last line>centered|userman} the last lines of the paragraphs % enclosed by this environment.\!\footnote{Also compare with the approach taken in % reference~\citenum{wermuth:2018}.} % % \begin{synopsis}\label{syn:lastlinecenteredpar} % \cs{begin}|{lastlinecenteredpar}| \ttdots{} \cs{end}|{lastlinecenteredpar}| % \end{synopsis} % % \begin{usecases} % |lastlineflushrightpar|: Narrow, justified parts of the text put flush against the right % margin.\visualpar |lastlinecenteredpar|: Table or figure captions typeset justified as % centered boxes. % \end{usecases} % % % \newpagetofixtoc % \toccontinuesonnextpage % \subsection[Fill Last Line] % {Fill Last Line of a Paragraph}\label{sec:fill-last-line} % \index{paragraph>fill last line|userman} % % The problem of when and how to \singlequotes{fill} the last line of a paragraph is quite % intricate. We first define the problem then we proceed to general purpose functions and we % close the section with specific environments to control the length of the last line. % % % \subsubsection{Problem Description} % % Depending on the value of \cs{parindent}, either zero or nonzero, there may be the need to % control the length of the last line of a paragraph. % % \iffalse %<*crookedparagraphs> prologues := 3; def draw_filled_rectangle(expr lower_left, upper_right, color) = fill lower_left -- (xpart upper_right, ypart lower_left) -- upper_right -- (xpart lower_left, ypart upper_right) -- cycle withcolor color; enddef; u := 100; em := 10; linelength := 2u; baselineskip := 1.2em; parskip := 3; parindent := 2.5em; cmykcolor line_color; line_color := (.08, 0, 0, .18); % cold silver color customred[]; customred[1] := (.890, .282, .282); customred[2] := (.831, .110, .110); customred[3] := (.686, .043, .043); customred[4] := (.569, .000, .000); customred[5] := (.420, .000, .000); color margin_color; margin_color := customred[2]; beginfig(1); % short line -- gap y := 0; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); y := y - baselineskip; draw_filled_rectangle((0, y), (1.1em, y + 1em), line_color); y := y - baselineskip; draw_filled_rectangle((parindent, y), (linelength, y + 1em), line_color); y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); draw_filled_rectangle((-.667em, 1em), (-.333em, -3baselineskip), margin_color); draw_filled_rectangle((linelength + .333em, 1em), (linelength + .667em, -3baselineskip), margin_color); endfig; beginfig(2); % short line -- covered y := 0; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); y := y - baselineskip; draw_filled_rectangle((0, y), (2parindent, y + 1em), line_color); y := y - baselineskip; draw_filled_rectangle((parindent, y), (linelength, y + 1em), line_color); y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); draw_filled_rectangle((-.667em, 1em), (-.333em, -3baselineskip), margin_color); draw_filled_rectangle((linelength + .333em, 1em), (linelength + .667em, -3baselineskip), margin_color); endfig; beginfig(3); % completely filled line -- no clear paragraph break y := 0; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); y := y - baselineskip - parskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); draw_filled_rectangle((-.667em, 1em), (-.333em, -3baselineskip - parskip), margin_color); draw_filled_rectangle((linelength + .333em, 1em), (linelength + .667em, -3baselineskip - parskip), margin_color); endfig; beginfig(4); % completely filled line -- opened right margin y := 0; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - parindent, y + 1em), line_color); y := y - baselineskip - parskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); draw_filled_rectangle((-.667em, 1em), (-.333em, -3baselineskip - parskip), margin_color); draw_filled_rectangle((linelength + .333em, 1em), (linelength + .667em, -3baselineskip - parskip), margin_color); endfig; end % % \fi % % \begin{enumerate} % \item\label{item:o1} % \(\cs{parindent} > 0\) \cite[O1]{wermuth:2018} % % \begin{minipage}{\linewidth} % If the last line of a paragraph is shorter than the \cs{parindent} of the following % paragraph a visual gap tears open. % % \begin{center} % \includegraphics{crooked-paragraphs-1.mps} % \end{center} % \end{minipage} % % A similar issue occurs with displayed math in a flush left\footnote{The common practice of % centering displayed equations does not call for the manipulations of a paragraph's last % line discussed here.} setting, e.\,g., \packagename{amsmath}~\cite{package:amsmath} and % option~|fleqn|.\!\footnote{For displayed equations and \packagename{amsmath} the relevant % parameter is~\cs{mathindent}.} % % \begin{minipage}{\linewidth} % A possible remedy is to reflow the paragraph in a way that its last line is clearly wider % than \cs{parindent}, a typical suggestion being twice the~\cs{parindent}. % % \begin{center} % \includegraphics{crooked-paragraphs-2.mps} % \end{center} % \end{minipage} % % \needspace{2\baselineskip} % \item\label{item:o2} % \(\cs{parindent} = 0\) \cite[O2]{wermuth:2018} % % \begin{minipage}{\linewidth} % If the last line of a paragraph is completely filled with text, i.\,e., flush with the % right margin, it may become hard to spot the start of the following paragraph unless % \cs{parskip} is large.\footnotemark % % \begin{center} % \includegraphics{crooked-paragraphs-3.mps} % \end{center} % \end{minipage}\footnotetext{Package~\packagename{parskip} defines \cs{parskip} % as \mbox{6\,pt plus 2\,pt} for a base size of~10\,pt.} % % \medskip % % \begin{minipage}{\linewidth} % A possible, more legible solution is to reformat the paragraph such that its last line % leaves a marked gap with respect to the right margin. % % \begin{center} % \includegraphics{crooked-paragraphs-4.mps} % \end{center} % \end{minipage} % % \medskip % % Recommended gap widths range from two ems to twice the typical \cs{parindent}\footnote{For % example, \LaTeX's class \packagename{article} uses a \cs{parindent} % of~25\,pt.} value~\cite{carlisle:1996}. % \end{enumerate} % % \begin{tip} % In theory both problems, O1 and O2 can be resolved by either shortening or prolonging the % last line of the paragraph. The user to decide which direction to go and to choose the % method that yields the most pleasing typographic results. % % \TeX{} evaluates paragraphs as a whole. Therefore, even changes intended for just the last % line may affect the entire paragraph and potentially degrade its appearance. % % Prudent users check the appearance of the problematic, original paragraph against one or % more corrected versions\spacedemdash at a minimum, visually. Quantitative comparisons can % be performed using \cs{tracingparagraphs}. % \end{tip} % % \begin{important} % For the techniques in the following two subsections to work the paragraphs treated with % them should have certain advantageous properties. % % \begin{itemize} % \item Technically, the paragraphs need to contain enough glue (see for example % \cref{sec:sloppy-paragraphs}) to achieve a low badness such that the desired paragraph % end is deemed feasible by \TeX.\shiftedmarginnote{This \code{itemize} list demonstrates % vertically adjusted label items (\cref{sec:adjust-label-items}).} % % \item Aesthetically, the paragraphs must be long enough to absorb the change in last-line % fill level otherwise their gray-values visibly deviate from the % average.\specialsectionendhere % \end{itemize} % \end{important} % % % \subsubsection{Manual Changes}\label{sec:fill-last-line-other-methods} % % Most \hyperref[item:o1]{O1} or \hyperref[item:o2]{O2} situations can be navigated with % do-it-yourself methods. Here are some common recipes. % % \begin{enumerate} % \item End-of-paragraph intervention.\label{enum:end-of-paragraph-intervention} % % \begin{enumerate}[notopsep] % \item Tie~\sample{\texttt{\char126}}\label{enum:tie-last-words} % \index{paragraph>fill last line>tie|userman} % % Tie the last words. % % The problem with the tie may be a hyphenation of one of the words that participates in % the tie. The next item avoids this disadvantage. % % \item \cs{mbox}\label{enum:mbox-last-words} % \index{paragraph>fill last line>mbox=\cs{mbox}|userman} % % Join the last words or inline equation at the end of the paragraph with an~\cs{mbox}. % % \item \cs{linebreak}\label{enum:linebreak} % \index{paragraph>fill last line>linebreak=\cs{linebreak}|userman} % % Add a \cs{linebreak} to the back part of the paragraph (approximately where the % \cs{mbox} of item~\ref{enum:mbox-last-words} would start) in a way that the last line % receives the desired length~\cite{wermuth:2022-8-2}. As a result, the penultimate % lines may become unsightly. Counteract this degradation e.\,g.~with % recipes~\ref{enum:vary-spacing} to~\ref{enum:vary-font-expansion}. % \end{enumerate} % % Tying and the use of \cs{mbox} can be generalized. They are useful not only at the end of % paragraphs but also effective for grouping logical units of sentences or inline equations, % ensuring the key information remains in the reader's focus. Of course, binding text % segments together must stop when overfull lines begin to appear. % % \item Uniform paragraph change.\label{enum:uniform-paragraph-change} % % \begin{enumerate}[notopsep] % \item Vary spacing.\label{enum:vary-spacing} % \index{font>spacing|userman} % % Modify the inter-word spacing, for example, with the macros introduced in % \cref{sec:looser-tighter-spacing}. % % Enclose the paragraph in either \hyperref[syn:loosespacing]{|loosespacing|} % or~\hyperref[syn:tightspacing]{|tightspacing|}. % Increase the spacing~\meta{level} until the last line gets the desired length. % % \item Vary font tracking.\label{enum:vary-font-tracking} % \index{font>tracking|userman} % % Enclose the paragraph in a \hyperref[syn:setfonttracking]{\code{setfonttracking}}~group. % See \cref{sec:tracking-control}. Increase or decrease the tracking in steps of % \nativetextfraction{1}{1000}\,em until the last line looks good. % % \item Vary font expansion.\label{enum:vary-font-expansion} % \index{font>expansion|userman} % % Enclose the paragraph in a \hyperref[syn:setfontexpand]{\code{setfontexpand}}~group. See % \cref{sec:font-expansion-control}. % \end{enumerate} % % \item A combination of any of the above items. % % \item Some curveballs.\label{enum:gonzo-tips}\par % \begin{enumerate}[notopsep] % \item If the paragraph already suffers from one of the problems that \TeX{} addresses with % \cs{doublehyphendemerits}, \cs{finalhyphendemerits}, or~\cs{adjdemerits}, crank up one or % all of these values to~10000 and observe whether the length of last line changes in the % desired direction. % % \item If any influential \packagename{microtype} features have been enabled try with one % more more of them \emph{disabled}. See, e.\,g., % environment~\hyperref[syn:nofontexpansion]{\code{nofontexpansion}} in % \cref{sec:font-expansion-control}. % \end{enumerate} % \end{enumerate} % % % \subsubsection{Multi\capitalhyphen Purpose Environments}\label{sec:fill-last-line-gp-environments} % % \DescribeEnv{shortenpar} % \DescribeEnv{prolongpar} % The two environments % \code{shortenpar}\index{paragraph>fill last line>shortenpar=\code{shortenpar}|userman} % and \code{prolongpar}\index{paragraph>fill last line>prolongpar=\code{prolongpar}|userman} % can be employed in quite general situations when a % paragraph should be typeset one line longer or shorter, e.\,g., to avoid a % widow~line\footnote{The last line of a paragraph becomes a % \singlequotes{widow}\detoxindex{forlorn line>widow|userman} (ger.~\foreignphrase{Hurenkind}) if it % starts the following page or column.} or a club~line\footnote{The first line of a paragraph % is called \singlequotes{club}\detoxindex{forlorn line>club|userman} % or~\singlequotes{orphan}\detoxindex{forlorn line>orphan|userman} % (ger.~\foreignphrase{Schusterjunge}) if it appears at the bottom of the page or % column.}~[\citenum{knuth:1986}, p.~104 and~\citenum{mittelbach:2018c}]. (See also % \cref{sec:vtie-paragraph} for special functions to avoid clubs or widows.) % \singlequotes{Accidentally}, they also change the length of the last line of the paragraph. % % \begin{synopsis}\label{syn:shortenpar} % \cs{begin}|{shortenpar}| % \ttdots{} % \cs{end}|{shortenpar}| % \end{synopsis} % % Environment |shortenpar| decreases the \cs{looseness} of the % paragraph.\!\footnote{\cs{looseness} is a \TeX{}~primitive~\cite[p.~103n]{knuth:1986}. A % thorough discussion of the interaction of \cs{linepenalty} and \cs{looseness} can be found in % reference~\citenum{wermuth:2017c}.} This environment works well when the last line is short or % the paragraph overall is loosely set. % % \begin{synopsis}\label{syn:prolongpar} % \cs{begin}|{prolongpar}| % \ttdots{} % \cs{end}|{prolongpar}| % \end{synopsis} % % This environment increases the \cs{looseness} of the paragraph, which is why it works best % with decent or tight last lines that are nearly full. % % % \subsubsection{Specialized Environments}\label{sec:fill-last-line-specialized-environments} % % We introduce environments not just skips to get the correct behavior\leftspacedendash set up % all paragraph parameters \emph{before} the paragraph ends\rightspacedendash and, at the same % time, limit the range of this parameter change. % % \DescribeEnv{covernextindentpar} % Environment \code{covernextindentpar}% % \index{paragraph>fill last line>covernextindentpar=\code{covernextindentpar}|userman} % can be helpful for \hyperref[item:o1]{case~O1}, i.\,e., a too short last line. % % \begin{synopsis}\label{syn:covernextindentpar} % \cs{begin}|{covernextindentpar}|\oarg{dim} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{covernextindentpar}| % \end{synopsis} % % The environment forces \TeX{} to extend the last line of a paragraph such that it takes at % least % \makeatletter\dumpmacro{\typog@covernextindentpar@nonzero@parindent}\makeatother{} % (if \(\cs{parindent} \not= 0\)), % \makeatletter\typog@covernextindentpar@zero@parindent\makeatother{} % (if \(\cs{parindent} = 0\)), or \meta{dim} if called with an optional argument. % % \DescribeEnv{openlastlinepar} % The next environment, \code{openlastlinepar},% % \index{paragraph>fill last line>openlastlinepar=\code{openlastlinepar}|userman} % takes care of \hyperref[item:o2]{case~O2}, i.\,e., a last line in a paragraph that is almost % full or completely filled. % % \begin{synopsis}\label{syn:openlastlinepar} % \cs{begin}|{openlastlinepar}|\oarg{dim} \ttdots{} \cs{end}|{openlastlinepar}| % \end{synopsis} % % It may resolve \hyperref[item:o2]{case~O2} as it attempts to prevent a completely filled line % by introducing a partly unshrinkable \cs{parfillskip}. Without optional argument the % threshold of unused last-line length is either % \makeatletter\dumpmacro{\typog@openlastlinepar@nonzero@parindent}\makeatother{} (if % \(\cs{parindent} \not= 0\)) or % \makeatletter\typog@openlastlinepar@zero@parindent\makeatother{} (if \(\cs{parindent} = 0\)). % The optional argument~\meta{dim} directly sets the gap threshold. % % Note that using this environment can succeed in avoiding a fully filled last line; however, % the result might still fall into case \hyperref[item:o1]{type~O1}. % % % \newpagetofixtoc % \subsubsection{Consistent Spacing of Last Line}\label{sec:consistent-spacing-of-last-line} % % \index{lastlinefit=\verb!*+\lastlinefit+|userman} % Since \eTeX{} the paragraph-breaking algorithm can be instructed to match the spacing of the % last line of a paragraph to the next-to-last line with the % built-in~\cs{lastlinefit}~\cite[Sec.~3.8]{package:etex}.\!\footnote{The actual algorithm is % somewhat involved. So, for ease of reference, we have included the relevant part of the % \eTeX-manual as \Cref{app:epsilon-tex-lastlinefit} starting on % \cpageref{app:epsilon-tex-lastlinefit}.} Package~\packagename{typog} wraps this control in % an environment to limit the scope as its effects are not always beneficial to the appearance % of the body. % % \DescribeEnv{lastlinefitpar} % \sinceversion{Since v0.5} % Typeset a single paragraph with \cs{lastlinefit} set to a given value. % % \begin{synopsis}\label{syn:lastlinefitpar} % \cs{begin}|{lastlinefitpar}|\oarg{value} \ttdots{} \cs{end}|{lastlinefitpar}| % \end{synopsis} % % The parameter range of \meta{value} is zero to thousand. It controls the fraction of % thousandths of the next-to-last-line's spacing to be used in the last line. This means that % \(\meta{value} = 0\) requests no transfer (as if \code{lastlinefit} is not used at all) and % \(\meta{value} = 1000\) initiates exact transfer of the spacing. The default \meta{value} % is~1000. % % Note that different \meta{value}s can lead to different breakpoints in the affected % paragraph. \eTeX{} still considers the \emph{whole} paragraph when calculating the optimal % line breaks. % % \begin{usecases} % Adapt the spacing of the last line of a paragraph to a very loose or very tight % next-to-last line or to a whole paragraph that is very loose or very tight. % \end{usecases} % % % \needtocspace % \subsection{Spacing}\label{sec:spacing-control} % \index{font>spacing|userman} % % \begin{whittyquote} % 90\% of design is typography. \\ % And the other 90\% is whitespace. \\ % \capitalemdash*~\propername{Jeffrey Zeldman} % \end{whittyquote} % % \noindent % The functions described in this section rely only on plain \LaTeX. No extra packages are % required. Compare to the \packagename{microtype}-based functionality of % \cref{sec:microtype-frontend}. % % % \subsubsection[Looser\kernedslash Tighter]{Looser or Tighter Spacing}\label{sec:looser-tighter-spacing} % \index{font>spacing>loose|userman} % \index{font>spacing>tight|userman} % % \begin{whittyquote} % Never try to adjust lines by squeezing or stretching the tracking. \\ % Go for the subtle solution: adjust word spacing instead. \\ % \capitalemdash*~\propername{Jan Middendorp}~\cite[p.~119]{middendorp:2014} % \end{whittyquote} % % \noindent % The environments in this section directly influence the spacing, this is, they change the % width and stretchability of the horizontal space. % % On the one hand, they act gently by adjusting the spacing only by a small amount. On the % other hand, they operate decidedly in controlling the glue associated with the adjusted % space. The latter is also important to ensure the monotonicity of the different % \meta{level}s. However, the strictly managed stretchability\slash shrinkability may lead to % many overfull boxes with \cs{fussy}, or when applied to short lines. % % \DescribeEnv{loosespacing} % \DescribeEnv{tightspacing} % Environments |loosespacing| and |tightspacing| introduce four \meta{level}s of % \singlequotes{looseness} or \singlequotes{tightness}, where \meta{level}~=~0 disables the % functionalities. The higher the \meta{level} the looser or tighter the text will by typeset. % % \begin{synopsis}\label{syn:loosespacing} % \cs{begin}|{loosespacing}|\oarg{level} % \ttdots{} % \cs{end}|{loosespacing}| % \end{synopsis} % % Environment~|loosespacing| increases the width of a space by the percentages given in % \cref{tab:loosespacing}. % % \begin{SCtable}[10] % \caption[Spacing changes made by \code{loosespacing}]% % {Adjustments made by environment \code{loosespacing} to \cs{spaceskip}. % The mapping of \meta{level} to the exact skip definitions are % \(1 \mapsto \formatskip{1.05}{.5}{.1}\), % \(2 \mapsto \formatskip{1.1}{.5}{.1}\), % \(3 \mapsto \formatskip{1.2}{.6}{.2}\), and % \(\ge 4 \mapsto \formatskip{1.3}{.8}{.3}\), % where all factors scale with \cs{dimen2}, % the current font's space-width.} % \label{tab:loosespacing} % % \begin{tabfigures} % \def~{\hphantom{0}}% % \begin{tabular}{@{}ccl@{}} % \toprule % \meta{level} & Adjustment & Note \\ % {} & \% & \\ % \midrule % 0 & n/a & neutral \\ % 1 & +5~ & default \\ % 2 & +10 & \\ % 3 & +20 & \\ % \(\ge\)\:4 & +30 & \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \end{SCtable} % % The default level of |loosespacing| is~1. % % \begin{synopsis}\label{syn:tightspacing} % \cs{begin}|{tightspacing}|\oarg{level} % \ttdots{} % \cs{end}|{tightspacing}| % \end{synopsis} % % Environment~|tightspacing| decreases the width of a space by the percentages given in % \cref{tab:tightspacing}. % % \begin{SCtable}[10] % \def~{\hphantom{0}} % \caption[Spacing changes made by \code{tightspacing}]% % {Adjustments made by environment \code{tightspacing} to \cs{spaceskip}. % The mapping of \meta{level} to the exact skip definitions are % \(1 \mapsto \formatskip{.9875}{.0125}{.5~~~}\)\!, % \(2 \mapsto \formatskip{.975}{.025}{.5~~}\)\!, % \(3 \mapsto \formatskip{.95}{.05}{.5~}\)\!, and % \(\ge 4 \mapsto \formatskip{.9}{.1}{.5}\), % where all factors scale with \cs{dimen2}, % the current font's space-width.} % \label{tab:tightspacing} % % \begin{tabfigures} % \begin{tabular}{@{}ccl@{}} % \toprule % \meta{level} & Adjustment & Note \\ % {} & \% & \\ % \midrule % 0 & n/a & neutral \\ % 1 & ~\textminus 1.25 & default \\ % 2 & ~\textminus 2.5~ & \\ % 3 & ~\textminus 5\hphantom{.}~~ & \\ % \(\ge\)\:4 & \textminus 10\hphantom{.}~~ & \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \end{SCtable} % % The default level of |tightspacing| is~1. % % \begin{note} % At a given \meta{level} the changes of |loosespacing| are much larger than those of % |tightspacing|. % \end{note} % % \begin{usecases} % Tighten spacing in narrow lines as, for example, in multi-column environments.\visualpar % Nudge line breaks or hyphenation points.\visualpar Separate clashing descenders and % ascenders.\visualpar Eliminate rivers. % \end{usecases} % % % \newpagetofixtoc % \subsubsection{Wide Space}\label{sec:wide-space} % \index{wide space|userman} % % The \cs{widespace} macro and its companion \cs{narrowspace} derive their appearances from % several of the current font's \cs{fontdimen}\meta{number}s. \TeX{} addresses the latter by % integers, which is totally non-memnonic. Therefore, we play softball by first presenting % \cref{tab:fontdimen} that associates the \cs{fontdimen}\meta{number}s with their meanings and % also reports on their current values (for this document).\!\footnote{The association is given % in Appendix~F (p.~433) of reference~\citenum{knuth:1986}. For a concise and understandable % explanation of the \TeX~\cs{fontdimen} parameters consult reference~\citenum{carlisle:2013}.} % % \begin{SCtable} % \caption[\cs{fontdimen}\meta{number} parameters] % {All \TeX{} font parameters normalized to the font's quad-size. The first % column~\sample{\#} states the index of the \cs{fontdimen} parameter: % \meta{number}. Column~2 presents short descriptions of % \cs{fontdimen}\meta{number}. As examples, the values for the current font are % shown in column~3 as percentages.\bottomstrut} % \label{tab:fontdimen} % % \begin{tabfigures} % \def~{\hphantom{0}}% % \ExplSyntaxOn % \def\straightfontdimen#1{\fp_eval:n {\the\fontdimen#1\font}} % \def\roundfontdimen#1{\fp_eval:n {round (1000 * \the\fontdimen#1\font) / 1000}} % \def\relativefontdimen#1{\fp_eval:n {round (1000 * \the\fontdimen#1\font / \the\fontdimen6\font) / 10}} % \ExplSyntaxOff % % \begin{tabular}{@{}lll@{}} % \toprule % \# & Description & Value \\ % \midrule % 1 & Slant per 1\,pt height & ~~\relativefontdimen1\topstrut \\ % 2 & Interword space width & ~\relativefontdimen2 \\ % 3 & Interword stretch & ~\relativefontdimen3 \\ % 4 & Interword shrink & ~~\relativefontdimen4 \\ % 5 & \sample{\itcorr{2}x\itcorr{2}} height & ~\relativefontdimen5 \\ % 6 & \cs{quad} height & \relativefontdimen6 \\ % 7 & Extra space width & ~~\relativefontdimen7 \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \end{SCtable} % % \DescribeMacro{\widespace} % \DescribeMacro{\widespace*} % \sinceversion{Starred form since v0.2} % Typeset a wide, sentence-ending space as if in \cs{nonfrenchspacing}~mode. Consult % \Cref{tab:space-sizes} for a comparison of the various sizes. % % \begin{synopsis}\label{syn:widespace} % \cs{widespace}\qquad \cs{widespace*} % \end{synopsis} % % \index{widespacestrength=\verb!*+\widespacestrength+|userman} % The unstarred macro~\cs{widespace} inserts a space that is as wide as the font's % sentence-ending space in \cs{nonfrenchspacing}~mode, this is % \begin{equation*} % |\fontdimen2| + \cs{widespacestrength} \times |\fontdimen7|. % \end{equation*} % % \noindent % Its width is independent of any \cs{frenchspacing} or \cs{nonfrenchspacing}~settings, but % depends on \cs{widespacestrength} which defaults % to~\widespacestrength\widespace\marginnote{The sentence that ends with % \singlequotes{\widespacestrength} uses \cs{widespace} after the period.} The latter can be % overridden by the user to get a more or less pronounced effect. % % \index{widespacescale=\verb!*+\widespacescale+|userman} % If |\fontdimen7| happens to be zero \cs{widespace} uses % \begin{equation*} % \cs{widespacescale} \times |\fontdimen2| % \end{equation*} % % \noindent % as width instead, where \cs{widespacescale} defaults to \widespacescale. The stretchability % and shrinkability of \cs{widespace} always are scaled with \cs{widespacescale}. The % \cs{widespacescale} too can be redefined by the user to achieve different effects. % % The starred form, \cs{widespace*}, unconditionally uses the \(|\fontdimen7| = 0\) code-path. % % \begin{usecase} % Useful as a sentence-ending space if, for example, the sentence ends in an abbreviation % with a period or decimal number without trailing digits \emph{and} the next sentence should % be delimited in a clearer way.\visualpar Open tight lines with a series % of~\cs{widespace}s.\!\footnote{\label{fn:widespace}See also \doublequotes{Investigating the % badness of a paragraph} on \Cpageref{sec:investigating-paragraph-badness}.} % \end{usecase} % % % \subsubsection{Narrow Space}\label{sec:narrow-space} % \index{narrow space|userman} % % \DescribeMacro{\narrowspace} % \DescribeMacro{\narrowspace*} % \sinceversion{Since v0.2} % Typeset a narrow space. Consult \Cref{tab:space-sizes} for a comparison of the various % sizes. % % \begin{synopsis}\label{syn:narrowspace} % \cs{narrowspace}\qquad \cs{narrowspace*} % \end{synopsis} % % \index{narrowspacestrength=\verb!*+\narrowspacestrength+|userman} % The unstarred macro~\cs{narrowspace} inserts a narrow space with the width % \begin{equation*} % |\fontdimen2| - \cs{narrowspacestrength} \times |\fontdimen7| % \end{equation*} % % \index{narrowspacescale=\verb!*+\narrowspacescale+|userman} % \noindent % if |\fontdimen7| is different from zero or otherwise % \begin{equation*} % \cs{narrowspacescale} \times |\fontdimen2|. % \end{equation*} % % \noindent % The starred version, \cs{narrowspace*}, unconditionally uses the \(\cs{fontdimen7} = 0\) % code-path. Refer to \Cref{tab:fontdimen} for the meanings of the various % \cs{fontdimen}~parameters. % % The stretchability and shrinkability of \cs{narrowspace} always get scaled with % \cs{narrowspacescale}. Both factors, \cs{narrowspacestrength} and \cs{narrowspacescale} can % be redefined by the user; their defaults are \narrowspacestrength{} and \narrowspacescale. % % \begin{usecases} % Tighten loose lines with a series of~\cs{narrowspace}s.\!\footnote{Footnote % \ref{fn:widespace} again applies.}\visualpar Compensate the visual gap that may occur when % switching from upright shape to italic shape. % \end{usecases} % % \begin{table} % \centering % \caption[Comparison of some space sizes] % {Exemplary comparison of standard \cs{space} versus \cs{narrowspace} and % \cs{widespace}. All values are relative to the size of the current font's % quad-size and shown as a percentage of it. \cs{narrowspace} and \cs{widespace} % use the package's defaults.\visualpar The upper values in the % \singlequotes{Width}~column for \cs{narrowspace} and \cs{widespace} refer to the % \(\cs{fontdimen7} \not= 0\) case and the lower ones to the \(\cs{fontdimen7} = 0\) % code-path.} % \label{tab:space-sizes} % % \begin{tabfigures} % \def~{\hphantom{0}} % \ExplSyntaxOn % \def\relativedimen#1{\fp_eval:n {round (1000 * (#1) / \the\fontdimen6\font) / 10}} % \def\relativefontdimen#1{\relativedimen{\the\fontdimen#1\font}} % \ExplSyntaxOff % \def\nrows{1.75} % % \begin{tabular}{@{}l*{3}{r}@{}} % \toprule % Macro & Width & Stretch & Shrink \\ % \midrule % \multirow{\nrows}{*}{\cs{narrowspace}} & % \relativedimen{\the\fontdimen2\font - \narrowspacestrength * \the\fontdimen7\font} & % \multirow{\nrows}{*}{\relativedimen{\narrowspacescale * \the\fontdimen3\font}} & % \multirow{\nrows}{*}{\relativedimen{\narrowspacescale * \the\fontdimen4\font}} \\[-.25\normalbaselineskip] % {} & \relativedimen{\narrowspacescale * \the\fontdimen2\font} & & \\ % \cs{space} & \relativefontdimen2 & \relativefontdimen3 & \relativefontdimen4 \\ % \multirow{\nrows}{*}{\cs{widespace}} & % \relativedimen{\the\fontdimen2\font + \widespacestrength * \the\fontdimen7\font} & % \multirow{\nrows}{*}{\relativedimen{\widespacescale * \the\fontdimen3\font}} & % \multirow{\nrows}{*}{\relativedimen{\widespacescale * \the\fontdimen4\font}} \\[-.25\normalbaselineskip] % {} & \relativedimen{\widespacescale * \the\fontdimen2\font} & & \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \end{table} % % % \subsection{\packagename{Microtype} Front\capitalhyphen End}\label{sec:microtype-frontend} % \index{microtype=\packagename{microtype} (package)|userman} % % \marginnote{The manual uses \hyperref[syn:spacedemdash]{\cs{spacedemdash}} for the em-dash.} % The functionalities are just front ends of selected macros in % package~\packagename{microtype}\spacedemdash welcome syntactic sugar. % % \begin{important} % All macros and environments introduced in this section require that % package~\packagename{microtype}~\cite{package:microtype} has been loaded, preferably % \emph{before} package~\packagename{typog} % % \begin{codeexample} % \cs{usepackage}[\meta{microtype-options}\ttdots]\{microtype\} \\ % \cs{usepackage}[\meta{typog-options}\ttdots]\{typog\} % \end{codeexample} % % \noindent % in the document preamble. % \end{important} % % % \subsubsection{Tracking}\label{sec:tracking-control} % \index{font>tracking|userman} % % \begin{caution} % The tracking changes may interfere with implicit changes of tracking declared with % \cs{SetTracking}. Explicit calls to \cs{textls} remain in effect. % \end{caution} % % \noindent % \DescribeEnv{setfonttracking} % Override the default tracking for all fonts. % % \begin{synopsis}\label{syn:setfonttracking} % \cs{begin}|{setfonttracking}|\marg{delta} \ttdots{} \cs{end}|{setfonttracking}| % \end{synopsis} % % The environment~|setfonttracking| manages a group for \cs{lsstyle} of % package~\packagename{microtype}. The change \meta{delta} in tracking is given as multiples % of \nativetextfraction{1}{1000}\,em. Positive as well as negative values of \meta{delta} are % allowed. % % See Sec.~5.3, \singlequotes{Tracking}, and~7, \doublequotes{Letterspacing revisited}, in the % documentation of \packagename{microtype}~\cite{package:microtype} for a detailed explanation. % % For font combinations involving monospaced fonts (\TeX{} lingo: typewriter) an overly large % spacing may show up at the borders where fonts change. This is caused by the calculation of % the \doublequotes{outer spacing} described in Sec.~5.3 of the \packagename{microtype}~manual. % % \indexpackageoption{trackingttspacing} % Use configuration variable~\hyperref[item:trackingttspacing]{\code{trackingttspacing}} to % reduce the outer spacing to a reasonable value either directly at package-load time % % \begin{codeexample} % \cs{usepackage}[trackingttspacing=\{250, 75, 50\}]\{typog\} % \end{codeexample} % % \noindent % or using \cs{typogsetup} in the document \emph{preamble} (after loading % \packagename{microtype} and \packagename{typog}) % % \begin{codeexample} % \cs{typogsetup}\{trackingttspacing=\{250, 75, 50\}\} % \end{codeexample} % % If the argument of option~\code{trackingttspacing} is omitted the outer spacing defaults to % \makeatletter\mbox{\typog@config@trackingttspacing}\makeatother. % % \begin{usecases} % Nudge line breaks or hyphenation points.\visualpar Avoid clashes of descenders and % ascenders, e.\,g., for \cs{smash}ed symbols of inline math.\spacedemdash Think of % integrals.\visualpar Control the length of the last line in a paragraph. % \end{usecases} % % % \subsubsection{Font Expansion}\label{sec:font-expansion-control} % \index{font>expansion|userman} % % \DescribeEnv{setfontshrink} % \DescribeEnv{setfontstretch} % Adjust the limits of either only stretchability or only shrinkability and zero the other % component, i.\,e., shrinkability and stretchability. % % \begin{synopsis}\label{syn:setfontshrink}\label{syn:setfontstretch} % \cs{begin}|{setfontshrink}|\oarg{level} % \ttdots{} % \cs{end}|{setfontshrink}| \\ % \cs{begin}|{setfontstretch}|\oarg{level} % \ttdots{} % \cs{end}|{setfontstretch}| % \end{synopsis} % % A \meta{level} of zero is a no-op. \Cref{tab:setfontshrink-values,tab:setfontstretch-values} % summarize the values for |stretch| and |shrink| in these environments. % % \begin{SCtable} % \caption[Shrink values of \code{setfontshrink}] % {\slightlysloppy[2] Preconfigured values for |shrink| inside of % environment~\code{setfontshrink} as \nativetextfraction{1}{1000}\,em. Note that all % |stretch| values are zero, so the fonts only can shrink.} % \label{tab:setfontshrink-values} % % \begin{tabfigures} % \def~{\hphantom{0}} % \begin{tabular}{@{}cccl@{}} % \toprule % \meta{level} & |stretch| & |shrink| & Note \\ % \midrule % 0 & n/a & n/a & no operation \\ % 1 & 0 & ~\makeatletter\typog@shrink@i\makeatother & default \\ % 2 & 0 & \makeatletter\typog@shrink@ii\makeatother & \\ % 3 & 0 & \makeatletter\typog@shrink@iii\makeatother & \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \end{SCtable} % % \begin{SCtable} % \centering % \caption[Stretch values of \code{setfontstretch}] % {\slightlysloppy[2] Preconfigured values for |stretch| inside of % environment~\code{setfontstretch} as \nativetextfraction{1}{1000}\,em. Note that all % |shrink| values are zero, so the fonts only can stretch.} % \label{tab:setfontstretch-values} % % \begin{tabfigures} % \def~{\hphantom{0}} % \begin{tabular}{@{}cccl@{}} % \toprule % \meta{level} & |stretch| & |shrink| \\ % \midrule % 0 & n/a & n/a & no operation \\ % 1 & ~\makeatletter\typog@stretch@i\makeatother & 0 & default \\ % 2 & \makeatletter\typog@stretch@ii\makeatother & 0 & \\ % 3 & \makeatletter\typog@stretch@iii\makeatother & 0 & \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \end{SCtable} % % \indexpackageoption{shrinklimits} % \indexpackageoption{stretchlimits} % The three (nonzero) shrink limits of \code{setfontshrink} can be configured with package % option~\hyperref[item:shrinklimits]{\code{shrinklimits}} and\leftspacedendash in the same % way\rightspacedendash the three (nonzero) stretch limits of \code{setfontstretch} with % package option~\hyperref[item:stretchlimits]{\code{stretchlimits}}. % % \begin{usecases} % Nudge line breaks or hyphenation points.\visualpar Control the length of the last line in % a paragraph. % \end{usecases} % % \noindent % \DescribeEnv{setfontexpand} % Manipulate both, |stretch| and |shrink|~values at the same time. % % \begin{synopsis}\label{syn:setfontexpand} % \cs{begin}|{setfontexpand}|\oarg{level} % \ttdots{} % \cs{end}|{setfontexpand}| % \end{synopsis} % % \Cref{tab:setfontexpand-values} gives an overview of the values associated with \meta{level}. % % \begin{SCtable} % \caption[Shrink and stretch values of \code{setfontexpand}] % {\slightlysloppy[2] Preconfigured values for |shrink| and |stretch| inside of % environment~\code{setfontexpand} as \nativetextfraction{1}{1000}\,em. Note that both % |shrink| and |stretch| values are nonzero, so the fonts can shrink or expand.} % \label{tab:setfontexpand-values} % % \begin{tabfigures} % \def~{\hphantom{0}} % \begin{tabular}{@{}cccl@{}} % \toprule % \meta{level} & |stretch| & |shrink| & Note \\ % \midrule % 0 & n/a & n/a & no operation \\ % 1 & ~\makeatletter\typog@stretch@i\makeatother & ~\makeatletter\typog@stretch@i\makeatother & default \\ % 2 & \makeatletter\typog@stretch@ii\makeatother & \makeatletter\typog@stretch@ii\makeatother & \\ % 3 & \makeatletter\typog@stretch@iii\makeatother & \makeatletter\typog@stretch@iii\makeatother & \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \end{SCtable} % % The six shrink and stretch limits of \code{setfontexpand} can be configured with package % options~\hyperref[item:shrinklimits]{\code{shrinklimits}} % and~\hyperref[item:stretchlimits]{\code{stretchlimits}}. % % \begin{notes} % \begin{itemize}[notopsep] % \item Environment~|setfontexpand| shares its % \hyperref[item:shrinklimits]{\code{shrinklimits}} with \code{setfontshrink} and its % \hyperref[item:stretchlimits]{\code{stretchlimits}} with \code{setfontstretch}. % % \item These environments do not nail down any font's expansion but only set up its % available range. See Sec.~3.3, \doublequotes{Font Expansion}, in the % \packagename{microtype} documentation~\cite{package:microtype}. % % Moreover, a text may not \singlequotes{respond} neither to \code{setfontshrink}, % \code{setfontstretch}, nor~\code{setfontexpand} because \TeX{} already considers it % optimal without expansion or within the previous expansion limits, e.\,g., those set at % \packagename{microtype} load~time as opposed to \packagename{typog}'s % load~time.\specialsectionendhere % \end{itemize} % \end{notes}\unskip % % \begin{usecases} % Nudge line breaks or hyphenation points.\visualpar Control the length of a paragraph, % e.\,g., to avoid a widow. % \end{usecases} % % \noindent % \DescribeEnv{nofontexpansion} % \DescribeEnv{nofontexpand} % Disable the \packagename{microtype} feature~\singlequotes{expansion} inside of the % environment. % % \begin{synopsis}\label{syn:nofontexpansion}\label{syn:nofontexpand} % \cs{begin}|{nofontexpansion}| % \ttdots{} % \cs{end}|{nofontexpansion}| \\[\smallskipamount] % |nofontexpand|~(alias) % \end{synopsis} % % The name |nofontexpand| is an alias for~|nofontexpansion|. % % \begin{usecases} % Nudge line breaks or hyphenation points.\visualpar Prevent severe scaling effects in % paragraphs strongly manipulated by other means, e.\,g., % \hyperref[syn:shortenpar]{\code{shortenpar}} % or~\hyperref[syn:prolongpar]{\code{prolongpar}}. % \end{usecases} % % % \subsubsection{Character Protrusion}\label{sec:protrusion} % \index{font>protrusion|userman} % % \DescribeEnv{nocharprotrusion} % Disable the \packagename{microtype} feature~\singlequotes{protrusion} inside of the % environment. % % \begin{synopsis}\label{syn:nocharprotrusion} % \cs{begin}|{nocharprotrusion}| % \ttdots{} % \cs{end}|{nocharprotrusion}| % \end{synopsis} % % \begin{usecases} % Table of Contents or similar tables with aligned section numbers.\visualpar Any table with % left- or right-aligned numerals in particular tabular numerals.\visualpar % Index.\label{secend:microtype-frontend} % \end{usecases} % % % \subsection{Sloppy Paragraphs}\label{sec:sloppy-paragraphs} % \index{paragraph>sloppy|userman} % % Experienced \LaTeX{} users know that \cs{sloppy} is more of a problem by itself and not % really a viable solution of the \doublequotes{overfull~box} syndrome. % % \DescribeMacro{\slightlysloppy} % \DescribeEnv{slightlysloppypar} % We define the macro~\cs{slightlysloppy} and the associated environment, % \code{slightlysloppypar}, with a user-selectable \meta{sloppiness} parameter. The % constructions recover the known settings \cs{fussy} (\meta{sloppiness}~=~0) and \cs{sloppy} % (\meta{sloppiness}~\(\ge\)~8), and introduce seven intermediate % \meta{sloppiness}~levels.\!\footnote{Also compare with the findings for \cs{emergencystretch} % in reference~\citenum{wermuth:2017a}.} The default \meta{sloppiness} is 1. % % \begin{synopsis}\label{syn:slightlysloppy}\label{syn:slightlysloppypar} % \cs{slightlysloppy}\oarg{sloppiness} \\[\smallskipamount] % \cs{begin}|{slightlysloppypar}|\oarg{sloppiness} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{slightlysloppypar}| % \end{synopsis} % % \Cref{tab:slightlysloppy} summarizes the adjustments that \cs{slightlysloppy} makes depending % on the \meta{sloppiness}~level. % % \begin{table} % \centering % \caption[Parameter adjustments of \cs{slightlysloppy}]% % {Adjustments made by \cs{slightlysloppy} to various \TeX~parameters at different % levels of \meta{sloppiness}.} % \label{tab:slightlysloppy} % % \newcommand*{\tolerancemark}{\tablenotemark{\dag}}% % \newcommand*{\scaledmark}{\tablenotemark{\ddag}}% % % \begin{suspendshortverb} % \begin{tabfigures} % \def~{\hphantom{0}} % \begin{tabular}{@{}ccccl@{}} % \toprule % \meta{sloppiness} & \cs{toler-} & \cs{hfuzz} & \cs{emergency-} & Note \\ % {} & \code{ance} & \cs{vfuzz} & \code{stretch}~\(G\) & \\ % {} & & pt & em & \\ % \midrule % 0 & ~200\hphantom{\tolerancemark} & .1~ & 0\hphantom{.000\scaledmark} & \TeX: \verb+\fussy+ \\ % 1 & ~330\tolerancemark & .15 & ~.375\scaledmark & default \\ % 2 & ~530\tolerancemark & .2~ & ~.75\scaledmark~ & \\ % 3 & ~870\tolerancemark & .25 & 1.125\scaledmark & \\ % 4 & 1410\tolerancemark & .3~ & 1.5\scaledmark~~ & \\ % 5 & 2310\tolerancemark & .35 & 1.875\scaledmark & \\ % 6 & 3760\tolerancemark & .4~ & 2.25\scaledmark~ & \\ % 7 & 6130\tolerancemark & .45 & 2.625\scaledmark & \\ % \(\ge\)\:8 & 9999\hphantom{\tolerancemark} & .5~ & 3\hphantom{.000\scaledmark} & \TeX: \verb+\sloppy+ \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \end{suspendshortverb} % % \begin{tablenotes} % \renewcommand*{\tablenotemark}[1]{#1}% % \tolerancemark\enspace % All intermediate levels set \(\cs{pretolerance} = \cs{tolerance} / 2\). % % \scaledmark\enspace % The intermediate levels scale the amount of available glue~\(G\) (indicated in column~4 % of the table) for \cs{emergencystretch} with the actual line length, this means, in these % levels % \begin{equation*} % \cs{emergencystretch} = G \times \frac{\cs{linewidth}}{\cs{textwidth}}. % \end{equation*} % to prevent excessive stretchability in narrow lines. % \end{tablenotes} % \end{table} % % Environment~|slightlysloppypar|\oarg{sloppiness} mimics \LaTeX's~\code{sloppypar}, while % offering the flexibility of~\cs{slightlysloppy}. % % \begin{usecases} % Drop-in replacement for \cs{sloppy}, whether explicit or implicit (think of % \cs{parbox}).\visualpar Initial paragraphs in theorem environments (e.\,g., as defined by % \packagename{amsmath} or \packagename{amsthm}), where the theorem~head already takes a lot % of space.\visualpar Bibliographies as environment~\code{thebibliography} sets~\cs{sloppy}. % \end{usecases} % % % \newpagetofixtoc % \subsection{Vertically Partially-Tied Paragraphs}\label{sec:vtie-paragraph} % \index{paragraph>vertically tied|userman} % % \LaTeX{} provides several macros and environments to tie material vertically\spacedemdash % most prominently |samepage| and |minipage|.\!\footnote{A valuable complement to these is % package~\packagename{needspace}~\cite{package:needspace} which takes a different approach and % reliably works in \emph{mixed} horizontal and vertical mode situations.} % \packagename{Typog's} macros and environments constitute more sophisticated but weaker forms % of these. They tie only the first or last couple of lines in a paragraph while the rest of % the paragraph gets broken into pages by \TeX{} in the usual way. % % The macros and environments described in this section locally set \eTeX{} penalty % arrays~\cite[Sec.~3.8]{package:etex}. In addition the environments~\code{vtietoppar}, % \code{vtiebotpar}, and~\code{vtiebotdisptoppar} explicitly issue a \cs{par} at the end of the % group. % % \DescribeMacro{\vtietop} % \DescribeEnv{vtietoppar} % Avoid a club\index{forlorn line>club|userman} line in each partial paragraph. % % \begin{synopsis}\label{syn:vtietop}\label{syn:vtietoppar} % \cs{vtietop}\oarg{number-of-lines} \\[\smallskipamount] % \cs{begin}|{vtietoppar}|\oarg{number-of-lines} % \ttdots{} % \cs{end}|{vtietoppar}| % \end{synopsis} % % Vertically tie the first \meta{number\hyp{}of\hyp{}lines} in a paragraph. Zero or one for % \meta{number\hyp{}of\hyp{}lines} are no-ops. Up to nine lines can be fused. The default is % to link three lines. % % \begin{usecases} % String together the first paragraph right after a sectioning macro.\visualpar Tie the % first line of an itemized, enumerated, or a description list\index{list|userman} with the % paragraph following~\cs{item}. % \end{usecases} % % \noindent % \DescribeMacro{\splicevtietop} % Inside of a \code{list} a one-off solution simply concatenates % \cs{item}[\dots\itcorr{-5}]\cs{vtietop} to fuse the line with the \code{item\#}, the % representation of the \code{enum\#}, or the description term with the first paragraph. For a % systematic use prefer \cs{splicevtietop} and apply it as the first thing in the % \code{list}~body. % % \begin{synopsis}\label{syn:splicevtietop} % \cs{splicevtietop}\oarg{number-of-lines} % \end{synopsis} % % Use this macro \emph{inside} of a \code{list}-like environment to equip each \cs{item} with % \cs{vtietop}\oarg{number-of-lines}. The default \meta{number-of-lines} is three as for any % of the \code{vtie\ttdots}~functions. % % Example for a \code{description}~list and plain \LaTeX: % % \begin{codeexample} % 12\=\kill % \cs{begin}\{description\} \\ % \> \cs{splicevtietop}[2] \\ % \> \cs{item}[...] \\ % \cs{end}\{description\} % \end{codeexample} % % Alternatively with package~\packagename{enumitem}~\cite{package:enumitem}: % % \begin{codeexample} % 12\=\kill % \cs{begin}\= \{description\}[first=\cs{splicevtietop[2]}] \\ % \> \cs{item}[...] \\ % \cs{end}\{description\} % \end{codeexample} % % \noindent % or shorter and with the default \meta{number-of-lines},~3, using the \packagename{enumitem} % style\footnote{The documentation of \packagename{enumitem} prosaically calls them % \singlequotes{keys} (Section~3) not \singlequotes{styles}.}~\code{vtietop}: % % \DescribeEnumItemKey{vtietop} % \begin{codeexample} % \cs{usepackage}\{enumitem\} \\ % \cs{begin}\= \{description\}[vtietop] \\ % ~~\cs{item}[...] \\ % \cs{end}\{description\} % \end{codeexample} % % \medskip % % \noindent % \DescribeMacro{\vtiebot} % \DescribeEnv{vtiebotpar} % Avoid a widow\index{forlorn line>widow|userman} line in each partial paragraph. % % \begin{synopsis}\label{syn:vtiebot}\label{syn:vtiebotpar} % \cs{vtiebot}\oarg{number-of-lines} \\[\smallskipamount] % \cs{begin}|{vtiebotpar}|\oarg{number-of-lines} % \ttdots{} % \cs{end}|{vtiebotpar}| % \end{synopsis} % % Vertically tie the last \meta{number\hyp{}of\hyp{}lines} in a paragraph. Zero or one for % \meta{number\hyp{}of\hyp{}lines} are no-ops. Up to nine lines can be fused. The default is % to link three lines. % % \noindent % \DescribeEnv{vtiebotdisp} % Avoid a display widow\index{forlorn line>display widow|userman} line in each partial % paragraph. % % \begin{synopsis}\label{syn:vtiebotdisp}\label{syn:vtiebotdisppar} % \cs{begin}|vtiebotdisp|\oarg{before-disp-number-of-lines} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{vtiebotdisp}| % \end{synopsis} % % Vertically tie the last \meta{before\hyp{}disp\hyp{}number\hyp{}of\hyp{}lines} in a paragraph % before a display. Zero or one for \meta{before\hyp{}disp\hyp{}number\hyp{}of\hyp{}lines} are % no-ops. Up to nine lines can be fused. The default is to link three lines. % % To use the environment, bracket the paragraph before the display (the one that needs % protection) and the associated displayed math: % % \begin{codeexample} % \cs{begin}\{vtiebotdisp\} \\ % ~~\% \textit{vertically tied paragraph before the math display} \\ % ~~\cs{begin}\{equation\} \\ % ~~~~\% \textit{math} \\ % ~~\cs{end}\{equation\} \\ % \cs{end}\{vtiebotdisp\} % \end{codeexample} % % \DescribeEnv{vtiebotdisptoppar} % Avoid a display widow, compound the display with its preceding \emph{and} following % paragraph, and avoid a club line in the paragraph right after the display. % % \begin{synopsis}\label{syn:vtiebotdisptop}\label{syn:vtiebotdisptoppar} % \begin{tabbing} % \cs{begin}|{vtiebotdisptoppar}|\= \oarg{before-disp-number-of-lines} \\ % \> \oarg{after-disp-number-of-lines} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{vtiebotdisptoppar}| % \end{tabbing} % \end{synopsis} % % Vertically tie the last \meta{before\hyp{}disp\hyp{}number\hyp{}of\hyp{}lines} in the % paragraph before a display and the first % \meta{after\hyp{}disp\hyp{}number\hyp{}of\hyp{}lines} in the paragraph after the display. % Moreover, turn the paragraphs and the display into an unbreakable unit.\!\footnote{The % paragraphs and the display are concreted together by setting both \cs{predisplaypenalty} % and~\cs{postdisplaypenalty} to~10000.} % % Zero or one for \meta{before-disp-number\hyp{}of\hyp{}lines} as well as % \meta{after\hyp{}disp\hyp{}number\hyp{}of\hyp{}lines} are no-ops for the paragraph. Up to % nine lines each can be fused. % % Both optional arguments default to three. If only the first argument is given the second % acquires the same value. % % To use the environment, bracket the paragraphs before and after the display: % % \begin{codeexample} % \cs{begin}\{vtiebotdisptoppar\} \\ % ~~\% \textit{vertically tied paragraph before the math display} \\ % ~~\cs{begin}\{equation\} \\ % ~~~~\% \textit{math} \\ % ~~\cs{end}\{equation\} \\ % ~~\% \textit{vertically tied paragraph after the math display} \\ % \cs{end}\{vtiebotdisptoppar\} % \end{codeexample} % % \smallskip % % \noindent % See also \cref{sec:fill-last-line-gp-environments} for other methods to avoid club or widow % lines. % % \begin{typoginspectpar}{partial-paragraphs} % \setlength{\smoothraggedrightragwidth}{8pt} % \paragraph{Partial Paragraphs And Counting Lines.} % % The top-of-paragraph ties, \cs{vtietop} and \code{vtietoppar} count % \meta{number\hyp{}of\hyp{}lines} from the beginning of every partial paragraph. Each % displayed math in the paragraph resets the count. The bottom-paragraph ties, \cs{vtiebot}, % \code{vtiebotpar}, \cs{vtiebotdisp}, and \code{vtiebotdisppar} count backward from the end % of each partial paragraph. Again, each displayed math in the paragraph resets the count. % According to \TeX's rules, a displayed math formula always is counted as \emph{three} lines % no matter its contents. \Cref{tab:partial-paragraph-line-counts} summarizes these rules % with the help of an example. % \end{typoginspectpar} % % \begin{table} % \centering % \caption[Partial paragraph line counts] % {Exemplary, eight-line paragraph compounded of two partial paragraphs of three and % two lines and a displayed math formula of arbitrary size sandwiched in between.} % \label{tab:partial-paragraph-line-counts} % % \newcommand*{\clubmark}{\tablenotemark{\dag}} % \newcommand*{\widowmark}{\tablenotemark{\ddag}} % % \begin{tabfigures} % \begin{tabular}{@{}clcc@{}} % \toprule % Continuous & Example & \cs{vtietop}\clubmark & \cs{vtiebot}\widowmark \\ % Line Number & Contents & Count & Count \\ % \midrule % 1 & Text line\textsubscript{1} & 1 & 3 \\ % 2 & Text line\textsubscript{2} & 2 & 2 \\ % 3 & Text line\textsubscript{3} & 3 & 1 \\ % 4 & & & \\ % 5 & \(\smash{\Biggr\}}\) \parbox[c][0pt]{3.5em}{Display \\[-.12em] math} & & \\ % 6 & & & \\ % 7 & Text line\textsubscript{4} & 1 & 2 \\ % 8 & Text line\textsubscript{5} & 2 & 1 \\ % \bottomrule % \end{tabular} % \end{tabfigures} % % \begin{tablenotes} % \renewcommand*{\tablenotemark}[1]{#1}% % \clubmark\enspace % This is \eTeX's counting scheme of \cs{clubpenalties}; it also holds for % \code{vtietoppar}. % % \widowmark\enspace % The same counting scheme also holds for \code{vtiebotpar}, \cs{vtiebotdisp}, % and~\code{vtiebotdisppar}. It is implied by \eTeX's line counts of \cs{widowpenalties} % and~\cs{displaywidowpenalties} on which the functions of this package are based. % \end{tablenotes} % \end{table} % % \begin{tips} % \begin{itemize}[notopsep] % \item The environments can be combined to arrive at paragraphs that simultaneously are % protected against club lines and (display) widow lines. % % \item For very long derivations that are not interrupted and thus made breakable with the % help of \cs{intertext}\footnote{Introduced in % package~\packagename{amsmath}~\cite{package:amsmath}.} or % \cs{shortintertext}\footnote{Defined in % package~\packagename{mathtools}~\cite{package:mathtools}.} it is desirable to make the % display breakable. This is achieved with \cs{allowdisplaybreaks} or the % environment~\code{breakabledisplay} which will be described % in~\cref{sec:breakable-display}.\specialsectionendhere % \end{itemize} % \end{tips}\unskip % % \begin{usecases} % Avoid widows and orphans, e.\,g., those turned up by % package~\packagename{widows-and-orphans}~\cite{package:widows-and-orphans}.\visualpar % Extend the convention of using three to four lines instead of a single club or widow line % to a flexible, context-dependent rule that aims to keep all the relevant information % together for the reader\spacedemdash ideally, at least. % \end{usecases} % % % \subsection{Breakable Displayed Equations}\label{sec:breakable-display} % \index{page break|userman} % % \DescribeEnv{breakabledisplay} % Package~\packagename{amsmath}\index{amsmath=\packagename{amsmath} (package)|userman} offers % \cs{allowdisplaybreaks} to render displayed equations breakable at each of their lines. % Environment~\cs{breakabledisplay} is a wrapper around it which limits the macro's influence % to the environment. Furthermore, the default \meta{level} of \code{breakabledisplay} is~3 % whereas that of \cs{allowdisplaybreaks} is~4. This results in fewer breaks in displayed % equations, making \code{breakabledisplay} more suitable for automated page breaking. % % \begin{synopsis}\label{syn:breakabledisplay} % \cs{begin}|{breakabledisplay}|\oarg{level} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{breakabledisplay}| % \end{synopsis} % % Environment~|breakabledisplay| simply passes on \meta{level} to \cs{allowdisplaybreaks}. % \Cref{tab:allowdisplaybreaks-penalties} shows the default penalties that % \packagename{amsmath} associated with each of the \meta{level}s. % % \begin{table} % \centering % \caption[Env.~\code{breakabledisplay} and \cs{interdisplaylinepenalty}]% % {Penalties~\cs{interdisplaylinepenalty} associated with different \meta{level}s of % environment~\code{breakabledisplay}. Depending on the version of % package~\packagename{amsmath} the actual penalties may differ.} % \label{tab:allowdisplaybreaks-penalties} % % \newcommand*{\clubmark}{\tablenotemark{\dag}} % % \begin{tabfigures} % \def~{\hphantom{0}} % \begin{tabular}{@{}ccl@{}} % \toprule % \meta{level} & \cs{interdisplay-} & Note \\ % {} & \code{linepenalty} & \\ % \midrule % 0 & 10000 & no operation \\ % 1 & ~9999 & \\ % 2 & ~6999 & \\ % 3 & ~2999 & default \\ % 4 & ~~~~0\rlap{\clubmark} & \\ % \bottomrule % \end{tabular} % \end{tabfigures} % % \begin{tablenotes} % \renewcommand*{\tablenotemark}[1]{#1}% % \clubmark\enspace % This is the default of \cs{allowdisplaybreaks}. % \end{tablenotes} % \end{table} % % \begin{tips} % \begin{itemize}[notopsep] % \item Terminating a line with \sample{\code{\textbackslash\textbackslash*}} inhibits a % break after this line. % % \item A \cs{displaybreak}\oarg{level} can be set for \emph{each} line of the displayed % equation separately. \LaTeX{} resumes with the original value of % \cs{interdisplaylinepenalty} in the following lines. Note, however, that % \cs{displaybreak} is only effective (immediately) in front of % \sample{\code{\textbackslash\textbackslash}}. See the \doublequotes{User's Guide for the % \packagename{amsmath}~Package} for a discussion~\cite[Sec.~3.9]{package:amsmath}. % % \item If a discretionary break of the displayed equation is to be accompanied with some aid % for the reader, team \cs{intertext} (or \cs{shortintertext}) with \cs{displaybreak} as, % e.\,g., % % \begin{codeexample} % \cs{newcommand*}\{\cs{discretionarydisplaybreak}\} \\ % 12\=3\=\kill % \> \{ \> \cs{intertext}\{\cs{hfill} Eq.\textasciitilde cont.\textasciitilde on next page.\}\% \\ % \> \> \cs{displaybreak} \\ % \> \> \cs{intertext}\{Eq.\textasciitilde cont.\textasciitilde % from prev.\textasciitilde page.\cs{hfill}\}\}\specialsectionendhere % \end{codeexample} % \end{itemize} % \end{tips}\unskip % % \begin{usecases} % Extremely long derivations without interspersed \cs{intertext} or % \cs{shortintertext}.\visualpar Draft phase of a document. % \end{usecases} % % % \subsection{\packagename{Setspace} Front End}\label{sec:setspace-frontend} % % Package \packagename{setspace} \cite{package:setspace} is a base hit when it comes to % consistently setting the line skip for a document via the macro~\cs{setstretch}. The % interface of \cs{setstretch} though is unintuitive as it asks for an obscure % factor.\fontsizeinfo{setspacefontsizeinfo}\marginnote{The copy of this document gets typeset % with~\setspacefontsizeinfo*.} The \LaTeX{} user however prefers to keep her eyes on the ball % and set the line skip\index{baseline skip|userman} directly (e.\,g.~12.5\,pt) or the lines' % leading\index{leading|userman} to a length or percentage of the font's size.\!\footnote{To % find out about the current font's size and the \cs{baselineskip} in printable form check out % \cref{sec:font-information} on \cpageref{sec:font-information}.} This is where the following % macros go to bat. % % \begin{important} % All macros that are introduced in this section rely on macro~\cs{setstretch}. So % package~\packagename{setspace} must have been loaded with % % \begin{codeexample} % \cs{usepackage}\{setspace\} % \end{codeexample} % % \noindent % in the document preamble. % \end{important} % % \DescribeMacro{\setbaselineskip} % \sinceversion{Since v0.3} % Set the line skip using an absolute length\spacedemdash technically: a |dimen|. % % \begin{synopsis}\label{syn:setbaselineskip} % \cs{setbaselineskip}\marg{baseline-skip} % \end{synopsis} % % Set the \cs{baselineskip} to \meta{baseline-skip}. This is what a non-initiated user expects % from the assignment % % \begin{codeexample} % \cs{setlength}\{\cs{baselineskip}\}\{\meta{baseline-skip}\} % \end{codeexample} % % The \meta{baseline-skip} can contain a rubber (stretch/shrink) component, however, % \cs{setbaselineskip} will discard of it and issue a warning that only the fixed-length part % will be used in the computation. % % \begin{example} % \begin{itemize}[notopsep] % \item Let us assume we want to lighten the gray value of the copy a tad with the % \cs{baselineskip} increased from 12\,pt to~12.5\,pt. To this end we say: % % \begin{codeexample} % \cs{setbaselineskip}\{12.5\,pt\} % \end{codeexample} % % \item In a generic part of the document, where the actual \cs{baselineskip} is not known, % we can refer to its current value and rescale it: % % \begin{codeexample} % \cs{setbaselineskip}\{\cs{baselineskip} * 12.5 / 12\} % \end{codeexample} % % Care should be taken if code like the above is implicitly or explicitly % repeated, because it results in a geometric series.\specialsectionendhere % \end{itemize} % \end{example} % % \DescribeMacro{\resetbaselineskip} % \sinceversion{Since v0.3} % Reset the \cs{baselineskip} to its original value. % % \begin{synopsis}\label{syn:resetbaselineskip} % \cs{resetbaselineskip} % \end{synopsis} % % This macro simply expands to |\setstretch{1}|. So, we rely on \packagename{setspace}'s % notion of what is a single-line \cs{baselineskip}. % % % \hangindent=2\parindent % \hangafter=-2 % \noindent % \DescribeMacro{\setbaselineskippercentage} % \sinceversion{Since v0.3} % Set the \cs{baselineskip} with a relative value calculated as a percentage of the current % font's point size. % % \begin{synopsis}\label{syn:setbaselineskippercentage} % \cs{setbaselineskippercentage}\marg{baselineskip-percentage} % \end{synopsis} % % Set \cs{baselineskip} to \(\cs{typogfontsize} \times \meta{baselineskip-percentage} / 100\). % % \begin{example} % We modify the previous example and assume a point size of 10\,pt, but now write % % \begin{codeexample} % \cs{setbaselineskippercentage}\{125\} % \end{codeexample} % % \noindent % which sets \cs{baselineskip} to \(10\text{\,pt} \times 125 / 100 = 12.5\text{\,pt}\). % \end{example} % % \DescribeMacro{\setleading} % \sinceversion{Since v0.3} % Set the \cs{baselineskip} with an absolute length that gets \emph{added to} \cs{typogfontsize}. % % \begin{synopsis}\label{syn:setleading} % \cs{setleading}\marg{leading} % \end{synopsis} % % Set the \cs{baselineskip} to \cs{typogfontsize} plus \meta{leading}. Note that % \meta{leading} can be negative, e.\,g.~to set solid. % % \begin{example} % Another solution of the previous example, given a point size of 10\,pt is to write % % \begin{codeexample} % \cs{setleading}\{2.5pt\} % \end{codeexample} % % \noindent % which sets \cs{baselineskip} to \(10\text{pt} + 2.5\text{pt} = 12.5\text{pt}\). % \end{example} % % \DescribeMacro{\setleadingpercentage} % \sinceversion{Since v0.3} % Set the \cs{baselineskip} to \cs{typogfontsize} \emph{plus} a relative value calculated as a % percentage of \cs{typogfontsize}. % % \begin{synopsis}\label{syn:setleadingpercentage} % \cs{setleadingpercentage}\marg{leading-percentage} % \end{synopsis} % % Set \cs{baselineskip} to \(\cs{typogfontsize} \times (1 + \meta{leading-percentage} / 100)\). % % \begin{example} % We modify the previous example and again assume a point size of 10\,pt, but now write % % \begin{codeexample} % \cs{setleadingpercentage}\{25\} % \end{codeexample} % % \noindent % which sets \cs{baselineskip} to \(10\text{\,pt} \times (1 + 25 / 100) = 12.5\text{\,pt}\). % \end{example} % % \smallskip % % \DescribeLaTeXDimen{\typogfontsize} % \sinceversion{Since v0.3} % The macros \cs{setbaselineskippercentage}, \cs{setleading}, and \cs{setleadingpercentage} all % depend on the font size. By changing \cs{typogfontsize} they can be configured for different % font sizes. % % The length \cs{typogfontsize} gets initialized at the end of the preamble to the default % font's quad size:\footnote{For an overview of the various % \cs{fontdimen}\meta{number}~parameters consult \cref{tab:fontdimen} on % \cpageref{tab:fontdimen}.} % % \begin{codeexample}\label{syn:typogfontsize} % \cs{typogfontsize}=\cs{fontdimen6}\cs{font} % \end{codeexample} % % \noindent % which is also called its \doublequotes{nominal size} or its \doublequotes{point size}. This % assignment can be repeated at any point in the document to record a reference font's size. % To set just \cs{typogfontsize} without changing the current font, encapsulate the font change % in a group and export the new value: % % \begin{codeexample} % \cs{begingroup} \\ % ~~\cs{usefont}\{T1\}\{Arvo-TLF\}\{m\}\{n\}\cs{selectfont} \\ % ~~\cs{normalsize} \\ % ~~\cs{global}\cs{typogfontsize}=\cs{fontdimen6}\cs{font} \\ % \cs{endgroup} % \end{codeexample} % % An alternative to relying on the point size is using the actual size of an uppercase letter: % % \begin{codeexample} % \cs{settoheight}\{\cs{typogfontsize}\}\{CEMNORSUVWXZ\} % \end{codeexample} % % \noindent % With \cs{typogfontsize} defined this way it becomes trivial to set solid: % % \begin{codeexample} % \cs{setleading}\{0pt\} % \end{codeexample} % % \noindent % or % % \begin{codeexample} % \cs{setleadingpercentage}\{0\} % \end{codeexample} % % \begin{tip} % All macros in this section actually accept expressions of their argument types, though the % sick rules of \TeX{} \meta{dimen}- and \meta{skip}-expressions apply. % % Here are some forms that do work: % % \begin{codeexample} % \cs{setbaselineskip}\{12pt + 0.6667pt\} \\ % \cs{setbaselineskip}\{12pt * 110 / 100\} \\ % \cs{setbaselineskippercentage}\{100 + 25\} \\ % \cs{setleading}\{1pt / -2.0\} \\ % \cs{setleadingpercentage}\{10 - 25 / 2\}\specialsectionendhere % \end{codeexample}\label{secend:setspace-frontend} % \end{tip} % % % \clearpage % \subsection{Smooth Ragged}\label{sec:smooth-ragged} % \index{ragged right|userman} % % \begin{whittyquote} % The attention someone gives \\ % to what he or she makes \\ % is reflected in the end result, \\ % whether it is obvious or not. \\ % \capitalemdash*~\propername{Erik Spiekermann} % \end{whittyquote} % % \noindent % Package \packagename{typog} implements a novel approach to typesetting ragged paragraphs. % Instead of setting the glue inside a paragraph to zero and letting the line~widths vary % accordingly~\cite{wermuth:2020}, we prescribe the line~widths with \TeX's % \cs{parshape}~primitive and leave the stretchability and shrinkability of the glue unchanged. % % \begin{caution} % None of the following environments work within lists (e.\,g.~\code{description}, % \code{enumerate}, or \code{itemize}). % \end{caution} % % \begin{slightlysloppypar}[2] % \hangindent=3.5\parindent % \hangafter=-6 % \noindent % \DescribeEnv{smoothraggedrightshapetriplet} % \DescribeEnv{smoothraggedrightshapequintuplet} % \DescribeEnv{smoothraggedrightshapeseptuplet} % We introduce three environments that define three, five, or seven different line~lengths % (which \TeX{} will, of course, repeat for paragraphs longer than three, five, or seven % lines): \code{smoothraggedrightshapetriplet}, \code{smoothraggedrightshapequintuplet}, and % \code{smoothraggedrightshapeseptuplet}. They work for paragraph lengths up to % \makeatletter % \typog@triplet@max@lines, \typog@quintuplet@max@lines, and % \typog@septuplet@max@lines~lines, respectively. % \makeatother % \end{slightlysloppypar} % % \begin{widebody} % \begin{synopsis}\label{syn:smoothraggedrightshapetriplet}\label{syn:smoothraggedrightshapequintuplet}\label{syn:smoothraggedrightshapeseptuplet} % \cs{begin}|{smoothraggedrightshapetriplet}|{[\meta{option}\ttdots]}\marg{width1}\marg{width2}\marg{width3} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{smoothraggedrightshapetriplet}| \\[\smallskipamount] % \cs{begin}|{smoothraggedrightshapequintuplet}|{[\meta{option}\ttdots]}\marg{width1}\ttdots\marg{width5} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{smoothraggedrightshapequintuplet}| \\[\smallskipamount] % \cs{begin}|smoothraggedrightshapeseptuplet|{[\meta{option}\ttdots]}\marg{width1}\ttdots\marg{width7} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{smoothraggedrightshapeseptuplet}| % \end{synopsis} % \end{widebody} % % The environments take \(N\) = 3, 5, or~7 mandatory line-width parameters, where each % \meta{width\itcorr{3}I}, \(I = 1,~\dots, N\), is a skip, i.\,e., a dimen that can include % some glue. % % Option \code{leftskip=}\meta{dim} sets the left margin of the smooth ragged paragraph to % \meta{dim}; it is similar to the \TeX{} parameter~\cs{leftskip}. % Option~\code{parindent=}\meta{dim} sets the first-line indent of the smooth ragged paragraph % to \meta{dim}; it is similar to the \TeX{} parameter~\cs{parindent}. % % \noindent % \DescribeEnv{smoothraggedrightpar} % Environment~|smoothraggedrightpar| builds upon the three environments just described, using % them as \singlequotes{generators}. It prescribes three, five, or seven relative line~lengths % that are known to yield convincing rags. % % \begin{synopsis}\label{syn:smoothraggedrightpar} % \cs{begin}|{smoothraggedrightpar}|{[\meta{option}\ttdots]} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{smoothraggedrightpar}| % \end{synopsis} % % Typeset a single paragraph with a given rag~width---set with the global % parameter~\hyperref[syn:smoothraggedrightragwidth]{\code{smoothraggedrightragwidth}}---of the % right margin, where with \doublequotes{rag width} we mean the length difference of the % longest and the shortest lines. Select the generator with % \hyperref[syn:smoothraggedrightgenerator]{\code{smoothraggedrightgenerator}}. The line % lengths equally divide the ragged margin, i.\,e., they form an arithmetic sequence based on % the generator size. % % Option \code{linewidth=}\meta{dim} overrides the length of the longest line with \meta{dim}. % The default line~width is the current \cs{line\-width}. % % \iffalse %<*smoothparshapes> prologues := 3; def draw_filled_rectangle(expr lower_left, upper_right, color) = fill lower_left -- (xpart upper_right, ypart lower_left) -- upper_right -- (xpart lower_left, ypart upper_right) -- cycle withcolor color; enddef; u := 100; em := 10; linelength := 2u; baselineskip := 1.2em; parskip := 3; parindent := 2.5em; ragwidth := 2em; cmykcolor line_color; line_color := (.08, 0, 0, .18); % cold silver color customred[]; customred[1] := (.890, .282, .282); customred[2] := (.831, .110, .110); customred[3] := (.686, .043, .043); customred[4] := (.569, .000, .000); customred[5] := (.420, .000, .000); color margin_color; margin_color := customred[2]; beginfig(1); % triplet y := 0; draw_filled_rectangle((0, y), (linelength - ragwidth, y + 1em), line_color); % (1) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); % (3) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - ragwidth/2, y + 1em), line_color); % (2) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - ragwidth, y + 1em), line_color); % (1) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); % (3) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - ragwidth/2, y + 1em), line_color); % (2) draw_filled_rectangle((-.667em, 1em), (-.333em, -5baselineskip), margin_color); draw_filled_rectangle((linelength + .333em, 1em), (linelength + .667em, -5baselineskip), margin_color); endfig; beginfig(2); % quintuplet y := 0; draw_filled_rectangle((0, y), (linelength - .75ragwidth, y + 1em), line_color); % (2) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); % (5) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .5ragwidth, y + 1em), line_color); % (3) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .25ragwidth, y + 1em), line_color); % (4) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - ragwidth, y + 1em), line_color); % (1) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .75ragwidth, y + 1em), line_color); % (2) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); % (5) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .5ragwidth, y + 1em), line_color); % (3) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .25ragwidth, y + 1em), line_color); % (4) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - ragwidth, y + 1em), line_color); % (1) draw_filled_rectangle((-.667em, 1em), (-.333em, -9baselineskip), margin_color); draw_filled_rectangle((linelength + .333em, 1em), (linelength + .667em, -9baselineskip), margin_color); endfig; beginfig(3); % septuplet y := 0; draw_filled_rectangle((0, y), (linelength - .6667ragwidth, y + 1em), line_color); % (3) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .1667ragwidth, y + 1em), line_color); % (6) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - ragwidth, y + 1em), line_color); % (1) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .3333ragwidth, y + 1em), line_color); % (5) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .8333ragwidth, y + 1em), line_color); % (2) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); % (7) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .5ragwidth, y + 1em), line_color); % (4) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .6667ragwidth, y + 1em), line_color); % (3) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .1667ragwidth, y + 1em), line_color); % (6) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - ragwidth, y + 1em), line_color); % (1) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .3333ragwidth, y + 1em), line_color); % (5) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .8333ragwidth, y + 1em), line_color); % (2) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength, y + 1em), line_color); % (7) y := y - baselineskip; draw_filled_rectangle((0, y), (linelength - .5ragwidth, y + 1em), line_color); % (4) draw_filled_rectangle((-.667em, 1em), (-.333em, -13baselineskip), margin_color); draw_filled_rectangle((linelength + .333em, 1em), (linelength + .667em, -13baselineskip), margin_color); endfig; end % % \fi % % \begin{itemize}[noindent] % \item % \begin{minipage}[t]{\linewidth} % The triplet generator repeats a \emph{short~line--long~line--middle-length~line} % sequence. Shown below are two complete cycles. % % \begin{center} % \includegraphics{smooth-parshapes-1.mps} % \end{center} % \end{minipage} % % \item % \begin{minipage}[t]{\linewidth} % The quintuplet generator varies the triplet theme and avoids the \singlequotes{ladder} % pattern of lines~2\figuredash3\figuredash4 (or, if numbered by % cycle:~1.2\figuredash1.3\figuredash2.1). Shown here are two cycles. % % \begin{center} % \includegraphics{smooth-parshapes-2.mps} % \end{center} % \end{minipage} % % \item % \begin{minipage}[t]{\linewidth} % The septuplet generator uses a permutation that appears \singlequotes{random}; at the % very least, it conceals the cycle boundaries effectively. Shown here are two of them. % % \begin{center} % \includegraphics{smooth-parshapes-3.mps} % \end{center} % \end{minipage} % \end{itemize} % % The graphical representations of the smooth-ragged-right-paragraph shapes shown above are % based on the actual values used by the environments and not made~up only for pretty figures. % % \noindent % \DescribeEnv{smoothraggedright} % Environment~|smoothraggedright| is the multi-paragraph version of % \code{smoothraggedrightpar}. It takes the same optional arguments. % % \begin{synopsis}\label{syn:smoothraggedright} % \cs{begin}|{smoothraggedright}|{[\meta{option}\ttdots]} \\ % \hspace*{1em}\ttdots \\ % \cs{end}|{smoothraggedright}| % \end{synopsis} % % \DescribeMacro{\smoothraggedrightfuzzfactor} % \indent % The environments \code{smoothraggedright} and \code{smoothraggedrightpar} add glue to every % line~width\footnote{The shortest line only gets stretchability, the longest receives only % shrinkability. All other lines are both stretchable and shrinkable.} to achieve a more % convincing \doublequotes{ragged appearance} and to reduce the number of overfull lines. The % algorithm divides the smooth margin into 3, 5, or~7 parts depending on the chosen % \cs{smoothraggedrightgenerator} (see below). % % \begin{synopsis}\label{syn:smoothraggedrightfuzzfactor} % \cs{renewcommand*}\{\cs{smoothraggedrightfuzzfactor}\}\marg{\itcorr{7}factor} % \end{synopsis} % % The \cs{smoothraggedrightfuzzfactor} is the amount of glue of each line expressed as a % multiple of the distance between the division points. The default~\meta{\itcorr{7}factor} of % 1.0 means that glue is added just enough to prevent the lines from overlapping (assuming % justification is feasible). % % \DescribeMacro{\smoothraggedrightgenerator} % \indent % This macro selects the generator to use. % % \begin{synopsis}\label{syn:smoothraggedrightgenerator} % \cs{renewcommand*}\{\cs{smoothraggedrightgenerator}\}\marg{generator} % \end{synopsis} % % Valid \meta{generator} names are % % \begin{itemize}[noitemsep] % \item |triplet|, % \item |quintuplet|, and % \item |septuplet|. % \end{itemize} % % \noindent % The default generator is |triplet|. % % \DescribeLaTeXSkip{\smoothraggedrightleftskip} % \indent % Value for |leftskip| to pass to the generator. % % \begin{synopsis}\label{syn:smoothraggedrightleftskip} % \cs{smoothraggedrightleftskip}=\meta{dim} % \end{synopsis} % % Default: \formatdimen*{0pt}. % % \DescribeLaTeXSkip{\smoothraggedrightparindent} % \indent Value for |parindent| to pass to the generator. % % \begin{synopsis}\label{syn:smoothraggedrightparindent} % \cs{smoothraggedrightparindent}=\meta{dim} % \end{synopsis} % % Default: \formatdimen*{0pt}. % % \DescribeLaTeXSkip{\smoothraggedrightragwidth} % \indent Value for the width of the ragged right margin. % % \begin{synopsis}\label{syn:smoothraggedrightragwidth} % \cs{smoothraggedrightragwidth}=\meta{dim} % \end{synopsis} % % Default:~2\,em.\!\footnote{This is also the default rag width of \packagename{ragged2e's} % \cs{RaggedRight}~\cite{package:ragged2e}.} % % \begin{usecases} % Replacement for \cs{RaggedRight}~\cite{package:ragged2e}.\visualpar A design alternative to % fully justified paragraphs when used with a small rag~width. % \end{usecases} % % \begin{futuredirection} % Translate the code to \packagename{l3galley} which is part of the % \packagename{l3experimental}~package~\cite{package:l3experimental}. Galley~code is % supposed to work inside of lists, too. % \end{futuredirection} % % % \paragraph{Sample Smooth-Ragged-Right Paragraph at Full Text-Width}\leavevmode\par % % \begin{samepage} % \def\smoothraggedrightgenerator{quintuplet} % \setlength{\smoothraggedrightragwidth}{7pt} % \begin{nocharprotrusion}\fussy % \begin{smoothraggedright} % Throughout this manual, we have demonstrated how \code{smoothraggedright} environments % work for very narrow columns\spacedemdash namely, inside the document's margins: all % marginal notes were typeset with \code{smoothraggedright} environments (quintuplet % generator, 1.5\,em rag~width, at footnote~size in addition to using % environments~\hyperref[syn:slightlysloppy]{\code{slightlysloppy}} and % \hyperref[syn:loosespacing]{\code{loosespacing}}). In this paragraph, we utilize it % with the \smoothraggedrightgenerator~generator and a rag~width of only % \formatdimen*{\smoothraggedrightragwidth} in the body that is % \formatdimen{\linewidth}~wide and averages around twelve words per line. There is much % more glue to adapt to the line ends, and thus the desired rag is achieved more easily. % The sloppiness is minimal; that is, \cs{fussy} is in effect, and character protrusion % into the margins is disabled. A limitation of the current implementation is that it is % ineffective inside of lists. Therefore, this paragraph has not been wrapped inside of % an \singlequotes{Example} because all of our examples are implemented as lists. % \end{smoothraggedright} % \end{nocharprotrusion} % \end{samepage} % % % \sectionfinish % \clearpage % \section{Limitations and Known Problems}\label{sec:limitations} % % \index{limitations|userman} % \index{known problems|userman} % Here is a list of some known problems with \packagename{typog}. % % \begin{description} % \item[Interference with the package \packagename{pdfcomment}~\cite{package:pdfcomment}.] % To ensure compatibility, \packagename{typog} \emph{disables} the default string % substitution inside \acronym{PDF}~bookmarks for the following macros (including their % starred variants) if \emph{both} packages are loaded. % % \setlength{\columnsep}{25pt} % \begin{multicols}{2} % \newcommand*{\synpageref}[1]{\leavevmode % \unskip % \penalty9999\hbox{}\nobreak % \hfill\quad % \mbox{\footnotesize\textbf{\pageref{#1}}}} % \begin{itemize}[label={}, leftmargin=0pt, nosep] % \item \cs{Adjustedlabelitemi}\synpageref{syn:Adjustedlabelitem} % \item \cs{Adjustedlabelitemii}\synpageref{syn:Adjustedlabelitem} % \item \cs{Adjustedlabelitemiii}\synpageref{syn:Adjustedlabelitem} % \item \cs{Adjustedlabelitemiv}\synpageref{syn:Adjustedlabelitem} % \item \cs{adjustedlabelitemi}\synpageref{syn:adjustedlabelitem} % \item \cs{adjustedlabelitemii}\synpageref{syn:adjustedlabelitem} % \item \cs{adjustedlabelitemiii}\synpageref{syn:adjustedlabelitem} % \item \cs{adjustedlabelitemiv}\synpageref{syn:adjustedlabelitem} % \item \cs{breakpoint}\synpageref{syn:breakpoint} % \item \cs{capitalemdash}\synpageref{syn:capitalemdash} % \item \cs{capitalendash}\synpageref{syn:capitalendash} % \item \cs{capitalhyphen}\synpageref{syn:capitalhyphen} % \item \cs{capitaltimes}\synpageref{syn:capitaltimes} % \item \cs{Doubleguillemetleft}\synpageref{syn:Doubleguillemetleft} % \item \cs{Doubleguillemetright}\synpageref{syn:Doubleguillemetright} % \item \cs{doubleguillemetleft}\synpageref{syn:doubleguillemetleft} % \item \cs{doubleguillemetright}\synpageref{syn:doubleguillemetright} % \item \cs{figuredash}\synpageref{syn:figuredash} % \item \cs{itcorr}\synpageref{syn:itcorr} % \item \cs{kernedhyphen}\synpageref{syn:kernedhyphen} % \item \cs{kernedslash}\synpageref{syn:kernedslash} % \item \cs{leftkernedhyphen}\synpageref{syn:leftkernedhyphen} % \item \cs{leftspacedemdash}\synpageref{syn:spacedemdash} % \item \cs{leftspacedendash}\synpageref{syn:spacedendash} % \item \cs{nolig}\synpageref{syn:nolig} % \item \cs{rightkernedhyphen}\synpageref{syn:rightkernedhyphen} % \item \cs{rightspacedemdash}\synpageref{syn:spacedemdash} % \item \cs{rightspacedendash}\synpageref{syn:spacedendash} % \item \cs{Singleguillemetleft}\synpageref{syn:Singleguillemetleft} % \item \cs{Singleguillemetright}\synpageref{syn:Singleguillemetright} % \item \cs{singleguillemetleft}\synpageref{syn:singleguillemetleft} % \item \cs{singleguillemetright}\synpageref{syn:singleguillemetright} % \item \cs{spacedcapitalemdash}\synpageref{syn:spacedcapitalemdash} % \item \cs{spacedcapitalendash}\synpageref{syn:spacedcapitalendash} % \item \cs{spaceddash}\synpageref{syn:spacedendash} % \item \cs{spacedemdash}\synpageref{syn:spacedemdash} % \item \cs{spacedendash}\synpageref{syn:spacedendash} % \end{itemize} % \end{multicols} % % Use \cs{texorpdfstring}\spacedendash\marginnote{The sentence uses \cs{spaced\-endash}es.} % which is part of the package~\packagename{hyperref}~\cite{package:hyperref}\spacedendash in % the relevant sectioning macros to restore string substitution on a case-by-case basis. % % \begin{example} % \begin{codeexample} % \cs{section}\{\=\cs{(}CP\cs{)}\cs{texorpdfstring}\{\cs{capitalhyphen}\}\{-\}\% \\ % \>Invariance\} % \end{codeexample} % \end{example} % \end{description} % % % \sectionfinish % \clearpage % \section{Other Packages for Fine \LaTeX~Typography}\label{sec:other-typography-packages} % % Many other packages help produce better output from \LaTeX. Here is a list\spacedemdash in % alphabetical order\spacedemdash of the ones the author considers particularly valuable. % % \sbox{\listlabelbox}{\packagename{enumitem}} % \begin{description}[font=\normalfont, labelsep*=1em, labelwidth=\wd\listlabelbox, leftmargin=!] % \item[\packagename{enumitem}] % Flexible and consistent definition of all basic \LaTeX{} list types, including inline % lists~\cite{package:enumitem}. % % \item[\packagename{geometry}] % Powerful and sophisticated configuration of page layout~\cite{package:geometry}. Best used % together with \packagename{layout}~\cite{package:layout} to visualize the page geometries. % % \item[\packagename{hyphenat}] % Provides hyphens that do not inhibit further auto-hyphenation of compound % words~\cite{package:hyphenat}. % % Also see \Cref{sec:latex-hyphenation} (pp.~\pageref{sec:latex-hyphenation}\figuredash % \pageref{secend:latex-hyphenation}) for this package's macros and environments that are % related to hyphenation. % % \item[\packagename{microtype}] % Fine control of spacing, tracking, sidebearings, character protrusion into the margins, % font expansion, and more~\cite{package:microtype}. % % See \Cref{sec:microtype-frontend} (pp.~\pageref{sec:microtype-frontend}\figuredash % \pageref{secend:microtype-frontend}) for a front end to \packagename{microtype} provided by % this package and also the discussion in reference~\citenum{khirevich:2013}. % % \item[\packagename{ragged2e}] % Improved versions of the \code{raggedleft}, \code{raggedright}, and \code{center} % environments~\cite{package:ragged2e}. % % \item[\packagename{setspace}] % Consistently sets the line spacing of a document (i.\,e., controls % \cs{baselineskip})~\cite{package:setspace}. % % See \Cref{sec:setspace-frontend} (pp.~\pageref{sec:setspace-frontend}\figuredash % \pageref{secend:setspace-frontend}) for a front end to \packagename{setspace} provided by % this package. % \end{description} % % % \sectionfinish % \appendix % \clearpage % \section{typog-grep} % \label{app:typog-grep} % % The companion program \programname{typog-grep} for analyzing the output of % \hyperref[syn:typoginspect]{\code{typoginspect}} and % \hyperref[syn:typoginspect]{\code{typoginspectpar}} has its own manual page. We reproduce it % here for completeness of the documentation. % % \addtocontents{toc}{\protect\setcounter{tocdepth}{0}} % \begin{suspendshortverb} % \setlength{\parindent}{0pt} % \setlength{\parskip}{6.0pt plus 2.0pt minus .5pt} % \input{typog-grep.tex} % \end{suspendshortverb} % \addtocontents{toc}{\protect\setcounter{tocdepth}{2}} % % % \sectionfinish % \clearpage % \section{\eTeX: Breaking Paragraphs into Lines} % \label{app:epsilon-tex-lastlinefit} % % \index{lastlinefit=\verb!*+\lastlinefit+|userman} % \index{lastlinefitpar={\ttfamily lastlinefitpar} (env.)|userman} % This is an excerpt from the \eTeX{} manual~\cite{package:etex}, Sec.~3.8, % \doublequotes{Breaking Paragraphs into Lines} that describes the \cs{lastlinefit}~algorithm. % Package~\packagename{typog} warps \cs{lastlinefit} in % environment~\hyperref[syn:lastlinefitpar]{\code{lastlinefitpar}}, which was introduced in % \cref{sec:consistent-spacing-of-last-line} on \cpageref{sec:consistent-spacing-of-last-line}. % % \begin{quotation} % \begin{covernextindentpar} % \noindent % Traditional typesetting with lead type used to adjust (stretch or shrink) the interword % spaces in the last line of a paragraph by the same amount as those in the preceding line. % With \TeX{} the last line is, however, usually typeset at its natural width due to % infinitely stretchable \cs{parfillskip} glue. \eTeX{} allows interpolation between these % two extremes by specifying a suitable value for \cs{lastlinefit}.\shiftedmarginnote{This % paragraph benefits from being enclosed in a \code{cover\-next\-indent\-par} environment.} % For a value of~0 or less, \eTeX{} behaves as \TeX, values from~1 to 1000 indicate a glue % adjustment fraction~\(f\) times 1000, values above 1000 are interpreted as \mbox{\(f = % 1\)}. % \end{covernextindentpar} % % The new algorithm is used only if % % \begin{tabfigures} % \begin{enumerate}[nosep] % \item \cs{lastlinefit} is positive; % \item \cs{parfillskip} has infinite stretchability; and % \item the stretchability of \cs{leftskip} plus \cs{rightskip} is finite.\!\footnote{As % usual for parameters influencing \TeX's line-breaking algorithm, the values current % at the end of the (partial) paragraph are used.} % \end{enumerate} % \end{tabfigures} % % \noindent % Thus the last line of a paragraph would normally be typeset at its natural width and the % stretchability of \cs{parfillskip} glue would be used to achieve the desired line width. % The algorithm proceeds as usual, considering all possible sequences of feasible break % points and accumulating demerits for the stretching or shrinking of lines as well as for % visually incompatible lines. When a candidate for the last line has been reached, the % following conditions are tested: % % \begin{tabfigures} % \begin{enumerate}[nosep, resume] % \item the previous line was not \doublequotes{infinitely bad} and was stretched with % positive finite stretchability or was shrunk with positive shrinkability; % \item the last line has infinite stretchability entirely due to \cs{par\-fill\-skip} glue; % \item if the previous line was stretched or shrunk the last line has positive finite % stretchability or shrinkability. % \end{enumerate} % \end{tabfigures} % % \noindent % If all three conditions are satisfied, a glue adjustment factor of \(f\)~times that of the % preceding line will be applied to the relevant stretch or shrink components of all glue % nodes in the last line, and the corresponding demerits are computed. (The last line will, % however, not be stretched beyond the desired line width.) % % When all possible candidates for the last line of the paragraph have been examined, the one % having fewest accumulated demerits is chosen. If \eTeX's modified algorithm was applied to % that last line, the actual stretching or shrinking is achieved by suitably modifying the % \cs{parfillskip} glue node. % % All computations described so far are performed with machine\hyp{}independent integer % arithmetic. Note, however, that the actual stretching requires machine\hyp{}dependent % floating point arithmetic. Therefore, when a paragraph is interrupted by a displayed % equation and the line preceding the display is subject to the adjustment just described, % the display will in general be preceded by \cs{abovedisplayskip} and not by % \cs{abovedisplayshortskip} glue. % \end{quotation} % % \noindent % Section~3.8 of the \eTeX{} manual closes with a description of the generalizations of % \cs{clubpenalties}, \cs{displaywidowpenalties}, \cs{interlinepenalties}, and % \cs{widowpenalties}. See also \cref{sec:vtie-paragraph}, \doublequotes{Vertically % Partially-Tied Paragraphs}, \cpageref{sec:vtie-paragraph} in this manual. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % \newcommand*{\codeidx}[1]{\linenumberdecoration\textbf{#1}} % \renewcommand*{\main}[1]{\linenumberdecoration\textit{\textbf{#1}}} % \renewcommand*{\usage}[1]{\textit{\textbf{#1}}} % % \MaybeStop{ % \sectionfinish % \clearpage % \begingroup % \setcounter{GlossaryColumns}{1} % \phantomsection % \label{sec:changes} % \resetfancyhead % \addtocontents{toc}{\bigskip} % \addcontentsline{toc}{section}{\protect\numberline{}Change History} % \GlossaryPrologue{\section*{Change History} % \markboth{\sf\letterspacedsmallcaps{Change History}}{\sf\letterspacedsmallcaps{Change History}}} % \PrintChanges % \endgroup % % % \sectionfinish % \clearpage % \phantomsection % \addtocontents{toc}{\medskip} % \addcontentsline{toc}{section}{\protect\numberline{}References} % \begin{mybibliography} % \bibitem{abrahams:2020} % \bibauthor{Abrahams, Paul~W.}, % \bibauthor{Kathryn A.~Hargreaves,} and % \bibauthor{Karl Berry}. % \bibtitle{\TeX{} for the Impatient}. % 2020, % \biburl{https://tug.ctan.org/info/impatient/book.pdf}. % % \bibitem{package:amsmath} % \bibauthor{American Mathematical Society} and the % \bibauthor{\LaTeXIII\ Project Team}. % \bibtitle{Package~\packagename{amsmath}}. % 2020, % \biburl{https://ctan.org/pkg/amsmath}. % % \bibitem{package:cite} % \bibauthor{Arseneau, Donald}. % \bibtitle{Package~\packagename{cite}}. % 2015, % \biburl{https://ctan.org/pkg/cite}. % % \bibitem{chicago-manual-of-style:2017} % \bibtitle{The Chicago Manual of Style}, % 17\textsuperior{th}~ed.\widespace % The University of Chicago Press, Chicago\kernedslash IL, % 2017. % % \bibitem{package:enumitem} % \bibauthor{Bezos, Javier}. % \bibtitle{Package~\packagename{enumitem}}. % 2019, % \biburl{https://ctan.org/pkg/enumitem}. % % \bibitem{package:babel} % \bibauthor{Bezos, Javier}. % \bibtitle{Package~\packagename{babel}}. % 2021, % \biburl{https://ctan.org/pkg/babel}. % The original author of package~\packagename{babel} was \bibauthor{J. L. Braams}. % % \bibitem{package:etex} % \bibauthor{Breitenlohner, Peter} and % the \bibauthor{\(\mathcal{N\kern-.1em\raisebox{-.2em}{T}\kern-.1emS}\)~Team}. % \bibtitle{\eTeX}. % 1998, % \biburl{https://mirrors.ctan.org/systems/doc/etex/etex_man.pdf}. % % \bibitem{package:mathastext} % \bibauthor{Burnol, Jean-François}. % \bibtitle{Package~\packagename{mathastext}}. % 2023, % \biburl{https://ctan.org/pkg/mathastext}. % % \bibitem{carlisle:1996} % \bibauthor{Carlisle, David}. % \bibtitle{Russian Paragraph Shapes}. % Baskerville, 6(1), 13\figuredash15, % 1996, % \biburl{http://uk-tug-archive.tug.org/wp-installed-content/uploads/2008/12/61.pdf}. % % \bibitem{carlisle:2013} % \bibauthor{Carlisle, David}. % \bibtitle{What do different \cs{fontdimen} mean}. % 2013\figuredash*1\figuredash*2, % \biburl{https://tex.stackexchange.com/questions/88991/what-do-different-fontdimennum-mean}. % % \bibitem{package:cleveref} % \bibauthor{Cubitt, Toby}. % \bibtitle{Package~\packagename{cleveref}}. % 2018, % \biburl{https://ctan.org/pkg/cleveref}. % % \bibitem{eijkhout:2007} % \bibauthor{Eijkhout, Victor}. % \bibtitle{\TeX\ By Topic, A Texnician's Reference}. % 2007, % \biburl{https://www.eijkhout.net/tex/tex-by-topic.html}. % % \bibitem{forssman-de-jong:2008} % \bibauthor{Forssman, Friedrich,} and \bibauthor{Ralf de Jong}. % \bibtitle{Detailtypographie}. % 4.~Aufl.\widespace % Verlag Hermann Schmitz, Mainz, % 2008. % % \bibitem{package:mathtools} % \bibauthor{H{\o}gholm, Morten}, % \bibauthor{Lars Madsen,} and % the \bibauthor{\LaTeXIII\ Project Team}. % \bibtitle{Package~\packagename{mathtools}}. % 2020, % \biburl{https://ctan.org/pkg/mathtools}. % % \bibitem{khirevich:2013} % \bibauthor{Khirevich, Siarhei}. % \bibtitle{Tips on Writing a Thesis in \LaTeX}. % 2013, % \biburl{https://www.khirevich.com/latex/microtype}. % % \bibitem{package:pdfcomment} % \bibauthor{Kleber, Josef}. % \bibtitle{Package~\packagename{pdfcomment}}. % 2018, % \biburl{https://ctan.org/pkg/pdfcomment}. % % \bibitem{knuth:1986} % \bibauthor{Knuth, Donald Ervin}. % \bibtitle{The \TeX{}book}. % Addison Wesley, Reading\kernedslash MA, % 1986. % % \bibitem{package:l3experimental} % \bibauthor{The \LaTeX\ Project}. % \bibtitle{Package~\packagename{l3experimental}}. % 2024, % \biburl{https://ctan.org/pkg/l3experimental}. % % \bibitem{package:layout} % \bibauthor{McPherson, Kent}. % \bibtitle{Package~\packagename{layout}}. % 2014, % \biburl{https://ctan.org/pkg/layout}. % The package was converted to \LaTeXe\ by \bibauthor{J. L. Braams} % and modified by \bibauthor{H. Umeki}. % % \bibitem{middendorp:2014} % \bibauthor{Middendorp, Jan}. % \bibtitle{Shaping Text}. % \acronym{BIS}~publishers, Amsterdam, % 2014. % % \bibitem{mittelbach:2018c} % \bibauthor{Mittelbach, Frank}. % \bibtitle{Managing forlorn paragraph lines (a.\,k.\,a.~widows and orphans) in \LaTeX}. % TUGboat, 39(3), 246\figuredash251, 2018, % \biburl{https://tug.org/TUGboat/tb39-3/tb123mitt-widows.pdf}. % % \bibitem{package:widows-and-orphans} % \bibauthor{Mittelbach, Frank}. % \bibtitle{Package~\packagename{widows-and-orphans}}. % 2020, % \biburl{https://ctan.org/pkg/widows-and-orphans}. % % \bibitem{package:tasks} % \bibauthor{Niederberger, Clemens}. % \bibtitle{Package~\packagename{tasks}}. % 2022, % \biburl{https://github.com/cgnieder/tasks}. % % \bibitem{package:hyperref} % \bibauthor{Rahtz, Sebastian,} and \bibauthor{Frank Mittelbach}. % \bibtitle{Package~\packagename{hyperref}}. % 2020, % \biburl{https://ctan.org/pkg/hyperref}. % The package is maintained by the \LaTeXIII~Project Team. % % \bibitem{package:microtype} % \bibauthor{Schlicht, Robert}. % \bibtitle{Package~\packagename{microtype}}. % 2020, % \biburl{https://ctan.org/pkg/microtype}. % % \bibitem{package:ragged2e} % \bibauthor{Schröder, Martin}. % \bibtitle{Package~\packagename{ragged2e}}. % 2019, % \biburl{https://ctan.org/pkg/ragged2e}. % % \bibitem{solomon:1990} % \bibauthor{Solomon, David}. % \bibtitle{Output Routines: Examples and Techniques. Part~I: Introduction and Examples}. % TUGboat, 11(1), 69\figuredash85, 1990, % \biburl{https://www.tug.org/TUGboat/Articles/tb11-1/tb27salomon.pdf}. % % \bibitem{strizver:2014} % \bibauthor{Strizver, Ilene}. % \bibtitle{Type rules!: the designer's guide to professional typography}, % 4\textsuperior{th}~ed.\widespace % John Wiley~\textit{\&} Sons, Hoboken\kernedslash NJ, % 2014. % % \bibitem{package:setspace} % \bibauthor{Tobin, Geoffrey,} and \bibauthor{Robin Fairbairns}. % \bibtitle{Package~\packagename{setspace}}. % 2011, % \biburl{https://ctan.org/pkg/setspace}. % % \bibitem{package:geometry} % \bibauthor{Umeki, Hideo}. % \bibtitle{Package~\packagename{geometry}}. % 2020, % \biburl{https://ctan.org/pkg/geometry}. % % \bibitem{wermuth:2016} % \bibauthor{Wermuth, Udo}. % \bibtitle{Tracing paragraphs}. % TUGboat, 37(3), 358\figuredash373, 2016, % \biburl{https://tug.org/TUGboat/tb37-3/tb117wermuth.pdf}. % % \bibitem{wermuth:2017a} % \bibauthor{Wermuth, Udo}. % \bibtitle{The optimal value for \cs{emergencystretch}}. % TUGboat, 38(1), 65\figuredash86, 2017, % \biburl{https://tug.org/TUGboat/tb38-1/tb118wermuth.pdf}. % % \bibitem{wermuth:2017c} % \bibauthor{Wermuth, Udo}. % \bibtitle{A note on \cs{linepenalty}}. % TUGboat, 38(3), 400\figuredash414, 2017, % \biburl{https://tug.org/TUGboat/tb38-3/tb120wermuth.pdf}. % % \bibitem{wermuth:2018} % \bibauthor{Wermuth, Udo}. % \bibtitle{Experiments with \cs{parfillskip}}. % TUGboat, 39(3), 276\figuredash303, 2018, % \biburl{https://tug.org/TUGboat/tb39-3/tb123wermuth-parfillskip.pdf}. % % \bibitem{wermuth:2020} % \bibauthor{Wermuth, Udo}. % \bibtitle{An attempt at ragged-right typesetting}. % TUGboat, 41(1), 73\figuredash94, 2020, % \biburl{https://tug.org/TUGboat/tb41-1/tb127wermuth-ragged.pdf}. % % \bibitem{wermuth:2022-8-2} % \bibauthor{Wermuth, Udo}. % Personal communication. % August~2, 2022. % % \bibitem{wermuth:2023} % \bibauthor{Wermuth, Udo}. % \bibtitle{Vertical alignments in plain \TeX}. % TUGboat, 44(3), 427\figuredash440, 2023, % \biburl{https://tug.org/TUGboat/tb44-3/tb138wermuth-valign.pdf}. % % \bibitem{package:hyphenat} % \bibauthor{Wilson, Peter}. % \bibtitle{Package~\packagename{hyphenat}}. % 2004, % \biburl{https://ctan.org/pkg/hyphenat}. % The package is maintained by \bibauthor{W. Robertson}. % % \bibitem{wilson:2007} % \bibauthor{Wilson, Peter}. % \bibtitle{Glisterings}. % TUGboat, 28(2), 229\figuredash232, 2007, % \biburl{https://tug.org/TUGboat/tb28-2/tb89glister.pdf}. % % \bibitem{package:needspace} % \bibauthor{Wilson, Peter}. % \bibtitle{Package~\packagename{needspace}}. % 2010, % \biburl{https://ctan.org/pkg/needspace}. % The package is maintained by \bibauthor{W. Robertson}. % \end{mybibliography} % % % \sectionfinish % \clearpage % \begingroup % \setcounter{IndexColumns}{2} % \setlength{\columnsep}{30pt} % \phantomsection % \label{sec:index} % \addtocontents{toc}{\medskip} % \addcontentsline{toc}{section}{\protect\numberline{}Index} % \raggedcolumns % \PrintIndex % \phantomsection % \label{secend:index} % \endgroup % } % % % \sectionfinish % \toccontinuesonnextpage % \clearpage % \section{Package Code}\label{sec:package-code} % \addtocontents{toc}{\protect\begin{list}{}{\leftmargin=\subsectiontocindent\parsep=0pt}} % \addtocontents{toc}{\protect\item} % \addtocontents{toc}{\RaggedRight} % \addtocontents{toc}{\small} % \addtocontents{toc}{\tocsquashedsubsections} % \addtocontents{toc}{\protect\begin{multicols}{2}} % \addtocontents{toc}{\protect\raggedcolumns} % \index{package code|(userman} % \index{code reference|(userman} % % This is the \doublequotes{Reference Manual}~section of the documentation % where we describe the package's code % and explain its implementation details. % % % \begin{macrocode} %<*package> \NeedsTeXFormat{LaTeX2e}[2005/12/01] \ProvidesPackage{typog} [2025/10/27 v0.5 TypoGraphic extensions] \RequirePackage{etoolbox} \RequirePackage{everyhook} \RequirePackage{xkeyval} % \end{macrocode} % % \bigskip % % \subsection*{Declarations of Lengths, Skips, etc.} % % \begin{macro}{\typog@TYPOG} % Define a macro that unequivocally identifies this very package. % % \begin{macrocode} \newcommand*{\typog@TYPOG}{} % \end{macrocode} % \end{macro} % % \begin{macro}{\typoglogo} % We have our own, low-key logo. % % \changes{v0.5}{2025-05-26}{Make macro independent of typog setup.} % \begin{macrocode} \newcommand*{\typoglogo}{\textsf{T\kern-.12em\textsl{y}poG}} % \end{macrocode} % \end{macro} % % \begin{macro}{\iftypog@debug} % Our switch for debug information. % % \begin{macrocode} \newif\iftypog@debug % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@typeout} % Our information printer. % Just adds a prefix so that we can tease apart the \filesystem{log} later. % % \begin{macrocode} \newcommand*{\typog@typeout}[1]{\typeout{typog: #1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@typeout} % Our debug information printer. % % \begin{macrocode} \newcommand*{\typog@debug@typeout}[1] {\iftypog@debug\typog@typeout{#1}\fi} % \end{macrocode} % \end{macro} % % \begin{tcounter}{typog@@iteration} % We want our own counter (currently for keeping track of iterations) that does not get % trampled underfoot too easily. % % \begin{macrocode} \newcounter{typog@@iteration} % \end{macrocode} % \end{tcounter} % % \begin{macro}{\typog@trim@spaces} % Pull \cs{tl\_trim\_spaces} into the \singlequotes{classic} namespace. % % \begin{macrocode} \ExplSyntaxOn \let\typog@trim@spaces=\tl_trim_spaces:o \ExplSyntaxOff % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@register@pdfsubstitute} % \changes{v0.4a}{2024-08-11} % {Using \cs{pdf\-stringdef\-Disable\-Commands} breaks package~\packagename{pdf\-comment}. % So we just refrain from using the macro if \packagename{pdf\-comment} was loaded.} % We often need to register (simple) substitute commands % suitable for \acronym{PDF}~bookmarks. % This is a convenient abbreviation for that task. % % \begin{macrocode} \newcommand{\typog@register@pdfsubstitute}[1]{% \AtBeginDocument{% \ifdefined\pdfstringdefDisableCommands \@ifpackageloaded{pdfcomment} {\PackageWarningNoLine{typog} {package pdfcomment loaded --\space typog will not touch PDF interface}} {\pdfstringdefDisableCommands{#1}}% \fi}} % \end{macrocode} % \end{macro} % % Some functionality depends on package~\packagename{microtype}. % To complicate matters for certain setup operations, e.\,g., \cs{SetExpansion}, % \packagename{microtype} must be loaded \emph{before} package~\packagename{typog}, % a fact that we encode in \cs{iftypog@microtype@preloaded}. % % \begin{macro}{\iftypog@microtype@preloaded} % \begin{macrocode} \newif\iftypog@microtype@preloaded % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@require@preloaded@microtype} % It is easy to determine whether \packagename{microtype} has been sourced. % We raise to the occasion and define a pair of check macros % which simplify the test for the correct \packagename{microtype} load~state. % % \begin{macrocode} \ifdefined\MT@MT \typog@typeout{package microtype preloaded}% \typog@microtype@preloadedtrue \def\typog@require@preloaded@microtype{\relax} \else \typog@microtype@preloadedfalse \def\typog@require@preloaded@microtype {\PackageError{typog}% {package microtype not (pre-)loaded}% {package microtype must be loaded before package typog}} \fi % \end{macrocode} % \end{macro} % % \begin{macro}{\iftypog@microtype@loaded} % \begin{macrocode} \newif\iftypog@microtype@loaded % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@require@microtype} % This code duplicates \cs{typog@require@preloaded@microtype}; % the only difference is that we call the test \emph{after} the preamble was processed. % % \begin{macrocode} \AtBeginDocument{ \ifdefined\MT@MT \typog@typeout{package microtype loaded}% \typog@microtype@loadedtrue \def\typog@require@microtype{\relax} \else \typog@microtype@loadedfalse \def\typog@require@microtype {\PackageError{typog}% {package microtype not loaded}% {require package microtype before package typog}}% \fi } % \end{macrocode} % \end{macro} % % Our own state \dots % % \begin{macro}{\typog@config@mathitaliccorrection} % \begin{macrocode} \newmuskip\typog@config@mathitaliccorrection % \end{macrocode} % \end{macro} % % Space around em-dash. % % \begin{ldimen}{\typog@config@emdashspace} % \begin{macrocode} \newlength{\typog@config@emdashspace} % \end{macrocode} % \end{ldimen} % % Space around en-dash. % % \begin{ldimen}{\typog@config@endashspace} % \begin{macrocode} \newlength{\typog@config@endashspace} % \end{macrocode} % \end{ldimen} % % Actual \cs{labelitem}\meta{N} corrections. % % \begin{ldimen}{\typog@adjust@labelitemi} % \begin{macrocode} \newdimen{\typog@adjust@labelitemi} % \end{macrocode} % \end{ldimen} % % \begin{ldimen}{\typog@adjust@labelitemii} % \begin{macrocode} \newdimen{\typog@adjust@labelitemii} % \end{macrocode} % \end{ldimen} % % \begin{ldimen}{\typog@adjust@labelitemiii} % \begin{macrocode} \newdimen{\typog@adjust@labelitemiii} % \end{macrocode} % \end{ldimen} % % \begin{ldimen}{\typog@adjust@labelitemiv} % \begin{macrocode} \newdimen{\typog@adjust@labelitemiv} % \end{macrocode} % \end{ldimen} % % Configuration constants for \cs{labelitem}\meta{N} corrections. % % \begin{ldimen}{\typog@adjust@lowercase@labelitemi} % \begin{macrocode} \newdimen{\typog@adjust@lowercase@labelitemi} % \end{macrocode} % \end{ldimen} % % \begin{ldimen}{\typog@adjust@lowercase@labelitemii} % \begin{macrocode} \newdimen{\typog@adjust@lowercase@labelitemii} % \end{macrocode} % \end{ldimen} % % \begin{ldimen}{\typog@adjust@lowercase@labelitemiii} % \begin{macrocode} \newdimen{\typog@adjust@lowercase@labelitemiii} % \end{macrocode} % \end{ldimen} % % \begin{ldimen}{\typog@adjust@lowercase@labelitemiv} % \begin{macrocode} \newdimen{\typog@adjust@lowercase@labelitemiv} % \end{macrocode} % \end{ldimen} % % \begin{ldimen}{\typog@adjust@uppercase@labelitemi} % \begin{macrocode} \newdimen{\typog@adjust@uppercase@labelitemi} % \end{macrocode} % \end{ldimen} % % \begin{ldimen}{\typog@adjust@uppercase@labelitemii} % \begin{macrocode} \newdimen{\typog@adjust@uppercase@labelitemii} % \end{macrocode} % \end{ldimen} % % \begin{ldimen}{\typog@adjust@uppercase@labelitemiii} % \begin{macrocode} \newdimen{\typog@adjust@uppercase@labelitemiii} % \end{macrocode} % \end{ldimen} % % \begin{ldimen}{\typog@adjust@uppercase@labelitemiv} % \begin{macrocode} \newdimen{\typog@adjust@uppercase@labelitemiv} % \end{macrocode} % \end{ldimen} % % Other lengths \dots % % \begin{macro}{\typog@config@textitaliccorrection} % \begin{macrocode} \newlength{\typog@config@textitaliccorrection} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@ligaturekern} % \begin{macrocode} \newlength{\typog@config@ligaturekern} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@lowerslash} % \begin{macrocode} \newlength{\typog@config@lowerslash} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@raisecapitaldash} % \begin{macrocode} \newlength{\typog@config@raisecapitaldash} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@raisecapitalguillemets} % \begin{macrocode} \newlength{\typog@config@raisecapitalguillemets} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@raisecapitalhyphen} % \begin{macrocode} \newlength{\typog@config@raisecapitalhyphen} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@raisecapitaltimes} % \begin{macrocode} \newlength{\typog@config@raisecapitaltimes} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@raiseguillemets} % \begin{macrocode} \newlength{\typog@config@raiseguillemets} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@raisefiguredash} % \begin{macrocode} \newlength{\typog@config@raisefiguredash} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@slashkern} % \begin{macrocode} \newlength{\typog@config@slashkern} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@breakpenalty} % \begin{macrocode} \newcommand*{\typog@config@breakpenalty}{\exhyphenpenalty} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@dim@unit} % We would like to express the argument values % for example of \cs{kernedhyphen*} and \cs{kernedhyphen} % as multiples of a thousandth of an~em. % Therefore, we define a dimen as \doublequotes{base unit} which simplifies matters greatly. % % \begin{macrocode} \newlength{\typog@dim@unit} \setlength{\typog@dim@unit}{.001em} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@trackingttspacing} % \begin{macrocode} \newcommand*{\typog@config@trackingttspacing}{300, 90, 60} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@default@shrink@i} % The default configuration for shrink values. % % \begin{macrocode} \newcommand*{\typog@default@shrink@i}{5} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@default@shrink@ii} % \begin{macrocode} \newcommand*{\typog@default@shrink@ii}{10} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@default@shrink@iii} % \begin{macrocode} \newcommand*{\typog@default@shrink@iii}{20} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@shrink@i} % Configurable shrink values. % Initialized from the \code{typog@default@shrink@} set. % % \begin{macrocode} \newcommand*{\typog@shrink@i}{} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@shrink@ii} % \begin{macrocode} \newcommand*{\typog@shrink@ii}{} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@shrink@iii} % \begin{macrocode} \newcommand*{\typog@shrink@iii}{} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@default@stretch@i} % The default configuration for stretch values. % % \begin{macrocode} \newcommand*{\typog@default@stretch@i}{5} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@default@stretch@ii} % \begin{macrocode} \newcommand*{\typog@default@stretch@ii}{10} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@default@stretch@iii} % \begin{macrocode} \newcommand*{\typog@default@stretch@iii}{20} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@stretch@i} % Configurable stretch values. % Initialized from the \code{typog@default@stretch} set. % % \begin{macrocode} \newcommand*{\typog@stretch@i}{} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@stretch@ii} % \begin{macrocode} \newcommand*{\typog@stretch@ii}{} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@stretch@iii} % \begin{macrocode} \newcommand*{\typog@stretch@iii}{} % \end{macrocode} % \end{macro} % % \iffalse \def\typog@one@of@three#1,#2,#3\relax{\typog@trim@spaces{#1}} \def\typog@two@of@three#1,#2,#3\relax{\typog@trim@spaces{#2}} \def\typog@three@of@three#1,#2,#3\relax{\typog@trim@spaces{#3}} \newcommand*{\typog@triple@get@i}[1]{\expandafter\typog@one@of@three #1\relax} \newcommand*{\typog@triple@get@ii}[1]{\expandafter\typog@two@of@three #1\relax} \newcommand*{\typog@triple@get@iii}[1]{\expandafter\typog@three@of@three #1\relax} \newcommand*{\typog@set@shrink@limits} {\edef\typog@@star{*}% \edef\typog@@limit{\typog@triple@get@i{\typog@config@shrinklimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@shrink@i{\number\typog@@limit}\fi \edef\typog@@limit{\typog@triple@get@ii{\typog@config@shrinklimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@shrink@ii{\number\typog@@limit}\fi \edef\typog@@limit{\typog@triple@get@iii{\typog@config@shrinklimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@shrink@iii{\number\typog@@limit}\fi} \newcommand*{\typog@set@stretch@limits} {\edef\typog@@star{*}% \edef\typog@@limit{\typog@triple@get@i{\typog@config@stretchlimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@stretch@i{\number\typog@@limit}\fi \edef\typog@@limit{\typog@triple@get@ii{\typog@config@stretchlimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@stretch@ii{\number\typog@@limit}\fi \edef\typog@@limit{\typog@triple@get@iii{\typog@config@stretchlimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@stretch@iii{\number\typog@@limit}\fi} \DeclareOptionX{breakpenalty}% {\renewcommand*{\typog@config@breakpenalty}{#1}} \DeclareOptionX{debug}{\typog@debugtrue} \DeclareOptionX{emdashspace}[.05555em]% {\setlength{\typog@config@emdashspace}{#1}} \DeclareOptionX{endashspace}[.2em plus.1em minus.0667em]% {\setlength{\typog@config@endashspace}{#1}} % \fi % % \changes{v0.5}{2025-06-15}{\backwardincompatiblechange{} % Rename package option \code{math\-italics\-correction} to \code{math\-italic\-correction}.} % % \iffalse \DeclareOptionX{mathitaliccorrection}[.4mu]% {\typog@config@mathitaliccorrection=#1\relax}% \DeclareOptionX{nodebug}{\typog@debugfalse} % \fi % % \changes{v0.5}{2025-06-15}{\backwardincompatiblechange{} % Rename package option \code{text\-italics\-correction} to \code{text\-italic\-correction}.} % % \iffalse \DeclareOptionX{textitaliccorrection}[.02em]% {\setlength{\typog@config@textitaliccorrection}{#1}} \DeclareOptionX{ligaturekern}[.033333em]% {\setlength{\typog@config@ligaturekern}{#1}} % \fi % % \changes{v0.5}{2024-09-22}{Rewrite parser for package option~\code{lowercase\-labelitem\-adjustments} to accept a star as a placeholder.} % % \iffalse \DeclareOptionX{lowercaselabelitemadjustments}% {\typog@debug@typeout{lowercaselabelitemadjustments={#1}}% \def\typog@@do##1{\addtocounter{typog@@iteration}{1}% \ifstrequal{##1}{*} {\relax} {\global\setlength{\csname typog@adjust@lowercase@labelitem\romannumeral\thetypog@@iteration\endcsname}{##1}}}% \setcounter{typog@@iteration}{0}% \forcsvlist{\typog@@do}{#1}} \newcommand*{\typog@config@lowercaselabelitemadjustments} {\the\typog@adjust@lowercase@labelitemi,\space \the\typog@adjust@lowercase@labelitemii,\space \the\typog@adjust@lowercase@labelitemiii,\space \the\typog@adjust@lowercase@labelitemiv} \DeclareOptionX{raisecapitaldash}[\z@]% {\setlength{\typog@config@raisecapitaldash}{#1}} \DeclareOptionX{raisecapitalguillemets}[\z@]% {\setlength{\typog@config@raisecapitalguillemets}{#1}} \DeclareOptionX{raisecapitalhyphen}[\z@]% {\setlength{\typog@config@raisecapitalhyphen}{#1}} \DeclareOptionX{raisecapitaltimes}[\z@]% {\setlength{\typog@config@raisecapitaltimes}{#1}} \DeclareOptionX{raiseguillemets}[\z@]% {\setlength{\typog@config@raiseguillemets}{#1}} \DeclareOptionX{raisefiguredash}[\z@]% {\setlength{\typog@config@raisefiguredash}{#1}} \DeclareOptionX{raise*}[\z@]% {\setlength{\typog@config@raisecapitaldash}{#1}% \setlength{\typog@config@raisecapitalhyphen}{#1}% \setlength{\typog@config@raisecapitaltimes}{#1}% \setlength{\typog@config@raisefiguredash}{#1}} \DeclareOptionX{raiseinvertedmarks}% {\typog@debug@typeout{raiseinvertedmarks={#1}} \def\typog@@do##1{\addtocounter{typog@@iteration}{1} \ifstrequal{##1}{*} {\relax} {\global\setlength{\csname typog@config@raiseinvertedmarks@\romannumeral\thetypog@@iteration\endcsname}{##1}}} \setcounter{typog@@iteration}{0} \forcsvlist{\typog@@do}{#1}} \newcommand*{\typog@config@raiseinvertedmarks} {\the\typog@config@raiseinvertedmarks@i,\space \the\typog@config@raiseinvertedmarks@ii,\space \the\typog@config@raiseinvertedmarks@iii} \DeclareOptionX{shrinklimits}% [\typog@default@shrink@i, \typog@default@shrink@ii, \typog@default@shrink@iii]% {\typog@require@preloaded@microtype \ifx\@onlypreamble\@notprerr \PackageWarning{typog}{option `shrinklimits' can only be used in the preamble}% \else \edef\typog@config@shrinklimits{#1}% \typog@set@shrink@limits \fi} \DeclareOptionX{slashkern}[.05em]% {\setlength{\typog@config@slashkern}{#1}} \DeclareOptionX{lowerslash}[\z@]% {\setlength{\typog@config@lowerslash}{#1}} \DeclareOptionX{stretchlimits}% [\typog@default@stretch@i, \typog@default@stretch@ii, \typog@default@stretch@iii]% {\typog@require@preloaded@microtype \ifx\@onlypreamble\@notprerr \PackageWarning{typog}{option `stretchlimits' can only be used in the preamble}% \else \edef\typog@config@stretchlimits{#1}% \typog@set@stretch@limits \fi} \DeclareOptionX{trackingttspacing}[\typog@config@trackingttspacing]% {\typog@require@preloaded@microtype \ifx\@onlypreamble\@notprerr \PackageWarning{typog}{option `trackingttspacing' can only be used in the preamble}% \else \typog@debug@typeout{trackingttspacing=#1}% \SetTracking[outer spacing={#1}]{encoding=*, family=tt*}{0}% \fi} % \fi % % \changes{v0.5}{2024-09-22}{Rewrite parser for package option~\code{uppercase\-labelitem\-adjustments} to accept a star as a placeholder.} % % \iffalse \DeclareOptionX{uppercaselabelitemadjustments}% {\typog@debug@typeout{uppercaselabelitemadjustments={#1}}% \def\typog@@do##1{\addtocounter{typog@@iteration}{1}% \ifstrequal{##1}{*} {\relax} {\setlength{\csname typog@adjust@uppercase@labelitem\romannumeral\thetypog@@iteration\endcsname}{##1}}}% \setcounter{typog@@iteration}{0}% \forcsvlist{\typog@@do}{#1}} \newcommand*{\typog@config@uppercaselabelitemadjustments} {\the\typog@adjust@uppercase@labelitemi,\space \the\typog@adjust@uppercase@labelitemii,\space \the\typog@adjust@uppercase@labelitemiii,\space \the\typog@adjust@uppercase@labelitemiv} \newcommand*{\typog@initialize@options} {\ExecuteOptionsX{ emdashspace, endashspace, ligaturekern, mathitaliccorrection, textitaliccorrection, raisecapitaldash, raisecapitalhyphen, raisecapitaltimes, raiseguillemets, raisecapitalguillemets, raisefiguredash, slashkern, lowerslash}% \ifdefined\MT@MT \unless\ifx\@onlypreamble\@notprerr \ExecuteOptionsX{shrinklimits, stretchlimits}% \fi \fi} \typog@initialize@options \ProcessOptionsX % \fi % % % \subsection{Setup and Reconfiguration} % % \begin{environment}{typogsetup} % An empty argument list resets all initialized values to their defaults. % % \begin{macrocode} \NewDocumentEnvironment{typogsetup}{m} {\def\typog@@arg{#1}% \ifx\typog@@arg\empty \typog@initialize@options \else \setkeys{typog}{#1}% \fi \ignorespaces} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % \begin{macro}{\typogget} % Access the package's configuration (name-)space. % % \begin{macrocode} \NewDocumentCommand{\typogget}{m} {\csname typog@config@#1\endcsname} % \end{macrocode} % \end{macro} % % \begin{macro}{\typoggetnth} % \changes{v0.4}{2024-05-15}{New macro.} % Access the \(n\)\textsuperscript{th} element of a comma-separated, list-like configuration % item's value. % % \begin{macrocode} \ExplSyntaxOn \cs_generate_variant:Nn \seq_set_split:Nnn {Nne} \cs_new:Npn \typog_get_nth_csname:cnn #1#2#3 { \seq_set_split:Nne \l_tmpa_seq {,} {\cs:w typog@config@#2 \cs_end:} \cs_gset:cpn {#1} {\seq_item:Nn \l_tmpa_seq {#3}} } \cs_new:Npn \typog_get_nth_dimen:nnn #1#2#3 { \seq_set_split:Nne \l_tmpa_seq {,} {\cs:w typog@config@#2 \cs_end:} \dim_set:Nn {#1} {\seq_item:Nn \l_tmpa_seq {#3}} } \NewDocumentCommand{\typoggetnth}{m m m}{ \token_if_dim_register:NTF {#1} { \typog_get_nth_dimen:nnn {#1} {#2} {#3} } { \typog_get_nth_csname:cnn {#1} {#2} {#3} } } \ExplSyntaxOff % \end{macrocode} % \end{macro} % % % \subsection{Information} % % \begin{macro}{\typog@round@dim@to@tenths} % \begin{macrocode} \ExplSyntaxOn \newcommand*{\typog@round@dim@to@tenths}[1] {\fp_to_decimal:n {round(10 * \dim_to_fp:n{#1} / 1\p@) / 10}} \ExplSyntaxOff % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@formatsizeinfo} % Arguments 1 and~2 are the font size and the line spacing. % The third parameter adds (decorative) units to both numbers. % % \begin{macrocode} \newcommand*{\typog@formatsizeinfo}[3] {#1#3\kernedslash #2#3} % \end{macrocode} % \end{macro} % % \begin{macro}{\fontsizeinfo} % All macros defined inside of \cs{fontsizeinfo} must be global % because the call can occur inside of a group. % % The two \cs{edef}s at the beginning capture the desired values % at the point where the macro \emph{is called}. % The user-macro is tricky for we need % a global macro with a constructed name % and an associated starred version. % % \begin{implementationnote} % \cs{@ifstar} caused too many problems which \cs{@ifnextchar} in combination with % \cs{@gobble} avoid. % \end{implementationnote} % % \begin{macrocode} \NewDocumentCommand{\fontsizeinfo}{s m} {\global\expandafter\edef\csname typog@fontsize@#2\endcsname {\typog@round@dim@to@tenths{\fontdimen6\font}}% \global\expandafter\edef\csname typog@linespacing@#2\endcsname {\typog@round@dim@to@tenths{\baselineskip}}% \protected\expandafter\gdef\csname #2\endcsname {\@ifnextchar*{\typog@formatsizeinfo {\csname typog@fontsize@#2\endcsname}% {\csname typog@linespacing@#2\endcsname}% {}% no unit \ignorespaces % eat spaces after star \@gobble} % consume the star itself {\typog@formatsizeinfo {\csname typog@fontsize@#2\endcsname}% {\csname typog@linespacing@#2\endcsname}% {\,pt}% decorative unit `pt' }}} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@default@inspect@id@prefix} % Id-prefix for those |typoinspect|~environments % that were not identified by the user. % % \begin{macrocode} \newcommand*{\typog@default@inspect@id@prefix}{a-} % \end{macrocode} % \end{macro} % % \begin{macro}{typog@inspect@count} % Counter to supply unique number and in turn \meta{id} % for those |typoinspect|~environments % that were not identified by the user. % % \begin{macrocode} \newcounter{typog@inspect@count} % \end{macrocode} % \end{macro} % % \begin{environment}{typoginspect} % \begin{macrocode} \define@key[typog]{typoginspect}{tracingboxes}[\maxdimen]% {\def\typog@@typoginspect@tracingboxes{#1}} \NewDocumentEnvironment{typoginspect}{O{} m} {\def\typog@@typoginspect@tracingboxes{\m@ne}% \setkeys[typog]{typoginspect}{#1}% % \end{macrocode} % % If the user does not supply an \meta{id}, % we fall back to our own counter % and construct a hopefully unique \meta{id} from that. % % \begin{macrocode} \edef\typog@@arg{#2}% \ifx\typog@@arg\empty \stepcounter{typog@inspect@count}% \edef\typog@@id{\typog@default@inspect@id@prefix \arabic{typog@inspect@count}}% \else \edef\typog@@id{\typog@trim@spaces{\typog@@arg}}% \fi \typeout{}% % \end{macrocode} % % Set both badness thresholds to absurdly low values as to activate \TeX's reports. % % \begin{macrocode} \hbadness=\m@ne \vbadness=\m@ne % \end{macrocode} % % Carefully select the tracing functionality we want (to improve our typography). % Too much trace data distracts % and the user always can turn on more tracing at the beginning of the environment. % % \begin{macrocode} \tracingnone \tracingpages=\@ne \tracingparagraphs=\@ne \showboxbreadth=\typog@@typoginspect@tracingboxes \showboxdepth=\typog@@typoginspect@tracingboxes} {\typeout{}% \ignorespacesafterend} % \end{macrocode} % \end{environment} % % \begin{environment}{typoginspectpar} % Companion environment to |typoginspect| % which adds a \cs{par} before the end of the group. % % \begin{macrocode} \NewDocumentEnvironment{typoginspectpar}{m} {\typoginspect{#1}} {\par\endtypoginspect} % \end{macrocode} % \end{environment} % % % \subsection{Hyphenation} % % \begin{macro}{\typog@allowhyphenation} % Re-enable automatic hyphenation. % % The same or almost the same implementation can be found % in \packagename{babel} as macro~\cs{bbl@allowhyphens} % and \packagename{hyphenat} as macro~\cs{prw@zbreak}. % % \begin{macrocode} \newcommand*{\typog@allowhyphenation} {\ifvmode \relax \else \nobreak \hskip\z@skip \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\allowhyphenation} % Define a user-visible alias unless the name is already used. % % \begin{macrocode} \unless\ifdefined\allowhyphenation \let\allowhyphenation=\typog@allowhyphenation \fi % \end{macrocode} % \end{macro} % % \begin{macro}{\breakpoint} % The starred form inhibits hyphenation of the right-hand component. % % \begin{macrocode} \NewDocumentCommand{\breakpoint}{s} {\discretionary{}{}{}% \IfBooleanTF{#1}% {\ignorespaces}% {\typog@allowhyphenation}} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\breakpoint#1{\if*\detokenize{#1}\ignorespaces\fi}% } % \end{macrocode} % \end{macro} % % \begin{environment}{hyphenmin} % \changes{v0.3}{2024-05-04}{New environment.} % No trickery here.\spacedemdash We use the mandatory argument for the value of % \cs{lefthyphenmin} if the optional argument has been omitted. % % \begin{macrocode} \NewDocumentEnvironment{hyphenmin}{o m} {\lefthyphenmin=\IfNoValueTF{#1}{#2}{#1}% \righthyphenmin=#2} {} % \end{macrocode} % \end{environment} % % % \subsection{Disable/Break Ligatures} % % \begin{macro}{\typog@hyphen} % We define our own hyphen so the user can override the definition in a pinch. % % \begin{macrocode} \newcommand*{\typog@hyphen}{\char`-} % \end{macrocode} % \end{macro} % % \begin{macro}{\nolig} % \begin{macrocode} \NewDocumentCommand{\nolig}{s o} {\dimen0=\IfNoValueTF{#2} {\typog@config@ligaturekern} {#2\typog@dim@unit}% \IfBooleanTF{#1}% {\kern\dimen0\ignorespaces}% {\discretionary{\typog@hyphen}{}{\kern\dimen0}% \typog@allowhyphenation \IfNoValueF{#2}{\ignorespaces}}} % \end{macrocode} % % The \acronym{PDF}-ready version of \cs{nolig} cannot be implemented with \cs{futurelet}. % Doh! % % \begin{macrocode} \typog@register@pdfsubstitute{ \RenewExpandableDocumentCommand{\nolig}{s o m}{% \ifx\typog@TYPOG#3\typog@TYPOG \relax \else \ifx\relax#3\relax \relax \else \typog@missing@argument \fi \fi} } % \end{macrocode} % \end{macro} % % % \subsection{Manual Italic Correction} % % \begin{macro}{\typog@itcorr@text@unconditional} % Fallback italic correction for text mode. % % \begin{macrocode} \newcommand*{\typog@itcorr@text@unconditional}[1] {\kern#1\typog@config@textitaliccorrection} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@itcorr@text} % Conditional italic correction depending on % the current font's own italic correction, % i.\,e., \cs{fontdimen1}. % % \begin{macrocode} \newcommand*{\typog@itcorr@text}[1] {\def\typog@@strength{#1}% \dimen0=\fontdimen1\font \ifdim\dimen0=\z@ \typog@itcorr@text@unconditional{\typog@@strength}% \else \kern\typog@@strength\dimen0 \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@itcorr@math} % Italic correction for math mode. % % \begin{macrocode} \newcommand*{\typog@itcorr@math}[1] {\mkern#1\typog@config@mathitaliccorrection} % \end{macrocode} % \end{macro} % % \begin{macro}{\itcorr} % If the font has no italic correction we fall back to out own length. % In text mode, the starred version always uses the fallback. % The star is a no-op in math mode. % % \begin{macrocode} \NewDocumentCommand{\itcorr}{s m} {\ifmmode \typog@itcorr@math{#2}% \else \IfBooleanTF{#1}% {\typog@itcorr@text{#2}}% {\typog@itcorr@text@unconditional{#2}}% \fi} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \RenewExpandableDocumentCommand{\itcorr}{s m}{} } % \end{macrocode} % \end{macro} % % % \subsection{Apply Extra Kerning} % % \subsubsection*{Slash} % % \begin{macro}{\typog@forwardslash} % We define our own forward-slash so the user can override the definition in a pinch. % % \begin{macrocode} \newcommand*{\typog@forwardslash}{\char`/} % \end{macrocode} % \end{macro} % % \begin{macro}{\kernedslash} % \changes{v0.5}{2024-09-15}{Allow for lowering (or raising) \cs{kernedslash} with package % option~\code{lowerslash}.} % Macro~\cs{kernedslash} introduces a hyphenation possibility right after the dash, % whereas the starred version does not. % % By the way, \cs{slash} expands to `|/|\cs{penalty}\cs{exhyphenpenalty}'. % % \begin{macrocode} \NewDocumentCommand{\kernedslash}{s} {\hspace*{\typog@config@slashkern}% \raisebox{-\typog@config@lowerslash}{\typog@forwardslash}% \IfBooleanTF{#1}% {\hspace*{\typog@config@slashkern}\ignorespaces}% {\typog@breakpoint \typog@allowhyphenation \hspace*{\typog@config@slashkern}}} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\kernedslash#1{\if*\detokenize{#1}/\ignorespaces\else/#1\fi}% } % \end{macrocode} % \end{macro} % % % \subsubsection*{Hyphen} % % \begin{macro}{\kernedhyphen} % \begin{macrocode} \NewDocumentCommand{\kernedhyphen}{s O{0} m m} {\ifmmode \mspace{\muexpr(#3 mu) * 18 / 1000}% \raisebox{#2\typog@dim@unit}{$\m@th\mathord{-}$}% \mspace{\muexpr(#4 mu) * 18 / 1000}% \else \def\typog@@auto{*}% \def\typog@@optarg{#2}% \hspace*{#3\typog@dim@unit}% \raisebox{\ifx\typog@@optarg\typog@@auto \typog@config@raisecapitalhyphen \else \typog@@optarg\typog@dim@unit \fi}{\typog@hyphen}% \hspace{#4\typog@dim@unit}% \IfBooleanT{#1}{\nobreak}% \fi} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \RenewExpandableDocumentCommand{\kernedhyphen}{s o m m}{-} } % \end{macrocode} % \end{macro} % % One-argument shorthands. % % \begin{macro}{\leftkernedhyphen} % Apply kerning on the left-hand side of the hyphen only. % % \begin{macrocode} \NewDocumentCommand{\leftkernedhyphen}{s O{0} m} {\IfBooleanTF{#1}% {\kernedhyphen*[#2]{#3}{0}\ignorespaces}% {\kernedhyphen[#2]{#3}{0}}} % \end{macrocode} % \end{macro} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \RenewExpandableDocumentCommand{\leftkernedhyphen}{s o m}{-} } % \end{macrocode} % % \begin{macro}{\rightkernedhyphen} % Apply kerning on the right-hand side of the hyphen only. % % \begin{macrocode} \NewDocumentCommand{\rightkernedhyphen}{s O{0} m} {\IfBooleanTF{#1}% {\kernedhyphen*[#2]{0}{#3}\ignorespaces}% {\kernedhyphen[#2]{0}{#3}}} % \end{macrocode} % \end{macro} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \RenewExpandableDocumentCommand{\rightkernedhyphen}{s o m}{-} } % \end{macrocode} % % % \subsubsection*{En-Dash and Em-Dash} % % \begin{macro}{\typog@wrap@endash} % Wrapper for the en-dash. The first and second arguments are used to control the % line breaking; the third argument is the actual en-dash macro. % % \begin{macrocode} \newcommand*{\typog@wrap@endash}[3] {#1\hspace{\typog@config@endashspace}% #3% #2\hspace{\typog@config@endashspace}} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@wrap@emdash} % Wrapper for the em-dash. The first and second arguments are used to control the % line breaking; the third argument is the actual em-dash macro. % % \begin{macrocode} \newcommand*{\typog@wrap@emdash}[3] {#1\hspace{\typog@config@emdashspace}% #3% #2\hspace{\typog@config@emdashspace}} % \end{macrocode} % \end{macro} % % \begin{macro}{\leftspacedendash} % \changes{v0.5}{2025-05-19}{New macro.} % User-land macro for the left (aka opening or introducing) spaced en-dash. % The unstarred variant introduces a breakpoint \emph{before} the en-dash. % % \begin{macrocode} \NewDocumentCommand{\leftspacedendash}{s o} {\IfBooleanTF{#1} {\IfNoValueTF{#2} {\typog@wrap@endash{\nobreak}{\nobreak} {\textendash}} {\typog@wrap@endash{\nobreak}{\nobreak} {\raisebox{#2}{\textendash}}}} {\IfNoValueTF{#2} {\typog@wrap@endash{\relax}{\nobreak} {\textendash}} {\typog@wrap@endash{\nobreak}{\nobreak} {\raisebox{#2}{\textendash}}}}% \ignorespaces} \let\leftspaceddash=\leftspacedendash % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \RenewExpandableDocumentCommand{\leftspacedendash}{s o m}{% \ifx\typog@TYPOG#3\typog@TYPOG \textendash \else \ifx\relax#3\relax \textendash \else \typog@missing@argument \fi \fi} \let\leftspaceddash=\leftspacedendash } % \end{macrocode} % \end{macro} % % \begin{macro}{\rightspacedendash} % \changes{v0.5}{2025-05-19}{New macro.} % User-land macro for the right (aka closing) spaced en-dash. % The unstarred variant introduces a breakpoint \emph{after} the en-dash. % % \begin{macrocode} \NewDocumentCommand{\rightspacedendash}{s o} {\IfBooleanTF{#1} {\IfNoValueTF{#2} {\typog@wrap@endash{\nobreak}{\nobreak} {\textendash}} {\typog@wrap@endash{\nobreak}{\nobreak} {\raisebox{#2}{\textendash}}}} {\IfNoValueTF{#2} {\typog@wrap@endash{\nobreak}{\relax} {\textendash}} {\typog@wrap@endash{\nobreak}{\nobreak} {\raisebox{#2}{\textendash}}}}% \ignorespaces} \let\rightspaceddash=\rightspacedendash \let\spacedendash=\rightspacedendash \let\spaceddash=\rightspacedendash % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \RenewExpandableDocumentCommand{\rightspacedendash}{s o m}{% \ifx\typog@TYPOG#3\typog@TYPOG \space\textendash\space \else \ifx\relax#3\relax \space\textendash\space \else \typog@missing@argument \fi \fi \ignorespaces} \let\rightspaceddash=\rightspacedendash \let\spacedendash=\rightspacedendash \let\spaceddash=\rightspacedendash } % \end{macrocode} % \end{macro} % % \begin{macro}{\swapendashskip} % \changes{v0.5}{2025-05-29}{New macro.} % \begin{macrocode} \NewDocumentCommand{\swapendashskip}{m} {\skip0=\lastskip \unskip #1% \hskip\skip0} % \end{macrocode} % \end{macro} % % \begin{macro}{\leftspacedendash} % \changes{v0.5}{2025-05-27}{New macro.} % User-land macro for the spaced em-dash. % % The two \cs{mbox}es turn off automatic hyphenation of the adjacent words. % This ensures \singlequotes{compatibility} with the en-dash~\sample{-\nolig*-}. % % \begin{macrocode} \NewDocumentCommand{\leftspacedemdash}{s o} {\mbox{}% \IfBooleanTF{#1} {\IfNoValueTF{#2} {\typog@wrap@emdash{\nobreak}{\nobreak} {\textemdash}} {\typog@wrap@emdash{\nobreak}{\nobreak} {\raisebox{#2}{\textemdash}}}} {\IfNoValueTF{#2} {\typog@wrap@emdash{\relax}{\nobreak} {\textemdash}} {\typog@wrap@emdash{\nobreak}{\nobreak} {\raisebox{#2}{\textemdash}}}}% \mbox{}% \ignorespaces} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \RenewExpandableDocumentCommand{\leftspacedemdash}{s o m}{% \ifx\typog@TYPOG#3\typog@TYPOG \textemdash \else \ifx\relax#3\relax \textemdash \else \typog@missing@argument \fi \fi} } % \end{macrocode} % \end{macro} % % \begin{macro}{\rightspacedemdash} % \changes{v0.5}{2025-05-27}{New macro.} % User-land macro for the right (aka closing) spaced em-dash. % The unstarred variant introduces a breakpoint \emph{after} the em-dash. % % The two \cs{mbox}es turn off automatic hyphenation of the adjacent words. % This ensures \singlequotes{compatibility} with the em-dash~\sample{-\nolig*-\nolig*-}. % % \begin{macrocode} \NewDocumentCommand{\rightspacedemdash}{s o} {\mbox{}% \IfBooleanTF{#1} {\IfNoValueTF{#2} {\typog@wrap@emdash{\nobreak}{\nobreak} {\textemdash}} {\typog@wrap@emdash{\nobreak}{\nobreak} {\raisebox{#2}{\textemdash}}}} {\IfNoValueTF{#2} {\typog@wrap@emdash{\nobreak}{\relax} {\textemdash}} {\typog@wrap@emdash{\nobreak}{\nobreak} {\raisebox{#2}{\textemdash}}}}% \mbox{}% \ignorespaces} \let\spacedemdash=\rightspacedemdash % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \RenewExpandableDocumentCommand{\rightspacedemdash}{s o m}{% \ifx\typog@TYPOG#3\typog@TYPOG \textemdash \else \ifx\relax#3\relax \textemdash \else \typog@missing@argument \fi \fi \ignorespaces} \let\spacedemdash=\rightspacedemdash } % \end{macrocode} % \end{macro} % % \subsection{Raise Selected Characters} % % \begin{macro}{\typog@breakpoint} % We want our own penalty for a line break at a particular point. % The predefined \cs{allowbreak} is too eager. % A package-private, user-configurable penalty fits best. % % \begin{macrocode} \newcommand*{\typog@breakpoint} {\penalty\typog@config@breakpenalty} % \end{macrocode} % \end{macro} % % % \begin{macro}{\capitalhyphen} % Macro~\cs{capitalhyphen} introduces a hyphenation possibility right after the dash, % whereas the starred version does not. % % \begin{macrocode} \NewDocumentCommand{\capitalhyphen}{s} {\raisebox{\typog@config@raisecapitalhyphen}{\typog@hyphen}% \IfBooleanTF{#1}% {\ignorespaces}% {\typog@breakpoint\typog@allowhyphenation}} % \end{macrocode} % % The non-hyperref version's code is straightforward. % The \cs{pdfstringdefDisableCommands}~version must be expandable % and must match the other version's signature. % Yikes! % We exploit the fact that conditions are expandable. % However, we cannot use \cs{typog@hyphen} in the expansion as \cs{char} gets in the way. % So, we fall back to the least~common denominator and use a bare dash. % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\capitalhyphen#1{% \if*\detokenize{#1}% -\ignorespaces \else -#1% \fi} } % \end{macrocode} % \end{macro} % % % \begin{macro}{\capitalendash} % Macro~\cs{capitalendash} introduces a hyphenation possibility right after the dash; % its starred version does not. % % \begin{macrocode} \NewDocumentCommand{\capitalendash}{s} {\raisebox{\typog@config@raisecapitaldash}{\textendash}% \IfBooleanTF{#1}% {\ignorespaces}% {\typog@breakpoint\typog@allowhyphenation}} \let\capitaldash=\capitalendash % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\capitalendash#1{% \if*\detokenize{#1}% \textendash\ignorespaces \else \textendash#1% \fi} \let\capitaldash=\capitalendash } % \end{macrocode} % \end{macro} % % % \begin{macro}{\capitalemdash} % Macro~\cs{capitalemdash} introduces a hyphenation possibility right after the dash; % its starred version does not. % % \begin{macrocode} \NewDocumentCommand{\capitalemdash}{s} {\raisebox{\typog@config@raisecapitaldash}{\textemdash}% \IfBooleanTF{#1}% {\ignorespaces}% {\typog@breakpoint\typog@allowhyphenation}} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\capitalemdash#1{% \if*\detokenize{#1}% \textemdash\ignorespaces \else \textemdash#1% \fi} } % \end{macrocode} % \end{macro} % % \begin{macro}{\leftspacedcapitalendash} % \changes{v0.5}{2025-05-21}{New macro.} % Thanks to our wrapper macro the definition of \cs{leftspacedcapitalendash} is easy to write. % \begin{macrocode} \NewDocumentCommand{\leftspacedcapitalendash}{s} {\IfBooleanTF{#1}% {\typog@wrap@endash{\nobreak}{\nobreak}{\capitalendash*}} {\typog@wrap@endash{\relax}{\nobreak}{\capitalendash}}% \ignorespaces} \let\leftspacedcapitaldash=\leftspacedcapitalendash % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\leftspacedcapitalendash#1{% \if*\detokenize{#1}% \textendash\ignorespaces \else \textendash#1% \fi} \let\leftspacedcapitaldash=\leftspacedcapitalendash } % \end{macrocode} % \end{macro} % % \begin{macro}{\rightspacedcapitalendash} % \changes{v0.5}{2025-05-21}{New macro.} % Thanks to our wrapper macro the definition of \cs{rightspacedcapitalendash} is easy to write. % \begin{macrocode} \NewDocumentCommand{\rightspacedcapitalendash}{s} {\IfBooleanTF{#1}% {\typog@wrap@endash{\nobreak}{\nobreak}{\capitalendash*}} {\typog@wrap@endash{\nobreak}{\relax}{\capitalendash}}% \ignorespaces} \let\rightspacedcapitaldash=\rightspacedcapitalendash \let\spacedcapitalendash=\rightspacedcapitalendash \let\spacedcapitaldash=\rightspacedcapitalendash % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\rightspacedcapitalendash#1{% \if*\detokenize{#1}% \textendash\ignorespaces \else \textendash#1% \fi} \let\rightspacedcapitaldash=\rightspacedcapitalendash \let\spacedcapitalendash=\rightspacedcapitalendash \let\spacedcapitaldash=\rightspacedcapitalendash } % \end{macrocode} % \end{macro} % % \begin{macro}{\leftspacedcapitalemdash} % \changes{v0.5}{2025-05-27}{New macro.} % Thanks to our wrapper macro the definition of \cs{leftspacedcapitalemdash} is easy to write. % \begin{macrocode} \NewDocumentCommand{\leftspacedcapitalemdash}{s} {\IfBooleanTF{#1}% {\typog@wrap@emdash{\nobreak}{\nobreak}{\capitalemdash*}} {\typog@wrap@emdash{\relax}{\nobreak}{\capitalemdash}}% \ignorespaces} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\leftspacedcapitalemdash#1{% \if*\detokenize{#1}% \textemdash\ignorespaces \else \textemdash#1% \fi} } % \end{macrocode} % \end{macro} % % \begin{macro}{\rightspacedcapitalemdash} % \changes{v0.5}{2025-05-27}{New macro.} % Thanks to our wrapper macro the definition of \cs{rightspacedcapitalemdash} is easy to write. % \begin{macrocode} \NewDocumentCommand{\rightspacedcapitalemdash}{s} {\IfBooleanTF{#1}% {\typog@wrap@emdash{\nobreak}{\nobreak}{\capitalemdash*}} {\typog@wrap@emdash{\nobreak}{\relax}{\capitalemdash}}% \ignorespaces} \let\spacedcapitalemdash=\rightspacedcapitalemdash % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\rightspacedcapitalemdash#1{% \if*\detokenize{#1}% \textemdash\ignorespaces \else \textemdash#1% \fi} \let\spacedcapitalemdash=\rightspacedcapitalemdash } % \end{macrocode} % \end{macro} % % \begin{macro}{\figuredash} % Macro~\cs{figuredash} introduces a hyphenation possibility right after the dash; % its starred version does not. % % \begin{macrocode} \NewDocumentCommand{\figuredash}{s} {\raisebox{\typog@config@raisefiguredash}{\textendash}% \IfBooleanTF{#1}% {\ignorespaces}% {\typog@breakpoint\typog@allowhyphenation}} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{\let\figuredash=\capitaldash} % \end{macrocode} % \end{macro} % % % \begin{macro}{\capitaltimes} % \begin{macrocode} \NewDocumentCommand{\capitaltimes}{} {\ifmmode \mathbin{\raisebox{\typog@config@raisecapitaltimes} {$\m@th\times$}}% \else \raisebox{\typog@config@raisecapitaltimes}{\texttimes}% \fi} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \RenewExpandableDocumentCommand{\capitaltimes}{}{\texttimes} } % \end{macrocode} % \end{macro} % % % \begin{macro}{\singleguillemetleft} % \begin{macrocode} \NewDocumentCommand{\singleguillemetleft}{} {\typog@allowhyphenation \raisebox{\typog@config@raiseguillemets}{\guilsinglleft}} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \let\singleguillemetleft\guilsinglleft } % \end{macrocode} % \end{macro} % % \begin{macro}{\singleguillemetright} % \begin{macrocode} \NewDocumentCommand{\singleguillemetright}{} {\raisebox{\typog@config@raiseguillemets}{\guilsinglright}% \typog@allowhyphenation} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \let\singleguillemetright\guilsinglright } % \end{macrocode} % \end{macro} % % \begin{macro}{\doubleguillemetleft} % \begin{macrocode} \NewDocumentCommand{\doubleguillemetleft}{} {\typog@allowhyphenation \raisebox{\typog@config@raiseguillemets}{\guillemotleft}} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \let\doubleguillemetleft\guillemotleft } % \end{macrocode} % \end{macro} % % \begin{macro}{\doubleguillemetright} % \begin{macrocode} \NewDocumentCommand{\doubleguillemetright}{} {\raisebox{\typog@config@raiseguillemets}{\guillemotright}% \typog@allowhyphenation} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \let\doubleguillemetright\guillemotright } % \end{macrocode} % \end{macro} % % \begin{macro}{\Singleguillemetleft} % \begin{macrocode} \NewDocumentCommand{\Singleguillemetleft}{} {\typog@allowhyphenation \raisebox{\typog@config@raisecapitalguillemets} {\guilsinglleft}} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \let\Singleguillemetleft\guilsinglleft } % \end{macrocode} % \end{macro} % % \begin{macro}{\Singleguillemetright} % \begin{macrocode} \NewDocumentCommand{\Singleguillemetright}{} {\raisebox{\typog@config@raisecapitalguillemets} {\guilsinglright}% \typog@allowhyphenation} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \let\Singleguillemetright\guilsinglright } % \end{macrocode} % \end{macro} % % \begin{macro}{\Doubleguillemetleft} % \begin{macrocode} \NewDocumentCommand{\Doubleguillemetleft}{} {\typog@allowhyphenation \raisebox{\typog@config@raisecapitalguillemets} {\guillemotleft}} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \let\Doubleguillemetleft\guillemotleft } % \end{macrocode} % \end{macro} % % \begin{macro}{\Doubleguillemetright} % \begin{macrocode} \NewDocumentCommand{\Doubleguillemetright}{} {\raisebox{\typog@config@raisecapitalguillemets} {\guillemotright}% \typog@allowhyphenation} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \let\Doubleguillemetright\guillemotright } % \end{macrocode} % \end{macro} % % % We need three lengths for three (pairs of) inverted exclamation marks and inverted question % marks. % % \begin{macro}{\typog@config@raiseinvertedmarks@i} % \begin{macrocode} \newlength{\typog@config@raiseinvertedmarks@i} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@raiseinvertedmarks@ii} % \begin{macrocode} \newlength{\typog@config@raiseinvertedmarks@ii} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@config@raiseinvertedmarks@iii} % \begin{macrocode} \newlength{\typog@config@raiseinvertedmarks@iii} % \end{macrocode} % \end{macro} % % And the three (pairs of) inverted exclamation marks and inverted question % marks themselves. Configurable. % % \begin{macro}{\typog@inverted@exclamationmark@i} % \begin{macrocode} \newcommand*{\typog@inverted@exclamationmark@i} {\textexclamdown} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@inverted@questionmark@i} % \begin{macrocode} \newcommand*{\typog@inverted@questionmark@i} {\textquestiondown} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@inverted@exclamationmark@ii} % \begin{macrocode} \newcommand*{\typog@inverted@exclamationmark@ii} {\textexclamdown} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@inverted@questionmark@ii} % \begin{macrocode} \newcommand*{\typog@inverted@questionmark@ii} {\textquestiondown} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@inverted@exclamationmark@iii} % \begin{macrocode} \newcommand*{\typog@inverted@exclamationmark@iii} {\textexclamdown} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@inverted@questionmark@iii} % \begin{macrocode} \newcommand*{\typog@inverted@questionmark@iii} {\textquestiondown} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@raise@inverted@mark} % The generic \singlequotes{raise}-macro handles all interesting cases. The first argument % selects the mark type and the second the associated raise-amount. % % If the raise-amount is exactly zero we shift-up the horizontal box with the mark to zero % its depth. % % \begin{macrocode} \newcommand*{\typog@raise@inverted@mark}[2] {\letcs{\@tempa}{typog@inverted@#1@\romannumeral#2}% \letcs{\@tempb}{typog@config@raiseinvertedmarks@\romannumeral#2}% \ifdim\@tempb=\z@ \setbox0=\hbox{\@tempa}% \dimen0=\dp0 \else \dimen0=\@tempb \fi \raisebox{\dimen0}{\@tempa}} % \end{macrocode} % \end{macro} % % The user-side macros are almost trivial now. % % \begin{macro}{\capitalinvertedexclamationmark} % \changes{v0.5}{2024-09-21}{New macro.} % \begin{macrocode} \NewDocumentCommand{\capitalinvertedexclamationmark}{m} {\typog@raise@inverted@mark{exclamationmark}{#1}% \typog@allowhyphenation} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\capitalinvertedexclamationmark#1{% \csname typog@inverted@exclamationmark@\romannumeral#1\endcsname } } % \end{macrocode} % \end{macro} % % \begin{macro}{\capitalinvertedquestionmark} % \changes{v0.5}{2024-09-21}{New macro.} % \begin{macrocode} \NewDocumentCommand{\capitalinvertedquestionmark}{m} {\typog@raise@inverted@mark{questionmark}{#1}% \typog@allowhyphenation} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\capitalinvertedquestionmark#1{% \csname typog@inverted@questionmark@\romannumeral#1\endcsname } } % \end{macrocode} % \end{macro} % % % \subsection[Vert. Adjust Label Items]{Vertically Adjusted Label Items} % % \begin{macro}{\@typog@uppercase@adjust@labelitem} % Handle all possible requests for uppercase label item correction. % Patch |itemize|~environments. % % \begin{macrocode} \newcommand*{\@typog@uppercase@adjust@labelitem}[1] {\@typog@maybe@patch@itemize \ifstrequal{#1}{*} {\setlength{\typog@adjust@labelitemi} {\typog@adjust@uppercase@labelitemi}% \setlength{\typog@adjust@labelitemii} {\typog@adjust@uppercase@labelitemii}% \setlength{\typog@adjust@labelitemiii} {\typog@adjust@uppercase@labelitemiii}% \setlength{\typog@adjust@labelitemiv} {\typog@adjust@uppercase@labelitemiv}} {\ifcase #1% 0 \relax % outside of any itemize environment \or % 1 \setlength{\typog@adjust@labelitemi} {\typog@adjust@uppercase@labelitemi}% \or % 2 \setlength{\typog@adjust@labelitemii} {\typog@adjust@uppercase@labelitemii}% \or % 3 \setlength{\typog@adjust@labelitemiii} {\typog@adjust@uppercase@labelitemiii}% \or % 4 \setlength{\typog@adjust@labelitemiv} {\typog@adjust@uppercase@labelitemiv}% \else \PackageError{typog} {Itemize level out of range} {Valid levels are 1, 2, 3, 4, and *} \fi}} % \end{macrocode} % \end{macro} % % \begin{macro}{\@typog@lowercase@adjust@labelitem} % Handle all possible requests for lowercase label item correction. % Patch |itemize|~environments. % % \begin{macrocode} \newcommand*{\@typog@lowercase@adjust@labelitem}[1] {\@typog@maybe@patch@itemize \ifstrequal{#1}{*} {\setlength{\typog@adjust@labelitemi} {\typog@adjust@lowercase@labelitemi}% \setlength{\typog@adjust@labelitemii} {\typog@adjust@lowercase@labelitemii}% \setlength{\typog@adjust@labelitemiii} {\typog@adjust@lowercase@labelitemiii}% \setlength{\typog@adjust@labelitemiv} {\typog@adjust@lowercase@labelitemiv}} {\ifcase #1% 0 \relax % outside of any itemize environment \or % 1 \setlength{\typog@adjust@labelitemi} {\typog@adjust@lowercase@labelitemi}% \or % 2 \setlength{\typog@adjust@labelitemii} {\typog@adjust@lowercase@labelitemii}% \or % 3 \setlength{\typog@adjust@labelitemiii} {\typog@adjust@lowercase@labelitemiii}% \or % 4 \setlength{\typog@adjust@labelitemiv} {\typog@adjust@lowercase@labelitemiv}% \else \PackageError{typog} {Itemize level out of range} {Valid levels are 1, 2, 3, 4, and *} \fi}} % \end{macrocode} % \end{macro} % % \begin{macro}{\@typog@noadjust@labelitem} % Neutralize all label item corrections. % This function \emph{does not} request patching any |itemize|~environment! % % \begin{macrocode} \newcommand*{\@typog@noadjust@labelitem}[1] {\ifstrequal{#1}{*} {\setlength{\typog@adjust@labelitemi}{\z@}% \setlength{\typog@adjust@labelitemii}{\z@}% \setlength{\typog@adjust@labelitemiii}{\z@}% \setlength{\typog@adjust@labelitemiv}{\z@}} {\ifcase #1% 0 \relax % outside of any itemize environment \or % 1 \setlength{\typog@adjust@labelitemi}{\z@}% \or % 2 \setlength{\typog@adjust@labelitemii}{\z@}% \or % 3 \setlength{\typog@adjust@labelitemiii}{\z@}% \or % 4 \setlength{\typog@adjust@labelitemiv}{\z@}% \else \PackageError{typog} {Itemize level out of range} {Valid levels are 1, 2, 3, 4, and *} \fi}} % \end{macrocode} % \end{macro} % % \begin{macro}{\uppercaseadjustlabelitems} % \changes{v0.4}{2024-05-14}{New macro.} % User macro that handles lists and the treats the empty list specially. We wrap the code % into \cs{AfterPreamble} because it may be called in the document's preamble where we don't % know whether package~\packagename{enumitem} already has been loaded and we can patch its % variant of \code{itemize}. % % \begin{macrocode} \NewDocumentCommand{\uppercaseadjustlabelitems}{m} {\AfterPreamble{% \ifblank{#1} {\@typog@uppercase@adjust@labelitem{\@itemdepth}} {\forcsvlist{\@typog@uppercase@adjust@labelitem}{#1}}% \ignorespaces}} % \end{macrocode} % \end{macro} % % \begin{macro}{\lowercaseadjustlabelitems} % \changes{v0.4}{2024-05-14}{New macro.} % User macro that handles lists and the treats the empty list specially. % % \begin{macrocode} \NewDocumentCommand{\lowercaseadjustlabelitems}{m} {\AfterPreamble{% \ifblank{#1} {\@typog@lowercase@adjust@labelitem{\@itemdepth}} {\forcsvlist{\@typog@lowercase@adjust@labelitem}{#1}}% \ignorespaces}} % \end{macrocode} % \end{macro} % % \begin{macro}{\noadjustlabelitems} % \changes{v0.4}{2024-05-14}{New macro.} % User macro that handles lists and the treats the empty list specially. % % \begin{macrocode} \NewDocumentCommand{\noadjustlabelitems}{m} {\ifblank{#1} {\@typog@noadjust@labelitem{\@itemdepth}} {\forcsvlist{\@typog@noadjust@labelitem}{#1}}% \ignorespaces} % \end{macrocode} % \end{macro} % % Now we get to the dirty part. All the above definitions do not get called until we hack the % existing |itemize|-environments, either the one of plain~\LaTeX{} or the one modified by % package~\packagename{enumitem}. % % Here comes the result of \code{latexdef -c article -s itemize}, which was used to derive the % patch code: % % \begin{verbatim} % \def\itemize{% % \ifnum \@itemdepth > \thr@@ % \@toodeep % \else % \advance\@itemdepth\@ne % \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% % \expandafter % \list % \csname\@itemitem\endcsname % {\def\makelabel##1{\hss\llap{##1}}}% % \fi}\end{verbatim} % % \begin{macro}{\@typog@itemize@patch} % This is the additional code we inject into plain \LaTeX's or % package~\packagename{enumitem}'s \cs{itemize}. % % \begin{macrocode} \newcommand*{\@typog@itemize@patch} % \end{macrocode} % % Save the original definition of \cs{@itemitem} for chain-calling it later on. % % \begin{macrocode} {\letcs{\@typog@old@itemitem}{\@itemitem} % \end{macrocode} % % Sneak in our own macro's name. % % \begin{macrocode} \edef\@itemitem{@typog@labelitem\romannumeral\the\@itemdepth} % \end{macrocode} % % Redefine under the original macro's name so that our code gets called and the old code % (\cs{@typog@old@itemitem}) is expanded. % % \begin{macrocode} \expandafter\def\csname\@itemitem\endcsname {\raisebox{\csname typog@adjust@labelitem\romannumeral\the\@itemdepth\endcsname} {\@typog@old@itemitem}}} % \end{macrocode} % \end{macro} % % If package~\packagename{enumitem} has been loaded, we use the \emph{same} patch. Here comes % the result of \code{latexdef -c article -p enumitem -s enit@itemize@i} that explains, why no % change is required: % % \begin{verbatim} % \def\enit@itemize@i#1#2#3#4{% % \ifnum #1 > #3 \relax % \enit@toodeep % \else % \enit@prelist\@ne{#1}{#2}% % \edef\@itemitem{label#2\romannumeral#1}% % \expandafter % \enit@list % \csname\@itemitem\endcsname % {\let\enit@calc\z@ % \def\makelabel##1{\enit@align{\enit@format{##1}}}% % \enit@preset{#2}{#1}{#4}% % \enit@calcleft % \enit@before % \enit@negwidth}% % \enit@keyfirst % \fi}\end{verbatim} % % \begin{macro}{\@typog@patch@itemize} % Unconditionally apply the patches that are just \emph{single} macro calls to disturb the % original macros as little as possible. If we detect \packagename{enumitem} to be present % we modify its definition of \code{itemize} otherwise we wrestle \LaTeX's macro. % % \begin{macrocode} \newcommand*{\@typog@patch@itemize} {\ifdefined\enit@itemize@i \patchcmd{\enit@itemize@i} {\expandafter} {\@typog@itemize@patch\expandafter} {\typog@debug@typeout{patching enumitem \string\enit@itemize@i\space succeeded}} {\PackageError{typog} {Patching enumitem macro \string\enit@itemize@i\space failed} {}}% \else \patchcmd{\itemize} {\expandafter} {\@typog@itemize@patch\expandafter} {\typog@debug@typeout{patching \string\itemize\space succeeded}} {\PackageError{typog} {Patching plain LaTeX macro \string\itemize\space failed} {}}% \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\@typog@maybe@patch@itemize} % Apply the patches only once. % % \begin{macrocode} \newbool{@typog@itemize@has@been@patched} \newcommand*{\@typog@maybe@patch@itemize} {\ifbool{@typog@itemize@has@been@patched} {\relax} {\@typog@patch@itemize \booltrue{@typog@itemize@has@been@patched}}} % \end{macrocode} % \end{macro} % % Freestanding height-adjusted label items. % % \begin{macro}{\Adjustedlabelitemi} % \changes{v0.5}{2024-12-30}{New macro.} % \begin{macrocode} \NewDocumentCommand{\Adjustedlabelitemi}{} {\raisebox{\typog@adjust@uppercase@labelitemi} {\labelitemi}} % \end{macrocode} % \end{macro} % % \begin{macro}{\adjustedlabelitemi} % \changes{v0.5}{2024-12-30}{New macro.} % \begin{macrocode} \NewDocumentCommand{\adjustedlabelitemi}{} {\raisebox{\typog@adjust@lowercase@labelitemi} {\labelitemi}} % \end{macrocode} % \end{macro} % % \begin{macro}{\Adjustedlabelitemii} % \changes{v0.5}{2024-12-30}{New macro.} % \begin{macrocode} \NewDocumentCommand{\Adjustedlabelitemii}{} {\raisebox{\typog@adjust@uppercase@labelitemii} {\labelitemii}} % \end{macrocode} % \end{macro} % % \begin{macro}{\adjustedlabelitemii} % \changes{v0.5}{2024-12-30}{New macro.} % \begin{macrocode} \NewDocumentCommand{\adjustedlabelitemii}{} {\raisebox{\typog@adjust@lowercase@labelitemii} {\labelitemii}} % \end{macrocode} % \end{macro} % % \begin{macro}{\Adjustedlabelitemiii} % \changes{v0.5}{2024-12-30}{New macro.} % \begin{macrocode} \NewDocumentCommand{\Adjustedlabelitemiii}{} {\raisebox{\typog@adjust@uppercase@labelitemiii} {\labelitemiii}} % \end{macrocode} % \end{macro} % % \begin{macro}{\adjustedlabelitemiii} % \changes{v0.5}{2024-12-30}{New macro.} % \begin{macrocode} \NewDocumentCommand{\adjustedlabelitemiii}{} {\raisebox{\typog@adjust@lowercase@labelitemiii} {\labelitemiii}} % \end{macrocode} % \end{macro} % % \begin{macro}{\Adjustedlabelitemiv} % \changes{v0.5}{2024-12-30}{New macro.} % \begin{macrocode} \NewDocumentCommand{\Adjustedlabelitemiv}{} {\raisebox{\typog@adjust@uppercase@labelitemiv} {\labelitemiv}} % \end{macrocode} % \end{macro} % % \begin{macro}{\adjustedlabelitemiv} % \changes{v0.5}{2024-12-30}{New macro.} % \begin{macrocode} \NewDocumentCommand{\adjustedlabelitemiv}{} {\raisebox{\typog@adjust@lowercase@labelitemiv} {\labelitemiv}} % \end{macrocode} % \end{macro} % % And now for their \acronym{PDF}substitutes. % % \begin{macrocode} \typog@register@pdfsubstitute{ \def\Adjustedlabelitemi{\labelitemi} \def\adjustedlabelitemi{\labelitemi} \def\Adjustedlabelitemii{\labelitemii} \def\adjustedlabelitemii{\labelitemii} \def\Adjustedlabelitemiii{\labelitemiii} \def\adjustedlabelitemiii{\labelitemiii} \def\Adjustedlabelitemiv{\labelitemiv} \def\adjustedlabelitemiv{\labelitemiv} } % \end{macrocode} % % Here come our convenience macros to simplify an accurate setup of the label adjustments. % % \begin{macro}{\typog@hairline@width} % Line width of the horizontal reference lines in our convenience macros. % % \begin{macrocode} \newcommand*{\typog@hairline@width}{.125pt} % \end{macrocode} % \end{macro} % % \begin{macro}{\typogadjuststairsfor} % The arguments are: % \#1: \meta{scale-factor}, % \#2: \meta{step-size}, % \#3: \meta{number-of-steps}, % \#4: \meta{sample}, and % \#5: \cs{labelitem}\meta{N}. % % Generate an ascending stairs of argument~\#5. % % \begin{macrocode} \newcommand*{\typogadjuststairsfor}[5] % \end{macrocode} % % Store (half of) the space between two samples in \cs{dimen0}. % % \begin{macrocode} {\dimen0=1pt% % \end{macrocode} % % Load the \meta{number-of-steps} and ensure that it is odd. % % \begin{macrocode} \count0=#3\relax \unless\ifodd\count0 \advance\count0 by 1% \fi % \end{macrocode} % % Set the iteration counter. % % \begin{macrocode} \setcounter{typog@@iteration}{1}% % \end{macrocode} % % Put the \meta{sample} into a box so that we can measure it with \cs{ht}. % % \begin{macrocode} \setbox0=\hbox{#4}% % \end{macrocode} % % Box~1 is the accumulator for the raised samples. % % \begin{macrocode} \setbox1=\hbox{}% % \end{macrocode} % % Build the stairs. % % \begin{macrocode} \loop \ifnum\thetypog@@iteration=\numexpr\count0 / 2\relax \dimen1=3\dimen0 \else \dimen1=\dimen0 \fi \dimen2=\dimexpr#2 * (\thetypog@@iteration - \count0 / 2)\relax \setbox1=\hbox{\unhbox1\raisebox{\dimen2}{\kern\dimen1 #5\kern\dimen1}}% \addtocounter{typog@@iteration}{1}% \unless\ifnum\thetypog@@iteration>\count0 \repeat % \end{macrocode} % % Merge the stairs with a hairline at \#1 times the height of \meta{sample}. % Answer just a single box. % % \begin{macrocode} \mbox{\rlap{\raisebox{\fpeval{#1}\ht0}{\rule{\wd1}{\typog@hairline@width}}}\box1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\typogadjuststairs} % \changes{v0.4}{2024-05-14}{New macro.} % The arguments are: % \#1: \meta{scale-factor}, % \#2: \meta{step-size}, % \#3: \meta{number-of-steps}, and % \#4: \meta{sample}. % % \begin{macrocode} \NewDocumentCommand{\typogadjuststairs}{O{.5} m m m} {\begingroup \unless\ifdim #2>\z@ \PackageError{typog} {\string\typogadjuststairs\space non-positive step-size} {step-size must be a positive dimension}% \fi \ifnum #3<1 \PackageError{typog} {\string\typogadjuststairs\space too few number-of-steps} {number-of-steps must at least be 1}% \fi \ifblank{#4} {\PackageError{typog} {sample must not be empty} {supply either some uppercase or some lowercase letters}} {}% \def\arraystretch{1}% \begin{tabular}{@{}c@{}} \typogadjuststairsfor{#1}{#2}{#3}{#4}{\labelitemi} \\ \typogadjuststairsfor{#1}{#2}{#3}{#4}{\labelitemii} \\ \typogadjuststairsfor{#1}{#2}{#3}{#4}{\labelitemiii} \\ \typogadjuststairsfor{#1}{#2}{#3}{#4}{\labelitemiv} \end{tabular} \endgroup} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@uppercase@adjusted@labelitems} % Return all four labelitems in a horizontal box after they have been adjusted with the % uppercase-constants set. % % \begin{macrocode} \newcommand*{\typog@uppercase@adjusted@labelitems} {\hbox{\raisebox{\typog@adjust@uppercase@labelitemi}{\labelitemi}% \raisebox{\typog@adjust@uppercase@labelitemii}{\labelitemii}% \raisebox{\typog@adjust@uppercase@labelitemiii}{\labelitemiii}% \raisebox{\typog@adjust@uppercase@labelitemiv}{\labelitemiv}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\typoguppercaseadjustcheck} % \changes{v0.4}{2024-05-14}{New macro.} % We stuff the user's sample text into a box only to measure its height. We typeset all four % labels and draw a hairline at half the height of the sample right through it. % % \begin{macrocode} \NewDocumentCommand{\typoguppercaseadjustcheck}{O{.5} m} {\setbox0=\hbox{#2}% \setbox1=\typog@uppercase@adjusted@labelitems \mbox{\rlap{\raisebox{\fpeval{#1}\ht0} {\rule{\wd1}{\typog@hairline@width}}}% \box1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@lowercase@adjusted@labelitems} % Return all four labelitems in a horizontal box after they have been adjusted with the % lowercase-constants set. % % \begin{macrocode} \newcommand*{\typog@lowercase@adjusted@labelitems} {\hbox{\raisebox{\typog@adjust@lowercase@labelitemi}{\labelitemi}% \raisebox{\typog@adjust@lowercase@labelitemii}{\labelitemii}% \raisebox{\typog@adjust@lowercase@labelitemiii}{\labelitemiii}% \raisebox{\typog@adjust@lowercase@labelitemiv}{\labelitemiv}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\typoglowercaseadjustcheck} % \changes{v0.4}{2024-05-14}{New macro.} % Same code as \cs{typoguppercaseadjustcheck} for lowercase. % % \begin{macrocode} \NewDocumentCommand{\typoglowercaseadjustcheck}{O{.5} m} {\setbox0=\hbox{#2}% \setbox1=\typog@lowercase@adjusted@labelitems \mbox{\rlap{\raisebox{\fpeval{#1}\ht0} {\rule{\wd1}{\typog@hairline@width}}}% \box1}} % \end{macrocode} % \end{macro} % % % \subsection[Align Last Line]{Align Last Line of a Paragraph} % % The code of environment |lastlineraggedleftpar| % has been inspired by macro~\cs{lastlineraggedleft}~\cite[Sec.~2]{wilson:2007}. % % \begin{environment}{lastlineraggedleftpar} % \begin{macrocode} \NewDocumentEnvironment{lastlineraggedleftpar}{} {\lastlinefit=0% \setlength{\leftskip}{\z@ \@plus 1fil}% \setlength{\rightskip}{-\leftskip}% \setlength{\parfillskip}{\leftskip}} {\par} % \end{macrocode} % \end{environment} % % \begin{environment}{lastlineflushrightpar} % Define |lastlineflushrightpar| as an alias of |lastlineraggedleftpar|. % % \begin{macrocode} \let\lastlineflushrightpar=\lastlineraggedleftpar \let\endlastlineflushrightpar=\endlastlineraggedleftpar % \end{macrocode} % \end{environment} % % \begin{environment}{lastlinecenteredpar} % The code of environment |lastlinecenteredpar| % has been inspired by \textit{Tex By Topic}~\cite[Sec.~18.3.1]{eijkhout:2007}. % % \begin{macrocode} \NewDocumentEnvironment{lastlinecenteredpar}{} {\lastlinefit=0% \setlength{\leftskip}{\z@ \@plus .5fil}% \setlength{\rightskip}{-\leftskip}% \setlength{\parfillskip}{\z@ \@plus 1fil}} {\par} % \end{macrocode} % \end{environment} % % % \subsection[Fill Last Line] % {Fill Last Line of a Paragraph} % % \begin{environment}{shortenpar} % \begin{macrocode} \NewDocumentEnvironment{shortenpar}{} {\advance\looseness by -1 \ifnum\tracingparagraphs>0 \typeout{@ looseness \the\looseness}% \fi} {\par} % \end{macrocode} % \end{environment} % % \begin{environment}{prolongpar} % We try to be prudent and inhibit hyphenation of the next-to-last line just in case the % longer paragraph could be cheaply achieved by hyphenation\leftspacedendash at the % worst\rightspacedendash of the last word. % % \begin{macrocode} \NewDocumentEnvironment{prolongpar}{} {\finalhyphendemerits=100000001 \advance\looseness by 1 \ifnum\tracingparagraphs>0 \typeout{@ looseness \the\looseness}% \fi} {\par} % \end{macrocode} % \end{environment} % % \begin{macro}{\typog@covernextindentpar@zero@parindent} % This auxiliary macro and the following one % are meant as an easy means to override the defaults % of the user-visible environment~|covernextindentpar|. % % \begin{macrocode} \newcommand*{\typog@covernextindentpar@zero@parindent}{2em} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@covernextindentpar@nonzero@parindent} % \begin{macrocode} \newcommand*{\typog@covernextindentpar@nonzero@parindent}{2\parindent} % \end{macrocode} % \end{macro} % % \begin{environment}{covernextindentpar} % \begin{macrocode} \NewDocumentEnvironment{covernextindentpar}{o} {\IfNoValueTF{#1} {\ifdim\parindent=\z@ \dimen0=\dimexpr\linewidth - \typog@covernextindentpar@zero@parindent \else \dimen0=\dimexpr\linewidth - \typog@covernextindentpar@nonzero@parindent \fi} {\dimen0=\dimexpr\linewidth - (#1)}% \parfillskip=\dimen0 \@minus \dimen0 \relax} {\par} % \end{macrocode} % \end{environment} % % \begin{macro}{\typog@openlastlinepar@zero@parindent} % These auxiliary macros are meant as a means to override the defaults % of the user-visible environment~|openlastlinepar|. % % \begin{macrocode} \newcommand*{\typog@openlastlinepar@zero@parindent}{2em} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@openlastlinepar@nonzero@parindent} % \begin{macrocode} \newcommand*{\typog@openlastlinepar@nonzero@parindent}{2\parindent} % \end{macrocode} % \end{macro} % % \begin{environment}{openlastlinepar} % Compare with the suggestion in reference~\citenum{wermuth:2018}. % % \begin{macrocode} \NewDocumentEnvironment{openlastlinepar}{o} {\IfNoValueTF{#1} {\ifdim\parindent=\z@ \skip0=\typog@openlastlinepar@zero@parindent \@plus 1fil \@minus \typog@openlastlinepar@zero@parindent \else \skip0=\typog@openlastlinepar@nonzero@parindent \@plus 1fil \@minus \typog@openlastlinepar@nonzero@parindent \fi} {\dimen0=\dimexpr#1\relax \skip0=\dimen0 \@plus 1fil \@minus \dimen0} \parfillskip=\skip0} {\par} % \end{macrocode} % \end{environment} % % \begin{environment}{lastlinefitpar} % \changes{v0.5}{2024-09-10}{New environment.} % Set value of \cs{lastlinefit} for a paragraph. % % \begin{macrocode} \NewDocumentEnvironment{lastlinefitpar}{O{1000}} {\lastlinefit=#1\relax} {\par} % \end{macrocode} % \end{environment} % % % \subsection{Spacing} % % \begin{macro}{\widespacestrength} % Weight factor (``strength'') for \cs{fontdimen7}, the extra width of a sentence-ending % space, we apply to construct our \cs{widespace} if \(\cs{fontdimen7} \not= 0\). Can be % increased to get a more pronounced effect. % % \begin{macrocode} \newcommand*{\widespacestrength}{1.} % \end{macrocode} % \end{macro} % % \begin{macro}{\widespacescale} % Scale factor we apply to the glue of the normal space to setup the glue of our % \cs{widespacescale}. Also used in the fall-back calculation for the width if % \(\cs{fontdimen7} = 0\). % % \begin{macrocode} \newcommand*{\widespacescale}{1.125} % \end{macrocode} % \end{macro} % % \begin{macro}{\widespace} % \changes{v0.2}{2024-3-29}{Add fallback if \cs{fontdimen7} is zero. Extend with a starred version.} % \begin{macrocode} \NewDocumentCommand{\widespace}{s} {\IfBooleanTF{#1}% {\dimen0=\widespacescale\fontdimen2\font}% {\ifdim\fontdimen7\font=\z@ \dimen0=\widespacescale\fontdimen2\font \else \dimen0=\dimexpr\fontdimen2\font + \widespacestrength\fontdimen7\font \fi}% \hskip \glueexpr\dimen0 \@plus \widespacescale\fontdimen3\font \@minus \widespacescale\fontdimen4\font \ignorespaces} % \end{macrocode} % \end{macro} % % \begin{macro}{\narrowspacestrength} % Weight factor (``strength'') for \cs{fontdimen7}, the extra width of a sentence-ending % space, we apply to construct our \cs{narrowspace} if \(\cs{fontdimen7} \not= 0\). Can be % increased to get a more pronounced effect. % % \begin{macrocode} \newcommand*{\narrowspacestrength}{.5} % \end{macrocode} % \end{macro} % % \begin{macro}{\narrowspacescale} % Scale factor we apply to the glue of the normal space to setup the glue of our % \cs{narrowspacescale}. Also used in the fall-back calculation for the width if % \(\cs{fontdimen7} = 0\). % % \begin{macrocode} \newcommand*{\narrowspacescale}{.9375} % \end{macrocode} % \end{macro} % % \begin{macro}{\narrowspace} % \changes{v0.2}{2024-3-29}{New macro.} % \begin{macrocode} \NewDocumentCommand{\narrowspace}{s} {\IfBooleanTF{#1}% {\dimen0=\narrowspacescale\fontdimen2\font}% {\ifdim\fontdimen7\font=\z@ \dimen0=\narrowspacescale\fontdimen2\font \else \dimen0=\dimexpr\fontdimen2\font - \narrowspacestrength\fontdimen7\font \fi}% \hskip \glueexpr\dimen0 \@plus \narrowspacescale\fontdimen3\font \@minus \narrowspacescale\fontdimen4\font \ignorespaces} % \end{macrocode} % \end{macro} % % % See also: TeX by Topic \cite[ch.~20, p.~185\figuredash190]{eijkhout:2007}. % % \begin{environment}{loosespacing} % \begin{macrocode} \NewDocumentEnvironment{loosespacing}{O{1}} {\dimen2=\fontdimen2\font \ifcase #1 \spaceskip=\z@ \or % 1 +5% \spaceskip=1.05\dimen2 \@plus .5\dimen2 \@minus .1\dimen2 \or % 2 +10% \spaceskip=1.1\dimen2 \@plus .5\dimen2 \@minus .1\dimen2 \or % 3 +20% \spaceskip=1.2\dimen2 \@plus .6\dimen2 \@minus .2\dimen2 \else % >= 4 +30% \spaceskip=1.3\dimen2 \@plus .8\dimen2 \@minus .3\dimen2 \fi \ignorespaces} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % \begin{environment}{tightspacing} % \begin{macrocode} \NewDocumentEnvironment{tightspacing}{O{1}} {\dimen2=\fontdimen2\font \ifcase #1 \spaceskip=\z@ \or % 1 -1.25% \spaceskip=.9875\dimen2 \@plus .0125\dimen2 \@minus .5\dimen2 \or % 2 -2.5% \spaceskip=.975\dimen2 \@plus .025\dimen2 \@minus .5\dimen2 \or % 3 -5% \spaceskip=.95\dimen2 \@plus .05\dimen2 \@minus .5\dimen2 \else % >= 4 -10% \spaceskip=.9\dimen2 \@plus .1\dimen2 \@minus .5\dimen2 \fi \ignorespaces} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % % \subsection{\packagename{Microtype} Front\capitalhyphen End} % % \subsubsection*{Tracking} % % \begin{environment}{setfonttracking} % % To achieve the control we want, % we must tinker with \packagename{microtype's} internals. % Doh! % % \begin{macrocode} \NewDocumentEnvironment{setfonttracking}{m} {\edef\MT@letterspace@{#1}% \lsstyle \ignorespaces} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % % \subsubsection*{Font Expansion} % % \begin{macro}{\typog@setup@font@expansion} % Note that we cannot factor the encodings into a macro; % a single encoding would qualify, though. % We need to support multiple encodings and thus go with the literal solution. % % \begin{macrocode} \newcommand*{\typog@setup@font@expansion} {\SetExpansion [context = typog@shrink1, shrink = \typog@shrink@i, stretch = 0]% {encoding = {*}}% {} \SetExpansion [context = typog@shrink2, shrink = \typog@shrink@ii, stretch = 0]% {encoding = {*}}% {} \SetExpansion [context = typog@shrink3, shrink = \typog@shrink@iii, stretch = 0]% {encoding = {*}}% {} \SetExpansion [context = typog@stretch1, shrink = 0, stretch = \typog@stretch@i]% {encoding = {*}}% {} \SetExpansion [context = typog@stretch2, shrink = 0, stretch = \typog@stretch@ii]% {encoding = {*}}% {} \SetExpansion [context = typog@stretch3, shrink = 0, stretch = \typog@stretch@iii]% {encoding = {*}}% {} \SetExpansion [context = typog@expand1, shrink = \typog@shrink@i, stretch = \typog@stretch@i]% {encoding = {*}}% {} \SetExpansion [context = typog@expand2, shrink = \typog@shrink@ii, stretch = \typog@stretch@ii]% {encoding = {*}}% {} \SetExpansion [context = typog@expand3, shrink = \typog@shrink@iii, stretch = \typog@stretch@iii]% {encoding = {*}}% {}} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@test@microtype@expansion@feature} % We cannot even parse the \cs{iftypog@microtype@preloaded}~part further down % unless the \cs{ifMT@expansion}~conditional exists. % So, we hoist this test in a macro of its own. % It only gets called if package~\packagename{microtype} already has been sourced. % % \begin{macrocode} \newcommand*{\typog@test@microtype@expansion@feature} {\ifMT@expansion \typog@typeout{microtype preloaded -- font expansion features available}% \def\typog@require@microtype@expansion{\relax} \typog@setup@font@expansion \else \PackageWarning{typog}{microtype preloaded,\space but font expansion is disabled}% \def\typog@require@microtype@expansion {\PackageError{typog} {microtype font expansion disabled} {pass option `expansion' to package microtype}} \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@require@microtype@expansion} % We are all set for the initialization of the font expansion, % however, we must be careful in which (load-)state % package~\packagename{microtype} is in. % Compare with the code for \cs{typog@require@microtype} % and~\cs{typog@require@preloaded@microtype}. % % Initialize our own flag and setup meaningful messages for later feature checks. % % \begin{macrocode} \iftypog@microtype@preloaded \typog@test@microtype@expansion@feature \else \def\typog@require@microtype@expansion {\PackageError{typog}% {package microtype not (pre-)loaded, % which is required for typog's font expansion}% {require package microtype before package typog}} \fi % \end{macrocode} % \end{macro} % % \begin{environment}{setfontshrink} % \begin{macrocode} \NewDocumentEnvironment{setfontshrink}{O{1}} {\typog@require@microtype@expansion \ifcase#1% 0 \relax \or % 1 \microtypecontext{expansion=typog@shrink1}% \or % 2 \microtypecontext{expansion=typog@shrink2}% \else % >= 3 \microtypecontext{expansion=typog@shrink3}% \fi \ignorespaces} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % \begin{environment}{setfontstretch} % \begin{macrocode} \NewDocumentEnvironment{setfontstretch}{O{1}} {\typog@require@microtype@expansion \ifcase#1% 0 \relax \or % 1 \microtypecontext{expansion=typog@stretch1}% \or % 2 \microtypecontext{expansion=typog@stretch2}% \else % >= 3 \microtypecontext{expansion=typog@stretch3}% \fi \ignorespaces} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % \begin{environment}{setfontexpand} % \begin{macrocode} \NewDocumentEnvironment{setfontexpand}{O{1}} {\typog@require@microtype@expansion \ifcase#1% 0 \relax \or % 1 \microtypecontext{expansion=typog@expand1}% \or % 2 \microtypecontext{expansion=typog@expand2}% \else % >= 3 \microtypecontext{expansion=typog@expand3}% \fi \ignorespaces} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % \begin{environment}{nofontexpansion} % Implementation: We proceed a different approach with respect to requiring package microtype. % The semantics of the macro is to switch something off. % If it is not \singlequotes{on} because the necessary package was not loaded, a no-op is ok. % % \begin{macrocode} \NewDocumentEnvironment{nofontexpansion}{} {\ifdefined\microtypesetup \microtypesetup{expansion=false}% \fi \ignorespaces} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % \begin{environment}{nofontexpand} % Define |nofontexpand| as an alias of |nofontexpansion|. % % \begin{macrocode} \let\nofontexpand=\nofontexpansion \let\endnofontexpand=\endnofontexpansion % \end{macrocode} % \end{environment} % % % \subsubsection*{Character Protrusion} % % \begin{environment}{nocharprotrusion} % See \singlequotes{Implementation} comment of |nofontexpansion|. % % \begin{macrocode} \NewDocumentEnvironment{nocharprotrusion}{} {\ifdefined\microtypesetup \microtypesetup{protrusion=false}% \fi \ignorespaces} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % % \subsection{Sloppy Paragraphs} % % \begin{macro}{\typog@scaled@emergencystretch} % Compute the correct scale factor for the emergency stretch, % even if we do not have a valid \cs{linewidth}. % % \begin{macrocode} \newcommand*{\typog@scaled@emergencystretch}[1] {\emergencystretch=\ifdim\linewidth=\z@ #1% \else \dimexpr (#1) * \linewidth / \textwidth \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\slightlysloppy} % Macro~\cs{slightlysloppy} takes an optional~\meta{sloppiness} index ranging from~0 to~8, % where~0 means the same as \cs{fussy} and~8 or more works like \cs{sloppy}. % The default \meta{sloppiness} is~1. % % \begin{macrocode} \NewDocumentCommand{\slightlysloppy}{O{1}} {\ifcase #1% 0 % \tolerance=200 % \emergencystretch=\z@ % \hfuzz=.1\p@ % \vfuzz=\hfuzz \fussy \or % 1 \pretolerance=165% \tolerance=330% \typog@scaled@emergencystretch{.375em}% \hfuzz=.15\p@ \vfuzz=\hfuzz \or % 2 \pretolerance=265% \tolerance=530% \typog@scaled@emergencystretch{.75em}% \hfuzz=.15\p@ \vfuzz=\hfuzz \or % 3 \pretolerance=435% \tolerance=870% \typog@scaled@emergencystretch{1.125em}% \hfuzz=.2\p@ \vfuzz=\hfuzz \or % 4 \pretolerance=705% \tolerance=1410% \typog@scaled@emergencystretch{1.5em}% \hfuzz=.3\p@ \vfuzz=\hfuzz \or % 5 \pretolerance=1155% \tolerance=2310% \typog@scaled@emergencystretch{1.875em}% \hfuzz=.35\p@ \vfuzz=\hfuzz \or % 6 \pretolerance=1880% \tolerance=3760% \typog@scaled@emergencystretch{2.25em}% \hfuzz=.4\p@ \vfuzz=\hfuzz \or % 7 \pretolerance=3065% \tolerance=6130% \typog@scaled@emergencystretch{2.625em}% \hfuzz=.45\p@ \vfuzz=\hfuzz \else % >= 8 % \tolerance=9999 % \emergencystretch=3em % \hfuzz=.5\p@ % \vfuzz=\hfuzz \sloppy \fi \ignorespaces} % \end{macrocode} % \end{macro} % % \begin{implementationnote} % \begin{itemize} % \item The \cs{tolerance}~values are calculated as the geometric mean of the extreme % values~200 and~9999. This means the factor % \begin{equation*} % f = \Big(\frac{9999}{200}\Big)^{1/8} \approx 1.63 % \end{equation*} % defines additional tolerances which we generously round values in the actual % implementation. % % \item The \cs{emergencystretch} is scaled linearly with \meta{sloppiness} \emph{and} the % ratio of the actual \cs{linewidth} to the (maximum) \cs{textwidth}. % % \item The \cs{hfuzz}~values are interpolated linearly with \meta{sloppiness} between .1pt % and~.5pt. % \end{itemize} % % Maxima code to calculate the intermediate values. % % \begin{description} % \item[Initialize.] \code{load("list\_functions")\$} % \item[\cs{tolerance}:] \code{logspace(log10(200), log10(9999), 9), numer;} % \item[\cs{emergencystretch}:] \code{linspace(0, 3, 9), numer;} % \item[\cs{hfuzz}:] \code{linspace(.1, .5, 9);} % \end{description} % \end{implementationnote} % % \begin{environment}{slightlysloppypar} % \begin{macrocode} \NewDocumentEnvironment{slightlysloppypar}{O{1}} {\par\slightlysloppy[#1]\ignorespaces} {\par} % \end{macrocode} % \end{environment} % % % \subsection[Vert.~Tie Paragraphs]{Vertically Partially-Tied Paragraphs} % % \begin{macro}{\typog@geometric@mean} % This is just the usual geometric mean of two values~\(x\) and~\(y\): \(\sqrt{x y}\). % % \begin{macrocode} \ExplSyntaxOn \newcommand*{\typog@geometric@mean}[2] {\fp_to_int:n {sqrt((#1) * (#2))}} \ExplSyntaxOff % \end{macrocode} % \end{macro} % % \begin{macro}{typog@mean@penalty} % Reserve a private counter for the geometric-mean penalties. % % \begin{macrocode} \newcounter{typog@mean@penalty} % \end{macrocode} % \end{macro} % % \begin{macro}{\vtietop} % \begin{macrocode} \NewDocumentCommand{\vtietop}{O{3}} {\setcounter{typog@mean@penalty} {\typog@geometric@mean{\@M}{\clubpenalty}}% \typog@debug@typeout{vtietop: penalties \the\@M--\the\value{typog@mean@penalty}--\the\clubpenalty}% \unless\ifnum\clubpenalty<\@M \PackageWarning{typog}{vtietop: clubpenalty=\the\clubpenalty\space>= 10000}% \fi \ifcase#1% 0 \relax \or % 1 \relax \or % 2 \clubpenalties 3 \@M \value{typog@mean@penalty} \clubpenalty \or % 3 \clubpenalties 4 \@M \@M \value{typog@mean@penalty} \clubpenalty \or % 4 \clubpenalties 5 \@M \@M \@M \value{typog@mean@penalty} \clubpenalty \or % 5 \clubpenalties 6 \@M \@M \@M \@M \value{typog@mean@penalty} \clubpenalty \or % 6 \clubpenalties 7 \@M \@M \@M \@M \@M \value{typog@mean@penalty} \clubpenalty \or % 7 \clubpenalties 8 \@M \@M \@M \@M \@M \value{typog@mean@penalty} \clubpenalty \or % 8 \clubpenalties 9 \@M \@M \@M \@M \@M \value{typog@mean@penalty} \clubpenalty \else % >= 9 \clubpenalties 10 \@M \@M \@M \@M \@M \@M \@M \@M \value{typog@mean@penalty} \clubpenalty \fi} % \end{macrocode} % \end{macro} % % \begin{environment}{vtietoppar} % \begin{macrocode} \NewDocumentEnvironment{vtietoppar}{O{3}} {\vtietop[#1]} {\par \ignorespacesafterend} % \end{macrocode} % \end{environment} % % \begin{macro}{\splicevtietop} % \begin{macrocode} \NewDocumentCommand{\splicevtietop}{O{3}} {\let\typog@old@item=\@item \def\@item[##1]{\typog@old@item[##1]\vtietop[#1]}% \ignorespaces} % \end{macrocode} % % We define an extra style for the users of \packagename{enumitem}. % Its only drawback is that it hard-codes the default number of tied lines~(3). % % \begin{macrocode} \ifdefined\SetEnumitemKey \SetEnumitemKey{vtietop}{first=\splicevtietop} \fi % \end{macrocode} % \end{macro} % % \begin{macro}{\vtiebot} % \begin{macrocode} \NewDocumentCommand{\vtiebot}{O{3}} {\setcounter{typog@mean@penalty} {\typog@geometric@mean{\@M}{\widowpenalty}}% \typog@debug@typeout{vtiebot: penalties \the\@M--\the\value{typog@mean@penalty}--\the\widowpenalty}% \unless\ifnum\widowpenalty<\@M \PackageWarning{typog}{vtiebot: widowpenalty=\the\widowpenalty\space>= 10000}% \fi \ifcase#1% 0 \relax \or % 1 \relax \or % 2 \widowpenalties 3 \@M \value{typog@mean@penalty} \widowpenalty \or % 3 \widowpenalties 4 \@M \@M \value{typog@mean@penalty} \widowpenalty \or % 4 \widowpenalties 5 \@M \@M \@M \value{typog@mean@penalty} \widowpenalty \or % 5 \widowpenalties 6 \@M \@M \@M \@M \value{typog@mean@penalty} \widowpenalty \or % 6 \widowpenalties 7 \@M \@M \@M \@M \@M \value{typog@mean@penalty} \widowpenalty \or % 7 \widowpenalties 8 \@M \@M \@M \@M \@M \@M \value{typog@mean@penalty} \widowpenalty \or % 8 \widowpenalties 9 \@M \@M \@M \@M \@M \@M \@M \value{typog@mean@penalty} \widowpenalty \else % >= 9 \widowpenalties 10 \@M \@M \@M \@M \@M \@M \@M \@M \value{typog@mean@penalty} \widowpenalty \fi} % \end{macrocode} % \end{macro} % % \begin{environment}{vtiebotpar} % \begin{macrocode} \NewDocumentEnvironment{vtiebotpar}{O{3}} {\vtiebot[#1]} {\par \ignorespacesafterend} % \end{macrocode} % \end{environment} % % \begin{macro}{\typog@vtiebotdisp} % \begin{macrocode} \NewDocumentCommand{\typog@vtiebotdisp}{m} {\setcounter{typog@mean@penalty} {\typog@geometric@mean{\@M}{\displaywidowpenalty}}% \typog@debug@typeout{vtiebotdisp: penalties \the\@M--\the\value{typog@mean@penalty}--\the\displaywidowpenalty}% \unless\ifnum\displaywidowpenalty<\@M \PackageWarning{typog}{vtiebotdisp: displaywidowpenalty=\the\displaywidowpenalty\space>= 10000}% \fi \ifcase#1% 0 \relax \or % 1 \relax \or % 2 \displaywidowpenalties 3 \@M \value{typog@mean@penalty} \displaywidowpenalty \or % 3 \displaywidowpenalties 4 \@M \@M \value{typog@mean@penalty} \displaywidowpenalty \or % 4 \displaywidowpenalties 5 \@M \@M \@M \value{typog@mean@penalty} \displaywidowpenalty \or % 5 \displaywidowpenalties 6 \@M \@M \@M \@M \value{typog@mean@penalty} \displaywidowpenalty \or % 6 \displaywidowpenalties 7 \@M \@M \@M \@M \@M \value{typog@mean@penalty} \displaywidowpenalty \or % 7 \displaywidowpenalties 8 \@M \@M \@M \@M \@M \@M \value{typog@mean@penalty} \displaywidowpenalty \or % 8 \displaywidowpenalties 9 \@M \@M \@M \@M \@M \@M \@M \value{typog@mean@penalty} \displaywidowpenalty \else % >= 9 \displaywidowpenalties 10 \@M \@M \@M \@M \@M \@M \@M \@M \value{typog@mean@penalty} \displaywidowpenalty \fi} % \end{macrocode} % \end{macro} % % \begin{environment}{vtiebotdisp} % \begin{macrocode} \NewDocumentEnvironment{vtiebotdisp}{O{3}} {\typog@vtiebotdisp{#1}} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % \begin{environment}{vtiebotdisptoppar} % \begin{macrocode} \NewDocumentEnvironment{vtiebotdisptoppar}{O{3}o} {\postdisplaypenalty=\@M \predisplaypenalty=10001% in accordance with package `widows-and-orphans' \edef\typog@@top@lines{\IfNoValueTF{#2}{#1}{#2}}% \edef\typog@@after@display@math{\vtietop[\typog@@top@lines]}% \PushPostHook{display}{\aftergroup\typog@@after@display@math}% \vtiebotdisp[#1]} {\par \PopPostHook{display}% \ignorespacesafterend} % \end{macrocode} % \end{environment} % % % \subsection[Breakable Disp.~Eqs.]{Breakable Displayed Equations} % % \begin{environment}{breakabledisplay} % We use a different default, 3, than \cs{allowdisplaybreaks} which utilizes~4 as its % default. % % \begin{macrocode} \newenvironment*{breakabledisplay}[1][3] {\allowdisplaybreaks[#1]} {\ignorespacesafterend} % \end{macrocode} % \end{environment} % % % \subsection{\packagename{Setspace} Front End} % % \begin{macro}{\typog@iter@limit} % The maximum number of iterations we perform before bailing out with an error. Can be % changed by the user if convergence is slow. % % \begin{macrocode} \newcommand*{\typog@setbaselineskip@iter@limit}{10} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@setbaselineskip@relative@error} % The maximum relative error of the ratio we tolerate for the final baselineskip over the % target baselineskip. Can also be changed by the user if necessary. % % \begin{macrocode} \newcommand*{\typog@setbaselineskip@relative@error}{.001} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@setbaselineskip} % Given the \meta{target-baselineskip} as argument iterate setting \cs{setstretch} until the % error drops below our threshold. % % \begin{macrocode} \ExplSyntaxOn \cs_new:Npn \typog@setbaselineskip #1 { % \end{macrocode} % % Initialize our ``emergency-stop'' loop counter. % % \begin{macrocode} \int_set:Nn \l_tmpa_int {1} \int_set:Nn \l_tmpb_int {\typog@setbaselineskip@iter@limit} % \end{macrocode} % % Note that the call to \cs{glueexpr} is required to consume dimensions that carry % stretchability via |plus| or |minus|. % % \begin{macrocode} \dim_set:Nn \l_tmpa_dim {\glueexpr #1} \typog@debug@typeout{\string\setbaselineskip:\space initial\space baselineskip:\space \the\baselineskip} \typog@debug@typeout{\string\setbaselineskip:\space target\space baselineskip:\space \dim_use:N \l_tmpa_dim} \dim_compare:nNnTF {\baselineskip} > {\c_zero_dim} {} { \PackageError{typog} {\string\setbaselineskip:\space baselineskip\space not\space positive} {} } \dim_compare:nNnTF {\l_tmpa_dim} > {\c_zero_dim} {} { \PackageError{typog} {\string\setbaselineskip:\space target\space baselineskip\space must\space be\space positive} {} } \skip_if_eq:nnTF {\l_tmpa_dim} {\glueexpr #1} {} { \PackageWarning{typog} {\string\setbaselineskip:\space argument\space is\space a\space skip;\space will\space ignore\space glue} {} } \fp_set:Nn \l_tmpa_fp {\l_tmpa_dim / \baselineskip} \fp_until_do:nNnn {abs(\l_tmpa_dim / \baselineskip - 1)} < {\typog@setbaselineskip@relative@error} { \setstretch{\fp_use:N \l_tmpa_fp} \fp_set:Nn \l_tmpa_fp {\l_tmpa_fp * \l_tmpa_dim / \baselineskip} \int_incr:N \l_tmpa_int \int_compare:nNnTF {\l_tmpa_int} > {\l_tmpb_int} { \PackageError{typog} {\string\setbaselineskip:\space excessive\space number\space of\space iterations:\space \int_use:N \l_tmpa_int\space >\space \int_use:N \l_tmpb_int} {} } {} } \typog@debug@typeout{\string\setbaselineskip:\space final\space \string\setstretch\space argument:\space \fp_use:N \l_tmpa_fp} \typog@debug@typeout{\string\setbaselineskip:\space final\space baselineskip:\space \the\baselineskip} } % \end{macrocode} % \end{macro} % % \begin{macro}{\setbaselineskip} % \changes{v0.3}{2024-04-04}{New macro.} % % Set the \cs{baselineskip} to an absolute length. % % \begin{implementationnote} % Viewed as a standalone macro \cs{setbaselineskip} does not need the decoration % \cs{After\-Preamble}. However, all of its siblings, \cs{set\-baseline\-skip\-percentage}, % \cs{set\-leading}, and \cs{set\-leading\-percentage} then would behave differently as they are % delayed to the end of the preamble, but \cs{set\-baseline\-skip} immediately becomes % effective. For example, the successive calls % % \begin{codeexample} % \cs{setbaselineskippercentage}\{140\} \\ % \cs{setbaselineskip}\{12.5pt\} % \end{codeexample} % % \noindent % in the preamble would set the baselineskip to 140\% in the document. Therefore, % \cs{setbaselineskip} is delayed too and the order of the calls thus preserved. % \end{implementationnote} % % \begin{macrocode} \cs_new:Npn \setbaselineskip #1 { \AfterPreamble{\typog@setbaselineskip{#1}} \ignorespaces } % \end{macrocode} % \end{macro} % % \begin{macro}{\resetbaselineskip} % \changes{v0.3}{2024-04-04}{New macro.} % % Set the \cs{baselineskip} to \singlequotes{neutral}. % % \begin{macrocode} \cs_new:Npn \resetbaselineskip { \AfterPreamble{\setstretch{1}} } % \end{macrocode} % \end{macro} % % \begin{ldimen}{\typogfontsize} % \changes{v0.3}{2024-04-04}{New dimen.} % Define the default font-size/quad size. % % \begin{macrocode} \dim_new:N \typogfontsize % \end{macrocode} % % Initialize \cs{typogfontsize} at the end of the preamble, which is after all fonts have % been setup. % % \begin{macrocode} \AfterEndPreamble{ \dim_set:Nn \typogfontsize {\fontdimen6\font} \typog@debug@typeout{\string\typogfontsize = \dim_use:N \typogfontsize\space (at\space begin\space of\space document)} } % \end{macrocode} % \end{ldimen} % % \begin{macro}{\setbaselineskippercentage} % \changes{v0.3}{2024-04-04}{New macro.} % \begin{macrocode} \cs_new:Npn \setbaselineskippercentage #1 { \AfterPreamble{ \dim_compare:nNnTF {\typogfontsize} > {\c_zero_dim} { \typog@setbaselineskip{ \fp_eval:n {(#1) / 100} \typogfontsize} } { \PackageError{typog} {\string\setbaselineskippercentage:\space \string\typogfontsize <= 0} {Maybe\space \string\typogfontsize\space is\space uninitialized?} } } \ignorespaces } % \end{macrocode} % \end{macro} % % \begin{macro}{\setleading} % \changes{v0.3}{2024-04-04}{New macro.} % \begin{macrocode} \cs_new:Npn \setleading #1 { \AfterPreamble{ \dim_compare:nNnTF {\typogfontsize} > {\c_zero_dim} { \typog@setbaselineskip{\typogfontsize + \dimexpr #1} } { \PackageError{typog} {\string\setleading:\space \string\typogfontsize <= 0} {Maybe\space \string\typogfontsize\space is\space uninitialized?} } } \ignorespaces } % \end{macrocode} % \end{macro} % % \begin{macro}{\setleadingpercentage} % \changes{v0.3}{2024-04-04}{New macro.} % \begin{macrocode} \cs_new:Npn \setleadingpercentage #1 { \AfterPreamble{ \dim_compare:nNnTF {\typogfontsize} > {\c_zero_dim} { \typog@setbaselineskip{ \fp_eval:n {1 + (#1) / 100} \typogfontsize} } { \PackageError{typog} {\string\setleadingpercentage:\space \string\typogfontsize <= 0} {Maybe\space \string\typogfontsize\space is\space uninitialized?} } } \ignorespaces } \ExplSyntaxOff % \end{macrocode} % \end{macro} % % % \subsection{Smooth Ragged} % % \begin{macro}{\typog@repeat} % As we shall have to repeat the line specifications for our paragraphs so often we introduce % the two argument macro~\cs{typog@repeat} that takes a \meta{repeat-count} and a \meta{body} % that is repeated. % % \begin{macrocode} \ExplSyntaxOn \cs_new_eq:NN \typog@repeat \prg_replicate:nn % \end{macrocode} % \end{macro} % % % \begin{macro}{\typog@mod} % For error checking we shall need the modulo operation on integers, i.\,e., the remainder of % an integral division. % % \begin{macrocode} \newcommand*{\typog@mod}[2]{\int_mod:nn{#1}{#2}} \ExplSyntaxOff % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@triplet@max@lines} % Maximum number of lines a smoothraggedright paragraph can have with the triplet generator. % The number must be divisible by~3. % % \begin{macrocode} \newcommand*{\typog@triplet@max@lines}{99} % \end{macrocode} % \end{macro} % % \begin{environment}{smoothraggedrightshapetriplet} % Engine for 3-line repetitions. % % \begin{macrocode} \define@key[typog]{smoothraggedrightshapetriplet}{leftskip}% {\def\typog@@triplet@leftskip{#1}} \define@key[typog]{smoothraggedrightshapetriplet}{parindent}% {\def\typog@@triplet@parindent{#1}} \NewDocumentEnvironment{smoothraggedrightshapetriplet}{O{} m m m} {\def\typog@@triplet@leftskip{\z@}% \def\typog@@triplet@parindent{\z@}% \setkeys*[typog]{smoothraggedrightshapetriplet}{#1}% \skip0=\typog@@triplet@leftskip\relax \skip1=#2\relax \skip2=#3\relax \skip3=#4\relax \typog@debug@typeout{smoothraggedrightshapetriplet: skip0=\the\skip0}% \typog@debug@typeout{smoothraggedrightshapetriplet: skip1=\the\skip1}% \typog@debug@typeout{smoothraggedrightshapetriplet: skip2=\the\skip2}% \typog@debug@typeout{smoothraggedrightshapetriplet: skip3=\the\skip3}% \unless\ifnum\typog@mod{\typog@triplet@max@lines}{3}=0 \PackageError{typog} {Line number of triplet generator\space (\typog@triplet@max@lines) not divisible by 3} {} \fi \edef\typog@@triplet@linespecs{% \glueexpr \skip0 + \typog@@triplet@parindent\relax \glueexpr \skip1 - \typog@@triplet@parindent\relax \skip0 \skip2 \skip0 \skip3 \typog@repeat{\numexpr\typog@triplet@max@lines / 3 - 1} {\skip0 \skip1 \skip0 \skip2 \skip0 \skip3}} \parshape=\typog@triplet@max@lines\typog@@triplet@linespecs\relax} {\par} % \end{macrocode} % \end{environment} % % % \begin{macro}{\typog@quintuplet@max@lines} % Maximum number of lines a smoothraggedright paragraph can have with the quintuplet % generator. The number must be divisible by~5. % % \begin{macrocode} \newcommand*{\typog@quintuplet@max@lines}{95} % \end{macrocode} % \end{macro} % % \begin{environment}{smoothraggedrightshapequintuplet} % Engine for 5-line repetitions. % % \begin{macrocode} \define@key[typog]{smoothraggedrightshapequintuplet}{leftskip} {\def\typog@@quintuplet@leftskip{#1}} \define@key[typog]{smoothraggedrightshapequintuplet}{parindent} {\def\typog@@quintuplet@parindent{#1}} \NewDocumentEnvironment{smoothraggedrightshapequintuplet}{O{} m m m m m} {\def\typog@@quintuplet@leftskip{\z@}% \def\typog@@quintuplet@parindent{\z@}% \setkeys*[typog]{smoothraggedrightshapequintuplet}{#1}% \skip0=\typog@@quintuplet@leftskip\relax \skip1=#2\relax \skip2=#3\relax \skip3=#4\relax \skip4=#5\relax \skip5=#6\relax \typog@debug@typeout{smoothraggedrightshapequintuplet: skip0=\the\skip0}% \typog@debug@typeout{smoothraggedrightshapequintuplet: skip1=\the\skip1}% \typog@debug@typeout{smoothraggedrightshapequintuplet: skip2=\the\skip2}% \typog@debug@typeout{smoothraggedrightshapequintuplet: skip3=\the\skip3}% \typog@debug@typeout{smoothraggedrightshapequintuplet: skip4=\the\skip4}% \typog@debug@typeout{smoothraggedrightshapequintuplet: skip5=\the\skip5}% \unless\ifnum\typog@mod{\typog@quintuplet@max@lines}{5}=0 \PackageError{typog} {Line number of quintuplet generator\space (\typog@quintuplet@max@lines) not divisible by 5} {} \fi \edef\typog@@quintuplet@linespecs{% \glueexpr \skip0 + \typog@@quintuplet@parindent\relax \glueexpr \skip1 - \typog@@quintuplet@parindent\relax \skip0 \skip2 \skip0 \skip3 \skip0 \skip4 \skip0 \skip5 \typog@repeat{\numexpr\typog@quintuplet@max@lines / 5 - 1} {\skip0 \skip1 \skip0 \skip2 \skip0 \skip3 \skip0 \skip4 \skip0 \skip5}} \parshape=\typog@quintuplet@max@lines\typog@@quintuplet@linespecs\relax} {\par} % \end{macrocode} % \end{environment} % % % \begin{macro}{\typog@septuplet@max@lines} % Maximum number of lines a smoothraggedright paragraph can have with the septuplet % generator. The number must be divisible by~7. % % \begin{macrocode} \newcommand*{\typog@septuplet@max@lines}{98} % \end{macrocode} % \end{macro} % % \begin{environment}{smoothraggedrightshapeseptuplet} % \changes{v0.4a}{2024-08-11} % {Add missing backslash to \cs{typog@@\-septuplet@\-parindent} in local % macro~\cs{typog@@\-septuplet@\-linespecs} which rendered % the septuplet~generator unusable.} % Engine for 7-line repetitions. % % \begin{macrocode} \define@key[typog]{smoothraggedrightshapeseptuplet}{leftskip}% {\def\typog@@septuplet@leftskip{#1}} \define@key[typog]{smoothraggedrightshapeseptuplet}{parindent}% {\def\typog@@septuplet@parindent{#1}} \NewDocumentEnvironment{smoothraggedrightshapeseptuplet}{O{} m m m m m m m} {\def\typog@@septuplet@leftskip{\z@}% \def\typog@@septuplet@parindent{\z@}% \setkeys*[typog]{smoothraggedrightshapeseptuplet}{#1}% \skip0=\typog@@septuplet@leftskip\relax \skip1=#2\relax \skip2=#3\relax \skip3=#4\relax \skip4=#5\relax \skip5=#6\relax \skip6=#7\relax \skip7=#8\relax \typog@debug@typeout{smoothraggedrightshapeseptuplet: skip0=\the\skip0}% \typog@debug@typeout{smoothraggedrightshapeseptuplet: skip1=\the\skip1}% \typog@debug@typeout{smoothraggedrightshapeseptuplet: skip2=\the\skip2}% \typog@debug@typeout{smoothraggedrightshapeseptuplet: skip3=\the\skip3}% \typog@debug@typeout{smoothraggedrightshapeseptuplet: skip4=\the\skip4}% \typog@debug@typeout{smoothraggedrightshapeseptuplet: skip5=\the\skip5}% \typog@debug@typeout{smoothraggedrightshapeseptuplet: skip6=\the\skip6}% \typog@debug@typeout{smoothraggedrightshapeseptuplet: skip7=\the\skip7}% \unless\ifnum\typog@mod{\typog@septuplet@max@lines}{7}=0 \PackageError{typog} {Line number of septuplet generator\space (\typog@septuplet@max@lines) not divisible by 7} {} \fi \edef\typog@@septuplet@linespecs{% \glueexpr \skip0 + \typog@@septuplet@parindent\relax \glueexpr \skip1 - \typog@@septuplet@parindent\relax \skip0 \skip2 \skip0 \skip3 \skip0 \skip4 \skip0 \skip5 \skip0 \skip6 \skip0 \skip7 \typog@repeat{\numexpr\typog@septuplet@max@lines / 7 - 1} {\skip0 \skip1 \skip0 \skip2 \skip0 \skip3 \skip0 \skip4 \skip0 \skip5 \skip0 \skip6 \skip0 \skip7}} \parshape=\typog@septuplet@max@lines\typog@@septuplet@linespecs\relax} {\par} % \end{macrocode} % \end{environment} % % \begin{macro}{\smoothraggedrightfuzzfactor} % \begin{macrocode} \newcommand*{\smoothraggedrightfuzzfactor}{1.0} % \end{macrocode} % \end{macro} % % \begin{macro}{\smoothraggedrightgenerator} % \begin{macrocode} \newcommand*{\smoothraggedrightgenerator}{triplet} % \end{macrocode} % \end{macro} % % \begin{lskip}{\smoothraggedrightleftskip} % \begin{macrocode} \newlength{\smoothraggedrightleftskip} % \end{macrocode} % \end{lskip} % % \begin{lskip}{\smoothraggedrightparindent} % \begin{macrocode} \newlength{\smoothraggedrightparindent} % \end{macrocode} % \end{lskip} % % \begin{lskip}{\smoothraggedrightragwidth} % \begin{macrocode} \newlength{\smoothraggedrightragwidth} \setlength{\smoothraggedrightragwidth}{2em} % \end{macrocode} % \end{lskip} % % \begin{ldimen}{\typog@fuzzwidth} % \begin{macrocode} \newdimen{\typog@fuzzwidth} % \end{macrocode} % \end{ldimen} % % \begin{environment}{smoothraggedrightpar} % The longest line will be \cs{linewidth} wide % unless overridden by optional argument~|linewidth|. % % \begin{macrocode} \define@key[typog]{smoothraggedrightpar}{linewidth}% {\def\typog@@linewidth{#1}} % \end{macrocode} % Convert generator name to an integer suitable for \cs{ifcase}. % Indicate an unknown name with -1. % \begin{macrocode} \ExplSyntaxOn \cs_new:Npn \typog@generator@index:n #1 { \str_case:nnTF {#1} { {triplet} {0} {quintuplet} {1} {septuplet} {2} } {} {-1} } \cs_generate_variant:Nn \typog@generator@index:n {e} \let\typog@generator@index=\typog@generator@index:e \ExplSyntaxOff \NewDocumentEnvironment{smoothraggedrightpar}{O{}} {\edef\typog@@linewidth{\linewidth}% \setkeys[typog]{smoothraggedrightpar}{#1}% \edef\typog@@generatorchoice{\typog@generator@index{\smoothraggedrightgenerator}}% % \end{macrocode} % Obey to the indentation prescribed by any list environment. % \begin{macrocode} \let\typog@@smoothraggedrightleftskip=\smoothraggedrightleftskip \ifnum\@listdepth>0 \addtolength{\typog@@smoothraggedrightleftskip}{\leftmargin}% \fi % \end{macrocode} % Scale the fuzz-width by the user's factor. % Later we shall rescale again specifically for each generator. % \begin{macrocode} \typog@fuzzwidth=\smoothraggedrightfuzzfactor\smoothraggedrightragwidth % \end{macrocode} % % Now for the generator-specific code \dots % \begin{macrocode} \ifcase\typog@@generatorchoice % \end{macrocode} % % |generator=triplet| produces a \doublequotes{short line -- long line -- middle length line}~sequence. % \begin{macrocode} \typog@fuzzwidth=.25\smoothraggedrightragwidth \typog@debug@typeout{smoothraggedright: generator=triplet, typog@fuzzwidth=\the\typog@fuzzwidth}% \smoothraggedrightshapetriplet[leftskip=\typog@@smoothraggedrightleftskip, parindent=\glueexpr\smoothraggedrightparindent + \parindent, #1]% {\glueexpr \typog@@linewidth - \smoothraggedrightragwidth + \glueexpr \z@ \@plus \typog@fuzzwidth\relax}% (1) {\glueexpr \typog@@linewidth \@minus \typog@fuzzwidth}% (3) {\glueexpr (\typog@@linewidth * 2 - \smoothraggedrightragwidth) / 2 + \glueexpr \z@ \@plus \typog@fuzzwidth \@minus \typog@fuzzwidth\relax}% (2) \or % \end{macrocode} % % |generator=quintuplet|. % \begin{macrocode} \typog@fuzzwidth=.125\smoothraggedrightragwidth \typog@debug@typeout{smoothraggedright: generator=quintuplet, typog@fuzzwidth=\the\typog@fuzzwidth}% \smoothraggedrightshapequintuplet[leftskip=\typog@@smoothraggedrightleftskip, parindent=\glueexpr\smoothraggedrightparindent + \parindent, #1]% {\glueexpr (\typog@@linewidth * 4 - \smoothraggedrightragwidth * 3) / 4 + \glueexpr \z@ \@plus \typog@fuzzwidth \@minus \typog@fuzzwidth\relax}% (2) {\glueexpr \typog@@linewidth \@minus \typog@fuzzwidth\relax}% (5) {\glueexpr (\typog@@linewidth * 2 - \smoothraggedrightragwidth) / 2 + \glueexpr \z@ \@plus \typog@fuzzwidth \@minus \typog@fuzzwidth\relax}% (3) {\glueexpr (\typog@@linewidth * 4 - \smoothraggedrightragwidth) / 4 + \glueexpr \z@ \@plus \typog@fuzzwidth \@minus \typog@fuzzwidth\relax}% (4) {\glueexpr \typog@@linewidth - \smoothraggedrightragwidth + \glueexpr \z@ \@plus \typog@fuzzwidth\relax}% (1) \or % \end{macrocode} % % |generator=septuplet|. % % Permutation \mbox{3 -- 6 -- 1 -- 5 -- 2 -- 7 -- 4} % looks \singlequotes{random} enough for our purposes. % % \begin{macrocode} \typog@fuzzwidth=.08333\smoothraggedrightragwidth \typog@debug@typeout{smoothraggedright: generator=septuplet, typog@fuzzwidth=\the\typog@fuzzwidth}% \smoothraggedrightshapeseptuplet[leftskip=\typog@@smoothraggedrightleftskip, parindent=\glueexpr\smoothraggedrightparindent + \parindent, #1]% {\glueexpr (\typog@@linewidth * 3 - \smoothraggedrightragwidth * 2) / 3 + \glueexpr \z@ \@plus \typog@fuzzwidth \@minus \typog@fuzzwidth\relax}% (3) {\glueexpr (\typog@@linewidth * 6 - \smoothraggedrightragwidth) / 6 + \glueexpr \z@ \@plus \typog@fuzzwidth \@minus \typog@fuzzwidth\relax}% (6) {\glueexpr \typog@@linewidth - \smoothraggedrightragwidth + + \glueexpr \z@ \@plus \typog@fuzzwidth\relax}% (1) {\glueexpr (\typog@@linewidth * 3 - \smoothraggedrightragwidth) / 3 + \glueexpr \z@ \@plus \typog@fuzzwidth \@minus \typog@fuzzwidth\relax}% (5) {\glueexpr (\typog@@linewidth * 6 - \smoothraggedrightragwidth * 5) / 6 + \glueexpr \z@ \@plus \typog@fuzzwidth \@minus \typog@fuzzwidth\relax}% (2) {\glueexpr \typog@@linewidth \@minus \typog@fuzzwidth\relax}% (7) {\glueexpr (\typog@@linewidth * 2 - \smoothraggedrightragwidth) / 2 + \glueexpr \z@ \@plus \typog@fuzzwidth \@minus \typog@fuzzwidth\relax}% (4) \else \PackageError{typog} {smoothraggedright: unknown generator name (\smoothraggedrightgenerator)} {valid generator names are triplet, quintuplet, and septuplet} \fi} {\ifcase\typog@@generatorchoice \endsmoothraggedrightshapetriplet \or \endsmoothraggedrightshapequintuplet \or \endsmoothraggedrightshapeseptuplet \fi} % \end{macrocode} % \end{environment} % % \begin{environment}{smoothraggedright} % \begin{macrocode} \NewDocumentEnvironment{smoothraggedright}{O{}} {\PushPostHook{par}{\hskip-\parindent\smoothraggedrightpar[#1]\relax}} {\par\PopPostHook{par}} % \end{macrocode} % \end{environment} % \index{package code|)userman} % \index{code reference|)userman} % % % \iffalse % % \fi % % % \addtocontents{toc}{\protect\end{multicols}} % \addtocontents{toc}{\protect\end{list}} % % % \Finale % % % % \iffalse %<*example> \documentclass[a4paper]{article} \tracingonline=0 \PassOptionsToPackage{dvipsnames}{xcolor} \usepackage{amsmath} \makeatletter\def\bbl@languages{}\makeatother\usepackage[german,english]{babel} \usepackage{float} \usepackage[T1]{fontenc} \usepackage{hyphenat} \usepackage{mathtools} \usepackage[activate=true, letterspace=50, verbose=false]{microtype} \usepackage{ragged2e} \usepackage[nobottomtitles*]{titlesec}\renewcommand*{\bottomtitlespace}{.2\textheight} \usepackage{trace} \usepackage[debug, trackingttspacing, uppercaselabelitemadjustments={-0.025em, .075em, .14em, .075em}, lowercaselabelitemadjustments={-.1em, 0pt, .065em, 0pt}]{typog} \usepackage{xcolor} \usepackage[loosest, proportional, scaled=1.064]{erewhon} \usepackage[erewhon]{newtxmath} \usepackage[scaled=.95]{cabin} \usepackage{inconsolata} \usepackage{setspace}\setstretch{1.08333} \def\xsfdefault{\relax} \def\examplefont{6} \ifcase\examplefont % 0 -- document's default sans-serif font (e.g., ecrm1000) \def\examplefontname{default} \let\xsf=\sf \let\xsfdefault=\sfdefault \or % 1 -- Nunito \def\examplefontname{Nunito} \def\xsfdefault{Nunito-TOsF} \def\xsf{\let\sfdefault=\xsfdefault\sf} \or % 2 -- OpenSans \def\examplefontname{OpenSans} \def\xsfdefault{opensans-TLF} \def\xsf{\let\sfdefault=\xsfdefault\sf} \or % 3 -- Noto Sans \def\examplefontname{Noto Sans} \def\xsfdefault{NotoSans-TLF} \def\xsf{\let\sfdefault=\xsfdefault\sf} \or % 4 -- Roboto \def\examplefontname{Roboto} \def\xsfdefault{Roboto-LF} \def\xsf{\let\sfdefault=\xsfdefault\sf} \or % 5 -- Montserrat \def\examplefontname{Montserrat Alternates} \def\xsfdefault{MontserratAlternates-LF} \def\xsf{\let\sfdefault=\xsfdefault\sf} \or % 6 -- Inter \def\examplefontname{Inter} \def\xsfdefault{Inter-LF} \def\xsf{\let\sfdefault=\xsfdefault\sf} \else \SelectedUnknownExampleFont \fi \typeout{typog-example: font for examples: `\xsfdefault'}% \usepackage{hyperref} \usepackage{cleveref} \hypersetup{ citecolor = CadetBlue, colorlinks = true, linkcolor = Blue, linktocpage = true, pdfauthor={Dr. Christoph L. Spiel}, pdfkeywords={Examples, LaTeX, typography, ligature, italic-correction, paragraph justification, sloppy, ragged}, pdfsubject={Examples for typographic fine-tuning of LaTeX}, pdftitle={Examples for LaTeX package typog}, raiselinks = false, urlcolor = Mulberry } \makeatletter \newcommand{\fs@myruled}{% \fs@ruled \def\@fs@capt##1##2{\floatc@ruled{##1\space\capitaldash*\space}{\fussy ##2}}% \def\@fs@pre{\hrule height.8pt depth0pt \kern4pt}% \def\@fs@mid{\kern3pt\hrule\kern3pt}% \def\@fs@post{\kern4pt\hrule\relax}% } \makeatother \floatstyle{myruled} \newfloat{exemplary}{htbp}{loe}[section] \floatname{exemplary}{Example} \Crefname{exemplary}{Example}{Examples} \crefname{exemplary}{Ex.}{Ex.} \newcommand*{\acronym}[1]{\mbox{\letterspacecapitals{\MakeUppercase{#1}}}} \newcommand*{\bibauthor}[1]{\textsc{#1}} \newcommand*{\bibtitle}[1]{\textit{#1}} \newcommand*{\bottomstrut}{\rule[-.5em]{0pt}{0pt}} \newcommand*{\code}[1]{{\ttfamily\hyphenchar\font=`\-\relax #1}} \newcommand*{\doublequotes}[1]{\doubleguillemetright#1\doubleguillemetleft} \newcommand*{\eTeX}{\mbox{\(\epsilon\)-\TeX}} \newcommand*{\letterspacecapitals}[1]{\textls[30]{#1}} \newcommand*{\metavar}[1]{\textit{#1}} \newcommand*{\packagename}[1]{\mbox{\textsf{#1}}} \newcommand*{\propername}[1]{\mbox{\textsc{\textls[25]{#1}}}} \newcommand*{\sample}[1]{\mbox{`\texttt{#1}'}} \newcommand*{\singlequotes}[1]{\singleguillemetright#1\singleguillemetleft} \newcommand*{\topstrut}{\rule{0pt}{1.25em}} \newcommand*{\visualpar}{\,\P\quad} \newlength{\emreference} \AtBeginDocument{\setlength{\emreference}{\fontdimen6\font}} \newrobustcmd*{\milliem}[1] {\ifdim #1=0pt #1% \else \generictextfraction{\the\numexpr\dimexpr (#1) * 1000 / \emreference}{1000}\:em% \fi} \makeatletter \newcommand*{\getpackagefullinfo}[1]{\csname ver@#1.sty\endcsname} \def\@synthslant@getpackagedate#1/#2/#3 v#4\@nil{#1/#2/#3} \newcommand*{\getpackagedate}[1] {\edef\@tempa{\getpackagefullinfo{#1}}% \expandafter\@synthslant@getpackagedate\@tempa\@nil} \def\@synthslant@getpackageversion#1/#2/#3 v#4 #5\@nil{#4} \newcommand*{\getpackageversion}[1] {\edef\@tempa{\getpackagefullinfo{#1}}% \expandafter\@synthslant@getpackageversion\@tempa\@nil} \def\@synthslant@getpackageinfo#1/#2/#3 v#4 #5\@nil{#5} \newcommand*{\getpackageinfo}[1] {\edef\@tempa{\getpackagefullinfo{#1}}% \expandafter\@synthslant@getpackageinfo\@tempa\@nil} \makeatother \newcommand*{\generictextfraction}[2] {\raisebox{.4em}[0pt]{\scriptsize #1}% \kern-.05em\textfractionsolidus\kern-.05em \raisebox{-.15em}[0pt][0pt]{\scriptsize #2}} \newcommand*{\leftmarker}{\rule{.2em}{.1pt}\rule{.1pt}{.667em}} \newcommand*{\rightmarker}{\rule{.1pt}{.667em}\rule{.2em}{.1pt}} \newcommand*{\indicatewidth}[1]{\mbox{\leftmarker #1\rightmarker}} \newenvironment*{widebody} {\begin{list}{}{\leftmargin=0pt \listparindent=\parindent \parsep=\parskip \rightmargin=-\marginparwidth \topsep=0pt} \item\relax} {\end{list}} \newlength{\examplewidth} \setlength{\examplewidth}{160pt} \newcommand*{\texbooktolerancesample} {If you want to avoid overfull boxes at all costs without trying to fix them manually, you might be tempt\-ed to set \texttt{tol\-er\-ance=\allowbreak10000}; this allows arbitrarily bad lines to be acceptable in tough situations. But infinite tolerance is a bad idea, because \TeX{} doesn't distinguish between terribly bad and preposterously horrible lines. Indeed, a tolerance of 10000 encourages \TeX{} to concentrate all the badness in one place, making one truly unsightly line instead of two moderately bad ones, because a single ``write-off'' produces fewest total demerits according to the rules.} \newcommand*{\texbooktolerancesamplecredits} {\medskip\noindent \textsl{The sample text was taken from The~\TeX{}book~\cite[p.~107]{knuth:1986}.}} \newcommand*{\texbookparfillskipsample} {We still haven't discussed the special trick that allows the final line of a paragraph to be shorter than the others. Just before \TeX{} begins to choose breakpoints, it does two important things: [\dots\itcorr{-4}]} \newcommand*{\texbooklongparfillskipsample} {We still haven't discussed the special trick that allows the final line of a paragraph to be shorter than the others. Just before \TeX{} begins to choose breakpoints, it does two important things: (1)~If the final item of the current horizontal list is glue, that glue is discarded. (The reason is that a blank space often gets into a token list just before \code{\char92par} or just before \code{\char36\char36}, and this blank space should not be part of the paragraph.) (2)~Three or more items are put at the end of the current horizontal list~[\dots\itcorr{-4}]} \newcommand*{\texbookparfillskipsamplecredits} {\medskip\noindent \textsl{The sample text was taken from The~\TeX{}book~\cite[p.~99n]{knuth:1986}.}} \newcommand*{\texbookparshapeskipsample} {It's possible to control the length of lines in a much more general way, if simple changes to \code{\string\leftskip} and \code{\string\rightskip} aren't flexible enough for your purposes. For example, a semicircular hole has been cut out of the present paragraph, in order to make room for a circular illustration that contains some of Galileo's immortal words about circles; all of the line breaks in this paragraph and in the circular quotation were found by \TeX's line-breaking algorithm. You can specify a essentially arbitrary paragraph shape, by saying \code{parshape}=\metavar{number}, where the \metavar{number} is a positive integer~\(n\), followed by \(2n\)~\metavar{dimen} specifications.} \newcommand*{\texbookparshapeskipsamplecredits} {\medskip\noindent \textsl{The sample text was taken from The~\TeX{}book~\cite[p.~101]{knuth:1986}.}} \newcommand*{\texbookbaselineskipsample} {When you are typsetting a document that spans several pages, it's generally best to define \code{\string\baselineskip} so that it cannot stretch or shrink, because this will give more uniformity to the pages. A small variation in the distance between the baselines---say only half a point---can make a substantial difference in the appearance of the type, since it significantly affects the proportion of white to black. On the other hand, if you are preparing a one-page document, you might want to give the baselineskip some stretchability, so that \TeX{} will help you fit the copy on the page.} \newcommand*{\texbookbaselineskipsamplecredits} {\medskip\noindent \textsl{The sample text was taken from The~\TeX{}book~\cite[p.~78]{knuth:1986}.}} \newcommand*{\examplepreset}{\microtypesetup{activate=false}} \newcommand*{\examplesetup}{\frenchspacing\xsf\small\fussy} \newcommand*{\exampleparbox}[2][n/a] {\begin{typoginspect}{#1} \examplepreset \parbox[t]{\examplewidth}{\examplesetup #2}% \end{typoginspect}} \newcommand*{\examplesep}{\hspace*{20pt}} \def\fontnameandweightinfo#1{% {\def\projectoutfontname##1-##2-##3\relax{##1~\lowercase{##2}}% \global\expandafter\edef\csname#1\endcsname{\expandafter\projectoutfontname\fontname\font\relax}}} \newcommand*{\examplefontinformation} {\smallskip \examplesetup \fontnameandweightinfo{exfontnameinfo}% \fontsizeinfo{exfontsizeinfo}% The font used in this example is \exfontnameinfo, \exfontsizeinfo*.} \setcounter{tocdepth}{1} \setlength{\overfullrule}{0pt} \hbadness=-1 \input{ushyphex} \hyphenation{ Double-guillemet-left Double-guillemet-right Double-quotes Single-guillemet-left Single-guillemet-right Single-quotes adj-demerits allow-display-breaks babel-hyphenation base-line-skip break-penalty breakable-display capital-hyphen capital-times cite-dash club-penalties cref-range-conjunction display-break display-widow-penalties double-guillemet-right double-hyphen-demerits double-quotes final-hyphen-demerits inter-display-line-penalty inter-text kerned-hyphen last-line-ragged-left last-line-ragged-left-par loose-ness loose-spacing make-at-letter make-at-other mar-gin-al math-italic-correction micro-type number-dash par-box par-indent parfillskip pdf-string-def-Disable-Commands post-display-penalty pre-display-penalty raise-capital-guillemets raise-capital-times raise-number-dash set-font-expand set-font-shrink set-font-stretch short-inter-text single-guillemet-left single-guillemet-right single-quotes slash-kern slightly-sloppy-par sloppy-par smooth-ragged-right-fuzz-factor smooth-ragged-right-par smooth-ragged-right-shape-quintuplet smooth-ragged-right-shape-septuplet smooth-ragged-right-shape-triplet space-skip text-italic-correction tight-spacing tracing-boxes tracing-para-graphs vtie-bot vtie-bot-disp vtie-bot-disp-par vtie-bot-disp-top-par vtie-bot-par vtie-top vtie-top-par widow-penalties } \SetExpansion[context=sloppy, stretch=30, shrink=60, step=5]{encoding={OT1, T1, TS1}}{}% p15 \SetTracking{encoding=*, shape=sc}{20} \newcount\defaultlastlinefit \defaultlastlinefit=\lastlinefit \begin{document} \fussy \lastlinefit=1000% \nonfrenchspacing \begin{center} \sf {\Huge\bfseries TypoG Examples} \medskip for \packagename{typog} version~\getpackageversion{typog} as of \getpackagedate{typog} \end{center} \bigskip \noindent The section numbers correspond to the subsections of section~3 in the official documentation of package~\packagename{typog}. \bigskip \tableofcontents \clearpage \listof{exemplary}{Examples} \clearpage \noindent Unless otherwise noted the font used in the examples is \singlequotes{\examplefontname}. \section{Setup and Reconfiguration} \noindent \code{\char`\\ typogget} \begin{list}{}{\itemsep=0pt\parsep=0pt} \newcommand*{\expandsto}{$\mathbin{\mapsto}$} \item \code{breakpenalty} \expandsto{} \the\typogget{breakpenalty} \item \code{emdashspace} \expandsto{} \the\typogget{emdashspace} \item \code{endashspace} \expandsto{} \the\typogget{endashspace} \item \code{ligaturekern} \expandsto{} \milliem{\typogget{ligaturekern}} \item \code{lowercaselabelitemadjustments} \expandsto{} \typogget{lowercaselabelitemadjustments} \item \code{lowerslash} \expandsto{} \the\typogget{lowerslash} \item \code{mathitaliccorrection} \expandsto{} \the\typogget{mathitaliccorrection} \item \code{raisecapitaldash} \expandsto{} \the\typogget{raisecapitaldash} \item \code{raisecapitalguillemets} \expandsto{} \the\typogget{raisecapitalguillemets} \item \code{raisecapitalhyphen} \expandsto{} \the\typogget{raisecapitalhyphen} \item \code{raisecapitaltimes} \expandsto{} \the\typogget{raisecapitaltimes} \item \code{raisefiguredash} \expandsto{} \the\typogget{raisefiguredash} \item \code{raiseguillemets} \expandsto{} \the\typogget{raiseguillemets} \item \code{raiseinvertedmarks} \expandsto{} \typogget{raiseinvertedmarks} \item \code{shrinklimits} \expandsto{} \typogget{shrinklimits} \item \code{slashkern} \expandsto{} \the\typogget{slashkern} \item \code{stretchlimits} \expandsto{} \typogget{stretchlimits} \item \code{textitaliccorrection} \expandsto{} \the\typogget{textitaliccorrection} \item \code{trackingttspacing} \expandsto{} \typogget{trackingttspacing} \item \code{uppercaselabelitemadjustments} \expandsto{} \typogget{uppercaselabelitemadjustments} \end{list} \begingroup \dimen0=\typogget{raisecapitaldash}% \setbox0=\hbox to \typogget{ligaturekern} {}% \endgroup \noindent \code{\char`\\ typoggetnth} \begin{list}{}{\parsep=0pt} \item \code{lowercaselabelitemadjustments}: (1)~\typoggetnth{\dimen0}{lowercaselabelitemadjustments}{1}\the\dimen0, (2)~\typoggetnth{\dimen0}{lowercaselabelitemadjustments}{2}\the\dimen0, (3)~\typoggetnth{\dimen0}{lowercaselabelitemadjustments}{3}\the\dimen0, and (4)~\typoggetnth{\dimen0}{lowercaselabelitemadjustments}{4}\the\dimen0. Same elements now accessed from the right-hand-side, i.\,e.~with negative indices: (\textminus4)~\typoggetnth{nth}{lowercaselabelitemadjustments}{-4}\nth, (\textminus3)~\typoggetnth{nth}{lowercaselabelitemadjustments}{-3}\nth, (\textminus2)~\typoggetnth{nth}{lowercaselabelitemadjustments}{-2}\nth, and (\textminus1)~\typoggetnth{nth}{lowercaselabelitemadjustments}{-1}\nth. \item \code{raiseinvertedmarks}: (1)~\typoggetnth{nth}{raiseinvertedmarks}{1}\nth, (2)~\typoggetnth{nth}{raiseinvertedmarks}{2}\nth, and (3)~\typoggetnth{nth}{raiseinvertedmarks}{3}\nth. \item \code{shrinklimits}: (1)~\typoggetnth{nth}{shrinklimits}{1}\nth, (2)~\typoggetnth{nth}{shrinklimits}{2}\nth, and (3)~\typoggetnth{nth}{shrinklimits}{3}\nth. \item \code{stretchlimits}: (1)~\typoggetnth{nth}{stretchlimits}{1}\nth, (2)~\typoggetnth{nth}{stretchlimits}{2}\nth, and (3)~\typoggetnth{nth}{stretchlimits}{3}\nth. \item \code{trackingttspacing}: (1)~\typoggetnth{nth}{trackingttspacing}{1}\nth, (2)~\typoggetnth{nth}{trackingttspacing}{2}\nth, and (3)~\typoggetnth{nth}{trackingttspacing}{3}\nth. \item \code{uppercaselabelitemadjustments}: (1)~\typoggetnth{\dimen0}{uppercaselabelitemadjustments}{1}\the\dimen0, (2)~\typoggetnth{\dimen0}{uppercaselabelitemadjustments}{2}\the\dimen0, (3)~\typoggetnth{\dimen0}{uppercaselabelitemadjustments}{3}\the\dimen0, and (4)~\typoggetnth{\dimen0}{uppercaselabelitemadjustments}{4}\the\dimen0. \end{list} \section{Information} \code{\string\fontsizeinfo} --\fontsizeinfo{docsizeinfo} At this point of the document, the font~size and the line~spacing are \docsizeinfo*~(w/o~units). For footnotes however, the current sizes are% \footnote{This is the footnote where we get the sizes from.\fontsizeinfo{footsizeinfo}} \footsizeinfo. Next we show a comparison of different font sizes and line spacings decorated with the results of \code{\string\fontsizeinfo}. \medskip \begin{widebody} \setstretch{1} \newcommand*{\baselineskipdoc}% {Macro \code{\string\baselineskip} is a length macro which specifies the minimum space between the bottom of two successive lines in a paragraph. Its value may be automatically reset by \LaTeX, for example, by font changes in the text.} \renewcommand*{\examplefontname}{Merriweather} Different font sizes and line spacings exemplified with the \examplefontname~font. \smallskip \begingroup \fontfamily{Merriwthr-TLF}\selectfont \noindent \parbox[t]{.31\linewidth}% {\fontsize{8.5}{12}\selectfont \baselineskipdoc \fontsizeinfo{examplesizeinfotight}} \hfill \parbox[t]{.31\linewidth}% {\fontsize{10}{12}\selectfont \baselineskipdoc \fontsizeinfo{examplesizeinfo}} \hfill \parbox[t]{.31\linewidth}% {\fontsize{10}{13.5}\selectfont \baselineskipdoc \fontsizeinfo{examplesizeinfoloose}} \endgroup \medskip \noindent \parbox[t]{.31\linewidth}{\examplefontname~\examplesizeinfotight*} \hfill \parbox[t]{.31\linewidth}{\examplefontname~\examplesizeinfo*} \hfill \parbox[t]{.31\linewidth}{\examplefontname~\examplesizeinfoloose*} \end{widebody} \noindent Starred form eats spaces? \examplesizeinfo* . \section{Hyphenation} \noindent Line-Break Behavior \begin{quote} \setlength{\overfullrule}{0pt} \parbox[t]{0pt}{% \code{\string\mbox+\string\breakpoint*} \\ \mbox{(pre-)}\breakpoint*Hilbert space} \hspace{100pt} \parbox[t]{0pt}{% \code{\string\breakpoint*} \\ (pre-)\breakpoint*Hilbert space} \hspace{100pt} \parbox[t]{0pt}{% \code{\string\breakpoint} \\ (pre-)\breakpoint Hilbert space} \end{quote} \noindent Starred form eats spaces? a\breakpoint* b. Unstarred: a\breakpoint b. \medskip \begin{quote} \setlength{\overfullrule}{0pt} \parbox[t]{0pt}{% \begin{hyphenmin}{6} Set minimum hyphenation values for both \code{\string\lefthyphenmin} and \code{\string\righthyphenmin}: \the\lefthyphenmin{} and \the\righthyphenmin. \end{hyphenmin}} \hspace{100pt} \parbox[t]{0pt}{% \begin{hyphenmin}[4]{5} Set minimum hyphenation values for \code{\string\lefthyphenmin} and \code{\string\righthyphenmin} separately: \the\lefthyphenmin{} and \the\righthyphenmin. \end{hyphenmin}} \hspace{100pt} \parbox[t]{0pt}{% Returned to the default values for \code{\string\lefthyphenmin} and \code{\string\righthyphenmin}: \the\lefthyphenmin{} and \the\righthyphenmin.} \end{quote} \section{Disable\kernedslash*Break Ligatures} \begin{center} \begin{tabular}{@{}ll@{}} \hline \multicolumn{1}{@{}l|}{Macro} & Result \\ \hline n/a & fine affirmation of baffling flavors \\ \code{\string\nolig*} & f\nolig*ine af\nolig*f\nolig*irmation of baf\nolig*f\nolig*ling f\nolig*lavors \\ \code{\string\nolig} & f\nolig{}ine af\nolig{}f\nolig{}irmation of baf\nolig{}f\nolig{}ling f\nolig{}lavors \\ \code{\string\nolig*[75]} & of\nolig*[75]f\nolig*[75]ice \end{tabular} \end{center} \noindent Line-Break Behavior \begin{quote} \setlength{\overfullrule}{0pt} \parbox[t]{0pt}{% \code{\string\nolig*} \\ bi\nolig*{}jection} \hspace{60pt} \parbox[t]{0pt}{% \code{\string\nolig} \\ bi\nolig{}jection} \end{quote} \noindent Starred form eats spaces? f\nolig* i, f\nolig*[0] i. \section{Manual Italic Correction} \paragraph{Text Mode.} The italic correction of the current font is \the\fontdimen1\font/pt. We demonstrate the effect of \code{\string\itcorr} with a pair of bookends: uncorrected italic: \indicatewidth{\it X}, \TeX-corrected (\code{\string\/}): \indicatewidth{\it X\/}, and \code{\string\itcorr\{7\}}: \indicatewidth{\it X\itcorr{7}}. Correction~0: \indicatewidth{\itcorr*{0}}; corr.~3: \indicatewidth{\itcorr{3}}, \indicatewidth{\itcorr*{3}} (starred); corr.~\textminus6: \indicatewidth{\itcorr{-6}}. \paragraph{Mathematical Mode.} Uncorrected: \([f]\), corrected: \([\itcorr{1} f\itcorr{1}]\) Correction~0: \indicatewidth{\(\itcorr{0}\)}; corr.~3: \indicatewidth{\(\itcorr{3}\)}; corr.~\textminus6: \indicatewidth{\(\itcorr{-6}\)}. \section{Apply Extra Kerning} \subsection{Slash} The slash with some extra space~(\code{slashkern}=\the\typogget{slashkern}) around it can be helpful for certain pairs, as for example years or names. \begin{center} \begin{tabular}{@{}lp{9em}p{15em}@{}} \hline \multicolumn{1}{@{}l|}{Macro} & \multicolumn{1}{l|}{Local Settings} & Result \\ \hline n/a & n/a & 1991/1992, New~York/NY, Korringa/Kohn/Rostoker \\ \code{\string\kernedslash} & n/a & 1991\kernedslash 1992, New~York\kernedslash NY, Korringa\kernedslash Kohn\kernedslash Rostoker \\ \code{\string\kernedslash} & \ttfamily lowerslash=.1em, slashkern=-.0333em & \typogsetup{lowerslash=.1em, slashkern=-.0333em} \scshape bardeen\kernedslash cooper\kernedslash shrieffer \\ \code{\string\kernedslash} & \ttfamily lowerslash=.1em, slashkern=0pt & \typogsetup{lowerslash=.1em, slashkern=0pt}abc\kernedslash def, uvw\kernedslash jkl \end{tabular} \end{center} \noindent Line-Break Behavior \begin{quote} \setlength{\overfullrule}{0pt} \parbox[t]{0pt}{% \code{\string\kernedslash*} \\ 1991\kernedslash*1992, New~York\kernedslash*NY, Korringa\kernedslash*Kohn\kernedslash*Rostoker} \hspace{120pt} \parbox[t]{0pt}{% \code{\string\kernedslash} \\ 1991\kernedslash{}1992, New~York\kernedslash{}NY, Korringa\kernedslash{}Kohn\kernedslash{}Rostoker} \end{quote} \begin{quote} \setlength{\overfullrule}{0pt} \parbox[t]{0pt}{% \code{\string\kernedslash*}\code{\string\nobreak} \\ 1991\kernedslash*\nobreak{}1992, New~York\kernedslash*\nobreak{}NY, Korringa\kernedslash*Kohn\kernedslash*\nobreak{}Rostoker} \hspace{140pt} \parbox[t]{0pt}{% \code{\string\allowhyphenation\string\kernedslash} \\ 1991\kernedslash{}1992, New~York\kernedslash{}NY, Korringa\allowhyphenation\kernedslash{}Kohn\kernedslash{}Rostoker} \end{quote} \noindent Starred form eats spaces? p\kernedslash* q. \subsection{Hyphen} Uncorrected \begin{quote} \(K\)-vector space, \(g\)-factor, \(f\)-function \end{quote} \noindent Corrected \begin{quote} \typogsetup{raisecapitalhyphen=.075em, raiseguillemets=.05em} \(K\)\leftkernedhyphen{-75}vector space, \(g\)\leftkernedhyphen{-25}factor, \(f\)\leftkernedhyphen{-100}function %% \(G\)\kernedhyphen[*]{50}{-50}Wirkung, %% \(G\)\leftkernedhyphen{50}äquivalent, %% \(K\)\kernedhyphen[*]{-50}{-50}Vektorraum, %% \(K\)\kernedhyphen{-50}{-25}bilinear, %% \propername{Young}\rightkernedhyphen{-50}Tableaux, %% \singlequotes{Bra}\kernedhyphen[50]{50}{-50}Vektor, %% \singlequotes{Ket}\kernedhyphen[50]{50}{-50}Vektor, %% halbzahlige~\(l\)\kernedhyphen{50}{-50}Werte. \end{quote} \noindent Line-Break Behavior \begin{quote} \setlength{\overfullrule}{0pt} \parbox[t]{0pt}{hyphen~\mbox{`\code{-}'} \\ self-energy} \hspace{80pt} \parbox[t]{0pt}{\code{\string\hyp} \\ self\hyp{}energy} \hspace{60pt} \parbox[t]{0pt}{\code{\string\kernedhyphen*} \\ self\kernedhyphen*{5}{-5}energy} \hspace{80pt} \parbox[t]{0pt}{\code{\string\kernedhyphen} \\ self\kernedhyphen{5}{-5}energy} \end{quote} \noindent If a \code{\string\kernedhyphen} goes astray in a math environment, it decays to an ordinary minus with appropriate kerning: \(G \kernedhyphen{-30}{-50} V\)\!. \subsection{En-Dash and Em-Dash} \iffalse \section{abc\spacedendash\relax def} \section{ghi\spacedendash*{}jkl} \section{mno\spacedendash[1pt]\relax pqr} \section{stu\spacedendash*[1pt]{}vwx} \section{GHI\spacedemdash\relax JKL} \section{MNO\spacedemdash[1pt]{}PQR} \fi En-Dash \setbox0=\hbox{\leftspacedendash}% \setbox0=\hbox{\leftspaceddash}% \setbox0=\hbox{\leftspacedendash*}% \setbox0=\hbox{\leftspaceddash*}% \setbox0=\hbox{\rightspacedendash}% \setbox0=\hbox{\rightspaceddash}% \setbox0=\hbox{\spacedendash}% \setbox0=\hbox{\spaceddash}% \setbox0=\hbox{\rightspacedendash*}% \setbox0=\hbox{\spacedendash*}% \setbox0=\hbox{\spaceddash*}% \begin{quote} abc\spacedendash{}def, ghi\spacedendash* jkl, mno\spacedendash[.3em] pqr (raised by .3\,em) \end{quote} \noindent Line-Break Behavior \begin{quote} \setlength{\overfullrule}{0pt} \parbox[t]{0pt}{\code{\string\leftspacedendash} \\ En\-dash\leftspacedendash Spacing} \hspace{100pt} \parbox[t]{0pt}{\code{\string\rightspacedendash} \\ En\-dash\rightspacedendash Spacing} \hspace{100pt} \parbox[t]{0pt}{\code{\string\spacedendash*} \\ En\-dash\spacedendash* Spacing} \end{quote} \noindent Em-Dash \setbox0=\hbox{\leftspacedemdash}% \setbox0=\hbox{\leftspacedemdash*}% \setbox0=\hbox{\rightspacedemdash}% \setbox0=\hbox{\spacedemdash}% \setbox0=\hbox{\rightspacedemdash*}% \setbox0=\hbox{\spacedemdash*}% \begin{quote} abc\spacedemdash{}def, ghi\spacedemdash* jkl, mno\spacedemdash[.3em] pqr (raised by .3\,em) \end{quote} \noindent Line-Break Behavior \begin{quote} \setlength{\overfullrule}{0pt} \parbox[t]{0pt}{\code{\string\leftspacedemdash} \\ Dash\leftspacedemdash Spacing} \hspace{100pt} \parbox[t]{0pt}{\code{\string\rightspacedemdash} \\ Dash\rightspacedemdash Spacing} \hspace{100pt} \parbox[t]{0pt}{\code{\string\spacedemdash*} \\ Dash\spacedemdash* Spacing} \end{quote} \section{Raise Selected Characters} \subsection{Capital Hyphen} \newlength{\exemplaryraisecapitalhyphen} \setlength{\exemplaryraisecapitalhyphen}{.6667pt} With the standard hyphen we get \begin{quote} \begin{otherlanguage}{german} \acronym{NMR}-Spektroskopie, \acronym{SI}-Einheit, \(G\)-Modul, and \(K\)-Vektorraum, \end{otherlanguage} \end{quote} \noindent whereas with raising the hyphen by \the\exemplaryraisecapitalhyphen{} when calling \code{\string\capitalhyphen}, we arrive at \begin{quote} \begin{otherlanguage}{german} \typogsetup{raisecapitalhyphen=.075em} \acronym{NMR}\capitalhyphen{}Spektroskopie, \acronym{SI}\capitalhyphen{}Einheit, \(G\)\capitalhyphen{}Modul, and \(K\)\capitalhyphen{}Vektorraum (even better with \code{\string\kernedhyphen} and the star-option for the correct raise-amount: \(K\)\leftkernedhyphen[*]{-100}Vektorraum). \end{otherlanguage} \end{quote} \noindent Line-Break Behavior \begin{quote} \setlength{\overfullrule}{0pt} \begin{otherlanguage}{german} \parbox[t]{0pt}{% \code{\string\capitalhyphen*} \\ \acronym{NMR}\capitalhyphen*{}Spektroskopie } \hspace{120pt} \parbox[t]{0pt}{% \code{\string\capitalhyphen} \\ \acronym{NMR}\capitalhyphen{}Spektroskopie } \end{otherlanguage} \end{quote} \noindent Starred form eats spaces? {\typogsetup{raisecapitalhyphen=.075em} V\capitalhyphen* W.} \subsection{Capital Dash} \newlength{\exemplaryraisecapitaldash} \setlength{\exemplaryraisecapitaldash}{.075em} Compare the result of plain~\code{\string\textendash} \begin{quote} A\textendash M, N\textendash Z, C1\,\textendash\,C4, LEED\:\textendash\:STM \end{quote} \noindent with \code{\string\capitaldash}: \begin{quote} \typogsetup{raisecapitaldash=\exemplaryraisecapitaldash} A\capitaldash{}M, N\capitaldash{}Z, C1\,\capitaldash\,C4, LEED\:\capitaldash\:STM \end{quote} \noindent where the en-dash has been raised by \milliem{\exemplaryraisecapitaldash}. Starred form eats spaces? V\capitaldash* W. \smallskip \noindent Spaced Capital En-Dash \setbox0=\hbox{\leftspacedcapitalendash}% \setbox0=\hbox{\leftspacedcapitaldash}% \setbox0=\hbox{\leftspacedcapitalendash*}% \setbox0=\hbox{\leftspacedcapitaldash*}% \setbox0=\hbox{\rightspacedcapitalendash}% \setbox0=\hbox{\rightspacedcapitaldash}% \setbox0=\hbox{\spacedcapitalendash}% \setbox0=\hbox{\spacedcapitaldash}% \setbox0=\hbox{\rightspacedcapitalendash*}% \setbox0=\hbox{\spacedcapitalendash*}% \setbox0=\hbox{\spacedcapitaldash*}% \begin{quote} abc\spacedcapitalendash{}def, ghi\spacedcapitalendash* jkl \end{quote} \noindent Spaced Capital Em-Dash \setbox0=\hbox{\leftspacedcapitalemdash}% \setbox0=\hbox{\leftspacedcapitalemdash*}% \setbox0=\hbox{\rightspacedcapitalemdash}% \setbox0=\hbox{\spacedcapitalemdash}% \setbox0=\hbox{\rightspacedcapitalemdash*}% \setbox0=\hbox{\spacedcapitalemdash*}% \begin{quote} abc\spacedcapitalemdash{}def, ghi\spacedcapitalemdash* jkl \end{quote} \subsection{Number Dash} \newlength{\exemplaryraisefiguredash} \setlength{\exemplaryraisefiguredash}{.6667pt} Compare the result of plain~\code{\string\textendash} \begin{quote} 3--5, 81--82, 485--491 \end{quote} \noindent with \code{\string\figuredash}: \begin{quote} \typogsetup{raisefiguredash=\exemplaryraisefiguredash} 3\figuredash 5, 81\figuredash 82, 485\figuredash 491 \end{quote} \noindent where the en-dash has been raised by \the\exemplaryraisefiguredash. \noindent Line-Break Behavior \begin{quote} \setlength{\overfullrule}{0pt} \typogsetup{raisefiguredash=\exemplaryraisefiguredash} \parbox[t]{0pt}{% \code{\string\figuredash*} \\ 3\figuredash*5, 81\figuredash*82, 485\figuredash*491 } \hspace{80pt} \parbox[t]{0pt}{% \code{\string\figuredash} \\ 3\figuredash 5, 81\figuredash 82, 485\figuredash 491 } \end{quote} \noindent Starred form eats spaces? 44\figuredash* 55. \subsection{Multiplication Sign \capitaldash{} Times~``\texttimes''} \newlength{\exemplaryraisetimes} \setlength{\exemplaryraisetimes}{.6667pt} The problem with a too-low multiplication sign arises for example with matrices of a given, specific size. \noindent Uncorrected \begin{quote} \acronym{LR}-mode: 2\texttimes2-matrix, \(N\)\texttimes\(M\)-matrix \\ Math-mode: \(2\times2\)-matrix, \(N\times M\)-matrix \end{quote} \noindent and corrected \begin{quote} \typogsetup{raisecapitalhyphen=\exemplaryraisecapitalhyphen, raisecapitaltimes=\exemplaryraisetimes} \acronym{LR}-mode: 2\capitaltimes2-matrix, \(N\)\capitaltimes\(M\)-matrix \\ Math-mode: \(2\capitaltimes2\)-matrix, \(N\capitaltimes M\)-matrix. \end{quote} \subsection{Guillemets} \newcommand*{\tschicholdi} {Use single quotes for a first quotation.} \newcommand*{\tschicholdii} {Use double quotes for quotations within quotations.} \newcommand*{\frenchsinglequotes}[1]{\singleguillemetright #1\singleguillemetleft} \newcommand*{\Frenchsinglequotes}[1]{\Singleguillemetright #1\Singleguillemetleft} \newcommand*{\frenchdoublequotes}[1]{\doubleguillemetright #1\doubleguillemetleft} \newcommand*{\Frenchdoublequotes}[1]{\Doubleguillemetright #1\Doubleguillemetleft} \newcommand*{\frenchsinglequotesFR}[1]{\singleguillemetleft\,\allowhyphenation#1\,\singleguillemetright} \newcommand*{\FrenchsinglequotesFR}[1]{\Singleguillemetleft\,\allowhyphenation#1\,\Singleguillemetright} \newcommand*{\frenchdoublequotesFR}[1]{\doubleguillemetleft\,\allowhyphenation#1\,\doubleguillemetright} \newcommand*{\FrenchdoublequotesFR}[1]{\Doubleguillemetleft\,\allowhyphenation#1\,\Doubleguillemetright} \newlength{\exemplaryraiseguillemets} \setlength{\exemplaryraiseguillemets}{.05em} \newlength{\exemplaryraisecapitalguillemets} \setlength{\exemplaryraisecapitalguillemets}{.1em} We again compare the default implementation with the adjusted one. \begin{quote} \frenchsinglequotes{\tschicholdi} \\ \frenchdoublequotes{\tschicholdii} \\ \Frenchsinglequotes{1}, \Frenchsinglequotes{2}, \Frenchsinglequotes{3}. \\ \Frenchdoublequotes{\letterspacecapitals{ABC}}, \Frenchdoublequotes{\letterspacecapitals{MN}}, \Frenchdoublequotes{\letterspacecapitals{XYZ}}. \end{quote} \noindent Corrected by raising the glyphs by \milliem{\exemplaryraiseguillemets} and \milliem{\exemplaryraisecapitalguillemets}: \begin{quote} \typogsetup{raiseguillemets=\exemplaryraiseguillemets, raisecapitalguillemets=\exemplaryraisecapitalguillemets} \frenchsinglequotes{\tschicholdi} \\ \frenchdoublequotes{\tschicholdii} \\ \Frenchsinglequotes{1}, \Frenchsinglequotes{2}, \Frenchsinglequotes{3}. \\ \Frenchdoublequotes{\letterspacecapitals{ABC}}, \Frenchdoublequotes{\letterspacecapitals{MN}}, \Frenchdoublequotes{\letterspacecapitals{XYZ}}. \end{quote} \noindent And the same using French typographic conventions: \begin{quote} \typogsetup{raiseguillemets=\exemplaryraiseguillemets, raisecapitalguillemets=\exemplaryraisecapitalguillemets} \frenchsinglequotesFR{\tschicholdi} \\ \frenchdoublequotesFR{\tschicholdii} \\ \FrenchsinglequotesFR{1}, \FrenchsinglequotesFR{2}, \FrenchsinglequotesFR{3}. \\ \FrenchdoublequotesFR{\letterspacecapitals{ABC}}, \FrenchdoublequotesFR{\letterspacecapitals{MN}}, \FrenchdoublequotesFR{\letterspacecapitals{XYZ}}. \end{quote} \noindent Line-Break Behavior \begin{quote} \setlength{\overfullrule}{0pt} \typogsetup{raiseguillemets=\exemplaryraiseguillemets, raisecapitalguillemets=\exemplaryraisecapitalguillemets} \newcommand*{\samplestring}{relation} \parbox[t]{0pt}{\frenchsinglequotes{\samplestring}} \hspace{30pt} \parbox[t]{0pt}{\Frenchsinglequotes{\samplestring}} \hspace{30pt} \parbox[t]{0pt}{\frenchdoublequotes{\samplestring}} \hspace{30pt} \parbox[t]{0pt}{\Frenchdoublequotes{\samplestring}} \smallskip \parbox[t]{0pt}{\frenchsinglequotesFR{\samplestring}} \hspace{30pt} \parbox[t]{0pt}{\FrenchsinglequotesFR{\samplestring}} \hspace{30pt} \parbox[t]{0pt}{\frenchdoublequotesFR{\samplestring}} \hspace{30pt} \parbox[t]{0pt}{\FrenchdoublequotesFR{\samplestring}} \end{quote} \subsection{Inverted Exclamation Mark and Inverted Question Mark} Without \typoglogo{} support: g\textexclamdown jk\textquestiondown y\enspace \textexclamdown E! \textquestiondown Q? All-caps versus small-caps: \noindent \begin{minipage}{.4\textwidth}\parindent=15pt \noindent \textsc{Carmen}\par {\lsstyle\capitalinvertedquestionmark{1}CÓMO ESTÁS, JOSÉ?} \noindent \textsc{José}\par {\lsstyle\capitalinvertedexclamationmark{1}BIEN! \capitalinvertedquestionmark{1}\itcorr{-2}Y TÚ?} \noindent \textsc{Carmen}\par {\lsstyle\capitalinvertedexclamationmark{1}BIEN TAMBIÉN!} \end{minipage} \hfill \begin{minipage}{.4\textwidth}\parindent=15pt \noindent \textsc{Carmen}\par {\scshape\capitalinvertedquestionmark{1}cómo estás, josé?} \noindent \textsc{José}\par {\scshape\capitalinvertedexclamationmark{1}bien! \capitalinvertedquestionmark{1}\itcorr{-2}y tú?} \noindent \textsc{Carmen}\par {\scshape\capitalinvertedexclamationmark{1}bien también!} \end{minipage} \medskip \begin{typogsetup}{raiseinvertedmarks={5pt,*,1sp}} \noindent Local settings are \{\typoggetnth{\dimen0}{raiseinvertedmarks}{1}\the\dimen0, \typoggetnth{\dimen0}{raiseinvertedmarks}{2}\the\dimen0, \typoggetnth{\dimen0}{raiseinvertedmarks}{3}\the\dimen0\}. Primaries: ?\capitalinvertedquestionmark{1}? and !\capitalinvertedexclamationmark{1}! \makeatletter \def\typog@inverted@exclamationmark@ii{\textexclamdown\textsubscript{2}} \def\typog@inverted@exclamationmark@iii{\textexclamdown\textsubscript{3}} \def\typog@inverted@questionmark@ii{\textquestiondown\textsubscript{2}} \def\typog@inverted@questionmark@iii{\textquestiondown\textsubscript{3}} \makeatother Secondaries -- indexed with 2: \capitalinvertedquestionmark{2}Más? \capitalinvertedexclamationmark{2}Por venir! Tertiaries -- indexed with 3: \capitalinvertedquestionmark{3}Continuemos? \capitalinvertedexclamationmark{3}Con el texto! \iffalse \section{\capitalinvertedexclamationmark{1}E! \capitalinvertedquestionmark{1}Q?} \section{\capitalinvertedexclamationmark{2}E! \capitalinvertedquestionmark{2}Q?} \section{\capitalinvertedexclamationmark{3}E! \capitalinvertedquestionmark{3}Q?} \fi \end{typogsetup} \section{Label Items} The current configurations for the uppercase and lowercase adjustments are \{\typogget{uppercaselabelitemadjustments}\} and \{\typogget{lowercaselabelitemadjustments}\}. Here are the results of the freestanding macros~\code{\string\adjusted\-label\-itemi}, \code{\string\adjusted\-label\-itemi} and so on: \begin{center} A\Adjustedlabelitemi B\Adjustedlabelitemii E\Adjustedlabelitemiii G\Adjustedlabelitemiv H. a\adjustedlabelitemi b\adjustedlabelitemii e\adjustedlabelitemiii g\adjustedlabelitemiv h. \end{center} For the following nested lists we adjust levels one and three for uppercase and levels two and four for lowercase. \begingroup \uppercaseadjustlabelitems{1,3} \lowercaseadjustlabelitems{2,4} \setlength{\itemsep}{0pt} \setlength{\parsep}{0pt} \setlength{\topsep}{0pt} \begin{itemize} \item A \item B \item C \begin{itemize} \item d \item e \item f \begin{itemize} \item G \item H \item I \begin{itemize} \item j \item k \item l \end{itemize} \end{itemize} \end{itemize} \end{itemize} \endgroup \noadjustlabelitems{*}% not necessary, but we want to exercise the macro The left example shows the result of \code{\string\typogadjuststairs\{.25pt\}\{11\}\{ABC\}} and the one on the right hand side just uses the same parameters except for the sample~\sample{ace}, this is, only lowercase letters. \begin{center} \begin{minipage}[t]{12em} \centering \typogadjuststairs{.25pt}{11}{ABC} \end{minipage} \begin{minipage}[t]{12em} \centering \typogadjuststairs{.25pt}{11}{ace} \end{minipage} \end{center} For this document the calls \code{\string\typoguppercaseadjustcheck\{ABC\-DEF\-GHI\-JKL\-MNO\-PQR\-STU\-VWX\-YZ\}} and \code{\string\typoglowercaseadjustcheck\{ace\-gmn\-opq\-rsu\-vwx\-yz\}} yield \sample{\typoguppercaseadjustcheck{ABCDEFGHIJKLMNOPQRSTUVWXYZ}} and \sample{\typoglowercaseadjustcheck{acegmnopqrsuvwxyz}}, where the adjustments in effect are \code{\{\typogget{uppercaselabelitemadjustments}\}} and \code{\{\typogget{lowercaselabelitemadjustments}\}}. \clearpage \section{Align Last Line} \subsection{Last Line Ragged Left/Flush Right} \Cref{ex:lastlineraggedleftpar} is a typical use of environment~\code{lastlineraggedleftpar}: A narrow paragraph gets typeset with full justification and put \code{\string\flushright} against the right margin as a whole. The layout may look more coherent if the last lines is moved to the right margin, too. \begin{exemplary} \flushright \caption[Justified -- flushright] {\begin{typoginspectpar}{justified-flushright}Typeset a justified paragraph flushright and let macro~\code{\string\lastlineraggedleft} shift the last line over to the right-hand side.\label{ex:lastlineraggedleftpar}\end{typoginspectpar}} \setlength{\examplewidth}{220pt} \exampleparbox[lastlineraggedleftpar]{\lastlineraggedleftpar\texbookparfillskipsample} \centering \texbookparfillskipsamplecredits \examplefontinformation \end{exemplary} \subsection{Last Line Centered} The situation shown in \cref{ex:lastlinecenteredpar} is more widespread than \cref{ex:lastlineraggedleftpar} because centered tables and figures are quite common. Their caption parboxes are centered too, which is where a centered last line might fortify the layout. Another possible use of environment~\code{lastlinecenteredpar} are the final lines of chapters~-- in particular if the chapters' ends are marked with centered dingbats. \begin{exemplary} \centering \caption[Typeset a justified paragraph that is centered.] {\lastlinecenteredpar Typeset a justified paragraph that is centered. This very caption uses \code{lastlinecenteredpar} to have its last line centered as well. Moreover, we put a nifty asterisk centered at the bottom of the sample text. \label{ex:lastlinecenteredpar}} \setlength{\examplewidth}{220pt} \exampleparbox[lastlinecenteredpar]{\lastlinecenteredpar\texbookparfillskipsample} \medskip\(\ast\) \texbookparfillskipsamplecredits \examplefontinformation \end{exemplary} \clearpage \section{Fill Last Line} \newcommand*{\abcsample}{abcd efgh ijkl mnop qrst uvwx yz12 3456} \begin{exemplary} \def\sness{2} \def\exparindent{25pt} \setlength{\examplewidth}{235pt} \centering \caption[Plain paragraph vs.~\code{covernextindentpar}] {Top example: Typeset a paragraph without correction of the last line. Middle example: Paragraph corrected with \code{covernextindentpar}. We set a \code{\string\parindent} of~\exparindent{} in both parboxes and we \emph{must} increase the amount of glue in the paragraph to reduce the penalty of stretching the last line under a \code{\string\fussy}~setting. For the samples below, we have chosen \code{\string\slightlysloppy[\sness]}. The \singlequotes{Alternative}, the bottom example, shows the effect of \code{tightspacing}; no extra sloppiness is required there.} \exampleparbox[covernextindentpar-reference]{% \setlength{\parindent}{\exparindent}% \slightlysloppy[\sness] \texbookparfillskipsample{} \abcsample} \medskip \exampleparbox[covernextindentpar]{% \setlength{\parindent}{\exparindent}% \slightlysloppy[\sness] \covernextindentpar \texbookparfillskipsample{} \abcsample} \medskip Alternative\dots\hfill\smallskip \exampleparbox[covernextindentpar-tightspacing]{% \setlength{\parindent}{\exparindent}% \begin{tightspacing} \texbookparfillskipsample{} \abcsample \end{tightspacing}} \texbookparfillskipsamplecredits \examplefontinformation \end{exemplary} \begin{exemplary} \def\sness{2} \def\exparindent{0pt} \setlength{\examplewidth}{155pt} \centering \caption[Plain paragraph vs.~\code{covernextindentpar} (narrow)] {Same comparison as the previous example, but for a small linewidth and zippo~\code{\string\parindent}. The left-hand side sample is uncorrected, the right-hand side features \code{\string\covernextindentpar}. The sloppiness level is~\sness{} for both samples.} \exampleparbox[narrow-covernextindentpar-reference]{% \setlength{\parindent}{\exparindent}% \slightlysloppy[\sness] \texbookparfillskipsample{} \abcsample} \qquad \exampleparbox[narrow-covernextindentpar]{% \setlength{\parindent}{\exparindent}% \slightlysloppy[\sness] \covernextindentpar[30pt] \texbookparfillskipsample{} \abcsample} \texbookparfillskipsamplecredits \examplefontinformation \end{exemplary} \begin{exemplary} \def\exparindent{10pt} \setlength{\examplewidth}{233pt} \centering \caption[Prevent full last line] {Sample~1: Typeset a paragraph without correction of the last line. Sample~2: Paragraph corrected with \code{\string\openlastlinepar}.~-- Disappointing! Sample~3: Same using macro~\code{\string\prolongpar}. Sample~4: Alternative solution that simply increases the tracking by \generictextfraction{2}{1000}\,em with~\code{setfonttracking}. Sample~5: Alternative solution that increases the spacing with \code{loosespacing}.} \exampleparbox[openline-reference]{% \setlength{\parindent}{\exparindent} \texbookparfillskipsample{} \abcsample} \medskip \exampleparbox[openlastlinepar]{% \setlength{\parindent}{\exparindent} \openlastlinepar \texbookparfillskipsample{} \abcsample} \medskip \exampleparbox[prolongpar]{% \setlength{\parindent}{\exparindent} \prolongpar \texbookparfillskipsample{} \abcsample} \medskip Alternatives\dots\hfill\smallskip \exampleparbox[openline-tracking]{% \setlength{\parindent}{\exparindent}% \setfonttracking{2} \texbookparfillskipsample{} \abcsample} \medskip \exampleparbox[openline-spacing]{% \setlength{\parindent}{\exparindent}% \begin{loosespacing} \texbookparfillskipsample{} \abcsample \end{loosespacing}} \texbookparfillskipsamplecredits \examplefontinformation \end{exemplary} \begin{typoginspect}{lastlinefitpar} \lastlinefit=\defaultlastlinefit \begin{nofontexpansion} \begin{lastlinefitpar} In this paragraph the value of \code{\string\lastlinefit} was increased to \the\lastlinefit. Thus, the spacing of its last line is equal to that of the next-to-last line. The effect can be double-checked with log-file, \textit{\jobname.log,} as this text was wrapped in a \code{typoginspect}~environment with id~\code{lastlinefitpar}. \end{lastlinefitpar} The value of \code{\string\lastlinefit} is reset to~\the\lastlinefit{} in the following paragraph. \end{nofontexpansion} \end{typoginspect} \clearpage \section{Spacing} \subsection{Narrow\kernedslash Wide Space} The current font's parameters are shown in \cref{tab:fontdim}.\!\footnote{For a concise and understandable explanation of the plethora of font parameters consult \propername{David Carlisle's} excellent post on \propername{StackExchange}: \href{https://tex.stackexchange.com/questions/88991/what-do-different-fontdimennum-mean}% {What Do Different Fontdimennum Mean}.} \begin{table}[htp] \centering \caption{Important \code{\string\fontdimen} values of the current text font. The middle column~(\#) states the number of the fontdimen.\bottomstrut} \label{tab:fontdim} \begin{tabular}{@{}lll@{}} \hline \multicolumn{1}{@{}l|}{Name} & \multicolumn{1}{l|}{\#} & Value \\ \hline Interword space & 2 & \the\fontdimen2\font\topstrut \\ Interword stretch & 3 & \the\fontdimen3\font \\ Interword shrink & 4 & \the\fontdimen4\font \\ Extra space & 7 & \the\fontdimen7\font \end{tabular} \end{table} \begin{center} \setlength{\overfullrule}{0pt} \newcommand*{\spacesampletext}[1]{some#1text#1with#1spaces\rule{.1pt}{1em}} \newsavebox{\narrowspacesample} \sbox{\narrowspacesample}{\spacesampletext{\narrowspace}} \newsavebox{\widespacesample} \sbox{\widespacesample}{\spacesampletext{\widespace}} \begin{tabular}{@{}ll@{\qquad}l@{}} Compare & \spacesampletext{\space} & default space, natural glue \\ with & \usebox{\narrowspacesample} & \code{\string\narrowspace}, natural glue \\ {} & \makebox[\wd\narrowspacesample][l]{\hbox to 0pt{\spacesampletext{\narrowspace}}} & \code{\string\narrowspace}, tight box \\ {} & \makebox[\wd\narrowspacesample][l]{\hbox spread 5pt{\spacesampletext{\narrowspace}}} & \code{\string\narrowspace}, spread 5pt \\ and again & \spacesampletext{\space} & default space, natural glue \\ with & \usebox{\widespacesample} & \code{\string\widespace}, natural glue \\ {} & \makebox[\wd\widespacesample][l]{\hbox to 0pt{\spacesampletext{\widespace}}} & \code{\string\widespace}, tight box \\ {} & \makebox[\wd\widespacesample][l]{\hbox spread 5pt{\spacesampletext{\widespace}}} & \code{\string\widespace}, spread 5pt \end{tabular} \end{center} \noindent Starred form eats spaces? Narrow\narrowspace* Space. Wide\widespace* Space. \subsection{Looser\kernedslash*Tighter} \Cref{ex:spacing-i,ex:spacing-ii} show \code{tightspacing} and \code{loosespacing} at work. \begin{exemplary} \newcommand*{\sness}{3} \newcommand*{\tlevel}{1} \centering \caption[Looser or tighter spacing -- sloppy] {Both parboxes are typeset with \code{\string\slightlysloppy[\sness]}, the left one with default spacing, the right one with \code{tightspacing[\tlevel]}.\label{ex:spacing-i}} \exampleparbox[tightspacing-reference]{\slightlysloppy[\sness]\texbooktolerancesample} \qquad \exampleparbox[tightspacing]{\slightlysloppy[\sness]\tightspacing[\tlevel]\texbooktolerancesample} \texbooktolerancesamplecredits \examplefontinformation \end{exemplary} \begin{exemplary} \newcommand*{\sness}{3} \newcommand*{\llevel}{2} \centering \caption[Looser or tighter spacing -- sloppy] {Both parboxes are typeset with \code{\string\slightlysloppy[\sness]}, the left one with default spacing, the right one with \code{loosespacing[\llevel]}.\label{ex:spacing-ii}} \exampleparbox[loosespacing-reference]{\slightlysloppy[\sness]\texbooktolerancesample} \qquad \exampleparbox[loosespacing]{\slightlysloppy[\sness]\loosespacing[\llevel]\texbooktolerancesample} \texbooktolerancesamplecredits \examplefontinformation \end{exemplary} \clearpage \section{Microtype Front\capitalhyphen End} \subsection{Tracking} \newcommand*{\trackingsampletext}{% This sentence contains an explicit call to \code{\string\textls} with an optional argument of \((+200)\) to \textls[200]{DEMONSTRATE} that this macro still works inside of \code{setfonttracking}. Apart from that it is just some more text to exercise the macro. Well, the explicit letterspacing example is particularly ugly.} \begin{exemplary} \renewcommand*{\examplepreset}{\microtypesetup{activate=true}} \def\extratracking{7} \centering \caption[Microtype: tracking] {Use \packagename{microtype} to change the font tracking. The sample on the left-hand side shows neutral tracking. The one on the right-hand side received an extra tracking of \generictextfraction{\extratracking}{1000}\,em.} \exampleparbox[microtype-tracking-reference]{% \fussy \noindent \trackingsampletext} \qquad \exampleparbox[microtype-tracking-stretch]{% \begin{setfonttracking}{\extratracking} \fussy \noindent \trackingsampletext \end{setfonttracking}} \examplefontinformation \end{exemplary} \newcommand*{\trackingsamplefontchangetext}{% {\rm RM} {\sf SF} {\rm RM} {\tt TT} {\rm RM}; {\rm RM} {\it IT\/} {\rm RM}; {\rm RM} {\sc SC} {\rm RM}. {\rm Rm} {\sf Sf} {\rm Rm} {\tt Tt} {\rm Rm}; {\rm Rm} {\it It\/} {\rm Rm}; {\rm Rm} {\sc Sc} {\rm Rm}. {\rm rm} {\sf sf} {\rm rm} {\tt tt} {\rm rm}; {\rm rm} {\it it\/} {\rm rm}; {\rm rm} {\sc sc} {\rm rm}.} \begin{exemplary} \renewcommand*{\examplepreset}{\microtypesetup{activate=true}} \def\extratracking{1} \centering \caption[Microtype: tracking -- font changes] {Check how font changes (serif, serif~italic, small-caps, sans~serif, typewriter) interfere with the interword spacing. The left sample has no tracking changes applied and serves as a reference, whereas the right sample got an extra tracking of \generictextfraction{\extratracking}{1000}\,em.\visualpar The switch from and to typewriter, i.\,e., constant-width fonts commonly is a source of spacing problems.} \exampleparbox[microtype-tracking-font-changes-reference]{\trackingsamplefontchangetext} \qquad \exampleparbox[microtype-tracking-font-changes-stretch]{% \begin{setfonttracking}{\extratracking} \trackingsamplefontchangetext \end{setfonttracking}} \end{exemplary} \noindent No contents: \leftmarker \begin{setfonttracking}{0} \end{setfonttracking}\rightmarker. \subsection{Font Expansion} \newcommand*{\expansionsample} {By default, all characters of a font are allowed to be stretched or shrunk by the same amount. However, it is also possible to limit the expansion of certain characters if they are more sensitive to deformation. This is the purpose of the \code{\string\SetExpansion}~macro.} \begin{exemplary} \setlength{\examplewidth}{250pt} \renewcommand*{\examplepreset}{\microtypesetup{activate=true}} \renewcommand*{\examplesetup}{\frenchspacing\small\fussy} \centering \caption[Microtype: font expansion] {Use \packagename{microtype} to stretch or shrink a font. The top sample uses \code{\string\setfontshrink} at level~3, the middle sample is the unchanged reference (which is allowed to shrink and expand), and the bottom sample utilizes \code{\string\setfontstretch} at level~2.} \exampleparbox[microtype-expansion-shrink]{% \begin{setfontshrink}[3] \noindent\expansionsample \end{setfontshrink}} \medskip \exampleparbox[microtype-expansion-neutral]{% \begin{setfontexpand}[0] \noindent\expansionsample \end{setfontexpand}} \medskip \exampleparbox[microtype-expansion-stretch]{% \begin{setfontstretch}[2] \noindent\expansionsample \end{setfontstretch}} \examplefontinformation \end{exemplary} \noindent No contents -- \code{setfontshrink}: \leftmarker \begin{setfontshrink} \end{setfontshrink}\rightmarker. \noindent No contents -- \code{setfontstretch}: \leftmarker \begin{setfontstretch} \end{setfontstretch}\rightmarker. \noindent No contents -- \code{setfontexpand}: \leftmarker \begin{setfontexpand} \end{setfontexpand}\rightmarker. \noindent No contents -- \code{nofontexpansion}: \leftmarker \begin{nofontexpansion} \end{nofontexpansion}\rightmarker. \subsection{Character Protrusion} \newcommand*{\zerodepthrule} {\raisebox{0pt}[0pt][0pt]{\rule[-4.5\baselineskip]{.1pt}{4.25\baselineskip}}} \newcommand*{\protrusionsampletext}{% \noindent \zerodepthrule\hfill\zerodepthrule \\ 1\hfill 1 \\ .2\hfill 2. \\ --3\hfill 3-- \\ ---4\hfill 4---} \begin{exemplary} \renewcommand*{\examplepreset}{\microtypesetup{activate=true}} \renewcommand*{\examplesetup}{\frenchspacing\small\fussy} \centering \caption[Microtype: protrusion] {Comparison of the \packagename{microtype} feature ``protrusion'' (left-hand side) and \code{nocharprotrusion} (right-hand side).} \exampleparbox[microtype-protrusion-reference]{% \microtypesetup{protrusion=true} \protrusionsampletext} \qquad \exampleparbox[microtype-protrusion-off]{% \microtypesetup{protrusion=true} \nocharprotrusion \protrusionsampletext} \medskip \end{exemplary} \noindent No contents -- \code{nocharprotrusion}: \leftmarker \begin{nocharprotrusion} \end{nocharprotrusion}\rightmarker. \clearpage \section{Sloppy Paragraphs} \Cref{ex:slightlysloppy-1,ex:slightlysloppy-2} put different amounts of ``sloppiness'' face to face. \begin{exemplary} \setlength{\examplewidth}{180pt} \def\sness{1} \centering \caption[Paragraphs typeset slightly sloppy~1] {Paragraphs typeset slightly sloppy: \code{\string\slightlysloppy} vs.~\code{\string\fussy}. The left parbox is typeset with \code{\string\slightlysloppy} and \(\metavar{sloppiness} = \sness\), whereas the right sample features the well known \code{\string\fussy} setting. Both parboxes have a width of \the\examplewidth.\label{ex:slightlysloppy-1}} \exampleparbox[fussy-vs-slightlysloppy]{\slightlysloppy[\sness]\texbooktolerancesample} \qquad \exampleparbox[fussy-vs-slightlysloppy-reference]{\fussy\texbooktolerancesample} \texbooktolerancesamplecredits \examplefontinformation \end{exemplary} \begin{exemplary} \setlength{\examplewidth}{150pt} \def\sness{2} \centering \caption[Paragraphs typeset slightly sloppy~2] {Paragraphs typeset slightly sloppy: \code{\string\slightlysloppy} vs.~\code{\string\sloppy}. The left sample is features \code{\string\slightlysloppy} with \(\metavar{sloppiness} = \sness\), the right sample is typeset with \code{\string\sloppy}. Both parboxes have a width of \the\examplewidth.\label{ex:slightlysloppy-2}} \exampleparbox[sloppy-vs-slightlysloppy]{\slightlysloppy[\sness]\texbooktolerancesample} \qquad \exampleparbox[sloppy-vs-slightlysloppy-reference]{\sloppy\texbooktolerancesample} \texbooktolerancesamplecredits \examplefontinformation \end{exemplary} In conclusion all renderings of the text in \cref{ex:slightlysloppy-1} and \cref{ex:slightlysloppy-2} have their merits and their own flaws. \clearpage \section{Vertically Partially-Tied Paragraphs} \paragraph{\code{vtietoppar}}\leavevmode\par \begin{typoginspect}{vtietoppar} \clubpenalty=150 \begin{vtietoppar}[2] After breaking a paragraph into lines, \TeX{} computes the interline penalties by adding the values of: \code{\string\clubpenalty} after the first line of a paragraph.\!\footnote{Footnote of \code{vtietoppar}.} \eTeX{} generalizes the concept of interline, club, widow, and display widow penalty by allowing their replacement by arrays of penalty values. \end{vtietoppar} \end{typoginspect} \paragraph{\code{vtiebotpar}}\leavevmode\par \begin{typoginspect}{vtiebotpar} \widowpenalty=150 \begin{vtiebotpar}[2] After breaking a paragraph into lines, \TeX{} computes the interline penalties by adding the values of: \code{\string\widowpenalty} before the last line of the paragraph.\marginpar{A float!} \eTeX{} generalizes the concept of interline, club, widow, and display widow penalty by allowing their replacement by arrays of penalty values. \end{vtiebotpar} \end{typoginspect} \paragraph{\code{vtiebotdisp}}\leavevmode\par \begin{typoginspect}[tracingboxes]{vtiebotdisp} \displaywidowpenalty=150 \begin{vtiebotdisp}[2] After breaking a paragraph into lines, \TeX{} computes the interline penalties by adding the values of: \code{\string\displaywidowpenalty} before the line immediately preceding a displayed equation. \eTeX{} generalizes the concept of interline, club, widow, and display widow penalty by allowing their replacement by arrays of penalty values. \[g H = H g \quad \text{for all} \enspace g \in G.\] \end{vtiebotdisp} Follow-up paragraph after and outside of the \code{vtiebotdisp}-environment. \end{typoginspect} \paragraph{\code{vtiebotdisptoppar}}\leavevmode\par \begin{typoginspect}{vtiebotdisptoppar} \displaywidowpenalty=150 \begin{vtiebotdisptoppar}[2] After breaking a paragraph into lines, \TeX{} computes the interline penalties by adding the values of: \code{\string\displaywidowpenalty} before the line immediately preceding a displayed equation. \eTeX{} generalizes the concept of interline, club, widow, and display widow penalty by allowing their replacement by arrays of penalty values. \begin{breakabledisplay} \begin{displaymath} g H = H g \quad \text{for all} \enspace g \in G. \end{displaymath} \end{breakabledisplay} In this example we need a paragraph that follows the displayed math. So, we have to type some more text here to be able to demonstrate the action of the environment. \end{vtiebotdisptoppar} \end{typoginspect} \clearpage \section{Breakable Displayed Equations} \newcommand*{\binaryminus}{\mathbin{-}} \newcommand*{\diracadj}[1]{\overline{#1}} \newcommand*{\unaryminus}{{-}} \begin{typoginspect}{breakabledisplay} \begin{breakabledisplay} \begin{align*} \diracadj{\psi}(x) \mathop{\partial_\mu} \psi(x) \mapsto \diracadj{\psi'}(x) \mathop{\partial_\mu} \psi'(x) &= e^{i \alpha(x)} \diracadj{\psi}(x) \mathop{\partial_\mu} \bigl( e^{\unaryminus i \alpha(x)} \psi(x) \bigr) \\ &= \underbrace{\diracadj{\psi}(x) \mathop{\partial_\mu} \psi(x)}_{\text{free particle}} \mskip\medmuskip \binaryminus \mskip\medmuskip i \, \diracadj{\psi}(x) \underbrace{\mathop{\partial_\mu} \bigl( \alpha(x) \bigr)}_{\mathclap{\text{vector field}}} \psi(x). \end{align*} \end{breakabledisplay} \end{typoginspect} \clearpage \section{\packagename{Setspace} Front End} \fontsizeinfo{defaultsize} Current settings are \defaultsize{} %--\settoheight{\typogfontsize}{CEMNORSUVWXZ} and \code{\string\typogfontsize} is \the\typogfontsize. \newcommand*{\absbls}{12pt plus 1pt minus .5pt} \paragraph{\code{\string\setbaselineskip\{\absbls\}}} \resetbaselineskip \setbaselineskip{10pt + 2.75pt}% addition \setbaselineskip{10.5pt * 100 / 105}% scaling \setbaselineskip{11.8pt * 85 / 100}% scaling \setbaselineskip{\absbls} \fontsizeinfo{baselinesetsize} New settings: \baselinesetsize. \texbookbaselineskipsample \newcommand*{\relbls}{130} \paragraph{\code{\string\setbaselineskippercentage\{\relbls\}}} \setbaselineskippercentage{1 + 2 + .3333 * 100 + 100 * .6667}% float expression \setbaselineskippercentage{\relbls} \fontsizeinfo{baselinesetsize} New settings: \baselinesetsize. \texbookbaselineskipsample \newcommand*{\absled}{1.5pt} \paragraph{\code{\string\setleading\{\absled\}}} \setleading{1pt / -2}% negative leading \setleading{\absled} \fontsizeinfo{baselinesetsize} New settings: \baselinesetsize. \texbookbaselineskipsample \newcommand*{\relled}{30} \paragraph{\code{\string\setleadingpercentage\{\relled\}}} \setleadingpercentage{10 - 25 / 2}% negative leading \setleadingpercentage{\relled} \fontsizeinfo{baselinesetsize} New settings: \baselinesetsize. \texbookbaselineskipsample \medskip \setstretch{1} \texbookbaselineskipsamplecredits \clearpage \section{Smooth Ragged} \begin{exemplary} \newcommand*{\ragwidth}{10pt} \centering \caption[Comparison of ragged right typesetting] {Comparison of ragged right typesetting. The first example uses \code{RaggedRight} of \packagename{ragged2e} the second \code{smoothraggedrightpar} of \packagename{typog}. Both examples share a \code{\string\fussy}~setting and a \ragwidth~wide ragged right margin.\label{ex:smoothraggedright}} \setlength{\RaggedRightRightskip}{0pt plus \ragwidth} %\def\smoothraggedrightgenerator{triplet} %\def\smoothraggedrightgenerator{quintuplet} %\def\smoothraggedrightgenerator{septuplet} \setlength{\smoothraggedrightragwidth}{\ragwidth} %\def\smoothraggedrightfuzzfactor{.667} \iffalse \begin{quote} \begin{RaggedRight}\examplesetup \texbookparshapeskipsample \end{RaggedRight} \end{quote} \begin{quote} \begin{smoothraggedrightpar}\examplesetup \texbookparshapeskipsample \end{smoothraggedrightpar} \end{quote} \else \exampleparbox[RaggedRight-reference]{\RaggedRight\texbooktolerancesample} \qquad \exampleparbox[smoothraggedrightpar]{\smoothraggedrightpar\texbooktolerancesample} \fi \texbookparshapeskipsamplecredits \examplefontinformation \end{exemplary} %--\setlength{\smoothraggedrightparindent}{25pt} %--\setlength{\parindent}{0pt} \noindent \code{\string\parindent}=\the\parindent, visually: \rule{.1pt}{.8em}\kern\parindent\rule{.1pt}{.8em}; \noindent \code{\string\smoothraggedrightleftskip}=\the\smoothraggedrightleftskip. \code{\string\smoothraggedrightparindent}=\the\smoothraggedrightparindent. \smallskip { %--\setlength{\smoothraggedrightragwidth}{8pt} \begin{smoothraggedright} \texbooktolerancesample \texbooktolerancesample \end{smoothraggedright} } \medskip { \setlength{\smoothraggedrightragwidth}{15pt} \newcommand*{\definitionnilpotent}{% Eine Abbildung oder ein Operator~\(A\) heißen nilpotent vom Grad~\(k\), falls \(k \in N\) die kleinste Zahl ist, für die gilt: \(A^k = 0\).} \begin{otherlanguage}{german} \parbox[t]{60pt}{\fussy\RaggedRight\definitionnilpotent} \hspace{40pt} \parbox[t]{60pt}{\fussy\smoothraggedright\definitionnilpotent} \end{otherlanguage} } \clearpage \begin{RaggedRight} \begin{thebibliography}{0} \bibitem{knuth:1986} \bibauthor{Knuth, D.~E.}, \bibtitle{The \TeX{}book}, Vol.~A of Computers\&Typesetting, Addison Wesley, Reading\kernedslash*MA, 1986. \end{thebibliography} \end{RaggedRight} \end{document} % % \fi % % % % \iffalse %<*without-microtype> \documentclass[]{article} \usepackage[english]{babel} \usepackage{csquotes} \DeclareQuoteStyle{typog-guillemets} {\doubleguillemetright} {\doubleguillemetleft} {\singleguillemetright} {\singleguillemetleft} \usepackage[uppercaselabelitemadjustments={.1em, .075em, .1em, .1em}, lowercaselabelitemadjustments={-.025em, -.05em, -.025em, -.025em}] {typog} \newcommand*{\packagename}[1]{\mbox{\textsf{#1}}} \begin{document} \begin{center} \Huge\bf\sf TypoG Examples \\ without Package~\packagename{microtype} \end{center} \bigskip \section*{No Microtype} This example \LaTeX-document uses package~\packagename{typog} \emph{without} package~\packagename{microtype}. We want \packagename{typog} to be as usable as possible even without the nice features that \packagename{microtype} offers. After all \packagename{typog} is just a front end for it. \section*{No EnumItem} We intentionally do not load package~\packagename{enumitem}, either. So, we can test whether \packagename{typog} correctly patches the plain \LaTeX{} definition if environment~\texttt{itemize}. The vertical alignment of the label items was setup for uppercase (ABC\typoguppercaseadjustcheck{ABCXYZ}XYZ) and for lowercase (ace\typoglowercaseadjustcheck{acexyz}xyz), though this is not necessary for the test. \uppercaseadjustlabelitems{*} \begin{itemize} \item Level i \item Sublist \dots \begin{itemize} \item Level ii \item Sublist \dots \begin{itemize} \item Level iii \item Sublist \dots \begin{itemize} \item Level iv \end{itemize} \end{itemize} \end{itemize} \end{itemize} \section*{CSQuotes} As we are testing a special configuration here anyhow, we hook up our quotes with package~csquotes to check whether they interact ok. {\setquotestyle{typog-guillemets}% \enquote{This is the outer part of the phrase which contains the \enquote{inner part}.}} \end{document} % % \fi % % % % \iffalse %<*minimal-test> \documentclass{minimal} \usepackage{typog} \newcommand*{\raiseamount}{0.5pt} \begin{document} \begin{typogsetup}{raise*=\raiseamount} Em-dash raised by \the\typogget{raisecapitaldash} (expected: \raiseamount). \end{typogsetup} \fontsizeinfo{typoinfo} Document class ``minimal'' sets up font size and line spacing as~\typoinfo. \end{document} % % \fi % % % % \iffalse %<*teximan2latex> ## Add some extra definitions. 1a\ \\let\\asis=\\relax ## Remove all lines we neither need nor want. /^\\input /d /^@anchor/d /^@bye/d /^@documentencoding/d /^@node/d /^@setfilename/d /^@settitle/d /^@top/d /@menu/,/@end menu/d ## Convert sectioning macros to our own hierarchy. s/^@chapter \(.*\)$/\\subsection{\\titlecase{\1}\\label{\1}}/ s/^@section \(.*\)$/\\subsubsection{\\titlecase{\1}}\\label{\1}/ ## Make `@asis' list resemble the Texinfo format. s/@table @asis/\\begin{list}{}{\\itemindent=-20pt\\leftmargin=20pt}/ s/@end table/\\end{list}/ ## We substitute our `widebody' environment for `@display'. s/@display/\\begin{widebody}/ s/@end display/\\end{widebody}/ ## Translate `@example' environments. s/@example/\\begin{quote}\\tt\\obeylines/ s/@end example/\\end{quote}\n\n/ ## Indenting by four spaces generates a `verbatim' environment. s/@verbatim/\\begin{verbatim}/ s/@end verbatim/\\end{verbatim}/ ## The argument format of the URL macro is different. s/@url{\([^,]*\), \([^}]*\)}/\\href{\1}{\2}/g ## Use our own markup. s/\.\.\./\\dots{}/g s/LaTeX/\\LaTeX{}/g s/@file/\\emph/g s/@strong/\\textbf/g s/@var/\\emph/g s/[w]{/mbox{/g ## Translate some Texinfo macros. s/@backslashchar/\\char`\\\\/g s/@lbracechar/\\{/g s/@noindent/\\noindent/g s/@rbracechar/\\}/g ## Quote some special characters. s/%/\\%/g s/_/\\_/g ## Add space around alternative-indicators. s/[|]/\\,|\\,/g ## Adapt to how a man-page is typeset. ## En-dashes in front of long options really suck! s/--/-\\nolig*-/g ## Converting the at-signs to backslashes is a bit tricky. s/^@item/\\item/ s/@\([A-Za-z][A-Za-z]*\){/\\\1{/g s/@@/@/g ## Convert selected macro names. s/\\jobname/\\textbackslash jobname/g ## Make qualified Perl names breakable. s/::/::\\breakpoint*/g % % \fi % % % % \iffalse %<*typog-grep> #! /usr/bin/env perl use autodie qw(:all); use strict; use warnings; use Data::Dumper (); use Encode (); use English; use File::Basename (); use Getopt::Long; use IO::File; use IO::Handle; use Term::ANSIColor (); use constant COMMAND_NAME => File::Basename::basename($PROGRAM_NAME); my $DEBUG = 0; my $MATCH_COUNT = 0; my $OUTPUT_IS_REDIRECTED; sub fail_with_error { print STDERR join('', COMMAND_NAME, ': ', @_, "\n"); exit 2; } sub issue_warning { print STDERR join('', COMMAND_NAME, ': warning: ', @_, "\n"); } sub debug_print { return unless $DEBUG; print STDERR "+ @_\n"; } sub quote_filesystem {qq("$_[0]")} sub quote_literal {qq(`$_[0]')} sub limit_string_length { my ($a_string, $a_maximum_length) = @_; if (length $a_string <= $a_maximum_length) { $a_string; } else { substr($a_string, 0, $a_maximum_length - 3) . '...'; } } ## We set all colors to `undef' and fill them later with the values ## of the actual configuration. my $highlight_patterns = { PARTIAL_LINE => { FONT_SPEC => [qr# \\ (?: OMS | OMX | OT1 | T1 | TS1 | U ) (?: /[^/]+ ){5} / \S+ \s (?: \([+-]\d+\) )? #x, undef], MATH => [qr# \$ \\ (?: LMS | OML ) (?: /[^/]+ ){5} / \S+ \s (?: \([+-]\d+\) )? .*? \$ #x, undef] }, WHOLE_LINE => { FILL_STATE => [qr#^(?:Under|Over)full \\hbox .*$#, undef], FIRST_VBOX => [qr#^%%#, undef], HORIZONTAL_BREAKPOINT => [qr#^@@\d+:.*$#, undef], HORIZONTAL_BREAK_CANDIDATE => [qr#^@[\\ ].*$#, undef], LINE_BREAK_PASS => [qr#^@[a-z]+?pass#, undef], TIGHTNESS => [qr#^(?:Loose|Tight) \\hbox .*$#, undef], VERTICAL_BREAKPOINT => [qr#^% t=\d+.*$#, undef] } }; sub colorize_line { my ($configuration, $line) = @_; foreach my $pattern_color_pair (values %{$highlight_patterns->{WHOLE_LINE}}) { next unless $pattern_color_pair->[1]; return Term::ANSIColor::colored($line, $pattern_color_pair->[1]) if $line =~ $pattern_color_pair->[0]; } return $line if $line =~ m#^\.#; # we do not paint box contents yet $line =~ s#$highlight_patterns->{PARTIAL_LINE}->{MATH}->[0] #Term::ANSIColor::colored($MATCH, $highlight_patterns->{PARTIAL_LINE}->{MATH}->[1]) #egx; $line =~ s#$highlight_patterns->{PARTIAL_LINE}->{FONT_SPEC}->[0] #Term::ANSIColor::colored($MATCH, $highlight_patterns->{PARTIAL_LINE}->{FONT_SPEC}->[1]) #egx; return $line; } my $open_or_close_tag_regexp = qr#^]#; # somewhat sloppy definition my $close_tag_regexp = qr#^#; my $open_tag_regexp = qr#^ #x; sub find_encoder { my $encoding = shift; my $encoder; if ($encoding) { $encoder = Encode::find_encoding($encoding); if (!$encoder) { issue_warning("encoding @{[quote_literal($encoding)]} unknown; proceeding without decoder"); } } return $encoder; } sub grep_log_file { my ($options, $configuration, $file, $filename, $id_regexp) = @_; my $encoder = find_encoder($options->{ENCODING}); my $job_name; my $line_number = 0; # line number in the log file we are inspecting, i.e., $filename my $match_count = 0; my $source_line_number; # line number in TeX file the log refers to, i.e., "$job_name.tex" my $page_number; my $regexp_modifier = $options->{IGNORE_CASE} ? 'i' : ''; my $id_value; my @nesting_levels; if ($options->{WORD_REGEXP}) { $id_regexp = "\\b$id_regexp\\b"; } while (my $line = readline $file) { chomp $line; $line_number++; $line = Encode::encode_utf8($encoder->decode($line, Encode::FB_CROAK)) if $encoder; if ($line =~ $close_tag_regexp) { fail_with_error("$filename: $line_number: mismatched open/close tags") unless @nesting_levels; pop @nesting_levels; } if (@nesting_levels and $nesting_levels[-1] and $line !~ $open_or_close_tag_regexp) { if ($options->{LOG_LINE_NUMBER}) { my $formatted_log_line_number = sprintf $configuration->{LOG_LINE_NUMBER_FORMAT}, $line_number; if ($options->{COLORIZE_OUTPUT}) { $formatted_log_line_number = Term::ANSIColor::colored($formatted_log_line_number, $configuration->{COLORS}->{LOG_LINE_NUMBER}); } print $formatted_log_line_number, ' '; } print "$job_name: " if $options->{JOB_NAME}; if ($options->{LINE_NUMBER}) { my $formatted_line_number = sprintf $configuration->{LINE_NUMBER_FORMAT}, $source_line_number; if ($options->{COLORIZE_OUTPUT}) { $formatted_line_number = Term::ANSIColor::colored($formatted_line_number, $configuration->{COLORS}->{LINE_NUMBER}); } print $formatted_line_number, ' '; } if ($options->{PAGE_NUMBER}) { my $formatted_page_number = sprintf $configuration->{PAGE_NUMBER_FORMAT}, $page_number; if ($options->{COLORIZE_OUTPUT}) { $formatted_page_number = Term::ANSIColor::colored($formatted_page_number, $configuration->{COLORS}->{PAGE_NUMBER}); } print $formatted_page_number, ' '; } if ($options->{ID} and not $configuration->{PRINT_ID_AS_HEADING}) { my $formatted_id = sprintf $configuration->{ID_INLINE_FORMAT}, $id_value; if ($options->{COLORIZE_OUTPUT}) { $formatted_id = Term::ANSIColor::colored($formatted_id , $configuration->{COLORS}->{ID_COLOR}); } print $formatted_id, ' '; } if ($options->{COLORIZE_OUTPUT}) { print colorize_line($configuration, $line); } else { print $line; } print "\n"; } if ($line =~ $open_tag_regexp) { $id_value = limit_string_length($+{id_match}, $configuration->{ID_MAX_LENGTH}); $job_name = $+{job_match}; $source_line_number = $+{line_match}; $page_number = $+{page_match}; my $found_matching_id = ($id_value =~ m/(?$regexp_modifier)$id_regexp/) ? 1 : 0; push @nesting_levels, $found_matching_id; if ($found_matching_id) { ++$MATCH_COUNT; # global count -- needed for return code of program ++$match_count; # per file count -- needed to be able to separate the hunks print "\n" if $match_count >= 2; if ($options->{ID} and $configuration->{PRINT_ID_AS_HEADING}) { my $formatted_id = sprintf $configuration->{ID_HEADING_FORMAT}, $id_value; if ($options->{COLORIZE_OUTPUT}) { $formatted_id = Term::ANSIColor::colored($formatted_id, $configuration->{COLORS}->{ID_HEADING_COLOR}); } print $formatted_id, "\n"; } } } } return $match_count; } sub show_ids_in_file { my ($options, $configuration, $file, $filename, $id_regexp) = @_; my $encoder = find_encoder($options->{ENCODING}); my $line_number = 0; my $match_count = 0; my @nesting_levels; while (my $line = readline $file) { chomp $line; $line_number++; $line = Encode::encode_utf8($encoder->decode($line, Encode::FB_CROAK)) if $encoder; if ($line =~ $close_tag_regexp) { fail_with_error("$filename: $line_number: mismatched open/close tags") unless @nesting_levels; pop @nesting_levels; } if ($line =~ $open_tag_regexp) { my $id_value = limit_string_length($+{id_match}, $configuration->{ID_MAX_LENGTH}); my $job_name = $+{job_match}; my $source_line_number = $+{line_match}; my $page_number = $+{page_match}; ++$MATCH_COUNT; ++$match_count; push @nesting_levels, 1; if ($options->{LOG_LINE_NUMBER}) { my $formatted_log_line_number = sprintf $configuration->{LOG_LINE_NUMBER_FORMAT}, $line_number; if ($options->{COLORIZE_OUTPUT}) { $formatted_log_line_number = Term::ANSIColor::colored($formatted_log_line_number, $configuration->{COLORS}->{LOG_LINE_NUMBER}); } print $formatted_log_line_number, ' '; } print "$job_name: " if $options->{JOB_NAME}; if ($options->{LINE_NUMBER}) { my $formatted_line_number = sprintf $configuration->{LINE_NUMBER_FORMAT}, $source_line_number; if ($options->{COLORIZE_OUTPUT}) { $formatted_line_number = Term::ANSIColor::colored($formatted_line_number, $configuration->{COLORS}->{LINE_NUMBER}); } print $formatted_line_number, ' '; } if ($options->{PAGE_NUMBER}) { my $formatted_page_number = sprintf $configuration->{PAGE_NUMBER_FORMAT}, $page_number; if ($options->{COLORIZE_OUTPUT}) { $formatted_page_number = Term::ANSIColor::colored($formatted_page_number, $configuration->{COLORS}->{PAGE_NUMBER}); } print $formatted_page_number, ' '; } my $indent = $configuration->{ID_INDENT} * (@nesting_levels - 1); print ' ' x $indent, $id_value, "\n"; } } return $match_count; } sub open_file_for_reading { my $filename = shift; my $file; if ($filename eq 'stdin') { $file = IO::Handle->new(); $file->fdopen(fileno(STDIN), 'r') or fail_with_error("cannot open stdin: $OS_ERROR"); } else { $file = IO::File->new($filename, 'r') or fail_with_error("cannot open @{[quote_filesystem($filename)]}: $OS_ERROR"); } return $file; } sub close_file { my ($file, $filename) = shift; $file->close or issue_warning("problems while closing @{[quote_filesystem($filename)]}: $OS_ERROR"); } sub grep_or_show { my ($options, $configuration, $file, $filename, $id_regexp) = @_; if ($options->{SHOW_ALL_IDS}) { return show_ids_in_file($options, $configuration, $file, $filename, $id_regexp); } else { return grep_log_file($options, $configuration, $file, $filename, $id_regexp); } } sub scan_files { my ($options, $configuration, $id_regexp, $log_filenames) = @_; my $match_count = 0; if (@$log_filenames) { foreach my $log_filename (@$log_filenames) { $log_filename = 'stdin' if $log_filename eq '-'; if (@$log_filenames >= 2) { print "\n" unless $log_filename eq $log_filenames->[0]; my $filename_header = "==> $log_filename <==\n"; $filename_header = Term::ANSIColor::colored($filename_header, $configuration->{COLORS}->{FILE_HEADER}) if $options->{COLORIZE_OUTPUT}; print $filename_header; } my $file = open_file_for_reading($log_filename); $match_count += grep_or_show($options, $configuration, $file, $log_filename, $id_regexp); close_file($file, $log_filename); } } else { my $log_filename = 'stdin'; my $file = open_file_for_reading($log_filename); $match_count = grep_or_show($options, $configuration, $file, $log_filename, $id_regexp); close_file($file, $log_filename); } return $match_count; } sub redirect_and_scan_files { my ($options, $configuration, $id_regexp, $log_filenames) = @_; my $pager; my $pid = open($pager, '|-', $configuration->{PAGER}, $configuration->{PAGER_FLAGS}); fail_with_error('failed to redirect to pager ', quote_literal($configuration->{PAGER}), ' with flags ', quote_literal($configuration->{PAGER_FLAGS}), ": $OS_ERROR") unless defined $pid; my $stdout = select $pager; $pager->autoflush; my $match_count = scan_files($options, $configuration, $id_regexp, $log_filenames); close $pager or issue_warning "error occurred while closing the pager (pid: $pid) pipe: $OS_ERROR"; select $stdout; return $match_count; } ######################################################################## my $configuration_key_map = { 'id-format' => 'ID_INLINE_FORMAT', 'id-indent' => 'ID_INDENT', 'id-heading' => 'PRINT_ID_AS_HEADING', 'id-heading-format' => 'ID_HEADING_FORMAT', 'id-max-length' => 'ID_MAX_LENGTH', 'line-number-format' => 'LINE_NUMBER_FORMAT', 'log-line-number-format' => 'LOG_LINE_NUMBER_FORMAT', 'page-number-format' => 'PAGE_NUMBER_FORMAT', 'file-header-color' => 'FILE_HEADER', 'fill-state-color' => 'FILL_STATE', 'first-vbox-color' => 'FIRST_VBOX', 'font-spec-color' => 'FONT_SPEC', 'horizontal-break-candidate-color' => 'HORIZONTAL_BREAK_CANDIDATE', 'horizontal-breakpoint-color' => 'HORIZONTAL_BREAKPOINT', 'id-color' => 'ID_COLOR', 'id-heading-color' => 'ID_HEADING_COLOR', 'line-break-pass-color' => 'LINE_BREAK_PASS', 'line-number-color' => 'LINE_NUMBER', 'log-line-number-color' => 'LOG_LINE_NUMBER', 'math-color' => 'MATH', 'page-number-color' => 'PAGE_NUMBER', 'pager' => 'PAGER', 'pager-flags' => 'PAGER_FLAGS', 'tightness-color' => 'TIGHTNESS', 'vertical-breakpoint-color' => 'VERTICAL_BREAKPOINT' }; my $default_configuration = { COLORS => { FILE_HEADER => 'bold black', FILL_STATE => 'bold magenta', FIRST_VBOX => 'bold red', FONT_SPEC => 'grey12', HORIZONTAL_BREAKPOINT => 'bold green', HORIZONTAL_BREAK_CANDIDATE => 'blue', ID_COLOR => 'white on_black', ID_HEADING_COLOR => 'white on_black', LINE_BREAK_PASS => 'bold green', LINE_NUMBER => 'bold black', LOG_LINE_NUMBER => 'italic black', MATH => 'yellow', PAGE_NUMBER => 'bold white on_red', TIGHTNESS => 'bold cyan', VERTICAL_BREAKPOINT => 'red' }, ID_INLINE_FORMAT => '%s:', ID_HEADING_FORMAT => '--> %s <--', ID_INDENT => 8, ID_MAX_LENGTH => 40, LINE_NUMBER_FORMAT => '%5d', LOG_LINE_NUMBER_FORMAT => '%6d', PAGE_NUMBER_FORMAT => '[%3d]', PAGER => 'less', PAGER_FLAGS => '--quit-if-one-screen', PRINT_ID_AS_HEADING => 0 }; sub initialize_highlighting_from_configuration { my $configuration = shift; while (my (undef, $assoc) = each %$highlight_patterns) { while (my ($name, $pattern_color_pair) = each %$assoc) { $pattern_color_pair->[1] = $configuration->{COLORS}->{$name}; } } } sub modify_configuration { my ($configuration, $key, $value) = @_; fail_with_error('malformed KEY=VALUE pair -- missing key') unless $key; if (defined $configuration_key_map->{$key}) { if ($key =~ m/-color$/) { $configuration->{COLORS}->{$configuration_key_map->{$key}} = $value; } else { $configuration->{$configuration_key_map->{$key}} = $value; } } else { fail_with_error("@{[quote_literal($key)]} is not a valid configuration KEY"); } } sub setup_configuation { my ($config_spec, $configuration) = @_; foreach my $spec (split ':', $config_spec) { my ($key, $value) = split '=', $spec; modify_configuration($configuration, $key, $value); } } my $default_options = { COLORIZE_MODE => 'auto', DEBUG => 0, ENCODING => undef, ID => 0, IGNORE_CASE => 0, JOB_NAME => 0, LINE_NUMBER => 0, LOG_LINE_NUMBER => 0, PAGE_NUMBER => 0, REQUEST_PAGER => 1, WORD_REGEXP => 0 }; sub show_help { print <encodings(':all'); foreach my $encoding (@all_encodings) { print "$encoding\n"; } exit 0; } sub show_configuration { my $format_string_value = sub {quote_literal($default_configuration->{$_[0]})}; print <('ID_INLINE_FORMAT')]} id-heading $default_configuration->{PRINT_ID_AS_HEADING} id-heading-format @{[$format_string_value->('ID_HEADING_FORMAT')]} id-indent $default_configuration->{ID_INDENT} id-max-length $default_configuration->{ID_MAX_LENGTH} line-number-format @{[$format_string_value->('LINE_NUMBER_FORMAT')]} log-line-number-format @{[$format_string_value->('LOG_LINE_NUMBER_FORMAT')]} page-number-format @{[$format_string_value->('PAGE_NUMBER_FORMAT')]} pager @{[$format_string_value->('PAGER')]} pager-flags @{[$format_string_value->('PAGER_FLAGS')]} FIXED_CONFIGURATION_TEXT foreach my $configuration_key (sort keys %$configuration_key_map) { next unless $configuration_key =~ m/-color$/; printf("%-36s %s\n", $configuration_key, quote_literal($default_configuration-> {COLORS}-> {$configuration_key_map->{$configuration_key}})); } exit 0; } sub show_version { print < \$options->{SHOW_ALL_IDS}, 'color|colour=s' => \$options->{COLORIZE_MODE}, 'C|configuration=s' => sub{setup_configuation($_[1], $configuration)}, 'debug+' => \$DEBUG, 'E|encoding=s' => \$options->{ENCODING}, 'h|help' => \&show_help, 'i|id!' => \$options->{ID}, 'y|ignore-case!' => \$options->{IGNORE_CASE}, 'j|job-name!' => \$options->{JOB_NAME}, 'n|line-number!' => \$options->{LINE_NUMBER}, 'N|log-line-number!' => \$options->{LOG_LINE_NUMBER}, 'p|page-number!' => \$options->{PAGE_NUMBER}, 'P|pager!' => \$options->{REQUEST_PAGER}, 'show-encodings' => \&show_encodings, 'show-config' => \&show_configuration, 'V|version' => \&show_version, 'w|word-regexp!' => \$options->{WORD_REGEXP}) or fail_with_error('problems while parsing options'); if ($options->{COLORIZE_MODE}) { fail_with_error("unknown colorize mode @{[quote_literal($options->{COLORIZE_MODE})]}") unless $options->{COLORIZE_MODE} =~ m/^(?:always|auto|never)$/i; } else { $options->{COLORIZE_MODE} = 'auto'; } } sub do_colorize { my $colorize_mode = shift; if ($colorize_mode =~ m/never/i) { 0; } elsif ($colorize_mode =~ m/always/i) { 1; } elsif ($colorize_mode =~ m/auto/i) { not $OUTPUT_IS_REDIRECTED; } } ## For the comparison with the POSIX spec of grep(1) consult ## https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html sub main { $OUTPUT_IS_REDIRECTED = -t STDOUT ? 0 : 1; my $configuration = {%$default_configuration}; my $options = {%$default_options}; debug_print(Data::Dumper::Dumper(['Default Configuration', $configuration])); debug_print(Data::Dumper::Dumper(['Default Options', $options])); my $user_options = {}; my $user_configuration = {}; get_options($user_options, $user_configuration); debug_print(Data::Dumper::Dumper(['User Configuration', $user_configuration])); debug_print(Data::Dumper::Dumper(['User Options', $user_options])); while (my ($key, $value) = each %$user_options) { $options->{$key} = $value if $value; } while (my ($key, $value) = each %$user_configuration) { $configuration->{$key} = $value if $value; } debug_print(Data::Dumper::Dumper(['Final Configuration', $configuration])); debug_print(Data::Dumper::Dumper(['Final Options', $options])); $options->{COLORIZE_OUTPUT} = do_colorize($options->{COLORIZE_MODE}); initialize_highlighting_from_configuration($configuration); my $id_regexp; if ($options->{SHOW_ALL_IDS}) { $id_regexp = '^'; issue_warning("option @{[quote_literal('--id')]} ignored in @{[quote_literal('--all')]} mode") if $options->{ID}; } else { fail_with_error('missing ID-REGEXP') unless @ARGV >= 1; $id_regexp = shift @ARGV; } if ($user_options->{REQUEST_PAGER} && $OUTPUT_IS_REDIRECTED) { issue_warning("option @{[quote_literal('--pager')]} ignored because output is redirected"); } my $use_pager = $options->{REQUEST_PAGER} && !$OUTPUT_IS_REDIRECTED; my $match_count; if ($use_pager) { $match_count = redirect_and_scan_files($options, $configuration, $id_regexp, \@ARGV); } else { $match_count = scan_files($options, $configuration, $id_regexp, \@ARGV); } exit ($match_count == 0); } main(); % % \fi % % % % \iffalse %<*typog-grep-documentation> =begin man .\" Turn off justification. .na =end man =head1 NAME typog-grep - specialized grep for typog-inspect elements in LaTeX log files =head1 SYNOPSIS =over =item B -a|--all|--any [I