2017-04-11 76 views
1

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

(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))))) 

但我不知道如何从文件中获得文本具有当前位置的agraph。我该如何纠正这个功能?

编辑:基本上,我想阅读它作为单独的行,但要保存为段落。

+0

你是什么意思“保存它是一个段落”? – ashawley

+1

手段让它作为原始文件中的段落。所以,将para分成几行只是为了阅读目的。 – rnso

回答

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)))))) 
+0

是的,我想将它作为单独的行阅读,但希望将其另存为段落。 – rnso

+0

您的代码无法使用。你自己尝试过吗?它会打开一个新的缓冲区,但不会分隔这些行。 @gilez代码正在工作(尽管在相同的缓冲区中)。可能需要检查字符串“。”并将其替换为“\ n”。 – rnso

+0

看起来你的句子在单个空间中结束。您是否使用M-x自定义变量RET句子结束双空间RET无RET? – ashawley

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

也看看'forward-sentence',它将处理各种各样的角落案例,并且可以用一些变量进行调整以获得您想要的行为。 – jpkotta

+0

输出如何在新的缓冲区中? – rnso

+0

如何添加另一个正则表达式(比如“;?”)以替换为“; \ n” – rnso