首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Daring Fireball: Markdown
CommonMark
Mou Markdown Editor for OS X
MacDown Open Source Markdown Editor
Marked
GitHub Flavored Markdown
V2EX  ›  Markdown

英文居然有“合字”这种冷知识,用 typora 输出 pdf 时碰到坑了

  •  1
     
  •   tankb52 · 120 天前 · 9413 次点击
    这是一个创建于 120 天前的主题,其中的信息可能已经有所发展或是发生改变。

    给新人写说明文档,当中有 wifi 一词,输出 pdf 后,新人直接复制文档中的内容,执行的时候出问题了。
    我查看日志发现是 wifi 处出现了乱码,好生奇怪。
    去网上一搜,才知道英文中有“合字”这一概念, 见 WIKI: 合字 ,常见的 æ& 就是合字。 我碰到的坑,就是wifi 中的 fi,输出文档时,被当成了合字,虽然显示是正常的,但复制后搜索,两个字母合在一起,变成了另外一个字符
    我不确认这是 Typora 的 bug 还是 Win10 的 bug,看了维基也不是很理解合字的用途。但 wifi是一个很常见的单字,不知道大家在写文档的时候,有碰到过类似的问题吗?又是如何解决的呢?

    第 1 条附言  ·  120 天前
    补充一下:wifi 是命令中需要用到的字符,所以没办法改成 Wi-Fi 等更标准的写法。
    第 2 条附言  ·  120 天前
    多谢 23# 的提醒。
    我重试了一下,
    放在代码块里的字符复制就没有问题。
    放在表格里面的字符复制就会出现合字。
    46 回复  |  直到 2019-05-03 09:11:29 +08:00
        1
    deepdark   120 天前 via Android
    一般不都是 WI-FI 吗
        2
    mytry   120 天前
    还有更神奇的呢,'fi'.toUpperCase() == 'FI','ffi'.toUpperCase() == 'FFI'
        3
    UIXX   120 天前
    标准表达 Wi-Fi
        4
    mytry   120 天前
    汉子也还有啊,嬲(逃)
        5
    cway   120 天前
    用 Typora 测试了下,生成后的 pdf 没这
        6
    geelaw   120 天前 via iPhone   ♥ 4
    这并不是一个 bug。这是是 Unicode 把 codepoint 和渲染方式耦合的结果,一个正确的文本搜索算法应该进行 Unicode 规范化比较,在某些模式下 fi 合字和 fi 应当是相等的。

    很多排版系统为了确保某些字最终显示、印刷是以合字的形式出现,会选择用合字字符替换原来的字符序列。

    另外,合字并不是只有拉丁文本才有,汉语的 biáng biáng 面的那个字也是合字,招财进宝也可以合为一个字,此外阿拉伯语有非常非常多的合字。

    我个人喜欢把合字叫做连笔,这是一种书法风格。
        7
    tinkerer   120 天前
    @geelaw 所以... 是因为 PDF 为了打印效果转成合字了么
        8
    xiaolanger   120 天前
    @Livid 我说句题外话,右侧的 Mou 链接 是不是可以下了?
        9
    marsgt   120 天前
    替换成“ WiFi ”更正规吧,或者你找找字体设置里有没有 OpenType 的连字选项,或者干脆换个非 OTF 的字体好了。。
    这个用途主要是在老式的排版里,会把常见的一些组合(比如 fi、ff )打成一个铅字,这样 2 合 1 了之后会比较省纸。。
        10
    geelaw   120 天前 via iPhone   ♥ 1
    @tinkerer #7 是的,这个和字体也有关系,例如有些字体只有在显示合字字符时才用合字风格,另外一些字体则可以把多个字符连排时就显示合字(可以注意很多手写字体在小写字母旁边有其他字母时会进行连接,就是用了对合字排版的支持),也和排版软件(的选项)有关系。
        11
    tinkerer   120 天前
    @geelaw 学习了
        12
    marsgt   120 天前
    其实技术这块你可以直接找个等宽字体试试,一般代码字体撑死了就 FireCode 这种只合“=>”、“===”符号的。有中文的话可以用更纱黑( https://github.com/be5invis/Sarasa-Gothic/releases )这种同时压进了英文和中文的。
        13
    tankb52   120 天前
    @marsgt
    Typora 编辑和导出 PDF 时,好像都没有字体设置啊?
        14
    marsgt   120 天前   ♥ 1
    @tankb52
    我查了下文档,好像字体得手写 CSS🤦‍♂
    或者你试试换个主题?主题里好像会改字体
        15
    tankb52   120 天前
    @geelaw
    那我这种情况有什么办法规避呢?
        16
    Universe   120 天前 via Android
    想到写 python2 的时候处理字符串,用 strip(char)的时候,有可能会因为 utf8 格式汉字的后半正好是 char 而被吞掉半个字造成不能 decode 回 unicode 的情况。。。
        17
    awesomes   120 天前
    @mytry 有啥神奇的 'fi'.toUpperCase() == 'FI' 和 ’'ffi'.toUpperCase() == 'FFI' 都为 true
        18
    arfaWong   120 天前 via Android
    PDF 阅读器的锅,曾经遇到类似的情况
        19
    tinkerer   120 天前
    @awesomes fi 是一个字符, 并不是 f 和 i
        20
    mytry   120 天前
    @awesomes 'ffi'.length ===1 'FFI'.length === 3
        21
    est   120 天前
    不冷。还有更好玩的用法。Ligature 用来打码!
        22
    halou12   120 天前
        23
    yzwduck   120 天前   ♥ 1
    “合字”的准确叫法是 ligature,已经存在几百年了,也是字体的基础特性之一。如果 PDF 里 ligature 的复制粘贴出问题的话,锅需要甩给生成 PDF 的软件,而不是 PDF 阅读器 @arfaWong
    要么换个生成 PDF 的软件,要么试试换个字体。
    题外话: 命令一般是要用等宽字体的吧。
        24
    tankb52   120 天前
    @yzwduck #23
    也不是专门写的代码,有高亮就不错了。
    只是把一行命令写在文档里,读者再把命令拷到工具里直接执行。
    我是用 typora 直接导出 pdf 的,一般不直接导出那用什么生成 pdf 呢?
        25
    kmahyyg   120 天前 via iPad   ♥ 1
    @tankb52 #24 你没有用 markdown 的 code block 吧. 正确操作不是 monospace 么
        26
    jadec0der   120 天前   ♥ 1
    实际上,类似的需求在使用拉丁字符的语言中同样存在。最典型的是西文排版中所谓 「合字」( ligature )的概念,即针对 ff、fi 这样笔画容易「打架」的字符组合,将其当作一个整体来专门设计造型。因此,这些字符组合在 Unicode 中需要有独立的码位,如 ff (U+FB00)、fi (U+FB01) 等(请试着动手复制一下这些字符)。可是,合字在显示时是一个整体,而在复制和搜索时却要看作两个独立的字符。而在 PDF 中,合字的这种双重身份也正是通过 CMap 的「一对多」映射实现的。

    因此,复制文字重复的故障,其责任并不在于 PDF 的编码。「一对多」的映射并不是一种冗余或者混淆,而是为了适应机器和用户的不同需要而必须加入的特殊处理。说到底,还是预览 App 的优化功夫没下到家,没有意识到 PDF 文本在显示、复制、搜索时应该受到不同的对待。这也再次应证了我之前文章中的一个观点:PDF 阅读器很多时候拼的不是功能有多丰富(反正都拼不过亲儿子 Acrobat ),而是能不能做好复制、搜索这些基础功能的细节。

    -《 PDF 复制中的文字重复问题》
    https://sspai.com/post/52073
        27
    tankb52   120 天前
    @kmahyyg #25
    啊,对了,有一段是因为要对比几行近似的命令,我写在了表格里面。
        28
    xiangyuecn   120 天前
    歪个楼 emoji 0x200d 控制字符,人物疯狂叠加

        29
    xiangyuecn   120 天前
    忘记一个好玩的了:泰文
        30
    tankb52   120 天前
    @kmahyyg #25
    刚刚试了一下,还真是。
    在代码块里面的复制就没有问题。
    在表格里面的复制就出现合字了。
        31
    tankb52   120 天前
    @cway #5
    找到原因了。你有兴趣可以再试一下,把 wifi 放在代码里面和放在表格里面。

    在代码块里面的复制就没有问题。
    在表格里面的复制就出现合字了。
        32
    whileFalse   120 天前
    PDF 是一种打印格式,其设计目的是可以完全确保显示不乱。
    不建议将需要复制的文本放在 PDF 里面。我所使用过的阅读器在复制文本时都会有这样那样的错误。也许 Adobe 的亲儿子做的很好,我反正是用不起。

    还是建议用 markdown (不要导出!)。
        33
    tankb52   120 天前
    @whileFalse #32
    我没法控制别人不偷懒复制——其实我有时也会偷这个懒。
    我只能优先保证排版不乱。
    直接输出 MD 文件,还得考虑对方手上有没有 markdown。
        34
    iowt   120 天前   ♥ 1
    https://upload.wikimedia.org/wikipedia/commons/thumb/8/8b/Long_S-I_Garamond_sort_001.png/440px-Long_S-I_Garamond_sort_001.png

    把 fi 和 ffi 等替换成单字是铅字时代就有的做法,例如上面的图片就是 Garamond 字体中的 fi 铅字。Unicode 在制定码位的时候,考虑到历史原因,把很多常用的铅字和电报控制字符都加入了,于是 fi 等连字( ligature )也有了自己的编码码位。

    但在那时,带有高级排版功能的 OpenType 还没有出现,所以那时的排版软件都会手动把 fi 这类字符替换成对应的合字,以达到排版需求,但坏处是复制时也会复制成合字,而不是原本的字符序列。

    直到后来 OpenType 增加了 GSUB、GPOS 和 GDEF 这三个表掌管各种合字的替换,这时候才能做到使得在原文字不变的情况下,在软件的渲染中仍然显示合字。Iosevka 和 Fira Code 这样能在代码编辑器中加入丰富的图形符号的字体(见下图)就是利用了这一点。

    https://github.com/tonsky/FiraCode/raw/master/showcases/swift.png

    https://raw.githubusercontent.com/be5invis/Iosevka/master/images/ligations.png
        35
    iowt   120 天前
    另外,有些 PDF 阅读器应该做到拆分复制合字以及删除跨行单词被插入的连字符。
        36
    nu11001   120 天前
    用反引号``不会被合
        37
    mcfog   120 天前
    font ligature 和 unicode grapheme 是两个不一样的机制吧,前者是发生在渲染过程的,二进制数据和分开写并没有区别,后者是二进制数据也发生了变化的,分开写和组合在一起的 unicode 表示都是不一样的
        38
    ho121   120 天前 via Android
        39
    laqow   120 天前 via Android
    所以为什么作为 markdown 这种求快求方便的应用要将文字排版的功能搞这么复杂呢
        40
    cyspy   120 天前
    应该说是开源软件对 pdf 的处理各有不同
        41
    whileFalse   120 天前 via iPhone
    @tankb52 代码块用的是等宽字体,所以不会出现合字。
        42
    lulinux   120 天前 via Android
    这应该叫字母连写吧。做过英文字体的人都知道这样设计更好看。
        43
    ps1aniuge   119 天前
    @tinkerer 没法重现楼主的问题。
    1 win10。
    2 office2019。
    3 新建表格。写入 aaaa bbbb wifi cccc,字体用默认的,即等线西文字体。
    4 word 直接就可以另存为 pdf。
    5 打开 pdf 文档,复制表格中的文字,粘贴在记事本中。

    我觉得更换字体,成为新宋体,或微软雅黑。或用 word 的另存为。就不会有楼主问题。
        44
    dalieba   119 天前 via Android
    还可以装个虚拟打印机软件,比如 doPDF,PDFCreator,CutePDF
        45
    dalieba   119 天前 via Android
    另外这种合字可以用 zwnj 这个字符断开。
        46
    ylrshui   114 天前 via iPhone
    是为了排版更好看,tex 里就会这样做,但似乎只是缩小 fi 之间的距离,而不会影响复制
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2008 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 22ms · UTC 02:34 · PVG 10:34 · LAX 19:34 · JFK 22:34
    ♥ Do have faith in what you're doing.