texlive[71202] trunk: typog (7may24)

commits+karl at tug.org commits+karl at tug.org
Tue May 7 22:11:51 CEST 2024


Revision: 71202
          https://tug.org/svn/texlive?view=revision&revision=71202
Author:   karl
Date:     2024-05-07 22:11:51 +0200 (Tue, 07 May 2024)
Log Message:
-----------
typog (7may24)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/Makefile.am
    trunk/Build/source/texk/texlive/linked_scripts/Makefile.in
    trunk/Build/source/texk/texlive/linked_scripts/scripts.lst
    trunk/Master/tlpkg/bin/tlpkg-ctan-check
    trunk/Master/tlpkg/libexec/ctan2tds
    trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc

Added Paths:
-----------
    trunk/Build/source/texk/texlive/linked_scripts/typog/
    trunk/Build/source/texk/texlive/linked_scripts/typog/typog-grep.pl
    trunk/Master/bin/aarch64-linux/typog-grep
    trunk/Master/bin/amd64-freebsd/typog-grep
    trunk/Master/bin/amd64-netbsd/typog-grep
    trunk/Master/bin/armhf-linux/typog-grep
    trunk/Master/bin/i386-freebsd/typog-grep
    trunk/Master/bin/i386-linux/typog-grep
    trunk/Master/bin/i386-netbsd/typog-grep
    trunk/Master/bin/i386-solaris/typog-grep
    trunk/Master/bin/universal-darwin/typog-grep
    trunk/Master/bin/windows/typog-grep.exe
    trunk/Master/bin/x86_64-cygwin/typog-grep
    trunk/Master/bin/x86_64-darwinlegacy/typog-grep
    trunk/Master/bin/x86_64-linux/typog-grep
    trunk/Master/bin/x86_64-linuxmusl/typog-grep
    trunk/Master/bin/x86_64-solaris/typog-grep
    trunk/Master/texmf-dist/doc/latex/typog/
    trunk/Master/texmf-dist/doc/latex/typog/README.md
    trunk/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md
    trunk/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp
    trunk/Master/texmf-dist/doc/latex/typog/index.md
    trunk/Master/texmf-dist/doc/latex/typog/slant-angle.mp
    trunk/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp
    trunk/Master/texmf-dist/doc/latex/typog/teximan2latex.sed
    trunk/Master/texmf-dist/doc/latex/typog/title.mp
    trunk/Master/texmf-dist/doc/latex/typog/typog-example.pdf
    trunk/Master/texmf-dist/doc/latex/typog/typog-example.tex
    trunk/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf
    trunk/Master/texmf-dist/doc/latex/typog/typog-grep.pod
    trunk/Master/texmf-dist/doc/latex/typog/typog-nomt.tex
    trunk/Master/texmf-dist/doc/latex/typog/typog.ist
    trunk/Master/texmf-dist/doc/latex/typog/typog.pdf
    trunk/Master/texmf-dist/doc/man/man1/typog-grep.1
    trunk/Master/texmf-dist/doc/man/man1/typog-grep.man1.pdf
    trunk/Master/texmf-dist/scripts/typog/
    trunk/Master/texmf-dist/scripts/typog/typog-grep.pl
    trunk/Master/texmf-dist/source/latex/typog/
    trunk/Master/texmf-dist/source/latex/typog/Makefile
    trunk/Master/texmf-dist/source/latex/typog/typog.dtx
    trunk/Master/texmf-dist/source/latex/typog/typog.ins
    trunk/Master/texmf-dist/tex/latex/typog/
    trunk/Master/texmf-dist/tex/latex/typog/typog.sty
    trunk/Master/tlpkg/tlpsrc/typog.tlpsrc

Modified: trunk/Build/source/texk/texlive/linked_scripts/Makefile.am
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/Makefile.am	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Build/source/texk/texlive/linked_scripts/Makefile.am	2024-05-07 20:11:51 UTC (rev 71202)
@@ -256,6 +256,7 @@
 	thumbpdf/thumbpdf.pl \
 	tlcockpit/tlcockpit.sh \
 	tlshell/tlshell.tcl \
+	typog/typog-grep.pl \
 	ulqda/ulqda.pl \
 	urlbst/urlbst \
 	vpe/vpe.pl \

Modified: trunk/Build/source/texk/texlive/linked_scripts/Makefile.in
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/Makefile.in	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Build/source/texk/texlive/linked_scripts/Makefile.in	2024-05-07 20:11:51 UTC (rev 71202)
@@ -473,6 +473,7 @@
 	thumbpdf/thumbpdf.pl \
 	tlcockpit/tlcockpit.sh \
 	tlshell/tlshell.tcl \
+	typog/typog-grep.pl \
 	ulqda/ulqda.pl \
 	urlbst/urlbst \
 	vpe/vpe.pl \

Modified: trunk/Build/source/texk/texlive/linked_scripts/scripts.lst
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/scripts.lst	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Build/source/texk/texlive/linked_scripts/scripts.lst	2024-05-07 20:11:51 UTC (rev 71202)
@@ -197,6 +197,7 @@
 thumbpdf/thumbpdf.pl
 tlcockpit/tlcockpit.sh
 tlshell/tlshell.tcl
+typog/typog-grep.pl
 ulqda/ulqda.pl
 urlbst/urlbst
 vpe/vpe.pl

Added: trunk/Build/source/texk/texlive/linked_scripts/typog/typog-grep.pl
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/typog/typog-grep.pl	                        (rev 0)
+++ trunk/Build/source/texk/texlive/linked_scripts/typog/typog-grep.pl	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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();


Property changes on: trunk/Build/source/texk/texlive/linked_scripts/typog/typog-grep.pl
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/aarch64-linux/typog-grep
===================================================================
--- trunk/Master/bin/aarch64-linux/typog-grep	                        (rev 0)
+++ trunk/Master/bin/aarch64-linux/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/aarch64-linux/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-freebsd/typog-grep
===================================================================
--- trunk/Master/bin/amd64-freebsd/typog-grep	                        (rev 0)
+++ trunk/Master/bin/amd64-freebsd/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-freebsd/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/amd64-netbsd/typog-grep
===================================================================
--- trunk/Master/bin/amd64-netbsd/typog-grep	                        (rev 0)
+++ trunk/Master/bin/amd64-netbsd/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/amd64-netbsd/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/armhf-linux/typog-grep
===================================================================
--- trunk/Master/bin/armhf-linux/typog-grep	                        (rev 0)
+++ trunk/Master/bin/armhf-linux/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/armhf-linux/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-freebsd/typog-grep
===================================================================
--- trunk/Master/bin/i386-freebsd/typog-grep	                        (rev 0)
+++ trunk/Master/bin/i386-freebsd/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-freebsd/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-linux/typog-grep
===================================================================
--- trunk/Master/bin/i386-linux/typog-grep	                        (rev 0)
+++ trunk/Master/bin/i386-linux/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-linux/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-netbsd/typog-grep
===================================================================
--- trunk/Master/bin/i386-netbsd/typog-grep	                        (rev 0)
+++ trunk/Master/bin/i386-netbsd/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-netbsd/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/i386-solaris/typog-grep
===================================================================
--- trunk/Master/bin/i386-solaris/typog-grep	                        (rev 0)
+++ trunk/Master/bin/i386-solaris/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/i386-solaris/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/universal-darwin/typog-grep
===================================================================
--- trunk/Master/bin/universal-darwin/typog-grep	                        (rev 0)
+++ trunk/Master/bin/universal-darwin/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/universal-darwin/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/windows/typog-grep.exe
===================================================================
(Binary files differ)

Index: trunk/Master/bin/windows/typog-grep.exe
===================================================================
--- trunk/Master/bin/windows/typog-grep.exe	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Master/bin/windows/typog-grep.exe	2024-05-07 20:11:51 UTC (rev 71202)

Property changes on: trunk/Master/bin/windows/typog-grep.exe
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/Master/bin/x86_64-cygwin/typog-grep
===================================================================
--- trunk/Master/bin/x86_64-cygwin/typog-grep	                        (rev 0)
+++ trunk/Master/bin/x86_64-cygwin/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-cygwin/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-darwinlegacy/typog-grep
===================================================================
--- trunk/Master/bin/x86_64-darwinlegacy/typog-grep	                        (rev 0)
+++ trunk/Master/bin/x86_64-darwinlegacy/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-darwinlegacy/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linux/typog-grep
===================================================================
--- trunk/Master/bin/x86_64-linux/typog-grep	                        (rev 0)
+++ trunk/Master/bin/x86_64-linux/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linux/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-linuxmusl/typog-grep
===================================================================
--- trunk/Master/bin/x86_64-linuxmusl/typog-grep	                        (rev 0)
+++ trunk/Master/bin/x86_64-linuxmusl/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-linuxmusl/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/bin/x86_64-solaris/typog-grep
===================================================================
--- trunk/Master/bin/x86_64-solaris/typog-grep	                        (rev 0)
+++ trunk/Master/bin/x86_64-solaris/typog-grep	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1 @@
+link ../../texmf-dist/scripts/typog/typog-grep.pl
\ No newline at end of file


