如何在 XeTeX 中在 -- (en-dash)周围添加额外的字距

如何在 XeTeX 中在 -- (en-dash)周围添加额外的字距

在 XeTeX 中,当短破折号(Unicode) 或--(TeX 连字符) 被数字包围时,是否有办法定义一些额外的字距?对于我可以使用 \XeTeXinterchartoks,但这对 不起作用--

% !TeX program = xelatex
\documentclass{article}

\usepackage{fontspec}

\XeTeXinterchartokenstate = 1

\newXeTeXintercharclass \enDashCharacterClass
\newXeTeXintercharclass \digitsCharacterClass

\XeTeXcharclass `– \enDashCharacterClass
%\XeTeXcharclass `- \enDashCharacterClass

\XeTeXcharclass `0 \digitsCharacterClass
\XeTeXcharclass `1 \digitsCharacterClass
\XeTeXcharclass `2 \digitsCharacterClass
\XeTeXcharclass `3 \digitsCharacterClass
\XeTeXcharclass `4 \digitsCharacterClass
\XeTeXcharclass `5 \digitsCharacterClass
\XeTeXcharclass `6 \digitsCharacterClass
\XeTeXcharclass `7 \digitsCharacterClass
\XeTeXcharclass `8 \digitsCharacterClass
\XeTeXcharclass `9 \digitsCharacterClass

% adding dots for testing only
\XeTeXinterchartoks \digitsCharacterClass \enDashCharacterClass {.\kern0.05em.}
\XeTeXinterchartoks \enDashCharacterClass \digitsCharacterClass {.\kern0.05em.}

\begin{document}
\textbf{works}

test – test

0 – 0

0–1–2–3–4–5–6–7–8–9–0

\bigskip
\textbf{doesn't work}

test -- test

0 -- 0

0--1--2--3--4--5--6--7--8--9--0

\bigskip
\textbf{should not be kerned}

42-storey building
\end{document}

给出以下结果:只有作为真正的破折号 ( ) 输入的破折号才会进行字距调整,而作为 TeX 连字符 ( ) 输入的破折号--则不会:

第一个结果

如果我们取消注释 MWE 中的一行并将连字符 ( -) 添加到 en-dash 类,--则连字符 ( ) 也会进行字距调整。但不幸的是,这也会影响不应进行字距调整的单个连字符:

第二个结果

笔记:这些点仅用于测试。

答案1

我认为跨字符类是不可能的,因为从--到 endash 的连字符是后来构建的。你所能做的就是通过映射添加一个细小的空格。

例如,通过这种映射,您会在 1 和破折号之间得到一个小的空间:

; TECkit mapping for TeX input conventions <-> Unicode characters

LHSName "kerndash"
RHSName "UNICODE"

pass(Unicode)

; ligatures from Knuth's original CMR fonts
U+002D U+002D                   <>      U+2013  ; -- -> en dash
U+002D U+002D U+002D    <>      U+2014  ; --- -> em dash

pass(Unicode)
U+0031 U+2013 <>  U+0031 U+2009 U+2013
U+0031 U+2014 <>  U+0031 U+2009 U+2014

这个答案显示了如何编译它使用 xetex 更改 OpenType 字体中的破折号字符

测试文档:

\documentclass{article}
\usepackage{fontspec}
\setmainfont{Arial}
\setsansfont[Mapping=kerndash]{Arial}
\begin{document}
1– 1-- 1— 1---

{\sffamily 1– 1-- 1— 1---}

\end{document}

在此处输入图片描述

答案2

(OP 主要要求基于 XeLaTeX 的方法。但是,他也鼓励提交基于 LuaLaTeX 的解决方案。)

这是一个基于 LuaLaTeX 的解决方案。它适用于分别编码为 和-----和 的en-和 破折号。LaTeX 宏可用于根据process_input_buffer需要打开或关闭执行额外字距插入的 Lua 函数的操作(在回调阶段,即在处理阶段的早期)。插入在数字和 en/em 破折号之间的额外字距量可以通过名为 的 LaTeX 宏进行修改\kset,例如\kset{0.07em}。(通过执行 恢复默认的字距量\kset{0.07em}。)

在此处输入图片描述

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{fontspec}

\usepackage{luacode}
\begin{luacode}
kval = "0.05em" -- Set default value of amount of extra kerning
function kern_dashes ( s )
  s = string.gsub ( s , "(%d)%-%-" , "%1\\kern"..kval.."--" )
  s = string.gsub ( s , "%-%-(%d)" , "--\\kern"..kval.."%1" ) 
  s = unicode.utf8.gsub ( s, "(%d)–" , "%1\\kern"..kval.."–" )
  s = unicode.utf8.gsub ( s, "–(%d)" , "–\\kern"..kval.."%1" ) 
  s = unicode.utf8.gsub ( s, "(%d)—" , "%1\\kern"..kval.."—" )
  s = unicode.utf8.gsub ( s, "—(%d)" , "—\\kern"..kval.."%1" ) 
  return s 
end
\end{luacode}
\newcommand{\extrakernOn}{\directlua{
    luatexbase.add_to_callback (   
    "process_input_buffer" , kern_dashes , "kern_dashes" )}}
\newcommand{\extrakernOff}{\directlua{
    luatexbase.remove_from_callback (   
    "process_input_buffer" , "kern_dashes" )}}
\AtBeginDocument{\extrakernOn} % switch function on by default

% Macro to set the amount of extra kerning
\newcommand\kset[1]{\directlua{kval=\luastring{#1}}} 

\begin{document}
\obeylines % just for this example

3--5, 3---5
3–5, 3—5

\extrakernOff % switch off automatic insertion of extra kerns
3--5, 3---5
3–5, 3—5

\extrakernOn% switch automatic insertion of extra kerns back on
\kset{.2em} % quadruple the amount of extra kerning
3--5, 3---5
3–5, 3—5

\end{document}

附录:在上例中,Lua 函数的kern_dashes编写方式是将额外的字距插入到短破折号和长破折号的开头(假设它们前面紧跟一个数字)或短破折号和长破折号的结尾(假设它们后面紧跟一个数字)之前。如果仅当短破折号和长破折号都位于开头时才插入字距后面跟着数字,下面的代码会更合适:

function kern_dashes ( s )
  s = string.gsub ( s , "(%d)%-%-(%d)"   ,  "%1\\kern"..kval.."--\\kern"..kval.."%2" )
  s = string.gsub ( s , "(%d)%-%-%-(%d)" ,  "%1\\kern"..kval.."---\\kern"..kval.."%2" )
  s = unicode.utf8.gsub ( s , "(%d)–(%d)" , "%1\\kern"..kval.."–\\kern"..kval.."%2" )
  s = unicode.utf8.gsub ( s , "(%d)—(%d)" , "%1\\kern"..kval.."—\\kern"..kval.."%2" )
  return s 
end

相关内容