Skip to content

Instantly share code, notes, and snippets.

@rmoehn
Created February 17, 2016 14:34
Show Gist options
  • Save rmoehn/acecb206d44af2053364 to your computer and use it in GitHub Desktop.
Save rmoehn/acecb206d44af2053364 to your computer and use it in GitHub Desktop.
Makes strings from triple-quoted string literals usable.
import re
import textwrap
def paragraphs(u):
"""
Makes strings from triple-quoted string literals usable.
When you write a string as a triple-quoted literal, you end up with
something that has superfluous newlines and lots of empty space from the
indentation, like this::
'\n Makes strings from triple-quoted string literals usable.\n\n When you write a string as a triple-quoted literal, you end up with\n something that has lots of newlines and lots of empty space from the\n indentation, like this:\n '
This function removes the indentation from the string, removes superfluous
newlines and rearranges it, so that paragraphs are single lines separated
from each other by an empty line. The above string would end up like
this::
'Makes strings from triple-quoted string literals usable.\n\nWhen you write a string as a triple-quoted literal, you end up with something that has lots of newlines and lots of empty space from the indentation, like this:'
You might ask why we put whole paragraphs on one line. This is because
texts where lines are wrapped at a specific length, for example 50
characters, end up very ugly when a UI tries to display them with a
different line length. With paragraphs on single lines we leave all the
formatting up to the UI.
Note that all the lines have to have the same basic indentation for the
formatting to work::
# Won't work, because first line not indented.
paragraphs(\"""some text
bla bla bla
bla bla bla
\""")
# Will work, because all on the same line.
paragraphs(\"""
some text
bla bla bla
bla bla bla
\""")
This behaviour makes it possible to preserve some extra indentation::
# The first and last line will be left-aligned, the third indented.
paragraphs(\"""
some item about bla:
- bla bla bla
bla bla bla
\""")
You can also force linebreaks: if you write a bell control code '\\a' before
a newline on an otherwise non-empty line, the newline will stay intact.
Precautions:
- Don't use '\\a' and '\\x01' for other purposes in your text.
- Don't use '\\a' on otherwise empty lines.
- Only works with unicodes.
Where can you use this function? For ``help`` parameters of Odoo fields,
for ``print``\outs and exception texts. Note that if you want to use it
together with ``_`` for translation purposes, you have to put it this way
round::
raise Exception(paragraphs(_('''
NT is genetically descended from Bell Labs’s ancestral Unix code
or written in close imitation of its descendants. In particular,
Linux (from which we draw nigh unto God.
executing the procedure body for a compound expression is
accomplished by setting pc to the beginning of the creation.
(Taken from http://kingjamesprogramming.tumblr.com/.)''')))
"""
assert isinstance(u, unicode)
masked = re.sub(r"\a\n", "\x01", u)
stripped = masked.rstrip().lstrip('\n')
dedented = textwrap.dedent(stripped)
normal_ns = re.sub(r"\n{2,}", "\n\n", dedented)
spaces_for_ns = re.sub(r"(?<! \n ) \n (?! \n )",
# Matches only solitary newlines.
" ",
normal_ns,
flags=re.X)
return re.sub(r"\x01", "\n", spaces_for_ns)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment