% \iffalse % % Copyright (C) 2024 by Ch. L. Spiel % % This work may be distributed and/or modified under the conditions % of the LaTeX Project Public License, either version 1.3 of this % license or (at your option) any later version. The latest version % of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2003/12/01 or later. % % \fi % % \iffalse %<*driver> \documentclass{ltxdoc} \tracingonline=0 %--\OnlyDescription \EnableCrossrefs \CodelineIndex \RecordChanges \PassOptionsToClass{a4paper}{article} \PassOptionsToPackage{hyperfootnotes=false}{hyperref} \PassOptionsToPackage{charter, scale=1.06}{newtxmath} \PassOptionsToPackage{dvipsnames}{xcolor} \usepackage{amsmath} \usepackage{amssymb} \usepackage{array} \usepackage{booktabs} \usepackage{caption} \usepackage{dtk-logos} \usepackage{enumitem} \usepackage{etoolbox}%--\tracingpatches \usepackage{fancyhdr} \usepackage[T1]{fontenc} \usepackage{fullwidth} \usepackage{hypdoc} \usepackage{hyphenat} \usepackage[shrink=10, stretch=10]{microtype} \usepackage{multirow} \usepackage{needspace} \usepackage{placeins} \usepackage{ragged2e} \usepackage{setspace} \usepackage{sidecap} \usepackage{tabularx} \usepackage{tcolorbox} \usepackage{titlesec}\renewcommand*{\bottomtitlespace}{.15\textheight}%nobottomtitles* \usepackage[debug, raise*=.05em]{typog} \usepackage{xcolor} \usepackage[default, lining, proportional, regular, semibold]{sourceserifpro} \usepackage[lining, proportional, regular, semibold]{sourcesanspro} \usepackage[lining, regular]{sourcecodepro} \usepackage[xcharter]{newtxmath} \setbaselineskip{12.5pt} \makeatletter \def\@get@fontclan#1-#2\relax{#1} \newcommand*{\fontclan}{\expandafter\@get@fontclan\f@family\relax} \makeatother \newcommand*{\proportionalliningfigures}{\fontfamily{\fontclan-LF}\selectfont} \newcommand*{\proportionaloldstylefigures}{\fontfamily{\fontclan-OsF}\selectfont} \newcommand*{\tabularliningfigures}{\fontfamily{\fontclan-TLF}\selectfont} \newcommand*{\tabularoldstylefigures}{\fontfamily{\fontclan-TOsF}\selectfont} \newcommand*{\textdenominator}[1]{{\fontfamily{\fontclan-Dnom}\selectfont #1}} \newcommand*{\textinferior}[1]{{\fontfamily{\fontclan-Inf}\selectfont #1}} \newcommand*{\textnumerator}[1]{{\fontfamily{\fontclan-Numr}\selectfont #1}} \newcommand*{\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} \newcommand*{\elseries}{\def\mdseries@rm{el}\def\mdseries@sf{el}\def\mdseries@tt{el}} \newcommand*{\textel}[1]{{\elseries\textmd{#1}}} \newcommand*{\lseries}{\def\mdseries@rm{l}\def\mdseries@sf{l}\def\mdseries@tt{l}} \newcommand*{\textl}[1]{{\lseries\textmd{#1}}} %%--\newcommand*{\mdseries}{\def\mdseries@rm{m}\def\mdseries@sf{m}\def\mdseries@tt{m}} %%--\newcommand*{\textmd}[1]{{\mdseries\textmd{#1}}} \newcommand*{\sbseries}{\def\bfseries@rm{sb}\def\bfseries@sf{sb}\def\bfseries@tt{sb}} \newcommand*{\textsb}[1]{{\sbseries\textbf{#1}}} \newcommand*{\bseries}{\def\bfseries@rm{b}\def\bfseries@sf{b}\def\bfseries@tt{b}} \newcommand*{\textb}[1]{{\bseries\textbf{#1}}} \newcommand*{\ebseries}{\def\bfseries@rm{k}\def\bfseries@sf{eb}\def\bfseries@tt{k}} \newcommand*{\texteb}[1]{{\ebseries\textbf{#1}}} \makeatother \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 = false, 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 } \makeatletter \renewcommand*{\@dotsep}{10000} % suppress leaders \patchcmd{\@dottedtocline}{\normalfont}{\bfseries}{\relax}{\PatchingFailed} \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}{ \fancyhead[L]{} \fancyhead[R]{\thepage} } \pagestyle{fancy} \fancyhf{} \fancyhead[L]{\rightmark} \fancyhead[R]{\thepage} \newcommand*{\resetfancyhead} {\fancyhead[L]{\textsf{\textsc{\textls[20]{\nouppercase\rightmark}}}}} \renewcommand*{\headrulewidth}{0pt} \renewcommand*{\sectionmark}[1] {\def\truesectionname{#1}% \markright{\textsf{\marginalizesectionnumber{\thesection}% \textsc{\textls[20]{#1}}}}} \renewcommand*{\subsectionmark}[1] {\markright{\textsf{\marginalizesectionnumber{\thesubsection}% \textsc{\textls[20]{\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}{} \let\footnoterule=\relax% suppress footnote rule \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}{3pt} \renewcommand*{\sidecaptionsep}{16pt} \newrobustcmd*{\acronym}[1]{\mbox{\scshape\MakeLowercase{#1}}} \newcommand*{\application}[1]{\mbox{\sffamily #1}} \renewcommand*{\arraystretch}{1.12} \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 \centering \begin{minipage}{\linewidth} \ttfamily \begin{tabbing}} {\end{tabbing} \end{minipage} \par \vspace{.5\smallskipamount}} \makeatletter \newcommand*{\citenum}[1]{\@nameuse{b@#1}} \makeatother \def\code#1{\texttt{#1}} \newrobustcmd*{\command}[1]{\mbox{\textbf{#1}}} \newcommand*{\doublequotes}[1]{\doubleguillemetright\kern-.03333em #1\doubleguillemetleft} \newcommand*{\dumpmacro}[1]{\texttt{\detokenize\expandafter{#1}}} \newcommand*{\filesystem}[1]{\mbox{\textit{#1\/}}} \newcommand*{\filledrectangle}[2]{\rule{#1}{#2}} \newcommand*{\filledsquare}[1]{\filledrectangle{#1}{#1}} \newcommand*{\foreignphrase}[1]{\textsl{#1}} \newcommand*{\formatskip}[3]{#1\genfrac{}{}{0pt}{}{{+}#2}{{-}#3}} \makeatletter \renewcommand*{\fps@figure}{htbp} \renewcommand*{\fps@table}{htbp} \makeatother \newcommand*{\hollowrectangle}[2] {\setlength{\fboxrule}{.5pt}% \setlength{\fboxsep}{0pt}% \framebox{\rule{#1}{0pt}\rule{0pt}{#2}}} \newcommand*{\hollowsquare}[1]{\hollowrectangle{#1}{#1}} \makeatletter \apptocmd{\index@prologue} {\marginnote{In the Index page ranges are stuck together with \hyperref[syn:figuredash]{\cs{figuredash*}}.}} {\relax} {\AppendingFailed} \makeatother \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} {\setstretch{1}%\overfullrule=0pt \sffamily \footnotesize \nofontexpansion \slightlysloppy[1] \loosespacing[1] \setlength{\smoothraggedrightragwidth}{1.5em} \def\smoothraggedrightgenerator{quintuplet}% \smoothraggedrightpar} \newcommand*{\marginnote}[1]{\marginpar{\marginnoteformat #1}} \addtolength{\marginparpush}{3pt} \addtolength{\marginparsep}{25pt} \addtolength{\marginparwidth}{-20pt} \newcommand*{\shiftedmarginnote}[1] {\marginpar{\moveleft \leftmargin \hbox{\parbox{\dimexpr\marginparwidth - \marginparsep} {\marginnoteformat #1}}}} \newenvironment*{maxipage} {\fullwidthsetup{leftmargin=-\marginparsep - \marginparwidth, width=\textwidth + \marginparsep + \marginparwidth}% \begin{fullwidth}} {\end{fullwidth}} \newcommand*{\microtyperequiredmarker} {\mbox{\normalfont\packagename{microtype}~req.}} \newlength{\emreference} \AtBeginDocument{\setlength{\emreference}{\fontdimen6\font}} \newrobustcmd*{\milliem}[1] {\ifdim #1=0pt #1% \else \nativetextfraction{\the\numexpr\dimexpr (#1) * 1000 / \emreference}{1000}\:em% \fi} \newcommand*{\needtocspace}[1][3] {\addtocontents{toc}{\protect\needspace{#1\baselineskip}}} \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*{\sectionfinish} {\vfill {\centering \textcolor{customred4} {\filledsquare{5pt}\enspace\filledsquare{5pt}}% \par}% \vfill} \let\sectionfinish=\relax \newcommand*{\sinceversion}[1]{% modeled after \NewIn of "doc.dtx" \leavevmode \marginpar{\hfill\textcolor{\markercolor}{\sf\scshape\proportionaloldstylefigures #1}}% \ignorespaces } \newcommand*{\singlequotes}[1]{\mbox{\singleguillemetright #1\singleguillemetleft}} \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}} \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 \& 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}[colback=white, colframe=\markercolor, bottomrule=0pt, leftrule=5pt, rightrule=0pt, toprule=0pt] \sf\typogsetupsf \begin{list} {\specialcodesectionheading{#1}} {\itemindent=0pt \labelwidth=20pt \leftmargin=25pt \listparindent=15pt \parsep=0pt \topsep=\medskipamount} \item \nointerlineskip \leavevmode\par \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*{\termparbox}[1]{\parbox[t]{\linewidth}{#1\bottomstrut}} \newcommand*{\thousandsseparator}{\mbox{,}} \newcommand*{\topstrut}{\rule{0pt}{1.3em}} \newcommand*{\typogsetuprm} {\typogsetup{raise*=.025em, raisecapitalguillemets=.05em, raiseguillemets=.03333em, raisefiguredash=.05em}} \newcommand*{\typogsetupsf} {\typogsetup{raise*=.06667em, raiseguillemets=.05em}} \newcommand*{\visualpar}{\textcolor{\markercolor}{\P}\linebreak[1]\enspace} \newenvironment*{whittyquote} {\begin{flushright} \renewcommand*{\propername}[1]{\mbox{##1}}% \sf\typogsetupsf} {\end{flushright}} \newenvironment*{widecodeexample} {\begin{maxipage} \flushright \begin{minipage}{\textwidth} \ttfamily \begin{tabbing}} {\end{tabbing} \end{minipage} \end{maxipage}} \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} \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-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-ragged-left last-line-ragged-left-par line-width loose-ness loose-spacing make-at-letter make-at-other mar-gin-al math-italics-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-number-dash set-baseline-skip set-baseline-skip-percentage set-font-expand set-font-shrink set-font-stretch set-leading set-leading-percentage short-inter-text 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-par smooth-ragged-right-shape-quintuplet smooth-ragged-right-shape-septuplet smooth-ragged-right-shape-triplet space-skip text-italics-correction tight-spacing tracing-boxes tracing-para-graphs tracking-tt-spacing typog-get typog-setup 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 \DocInput{typog.dtx} \end{document} % %<*index-style> actual '=' delim_r "\\figuredash*" heading_prefix "\\pagebreak[3]\\smallskip\n\n{\\sffamily\\bfseries\\large " heading_suffix "}\\nopagebreak\n" headings_flag 1 level '>' quote '!' % % \fi % % % \DoNotIndex{\,} % \DoNotIndex{\addtolength,\advance,\aftergroup,\allowdisplaybreaks,\arabic} % \DoNotIndex{\AtBeginDocument,\autotransfer} % \DoNotIndex{\baselineskip} % \DoNotIndex{\c,\char,\clubpenalties,\clubpenalty,\count,\cs,\csname} % \DoNotIndex{\DeclareRobustCommand,\def,\define@choicekey,\define@key,\detokenize} % \DoNotIndex{\dim,\dimen,\dimexpr,\discretionary,\displaywidowpenalties,\displaywidowpenalty} % \DoNotIndex{\edef,\else,\emergencystretch,\empty,\endcsname} % \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,\fp,\fussy,\futurelet} % \DoNotIndex{\gdef,\global,\glueexpr,\@gobble} % \DoNotIndex{\guillemotleft,\guillemotright,\guilsinglleft,\guilsinglright} % \DoNotIndex{\hbadness,\hfuzz,\hskip,\hspace} % \DoNotIndex{\ignorespaces,\ignorespacesafterend} % \DoNotIndex{\if,\IfBooleanT,\IfBooleanTF,\ifcase,\ifdefined,\ifdim,\iffalse,\ifmmode,\ifMT@expansion} % \DoNotIndex{\@ifnextchar,\IfNoValueF,\IfNoValueTF,\ifnum} % \DoNotIndex{\iftypog@microtype@loadedfalse} % \DoNotIndex{\iftypog@microtype@preloadedfalse} % \DoNotIndex{\ifvmode,\ifx,\ignorespaces,\inputlineno,\int,\interlinepenalty} % \DoNotIndex{\jobname} % \DoNotIndex{\kern} % \DoNotIndex{\l,\lastlinefit,\lastlineflushrightpar,\lastlineraggedleftpar,\leftmargin,\leftskip,\let} % \DoNotIndex{\linepenalty,\linewidth,\@listdepth,\looseness,\lsstyle} % \DoNotIndex{\@M,\m@th,\mathbin,\mathord,\maxdimen,\message,\microtypecontext,\microtypesetup} % \DoNotIndex{\@minus,\mkern,\m@ne,\mspace,\MT@letterspace@,\MT@MT,\muexpr} % \DoNotIndex{\@ne,\NeedsTeXFormat,\NewDocumentCommand,\NewDocumentEnvironment,\newcommand,\newenvironment} % \DoNotIndex{\newcounter,\newdimen,\newif,\newlength,\newmuskip} % \DoNotIndex{\nobreak,\nofontexpand,\nofontexpansion,\nr,\numexpr} % \DoNotIndex{\or,\optarg} % \DoNotIndex{\p@,\PackageError,\PackageWarning} % \DoNotIndex{\par,\parfillskip,\parindent,\parshape,\pdf@strcmp} % \DoNotIndex{\pdfstringdefDisableCommands} % \DoNotIndex{\penalty,\@plus,\PopPostHook,\postdisplaypenalty,\predisplaypenalty,\prg} % \DoNotIndex{\pretolerance,\protected,\ProvidesPackage,\PushPostHook} % \DoNotIndex{\raisebox,\refstepcounter,\relax,\RenewExpandableDocumentCommand,\RequirePackage,\rightskip} % \DoNotIndex{\setcounter,\SetEnumitemKey,\SetExpansion,\setkeys,\setlength,\setstretch} % \DoNotIndex{\showboxbreadth,\showboxdepth,\skip,\sloppy} % \DoNotIndex{\smoothraggedrightpar} % \DoNotIndex{\smoothraggedrightshapequintuplet} % \DoNotIndex{\smoothraggedrightshapeseptuplet} % \DoNotIndex{\smoothraggedrightshapetriplet} % \DoNotIndex{\space,\spaceskip,\stepcounter,\@strength,\string} % \DoNotIndex{\textemdash,\textendash,\textsf,\textsl,\texttimes,\textwidth,\the,\times,\tl,\tolerance} % \DoNotIndex{\tracingnone,\tracingpages,\tracingparagraphs} % \DoNotIndex{\typeout,\typoginspect,\typoglogo} % \DoNotIndex{\unless} % \DoNotIndex{\val,\value,\vbadness,\vfuzz} % \DoNotIndex{\widowpenalties,\widowpenalty} % \DoNotIndex{\z@,\z@skip} % % % \changes{v0.1}{2024-3-7}{Initial version.} % % % \pagenumbering{roman} % % \title{\typoglogo{} \capitalendash{} Typographic Fine\rightkernedhyphen*[20]{-120}Tuning} % \author{Ch.~L.~Spiel\footnote{\quarterspace\texttt{cspiel@users.sourceforge.org}}} % \date{\fileversion\qquad \filedate} % \maketitle % \thispagestyle{empty} % % \begingroup % \let\small=\normalsize % \begin{abstract} % \begin{lastlinecenteredpar} % \noindent % Package~\packagename{typog} provides macros and environments for % \mbox{(micro-)\itcorr{2}}\breakpoint typographic enhancements. It also supplies some % means to avoid common typographic problems as, for example, orphan or widow lines. % Moreover it supplies high-level front-ends for packages~\packagename{microtype} and % \packagename{setspace}. % \end{lastlinecenteredpar} % \end{abstract} % \endgroup % % % \iffalse %<*title> prologues := 3; truecorners := 1; linecap := butt; string roman_font; roman_font := "pplr8r"; % URW Palladio L - Roman string italics_font; italics_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 % % % \vspace*{20pt} % % \begin{center} % \includegraphics{title-1.mps} % \end{center} % % \vfill % % \begin{lastlinecenteredpar} % \footnotesize % \noindent % This package is copyright \textcopyright~2024 Ch.~L.~Spiel. It may be distributed % and\kernedslash*or modified under the conditions of the \LaTeX{} Project Public License % \acronym{(LPPL)}, either version~1.3c of this license or --~at your option~-- any later % version. This work has the \acronym{LPPL} maintenance status % \doublequotes{author-maintained}. % \end{lastlinecenteredpar} % % % \clearpage % \thispagestyle{pagenumberonly} % \tableofcontents % \vspace{\fill} % % % \thispagestyle{pagenumberonly} % \listoftables % \phantomsection % \addcontentsline{toc}{subsection}{List of Tables} % \vspace{\fill} % % % \begingroup % \footnotesize % \singlespacing % \noindent % The font sample on the title page was generated with the help of \MP{} using % \doublequotes{\acronym{URW} Palladio~L}\index{font>URW Palladio L=\acronym{URW} Palladio % L}. % \endgroup % % % \clearpage % \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 -- not the end. This package provides some % tools for even better looking documents. When applied correctly its effects appear subtle % and inconspicuous. % % % \subsection{Overview}\label{sec:overview} % % Package~\packagename{typog} focuses on (micro-)typographic improvements. % % \Cref{sec:information} tends to the wish 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 features in the margin. All these % notes are examples themselves as they are typeset with % \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,sec:extra-kerning,sec:raise-characters} % deal with vertically positioning glyphs in a more pleasant way. % % \Cref{sec:align-last-line,sec:fill-last-line} discuss dearly missed macros for better control % of the last line of a paragraph. % % \Cref{sec:spacing-control} covers the manipulation of the length of a paragraph. % % \Cref{sec:microtype-frontend} expounds on 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 special 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 still is experimental. % % % \subsection{Prerequisites}\label{sec:packageprerequisites} % % Package \packagename{typog} requires \eTeX; it relies on the \LaTeXIII{}~interface. Parts of % it are based on package~\packagename{microtype}. However, if the respective 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-2.6-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} % % Package \packagename{typog} does not override any existing macros or environments when % loaded, unless explicitly told by a package option. % % \begin{synopsis} % \begin{tabbing} % |\usepackage[|\,\dots|]{microtype}| % \=\texttt{\%\space}\textit{Only required for macros and} \\ % \>\texttt{\%\space}\textit{environments in \cref{sec:microtype-frontend}.} \\ % \\[-.5em] % |\usepackage[|\,\dots|]{setspace}| % \=\texttt{\%\space}\textit{Only required for macros in \cref{sec:setspace-frontend}.} \\ % \\[-.5em] % |\usepackage[|\meta{OPTION}\dots|]{typog}| % \end{tabbing} % \end{synopsis} % % \index{package options|(} % The package \meta{OPTIONs} serve as configuration \meta{key}s, too. 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}{} % \newcommand*{\indexpackageoption}[1] % {\index{package option>#1=\code{#1}}\index{#1=\code{#1}~(option)}\ignorespaces} % \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} % \indexpackageoption{penalty} % \shiftedmarginnote{This sub-section 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} % \indexpackageoption{debug} % \indexpackageoption{nodebug} % Write package-specific debug information to the log file. Opposite: |nodebug|. The % default is not to log debug information. % % \item[|ligaturekern=|\meta{dim}]\label{item:ligaturekern} % \indexpackageoption{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}.\shiftedmarginnote{We access the configuration values with % \hyperref[syn:typogget]{\cs{typogget}}.} Default % value:~\milliem{\typogget{ligaturekern}}. % % \item[|mathitalicscorrection=|\meta{dim}]\label{item:mathitalicscorrection} % \indexpackageoption{mathitalicscorrection} % Italics correction in math mode. See \cref{sec:manual-italic-correction} and also the % complementary configuration % option~\hyperref[item:textitalicscorrection]{|textitalicscorrection|}. Default % value:~\the\typogget{mathitalicscorrection}.\footnote{Note that 1\,mu is % \nativetextfraction{1}{18}\,em of the mathematical font's~em.} % % \item[|raise*=|\meta{dim}]\label{item:raise} % \indexpackageoption{raise*} % Set the length by which selected characters (dash, hyphen, times, and number dash) are % raised. Default value:~0pt. % % Only the raise amounts for guillemets are unaffected by this option. % % \item[|raisecapitaldash=|\meta{dim}]\label{item:raisecapitaldash} % \indexpackageoption{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[|raisecapitalhyphen=|\meta{dim}]\label{item:raisecapitalhyphen} % \indexpackageoption{raisecapitalhyphen} % Set the length that the hyphen character~\sample{-} is raised in % \hyperref[syn:capitalhyphen]{\cs{capitalhyphen}}. See % \cref{sec:capital-hyphen}.\shiftedmarginnote{This description list is protected against % breaking items across pages within the first three lines by % \hyperref[syn:vtietop]{\code{vtietop}}.} Default % value:~\milliem{\the\typogget{raisecapitalhyphen}}. % % \item[|raisecapitaltimes=|\meta{dim}]\label{item:raisecapitaltimes} % \indexpackageoption{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[|raisecapitalguillemets=|\meta{dim}]\label{item:raisecapitalguillemets} % \indexpackageoption{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[|raiseguillemets=|\meta{dim}]\label{item:raiseguillemets} % \indexpackageoption{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[|raisefiguredash=|\meta{dim}]\label{item:raisefiguredash} % \indexpackageoption{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[|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} % \indexpackageoption{shrinklimits} % \indexpackageoption{stretchlimits} % Set the three limits, given in \nativetextfraction{1}{1000}\,em, of shrinkability and % stretchability for the respective levels. They are used in % \hyperref[syn:setfontshrink]{\code{setfontshrink}} (|shrinklimits| triple only), % \hyperref[syn:setfontstretch]{\code{setfontstretch}} (|stretchlimits| triple only), and % \hyperref[syn:setfontexpand]{\code{setfontexpand}} (both triples of limits). 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 \smash{\sample{*}} 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} % \indexpackageoption{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[|textitalicscorrection=|\meta{dim}]\label{item:textitalicscorrection} % \indexpackageoption{textitalicscorrection} % Italics 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:mathitalicscorrection]{|mathitalicscorrection|}. Default % value:~\milliem{\typogget{textitalicscorrection}}. % % \item[|trackingttspacing=|\code{\{\meta{outer-spacing}\}}\quad\microtyperequiredmarker]\label{item:trackingttspacing} % \indexpackageoption{trackingttspacing} % Set the outer spacing of all typewriter fonts if used in environment~\code{settracking} % 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 it % 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. % \end{description} % \end{typogsetup} % \index{package options|)} % % % \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 \code{\dots par} % issues a \cs{par} at its end. Environments with different name suffixes never close % with~\cs{par}. % % \bigskip % % \noindent % \DescribeEnv{typogsetup} % Configure\index{configuration}\index{setup} 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} % \dots{} % \cs{end}|{typogsetup}| % \end{synopsis} % % The package can be (re-)configured\index{reconfigure} at any point with % \cs{typogsetup}\marg{keys}, or --~for localized changes~-- as % % \begin{codeexample} % 12\=\kill % \cs{begin}|{typogsetup}|\marg{keys} \\ % \> \dots \\ % \cs{end}|{typogsetup}| % \end{codeexample} % % \noindent % where \meta{keys} have the same format as the package options described in % \cref{sec:package-options}. % % \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 gets attached to font-changing macros % like \cs{rm}, \cs{sf},~etc. % \end{usecases} % % % \noindent % \DescribeMacro{\typogget} % Sometimes the user needs to access internal configuration values of % package~\packagename{typog}. This can be done in a safe way without resorting to code that % is bracketed by \cs{makeatletter}/\cs{makeatother} with the help 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. % \end{usecase} % % % \subsection{Information}\label{sec:information}\index{information} % % \begin{whittyquote} % Never forget: The visual output counts; \\ % it must always be checked, [\dots]. \\ % \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 introspection of the typesetting process. % % % \subsubsection{Font Information}\label{sec:font-information} % \index{font>information} % % \DescribeMacro{\fontsizeinfo} % Capture the font~size\footnote{We use \cs{fontdimen6}, the em-height as the font % size.}\index{font>size} and line~spacing\footnote{The line~spacing simply is % \cs{baselineskip}.}\index{line spacing} at the point where \cs{fontsizeinfo} \emph{is called} % in macro~\meta{cs-name}. Both dimensions are measured in points~(pt) and the results are % rounded to tenths. % % \begin{synopsis}\label{syn:fontsizeinfo} % \cs{fontsizeinfo}\marg{cs-name} % \end{synopsis} % % The call to \cs{fontsizeinfo} introduces a pair of macros to access the stored values. The % unstarred version~\cs{cs-name} expands to the lengths including their units (i.\,e.,~pt), the % starred version~\cs{cs-name*} 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 can assist the user % in identifying typographic problems in a quantitative way without getting distracted by % unrelated information in the trace or the \filesystem{log}-file. % % \begin{synopsis}\label{syn:typoginspect} % \cs{begin}|{typoginspect}|\oarg{option}\marg{id} % \dots{} % \cs{end}|{typoginspect}| \\[\smallskipamount] % \cs{begin}|{typoginspectpar}|\oarg{option}\marg{id} \\ % \hspace*{1em}\dots \\ % \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 the 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. % \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} % \\ % ~~\dots \\ % % \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 ferret out the tags. \propername{Emacs} users will find % \mbox{\code{(occur \meta{regexp})}} to be useful. % % \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. % % We reproduce the complete manual page of \programname{typog-grep} 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 respective command-line. % % \item If more trace information is needed just add \cs{tracing\dots} calls right after % \code{\string\begin\{typoginspect\}} % or~\code{\string\begin\{typoginspectpar\}}.\specialsectionendhere % \end{itemize} % \end{tips} % % % \phantomsection % \paragraph{Investigating the badness of a paragraph.}\label{sec:investigating-paragraph-badness}\index{paragraph>badness} % % 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 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 \code{s}, \code{a}, or~\code{g}. 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 feature 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) \dots % \end{codeexample} % % or % % \begin{codeexample} % \textbackslash T1/erewhon-LF/m/n/9/@/@/10ls (+7) \dots % \end{codeexample} % % An \sample{ls} appended to the font name specification indicates that % \packagename{microtype}'s letter~spacing feature is active and changed the tracking by that % many thousands on an em as indicated before~\sample{ls}. % \end{note} % % % \paragraph{Investigating page-breaks.}\index{page break} % % 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} % % \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} % \cs{allowhyphenation} % \end{synopsis} % % Macro~\cs{allowhyphenation}\index{hyphenation>re-enable automatic} re-enables automatic % hyphenation after \TeX{} has turned it off, for example, in the innocuous case of a % hyphenated compound. % % The admittedly simple rules when \TeX{} auto-hyphenates and when 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} % All examples from the bottom of \cref{tab:hyphens-and-hyphenations} on % \cpageref{tab:hyphens-and-hyphenations}.~\visualpar % % Fix line breaks of index-entries in a narrow index: % % \begin{codeexample} % Halbgruppe, Transformations\cs{allowhyphenation}\cs{mbox}\{-\}\cs{,}-\nolig*-\nolig*- % \end{codeexample} % % \noindent % 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.~\visualpar % % Re-enable hyphenation when a macro decays into a \cs{hbox}: % % \begin{codeexample} % Einselement\cs{allowhyphenation}\cs{rlap}\{,\}\cs{footnote}\{\dots\} % \end{codeexample} % % where \cs{rlap} is equivalent to something like % \code{\cs{makebox}[0pt]\{\#1\cs{hss}\}}.~\visualpar % % 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} % % \noindent % A common trick to sweet-talk \TeX{} into hyphenating the first word of a paragraph is to % put \cs{hskip0pt} in front of it. % \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 un-breakable \\ % % \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 hyphenatable \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. % % \begin{tip}[Typewriter Fonts] % Sometimes it is desired to get a hyphenatable typewriter font. \LaTeX{} suppresses any % hyphenation for fonts in \cs{ttfamily} by un-defining their \cs{hyphenchar}s. If these are % reassigned, the usual 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 so helpful that it deserves its own macro --~with a descriptive name. % % \begin{synopsis} % \cs{breakpoint} \\ % \cs{breakpoint*} % \end{synopsis} % % The starred form inserts an empty discretionary,\index{hyphenation>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}\dots \\ % \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, respectively.} % % \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. % \end{usecase} % % % \subsection{Disable\kernedslash Break Ligatures}\label{sec:break-ligatures} % \index{ligature} % % \DescribeMacro{\nolig*} % Break a ligature without introducing a hyphenation opportunity. % % \begin{synopsis}\label{syn:nolig-star} % \cs{nolig*}\oarg{kerning} % \end{synopsis} % % Inserting \cs{nolig*} disables a ligature at the given point by a kern. Set the size of the % kern\index{kerning>ligature} with \hyperref[item:ligaturekern]{|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} % % 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]\index{hyperref=\packagename{hyperref} (package)} % If a \cs{nolig} --~whether starred or un-starred~-- occurs in an argument that is processed % with package~\packagename{hyperref} for inclusion into the document's % \acronym{PDF}-bookmarks\index{PDF=\acronym{PDF}}\index{bookmark} an additional argument is % necessary to parse the macro. This argument either is \cs{relax} or~the empty % group~(\code{\{\}}). % % \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 bail out with an error if the extra argument is not passed to \cs{nolig} in % these situations. % % 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.~\visualpar It also has proven beneficial in separating pairs of characters that are % kerned to tightly (e.\,g.~the \sample{ij}, as in bi\itcorr{2}jection, which is particularly % distractive here, for it occurs at the boundary of two syllables). % \end{usecases} % % % \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 a helping hand. % % \begin{synopsis}\label{syn:itcorr} % \cs{itcorr}\marg{strength} \\ % \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. If \cs{fontdim1} happens to be zero (e.\,g.~for an % upright font), \cs{itcorr} uses the value set with % \hyperref[item:textitalicscorrection]{\code{textitalicscorrection}} instead of \cs{fontdim1}. % The starred version always uses % \hyperref[item:textitalicscorrection]{\code{textitalicscorrection}}. In math mode % macro~\cs{itcorr} uses the value set with % \hyperref[item:mathitalicscorrection]{\code{mathitalicscorrection}}\footnote{Separate % adjustments may be desirable if the math font's italics have markedly different slants.} in % both the starred and the unstarred form. % % Typical slant angles of serif italics fonts range from 8\textdegree{} to~18\textdegree{} and % thus values for |textitalicscorrection| 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 italics, i.\,e., compensate \doublequotes{shift-to-the-right effect} of % italics.~\visualpar Positive correction at the left-hand side of italics, 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?} So, \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 italics collide with other --~usually non-italics~-- 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 italics_font; italics_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 italics_font scaled font_scale, loc[1]); picture letter_L; letter_L := thelabel.top("L" infont italics_font scaled font_scale, loc[2]); picture letter_a; letter_a := thelabel.top("a" infont italics_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 italics correction is. % % \begin{figure} % \centering % \includegraphics{slant-angle-1.mps} % \caption[Some letters of an italics font.] % {Some letters of an italics 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 % italics 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\) --~despite being a member of the same font~-- 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 with the help of % \hyperref[syn:lastlinecenteredpar]{\code{lastlinecenteredpar}}.} % \hspace*{\marginparsep}} % \end{figure} % % % \subsection{Apply Extra Kerning}\label{sec:extra-kerning} % \index{kerning>extra} % % Package \packagename{typog} supplies two sets of macros to kern some of the punctuation % symbols. One is for forward slashes the other, more extensive one, for hyphens. % % % \subsubsection{Slash}\label{sec:slash-with-kern} % \index{kerning>forward slash} % % \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} \\ % \cs{kernedslash*} % \end{synopsis} % % The starred form is unbreakable, the non-starred version introduces a break point with % penalty~\hyperref[item:breakpenalty]{|breakpenalty|} after the slash. Configure the kerning % around the slash with~\hyperref[item:slashkern]{|slashkern|}. % % 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}). % \end{usecases} % % % \subsubsection{Hyphen}\label{sec:hyphen-with-kern} % \index{kerning>hyphen} % % \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}. In text mode the special argument~\sample{|*|} for \meta{raise} % transfers 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 appropriate other % 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} \\ % \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} % % % \subsection{Raise Selected Characters}\label{sec:raise-characters} % \index{raised character} % % 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 allow typsetting these characters % at a user definable, adjusted height above the baseline. Users can base their own % definitions of raised characters on their associated dimensions.\footnote{Also compare with % Ex.~12 in Ref.~\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} % % \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} \\ % \cs{capitalhyphen*} % \end{synopsis} % % 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} % % % \subsubsection{Capital Dash}\label{sec:capital-dash} % \index{raised character>en-dash} % % \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} % % The unstarred version introduces a hyphenation opportunity right after the dash (with % penalty~\hyperref[item:breakpenalty]{|breakpenalty|}) whereas the starred version does not. % The actual amount the hyphen gets raised in \cs{capitaldash} is determined by % \hyperref[item:raisecapitalhyphen]{|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} % % \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} \\ % \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} % % % \subsubsection{Number Dash (Figure Dash)}\label{sec:number-dash} % \index{raised character>number dash} % % \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 --~depending on the font~-- 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} \\ % \cs{figuredash*} % \end{synopsis} % % The unstarred version introduces a hyphenation opportunity right after the en-dash with % penalty~\hyperref[item:breakpenalty]{|breakpenalty|} whereas the starred version does not. % The actual amount the en-dash gets raised in \cs{figuredash} is determined by % \hyperref[item:raisefiguredash]{|raisefiguredash|}. % % Values of .05em to .1em are typical for fonts that need this kind of correction and~.1em 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 the en-dash between lining numerals of some selected % fonts.} % \label{tab:raisefiguredash} % % \begin{tabfigures} % \begin{tabular}{@{}l>{\RaggedRight}p{20em}@{}} % \toprule % Raise & Font Name \\ % em & \\ % \midrule % 0 & Alegreya\index{font>Alegreya}, Arvo\index{font>Arvo}, % Bitter\index{font>Bitter}, Clara\index{font>Clara}, % \acronym{EB}~Garamond\index{font>EB Garamond=\acronym{EB} Garamond}, % Gentium\index{font>Gentium}, % Ibarra Real Nova\index{font>Ibarra Real Nova}, % \acronym{Inria}~Serif\index{font>Inria Serif=\acronym{Inria} Serif}, % Libertine\index{font>Libertine}, Libertinus\index{font>Libertinus}, % Merriweather\index{font>Merriweather}, % \acronym{PT}~Serif\index{font>PT Serif=\acronym{PT} Serif}, % Roboto Slab\index{font>Roboto Slab}, Spectral\index{font>Spectral}, % \acronym{STIX}\index{font>STIX=\acronym{STIX}}, and many more \\ % .05 & fbb\index{font>fbb}, Source Serif Pro\index{font>Source Serif Pro} \\ % .0667 & Libre Baskerville\index{font>Libre Baskerville}, % Crimson Pro\index{font>Crimson Pro}, % Erewhon\index{font>Erewhon}, Droid Serif\index{font>Droid Serif} \\ % .1 & \acronym{GFS}~Artemisia\index{font>GFS Artemisia=\acronym{GFS} Artemisia}, % Libre Caslon\index{font>Libre Caslon}, % Coelacanth\index{font>Coelacanth}, Crimson Pro\index{font>Crimson Pro}, % Crimson Text\index{font>Crimson Text}, % \TeX{} Gyre~Pagella\index{font>TeX Gyre Pagella=\TeX{} Gyre Pagella}, % Quattrocento\index{font>}, % \acronym{TX}~Fonts\index{font>TX Fonts=\acronym{TX} Fonts}, % \acronym{ADF}~Venturis\index{font>ADF Venturis=\acronym{ADF} Venturis}, % and many more \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \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} % % % \subsubsection[Multiplication Sign]% % {Multiplication Sign -- Times~\sample{\texttimes}}\label{sec:mult-sign} % \index{raised character>multiplication sign} % % \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} % % 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} % % Another possible typographic problem this package addresses is that both sets --~single and % double quotes~-- 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\index{font>encoding} 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:doubleguillemetleft} % \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}. 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:Doubleguillemetleft} % \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. Their height above the baseline is adjusted with % \hyperref[item:raisecapitalguillemets]{|raisecapitalguillemets|}. Values of .025em to .075em % 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.} % \label{tab:raiseguillemets} % % \begin{tabfigures} % \begin{tabular}{@{}cc>{\RaggedRight}p{20em}@{}} % \toprule % \multicolumn{2}{@{}c}{Raise} & Font Name \\ % Lowercase & Uppercase & \\ % em & em & \\ % \midrule % 0 & .05\hphantom{00} & % \acronym{EB}~Garamond\index{font>EB Garamond=\acronym{EB} Garamond}, % Libertinus\index{font>Libertinus}, % Merriweather\index{font>Merriweather}, and many more \\ % .025 & .05\hphantom{00} & Gentium\index{font>Gentium} \\ % .04\hphantom{0} & .0667 & % \acronym{ADF}~Baskervald\index{font>ADF Baskervald=\acronym{ADF} Baskervald} \\ % .05\hphantom{0} & .0625 & % \acronym{GFS}~Artemisia\index{font>GFS Artemisia=\acronym{GFS} Artemisia}, % \acronym{GFS}~Didot\index{font>GFS Didot=\acronym{GFS} Didot} \\ % \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} % % 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)} % % 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} % % % \subsection[Align Last Line] % {Align Last Line of a Paragraph}\label{sec:align-last-line} % \index{paragraph>align last line} % % 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 Ref.~\citenum{eijkhout:2007}. % The following environments allow to adjust the last lines of paragraphs in different ways. % % \DescribeEnv{lastlineraggedleftpar} % \DescribeEnv{lastlineflushrightpar} % The environment |lastlineraggedleftpar|\index{paragraph>align last line>flush right} 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}\dots \\ % \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} the last lines of the paragraphs enclosed by % this environment.\footnote{Also compare the approach taken in Ref.~\citenum{wermuth:2018}.} % % \begin{synopsis}\label{syn:lastlinecenteredpar} % \cs{begin}|{lastlinecenteredpar}| \\ % \hspace*{1em}\dots \\ % \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} % % % \needtocspace % \subsection[Fill Last Line] % {Fill Last Line of a Paragraph}\label{sec:fill-last-line} % \index{paragraph>fill last line} % % 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 Definition} % % Depending on the value of \cs{parindent}, either zero or nonzero, there may be the desire 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} % % The same problem arises 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} % % \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{6pt plus 2pt} for a base size of~10pt.} % % \medskip % \begin{minipage}{\linewidth} % A possible, more legible solution is to reformat the paragraph in a way 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} % % The suggestions for the gap-width vary from two~em to twice the width of a % \singlequotes{typical} \cs{parindent}\footnote{% For example, \LaTeX's class % \packagename{article} uses a \cs{parindent} of~25pt.} for the gap~\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. For the concrete case it is up to the user to decide which % direction to go and to choose the method that yields the most pleasing typographic results. % % \TeX{} always considers the paragraph in its entirety. Thus any change the user demands % \doublequotes{just for the last line} will permeate the whole paragraph and in unfortunate % cases botch it. % % Prudent users check the appearance of the problematic, original paragraph against one or % more corrected versions of it~-- at least visually. Quantitative comparisons can be % performed with the help of~\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 % e.\,g.~\cref{sec:sloppy-paragraphs}) to achieve a low badness such that the desired % paragraph end is deemed feasible by \TeX. % % \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} % % 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}} % % 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}} % % 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}. In turn the next-to-last 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 \cs{mbox}ing lend themselves to generalizations. We need not only tie at end of % a paragraph but fuse logical units of sentences or inline equations so that the relevant % information literally stays in the reader's focus. Cementing together text of course finds % an end when overfull lines start to show up. % % \item Uniform paragraph change.\label{enum:uniform-paragraph-change} % % \begin{enumerate}[notopsep] % \item Vary spacing.\label{enum:vary-spacing}\index{font>spacing} % % 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} % % 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} % % 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 |shortenpar|\index{paragraph>fill last % line>shortenpar=\code{shortenpar}} and |prolongpar|\index{paragraph>fill last % line>prolongpar=\code{prolongpar}} 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}\index{forlorn % line>widow} (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}\index{forlorn line>club} or~\singlequotes{orphan}\index{forlorn % line>orphan} (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}| % \dots{} % \cs{end}|{shortenpar}| % \end{synopsis} % % Environment |shortenpar| decreases the \cs{looseness} of the paragraph.\footnote{Command % \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 % Ref.~\citenum{wermuth:2017c}.} It performs well if the last line of the paragraph is short % or the whole paragraph is loose. % % \begin{synopsis}\label{syn:prolongpar} % \cs{begin}|{prolongpar}| % \dots{} % \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 almost full. % % % \subsubsection{Specialized Environments}\label{sec:fill-last-line-specialized-environments} % % We introduce environments not just skips to get the correct behavior --~set up all paragraph % parameters \emph{before} the paragraph ends~-- and, at the same time, limit the range of this % parameter change. % % \DescribeEnv{covernextindentpar} % Environment |covernextindentpar|\index{paragraph>fill last line>covernextindentpar=\code{covernextindentpar}} % 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}\dots \\ % \cs{end}|{covernextindentpar}| % \end{synopsis} % % The environment asks \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, |openlastlinepar|,\index{paragraph>fill last % line>openlastlinepar=\code{openlastlinepar}} 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} \\ % \hspace*{1em}\dots \\ % \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 the application of this environment can be successful, this is, a completely filled % last line is avoided, but the result may be of \hyperref[item:o1]{type~O1} nonetheless. % % % \needtocspace % \Needspace{150pt} % \subsection{Spacing}\label{sec:spacing-control}\index{font>spacing} % % \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}\index{font>spacing>tight} % % % \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. % % They at the one hand 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 also being 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, % respectively. % % \begin{synopsis}\label{syn:loosespacing} % \cs{begin}|{loosespacing}|\oarg{level} % \dots{} % \cs{end}|{loosespacing}| % \end{synopsis} % % Environment~|loosespacing| increases the width of a space by the percentages given in the % \cref{tab:loosespacing}. % % \begin{SCtable}[10] % \caption[Spacing changes made by \code{loosespacing}]% % {Adjustments made by environment |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 & Comment \\ % {} & \% & \\ % \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} % \dots{} % \cs{end}|{tightspacing}| % \end{synopsis} % % Environment~|tightspacing| decreases the width of a space by the percentages given in % \cref{tab:tightspacing}. % % \begin{SCtable}[10] % \caption[Spacing changes made by \code{tightspacing}]% % {Adjustments made by environment |tightspacing| to \cs{spaceskip}. % The mapping of \meta{level} to the exact skip definitions are % \(1 \mapsto \formatskip{.9875}{.0125}{.5\hphantom{000}}\)\!, % \(2 \mapsto \formatskip{.975}{.025}{.5\hphantom{00}}\)\!, % \(3 \mapsto \formatskip{.95}{.05}{.5\hphantom{0}}\)\!, 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} % \def~{\hphantom{0}}% % \begin{tabular}{@{}ccl@{}} % \toprule % \meta{level} & Adjustment & Comment \\ % {} & \% & \\ % \midrule % 0 & n/a & neutral \\ % 1 & ~{-}1.25 & default \\ % 2 & ~{-}2.5~ & \\ % 3 & ~{-}5\hphantom{.00} & \\ % \(\ge\)\:4 & -10\hphantom{.00} & \\ % \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} % Nudge line breaks or hyphenation points.~\visualpar Separate clashing descenders and % ascenders.~\visualpar Eliminate rivers. % \end{usecases} % % % \subsubsection{Wide Space}\label{sec:wide-space}\index{wide space} % % 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 Ref.~\citenum{knuth:1986}. For a concise and understandable % explanation of the \TeX~\cs{fontdimen} parameters consult Ref.~\citenum{carlisle:2013}.} % % \begin{SCtable} % \caption[\cs{fontdimen}\meta{number} parameters] % {The first column~\sample{\#} states the index of the \cs{fontdimen} parameter: % \meta{number}. Column~2 presents short descriptions of the % \cs{fontdimen}\meta{number} parameters. As examples, the values for the current % font are shown in column~3; they are normalized to the quad-size.\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 \\ % {} & & \multicolumn{1}{c}{\%} \\ % \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} \\ % \cs{widespace*} % \end{synopsis} % % 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. % % 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} % % \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} \\ % \cs{narrowspace*} % \end{synopsis} % % The unstarred macro~\cs{narrowspace} inserts a narrow space with the width % \begin{equation*} % |\fontdimen2| - \cs{narrowspacestrength} \times |\fontdimen7| % \end{equation*} % % \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, % respectively. % % \begin{usecase} % Tighten loose lines with a series of~\cs{narrowspace}s.\footnote{Footnote % \ref{fn:widespace} again applies.} % \end{usecase} % % \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. \cs{narrowspace} and \cs{widespace} use the package's defaults.~\visualpar % The upper values in the 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}{@{}llll@{}} % \toprule % Name & 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)} % % The functionalities are just front-ends of selected macros in % package~\packagename{microtype} -- 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}\dots]\{microtype\} \\ % \cs{usepackage}[\meta{typog-options}\dots]\{typog\} % \end{codeexample} % % \noindent % in the document preamble. % \end{important} % % % \subsubsection{Tracking}\label{sec:tracking-control}\index{font>tracking} % % \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} \\ % \hspace*{1em}\dots \\ % \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. % % 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 with the help of \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@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.~-- 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} % % \DescribeEnv{setfontshrink} % \DescribeEnv{setfontstretch} % Adjust the limits of either only stretchability or only shrinkability and zero the other % component, i.\,e., shrinkability and stretchability, respectively. % % \begin{synopsis}\label{syn:setfontshrink}\label{syn:setfontstretch} % \cs{begin}|{setfontshrink}|\marg{level} % \dots{} % \cs{end}|{setfontshrink}| \\ % \cs{begin}|{setfontstretch}|\marg{level} % \dots{} % \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}. Note that all |stretch| values are zero, so the fonts % only can shrink.} % \label{tab:setfontshrink-values} % % \begin{tabfigures} % \begin{tabular}{@{}cccl@{}} % \toprule % \meta{level} & |stretch| & |shrink| & Comment \\ % {} & \nativetextfraction{1}{1000}\,em & \nativetextfraction{1}{1000}\,em & \\ % \midrule % 0 & n/a & n/a & no operation \\ % 1 & 0 & \hphantom{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}. Note that all |shrink| values are zero, so the fonts % only can stretch.} % \label{tab:setfontstretch-values} % % \begin{tabfigures} % \begin{tabular}{@{}cccl@{}} % \toprule % \meta{level} & |stretch| & |shrink| \\ % {} & \nativetextfraction{1}{1000}\,em & \nativetextfraction{1}{1000}\,em & \\ % \midrule % 0 & n/a & n/a & no operation \\ % 1 & \hphantom{0}\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} % % The three (nonzero) shrink limits of \code{setfontshrink} can be configured with package % option~\hyperref[item:shrinklimits]{\code{shrinklimits}} and --~in the same way~-- 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}|\marg{level} % \dots{} % \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}. Note that both |shrink| and |stretch| values are % nonzero, so the fonts can shrink or expand.} % \label{tab:setfontexpand-values} % % \begin{tabfigures} % \begin{tabular}{@{}cccl@{}} % \toprule % \meta{level} & |stretch| & |shrink| & Comment \\ % {} & \nativetextfraction{1}{1000}\,em & \nativetextfraction{1}{1000}\,em & \\ % \midrule % 0 & n/a & n/a & no operation \\ % 1 & \hphantom{0}\makeatletter\typog@stretch@i\makeatother & \hphantom{0}\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} % Disable the \packagename{microtype} feature~\singlequotes{expansion} inside of the % environment. % % \begin{synopsis}\label{syn:nofontexpansion}\label{syn:nofontexpand} % \cs{begin}|{nofontexpansion}| % \dots{} % \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} % % \DescribeEnv{nocharprotrusion} % Disable the \packagename{microtype} feature~\singlequotes{protrusion} inside of the % environment. % % \begin{synopsis}\label{syn:nocharprotrusion} % \cs{begin}|{nocharprotrusion}| % \dots{} % \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. % \end{usecases} % % % \FloatBarrier % \subsection{Sloppy Paragraphs}\label{sec:sloppy-paragraphs}\index{paragraph>sloppy} % % 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 the findings for \cs{emergencystretch} in % Ref.~\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}\dots \\ % \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} % \begin{tabular}{@{}ccccl@{}} % \toprule % \meta{sloppiness} & \cs{toler-} & \cs{hfuzz} & \cs{emergency-} & Comment \\ % {} & \code{ance} & \cs{vfuzz} & \code{stretch}~\(G\) & \\ % {} & & pt & em & \\ % \midrule % 0 & \hphantom{0}200\hphantom{\tolerancemark} & .1\hphantom{0} & 0\hphantom{.000\scaledmark} & \TeX: \verb+\fussy+ \\ % 1 & \hphantom{0}330\tolerancemark & .15 & \hphantom{0}.375\scaledmark & default \\ % 2 & \hphantom{0}530\tolerancemark & .2\hphantom{0} & \hphantom{0}.75\scaledmark\hphantom{0} & \\ % 3 & \hphantom{0}870\tolerancemark & .25 & 1.125\scaledmark & \\ % 4 & 1410\tolerancemark & .3\hphantom{0} & 1.5\scaledmark\hphantom{00} & \\ % 5 & 2310\tolerancemark & .35 & 1.875\scaledmark & \\ % 6 & 3760\tolerancemark & .4\hphantom{0} & 2.25\scaledmark\hphantom{0} & \\ % 7 & 6130\tolerancemark & .45 & 2.625\scaledmark & \\ % \(\ge\)\:8 & 9999\hphantom{\tolerancemark} & .5\hphantom{0} & 3\hphantom{.000\scaledmark} & \TeX: \verb+\sloppy+ \\ % \bottomrule % \end{tabular} % \end{tabfigures} % \end{suspendshortverb} % % \begin{tablenotes} % \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} % % % \FloatBarrier % \subsection{Vertically Partially-Tied Paragraphs}\label{sec:vtie-paragraph}\index{paragraph>vertically tied} % % \LaTeX{} provides several macros and environments to tie material vertically~-- 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} 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} % \dots{} % \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 command.~\visualpar Tie the % first line of an itemized, enumerated, or a description list\index{list} 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]\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\dots}~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} 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} % \dots{} % \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} line in each partial paragraph. % % \begin{synopsis}\label{syn:vtiebotdisp}\label{syn:vtiebotdisppar} % \cs{begin}|vtiebotdisp|\oarg{before-disp-number-of-lines} \\ % \hspace*{1em}\dots \\ % \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 function bracket the paragraph before the display (the one that needs protection) % and the associated displayed math: % % \begin{codeexample} % \cs{begin}\{vtiebotdisp\} \\ % ~~\% vertically tied paragraph before the math display \\ % ~~\cs{begin}\{equation\} \\ % ~~~~\% 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}\dots \\ % \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 un-breakable 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 respective % 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 function bracket the paragraphs before and after the display: % % \begin{codeexample} % \cs{begin}\{vtiebotdisptoppar\} \\ % ~~\% vertically tied paragraph before the math display \\ % ~~\cs{begin}\{equation\} \\ % ~~~~\% math \\ % ~~\cs{end}\{equation\} \\ % ~~\% 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} % \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} % Fix widows and orphans, e.\,g., those turned up by % package~\packagename{widows-and-orphans}~\cite{package:widows-and-orphans}.~\visualpar % Extend the typographic convention of \doublequotes{three to four lines instead of a single % club or widow line} to a context-dependent number of lines that tries to keep all (well, % dream on) the information together the reader needs at that particular point. % \end{usecases} % % % \FloatBarrier % \subsection{Breakable Displayed Equations}\label{sec:breakable-display}\index{page break} % % \DescribeEnv{breakabledisplay} % Package~\packagename{amsmath}\index{amsmath=\packagename{amsmath} (package)} 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 makes \code{breakabledisplay} less eager % to break a displayed equation and thus better suited to full automation of the page-breaking % process. % % \begin{synopsis}\label{syn:breakabledisplay} % \cs{begin}|{breakabledisplay}|\oarg{level} \\ % \hspace*{1em}\dots \\ % \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} % \begin{tabular}{@{}ccl@{}} % \toprule % \meta{level} & \cs{interdisplay-} & Comment \\ % {} & \code{linepenalty} & \\ % \midrule % 0 & 10000 & no operation \\ % 1 & \hphantom{0}9999 & \\ % 2 & \hphantom{0}6999 & \\ % 3 & \hphantom{0}2999 & default \\ % 4 & \hphantom{0000}0\rlap{\clubmark} & \\ % \bottomrule % \end{tabular} % \end{tabfigures} % % \begin{tablenotes} % \clubmark\enspace % This is the default of \cs{allowdisplaybreaks}. % \end{tablenotes} % \end{table} % % \begin{tips} % \begin{itemize}[notopsep] % \item Terminating a line with \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. % % \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} % % % \FloatBarrier % \clearpage % \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{In 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} directly (e.\,g.~12.5pt) or the lines' % leading\index{leading} 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 -- 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} % Let us assume we want to lighten the gray value of the copy a tad with a \cs{baselineskip} % increased (from e.g.~12pt) to~12.5pt. To this end we say: % % \begin{codeexample} % \cs{setbaselineskip}\{12.5pt\}\specialsectionendhere % \end{codeexample} % \end{example} % % \begin{tip} % To set the \cs{baselineskip} relative to the current value use % % \begin{codeexample} % \cs{setbaselineskip}\{\meta{factor}\cs{baselineskip}\} % \end{codeexample} % % \noindent % where \meta{factor} is a floating-point number. % \end{tip} % % \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}. % % % \DescribeMacro{\setbaselineskippercentage} % \sinceversion{Since v0.3} % Set the \cs{baselineskip} with a relative value calculated as a percentage of the current % font's design 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 font design size of 10pt, 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 font design size of 10pt 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 font design size of 10pt, 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} % \cs{typogfontsize}=\cs{fontdimen6}\cs{font} % \end{codeexample} % % \noindent % which is also called its \doublequotes{nominal size} or its \doublequotes{design 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 design 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 respective 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} % \end{tip} % % % \FloatBarrier % \clearpage % \subsection{Smooth Ragged}\label{sec:smooth-ragged}\index{ragged right} % % \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 typeset ragged paragraphs. % Instead of setting the glue inside of a paragraph to zero and letting the line-widths vary % accordingly~\cite{wermuth:2020} we prescribe the line-widths with the \cs{parshape}~primitive % and leave alone the stretchability or shrinkability of the glue. % % \begin{slightlysloppypar} % \hangindent=5.5em\hangafter=-5 % \DescribeEnv{smoothraggedrightshapetriplet} % \DescribeEnv{smoothraggedrightshapequintuplet} % \DescribeEnv{smoothraggedrightshapeseptuplet} % We introduce three environments that allow for setting three, five, or seven different % line-lengths: \code{smoothraggedrightshapetriplet}, % \code{smoothraggedrightshapequintuplet}, and \code{smoothraggedrightshapeseptuplet}; they % work for paragraphs up to % \makeatletter % \typog@triplet@max@lines, \typog@quintuplet@max@lines, or \typog@septuplet@max@lines~lines, % \makeatother % respectively. % \end{slightlysloppypar} % % % \begin{maxipage} % \begin{synopsis}\label{syn:smoothraggedrightshapetriplet}\label{syn:smoothraggedrightshapequintuplet}\label{syn:smoothraggedrightshapeseptuplet} % \cs{begin}|{smoothraggedrightshapetriplet}|\oarg{option\dots}\marg{width1}\marg{width2}\marg{width3} \\ % \hspace*{1em}\dots \\ % \cs{end}|{smoothraggedrightshapetriplet}| \\[\smallskipamount] % \cs{begin}|{smoothraggedrightshapequintuplet}|\oarg{option\dots}\marg{width1}\marg{width2}\dots\marg{width5} \\ % \hspace*{1em}\dots \\ % \cs{end}|{smoothraggedrightshapequintuplet}| \\[\smallskipamount] % \cs{begin}|smoothraggedrightshapeseptuplet|\oarg{option\dots}\marg{width1}\marg{width2}\dots\marg{width7} % \hspace*{1em}\dots \\ % \cs{end}|{smoothraggedrightshapeseptuplet}| % \end{synopsis} % \end{maxipage} % % 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. % % % \paragraph{Options} % % \begin{description}[style=nextline] % \item[|leftskip=|\meta{dim}] % Set the left margin for the smooth ragged paragraph to \meta{dim}. Similar to the \TeX{} % parameter~\cs{leftskip}. % % \item[|parindent=|\meta{dim}] % Set the first-line indent for the smooth ragged paragraph to \meta{dim}. Similar to the % \TeX{} parameter~\cs{parindent}. % \end{description} % % \noindent % \DescribeEnv{smoothraggedrightpar} % Environment~|smoothraggedrightpar| builds upon the three generators. It typesets a single % paragraph with a given \meta{ragwidth} of the ragged, right margin, where the rag~width is % the length-difference of the longest and the shortest lines. % % \begin{synopsis}\label{syn:smoothraggedrightpar} % \cs{begin}|{smoothraggedrightpar}|\oarg{option\dots} \\ % \hspace*{1em}\dots \\ % \cs{end}|{smoothraggedrightpar}| % \end{synopsis} % % The line lengths equally divide the ragged margin, i.\,e., they are arithmetic means with % respect to the generator size. % % \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 theme of the triplets and avoids the % \singlequotes{ladder} of lines~2\figuredash3\figuredash4 (or, if numbered by % cycle:~1.2\figuredash1.3\figuredash2.1) there. 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 looks \singlequotes{random}. At least it % hides the boundaries of cycles well. Shown here are two of them. % % \begin{center} % \includegraphics{smooth-parshapes-3.mps} % \end{center} % \end{minipage} % \end{itemize} % % \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}|\oarg{option\dots} \\ % \hspace*{1em}\dots \\ % \cs{end}|{smoothraggedright}| % \end{synopsis} % % % \paragraph{Options} % % \begin{description}[style=nextline] % \item[|linewidth=|\meta{dim}] % Override the length of the longest line. The default line-width is \cs{linewidth}. % \end{description} % % % \paragraph{Global Parameters} % % \begin{description}[style=nextline] % \item[\cs{smoothraggedrightfuzzfactor}=\meta{factor}] % The environment adds glue to every line-width\footnote{The shortest line only gets % stretchability, the longest only receives 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). The % \cs{smoothraggedrightfuzzfactor} is the amount of glue of each line expressed as a multiple % of the distance between the division points. The default of 1.0 means to add as much glue % such that the lines just do not overlap (assuming justification is feasible). % % \item[\cs{smoothraggedrightgenerator}] % Select a generator to use. Valid generator names: % \begin{itemize}[noitemsep] % \item |triplet|, % \item |quintuplet|, % \item |septuplet|. % \end{itemize} % % The default generator is |triplet|. % % \item[\cs{smoothraggedrightleftskip}=\meta{dim}] % Value for |leftskip| to pass to the generator. Default:~0pt. % % \item[\cs{smoothraggedrightparindent}=\meta{dim}] % Value for |parindent| to pass to the generator. Default:~0pt. % % \item[\cs{smoothraggedrightragwidth}=\meta{dim}] % Value for the width of the ragged right margin. Default:~2em. % \end{description} % % \begin{usecases} % Replacement for \cs{RaggedRight}~\cite{package:ragged2e}.~\visualpar Design alternative for % fully justified paragraphs if used with a small rag-width. % \end{usecases} % % % \addtocontents{toc}{\par\bigskip\hfill\textit{Table of Contents continued on next page.}} % \addtocontents{toc}{\clearpage} % % % \sectionfinish % \clearpage % \section{Other Packages for Fine \LaTeX~Typography}\label{sec:other-typography-packages} % % Many other packages help with getting better output from \LaTeX. Here is a list --~in % alphabetical order~-- of the ones the author considers particularly valuable. % % \sbox{\listlabelbox}{\packagename{microtype}} % \begin{description}[font=\normalfont, labelsep*=1em, labelwidth=\wd\listlabelbox, leftmargin=!] % \item[\packagename{enumitem}] % Flexible and consistent definition of all basic \LaTeX-list types plus inline % lists~\cite{package:enumitem}. % % \item[\packagename{geometry}] % Powerful and sophisticated setup of the page layout~\cite{package:geometry}. Best % accompanied by \packagename{layout}~\cite{package:layout} to visualize the page geometries. % % \item[\packagename{hyphenat}] % Hyphens that do not inhibit further auto-hyphenation of a compound % word~\cite{package:hyphenat}. % % \item[\packagename{microtype}] % Fine control of spacing, tracking, sidebearings, character protrusion into the margins, % font expansion, and much more~\cite{package:microtype}. % % See also \propername{Khirevich's} discussion~\cite{khirevich:2013}. % % \item[\packagename{ragged2e}] % Improved versions of environments |raggedleft|, |raggedright|, and % |center|~\cite{package:ragged2e}. % % \item[\packagename{setspace}] % Consistently set the document's line-spacing, i.\,e., % \cs{baselineskip}~\cite{package:setspace}. % \end{description} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % \MaybeStop{ % \sectionfinish % \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. % % \begin{suspendshortverb} % \setlength{\parindent}{0pt} % \setlength{\parskip}{6.0pt plus 2.0pt minus .5pt} % \input typog-grep % \end{suspendshortverb} % % \sectionfinish % \clearpage % \phantomsection % \resetfancyhead % \addcontentsline{toc}{section}{Change History} % \PrintChanges % % \sectionfinish % \clearpage % \phantomsection % \addcontentsline{toc}{section}{References} % \begin{RaggedRight} % \begin{thebibliography}{88} % \bibitem{abrahams:2020} % \bibauthor{Abrahams, Paul~W.}, % \bibauthor{Hargreaves, Kathryn~A.,} and % \bibauthor{Karl Berry}. % \bibtitle{\TeX{} for the Impatient}. % 2020, % \biburl{http://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{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{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{package:mathtools} % \bibauthor{H{\o}gholm, Morten}, % \bibauthor{Madsen, Lars} 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{http://www.khirevich.com/latex/microtype}. % % \bibitem{knuth:1986} % \bibauthor{Knuth, Donald Ervin}. % \bibtitle{The \TeX{}book}. % Addison Wesley, Reading\kernedslash MA, % 1986. % % \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: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\"oder, 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{http://www.tug.org/TUGboat/Articles/tb11-1/tb27salomon.pdf}. % % \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{thebibliography} % \end{RaggedRight} % % \sectionfinish % \clearpage % \begin{RaggedRight} % \setcounter{IndexColumns}{2} % \setlength{\columnsep}{30pt} % \label{sec:index} % \phantomsection % \addcontentsline{toc}{section}{Index} % \PrintIndex % \end{RaggedRight} % } % % % \sectionfinish % \clearpage % \appendix % \section{Package Code}\label{sec:package-code} % \addtocontents{toc}{\begingroup\small} % \addtocontents{toc}{\protect\begin{multicols}{2}} % \addtocontents{toc}{\protect\raggedcolumns} % % 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} [2024/05/07 v0.3 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. % % \begin{macrocode} \newcommand*{\typoglogo}{\textsf{T\itcorr*{-5}\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 debug information printer. % % \begin{macrocode} \newcommand*{\typog@typeout}[1] {\iftypog@debug \typeout{typog: #1}% \fi} % \end{macrocode} % \end{macro} % % \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} % 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 \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@mathitalicscorrection} % \begin{macrocode} \newmuskip\typog@mathitalicscorrection % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@textitalicscorrection} % \begin{macrocode} \newlength{\typog@textitalicscorrection} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@ligaturekern} % \begin{macrocode} \newlength{\typog@ligaturekern} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@raisecapitaldash} % \begin{macrocode} \newlength{\typog@raisecapitaldash} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@raisecapitalguillemets} % \begin{macrocode} \newlength{\typog@raisecapitalguillemets} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@raisecapitalhyphen} % \begin{macrocode} \newlength{\typog@raisecapitalhyphen} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@raisecapitaltimes} % \begin{macrocode} \newlength{\typog@raisecapitaltimes} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@raiseguillemets} % \begin{macrocode} \newlength{\typog@raiseguillemets} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@raisefiguredash} % \begin{macrocode} \newlength{\typog@raisefiguredash} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@slashkern} % \begin{macrocode} \newlength{\typog@slashkern} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@breakpenalty} % \begin{macrocode} \newcommand*{\typog@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@trackingttspacing} % \begin{macrocode} \newcommand*{\typog@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@shrinklimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@shrink@i{\number\typog@@limit}\fi \edef\typog@@limit{\typog@triple@get@ii{\typog@shrinklimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@shrink@ii{\number\typog@@limit}\fi \edef\typog@@limit{\typog@triple@get@iii{\typog@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@stretchlimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@stretch@i{\number\typog@@limit}\fi \edef\typog@@limit{\typog@triple@get@ii{\typog@stretchlimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@stretch@ii{\number\typog@@limit}\fi \edef\typog@@limit{\typog@triple@get@iii{\typog@stretchlimits}}% \unless\ifx\typog@@limit\typog@@star\edef\typog@stretch@iii{\number\typog@@limit}\fi} \DeclareOptionX{breakpenalty}% {\renewcommand*{\typog@breakpenalty}{#1}} \DeclareOptionX{debug}{\typog@debugtrue} \DeclareOptionX{mathitalicscorrection}[.4mu]% {\typog@mathitalicscorrection=#1\relax}% \DeclareOptionX{nodebug}{\typog@debugfalse} \DeclareOptionX{textitalicscorrection}[.02em]% {\setlength{\typog@textitalicscorrection}{#1}} \DeclareOptionX{ligaturekern}[.033333em]% {\setlength{\typog@ligaturekern}{#1}} \DeclareOptionX{raisecapitaldash}[\z@]% {\setlength{\typog@raisecapitaldash}{#1}} \DeclareOptionX{raisecapitalguillemets}[\z@]% {\setlength{\typog@raisecapitalguillemets}{#1}} \DeclareOptionX{raisecapitalhyphen}[\z@]% {\setlength{\typog@raisecapitalhyphen}{#1}} \DeclareOptionX{raisecapitaltimes}[\z@]% {\setlength{\typog@raisecapitaltimes}{#1}} \DeclareOptionX{raiseguillemets}[\z@]% {\setlength{\typog@raiseguillemets}{#1}} \DeclareOptionX{raisefiguredash}[\z@]% {\setlength{\typog@raisefiguredash}{#1}} \DeclareOptionX{raise*}[\z@]% {\setlength{\typog@raisecapitaldash}{#1}% \setlength{\typog@raisecapitalhyphen}{#1}% \setlength{\typog@raisecapitaltimes}{#1}% \setlength{\typog@raisefiguredash}{#1}} \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@shrinklimits{#1}% \typog@set@shrink@limits \fi} \DeclareOptionX{slashkern}[.05em]% {\setlength{\typog@slashkern}{#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@stretchlimits{#1}% \typog@set@stretch@limits \fi} \DeclareOptionX{trackingttspacing}[\typog@trackingttspacing]% {\typog@require@preloaded@microtype \ifx\@onlypreamble\@notprerr \PackageWarning{typog}{option `trackingttspacing' can only be used in the preamble}% \else \typog@typeout{trackingttspacing=#1}% \SetTracking[outer spacing={#1}]{encoding=*, family=tt*}{0}% \fi} \newcommand*{\typog@initialize@options} {\ExecuteOptionsX{ ligaturekern, mathitalicscorrection, textitalicscorrection, raisecapitaldash, raisecapitalhyphen, raisecapitaltimes, raiseguillemets, raisecapitalguillemets, raisefiguredash, slashkern} \ifdefined\MT@MT \unless\ifx\@onlypreamble\@notprerr \ExecuteOptionsX{shrinklimits, stretchlimits} \fi \fi} \typog@initialize@options \ProcessOptionsX % \fi % % % \subsection*{Setup} % % \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} % \begin{macrocode} \NewDocumentCommand{\typogget}{m}{\csname typog@#1\endcsname} % \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 out 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. -- 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@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 \PackageError{typog} {Missing third argument of \nolig} {Append empty group or \relax after macro invocation} \fi \fi} } % \end{macrocode} % \end{macro} % % % \subsection{Manual Italic Correction} % % \begin{macro}{\typog@itcorr@text@unconditional} % Fallback italics correction for text mode. % % \begin{macrocode} \newcommand*{\typog@itcorr@text@unconditional}[1] {\kern#1\typog@textitalicscorrection} % \end{macrocode} % \end{macro} % % \begin{macro}{\typog@itcorr@text} % Conditional italics correction depending on % the current font's own italics 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} % Italics correction for math mode. % % \begin{macrocode} \newcommand*{\typog@itcorr@math}[1] {\mkern#1\typog@mathitalicscorrection} % \end{macrocode} % \end{macro} % % \begin{macro}{\itcorr} % If the font has no italics 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} % 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@slashkern}% \typog@forwardslash \IfBooleanTF{#1}% {\hspace*{\typog@slashkern}\ignorespaces}% {\typog@breakpoint\typog@allowhyphenation\hspace*{\typog@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@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} % % % \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@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@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@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@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}{\figuredash} % Macro~\cs{figuredash} introduces a hyphenation possibility right after the dash; % its starred version does not. % % \begin{macrocode} \NewDocumentCommand{\figuredash}{s} {\raisebox{\typog@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@raisecapitaltimes}{$\m@th\times$}}% \else \raisebox{\typog@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@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@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@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@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@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@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@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@raisecapitalguillemets}{\guillemotright}% \typog@allowhyphenation} % \end{macrocode} % % \acronym{PDF}-substitute definition % % \begin{macrocode} \typog@register@pdfsubstitute{\let\Doubleguillemetright\guillemotright} % \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 % --~at the worst~-- 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 Ref.~\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} % % % \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{Microtype Front\capitalhyphen End} % % \subsubsection*{Tracking} % % \begin{environment}{setfonttracking} % % To archieve 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 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(0.1, 0.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@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@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@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.} % % \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{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@typeout{\string\setbaselineskip:\space initial\space baselineskip:\space \the\baselineskip} \typog@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@typeout{\string\setbaselineskip:\space final\space \string\setstretch\space argument:\space \fp_use:N \l_tmpa_fp} \typog@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{AfterPreamble}. However, all of its siblings, \cs{setbaselineskippercentage}, % \cs{setleading}, and \cs{setleadingpercentage} then would behave differently as they are % delayed to the end of the preamble, but \cs{setbaselineskip} 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@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@typeout{smoothraggedrightshapetriplet: skip0=\the\skip0}% \typog@typeout{smoothraggedrightshapetriplet: skip1=\the\skip1}% \typog@typeout{smoothraggedrightshapetriplet: skip2=\the\skip2}% \typog@typeout{smoothraggedrightshapetriplet: skip3=\the\skip3}% \unless\ifnum\typog@mod{\typog@triplet@max@lines}{3}=0 \PackageError{typog} {Line number of triplet generator % (\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 \skip1=#2\relax \skip2=#3\relax \skip3=#4\relax \skip4=#5\relax \skip5=#6\relax \typog@typeout{smoothraggedrightshapequintuplet: skip0=\the\skip0}% \typog@typeout{smoothraggedrightshapequintuplet: skip1=\the\skip1}% \typog@typeout{smoothraggedrightshapequintuplet: skip2=\the\skip2}% \typog@typeout{smoothraggedrightshapequintuplet: skip3=\the\skip3}% \typog@typeout{smoothraggedrightshapequintuplet: skip4=\the\skip4}% \typog@typeout{smoothraggedrightshapequintuplet: skip5=\the\skip5}% \unless\ifnum\typog@mod{\typog@quintuplet@max@lines}{5}=0 \PackageError{typog} {Line number of quintuplet generator % (\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} % 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 \skip1=#2\relax \skip2=#3\relax \skip3=#4\relax \skip4=#5\relax \skip5=#6\relax \skip6=#7\relax \skip7=#8\relax \typog@typeout{smoothraggedrightshapeseptuplet: skip0=\the\skip0}% \typog@typeout{smoothraggedrightshapeseptuplet: skip1=\the\skip1}% \typog@typeout{smoothraggedrightshapeseptuplet: skip2=\the\skip2}% \typog@typeout{smoothraggedrightshapeseptuplet: skip3=\the\skip3}% \typog@typeout{smoothraggedrightshapeseptuplet: skip4=\the\skip4}% \typog@typeout{smoothraggedrightshapeseptuplet: skip5=\the\skip5}% \typog@typeout{smoothraggedrightshapeseptuplet: skip6=\the\skip6}% \typog@typeout{smoothraggedrightshapeseptuplet: skip7=\the\skip7}% \unless\ifnum\typog@mod{\typog@septuplet@max@lines}{7}=0 \PackageError{typog} {Line number of septuplet generator % (\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{macro}{\smoothraggedrightleftskip} % \begin{macrocode} \newlength{\smoothraggedrightleftskip} % \end{macrocode} % \end{macro} % % \begin{macro}{\smoothraggedrightparindent} % \begin{macrocode} \newlength{\smoothraggedrightparindent} % \end{macrocode} % \end{macro} % % \begin{macro}{\smoothraggedrightragwidth} % \begin{macrocode} \newlength{\smoothraggedrightragwidth} \setlength{\smoothraggedrightragwidth}{2em} % \end{macrocode} % \end{macro} % % \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}} \NewDocumentEnvironment{smoothraggedrightpar}{O{}} {\edef\typog@@linewidth{\linewidth}% \setkeys[typog]{smoothraggedrightpar}{#1}% % \end{macrocode} % Convert generator name to an integer suitable for \cs{ifcase}. % \begin{macrocode} \edef\typog@@generatorchoice{% \ifnum\pdf@strcmp{\smoothraggedrightgenerator}{triplet}=\z@ 0% \else \ifnum\pdf@strcmp{\smoothraggedrightgenerator}{quintuplet}=\z@ 1% \else \ifnum\pdf@strcmp{\smoothraggedrightgenerator}{septuplet}=\z@ 2% \else \PackageError{typog} {smoothraggedright: unknown generator name} {valid generator names are triplet, quintuplet, and septuplet}% \fi \fi \fi}% % \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@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@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@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) \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} % % % \iffalse % % \fi % % % \addtocontents{toc}{\protect\end{multicols}} % \addtocontents{toc}{\endgroup} % % % \Finale % % % % \iffalse %<*example> \documentclass[a4paper]{article} \tracingonline=0 \PassOptionsToPackage{dvipsnames}{xcolor} \usepackage{amsmath} \usepackage[main=USenglish, german]{babel} \usepackage{float} \usepackage[T1]{fontenc} \usepackage{fullwidth} \usepackage{hyphenat} \usepackage{mathtools} \usepackage[activate=true, verbose=true]{microtype} \usepackage{ragged2e} \usepackage[nobottomtitles*]{titlesec}\renewcommand*{\bottomtitlespace}{.2\textheight} \usepackage[debug, trackingttspacing]{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) \gdef\examplefontname{default} \global\let\xsf=\sf \global\let\xsfdefault=\sfdefault \or % 1 -- Nunito \gdef\examplefontname{Nunito} \usepackage{nunito} \xdef\xsfdefault{\rmdefault} \gdef\xsf{\let\sfdefault=\xsfdefault\sf} \or % 2 -- OpenSans \gdef\examplefontname{OpenSans} \usepackage[defaultsans]{opensans} \xdef\xsfdefault{\sfdefault} \gdef\xsf{\let\sfdefault=\xsfdefault\sf} \or % 3 -- Noto Sans \gdef\examplefontname{OpenSans} \usepackage[sfdefault]{noto} \xdef\xsfdefault{\sfdefault} \gdef\xsf{\let\sfdefault=\xsfdefault\sf} \or % 4 -- Roboto \gdef\examplefontname{Roboto} \usepackage[sfdefault]{roboto} \xdef\xsfdefault{\sfdefault} \gdef\xsf{\let\sfdefault=\xsfdefault\sf} \or % 5 -- Montserrat \gdef\examplefontname{Montserrat Alternate} \usepackage[alternates]{montserrat} \xdef\xsfdefault{\sfdefault} \gdef\xsf{\let\sfdefault=\xsfdefault\sf} \or % 6 -- Inter \gdef\examplefontname{Inter} \usepackage[sfdefault]{inter} \xdef\xsfdefault{\sfdefault} \gdef\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} \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}} \newcommand*{\maxipagerule}{\medskip\hrule\medskip} \newenvironment*{maxipage*} {\par \noindent \fullwidthsetup{leftmargin=-\marginparsep - \marginparwidth, width=\textwidth + 2\marginparsep + 2\marginparwidth} \begin{fullwidth}% \vspace*{1pt}% Why is some vspace necessary? \parskip=.5\baselineskip} {\par \end{fullwidth}% \par} \newenvironment*{maxipage} {\par \noindent \fullwidthsetup{leftmargin=-\marginparsep - \marginparwidth, width=\textwidth + 2\marginparsep + 2\marginparwidth} \begin{fullwidth}% \maxipagerule \parskip=.5\baselineskip} {\par \vskip\parskip \maxipagerule \end{fullwidth}% \par} \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.} %There is a much better way to get the desired effect:~[\dots] \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]} \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]} \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}{3pt} \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 line-width loose-ness loose-spacing make-at-letter make-at-other mar-gin-al math-italics-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-italics-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} \begin{document} \fussy \lastlinefit=1000 \nonfrenchspacing \begin{center} \Huge\bf\sf TypoG Examples \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}. \bigskip \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{maxipage} \setstretch{1} \newcommand*{\baselineskipdoc}% {Macro \code{\string\baselineskip} is a length command 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{maxipage} \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 italics: \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 around it can be helpful for certain pairs, as for example years or names. \begin{center} \begin{tabular}{@{}ll@{}} \hline \multicolumn{1}{@{}l|}{Macro} & Result \\ \hline n/a & 1991/1992, New~York/NY, Korringa/Kohn/Rostoker \\ \code{\string\kernedslash} & 1991\kernedslash1992, New~York\kernedslash{}NY, Korringa\kernedslash{}Kohn\kernedslash{}Rostoker \\ \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\)\!. \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. \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}, respectively: \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} \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 sloppyness 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 sloppyness 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} \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{0.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~italics, 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}~command.} \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 * 0.6667}% float expression \setbaselineskippercentage{\relbls} \fontsizeinfo{baselinesetsize} New settings: \baselinesetsize. \texbookbaselineskipsample \newcommand*{\absled}{1.5pt} \paragraph{\code{\string\setleading\{\absled\}}} \setleading{1pt / -2.0}% 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{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 %<*nomicrotype> \documentclass[]{article} \usepackage[english]{babel} \usepackage{csquotes} \DeclareQuoteStyle{typog-guillemets} {\doubleguillemetright} {\doubleguillemetleft} {\singleguillemetright} {\singleguillemetleft} \usepackage[]{typog} \newcommand*{\packagename}[1]{\mbox{\textsf{#1}}} \begin{document} \begin{center} \Huge\bf\sf TypoG Examples \\ without Package~\packagename{microtype} \end{center} \bigskip \noindent 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. 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 %<*teximan2latex> ## 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*{\\textls[40]{\1}}/ s/^@section \(.*\)$/\\subsubsection*{\1}/ ## Make `@asis' list resemble the Texinfo format. s/@table @asis/\\begin{list}{}{\\itemindent=-20pt\\leftmargin=20pt}/ s/@end table/\\end{list}/ ## Indenting by four spaces generates a `verbatim' environment. s/@verbatim/\\begin{verbatim}/ s/@end verbatim/\\end{verbatim}/ ## We substitute @display for our maxipage environment. s/@display/\\begin{maxipage}/ s/@end display/\\end{maxipage}/ ## 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/\\textit/g s/@strong/\\textbf/g s/[w]{/mbox{/g ## Quote some special characters. s/%/\\%/g 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/::/::\\discretionary{}{}{}/g % % \fi % % % % \iffalse %<*typog-grep> #! /usr/bin/env perl use autodie qw(:all); use strict; use warnings; use Data::Dumper (); 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 grep_log_file { my ($options, $configuration, $file, $filename, $id_regexp) = @_; 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++; 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"; } } } } } sub show_ids_in_file { my ($options, $configuration, $file, $filename, $id_regexp) = @_; my $line_number = 0; my @nesting_levels; while (my $line = readline $file) { chomp $line; $line_number++; 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; 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"; } } } 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"); } $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}) { show_ids_in_file($options, $configuration, $file, $filename, $id_regexp); } else { grep_log_file($options, $configuration, $file, $filename, $id_regexp); } } sub scan_files { my ($options, $configuration, $id_regexp, $log_filenames) = @_; 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); 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); grep_or_show($options, $configuration, $file, $log_filename, $id_regexp); close_file($file, $log_filename); } } 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; 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; } ######################################################################## 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, 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 <{$_[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, '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-config' => \&show_configuration, 'V|version' => \&show_version, 'w|word-regexp!' => \$options->{WORD_REGEXP}) or fail_with_error('problems while parsing options'); fail_with_error("unknown colorize mode @{[quote_literal($options->{COLORIZE_MODE})]}") unless $options->{COLORIZE_MODE} =~ m/^(?:always|auto|never)$/i } 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 $options = {%$default_options}; my $configuration = {%$default_configuration}; get_options($options, $configuration); $options->{COLORIZE_OUTPUT} = do_colorize($options->{COLORIZE_MODE}); initialize_highlighting_from_configuration($configuration); debug_print(Data::Dumper::Dumper($configuration)); debug_print(Data::Dumper::Dumper($options)); 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 ($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; if ($use_pager) { redirect_and_scan_files($options, $configuration, $id_regexp, \@ARGV); } else { 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 - grep for typog-inspect elements in LaTeX log files =head1 SYNOPSIS =over =item B -a|--all|--any [I