Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

A LaTeX package I'm currently writing makes use of -- and definitely requires -- some of the power of LuaLaTeX. I would like to make my package's user interface -- in particular, the options that need to be loaded -- as simple as possible by making the package determine on its own which "font features" have been activated via commands such as \fontspec, \setmainfont, \defaultfontfeatures, and \addfontfeatures that are provided by the fontspec package.

The font features I'm most interested in are ligatures, in particular those called "Common" (activated by +liga), "Required" (+rlig), "Contextual" (+clig), "Historic" (+hlig), and "Discretionary"/"Rare" (+dlig).

Some functionality of the type I'm looking for is mentioned in section 25.3 of the user guide (named "Programmer's interface) of the fontspec manual. However, no specific examples are provided to demonstrate how the macros listed in this section might be used in practice. Moreover, I must confess, I'm not at all familiar with LaTeX3, the LaTeX dialect used by the fontspec package. Thus, I'm in no position to construct a user macro of this type on my own.

My question thus is: How would one write a Boolean test -- likely based on a macro that uses the interface noted in section 25.3 of the fontspec manual -- to query if, say, "historic" ligatures have been activated via one of the methods provided by the fontspec package?

share|improve this question
4  
You're probably looking for \fontspec_if_feature:nTF {rawfeature}{true}{false} which could be \let to a more convenient name: \ExplSyntaxOn \cs_new_eq:NN \testforfeature \fontspec_if_feature:nTF \ExplSyntaxOff. This could then be used like feauture hlig is \testforfeature{hlig}{active}{inactive} –  cgnieder Nov 11 '12 at 14:44
    
@cgnieder You should make this into an answer. –  egreg Nov 11 '12 at 21:39
    
@egreg After reading the manual again I'm not so sure. It says about \fontspec_if_feature:nTF: “Test whether the currently selected font contains the raw OpenType feature #1.” So the test is apparently not for active features but for existent ones. –  cgnieder Nov 12 '12 at 10:32

1 Answer 1

up vote 7 down vote accepted

First of all: there might be better ways to do this. Or at least other recommended ways...

It appears that fontspec updates what it calls a “sclist” with the activated raw features. A sclist is a list separated with a semicolon which means it is basically a token list. The idea would now be to look if a given raw feature is stored in that token list or not. The list containing the raw features appears to be \l_fontspec_rawfeatures_sclist. One can now test with \tl_if_in:NnTF <tokenlistmacro> { tokens } { true } { false } if a given feature is active.

\cs_new:Npn basically is a wrapper for \long\def and \cs_new_eq:NN basically is \let. The arg spec nTF means that the macro has three arguments, the n being a group of tokens given in braces. T and F also are arguments given in braces and are expanded if the test is either true or false, respectively.

\ExplSyntaxOn
% test if active font has feature:
\cs_new_eq:NN \IfFontFeatureExists \fontspec_if_feature:nTF
% test if feature is active:
\cs_new:Npn \mico_fontfeature_if_active:nTF #1
  { \tl_if_in:NnTF \l_fontspec_rawfeatures_sclist { #1 } }
\cs_new_eq:NN \IfFontFeatureActive \mico_fontfeature_if_active:nTF
\ExplSyntaxOff

A whole MWE could now look as follows:

\documentclass{article}
\usepackage{fontspec}
\setmainfont[Numbers=OldStyle]{LinLibertineO}

\ExplSyntaxOn
\cs_new_eq:NN \IfFontFeatureExists \fontspec_if_feature:nTF
\cs_new:Npn \mico_fontfeature_if_active:nTF #1
  { \tl_if_in:NnTF \l_fontspec_rawfeatures_sclist { #1 } }
\cs_new_eq:NN \IfFontFeatureActive \mico_fontfeature_if_active:nTF
\ExplSyntaxOff

\begin{document}

liga \IfFontFeatureExists{liga}{exists}{does not exist},
clig \IfFontFeatureExists{clig}{exists}{does not exist},
rlig \IfFontFeatureExists{rlig}{exists}{does not exist},
hlig \IfFontFeatureExists{hlig}{exists}{does not exist},
dlig \IfFontFeatureExists{dlig}{exists}{does not exist}

liga is \IfFontFeatureActive{liga}{}{not} active,
hlig is \IfFontFeatureActive{hlig}{}{not} active,
dlig is \IfFontFeatureActive{dlig}{}{not} active

\addfontfeatures{Ligatures={Common,Historic}}
liga is \IfFontFeatureActive{liga}{}{not} active,
hlig is \IfFontFeatureActive{hlig}{}{not} active,
dlig is \IfFontFeatureActive{dlig}{}{not} active

\end{document}

enter image description here

share|improve this answer
    
Thanks so much! Your code works like a charm!! –  Mico Nov 12 '12 at 22:02
    
@Mico You're welcome! –  cgnieder Nov 13 '12 at 10:57
    
Any idea why \IfFontFeaturesActive doesn't work right for pnum, tnum, onum, lnum ? –  user22108 Nov 25 '13 at 3:19
    
@user22108 No... actually I don't know too much about the innards of fontspec. Maybe you should ask the fontspec maintainer. He should be able to give some insights –  cgnieder Nov 25 '13 at 9:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.