将直引号转换为引号的想法

Shr*_*saR 13 language-agnostic algorithm typography

我有一个包含"直"(普通,ASCII)引号的文件,我正在尝试将它们转换为真正的引号字形("卷曲"引号,U + 2018到U + 201D).由于从两个不同的引号字符转换为单个字符首先是有损的,显然没有办法自动执行这种转换; 尽管如此,我怀疑一些启发式方法将涵盖大多数情况.因此,该计划是一个脚本(在Emacs中),它执行以下操作:对于每个直引号字符,

  1. 如果可能的话,猜猜要使用哪个卷曲引号字符
  2. 要求用户(我)确认或做出选择

这个问题是关于第一步:对于普通的英文文本(例如小说),使用什么是一个好的算法(一组启发式,更像是)?以下是一些初步的想法,我认为这些想法适用于双引号(欢迎反例!):

  1. 如果双引号位于一行的开头,则猜测它是一个开头报价.
  2. 如果双引号位于一行的末尾,则猜一个结束报价.
  3. 如果双引号前面有空格,请猜一个开头报价.
  4. 如果双引号后面跟一个空格,请猜一个收盘价.
  5. 如果双引号不符合上述类别之一,则猜测它是最近使用的双引号的"反面".

单引号比较复杂,因为a '可能是开头引号,结束引号撇号,我们想要单独留下撇号(不能写"绝对不能").一些与上述相同的规则适用,但'可能的撇号是在单词(或行)的开头,尽管它不像过去的'twas那样常见.我不能随便想到能够正确处理像["我喜欢'那'70年代表演''这样片段的规则,"她说.它可能需要查看不仅仅是相邻字符,并计算引号之间的距离,例如......

还有什么想法吗?如果不是所有可能的案件都包括在内,那也没关系; 我们的目标是尽可能聪明,但不能再进一步.:-)

编辑:可能值得考虑的更多事情(或者可能是不相关的,不确定):

  • 引号可能并不总是匹配对:对于单引号,显而易见的原因如上所述.但即使对于双引号,如果有一个引用延伸多个段落,通常的排版约定(不要问我为什么)是用引号开始每个段落,即使它在之前没有被关闭一.所以,简单地保持状态机两种状态会之间交替工作!
  • 嵌套引用(在上面的"我喜欢'那个'70年代展示''例子中提到):这可能使得任何一种引用都不会在空格之前或之后.
  • 英/美标点符号样式:引号内或外引号?
  • 许多文字处理器(例如Microsoft Word)已经像这样进行某种转换.虽然它们并不完美并且经常令人讨厌,但了解它们如何工作可能是有益的...

Dav*_*vis 3

您无法使用正则表达式解析英文引号,因为正则表达式无法解析英文引号。正则表达式的表达能力不足以解析英文引文。在某些情况下您可以应付自如,但无法使用正则表达式创建通用解决方案。请参阅我的解决方案测试用例

鉴于:

  • 用于从字符流创建词位的词法分析器。
  • 发布各种类型引号的发射器。
  • 创建嵌套树的歧义解析器。
  • 一组已知的模糊和明确缩写。
  • 词汇的循环缓冲区,长度为 4。

然后,从广义上讲,一种可能的算法如下:

  1. 使用词法分析器迭代文档。
  2. 词素从词法分析器传递到发射器。
  3. 词位推入发射器的循环缓冲区。
  4. 在发射器中一次 解析 4 个词位以对旋度进行分类:
    • 开始/结束双/单引号
    • 撇号
    • 直接引用
    • 不明确的开头单引号
    • 不明确的结束单引号
    • 不明确的单引号
    • 不明确的双引号
  5. 将分类的引号作为令牌发送给歧义解析器。
  6. 让解析器创建树(用于跟踪嵌套引号):
    1. 打开用于打开报价标记的树(单/双)
    2. 关闭树以关闭报价标记(单/双)
    3. 否则,跟踪当前树中任何不明确的标记
  7. 所有标记都位于嵌套树中之后:
    1. 从根开始
    2. 消除标记的歧义
    3. 对标记列表进行排序
    4. 解决剩余的令牌
    5. 消除标记的歧义(是的,再次)
    6. 将令牌中继到文档解析器

消除歧义需要用可解析的等价物替换不明确的引号。基本上,您需要计算不明确的前导、滞后和不确定单引号的数量。根据树的当前级别是否已包含前导/滞后引号的某种组合,您可以确定不明确的引号是否为:右单引号、左引号或撇号。

这不是一个简单的算法,因为它可能需要:

  • 循环缓冲区
  • 词法分析器(分词器)
  • 解析器(发射器)
  • 解析器(歧义)
  • 一颗树
  • 一组缩写(歧义和明确)

以下是KeenQuotes的一些屏幕截图,它已集成到我的文本编辑器KeenWrite中:

敏锐的报价 01

尼特:是的'70s,并不是'70's因为几十年不能拥有任何东西。

敏锐的报价 02