diff options
author | Karl Berry <karl@freefriends.org> | 2024-05-07 20:11:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2024-05-07 20:11:51 +0000 |
commit | ab60ca3774663a7c219641b4a47296cdd2b28149 (patch) | |
tree | ffe26f05768770125971090cd4f7ea204886ce0d /Master | |
parent | a82447a1b9056aeb9499e8452dd8aa4f1e1c4b6b (diff) |
typog (7may24)
git-svn-id: svn://tug.org/texlive/trunk@71202 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
41 files changed, 15520 insertions, 1 deletions
diff --git a/Master/bin/aarch64-linux/typog-grep b/Master/bin/aarch64-linux/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/aarch64-linux/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/amd64-freebsd/typog-grep b/Master/bin/amd64-freebsd/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/amd64-freebsd/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/amd64-netbsd/typog-grep b/Master/bin/amd64-netbsd/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/amd64-netbsd/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/armhf-linux/typog-grep b/Master/bin/armhf-linux/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/armhf-linux/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/i386-freebsd/typog-grep b/Master/bin/i386-freebsd/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/i386-freebsd/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/i386-linux/typog-grep b/Master/bin/i386-linux/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/i386-linux/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/i386-netbsd/typog-grep b/Master/bin/i386-netbsd/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/i386-netbsd/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/i386-solaris/typog-grep b/Master/bin/i386-solaris/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/i386-solaris/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/universal-darwin/typog-grep b/Master/bin/universal-darwin/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/universal-darwin/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/windows/typog-grep.exe b/Master/bin/windows/typog-grep.exe Binary files differnew file mode 100755 index 00000000000..3332231b08c --- /dev/null +++ b/Master/bin/windows/typog-grep.exe diff --git a/Master/bin/x86_64-cygwin/typog-grep b/Master/bin/x86_64-cygwin/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/x86_64-cygwin/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/x86_64-darwinlegacy/typog-grep b/Master/bin/x86_64-darwinlegacy/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/x86_64-darwinlegacy/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/x86_64-linux/typog-grep b/Master/bin/x86_64-linux/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/x86_64-linux/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/x86_64-linuxmusl/typog-grep b/Master/bin/x86_64-linuxmusl/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/x86_64-linuxmusl/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/bin/x86_64-solaris/typog-grep b/Master/bin/x86_64-solaris/typog-grep new file mode 120000 index 00000000000..74d1a6a5621 --- /dev/null +++ b/Master/bin/x86_64-solaris/typog-grep @@ -0,0 +1 @@ +../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/typog/README.md b/Master/texmf-dist/doc/latex/typog/README.md new file mode 100644 index 00000000000..fb55ccb1e12 --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/README.md @@ -0,0 +1,79 @@ +# TypoG – Typographic Fine-Tuning for LaTeX + +LaTeX package `typog` provides macros for (micro-)typographic enhancements; +it covers a variety of topics: + +* Precise hyphenation control +* Disable/break ligatures +* Manual italic correction +* Extra kerning for slash and hyphen +* Raising selected characters (e.g. hyphen, en-dash, and em-dash) +* Aligning of the last line of a paragraph +* Filling of the last line last line of a paragraph +* Word spacing control +* [Microtype](https://github.com/schlcht/microtype) front-end +* Slightly sloppy paragraphs +* Vertically partially-tied paragraphs +* Breakable displayed equations +* Setspace front-end +* Smooth ragged-right paragraphs + +Moreover `typog` provides an environment to flag interesting parts of +the information deluge typically accumulating in a LaTeX *log*-file +and an associated tool, **typog-grep**, that selectively retrieves +these parts. + + +## Installation + +The minimally necessary files to install typog are *typog.ins* and *typog.dtx*. Running LaTeX +on *typog.ins* in particular produces *typog.sty*: + + latex typog.ins + +After extraction from *typog.dtx* place *typog.sty* in a directory mentioned in your TEXINPUTS +paths or copy it into one of the directories for your LaTeX installation's *sty*-files and run +**mktexlsr** or equivalent. + +To build the documentation it is easier to use the GNU *Makefile*: + + make + +To construct the manual *typog.pdf* or the usage example *typog-example.pdf* a working +[MetaPost](https://tug.org/metapost.html) installation and some +[POD](https://perldoc.perl.org/perlpod) utilities of a [Perl](https://www.perl.org/) +distribution are required. Cautious users can run + + make tool-check + +ahead to verify that the required utilities are installed and working. +For an overview over the most important *Makefile* targets use + + make help + + +## Usage + +Load the package with the usual incantation + + \usepackage{typog} + +See Section 2 of the package documentation for available options. + + +## Documentation + +The package documentation can be found +[online](https://cspiel.github.io/typog/). + + +## Credits + +Typog is written by Ch. L. Spiel <cspiel@users.sourceforge.org>. + + +## License + +Released under the +[LaTeX Project Public License v1.3c](https://www.latex-project.org/lppl.txt) +or later. diff --git a/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md b/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md new file mode 100644 index 00000000000..13435ef66d5 --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md @@ -0,0 +1,51 @@ +# How to prepare a new release + +... and not make too many mistakes. + + +1. Check that the work-area is clean with respect to **git**-tracked + files. + + ``` git status ``` + +1. Update the date stamp of `\ProvidesPackage`. + +1. (Temporarily) Zero the `\overfullrule`s of the documentation and + the example files. + +1. Thoroughly clean the work-area: + + ```make maintainer-clean``` + +1. Rebuild: + + ```make``` + +1. Check that all _*.sty_ and _*.pdf_ files are in good shape. + +1. Push the documentation files created in the previous step down into + the *docs* directory: + + ```make update-docs``` + +1. Undo the `\overfullrule` change. + +1. Commit the changes: + + ``` + git add . + ``` + + and finally + + ``` + git commit + ``` + +1. Tag the commit with the version string of `\ProvidesPackage`: + + ```git tag v1.23``` + +1. Push the changes to the public repository: + + ```git push origin master --tags``` diff --git a/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp b/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp new file mode 100644 index 00000000000..778a3bc3846 --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp @@ -0,0 +1,119 @@ +%% +%% This is file `crooked-paragraphs.mp', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% typog.dtx (with options: `crookedparagraphs') +%% +%% This is a generated file. +%% +%% 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. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Ch. L. Spiel. +%% +%% This work consists of the files typog.dtx and typog.ins +%% and the derived files typog.sty, slant-angle.mp, +%% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, +%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-grep.pod, and teximan2latex.sed. +%% +%% +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 diff --git a/Master/texmf-dist/doc/latex/typog/index.md b/Master/texmf-dist/doc/latex/typog/index.md new file mode 100644 index 00000000000..f4dc2e8bd9a --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/index.md @@ -0,0 +1,5 @@ +### Package Documentation + +- Comprehensive `typog` documentation: [typog.pdf](https://cspiel.github.io/typog/typog.pdf) +- `typog` examples and tests: [typog-example.pdf](https://cspiel.github.io/typog/typog-example.pdf) +- **typog-grep** manual page: [typog-grep.1](https://cspiel.github.io/typog/typog-grep.1) and as PDF: [typog-grep.1.pdf](https://cspiel.github.io/typog/typog-grep.1.pdf) diff --git a/Master/texmf-dist/doc/latex/typog/slant-angle.mp b/Master/texmf-dist/doc/latex/typog/slant-angle.mp new file mode 100644 index 00000000000..f25f790ea6f --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/slant-angle.mp @@ -0,0 +1,87 @@ +%% +%% This is file `slant-angle.mp', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% typog.dtx (with options: `slantangle') +%% +%% This is a generated file. +%% +%% 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. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Ch. L. Spiel. +%% +%% This work consists of the files typog.dtx and typog.ins +%% and the derived files typog.sty, slant-angle.mp, +%% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, +%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-grep.pod, and teximan2latex.sed. +%% +%% +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 diff --git a/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp b/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp new file mode 100644 index 00000000000..ce47135a56e --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp @@ -0,0 +1,140 @@ +%% +%% This is file `smooth-parshapes.mp', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% typog.dtx (with options: `smoothparshapes') +%% +%% This is a generated file. +%% +%% 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. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Ch. L. Spiel. +%% +%% This work consists of the files typog.dtx and typog.ins +%% and the derived files typog.sty, slant-angle.mp, +%% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, +%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-grep.pod, and teximan2latex.sed. +%% +%% +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 diff --git a/Master/texmf-dist/doc/latex/typog/teximan2latex.sed b/Master/texmf-dist/doc/latex/typog/teximan2latex.sed new file mode 100644 index 00000000000..b329ac3845f --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/teximan2latex.sed @@ -0,0 +1,55 @@ +## 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 diff --git a/Master/texmf-dist/doc/latex/typog/title.mp b/Master/texmf-dist/doc/latex/typog/title.mp new file mode 100644 index 00000000000..2fd74e91f9d --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/title.mp @@ -0,0 +1,92 @@ +%% +%% This is file `title.mp', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% typog.dtx (with options: `title') +%% +%% This is a generated file. +%% +%% 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. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Ch. L. Spiel. +%% +%% This work consists of the files typog.dtx and typog.ins +%% and the derived files typog.sty, slant-angle.mp, +%% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, +%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-grep.pod, and teximan2latex.sed. +%% +%% +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 diff --git a/Master/texmf-dist/doc/latex/typog/typog-example.pdf b/Master/texmf-dist/doc/latex/typog/typog-example.pdf Binary files differnew file mode 100644 index 00000000000..621ac319d20 --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/typog-example.pdf diff --git a/Master/texmf-dist/doc/latex/typog/typog-example.tex b/Master/texmf-dist/doc/latex/typog/typog-example.tex new file mode 100644 index 00000000000..af04d490094 --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/typog-example.tex @@ -0,0 +1,1616 @@ +%% +%% This is file `typog-example.tex', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% typog.dtx (with options: `example') +%% +%% This is a generated file. +%% +%% 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. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Ch. L. Spiel. +%% +%% This work consists of the files typog.dtx and typog.ins +%% and the derived files typog.sty, slant-angle.mp, +%% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, +%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-grep.pod, and teximan2latex.sed. +%% +%% +\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{} +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} +\endinput +%% +%% End of file `typog-example.tex'. diff --git a/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf b/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf Binary files differnew file mode 100644 index 00000000000..09647860d5d --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf diff --git a/Master/texmf-dist/doc/latex/typog/typog-grep.pod b/Master/texmf-dist/doc/latex/typog/typog-grep.pod new file mode 100644 index 00000000000..83f4f11f474 --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/typog-grep.pod @@ -0,0 +1,345 @@ +=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<typog-grep> -a|--all|--any [I<OPTION>...] F<LOG-FILE>... + +=item B<typog-grep> [I<OPTION>...] I<REGEXP> F<LOG-FILE>... + +=back + +The first form shows all C<E<lt>typog-inspect id="I<ID>" ...E<gt>> elements in F<LOG-FILE>. + +The second form shows the contents of C<E<lt>typog-inspect id="I<ID>" ...E<gt>> elements +whose I<ID>s match I<REGEXP> in F<LOG-FILE>. + +If no F<LOG-FILE> is given read from F<stdin>. +The S<filename C<->> is synonymous to F<stdin>. + +=head1 DESCRIPTION + +B<typog-grep> is a tailored post-processor for LaTeX log files +and the C<typoginspect> environment as provided by S<package typog>. +It shares more with the venerable +L<B<sgrep>|https://www.cs.helsinki.fi/u/jjaakkol/sgrep.html> +than with S<POSIX L<B<grep>|https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html>>. + +The LaTeX user brackets her text in + + \begin{typoginspect}{ID} + Text and code to investigate + \end{typoginspect} + +where I<ID> is used to identify one or more bracketed snippets. +I<ID> does not have to be unique. +The I<REGEXP> mechanism makes it easy to select groups of related I<ID>s +if they are named accordingly. + +In F<LOG-FILE> the environment shows up, packed with tracing information, as + +=begin texinfo + +@display +@relax + +=end texinfo + + <typog-inspect id="ID" job="JOB-NAME" line="LINE-NUMBER" page="PAGE-NUMBER"> + Trace Data + </typog-inspect> + +=begin texinfo + +@end display +@relax + +=end texinfo + +where all the capital-letter sequences are meta-variables +and in particular +I<JOB-NAME> is the expansion of C<\jobname>, +I<LINE-NUMBER> is the LaTeX source file line number +of the beginning of the C<typoginspect> environment, +and I<PAGE-NUMBER> is the page where +the output of S<C<Text and code to investigate>> occurs. + +B<typog-grep> reveals the contents of F<LOG-FILE> +between C<E<lt>typog-inspect id="I<ID>" ...E<gt>> +and C<E<lt>/typog-inspectE<gt>> excluding the XML-tags. +Access the I<JOB-NAME>, I<LINE-NUMBER>, and I<PAGE-NUMBER> +with the commandline options +B<--job-name>, B<--line-number>, and B<--page-number>, respectively. +Use B<--id> to show the name of the IDs that matched I<REGEXP>. + +C<typoginspect> environments can be nested. +B<typog-grep> respects the nesting, +i.e., if the I<ID> of the nested environment does not match I<REGEXP> +it will not be included in the program's output. + +=head1 OPTIONS + +The list of options is sorted by the names of the long options. + +=over 4 + +=item B<-a>, B<--all>, B<--any> + +ID-discovery mode: +Show all C<typog-inspect> elements independent of any matching patterns. + +=item B<--color>, B<colour> I<WHEN> + +Colorize specific log contents for the matching ids. +The S<argument I<WHEN>> determines when to apply color: +C<always>, C<never>, S<or C<auto>>. +The setting C<auto> checks whether standard output has been redirected. +This is the default. + +=item B<-C>, B<--config> I<KEY>=I<VALUE>[:I<KEY>=I<VALUE>[:...]] + +Set one or more configuration I<KEY> to I<VALUE> pairs. +See S<Sec. CONFIGURATION> below for a description of all available configuration items. +Use option B<--show-config> to display the default configuration. + +=item B<--debug> + +Turn on debug output on F<stderr>. + +=item B<-h>, B<--help> + +Display brief help then exit. + +=item B<-i>, B<--[no-]id> + +Print the actual id name that matched I<REGEXP>. +Control the appearance of the matching id with configuration S<item C<id-heading>>. + +=item B<-y>, B<--[no-]ignore-case> + +Match ids while ignoring case distinctions in patterns and data. + +=item B<-j>, B<--[no-]job-name> + +Print the C<\jobname> that B<tex> associated with the input file. + +=item B<-n>, B<--[no-]line-number> + +Print the line number where the S<C<typoginspect> environment> +was encountered in the LaTeX source file. + +=item B<-N>, B<--[no-]log-line-number> + +Print the line number of the F<log>-file where the current line was encountered. + +=item B<-p>, B<--[no-]page-number> + +Print page number where the contents of the S<C<typoginspect> environment> +starts in the typeset document. + +=item B<-P>, B<--[no-]pager> + +Redirect output from F<stdout> to the configured pager. + +=item B<--show-config> + +Show the default configuration and exit. + +=item B<-V>, B<--version> + +Show version information and exit. + +=item B<-w>, B<--[no-]word-regexp> + +Match only whole words. + +=back + +=head1 CONFIGURATION + +=over 4 + +=item C<id-format>=I<FORMAT> + +Control the I<FORMAT> for printing matching ids in inline-mode, +where I<FORMAT> is passed to Perl's C<printf>. +S<Default: C<%s:>.> + +=item C<id-heading>=C<0>E<verbar>C<1> + +Choose between printing the matching ids with S<option B<--id>>: +S<Inline (C<0>)> or heading before the matching data (C<1>). +S<Default: C<0>.> + +=item C<id-heading-format>=I<FORMAT> + +Control the I<FORMAT> for printing matching ids in heading-mode, +where I<FORMAT> is passed to Perl's C<printf>. +S<Default: C<--E<gt> %s E<lt>-->.> + +=item C<id-indent>=I<INDENT> + +Indentation of nested typog-inspect tags. +Only used in ``discovery'' mode (first form), i.e., if B<--all> is active. +S<Default: 8.> + +=item C<id-max-length>=I<MAXIMUM-LENGTH> + +Set the maximum length of a matching id for printing. +It a matching id exceeds this length it will be truncated +and the last three characters (short of I<MAXIMUM-LENGTH>) will be replaced by dots. +S<Default: 40.> + +=item C<line-number-format>=I<FORMAT> + +Control the I<FORMAT> for printing TeX source line numbers, +where I<FORMAT> is passed to Perl's C<printf>. +S<Default: C<%5d>.> + +=item C<log-line-number-format>=I<FORMAT> + +Control the I<FORMAT> for printing log line numbers, +where I<FORMAT> is passed to Perl's C<printf>. +S<Default: C<%6d>.> + +=item C<page-number-format>=I<FORMAT> + +Control the I<FORMAT> for printing page numbers, +where I<FORMAT> is passed to Perl's C<printf>. +S<Default: C<[%3d]>.> + +=item C<pager>=I<PAGER> + +Name of pager application to pipe output into +if run with S<option B<--pager>>. +S<Default: C<less>>. + +=item C<pager-flags>=I<FLAGS> + +Pass I<FLAGS> to I<PAGER>. +S<Default: C<--quit-if-one-screen>>. + +=item Color Configuration + +For the syntax of the color specifications consult +the manual page of Term::ANSIColor(pm). + +=over 4 + +=item C<file-header-color> + +Color of the filename header. + +=item C<fill-state-color> + +Color of the messages that report ``Underfull hbox'' or ``Overfull hbox''. + +=item C<first-vbox-color> + +Color of the first vbox on a page. + +=item C<font-spec-color> + +Color of font specifications. + +=item C<horizontal-break-candidate-color> + +Color of lines with horizontal-breakpoint S<candidates C<@>>. + +=item C<horizontal-breakpoint-color> + +Color of lines with horizontal S<breakpoints C<@@>>. + +=item C<id-color> + +Color of matching ids when printed inline. + +=item C<id-heading-color> + +Color of matching ids when printed in heading form. + +=item C<line-break-pass-color> + +Color of the lines showing which pass (e.g., C<@firstpass>) +of the line-breaking algorithm is active. + +=item C<line-number-color> + +Color of TeX-source-file line numbers. + +=item C<log-line-number-color> + +Color of log-file line numbers. + +=item C<math-color> + +Color used for math expressions including their font specs. + +=item C<page-number-color> + +Color of page numbers of the final output. + +=item C<tightness-color> + +Color of lines with Tight/Loose hbox reports. + +=item C<vertical-breakpoint-color> + +Color of possible vertical breakpoints. + +=back + +=back + +=head2 Brief summary of colors and attributes + +=over 4 + +=item Foreground Color + +C<black>, C<red>, C<green>, C<yellow>, +C<blue>, C<magenta>, C<cyan>, C<white>, + +Prefix with C<bright_> for high-intensity or bold foreground. + +=item Foreground Grey + +C<grey0>, ..., C<grey23> + +=item Background Color + +C<on_black>, C<on_red>, C<on_green>, C<on_yellow>, +S<C<on_blue>>, S<C<on_magenta>>, S<C<on_cyan>>, S<C<on_white>> + +Replace C<on_> with C<on_bright_> for high-intensity or bold background. + +=item Background Grey + +C<on_grey0>, ..., C<on_grey23> + +=item Text Attribute + +C<bold>, C<dark>, C<italic>, C<underline>, C<reverse> + +=back + +=head1 EXIT STATUS + +The exit status is 0 if at least one I<ID> matched I<REGEXP>, +1 if no I<ID> matched I<REGEXP>, and 2 if an error occurred. + +=head1 SEE ALSO + +B<grep>(1), B<printf>(3), B<Term::ANSIColor>(pm) + +=cut diff --git a/Master/texmf-dist/doc/latex/typog/typog-nomt.tex b/Master/texmf-dist/doc/latex/typog/typog-nomt.tex new file mode 100644 index 00000000000..ebac4efd1f7 --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/typog-nomt.tex @@ -0,0 +1,73 @@ +%% +%% This is file `typog-nomt.tex', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% typog.dtx (with options: `nomicrotype') +%% +%% This is a generated file. +%% +%% 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. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Ch. L. Spiel. +%% +%% This work consists of the files typog.dtx and typog.ins +%% and the derived files typog.sty, slant-angle.mp, +%% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, +%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-grep.pod, and teximan2latex.sed. +%% +%% +\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} +\endinput +%% +%% End of file `typog-nomt.tex'. diff --git a/Master/texmf-dist/doc/latex/typog/typog.ist b/Master/texmf-dist/doc/latex/typog/typog.ist new file mode 100644 index 00000000000..9b8104b16c0 --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/typog.ist @@ -0,0 +1,41 @@ +%% +%% This is file `typog.ist', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% typog.dtx (with options: `index-style') +%% +%% This is a generated file. +%% +%% 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. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Ch. L. Spiel. +%% +%% This work consists of the files typog.dtx and typog.ins +%% and the derived files typog.sty, slant-angle.mp, +%% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, +%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-grep.pod, and teximan2latex.sed. +%% +%% +actual '=' +delim_r "\\figuredash*" +heading_prefix "\\pagebreak[3]\\smallskip\n\n{\\sffamily\\bfseries\\large " +heading_suffix "}\\nopagebreak\n" +headings_flag 1 +level '>' +quote '!' +\endinput +%% +%% End of file `typog.ist'. diff --git a/Master/texmf-dist/doc/latex/typog/typog.pdf b/Master/texmf-dist/doc/latex/typog/typog.pdf Binary files differnew file mode 100644 index 00000000000..9d00685045a --- /dev/null +++ b/Master/texmf-dist/doc/latex/typog/typog.pdf diff --git a/Master/texmf-dist/doc/man/man1/typog-grep.1 b/Master/texmf-dist/doc/man/man1/typog-grep.1 new file mode 100644 index 00000000000..372c87bc5ff --- /dev/null +++ b/Master/texmf-dist/doc/man/man1/typog-grep.1 @@ -0,0 +1,428 @@ +.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "TYPOG-GREP 1" +.TH TYPOG-GREP 1 "2024-05-07" "perl v5.36.0" "User Contributed Perl Documentation" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.\" Turn off justification. +.na +.SH "NAME" +typog\-grep \- grep for typog\-inspect elements in LaTeX log files +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +.IP "\fBtypog-grep\fR \-a|\-\-all|\-\-any [\fI\s-1OPTION\s0\fR...] \fILOG-FILE\fR..." 4 +.IX Item "typog-grep -a|--all|--any [OPTION...] LOG-FILE..." +.PD 0 +.IP "\fBtypog-grep\fR [\fI\s-1OPTION\s0\fR...] \fI\s-1REGEXP\s0\fR \fILOG-FILE\fR..." 4 +.IX Item "typog-grep [OPTION...] REGEXP LOG-FILE..." +.PD +.PP +The first form shows all \f(CW\*(C`<typog\-inspect id="\f(CIID\f(CW" ...>\*(C'\fR elements in \fILOG-FILE\fR. +.PP +The second form shows the contents of \f(CW\*(C`<typog\-inspect id="\f(CIID\f(CW" ...>\*(C'\fR elements +whose \fI\s-1ID\s0\fRs match \fI\s-1REGEXP\s0\fR in \fILOG-FILE\fR. +.PP +If no \fILOG-FILE\fR is given read from \fIstdin\fR. +The filename\ \f(CW\*(C`\-\*(C'\fR is synonymous to \fIstdin\fR. +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\fBtypog-grep\fR is a tailored post-processor for LaTeX log files +and the \f(CW\*(C`typoginspect\*(C'\fR environment as provided by package\ typog. +It shares more with the venerable +\&\fBsgrep\fR <https://www.cs.helsinki.fi/u/jjaakkol/sgrep.html> +than with \s-1POSIX\s0\ \fBgrep\fR <https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html>. +.PP +The LaTeX user brackets her text in +.PP +.Vb 3 +\& \ebegin{typoginspect}{ID} +\& Text and code to investigate +\& \eend{typoginspect} +.Ve +.PP +where \fI\s-1ID\s0\fR is used to identify one or more bracketed snippets. +\&\fI\s-1ID\s0\fR does not have to be unique. +The \fI\s-1REGEXP\s0\fR mechanism makes it easy to select groups of related \fI\s-1ID\s0\fRs +if they are named accordingly. +.PP +In \fILOG-FILE\fR the environment shows up, packed with tracing information, as +.PP +.Vb 3 +\& <typog\-inspect id="ID" job="JOB\-NAME" line="LINE\-NUMBER" page="PAGE\-NUMBER"> +\& Trace Data +\& </typog\-inspect> +.Ve +.PP +where all the capital-letter sequences are meta-variables +and in particular +\&\fIJOB-NAME\fR is the expansion of \f(CW\*(C`\ejobname\*(C'\fR, +\&\fILINE-NUMBER\fR is the LaTeX source file line number +of the beginning of the \f(CW\*(C`typoginspect\*(C'\fR environment, +and \fIPAGE-NUMBER\fR is the page where +the output of \f(CW\*(C`Text\ and\ code\ to\ investigate\*(C'\fR occurs. +.PP +\&\fBtypog-grep\fR reveals the contents of \fILOG-FILE\fR +between \f(CW\*(C`<typog\-inspect id="\f(CIID\f(CW" ...>\*(C'\fR +and \f(CW\*(C`</typog\-inspect>\*(C'\fR excluding the XML-tags. +Access the \fIJOB-NAME\fR, \fILINE-NUMBER\fR, and \fIPAGE-NUMBER\fR +with the commandline options +\&\fB\-\-job\-name\fR, \fB\-\-line\-number\fR, and \fB\-\-page\-number\fR, respectively. +Use \fB\-\-id\fR to show the name of the IDs that matched \fI\s-1REGEXP\s0\fR. +.PP +\&\f(CW\*(C`typoginspect\*(C'\fR environments can be nested. +\&\fBtypog-grep\fR respects the nesting, +i.e., if the \fI\s-1ID\s0\fR of the nested environment does not match \fI\s-1REGEXP\s0\fR +it will not be included in the program's output. +.SH "OPTIONS" +.IX Header "OPTIONS" +The list of options is sorted by the names of the long options. +.IP "\fB\-a\fR, \fB\-\-all\fR, \fB\-\-any\fR" 4 +.IX Item "-a, --all, --any" +ID-discovery mode: +Show all \f(CW\*(C`typog\-inspect\*(C'\fR elements independent of any matching patterns. +.IP "\fB\-\-color\fR, \fBcolour\fR \fI\s-1WHEN\s0\fR" 4 +.IX Item "--color, colour WHEN" +Colorize specific log contents for the matching ids. +The argument\ \fI\s-1WHEN\s0\fR determines when to apply color: +\&\f(CW\*(C`always\*(C'\fR, \f(CW\*(C`never\*(C'\fR, or\ \f(CW\*(C`auto\*(C'\fR. +The setting \f(CW\*(C`auto\*(C'\fR checks whether standard output has been redirected. +This is the default. +.IP "\fB\-C\fR, \fB\-\-config\fR \fI\s-1KEY\s0\fR=\fI\s-1VALUE\s0\fR[:\fI\s-1KEY\s0\fR=\fI\s-1VALUE\s0\fR[:...]]" 4 +.IX Item "-C, --config KEY=VALUE[:KEY=VALUE[:...]]" +Set one or more configuration \fI\s-1KEY\s0\fR to \fI\s-1VALUE\s0\fR pairs. +See Sec.\ \s-1CONFIGURATION\s0 below for a description of all available configuration items. +Use option \fB\-\-show\-config\fR to display the default configuration. +.IP "\fB\-\-debug\fR" 4 +.IX Item "--debug" +Turn on debug output on \fIstderr\fR. +.IP "\fB\-h\fR, \fB\-\-help\fR" 4 +.IX Item "-h, --help" +Display brief help then exit. +.IP "\fB\-i\fR, \fB\-\-[no\-]id\fR" 4 +.IX Item "-i, --[no-]id" +Print the actual id name that matched \fI\s-1REGEXP\s0\fR. +Control the appearance of the matching id with configuration item\ \f(CW\*(C`id\-heading\*(C'\fR. +.IP "\fB\-y\fR, \fB\-\-[no\-]ignore\-case\fR" 4 +.IX Item "-y, --[no-]ignore-case" +Match ids while ignoring case distinctions in patterns and data. +.IP "\fB\-j\fR, \fB\-\-[no\-]job\-name\fR" 4 +.IX Item "-j, --[no-]job-name" +Print the \f(CW\*(C`\ejobname\*(C'\fR that \fBtex\fR associated with the input file. +.IP "\fB\-n\fR, \fB\-\-[no\-]line\-number\fR" 4 +.IX Item "-n, --[no-]line-number" +Print the line number where the \f(CW\*(C`typoginspect\*(C'\fR\ environment +was encountered in the LaTeX source file. +.IP "\fB\-N\fR, \fB\-\-[no\-]log\-line\-number\fR" 4 +.IX Item "-N, --[no-]log-line-number" +Print the line number of the \fIlog\fR\-file where the current line was encountered. +.IP "\fB\-p\fR, \fB\-\-[no\-]page\-number\fR" 4 +.IX Item "-p, --[no-]page-number" +Print page number where the contents of the \f(CW\*(C`typoginspect\*(C'\fR\ environment +starts in the typeset document. +.IP "\fB\-P\fR, \fB\-\-[no\-]pager\fR" 4 +.IX Item "-P, --[no-]pager" +Redirect output from \fIstdout\fR to the configured pager. +.IP "\fB\-\-show\-config\fR" 4 +.IX Item "--show-config" +Show the default configuration and exit. +.IP "\fB\-V\fR, \fB\-\-version\fR" 4 +.IX Item "-V, --version" +Show version information and exit. +.IP "\fB\-w\fR, \fB\-\-[no\-]word\-regexp\fR" 4 +.IX Item "-w, --[no-]word-regexp" +Match only whole words. +.SH "CONFIGURATION" +.IX Header "CONFIGURATION" +.ie n .IP """id\-format""=\fI\s-1FORMAT\s0\fR" 4 +.el .IP "\f(CWid\-format\fR=\fI\s-1FORMAT\s0\fR" 4 +.IX Item "id-format=FORMAT" +Control the \fI\s-1FORMAT\s0\fR for printing matching ids in inline-mode, +where \fI\s-1FORMAT\s0\fR is passed to Perl's \f(CW\*(C`printf\*(C'\fR. +Default:\ \f(CW%s:\fR. +.ie n .IP """id\-heading""=0|1" 4 +.el .IP "\f(CWid\-heading\fR=\f(CW0\fR|\f(CW1\fR" 4 +.IX Item "id-heading=0|1" +Choose between printing the matching ids with option\ \fB\-\-id\fR: +Inline\ (\f(CW0\fR) or heading before the matching data (\f(CW1\fR). +Default:\ \f(CW0\fR. +.ie n .IP """id\-heading\-format""=\fI\s-1FORMAT\s0\fR" 4 +.el .IP "\f(CWid\-heading\-format\fR=\fI\s-1FORMAT\s0\fR" 4 +.IX Item "id-heading-format=FORMAT" +Control the \fI\s-1FORMAT\s0\fR for printing matching ids in heading-mode, +where \fI\s-1FORMAT\s0\fR is passed to Perl's \f(CW\*(C`printf\*(C'\fR. +Default:\ \f(CW\*(C`\-\->\ %s\ <\-\-\*(C'\fR. +.ie n .IP """id\-indent""=\fI\s-1INDENT\s0\fR" 4 +.el .IP "\f(CWid\-indent\fR=\fI\s-1INDENT\s0\fR" 4 +.IX Item "id-indent=INDENT" +Indentation of nested typog-inspect tags. +Only used in ``discovery'' mode (first form), i.e., if \fB\-\-all\fR is active. +Default:\ 8. +.ie n .IP """id\-max\-length""=\fIMAXIMUM-LENGTH\fR" 4 +.el .IP "\f(CWid\-max\-length\fR=\fIMAXIMUM-LENGTH\fR" 4 +.IX Item "id-max-length=MAXIMUM-LENGTH" +Set the maximum length of a matching id for printing. +It a matching id exceeds this length it will be truncated +and the last three characters (short of \fIMAXIMUM-LENGTH\fR) will be replaced by dots. +Default:\ 40. +.ie n .IP """line\-number\-format""=\fI\s-1FORMAT\s0\fR" 4 +.el .IP "\f(CWline\-number\-format\fR=\fI\s-1FORMAT\s0\fR" 4 +.IX Item "line-number-format=FORMAT" +Control the \fI\s-1FORMAT\s0\fR for printing TeX source line numbers, +where \fI\s-1FORMAT\s0\fR is passed to Perl's \f(CW\*(C`printf\*(C'\fR. +Default:\ \f(CW%5d\fR. +.ie n .IP """log\-line\-number\-format""=\fI\s-1FORMAT\s0\fR" 4 +.el .IP "\f(CWlog\-line\-number\-format\fR=\fI\s-1FORMAT\s0\fR" 4 +.IX Item "log-line-number-format=FORMAT" +Control the \fI\s-1FORMAT\s0\fR for printing log line numbers, +where \fI\s-1FORMAT\s0\fR is passed to Perl's \f(CW\*(C`printf\*(C'\fR. +Default:\ \f(CW%6d\fR. +.ie n .IP """page\-number\-format""=\fI\s-1FORMAT\s0\fR" 4 +.el .IP "\f(CWpage\-number\-format\fR=\fI\s-1FORMAT\s0\fR" 4 +.IX Item "page-number-format=FORMAT" +Control the \fI\s-1FORMAT\s0\fR for printing page numbers, +where \fI\s-1FORMAT\s0\fR is passed to Perl's \f(CW\*(C`printf\*(C'\fR. +Default:\ \f(CW\*(C`[%3d]\*(C'\fR. +.ie n .IP """pager""=\fI\s-1PAGER\s0\fR" 4 +.el .IP "\f(CWpager\fR=\fI\s-1PAGER\s0\fR" 4 +.IX Item "pager=PAGER" +Name of pager application to pipe output into +if run with option\ \fB\-\-pager\fR. +Default:\ \f(CW\*(C`less\*(C'\fR. +.ie n .IP """pager\-flags""=\fI\s-1FLAGS\s0\fR" 4 +.el .IP "\f(CWpager\-flags\fR=\fI\s-1FLAGS\s0\fR" 4 +.IX Item "pager-flags=FLAGS" +Pass \fI\s-1FLAGS\s0\fR to \fI\s-1PAGER\s0\fR. +Default:\ \f(CW\*(C`\-\-quit\-if\-one\-screen\*(C'\fR. +.IP "Color Configuration" 4 +.IX Item "Color Configuration" +For the syntax of the color specifications consult +the manual page of Term::ANSIColor(pm). +.RS 4 +.ie n .IP """file\-header\-color""" 4 +.el .IP "\f(CWfile\-header\-color\fR" 4 +.IX Item "file-header-color" +Color of the filename header. +.ie n .IP """fill\-state\-color""" 4 +.el .IP "\f(CWfill\-state\-color\fR" 4 +.IX Item "fill-state-color" +Color of the messages that report ``Underfull hbox'' or ``Overfull hbox''. +.ie n .IP """first\-vbox\-color""" 4 +.el .IP "\f(CWfirst\-vbox\-color\fR" 4 +.IX Item "first-vbox-color" +Color of the first vbox on a page. +.ie n .IP """font\-spec\-color""" 4 +.el .IP "\f(CWfont\-spec\-color\fR" 4 +.IX Item "font-spec-color" +Color of font specifications. +.ie n .IP """horizontal\-break\-candidate\-color""" 4 +.el .IP "\f(CWhorizontal\-break\-candidate\-color\fR" 4 +.IX Item "horizontal-break-candidate-color" +Color of lines with horizontal-breakpoint candidates\ \f(CW\*(C`@\*(C'\fR. +.ie n .IP """horizontal\-breakpoint\-color""" 4 +.el .IP "\f(CWhorizontal\-breakpoint\-color\fR" 4 +.IX Item "horizontal-breakpoint-color" +Color of lines with horizontal breakpoints\ \f(CW\*(C`@@\*(C'\fR. +.ie n .IP """id\-color""" 4 +.el .IP "\f(CWid\-color\fR" 4 +.IX Item "id-color" +Color of matching ids when printed inline. +.ie n .IP """id\-heading\-color""" 4 +.el .IP "\f(CWid\-heading\-color\fR" 4 +.IX Item "id-heading-color" +Color of matching ids when printed in heading form. +.ie n .IP """line\-break\-pass\-color""" 4 +.el .IP "\f(CWline\-break\-pass\-color\fR" 4 +.IX Item "line-break-pass-color" +Color of the lines showing which pass (e.g., \f(CW@firstpass\fR) +of the line-breaking algorithm is active. +.ie n .IP """line\-number\-color""" 4 +.el .IP "\f(CWline\-number\-color\fR" 4 +.IX Item "line-number-color" +Color of TeX-source-file line numbers. +.ie n .IP """log\-line\-number\-color""" 4 +.el .IP "\f(CWlog\-line\-number\-color\fR" 4 +.IX Item "log-line-number-color" +Color of log-file line numbers. +.ie n .IP """math\-color""" 4 +.el .IP "\f(CWmath\-color\fR" 4 +.IX Item "math-color" +Color used for math expressions including their font specs. +.ie n .IP """page\-number\-color""" 4 +.el .IP "\f(CWpage\-number\-color\fR" 4 +.IX Item "page-number-color" +Color of page numbers of the final output. +.ie n .IP """tightness\-color""" 4 +.el .IP "\f(CWtightness\-color\fR" 4 +.IX Item "tightness-color" +Color of lines with Tight/Loose hbox reports. +.ie n .IP """vertical\-breakpoint\-color""" 4 +.el .IP "\f(CWvertical\-breakpoint\-color\fR" 4 +.IX Item "vertical-breakpoint-color" +Color of possible vertical breakpoints. +.RE +.RS 4 +.RE +.SS "Brief summary of colors and attributes" +.IX Subsection "Brief summary of colors and attributes" +.IP "Foreground Color" 4 +.IX Item "Foreground Color" +\&\f(CW\*(C`black\*(C'\fR, \f(CW\*(C`red\*(C'\fR, \f(CW\*(C`green\*(C'\fR, \f(CW\*(C`yellow\*(C'\fR, +\&\f(CW\*(C`blue\*(C'\fR, \f(CW\*(C`magenta\*(C'\fR, \f(CW\*(C`cyan\*(C'\fR, \f(CW\*(C`white\*(C'\fR, +.Sp +Prefix with \f(CW\*(C`bright_\*(C'\fR for high-intensity or bold foreground. +.IP "Foreground Grey" 4 +.IX Item "Foreground Grey" +\&\f(CW\*(C`grey0\*(C'\fR, ..., \f(CW\*(C`grey23\*(C'\fR +.IP "Background Color" 4 +.IX Item "Background Color" +\&\f(CW\*(C`on_black\*(C'\fR, \f(CW\*(C`on_red\*(C'\fR, \f(CW\*(C`on_green\*(C'\fR, \f(CW\*(C`on_yellow\*(C'\fR, +\&\f(CW\*(C`on_blue\*(C'\fR, \f(CW\*(C`on_magenta\*(C'\fR, \f(CW\*(C`on_cyan\*(C'\fR, \f(CW\*(C`on_white\*(C'\fR +.Sp +Replace \f(CW\*(C`on_\*(C'\fR with \f(CW\*(C`on_bright_\*(C'\fR for high-intensity or bold background. +.IP "Background Grey" 4 +.IX Item "Background Grey" +\&\f(CW\*(C`on_grey0\*(C'\fR, ..., \f(CW\*(C`on_grey23\*(C'\fR +.IP "Text Attribute" 4 +.IX Item "Text Attribute" +\&\f(CW\*(C`bold\*(C'\fR, \f(CW\*(C`dark\*(C'\fR, \f(CW\*(C`italic\*(C'\fR, \f(CW\*(C`underline\*(C'\fR, \f(CW\*(C`reverse\*(C'\fR +.SH "EXIT STATUS" +.IX Header "EXIT STATUS" +The exit status is 0 if at least one \fI\s-1ID\s0\fR matched \fI\s-1REGEXP\s0\fR, +1 if no \fI\s-1ID\s0\fR matched \fI\s-1REGEXP\s0\fR, and 2 if an error occurred. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +\&\fBgrep\fR(1), \fBprintf\fR(3), \fBTerm::ANSIColor\fR(pm) diff --git a/Master/texmf-dist/doc/man/man1/typog-grep.man1.pdf b/Master/texmf-dist/doc/man/man1/typog-grep.man1.pdf Binary files differnew file mode 100644 index 00000000000..ca0157d129b --- /dev/null +++ b/Master/texmf-dist/doc/man/man1/typog-grep.man1.pdf diff --git a/Master/texmf-dist/scripts/typog/typog-grep.pl b/Master/texmf-dist/scripts/typog/typog-grep.pl new file mode 100755 index 00000000000..bc7f0e98fbd --- /dev/null +++ b/Master/texmf-dist/scripts/typog/typog-grep.pl @@ -0,0 +1,614 @@ +#! /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#^</?typog-inspect[ >]#; # somewhat sloppy definition +my $close_tag_regexp = qr#^</typog-inspect>#; +my $open_tag_regexp = + qr#^ + <typog-inspect \s+ + id="(?<id_match> .*?)" \s+ + job="(?<job_match> .*?)" \s+ + line="(?<line_match> .*?)" \s+ + page="(?<page_match> .*?)" + >#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 <<HELP_TEXT; +Usage: @{[COMMAND_NAME]} [OPTION] ID-REGEXP LOG-FILE... +Structured grep for typog-inspect elements that match ID-REGEXP in LOG-FILE. + +Options + --color [WHEN], + --colour [WHEN] use color to highlight specific log contents + WHEN is 'always', 'never', or 'auto' + -C, --config KEY=VALUE set configuration KEY to VALUE + -i, --[no-]id print matching id with output lines + -y, --[no-]ignore-case ignore case distinctions in patterns and data + -j, --[no-]job-name print \\jobname with output lines + -n, --[no-]line-number print TeX-source line number with output lines + -N, --[no-]log-line-number print log-file line number with output lines + -p, --[no-]page-number print page number with output lines + -P, --[no-]pager redirect output to pager + -w, --[no-]word-regexp match only whole words + + -a, --all, --any show all IDs in LOG-FILE + --debug turn on debug output + -h, --help display this help and exit + --show-config show default configuration and exit + -V, --version show version information and exit + +HELP_TEXT + + exit 0; +} + +sub show_configuration { + my $format_string_value = sub {quote_literal($default_configuration->{$_[0]})}; + + print <<FIXED_CONFIGURATION_TEXT; +Configuration +Key Default Value +------------------------------------ ------------- +id-format @{[$format_string_value->('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 <<VERSION_TEXT; +typog-grep 0.1 + +Copyright (C) 2024 by Ch. L. Spiel +License LPPL: LaTeX Project Public License version 1.3 or later +VERSION_TEXT + + exit 0; +} + +sub get_options { + my ($options, $configuration) = @_; + + Getopt::Long::Configure('gnu_getopt', 'no_ignore_case'); + + Getopt::Long::GetOptions('a|all|any' => \$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(); diff --git a/Master/texmf-dist/source/latex/typog/Makefile b/Master/texmf-dist/source/latex/typog/Makefile new file mode 100644 index 00000000000..bb3c83ab24b --- /dev/null +++ b/Master/texmf-dist/source/latex/typog/Makefile @@ -0,0 +1,302 @@ +### name: Makefile +### synopsis: Build `typog' style file, tools, and documentation +### author: Dr. Christoph L. Spiel +### GNU make version: 4.3 + + +SHELL := /bin/sh + + +LATEX := /usr/bin/env max_print_line=2147483647 pdflatex +LATEX_FLAGS := -file-line-error -halt-on-error -interaction=nonstopmode +LATEX_RERUN_TRIGGER := '^Package rerunfilecheck Warning: File [^ ]* has changed' +LATEX_WARNING := '^LaTeX (|[A-Za-z0-9_]* )Warning:' + +MAKEINDEX := makeindex +MAKEINDEX_FLAGS := -q + + +METAPOST := mpost +METAPOST_FLAGS := -file-line-error -interaction=nonstopmode -tex=latex + + +PODCHECKER := podchecker +PODCHECKER_FLAGS := -warnings + + +POD2MAN := pod2man +POD2MAN_FLAGS := $$(sed -ne 's,\\ProvidesPackage{typog}\[\([0-9][0-9]*/[0-9][0-9]*/[0-9][0-9]*\) *v\([^ ]*\) .*$$,--date=\1 --release=\2,p' < typog.sty) + + +POD2TEXI := pod2texi +POD2TEXI_FLAGS := + + +GROFF := groff +## Codes of serif fonts that work for PDF output +## BM: URW Bookman L +## N: URW Century Schoolbook L +## P: URW Palladio L +## T: URW Nimbus Roman No9 L +GROFF_FLAGS := -Tpdf -dpaper=a4 -fP -man -wall + + +SPELLCHECK := aspell +SPELLCHECK_FLAGS := \ + --add-tex-command='citenum p' --add-tex-command='code p' \ + --add-tex-command='Cref p' --add-tex-command='cref p' \ + --add-tex-command='cs p' \ + --add-tex-command='DescribeEnv p' --add-tex-command='DescribeMacro p' \ + --add-tex-command='marg p' --add-tex-command='meta p' \ + --add-tex-command='oarg p' \ + --lang=en_US --mode=tex + + +SOURCE_FILES := LICENSE Makefile typog.dtx typog.ins + + + +.PHONY: all +all: sty pdf man + + +.PHONY: sty +sty: typog.sty + + +.PHONY: pdf +pdf: doc ex nomt + + +.PHONY: doc +doc: typog.pdf + + +.PHONY: ex +ex: typog-example.pdf + + +.PHONY: nomt +nomt: typog-nomt.pdf + + +.PHONY: man +man: typog-grep.1 + + +.PHONY: cpio +cpio: + cd ..; \ + echo $(addprefix typog/,$(SOURCE_FILES)) | \ + cpio -o | \ + gzip > "typog-$$(date +%Y-%m-%d).cpio.gz" + + +.PHONY: tar +tar: + cd ..; \ + tar czf "typog-$$(date +%Y-%m-%d).tar.gz" $(addprefix typog/,$(SOURCE_FILES)) + + +.PHONY: clean +clean: + $(RM) ./*.1 ./*.aux ./*.brf ./*.glg ./*.glo ./*.gls + $(RM) ./*.hd ./*.idx ./*.ilg ./*.ind ./*.loe ./*.lof ./*.log ./*.lot + $(RM) ./*.mps ./*.mpx ./*.out ./*.pdf ./*.toc + $(RM) mptextmp.* mpxerr.tex + $(RM) README README.html RELEASE-HOWTO RELEASE-HOWTO.html + + +.PHONY: mostlyclean +mostlyclean: clean + + +.PHONY: maintainer-clean +maintainer-clean: mostlyclean + $(RM) ./*.ist ./*.mp ./*.pl ./*.pod ./*.sed ./*.sty ./*.tex + + +.PHONY: tool-check +tool-check: + @printf '*** LATEX = "%s"\n' '$(LATEX)' + $(LATEX) --version + @printf '\n\n*** MAKEINDEX = "%s"\n' '$(MAKEINDEX)' + $(MAKEINDEX) < /dev/null + @printf '\n\n*** METAPOST = "%s"\n' '$(METAPOST)' + $(METAPOST) --version + @printf '\n*** POD2MAN = "%s"\n' '$(POD2MAN)' + $(POD2MAN) --help > /dev/null + @printf '\n\n*** POD2TEXI = "%s"\n' '$(POD2TEXI)' + $(POD2TEXI) --version + @printf '\n\nTool check passed.\n' + + +.PHONY: spell-check +spell-check: + @sed -e '\#<DISABLE-SPELL-CHECK/>#d' \ + -e '\#<DISABLE-SPELL-CHECK>#,\#</DISABLE-SPELL-CHECK>#d' < typog.dtx | \ + sed -e 's/^ *%%*//' | \ + sed -e 's/\\-//g' -e 's/|[^|]*|/ /g' | \ + $(SPELLCHECK) $(SPELLCHECK_FLAGS) list | \ + sort | uniq | fmt | sed -e 's/ / /g' + + +.PHONY: update-docs +update-docs: doc ex typog-grep.1.pdf + cp -f typog.pdf typog-example.pdf typog-grep.1 typog-grep.1.pdf docs + + +define HELP_SCREEN +Selected Phony Targets +---------------------- +all: Make everything there is to make. This is the .DEFAULT_GOAL. + +clean: Remove some products. + +cpio: In the parent directory create a cpio(1) archive of the + project source files whose name is time-stamped. + +doc: Build "typog.pdf" the Typog documentation. + +ex: Build "typog-example.pdf" an example and test file for Typog. + +maintainer-clean: Remove every product file that can be rebuilt even + if uncommon tools are necessary. + +mostlyclean: Remove some more products than clean:. + +pdf: Build doc: and gauge:. + +sty: Only extract "typog.sty" from "typog.dtx". This + operation requires LaTeX (-> $(LATEX)) and nothing else. + +tar: In the parent directory create a tar(1) file of the project + source files whose name is time-stamped. + +tool-check: Check whether some of the required tools to build the + project are available. + + +Selected Implicit Rules +----------------------- +%.pdf: %.dtx + Run LaTeX or pdfLaTeX (-> $(LATEX)) on dtx source until a + fix-point is reached. + +%.pdf: %.tex + Run LaTeX or pdfLaTeX (-> $(LATEX)) on tex file until a + fix-point is reached. + +%.1: %.pod + Create a manual page from plain old documentation format. + Requires podchecker (-> $(PODCHECKER)) and pod2man + (-> $(POD2MAN)). + +%.1.pdf: %.1 + Convert a manual page into a pdf file. Requires groff + (-> $(GROFF)). + + +Some Explicit Rules +------------------- +README.html: + Convert "README.md" to html. Requires markdown(1). + +README: Convert "README.html" to plain text. Requires w3m(1). + +endef + +.PHONY: help +help: + $(info $(HELP_SCREEN)) + + + +.PRECIOUS: %.mps + + + +define MAKE_INDEX_AND_GLOSSARY +sed -e '/@/d' -e 's/{\\ttfamily /{\\ttfamily\\hskip0pt\\relax /' < $*.idx > ,$*.idx; \ +mv ,$*.idx $*.idx; \ +$(MAKEINDEX) $(MAKEINDEX_FLAGS) -s typog.ist -t $*.ilg -o $*.ind $*.idx; \ +$(MAKEINDEX) $(MAKEINDEX_FLAGS) -s gglo.ist -t $*.glg -o $*.gls $*.glo +endef + +define GREP_LATEX_WARNINGS +test -e $*.log && grep -E $(LATEX_WARNING) $*.log | uniq +endef + +%.pdf: %.dtx + $(RM) ./$*.aux ./$*.ind ./$*.idx ./$*.gls ./$*.glo ./$*.lot ./$*.toc + $(LATEX) $(LATEX_FLAGS) -draftmode $< + $(MAKE_INDEX_AND_GLOSSARY) + $(LATEX) $(LATEX_FLAGS) $< + $(MAKE_INDEX_AND_GLOSSARY) + while test -e $*.log && grep -q $(LATEX_RERUN_TRIGGER) $*.log; \ + do \ + $(LATEX) $(LATEX_FLAGS) $<; \ + $(MAKE_INDEX_AND_GLOSSARY); \ + done + $(GREP_LATEX_WARNINGS) + + +%.pdf: %.tex + $(RM) ./$*.aux ./$*.ind ./$*.idx ./$*.lot ./$*.toc + $(LATEX) $(LATEX_FLAGS) -draftmode $< + $(LATEX) $(LATEX_FLAGS) $< + while test -e $*.log && grep -q $(LATEX_RERUN_TRIGGER) $*.log; \ + do \ + $(LATEX) $(LATEX_FLAGS) $<; \ + done + $(GREP_LATEX_WARNINGS) + + +%-1.mps %-2.mps %-3.mps %-4.mps: %.mp + $(METAPOST) -s 'outputtemplate="%j-%c.mps"' $(METAPOST_FLAGS) $< + + +%.1: %.pod + $(PODCHECKER) $(PODCHECKER_FLAGS) $< + $(POD2MAN) $(POD2MAN_FLAGS) $< $@ + +%.1.pdf: %.1 + $(GROFF) $(GROFF_FLAGS) ./$< > $@ + +%.tex: %.pod | teximan2latex.sed + $(POD2TEXI) $(POD2TEXI_FLAGS) ./$< | sed -f teximan2latex.sed > $@ + + +%.html: %.md + markdown $< > $@ + +%: %.html + w3m -cols 79 $< > $@ + + +crooked-paragraphs.mp slant-angle.mp smooth-parshapes.mp title.mp \ +teximan2latex.sed \ +typog-grep.pl typog-grep typog-grep.pod \ +typog.sty typog.ist typog-example.tex typog-nomt.tex: \ + typog.ins typog.dtx + $(LATEX) $(LATEX_FLAGS) $< + chmod 755 typog-grep.pl + ln -sf typog-grep.pl typog-grep + + +crooked-paragraphs-1.mps crooked-paragraphs-2.mps \ +crooked-paragraphs-3.mps crooked-paragraphs-4.mps: crooked-paragraphs.mp + +smooth-parshapes-1.mps smooth-parshapes-2.mps smooth-parshapes-3.mps: smooth-parshapes.mp + +slant-angle-1.mps: slant-angle.mp + +title-1.mps: title.mp + +typog.pdf: typog.dtx \ + crooked-paragraphs-1.mps crooked-paragraphs-2.mps \ + crooked-paragraphs-3.mps crooked-paragraphs-4.mps \ + slant-angle-1.mps title-1.mps \ + smooth-parshapes-1.mps smooth-parshapes-2.mps smooth-parshapes-3.mps \ + typog-grep.tex \ + | typog.sty diff --git a/Master/texmf-dist/source/latex/typog/typog.dtx b/Master/texmf-dist/source/latex/typog/typog.dtx new file mode 100644 index 00000000000..0f2176206a2 --- /dev/null +++ b/Master/texmf-dist/source/latex/typog/typog.dtx @@ -0,0 +1,9974 @@ +% \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} +%</driver> +%<*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 '!' +%</index-style> +% \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 +%</title> +% \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} +% <typog-inspect\textvisiblespace +% id="\meta{id}"\textvisiblespace +% job="\meta{jobname}"\textvisiblespace +% line="\meta{line-number}"\textvisiblespace +% page="\meta{page-number}"> \\ +% ~~\dots \\ +% </typog-inspect> +% \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 '/<typog-inspect\textvisiblespace id="\dots"/,\textbackslash\#</typog-inspect>\#p' \\ +% \> < jobname.log +% \end{codeexample} +% +% or +% +% \begin{codeexample} +% perl \= -ne '\= \$a=0 if /<\textbackslash/typog-inspect>/; \textbackslash \\ +% \>\> print \$\_ if \$a; \textbackslash \\ +% \>\> \$a=1 if /<typog-inspect\textvisiblespace id="\dots"/' \textbackslash \\ +% \> < 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 +%</slantangle> +% \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 +%</crookedparagraphs> +% \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 +%</smoothparshapes> +% \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<num>} 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<typog>{breakpenalty}% + {\renewcommand*{\typog@breakpenalty}{#1}} +\DeclareOptionX<typog>{debug}{\typog@debugtrue} +\DeclareOptionX<typog>{mathitalicscorrection}[.4mu]% + {\typog@mathitalicscorrection=#1\relax}% +\DeclareOptionX<typog>{nodebug}{\typog@debugfalse} +\DeclareOptionX<typog>{textitalicscorrection}[.02em]% + {\setlength{\typog@textitalicscorrection}{#1}} +\DeclareOptionX<typog>{ligaturekern}[.033333em]% + {\setlength{\typog@ligaturekern}{#1}} +\DeclareOptionX<typog>{raisecapitaldash}[\z@]% + {\setlength{\typog@raisecapitaldash}{#1}} +\DeclareOptionX<typog>{raisecapitalguillemets}[\z@]% + {\setlength{\typog@raisecapitalguillemets}{#1}} +\DeclareOptionX<typog>{raisecapitalhyphen}[\z@]% + {\setlength{\typog@raisecapitalhyphen}{#1}} +\DeclareOptionX<typog>{raisecapitaltimes}[\z@]% + {\setlength{\typog@raisecapitaltimes}{#1}} +\DeclareOptionX<typog>{raiseguillemets}[\z@]% + {\setlength{\typog@raiseguillemets}{#1}} +\DeclareOptionX<typog>{raisefiguredash}[\z@]% + {\setlength{\typog@raisefiguredash}{#1}} +\DeclareOptionX<typog>{raise*}[\z@]% + {\setlength{\typog@raisecapitaldash}{#1}% + \setlength{\typog@raisecapitalhyphen}{#1}% + \setlength{\typog@raisecapitaltimes}{#1}% + \setlength{\typog@raisefiguredash}{#1}} +\DeclareOptionX<typog>{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<typog>{slashkern}[.05em]% + {\setlength{\typog@slashkern}{#1}} +\DeclareOptionX<typog>{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<typog>{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<typog>{ + ligaturekern, + mathitalicscorrection, textitalicscorrection, + raisecapitaldash, raisecapitalhyphen, raisecapitaltimes, + raiseguillemets, raisecapitalguillemets, + raisefiguredash, + slashkern} + \ifdefined\MT@MT + \unless\ifx\@onlypreamble\@notprerr + \ExecuteOptionsX<typog>{shrinklimits, stretchlimits} + \fi + \fi} + +\typog@initialize@options +\ProcessOptionsX<typog> + +% \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{<typog-inspect id="\typog@@id" job="\jobname" line="\the\inputlineno" page="\the\value{page}">}% +% \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{</typog-inspect>}% + \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 +%</package> +% \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} +%</example> +% \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} +%</nomicrotype> +% \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 +%</teximan2latex> +% \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#^</?typog-inspect[ >]#; # somewhat sloppy definition +my $close_tag_regexp = qr#^</typog-inspect>#; +my $open_tag_regexp = + qr#^ + <typog-inspect \s+ + id="(?<id_match> .*?)" \s+ + job="(?<job_match> .*?)" \s+ + line="(?<line_match> .*?)" \s+ + page="(?<page_match> .*?)" + >#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 <<HELP_TEXT; +Usage: @{[COMMAND_NAME]} [OPTION] ID-REGEXP LOG-FILE... +Structured grep for typog-inspect elements that match ID-REGEXP in LOG-FILE. + +Options + --color [WHEN], + --colour [WHEN] use color to highlight specific log contents + WHEN is 'always', 'never', or 'auto' + -C, --config KEY=VALUE set configuration KEY to VALUE + -i, --[no-]id print matching id with output lines + -y, --[no-]ignore-case ignore case distinctions in patterns and data + -j, --[no-]job-name print \\jobname with output lines + -n, --[no-]line-number print TeX-source line number with output lines + -N, --[no-]log-line-number print log-file line number with output lines + -p, --[no-]page-number print page number with output lines + -P, --[no-]pager redirect output to pager + -w, --[no-]word-regexp match only whole words + + -a, --all, --any show all IDs in LOG-FILE + --debug turn on debug output + -h, --help display this help and exit + --show-config show default configuration and exit + -V, --version show version information and exit + +HELP_TEXT + + exit 0; +} + + +sub show_configuration { + my $format_string_value = sub {quote_literal($default_configuration->{$_[0]})}; + + print <<FIXED_CONFIGURATION_TEXT; +Configuration +Key Default Value +------------------------------------ ------------- +id-format @{[$format_string_value->('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 <<VERSION_TEXT; +typog-grep 0.1 + +Copyright (C) 2024 by Ch. L. Spiel +License LPPL: LaTeX Project Public License version 1.3 or later +VERSION_TEXT + + exit 0; +} + + +sub get_options { + my ($options, $configuration) = @_; + + Getopt::Long::Configure('gnu_getopt', 'no_ignore_case'); + + Getopt::Long::GetOptions('a|all|any' => \$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(); +%</typog-grep> +% \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<typog-grep> -a|--all|--any [I<OPTION>...] F<LOG-FILE>... + +=item B<typog-grep> [I<OPTION>...] I<REGEXP> F<LOG-FILE>... + +=back + +The first form shows all C<E<lt>typog-inspect id="I<ID>" ...E<gt>> elements in F<LOG-FILE>. + +The second form shows the contents of C<E<lt>typog-inspect id="I<ID>" ...E<gt>> elements +whose I<ID>s match I<REGEXP> in F<LOG-FILE>. + +If no F<LOG-FILE> is given read from F<stdin>. +The S<filename C<->> is synonymous to F<stdin>. + + +=head1 DESCRIPTION + +B<typog-grep> is a tailored post-processor for LaTeX log files +and the C<typoginspect> environment as provided by S<package typog>. +It shares more with the venerable +L<B<sgrep>|https://www.cs.helsinki.fi/u/jjaakkol/sgrep.html> +than with S<POSIX L<B<grep>|https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html>>. + +The LaTeX user brackets her text in + + \begin{typoginspect}{ID} + Text and code to investigate + \end{typoginspect} + +where I<ID> is used to identify one or more bracketed snippets. +I<ID> does not have to be unique. +The I<REGEXP> mechanism makes it easy to select groups of related I<ID>s +if they are named accordingly. + +In F<LOG-FILE> the environment shows up, packed with tracing information, as + +=begin texinfo + +@display +@relax + +=end texinfo + + <typog-inspect id="ID" job="JOB-NAME" line="LINE-NUMBER" page="PAGE-NUMBER"> + Trace Data + </typog-inspect> + +=begin texinfo + +@end display +@relax + +=end texinfo + +where all the capital-letter sequences are meta-variables +and in particular +I<JOB-NAME> is the expansion of C<\jobname>, +I<LINE-NUMBER> is the LaTeX source file line number +of the beginning of the C<typoginspect> environment, +and I<PAGE-NUMBER> is the page where +the output of S<C<Text and code to investigate>> occurs. + +B<typog-grep> reveals the contents of F<LOG-FILE> +between C<E<lt>typog-inspect id="I<ID>" ...E<gt>> +and C<E<lt>/typog-inspectE<gt>> excluding the XML-tags. +Access the I<JOB-NAME>, I<LINE-NUMBER>, and I<PAGE-NUMBER> +with the commandline options +B<--job-name>, B<--line-number>, and B<--page-number>, respectively. +Use B<--id> to show the name of the IDs that matched I<REGEXP>. + +C<typoginspect> environments can be nested. +B<typog-grep> respects the nesting, +i.e., if the I<ID> of the nested environment does not match I<REGEXP> +it will not be included in the program's output. + + +=head1 OPTIONS + +The list of options is sorted by the names of the long options. + +=over 4 + +=item B<-a>, B<--all>, B<--any> + +ID-discovery mode: +Show all C<typog-inspect> elements independent of any matching patterns. + +=item B<--color>, B<colour> I<WHEN> + +Colorize specific log contents for the matching ids. +The S<argument I<WHEN>> determines when to apply color: +C<always>, C<never>, S<or C<auto>>. +The setting C<auto> checks whether standard output has been redirected. +This is the default. + +=item B<-C>, B<--config> I<KEY>=I<VALUE>[:I<KEY>=I<VALUE>[:...]] + +Set one or more configuration I<KEY> to I<VALUE> pairs. +See S<Sec. CONFIGURATION> below for a description of all available configuration items. +Use option B<--show-config> to display the default configuration. + +=item B<--debug> + +Turn on debug output on F<stderr>. + +=item B<-h>, B<--help> + +Display brief help then exit. + +=item B<-i>, B<--[no-]id> + +Print the actual id name that matched I<REGEXP>. +Control the appearance of the matching id with configuration S<item C<id-heading>>. + +=item B<-y>, B<--[no-]ignore-case> + +Match ids while ignoring case distinctions in patterns and data. + +=item B<-j>, B<--[no-]job-name> + +Print the C<\jobname> that B<tex> associated with the input file. + +=item B<-n>, B<--[no-]line-number> + +Print the line number where the S<C<typoginspect> environment> +was encountered in the LaTeX source file. + +=item B<-N>, B<--[no-]log-line-number> + +Print the line number of the F<log>-file where the current line was encountered. + +=item B<-p>, B<--[no-]page-number> + +Print page number where the contents of the S<C<typoginspect> environment> +starts in the typeset document. + +=item B<-P>, B<--[no-]pager> + +Redirect output from F<stdout> to the configured pager. + +=item B<--show-config> + +Show the default configuration and exit. + +=item B<-V>, B<--version> + +Show version information and exit. + +=item B<-w>, B<--[no-]word-regexp> + +Match only whole words. + +=back + + +=head1 CONFIGURATION + +=over 4 + +=item C<id-format>=I<FORMAT> + +Control the I<FORMAT> for printing matching ids in inline-mode, +where I<FORMAT> is passed to Perl's C<printf>. +S<Default: C<%s:>.> + +=item C<id-heading>=C<0>E<verbar>C<1> + +Choose between printing the matching ids with S<option B<--id>>: +S<Inline (C<0>)> or heading before the matching data (C<1>). +S<Default: C<0>.> + +=item C<id-heading-format>=I<FORMAT> + +Control the I<FORMAT> for printing matching ids in heading-mode, +where I<FORMAT> is passed to Perl's C<printf>. +S<Default: C<--E<gt> %s E<lt>-->.> + +=item C<id-indent>=I<INDENT> + +Indentation of nested typog-inspect tags. +Only used in ``discovery'' mode (first form), i.e., if B<--all> is active. +S<Default: 8.> + +=item C<id-max-length>=I<MAXIMUM-LENGTH> + +Set the maximum length of a matching id for printing. +It a matching id exceeds this length it will be truncated +and the last three characters (short of I<MAXIMUM-LENGTH>) will be replaced by dots. +S<Default: 40.> + +=item C<line-number-format>=I<FORMAT> + +Control the I<FORMAT> for printing TeX source line numbers, +where I<FORMAT> is passed to Perl's C<printf>. +S<Default: C<%5d>.> + +=item C<log-line-number-format>=I<FORMAT> + +Control the I<FORMAT> for printing log line numbers, +where I<FORMAT> is passed to Perl's C<printf>. +S<Default: C<%6d>.> + +=item C<page-number-format>=I<FORMAT> + +Control the I<FORMAT> for printing page numbers, +where I<FORMAT> is passed to Perl's C<printf>. +S<Default: C<[%3d]>.> + +=item C<pager>=I<PAGER> + +Name of pager application to pipe output into +if run with S<option B<--pager>>. +S<Default: C<less>>. + +=item C<pager-flags>=I<FLAGS> + +Pass I<FLAGS> to I<PAGER>. +S<Default: C<--quit-if-one-screen>>. + +=item Color Configuration + +For the syntax of the color specifications consult +the manual page of Term::ANSIColor(pm). + +=over 4 + +=item C<file-header-color> + +Color of the filename header. + +=item C<fill-state-color> + +Color of the messages that report ``Underfull hbox'' or ``Overfull hbox''. + +=item C<first-vbox-color> + +Color of the first vbox on a page. + +=item C<font-spec-color> + +Color of font specifications. + +=item C<horizontal-break-candidate-color> + +Color of lines with horizontal-breakpoint S<candidates C<@>>. + +=item C<horizontal-breakpoint-color> + +Color of lines with horizontal S<breakpoints C<@@>>. + +=item C<id-color> + +Color of matching ids when printed inline. + +=item C<id-heading-color> + +Color of matching ids when printed in heading form. + +=item C<line-break-pass-color> + +Color of the lines showing which pass (e.g., C<@firstpass>) +of the line-breaking algorithm is active. + +=item C<line-number-color> + +Color of TeX-source-file line numbers. + +=item C<log-line-number-color> + +Color of log-file line numbers. + +=item C<math-color> + +Color used for math expressions including their font specs. + +=item C<page-number-color> + +Color of page numbers of the final output. + +=item C<tightness-color> + +Color of lines with Tight/Loose hbox reports. + +=item C<vertical-breakpoint-color> + +Color of possible vertical breakpoints. + +=back + +=back + + +=head2 Brief summary of colors and attributes + +=over 4 + +=item Foreground Color + +C<black>, C<red>, C<green>, C<yellow>, +C<blue>, C<magenta>, C<cyan>, C<white>, + +Prefix with C<bright_> for high-intensity or bold foreground. + +=item Foreground Grey + +C<grey0>, ..., C<grey23> + +=item Background Color + +C<on_black>, C<on_red>, C<on_green>, C<on_yellow>, +S<C<on_blue>>, S<C<on_magenta>>, S<C<on_cyan>>, S<C<on_white>> + +Replace C<on_> with C<on_bright_> for high-intensity or bold background. + +=item Background Grey + +C<on_grey0>, ..., C<on_grey23> + +=item Text Attribute + +C<bold>, C<dark>, C<italic>, C<underline>, C<reverse> + +=back + + +=head1 EXIT STATUS + +The exit status is 0 if at least one I<ID> matched I<REGEXP>, +1 if no I<ID> matched I<REGEXP>, and 2 if an error occurred. + + +=head1 SEE ALSO + +B<grep>(1), B<printf>(3), B<Term::ANSIColor>(pm) + + +=cut +%</typog-grep-documentation> +% \fi +% +% +% +\endinput +% +% +% +%%% Local Variables: +%%% compile-command: "latex typog.dtx" +%%% fill-column: 96 +%%% End: diff --git a/Master/texmf-dist/source/latex/typog/typog.ins b/Master/texmf-dist/source/latex/typog/typog.ins new file mode 100644 index 00000000000..06378d86bbe --- /dev/null +++ b/Master/texmf-dist/source/latex/typog/typog.ins @@ -0,0 +1,74 @@ +%% 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. + + +\input docstrip + + +\keepsilent +\askforoverwritefalse + + +\preamble + +This is a generated file. + +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. + +This work has the LPPL maintenance status `maintained'. + +The Current Maintainer of this work is Ch. L. Spiel. + +This work consists of the files typog.dtx and typog.ins +and the derived files typog.sty, slant-angle.mp, +crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, +typog-example.tex, typog-nomt.tex, typog-grep.pl, +typog-grep.pod, and teximan2latex.sed. + + +\endpreamble + + +\edef\source{\jobname.dtx} + +\generate{\file{typog.sty}{\from{\source}{package}} + \file{typog-example.tex}{\from{\source}{example}} + \file{typog-nomt.tex}{\from{\source}{nomicrotype}} + \file{typog.ist}{\from{\source}{index-style}}} + + +\nopostamble +\generate{\file{title.mp}{\from{\source}{title}} + \file{slant-angle.mp}{\from{\source}{slantangle}} + \file{crooked-paragraphs.mp}{\from{\source}{crookedparagraphs}} + \file{smooth-parshapes.mp}{\from{\source}{smoothparshapes}}} + + +\nopreamble +\generate{\file{teximan2latex.sed}{\from{\source}{teximan2latex}} + \file{typog-grep.pl}{\from{\source}{typog-grep}} + \file{typog-grep.pod}{\from{\source}{typog-grep-documentation}}} + + +\endbatchfile + + +%% Local Variables: +%% compile-command: "latex typog.ins" +%% mode: latex +%% End: diff --git a/Master/texmf-dist/tex/latex/typog/typog.sty b/Master/texmf-dist/tex/latex/typog/typog.sty new file mode 100644 index 00000000000..bbb03cb5cbe --- /dev/null +++ b/Master/texmf-dist/tex/latex/typog/typog.sty @@ -0,0 +1,1401 @@ +%% +%% This is file `typog.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% typog.dtx (with options: `package') +%% +%% This is a generated file. +%% +%% 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. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Ch. L. Spiel. +%% +%% This work consists of the files typog.dtx and typog.ins +%% and the derived files typog.sty, slant-angle.mp, +%% crooked-paragraphs.mp, smooth-parshapes.mp, title.mp, +%% typog-example.tex, typog-nomt.tex, typog-grep.pl, +%% typog-grep.pod, and teximan2latex.sed. +%% +%% +\NeedsTeXFormat{LaTeX2e}[2005/12/01] +\ProvidesPackage{typog} + [2024/05/07 v0.3 TypoGraphic extensions] + +\RequirePackage{etoolbox} +\RequirePackage{everyhook} +\RequirePackage{xkeyval} + +\newcommand*{\typog@TYPOG}{} +\newcommand*{\typoglogo}{\textsf{T\itcorr*{-5}\textsl{y}poG}} +\newif\iftypog@debug +\newcommand*{\typog@typeout}[1] + {\iftypog@debug + \typeout{typog: #1}% + \fi} + +\ExplSyntaxOn +\let\typog@trim@spaces=\tl_trim_spaces:o +\ExplSyntaxOff + +\newcommand{\typog@register@pdfsubstitute}[1]{% + \AtBeginDocument{% + \ifdefined\pdfstringdefDisableCommands + \pdfstringdefDisableCommands{#1}% + \fi}} + +\newif\iftypog@microtype@preloaded + +\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 + +\newif\iftypog@microtype@loaded + +\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 +} + +\newmuskip\typog@mathitalicscorrection +\newlength{\typog@textitalicscorrection} +\newlength{\typog@ligaturekern} +\newlength{\typog@raisecapitaldash} +\newlength{\typog@raisecapitalguillemets} +\newlength{\typog@raisecapitalhyphen} +\newlength{\typog@raisecapitaltimes} +\newlength{\typog@raiseguillemets} +\newlength{\typog@raisefiguredash} +\newlength{\typog@slashkern} +\newcommand*{\typog@breakpenalty}{\exhyphenpenalty} +\newlength{\typog@dim@unit} +\setlength{\typog@dim@unit}{.001em} +\newcommand*{\typog@trackingttspacing}{300, 90, 60} +\newcommand*{\typog@default@shrink@i}{5} +\newcommand*{\typog@default@shrink@ii}{10} +\newcommand*{\typog@default@shrink@iii}{20} +\newcommand*{\typog@shrink@i}{} +\newcommand*{\typog@shrink@ii}{} +\newcommand*{\typog@shrink@iii}{} +\newcommand*{\typog@default@stretch@i}{5} +\newcommand*{\typog@default@stretch@ii}{10} +\newcommand*{\typog@default@stretch@iii}{20} +\newcommand*{\typog@stretch@i}{} +\newcommand*{\typog@stretch@ii}{} +\newcommand*{\typog@stretch@iii}{} + +\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<typog>{breakpenalty}% + {\renewcommand*{\typog@breakpenalty}{#1}} +\DeclareOptionX<typog>{debug}{\typog@debugtrue} +\DeclareOptionX<typog>{mathitalicscorrection}[.4mu]% + {\typog@mathitalicscorrection=#1\relax}% +\DeclareOptionX<typog>{nodebug}{\typog@debugfalse} +\DeclareOptionX<typog>{textitalicscorrection}[.02em]% + {\setlength{\typog@textitalicscorrection}{#1}} +\DeclareOptionX<typog>{ligaturekern}[.033333em]% + {\setlength{\typog@ligaturekern}{#1}} +\DeclareOptionX<typog>{raisecapitaldash}[\z@]% + {\setlength{\typog@raisecapitaldash}{#1}} +\DeclareOptionX<typog>{raisecapitalguillemets}[\z@]% + {\setlength{\typog@raisecapitalguillemets}{#1}} +\DeclareOptionX<typog>{raisecapitalhyphen}[\z@]% + {\setlength{\typog@raisecapitalhyphen}{#1}} +\DeclareOptionX<typog>{raisecapitaltimes}[\z@]% + {\setlength{\typog@raisecapitaltimes}{#1}} +\DeclareOptionX<typog>{raiseguillemets}[\z@]% + {\setlength{\typog@raiseguillemets}{#1}} +\DeclareOptionX<typog>{raisefiguredash}[\z@]% + {\setlength{\typog@raisefiguredash}{#1}} +\DeclareOptionX<typog>{raise*}[\z@]% + {\setlength{\typog@raisecapitaldash}{#1}% + \setlength{\typog@raisecapitalhyphen}{#1}% + \setlength{\typog@raisecapitaltimes}{#1}% + \setlength{\typog@raisefiguredash}{#1}} +\DeclareOptionX<typog>{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<typog>{slashkern}[.05em]% + {\setlength{\typog@slashkern}{#1}} +\DeclareOptionX<typog>{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<typog>{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<typog>{ + ligaturekern, + mathitalicscorrection, textitalicscorrection, + raisecapitaldash, raisecapitalhyphen, raisecapitaltimes, + raiseguillemets, raisecapitalguillemets, + raisefiguredash, + slashkern} + \ifdefined\MT@MT + \unless\ifx\@onlypreamble\@notprerr + \ExecuteOptionsX<typog>{shrinklimits, stretchlimits} + \fi + \fi} + +\typog@initialize@options +\ProcessOptionsX<typog> + +\NewDocumentEnvironment{typogsetup}{m} + {\def\typog@@arg{#1}% + \ifx\typog@@arg\empty + \typog@initialize@options + \else + \setkeys{typog}{#1}% + \fi + \ignorespaces} + {\ignorespacesafterend} +\NewDocumentCommand{\typogget}{m}{\csname typog@#1\endcsname} + +\ExplSyntaxOn +\newcommand*{\typog@round@dim@to@tenths}[1] + {\fp_to_decimal:n {round(10 * \dim_to_fp:n{#1} / 1\p@) / 10}} +\ExplSyntaxOff + +\newcommand*{\typog@formatsizeinfo}[3] + {#1#3\kernedslash #2#3} + +\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' + }}} + +\newcommand*{\typog@default@inspect@id@prefix}{a-} +\newcounter{typog@inspect@count} +\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}% + \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{<typog-inspect id="\typog@@id" job="\jobname" line="\the\inputlineno" page="\the\value{page}">}% + \hbadness=\m@ne + \vbadness=\m@ne + \tracingnone + \tracingpages=\@ne + \tracingparagraphs=\@ne + \showboxbreadth=\typog@@typoginspect@tracingboxes + \showboxdepth=\typog@@typoginspect@tracingboxes} + {\typeout{</typog-inspect>}% + \ignorespacesafterend} +\NewDocumentEnvironment{typoginspectpar}{m} + {\typoginspect{#1}} + {\par\endtypoginspect} + +\newcommand*{\typog@allowhyphenation} + {\ifvmode + \relax + \else + \nobreak + \hskip\z@skip + \fi} + +\unless\ifdefined\allowhyphenation + \let\allowhyphenation=\typog@allowhyphenation +\fi + +\NewDocumentCommand{\breakpoint}{s} + {\discretionary{}{}{}% + \IfBooleanTF{#1}% + {\ignorespaces}% + {\typog@allowhyphenation}} + +\typog@register@pdfsubstitute{ + \def\breakpoint#1{\if*\detokenize{#1}\ignorespaces\fi}% +} + +\NewDocumentEnvironment{hyphenmin}{o m} + {\lefthyphenmin=\IfNoValueTF{#1}{#2}{#1}% + \righthyphenmin=#2} + {} + +\newcommand*{\typog@hyphen}{\char`-} + +\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}}} + +\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} +} + +\newcommand*{\typog@itcorr@text@unconditional}[1] + {\kern#1\typog@textitalicscorrection} +\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} +\newcommand*{\typog@itcorr@math}[1] + {\mkern#1\typog@mathitalicscorrection} +\NewDocumentCommand{\itcorr}{s m} + {\ifmmode + \typog@itcorr@math{#2}% + \else + \IfBooleanTF{#1}% + {\typog@itcorr@text{#2}}% + {\typog@itcorr@text@unconditional{#2}}% + \fi} +\typog@register@pdfsubstitute{ + \RenewExpandableDocumentCommand{\itcorr}{s m}{} +} + +\newcommand*{\typog@forwardslash}{\char`/} +\NewDocumentCommand{\kernedslash}{s} + {\hspace*{\typog@slashkern}% + \typog@forwardslash + \IfBooleanTF{#1}% + {\hspace*{\typog@slashkern}\ignorespaces}% + {\typog@breakpoint\typog@allowhyphenation\hspace*{\typog@slashkern}}} +\typog@register@pdfsubstitute{ + \def\kernedslash#1{\if*\detokenize{#1}/\ignorespaces\else/#1\fi}% +} + +\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} +\typog@register@pdfsubstitute{ + \RenewExpandableDocumentCommand{\kernedhyphen}{s o m m}{-} +} +\NewDocumentCommand{\leftkernedhyphen}{s O{0} m} + {\IfBooleanTF{#1}% + {\kernedhyphen*[#2]{#3}{0}\ignorespaces}% + {\kernedhyphen[#2]{#3}{0}}} +\typog@register@pdfsubstitute{ + \RenewExpandableDocumentCommand{\leftkernedhyphen}{s o m}{-} +} + +\NewDocumentCommand{\rightkernedhyphen}{s O{0} m} + {\IfBooleanTF{#1}% + {\kernedhyphen*[#2]{0}{#3}\ignorespaces}% + {\kernedhyphen[#2]{0}{#3}}} +\typog@register@pdfsubstitute{ + \RenewExpandableDocumentCommand{\rightkernedhyphen}{s o m}{-} +} + +\newcommand*{\typog@breakpoint} + {\penalty\typog@breakpenalty} +\NewDocumentCommand{\capitalhyphen}{s} + {\raisebox{\typog@raisecapitalhyphen}{\typog@hyphen}% + \IfBooleanTF{#1}% + {\ignorespaces}% + {\typog@breakpoint\typog@allowhyphenation}} +\typog@register@pdfsubstitute{ + \def\capitalhyphen#1{% + \if*\detokenize{#1}% + -\ignorespaces + \else + -#1% + \fi} +} + +\NewDocumentCommand{\capitalendash}{s} + {\raisebox{\typog@raisecapitaldash}{\textendash}% + \IfBooleanTF{#1}% + {\ignorespaces}% + {\typog@breakpoint\typog@allowhyphenation}} +\let\capitaldash=\capitalendash +\typog@register@pdfsubstitute{ + \def\capitalendash#1{% + \if*\detokenize{#1}% + \textendash\ignorespaces + \else + \textendash#1% + \fi} + \let\capitaldash=\capitalendash +} + +\NewDocumentCommand{\capitalemdash}{s} + {\raisebox{\typog@raisecapitaldash}{\textemdash}% + \IfBooleanTF{#1}% + {\ignorespaces}% + {\typog@breakpoint\typog@allowhyphenation}} +\typog@register@pdfsubstitute{ + \def\capitalemdash#1{% + \if*\detokenize{#1}% + \textemdash\ignorespaces + \else + \textemdash#1% + \fi} +} + +\NewDocumentCommand{\figuredash}{s} + {\raisebox{\typog@raisefiguredash}{\textendash}% + \IfBooleanTF{#1}% + {\ignorespaces}% + {\typog@breakpoint\typog@allowhyphenation}} +\typog@register@pdfsubstitute{\let\figuredash=\capitaldash} + +\NewDocumentCommand{\capitaltimes}{} + {\ifmmode + \mathbin{\raisebox{\typog@raisecapitaltimes}{$\m@th\times$}}% + \else + \raisebox{\typog@raisecapitaltimes}{\texttimes}% + \fi} +\typog@register@pdfsubstitute{ + \RenewExpandableDocumentCommand{\capitaltimes}{}{\texttimes} +} + +\NewDocumentCommand{\singleguillemetleft}{} + {\typog@allowhyphenation + \raisebox{\typog@raiseguillemets}{\guilsinglleft}} +\typog@register@pdfsubstitute{\let\singleguillemetleft\guilsinglleft} +\NewDocumentCommand{\singleguillemetright}{} + {\raisebox{\typog@raiseguillemets}{\guilsinglright}% + \typog@allowhyphenation} +\typog@register@pdfsubstitute{\let\singleguillemetright\guilsinglright} +\NewDocumentCommand{\doubleguillemetleft}{} + {\typog@allowhyphenation + \raisebox{\typog@raiseguillemets}{\guillemotleft}} +\typog@register@pdfsubstitute{\let\doubleguillemetleft\guillemotleft} +\NewDocumentCommand{\doubleguillemetright}{} + {\raisebox{\typog@raiseguillemets}{\guillemotright}% + \typog@allowhyphenation} +\typog@register@pdfsubstitute{\let\doubleguillemetright\guillemotright} +\NewDocumentCommand{\Singleguillemetleft}{} + {\typog@allowhyphenation + \raisebox{\typog@raisecapitalguillemets}{\guilsinglleft}} +\typog@register@pdfsubstitute{\let\Singleguillemetleft\guilsinglleft} +\NewDocumentCommand{\Singleguillemetright}{} + {\raisebox{\typog@raisecapitalguillemets}{\guilsinglright}% + \typog@allowhyphenation} +\typog@register@pdfsubstitute{\let\Singleguillemetright\guilsinglright} +\NewDocumentCommand{\Doubleguillemetleft}{} + {\typog@allowhyphenation + \raisebox{\typog@raisecapitalguillemets}{\guillemotleft}} +\typog@register@pdfsubstitute{\let\Doubleguillemetleft\guillemotleft} +\NewDocumentCommand{\Doubleguillemetright}{} + {\raisebox{\typog@raisecapitalguillemets}{\guillemotright}% + \typog@allowhyphenation} +\typog@register@pdfsubstitute{\let\Doubleguillemetright\guillemotright} + +\NewDocumentEnvironment{lastlineraggedleftpar}{} + {\lastlinefit=0% + \setlength{\leftskip}{\z@ \@plus 1fil}% + \setlength{\rightskip}{-\leftskip}% + \setlength{\parfillskip}{\leftskip}} + {\par} +\let\lastlineflushrightpar=\lastlineraggedleftpar +\let\endlastlineflushrightpar=\endlastlineraggedleftpar + +\NewDocumentEnvironment{lastlinecenteredpar}{} + {\lastlinefit=0% + \setlength{\leftskip}{\z@ \@plus .5fil}% + \setlength{\rightskip}{-\leftskip}% + \setlength{\parfillskip}{\z@ \@plus 1fil}} + {\par} + +\NewDocumentEnvironment{shortenpar}{} + {\advance\looseness by -1 + \ifnum\tracingparagraphs>0 + \typeout{@ looseness \the\looseness}% + \fi} + {\par} + +\NewDocumentEnvironment{prolongpar}{} + {\finalhyphendemerits=100000001 + \advance\looseness by 1 + \ifnum\tracingparagraphs>0 + \typeout{@ looseness \the\looseness}% + \fi} + {\par} + +\newcommand*{\typog@covernextindentpar@zero@parindent}{2em} +\newcommand*{\typog@covernextindentpar@nonzero@parindent}{2\parindent} +\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} + +\newcommand*{\typog@openlastlinepar@zero@parindent}{2em} +\newcommand*{\typog@openlastlinepar@nonzero@parindent}{2\parindent} +\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} + +\newcommand*{\widespacestrength}{1.} +\newcommand*{\widespacescale}{1.125} +\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} + +\newcommand*{\narrowspacestrength}{.5} +\newcommand*{\narrowspacescale}{.9375} +\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} + +\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} + +\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} + +\NewDocumentEnvironment{setfonttracking}{m} + {\edef\MT@letterspace@{#1}% + \lsstyle + \ignorespaces} + {\ignorespacesafterend} + +\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 = {*}}% + {}} +\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} +\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 + +\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} + +\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} + +\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} + +\NewDocumentEnvironment{nofontexpansion}{} + {\ifdefined\microtypesetup + \microtypesetup{expansion=false}% + \fi + \ignorespaces} + {\ignorespacesafterend} +\let\nofontexpand=\nofontexpansion +\let\endnofontexpand=\endnofontexpansion + +\NewDocumentEnvironment{nocharprotrusion}{} + {\ifdefined\microtypesetup + \microtypesetup{protrusion=false}% + \fi + \ignorespaces} + {\ignorespacesafterend} + +\newcommand*{\typog@scaled@emergencystretch}[1] + {\emergencystretch=\ifdim\linewidth=\z@ + #1% + \else + \dimexpr (#1) * \linewidth / \textwidth + \fi} + +\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} +\NewDocumentEnvironment{slightlysloppypar}{O{1}} + {\par\slightlysloppy[#1]\ignorespaces} + {\par} + +\ExplSyntaxOn +\newcommand*{\typog@geometric@mean}[2] + {\fp_to_int:n {sqrt((#1) * (#2))}} +\ExplSyntaxOff + +\newcounter{typog@mean@penalty} + +\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} + +\NewDocumentEnvironment{vtietoppar}{O{3}} + {\vtietop[#1]} + {\par + \ignorespacesafterend} + +\NewDocumentCommand{\splicevtietop}{O{3}} + {\let\typog@old@item=\@item + \def\@item[##1]{\typog@old@item[##1]\vtietop[#1]}% + \ignorespaces} + +\ifdefined\SetEnumitemKey + \SetEnumitemKey{vtietop}{first=\splicevtietop} +\fi + +\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} + +\NewDocumentEnvironment{vtiebotpar}{O{3}} + {\vtiebot[#1]} + {\par + \ignorespacesafterend} + +\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} + +\NewDocumentEnvironment{vtiebotdisp}{O{3}} + {\typog@vtiebotdisp{#1}} + {\ignorespacesafterend} + +\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} + +\newenvironment*{breakabledisplay}[1][3] + {\allowdisplaybreaks[#1]} + {\ignorespacesafterend} + +\newcommand*{\typog@setbaselineskip@iter@limit}{10} +\newcommand*{\typog@setbaselineskip@relative@error}{.001} +\ExplSyntaxOn +\cs_new:Npn \typog@setbaselineskip #1 +{ + \int_set:Nn \l_tmpa_int {1} + \int_set:Nn \l_tmpb_int {\typog@setbaselineskip@iter@limit} + \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} +} + +\cs_new:Npn \setbaselineskip #1 +{ + \AfterPreamble{\typog@setbaselineskip{#1}} + \ignorespaces +} + +\cs_new:Npn \resetbaselineskip +{ + \AfterPreamble{\setstretch{1}} +} + +\dim_new:N \typogfontsize +\AfterEndPreamble{ + \dim_set:Nn \typogfontsize {\fontdimen6\font} + \typog@typeout{\string\typogfontsize = + \dim_use:N \typogfontsize\space + (at\space begin\space of\space document)} +} + +\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 +} + +\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 +} + +\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 + +\ExplSyntaxOn +\cs_new_eq:NN \typog@repeat \prg_replicate:nn + +\newcommand*{\typog@mod}[2]{\int_mod:nn{#1}{#2}} +\ExplSyntaxOff + +\newcommand*{\typog@triplet@max@lines}{99} + +\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} + +\newcommand*{\typog@quintuplet@max@lines}{95} + +\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} + +\newcommand*{\typog@septuplet@max@lines}{98} + +\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} + +\newcommand*{\smoothraggedrightfuzzfactor}{1.0} +\newcommand*{\smoothraggedrightgenerator}{triplet} +\newlength{\smoothraggedrightleftskip} +\newlength{\smoothraggedrightparindent} +\newlength{\smoothraggedrightragwidth} +\setlength{\smoothraggedrightragwidth}{2em} + +\newdimen{\typog@fuzzwidth} + +\define@key[typog]{smoothraggedrightpar}{linewidth}% + {\def\typog@@linewidth{#1}} + +\NewDocumentEnvironment{smoothraggedrightpar}{O{}} + {\edef\typog@@linewidth{\linewidth}% + \setkeys[typog]{smoothraggedrightpar}{#1}% + \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}% + \let\typog@@smoothraggedrightleftskip=\smoothraggedrightleftskip + \ifnum\@listdepth>0 + \addtolength{\typog@@smoothraggedrightleftskip}{\leftmargin}% + \fi + \typog@fuzzwidth=\smoothraggedrightfuzzfactor\smoothraggedrightragwidth + \ifcase\typog@@generatorchoice + \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 + \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 + \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} + +\NewDocumentEnvironment{smoothraggedright}{O{}} + {\PushPostHook{par}{\hskip-\parindent\smoothraggedrightpar[#1]\relax}} + {\par\PopPostHook{par}} + +\endinput +%% +%% End of file `typog.sty'. diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 6e0e05f252f..8a0498ea86b 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -876,7 +876,7 @@ my @TLP_working = qw( twemoji-colr twemojis twoinone twoup twoxtwogame txfonts txfontsb txgreeks txuprcal type1cm typed-checklist typeface typehtml typeoutfileinfo typewriter - typicons typoaid typogrid typstfun tzplot + typicons typoaid typog typogrid typstfun tzplot uaclasses uafthesis uantwerpendocs uassign ucalgmthesis ucharcat ucharclasses ucbthesis ucdavisthesis ucph-revy ucs ucsmonograph diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds index 1b3c6a55dc8..5ffd4403824 100755 --- a/Master/tlpkg/libexec/ctan2tds +++ b/Master/tlpkg/libexec/ctan2tds @@ -1484,6 +1484,7 @@ chomp (my $ctan_root = `tlpkginfo --ctan-root`); 'typedref', "die 'skipping, nonfree license'", 'typespec', "die 'skipping, nonfree font specimens'", 'typingtex', "die 'skipping, ancient mac docs'", + 'typog', "&MAKEflatten", 'uafthesis', "&MAKEnosymlinks", 'uebungsblatt',"&MAKEflatten", 'ufrgscca', "&MAKEflatten", @@ -3449,6 +3450,7 @@ $standardinsrunner = "latex -8bit"; 'synthslant' => 'NULL', # doc 'tipfr' => 'NULL', # doc 'ticollege' => 'NULL', # doc + 'typog' => 'NULL', # doc 'tzplot' => 'NULL', # doc 'turnthepage' => 'NULL', # doc 'voss-mathmode' => 'NULL', # doc @@ -3485,6 +3487,7 @@ $standardmp = '\.mp$'; 'semioneside', 'NULL', # not figure*.mp 'synthslant', 'NULL', # doc figures 'textpath', 'textpath.mp', # not textpathfigs.mp + 'typog', 'NULL', # doc figures ); @@ -3867,6 +3870,7 @@ $standardttf = '\.ttf|\.TTC'; 'thumbpdf' => '\.pl$', 'tikztosvg' => '^tikztosvg$', 'tlcockpit' => '\.sh$', + 'typog' => 'typog-grep.pl$', 'ulqda' => '\.pl$', 'urlbst' => 'urlbst$', 'vpe' => '\.pl$', @@ -3957,6 +3961,7 @@ $standardttf = '\.ttf|\.TTC'; 'texlogsieve' => '\.1$', 'tikztosvg' => '\.1$', 'tlcockpit' => '\.man$', + 'typog' => '\.1$', 'webquiz' => '\.1$', 'wheretotrim' => '\.1$', ); diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc index 570b25af4e3..36fc9338898 100644 --- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc @@ -1434,6 +1434,7 @@ depend type1cm depend typed-checklist depend typeface depend typoaid +depend typog depend typogrid depend uassign depend ucs diff --git a/Master/tlpkg/tlpsrc/typog.tlpsrc b/Master/tlpkg/tlpsrc/typog.tlpsrc new file mode 100644 index 00000000000..27aa6ccdd1b --- /dev/null +++ b/Master/tlpkg/tlpsrc/typog.tlpsrc @@ -0,0 +1,3 @@ +binpattern f bin/${ARCH}/${PKGNAME}-grep +docpattern +f texmf-dist/doc/man/man1/${PKGNAME}-grep.* + |