
Мне нужно, чтобы все заглавные буквы с диакритическими знаками имели ту же высоту (глубину), что и соответствующая голая заглавная буква.
Мотивация: получение регулярной сетки базовой линии при растяжении базовой линии не представляется возможным.
Вот MWE, с которым можно повозиться
\documentclass{standalone}
\usepackage[utf8]{inputenc}
\let\oldAcute\' \def\'#1{\protect\vphantom{#1}\smash{\oldAcute#1}} % 1)
\let\oldHacek\v \def\v#1{\protect\vphantom{#1}\smash{\oldHacek#1}} % 2)
\DeclareUnicodeCharacter{00C7}{\protect\vphantom{C}\smash{\c C}} % 3)
\setlength\fboxsep{0pt}
\let\MU\MakeUppercase
\begin{document}
\fbox{\fbox{A}\fbox{Á}\fbox{\'{A}}\fbox{\MU{á}}\fbox{\MU{\'{a}}}}
\fbox{\fbox{C}\fbox{Č}\fbox{\v{C}}\fbox{\MU{č}}\fbox{\MU{\v{c}}}}
\fbox{\fbox{C}\fbox{Ç}\fbox{\c{C}}\fbox{\MU{ç}}\fbox{\MU{\c{c}}}}
\end{document}
Мой документ имеет кодировку UTF8, поэтому метода примера 3)
будет достаточно. Недостатки:
- диакритические знаки, введенные с помощью макросов, не изменяются
- необходимо составить длинный список команд
Это осуществимо. Но я бы не хотел беспокоиться об использовании макросов. Кроме того, я использую больше двух языков, переполненных диакритическими знаками. Составление списка будет раздражать.
(Q1) Можно ли автоматизировать хотя бы эту последнюю задачу? (Q2) Даже простое знание общего метода восстановления голой буквы из символа с ударением (или ее идентификатора Unicode) было бы шагом вперед.
Другое предварительное решение представлено в примере 2)
. Кажется, что оно работает во всех ситуациях, которые мне нужны, но на самом деле это мусор, как показано в контрпримере 1)
. (Помните, мой документ в кодировке UTF8.)
(Q3) Существует ли исправление 1)
?
Я также пробовала вырезать и сшить что-нибудь на \accent
примитиве, но безрезультатно.
(4-й квартал) Существует ли другой способ, лучший, чем тот, который я смог придумать?
Я использую LaTeX
и хотел бы продолжать пользоваться им.
Конечно, было бы интересно увидеть элегантное решение, работающее на любом другом движке!
решение1
Прежде всего, вам абсолютно необходимо сказать тому, кто отвечает за проект, то, что вы почти говорите в комментариях: то, что вы просите сделать здесь, является следствием плохих решений, с которыми вам не следует иметь дело. Все, что вы здесь делаете, это работаете вокруг этих плохих решений, потому что вы не можете справиться с главной проблемой.
Теперь, если вы это знаете, ваш обходной путь 3 действительно легко реализовать с помощьюБаза данных символов Unicode(смотрите такжеподробное описание), потому что у него есть отображения декомпозиции. Следующий скрипт на Lua делает именно это (при условии, что у вас есть UnicodeData.txt
в текущем каталоге). Вы можете обработать его с помощью texlua
(не просто Lua, потому что ему нужна lpeg
библиотека).
local P, C, Ct = lpeg.P, lpeg.C, lpeg.Ct
local semicolon = P';'
local field = C((1 - semicolon)^1)
local linepatt = field * (semicolon * field)^0
local space = P' '
local singlechar = C((1 - space)^1)
local ltsign = P'<'
local initchar = C((1 - space - ltsign)^1)
local nfdpatt = Ct(initchar * (space * singlechar)^0)
texaccents = {
['0300'] = '\\`',
['0301'] = "\\'",
['0302'] = '\\^',
['0303'] = '\\~',
['0308'] = '\\"',
['030B'] = '\\H',
['030A'] = '\\r',
['030C'] = '\\v',
['0306'] = '\\u',
['0304'] = '\\=',
['0307'] = '\\.',
['0328'] = '\\k'
}
for line in io.lines('UnicodeData.txt') do
local usv, _, _, _, _, nfd = linepatt:match(line)
if nfd then
local chars = nfdpatt:match(nfd)
if chars and #chars > 1 then
local base = chars[1]
smashedchr = '\\char"' .. base
for i = 2, #chars do
local diac = texaccents[chars[i]]
if diac then
smashedchr = diac .. '{' .. smashedchr .. '}'
else
break
end
end
print('\\DeclareUnicodeCharacter{' .. usv .. '}{\\protect\\vphantom{\\char"' .. base .. '}\\smash{' .. smashedchr .. '}}')
end
end
end
Вот первые несколько строк, которые он выводит:
\DeclareUnicodeCharacter{00C0}{\protect\vphantom{\char"0041}\smash{\`{\char"0041}}}
\DeclareUnicodeCharacter{00C1}{\protect\vphantom{\char"0041}\smash{\'{\char"0041}}}
\DeclareUnicodeCharacter{00C2}{\protect\vphantom{\char"0041}\smash{\^{\char"0041}}}
\DeclareUnicodeCharacter{00C3}{\protect\vphantom{\char"0041}\smash{\~{\char"0041}}}
\DeclareUnicodeCharacter{00C4}{\protect\vphantom{\char"0041}\smash{\"{\char"0041}}}
\DeclareUnicodeCharacter{00C5}{\protect\vphantom{\char"0041}\smash{\r{\char"0041}}}
Обратите внимание, что базовые символы включены с помощью \char
, а не напрямую, потому что так было проще; я смогу изменить это позже.