2015-11-14 A simple unfilling function

While the concept of filling text (i.e., putting hard newlines so that no line is longer than some limit) is well-known and very useful, the question about how to unfill some text (i.e., change all hard newlines to spaces) comes up again and again. The internet is full of solutions to that, but I never bothered to look into any of these – if I had a need to unfill a paragraph, I just used to set-fill-column to, say, ten thounsand and filled the paragraph. It was never a common thing for me to do, so I didn’t feel the need to optimize it.

Until recently, when it turned out that I need to unfill some text programatically. So I went and implemented a simple solution. Since it was important for me to be able to unfill not only a single paragraph, I had to preserve strings of two or more newlines (in the spirit of TeX, Org-mode and Emacs itself, where a “paragraph” is delimited by one or more blank lines). (One distinction is that a line containing some whitespace characters – tabs or spaces – is not considered “blank” by my code. It doesn’t really matter a lot, though – I never do things like that myself, and I ussually run delete-trailing-whitespace on files I get from someone else.)

So, here’s the code.

(defun unfill-region (begin end)
  "Change isolated newlines in region into spaces."
  (interactive (if (use-region-p)
		   (list (region-beginning)
		 (list nil nil)))
    (narrow-to-region (or begin (point-min))
		      (or end (point-max)))
    (goto-char (point-min))
    (while (search-forward "\n" nil t)
      (if (eq (char-after) ?\n)
	  (skip-chars-forward "\n")
	(delete-char -1)
	(insert ?\s)))))

The code itself is fairly straightforward – it just searches for a newline repeatedly, and if found – and not followed by another newline – deletes it and inserts a space instead. What you might find useful is the pattern in the interactive clause: not everyone seems to know about the use-region-p function, and also the way you pass the region to the function so that if there is no region to act upon, you end up operating on the whole (visible portion of) buffer.

CategoryEnglish, CategoryBlog, CategoryEmacs