TransWikia.com

LuaLaTeX: Smarter font selection macro for super-families

TeX - LaTeX Asked on May 27, 2021

NOTE: This question is not answered yet. The only "answer" to this question from user Davislor does not answer this question, even though it has up-votes to make it look like. Please feel free to answer if you have a real solution.

Fontspec with LuaLaTeX works well for small font families, but appears cumbersome to use with super-families. A modern super-family can contain tens of fonts in Weight/Width/Slope (WWS) matrix. As an example Avenir Next has 32 fonts in one family.

Opentype font tables contain fields that can be used to accurately select a font in a super family: 1) WWS family name, 2) WWS subfamily name. So ideally, one should be able to set a family by specifying just family name, and optionally select a subfamily by just specifying subfamily name. Is there a LuaLaTeX way to do that?

Note 1): This sub family name is not always a substring of font’s "full name", so you cannot do string concatenation trick and use fontspec 🙂

Note 2) If WWS fields are missing in the font, then the appropriate fields to resolve the font are: 1) font family name, and 2) font subfamily name. So somewhere a if-else statement will be needed.

fontfamily{Avenir Next LT Pro}
.
.
.
Hello world {fstyle{Ultra Light Italic} Hello world} Hello world


Here are some relevant screenshots:

enter image description here

enter image description here

enter image description here

One Answer

You would do this with an extensive list of FontFace= options, ideally in a .fontspec or .sty file. I don’t have that specific font to test, so I downloaded this version of Noto Serif into a subdirectory named fonts. Here is a sample:

documentclass{article}
usepackage{fontspec}
usepackage{parskip}
usepackage[paperwidth=10cm]{geometry}

pagestyle{empty}

