【问题标题】:Split lines of current paragraph in EmacsEmacs中当前段落的拆分行
【发布时间】:2017-04-11 16:56:03
【问题描述】:

我想在 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)))))

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

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

【问题讨论】:

  • “保存为段落”是什么意思?
  • 意思是让它在原始文档中作为一个段落。因此,将 para 拆分为行仅用于阅读目的。

标签: emacs split lisp


【解决方案1】:

以下示例可能对您有所帮助。它会将您转换为当前段落(即光标所在的位置),而不是转换为新缓冲区。如果这是您需要的,您可以修改它以将字符串传递给您的函数。

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

【讨论】:

  • 还可以查看forward-sentence,它可以处理各种极端情况,并且可以使用一些变量进行调整以获得您想要的行为。
  • 输出如何在新缓冲区中?
  • 我怎样才能添加另一个正则表达式(比如“;?”)也被替换为“;\n”
  • 要添加另一个正则表达式,请使用上面的模式(backward-paragraphreplace-regexp)。或者您可以巧妙地使用现有的正则表达式,使用| 分隔的两个不同的匹配选项......类似于(\\.|;) ? 只是要警惕旧的:有些人在遇到问题时会想知道,我会使用正则表达式。”现在他们有两个问题。
  • @rnso 虽然我同意代码中的 cmets 很好,但该示例是如此微不足道,如果您无法理解诸如 backward-paragraphreplace -regexp 之类的事情,那么您有很多事情要做学习。也许尝试^h f 和函数名称来阅读有关特定函数作用的文档....
【解决方案2】:

我只会运行 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))))))

【讨论】:

  • 是的,我想将其作为单独的行阅读,但想将其保存为段落。
  • 您的代码不起作用。你自己试过吗?它打开一个新缓冲区,但不分隔行。 @gilez 的代码正在运行(尽管在同一个缓冲区中)。可能需要检查字符串 ". " 并用 "\n" 替换它们。
  • 看起来你的句子以一个空格结尾。你M-x customize-variable RET sentence-end-double-space RET nil RET了吗?
  • 我怎样才能从 init.el 文件中做到这一点,以便它在启动时就在那里?
  • 尽管 M-x customize-variable RET sentence-end-double-space RET nil RET,但它不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-09
  • 1970-01-01
  • 2020-09-21
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
  • 1970-01-01
相关资源
最近更新 更多