关于(中文友好)的 Org Mode 行内标记语法的设计想法征集

目前在 Org Mode 中正常对行内中文进行语义化标记。无需任何 hack 能直接被支持的只有使用零宽空格(<zws>),如:

请*注意*我           -> 请*注意*我
请<zws>*注意*<zws>我 -> 请\textbf{注意}我

现在 Org Mode 开发者有意为解决这个问题,设计一个新的行内标记语法,希望征集一下各位的意见。前提就是不破坏已有 Org 文档的语义。

目前开发者的想法有:

\--{} -> <zws>      n.b. 为了方便输入
text@*{bold}text
text@bold{bold}text

相关讨论:Re: [BUG] Issues with Chinese (and potentially Japanese) text inline mar

6 个赞

我觉得zws的存在可能毒害文档,因为它们不可见,自动插入zws就像自动把patch里面的空格替换成tab一样恐怖。如果要用zws,我宁可插入空格。

英文按词折行等于中文按字折行。因为中文的语素并不是基于词的,单个字也可以构成语素。我遇到过的一个相关问题是,当开启按词折行的时候,中文会按句子折行,这可以说是错误的行为。而且,如果我们使用空格分隔标记文本,那么按词折行作用在中文上的效果会更差。我担心使用新标记或许不是一个好的主意,因为它似乎会加剧上述的折行问题,在我看来折行问题对格式的影响会更严重。

如果有人想解决这个问题,或许应该在解析文本时彻底区分中文(以及韩文,日文等不用空格分隔的语言)和那些使用空格分隔词汇的文字的上下文。而且,还有一点更糟糕的事情:26个拉丁字母也在中文的范畴里,中文不仅使用拉丁字母注音,而且它们构成正规的词汇,例如X光(X-Ray),B超(B-mode Ultrasound),这些词汇都是《现代汉语词典》中明确记载的中文词汇。

7 个赞

可以考虑自定义一个等同于空格/零宽空格的符号,然后在导出的文本里直接批量替换删除掉这个符号就好吧。

为了让 Org-mode 的无间隔标记(比如 **, ++ 这些)能够在 HTML 导出中正常使用,我写了个函数然后绑定到 C-\ 上方便地插入零宽空格(双引号里面有个零宽空格):

(defun yy/insert-zws () (interactive) (insert "​"))

就我个人来说,如果选择了 @*{bold}@bold{bold} 语法的话,如果能解析得到富文本标记的名字(比如 bold, italic),那么一些 Org 导出后端可能能够更加方便地实现更加丰富的标记。

举个例子,如果我们要使文本颜色为红色(仅在 HTML 后端下),一种做法是 @@HTML:<span style="color:red">TEXT</span>@@。一种 Hack 方式是引入新的内嵌导出名字,比如 @@red:TEXT@@。如果引入了这个新的语法,那可能就可以写成 @red{TEXT}

当然,仅仅从导出目的来说 Org-mode 的 link [[][]] 是一种不错的解决方法,也就是定义新的 Link-type 然后插入对应的东西即可。这一做法具体可以参考 alhassy/org-special-block-extras: A number of new custom blocks and link types for Emacs’ Org-mode :slight_smile:。使用它的话,红色标记的写法可能是 [[red:TEXT]]

1 个赞

使用 zws 在语义上是没有问题的。

The zero-width space (rendered: ; HTML entity: or ), abbreviated ZWSP, is a non-printing character used in computerized typesetting to indicate where the word boundaries are, without actually displaying a visible space in the rendered text. This enables text-processing systems for scripts that do not use explicit spacing to recognize where word boundaries are for the purpose of handling line breaks appropriately.

Zero-width space - Wikipedia. (与 The Unicode Standard – Core Specification 一致)

至于毒害文档,我只能说仁者见仁吧:既然在 Unicode 标准中,同时具有空格的语义且不会被显示,我认为没有理由不使用。

如果有人想解决这个问题,或许应该在解析文本时彻底区分中文(以及韩文,日文等不用空格分隔的语言)和那些使用空格分隔词汇的文字的上下文。而且,还有一点更糟糕的事情:26个拉丁字母也在中文的范畴里,中文不仅使用拉丁字母注音,而且它们构成正规的词汇,例如X光(X-Ray),B超(B-mode Ultrasound),这些词汇都是《现代汉语词典》中明确记载的中文词汇。

这个我会在邮件列表里提及。

当然我认为在近期被 Org 实现的可能性不大,毕竟目前的需求不是 Org 内的断行优化这些依赖对文字解析的行为,而仅是做到 MarkDown 那样能正常使用 CJK 的行内标记。

类似

\--{} -> <zws> n.b. 为了方便输入 <zws>

这个方案?

不知有没有比较好的这个替代输入方案的设计思路

是的,这个也是已经支持的方案。目前会导致 LaTeX 输出后端的一些问题。现在 all-tex-fonts 后端正在添加开箱即用的 XeTeX 和 LuaTeX 的中文支持,会解决这个问题(通过在导出时去除 ,或是在 TeX 端忽略)

