ucharclasses 在间距修饰字母和组合变音符号方面存在错误

ucharclasses 在间距修饰字母和组合变音符号方面存在错误

ucharclasses软件包可以根据 Unicode 字符块自动切换字体(或执行其他有用的操作)。但是,在以下情况下,它似乎无法重置字体:间距修饰字母组合变音符号,与...一起使用时fontspec(在本例中与 XeLaTeX 一起使用)。

我找到了一些解决这个问题的方法,但似乎都无法完全解决这个问题。

我根据正常使用情况和我发现的解决相关问题的几个建议制作了最低限度的工作示例。所有示例都尝试为 IPA 扩展、组合变音符号和间距修饰字母设置衬线字体 (DejaVu Serif),并为其他所有内容设置无衬线字体 (DejaVu Sans)。这两种字体都包含所有测试字符的字形。

  1. 本 mwe 使用常规方法来设置这些字体

    \documentclass{article}
    
    \usepackage{polyglossia}
    \setdefaultlanguage[variant=british]{english}
    \usepackage[Latin, Phonetics, Diacritics, SpacingModifierLetters]{ucharclasses}
    \usepackage{fontspec}
    \defaultfontfeatures{Scale=MatchLowercase,Mapping=tex-text}
    \newfontfeature{IPA}{+mgrk}
    \setmainfont[IPA]{DejaVu Sans}
    \newfontfamily\dejavuserif[IPA]{DejaVu Serif}
    
    \setTransitionsFor{IPAExtensions}{\dejavuserif}{\normalfont}
    \setTransitionsFor{CombiningDiacriticalMarks}{\dejavuserif}{\normalfont}
    \setTransitionsFor{SpacingModifierLetters}{\dejavuserif}{\normalfont}
    
    \begin{document}
    \thispagestyle{empty}
    
    thaaw [tʰɑɑɯ] [tɑɑɯ] [tʰɑ́ɑɯ] [tɑ́ɑɯ] thaaw
    
    \end{document}
    

    使用传统方法输出

    在此示例的输出中,间距修饰字母(在本例中为 [ʰ],U+02B0)或组合变音符号(在本例中为 [◌́],U+301)后面的“单词”中的所有字符都以默认的无衬线字体显示。

  2. 本研究对传统方法进行了轻微修改,基于这个答案

    \documentclass{article}
    
    \usepackage{polyglossia}
    \setdefaultlanguage[variant=british]{english}
    \usepackage[Latin, Phonetics, Diacritics, SpacingModifierLetters]{ucharclasses}
    \usepackage{fontspec}
    \defaultfontfeatures{Scale=MatchLowercase,Mapping=tex-text}
    \newfontfeature{IPA}{+mgrk}
    \setmainfont[IPA]{DejaVu Sans}
    \newfontfamily\dejavuserif[IPA]{DejaVu Serif}
    
    \setTransitionTo{IPAExtensions}{\dejavuserif}
    \setTransitionFrom{IPAExtentions}{\normalfont}
    \setTransitionTo{CombiningDiacriticalMarks}{\dejavuserif}
    \setTransitionFrom{CombiningDiacriticalMarks}{\normalfont}
    \setTransitionTo{SpacingModifierLetters}{\dejavuserif}
    \setTransitionFrom{SpacingModifierLetters}{\normalfont}
    
    \begin{document}
    \thispagestyle{empty}
    
    thaaw [tʰɑɑɯ] [tɑɑɯ] [tʰɑ́ɑɯ] [tɑ́ɑɯ] thaaw
    
    \end{document}
    

    第二种方法的输出

    我没想到这个方法和传统方法有什么不同,但还是有一点小区别:在没有问题字符(即 [tɑɑɯ])的一个“单词”之后,所有字符(“] [t”)直到下一个问题字符(ʰ)都使用衬线字体渲染。否则,它仍然使用无衬线字体渲染问题字符之后的剩余字符。

  3. 本文采用了在这个答案

    \documentclass{article}
    
    \usepackage{polyglossia}
    \setdefaultlanguage[variant=british]{english}
    
    \usepackage[Latin, Phonetics, Diacritics, SpacingModifierLetters]{ucharclasses}
    
    \usepackage{fontspec}
    \defaultfontfeatures{Scale=MatchLowercase,Mapping=tex-text}
    \newfontfeature{IPA}{+mgrk}
    
    \setmainfont[IPA]{DejaVu Sans}
    \newfontfamily\dejavuserif[IPA]{DejaVu Serif}
    
    \setTransitionsFor{IPAExtensions}{\begingroup\dejavuserif}{\endgroup}
    \setTransitionsFor{CombiningDiacriticalMarks}{\begingroup\dejavuserif}{\endgroup}
    \setTransitionsFor{SpacingModifierLetters}{\begingroup\dejavuserif}{\endgroup}
    
    \begin{document}
    \thispagestyle{empty}
    
    thaaw [tʰɑɑɯ] [tɑɑɯ] [tʰɑ́ɑɯ] [tɑ́ɑɯ] thaaw
    
    \end{document}
    

    第三种方法的输出

    这种方法的输出比以前的方法略好一些,因为组合变音符号 (◌́) 的行为符合预期 — 即,它后面的字符都以衬线字体呈现,但前提是它前面没有其他有问题的字符(如 ʰ)。它还会在控制台中产生以下错误:

    ! Extra \endgroup.
    <XeTeXinterchartoks> \endgroup 
    
    l.23 tháaw [tʰɑɑɯ]
                             [tɑɑɯ] [tʰɑ́ɑɯ] [tɑ́ɑɯ] tháaw
    ? 
    ! Extra \endgroup.
    <XeTeXinterchartoks> \endgroup 
    
    l.23 thaaw [tʰɑɑɯ] [tɑɑɯ] [tʰɑ́ɑɯ]
                                                     [tɑ́ɑɯ] thaaw
    ? 
    [1] (./2016-04-02b.aux) )
    
  4. 此 mwe 使用建议的解决方案这个答案

    \documentclass{article}
    
    \usepackage{polyglossia}
    \setdefaultlanguage[variant=british]{english}
    \usepackage[Latin, Phonetics, Diacritics, SpacingModifierLetters]{ucharclasses}
    \usepackage{fontspec}
    \defaultfontfeatures{Scale=MatchLowercase,Mapping=tex-text}
    \newfontfeature{IPA}{+mgrk}
    \setmainfont[IPA]{DejaVu Sans}
    \newfontfamily\dejavuserif[IPA]{DejaVu Serif}
    
    \makeatletter
    \setTransitionsFor{IPAExtensions}
        {\let\curfamily\f@family\let\curshape\f@shape\let\curseries\f@series\dejavuserif}
        {\fontfamily{\curfamily}\fontshape{\curshape}\fontseries{\curseries}\selectfont}
    \setTransitionsFor{SpacingModifierLetters}
        {\let\curfamily\f@family\let\curshape\f@shape\let\curseries\f@series\dejavuserif}
        {\fontfamily{\curfamily}\fontshape{\curshape}\fontseries{\curseries}\selectfont}
    \setTransitionsFor{CombiningDiacriticalMarks}
        {\let\curfamily\f@family\let\curshape\f@shape\let\curseries\f@series\dejavuserif}
        {\fontfamily{\curfamily}\fontshape{\curshape}\fontseries{\curseries}\selectfont}
    \makeatother
    
    \begin{document}
    \thispagestyle{empty}
    
    thaaw [tʰɑɑɯ] [tɑɑɯ] [tʰɑ́ɑɯ] [tɑ́ɑɯ] thaaw
    
    \end{document}
    

    第四种方法的输出

    这种方法的输出似乎表明组合变音符号(◌́)不是问题 - 即,如果没有其他字符(如 [ʰ])使它们成为无衬线,则单词中的后续字符将以衬线字体显示 - 但衬线也会“扩展”到下一个单词中。