defaultfontfeatures[NotoSerif]{
  Path=fonts/,
  Extension=.ttf,
  FontFace={ul}{n}{Font={*-Thin}},
  FontFace={ul}{it}{Font={*-ThinItalic}},
  FontFace={el}{n}{Font={*-ExtraLight}},
  FontFace={el}{it}{Font={*-ExtraLightItalic}},
  FontFace={l}{n}{Font={*-Light}},
  FontFace={l}{it}{Font={*-LightItalic}},
  UprightFont=*-Regular,
  ItalicFont=*-Italic,
  FontFace={mb}{n}{Font={*-Medium}},
  FontFace={mb}{it}{Font={*-MediumItalic}},
  FontFace={sb}{n}{Font={*-SemiBold}},
  FontFace={sb}{it}{Font={*-SemiBoldItalic}},
  BoldFont=*-Bold,
  BoldItalicFont=*-BoldItalic,
  FontFace={eb}{n}{Font={*-ExtraBold}},
  FontFace={eb}{it}{Font={*-ExtraBoldItalic}},
  FontFace={ub}{n}{Font={*-Black}},
  FontFace={ub}{it}{Font={*-BlackItalic}},
  FontFace={uluc}{n}{Font={*-ExtraCondensedThin}},
  FontFace={uluc}{it}{Font={*-ExtraCondensedThinItalic}},
  FontFace={eluc}{n}{Font={*-ExtraCondensedExtraLight}},
  FontFace={eluc}{it}{Font={*-ExtraCondensedExtraLightItalic}},
  FontFace={luc}{n}{Font={*-ExtraCondensedLight}},
  FontFace={luc}{it}{Font={*-ExtraCondensedLightItalic}},
  FontFace={uc}{n}{Font={*-ExtraCondensed}},
  FontFace={uc}{it}{Font={*-ExtraCondensedItalic}},
  FontFace={mbuc}{n}{Font={*-ExtraCondensedMedium}},
  FontFace={mbuc}{it}{Font={*-ExtraCondensedMediumItalic}},
  FontFace={sbuc}{n}{Font={*-ExtraCondensedSemiBold}},
  FontFace={sbuc}{it}{Font={*-ExtraCondensedSemiBoldItalic}},
  FontFace={buc}{n}{Font={*-ExtraCondensedBold}},
  FontFace={buc}{it}{Font={*-ExtraCondensedBoldItalic}},
  FontFace={ebuc}{n}{Font={*-ExtraCondensedExtraBold}},
  FontFace={ebuc}{it}{Font={*-ExtraCondensedExtraBoldItalic}},
  FontFace={ubuc}{n}{Font={*-ExtraCondensedBlack}},
  FontFace={ubuc}{it}{Font={*-ExtraCondensedBlackItalic}},
  FontFace={ulec}{n}{Font={*-CondensedThin}},
  FontFace={ulec}{it}{Font={*-CondensedThinItalic}},
  FontFace={elec}{n}{Font={*-CondensedExtraLight}},
  FontFace={elec}{it}{Font={*-CondensedExtraLightItalic}},
  FontFace={lec}{n}{Font={*-CondensedLight}},
  FontFace={lec}{it}{Font={*-CondensedLightItalic}},
  FontFace={ec}{n}{Font={*-Condensed}},
  FontFace={ec}{it}{Font={*-CondensedItalic}},
  FontFace={mbec}{n}{Font={*-CondensedMedium}},
  FontFace={mbec}{it}{Font={*-CondensedMediumItalic}},
  FontFace={sbec}{n}{Font={*-CondensedSemiBold}},
  FontFace={sbec}{it}{Font={*-CondensedSemiBoldItalic}},
  FontFace={bec}{n}{Font={*-CondensedBold}},
  FontFace={bec}{it}{Font={*-CondensedBoldItalic}},
  FontFace={ebec}{n}{Font={*-CondensedExtraBold}},
  FontFace={ebec}{it}{Font={*-CondensedExtraBoldItalic}},
  FontFace={ubec}{n}{Font={*-CondensedBlack}},
  FontFace={ubec}{it}{Font={*-CondensedBlackItalic}},
  FontFace={ulc}{n}{Font={*-SemiCondensedThin}},
  FontFace={ulc}{it}{Font={*-SemiCondensedThinItalic}},
  FontFace={elc}{n}{Font={*-SemiCondensedExtraLight}},
  FontFace={elc}{it}{Font={*-SemiCondensedExtraLightItalic}},
  FontFace={lc}{n}{Font={*-SemiCondensedLight}},
  FontFace={lc}{it}{Font={*-SemiCondensedLightItalic}},
  FontFace={c}{n}{Font={*-SemiCondensed}},
  FontFace={c}{it}{Font={*-SemiCondensedItalic}},
  FontFace={mbc}{n}{Font={*-SemiCondensedMedium}},
  FontFace={mbc}{it}{Font={*-SemiCondensedMediumItalic}},
  FontFace={sbc}{n}{Font={*-SemiCondensedSemiBold}},
  FontFace={sbc}{it}{Font={*-SemiCondensedSemiBoldItalic}},
  FontFace={bc}{n}{Font={*-SemiCondensedBold}},
  FontFace={bc}{it}{Font={*-SemiCondensedBoldItalic}},
  FontFace={ebc}{n}{Font={*-SemiCondensedExtraBold}},
  FontFace={ebc}{it}{Font={*-SemiCondensedExtraBoldItalic}},
  FontFace={ubc}{n}{Font={*-SemiCondensedBlack}},
  FontFace={ubc}{it}{Font={*-SemiCondensedBlackItalic}}
}

setmainfont{NotoSerif}

makeatletter
edefcurrent@weight{m}
edefcurrent@extent{}

