关于Emacs的org-mode中文行内格式问题

关于Emacs的org-mode中文行内格式问题

关于Emacs的org-mode中文行内格式问题

Table of Contents

1. 引言

使用Emacs的org-mode写中文时,一直受中文行内格式问题困扰,这两天试着解决。目前认为通过修改org-emphasis-regexp-components的值,可达到较好效果。思路和解决方案主要是参考emacs-china网站的帖子:

2. 环境

  • Ubuntu 20.04
  • Emacs 27.1
  • Spacemacs 0.300, develop branch

3. 问题

Emacs的org-mode使用中文行内格式时,往往需要在前标记符前加空格,在后标记符后也加上空格,不然行内格式不起作用。比如句子:“今天是国庆节假日的第四天”,为了加粗国庆节,需要在前星号前和后星号后都加一个空格,写成:

今天是 *国庆节* 假日的第四天

国庆节前后多加的这两个空格是不符合中文的书写习惯的,也影响整体版面效果。

4. 解决方案

目前认为较好的解决方案为修改变量org-emphasis-regexp-components的值。

org-emphasis-regexp-components这个变量在文件“rog.el”中进行定义,它的默认值为:

'(
  "-[:space:]('\"{"
  "-[:space:].,:!?;'\")}\\["
  "[:space:]"
  "."
  1)

也就是说,org-emphasis-regexp-components是一个有5个条目的列表(list),用于构造用于行内强调(emphasis)的正则表达式(regular expression)。关于org-emphasis-regexp-components,reg.el文件中的注释如下:

"Components used to build the regular expression for emphasis.
This is a list with five entries.  Terminology:  In an emphasis string
like \" *strong word* \", we call the initial space PREMATCH, the final
space POSTMATCH, the stars MARKERS, \"s\" and \"d\" are BORDER characters
and \"trong wor\" is the body.  The different components in this variable
specify what is allowed/forbidden in each part:

pre          Chars allowed as prematch.  Beginning of line will be allowed too.
post         Chars allowed as postmatch.  End of line will be allowed too.
border       The chars *forbidden* as border characters.
body-regexp  A regexp like \".\" to match a body character.  Don't use
             non-shy groups here, and don't allow newline here.
newline      The maximum number of newlines allowed in an emphasis exp.

You need to reload Org or to restart Emacs after setting this."

所以,由于单词间有空格进行分隔,所以强调内容前后的空格可以作为prematch和postmatch,而中文字与字间没有空格,为了实现强调内容,额外加空格当然是可以的,但是不好看。更好的方法是修改变量org-emphasis-regexp-components的0号和1号条目的值。方法如下:

(setcar (nthcdr 0 org-emphasis-regexp-components)
        "-[:multibyte:][:space:]('\"{")
(setcar (nthcdr 1 org-emphasis-regexp-components) 
        "-[:multibyte:][:space:].,:!?;'\")}\\[")

也就是在允许[:multibyte:]作为prematch和postmatch,汉字都是[:multibyte:]。

所以,考虑到句法更新,需要在emacs的初始化代码中合适的位置加入:

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

或者:

(setq org-emphasis-regexp-components
      '("-[:multibyte:][:space:]('\"{"
        "-[:multibyte:][:space:].,:!?;'\")}\\["
        "[:space:]"
        "."
        1))
(org-set-emph-re 'org-emphasis-regexp-components org-emphasis-regexp-components)
(org-element-update-syntax)

在Spacemacs,可以把

(setq org-emphasis-regexp-components
      '("-[:multibyte:][:space:]('\"{"
        "-[:multibyte:][:space:].,:!?;'\")}\\["
        "[:space:]"
        "."
        1))

放在defun dotspacemacs/user-init ()中。

(org-set-emph-re 'org-emphasis-regexp-components org-emphasis-regexp-components)
(org-element-update-syntax)

放在defun dotspacemacs/user-config ()中。

5. 参考

Date: 2021-10-04 Beijing(初稿日期、地点)

Created: 2021-10-04 一 19:32

Validate

上一篇:ExpRe[23] emacs初步,Oz语言Hello world


下一篇:win10 下全局安装的npm包无法执行如cnpm rollup vue-cli...