一般讨论;一般交流

一般讨论;一般交流

是否可以重新定义字符组---,以便在键入时输出---两个“en-dash”(––),而不是绘制“em-dash”?

答案1

您可以简单地将---tex 文件中的所有实例替换为--{}--,或者,如果您愿意的话,用替换\textendash\textendash{}

--{}--在 Computer Modern 字体系列中,和的输出---在视觉上难以区分,因为 em-dash 的宽度恰好是 en-dash 的两倍。


如果你选择使用 LuaLaTeX,那么可以简单地设置一个小函数,将所有实例替换为---\textendash\textendash{}即时”,TeX 开始进行常规处理:

\documentclass{article}

\usepackage{luacode}
\begin{luacode}
function em2en ( buff )
  return ( string.gsub ( buff, "%-%-%-", "\\textendash\\textendash{}" ) )
end
luatexbase.add_to_callback( "process_input_buffer", em2en, "em2en" )
\end{luacode}

\begin{document}
--- vs.\ \textendash\textendash
\end{document}

附录:如果目的包括在一对短破折号之间留出一点空白,则只需按如下方式修改 MWE。(此处使用的间距量为\kern0.75pt;您可以根据需要随意更改宽度。)

在此处输入图片描述

\documentclass{article}

\usepackage{luacode}
\begin{luacode}
function em2en ( buff )
  return ( string.gsub ( buff, "%-%-%-", "\\textendash\\kern0.75pt\\textendash{}" ) )
end
luatexbase.add_to_callback( "process_input_buffer", em2en, "em2en" )
\end{luacode}

\begin{document}
---and\textendash\kern0.75pt\textendash
\end{document}

答案2

我仍然欠我(或多或少)承诺的答案,以展示如何通过字体度量数据的补丁来解决这个问题。我把它推迟到现在,因为我们要应对的情况相当复杂和错综复杂,值得仔细解释。


一般讨论;一般交流

输入---被翻译成破折号是您正在使用的特定字体的一个特性:它与将输入转换fi为“fi”连字的机制完全相同。因此,问题似乎是关于如何改变字体设计者有意赋予字体的外观;但正如 Ulrike Fischer 在此评论针对这个问题将“-”更改为\textendash, “如果不喜欢某种字体的外观,一般的建议是:使用其他字体”。

请注意,表示连字的字形也可以通过适当定义的控制序列(或通过\symbolLaTeX 命令或\charTeX 原语)直接访问;在我们的例子中,长破折号的字形也可以通过控制序列(或 LICR 名称)访问\textemdash,并且从问题中无法清楚地知道当以这种方式引用它时是否也应该替换它,或者仅当源包含字符串时才应该替换它---

总是谈到连字,应该指出的是,有众所周知的方法可以选择性地禁用给定的连字符,其中我想回顾以下两个:

  1. selnolig软件包允许基于上下文(而不是文档范围)抑制连字。但请注意,它需要 LuaTeX 作为排版引擎才能部署任何重要功能。

  2. 另一方面,pdfTeX 提供了一个原语(\tagcode),允许有选择地禁用给定字符的某些属性,其中包括其形成连字的能力;但是,它不允许基于上下文的禁用。

但这个问题要求的不仅仅是禁用连字符,而是代替用不同的字符组合来替换它,而上述两种方法都无法实现这一点:事实上,这需要重写连字程序。正是出于这个原因,我才不辞辛劳地写下这个答案:展示如何修改字体的连字程序可能会很有趣。


与字体规格无关的其他可能解决方案

我会考虑两种可能性:使- 角色活跃并使用不同的输入编码;但我只会触及它们,因为它们不是这个答案的主题。

转变-为活跃角色

活动字符是一种行为类似于宏的字符:可以为其分配一个定义,其内容将替换该字符的每次后续出现。在这种情况下,想法是将其定义-为一个宏,它会提前查看后面是否还有两个相同的字符,如果是,则用所需的字符组合替换---三元组。不幸的是,用字符来实现这一点非常尴尬- ,因为它在用于与 TeX 本身通信的数字表达式中也扮演着语法角色(例如\setcounter{FOO}{-1})。在这方面,请注意---1是 的一个完全合法的实例<number>。还应该注意的是,此解决方案不会影响 产生的输出\textemdash,如上所述,输出可能是也可能不是想要的。

