/emacs-chinese

Emacs相关中文问题以及解决方案

Primary LanguageEmacs LispCreative Commons Zero v1.0 UniversalCC0-1.0

Emacs相关中文问题以及解决方案

本文尝试收集整理 Emacs 使用过程中的中文相关问题以及解决方案. 欢迎 Emacs 爱好者加 hick 微信 3715397 邀请进只聊 Emacs 话题的微信大群.

changelog :

  • 2019-02-01 增加中文相关网站和聚集地 emacs-china
  • 2018-02-25 Writing GNU Emacs Extensions 中文翻译
  • 2016-09-09 增加清华和 Emacs-China 的 elpa 镜像
  • 2016-01-01 安装包镜像/安装源**大陆服务器
  • 2015-12-27 文件编码问题整理

目录

Emacs 中文基础

Emacs 的各种字符集

Emacs 中的文件编码问题跟其他编辑器不大一样, M-x describe-current-coding-system 能查看 Emacs 当前编码设置的情况, M-x describe-coding-system 能看到所有可选择编码, 除了常见的 utf-8 这样的, dos/unix 这样的换行符也作为了编码的一部分. 作为比较通用的方式, 一般建议没有特殊需要都使用 utf-8 编码, unix 还是 dos 看个人需要.

默认配置下, mode line 最左会显示当前文件编码以及换行符格式, 比如 U(Unix) 标示 UTF-8 编码, UNIX 格式换行符,鼠标点击可以查看更多详情.

Unicad 是一个自动检测文件编码的 mode , 有看到反馈说有时候不能成功检测: Unicad is short for Universal Charset Auto Detector. It is an Emacs-Lisp port of Mozilla Universal Charset Detector.

不同版本的 Emacs 可能设置方法不一样, 推荐下面的设置:

