Org-mode 中文行内格式化的问题

最近我开始用 org-mode 写些中文内容 [1],但 org-mode 不能处理行内(inline)格式化:一、org-mode 中显示不出来效果;二、导出的 HTML 也没效果

org-mode 中/斜体/没效果,必须要在前后都加个空格才行,但中文与中文之间加空格是不可以接受的。

目前只能放弃中文行内格式化了。而且,我还觉得在 Github 上用 org-mode 写中文内容不是个好主意,似乎连中文全角标点符号都没法处理

Emacs 中最重要的快捷键是 =M-x=。

这种情况在 org-mode 里可以通过定制 org-emphasis-regexp-components 解决。Github 上一些中文 org-mode 文档里 [2][3],全用西文半角标点、全角半角标点混用、多余的空格,似乎都是跟 org-mode 的中文问题有关。相比之下,似乎 Markdown 要好些。


目前我的打算:

  • 不使用中文行内格式化
  • 在 Github 上不用 org-mode 写中文内容,用 Markdown

[1] https://xuchunyang.me

[2] https://github.com/redguardtoo/mastering-emacs-in-one-year-guide/blob/master/guide-zh.org

[3] https://github.com/emacs-china/Spacemacs-rocks/blob/master/README.org

1赞

两边加上空格咯。修改org-emphasis记得还要调用一些函数才会生效。

这个是可以的,但不优雅,可惜Emacs不支持RL1.2:

  (setcar (nthcdr 0 org-emphasis-regexp-components) " \t('\"{[:nonascii:]")
  (setcar (nthcdr 1 org-emphasis-regexp-components) "- \t.,:!?;'\")}\\[[:nonascii:]")
  (org-set-emph-re 'org-emphasis-regexp-components org-emphasis-regexp-components)
  (org-element-update-syntax)
2赞

我不喜欢两边加空格:

我的*主力*文本编辑器是 =Emacs=。

两边加空格的话 =>

我的 *主力* 文本编辑器是 =Emacs= 。

Updated. Ping.

好主意,现在 org-mode 中显示正常了,导出 HTML 中除了下划线之外都正常

Org 里中文/斜体/、*粗体*、_下划线_、+删除+、~代码~、=常量=。

上面的下划线导出的结果是

<sub>下划线</sub>

还不清楚什么原因


考虑到 defvar 不会覆盖 setq,提前设置 org-emphasis-regexp-components 也行。

;; 必须在 (require 'org) 之前
(setq org-emphasis-regexp-components
      ;; markup 记号前后允许中文
      (list (concat " \t('\"{"            "[:nonascii:]")
            (concat "- \t.,:!?;'\")}\\["  "[:nonascii:]")
            " \t\r\n,\"'"
            "."
            1))

什么意思?

inline 下划线如果两边不加空格的话,导出的时候,org 会认为它是下标。可以把匹配下标的 regexp 改成更加严格,导出就正常了,不清楚有没有更优雅的方法。

(with-eval-after-load 'org
  (setq org-match-substring-regexp
        (concat
         ;; 限制上标和下标的匹配范围,org 中对其的介绍见:(org) Subscripts and superscripts
         "\\([0-9a-zA-Zα-γΑ-Ω]\\)\\([_^]\\)\\("
         "\\(?:" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)"
         "\\|"
         "\\(?:" (org-create-multibrace-regexp "(" ")" org-match-sexp-depth) "\\)"
         "\\|"
         "\\(?:\\*\\|[+-]?[[:alnum:].,\\]*[[:alnum:]]\\)\\)")))
1赞

我的想法是可以用一个更准确的方法来匹配中文,但是Emacs并没有支持\p{Han},所谓的R1.2.

这个问题也困扰了我好久,一直是靠两边加空格,原来还有这种方式。感谢两位

Elisp manual [1] 中有提到用 \cc 匹配中文字符,用 \Cc 匹配非中文字符。我试过几个汉字和全角标点,是可行的。不清楚是不是准确。

(mapcar (lambda (s) (string-match-p "\\cc" s))
        '("a"
          "1"
          "."
          "中文"
          "。"))
    ⇒ (nil nil nil 0 0)

[:nonascii:] 换成 \cc 也可以。


[1] 参见节点:(elisp) Regexp Backslash

1赞

真是相见恨晚!我一直都无奈地加着空格。

想请教一下,由于我参考的是山人spacemacs的layer的方式@guanghui.qu ,所以并没有写 (require `org)这个语句。而是把org的相关配置放到了 defun layerName/post-init-org()里面。对于这种情况,我该把这段代码放在哪里才会生效呢?

我试了几种方式都不行:

  1. 放在 defun layerName/post-init-org()中;
  2. 放在 defun layerName/init-org()中;
  3. 放在defun dotspacemacs/user-config ()中,并在语句后加上(require `org)

另外,我重启emacs后查看变量org-emphasis-regexp-components 发现它的值已经改了:

但是为什么我还是需要加空格呢?

用 Org 或者别的标记语言(如 Markdown)写中文本来就会有各式各样的问题。

用不着在配置里写 (require 'org,我的意思是

(setq org-emphasis-regexp-components ...)

需要在 Org 被加载之前执行,比如假设你对 Org 的配置如下,第一个 setq 会在 Org 加载之前执行,第二个是在加载之后:

(setq org-emphasis-regexp-components
      ;; markup 记号前后允许中文
      (list (concat " \t('\"{"            "[:nonascii:]")
            (concat "- \t.,:!?;'\")}\\["  "[:nonascii:]")
            " \t\r\n,\"'"
            "."
            1))

(with-eval-after-load 'org
  (setq org-agenda-files '("~/Sync/org/")))

我没用过 Spacemacs,不清楚它那边应该怎么做。

你提醒了我,放到了defun dotspacemacs/user-init ()里面,终于可以了。

PS: (关于下划线)我在org文件头上设置#+OPTIONS: ^:{}也是可以解决的。这样一来,想写上下标就必须严格地用{}括起来。

你似乎忘了有个 pre-init-org 可以用。

对啊!忘了用了

emphasize 符号配对之后就隐藏了,这给编辑操作造成一些不便。org-mode 有没有这样一个选项,当光标移到 emphasize 符号包裹的字符串内(或边界),自动把=+~_显示出来?

我这边默认没这效果,你用了什么设置/包有这效果?

手动的话可以开启 front-lock,当前buffer就变成 plain text 了

这个要怎么解决啊?

不知道。另外,中英文有明显的差别,把用来格式化英文的那一套用到中文上难免水土不服。

可以换个角度思考 标记的时候加不加空格问题不大,只要能保证渲染和输出的时候没空格就够理想了。