我的文档中使用的字体提供哪些连字符?

我的文档中使用的字体提供哪些连字符?

这是一个后续问题:我如何知道我的文档中使用了哪些连字符?

为了知道我可能会考虑禁用哪些连字符(我想到的是microtype命令\DisableLigatures;有关选择性禁用连字符的一些重要说明,请参见这个问题),了解可能应用哪些连字符将非常有用。我的文档中使用的字体提供哪些连字符?

答案1

下面介绍了 pdftex 和 Type 1 字体的解决方案。由于 TeX 不提供将连字分解为其组成字符的任何可能性(这些信息在它们被连字替换后会丢失),因此我们必须采取相反的方法:我们循环遍历字体中的所有字形对,将它们排版在临时框中,然后通过 etex 测试\lastnodetype我们是否已获得连字。然后,我们可以将连字字符的槽号写入文件log和/或实际排版连字及其部分,而连字的槽号仅在 中可用\showbox(见下文)。

\RequirePackage{fix-cm}
\documentclass[12pt]{article}
\usepackage[LY1,T1]{fontenc}
\usepackage{fixltx2e}[2006/09/13]
\usepackage[expansion=false]{microtype}
\usepackage{yfonts}
% enable microtype's no ligatures procedure, without actually disabling any ligatures
\DisableLigatures{encoding = }
\makeatletter
\showboxbreadth100
\showboxdepth100
\newcount\MT@ligcount
\newbox\MT@ligbox
\newtoks\MT@ligtoks
\def\MT@showligs{%
  \MT@info@nl{showing ligatures in font `\MT@@font'}%
  \let\lig@temp\@empty
  % loop over all glyph pairs in the font
  \MT@do@font{%
    %\iffontchar\MT@font\@tempcnta\relax  % only test those glyphs that
    \ifnum\tagcode\MT@font\@tempcnta=\@ne % have a "lig/kern program"
      \MT@ligcount\z@
      \loop
      \iffontchar\MT@font\MT@ligcount
        \setbox\@tempboxa\hbox{\MT@font
          \setbox\MT@ligbox\hbox{\char\@tempcnta\char\MT@ligcount}%
          \unhbox\MT@ligbox
          \ifnum\lastnodetype=7 % ligature
            \aftergroup\@firstofone
          \else
            \aftergroup\@gobble
          \fi
        }%
        {% info in the log file
        %\showbox\@tempboxa
         \MT@info@nl{\the\@tempcnta\space + \the\MT@ligcount}%
         % store information for later
         \edef\lig@temp{\lig@temp
             \noexpand\char\the\@tempcnta\noexpand\char\the\MT@ligcount
            $($\noexpand\char\the\@tempcnta$^{[\the\@tempcnta]}$%
               \noexpand\char\the\MT@ligcount$^{[\the\MT@ligcount]}),$ }%
         }%
      \fi
      \advance\MT@ligcount\@ne
      \ifnum\MT@ligcount < \@cclvi \repeat
    \fi
  }%
  \ifx\lig@temp\@empty
    \edef\lig@temp{\noexpand\normalfont No ligatures in `\MT@@font'.}
  \else
    \edef\lig@temp{\noexpand\normalfont Ligatures in `\MT@@font': \MT@font\lig@temp}%
  \fi
  \global\MT@ligtoks\expandafter\expandafter\expandafter
    {\expandafter\the\expandafter\MT@ligtoks\lig@temp\par}%
}

% hook into microtype to make sure that all fonts are caught
\let\MT@noligatures@orig\MT@noligatures
\def\MT@noligatures{\MT@noligatures@orig\MT@showligs}

\AtEndDocument{\par\hrule\the\MT@ligtoks}

\begin{document}

Selecting 
{\fontencoding{LY1}\selectfont various} 
\textit{(including $\mathrm{maths}$)} 
\textfrak{fonts:}

\end{document}

显示连字输出

取消注释该\showbox行将允许以笨拙的方式找出连字的槽号,它将以如下形式呈现:

> \box12=
hbox(5.1654+0.0)x11.74713
.T1/cmr/m/n/12 ^^V (ligature ^^U-)

这里显示了三重连字符 — ( emdash),由连字符 – ( endash) 和字符 - ( hyphen) 组成,通常写为---,其中^^V= 22,且^^U= 21 (转换规则这里)。除此之外,获取连字的槽号需要离开 pdftex 领域并依靠检查tfm文件(参见@egreg 的解决方案)、使用 metapost(@AndrewKepert)或(可能)luatex。

答案2

如果您有.tfm基础字体,即经典字体之一,您可以检查该文件。假设您想了解pplr8t(Palatino Roman,T1 编码)。然后您可以运行此 shell 命令

tftopl pplr8t.tfm > pplr8t.pl

pplr8t.pl文件中,查找LIGTABLE;这是文件开头附近的一大块。如果您运行 grep 搜索,例如

egrep '\(LABEL|LIG|STOP\)' pplr8t.pl

你会得到

(LIGTABLE
   (LABEL O 25)
   (LIG O 55 O 26)
   (STOP)
   (LABEL O 33)
   (LIG C i O 36)
   (LIG C l O 37)
   (STOP)
   (LABEL O 40)
   (STOP)
   (LABEL O 41)
   (LIG O 140 O 275)
   (STOP)
   (LABEL O 47)
   (LIG O 47 O 21)
   (STOP)
   (LABEL O 54)
   (LIG O 54 O 22)
   (STOP)
   (LABEL O 55)
   (LIG O 55 O 25)
   (LIG O 177 O 177)
   (STOP)
   (LABEL O 74)
   (LIG O 74 O 23)
   (STOP)
   (LABEL O 76)
   (LIG O 76 O 24)
   (STOP)
   (LABEL O 77)
   (LIG O 140 O 276)
   (STOP)
   (LABEL C A)
   (STOP)
   (LABEL C F)
   (STOP)
   (LABEL C L)
   (STOP)
   (LABEL C P)
   (STOP)
   (LABEL C R)
   (STOP)
   (LABEL C T)
   (STOP)
   (LABEL C V)
   (STOP)
   (LABEL C W)
   (STOP)
   (LABEL C Y)
   (STOP)
   (LABEL O 140)
   (LIG O 140 O 20)
   (STOP)
   (LABEL C f)
   (LIG C i O 34)
   (LIG C f O 33)
   (LIG C l O 35)
   (STOP)
   (LABEL C r)
   (STOP)
   (LABEL C v)
   (STOP)
   (LABEL C w)
   (STOP)
   (LABEL C y)
   (STOP)
   (LABEL O 200)
   (STOP)
   (LABEL O 201)
   (STOP)
   (LABEL O 210)
   (STOP)
   (LABEL O 212)
   (STOP)
   (LABEL O 217)
   (STOP)
   (LABEL O 220)
   (STOP)
   (LABEL O 224)
   (STOP)
   (LABEL O 225)
   (STOP)
   (LABEL O 230)
   (STOP)
   (LABEL O 300)
   (STOP)
   (LABEL O 301)
   (STOP)
   (LABEL O 302)
   (STOP)
   (LABEL O 303)
   (STOP)
   (LABEL O 304)
   (STOP)
   (LABEL O 305)
   (STOP)
   (LABEL O 335)
   (STOP)
      (LIG O 55 O 26)
      (LIG C i O 36)
      (LIG C l O 37)
      (LIG O 140 O 275)
      (LIG O 47 O 21)
      (LIG O 54 O 22)
      (LIG O 55 O 25)
      (LIG O 177 O 177)
      (LIG O 74 O 23)
      (LIG O 76 O 24)
      (LIG O 140 O 276)
      (LIG O 140 O 20)
      (LIG C i O 34)
      (LIG C f O 33)
      (LIG C l O 35)

相关块的形式如下

   (LABEL O 41)
   (LIG O 140 O 275)
   (STOP)

这意味着字符“八进制 41”(即!)后跟“八进制 140”(即`)应该更改为字体位置“八进制 275”的字符。

相似地,

   (LABEL C f)
   (LIG C i O 34)
   (LIG C f O 33)
   (LIG C l O 35)
   (STOP)

表示f后面跟着的i字符变为“八进制 34”位置中的字符,后面跟着的字符f变为“八进制 33”,后面跟着的字符变为l“八进制 35”。还有一个“八进制 33”的条目:

   (LABEL O 33)
   (LIG C i O 36)
   (LIG C l O 37)
   (STOP)

因此组合ffi首先变成“八进制 33”,然后变成“八进制 36”。

如果你想禁用“ffl”连字,你必须告诉microtype删除以“octal 33”开头的连字,这可以这样做

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{microtype}

\catcode`\^^[=12 % for technical reasons

\DisableLigatures[^^[]{encoding=T1}

\begin{document}
ffl ffi
\end{document}

由于“八进制 33”不可打印,因此必须使用低级技巧来指定它(^^[,因为的字符代码[是“八进制 133”)。这个\catcode技巧是因为 LaTeX 默认将所有不可打印的字符声明为无效。

但是,您无法使用此microtype方法来禁用ffl并保留ffi

在此处输入图片描述

答案3

关于上述评论

“不幸的是,我不知道如何从排版文本中找出连字符的槽号。”

我想我确实知道一种方法 - 它们可以从 dvi 中提取出来。由于 dvi 的可读性不强,我知道的最简单的方法是使用 metapost,它可以很轻松地生成 tex 文件,将它们排版为 dvi,输入 dvi,分解图片并进行分析。这可能不是最好的方法!

以下是快速而粗略的版本:

input TEX

pair pt[];
string s[],temp_fname;
picture lig[][];

string fontname;

fontname="cmbx12";
minchar:=0;
maxchar:=127;


def charcount(expr obj)=
    begingroup
    if (textual obj): 
        (length textpart obj)
    elseif (picture obj) and (length(obj)>0) :
        (for $ within obj: charcount($) + endfor 0)
    else: 0
    fi
    endgroup
    enddef;

def charcodelist(expr obj)=
    begingroup save s; string s;
    if (textual obj):
        s:=textpart obj;
        (for i=0 upto (length s)-1:
                decimal(ASCII(substring(i,i+1) of s)) & 
            endfor ""
            )
    elseif (picture obj) and (length(obj)>0) :
        (for $ within obj:  charcodelist($) & endfor "")
    else:
        ""
    fi
    endgroup
    enddef;


% quickly generate a file with all possible character pairs, then read it back in
temp_fname:=jobname&"-temp.mp";

write "verbatimtex \font\myfont="&fontname&"etex" to temp_fname;
for i = minchar upto maxchar:
    for j = minchar upto maxchar:
        write "lig["&decimal(i)&"]["&decimal(j)&"]:=btex \myfont\char"&decimal(i)&"\char"&decimal(j)&" etex;"
            to temp_fname;
    endfor
endfor
write EOF to temp_fname;
scantokens ("input "&temp_fname)



beginfig(1)
    draw TEX("Ligatures in "&fontname) shifted (0,20);
    pt0:=origin;
    for i = minchar upto maxchar:
        for j = minchar upto maxchar:
            if charcount(lig[i][j])=1:
                draw char(i) infont fontname shifted pt0;
                draw decimal(i) infont "cmr10" shifted (pt0+20right);
                draw char(j) infont fontname shifted (pt0+50right);
                draw decimal(j) infont "cmr10" shifted (pt0+70right);
                draw lig[i][j]  shifted (pt0+100right);
                draw charcodelist(lig[i][j]) infont "cmr10" shifted (pt0+120right);
                pt0:=pt0+20down;
            fi
        endfor
    endfor
endfig;

bye

产生如下输出:

在此处输入图片描述

答案4

这里http://www.gust.org.pl/projects/pearls/2005p/index_html(测试两个字符是否形成连字,作者 Petr Olšák)我们可以找到一个完美的两个字符的解决方案:

\newif\ifligature
\def\testligature #1#2{\setbox0=\hbox{%
   \thickmuskip=1000mu \textfont0=\the\font
   $\mathchar`#1 \mathrel\mathchar`#2$}%
   \ifdim\wd0>500pt \ligaturefalse \else \ligaturetrue \fi}

添加循环很容易。

相关内容