1

I have a document with paragraphs where some sentences end with a dot and one space (". Nextline"), while others end with a dot and two spaces (". Nextline"). I want to replace replace dot and one space to dot and two spaces but without increasing existing dot and two spaces to dot and three spaces.

The sentences of paragraph are not ending with newline or "\n", except the last one. There will be a newline character at the end of the paragraph. I want to start each sentence with 2 spaces, neither 1 nor 3 or more. If I use search and replace from the menu, sentences starting with 2 spaces increase to 3 spaces at their start.

How can I do that? I tried following but it increases two spaces to three:

(defun space12 ()
    (interactive)
    (while (re-search-forward "\\. ?" nil t)
        (replace-match ".  ")))

Where is the problem and how can I correct it.

Sample input text:

This is first sentence (I called it line earlier). This sentence has one space at start.  This has two. And this again has one space at start.
Drew
  • 29,895
  • 7
  • 74
  • 104
rnso
  • 23,686
  • 25
  • 112
  • 234

2 Answers2

2

There's repunctuate-sentences:

Put two spaces at the end of sentences from point to the end of buffer.

It works using query-replace-regexp.
If optional argument NO-QUERY is non-nil, make changes without asking for confirmation.

It's fairly straightforward, just using query-replace-regexp with the regex: \\([]\"')]?\\)\\([.?!]\\)\\([]\"')]?\\) +, but you've got the option to decide for each in turn if you like, which is useful for false positives (e.g. "i.e.").

Amory
  • 758
  • 2
  • 19
  • 31
  • 1
    Thanks for your reply. Interestingly, I had asked this question almost exactly 3 years back! – rnso Apr 11 '21 at 18:57
0

You can use C-M-% (M-x query-replace-regexp) with search string \. \([^ ]\) and replacement string . \1.

When you want to put \ in a string remember that you have to escape it with another \. For example:

(defun space12 ()
  (interactive)
  (while (re-search-forward "\\. \\([^ ]\\)" nil t)
    (replace-match ".  \\1" t)))

To get this “well behaved” I'd make it always process the whole buffer and go back to the original position after:

(defun space12 ()
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "\\. \\([^ ]\\)" nil t)
      (replace-match ".  \\1" t))))
kmkaplan
  • 18,655
  • 4
  • 51
  • 65
  • It works but how can I make a function out of it to include in my init.el file? I tried " `(defun space12 () (interactive) (replace-regexp "\. \([^ ]\)" ". \1") )` " , it runs without error but does not replace any occurrences. – rnso Apr 14 '17 at 23:58
  • @mso edited to make it into a function. Note that `replace-regexp` is for interactive use only. – kmkaplan Apr 15 '17 at 07:15
  • Yes, this works well. How can I set it up so that it is executed at time of opening a document automatically? – rnso Apr 15 '17 at 09:54
  • @mso you would have to add this to the suitable hook. Depending upon your needs `find-file-hook` (https://www.gnu.org/software/emacs/manual/html_node/elisp/Visiting-Functions.html) could be your friend. Also see the list at https://www.gnu.org/software/emacs/manual/html_node/elisp/Standard-Hooks.html – kmkaplan Apr 15 '17 at 14:09