Я работаю с экранным шрифтом, в котором отсутствуют многие распространенные символы, включая скобки, длинное тире и настоящие «направленные кавычки».
Мне бы хотелось иметь простой способ заменить их соответствующими символами из другого шрифта, когда они встречаются. Общее «если в основном шрифте отсутствует этот символ, используйте этот другой шрифт» сработало бы, но я могу определить все нужные мне символы. Мне не нужно менять символ; если отсутствующий символ, скажем, «(», в резервном шрифте он будет (. Я использую этот шрифт только в ограниченных обстоятельствах (\chapter и \section в memoir), что может упростить или усложнить проблему. Аналогично, все задействованные шрифты — TrueType/OpenType.
новыйunicodecharиucharclassesкажутся многообещающими, но первый вариант не будет работать с символами ASCII, а второй работает только с целыми блоками Unicode.
Механизм классов interchar в XeTeX выглядит многообещающим, и это мой план Б. Но я бы предпочел что-то более портативное, хотя бы между XeLaTeX и LuaLaTex.
Минимальный рабочий пример, опирающийся набесплатный шрифт Cyberfunk.
\documentclass{article}
\usepackage{fontspec}
\begin{document}
``Dr. J---/Mr. H---'s (Missing Glyph) Day''
\fontspec{Cyberfunk}``Dr. J---/Mr. H---'s (Missing Glyph) Day''
\end{document}
Я могу привести более длинный и реалистичный пример того, как я использую это в мемуарах, если это будет полезно; но он был намного длиннее.
решение1
Здесь вы можете настроить цикл токенов для поиска отсутствующих глифов и замены их глифами альтернативного шрифта, в данном случае Calibri.
Здесь я взял на себя смелость найти и заменить следующие глифы/строки: (
, )
, ‘
, '
, /
, -
, --
и ---
.
Обратите внимание, что изменение catcodes внутри цикла токена не может быть легко выполнено, поскольку токены сканируются текущими catcodes перед их выполнением. Это влияет, например, на блоки verbatim.
\documentclass{article}
\usepackage{fontspec,tokcycle}
\newif\ifemdash
\newif\ifendash
\newcommand\dashtest{\emdashfalse\endashfalse\tcpeek\Q
\ifx-\Q\tcpop\Q\tcpeek\QQ\ifx-\QQ\tcpop\QQ\emdashtrue\else
\endashtrue\fi\fi
}
\Characterdirective{%
\ifx(#1\addcytoks{{\setmainfont{Calibri}(}}\else
\ifx)#1\addcytoks{{\setmainfont{Calibri})}}\else
\ifx`#1\addcytoks{{\setmainfont{Calibri}`}}\else
\ifx'#1\addcytoks{{\setmainfont{Calibri}'}}\else
\ifx/#1\addcytoks{{\setmainfont{Calibri}/}}\else
\ifx-#1\dashtest
\ifemdash\addcytoks{{\setmainfont{Calibri}---}}\else
\ifendash\addcytoks{{\setmainfont{Calibri}--}}\else
\addcytoks{{\setmainfont{Calibri}-}}\fi\fi
\else
\addcytoks{#1}\fi\fi\fi\fi\fi\fi
}
\begin{document}
``Dr. J---/Mr. H---'s (Missing Glyph) Day''
Endash -- and Hyphen -
\setmainfont{Cyberfunk}
\tokencyclexpress
``Dr. J---/Mr. H---'s (Missing Glyph) Day''
Endash -- and Hyphen -
\endtokencyclexpress
\end{document}
Обработанные токены цикла буферизуются и выводятся по завершении цикла. Если цикл токена очень большой (например, охватывает весь документ) и есть опасения по поводу превышения внутреннего размера буфера, можно указать циклу токена очищать буфер после каждого разгруппированного \par
, добавив \Macrodirective
, следующим образом:
\Macrodirective{
\addcytoks{#1}\ifnum\tcdepth=0
\ifx\par#1\the\cytoks\cytoks{}\fi
\fi% CLEARS BUFFER ON UNGROUPED \par
}