当然,仅仅从导出目的来说 Org-mode 的 link [[][]] 是一种不错的解决方法,也就是定义新的 Link-type 然后插入对应的东西即可。这一做法具体可以参考 alhassy/org-special-block-extras: A number of new custom blocks and link types for Emacs’ Org-mode :slight_smile:。使用它的话,红色标记的写法可能是 [[red:TEXT]]

感谢

引入这个语法之后可以拿来干点比较好玩的事,比如像 Racket 的 Pollen 那样: 7 Third tutorial: Pollen markup & tag functions

#lang pollen
 
I want to attend ◊em{RacketCon this year}.

==========
'(root "I want to attend " (em "RacketCon this year") ".")
#lang pollen
 
I want to attend ◊em{RacketCon ◊strong{this} year}.
============
'(root "I want to attend " (em "RacketCon " (strong "this") " year") ".")
#lang pollen
 
◊span[#:class "author" #:id "primary" #:living "true"]{Prof. Leonard}

我目前用的一种临时方案是加一个 eval 的导出项,然后 @@eval:(sexp)@@

1 个赞

在我个人的使用场景里,不是很在意这一个行内标记语法。因为:

1.中文本身就可以通过空一格方式表示停顿,直接用空格方式配合 强调符号 表示 强调普通的行文可能也 未尝不可。

B.3.6用于章节、条款的序次语后宜用空格表示停顿。

示例:第一课 春天来了

2.如果要导出为有严格格式规定的docx文件,里面其实不应该使用半角空格进行排版,所以可以在word/wps中批量搜索替换掉文件里的半角空格。

正文部分用空格的很少吧。而且就像上面说的,空格会导致 xelatex 导出有问题(

只是在导出的时候语义上没问题。zws也是字符,占一个字符的位置,它对其它的文本编辑函数是可见的。一个简单的例子,假如你按下C-u 10 C-f,在中间有zws的情况下,光标停止的位置是不一致的。虽然org可能重载C-f,但是它不可能重载用户的所有编辑函数。标记并不是一个只服务于导出的功能,我们显然不能说“它不影响导出,所以它无影响”。

如果我没记错的话,org的标记解析用的是一个空格开头的syntax table,这对中文来说不适用。要做中英文混排的话,我们应该考虑用新的规则组合出正则表达式,不依赖单一字符做为判定边界。加入zws并不会让这种匹配机制对中文变得更友好。

1 个赞

个人感觉,在表示强调的时候加入空格似乎也没有什么问题,特别是网络分发内容时。

建议采用额外特殊字符识别,如识别某个 unicode 字符环绕:中间这个️⃣加粗️⃣要加粗 单独的*️⃣可采用反斜杠转义等方式

论坛能识别*️⃣环绕?

  1. zws 的用法原本存在,并不存在「加入」(当然可以选择不去使用)
  2. 如果你把 zws 真正看成一个零宽的空格就不会有第一段的问题(或者可能是我没能理解你的意思)
  3. zws 可以在导出过程中被去除,现在担心的是会一并去除有意加入的 zws(比如我主张在不需要 zws 的地方如 HTML 和 OpenOffice 去除,但是你还需要考虑一些语言需要依赖 zws 才能获得正确的断行结果的地方)
  4. 为了不破坏已有的 Org 文档,我们没法改变解析已有行内标记的正则表达式
  5. Org 的定位还是一个标记语言,希望它能在解析文本是彻底区分中文可行性绝对是很小的,特别是包含拉丁字符的中文词语
  6. Org 支持多语言,不止中文

要做中英文混排的话,我们应该考虑用新的规则组合出正则表达式,不依赖单一字符做为判定边界。

不知可否展开说说(如果需要对中文作分词就算了p

空格不会导致 XeLaTeX 导出有问题。

如果你原本在 Org 的行内标记两边插入了空格,导出的 TeX 和编译得到的 PDF 中存在空格是正确的行为。

我上面说的问题是 zws(零宽空格,U+200B)导致的,在 XeTeX 中被 xeCJK 渲染为一个全角空格。

感觉这样跟使用 zws 没什么区别,也并没有说更方便用户输入

为什么不直接用 请 *注意* 我,在导出时再除去中文间的空格,順手把导出 md/HTML 的中文也正规化了。

妙妙

因为这样就破坏语义了(

Org 的行内标记目前需要用空格隔开,同时导出时空格被保留的。我不确定为了一个语言的支持破坏语义是否会被接受。

而且如果有需要保留汉字间空格的场景就会很麻烦(虽然目前没想到类似场景)

感觉不如 zws:

  1. zws 语义正确
  2. zws 在 Emacs Org Mode 中是能保证被正确处理的,不管是希望显示一个占位符提示这里有一个 zws,还是希望让 C-f 忽略它
  3. zws 更方便在导出时被去除

在输入的方便性上,也不如加入一个 @bold{text} 类似的语法