30

With LuaTeX, how do I get a list of OTF features supported by the current font in use printed?

For example, with otfinfo, I can get a list of OTF features by otfinfo -f font_file_name. Can I do anything similar with LuaTeX?

The goal is to produce such a list for each font I tested. For example, I would like to have such a macro,

\def\listfontfeatures{
 \directlua{... some lua code to list font features to a string, say ff ...}
 \directlua{tex.print(ff)}
}

And use it like the following,

Times Ten LT Std: \fontspec{Times Ten LT Std} \listfontfeatures \par
Palatino LT Std:  \fontspec{Palatino LT Std}  \listfontfeatures \par
Minion Pro:       \fontspec{Minion Pro}       \listfontfeatures \par

Update 12/01/2017

Here's just a small improvement to michal.h21's answer, just in case anyone will be interested.

fontspec_if_feature actually tests font features for the currently selected font family instead of the currently selected font. Normally this makes little difference and I only noticed this recently. For some fonts, different shapes have different features. For example, the italics may have swashes while the roman fonts lack it.

Below is a few macros that I now use for font feature test. It only work for LuaTeX. some modifications to the FontName macro is needed to make it to work with XeTeX.

\ExplSyntaxOff % remove the necessity to use ~ for space
\NewDocumentCommand\FontName{}{%
  \directlua{
    local i = font.current()
    local f = font.getfont(i)
    local n = f.fullname
    tex.sprint(n)
  }%
}
\ExplSyntaxOn

