Замена отсутствующих символов в блоке ASCII/Latin

Замена отсутствующих символов в блоке ASCII/Latin

Я работаю с экранным шрифтом, в котором отсутствуют многие распространенные символы, включая скобки, длинное тире и настоящие «направленные кавычки».

Мне бы хотелось иметь простой способ заменить их соответствующими символами из другого шрифта, когда они встречаются. Общее «если в основном шрифте отсутствует этот символ, используйте этот другой шрифт» сработало бы, но я могу определить все нужные мне символы. Мне не нужно менять символ; если отсутствующий символ, скажем, «(», в резервном шрифте он будет (. Я использую этот шрифт только в ограниченных обстоятельствах (\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
}

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