【求助】中英文标点转换

基本信息:

  • 操作系统:win10 22H2
  • emacs version:GNU Emacs 31.0.50 (build 1, x86_64-w64-mingw32) of 2024-11-16
  • emacs 配置: spaemacs develop

在李杀那找到如下代码:

(defun xah-convert-english-chinese-punctuation (&optional Begin End ToDirection)
  "Convert punctuation from/to English/Chinese characters.

When called interactively, do current line or selection. The conversion direction is automatically determined.

If `universal-argument' is called, ask user for change direction.

When called in lisp code, Begin End are region begin/end positions. ToDirection must be any of the following string values:

chinese
english
auto

URL `http://xahlee.info/emacs/emacs/elisp_convert_chinese_punctuation.html'
Version: 2012-12-10 2022-05-18 2023-08-26 2023-11-25"
  (interactive)
  (let (xp1 xp2 xinputStr xcontainChinese
            (xengToChinesePairs
             [
              [". " "。"]
              [".\n" "。\n"]
              [", " ","]
              [",\n" ",\n"]
              [": " ":"]
              ["; " ";"]
              ["? " "?"] ; no space after
              ["! " "!"]
              ["& " "&"]
              [" (" "("]
              [") " ")"]
              ;; for inside HTML
              [".</" "。</"]
              ["?</" "?</"]
              [":</" ":</"]
              [" " " "]
              ]
             ))
    (if (and Begin End)
        (setq xp1 Begin xp2 End)
      (if (region-active-p)
          (setq xp1 (region-beginning) xp2 (region-end))
        (setq xp1 (line-beginning-position) xp2 (line-end-position))))
    (setq xinputStr (buffer-substring-no-properties xp1 xp2))

    (when (not ToDirection)
      (setq ToDirection (if current-prefix-arg
                            (completing-read
                             "Change to: "
                             '("english"  "chinese")
                             nil
                             t)
                          "auto"
                          )))

    (setq xcontainChinese
          (seq-some
           (lambda (x) (string-match (aref x 1) xinputStr))
           xengToChinesePairs))

    (when (string-equal ToDirection "auto")
      (setq
       ToDirection
       (if xcontainChinese
           "english"
         "chinese")))
    (save-restriction
      (narrow-to-region xp1 xp2)
      (mapc
       (lambda (xx)
         (progn
           (goto-char (point-min))
           (while (search-forward (aref xx 0) nil t)
             (replace-match (aref xx 1)))))
       (cond
        ((string-equal ToDirection "chinese") xengToChinesePairs)
        ((string-equal ToDirection "english") (mapcar (lambda (x) (vector (elt x 1) (elt x 0))) xengToChinesePairs))
        (t (user-error "Your 3rd argument 「%s」 isn't valid" ToDirection))))
      (goto-char (point-max)))))

将上述代码放到 dotspacemacs/user-config () 后,通过如下代码并定义快捷键,可快速将英文标点符号转换成中文标点符号。

  (defun etc ()
    (interactive)
    (xah-convert-english-chinese-punctuation nil nil "chinese"))
  (global-set-key (kbd "M-m o c") 'etc)

问题:

总觉得 (global-set-key (kbd "M-m o c") 'etc) 实现的不好,请求大佬优化下代码?

用 general.el 来设定 leader-key 会方便一些。李杀自己用的的 Xah-fly-key,可以实现单键按某些固定的组合键比如 M-x,他按 a 就可以。

所以这么设置,对于他来说是方便的。或者你也可以考虑 C-c o c 这种也可以。

大佬好,有没有可能不用重新定义 etc 这个函数,而是直接调用李杀提供的那个函数来设置调用快捷键呢?

可以,实际上你的这个 etc 完全是多余的,直接绑定他那个函数效果是一样的

请问大佬直接调用李杀的函数如何传入参数呢?之所以写这个 etc 的函数,是想调用后直接将英文标点转换成中文标点。调用李杀的函数,需要用 c-u 选择是中文到英文,还是英文到中文,多了一个步骤。并且,李杀的那个函数默认是中文到英文标点符号转换。

试过如下形式,没有成功! 请大佬明示!:joy:

  (global-set-key (kbd "M-m o c") '(xah-convert-english-chinese-punctuation nil nil "chinese"))

他原本的函数是能猜中文还是英文的,但是你复制代码的时候,或者是他上传的时候,有软件擅作主张把一个中文空格弄成了英文空格,这个自动检测就不灵了。

把那行

[" " " "]

改成

[" " "\u3000"]

或者如果不想转换中文全角空格,直接删去,自动猜转英文还是中文就正常了。

感谢大佬的耐心解答!

其实我只想强制将英文标点转化成中文标点。使用场景是这样的,通过 OCR 识别的文本,常常将中文的标点识别成英文标点,这就造成标点符号使用不统一和标点使用错误(如英文标点后有空格,中文标点后无空格,中文环境下以英文单词结尾使用中文标点情况。

上述问题如果使用李杀的函数自动猜测,十有八九猜测是错误的,因为原文标点使用的就是错误的,所以莫不如全部全部转换成中文符号,再做进一步的校订!

其实我还有一个需求,就是想先高亮所有的英文标点符号,然后通过交互式方式确认是否转换标点符号。:joy:

对于李杀的函数的符号对,我是修改过的,仅保留的部分我需要转换的标点。

那你自己写正则替换就完事了,甚至没必要绑快捷键

1 个赞

大佬好,我的工作流程是这样的,不定时不定量从 ocr 识别的文本,想在 Emacs 中修改好,然后粘贴到 M$ word 中。

不用快捷键会频繁的输入正则表达式,而且也不能保证每次输入的都是正确的,会增加很多工作!

综上,还是用快捷键来操作最优!

我觉得这么搞有很多改进的空间,比如你可以

  1. 把多组输入整理成一个文件
  2. 写代码用正则统一粗略替换
  3. 在 Emacs 里校对,并且改进上一步的代码减少之后的校对工作
  4. 最后一起导入 MS Word

减少在不同界面的切换,减少操作,减少失误