2017-04-11 120 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