% Setup a new font family whose "n/m" shape is the current font.
% Limitations: The contents of the true/false clauses will be
% set in current fonts without any features selected by default,
% and it will be set in a group. For myself, this was intentionally.
\NewDocumentCommand\FontFeatureTF{m +m +m}{
  \group_begin:
  \fontspec_set_family:Nnn\thisfont:{}{\FontName}
  \fontfamily\thisfont:\selectfont
  \fontspec_if_feature:nTF{#1}{#2}{#3}
  \group_end:
}

\NewDocumentCommand\FontFeatureT{m +m}{
  \FontFeatureTF{#1}{#2}{\prg_do_nothing:}
}

\NewDocumentCommand\FontFeatureF{m +m}{
  \FontFeatureTF{#1}{\prg_do_nothing:}{#2}
}
1
  • I don't have time to write an answer, but fontspec has function \fontspec_if_feature:nTF - it uses expl syntax - and it should be possible, to iterate over list of features with this function, both in lualatex and xelatex
    – michal.h21
    Aug 17, 2011 at 13:38

4 Answers 4

18

You can use fontspec function \fontspec_if_feature:nTF. It will work in both xelatex and lualatex

\documentclass{article}
\usepackage{fontspec,etoolbox,expl3}
\setmainfont{Cambria}
\def\fontfeatures{abvf, abvm, abvs, aalt, akhn, nalt, halt, afrc, valt, vhal, blwf, blwm, blws, cpsp, c2pc, c2sc, case, cpct, cv01, cv02, cv03, cv04, cv05, cv06, cv07, cv08, cv09, cv10, cv11, cv12, cv13, cv14, cv15, cv16, cv17, cv18, cv19, cv20, cv21, cv22, cv23, cv24, cv25, cv26, cv27, cv28, cv29, cv30, cv31, cv32, cv33, cv34, cv35, cv36, cv37, cv38, cv39, cv40, cv41, cv42, cv43, cv44, cv45, cv46, cv47, cv48, cv49, cv50, cv51, cv52, cv53, cv54, cv55, cv56, cv57, cv58, cv59, cv60, cv61, cv62, cv63, cv64, cv65, cv66, cv67, cv68, cv69, cv70, cv71, cv72, cv73, cv74, cv75, cv76, cv77, cv78, cv79, cv80, cv81, cv82, cv83, cv84, cv85, cv86, cv87, cv88, cv89, cv90, cv91, cv92, cv93, cv94, cv95, cv96, cv97, cv98, cv99, cjct, cfar, calt, clig, cswh, curs, dnom, dlig, dist, expt, falt, frac, fwid, ccmp, haln, half, hwid, hngl, hist, hlig, hkna, hojo, init, isol, ital, jp04, jp78, jp83, jp90, jalt, kern, lnum, ljmo, lfbd, ltra, ltrm, locl, mark, mset, mkmk, mgrk, medi, med2, nlck, nukt, numr, onum, opbd, size, ordn, ornm, pcap, pref, pres, psts, pstf, palt, vpal, pnum, pkna, pwid, qwid, rand, rkrf, rphf, rlig, rtbd, rtla, rtlm, ruby, sinf, smpl, zero, smcp, liga, salt, ss01, ss02, ss03, ss04, ss05, ss06, ss07, ss08, ss09, ss10, ss11, ss12, ss13, ss14, ss15, ss16, ss17, ss18, ss19, ss20, subs, sups, swsh, tnum, fina, fin2, fin3, twid, titl, trad, tnam, tjmo, unic, vatu, vert, vrt2, vkna, vkrn, vjmo}
% see http://en.wikipedia.org/wiki/OpenType_feature_tag_list#OpenType_Typographic_Features for their list 
\ExplSyntaxOn
\newcommand\listfontfeatures{%
\renewcommand*{\do}[1]{
\fontspec_if_feature:nTF {##1}{##1,\ }{}
}
\expandafter\docsvlist\expandafter{\fontfeatures}
}
\ExplSyntaxOff
\begin{document}
\listfontfeatures
\end{document}
5
  • 1
    @doncherry you are right, there was no space between features, I fixed the code and it should allow to break the lines now
    – michal.h21
    Oct 7, 2012 at 17:39
  • There is a bug here in the part of the \fontfeatures list that has ..., cv01-, cv99, ... as what you should instead have are cv01, cv02, cv03, and so on up to cv99 (without the hyphen after cv01, and with 99 entries not just 2). Jun 24, 2017 at 5:57
  • Ignore the above comment; I just realized I could fix it myself (and have done so). Jun 24, 2017 at 7:13
  • This code works great for me using XeLaTeX on Windows for most fonts. However, when I run it on Agency FB (which appears to be an OT font) I get a strange result. XeLaTeX exist successfully: it shows no errors. But no pdf is created. Does that mean that Agency FB has no OT features? Or is something else going on?
    – ltcomdata
    Apr 5, 2021 at 13:22
  • @ltcomdata that font was designed between 1992-1995 according to Wikipedia, so it is indeed possible that it doesn't have any features, as they weren't supported back then.
    – michal.h21
    Apr 5, 2021 at 14:16
12

This should list all features in the current font, it can even be extended to list supported scripts and languages for every feature:

\documentclass{article}
\usepackage{fontspec}

\begin{document}
\newcommand\listfontfeatures{%
\directlua{
local id   = font.current()
local font = fonts.identifiers[id]
local data = font.shared.otfdata
if data then
  local features = data.luatex.features
  for i,_ in next, features do
    for f,_ in next, features[i] do
      %print(f, table.serialize(features[i][f]))
      tex.sprint(-1, f.." ")
    end
  end
end
}}

\fontspec{TeX Gyre Pagella} \listfontfeatures
\end{document}
4
  • Thanks very much for the answer. However I still have a small question. I searched the LuaTeX manual and it seems that the shared key and otfdata are not defined by LuaTeX. So I greped my texmf-dist try to find out where otfdata are defined, and it seems they are from luaotfload. I am right now reading the source, but do you know if there are any user friendly documents for it and other things defined there?
    – Yan Zhou
    Aug 17, 2011 at 19:50
  • There aren't, sorry. Much of that code is derived from ConTeXt and Hans Hagan (main ConTeXt developer) does not consider it stable yet, it will be documented once the interface is stabilised. Aug 17, 2011 at 21:38
  • Em, I tried to read the source documentation of ConTeXt and found out that most are merely code without doc. However, I managed to serialize the table and print it to terminal. Though not perfect, but it still give a rough idea about everything there.
    – Yan Zhou
    Aug 18, 2011 at 10:40
  • the example doesn't work with current 'luaotfload`
    – user2478
    Oct 28, 2014 at 10:09
9

On Linux it is simple and I suppose that Windows has a similiar command

voss@shania:~/.fonts/Junicode> otfinfo -f Junicode.ttf 
c2sc    Small Capitals From Capitals
calt    Contextual Alternates
case    Case-Sensitive Forms
ccmp    Glyph Composition/Decomposition
dlig    Discretionary Ligatures
fina    Terminal Forms
frac    Fractions
hist    Historical Forms
hlig    Historical Ligatures
kern    Kerning
liga    Standard Ligatures
mark    Mark Positioning
mgrk    Mathematical Greek
mkmk    Mark to Mark Positioning
onum    Oldstyle Figures
rtlm    <unknown feature>
salt    Stylistic Alternates
smcp    Small Capitals
ss01    Stylistic Set 1
ss02    Stylistic Set 2
ss04    Stylistic Set 4
ss05    Stylistic Set 5
ss06    Stylistic Set 6
ss07    Stylistic Set 7
ss08    Stylistic Set 8
ss09    Stylistic Set 9
ss14    Stylistic Set 14
ss15    Stylistic Set 15
ss18    Stylistic Set 18
ss19    Stylistic Set 19
ss20    Stylistic Set 20
subs    Subscript
sups    Superscript
swsh    Swash
3
  • 2
    otfinfo is available for windows from lcdf.org/type
    – maetra
    Nov 14, 2012 at 12:17
  • What I need is add the features list to a latex file which list fonts directly. Of course I know I can query it from otfinfo from a terminal
    – Yan Zhou
    Nov 14, 2012 at 13:12
  • 1
    you can run otfinfo fontname > file.tmp from inside LaTeX and then read it with \input{file.tmp}
    – user2478
    Nov 14, 2012 at 13:28
5

You can use the ConTeXt script mtxrun to get this information:

$mtxrun --script fonts --info --list --name --pattern="*Cambria*"

mtx-fonts       |
mtx-fonts       | mapping : cambriaitalic
mtx-fonts       | fontname: cambriaitalic
mtx-fonts       | fullname: cambriaitalic
mtx-fonts       | filename: cambriai.ttf
mtx-fonts       | family  : cambria
mtx-fonts       | weight  : normal
mtx-fonts       | style   : italic
mtx-fonts       | width   : normal
mtx-fonts       | variant : normal
mtx-fonts       | subfont : 
mtx-fonts       | fweight : conflict: book
mtx-fonts       |
mtx-fonts       | gpos features:
mtx-fonts       |
mtx-fonts       | feature  script   languages
mtx-fonts       |
mtx-fonts       | kern     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       |
mtx-fonts       | gsub features:
mtx-fonts       |
mtx-fonts       | feature  script   languages
mtx-fonts       |
mtx-fonts       | c2sc     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | calt     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | case     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | ccmp     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | dnom     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | frac     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | liga     latn     dflt rom trk
mtx-fonts       | lnum     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | locl     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     rom     
mtx-fonts       | numr     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | onum     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | ordn     latn     dflt rom trk
mtx-fonts       | pnum     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | salt     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | sinf     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | smcp     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | sups     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk
mtx-fonts       | tnum     cyrl     dflt srb
mtx-fonts       |          grek     dflt    
mtx-fonts       |          latn     dflt rom trk

See $TEXMF/scripts/context/lua/mtx-fonts.lua for the lua code that implements this.

2
  • Thanks for the answer. But what I want is to get these information into a TeX file and output to PDF. In addition, I would like it to find what is the font's currently in use at a point of the tex source file. If only to get information on terminal, I can also use otfinfo, like I said in the question.
    – Yan Zhou
    Aug 17, 2011 at 19:42
  • The code in mtx-fonts.lua should also work inside a \startluacode ... \stopluacode (or the equivalent LaTeX) environment. It is a simple matter of change a few print statements to tex.print to get the output in PDF.
    – Aditya
    Aug 17, 2011 at 21:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .