如何让Emacs自动换行模式不拆分LaTeX polyglossia的\text类行内命令
嘿,这个问题我之前刚好处理过!要让Emacs的auto-fill mode不拆分polyglossia的\text[language]{...}行内命令块,核心就是给auto-fill设置一个“禁区判断规则”——让它识别出这些命令块,并且在这些区域内禁止自动换行拆分。下面是具体的实现步骤:
1. 定义匹配polyglossia命令的正则规则
首先我们需要一个精准识别\textspanish{...}这类格式的正则表达式,在Emacs Lisp里对应的写法是:
"\\\\text[a-zA-Z]*{[^}]*}"
简单解释下:
\\\\text:匹配\text(Emacs里反斜杠需要双重转义)[a-zA-Z]*:匹配后面的语言名(比如spanish、french){[^}]*}:匹配花括号里的内容,直到遇到闭合的}为止
2. 编写自定义的禁止拆分函数
接下来写一个Emacs Lisp函数,用来检查当前要换行的位置是否处于polyglossia命令块内部。如果是,就告诉auto-fill“别拆这里”:
(defun my/polyglossia-no-fill (start end) "Prevent auto-fill from splitting polyglossia \\text[...]{} blocks." (save-excursion (goto-char start) (let ((current-pos (point))) ;; 搜索当前位置前后的polyglossia命令块边界 (or (re-search-backward "\\\\text[a-zA-Z]*{" current-pos t) (re-search-forward "[^}]*}" current-pos t)) ;; 判断当前位置是否在命令块范围内 (and (match-beginning 0) (<= (match-beginning 0) current-pos) (>= (match-end 0) current-pos)))))
3. 把规则绑定到LaTeX模式
我们只需要在LaTeX模式下启用这个规则,所以把上面的函数添加到LaTeX模式的钩子中,同时加入auto-fill的禁止拆分判断列表:
(add-hook 'LaTeX-mode-hook (lambda () (add-to-list 'fill-nobreak-predicate 'my/polyglossia-no-fill)))
把这段代码放到你的Emacs配置文件(比如init.el或者.emacs)里,重启Emacs或者按M-x eval-buffer重新加载配置就生效了。
4. 测试验证
打开一个LaTeX文件,输入类似\textspanish{Soy el hijo de Fernando}的内容,故意让行变得很长触发auto-fill(比如按M-q格式化段落),你会发现这个polyglossia命令块会保持完整,不会被拆分成两行,完美避免导出时的解析错误!
小提示
如果你的polyglossia命令里有嵌套的花括号(这种情况比较少见),这个简单的正则可能会失效。如果遇到这种场景,你可能需要用更复杂的语法分析来匹配嵌套结构,但对于绝大多数日常使用的情况,上面的方案已经足够好用了。
内容的提问来源于stack exchange,提问作者Carlos Alberto Rivera Carreño

