[Tex/LaTex] Generating a table of all glyphs – including meta data like name, Unicode etc

fontsfontspecopentypexetex

The answers to Generating a table of glyphs with XeTeX cycle through character positions in the font and output a glyph (and its ordinal number) if one is assigned to that position, which is only sometimes the same as Unicode position. Some glyphs may be shared by several Unicode code points. Some Unicode code points have several glyphs assigned to them, possibly selected by smart font features. Furthermore, Unicode has more positions than fit into 16bit (as in Open Type).

I can use a font editor to look up the names assigned to glyphs, which may adhere to Adobe’s glyph naming standards, but often deviate from that, especially for alternate glyphs (dot suffixes) and for non-roman characters. Nevertheless, I want to print out a customizable glyph list containing that info using XeLaTeX.

How can I adapt @LeoLiu’s code, repeated below, to show glyph names besides ordinal number?

\documentclass[landscape]{article}
\usepackage{geometry}
\usepackage{fontspec}
\setmainfont{Linux Libertine O}
\usepackage{multicol}
\setlength{\columnseprule}{0.4pt}
\setlength{\parindent}{0pt}
\usepackage{multido}
\begin{document}

\begin{multicols}{10}
\multido{\i=0+1}{"10000}{% from 0x0000 to 0xFFFF
  \iffontchar\font\i
    \makebox[3em][l]{\i}%
    \symbol{\i}\endgraf
  \fi
}
\end{multicols}

\end{document}

JFTR, as it happens the libertine package documentation and guide already include glyph lists, but they might be out of date and I want to do it for other fonts, too. The former has some code that might be relevant, because it seems to generate glyph lists, but I don’t understand it (i.e. the cathode magic, I guess):

\renewcommand\DeclareTextGlyphY[3]{%
  \makebox[2.5cm]{\LARGE\strut\fbox{\biolinumKeyGlyph{#2}}} #2\\}%
\catcode`\_=12%
\begin{multicols}{2}
\par\noindent
\input{LinBiolinum_K}
\end{multicols}

Update: This is the code from libertine.sty (for XeTeX and LuaTeX) which is adapted by the code above:

\providecommand*\DeclareTextGlyphY[3]{%
  % \DeclareTextGlyphY{fxl}{s_t}{64262}
  % #1=basefont #2=glyphname, #3=position
  \def\lib@temp{#1}%
  \ifx\lib@temp\lib@fxl \@namedef{#1@#2}{{\libertine\char#3\relax}}\else%
    \ifx\lib@temp\lib@fxb \@namedef{#1@#2}{{\biolinum\char#3\relax}}\else%
      \ifx\lib@temp\lib@fxk \@namedef{#1@#2}{{\biolinumkey\char#3\relax}}\else%
        \ifx\lib@temp\lib@fxi \@namedef{#1@#2}{{\libertineInitial\char#3\relax}}\else%
  \fi\fi\fi\fi}
%
\input{LinLibertine_R}
\input{LinBiolinum_R}
\input{LinBiolinum_K}
\input{LinLibertine_I}
%
\DeclareRobustCommand*\libertineGlyph[1]{\@nameuse{LinLibertine_R@#1}}
\DeclareRobustCommand*\biolinumGlyph[1]{\@nameuse{LinBiolinum_R@#1}}
\DeclareRobustCommand*\biolinumKeyGlyph[1]{\@nameuse{LinBiolinum_K@#1}}
\DeclareRobustCommand*\libertineInitialGlyph[1]{\@nameuse{LinLibertine_I@#1}}

The files LinLibertine_R.tex, LinBiolinum_R.tex, LinBiolinum_K.tex and LinLibertine_I.tex contain a lot of \DeclareTextGlyphY calls and nothing else.

Best Answer

With XeTeX you can get glyph by name, but I don't think it's possible to map the name to the Unicode point, which wouldn't make sense anyway, because a code point can correspond to several glyphs.

Here's how: if you know the name, say zero.slash, you can print the glyph with

\XeTeXglyph\XeTeXglyphindex"zero.slash"<space>

I got the list of glyph names for Linux Libertine O with

otfinfo -g `kpsewhich LinLibertine_R.otf` > libert.list

which produced the text file

.notdef
space
exclam
quotedbl
numbersign
dollar
percent
ampersand
quotesingle
parenleft
parenright
asterisk
...
longs_t
s_t
uniFFFD
u1D538
u1D539
u1D53B
u1D53C
u1D53D
u1D53E
u1D540
u1D541
u1D542
u1D543
u1D544
u1D546
u1D547
u1D54A
u1D54B
u1D54C
u1D54D
u1D54E
u1D54F
u1D550

and then ran the following LaTeX document with XeLaTeX: it just loops over the file and feeds lines to the mapping function.

\documentclass{article}
\usepackage{xparse,fontspec,multicol}
\usepackage[a4paper,margin=2cm]{geometry}
\ExplSyntaxOn
\NewDocumentCommand{\printlist}{m}
 {
  \crissov_print_list:n { #1 }
 }

\ior_new:N \g_crissov_input_stream
\cs_new_protected:Npn \crissov_print_list:n #1
 {
  \ior_open:Nn \g_crissov_input_stream { #1 }
  \ior_str_map_inline:Nn \g_crissov_input_stream
   {
    \makebox[2.5em][l]{\XeTeXglyph\XeTeXglyphindex"##1"~}
    {\footnotesize(##1)}\par
   }
 }
\ExplSyntaxOff

\setlength{\parindent}{0pt}

\begin{document}
\fontspec{Linux Libertine O}
\begin{multicols}{3}
\printlist{libert.list}
\end{multicols}
\end{document}

This is a picture of the last page:

enter image description here

Note that the last glyph never shows up due to what I think is a bug in XeTeX.