我需要所有带变音符号的大写字母具有与相应裸大写字母相同的高度(深度)。
动机:当无法拉伸基线时,获取规则的基线网格。
以下是一个需要修改的 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)
就足够了。缺点:
- 与宏一起放置的变音符号不受影响
- 需要编译一长串的命令
这是可行的。但我不想担心使用宏。另外,我使用的语言中有很多变音符号。写列表会很烦人。
(问题 1)至少这最后一项任务可以自动化吗?(第二季度) 即使只是知道从重音字符(或其 unicode id)中恢复裸字母的通用方法也是向前迈出的一步。
示例提供了另一个尝试性解决方案2)
。 看起来它适用于我需要的所有情况,但实际上它很糟糕,如反例所示1)
。 (请记住,我的文档是 UTF8 编码的。)
(第三季度) 是否存在修复方法1)
?
我也尝试在原始上进行一些裁剪和缝合\accent
,但无济于事。
(Q4) 是否存在比我能想到的更好的方法?
我正在使用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
,而不是直接包含,因为这样做更容易;我可以稍后更改它。