diff options
author | Karl Berry <karl@freefriends.org> | 2021-10-21 20:31:49 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-10-21 20:31:49 +0000 |
commit | a4756b9a2c587fe3fe092cc9cfd8e3b1fb267445 (patch) | |
tree | 0b4d0134bccafad5daeb2ede7b872e66e611a6a6 /Master/texmf-dist/source/latex/unicodefonttable | |
parent | c1fb42e1c4a88d363f56d1eed4804bc16bcaee59 (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.dtx | 2295 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/unicodefonttable/unicodefonttable.ins | 72 |
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 |