DeclareRobustCommandfontweight[1]{%
  edefcurrent@weight{#1}%
  update@series%
}

DeclareRobustCommandfontextent[1]{%
  edefcurrent@extent{#1}%
  update@series%
}

DeclareRobustCommandupdate@series{%
  expandafterifxcurrent@extentrelax%
    fontseries{current@weight}%
  else%
    ifxcurrent@weight m%
      fontseries{current@extent}%
    else%
      fontseries{current@weightcurrent@extent}%
    fi%
  fi%
}
makeatother

newcommandulweight{fontweight{ul}selectfont}
newcommandelweight{fontweight{el}selectfont}
newcommandltweight{fontweight{l}selectfont}
newcommandmdweight{fontweight{m}selectfont}
newcommandmbweight{fontweight{mb}selectfont}
newcommandsbweight{fontweight{sb}selectfont}
newcommandbfweight{fontweight{b}selectfont}
newcommandebweight{fontweight{eb}selectfont}
newcommandubweight{fontweight{ub}selectfont}
newcommanducwidth{fontextent{uc}selectfont}
newcommandecwidth{fontextent{ec}selectfont}
newcommandcdwidth{fontextent{c}selectfont}

begin{document}
mdweight Noto Serif textit{Italic}
ulweight Thin textit{Italic}
elweight ExtraLight textit{Italic}
ltweight Light textit{Italic}
mbweight Medium textit{Italic}
sbweight Semibold textit{Italic}
bfweight Bold textit{Italic}
ebweight Extra-Bold textit{Italic}
ubweight Heavy textit{Italic}

ucwidth
mdweight Noto Serif Extra-Condensed textit{Italic}
ulweight Thin textit{Italic}
elweight ExtraLight textit{Italic}
ltweight Light textit{Italic}
mbweight Medium textit{Italic}
sbweight Semibold textit{Italic}
bfweight Bold textit{Italic}
ebweight Extra-Bold textit{Italic}
ubweight Heavy textit{Italic}

ecwidth
mdweight Noto Serif Condensed textit{Italic}
ulweight Thin textit{Italic}
elweight ExtraLight textit{Italic}
ltweight Light textit{Italic}
mbweight Medium textit{Italic}
sbweight Semibold textit{Italic}
bfweight Bold textit{Italic}
ebweight Extra-Bold textit{Italic}
ubweight Heavy textit{Italic}

cdwidth
mdweight Noto Serif Semi-Condensed textit{Italic}
ulweight Thin textit{Italic}
elweight ExtraLight textit{Italic}
ltweight Light textit{Italic}
mbweight Medium textit{Italic}
sbweight Semibold textit{Italic}
bfweight Bold textit{Italic}
ebweight Extra-Bold textit{Italic}
ubweight Heavy textit{Italic}
end{document}

Noto Serif Sample

I re-invented the wheel there: the nfssext-cfr package by @cfr also defines commands to set weight and width separately, and I used similar names. If you also want commands corresponding to textit, textup, and so on, you would define them with DeclareTextFontCommandtextul{ulwidth}, etc.

You might instead want to redefine the standard bfseries, mdseries and so on, so that bold condensed would be bfseriescdseries instead of bfweightcdwidth. This is how fontaxes and fontspec handle itshapescshape for italic small caps. I avoided overriding the standard commands here, but that means they aren’t compatible with the new ones.

Like most packages, I used the official LaTeX series names from The LaTeX Font Installation Guide, but note that fontspec allows you to give your series and shapes arbitrary names. There is no reason you couldn’t set up fontweight{Semibold}fontextent{Condensed}selectfont to work, or fontseries{SemiboldCondensed}selectfont. Just declare FontFace{SemiboldCondensed}{n} instead of FontFace{sbc}{n}.

To enable options such as support for optical sizes or variable fonts, add them inside the braces after Font=, such as FontFace{ebc}{n}{ Font={*-ExtraBoldCondensed}, SizeFeatures={...} }. See the fontspec manual for the features you need.

LuaTeX 1.13 and up now supports variable fonts as well.

If you just want to use the human-readable names in your code, you could attempt something like fontspec{Avenir Next LT Pro Medium Condensed}. Loading fonts by display name is deprecated, however.

Answered by Davislor on May 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP