2
\$\begingroup\$

I wondered if there was any better way of doing so.

I had a hard time figuring it out (it seemed nobody else already tried to do so).

import re
import string

class BetterFormat(string.Formatter):
    """ Introduce better formatting """

    def parse(self, format_string):
        """ Receive the string to be transformed and split its elements to facilitate the actual replacing """

        # Automatically counts how many tabs are before the {} then automatically adds the new rule (defined in format_field)
        return [(before, identifiant, str(len(re.search('\t*$', before).group(0))) + '\t' + (param if param is not None else ''), modif) for before, identifiant, param, modif in super().parse(format_string)]

    def format_field(self, v, pattern):
        """ Receive the string to be transformed and the pattern according which it is supposed to be modified """

        # Hacky way to remove a dynamic sequence of characters ([0-9]+\t) and returning it

        sharedData = {'numberOfTabs': 0}

        def extractTabs(pattern):
            sharedData['numberOfTabs'] = int(pattern.group(0)[:-1]) # Save the data that will be erased
            return "" # This will erase it

        pattern = re.sub('[0-9]+\t', extractTabs, pattern)

        if sharedData['numberOfTabs']: # If there are tabs to be added
            v = (sharedData['numberOfTabs'] * '\t').join(v.splitlines(True))

        return super().format_field(v, pattern)

css = """
/* Some multi-lines CSS
All automatically indented */
"""

print(BetterFormat.format("""
<html>
    <head>
        <style type="text/css">
            {css}
        </style>
    </head>
    <body>
        <!-- Whatever -->
    </body>
</html>""",
    css=css
 ))

 # Output
 <html>
    <head>
        <style type="text/css">
            /* Some multi-line CSS 
            All automatically indented */
        </style>
    </head>
    <body>
        <!-- Whatever -->
    </body>
</html>

Otherwise, previously I had to do this:

# […]

print(""" […]
            {css}
[…]""".format(css='\t\t\t'.join(css.splitlines(True)))
)

And just so you better understand, I first only implemented BetterFormat.format_field, then I was able to do that, but I was still required to count the number of tabulations myself:

# […]

print(""" […]
            {css:3\t}
[…]""".format(css=css)
)    
\$\endgroup\$
1
  • \$\begingroup\$ parse() is doing too much to be one-lined. List comprehension can be very useful, but not when it causes the line to be over 200 characters. This would be more legible if the line was broken down into smaller parts. Making the tuple creation a different method would be an easy piece to extract. \$\endgroup\$ Aug 26, 2013 at 20:26

1 Answer 1

1
\$\begingroup\$

Could textwrap do some of the job?

Particularly the dedent and indent function? You will still need to count the number of tabs you want, but the rest will be done.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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