使用不同的输入编码

由于计算机是出了名的笨,因此在与计算机打交道时,最好使用不同的符号来传达不同的含义。通过该inputenc包,您只需在源代码中写一个破折号,以指示输出中的破折号:该包会自动将其转换为命令\textemdash,而不会与- TeX 算术中使用的符号混淆。出于这个原因,我认为曼努埃尔的回答是最好的解决方案。


基于字体指标的解决方案:概念证明

TeX 在字体本身的 TFM(TeX Font Metric)文件中查找有关如何从给定字体的字符构建连字的说明,这些说明以所谓的连字程序连字程序最好在字体设计阶段编写,例如,在 METAFONT 源级别,用于使用该语言设计的字体;但如果设计阶段对您来说并不可行(这种情况很可能发生),您也可以在稍后阶段对其进行修改。只需将相关的 TFM 文件转换为 PL(属性​​列表)文件(其完全可读的对应文件),在此 PL 文件中进行所需的更改,然后将其“编译”回 TFM 文件即可。如果您将修改后的 TFM 文件命名为与原始文件相同的名称,并将其放置在与要编译的 TeX 源相同的目录中,如果“运气好”(详情见下文),TeX 将加载它而不是原始文件,从而遵循您的连字程序。如果您将其放在个人或本地(机器范围)texmf 树中,也会发生同样的情况:请参阅发行版的文档以了解适当的位置。例如,对于 MacTeX,相关目录是

~/Library/texmf/fonts/tfm/

(个人 texmf 树),或

/usr/local/texlive/texmf-local/fonts/tfm/

(本地 texmf 树)。

不过,我想再次强调,对字体的连字程序的修改显然既不能改变 的输出\textemdash,也不能改变源文件中逐字写入并通过inputenc包解释的破折号的输出。所以,从现在开始,我会假设所问的问题只是关于如何更改文字输入序列的输出---(毕竟,这就是问题所说的)。

修补连字符程序

让我们直接看一个实际的例子:我们将修改cmr12字体的连字程序,使其---产生两个由非常小的空格(0.9pt)隔开的短划线。我们选择cmr12而不是 的原因,cmr10对于第一个示例,将在下文中变得清晰。

为本示例创建一个新目录并移至该目录。然后输入

tftopl cmr12.tfm cmr12.pl

在命令行上。这将在当前目录中生成文件cmr12.pl。请注意,该tftopl实用程序使用与 TeX 相同的搜索路径来查找 TFM 文件,因此它应该自动选择原始文件。

打开cmr12.pl刚刚创建的文件;它很长,但第一行应该如下

(FAMILY CMR)
(FACE O 346)
(CODINGSCHEME TEX TEXT)
(DESIGNSIZE R 12.0)
(COMMENT DESIGNSIZE IS IN POINTS)
(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)
(CHECKSUM O 13052650413)
(FONTDIMEN
   (SLANT R 0.0)
   (SPACE R 0.3263855)
   (STRETCH R 0.163193)
   (SHRINK R 0.108795)
   (XHEIGHT R 0.430556)
   (QUAD R 0.9791565)
   (EXTRASPACE R 0.108795)
   )
