Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have an RTF file which is formatted like so:

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.\par
Nullam vitae sem porttitor urna pellentesque gravida. Nulla\par
consequat purus vel est vehicula porttitor.\par
    Maecenas pharetra metus in enim sollicitudin sollicitudin.\par
Etiam et odio tellus, eget placerat enim. Aliquam sem purus,\par
gravida sed feugiat eget, consectetur quis nisl.\par

(\par added for brevity)

As you can see, newlines have been inserted to fit a page's width. The problem arises when I try to read the text on my iPhone, which has a different line length. The lines break and readability is hindered.

The ideal solution would be one that converts the file to a single line for each paragraph, while keeping the newline and indent for new paragraphs.

So far I've tried parsing the file with sed but was unable to create a multiline regex. Ideally, I want to replace all "\r\n"s with " ", unless the next line begins with a space.

Is there a better solution for this? If not, how can I do it using sed?

share|improve this question

2 Answers 2

This regex will match what you want:

\r\n(?! )


So to use that with sed:

sed 's/\r\n(?! )/ /g' filename.rtf


Except, it appears that sed doesn't support negative lookahead, and requires backslashed parens, so you can instead use:

sed 's/\r\n\([^ ]\)/ \1/g' filename.rtf
share|improve this answer
    
sed works by reading one line at a time. \r\n doesn't match –  MoshiBin Jul 28 '09 at 21:24
    
Hmm, then use a tool that works on the whole file at once then –  Peter Boughton Jul 28 '09 at 21:25
    
Or here's a possible solution for doing multi-line with sed: ilfilosofo.com/blog/2008/04/26/… –  Peter Boughton Jul 28 '09 at 21:27
up vote 2 down vote accepted

The solution lied in a tool I haven't given serious thought - awk

awk 'BEGIN { FS="\\\\par" } ; /^    / {print "\\par" $1} /^[^ ]/ {print " " $1}'

This will go over the file, with \par as the field seperator, and will print a \par before any line that starts with 4 spaces (which marks the beginning of a new paragraph), and remove (or simply won't print) it when it starts with anything but a space.

Now what we have is a file with \par only where legal line breaks should be. The next step would be to remove all newlines altogether, to get rid of rogue line breaks:

tr -d '\r\n'

And then feed the result to sed to replace \par with \par\r\n, practically adding a newline where a \par is.

sed 's/\\par/\\par\r\n/g'

And done.

The only real issue I've found with this method is that it ruined the RTF header. No problem, I just copied over the header from the original file.

Another smaller issue was that chapter titles were being printed inline with previous paragraphs. This is because chapter titles do not start with a space yet should be considered a paragraph. In my case, chapters were marked like so:

CHAPTER THIRTY-TWO
Chapter's Name

So a quick sed took care of them:

sed 's/\s*\(CHAPTER [[:upper:]-]* \)\(.*\\par\)/\\par\r\n\\par\r\n\\par\r\n\1\\par\r\n\2\\par\r\n/'

I now have my book in proper format, which makes it readable on other devices (such as my iPod).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.