Загрузка массива шрифтов с помощью fontspec и pgffor

Загрузка массива шрифтов с помощью fontspec и pgffor

Я пытаюсь создать документ для сравнения набора шрифтов. Я хотел бы разобрать массив, чтобы загрузить и попробовать их все.

Вот что я сделал:

\documentclass{article}

\usepackage{lipsum}
\usepackage{pgffor}
\usepackage{fontspec}

\def\LoadFont#1{\expandafter\newfontface\csname#1\endcsname{#1}}
\def\UseFont#1{\csname#1\endcsname}

\def\FontList{Charter,Lato,Linux Libertine O}

% these work just fine
%\LoadFont{Charter}
%\LoadFont{Lato}
%\LoadFont{Linux Libertine O}

% THIS DOES NOT WORK
\foreach \FontName in \FontList {\LoadFont\FontName}

\begin{document}
\foreach \FontName in \FontList {\UseFont\FontName\lipsum[1]}
\end{document}

Цикл с \UseFontработает нормально, а вот с — \LoadFontнет. Сам по себе \LoadFontделает то, что и ожидается.

Думаю, это может быть проблема расширения, но я не уверен, в чем именно она заключается; слепые попытки ни к чему не привели.

Что не так с циклом загрузки?

решение1

Как уже объяснялось, наблюдаемое вами поведение обусловлено устоявшейся особенностью \foreachвыполнения итераций внутри групп, ограничивающих область действия.

Вот с \xintFor. Я переключился на другой шрифт, так как у меня не установлен Lato.

\documentclass{article}

\usepackage{lipsum}
\usepackage{xinttools}
\usepackage{fontspec}

\def\LoadFont#1{\expandafter\newfontface\csname#1\endcsname{#1}}
\def\UseFont#1{\csname#1\endcsname}

% original
% \def\FontList{Charter,Lato,Linux Libertine O}
% as I don't have Lato:

\def\FontList {Charter, TeX Gyre Heros, Linux Libertine O}

\xintFor #1 in \FontList \do {\LoadFont {#1}}

\begin{document}

\xintFor #1 in \FontList \do {\UseFont {#1}\lipsum[1]}

\end{document}

% Local Variables:
% TeX-engine: xetex
% End:

Цитата из блока

решение2

Когда ты это сделаешь

\foreach \FontName in \FontList {\LoadFont\FontName}

инструкция \newfontfaceвыполняется внутри группы, поэтому определение шрифта теряется, как только группа заканчивается. Это особенность \foreach.

Вот набор макросов, expl3которые могут дать вам некоторые идеи по их расширению.

\documentclass{article}

\usepackage{fontspec}
\usepackage{lipsum}

\ExplSyntaxOn
\NewDocumentCommand{\LoadFont}{m}
 {
  \exp_args:Nc \newfontface { #1 } { #1 }
 }
\NewDocumentCommand{\LoadFonts}{m}
 {
  \clist_map_inline:nn { #1 }
   {
    \LoadFont{##1}
   }
 }
\NewDocumentCommand{\UseFont}{m}
 {
  \use:c { #1 }
 }
\NewDocumentCommand{\UseFonts}{m +m}
 {
  \clist_map_inline:nn { #1 }
   {
    \group_begin:
    \UseFont{##1} ##1:~#2
    \group_end:
   }
 }
\ExplSyntaxOff

\LoadFonts{Charter,Lato,Linux Libertine O}

\begin{document}

\UseFonts{Charter,Lato,Linux Libertine O}{\lipsum[2]}

\end{document}

Обратите внимание, что \exp_args:Nc \newfontface { #1 } { #1 }по сути это то же самое, что

\expandafter\newfontface\csname #1\endcsname{#1}

введите описание изображения здесь

Если вы хотите использовать символическое имя для списка, определите *-вариант:

\documentclass{article}

\usepackage{fontspec}
\usepackage{lipsum}

\ExplSyntaxOn
\NewDocumentCommand{\LoadFont}{m}
 {
  \exp_args:Nc \newfontface { #1 } { #1 }
 }
\NewDocumentCommand{\LoadFonts}{sm}
 {
  \IfBooleanTF{#1}
   { \clist_map_inline:Nn #2 }
   { \clist_map_inline:nn { #2 } }
   {
    \LoadFont{##1}
   }
 }
\NewDocumentCommand{\UseFont}{m}
 {
  \use:c { #1 }
 }
\NewDocumentCommand{\UseFonts}{s m +m}
 {
  \IfBooleanTF{#1}
   { \clist_map_inline:Nn #2 }
   { \clist_map_inline:nn { #2 } }
   {
    \group_begin:
    \UseFont{##1} ##1:~#3
    \group_end:
   }
 }
\ExplSyntaxOff

%\LoadFonts{Charter,Lato,Linux Libertine O}

\newcommand\FontList{Charter,Lato,Linux Libertine O}
\LoadFonts*{\FontList}

\begin{document}

%\UseFonts{Charter,Lato,Linux Libertine O}{\lipsum[2]}

\UseFonts*{\FontList}{\lipsum[2]}

\end{document}

Связанный контент