在Emacs中拆分当前段落的行

时间:2017-04-11 16:56:03

标签: emacs split lisp

我想在Emacs中添加一个函数(para2lines),通过它我可以将当​​前段落分成句子并在一个单独的缓冲区中逐行打印。以下是Racket / Scheme中的代码:

(define (p2l paraString)
  (define lst (string-split paraString ". "))
  (for ((i lst))
    (displayln i)))

测试:

(p2l "This is a test. For checking only. Only three lines.")

输出:

This is a test
For checking only
Only three lines.

在Emacs Lisp中,我可以管理以下代码:

(defun pl (ss)
  (interactive)
  (let ((lst (split-string (ss))))
    (while lst
      (print (pop lst)))))

但我不知道如何从当前位置的段落中获取文本。我该如何纠正这个功能?

编辑:基本上,我想将它作为单独的行读取,但希望将其保存为段落。

2 个答案:

答案 0 :(得分:2)

这是一个可以帮助你的例子。它将转换到当前段落(即光标所在的位置),而不是新的缓冲区。你可以修改它以将字符串传递给你的函数,如果这是你需要的。

(defun p2l ()
  "Format current paragraph into single lines."
  (interactive "*")
  (save-excursion
    (forward-paragraph)
    (let ((foo (point)))
      (backward-paragraph)
      (replace-regexp "\n" " " nil (1+ (point)) foo)
      (backward-paragraph)
      (replace-regexp "\\. ?" ".\n" nil (point) foo))))

答案 1 :(得分:1)

我只是运行Emacs命令或编写一个宏来将段落转换为单句行,但也许你真的只是想把包装的段落读成行,因此需要有一个Emacs命令。

这里会抓取当前段落,插入新缓冲区*Lines*,然后将句子转换为行。

(defun para-lines ()
  "Split sentences of paragraph to lines in new buffer."
  (interactive)
  ;; Move the paragraph to a new buffer.
  (let ((b (generate-new-buffer "*Lines*")))
    (with-output-to-temp-buffer b
      (let ((beg (save-excursion (forward-paragraph -1) (point)))
            (end (save-excursion (forward-paragraph +1) (point))))
        (princ (buffer-substring-no-properties beg end))))
    ;; Switch to new buffer
    (with-current-buffer b
      ;; Since the name starts with "*", shut off Help Mode
      (fundamental-mode)
      ;; Make sure buffer is writable
      (setq buffer-read-only nil)
      ;; From the start of the buffer
      (goto-char (point-min))
      ;; While not at the end of the buffer
      (while (< (point) (point-max))
        (forward-sentence 1)
        ;; Delete spaces between sentences before making new new line
        (delete-horizontal-space)
        ;; Don't add a new line, if already at the end of the line
        (unless (= (line-end-position) (point))
            (newline))))))

要避免使用forward-sentence,只使用正则表达式,请使用re-search-forward。例如,匹配分号和句号。

(defun para-lines ()
  "Split sentences of paragraph to lines in new buffer."
  (interactive)
  ;; Move the paragraph to a new buffer.
  (let ((b (generate-new-buffer "*Lines*")))
    (with-output-to-temp-buffer b
      (let ((beg (save-excursion (forward-paragraph -1) (point)))
            (end (save-excursion (forward-paragraph +1) (point))))
        (princ (buffer-substring-no-properties beg end))))
    ;; Switch to new buffer
    (with-current-buffer b
      ;; Since the name starts with "*", shut off Help Mode
      (fundamental-mode)
      ;; Make sure buffer is writable
      (setq buffer-read-only nil)
      ;; From the start of the buffer
      (goto-char (point-min))
      ;; While not at the end of the buffer
      (while (< (point) (point-max))
        (re-search-forward "[.;]\\s-+" nil t)
        ;; Delete spaces between sentences before making new new line
        (delete-horizontal-space)
        ;; Don't add a new line, if already at the end of the line
        (unless (= (line-end-position) (point))
            (newline))))))