(set-language-environment "UTF-8")
(set-default-coding-systems 'utf-8)
(set-buffer-file-coding-system 'utf-8-unix)
(set-clipboard-coding-system 'utf-8-unix)
(set-file-name-coding-system 'utf-8-unix)
(set-keyboard-coding-system 'utf-8-unix)
(set-next-selection-coding-system 'utf-8-unix)
(set-selection-coding-system 'utf-8-unix)
(set-terminal-coding-system 'utf-8-unix)
(setq locale-coding-system 'utf-8)
(prefer-coding-system 'utf-8)

如果一个非 UTF-8 编码, 比如 GBK 编码的文件打开, 可能 Emacs 会乱码, 这时候 M-x revert-buffer-with-coding-system 选择 gbk 即可.

MS-Windows 环境的 UTF-8 配置

UTF-8 编码在 MS-Windows 环境下是 「二等公民」, 特别是与命令行工具进行交互作时, 如果设置了使用 UTF-8 编码会导致 Windows 自带程序输出乱码. Emacs的默认设置已经尝试对此类情况进行了处理, 下面的代码在默认设置的基础上设置 cmdproxy.exe 使用GBK编码, 进一步减少设置 UTF-8 编码的副作用:

 (when (eq system-type 'windows-nt)
   (set-default 'process-coding-system-alist
     '(("[pP][lL][iI][nN][kK]" gbk-dos . gbk-dos)
	("[cC][mM][dD][pP][rR][oO][xX][yY]" gbk-dos . gbk-dos))))

参考 issue#4 jacobsun 的分享, 有可能需要如下设置, 否则可能出现乱码, 暂时未获知具体版本等相关信息, hick 个人的 windows 下设置的只有下面说的一行:

;; jacobsun 分享
(when (eq system-type 'windows-nt)
  (set-next-selection-coding-system 'utf-16-le)
  (set-selection-coding-system 'utf-16-le)
  (set-clipboard-coding-system 'utf-16-le))
;; hick 个人的设置:
(set-default-coding-systems 'utf-8)

中文断行

如果开启了 auto-fill 或者使用 refill-mode 等, Emacs 会根据 fill-column 的大小,在合适的位置插入换行符. 这时候再导出成 html 等格式, 可能导致被自动断行的中文之间多一个空格(中文和英文以及英文与英文之间的空格还是自然的), 一种建议是关掉或者不是用自动断行, 采用 truncate-lines 的方式让 Emacs 自动根据 window 大小处理成显示层的断行.

另外一种比较常见的做法是在导出的时候, 通过导出的过滤器机制, 导出之前去掉中文之间的换行的模式, 具体参考有 zwztumashu 两种类似的实现:

;;; 下面一段是 Feng Shu 的
(defun eh-org-clean-space (text backend info)
  "在export为HTML时,删除中文之间不必要的空格"
  (when (org-export-derived-backend-p backend 'html)
    (let ((regexp "[[:multibyte:]]")
          (string text))
      ;; org默认将一个换行符转换为空格,但中文不需要这个空格,删除.
      (setq string
            (replace-regexp-in-string
             (format "\\(%s\\) *\n *\\(%s\\)" regexp regexp)
             "\\1\\2" string))
      ;; 删除粗体之前的空格
      (setq string
            (replace-regexp-in-string
             (format "\\(%s\\) +\\(<\\)" regexp)
             "\\1\\2" string))
      ;; 删除粗体之后的空格
      (setq string
            (replace-regexp-in-string
             (format "\\(>\\) +\\(%s\\)" regexp)
             "\\1\\2" string))
      string)))
(add-to-list 'org-export-filter-paragraph-functions
             'eh-org-clean-space)


;;; 下面一段是 zwz 的, 作者声明只适应 org-mode 8.0 以及以上版本
(defun clear-single-linebreak-in-cjk-string (string)
  "clear single line-break between cjk characters that is usually soft line-breaks"
  (let* ((regexp "\\([\u4E00-\u9FA5]\\)\n\\([\u4E00-\u9FA5]\\)")
         (start (string-match regexp string)))
    (while start
      (setq string (replace-match "\\1\\2" nil nil string)
            start (string-match regexp string start))))
  string)

(defun ox-html-clear-single-linebreak-for-cjk (string backend info)
  (when (org-export-derived-backend-p backend 'html)
    (clear-single-linebreak-in-cjk-string string)))

(add-to-list 'org-export-filter-final-output-functions
             'ox-html-clear-single-linebreak-for-cjk)

中文字体设置

为了保证显示效果, 一般使用中英文等宽字体(一个中文字显示宽度等于俩个英文字母显示宽度), 推荐字体:

  • 文泉驿等宽微米黑优化版.ttf
  • 雅黑mono.ttf
  • DroidSansFallback.ttf

以上字体都包含中文字体, 可以点 百度网盘 下载.

日历设置

Emacs 中有日历, 而且可以称之为一个系统, 因为其中除了最常用的日历之外, 还有其他的近十种历法, 其中有日记、约会提醒、纪念日提示以及节假日提示等等. 其中的历法包括**的农历、希伯来历、伊斯兰历、法国革命历、中美玛雅历等等,可以根据经纬度告知你的所在的每天日出日落的时间等等.

Emacs 自带 calc-china.el , 以下为设置中文里的 ‘celestial-stem’ (天干) 和 ‘terrestrial-branch’ (地支):

(setq chinese-calendar-celestial-stem
          ["" "" "" "" "" "" "" "" "" ""]
          chinese-calendar-terrestrial-branch
          ["" "" "" "" "" "" "" "" "" "" "" ""])

设置阳历节日和阴历节日(参考 fog_proxy ):

;;; 补充用法: holiday-float m w n 浮动阳历节日, m 月的第 n 个星期 w%7
(setq general-holidays '((holiday-fixed 1 1   "元旦")
                         (holiday-fixed 2 14  "情人节")
                         (holiday-fixed 4 1   "愚人节")
                         (holiday-fixed 12 25 "圣诞节")
                         (holiday-fixed 10 1  "国庆节")
                         (holiday-float 5 0 2 "母亲节")   ;5月的第二个星期天
                         (holiday-float 6 0 3 "父亲节")
                         ))
(setq local-holidays '((holiday-chinese 1 15  "元宵节 (正月十五)")
                       (holiday-chinese 5 5   "端午节 (五月初五)")
                       (holiday-chinese 9 9   "重阳节 (九月初九)")
                       (holiday-chinese 8 15  "中秋节 (八月十五)")
                       ;; 生日
                       (birthday-fixed 9 28  "爸爸生日(1950)")
                       (birthday-fixed 10 1  "妈妈生日(1953)")
                       (holiday-chinese 5 29 "老婆生日")           ;阴历生日

                       (holiday-lunar 1 1 "春节" 0)
                       ))

另外一种中文阴历节日的 holiday-lunar 的写法参考自: 在emacs Calendar中定制**农历节日

更强大的中文日历工具:

中文输入

外部中文输入法

个人用搜狗中文输入法的还可以

内置的输入法

默认情况下 toggle-input-method 命令切换输入法.

输入法相关 mode

org 的中文问题

table 中英文对齐等

因为 Emacs 处理字体的方式的问题, 即使设置字体为等宽字体(一个中文相当于两个英文宽度), org 中的 table 出现中文经常都无法工整的对齐. 需要分别对中英文字体设置合适的大小. 处理该问题有现成的方案: https://github.com/tumashu/chinese-fonts-setup . 其中默认定义了各个系统平台常见的字体以及中英文字体搭配, 使得 org table 里的出现中文也能很好的对齐. 如果安装好以后显示的字体过大, 可以通过 cfs-increase-fontsize/cfs-decrease-fontsize 调整选择合适的大小.

更多参考资料:

org 导出中文 html 的空格问题

严格来说跟 org 没什么关系, 参见上文的 中文断行

org 以及 LaTex 等导出中文 pdf

导出中文也分直接转 LaTeX 再转 pdf 以及先转 html 再转 pdf 等各种方式, 中间方案的可以参考这个 中文支持不错的pdf工具rst2pdf

arthur@微信群 分享的 TeX 解决方案, 用 XeTeX 或者 xetex-tutorial .

中文用户聚集地

Emacs 爱好者微信群

分一个主群和一个闲聊群, 截止 2019-02-01 分别 400 多人和 200 多人.

微信加 3715397 注明 Emacs 可以邀请入群. 特别注意主群约定之聊 Emacs 相关话题, 无关话题转闲聊群.

Emacs-China

主要由 子龙山人 创建的 , Emacs 讨论社区 创建以后比较活跃, 讨论比较有序.

水木社区 Emacs 版

源自水木清华的 telnet BBS 的社区, 目前同时有 web 版 和 telnet 版

telegram emacs_zh ***

2020-03 左右上去看过也还比较活跃 telegram emacs_zh

其他中文相关工具

Writing GNU Emacs Extensions 中文翻译

微信群 Emacsist 技术群 slegetank 翻译的 Writing GNU Emacs Extensions 中文版

安装包镜像/安装源**大陆服务器

由于大陆地区特殊的网络条件, 直连国外的 ELPA 服务器可能特别慢甚至有时候安装不成功, 有以下几个国内镜像推荐大家使用.

“清华大学 TUNA 协会原名清华大学学生网管会,注册名清华大学学生网络与开源软件协会” 搭建的镜像, 因为有清华的网络后盾, 比较推荐这个, 其中也包括 marmalade 和 org 等几个其他 Emacs 包的镜像:

https://mirrors.tuna.tsinghua.edu.cn/elpa/

国内的 Emacs 爱好者搭建的 Emacs-China (作为 Emacs 专属社区也是一个很好的地方) 的镜像也跟上面的类似, 还包括简单的使用方法说明:

http://elpa.emacs-china.org/

@aborn 有搭建的镜像, ELPA 的 EmacsWiki 上也有 相关说明 :

(add-to-list 'package-archives
          '("aborn" . "http://elpa.popkit.org/packages/"))

顺带提一句, 如果 M-x package-install 出现找不到包的 url , 可能是本地缓存的包地址已经升级变换, M-x package-refresh-contents 可能就可以了.

ace-pinyin

https://github.com/cute-jumper/ace-pinyin

Jump to Chinese characters using ace-jump-char-mode or avy-goto-char : input the first letter of the pinyin of the Chinese character, then use ace-jump-char-mode or avy-goto-char to jump to it.

cedict

https://github.com/danmey/cedict.el

Emacs interface to Chinese-English dictionary in CEDICT format.

chinese-word-at-point

https://github.com/xuchunyang/chinese-word-at-point.el

Get (most likely) Chinese word under the cursor in Emacs

中文分词跟英文可以时候完全不是一回事, 徐春阳同学弄的这个, 依赖外部分词的命令行: 可以用结巴分词或者 SCWS (简易中文分词系统).

chinese-fonts-setup

原地址 https://github.com/tumashu/chinese-fonts-setup 已经更新为 https://github.com/tumashu/cnfonts

emacs中文字体配置工具. 可以快速方便的的实现中文字体和英文字体等宽(也就是常说的中英文对齐)

chinese-pyim-bigdict

https://github.com/tumashu/chinese-pyim-bigdict

这个文件是一个 Chinese-pyim 拼音词库文件, 词量超过100万, 词库大于20M, 这个词库仅供个人使用.

Chinese in Spacemacs

子龙山人给 Spacemacs 贡献了一个中文 layer

另外还有 et2010 也有一个稍有差别的中文处理 lay: https://github.com/et2010/Chinese

emacs-hz2py

https://github.com/kawabata/emacs-hz2py

Hanzi to Pinyin converter for Emacs

find-by-pinyin-dired

https://github.com/redguardtoo/find-by-pinyin-dired

Find file by first Pinyin characters of Chinese Hanzi. 输入拼音首字母定位对应的中文目录/文件

ido-pinyin

https://github.com/pengpengxp/ido-pinyin

Make ido support chinese pinyin

magit 的中文问题

按照前面的设置好编码一般不会有问题了. 有收到一种情况是 linux 下的终端的问题, 有网友这样尝试解决了:

vi /etc/profile
# 添加
export LESSCHARSET=utf-8
# 填完以后执行
source /etc/profile

pangu-spacing

https://github.com/coldnew/pangu-spacing

emacs minor-mode to add space between Chinese and English characters.

看演示 gif 挺好玩.

pinyin-search

https://github.com/xuchunyang/pinyin-search.el

Search Chinese by the first letter of Chinese pinyin.

pyim-hanzi2pinyin

是一个汉字转拼音得函数, 包含在chinese-pyim中, 主要用于生成词库 @tushuma 天然二呆

ta.el 同音字处理

**的 kuanyui 写的处理同音字的 mode , https://github.com/kuanyui/ta.el

https://github.com/kuanyui/ta.el/raw/master/demo.gif

中文分词工具

emacs-chinese-word-segmentation : 基于 cjieba 的中文分词工具。实现了以中文词语为单位的移动和编辑。

欢迎补充

参考和鸣谢

本文档由 hick 初始整理, 主要是在 Emacs 微信群中 @求其 @arthur @子龙山人 @peng 等讨论中文 org 中 table 中英文混排对齐的时候, 发现有各种做法, 引发整理中文问题的想法.

特别鸣谢:

  • zklhp 补充 windows 环境的处理
  • 本文目录使用 toc-org 自动生成, 安装好以后每次保存会自动刷新目录

欢迎提议和补充条目.