Created
February 17, 2016 14:34
-
-
Save rmoehn/acecb206d44af2053364 to your computer and use it in GitHub Desktop.
Makes strings from triple-quoted string literals usable.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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