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

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

  •  1
     
  •   tankb52 · 2019-04-26 17:12:08 +08:00 · 20749 次点击
    这是一个创建于 2022 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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

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

    xiangyuecn
        29
    xiangyuecn  
       2019-04-26 18:30:37 +08:00
    忘记一个好玩的了:泰文
    tankb52
        30
    tankb52  
    OP
       2019-04-26 18:32:56 +08:00
    @kmahyyg #25
    刚刚试了一下,还真是。
    在代码块里面的复制就没有问题。
    在表格里面的复制就出现合字了。
    tankb52
        31
    tankb52  
    OP
       2019-04-26 18:34:13 +08:00
    @cway #5
    找到原因了。你有兴趣可以再试一下,把 wifi 放在代码里面和放在表格里面。

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

    还是建议用 markdown (不要导出!)。
    tankb52
        33
    tankb52  
    OP
       2019-04-26 18:40:58 +08:00
    @whileFalse #32
    我没法控制别人不偷懒复制——其实我有时也会偷这个懒。
    我只能优先保证排版不乱。
    直接输出 MD 文件,还得考虑对方手上有没有 markdown。
    iowt
        34
    iowt  
       2019-04-26 19:02:22 +08:00   ❤️ 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
    iowt
        35
    iowt  
       2019-04-26 19:06:38 +08:00
    另外,有些 PDF 阅读器应该做到拆分复制合字以及删除跨行单词被插入的连字符。
    nu11001
        36
    nu11001  
       2019-04-26 19:12:03 +08:00
    用反引号``不会被合
    mcfog
        37
    mcfog  
       2019-04-26 19:12:33 +08:00
    font ligature 和 unicode grapheme 是两个不一样的机制吧,前者是发生在渲染过程的,二进制数据和分开写并没有区别,后者是二进制数据也发生了变化的,分开写和组合在一起的 unicode 表示都是不一样的
    ho121
        38
    ho121  
       2019-04-26 19:41:24 +08:00 via Android
    laqow
        39
    laqow  
       2019-04-26 19:45:47 +08:00 via Android
    所以为什么作为 markdown 这种求快求方便的应用要将文字排版的功能搞这么复杂呢
    cyspy
        40
    cyspy  
       2019-04-26 19:53:44 +08:00
    应该说是开源软件对 pdf 的处理各有不同
    whileFalse
        41
    whileFalse  
       2019-04-27 07:21:43 +08:00 via iPhone
    @tankb52 代码块用的是等宽字体,所以不会出现合字。
    lulinux
        42
    lulinux  
       2019-04-27 08:08:47 +08:00 via Android
    这应该叫字母连写吧。做过英文字体的人都知道这样设计更好看。
    ps1aniuge
        43
    ps1aniuge  
       2019-04-27 14:48:17 +08:00
    @tinkerer 没法重现楼主的问题。
    1 win10。
    2 office2019。
    3 新建表格。写入 aaaa bbbb wifi cccc,字体用默认的,即等线西文字体。
    4 word 直接就可以另存为 pdf。
    5 打开 pdf 文档,复制表格中的文字,粘贴在记事本中。

    我觉得更换字体,成为新宋体,或微软雅黑。或用 word 的另存为。就不会有楼主问题。
    dalieba
        44
    dalieba  
       2019-04-27 18:33:00 +08:00 via Android
    还可以装个虚拟打印机软件,比如 doPDF,PDFCreator,CutePDF
    dalieba
        45
    dalieba  
       2019-04-27 18:35:12 +08:00 via Android
    另外这种合字可以用 zwnj 这个字符断开。
    ylrshui
        46
    ylrshui  
       2019-05-03 09:11:29 +08:00 via iPhone
    是为了排版更好看,tex 里就会这样做,但似乎只是缩小 fi 之间的距离,而不会影响复制
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4967 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 03:53 · PVG 11:53 · LAX 19:53 · JFK 22:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.