summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/unicodefonttable
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-10-21 20:31:49 +0000
committerKarl Berry <karl@freefriends.org>2021-10-21 20:31:49 +0000
commita4756b9a2c587fe3fe092cc9cfd8e3b1fb267445 (patch)
tree0b4d0134bccafad5daeb2ede7b872e66e611a6a6 /Master/texmf-dist/source/latex/unicodefonttable
parentc1fb42e1c4a88d363f56d1eed4804bc16bcaee59 (diff)
unicodefonttable (21oct21)
git-svn-id: svn://tug.org/texlive/trunk@60826 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/unicodefonttable')
-rw-r--r--Master/texmf-dist/source/latex/unicodefonttable/unicodefonttable.dtx2295
-rw-r--r--Master/texmf-dist/source/latex/unicodefonttable/unicodefonttable.ins72
2 files changed, 2367 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/unicodefonttable/unicodefonttable.dtx b/Master/texmf-dist/source/latex/unicodefonttable/unicodefonttable.dtx
new file mode 100644
index 00000000000..67cb3a8d643
--- /dev/null
+++ b/Master/texmf-dist/source/latex/unicodefonttable/unicodefonttable.dtx
@@ -0,0 +1,2295 @@
+%%%%% \iffalse meta-comment
+%
+%% File: unicodefonttable.dtx (C) Copyright 2019-2021 Frank Mittelbach
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% https://www.latex-project.org/lppl.txt
+%
+%
+% The development version of the bundle can be found below
+%
+% https://github.com/FrankMittelbach/fmitex/
+%
+% for those people who are interested or want to report an issue.
+%
+
+\def\unicodefonttabledate {2021/10/19}
+\def\unicodefonttableversion{v1.0e}
+
+
+%<*driver>
+\documentclass{l3doc-TUB}
+
+% some fixes local to this documentation
+
+\ExplSyntaxOn
+ \cs_new:Npn\IfImplementationShownTF
+ {\bool_if:NTF \g__codedoc_typeset_implementation_bool}
+\ExplSyntaxOff
+
+\makeatletter
+\def\meta@font@select{\normalfont\itshape}
+
+\IndexPrologue{%
+ \IfImplementationShownTF{\section*{Index}%
+ Numbers written in italic refer to the page
+ where the corresponding entry is described
+ or mentioned. Numbers underlined refer to the
+ code line of the
+ definition; numbers in Roman refer to the
+ code lines where the entry is used.}%
+ {\section{Index}%
+ Numbers written in italic refer to the page
+ where the corresponding entry is described
+ or mentioned.}}
+
+\makeatother
+
+
+\usepackage{graphicx,unicodefonttable}
+
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+ \DocInput{unicodefonttable.dtx}
+\advance\signaturewidth by 40pt
+\makesignature
+\end{document}
+%</driver>
+%
+% \fi
+%
+% \tracinglostchars=3
+%
+% \newcommand\key [1]{\texttt{#1}}
+% \newcommand\kval[1]{\texttt{#1}}
+%
+% \newcommand\keysetup[1]{\noindent\marginpar{\raggedleft Key setup: #1}\ignorespaces}
+% \renewcommand\keysetup[1]{\paragraph*{\hspace*{-8pc}Key setup (#1)}}
+%
+%
+% \title{The \texttt{unicodefonttable} package\thanks{This is
+% version \unicodefonttableversion\ of the package, dated
+% \unicodefonttabledate; the license is LPPL.}}
+% \author{Frank Mittelbach}
+% \address{Mainz, Germany}
+% \netaddress{https://www.latex-project.org}
+% \personalURL{https://ctan.org/pkg/unicodefonttable}
+% \raggedbottom
+%
+% \maketitle
+%
+%
+% \begin{abstract}
+% A package for typesetting font tables for larger fonts, e.g.,
+% TrueType or OpenType Unicode fonts.
+% To produce a one-off table, a standalone version is available as well.
+% \end{abstract}
+%
+%
+% \tableofcontents
+%
+%
+%
+% \section{Introduction}
+%
+% When I started to write a new chapter for the third edition of
+% \emph{The \LaTeX{} Companion} on modern fonts available for
+% different \LaTeX{} engines, I was a bit surprised that I couldn't
+% find a way to easily typeset tables showing the glyphs available in
+% TrueType or OpenType fonts. The \pkg{nfssfont} package available
+% with \LaTeX{} only supports fonts from the 8-bit world, but
+% modern fonts that can be used with \XeTeX{} or \LuaTeX{} can
+% contain thousands of glyphs and having a method to display what
+% is available in them was important for me.
+%
+% I therefore set out to write my own little package and what
+% started as an afternoon exercise ended up being this package,
+% offering plenty of bells and whistles for typesetting such
+% font tables.
+%
+% As there can be many glyphs in such fonts a tabular
+% representation of them might run for several pages, so the
+% package internally uses the \pkg{longtable} package to handle
+% that.
+%
+% In most cases the glyphs inside the fonts are indexed by their
+% Unicode numbers so it is natural to display them sorted by their
+% position in the Unicode character set.
+%
+% Unicode is organized in named blocks such as ``Basic Latin'',
+% ``Latin-1~Supplement'', etc., typically consisting of 265
+% characters each.\footnote{Some blocks are smaller, while those
+% containing the Asian ideographs are much larger.} It is therefore
+% helpful to use these block names as subtitles within the table,
+% to more easily find the information one is looking for.
+%
+% A common way to represent the number of a single Unicode
+% character is \texttt{U+} followed by four (or more)
+% hexadecimal digits. For example, \texttt{U+0041} represents the letter
+% ``A'' and \texttt{U+20AC} the Euro currency symbol ``\texteuro''.
+% We use this convention by showing a Unicode range of sixteen
+% characters at the left of each table row, e.g., \texttt{U+0040 -
+% 004F}, followed by the sixteen glyphs in the range. Thus that
+% particular table row from the ``Basic Latin'' block would show
+% something like
+%
+% \displayfonttable*[noheader,range-start=0040, range-end=004F,
+% color=black!50]{Latin Modern Sans}
+%
+% If a Unicode character has no glyph representation in a given
+% font then this is indicated by a special symbol (by default a
+% colored hyphen). By default some color is used, but we've grayscaled
+% the output for \TUB.
+%
+% In order to easily locate any Unicode character the table shows by
+% default sixteen hex digits as a column heading. For example, to find
+% Euro currency symbol (\texttt{U+20AC}) one first finds the
+% right row, which is the range \texttt{U+20A0 - 20AF}, and then
+% the \texttt{C} column in that row, and the glyph is there (or an
+% indication that the font is missing that glyph;
+% the line shows that for some of the other slots).
+%
+% \displayfonttable*[noheader,range-start=20A0, range-end=20AF,
+% color=black!50]{Latin Modern Sans}
+%
+% It can be useful to compare two fonts with each other by
+% filling the table with glyphs from a secondary font if the
+% primary font is missing them. For example, the next display shows
+% two rows of Latin Modern Math (black glyphs) and instead of showing
+% a missing glyph symbol in most slots, we use the glyphs from New
+% Computer Modern Math, which has a much larger glyph set
+% (normally red glyphs with gray background but again, grayscaled for
+% \TUB).
+%
+%
+% \displayfonttable[noheader,nostatistics,display-block=none,
+% compare-with=NewCMMath-Regular.otf,range-start=2A00,range-end=2A1F,
+% color=black!50,compare-color=none]
+% {latinmodern-math.otf}
+%
+%
+% \section{The user interface}
+%
+% The package offers one command to typeset a font table. The
+% appearance of the table can be customized by specifying key/value
+% pairs.
+%
+% \begin{function}{\displayfonttable}
+% \begin{syntax}
+% \cs{displayfonttable} \texttt{*} \oarg{key/value-list} \Arg{font-name} \oarg{font-features}
+% \end{syntax}
+% The \meta{font-name} is the font to be displayed. This and the
+% \meta{font-features} argument are passed to \pkg{fontspec}, thus they
+% should follow the conventions of that package for specifying a
+% font. The \meta{key/value-list} offers customization
+% possibilities discussed below.
+%
+% The \cs{displayfonttable*} is a variant of the command, intended
+% for use with 8-bit legacy fonts. It presets some keys, but
+% otherwise behaves identically. The preset values are:
+%\begin{verbatim}
+% nostatistics, display-block=none, hex-digits=head, range-end=FF
+%\end{verbatim}
+% For details see the next section.
+% \end{function}
+%
+%
+%
+% \begin{function}{\fonttablesetup}
+% \begin{syntax}
+% \cs{fonttablesetup} \Arg{key/value-list}
+% \end{syntax}
+% Instead of or in addition to specifying key/values to
+% \cs{displayfonttable} it is possible to set them up as
+% defaults. Inside \cs{displayfonttable} the defaults are applied first,
+% so one can still overwrite their values for an individual table.
+% \end{function}
+%
+%
+% \begin{function}{\fonttableglyphcount}
+% \begin{syntax}
+% \cs{fonttableglyphcount}
+% \end{syntax}
+% While typesetting a font table the package keeps track of the
+% number of glyphs it finds in the font. After the table has finished,
+% this value is available in \cs{fonttableglyphcount} and it is, for
+% example, used when statistics are produced. At the start of the
+% next table it is reset to zero.
+% \end{function}
+%
+%
+%
+%
+% \subsection{Keys and their values}
+%
+% Several of the available keys are booleans accepting \texttt{true}
+% or \texttt{false}. They usually exist in pairs so that one can
+% specify the desired behavior without needing to provide a value,
+% e.g., specifying \key{header} is equivalent to specifying
+% \key{header}\texttt{=true} or \key{noheader}\texttt{=false}, etc.
+% In the lists below the default settings are indicated by an
+% underline.
+%
+% \begin{variable}{
+% header, noheader,
+% title-format, title-format-cont,
+% }
+% The first set of keys is concerned with the overall look and
+% feel of the generated table.
+% \begin{description}
+% \item[\underline{\key{header}}, \key{noheader}]
+% These keys determine whether a header to the table is
+% produced.
+%
+% \item[\key{title-format}, \key{title-format-cont}]
+% These keys define what is provided as a header title or
+% continuation title if the table consists of several pages.
+% They expect code as their value. This code can contain \verb=#1=
+% and \verb=#2= to denote the \meta{font-name} and
+% \meta{font-features} arguments, respectively.
+%
+% By default a title using the \cs{caption} command is produced; on
+% continuation titles, the \meta{font-features} are not shown.
+% This is typeset as a \env{longtable} header row, so you either need to use
+% \cs{multicolumn} or a \cs{caption} command\Dash otherwise everything
+% ends up in the first column.
+%
+% \end{description}
+%
+% \end{variable}
+%
+%
+% \begin{variable}{
+% display-block,
+% hex-digits, color,
+% }
+% These keys handle the inner parts of the table.
+%
+% \begin{description}
+% \item[\key{display-block}]
+% The Unicode dataset is organized in named blocks that are typically 128 or
+% 256 characters, though some are noticeably larger and a few are
+% smaller. With the \key{display-block} key it is
+% possible to specify if and how such blocks should be made visible.
+% The following values are supported:
+% \begin{description}
+% \item[\underline{\kval{titles}}]
+% Above each display block that contains glyphs the Unicode title
+% of the block is displayed.
+%
+% \item[\kval{rules}]
+% Display blocks are indicated only by a \cs{midrule}.
+%
+% \item[\kval{none}]
+% Display blocks are not indicated at all.
+% \end{description}
+%
+% \item[\key{hex-digits}]
+% To ease reading the table, rows of hex digits are added to
+% it. Where or if this happens is controlled by this key. Allowed
+% values for it are the following:
+% \begin{description}
+% \item[\kval{block}]
+% A row of hex digits is placed at the beginning of each Unicode
+% block containing glyphs in the displayed font.
+%
+% \item[\kval{foot}]
+% A row is added to the foot of each table page.
+%
+% \item[\underline{\kval{head}}]
+% A row is added to the top of each table page.
+%
+% \item[\kval{head+foot}]
+% A row is added to the top and the foot of each table page.
+%
+% \item[\kval{none}]
+% All hex digit rows are suppressed.
+% \end{description}%
+%
+% \item[\key{hex-digits-font}]
+% The font to use for the hex digits, by default
+% \underline{\cs{ttfamily}\cs{scriptsize}}.{\hfuzz=2.7pt\par}
+%
+% \item[\key{color}]
+% This key determines the color for parts of the table (hex digits
+% and Unicode ranges). It can be either \kval{none} or a color
+% specification as understood by the \cs{color} command.
+% The default is \underline{\texttt{blue}}.
+%
+% \end{description}
+%
+% \end{variable}
+%
+%
+% \begin{variable}{
+% statistics, nostatistics,
+% statistics-font,statistics-format,
+% }
+% The next set of keys allows altering the statistics that are produced.
+% \begin{description}
+%
+% \item[\underline{\key{statistics}}, \key{nostatistics}]
+% These keys determine whether some statistics are listed at
+% the end of the table.
+%
+% \item[\key{statistics-font}]
+% The font used to typeset the statistics; the default is\\
+% \underline{\cs{normalfont}\cs{small}}.
+%
+%
+% \item[\key{statistics-format}]
+% Code (text) to specify what should be typeset in the
+% statistics. One can use \verb=#1= for the \meta{font-name} and
+% \verb=#2= for the glyph count.
+% The material is typeset on a single line at the end of the
+% table. If several lines are needed you need to use \cs{parbox}
+% or a similar construct.
+% \end{description}
+% \end{variable}
+%
+%
+%
+% \begin{variable}{
+% glyph-width,
+% missing-glyph, missing-glyph-font, missing-glyph-color,
+% }
+% Another set of keys deals with customization on the glyph level.
+% \begin{description}
+% \item[\key{glyph-width}]
+% All glyphs are typeset in a box with the same width, the default
+% value is \underline{\texttt{6pt}} which is suitable for most 10pt
+% fonts
+% and make the table fit comfortably into the text width of
+% a typical document.
+%
+% \item[\key{missing-glyph}]
+% If a slot in a row doesn't have a glyph in the font you may still
+% want display something to indicate this state. By giving the key
+% a value any arbitrary glyph or material can be typeset. The
+% default is to typeset a \kval{-} (hyphen) in a special color.
+%
+% Rows that contain no glyph whatsoever are not displayed at
+% all. Instead a small vertical space is added to indicate the one
+% or more rows are omitted.
+%
+% \item[\key{missing-glyph-font}]
+%
+% The font used for the missing glyphs (the default value is
+% \underline{\cs{ttfamily}\cs{scriptsize}}).
+%
+% \item[\key{missing-glyph-color}]
+% If not specified it uses the value specified with the \key{color}
+% key. If you want a different color, e.g., \texttt{red}, you can
+% use a color value or you can specify \kval{none} to use no coloring.
+%
+% \end{description}
+%
+% \end{variable}
+%
+%
+% \begin{variable}{
+% compare-with,compare-color, compare-bgcolor,statistics-compare-format
+% }
+%
+% You can make comparisons between two fonts, which is useful, for
+% example when dealing with incomplete math fonts and you need to
+% see how well the symbols from one font blend with the supplementary
+% symbols from another font.
+%
+% \begin{description}
+% \item[\key{compare-with}]
+%
+% If given, the value is a \meta{comparison-font-name} that is used
+% to supply missing glyphs. This means that if the \meta{font-name}
+% to be displayed is missing a glyph in a slot, then the
+% \meta{comparison-font-name} is checked, and if that font has the
+% glyph in question, it will be displayed instead of showing a
+% missing glyph indicator.
+%
+% \item[\key{compare-color}, \key{compare-bgcolor}]
+%
+% To distinguish real glyphs from missing but substituted glyphs,
+% they can be colored specially (default \underline{\texttt{red}})
+% and/or you can have their background colored (default is
+% \underline{\texttt{black!10}}, i.e., a light gray).
+%
+% \item[\key{statistics-compare-format}]
+%
+% Code (text) to specify what should be typeset in the statistics
+% when comparing two fonts. One can use \verb=#1= for the
+% \meta{font-name} and \verb=#2= for its glyph count, \verb=#3= is
+% the name of the comparison font, \verb=#4= its glyph count,
+% \verb=#5= for the number of glyphs missing in this font and
+% \verb=#6= the number of extra glyphs in it. This code is used
+% instead of \key{statistics-format} when comparisons are made.
+%
+% The material is typeset on a single line at the end of the
+% table. If several lines are needed you need to use \cs{parbox}
+% or a similar construct.
+%
+% \end{description}
+% \end{variable}
+%
+%
+% \begin{variable}{
+% range-start, range-end,
+% }
+% Finally there are two keys for restricting the display range.
+% \begin{description}
+% \item[\key{range-start}, \key{range-end}]
+% The full Unicode set of characters is huge and checking every
+% slot to see if the current font contains a glyph in the slot
+% takes a long time. If you know that font contains only a
+% certain subset then you can speed up the table generation
+% considerably by limiting the search (and consequently the output
+% generation).
+% The \key{range-start} specifies where to start with the search
+% (default \underline{\texttt{0000}}) and \key{range-end} gives
+% the last slot that is tested (default
+% \underline{\texttt{FFFF}}).
+%
+% Thus, by default we restrict the display to slots below
+% \texttt{10000}, because text fonts seldom contain glyphs in the
+% higher planes. But if you want to see everything of the font (as
+% far as supported by this package) and are prepared to wait for
+% the higher
+% planes to be scanned, you can go up to a value of \texttt{FFFFF}.
+%
+% These keys are also quite useful in combination with the previous
+% \key{compare-with} key, to display only, for example, the Greek
+% letters and see how glyphs from two fonts blend with each other.
+
+% \end{description}
+% \end{variable}
+%
+%
+%
+% \subsection{A standalone interactive version}
+%
+% If you want to quickly display a single font, you can run
+% \texttt{unicodefont.tex} through \LuaTeX{} (or \XeTeX{}). Similar to
+% \texttt{nfssfont.tex} (which is for 8-bit fonts with \pdfTeX) it
+% asks you a few questions and then generates the font table for
+% you. There are fewer configuration options available,
+% but this workflow saves you writing a document to get a
+% one-off table.
+%
+% Most font tables need several runs due to the use of
+% \pkg{longtable}, which has to find the right width for the columns
+% across several pages. The \texttt{unicodefont} file therefore
+% remembers your selection from the previous run and asks you if
+% you want to reapply it to speed up the process.
+%
+%
+%
+% \section{Notes on the table data}
+%
+% If you look at some parts of a Unicode font table you see a number of slots that
+% do not show a \enquote{missing glyph} sign, but nonetheless appear
+% to be empty. For example:
+%
+% \displayfonttable[noheader,nostatistics,display-block=none,
+% range-start=0020,range-end=00BF,
+% color=black!50]
+% {TeX Gyre Pagella}
+%
+%
+% The reason is that Unicode contains a lot of special
+% spaces or otherwise invisible characters, e.g., \texttt{U+0020}
+% is the normal space, \texttt{U+00A0} is a non-breaking space,
+% \texttt{U+00AD} is a soft-hyphen (what \LaTeX{} users would
+% indicate with \cs{-}), and so forth. Especially the row
+% \texttt{U+2000-200F} in Table~1 looks strange as it appears to be totally
+% empty, but in fact most of its slots contain spaces of different
+% width.
+%
+%\displayfonttable[noheader,nostatistics,hex-digits=foot,
+% range-start=2000,range-end=202F,
+% color=black!50]
+% {latinmodern-math.otf}
+%
+%
+% Another somewhat surprising area is the \enquote{Mathematical
+% Alphanumeric Symbols} block in math fonts, starting at \texttt{U+1D400}.
+% There you see a number of missing characters, the first two being
+% \texttt{U+1D455} (math italic small h) and \texttt{U+1D49D} (math
+% script B).
+%
+% \displayfonttable[noheader,nostatistics,hex-digits=foot,
+% range-start=1D400,range-end=1D4AF,
+% color=black!50]
+% {latinmodern-math.otf}
+%
+% In this case the reason is \emph{not} that the font
+% fails to implement the characters, but that these characters have
+% already been defined in earlier revisions of the Unicode standard in the
+% lower Unicode plane. For example, the \enquote{h} is the
+% Planck constant \texttt{U+210E} and \texttt{U+212C} is
+% the script capital B, etc. The Unicode Consortium decided not
+% to encode the \emph{same} character twice, hence the apparent
+% holes.
+%
+%
+% \IfImplementationShownTF{}
+% {\appendix
+% \def\theHsection{Appendix.\thesection}
+% \addtocontents{toc}{\smallskip}
+% \setlength\IndexMin{200pt}
+% \PrintIndex
+% }
+%
+%
+% \section{Examples}
+%
+% In this section we show the results of a few calls to
+% \cs{displayfonttable}.
+% The tables are a bit easier to navigate if they use color in some
+% places, but for \TUB{} this is not practical, so we
+% use black and gray.
+%
+% \subsection{Computer Modern Sans --- 8-bit font}
+%
+% Our first example is an 8-bit font which gives a concise table.
+% Command used: \begin{verbatim}
+% \displayfonttable*[color=none, range-end=7F]{cmss10}
+% \end{verbatim}
+%
+% \displayfonttable*[color=none, range-end=7F]{cmss10}
+%
+%
+% \iffalse
+%
+%\subsection{\TeX{} Gyre Pagella (Palatino) oldstyle figures --- OTF font}
+%
+% This example shows Pagella with oldstyle numerals.
+% Command used:
+%\begin{verbatim}
+%\displayfonttable{TeX Gyre Pagella}[Numbers=OldStyle]
+%\end{verbatim}
+%
+%\displayfonttable{TeX Gyre Pagella}[Numbers=OldStyle]
+%
+% \fi
+%
+%
+%
+% \subsection{Latin Modern Math compared to New Computer Modern Math}
+%
+% This example shows the extra symbols available in New Computer
+% Modern Math in comparison to Latin Modern Math as the base font.
+% We use the following setup (including settings for the
+% grayscaled \TUB\ output, as an example of color overrides):
+%\begin{verbatim}
+% \displayfonttable[hex-digits=head+foot, range-end=1FFFF,
+% compare-with=New Computer Modern Math,
+% compare-color=black, compare-bgcolor=black!5,
+% missing-glyph-color=black!50, color=black!75]
+% {Latin Modern Math}
+%\end{verbatim}
+% That is, glyphs only in \texttt{NewCM} are shown with a light gray
+% background.
+%
+% We also extended the range to cover \texttt{U+10000} to
+% \texttt{U+1FFFF} in order to include the Unicode Math alphabets.
+%
+% \displayfonttable[hex-digits=head+foot, range-end=1FFFF,
+% compare-with=New Computer Modern Math,
+% compare-color=black, compare-bgcolor=black!5,
+% missing-glyph-color=black!50, color=black!75]
+% {Latin Modern Math}
+%
+%
+%\subsection{Garamond Libre's Byzantine Musical Symbols}
+%
+% As a final example we exhibit the Byzantine Musical Symbols as provided by
+% Garamond Libre.
+% Command used:
+%\begin{verbatim}
+% \displayfonttable[range-start=1D000, range-end=1D0FF,
+% hex-digits=block,
+% missing-glyph-color=black!50, color=black!75,
+% statistics-format=Total number of glyphs in
+% this block of #1 is #2]
+% {Garamond Libre}
+%\end{verbatim}
+%
+% Note that we have altered the text produced by the statistics,
+% because the default is somewhat misleading if only a portion of
+% the font is displayed. This produces the following table:
+%
+% \displayfonttable[range-start=1D000, range-end=1D0FF,
+% hex-digits=foot,
+% missing-glyph-color=black!50, color=black!75,
+% statistics-format=Total number of glyphs in
+% this block of #1 is #2]
+% {Garamond Libre}
+%
+%
+%
+% \IfImplementationShownTF
+% {\StopEventually{\setlength\IndexMin{200pt} \PrintIndex }}
+% {\StopEventually{}}
+%
+%
+%
+% \section{The package implementation}
+%
+% \hfuzz=10pt ^^A lots of slightly overfull tt lines
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% By default the package uses coloring to improve the table
+% appearance and therefore requires a color package.
+% \begin{macrocode}
+\RequirePackage{xcolor}
+% \end{macrocode}
+%
+
+% \begin{macrocode}
+%<@@=fmuft>
+% \end{macrocode}
+%
+% We need the package \pkg{xparse} for specifying the document-level
+% interface commands and \pkg{l3keys2e} to use the \pkg{expl3} key
+% value methods within \LaTeXe{}. These packages automatically
+% require \pkg{expl3} so there is no need to load that explicitly.
+% Actually, \pkg{expl3}, \pkg{l3keys2e} and the \pkg{xparse}
+% functionality is now all part of the \LaTeX{} kernel so the next
+% line is actually not needed at all with a current \LaTeX{} kernel, but
+% in order to support older installations we keep it for now.
+%
+% \begin{macrocode}
+\RequirePackage{xparse,l3keys2e}
+% \end{macrocode}
+%
+% Here we introduce the package and specify its version number:
+% \begin{macrocode}
+\ProvidesExplPackage{unicodefonttable}
+ {\unicodefonttabledate}
+ {\unicodefonttableversion}
+ {Producing font tables for Unicode and other fonts}
+% \end{macrocode}
+%
+% \newcommand\hex[1]{$\langle\textit{hex}_{#1}\rangle$}
+%
+%
+%
+%
+%
+% \subsection{User interface commands}
+%
+%
+% Throughout the implementation we will define a number of keys (and
+% their allowed values). We introduce them at the point where they are
+% used, so they are sprinkled throughout the code.\footnote{This fits
+% with the way this package was developed. I first implemented a
+% single rigid table layout without configuration possibilities and
+% then thought about which parts I wanted to have flexible. I then
+% replaced the rigid code with code that is affected by setting
+% key/value pairs.}
+
+% \begin{macro}{\fonttablesetup}
+% To set up user defaults for the keys we provide a standard
+% interface. The command \cs{unicodefonttabletablesetup} expects a
+% key/value list and can be called as often as necessary.
+% \begin{macrocode}
+\NewDocumentCommand \fonttablesetup { m }
+ { \keys_set:nn {@@} {#1} \ignorespaces }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\displayfonttable}
+% The document-level command for generating a font table.
+% \begin{macrocode}
+\NewDocumentCommand\displayfonttable {s O{} m o}{%
+ \IfBooleanTF #1
+ {
+% \end{macrocode}
+% For the starred form we preset a number of keys with values
+% suitable when displaying 8-bit legacy fonts.
+% With such fonts Unicode block headers make little
+% sense (as the fonts do not conform to the Unicode layout and
+% since they have at most 265 glyphs). It is therefore also unnecessary to
+% loop over the whole Unicode range of the first plane.
+% If necessary all of them can still be overwritten in the optional argument.
+% \begin{macrocode}
+ \@@_display_fonttable:nnn
+ {nostatistics,display-block=none,hex-digits=head,range-end=FF,#2}
+ {#3}{#4}
+ }
+ {
+ \@@_display_fonttable:nnn {#2}{#3}{#4}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_display_fonttable:nnn}
+% This command is the main workhorse of the
+% package. It produces a \texttt{longtable} containing all font
+% glyphs with 16 glyphs per row. The first optional argument is
+% used to configure the table through key/value pairs, the
+% mandatory argument is the font name to display (in
+% \texttt{fontspec} conventions) and the final optional argument is
+% the font feature list if any. If the latter is not provided it
+% will get a special value (\texttt{--NoValue--}) assigned by
+% \texttt{xparse}, which is something that can be tested for.
+% \begin{macrocode}
+\cs_new:Npn \@@_display_fonttable:nnn #1#2#3 {
+ \group_begin:
+% \end{macrocode}
+% First initialize the font that should be displayed (perhaps with a
+% feature list) and then update the key/value list using \verb=#1=.
+% \begin{macrocode}
+ \fontspec{#2}[#3]
+ \keys_set:nn{@@}{#1}
+% \end{macrocode}
+% If the user has asked for a comparsion to some other font we need to set this up:
+% \begin{macrocode}
+ \tl_if_empty:NTF \l_@@_compare_with_tl
+ { \tl_clear:N \l_@@_compare_font_tl }
+ {
+ \setfontface \l_@@_compare_font_tl {\l_@@_compare_with_tl}[]
+ \cs_set_eq:NN \@@_handle_missing_glyph:n
+ \@@_handle_missing_glyph_compare:n
+ }
+% \end{macrocode}
+% Then we start the table with 17 columns. We use \texttt{longtable}
+% if we produce a caption and \texttt{longtable*} if not (so that
+% the table number is not increased, which would look odd if you
+% have other tables in your document).
+% \begin{macrocode}
+ \begin{longtable\bool_if:NF\l_@@_display_header_bool{*}}
+ {@{}r@{\quad}*{16}{c}@{}}
+% \end{macrocode}
+% Special headers and footers are set up first:
+% \begin{macrocode}
+ \@@_setup_header_footer:nn{#2}{#3}
+% \end{macrocode}
+% Then we produce all table rows with the glyphs.
+% \begin{macrocode}
+ \@@_produce_table_rows:
+% \end{macrocode}
+% At the very end we may typeset some statistics. This can't be
+% done in the table footer, because the data is dynamic (e.g.,
+% number of glyphs processed) and the table footers are static and
+% do not change based on the table content.
+% \begin{macrocode}
+ \@@_handle_table_ending:n {#2}
+ \end{longtable\bool_if:NF\l_@@_display_header_bool{*}}
+ \group_end:
+}
+% \end{macrocode}
+% \end{macro}
+
+
+%
+% \begin{macro}{\fonttableglyphcount}
+% \begin{macro}{\g_@@_glyph_int,\g_@@_glyph_only_B_int,\g_@@_glyph_also_B_int}
+% While generating the font table we count the number of glyphs we
+% see (and typeset). The total is available in the command
+% \cs{fonttableglyphcount} after the table got finished and will be reset to
+% zero when the next table starts.
+% \begin{macrocode}
+\DeclareDocumentCommand \fonttableglyphcount {}
+ { \int_use:N \g_@@_glyph_int }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\int_new:N \g_@@_glyph_int
+% \end{macrocode}
+% When comparing fonts we also record data for the second font: the
+% number of glyphs in both and the number of glyphs only in the
+% second one.
+% \begin{macrocode}
+\int_new:N \g_@@_glyph_only_B_int
+\int_new:N \g_@@_glyph_also_B_int
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+
+
+
+
+% \subsection{The overall table layout}
+%
+%
+% \begin{macro}{\@@_setup_header_footer:nn}
+% Setting up header and footer lines of the table.
+% This macro receives the \textit{font name} and the \textit{font
+% features} specified by the user as its arguments.
+% \begin{macrocode}
+\cs_new:Npn \@@_setup_header_footer:nn #1#2{
+% \end{macrocode}
+% On the first page of the table the header may show a caption or
+% some other sort of title based on the value of
+% \cs{l_@@_display_header_bool}. The formatting is handled by
+% \cs{@@_format_table_title:nn} which can be customized through the
+% key \key{title-format}.
+% \begin{macrocode}
+ \bool_if:NT \l_@@_display_header_bool
+ { \@@_format_table_title:nn{#1}{#2} \@@_debug_nl:n{T}\\*[6pt] }
+% \end{macrocode}
+% We may also want to display a line of hex digits. This is
+% controlled through the key \key{hex-digits} that accepts different
+% values: \kval{head}, \kval{foot}, \kval{head+foo}, \kval{block}
+% (after a block title) or \kval{none}.
+% \begin{macrocode}
+ \bool_if:NT \l_@@_header_hex_digits_bool
+ { \@@_display_row_of_hex_digits: \@@_debug_nl:n{H}\\* }
+ \endfirsthead
+% \end{macrocode}
+% Headers for later table pages have a continuation title and
+% maybe a row of hex digits.
+% \begin{macrocode}
+ \bool_if:NT \l_@@_display_header_bool
+ { \@@_format_table_cont:nn{#1}{#2} \@@_debug_nl:n{T}\\*[6pt] }
+ \bool_if:NT \l_@@_header_hex_digits_bool
+ { \@@_display_row_of_hex_digits: \@@_debug_nl:n{H}\\* }
+ \endhead
+% \end{macrocode}
+% Footers of the table are either empty or show a row of hex digits.
+% \begin{macrocode}
+ \bool_if:NT \l_@@_footer_hex_digits_bool
+ { \@@_display_row_of_hex_digits: \@@_debug_nl:n{H}\\* }
+ \endfoot
+% \end{macrocode}
+% The footer of the last page of the table will always be
+% empty. Any special row, such as a row of hex digits, will be
+% provided in the table body. The reason is that we may want to
+% display statistics at the very end of the table and those can't be
+% placed into a static footer.
+% \begin{macrocode}
+ \endlastfoot
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_header_hex_digits_bool}
+% \begin{macro}{\l_@@_footer_hex_digits_bool}
+% \begin{macro}{\l_@@_blockwise_hex_digits_bool}
+% Here are the booleans we use in the code.
+% \begin{macrocode}
+\bool_new:N \l_@@_header_hex_digits_bool
+\bool_new:N \l_@@_footer_hex_digits_bool
+\bool_new:N \l_@@_blockwise_hex_digits_bool
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_display_row_of_hex_digits:}
+% \begin{macro}{\@@_format_hex_digit:n}
+% Producing a row of hex digits is simple.
+% \begin{macrocode}
+\cs_new:Npn \@@_display_row_of_hex_digits: {
+ & \@@_format_hex_digit:n{0} & \@@_format_hex_digit:n{1}
+ & \@@_format_hex_digit:n{2} & \@@_format_hex_digit:n{3}
+ & \@@_format_hex_digit:n{4} & \@@_format_hex_digit:n{5}
+ & \@@_format_hex_digit:n{6} & \@@_format_hex_digit:n{7}
+ & \@@_format_hex_digit:n{8} & \@@_format_hex_digit:n{9}
+ & \@@_format_hex_digit:n{A} & \@@_format_hex_digit:n{B}
+ & \@@_format_hex_digit:n{C} & \@@_format_hex_digit:n{D}
+ & \@@_format_hex_digit:n{E} & \@@_format_hex_digit:n{F} }
+% \end{macrocode}
+% Each digit is typeset in typewriter and in script size. We offer
+% font and color
+% customizations. Note that it is important to set an explicit
+% family. Otherwise the hex digits are formatted using the current
+% table font (which may or may not work at all).
+% \begin{macrocode}
+\cs_new:Npn \@@_format_hex_digit:n #1 {
+ \l_@@_hex_digits_font_tl \l_@@_color_tl #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+
+% \begin{macro}{\l_@@_color_tl}
+% The token list to hold definition if set up.
+% \begin{macrocode}
+\tl_new:N \l_@@_color_tl
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \keysetup{overall table}
+% Here are the definitions for the keys used in the code above:
+% \begin{macrocode}
+\keys_define:nn {@@} {
+% \end{macrocode}
+% The \key{header} key is a boolean that determines if a header
+% title should be produced (default)
+% \begin{macrocode}
+ ,header .bool_set:N = \l_@@_display_header_bool
+ ,header .default:n = true
+ ,header .initial:n = true
+% \end{macrocode}
+% To ease the setup we also support the key \key{noheader} which is
+% a short form for \texttt{header=false}.
+% \begin{macrocode}
+ ,noheader .bool_set_inverse:N = \l_@@_display_header_bool
+ ,noheader .default:n = true
+% \end{macrocode}
+% The default for the \key{title-format} key is to produce a
+% \cs{caption} listing the font name and any features (if
+% given). Note the \cs{IfValueTF} command (provided by
+% \texttt{xparse}) that checks if the second argument got any value
+% or has the special \texttt{--NoValue--} value.
+% \begin{macrocode}
+ ,title-format .cs_set:Np = \@@_format_table_title:nn #1#2
+ ,title-format .initial:n =
+ \IfValueTF{#2} { \caption{ #1~ (features:~ \texttt{\small#2}) } }
+ { \caption{ #1 } }
+% \end{macrocode}
+% The default continuation title ignores the given features, so the
+% formatting is somewhat simpler. It uses \verb=\caption[]{...}= to
+% make a caption that doesn't alter the table number.
+% \begin{macrocode}
+ ,title-cont-format .cs_set:Np = \@@_format_table_cont:nn #1#2
+ ,title-cont-format .initial:n = \caption[]{#1~ \emph{cont.}}
+% \end{macrocode}
+% The key \key{hex-digits} is implemented as a choice, where each
+% allowed value sets different booleans that are then used in the code.
+% \begin{macrocode}
+ ,hex-digits .choice:
+ ,hex-digits / block .code:n =
+ \bool_set_true:N \l_@@_blockwise_hex_digits_bool
+ \bool_set_false:N \l_@@_header_hex_digits_bool
+ \bool_set_false:N \l_@@_footer_hex_digits_bool
+ ,hex-digits / foot .code:n =
+ \bool_set_true:N \l_@@_footer_hex_digits_bool
+ \bool_set_false:N \l_@@_header_hex_digits_bool
+ \bool_set_false:N \l_@@_blockwise_hex_digits_bool
+ ,hex-digits / head .code:n =
+ \bool_set_true:N \l_@@_header_hex_digits_bool
+ \bool_set_false:N \l_@@_footer_hex_digits_bool
+ \bool_set_false:N \l_@@_blockwise_hex_digits_bool
+ ,hex-digits / head+foot .code:n =
+ \bool_set_true:N \l_@@_header_hex_digits_bool
+ \bool_set_true:N \l_@@_footer_hex_digits_bool
+ \bool_set_false:N \l_@@_blockwise_hex_digits_bool
+ ,hex-digits / none .code:n =
+ \bool_set_false:N \l_@@_header_hex_digits_bool
+ \bool_set_false:N \l_@@_footer_hex_digits_bool
+ \bool_set_false:N \l_@@_blockwise_hex_digits_bool
+ ,hex-digits .initial:n = head
+% \end{macrocode}
+% The font for hex digits are set with \key{hex-digits-font}.
+% \begin{macrocode}
+ ,hex-digits-font .tl_set:N = \l_@@_hex_digits_font_tl
+ ,hex-digits-font .initial:n = \ttfamily \scriptsize
+% \end{macrocode}
+% The \key{color} key is used in most places that get colored; some
+% have their own key but default to the main color.
+% \begin{macrocode}
+ ,color .choice:
+ ,color / none .code:n = \tl_clear:N \l_@@_color_tl
+ ,color / unknown .code:n = \tl_set:Nn \l_@@_color_tl { \color {#1} }
+ ,color .initial:n = blue
+ }
+% \end{macrocode}
+%
+%
+%
+%
+% \begin{macro}{\@@_handle_table_ending:n}
+% At the end of the table we may want to display a final row of
+% hex digits and perhaps some statistics, i.e., the number of
+% typeset glyphs.
+% \begin{macrocode}
+\cs_new:Npn \@@_handle_table_ending:n #1 {
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \@@_debug_nl:n{H} \\*
+ \bool_if:NT \l_@@_footer_hex_digits_bool
+ { \@@_display_row_of_hex_digits: \@@_debug_nl:n{H} \\* }
+ \bool_if:NT \l_@@_display_statistics_bool
+ { \\*[2pt]
+ \multicolumn{17}{l}{ \l_@@_stats_font_tl
+% \end{macrocode}
+% If we do font comparison, we use a different command for
+% displaying statistics and pass more data to it.
+% \begin{macrocode}
+ \tl_if_empty:NTF \l_@@_compare_with_tl
+ {
+ \@@_format_stats:nn{#1}{\fonttableglyphcount}
+ }
+ {
+ \@@_format_compare_stats:nnnnnn{#1}{\fonttableglyphcount}
+ { \l_@@_compare_with_tl }
+% \end{macrocode}
+% The extra arguments are total glyph number in second font, glyphs
+% missing in second font and glyphs only in second font.
+% \begin{macrocode}
+ { \int_eval:n { \int_use:N\g_@@_glyph_also_B_int +
+ \int_use:N\g_@@_glyph_only_B_int }
+ }
+ { \int_eval:n { \fonttableglyphcount -
+ \int_use:N\g_@@_glyph_also_B_int }
+ }
+ { \int_use:N\g_@@_glyph_only_B_int }
+ }
+% \end{macrocode}
+% We don't know exactly how wide the table is (and nor does the
+% user) but one may need to use \cs{parbox} when formatting
+% the statistic line(s). So we back up a bit (rather random) which
+% allows us to use \verb=\parbox{\linewidth}{...= in the key
+% without thinking too much about it.
+% \begin{macrocode}
+ \hspace*{-3cm}
+ }
+ }
+}
+% \end{macrocode}
+%
+% \keysetup{for statistics}
+% Here are the keys used above. By default we produce statistics.
+% \begin{macrocode}
+\keys_define:nn {@@} {
+ ,statistics .bool_set:N = \l_@@_display_statistics_bool
+ ,statistics .default:n = true
+ ,statistics .initial:n = true
+% \end{macrocode}
+% the key \key{nostatistics} is just short for \texttt{statistics=false}:
+% \begin{macrocode}
+ ,nostatistics .bool_set_inverse:N = \l_@@_display_statistics_bool
+ ,nostatistics .default:n = true
+% \end{macrocode}
+% The default font we use is \cs{normalfont}. Again we need to
+% supply a family to avoid getting the font used in the table body.
+% \begin{macrocode}
+ ,statistics-font .tl_set:N = \l_@@_stats_font_tl
+ ,statistics-font .initial:n = \normalfont\small
+% \end{macrocode}
+% And here we have the default text. There is only space for a
+% single line. If more text is needed one needs to provide some
+% explicit \cs{parbox}.
+% \begin{macrocode}
+ ,statistics-format .cs_set:Np = \@@_format_stats:nn #1#2
+ ,statistics-format .initial:n = Total~ number~ of~ glyphs~ in~ #1:~#2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+% \begin{macro}{\@@_debug_nl:n}
+% While developing the code I had a bit of trouble getting the line
+% endings correct, so I added a little macro that made them visible
+% (displaying its argument in the table margin when the key
+% \key{debug} is used. By default it does nothing.
+% \begin{macrocode}
+\cs_new:Npn \@@_debug_nl:n #1 {}
+% \end{macrocode}
+%
+% \keysetup{debugging}
+% This key is really internal and is therefore not documented above
+% (and its behavior may changes over time).
+% \begin{macrocode}
+\keys_define:nn {@@} {
+ debug .code:n = \cs_set:Npn \@@_debug_nl:n ##1
+ {\rlap{\normalfont\scriptsize \qquad ##1}} }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%
+% \subsection{The producing the table content}
+%
+%
+% The body of the table consists of rows with sixteen glyphs each
+% and to produce it we loop through all possible Unicode points
+% starting at \texttt{U+0000} and ending with \texttt{U+FFFF}.
+%
+% This is implemented with a four-level nested loop that runs through the
+% values \texttt{0}, \texttt{1}, \ldots, \texttt{F} with the
+% current hex value in each of the four positions stored in some variable.
+
+
+% \begin{macro}{\g_@@_hex_H_tl,\g_@@_hex_A_tl,
+% \g_@@_hex_B_tl,\g_@@_hex_C_tl}
+% \cs{g_@@_hex_H_tl} is a bit special because, it is initially not
+% zero, but empty, so that slots in the lower plane are denoted by 4
+% hex digits.
+% We really only need three further variables, as the value in the
+% innermost loop can used directly.
+% \begin{macrocode}
+\tl_new:N \g_@@_hex_H_tl % higher plane
+\tl_new:N \g_@@_hex_A_tl
+\tl_new:N \g_@@_hex_B_tl
+\tl_new:N \g_@@_hex_C_tl
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\c_@@_hex_digits_clist}
+% Here is the sequence we loop through on each level, except the
+% one for the outer level.
+% \begin{macrocode}
+\clist_const:Nn\c_@@_hex_digits_clist{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_produce_table_rows:,\@@_handle_hex_H:n,
+% \@@_handle_hex_A:n,\@@_handle_hex_B:n,
+% \@@_handle_hex_C:n,\@@_handle_hex_D:n}
+% The overall code layout is then fairly simply:
+% \begin{macrocode}
+\cs_new:Npn \@@_produce_table_rows: {
+% \end{macrocode}
+% First to some general initialization
+% \begin{macrocode}
+ \@@_initialize_table_rows:
+% \end{macrocode}
+% and then loop we start the loop. The outer level is a bit special
+% as currently Unicode has only slots allocated in plane 0, 1, 2
+% and E (well, and F, but that is a private area) so we loop only
+% over those and instead of \texttt{0} we use an empty value.
+% Not covered is the whole of plane 16 which too is now a
+% private area.
+%
+% \begin{macrocode}
+ \clist_map_function:nN { { } , 1, 2, E, F } \@@_handle_hex_H:n }
+% \end{macrocode}
+%
+% Most fonts do not have glyphs in the higher planes, which is why
+% by default we don't loop using a nonempty \cs{@@_handle_hex_H:n}.
+% But if the user wants to scan and display the higher slots they
+% can by setting \key{range-end} appropriatly.
+%
+% So after setting \cs{@@_handle_hex_H:n} we loop over
+% \cs{c_@@_hex_digits_clist} for the next
+% hex digit (which we call \enquote{A}).
+% \begin{macrocode}
+\cs_new:Npn \@@_handle_hex_H:n #1 { \tl_gset:Nn\g_@@_hex_H_tl{#1}
+ \clist_map_function:NN \c_@@_hex_digits_clist \@@_handle_hex_A:n }
+% \end{macrocode}
+%
+% Handling \enquote{A} means storing its value for later use and
+% then start a loop for setting the second (or third on higher planes) hex digits:
+% \begin{macrocode}
+\cs_new:Npn \@@_handle_hex_A:n #1 { \tl_gset:Nn\g_@@_hex_A_tl{#1}
+ \clist_map_function:NN \c_@@_hex_digits_clist \@@_handle_hex_B:n }
+% \end{macrocode}
+%
+% Same game for \enquote{B} and \enquote{C}\footnote{Actually this
+% is a white lie. In reality we do a lot of extra stuff when
+% handling \enquote{C} so later one we give a second definition for
+% \cs{@@_handle_hex_C:n} but for understanding the overall picture
+% the simpler one shown here is better.}:
+% \begin{macrocode}
+\cs_new:Npn \@@_handle_hex_B:n #1 { \tl_gset:Nn\g_@@_hex_B_tl{#1}
+ \clist_map_function:NN \c_@@_hex_digits_clist \@@_handle_hex_C:n }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_handle_hex_C:n #1 { \tl_gset:Nn\g_@@_hex_C_tl{#1}
+ \clist_map_function:NN \c_@@_hex_digits_clist \@@_handle_hex_D:n }
+% \end{macrocode}
+% In the innermost loop we now have the full Unicode number
+% available, so there we have to decide what to do with it. This is
+% done by \cs{@@_handle_hex_D:n} that receives the full number,
+% e.g., \texttt{1A7C} or \texttt{1AD00}, as its argument.
+% \begin{macrocode}
+\cs_new:Npn \@@_handle_hex_D:n #1 {
+ \@@_handle_slot:x
+ { " \g_@@_hex_H_tl \g_@@_hex_A_tl
+ \g_@@_hex_B_tl \g_@@_hex_C_tl #1 }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\g_@@_row_tl}
+% We first collect the glyphs for a whole row before deciding to
+% typeset it, because if the row is entirely empty we want to omit
+% it. The data for the row is collected slot by slot and the typesetting
+% information (the glyph or the indication for a missing glyph is
+% appended to \cs{g_@@_row_tl}.
+% \begin{macrocode}
+\tl_new:N \g_@@_row_tl
+% \end{macrocode}
+% \end{macro}
+
+
+% \begin{macro}{\@@_handle_slot:n,\@@_handle_slot:x}
+% If the current slot number under inspection contains a glyph in
+% our font we want to typeset it. But we don't do this immediately,
+% instead we build up the whole row and typeset it later. We
+% therefore append a \verb=&= and the glyph (including the necessary
+% formatting) to the token list \cs{g_@@_row_tl}.
+% \begin{macrocode}
+\cs_new:Npn \@@_handle_slot:n #1 {
+ \@@_if_uchar_exists:nTF { #1 }
+ { \tl_gput_right:Nn \g_@@_row_tl
+ { & \@@_format_glyph:n { \symbol{#1} } }
+% \end{macrocode}
+% We then increment the overall glyph count and record that we have
+% seen at least one glyph in the current row. There is not much
+% point in displaying rows that are completely empty; indeed,
+% we'd end up with extremely large tables which are
+% mostly empty.
+% \begin{macrocode}
+ \int_gincr:N\g_@@_glyph_int
+ \bool_gset_true:N \g_@@_glyph_seen_bool
+% \end{macrocode}
+% If we do font comparison we also check if the glyph is in the
+% second font and if so record that fact.
+% \begin{macrocode}
+ \tl_if_empty:NF \l_@@_compare_font_tl
+ {
+ \group_begin:
+ \l_@@_compare_font_tl
+ \@@_if_uchar_exists:nT { #1 }
+ { \int_gincr:N \g_@@_glyph_also_B_int }
+ \group_end:
+ }
+ }
+% \end{macrocode}
+% If the current slot has no glyph in the font we also add a
+% \verb=&= followed by something that indicates the glyph is
+% missing. If we do font comparison, it may show the glyph from
+% the other font (if it exists there) in some special way to indicate which glyph
+% should be in this slot.
+% \begin{macrocode}
+ { \@@_handle_missing_glyph:n {#1} }
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \@@_handle_slot:n {x}
+% \end{macrocode}
+% \end{macro}
+%
+
+% \begin{macro}{\@@_handle_missing_glyph:n,
+% \@@_handle_missing_glyph_std:n,
+% \@@_handle_missing_glyph_compare:n}
+%
+% In the standard case we typeset a special symbol to indicate that the glyph is missing.
+% For this case we provide some customization through keys:
+% \cs{l_@@_missing_glyph_tl} holds the symbol for a missing glyph
+% (default: a hyphen). It is typeset in a specific color and we allow for
+% setting it in a special font. The actual symbol number in
+% \verb=#1= is not needed in this scenario.
+% \begin{macrocode}
+\cs_new:Npn \@@_handle_missing_glyph_std:n #1 {
+ \tl_gput_right:Nn \g_@@_row_tl
+ { &
+ \@@_format_glyph:n {
+% \colorbox{black!30} % <--- povide interface
+ {\l_@@_missing_glyph_color_tl
+ \l_@@_missing_glyph_font_tl
+ \l_@@_missing_glyph_tl }
+ }
+ }
+}
+% \end{macrocode}
+%
+% \keysetup{missing glyphs}
+% Here are the keys for customizing the missing glyph representation.
+% \begin{macrocode}
+\keys_define:nn {@@} {
+ missing-glyph-color .choice:
+ ,missing-glyph-color / none .code:n =
+ \tl_clear:N \l_@@_missing_glyph_color_tl
+ ,missing-glyph-color / unknown .code:n =
+ \tl_set:Nn \l_@@_missing_glyph_color_tl { \color {#1} }
+%
+ ,missing-glyph-font .tl_set:N = \l_@@_missing_glyph_font_tl
+ ,missing-glyph-font .initial:n = \ttfamily \scriptsize
+ ,missing-glyph .tl_set:N = \l_@@_missing_glyph_tl
+ ,missing-glyph .initial:n = - }
+% \end{macrocode}
+%
+%
+% The default definition for the color is to use the same as the
+% one specified by the \key{color} key. We therefore define the
+% default outside of the \pkg{l3keys} method.
+% \begin{macrocode}
+\tl_new:N \l_@@_missing_glyph_color_tl
+\tl_set:Nn \l_@@_missing_glyph_color_tl {\l_@@_color_tl}
+% \end{macrocode}
+%
+% This is the version that handles a missing glyph by checking
+% the \key{compare-with} font to see if that font contains the
+% glyph.
+% If yes, the substitute glyph will be typeset, otherwise the missing
+% glyph symbol is shown by calling \cs{@@_handle_missing_glyph_std:n}.
+% \begin{macrocode}
+\cs_new:Npn \@@_handle_missing_glyph_compare:n #1 {
+ \group_begin:
+% \end{macrocode}
+% Locally switch to the other font, then check for the glyph:
+% \begin{macrocode}
+ \l_@@_compare_font_tl
+ \@@_if_uchar_exists:nTF { #1 }
+ {
+% \end{macrocode}
+% If available, format it (together with the \texttt{\&}) but use a
+% special color and perhaps a background color.
+% \begin{macrocode}
+ \tl_gput_right:Nn \g_@@_row_tl
+ { &
+ \@@_format_glyph:n
+ { \l_@@_compare_bgcolor_tl { \l_@@_compare_color_tl
+ \l_@@_compare_font_tl
+ \symbol {#1} }
+ }
+ }
+% \end{macrocode}
+% Having seen a glyph only in the second font we record this fact.
+% \begin{macrocode}
+ \int_gincr:N \g_@@_glyph_only_B_int
+% \end{macrocode}
+% Also tell the algorithm that we have seen a glyph to typeset. If
+% we don't do this then a row consisting of only substitute glyphs is not
+% typeset. However, we don't update the glyph count, because this
+% is not a glyph from the main font we display.
+% \begin{macrocode}
+ \bool_gset_true:N \g_@@_glyph_seen_bool
+ }
+% \end{macrocode}
+% If the alternate font doesn't have the glyph either we
+% typeset the missing glyph symbol.
+% \begin{macrocode}
+ { \@@_handle_missing_glyph_std:n {} }
+ \group_end:
+}
+% \end{macrocode}
+%
+% \keysetup{comparison}
+%
+% In order to display glyphs from a secondary font we need a
+% secondary color for the glyph itself and possibly some background color.
+% \begin{macrocode}
+\tl_new:N \l_@@_compare_with_tl
+\tl_new:N \l_@@_compare_color_tl
+\tl_new:N \l_@@_compare_bgcolor_tl
+% \end{macrocode}
+%
+% \begin{macrocode}
+\keys_define:nn {@@}
+ {
+ ,compare-with .tl_set:N = \l_@@_compare_with_tl
+ ,compare-with .initial:n =
+ ,compare-color .choice:
+ ,compare-color / none .code:n
+ = \tl_clear:N \l_@@_compare_color_tl
+ ,compare-color / unknown .code:n
+ = \tl_set:Nn \l_@@_compare_color_tl { \color {#1} }
+ ,compare-color .initial:n = red
+ ,compare-bgcolor .choice:
+ ,compare-bgcolor / none .code:n
+ = \tl_clear:N \l_@@_compare_bgcolor_tl
+ ,compare-bgcolor / unknown .code:n
+ = \tl_set:Nn \l_@@_compare_bgcolor_tl { \colorbox {#1} }
+ ,compare-bgcolor .initial:n = black!10
+% \end{macrocode}
+% If we run a comparison we show different statistics that have
+% their own key.
+% \begin{macrocode}
+ ,statistics-compare-format .cs_set:Np
+ = \@@_format_compare_stats:nnnnnn #1#2#3#4#5#6
+ ,statistics-compare-format .initial:n
+ = \parbox{\linewidth}{
+ Total~ number~ of~ glyphs~ in~ \texttt{#1}:~#2\\
+ Comparison~ font~ \texttt{#3}~ has~ #5~ missing~ and~ #6~
+ extra~ glyphs}
+ }
+% \end{macrocode}
+%
+%
+% By default, i.e., if no font for comparison has been specified, we
+% handle missing glyphs by displaying a missing glyph symbol.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_handle_missing_glyph:n
+ \@@_handle_missing_glyph_std:n
+% \end{macrocode}
+% \end{macro}
+%
+
+
+% \begin{macro}{\@@_format_glyph:n}
+% Every glyph is typeset in a box of equal width with the glyph
+% centered and if necessary protruding on both sides.
+% \begin{macrocode}
+\cs_new:Npn \@@_format_glyph:n #1 {
+ \hbox_to_wd:nn {\l_@@_glyph_box_dim} { \hss #1 \hss } }
+% \end{macrocode}
+%
+% \keysetup{glyph typesetting}
+% The key to customize the width. The 6pt are fine for most cases.
+% \begin{macrocode}
+\dim_new:N\l_@@_glyph_box_dim
+% \end{macrocode}
+%
+% \begin{macrocode}
+\keys_define:nn {@@} {
+ glyph-width .dim_set:N = \l_@@_glyph_box_dim
+ ,glyph-width .initial:n = 6pt
+}
+% \end{macrocode}
+% \end{macro}
+
+
+% \begin{macro}{\@@_if_uchar_exists:n}
+% For testing whether or not a slot position contains a glyph we
+% need to resort to low-level methods, because so far
+% \texttt{expl3} doesn't offer an interface.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \@@_if_uchar_exists:n #1 { TF , T }
+ { \tex_iffontchar:D \tex_font:D #1 \scan_stop:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \subsection{Handling a single row}
+%
+%
+% \begin{macro}{\@@_handle_hex_C:n}
+% As promised here is the read definition for
+% \cs{@@_handle_hex_C:n} in all its glory.
+% \begin{macrocode}
+\cs_set:Npn \@@_handle_hex_C:n #1 {
+% \end{macrocode}
+% We are now at the start of a new row (but with the last row not
+% yet typeset) and this last row may need a Unicode block heading
+% before it. This is the reason why we have to delay the
+% typesetting, because in case the line doesn't contain any glyphs
+% we want to typeset neither and that is only known after all
+% slots in the row have been processed.
+% \begin{macrocode}
+ \@@_maybe_typeset_a_row_and_display_a_block_title:
+% \end{macrocode}
+% We then store away the value for the third hex digit (denoted as
+% C) in order to start with the next row.
+% \begin{macrocode}
+ \tl_gset:Nn\g_@@_hex_C_tl{#1}
+% \end{macrocode}
+% Being at the start of a new row we might be at the start of a new
+% Unicode block. If so we have to update the block title to add in
+% front of the row when we typeset it (or in front of one of the
+% next rows if the first rows in the is block have no glyphs). If
+% we are still in the same block no update happens.
+% \begin{macrocode}
+ \@@_update_block_title:n { \g_@@_hex_H_tl
+ \g_@@_hex_A_tl
+ \g_@@_hex_B_tl
+ \g_@@_hex_C_tl }
+% \end{macrocode}
+% We now check if this row is within the requested range, i.e.,
+% greater than or equal to \cs{l_@@_range_start_tl} and not greater than
+% \cs{l_@@_range_end_tl}.
+% \begin{macrocode}
+ \int_compare:nNnF
+ { " \g_@@_hex_H_tl \g_@@_hex_A_tl
+ \g_@@_hex_B_tl \g_@@_hex_C_tl 0 }
+ < { "\l_@@_range_start_tl }
+ {
+ \int_compare:nNnTF
+ { " \g_@@_hex_H_tl \g_@@_hex_A_tl
+ \g_@@_hex_B_tl \g_@@_hex_C_tl 0 }
+ > { "\l_@@_range_end_tl }
+% \end{macrocode}
+% If we are past the \texttt{end-range} we break out the clist
+% mapping, to avoind unnecessary repetition. This should be
+% propagated back to the outer clists as well (not done).
+% \begin{macrocode}
+ { \clist_map_break: }
+% \end{macrocode}
+% If we are within range we process the slots in the row by first
+% initializing \cs{g_@@_row_tl} with the row title (the info on the
+% left) and then loop through all slots the row to append glyphs
+% (or missing glyphs) to \cs{g_@@_row_tl} to build up everything we
+% need to finally typeset it.
+% \begin{macrocode}
+ {
+ \tl_gset:Nx \g_@@_row_tl
+ {
+ \exp_not:N \@@_format_row_title:n
+ { \g_@@_hex_H_tl \g_@@_hex_A_tl
+ \g_@@_hex_B_tl \g_@@_hex_C_tl }
+ }
+ \clist_map_function:NN \c_@@_hex_digits_clist
+ \@@_handle_hex_D:n
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_format_row_title:n}
+% The function to format the row title on the left, as used above.
+% \begin{macrocode}
+\cs_new:Npn \@@_format_row_title:n #1 {
+ \texttt { \footnotesize \l_@@_color_tl U+#1 0 \, - \, #1 F }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \keysetup{ranges}
+%
+% For the range we have two keys, its start and the end. By default the
+% whole range from 0 to FFFF is processed.
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_range_start_tl
+\tl_new:N \l_@@_range_end_tl
+% \end{macrocode}
+%
+% \begin{macrocode}
+\keys_define:nn {@@}
+ {
+ ,range-start .tl_set:N = \l_@@_range_start_tl
+ ,range-start .initial:n = 0000
+ ,range-end .tl_set:N = \l_@@_range_end_tl
+ ,range-end .initial:n = FFFF
+ }
+% \end{macrocode}
+%
+%
+%
+%
+%
+% \begin{macro}{\@@_maybe_typeset_a_row_and_display_a_block_title:}
+% The function handles the just-finished row and, if the row does not
+% consist only of missing glyphs, typesets it. If necessary it also typesets
+% a Unicode block name first.
+% \begin{macrocode}
+\cs_new:Npn \@@_maybe_typeset_a_row_and_display_a_block_title: {
+% \end{macrocode}
+% We first check if the row had any real glyphs.
+% \begin{macrocode}
+ \bool_if:NTF \g_@@_glyph_seen_bool
+ {
+% \end{macrocode}
+% If the row needs typesetting the fun part starts. We first look
+% at the content of \cs{g_@@_block_title_tl}.
+% \begin{macrocode}
+ \tl_if_empty:NTF \g_@@_block_title_tl
+ {
+% \end{macrocode}
+% It is empty we are in the middle of a block and we can ignore
+% the Unicode title. However, we have to see if the previous row
+% (or several) was missing (i.e., contained no glyphs). In that
+% case we leave a little extra space, otherwise we just finish the
+% previous row
+% \begin{macrocode}
+ \bool_if:NTF \g_@@_row_missing_bool
+ { \@@_debug_nl:n{A}\\[6pt] }
+ { \@@_debug_nl:n{B}\\ }
+ }
+ {
+% \end{macrocode}
+% Otherwise we first have to typeset the Unicode block title (or
+% whatever should happen instead).
+% \begin{macrocode}
+ \typeout{ Processing~ \tl_use:N \g_@@_block_title_tl }
+ \bool_if:NTF \l_@@_display_block_bool
+ {
+% \end{macrocode}
+% If we are to typeset the title the action depends a bit on
+% whether we are at the very first row or typesetting a later block.
+% \begin{macrocode}
+ \bool_if:NTF \g_@@_first_row_bool
+ {
+ \bool_gset_false:N \g_@@_first_row_bool
+ \@@_debug_nl:n{C}\\[-4pt]
+ }
+ {
+ \@@_debug_nl:n{D}\\[8pt]
+ \noalign{\vskip 1pt plus 1pt} % space above block: customizable?
+ }
+% \noalign{\smallskip} % space above block: customizable?
+ \multicolumn{17}{c}{\normalfont \bfseries
+ \tl_use:N \g_@@_block_title_tl}
+% \end{macrocode}
+% After the block title is typeset we may want to add a row of hex
+% digits as well if that was requested, otherwise we only leave a
+% bit of extra space.
+% \begin{macrocode}
+ \bool_if:NTF \l_@@_blockwise_hex_digits_bool
+ { \@@_debug_nl:n{E}\\*
+ \@@_display_row_of_hex_digits:
+ \@@_debug_nl:n{H}\\*[2pt]
+ }
+ { \@@_debug_nl:n{F}\\*[2pt] }
+ }
+ {
+% \end{macrocode}
+% If the Unicode block title is not typeset we may still have to do
+% someting special and again it differs if we at the very beginning
+% of the table (because there we do nothing except changing the
+% state of \cs{g_@@_first_row_bool}).
+% \begin{macrocode}
+ \bool_if:NTF \g_@@_first_row_bool
+ { \bool_gset_false:N \g_@@_first_row_bool }
+ {
+ \@@_debug_nl:n{G~ (new~ block)}
+ \l_@@_display_block_action_tl
+ }
+ }
+% \end{macrocode}
+% Once we are past the block title we clear it, so that it is not
+% retypeset before the next row.
+% \begin{macrocode}
+ \tl_gclear:N \g_@@_block_title_tl
+ }
+% \end{macrocode}
+% The final action is to typeset the row and reset the booleans (in
+% case they were true; if they are false already then we do this
+% unnecessarily, but that is probably faster than testing first).
+% \begin{macrocode}
+ \bool_gset_false:N \g_@@_glyph_seen_bool
+ \bool_gset_false:N \g_@@_row_missing_bool
+ \tl_use:N \g_@@_row_tl
+ }
+% \end{macrocode}
+% Current row had no glyphs; remember that fact, and that is all we
+% have to do in that case.
+% \begin{macrocode}
+ {
+ \bool_gset_true:N \g_@@_row_missing_bool
+ }
+}
+% \end{macrocode}
+% \end{macro}
+
+%
+%
+% \subsection{Initialisation at the start of the table}
+%
+%
+% \begin{macro}{\g_@@_first_row_bool,\g_@@_glyph_seen_bool,\g_@@_row_missing_bool}
+% Declare the three booleans used in the code below. They will tell
+% us answers to the following questions:
+% \begin{itemize}
+% \item Are we processing the first row?
+% \item Have we seen any glyph so far (in the current row)?
+% \item Did we have one or more missing rows recently?
+% \end{itemize}
+% \begin{macrocode}
+\bool_new:N \g_@@_first_row_bool
+\bool_new:N \g_@@_glyph_seen_bool
+\bool_new:N \g_@@_row_missing_bool
+% \end{macrocode}
+% \end{macro}
+
+
+
+
+
+
+% \begin{macro}{\@@_initialize_table_rows:}
+% At the start of a table we are processing the first row
+% and so we (obviously) haven't seen a glyph yet and there wasn't a
+% missing row recently.
+% \begin{macrocode}
+\cs_new:Npn \@@_initialize_table_rows: {
+ \bool_gset_true:N \g_@@_first_row_bool
+ \bool_gset_false:N \g_@@_glyph_seen_bool
+ \bool_gset_false:N \g_@@_row_missing_bool
+% \end{macrocode}
+% And clearly the glyph count for the font(s) is zero.
+% \begin{macrocode}
+ \int_gzero:N \g_@@_glyph_int
+ \int_gzero:N \g_@@_glyph_only_B_int
+ \int_gzero:N \g_@@_glyph_also_B_int
+}
+% \end{macrocode}
+% \end{macro}
+
+
+%
+%
+% \subsection{Handling block titles}
+%
+% \begin{macro}{g_@@_block_title_tl}
+% We keep the current block title in this token list.
+% \begin{macrocode}
+\tl_new:N \g_@@_block_title_tl
+% \end{macrocode}
+% \end{macro}
+
+
+% \begin{macro}{\@@_update_block_title:n}
+% A block title is updated when the hex digits A,B,C have a certain
+% value, so this is nothing more than a huge case switch.
+% \begin{macrocode}
+\cs_new:Npn \@@_update_block_title:n #1 {
+ \tl_gset:Nx \g_@@_block_title_tl {
+ \int_case:nnF{ "#1 }
+ {
+ { "000 }{ Basic~ Latin }
+ { "008 }{ Latin-1~ Supplement }
+ { "010 }{ Latin~ Extended-A }
+ { "018 }{ Latin~ Extended-B }
+ { "025 }{ IPA~ Extensions }
+ { "02B }{ Spacing~ Modifier~ Letters }
+ { "030 }{ Combining~ Diacritical~ Marks }
+ { "037 }{ Greek~ and~ Coptic }
+ { "040 }{ Cyrillic }
+ { "053 }{ Armenian }
+ { "059 }{ Hebrew }
+ { "060 }{ Arabic }
+ { "070 }{ Syriac }
+ { "075 }{ Arabic~ Supplement }
+ { "078 }{ Thaana }
+ { "07C }{ NKo }
+ { "090 }{ Devanagari }
+ { "098 }{ Bengali }
+ { "0A0 }{ Gurmukhi }
+ { "0A8 }{ Gujarati }
+ { "0B0 }{ Oriya }
+ { "0B8 }{ Tamil }
+ { "0C0 }{ Telugu }
+ { "0C8 }{ Kannada }
+ { "0D0 }{ Malayalm }
+ { "0D8 }{ Sinhala }
+ { "0E0 }{ Thai }
+ { "0E8 }{ Lao }
+ { "0F0 }{ Tibetan }
+ { "100 }{ Myanmar }
+ { "10A }{ Georgian }
+ { "110 }{ Hangul~ Jamo }
+ { "120 }{ Ethiopic }
+ { "138 }{ Ethiopic~ Supplement }
+ { "13A }{ Cherokee }
+ { "140 }{ Unified~ Canadian~ Aboriginal~ Syllabics }
+ { "168 }{ Ogham }
+ { "16A }{ Runic }
+ { "170 }{ Tagalog }
+ { "172 }{ Hanunoo }
+ { "174 }{ Buhid }
+ { "176 }{ Tagbanwa }
+ { "178 }{ Khmer }
+ { "180 }{ Mongolian }
+ { "190 }{ Limbu }
+ { "195 }{ Tai~ Le }
+ { "198 }{ New~ Tai~ Le }
+ { "19E }{ Khmer~ Symbols }
+ { "1A0 }{ Buginese }
+ { "1B0 }{ Balinese }
+ { "1D0 }{ Phonetic~ Extensions }
+ { "1D8 }{ Phonetic~ Extensions~ Supplement }
+ { "1DC }{ Combining~ Diacritical~ Marks~ Supplement }
+ { "1E0 }{ Latin~ Extended~ Additional }
+ { "1F0 }{ Greek~ Extended }
+ { "200 }{ General~ Punctuation }
+ { "207 }{ Superscripts~ and~ Subscripts }
+ { "20A }{ Currency~ Symbols }
+ { "20D }{ Combining~ Diacritical~ Marks~ for~ Symbols }
+ { "210 }{ Letterlike~ Symbols }
+ { "215 }{ Number~ Forms }
+ { "219 }{ Arrows }
+ { "220 }{ Mathematical~ Operators }
+ { "230 }{ Miscellaneous~ Technical }
+ { "240 }{ Control~ Pictures }
+ { "244 }{ Optical~ Character~ Recognition }
+ { "246 }{ Enclosed~ Alphanumerics }
+ { "250 }{ Box~ Drawing }
+ { "258 }{ Block~ Elements }
+ { "25A }{ Geometric~ Shapes }
+ { "260 }{ Miscellaneous~ Shapes }
+ { "270 }{ Dingbats }
+ { "27C }{ Miscellaneous~ Mathematical~ Symbols-A }
+ { "27F }{ Supplemental~ Arrows-A }
+ { "280 }{ Braille~ Patterns }
+ { "290 }{ Supplemental~ Arrows-B }
+ { "298 }{ Miscellaneous~ Mathematical~ Symbols-B }
+ { "2A0 }{ Supplemental~ Mathematical~ Operators }
+ { "2B0 }{ Miscellaneous~ Symbols~ and~ Arrows }
+ { "2C0 }{ Glagolitic }
+ { "2C6 }{ Latin~ Extended-C }
+ { "2C8 }{ Coptic }
+ { "2D0 }{ Georgian~ Supplement }
+ { "2D3 }{ Tifinagh }
+ { "2D8 }{ Ethiopic~ Extended }
+ { "2E0 }{ Supplemental~ Punctuation }
+ { "2E8 }{ CJK~ Radicals~ Supplement }
+ { "2F0 }{ Kangxi~ Radicals }
+ { "2FF }{ Ideographic~ Description~ Characters }
+ { "300 }{ CJK~ Symbols~ and~ Punctuation }
+ { "304 }{ Hiragana }
+ { "30A }{ Katakana }
+ { "310 }{ Bopomofo }
+ { "313 }{ Hangul~ Compatibility~ Jamo }
+ { "319 }{ Kanbun }
+ { "31A }{ Bopomofo~ Extended }
+ { "31C }{ CJK~ Strokes }
+ { "31F }{ Katakana~ Phonetic~ Extensions }
+ { "320 }{ Enclosed~ CJK~ Letters~ and~ Months }
+ { "330 }{ CJK~ Compatibility }
+ { "4DC }{ Yijing~ Hexagram~ Symbols }
+ { "A00 }{ Yi~ Syllables }
+ { "A49 }{ Yi~ Radicals }
+ { "A70 }{ Modifier~ Tone~ Letters }
+ { "A72 }{ Latin~ Extended-D }
+ { "A80 }{ Syloti~ Nagri }
+ { "A84 }{ Phags-pa }
+ { "A88 }{ Saurashtra }
+ { "A8E }{ Devanagari Extended }
+ { "A90 }{ Kayah Li }
+ { "A93 }{ Rejang }
+ { "A96 }{ Hangul Jamo Extended-A }
+ { "A98 }{ Javanese }
+ { "A9E }{ Myanmar Extended-B }
+ { "AA0 }{ Cham }
+ { "AA6 }{ Myanmar Extended-A }
+ { "AA8 }{ Tai Viet }
+ { "AAE }{ Meetei Mayek Extensions }
+ { "AB0 }{ Ethiopic Extended-A }
+ { "AB3 }{ Latin Extended-E }
+ { "AB7 }{ Cherokee Supplement }
+ { "ABC }{ Meetei Mayek }
+ { "AC0 }{ Hangul Syllables }
+ { "D7B }{ Hangul Jamo Extended-B }
+ { "D80 }{ High Surrogates }
+ { "DB8 }{ High Private Use Surrogates }
+ { "DC0 }{ Low Surrogates }
+ { "E00 }{ Private~ Use~ Area }
+ { "F90 }{ CJK~ Compatibility~ Ideographs }
+ { "FB0 }{ Alphabetic~ Presentation~ Forms }
+ { "FB5 }{ Arabic~ Presentation~ Forms-A }
+ { "FE0 }{ Variation~ Selectors }
+ { "FE1 }{ Vertical~ Forms }
+ { "FE2 }{ Combining~ Half~ Marks }
+ { "FE3 }{ CJK~ Compatibility~ Forms }
+ { "FE5 }{ Small~ Form~ Variants }
+ { "FE7 }{ Arabic~ Presentation~ Forms-B }
+ { "FF0 }{ Halfwidth~ and Fullwidth~ Forms }
+ { "FFF }{ Specials~ ... }
+%% ... Plane 1 ...
+ { "1000 }{ Linear~ B~ Syllabary }
+ { "1008 }{ Linear~ B~ Ideograms }
+ { "1010 }{ Aegean~ Numbers }
+ { "1014 }{ Ancient~ Greek~ Numbers }
+ { "1019 }{ Ancient~ Symbols }
+ { "101D }{ Phaistos~ Disc }
+ { "1028 }{ Lycian }
+ { "102A }{ Carian }
+ { "102E }{ Coptic~ Epact~ Numbers }
+ { "1030 }{ Old~ Italic }
+ { "1033 }{ Gothic }
+ { "1035 }{ Old~ Permic }
+ { "1038 }{ Ugaritic }
+ { "103A }{ Old~ Persian }
+ { "1040 }{ Deseret }
+ { "1045 }{ Shavian }
+ { "1048 }{ Osmanya }
+ { "104B }{ Osage }
+ { "1050 }{ Elbasan }
+ { "1053 }{ Caucasian~ Albanian }
+ { "1060 }{ Linear~ A }
+ { "1080 }{ Cypriot~ Syllabary }
+ { "1084 }{ Imperial~ Aramaic }
+ { "1086 }{ Palmyrene }
+ { "1088 }{ Nabataean }
+ { "108E }{ Hatran }
+ { "1090 }{ Phoenician }
+ { "1092 }{ Lydian }
+ { "1098 }{ Meroitic~ Hieroglyphs }
+ { "109A }{ Meroitic~ Cursive }
+ { "10A0 }{ Kharoshthi }
+ { "10A6 }{ Old~ South~ Arabian }
+ { "10A8 }{ Old~ North~ Arabian }
+ { "10AC }{ Manichaean }
+ { "10B0 }{ Avestan }
+ { "10B4 }{ Inscriptional~ Parthian }
+ { "10B6 }{ Inscriptional~ Pahlavi }
+ { "10B8 }{ Psalter~ Pahlavi }
+ { "10C0 }{ Old~ Turkic }
+ { "10C8 }{ Old~ Hungarian }
+ { "10E6 }{ Rumi~ Numeral~ Symbols }
+ { "1100 }{ Brahmi }
+ { "1108 }{ Kaithi }
+ { "110D }{ Sora~ Sompeng }
+ { "1110 }{ Chakma }
+ { "1115 }{ Mahajani }
+ { "1118 }{ Sharada }
+ { "111E }{ Sinhala~ Archaic~ Numbers }
+ { "1120 }{ Khojki }
+ { "1128 }{ Multani }
+ { "112B }{ Khudawadi }
+ { "1130 }{ Grantha }
+ { "1140 }{ Newa }
+ { "1148 }{ Tirhuta }
+ { "1158 }{ Siddham }
+ { "1160 }{ Modi }
+ { "1166 }{ Mongolian~ Supplement }
+ { "1168 }{ Takri }
+ { "1170 }{ Ahom }
+ { "118A }{ Warang~ Citi }
+ { "11A0 }{ Zanabazar~ Square }
+ { "11A5 }{ Soyombo }
+ { "11AC }{ Pau~ Cin~ Hau }
+ { "11C0 }{ Bhaiksuki }
+ { "11C7 }{ Marchen }
+ { "11D0 }{ Masaram~ Gondi }
+ { "1200 }{ Cuneiform }
+ { "1240 }{ Cuneiform~ Numbers~ and~ Punctuation }
+ { "1248 }{ Early~ Dynastic~ Cuneiform }
+ { "1300 }{ Egyptian~ Hieroglyphs }
+ { "1440 }{ Anatolian~ Hieroglyphs }
+ { "1680 }{ Bamum~ Supplement }
+ { "16A4 }{ Mro }
+ { "16AD }{ Bassa~ Vah }
+ { "16B0 }{ Pahawh~ Hmong }
+ { "16F0 }{ Miao }
+ { "16FE }{ Ideographic~ Symbols~ and~ Punctuation }
+ { "1700 }{ Tangut }
+ { "1880 }{ Tangut~ Components }
+ { "1B00 }{ Kana~ Supplement }
+ { "1B10 }{ Kana~ Extended-A }
+ { "1B17 }{ Nushu }
+ { "1BC0 }{ Duployan }
+ { "1BCA }{ Shorthand~ Format~ Controls }
+ { "1D00 }{ Byzantine~ Musical~ Symbols }
+ { "1D10 }{ Musical~ Symbols }
+ { "1D20 }{ Ancient~ Greek~ Musical~ Notation }
+ { "1D30 }{ Tai~ Xuan~ Jing~ Symbols }
+ { "1D36 }{ Counting~ Rod~ Numerals }
+ { "1D40 }{ Mathematical~ Alphanumeric~ Symbols }
+ { "1D80 }{ Sutton~ SignWriting }
+ { "1E00 }{ Glagolitic~ Supplement }
+ { "1E80 }{ Mende~ Kikakui }
+ { "1E90 }{ Adlam }
+ { "1EE0 }{ Arabic~ Mathematical~ Alphabetic~ Symbols }
+ { "1F00 }{ Mahjong~ Tiles }
+ { "1F03 }{ Domino~ Tiles }
+ { "1F0A }{ Playing~ Cards }
+ { "1F10 }{ Enclosed~ Alphanumeric~ Supplement }
+ { "1F20 }{ Enclosed~ Ideographic~ Supplement }
+ { "1F30 }{ Miscellaneous~ Symbols~ and~ Pictographs }
+ { "1F60 }{ Emoticons }
+ { "1F65 }{ Ornamental~ Dingbats }
+ { "1F68 }{ Transport~ and~ Map~ Symbols }
+ { "1F70 }{ Alchemical~ Symbols }
+ { "1F78 }{ Geometric~ Shapes~ Extended }
+ { "1F80 }{ Supplemental~ Arrows-C }
+ { "1F90 }{ Supplemental~ Symbols~ and~ Pictographs }
+ { "2000 }{ CJK~ Unified~ Ideographs~ Extension~ B }
+ { "2A70 }{ CJK~ Unified~ Ideographs~ Extension~ C }
+ { "2B74 }{ CJK~ Unified~ Ideographs~ Extension~ D }
+ { "2B82 }{ CJK~ Unified~ Ideographs~ Extension~ E }
+ { "2CEB }{ CJK~ Unified~ Ideographs~ Extension~ F }
+ { "2F80 }{ CJK~ Compatibility~ Ideographs~ Supplement }
+ { "E010 }{ Tags }
+ { "E000 }{ Variation~ Selectors~ Supplement }
+ { "F000 }{ Supplementary~ Private~ Use~ Area-A }
+% higher up not covered!
+ }
+% \end{macrocode}
+% If none of the above has matched we are somewhere within a block
+% so we want keep the current name. However, since the case
+% statement was executed within a |\tl_gset:Nx| we have to do this
+% by passing the current block name back.
+% \begin{macrocode}
+ { \tl_use:N \g_@@_block_title_tl }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \keysetup{display blocks}
+%
+% The Unicode blocks may get indicated in different ways: with titles,
+% only through rules, or not at all. Here is the necessary setup.
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_display_block_bool
+\tl_new:N \l_@@_display_block_action_tl
+% \end{macrocode}
+%
+% \begin{macrocode}
+\keys_define:nn {@@}
+ {
+ ,display-block .choice:
+ ,display-block / titles .code:n =
+ \bool_set_true:N \l_@@_display_block_bool
+ \tl_set:Nn \l_@@_display_block_action_tl {\\}
+ ,display-block / rules .code:n =
+ \bool_set_false:N \l_@@_display_block_bool
+ \tl_set:Nn \l_@@_display_block_action_tl {\\ \midrule}
+ ,display-block / none .code:n =
+ \bool_set_false:N \l_@@_display_block_bool
+ \tl_set:Nn \l_@@_display_block_action_tl {\\}
+ ,display-block .initial:n = titles
+ }
+% \end{macrocode}
+%
+%
+% That's all of the programming using the L3 layer.
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+% What remains is to require all packages needed \ldots
+% \begin{macrocode}
+\RequirePackage{longtable,booktabs,caption,fontspec}
+% \end{macrocode}
+% \ldots and executing all options passed to the
+% package via \cs{usepackage}.
+% \begin{macrocode}
+\ProcessKeysPackageOptions{@@}
+%</package>
+% \end{macrocode}
+%
+%
+%
+%
+%
+% \section{The standalone \texttt{unicodefont.tex} file}
+%
+% \begin{macrocode}
+%<*standalone>
+\documentclass{article}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\setlength\textwidth{470pt}
+\setlength\oddsidemargin{0pt}
+\addtolength\textheight{7\baselineskip}
+\addtolength\topmargin{-3\baselineskip}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\usepackage{unicodefonttable}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\DEFAULTfontname{Latin Modern Roman}
+\def\DEFAULTfontfeatures{}
+\def\DEFAULTtableconfig{}
+\def\DEFAULTunicodefont{}
+\begin{document}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\typeout{^^J}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ifx\generatetable\undefined
+\else
+ \typein[\answer]{^^JReuse settings from last time (default yes)?^^J^^J%
+ [ font name = \DEFAULTfontname^^J
+ \space unicode? = \ifx\DEFAULTunicodefont\empty yes^^J
+ \space font features = \DEFAULTfontfeatures
+ \else no\fi^^J
+ \space table config = \DEFAULTtableconfig \space]}
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ifx\answer\empty
+ \let\FontNameToTable\DEFAULTfontname
+ \let\IsUnicodeFont\DEFAULTunicodefont
+ \let\FontFeaturesToApply\DEFAULTfontfeatures
+ \let\TableConfigurationToApply\DEFAULTtableconfig
+\else
+% \end{macrocode}
+%
+% \begin{macrocode}
+\typein[\FontNameToTable]%
+ {^^JInput external font name as understood by fontspec, e.g.,^^J%
+ 'TeX Gyre Pagella' or 'lmroman10-regular.otf'%
+ \ifx\DEFAULTfontname\empty\else
+ ^^J^^J[default \DEFAULTfontname]\fi:}
+\ifx\FontNameToTable\empty \let\FontNameToTable\DEFAULTfontname \fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\typein[\IsUnicodeFont]%
+ {^^JIs this a Unicode font?^^J^^J%
+ \ifx\DEFAULTunicodefont\empty [default yes]\else [default no]\fi:}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ifx\IsUnicodeFont\empty
+% \ifx\DEFAULTunicodefont\empty
+% \else
+ \let\IsUnicodeFont\DEFAULTunicodefont
+% \fi
+\else
+ \ifx\DEFAULTunicodefont\empty
+ \else
+ \let\IsUnicodeFont\empty
+ \fi
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ifx\IsUnicodeFont\empty
+ \typein[\FontFeaturesToApply]%
+ {^^JInput font feature key/value list to apply%
+ \ifx\DEFAULTfontfeatures\empty\else
+ ^^J^^J[default \DEFAULTfontfeatures]\fi:}
+ \ifx\FontFeaturesToApply\empty \let\FontFeaturesToApply\DEFAULTfontfeatures \fi
+\else
+ \let\FontFeaturesToApply\DEFAULTfontfeatures
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\typein[\TableConfigurationToApply]%
+ {^^JInput table configuration key/value list to apply%
+ \ifx\DEFAULTtableconfig\empty\else
+ ^^J^^J[default
+ \expandafter\detokenize\expandafter{\DEFAULTtableconfig}]\fi:}
+\ifx\TableConfigurationToApply\empty
+ \let\TableConfigurationToApply\DEFAULTtableconfig
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\edef\generatetable{\noexpand\displayfonttable
+ \ifx\IsUnicodeFont\empty\else *\fi
+ \ifx\TableConfigurationToApply\empty\else
+ [\expandafter\unexpanded\expandafter{\TableConfigurationToApply}]\fi
+ {\FontNameToTable}%
+ \ifx\FontFeaturesToApply\empty\else[\FontFeaturesToApply]\fi
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\makeatletter
+\protected@write\@auxout{}{\gdef\string\generatetable
+ {\expandafter\detokenize\expandafter{\generatetable}}}
+\protected@write\@auxout{}{\gdef\string\DEFAULTfontname{\FontNameToTable}}
+\protected@write\@auxout{}{\gdef\string\DEFAULTunicodefont{\IsUnicodeFont}}
+\protected@write\@auxout{}{\gdef\string\DEFAULTfontfeatures{\FontFeaturesToApply}}
+\protected@write\@auxout{}{\gdef\string\DEFAULTtableconfig
+ {\expandafter\detokenize\expandafter{\TableConfigurationToApply}}}
+\makeatother
+% \end{macrocode}
+%
+% \begin{macrocode}
+\generatetable
+\end{document}
+%</standalone>
+% \end{macrocode}
+%
+%
+%
+% \section{A samples file}
+%
+% \begin{macrocode}
+%<*samples>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<<VERBATIMLINE
+%!TEX program = lualatex
+
+%VERBATIMLINE
+% \end{macrocode}
+%
+% \begin{macrocode}
+\documentclass{article}
+
+\usepackage{xparse,color}
+
+\usepackage{fontspec}
+
+\setmainfont{Linux Biolinum O}
+\setmonofont{SourceCodePro}
+
+\usepackage{unicodefonttable}
+
+\addtolength\textwidth{30pt}
+
+\begin{document}
+
+\listoftables
+
+\section{Computer Modern --- 8bit font}
+
+\displayfonttable*[color=none,
+ range-end = 7F,
+]{cmr10}
+
+%\section{Computer Modern Sans --- 8bit font} \displayfonttable*[]{cmss10}
+
+\newpage
+
+\section{TeX Gyre Heros (Helvetica) --- 8bit font}
+
+\displayfonttable*[color=red,nostatistics=false,
+ hex-digits = head+foot,
+ range-end = FF,
+]{ec-qhvr}
+
+\newpage
+
+\section{Latin Modern Sans --- OTF font}
+
+\displayfonttable[
+% display-block = rules,
+ % missing-glyph = \tiny\setlength\fboxsep{0pt}\fbox{$\times$},
+ hex-digits = block,
+ title-cont-format = \caption[]{\emph{continued}},
+]{Latin Modern Sans}
+
+\newpage
+
+\section{\TeX{} Gyre Pagella (Palatino) oldstyle figures --- OTF font}
+
+\displayfonttable{TeX Gyre Pagella}[Numbers=OldStyle]
+
+\newpage
+
+\section{Comparing Latin Modern Math with New Computer Modern Math}
+
+\displayfonttable[compare-with=NewCMMath-Regular.otf, range-end=1FFFF]
+ {latinmodern-math.otf}
+
+\end{document}
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</samples>
+% \end{macrocode}
+%
+% \Finale
+%
+
+
+\endinput
+
+%%%%%%%%%%%%%%%%%%%
diff --git a/Master/texmf-dist/source/latex/unicodefonttable/unicodefonttable.ins b/Master/texmf-dist/source/latex/unicodefonttable/unicodefonttable.ins
new file mode 100644
index 00000000000..b87cb4e13f4
--- /dev/null
+++ b/Master/texmf-dist/source/latex/unicodefonttable/unicodefonttable.ins
@@ -0,0 +1,72 @@
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the dtx file(s) in this package when run through
+%% LaTeX or TeX.
+%%
+%% Copyright 2019-2021 Frank Mittelbach
+%%
+%%
+%% This file is part of the unicodefonttable Bundle for LaTeX.
+%% -------------------------------------------------------
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2008 or later.
+%%
+%% As this file contains legal notices, it is NOT PERMITTED to modify
+%% this file in any way that the legal information placed into
+%% generated files is changed (i.e., the files generated when the
+%% original file is executed). This restriction does not apply if
+%% (parts of) the content is reused in a different WORK producing its
+%% own generated files.
+%%
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\input docstrip
+
+\keepsilent
+\askforoverwritefalse
+
+\usedir{tex/latex/unicodefonttable}
+
+\preamble
+
+This is a generated file.
+
+Copyright 2019-2021 Frank Mittelbach
+
+This file was generated from file(s) of the LaTeX `unicodefonttable Bundle'.
+--------------------------------------------------------------------------
+
+It may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version.
+The latest version of this license is in
+ https://www.latex-project.org/lppl.txt
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008 or later.
+
+This file may only be distributed together with a copy of the LaTeX
+`unicodefonttable Bundle'. You may however distribute the `unicodefonttable Bundle'
+without such generated files.
+
+The newest sources can be found below
+
+ https://github.com/FrankMittelbach/fmitex-unicodetable
+
+where one can also log issues in case there are any.
+
+
+\endpreamble
+
+\generate{\file{unicodefonttable.sty}{\from{unicodefonttable.dtx}{package}}}
+\generate{\file{unicodefonttable-samples.tex}{\from{unicodefonttable.dtx}{samples}}}
+
+\generate{\file{unicodefont.tex}{\from{unicodefonttable.dtx}{standalone}}}
+
+\endbatchfile