I'm using the python cog module to generate C++ boilerplate code, and it is working great so far, but my only concern is that the resulting code, which is ugly by itself, is made worse by the fact that it's not indented. I'm too lazy to get the indentation right in the string generation function, so I'm wondering if there is a Python util function to indent the content of a multi-line string?
-
What platform are you running on. On many you could use some external formatter like uncrustify, astyle or indent. – Benjamin Bannier Nov 22 '11 at 22:05
-
@honk, this is on ubuntu 10.10 running python 2.6 – lurscher Nov 23 '11 at 02:07
-
2`mytext = re.sub( '^',' '*4, mytext ,flags=re.MULTILINE )` – dreftymac Aug 07 '17 at 17:42
4 Answers
You can indent the lines in a string by just padding each one with proper number of pad characters. This can easily be done by using the textwrap.indent()
function which was added to the module in Python 3.3. Alternatively you could use the code below which will also work in earlier Python versions.
try:
import textwrap
textwrap.indent
except AttributeError: # undefined function (wasn't added until Python 3.3)
def indent(text, amount, ch=' '):
padding = amount * ch
return ''.join(padding+line for line in text.splitlines(True))
else:
def indent(text, amount, ch=' '):
return textwrap.indent(text, amount * ch)
text = '''\
And the Lord God said unto the serpent,
Because thou hast done this, thou art
cursed above all cattle, and above every
beast of the field; upon thy belly shalt
thou go, and dust shalt thou eat all the
days of thy life: And I will put enmity
between thee and the woman, and between
thy seed and her seed; it shall bruise
thy head, and thou shalt bruise his
heel.
3:15-King James
'''
print('Text indented 4 spaces:\n')
print(indent(text, 4))
Result:
Text indented 4 spaces:
And the Lord God said unto the serpent,
Because thou hast done this, thou art
cursed above all cattle, and above every
beast of the field; upon thy belly shalt
thou go, and dust shalt thou eat all the
days of thy life: And I will put enmity
between thee and the woman, and between
thy seed and her seed; it shall bruise
thy head, and thou shalt bruise his
heel.
3:15-King James

- 119,623
- 25
- 170
- 301
-
1Thanks, I found this useful. However, if the text to be indented _ends_ in a newline this will add padding afterwards, which will indent whatever comes next. So, best to add a check for that if it's important. – Beright Oct 05 '13 at 08:16
-
@Beright: Sorry, I think you bewrong about that. The `text` in my answer ends with a newline. If you add a `print 'another line'` at the end of it that will _not_ be indented. – martineau Oct 05 '13 at 08:25
-
No I Beright. If you place a comma after your print statement ("print indent(text, 4),") and then, on the next line, put "print 'another line'" it will in fact be indented 4 spaces (plus an extra space from the comma) – Beright Mar 20 '14 at 22:35
-
@Beright: Of course doing so would do that, since it supresses the newline `print` normally adds to the end of its output -- however it's not because the code in my answer added any extra padding regardless of whether the text to be indented ends in a newline or not. – martineau Mar 21 '14 at 01:49
-
I didn't say regardless, I explicitly said that "if the text to be indented ends in a newline" it's something to look out for. I was just trying to warn anyone who doesn't expect a line containing nothing to be indented. (BTW when I put @martineau at the beginning it disappears, do you know what I'm doing wrong?) – Beright Mar 21 '14 at 15:06
-
1@Beright: As I said, the text in the example in my answer does end in a newline -- it's right after the word "James" before the ending triple-quotes. You must mean additional newlines beyond that -- as indeed it will indent such trailing blank lines. That can easily be remedied by changing the last line to `return padding + ('\n'+padding).join(lines.rstrip().split('\n'))`. It keeps removing the @martineau because it'll happen automatically since your comment is under my answer. – martineau Mar 21 '14 at 15:37
-
4Since python v3.3, you can just `import textwrap` and then `textwrap.indent(text, ' ' * 4)` – gimboland Nov 14 '16 at 15:52
-
@gimboland: Good point, but it didn't exist almost 6 years ago when I wrote my answer (Python 3.3 wasn't released until Sep 29 '12). In addition, `textwrap.indent()` has an additional argument named `predicate` which might address @Beright's issues if it were used directly (instead of indirectly as my updated answer does when it's present). – martineau Nov 14 '16 at 19:01
-
@martineau Yep, I wasn't saying it in response to your answer, but as extra information for anyone else coming across this question today. Thanks for the tip about `predicate` - I hadn't noticed that. :-) – gimboland Dec 05 '16 at 10:21
-
Can we try & keep vulgar language out of answers that don't absolutely require it? Rolled back & locked; email me or take it to [meta] if you have some pressing need to alter the quote after 5 years of peace. – Shog9 Jan 14 '17 at 02:58
If you have a leading newline:
Heredocs can contain a literal newline, or you can prepend one.
indent = ' '
indent_me = '''
Hello
World
'''
indented = indent_me.replace('\n', '\n' + indent)
print(indented)
Here is it shown in pprint dump:
>>> pprint(indented)
' Hello\n World\n '
Awkward, but works
If you do not have a leading newline:
indent = ' '
indent_me = '''\
Hello
World
'''
indented = indent + indent_me.replace('\n', '\n' + indent)
print(indented)
Optional, trim first newline and trailing spaces/tabs
.lstrip('\n').rstrip(' \t')

- 16,657
- 15
- 135
- 147
Why not pipe the output through a command-line code formatter such as astyle?
-
-
i think this can work, since in any case i have to add `cog` as a pre-build step, i might as well add `indent` or whatever in it – lurscher Nov 23 '11 at 19:26
There is a script located in the python Tools/Scripts/
directory which is primarily for fixing the indentation of entire python files. However, you can easily tweak the script a little and apply it to sections/lines of code, or other types of files.
The script is also located online, here:
http://svn.python.org/projects/python/trunk/Tools/scripts/reindent.py
Or, as a module here:
http://pypi.python.org/pypi/Reindent/0.1.0

- 51,908
- 16
- 134
- 170
-
@honk Yea, I think so too, but since the `reindent.py` is only a hundred or so lines of pretty simple code, what I am suggesting is to customize it a little and apply it to the c/c++. Or even subclass the `Reindenter` class in `reindent.py` to make it specific for c++. It may not be the quickest solution, but its an option ). – chown Nov 22 '11 at 22:08