(LIGTABLE

(LIGTABLE行标志着连字程序集合(或表格)的开始。我们无法在此处描述它们的格式,但为了获取继续阅读所需的信息,您可以键入

texdoc pltotf

在命令行上,阅读显示的文档的第 13 节。但请注意,它相当简洁(只有大约半页长)。

连字符的八进制代码为 55,您可以在下面几行找到其相关的连字程序:

   (LABEL O 55)
   (LIG O 55 O 173)
   (STOP)

它规定,如果后面跟着另一个相同的字符,则两个字符都应替换为八进制 173 号槽中的字符;这是短划线。新字符依次进行连字符替换:事实上,我们在下面立即找到了相关的连字符程序。

   (LABEL O 173)
   (LIG O 55 O 174)
   (STOP)

它表示如果一个短破折号 (Octal 173) 后面跟着一个连字符 (Octal 55),那么该对将替换为一个长破折号 (Octal 174)。因此,我们看到这正是我们需要更改的单个程序。可能的补丁如下(您应该代替以下四行代替以上三个):

   (LABEL O 173)
   (/LIG O 55 O 173)
   (KRN O 173 R 0.075)
   (STOP)

现在LIG指令写成(/LIG O 55 O 173):第一个斜线规定该程序应用的字符是不是删除,这就是随后的指令的原因KRN,该指令导致两个相邻的短破折号(即使第二个短破折号刚刚由连字指令添加)由字体设计大小的 0.075 倍的正字距分隔,也就是说,在这个字体的情况下,是 0.9pt。

在保存文件之前,你只需要再做一次更改:转到顶部并删除以下行

(CHECKSUM O 13052650413)

这将指示pltotf程序重新计算校验和,并将我们的修改考虑在内。现在您可以保存修改后的文件,最好使用新名称,例如noemdlig-cmr12.pl

“编译”并使用新的 TFM 文件

编辑 PL 文件后,您需要将其“编译”为 TFM 文件;您可以通过以下命令执行此操作

pltotf noemdlig-cmr12.pl cmr12.tfm

请注意,pltotf程序应该从当前目录加载 PL 文件,并将 TFM 文件保存到当前目录。

好的,现在让我们尝试一下:将以下测试 LaTeX 源保存在相同的目录作为修改后的cmr12.tfm文件

\documentclass[12pt,% This is crucial!
        a4paper% This is not, of course!
    ]{article}
% Note that you must *not* change the default OT1 encoding!

\newcommand*\myFontID{}



\begin{document}

We are now using the font\edef\myFontID{\the\font}
\texttt{\fontname\myFontID},
identified internally by the control sequence
\texttt{\expandafter\string\myFontID}.
This is an em-dash formed by a ligature:%
~---\spacefactor\sfcode`. \space
This, on the other hand, is an em-dash produced by 
\verb|\textemdash|:~\textemdash

\end{document}

并编译它;运气好的话(见下一小节),你会得到以下输出

代码输出

您可以看到,第一个破折号已被两个以细空格隔开的短破折号所取代。

预加载字体的问题

您可能想知道为什么我们坚持在上述示例中使用 12 点大小的 CMR 字体。好吧,让我们尝试用字体重复整个过程cmr10。创建一个新目录,移动到该目录,输入

tftopl cmr10.tfm cmr10.pl

在命令行上,以便在当前目录中获取文件cmr10.pl;按照与上述相同的方式修改此文件并将其保存在名称下noemdlig-cmr10.pl;然后通过发出命令“编译”新的指标文件

pltotf noemdlig-cmr10.pl cmr10.tfm

但是,如果您这样做,然后尝试编译.tex上面显示的相同源代码,将选项的唯一修改12pt替换为10pt,您将无法获得预期的结果: 产生的破折号仍然是单个实心破折号。为什么会发生这种情况?

原因是 LaTeX 格式“合并”了在格式本身构建过程中预加载的一些字体。与这些预加载字体有关的所有信息(包括连字程序)都已存在于格式记录的 TeX 内存的“冻结”图像中,因为在构建格式时已经读取了这些信息。TeX 不会绝不多次加载相同的 TFM 文件,因此对于预加载的字体,根本不可能更改原始连字符。在常规设置下,字体cmr10是预加载的,但cmr12实际上并非如此:这就是为什么我们的第一个示例可以工作,而第二个示例却不行。但请注意,预加载到 LaTeX 格式中的字体集是站点维护者可以自定义的少数几个方面之一,因此在您的特定 LaTeX 安装中设置可能会有所不同:这就是我们上面说 12 点示例需要“一点运气”才能工作的原因。

如上所述,除了使用不同的字体名称外,没有其他办法可以解决这个问题。例如,我们可以将修改后的 PL 文件编译为同名的 TFM 文件

pltotf noemdlig-cmr10.pl noemdlig-cmr10.tfm

然后指示 LaTeX 使用此 TFM 文件而不是cmr10.tfm

\documentclass[10pt,% This is crucial!
        a4paper% This is not, of course!
    ]{article}

% Define a new font family called "modcmr", and specify that 
% "noemdlig-cmr10.tfm" is the TFM file associated with the font from this 
% family in medium weight, normal shape, and 10 point size:
\DeclareFontFamily{OT1}{modcmr}{}
\DeclareFontShape{OT1}{modcmr}{m}{n}{<10> noemdlig-cmr10}{}

% Tell pdfTeX where to find the corresponding PFB file:
\pdfmapline{+noemdlig-cmr10 CMR10 <cmr10.pfb}

% Set "modcmr" as the default seriffed family
% (BEWARE, THIS WON'T WORK IN GENERAL!):
\renewcommand{\rmdefault}{modcmr}

\newcommand*\myFontID{}



\begin{document}

We are now using the font\edef\myFontID{\the\font}
\texttt{\fontname\myFontID},
identified internally by the control sequence
\texttt{\expandafter\string\myFontID}.
This is an em-dash formed by a ligature:%
~---\spacefactor\sfcode`. \space
This, on the other hand, is an em-dash produced by 
\verb|\textemdash|:~\textemdash

\end{document}

这段代码中有两点特别值得注意:

  1. 该文件专门用于 pdfTeX 引擎。以下行

    \pdfmapline{+noemdlig-cmr10 CMR10 <cmr10.pfb}
    

    需要告诉 pdfTeX 我们的新字体的字形应该从哪里获取;这行不通,例如,在使用 生成 DVI 输出时 latex。另一种可能的方法是使用虚拟字体,这种方法省去了线条 \pdfmapline,因此可以应用于任何引擎,虚拟字体本身“知道”在哪里找到自己的字形;然而,这需要创建一个额外的文件(VF,或“虚拟字体”文件),随后 TeX 必须在每次编译时读取该文件,因此这种替代方法在空间和时间方面都效率较低。

  2. 线路

    \renewcommand{\rmdefault}{modcmr}
    

    指示 LaTeX 使用我们的modcmr系列作为默认的 seriffed 系列适合所有体重、形状和尺寸。因此,为了使其正常工作,我们不仅应该提供字体的修改版本cmr,还应该提供所有可用尺寸的cmbxcmsl和的修改版本!cmti

尤其是第二点表明,实际上,预加载字体的问题不仅限于实际预加载的形状和大小,还会传播到包含这些形状和大小的整个字体系列。换句话说,没有有效的解决方法……


基于字体规格的解决方案:工作示例

上面概述的策略可以应用于任何现实生活中的例子吗?我的回答是肯定的,也可以是否定的。以下两个例子应该可以说明我的意思。

一个合理大小的例子

第一个例子使用了times包。由于 Times 字体是可缩放字体,因此在该包提供的设置中,对于每个给定的字体形状,单身的所有大小的 TFM 文件都会被使用。事实证明,只需要修补 8 个 TFM 文件,这就是为什么这个示例仍然可以被视为合理的原因。但是,8 个文件已经足够了,这表明我们可以求助于 shell 脚本。

为此示例创建一个新目录并将以下 TeX 源放入其中:

\documentclass[a4paper]{article} % To avoid confusion, let us explicitly 
                                 % declare the paper format.

\usepackage[T1]{fontenc}         % This example uses T1 encoding; using OT1 
                                 % encoding is also possible, but requires some 
                                 % other modifications besides removing (or 
                                 % changing) this declaration.

\usepackage{times}               % This example specifically uses the fonts 
                                 % selected by this package.

\newcommand*\myFontID{}
\DeclareRobustCommand*\command[1]{%
    \texttt{\char\escapechar #1}%
}
\newcommand*\testtext{%
    \par
    We are now using the font\edef\myFontID{\the\font}
    \texttt{\fontname\myFontID}
    (external name, optionally followed by
    \texttt{at} size at which it is loaded),
    identified internally by the control sequence
    \texttt{\expandafter\string\myFontID}.
    This is an em-dash formed by a ligature:%
    ~---\spacefactor\sfcode`. \space
    This, on the other hand, is an em-dash produced by 
    \command{textemdash}:~\textemdash
    \par
}
\newcommand*\fulltest[1]{%
    \subsection{Test for \command{#1}}%
    \begingroup
        \csname #1\endcsname
        \parskip \smallskipamount
        \tolerance 9000
        \hbadness  9000
        \emergencystretch 3em
        %
        \normalfont
        %
        \upshape\testtext
        \scshape\testtext
        \itshape\testtext
        \slshape\testtext
        %
        \normalfont\bfseries
        %
        \upshape\testtext
        \scshape\testtext
        \itshape\testtext
        \slshape\testtext
    \endgroup
}

\renewcommand*{\thesubsection}{\arabic{subsection}}



\begin{document}

\tableofcontents

\fulltest{normalsize}

\fulltest{small}
\fulltest{footnotesize}
\fulltest{scriptsize}

\fulltest{large}
\fulltest{Large}

\end{document}

编译上述代码并查看输出:破折号全部都存在。现在我们将制作补丁。

将以下 shell 脚本保存在同一目录中:

#! /bin/bash

# Constants

declare -r kern_between_dashes='0.075'
# Modify the above value .......^^^^^
# according to your taste: it represents the amount of space inserted 
# between the two en-dashes that take the place of what would have been 
# the "original" em-dash, expressed in units equal to the design size of 
# the font; for example, for a font with a design size of 10 points, the 
# value "0.075" corresponds to a space of 0.75pt between the dashes.

declare -r new_vp_prefix='noemdlig-'
declare -r vfont_banner_1='Font '
declare -r vfont_banner_2=' with modified em-dash ligature'
declare -r flag_change_comment='MODIFIED LIGATURE FOLLOWS'

declare -ri err_none=0
declare -ri err_bad_line_in_vpl=-1
declare -ri err_vpl_not_created=-2

declare -r errMess_no_error='no error'
declare -r errMess_bad_line_in_vpl='ligature program is not as expected'
declare -r errMess_vpl_not_created='could not create VPL file'
declare -r errMess_generic_error='unknown error'

declare -r warnMess_no_em_lig="this font hasn't got an em-dash ligature"



# Functions

function PrintMessage () {
    { echo "`basename $0`: $1"; } >&2
}



function PrintWarningMessage () {
    PrintMessage "warning in font $1: $2."
}



function PrintErrorMessage () {
    PrintMessage "*ERROR* in font $1: $2."
}



function Error () {
    case $2 in
        ($err_none)
            PrintErrorMessage "$1" "$errMess_no_error"
        ;;
        ($err_bad_line_in_vpl)
            PrintErrorMessage "$1" "$errMess_bad_line_in_vpl"
        ;;
        ($err_vpl_not_created)
            PrintErrorMessage "$1" "$errMess_vpl_not_created"
        ;;
        (*)
            PrintErrorMessage "$1" "$errMess_generic_error"
        ;;
    esac
    exit $2
}



function VFtoVP () {
    vftovp "$1.vf" "$1.tfm" "$1.vpl"
}



function VPtoVF () {
    vptovf "${new_vp_prefix}$1.vpl" "$1.vf" "$1.tfm"
}



function PatchVPLFile () {
    local LINE
    local -i bad_line=0
    local -i lig_seen=0
    
    {
        while IFS= read -r LINE ; do
            if [ "${LINE:0:7}" == '(VTITLE' ] ; then # ) paren match
                echo "(VTITLE $vfont_banner_1$1$vfont_banner_2)"
            elif [ "${LINE:0:9}" == '(CHECKSUM' ] ; then # ) paren match
                # gobble line
                :
            elif [ "${LINE:0:15}" == '   (LABEL O 25)' ] ; then
                # check next two lines
                if IFS= read -r LINE && [ "${LINE:0:18}" == '   (LIG O 55 O 26)' ] ; then
                    if IFS= read -r LINE && [ "${LINE:0:9}" == '   (STOP)' ] ; then
                        lig_seen=1
                        echo "   (COMMENT $flag_change_comment)"
                        echo '   (LABEL O 25)'
                        echo '   (/LIG O 55 O 25)'
                        echo "   (KRN O 25 R $kern_between_dashes)"
                        echo '   (STOP)'
                    else
                        bad_line=1
                    fi
                else
                    bad_line=1
                fi
            else
                # hand line on, unchanged
                echo "$LINE"
            fi
        done
    } <"$1.vpl" >"${new_vp_prefix}$1.vpl"
    
    [ $bad_line -eq 1 ] && return $err_bad_line_in_vpl
    [ $lig_seen -ne 1 ] && PrintWarningMessage "$1" "$warnMess_no_em_lig"
    return $err_none
}



function Process1Font () {
    local -i last_err
    
    # ensure removal of local copies in case called twice
    rm -f "./$1.vf" "./$1.tfm"
    
    VFtoVP "$1" && PatchVPLFile "$1" && VPtoVF "$1"
    last_err=$?
    
    if [ $last_err -ne $err_none ] ; then
        Error "$1" $last_err
    else
        return $err_none
    fi
}






# Main

Process1Font ptmr8t
Process1Font ptmrc8t
Process1Font ptmri8t
Process1Font ptmro8t
Process1Font ptmb8t
Process1Font ptmbc8t
Process1Font ptmbi8t
Process1Font ptmbo8t

运行脚本,然后重新编译上述 LaTeX 源并再次查看结果。

请注意,ptm字体是虚拟字体,因此我们需要处理 VF(虚拟字体)文件以及 TFM 文件,并用 VPL(虚拟属性列表)文件替换 PL 文件。

一个不合理大小的例子

如果每个不同的尺寸都需要不同的 TFM 文件,则需要修补的文件数量很容易增加到数百个。这里我们使用 Computer Modern 的 EC 版本,以避免预加载字体的问题(见上文)。

为此示例创建一个新目录并将以下源保存到其中:

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

\newcommand*\myFontID{}
\DeclareRobustCommand*\command[1]{%
    \texttt{\char\escapechar #1}%
}
\newcommand*\testtext{%
    \par
    We are now using the font\edef\myFontID{\the\font}
    \texttt{\fontname\myFontID}
    (external name, optionally followed by
    \texttt{at} size at which it is loaded),
    identified internally by the control sequence
    \texttt{\expandafter\string\myFontID}.
    This is an em-dash formed by a ligature:%
    ~---\spacefactor\sfcode`. \space
    This, on the other hand, is an em-dash produced by 
    \command{textemdash}:~\textemdash
    \par
}
\newcommand*\fulltest[1]{%
    \subsection{Test for \command{#1}}%
    \begingroup
        \csname #1\endcsname
        \parskip \smallskipamount
        \tolerance 9000
        \hbadness  9000
        %
        \normalfont
        %
        \upshape\testtext
        \scshape\testtext
        \itshape\testtext
        \slshape\testtext
        %
        \normalfont\bfseries
        %
        \upshape\testtext
        \scshape\testtext
        \itshape\testtext
        \slshape\testtext
        %
        \usefont{T1}{cmr}{b}{n} \testtext
        \usefont{T1}{cmr}{m}{ui}\testtext
    \endgroup
}

\renewcommand*{\thesubsection}{\arabic{subsection}}



\begin{document}

\tableofcontents

\fulltest{normalsize}

\fulltest{small}
\fulltest{footnotesize}
\fulltest{scriptsize}

\fulltest{large}
\fulltest{Large}

\end{document}

编译并查看输出。然后在同一目录中保存以下 shell 脚本:

#! /bin/bash

# Constants

declare -r kern_between_dashes='0.075'
# Modify the above value .......^^^^^ according to your taste.

declare -r new_pl_prefix='noemdlig-'
declare -r flag_change_comment='MODIFIED LIGATURE FOLLOWS'

declare -ri err_none=0
declare -ri err_bad_line_in_pl=-1
declare -ri err_pl_not_created=-2

declare -r errMess_no_error='no error'
declare -r errMess_bad_line_in_pl='ligature program is not as expected'
declare -r errMess_pl_not_created='could not create PL file'
declare -r errMess_generic_error='unknown error'

declare -r warnMess_no_em_lig="this font hasn't got an em-dash ligature"



# Functions

function PrintMessage () {
    { echo "`basename $0`: $1"; } >&2
}



function PrintWarningMessage () {
    PrintMessage "warning in font $1: $2."
}



function PrintErrorMessage () {
    PrintMessage "*ERROR* in font $1: $2."
}



function Error () {
    case $2 in
        ($err_none)
            PrintErrorMessage "$1" "$errMess_no_error"
        ;;
        ($err_bad_line_in_pl)
            PrintErrorMessage "$1" "$errMess_bad_line_in_pl"
        ;;
        ($err_pl_not_created)
            PrintErrorMessage "$1" "$errMess_pl_not_created"
        ;;
        (*)
            PrintErrorMessage "$1" "$errMess_generic_error"
        ;;
    esac
    exit $2
}



function TFtoPL () {
    tftopl "$1.tfm" "$1.pl" 2> /dev/null
}



function PLtoTF () {
    pltotf "${new_pl_prefix}$1.pl" "$1.tfm"
}



function PatchPLFile () {
    local LINE
    local -i bad_line=0
    local -i lig_seen=0
    
    {
        while IFS= read -r LINE ; do
            if [ "${LINE:0:9}" == '(CHECKSUM' ] ; then # ) paren match
                # gobble line
                :
            elif [ "${LINE:0:15}" == '   (LABEL O 25)' ] ; then
                # check next two lines
                if IFS= read -r LINE && [ "${LINE:0:18}" == '   (LIG O 55 O 26)' ] ; then
                    if IFS= read -r LINE && [ "${LINE:0:9}" == '   (STOP)' ] ; then
                        lig_seen=1
                        echo "   (COMMENT $flag_change_comment)"
                        echo '   (LABEL O 25)'
                        echo '   (/LIG O 55 O 25)'
                        echo "   (KRN O 25 R $kern_between_dashes)"
                        echo '   (STOP)'
                    else
                        bad_line=1
                    fi
                else
                    bad_line=1
                fi
            else
                # hand line on, unchanged
                echo "$LINE"
            fi
        done
    } <"$1.pl" >"${new_pl_prefix}$1.pl"
    
    [ $bad_line -eq 1 ] && return $err_bad_line_in_pl
    [ $lig_seen -ne 1 ] && PrintWarningMessage "$1" "$warnMess_no_em_lig"
    return $err_none
}



function Process1FontSize () {
    local -i last_err
    
    # ensure removal of local copies in case called twice
    rm -f "./$1.pl" "./$1.tfm"
    
    TFtoPL "$1" && PatchPLFile "$1" && PLtoTF "$1"
    last_err=$?
    
    if [ $last_err -ne $err_none ] ; then
        Error "$1" $last_err
    else
        return $err_none
    fi
}



function Process1Font () {
    local csiz
    
    for csiz in '0500' '0600' '0700' '0800' '0900' '1000' \
                '1095' '1200' '1440' '1728' \
                '2074' '2488' '2986' '3583' ; do
        Process1FontSize "$1${csiz}"
    done
}






# Main

for font in 'bi' 'bl' 'bx' 'cc' 'ci' 'oc' 'rb' 'rm' 'sc' 'si' \
            'sl' 'so' 'ss' 'sx' 'ti' 'ui' 'xc' ; do
    Process1Font "ec${font}"
done

运行脚本(注意,这次将需要一分钟左右),重新编译,然后再次查看输出。


足够的!

答案3

混合一些其他答案。我会使用 utf8 字符,并且我会正确使用它们,当有连字符时使用连字符,当有短破折号时使用短破折号,当有长破折号时使用长破折号。然后更改这些符号的输出。

就我个人而言,我会加载

\usepackage[utf8]{inputenc}

然后搜索并替换---into (em-dash) 和--into (en-dash)。然后我会重新定义

\let\textemdash\relax
\DeclareRobustCommand\textemdash{\textendash\textendash}

并在其位置上正确地使用每一个,使得输出不同。

\documentclass{scrartcl}

\usepackage[utf8]{inputenc}
\protected\def\textemdash{\textendash\textendash}

\begin{document}

This is an em-dash — and this is two en-dashes ––.

\end{document}

我期待Gustavo Mezzeti的回答。

相关内容