我怀疑这是ucharclasses软件包的一个错误或限制。如果能确认这一点,或者提供解决方案或变通方法,我们将非常欢迎。

答案1

在文字中混合 unicode 块 = 人类书写;在输入不同的 unicode 块(或离开它)时设置字体 = ucharclasses。

因此,英语和越南语无法通过字符所属的块来区分,因为它们都共享拉丁块。但英语和古波斯语可以通过字符类来区分。

组合变音符号块与基本拉丁语块不同,所以,是的,这是可能的:

abc 变音符号

甚至这个:

鸡

平均能量损失

\documentclass[12pt]{article}
\usepackage[no-math]{fontspec}
\usepackage[BasicLatin, CombiningDiacriticalMarks]{ucharclasses}
\usepackage{xcolor}



\setmainfont{Noto Serif}
\newfontfamily\fdiac[Colour=red,Scale=1.5]{Fira Sans Black}

\setTransitionTo{BasicLatin}{\normalfont}
\setTransitionTo{CombiningDiacriticalMarks}{\fdiac}

\begin{document}
\large
a a\symbol{"0302} xyẑ abc \ \ o\symbol{"0302}\symbol{"0344}o\symbol{"0302}\symbol{"0321}\symbol{"0325}\symbol{"032C}

\end{document

“不相交”意味着ucharclasses一次只能产生一个输出,而不是两个或更多个输出,因此意味着要处理的字符集不应该重叠或共享元素。

=== 编辑并添加:

这些组合标记确实很有用。

狒狒

的标志为“嗯,哦,呃,嗯,那真是太好了……“ 对话填充词,就像在彬彬有礼的狒狒个体之间的社交互动中使用的那样。

\documentclass[12pt]{article}
\usepackage[no-math]{fontspec}
\usepackage[BasicLatin, CombiningDiacriticalMarks]{ucharclasses}
\usepackage{xcolor}



\setmainfont{Noto Serif}
\newfontfamily\fdiac[Colour=red,Scale=1.5]{Fira Sans Black}
\newfontfamily\fdiacb[Colour=blue,Scale=2.5]{Gentium Plus}


\setTransitionTo{BasicLatin}{\normalfont}
\setTransitionTo{CombiningDiacriticalMarks}{\fdiac}

\begin{document}
\large
 (o\symbol{"0302}\symbol{"032B}{\let\fdiac\fdiacb\symbol{"0308}\symbol{"036A}}o\symbol{"0302}\symbol{"0321}\symbol{"0325}\symbol{"032C})

\end{document}

进一步编辑

关于过渡 -

假设转换需要(顺序?)转换,插入转换,使用{}或零宽度连接器(均在相关代码块之外):

非拉丁语过渡

变音符号和基本字符在字体方面起着一个单位(某种意义上)的作用,因此在基本字符后插入一个过渡。

平均能量损失

\documentclass{article}
\usepackage{xcolor}
\usepackage[Latin, Phonetics, Diacritics, SpacingModifierLetters]{ucharclasses}
\usepackage{fontspec}
\defaultfontfeatures{Scale=MatchLowercase,Mapping=tex-text}
\newfontfeature{IPA}{+mgrk}
\setmainfont[IPA]{DejaVu Sans}
\newfontfamily\dejavuserif[IPA]{DejaVu Serif}[Colour=red]

\setTransitionsFor{IPAExtensions}{\dejavuserif}{\normalfont}
\setTransitionsFor{CombiningDiacriticalMarks}{\dejavuserif}{\normalfont}
\setTransitionsFor{SpacingModifierLetters}{\dejavuserif}{\normalfont}

\newcommand\zwnj{^^^^200c}

\begin{document}

thaaw [tʰ{}ɑɑɯ] [tɑɑɯ] [tʰ{}ɑ́{}ɑɯ] [tɑ́{}ɑɯ] thaaw  
\normalfont

thaaw [t^^^^02b0\zwnj ɑɑɯ] [tɑɑɯ] [tʰ\zwnj ɑ́\zwnj ɑɯ] [tɑ́\zwnj ɑɯ] thaaw  


\end{document}

但是,保持意义单位和显示单位同步可以减轻读者的认知负担:

语音学

平均能量损失

\documentclass{article}
\usepackage{xcolor}
\usepackage{fontspec}
\defaultfontfeatures{Scale=MatchLowercase,Mapping=tex-text}
\newfontfeature{IPA}{+mgrk}
\setmainfont[IPA]{DejaVu Sans}
\newfontfamily\dejavuserif[IPA]{DejaVu Serif}[Colour=red]
\newcommand\ph[1]{[{\dejavuserif #1}]}

\begin{document}

thaaw \ph{tʰɑɑɯ} \ph{tɑɑɯ} \ph{tʰɑ́ɑɯ} \ph{tɑ́ɑɯ} thaaw  

\end{document}

在堆叠变音符号的问题上,字体设计师的手工和选择发挥了作用。

一些随机字体,用于说明:

诺托衬线

诺托衬线

阿姜亚

阿姜亚

阿朱尔

阿朱尔

安迪卡

安迪卡

宋体

宋体

似曾相识的衬线体

似曾相识的衬线体


循环

假设:根本原因是计数从 1 开始,然后向上。仅一次。因此,输入排版流的最后一个字体切换命令是具有可见效果的命令。

当 A 块文本和 B 块文本彼此相邻且没有分隔符时,AB 转换代码循环遍历所有块,发现 A 正在结束,输出“退出 A 块”代码,发现 B 正在开始,输出“进入 B 块”代码 -如果首先检查代码块

如果 A 代码块具有比 B 代码块更高的 Unicode 起点/终点,则循环会发现:B 块正在开始,输出“进入 B 块”代码,发现 A 块正在结束,输出“离开 A 块”代码,并且用户感到惊讶:我们已恢复正常字体(例如)。

在现实生活中,块(用作脚本块)之间的正常分隔符是空格(拉丁语),Tex 将其转换为胶水 - 但如上所述,标点符号块中的 ZW 字符也可以充当其他块(技术上是类,而不是块)之间的“分隔符”。

上层阶级胜过下层阶级。

理想情况下,明确指定代码块转换的所有进入/退出成对组合(其中代码块是连续的文本)将涵盖一般情况 - 跨 Unicode 块文本除外。

如果未使用分隔符,则较高的 unicode 块优先于其他块

平均能量损失

\documentclass{article}
\usepackage{xcolor}
\usepackage[Latin, Cyrillic, Cuneiform, Coptic]{ucharclasses}
\usepackage{fontspec}

\setmainfont{DejaVu Sans}
\newfontfamily\fa{Noto Sans Coptic}[Colour=red]
\newfontfamily\fb{Noto Serif}[Colour=blue]
\newfontfamily\fc{Noto Sans Cuneiform}[Colour=green]

\setTransitionsFor{Coptic}{\fa}{\normalfont}
\setTransitionsFor{Cyrillic}{\fb}{\normalfont}
\setTransitionsFor{Cuneiform}{\fc}{\normalfont}

\newcommand\zwnj{^^^^200c}

\begin{document}
ⲀⲁⲂⲃⲄⲅxАБВГДЕx

答案2

完全不同的方法:将括号[]放入它们自己的 interchartok 类中 - 并且,当它们处于“活动”状态时,它们之间的所有内容都采用相同的字体:

拼音括号

平均能量损失

\documentclass[varwidth,border=6pt]{standalone}
\usepackage{xcolor}
\usepackage{fontspec}
\defaultfontfeatures{Scale=MatchLowercase,Mapping=tex-text}
\newfontfeature{IPA}{+mgrk}
\setmainfont[IPA]{DejaVu Sans}
\newfontfamily\dejavuserif[IPA]{DejaVu Serif}[Colour=red]

% Define the opening-bracket class
\newXeTeXintercharclass\phopenclass
% Add [ to it
\XeTeXcharclass `\[ = \phopenclass\relax
% Define the closing-bracket class
\newXeTeXintercharclass\phcloseclass
% Add ] to it
\XeTeXcharclass `\] = \phcloseclass\relax

% When encountering an open bracket class, no need to insert any code at all.
%\XeTeXinterchartoks 0 \phopenclass {}
%\XeTeXinterchartoks 4095 \phopenclass {}

%When leaving an open bracket behind and encountering normal text or a boundary, switch on the phonetic font:
\XeTeXinterchartoks \phopenclass  4095 {\startphon}
\XeTeXinterchartoks \phopenclass 0 {\startphon}

%When encountering a closing bracket class, insert code to switch back to normal font:
\XeTeXinterchartoks 0 \phcloseclass {\finishphon}
\XeTeXinterchartoks 4095 \phcloseclass {\finishphon}

%When leaving a closing-bracket class, nothing to do: we are already back at normal font.
%\XeTeXinterchartoks \phcloseclass  4095 {}
%\XeTeXinterchartoks \phcloseclass 0 {}

\newcommand\startphon{\dejavuserif}
\newcommand\finishphon{\normalfont}
\XeTeXinterchartokenstate=1%switch on 


\begin{document}

thaaw [tʰɑɑɯ] [tɑɑɯ] [tʰɑ́ɑɯ] [tɑ́ɑɯ] [tʰɑ́ɑɯʰ] thaaw  

\XeTeXinterchartokenstate=0
These brackets [square ones] are [quite] normal text.

\XeTeXinterchartokenstate=1
Back to phonetic [pʰɶɴɛtɪk] brackets.

\end{document}

相关内容