缩进保留多行字符串的格式
Indentation preserving formatting of multiline strings
我使用
等格式字符串生成 (C++) 代码位
memfn_declaration = '''\
{doc}
{static}auto {fun}({formals}){const}
-> {result};
'''
格式字符串很适合这个,但是有没有办法让它们在这里保持 {doc}
的缩进级别?它通常是多行的。
我知道我可以将 doc
对应的字符串缩进两个空格,我知道为此目的有很多功能,但这不是我要问的:我正在寻找一些东西无需调整我传递的字符串即可工作。
现在您已经发布了自己的答案并稍微澄清了您想要的内容。我认为通过定义自己的 str
子类来实现它会稍微好一些,该子类通过支持新的转换类型 'i'
来扩展字符串的格式化方式,它后面必须跟一个十进制数字表示所需的缩进级别。
这是在 Python 2 和 3 中都有效的实现:
import re
from textwrap import dedent
try:
from textwrap import indent
except ImportError:
def indent(s, prefix):
return prefix + prefix.join(s.splitlines(True))
class Indentable(str):
indent_format_spec = re.compile(r'''i([0-9]+)''')
def __format__(self, format_spec):
matches = self.indent_format_spec.search(format_spec)
if matches:
level = int(matches.group(1))
first, sep, text = dedent(self).strip().partition('\n')
return first + sep + indent(text, ' ' * level)
return super(Indentable, self).__format__(format_spec)
sample_format_string = '''\
{doc:i2}
{static}auto {fun}({formals}){const}
-> {result};
'''
specs = {
'doc': Indentable('''
// Convert a string to a float.
// Quite obsolete.
// Use something better instead.
'''),
'static': '',
'fun': 'atof',
'formals': 'const char*',
'const': '',
'result': 'float',
}
print(sample_format_string.format(**specs))
输出:
// Convert a string to a float.
// Quite obsolete.
// Use something better instead.
auto atof(const char*)
-> float;
问题是这样的:
'''\
反斜杠将忽略直到下一个字符的所有空格。删除反斜杠。
我正在寻找调用方站点上的轻量级内容。我可以接受以下折衷方案:我使用允许格式字符串查询属性 (0.foo
) 或项目 (0['foo']
) 的事实来传递格式字符串中的缩进级别。
import textwrap
class Indent(str):
def __new__(cls, *args, **kwargs):
return super(Indent, cls).__new__(cls, *args, **kwargs)
def __getitem__(self, level):
first, _, text = textwrap.dedent(self).strip().partition('\n')
text = textwrap.indent(text, ' ' * level)
return first + '\n' + text
def indent_doc(d):
res = dict(d)
res['doc'] = Indent(d['doc'])
return res
format = '''
{doc[2]}
{static}auto {fun}({formals}){const}
-> {result};
'''
specs = {
'doc': '''
// Convert a string to a float.
// Quite obsolete.
// Use something better instead.
''',
'static': '',
'fun': 'atof',
'formals': 'const char*',
'const': '',
'result': 'float',
}
print(format.format_map(indent_doc(specs)))
给出:
$ python /tmp/foo.py
// Convert a string to a float.
// Quite obsolete.
// Use something better instead.
auto atof(const char*)
-> float;
我很乐意阅读相关意见。
我使用
等格式字符串生成 (C++) 代码位memfn_declaration = '''\
{doc}
{static}auto {fun}({formals}){const}
-> {result};
'''
格式字符串很适合这个,但是有没有办法让它们在这里保持 {doc}
的缩进级别?它通常是多行的。
我知道我可以将 doc
对应的字符串缩进两个空格,我知道为此目的有很多功能,但这不是我要问的:我正在寻找一些东西无需调整我传递的字符串即可工作。
现在您已经发布了自己的答案并稍微澄清了您想要的内容。我认为通过定义自己的 str
子类来实现它会稍微好一些,该子类通过支持新的转换类型 'i'
来扩展字符串的格式化方式,它后面必须跟一个十进制数字表示所需的缩进级别。
这是在 Python 2 和 3 中都有效的实现:
import re
from textwrap import dedent
try:
from textwrap import indent
except ImportError:
def indent(s, prefix):
return prefix + prefix.join(s.splitlines(True))
class Indentable(str):
indent_format_spec = re.compile(r'''i([0-9]+)''')
def __format__(self, format_spec):
matches = self.indent_format_spec.search(format_spec)
if matches:
level = int(matches.group(1))
first, sep, text = dedent(self).strip().partition('\n')
return first + sep + indent(text, ' ' * level)
return super(Indentable, self).__format__(format_spec)
sample_format_string = '''\
{doc:i2}
{static}auto {fun}({formals}){const}
-> {result};
'''
specs = {
'doc': Indentable('''
// Convert a string to a float.
// Quite obsolete.
// Use something better instead.
'''),
'static': '',
'fun': 'atof',
'formals': 'const char*',
'const': '',
'result': 'float',
}
print(sample_format_string.format(**specs))
输出:
// Convert a string to a float.
// Quite obsolete.
// Use something better instead.
auto atof(const char*)
-> float;
问题是这样的:
'''\
反斜杠将忽略直到下一个字符的所有空格。删除反斜杠。
我正在寻找调用方站点上的轻量级内容。我可以接受以下折衷方案:我使用允许格式字符串查询属性 (0.foo
) 或项目 (0['foo']
) 的事实来传递格式字符串中的缩进级别。
import textwrap
class Indent(str):
def __new__(cls, *args, **kwargs):
return super(Indent, cls).__new__(cls, *args, **kwargs)
def __getitem__(self, level):
first, _, text = textwrap.dedent(self).strip().partition('\n')
text = textwrap.indent(text, ' ' * level)
return first + '\n' + text
def indent_doc(d):
res = dict(d)
res['doc'] = Indent(d['doc'])
return res
format = '''
{doc[2]}
{static}auto {fun}({formals}){const}
-> {result};
'''
specs = {
'doc': '''
// Convert a string to a float.
// Quite obsolete.
// Use something better instead.
''',
'static': '',
'fun': 'atof',
'formals': 'const char*',
'const': '',
'result': 'float',
}
print(format.format_map(indent_doc(specs)))
给出:
$ python /tmp/foo.py
// Convert a string to a float.
// Quite obsolete.
// Use something better instead.
auto atof(const char*)
-> float;
我很乐意阅读相关意见。