Property changes on: trunk/Master/bin/x86_64-solaris/typog-grep
___________________________________________________________________
Added: svn:special
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/README.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/README.md	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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 at users.sourceforge.org>.
+
+
+##  License
+
+Released under the
+[LaTeX Project Public License v1.3c](https://www.latex-project.org/lppl.txt)
+or later.


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/README.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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```


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/RELEASE-HOWTO.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/crooked-paragraphs.mp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/index.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/index.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/index.md	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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)


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/index.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/slant-angle.mp
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/slant-angle.mp	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/slant-angle.mp	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/slant-angle.mp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/smooth-parshapes.mp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/teximan2latex.sed
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/teximan2latex.sed	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/teximan2latex.sed	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/teximan2latex.sed
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/title.mp
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/title.mp	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/title.mp	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/title.mp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/typog-example.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/typog/typog-example.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/typog-example.pdf	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Master/texmf-dist/doc/latex/typog/typog-example.pdf	2024-05-07 20:11:51 UTC (rev 71202)

Property changes on: trunk/Master/texmf-dist/doc/latex/typog/typog-example.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/typog-example.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/typog-example.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/typog-example.tex	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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 at myruled}{%
+  \fs at ruled
+  \def\@fs at capt##1##2{\floatc at ruled{##1\space\capitaldash*\space}{\fussy ##2}}%
+  \def\@fs at pre{\hrule height.8pt depth0pt \kern4pt}%
+  \def\@fs at mid{\kern3pt\hrule\kern3pt}%
+  \def\@fs at 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'.


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/typog-example.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf	2024-05-07 20:11:51 UTC (rev 71202)

Property changes on: trunk/Master/texmf-dist/doc/latex/typog/typog-grep.1.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/typog-grep.pod
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/typog-grep.pod	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/typog-grep.pod	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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
+
+ at display
+ at relax
+
+=end texinfo
+
+    <typog-inspect id="ID" job="JOB-NAME" line="LINE-NUMBER" page="PAGE-NUMBER">
+      Trace Data
+    </typog-inspect>
+
+=begin texinfo
+
+ at end display
+ at 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


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/typog-grep.pod
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/typog-nomt.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/typog-nomt.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/typog-nomt.tex	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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'.


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/typog-nomt.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/typog.ist
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/typog.ist	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/typog/typog.ist	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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'.


Property changes on: trunk/Master/texmf-dist/doc/latex/typog/typog.ist
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/typog/typog.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/typog/typog.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/typog/typog.pdf	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Master/texmf-dist/doc/latex/typog/typog.pdf	2024-05-07 20:11:51 UTC (rev 71202)

Property changes on: trunk/Master/texmf-dist/doc/latex/typog/typog.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/typog-grep.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/typog-grep.1	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/man/man1/typog-grep.1	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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 at 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)


Property changes on: trunk/Master/texmf-dist/doc/man/man1/typog-grep.1
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/man/man1/typog-grep.man1.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/man/man1/typog-grep.man1.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/typog-grep.man1.pdf	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Master/texmf-dist/doc/man/man1/typog-grep.man1.pdf	2024-05-07 20:11:51 UTC (rev 71202)

Property changes on: trunk/Master/texmf-dist/doc/man/man1/typog-grep.man1.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/typog/typog-grep.pl
===================================================================
--- trunk/Master/texmf-dist/scripts/typog/typog-grep.pl	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/typog/typog-grep.pl	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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();


Property changes on: trunk/Master/texmf-dist/scripts/typog/typog-grep.pl
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/typog/Makefile
===================================================================
--- trunk/Master/texmf-dist/source/latex/typog/Makefile	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/typog/Makefile	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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


Property changes on: trunk/Master/texmf-dist/source/latex/typog/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/typog/typog.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/typog/typog.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/typog/typog.dtx	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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 at fontclan#1-#2\relax{#1}
+\newcommand*{\fontclan}{\expandafter\@get at fontclan\f at 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 at figurestyle}\rm\ignorespaces}
+                {\ignorespacesafterend}
+
+\newcommand*{\elseries}{\def\mdseries at rm{el}\def\mdseries at sf{el}\def\mdseries at tt{el}}
+\newcommand*{\textel}[1]{{\elseries\textmd{#1}}}
+\newcommand*{\lseries}{\def\mdseries at rm{l}\def\mdseries at sf{l}\def\mdseries at tt{l}}
+\newcommand*{\textl}[1]{{\lseries\textmd{#1}}}
+%%--\newcommand*{\mdseries}{\def\mdseries at rm{m}\def\mdseries at sf{m}\def\mdseries at tt{m}}
+%%--\newcommand*{\textmd}[1]{{\mdseries\textmd{#1}}}
+\newcommand*{\sbseries}{\def\bfseries at rm{sb}\def\bfseries at sf{sb}\def\bfseries at tt{sb}}
+\newcommand*{\textsb}[1]{{\sbseries\textbf{#1}}}
+\newcommand*{\bseries}{\def\bfseries at rm{b}\def\bfseries at sf{b}\def\bfseries at tt{b}}
+\newcommand*{\textb}[1]{{\bseries\textbf{#1}}}
+\newcommand*{\ebseries}{\def\bfseries at rm{k}\def\bfseries at sf{eb}\def\bfseries at 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 at figure}{htbp}
+\renewcommand*{\fps at 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 at 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 at choicekey,\define at 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 at expansion}
+%  \DoNotIndex{\@ifnextchar,\IfNoValueF,\IfNoValueTF,\ifnum}
+%  \DoNotIndex{\iftypog at microtype@loadedfalse}
+%  \DoNotIndex{\iftypog at 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 at th,\mathbin,\mathord,\maxdimen,\message,\microtypecontext,\microtypesetup}
+%  \DoNotIndex{\@minus,\mkern,\m at ne,\mspace,\MT at letterspace@,\MT at 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 at 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 at 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 at 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 at default@shrink at i, \typog at default@shrink at ii,
+%      \typog at default@shrink at iii} and those for |stretchlimits| are
+%      \mbox{\typog at default@stretch at i, \typog at default@stretch at ii, \typog at default@stretch at 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 at covernextindentpar@nonzero at parindent}\makeatother{}
+%  (if \(\cs{parindent} \not= 0\)),
+%  \makeatletter\typog at covernextindentpar@zero at 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 at openlastlinepar@nonzero at parindent}\makeatother{} (if
+%  \(\cs{parindent} \not= 0\)) or
+%  \makeatletter\typog at openlastlinepar@zero at 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 at 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 at shrink@i\makeatother  &  default  \\
+%        2  &  0  &  \makeatletter\typog at shrink@ii\makeatother  &  \\
+%        3  &  0  &  \makeatletter\typog at 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 at stretch@i\makeatother  &  0  &  default  \\
+%        2  &  \makeatletter\typog at stretch@ii\makeatother  &  0  &  \\
+%        3  &  \makeatletter\typog at 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 at stretch@i\makeatother  &  \hphantom{0}\makeatletter\typog at stretch@i\makeatother  &  default  \\
+%        2  &  \makeatletter\typog at stretch@ii\makeatother  &  \makeatletter\typog at stretch@ii\makeatother  &  \\
+%        3  &  \makeatletter\typog at stretch@iii\makeatother  &  \makeatletter\typog at 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 at triplet@max at lines, \typog at quintuplet@max at lines, or \typog at septuplet@max at 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 at TYPOG}
+%    Define a macro that unequivocally identifies this very package.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at 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 at debug}
+%    Our switch for debug information.
+%
+%    \begin{macrocode}
+\newif\iftypog at debug
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at typeout}
+%    Our debug information printer.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at typeout}[1]
+  {\iftypog at debug
+     \typeout{typog: #1}%
+   \fi}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at trim@spaces}
+%    Pull \cs{tl\_trim\_spaces} into the \singlequotes{classic} namespace.
+%
+%    \begin{macrocode}
+\ExplSyntaxOn
+\let\typog at trim@spaces=\tl_trim_spaces:o
+\ExplSyntaxOff
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at 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 at 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 at microtype@preloaded}.
+%
+%  \begin{macro}{\iftypog at microtype@preloaded}
+%    \begin{macrocode}
+\newif\iftypog at microtype@preloaded
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at require@preloaded at 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 at MT
+  \typog at typeout{package microtype preloaded}%
+  \typog at microtype@preloadedtrue
+  \def\typog at require@preloaded at microtype{\relax}
+\else
+  \typog at microtype@preloadedfalse
+  \def\typog at require@preloaded at microtype
+    {\PackageError{typog}%
+                  {package microtype not (pre-)loaded}%
+                  {package microtype must be loaded before package typog}}
+\fi
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\iftypog at microtype@loaded}
+%    \begin{macrocode}
+\newif\iftypog at microtype@loaded
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at require@microtype}
+%    This code duplicates \cs{typog at require@preloaded at microtype};
+%    the only difference is that we call the test \emph{after} the preamble was processed.
+%
+%    \begin{macrocode}
+\AtBeginDocument{
+  \ifdefined\MT at MT
+    \typog at typeout{package microtype loaded}%
+    \typog at microtype@loadedtrue
+    \def\typog at require@microtype{\relax}
+  \else
+    \typog at microtype@loadedfalse
+    \def\typog at 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 at mathitalicscorrection}
+%    \begin{macrocode}
+\newmuskip\typog at mathitalicscorrection
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at textitalicscorrection}
+%    \begin{macrocode}
+\newlength{\typog at textitalicscorrection}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at ligaturekern}
+%    \begin{macrocode}
+\newlength{\typog at ligaturekern}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at raisecapitaldash}
+%    \begin{macrocode}
+\newlength{\typog at raisecapitaldash}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at raisecapitalguillemets}
+%    \begin{macrocode}
+\newlength{\typog at raisecapitalguillemets}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at raisecapitalhyphen}
+%    \begin{macrocode}
+\newlength{\typog at raisecapitalhyphen}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at raisecapitaltimes}
+%    \begin{macrocode}
+\newlength{\typog at raisecapitaltimes}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at raiseguillemets}
+%    \begin{macrocode}
+\newlength{\typog at raiseguillemets}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at raisefiguredash}
+%    \begin{macrocode}
+\newlength{\typog at raisefiguredash}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at slashkern}
+%    \begin{macrocode}
+\newlength{\typog at slashkern}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at breakpenalty}
+%    \begin{macrocode}
+\newcommand*{\typog at breakpenalty}{\exhyphenpenalty}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at 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 at dim@unit}
+\setlength{\typog at dim@unit}{.001em}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at trackingttspacing}
+%    \begin{macrocode}
+\newcommand*{\typog at trackingttspacing}{300, 90, 60}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at default@shrink at i}
+%    The default configuration for shrink values.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at default@shrink at i}{5}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at default@shrink at ii}
+%    \begin{macrocode}
+\newcommand*{\typog at default@shrink at ii}{10}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at default@shrink at iii}
+%    \begin{macrocode}
+\newcommand*{\typog at default@shrink at iii}{20}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at shrink@i}
+%    Configurable shrink values.
+%    Initialized from the \code{typog at default@shrink@} set.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at shrink@i}{}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at shrink@ii}
+%    \begin{macrocode}
+\newcommand*{\typog at shrink@ii}{}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at shrink@iii}
+%    \begin{macrocode}
+\newcommand*{\typog at shrink@iii}{}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at default@stretch at i}
+%    The default configuration for stretch values.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at default@stretch at i}{5}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at default@stretch at ii}
+%    \begin{macrocode}
+\newcommand*{\typog at default@stretch at ii}{10}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at default@stretch at iii}
+%    \begin{macrocode}
+\newcommand*{\typog at default@stretch at iii}{20}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at stretch@i}
+%    Configurable stretch values.
+%    Initialized from the \code{typog at default@stretch} set.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at stretch@i}{}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at stretch@ii}
+%    \begin{macrocode}
+\newcommand*{\typog at stretch@ii}{}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at stretch@iii}
+%    \begin{macrocode}
+\newcommand*{\typog at stretch@iii}{}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \iffalse
+
+\def\typog at one@of at three#1,#2,#3\relax{\typog at trim@spaces{#1}}
+\def\typog at two@of at three#1,#2,#3\relax{\typog at trim@spaces{#2}}
+\def\typog at three@of at three#1,#2,#3\relax{\typog at trim@spaces{#3}}
+
+\newcommand*{\typog at triple@get at i}[1]{\expandafter\typog at one@of at three #1\relax}
+\newcommand*{\typog at triple@get at ii}[1]{\expandafter\typog at two@of at three #1\relax}
+\newcommand*{\typog at triple@get at iii}[1]{\expandafter\typog at three@of at three #1\relax}
+
+\newcommand*{\typog at set@shrink at limits}
+  {\edef\typog@@star{*}%
+   \edef\typog@@limit{\typog at triple@get at i{\typog at shrinklimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at shrink@i{\number\typog@@limit}\fi
+   \edef\typog@@limit{\typog at triple@get at ii{\typog at shrinklimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at shrink@ii{\number\typog@@limit}\fi
+   \edef\typog@@limit{\typog at triple@get at iii{\typog at shrinklimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at shrink@iii{\number\typog@@limit}\fi}
+
+\newcommand*{\typog at set@stretch at limits}
+  {\edef\typog@@star{*}%
+   \edef\typog@@limit{\typog at triple@get at i{\typog at stretchlimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at stretch@i{\number\typog@@limit}\fi
+   \edef\typog@@limit{\typog at triple@get at ii{\typog at stretchlimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at stretch@ii{\number\typog@@limit}\fi
+   \edef\typog@@limit{\typog at triple@get at iii{\typog at stretchlimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at stretch@iii{\number\typog@@limit}\fi}
+
+\DeclareOptionX<typog>{breakpenalty}%
+  {\renewcommand*{\typog at breakpenalty}{#1}}
+\DeclareOptionX<typog>{debug}{\typog at debugtrue}
+\DeclareOptionX<typog>{mathitalicscorrection}[.4mu]%
+  {\typog at mathitalicscorrection=#1\relax}%
+\DeclareOptionX<typog>{nodebug}{\typog at debugfalse}
+\DeclareOptionX<typog>{textitalicscorrection}[.02em]%
+  {\setlength{\typog at textitalicscorrection}{#1}}
+\DeclareOptionX<typog>{ligaturekern}[.033333em]%
+  {\setlength{\typog at ligaturekern}{#1}}
+\DeclareOptionX<typog>{raisecapitaldash}[\z@]%
+  {\setlength{\typog at raisecapitaldash}{#1}}
+\DeclareOptionX<typog>{raisecapitalguillemets}[\z@]%
+  {\setlength{\typog at raisecapitalguillemets}{#1}}
+\DeclareOptionX<typog>{raisecapitalhyphen}[\z@]%
+  {\setlength{\typog at raisecapitalhyphen}{#1}}
+\DeclareOptionX<typog>{raisecapitaltimes}[\z@]%
+  {\setlength{\typog at raisecapitaltimes}{#1}}
+\DeclareOptionX<typog>{raiseguillemets}[\z@]%
+  {\setlength{\typog at raiseguillemets}{#1}}
+\DeclareOptionX<typog>{raisefiguredash}[\z@]%
+  {\setlength{\typog at raisefiguredash}{#1}}
+\DeclareOptionX<typog>{raise*}[\z@]%
+  {\setlength{\typog at raisecapitaldash}{#1}%
+   \setlength{\typog at raisecapitalhyphen}{#1}%
+   \setlength{\typog at raisecapitaltimes}{#1}%
+   \setlength{\typog at raisefiguredash}{#1}}
+\DeclareOptionX<typog>{shrinklimits}%
+  [\typog at default@shrink at i, \typog at default@shrink at ii, \typog at default@shrink at iii]%
+  {\typog at require@preloaded at microtype
+   \ifx\@onlypreamble\@notprerr
+     \PackageWarning{typog}{option `shrinklimits' can only be used in the preamble}%
+   \else
+     \edef\typog at shrinklimits{#1}%
+     \typog at set@shrink at limits
+   \fi}
+\DeclareOptionX<typog>{slashkern}[.05em]%
+  {\setlength{\typog at slashkern}{#1}}
+\DeclareOptionX<typog>{stretchlimits}%
+  [\typog at default@stretch at i, \typog at default@stretch at ii, \typog at default@stretch at iii]%
+  {\typog at require@preloaded at microtype
+   \ifx\@onlypreamble\@notprerr
+     \PackageWarning{typog}{option `stretchlimits' can only be used in the preamble}%
+   \else
+     \edef\typog at stretchlimits{#1}%
+     \typog at set@stretch at limits
+   \fi}
+\DeclareOptionX<typog>{trackingttspacing}[\typog at trackingttspacing]%
+  {\typog at require@preloaded at microtype
+   \ifx\@onlypreamble\@notprerr
+     \PackageWarning{typog}{option `trackingttspacing' can only be used in the preamble}%
+   \else
+     \typog at typeout{trackingttspacing=#1}%
+     \SetTracking[outer spacing={#1}]{encoding=*, family=tt*}{0}%
+   \fi}
+
+\newcommand*{\typog at initialize@options}
+  {\ExecuteOptionsX<typog>{
+     ligaturekern,
+     mathitalicscorrection, textitalicscorrection,
+     raisecapitaldash, raisecapitalhyphen, raisecapitaltimes,
+     raiseguillemets, raisecapitalguillemets,
+     raisefiguredash,
+     slashkern}
+   \ifdefined\MT at MT
+     \unless\ifx\@onlypreamble\@notprerr
+       \ExecuteOptionsX<typog>{shrinklimits, stretchlimits}
+     \fi
+   \fi}
+
+\typog at 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 at 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 at round@dim at to@tenths}
+%    \begin{macrocode}
+\ExplSyntaxOn
+\newcommand*{\typog at round@dim at 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 at 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 at 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 at fontsize@#2\endcsname
+     {\typog at round@dim at to@tenths{\fontdimen6\font}}%
+   \global\expandafter\edef\csname typog at linespacing@#2\endcsname
+     {\typog at round@dim at to@tenths{\baselineskip}}%
+   \protected\expandafter\gdef\csname #2\endcsname
+     {\@ifnextchar*{\typog at formatsizeinfo
+                      {\csname typog at fontsize@#2\endcsname}%
+                      {\csname typog at linespacing@#2\endcsname}%
+                      {}% no unit
+                      \ignorespaces % eat spaces after star
+                      \@gobble}     % consume the star itself
+                   {\typog at formatsizeinfo
+                      {\csname typog at fontsize@#2\endcsname}%
+                      {\csname typog at linespacing@#2\endcsname}%
+                      {\,pt}% decorative unit `pt'
+  }}}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at default@inspect at id@prefix}
+%    Id-prefix for those |typoinspect|~environments
+%    that were not identified by the user.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at default@inspect at id@prefix}{a-}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{typog at 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 at inspect@count}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{environment}{typoginspect}
+%    \begin{macrocode}
+\define at key[typog]{typoginspect}{tracingboxes}[\maxdimen]%
+           {\def\typog@@typoginspect at tracingboxes{#1}}
+\NewDocumentEnvironment{typoginspect}{O{} m}
+  {\def\typog@@typoginspect at tracingboxes{\m at 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 at inspect@count}%
+     \edef\typog@@id{\typog at default@inspect at id@prefix\arabic{typog at inspect@count}}%
+   \else
+     \edef\typog@@id{\typog at 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 at ne
+   \vbadness=\m at 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 at tracingboxes
+   \showboxdepth=\typog@@typoginspect at 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 at allowhyphenation}
+%    Re-enable automatic hyphenation.
+%
+%    The same or almost the same implementation can be found
+%    in \packagename{babel} as macro~\cs{bbl at allowhyphens}
+%    and \packagename{hyphenat} as macro~\cs{prw at zbreak}.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at allowhyphenation}
+  {\ifvmode
+     \relax
+   \else
+     \nobreak
+     \hskip\z at 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 at 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 at allowhyphenation}}
+
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at 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 at hyphen}
+%    We define our own hyphen so the user can override the definition in a pinch.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at hyphen}{\char`-}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\nolig}
+%    \begin{macrocode}
+\NewDocumentCommand{\nolig}{s o}
+  {\dimen0=\IfNoValueTF{#2}{\typog at ligaturekern}{#2\typog at dim@unit}%
+   \IfBooleanTF{#1}%
+     {\kern\dimen0\ignorespaces}%
+     {\discretionary{\typog at hyphen}{}{\kern\dimen0}%
+      \typog at allowhyphenation
+      \IfNoValueF{#2}{\ignorespaces}}}
+
+%    \end{macrocode}
+%
+%  The \acronym{PDF}-ready version of \cs{nolig} cannot be implemented with \cs{futurelet}.
+%  Doh!
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{
+  \RenewExpandableDocumentCommand{\nolig}{s o m}{%
+    \ifx\typog at TYPOG#3\typog at 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 at itcorr@text at unconditional}
+%    Fallback italics correction for text mode.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at itcorr@text at unconditional}[1]
+  {\kern#1\typog at textitalicscorrection}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at itcorr@text}
+%    Conditional italics correction depending on
+%    the current font's own italics correction,
+%    i.\,e., \cs{fontdimen1}.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at itcorr@text}[1]
+  {\def\typog@@strength{#1}%
+   \dimen0=\fontdimen1\font
+   \ifdim\dimen0=\z@
+     \typog at itcorr@text at unconditional{\typog@@strength}%
+   \else
+     \kern\typog@@strength\dimen0
+   \fi}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at itcorr@math}
+%    Italics correction for math mode.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at itcorr@math}[1]
+  {\mkern#1\typog at 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 at itcorr@math{#2}%
+   \else
+     \IfBooleanTF{#1}%
+       {\typog at itcorr@text{#2}}%
+       {\typog at itcorr@text at unconditional{#2}}%
+   \fi}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{
+  \RenewExpandableDocumentCommand{\itcorr}{s m}{}
+}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \subsection{Apply Extra Kerning}
+%
+%  \subsubsection*{Slash}
+%
+%  \begin{macro}{\typog at forwardslash}
+%    We define our own forward-slash so the user can override the definition in a pinch.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at 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 at slashkern}%
+   \typog at forwardslash
+   \IfBooleanTF{#1}%
+     {\hspace*{\typog at slashkern}\ignorespaces}%
+     {\typog at breakpoint\typog at allowhyphenation\hspace*{\typog at slashkern}}}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at 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 at dim@unit}{$\m at th\mathord{-}$}%
+     \mspace{\muexpr(#4 mu) * 18 / 1000}%
+   \else
+     \def\typog@@auto{*}%
+     \def\typog@@optarg{#2}%
+     \hspace*{#3\typog at dim@unit}%
+     \raisebox{\ifx\typog@@optarg\typog@@auto
+                 \typog at raisecapitalhyphen
+               \else
+                 \typog@@optarg\typog at dim@unit
+               \fi}{\typog at hyphen}%
+     \hspace{#4\typog at dim@unit}%
+     \IfBooleanT{#1}{\nobreak}%
+   \fi}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at 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 at 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 at register@pdfsubstitute{
+  \RenewExpandableDocumentCommand{\rightkernedhyphen}{s o m}{-}
+}
+
+%    \end{macrocode}
+%
+%
+%  \subsection{Raise Selected Characters}
+%
+%  \begin{macro}{\typog at 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 at breakpoint}
+  {\penalty\typog at 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 at raisecapitalhyphen}{\typog at hyphen}%
+   \IfBooleanTF{#1}%
+     {\ignorespaces}%
+     {\typog at breakpoint\typog at 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 at 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 at 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 at raisecapitaldash}{\textendash}%
+   \IfBooleanTF{#1}%
+     {\ignorespaces}%
+     {\typog at breakpoint\typog at allowhyphenation}}
+\let\capitaldash=\capitalendash
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at 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 at raisecapitaldash}{\textemdash}%
+   \IfBooleanTF{#1}%
+     {\ignorespaces}%
+     {\typog at breakpoint\typog at allowhyphenation}}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at 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 at raisefiguredash}{\textendash}%
+   \IfBooleanTF{#1}%
+     {\ignorespaces}%
+     {\typog at breakpoint\typog at allowhyphenation}}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{\let\figuredash=\capitaldash}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\capitaltimes}
+%    \begin{macrocode}
+\NewDocumentCommand{\capitaltimes}{}
+  {\ifmmode
+     \mathbin{\raisebox{\typog at raisecapitaltimes}{$\m at th\times$}}%
+   \else
+     \raisebox{\typog at raisecapitaltimes}{\texttimes}%
+   \fi}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{
+  \RenewExpandableDocumentCommand{\capitaltimes}{}{\texttimes}
+}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\singleguillemetleft}
+%    \begin{macrocode}
+\NewDocumentCommand{\singleguillemetleft}{}
+  {\typog at allowhyphenation
+   \raisebox{\typog at raiseguillemets}{\guilsinglleft}}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{\let\singleguillemetleft\guilsinglleft}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\singleguillemetright}
+%    \begin{macrocode}
+\NewDocumentCommand{\singleguillemetright}{}
+  {\raisebox{\typog at raiseguillemets}{\guilsinglright}%
+   \typog at allowhyphenation}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{\let\singleguillemetright\guilsinglright}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\doubleguillemetleft}
+%    \begin{macrocode}
+\NewDocumentCommand{\doubleguillemetleft}{}
+  {\typog at allowhyphenation
+   \raisebox{\typog at raiseguillemets}{\guillemotleft}}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{\let\doubleguillemetleft\guillemotleft}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\doubleguillemetright}
+%    \begin{macrocode}
+\NewDocumentCommand{\doubleguillemetright}{}
+  {\raisebox{\typog at raiseguillemets}{\guillemotright}%
+   \typog at allowhyphenation}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{\let\doubleguillemetright\guillemotright}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\Singleguillemetleft}
+%    \begin{macrocode}
+\NewDocumentCommand{\Singleguillemetleft}{}
+  {\typog at allowhyphenation
+   \raisebox{\typog at raisecapitalguillemets}{\guilsinglleft}}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{\let\Singleguillemetleft\guilsinglleft}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\Singleguillemetright}
+%    \begin{macrocode}
+\NewDocumentCommand{\Singleguillemetright}{}
+  {\raisebox{\typog at raisecapitalguillemets}{\guilsinglright}%
+   \typog at allowhyphenation}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{\let\Singleguillemetright\guilsinglright}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\Doubleguillemetleft}
+%    \begin{macrocode}
+\NewDocumentCommand{\Doubleguillemetleft}{}
+  {\typog at allowhyphenation
+   \raisebox{\typog at raisecapitalguillemets}{\guillemotleft}}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at register@pdfsubstitute{\let\Doubleguillemetleft\guillemotleft}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\Doubleguillemetright}
+%    \begin{macrocode}
+\NewDocumentCommand{\Doubleguillemetright}{}
+  {\raisebox{\typog at raisecapitalguillemets}{\guillemotright}%
+   \typog at allowhyphenation}
+%    \end{macrocode}
+%
+%    \acronym{PDF}-substitute definition
+%
+%    \begin{macrocode}
+\typog at 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 at covernextindentpar@zero at 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 at covernextindentpar@zero at parindent}{2em}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at covernextindentpar@nonzero at parindent}
+%    \begin{macrocode}
+\newcommand*{\typog at covernextindentpar@nonzero at parindent}{2\parindent}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{environment}{covernextindentpar}
+%    \begin{macrocode}
+\NewDocumentEnvironment{covernextindentpar}{o}
+  {\IfNoValueTF{#1}
+     {\ifdim\parindent=\z@
+        \dimen0=\dimexpr\linewidth - \typog at covernextindentpar@zero at parindent
+      \else
+        \dimen0=\dimexpr\linewidth - \typog at covernextindentpar@nonzero at parindent
+      \fi}
+     {\dimen0=\dimexpr\linewidth - (#1)}%
+   \parfillskip=\dimen0 \@minus \dimen0
+   \relax}
+  {\par}
+
+%    \end{macrocode}
+%  \end{environment}
+%
+%  \begin{macro}{\typog at openlastlinepar@zero at parindent}
+%    These auxiliary macros are meant as a means to override the defaults
+%    of the user-visible environment~|openlastlinepar|.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at openlastlinepar@zero at parindent}{2em}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at openlastlinepar@nonzero at parindent}
+%    \begin{macrocode}
+\newcommand*{\typog at openlastlinepar@nonzero at 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 at openlastlinepar@zero at parindent
+               \@plus 1fil
+               \@minus \typog at openlastlinepar@zero at parindent
+      \else
+        \skip0=\typog at openlastlinepar@nonzero at parindent
+               \@plus 1fil
+               \@minus \typog at openlastlinepar@nonzero at 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 at letterspace@{#1}%
+   \lsstyle
+   \ignorespaces}
+  {\ignorespacesafterend}
+
+%    \end{macrocode}
+%  \end{environment}
+%
+%
+%  \subsubsection*{Font Expansion}
+%
+%  \begin{macro}{\typog at setup@font at 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 at setup@font at expansion}
+  {\SetExpansion
+     [context = typog at shrink1,
+      shrink = \typog at shrink@i,
+      stretch = 0]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at shrink2,
+      shrink = \typog at shrink@ii,
+      stretch = 0]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at shrink3,
+      shrink = \typog at shrink@iii,
+      stretch = 0]%
+     {encoding = {*}}%
+     {}
+
+   \SetExpansion
+     [context = typog at stretch1,
+      shrink = 0,
+      stretch = \typog at stretch@i]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at stretch2,
+      shrink = 0,
+      stretch = \typog at stretch@ii]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at stretch3,
+      shrink = 0,
+      stretch = \typog at stretch@iii]%
+     {encoding = {*}}%
+     {}
+
+   \SetExpansion
+     [context = typog at expand1,
+      shrink = \typog at shrink@i,
+      stretch = \typog at stretch@i]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at expand2,
+      shrink = \typog at shrink@ii,
+      stretch = \typog at stretch@ii]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at expand3,
+      shrink = \typog at shrink@iii,
+      stretch = \typog at stretch@iii]%
+     {encoding = {*}}%
+     {}}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at test@microtype at expansion@feature}
+%    We cannot even parse the \cs{iftypog at microtype@preloaded}~part further down
+%    unless the \cs{ifMT at 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 at test@microtype at expansion@feature}
+  {\ifMT at expansion
+     \typog at typeout{microtype preloaded -- font expansion features available}%
+     \def\typog at require@microtype at expansion{\relax}
+     \typog at setup@font at expansion
+   \else
+     \PackageWarning{typog}{microtype preloaded,\space
+                            but font expansion is disabled}%
+     \def\typog at require@microtype at expansion
+       {\PackageError{typog}
+                     {microtype font expansion disabled}
+                     {pass option `expansion' to package microtype}}
+   \fi}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at require@microtype at 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 at require@microtype}
+%    and~\cs{typog at require@preloaded at microtype}.
+%
+%    Initialize our own flag and setup meaningful messages for later feature checks.
+%
+%    \begin{macrocode}
+\iftypog at microtype@preloaded
+  \typog at test@microtype at expansion@feature
+\else
+  \def\typog at require@microtype at 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 at require@microtype at expansion
+   \ifcase#1% 0
+     \relax
+   \or % 1
+     \microtypecontext{expansion=typog at shrink1}%
+   \or % 2
+     \microtypecontext{expansion=typog at shrink2}%
+   \else % >= 3
+     \microtypecontext{expansion=typog at shrink3}%
+   \fi
+   \ignorespaces}
+  {\ignorespacesafterend}
+
+%    \end{macrocode}
+%  \end{environment}
+%
+%  \begin{environment}{setfontstretch}
+%    \begin{macrocode}
+\NewDocumentEnvironment{setfontstretch}{O{1}}
+  {\typog at require@microtype at expansion
+   \ifcase#1% 0
+     \relax
+   \or % 1
+     \microtypecontext{expansion=typog at stretch1}%
+   \or % 2
+     \microtypecontext{expansion=typog at stretch2}%
+   \else % >= 3
+     \microtypecontext{expansion=typog at stretch3}%
+   \fi
+   \ignorespaces}
+  {\ignorespacesafterend}
+
+%    \end{macrocode}
+%  \end{environment}
+%
+%  \begin{environment}{setfontexpand}
+%    \begin{macrocode}
+\NewDocumentEnvironment{setfontexpand}{O{1}}
+  {\typog at require@microtype at expansion
+   \ifcase#1% 0
+     \relax
+   \or % 1
+     \microtypecontext{expansion=typog at expand1}%
+   \or % 2
+     \microtypecontext{expansion=typog at expand2}%
+   \else % >= 3
+     \microtypecontext{expansion=typog at 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 at 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 at 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 at scaled@emergencystretch{.375em}%
+     \hfuzz=.15\p@
+     \vfuzz=\hfuzz
+   \or % 2
+     \pretolerance=265%
+     \tolerance=530%
+     \typog at scaled@emergencystretch{.75em}%
+     \hfuzz=.15\p@
+     \vfuzz=\hfuzz
+   \or % 3
+     \pretolerance=435%
+     \tolerance=870%
+     \typog at scaled@emergencystretch{1.125em}%
+     \hfuzz=.2\p@
+     \vfuzz=\hfuzz
+   \or % 4
+     \pretolerance=705%
+     \tolerance=1410%
+     \typog at scaled@emergencystretch{1.5em}%
+     \hfuzz=.3\p@
+     \vfuzz=\hfuzz
+   \or % 5
+     \pretolerance=1155%
+     \tolerance=2310%
+     \typog at scaled@emergencystretch{1.875em}%
+     \hfuzz=.35\p@
+     \vfuzz=\hfuzz
+   \or % 6
+     \pretolerance=1880%
+     \tolerance=3760%
+     \typog at scaled@emergencystretch{2.25em}%
+     \hfuzz=.4\p@
+     \vfuzz=\hfuzz
+   \or % 7
+     \pretolerance=3065%
+     \tolerance=6130%
+     \typog at 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 at geometric@mean}
+%    This is just the usual geometric mean of two values~\(x\) and~\(y\): \(\sqrt{x y}\).
+%
+%    \begin{macrocode}
+\ExplSyntaxOn
+\newcommand*{\typog at geometric@mean}[2]
+            {\fp_to_int:n {sqrt((#1) * (#2))}}
+\ExplSyntaxOff
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{typog at mean@penalty}
+%    Reserve a private counter for the geometric-mean penalties.
+%
+%    \begin{macrocode}
+\newcounter{typog at mean@penalty}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\vtietop}
+%    \begin{macrocode}
+\NewDocumentCommand{\vtietop}{O{3}}
+  {\setcounter{typog at mean@penalty}
+              {\typog at geometric@mean{\@M}{\clubpenalty}}%
+   \typog at typeout{vtietop: penalties \the\@M--\the\value{typog at 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 at mean@penalty}
+         \clubpenalty
+   \or % 3
+     \clubpenalties 4
+         \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \or % 4
+     \clubpenalties 5
+         \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \or % 5
+     \clubpenalties 6
+         \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \or % 6
+     \clubpenalties 7
+         \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \or % 7
+     \clubpenalties 8
+         \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \or % 8
+     \clubpenalties 9
+         \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \else % >= 9
+     \clubpenalties 10
+         \@M \@M \@M \@M \@M \@M \@M \@M
+         \value{typog at 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 at old@item=\@item
+   \def\@item[##1]{\typog at 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 at mean@penalty}
+              {\typog at geometric@mean{\@M}{\widowpenalty}}%
+   \typog at typeout{vtiebot: penalties \the\@M--\the\value{typog at 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 at mean@penalty}
+         \widowpenalty
+   \or % 3
+     \widowpenalties 4
+         \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \or % 4
+     \widowpenalties 5
+         \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \or % 5
+     \widowpenalties 6
+         \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \or % 6
+     \widowpenalties 7
+         \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \or % 7
+     \widowpenalties 8
+         \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \or % 8
+     \widowpenalties 9
+         \@M \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \else % >= 9
+     \widowpenalties 10
+         \@M \@M \@M \@M \@M \@M \@M \@M
+         \value{typog at 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 at vtiebotdisp}
+%    \begin{macrocode}
+\NewDocumentCommand{\typog at vtiebotdisp}{m}
+  {\setcounter{typog at mean@penalty}
+              {\typog at geometric@mean{\@M}{\displaywidowpenalty}}%
+   \typog at typeout{vtiebotdisp: penalties \the\@M--\the\value{typog at 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 at mean@penalty}
+         \displaywidowpenalty
+   \or % 3
+     \displaywidowpenalties 4
+         \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \or % 4
+     \displaywidowpenalties 5
+         \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \or % 5
+     \displaywidowpenalties 6
+         \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \or % 6
+     \displaywidowpenalties 7
+         \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \or % 7
+     \displaywidowpenalties 8
+         \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \or % 8
+     \displaywidowpenalties 9
+         \@M \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \else % >= 9
+     \displaywidowpenalties 10
+         \@M \@M \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \fi}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{environment}{vtiebotdisp}
+%    \begin{macrocode}
+\NewDocumentEnvironment{vtiebotdisp}{O{3}}
+  {\typog at 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 at lines{\IfNoValueTF{#2}{#1}{#2}}%
+   \edef\typog@@after at display@math{\vtietop[\typog@@top at lines]}%
+   \PushPostHook{display}{\aftergroup\typog@@after at 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 at 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 at setbaselineskip@iter at limit}{10}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at setbaselineskip@relative at 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 at setbaselineskip@relative at error}{.001}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at 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 at 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 at setbaselineskip@iter at 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 at typeout{\string\setbaselineskip:\space
+    initial\space baselineskip:\space \the\baselineskip}
+  \typog at 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 at setbaselineskip@relative at 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 at typeout{\string\setbaselineskip:\space
+    final\space \string\setstretch\space argument:\space
+    \fp_use:N \l_tmpa_fp}
+  \typog at 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 at 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 at 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 at 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 at 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 at 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 at repeat}
+%    As we shall have to repeat the line specifications for our paragraphs so often we introduce
+%    the two argument macro~\cs{typog at repeat} that takes a \meta{repeat-count} and a \meta{body}
+%    that is repeated.
+%
+%    \begin{macrocode}
+\ExplSyntaxOn
+\cs_new_eq:NN \typog at repeat \prg_replicate:nn
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\typog at mod}
+%    For error checking we shall need the modulo operation on integers, i.\,e., the remainder of
+%    an integral division.
+%
+%    \begin{macrocode}
+\newcommand*{\typog at mod}[2]{\int_mod:nn{#1}{#2}}
+\ExplSyntaxOff
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\typog at triplet@max at 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 at triplet@max at lines}{99}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{environment}{smoothraggedrightshapetriplet}
+%    Engine for 3-line repetitions.
+%
+%    \begin{macrocode}
+\define at key[typog]{smoothraggedrightshapetriplet}{leftskip}%
+           {\def\typog@@triplet at leftskip{#1}}
+\define at key[typog]{smoothraggedrightshapetriplet}{parindent}%
+           {\def\typog@@triplet at parindent{#1}}
+\NewDocumentEnvironment{smoothraggedrightshapetriplet}{O{} m m m}
+  {\def\typog@@triplet at leftskip{\z@}%
+   \def\typog@@triplet at parindent{\z@}%
+   \setkeys*[typog]{smoothraggedrightshapetriplet}{#1}%
+   \skip0=\typog@@triplet at leftskip\relax
+   \skip1=#2\relax
+   \skip2=#3\relax
+   \skip3=#4\relax
+   \typog at typeout{smoothraggedrightshapetriplet: skip0=\the\skip0}%
+   \typog at typeout{smoothraggedrightshapetriplet: skip1=\the\skip1}%
+   \typog at typeout{smoothraggedrightshapetriplet: skip2=\the\skip2}%
+   \typog at typeout{smoothraggedrightshapetriplet: skip3=\the\skip3}%
+   \unless\ifnum\typog at mod{\typog at triplet@max at lines}{3}=0
+     \PackageError{typog}
+                  {Line number of triplet generator %
+                    (\typog at triplet@max at lines) not divisible by 3}
+                  {}
+   \fi
+   \edef\typog@@triplet at linespecs{%
+     \glueexpr \skip0 + \typog@@triplet at parindent\relax
+            \glueexpr \skip1 - \typog@@triplet at parindent\relax
+                    \skip0 \skip2  \skip0 \skip3
+     \typog at repeat{\numexpr\typog at triplet@max at lines / 3 - 1}
+                  {\skip0 \skip1  \skip0 \skip2  \skip0 \skip3}}
+   \parshape=\typog at triplet@max at lines\typog@@triplet at linespecs\relax}
+  {\par}
+
+%    \end{macrocode}
+%  \end{environment}
+%
+%
+%  \begin{macro}{\typog at quintuplet@max at 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 at quintuplet@max at lines}{95}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{environment}{smoothraggedrightshapequintuplet}
+%    Engine for 5-line repetitions.
+%
+%    \begin{macrocode}
+\define at key[typog]{smoothraggedrightshapequintuplet}{leftskip}
+           {\def\typog@@quintuplet at leftskip{#1}}
+\define at key[typog]{smoothraggedrightshapequintuplet}{parindent}
+           {\def\typog@@quintuplet at parindent{#1}}
+\NewDocumentEnvironment{smoothraggedrightshapequintuplet}{O{} m m m m m}
+  {\def\typog@@quintuplet at leftskip{\z@}%
+   \def\typog@@quintuplet at parindent{\z@}%
+   \setkeys*[typog]{smoothraggedrightshapequintuplet}{#1}%
+   \skip0=\typog@@quintuplet at leftskip
+   \skip1=#2\relax
+   \skip2=#3\relax
+   \skip3=#4\relax
+   \skip4=#5\relax
+   \skip5=#6\relax
+   \typog at typeout{smoothraggedrightshapequintuplet: skip0=\the\skip0}%
+   \typog at typeout{smoothraggedrightshapequintuplet: skip1=\the\skip1}%
+   \typog at typeout{smoothraggedrightshapequintuplet: skip2=\the\skip2}%
+   \typog at typeout{smoothraggedrightshapequintuplet: skip3=\the\skip3}%
+   \typog at typeout{smoothraggedrightshapequintuplet: skip4=\the\skip4}%
+   \typog at typeout{smoothraggedrightshapequintuplet: skip5=\the\skip5}%
+   \unless\ifnum\typog at mod{\typog at quintuplet@max at lines}{5}=0
+     \PackageError{typog}
+                  {Line number of quintuplet generator %
+                    (\typog at quintuplet@max at lines) not divisible by 5}
+                  {}
+   \fi
+   \edef\typog@@quintuplet at linespecs{%
+     \glueexpr \skip0 + \typog@@quintuplet at parindent\relax
+            \glueexpr \skip1 - \typog@@quintuplet at parindent\relax
+                    \skip0 \skip2  \skip0 \skip3  \skip0 \skip4  \skip0 \skip5
+     \typog at repeat{\numexpr\typog at quintuplet@max at lines / 5 - 1}
+                  {\skip0 \skip1  \skip0 \skip2  \skip0 \skip3  \skip0 \skip4  \skip0 \skip5}}
+   \parshape=\typog at quintuplet@max at lines\typog@@quintuplet at linespecs\relax}
+  {\par}
+%    \end{macrocode}
+
+%  \end{environment}
+%
+%
+%  \begin{macro}{\typog at septuplet@max at 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 at septuplet@max at lines}{98}
+
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{environment}{smoothraggedrightshapeseptuplet}
+%    Engine for 7-line repetitions.
+%
+%    \begin{macrocode}
+\define at key[typog]{smoothraggedrightshapeseptuplet}{leftskip}%
+           {\def\typog@@septuplet at leftskip{#1}}
+\define at key[typog]{smoothraggedrightshapeseptuplet}{parindent}%
+           {\def\typog@@septuplet at parindent{#1}}
+\NewDocumentEnvironment{smoothraggedrightshapeseptuplet}{O{} m m m m m m m}
+  {\def\typog@@septuplet at leftskip{\z@}%
+   \def\typog@@septuplet at parindent{\z@}%
+   \setkeys*[typog]{smoothraggedrightshapeseptuplet}{#1}%
+   \skip0=\typog@@septuplet at leftskip
+   \skip1=#2\relax
+   \skip2=#3\relax
+   \skip3=#4\relax
+   \skip4=#5\relax
+   \skip5=#6\relax
+   \skip6=#7\relax
+   \skip7=#8\relax
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip0=\the\skip0}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip1=\the\skip1}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip2=\the\skip2}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip3=\the\skip3}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip4=\the\skip4}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip5=\the\skip5}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip6=\the\skip6}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip7=\the\skip7}%
+   \unless\ifnum\typog at mod{\typog at septuplet@max at lines}{7}=0
+     \PackageError{typog}
+                  {Line number of septuplet generator %
+                    (\typog at septuplet@max at lines) not divisible by 7}
+                  {}
+   \fi
+   \edef\typog@@septuplet at linespecs{%
+     \glueexpr \skip0 + \typog@@septuplet at parindent\relax
+            \glueexpr \skip1 - typog@@septuplet at parindent\relax
+                    \skip0 \skip2  \skip0 \skip3  \skip0 \skip4  \skip0 \skip5  \skip0 \skip6  \skip0 \skip7
+     \typog at repeat{\numexpr\typog at septuplet@max at lines / 7 - 1}
+                  {\skip0 \skip1  \skip0 \skip2  \skip0 \skip3  \skip0 \skip4  \skip0 \skip5  \skip0 \skip6  \skip0 \skip7}}
+   \parshape=\typog at septuplet@max at lines\typog@@septuplet at 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 at fuzzwidth}
+%    \begin{macrocode}
+\newdimen{\typog at 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 at 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 at strcmp{\smoothraggedrightgenerator}{triplet}=\z@
+       0%
+     \else
+       \ifnum\pdf at strcmp{\smoothraggedrightgenerator}{quintuplet}=\z@
+         1%
+       \else
+         \ifnum\pdf at 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 at 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 at fuzzwidth=.25\smoothraggedrightragwidth
+     \typog at typeout{smoothraggedright: generator=triplet, typog at fuzzwidth=\the\typog at fuzzwidth}%
+     \smoothraggedrightshapetriplet[leftskip=\typog@@smoothraggedrightleftskip,
+                                    parindent=\glueexpr\smoothraggedrightparindent + \parindent,
+                                    #1]%
+        {\glueexpr \typog@@linewidth - \smoothraggedrightragwidth
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth\relax}% (1)
+        {\glueexpr \typog@@linewidth \@minus \typog at fuzzwidth}% (3)
+        {\glueexpr (\typog@@linewidth * 2 - \smoothraggedrightragwidth) / 2
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (2)
+   \or
+%    \end{macrocode}
+%
+%    |generator=quintuplet|.
+%    \begin{macrocode}
+     \typog at fuzzwidth=.125\smoothraggedrightragwidth
+     \typog at typeout{smoothraggedright: generator=quintuplet, typog at fuzzwidth=\the\typog at fuzzwidth}%
+     \smoothraggedrightshapequintuplet[leftskip=\typog@@smoothraggedrightleftskip,
+                                       parindent=\glueexpr\smoothraggedrightparindent + \parindent,
+                                       #1]%
+        {\glueexpr (\typog@@linewidth * 4 - \smoothraggedrightragwidth * 3) / 4
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (2)
+        {\glueexpr \typog@@linewidth \@minus \typog at fuzzwidth\relax}% (5)
+        {\glueexpr (\typog@@linewidth * 2 - \smoothraggedrightragwidth) / 2
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (3)
+        {\glueexpr (\typog@@linewidth * 4 - \smoothraggedrightragwidth) / 4
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (4)
+        {\glueexpr \typog@@linewidth - \smoothraggedrightragwidth
+                   + \glueexpr \z@ \@plus \typog at 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 at fuzzwidth=.08333\smoothraggedrightragwidth
+     \typog at typeout{smoothraggedright: generator=septuplet, typog at fuzzwidth=\the\typog at fuzzwidth}%
+     \smoothraggedrightshapeseptuplet[leftskip=\typog@@smoothraggedrightleftskip,
+                                      parindent=\glueexpr\smoothraggedrightparindent + \parindent,
+                                      #1]%
+        {\glueexpr (\typog@@linewidth * 3 - \smoothraggedrightragwidth * 2) / 3
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (3)
+        {\glueexpr (\typog@@linewidth * 6 - \smoothraggedrightragwidth) / 6
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (6)
+        {\glueexpr \typog@@linewidth - \smoothraggedrightragwidth +
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth\relax}% (1)
+        {\glueexpr (\typog@@linewidth * 3 - \smoothraggedrightragwidth) / 3
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (5)
+        {\glueexpr (\typog@@linewidth * 6 - \smoothraggedrightragwidth * 5) / 6
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (2)
+        {\glueexpr \typog@@linewidth \@minus \typog at fuzzwidth\relax}% (7)
+        {\glueexpr (\typog@@linewidth * 2 - \smoothraggedrightragwidth) / 2
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at 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 at myruled}{%
+  \fs at ruled
+  \def\@fs at capt##1##2{\floatc at ruled{##1\space\capitaldash*\space}{\fussy ##2}}%
+  \def\@fs at pre{\hrule height.8pt depth0pt \kern4pt}%
+  \def\@fs at mid{\kern3pt\hrule\kern3pt}%
+  \def\@fs at 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
+
+ at display
+ at relax
+
+=end texinfo
+
+    <typog-inspect id="ID" job="JOB-NAME" line="LINE-NUMBER" page="PAGE-NUMBER">
+      Trace Data
+    </typog-inspect>
+
+=begin texinfo
+
+ at end display
+ at 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:


Property changes on: trunk/Master/texmf-dist/source/latex/typog/typog.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/typog/typog.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/typog/typog.ins	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/typog/typog.ins	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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:

Added: trunk/Master/texmf-dist/tex/latex/typog/typog.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/typog/typog.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/typog/typog.sty	2024-05-07 20:11:51 UTC (rev 71202)
@@ -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 at TYPOG}{}
+\newcommand*{\typoglogo}{\textsf{T\itcorr*{-5}\textsl{y}poG}}
+\newif\iftypog at debug
+\newcommand*{\typog at typeout}[1]
+  {\iftypog at debug
+     \typeout{typog: #1}%
+   \fi}
+
+\ExplSyntaxOn
+\let\typog at trim@spaces=\tl_trim_spaces:o
+\ExplSyntaxOff
+
+\newcommand{\typog at register@pdfsubstitute}[1]{%
+  \AtBeginDocument{%
+    \ifdefined\pdfstringdefDisableCommands
+      \pdfstringdefDisableCommands{#1}%
+    \fi}}
+
+\newif\iftypog at microtype@preloaded
+
+\ifdefined\MT at MT
+  \typog at typeout{package microtype preloaded}%
+  \typog at microtype@preloadedtrue
+  \def\typog at require@preloaded at microtype{\relax}
+\else
+  \typog at microtype@preloadedfalse
+  \def\typog at require@preloaded at microtype
+    {\PackageError{typog}%
+                  {package microtype not (pre-)loaded}%
+                  {package microtype must be loaded before package typog}}
+\fi
+
+\newif\iftypog at microtype@loaded
+
+\AtBeginDocument{
+  \ifdefined\MT at MT
+    \typog at typeout{package microtype loaded}%
+    \typog at microtype@loadedtrue
+    \def\typog at require@microtype{\relax}
+  \else
+    \typog at microtype@loadedfalse
+    \def\typog at require@microtype
+      {\PackageError{typog}%
+                    {package microtype not loaded}%
+                    {require package microtype before package typog}}%
+  \fi
+}
+
+\newmuskip\typog at mathitalicscorrection
+\newlength{\typog at textitalicscorrection}
+\newlength{\typog at ligaturekern}
+\newlength{\typog at raisecapitaldash}
+\newlength{\typog at raisecapitalguillemets}
+\newlength{\typog at raisecapitalhyphen}
+\newlength{\typog at raisecapitaltimes}
+\newlength{\typog at raiseguillemets}
+\newlength{\typog at raisefiguredash}
+\newlength{\typog at slashkern}
+\newcommand*{\typog at breakpenalty}{\exhyphenpenalty}
+\newlength{\typog at dim@unit}
+\setlength{\typog at dim@unit}{.001em}
+\newcommand*{\typog at trackingttspacing}{300, 90, 60}
+\newcommand*{\typog at default@shrink at i}{5}
+\newcommand*{\typog at default@shrink at ii}{10}
+\newcommand*{\typog at default@shrink at iii}{20}
+\newcommand*{\typog at shrink@i}{}
+\newcommand*{\typog at shrink@ii}{}
+\newcommand*{\typog at shrink@iii}{}
+\newcommand*{\typog at default@stretch at i}{5}
+\newcommand*{\typog at default@stretch at ii}{10}
+\newcommand*{\typog at default@stretch at iii}{20}
+\newcommand*{\typog at stretch@i}{}
+\newcommand*{\typog at stretch@ii}{}
+\newcommand*{\typog at stretch@iii}{}
+
+\def\typog at one@of at three#1,#2,#3\relax{\typog at trim@spaces{#1}}
+\def\typog at two@of at three#1,#2,#3\relax{\typog at trim@spaces{#2}}
+\def\typog at three@of at three#1,#2,#3\relax{\typog at trim@spaces{#3}}
+
+\newcommand*{\typog at triple@get at i}[1]{\expandafter\typog at one@of at three #1\relax}
+\newcommand*{\typog at triple@get at ii}[1]{\expandafter\typog at two@of at three #1\relax}
+\newcommand*{\typog at triple@get at iii}[1]{\expandafter\typog at three@of at three #1\relax}
+
+\newcommand*{\typog at set@shrink at limits}
+  {\edef\typog@@star{*}%
+   \edef\typog@@limit{\typog at triple@get at i{\typog at shrinklimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at shrink@i{\number\typog@@limit}\fi
+   \edef\typog@@limit{\typog at triple@get at ii{\typog at shrinklimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at shrink@ii{\number\typog@@limit}\fi
+   \edef\typog@@limit{\typog at triple@get at iii{\typog at shrinklimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at shrink@iii{\number\typog@@limit}\fi}
+
+\newcommand*{\typog at set@stretch at limits}
+  {\edef\typog@@star{*}%
+   \edef\typog@@limit{\typog at triple@get at i{\typog at stretchlimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at stretch@i{\number\typog@@limit}\fi
+   \edef\typog@@limit{\typog at triple@get at ii{\typog at stretchlimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at stretch@ii{\number\typog@@limit}\fi
+   \edef\typog@@limit{\typog at triple@get at iii{\typog at stretchlimits}}%
+   \unless\ifx\typog@@limit\typog@@star\edef\typog at stretch@iii{\number\typog@@limit}\fi}
+
+\DeclareOptionX<typog>{breakpenalty}%
+  {\renewcommand*{\typog at breakpenalty}{#1}}
+\DeclareOptionX<typog>{debug}{\typog at debugtrue}
+\DeclareOptionX<typog>{mathitalicscorrection}[.4mu]%
+  {\typog at mathitalicscorrection=#1\relax}%
+\DeclareOptionX<typog>{nodebug}{\typog at debugfalse}
+\DeclareOptionX<typog>{textitalicscorrection}[.02em]%
+  {\setlength{\typog at textitalicscorrection}{#1}}
+\DeclareOptionX<typog>{ligaturekern}[.033333em]%
+  {\setlength{\typog at ligaturekern}{#1}}
+\DeclareOptionX<typog>{raisecapitaldash}[\z@]%
+  {\setlength{\typog at raisecapitaldash}{#1}}
+\DeclareOptionX<typog>{raisecapitalguillemets}[\z@]%
+  {\setlength{\typog at raisecapitalguillemets}{#1}}
+\DeclareOptionX<typog>{raisecapitalhyphen}[\z@]%
+  {\setlength{\typog at raisecapitalhyphen}{#1}}
+\DeclareOptionX<typog>{raisecapitaltimes}[\z@]%
+  {\setlength{\typog at raisecapitaltimes}{#1}}
+\DeclareOptionX<typog>{raiseguillemets}[\z@]%
+  {\setlength{\typog at raiseguillemets}{#1}}
+\DeclareOptionX<typog>{raisefiguredash}[\z@]%
+  {\setlength{\typog at raisefiguredash}{#1}}
+\DeclareOptionX<typog>{raise*}[\z@]%
+  {\setlength{\typog at raisecapitaldash}{#1}%
+   \setlength{\typog at raisecapitalhyphen}{#1}%
+   \setlength{\typog at raisecapitaltimes}{#1}%
+   \setlength{\typog at raisefiguredash}{#1}}
+\DeclareOptionX<typog>{shrinklimits}%
+  [\typog at default@shrink at i, \typog at default@shrink at ii, \typog at default@shrink at iii]%
+  {\typog at require@preloaded at microtype
+   \ifx\@onlypreamble\@notprerr
+     \PackageWarning{typog}{option `shrinklimits' can only be used in the preamble}%
+   \else
+     \edef\typog at shrinklimits{#1}%
+     \typog at set@shrink at limits
+   \fi}
+\DeclareOptionX<typog>{slashkern}[.05em]%
+  {\setlength{\typog at slashkern}{#1}}
+\DeclareOptionX<typog>{stretchlimits}%
+  [\typog at default@stretch at i, \typog at default@stretch at ii, \typog at default@stretch at iii]%
+  {\typog at require@preloaded at microtype
+   \ifx\@onlypreamble\@notprerr
+     \PackageWarning{typog}{option `stretchlimits' can only be used in the preamble}%
+   \else
+     \edef\typog at stretchlimits{#1}%
+     \typog at set@stretch at limits
+   \fi}
+\DeclareOptionX<typog>{trackingttspacing}[\typog at trackingttspacing]%
+  {\typog at require@preloaded at microtype
+   \ifx\@onlypreamble\@notprerr
+     \PackageWarning{typog}{option `trackingttspacing' can only be used in the preamble}%
+   \else
+     \typog at typeout{trackingttspacing=#1}%
+     \SetTracking[outer spacing={#1}]{encoding=*, family=tt*}{0}%
+   \fi}
+
+\newcommand*{\typog at initialize@options}
+  {\ExecuteOptionsX<typog>{
+     ligaturekern,
+     mathitalicscorrection, textitalicscorrection,
+     raisecapitaldash, raisecapitalhyphen, raisecapitaltimes,
+     raiseguillemets, raisecapitalguillemets,
+     raisefiguredash,
+     slashkern}
+   \ifdefined\MT at MT
+     \unless\ifx\@onlypreamble\@notprerr
+       \ExecuteOptionsX<typog>{shrinklimits, stretchlimits}
+     \fi
+   \fi}
+
+\typog at initialize@options
+\ProcessOptionsX<typog>
+
+\NewDocumentEnvironment{typogsetup}{m}
+  {\def\typog@@arg{#1}%
+   \ifx\typog@@arg\empty
+     \typog at initialize@options
+   \else
+     \setkeys{typog}{#1}%
+   \fi
+   \ignorespaces}
+  {\ignorespacesafterend}
+\NewDocumentCommand{\typogget}{m}{\csname typog@#1\endcsname}
+
+\ExplSyntaxOn
+\newcommand*{\typog at round@dim at to@tenths}[1]
+  {\fp_to_decimal:n {round(10 * \dim_to_fp:n{#1} / 1\p@) / 10}}
+\ExplSyntaxOff
+
+\newcommand*{\typog at formatsizeinfo}[3]
+  {#1#3\kernedslash #2#3}
+
+\NewDocumentCommand{\fontsizeinfo}{s m}
+  {\global\expandafter\edef\csname typog at fontsize@#2\endcsname
+     {\typog at round@dim at to@tenths{\fontdimen6\font}}%
+   \global\expandafter\edef\csname typog at linespacing@#2\endcsname
+     {\typog at round@dim at to@tenths{\baselineskip}}%
+   \protected\expandafter\gdef\csname #2\endcsname
+     {\@ifnextchar*{\typog at formatsizeinfo
+                      {\csname typog at fontsize@#2\endcsname}%
+                      {\csname typog at linespacing@#2\endcsname}%
+                      {}% no unit
+                      \ignorespaces % eat spaces after star
+                      \@gobble}     % consume the star itself
+                   {\typog at formatsizeinfo
+                      {\csname typog at fontsize@#2\endcsname}%
+                      {\csname typog at linespacing@#2\endcsname}%
+                      {\,pt}% decorative unit `pt'
+  }}}
+
+\newcommand*{\typog at default@inspect at id@prefix}{a-}
+\newcounter{typog at inspect@count}
+\define at key[typog]{typoginspect}{tracingboxes}[\maxdimen]%
+           {\def\typog@@typoginspect at tracingboxes{#1}}
+\NewDocumentEnvironment{typoginspect}{O{} m}
+  {\def\typog@@typoginspect at tracingboxes{\m at ne}%
+   \setkeys[typog]{typoginspect}{#1}%
+   \edef\typog@@arg{#2}%
+   \ifx\typog@@arg\empty
+     \stepcounter{typog at inspect@count}%
+     \edef\typog@@id{\typog at default@inspect at id@prefix\arabic{typog at inspect@count}}%
+   \else
+     \edef\typog@@id{\typog at trim@spaces{\typog@@arg}}%
+   \fi
+   \typeout{<typog-inspect id="\typog@@id" job="\jobname" line="\the\inputlineno" page="\the\value{page}">}%
+   \hbadness=\m at ne
+   \vbadness=\m at ne
+   \tracingnone
+   \tracingpages=\@ne
+   \tracingparagraphs=\@ne
+   \showboxbreadth=\typog@@typoginspect at tracingboxes
+   \showboxdepth=\typog@@typoginspect at tracingboxes}
+  {\typeout{</typog-inspect>}%
+   \ignorespacesafterend}
+\NewDocumentEnvironment{typoginspectpar}{m}
+  {\typoginspect{#1}}
+  {\par\endtypoginspect}
+
+\newcommand*{\typog at allowhyphenation}
+  {\ifvmode
+     \relax
+   \else
+     \nobreak
+     \hskip\z at skip
+   \fi}
+
+\unless\ifdefined\allowhyphenation
+  \let\allowhyphenation=\typog at allowhyphenation
+\fi
+
+\NewDocumentCommand{\breakpoint}{s}
+  {\discretionary{}{}{}%
+   \IfBooleanTF{#1}%
+     {\ignorespaces}%
+     {\typog at allowhyphenation}}
+
+\typog at register@pdfsubstitute{
+  \def\breakpoint#1{\if*\detokenize{#1}\ignorespaces\fi}%
+}
+
+\NewDocumentEnvironment{hyphenmin}{o m}
+  {\lefthyphenmin=\IfNoValueTF{#1}{#2}{#1}%
+   \righthyphenmin=#2}
+  {}
+
+\newcommand*{\typog at hyphen}{\char`-}
+
+\NewDocumentCommand{\nolig}{s o}
+  {\dimen0=\IfNoValueTF{#2}{\typog at ligaturekern}{#2\typog at dim@unit}%
+   \IfBooleanTF{#1}%
+     {\kern\dimen0\ignorespaces}%
+     {\discretionary{\typog at hyphen}{}{\kern\dimen0}%
+      \typog at allowhyphenation
+      \IfNoValueF{#2}{\ignorespaces}}}
+
+\typog at register@pdfsubstitute{
+  \RenewExpandableDocumentCommand{\nolig}{s o m}{%
+    \ifx\typog at TYPOG#3\typog at 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 at itcorr@text at unconditional}[1]
+  {\kern#1\typog at textitalicscorrection}
+\newcommand*{\typog at itcorr@text}[1]
+  {\def\typog@@strength{#1}%
+   \dimen0=\fontdimen1\font
+   \ifdim\dimen0=\z@
+     \typog at itcorr@text at unconditional{\typog@@strength}%
+   \else
+     \kern\typog@@strength\dimen0
+   \fi}
+\newcommand*{\typog at itcorr@math}[1]
+  {\mkern#1\typog at mathitalicscorrection}
+\NewDocumentCommand{\itcorr}{s m}
+  {\ifmmode
+     \typog at itcorr@math{#2}%
+   \else
+     \IfBooleanTF{#1}%
+       {\typog at itcorr@text{#2}}%
+       {\typog at itcorr@text at unconditional{#2}}%
+   \fi}
+\typog at register@pdfsubstitute{
+  \RenewExpandableDocumentCommand{\itcorr}{s m}{}
+}
+
+\newcommand*{\typog at forwardslash}{\char`/}
+\NewDocumentCommand{\kernedslash}{s}
+  {\hspace*{\typog at slashkern}%
+   \typog at forwardslash
+   \IfBooleanTF{#1}%
+     {\hspace*{\typog at slashkern}\ignorespaces}%
+     {\typog at breakpoint\typog at allowhyphenation\hspace*{\typog at slashkern}}}
+\typog at 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 at dim@unit}{$\m at th\mathord{-}$}%
+     \mspace{\muexpr(#4 mu) * 18 / 1000}%
+   \else
+     \def\typog@@auto{*}%
+     \def\typog@@optarg{#2}%
+     \hspace*{#3\typog at dim@unit}%
+     \raisebox{\ifx\typog@@optarg\typog@@auto
+                 \typog at raisecapitalhyphen
+               \else
+                 \typog@@optarg\typog at dim@unit
+               \fi}{\typog at hyphen}%
+     \hspace{#4\typog at dim@unit}%
+     \IfBooleanT{#1}{\nobreak}%
+   \fi}
+\typog at 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 at 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 at register@pdfsubstitute{
+  \RenewExpandableDocumentCommand{\rightkernedhyphen}{s o m}{-}
+}
+
+\newcommand*{\typog at breakpoint}
+  {\penalty\typog at breakpenalty}
+\NewDocumentCommand{\capitalhyphen}{s}
+  {\raisebox{\typog at raisecapitalhyphen}{\typog at hyphen}%
+   \IfBooleanTF{#1}%
+     {\ignorespaces}%
+     {\typog at breakpoint\typog at allowhyphenation}}
+\typog at register@pdfsubstitute{
+  \def\capitalhyphen#1{%
+    \if*\detokenize{#1}%
+      -\ignorespaces
+    \else
+      -#1%
+    \fi}
+}
+
+\NewDocumentCommand{\capitalendash}{s}
+  {\raisebox{\typog at raisecapitaldash}{\textendash}%
+   \IfBooleanTF{#1}%
+     {\ignorespaces}%
+     {\typog at breakpoint\typog at allowhyphenation}}
+\let\capitaldash=\capitalendash
+\typog at register@pdfsubstitute{
+  \def\capitalendash#1{%
+    \if*\detokenize{#1}%
+      \textendash\ignorespaces
+    \else
+      \textendash#1%
+    \fi}
+  \let\capitaldash=\capitalendash
+}
+
+\NewDocumentCommand{\capitalemdash}{s}
+  {\raisebox{\typog at raisecapitaldash}{\textemdash}%
+   \IfBooleanTF{#1}%
+     {\ignorespaces}%
+     {\typog at breakpoint\typog at allowhyphenation}}
+\typog at register@pdfsubstitute{
+  \def\capitalemdash#1{%
+    \if*\detokenize{#1}%
+      \textemdash\ignorespaces
+    \else
+      \textemdash#1%
+    \fi}
+}
+
+\NewDocumentCommand{\figuredash}{s}
+  {\raisebox{\typog at raisefiguredash}{\textendash}%
+   \IfBooleanTF{#1}%
+     {\ignorespaces}%
+     {\typog at breakpoint\typog at allowhyphenation}}
+\typog at register@pdfsubstitute{\let\figuredash=\capitaldash}
+
+\NewDocumentCommand{\capitaltimes}{}
+  {\ifmmode
+     \mathbin{\raisebox{\typog at raisecapitaltimes}{$\m at th\times$}}%
+   \else
+     \raisebox{\typog at raisecapitaltimes}{\texttimes}%
+   \fi}
+\typog at register@pdfsubstitute{
+  \RenewExpandableDocumentCommand{\capitaltimes}{}{\texttimes}
+}
+
+\NewDocumentCommand{\singleguillemetleft}{}
+  {\typog at allowhyphenation
+   \raisebox{\typog at raiseguillemets}{\guilsinglleft}}
+\typog at register@pdfsubstitute{\let\singleguillemetleft\guilsinglleft}
+\NewDocumentCommand{\singleguillemetright}{}
+  {\raisebox{\typog at raiseguillemets}{\guilsinglright}%
+   \typog at allowhyphenation}
+\typog at register@pdfsubstitute{\let\singleguillemetright\guilsinglright}
+\NewDocumentCommand{\doubleguillemetleft}{}
+  {\typog at allowhyphenation
+   \raisebox{\typog at raiseguillemets}{\guillemotleft}}
+\typog at register@pdfsubstitute{\let\doubleguillemetleft\guillemotleft}
+\NewDocumentCommand{\doubleguillemetright}{}
+  {\raisebox{\typog at raiseguillemets}{\guillemotright}%
+   \typog at allowhyphenation}
+\typog at register@pdfsubstitute{\let\doubleguillemetright\guillemotright}
+\NewDocumentCommand{\Singleguillemetleft}{}
+  {\typog at allowhyphenation
+   \raisebox{\typog at raisecapitalguillemets}{\guilsinglleft}}
+\typog at register@pdfsubstitute{\let\Singleguillemetleft\guilsinglleft}
+\NewDocumentCommand{\Singleguillemetright}{}
+  {\raisebox{\typog at raisecapitalguillemets}{\guilsinglright}%
+   \typog at allowhyphenation}
+\typog at register@pdfsubstitute{\let\Singleguillemetright\guilsinglright}
+\NewDocumentCommand{\Doubleguillemetleft}{}
+  {\typog at allowhyphenation
+   \raisebox{\typog at raisecapitalguillemets}{\guillemotleft}}
+\typog at register@pdfsubstitute{\let\Doubleguillemetleft\guillemotleft}
+\NewDocumentCommand{\Doubleguillemetright}{}
+  {\raisebox{\typog at raisecapitalguillemets}{\guillemotright}%
+   \typog at allowhyphenation}
+\typog at 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 at covernextindentpar@zero at parindent}{2em}
+\newcommand*{\typog at covernextindentpar@nonzero at parindent}{2\parindent}
+\NewDocumentEnvironment{covernextindentpar}{o}
+  {\IfNoValueTF{#1}
+     {\ifdim\parindent=\z@
+        \dimen0=\dimexpr\linewidth - \typog at covernextindentpar@zero at parindent
+      \else
+        \dimen0=\dimexpr\linewidth - \typog at covernextindentpar@nonzero at parindent
+      \fi}
+     {\dimen0=\dimexpr\linewidth - (#1)}%
+   \parfillskip=\dimen0 \@minus \dimen0
+   \relax}
+  {\par}
+
+\newcommand*{\typog at openlastlinepar@zero at parindent}{2em}
+\newcommand*{\typog at openlastlinepar@nonzero at parindent}{2\parindent}
+\NewDocumentEnvironment{openlastlinepar}{o}
+  {\IfNoValueTF{#1}
+     {\ifdim\parindent=\z@
+        \skip0=\typog at openlastlinepar@zero at parindent
+               \@plus 1fil
+               \@minus \typog at openlastlinepar@zero at parindent
+      \else
+        \skip0=\typog at openlastlinepar@nonzero at parindent
+               \@plus 1fil
+               \@minus \typog at openlastlinepar@nonzero at 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 at letterspace@{#1}%
+   \lsstyle
+   \ignorespaces}
+  {\ignorespacesafterend}
+
+\newcommand*{\typog at setup@font at expansion}
+  {\SetExpansion
+     [context = typog at shrink1,
+      shrink = \typog at shrink@i,
+      stretch = 0]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at shrink2,
+      shrink = \typog at shrink@ii,
+      stretch = 0]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at shrink3,
+      shrink = \typog at shrink@iii,
+      stretch = 0]%
+     {encoding = {*}}%
+     {}
+
+   \SetExpansion
+     [context = typog at stretch1,
+      shrink = 0,
+      stretch = \typog at stretch@i]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at stretch2,
+      shrink = 0,
+      stretch = \typog at stretch@ii]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at stretch3,
+      shrink = 0,
+      stretch = \typog at stretch@iii]%
+     {encoding = {*}}%
+     {}
+
+   \SetExpansion
+     [context = typog at expand1,
+      shrink = \typog at shrink@i,
+      stretch = \typog at stretch@i]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at expand2,
+      shrink = \typog at shrink@ii,
+      stretch = \typog at stretch@ii]%
+     {encoding = {*}}%
+     {}
+   \SetExpansion
+     [context = typog at expand3,
+      shrink = \typog at shrink@iii,
+      stretch = \typog at stretch@iii]%
+     {encoding = {*}}%
+     {}}
+\newcommand*{\typog at test@microtype at expansion@feature}
+  {\ifMT at expansion
+     \typog at typeout{microtype preloaded -- font expansion features available}%
+     \def\typog at require@microtype at expansion{\relax}
+     \typog at setup@font at expansion
+   \else
+     \PackageWarning{typog}{microtype preloaded,\space
+                            but font expansion is disabled}%
+     \def\typog at require@microtype at expansion
+       {\PackageError{typog}
+                     {microtype font expansion disabled}
+                     {pass option `expansion' to package microtype}}
+   \fi}
+\iftypog at microtype@preloaded
+  \typog at test@microtype at expansion@feature
+\else
+  \def\typog at require@microtype at 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 at require@microtype at expansion
+   \ifcase#1% 0
+     \relax
+   \or % 1
+     \microtypecontext{expansion=typog at shrink1}%
+   \or % 2
+     \microtypecontext{expansion=typog at shrink2}%
+   \else % >= 3
+     \microtypecontext{expansion=typog at shrink3}%
+   \fi
+   \ignorespaces}
+  {\ignorespacesafterend}
+
+\NewDocumentEnvironment{setfontstretch}{O{1}}
+  {\typog at require@microtype at expansion
+   \ifcase#1% 0
+     \relax
+   \or % 1
+     \microtypecontext{expansion=typog at stretch1}%
+   \or % 2
+     \microtypecontext{expansion=typog at stretch2}%
+   \else % >= 3
+     \microtypecontext{expansion=typog at stretch3}%
+   \fi
+   \ignorespaces}
+  {\ignorespacesafterend}
+
+\NewDocumentEnvironment{setfontexpand}{O{1}}
+  {\typog at require@microtype at expansion
+   \ifcase#1% 0
+     \relax
+   \or % 1
+     \microtypecontext{expansion=typog at expand1}%
+   \or % 2
+     \microtypecontext{expansion=typog at expand2}%
+   \else % >= 3
+     \microtypecontext{expansion=typog at 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 at 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 at scaled@emergencystretch{.375em}%
+     \hfuzz=.15\p@
+     \vfuzz=\hfuzz
+   \or % 2
+     \pretolerance=265%
+     \tolerance=530%
+     \typog at scaled@emergencystretch{.75em}%
+     \hfuzz=.15\p@
+     \vfuzz=\hfuzz
+   \or % 3
+     \pretolerance=435%
+     \tolerance=870%
+     \typog at scaled@emergencystretch{1.125em}%
+     \hfuzz=.2\p@
+     \vfuzz=\hfuzz
+   \or % 4
+     \pretolerance=705%
+     \tolerance=1410%
+     \typog at scaled@emergencystretch{1.5em}%
+     \hfuzz=.3\p@
+     \vfuzz=\hfuzz
+   \or % 5
+     \pretolerance=1155%
+     \tolerance=2310%
+     \typog at scaled@emergencystretch{1.875em}%
+     \hfuzz=.35\p@
+     \vfuzz=\hfuzz
+   \or % 6
+     \pretolerance=1880%
+     \tolerance=3760%
+     \typog at scaled@emergencystretch{2.25em}%
+     \hfuzz=.4\p@
+     \vfuzz=\hfuzz
+   \or % 7
+     \pretolerance=3065%
+     \tolerance=6130%
+     \typog at 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 at geometric@mean}[2]
+            {\fp_to_int:n {sqrt((#1) * (#2))}}
+\ExplSyntaxOff
+
+\newcounter{typog at mean@penalty}
+
+\NewDocumentCommand{\vtietop}{O{3}}
+  {\setcounter{typog at mean@penalty}
+              {\typog at geometric@mean{\@M}{\clubpenalty}}%
+   \typog at typeout{vtietop: penalties \the\@M--\the\value{typog at 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 at mean@penalty}
+         \clubpenalty
+   \or % 3
+     \clubpenalties 4
+         \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \or % 4
+     \clubpenalties 5
+         \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \or % 5
+     \clubpenalties 6
+         \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \or % 6
+     \clubpenalties 7
+         \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \or % 7
+     \clubpenalties 8
+         \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \or % 8
+     \clubpenalties 9
+         \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \else % >= 9
+     \clubpenalties 10
+         \@M \@M \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \clubpenalty
+   \fi}
+
+\NewDocumentEnvironment{vtietoppar}{O{3}}
+  {\vtietop[#1]}
+  {\par
+   \ignorespacesafterend}
+
+\NewDocumentCommand{\splicevtietop}{O{3}}
+  {\let\typog at old@item=\@item
+   \def\@item[##1]{\typog at old@item[##1]\vtietop[#1]}%
+   \ignorespaces}
+
+\ifdefined\SetEnumitemKey
+  \SetEnumitemKey{vtietop}{first=\splicevtietop}
+\fi
+
+\NewDocumentCommand{\vtiebot}{O{3}}
+  {\setcounter{typog at mean@penalty}
+              {\typog at geometric@mean{\@M}{\widowpenalty}}%
+   \typog at typeout{vtiebot: penalties \the\@M--\the\value{typog at 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 at mean@penalty}
+         \widowpenalty
+   \or % 3
+     \widowpenalties 4
+         \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \or % 4
+     \widowpenalties 5
+         \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \or % 5
+     \widowpenalties 6
+         \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \or % 6
+     \widowpenalties 7
+         \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \or % 7
+     \widowpenalties 8
+         \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \or % 8
+     \widowpenalties 9
+         \@M \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \else % >= 9
+     \widowpenalties 10
+         \@M \@M \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \widowpenalty
+   \fi}
+
+\NewDocumentEnvironment{vtiebotpar}{O{3}}
+  {\vtiebot[#1]}
+  {\par
+   \ignorespacesafterend}
+
+\NewDocumentCommand{\typog at vtiebotdisp}{m}
+  {\setcounter{typog at mean@penalty}
+              {\typog at geometric@mean{\@M}{\displaywidowpenalty}}%
+   \typog at typeout{vtiebotdisp: penalties \the\@M--\the\value{typog at 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 at mean@penalty}
+         \displaywidowpenalty
+   \or % 3
+     \displaywidowpenalties 4
+         \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \or % 4
+     \displaywidowpenalties 5
+         \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \or % 5
+     \displaywidowpenalties 6
+         \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \or % 6
+     \displaywidowpenalties 7
+         \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \or % 7
+     \displaywidowpenalties 8
+         \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \or % 8
+     \displaywidowpenalties 9
+         \@M \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \else % >= 9
+     \displaywidowpenalties 10
+         \@M \@M \@M \@M \@M \@M \@M \@M
+         \value{typog at mean@penalty}
+         \displaywidowpenalty
+   \fi}
+
+\NewDocumentEnvironment{vtiebotdisp}{O{3}}
+  {\typog at vtiebotdisp{#1}}
+  {\ignorespacesafterend}
+
+\NewDocumentEnvironment{vtiebotdisptoppar}{O{3}o}
+  {\postdisplaypenalty=\@M
+   \predisplaypenalty=10001% in accordance with package `widows-and-orphans'
+   \edef\typog@@top at lines{\IfNoValueTF{#2}{#1}{#2}}%
+   \edef\typog@@after at display@math{\vtietop[\typog@@top at lines]}%
+   \PushPostHook{display}{\aftergroup\typog@@after at display@math}%
+   \vtiebotdisp[#1]}
+  {\par
+   \PopPostHook{display}%
+   \ignorespacesafterend}
+
+\newenvironment*{breakabledisplay}[1][3]
+  {\allowdisplaybreaks[#1]}
+  {\ignorespacesafterend}
+
+\newcommand*{\typog at setbaselineskip@iter at limit}{10}
+\newcommand*{\typog at setbaselineskip@relative at error}{.001}
+\ExplSyntaxOn
+\cs_new:Npn \typog at setbaselineskip #1
+{
+  \int_set:Nn \l_tmpa_int {1}
+  \int_set:Nn \l_tmpb_int {\typog at setbaselineskip@iter at limit}
+  \dim_set:Nn \l_tmpa_dim {\glueexpr #1}
+
+  \typog at typeout{\string\setbaselineskip:\space
+    initial\space baselineskip:\space \the\baselineskip}
+  \typog at 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 at setbaselineskip@relative at 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 at typeout{\string\setbaselineskip:\space
+    final\space \string\setstretch\space argument:\space
+    \fp_use:N \l_tmpa_fp}
+  \typog at typeout{\string\setbaselineskip:\space
+    final\space baselineskip:\space \the\baselineskip}
+}
+
+\cs_new:Npn \setbaselineskip #1
+{
+  \AfterPreamble{\typog at setbaselineskip{#1}}
+  \ignorespaces
+}
+
+\cs_new:Npn \resetbaselineskip
+{
+  \AfterPreamble{\setstretch{1}}
+}
+
+\dim_new:N \typogfontsize
+\AfterEndPreamble{
+  \dim_set:Nn \typogfontsize {\fontdimen6\font}
+  \typog at 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 at 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 at 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 at 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 at repeat \prg_replicate:nn
+
+\newcommand*{\typog at mod}[2]{\int_mod:nn{#1}{#2}}
+\ExplSyntaxOff
+
+\newcommand*{\typog at triplet@max at lines}{99}
+
+\define at key[typog]{smoothraggedrightshapetriplet}{leftskip}%
+           {\def\typog@@triplet at leftskip{#1}}
+\define at key[typog]{smoothraggedrightshapetriplet}{parindent}%
+           {\def\typog@@triplet at parindent{#1}}
+\NewDocumentEnvironment{smoothraggedrightshapetriplet}{O{} m m m}
+  {\def\typog@@triplet at leftskip{\z@}%
+   \def\typog@@triplet at parindent{\z@}%
+   \setkeys*[typog]{smoothraggedrightshapetriplet}{#1}%
+   \skip0=\typog@@triplet at leftskip\relax
+   \skip1=#2\relax
+   \skip2=#3\relax
+   \skip3=#4\relax
+   \typog at typeout{smoothraggedrightshapetriplet: skip0=\the\skip0}%
+   \typog at typeout{smoothraggedrightshapetriplet: skip1=\the\skip1}%
+   \typog at typeout{smoothraggedrightshapetriplet: skip2=\the\skip2}%
+   \typog at typeout{smoothraggedrightshapetriplet: skip3=\the\skip3}%
+   \unless\ifnum\typog at mod{\typog at triplet@max at lines}{3}=0
+     \PackageError{typog}
+                  {Line number of triplet generator %
+                    (\typog at triplet@max at lines) not divisible by 3}
+                  {}
+   \fi
+   \edef\typog@@triplet at linespecs{%
+     \glueexpr \skip0 + \typog@@triplet at parindent\relax
+            \glueexpr \skip1 - \typog@@triplet at parindent\relax
+                    \skip0 \skip2  \skip0 \skip3
+     \typog at repeat{\numexpr\typog at triplet@max at lines / 3 - 1}
+                  {\skip0 \skip1  \skip0 \skip2  \skip0 \skip3}}
+   \parshape=\typog at triplet@max at lines\typog@@triplet at linespecs\relax}
+  {\par}
+
+\newcommand*{\typog at quintuplet@max at lines}{95}
+
+\define at key[typog]{smoothraggedrightshapequintuplet}{leftskip}
+           {\def\typog@@quintuplet at leftskip{#1}}
+\define at key[typog]{smoothraggedrightshapequintuplet}{parindent}
+           {\def\typog@@quintuplet at parindent{#1}}
+\NewDocumentEnvironment{smoothraggedrightshapequintuplet}{O{} m m m m m}
+  {\def\typog@@quintuplet at leftskip{\z@}%
+   \def\typog@@quintuplet at parindent{\z@}%
+   \setkeys*[typog]{smoothraggedrightshapequintuplet}{#1}%
+   \skip0=\typog@@quintuplet at leftskip
+   \skip1=#2\relax
+   \skip2=#3\relax
+   \skip3=#4\relax
+   \skip4=#5\relax
+   \skip5=#6\relax
+   \typog at typeout{smoothraggedrightshapequintuplet: skip0=\the\skip0}%
+   \typog at typeout{smoothraggedrightshapequintuplet: skip1=\the\skip1}%
+   \typog at typeout{smoothraggedrightshapequintuplet: skip2=\the\skip2}%
+   \typog at typeout{smoothraggedrightshapequintuplet: skip3=\the\skip3}%
+   \typog at typeout{smoothraggedrightshapequintuplet: skip4=\the\skip4}%
+   \typog at typeout{smoothraggedrightshapequintuplet: skip5=\the\skip5}%
+   \unless\ifnum\typog at mod{\typog at quintuplet@max at lines}{5}=0
+     \PackageError{typog}
+                  {Line number of quintuplet generator %
+                    (\typog at quintuplet@max at lines) not divisible by 5}
+                  {}
+   \fi
+   \edef\typog@@quintuplet at linespecs{%
+     \glueexpr \skip0 + \typog@@quintuplet at parindent\relax
+            \glueexpr \skip1 - \typog@@quintuplet at parindent\relax
+                    \skip0 \skip2  \skip0 \skip3  \skip0 \skip4  \skip0 \skip5
+     \typog at repeat{\numexpr\typog at quintuplet@max at lines / 5 - 1}
+                  {\skip0 \skip1  \skip0 \skip2  \skip0 \skip3  \skip0 \skip4  \skip0 \skip5}}
+   \parshape=\typog at quintuplet@max at lines\typog@@quintuplet at linespecs\relax}
+  {\par}
+
+\newcommand*{\typog at septuplet@max at lines}{98}
+
+\define at key[typog]{smoothraggedrightshapeseptuplet}{leftskip}%
+           {\def\typog@@septuplet at leftskip{#1}}
+\define at key[typog]{smoothraggedrightshapeseptuplet}{parindent}%
+           {\def\typog@@septuplet at parindent{#1}}
+\NewDocumentEnvironment{smoothraggedrightshapeseptuplet}{O{} m m m m m m m}
+  {\def\typog@@septuplet at leftskip{\z@}%
+   \def\typog@@septuplet at parindent{\z@}%
+   \setkeys*[typog]{smoothraggedrightshapeseptuplet}{#1}%
+   \skip0=\typog@@septuplet at leftskip
+   \skip1=#2\relax
+   \skip2=#3\relax
+   \skip3=#4\relax
+   \skip4=#5\relax
+   \skip5=#6\relax
+   \skip6=#7\relax
+   \skip7=#8\relax
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip0=\the\skip0}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip1=\the\skip1}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip2=\the\skip2}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip3=\the\skip3}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip4=\the\skip4}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip5=\the\skip5}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip6=\the\skip6}%
+   \typog at typeout{smoothraggedrightshapeseptuplet: skip7=\the\skip7}%
+   \unless\ifnum\typog at mod{\typog at septuplet@max at lines}{7}=0
+     \PackageError{typog}
+                  {Line number of septuplet generator %
+                    (\typog at septuplet@max at lines) not divisible by 7}
+                  {}
+   \fi
+   \edef\typog@@septuplet at linespecs{%
+     \glueexpr \skip0 + \typog@@septuplet at parindent\relax
+            \glueexpr \skip1 - typog@@septuplet at parindent\relax
+                    \skip0 \skip2  \skip0 \skip3  \skip0 \skip4  \skip0 \skip5  \skip0 \skip6  \skip0 \skip7
+     \typog at repeat{\numexpr\typog at septuplet@max at lines / 7 - 1}
+                  {\skip0 \skip1  \skip0 \skip2  \skip0 \skip3  \skip0 \skip4  \skip0 \skip5  \skip0 \skip6  \skip0 \skip7}}
+   \parshape=\typog at septuplet@max at lines\typog@@septuplet at linespecs\relax}
+  {\par}
+
+\newcommand*{\smoothraggedrightfuzzfactor}{1.0}
+\newcommand*{\smoothraggedrightgenerator}{triplet}
+\newlength{\smoothraggedrightleftskip}
+\newlength{\smoothraggedrightparindent}
+\newlength{\smoothraggedrightragwidth}
+\setlength{\smoothraggedrightragwidth}{2em}
+
+\newdimen{\typog at fuzzwidth}
+
+\define at key[typog]{smoothraggedrightpar}{linewidth}%
+           {\def\typog@@linewidth{#1}}
+
+\NewDocumentEnvironment{smoothraggedrightpar}{O{}}
+  {\edef\typog@@linewidth{\linewidth}%
+   \setkeys[typog]{smoothraggedrightpar}{#1}%
+   \edef\typog@@generatorchoice{%
+     \ifnum\pdf at strcmp{\smoothraggedrightgenerator}{triplet}=\z@
+       0%
+     \else
+       \ifnum\pdf at strcmp{\smoothraggedrightgenerator}{quintuplet}=\z@
+         1%
+       \else
+         \ifnum\pdf at 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 at fuzzwidth=\smoothraggedrightfuzzfactor\smoothraggedrightragwidth
+   \ifcase\typog@@generatorchoice
+     \typog at fuzzwidth=.25\smoothraggedrightragwidth
+     \typog at typeout{smoothraggedright: generator=triplet, typog at fuzzwidth=\the\typog at fuzzwidth}%
+     \smoothraggedrightshapetriplet[leftskip=\typog@@smoothraggedrightleftskip,
+                                    parindent=\glueexpr\smoothraggedrightparindent + \parindent,
+                                    #1]%
+        {\glueexpr \typog@@linewidth - \smoothraggedrightragwidth
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth\relax}% (1)
+        {\glueexpr \typog@@linewidth \@minus \typog at fuzzwidth}% (3)
+        {\glueexpr (\typog@@linewidth * 2 - \smoothraggedrightragwidth) / 2
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (2)
+   \or
+     \typog at fuzzwidth=.125\smoothraggedrightragwidth
+     \typog at typeout{smoothraggedright: generator=quintuplet, typog at fuzzwidth=\the\typog at fuzzwidth}%
+     \smoothraggedrightshapequintuplet[leftskip=\typog@@smoothraggedrightleftskip,
+                                       parindent=\glueexpr\smoothraggedrightparindent + \parindent,
+                                       #1]%
+        {\glueexpr (\typog@@linewidth * 4 - \smoothraggedrightragwidth * 3) / 4
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (2)
+        {\glueexpr \typog@@linewidth \@minus \typog at fuzzwidth\relax}% (5)
+        {\glueexpr (\typog@@linewidth * 2 - \smoothraggedrightragwidth) / 2
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (3)
+        {\glueexpr (\typog@@linewidth * 4 - \smoothraggedrightragwidth) / 4
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (4)
+        {\glueexpr \typog@@linewidth - \smoothraggedrightragwidth
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth\relax}% (1)
+   \or
+     \typog at fuzzwidth=.08333\smoothraggedrightragwidth
+     \typog at typeout{smoothraggedright: generator=septuplet, typog at fuzzwidth=\the\typog at fuzzwidth}%
+     \smoothraggedrightshapeseptuplet[leftskip=\typog@@smoothraggedrightleftskip,
+                                      parindent=\glueexpr\smoothraggedrightparindent + \parindent,
+                                      #1]%
+        {\glueexpr (\typog@@linewidth * 3 - \smoothraggedrightragwidth * 2) / 3
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (3)
+        {\glueexpr (\typog@@linewidth * 6 - \smoothraggedrightragwidth) / 6
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (6)
+        {\glueexpr \typog@@linewidth - \smoothraggedrightragwidth +
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth\relax}% (1)
+        {\glueexpr (\typog@@linewidth * 3 - \smoothraggedrightragwidth) / 3
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (5)
+        {\glueexpr (\typog@@linewidth * 6 - \smoothraggedrightragwidth * 5) / 6
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at fuzzwidth\relax}% (2)
+        {\glueexpr \typog@@linewidth \@minus \typog at fuzzwidth\relax}% (7)
+        {\glueexpr (\typog@@linewidth * 2 - \smoothraggedrightragwidth) / 2
+                   + \glueexpr \z@ \@plus \typog at fuzzwidth \@minus \typog at 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'.


Property changes on: trunk/Master/texmf-dist/tex/latex/typog/typog.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/tlpkg/bin/tlpkg-ctan-check
===================================================================
--- trunk/Master/tlpkg/bin/tlpkg-ctan-check	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Master/tlpkg/bin/tlpkg-ctan-check	2024-05-07 20:11:51 UTC (rev 71202)
@@ -876,7 +876,7 @@
     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

Modified: trunk/Master/tlpkg/libexec/ctan2tds
===================================================================
--- trunk/Master/tlpkg/libexec/ctan2tds	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Master/tlpkg/libexec/ctan2tds	2024-05-07 20:11:51 UTC (rev 71202)
@@ -1484,6 +1484,7 @@
  '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 @@
  '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 @@
  'semioneside', 'NULL',         # not figure*.mp
  'synthslant',	'NULL',         # doc figures
  'textpath',    'textpath.mp',  # not textpathfigs.mp
+ 'typog',	'NULL',         # doc figures
 );
 
 

@@ -3867,6 +3870,7 @@
  'thumbpdf'             => '\.pl$',
  'tikztosvg'		=> '^tikztosvg$',
  'tlcockpit'		=> '\.sh$',
+ 'typog'		=> 'typog-grep.pl$',
  'ulqda'                => '\.pl$',
  'urlbst'               => 'urlbst$',
  'vpe'                  => '\.pl$',
@@ -3957,6 +3961,7 @@
  'texlogsieve'		=> '\.1$',
  'tikztosvg'		=> '\.1$',
  'tlcockpit'		=> '\.man$',
+ 'typog'                => '\.1$',
  'webquiz'              => '\.1$',
  'wheretotrim'          => '\.1$',
 );

Modified: trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2024-05-07 20:02:41 UTC (rev 71201)
+++ trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2024-05-07 20:11:51 UTC (rev 71202)
@@ -1434,6 +1434,7 @@
 depend typed-checklist
 depend typeface
 depend typoaid
+depend typog
 depend typogrid
 depend uassign
 depend ucs

Added: trunk/Master/tlpkg/tlpsrc/typog.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/typog.tlpsrc	                        (rev 0)
+++ trunk/Master/tlpkg/tlpsrc/typog.tlpsrc	2024-05-07 20:11:51 UTC (rev 71202)
@@ -0,0 +1,3 @@
+binpattern f bin/${ARCH}/${PKGNAME}-grep
+docpattern +f texmf-dist/doc/man/man1/${PKGNAME}-grep.*
+



More information about the tex-live-commits mailing list.