Add core.util.formatp (this is going to be good)

This commit is contained in:
enkore 2013-08-03 03:18:24 +02:00
parent e848fc4a6f
commit d5d0b19330
3 changed files with 80 additions and 0 deletions

View File

@ -7,11 +7,13 @@ from i3pystatus.core import Status
from i3pystatus.core.modules import Module, IntervalModule
from i3pystatus.core.settings import SettingsBase
from i3pystatus.core.config import Config
from i3pystatus.core.util import formatp
__all__ = [
"SettingsBase",
"Module", "IntervalModule",
"Status",
"formatp",
]
def main():

View File

@ -1,6 +1,7 @@
import collections
import itertools
import re
from .exceptions import *
from .imputil import ClassFinder
@ -106,3 +107,56 @@ def convert_position(pos, json):
if pos < 0:
pos = len(json) + (pos+1)
return pos
def formatp(string, **kwargs):
"""
Function for advanced format strings with partial formatting
This function consumes format strings with groups enclosed in brackets. A
group enclosed in brackets will only become part of the result if all fields
inside the group evaluate True in boolean contexts.
Groups can be nested. The fields in a nested group do not count as fields in
the enclosing group, i.e. the enclosing group will evaluate to an empty
string even if a nested group would be eligible for formatting. Nesting is
thus equivalent to a logical or of all enclosing groups with the enclosed
group.
Escaped brackets, i.e. \[ and \] are copied verbatim to output.
"""
pbracket = formatp.obracket_re.search(string)
if not pbracket:
return string.format(**kwargs)
pbracket = pbracket.start()
sbracket = list(formatp.cbracket_re.finditer(string))[-1].end()-1
prefix = string[:pbracket].format(**kwargs)
suffix = string[sbracket+1:].format(**kwargs)
string = string[pbracket+1:sbracket]
while True:
b = formatp.obracket_re.search(string)
e = list(formatp.cbracket_re.finditer(string))
if b and e:
b = b.start()
e = e[-1].end()
string = string[:b] + formatp(string[b:e], **kwargs) + string[e:]
else:
break
fields = formatp.field_re.findall(string)
successful_fields = 0
for fieldspec, fieldname in fields:
if kwargs.get(fieldname, False):
successful_fields += 1
if successful_fields != len(fields):
return prefix + suffix
else:
string = string.replace("\[", "[").replace("\]", "]")
return prefix + string.format(**kwargs) + suffix
formatp.field_re = re.compile(r"({(\w+)[^}]*})")
formatp.obracket_re = re.compile(r"(?<!\\)\[")
formatp.cbracket_re = re.compile(r"(?<!\\)\]")

View File

@ -238,3 +238,27 @@ class KeyConstraintDictAdvancedTests(unittest.TestCase):
assert kcd.missing() == set()
del kcd["foo"]
assert kcd.missing() == set(["foo"])
class FormatPTests(unittest.TestCase):
def test_escaping(self):
assert util.formatp("[razamba \[ mabe \]]") == "razamba [ mabe ]"
def test_numerical(self):
assert util.formatp("[{t} - [schmuh {x}]]", t=1, x=2) == "1 - schmuh 2"
assert util.formatp("[{t} - [schmuh {x}]]", t=1, x=0) == "1 - "
assert util.formatp("[{t} - [schmuh {x}]]", t=0, x=0) == ""
def test_nesting(self):
s = "[[{artist} - ]{album} - ]{title}"
assert util.formatp(s, title="Black rose") == "Black rose"
assert util.formatp(s, artist="In Flames", title="Gyroscope") == "Gyroscope"
assert util.formatp(s, artist="SOAD", album="Toxicity", title="Science") == "SOAD - Toxicity - Science"
assert util.formatp(s, album="Toxicity", title="Science") == "Toxicity - Science"
def test_bare(self):
assert util.formatp("{foo} blar", foo="bar") == "bar blar"
def test_presuffix(self):
assert util.formatp("ALINA[{title} schnacke]KOMMAHER", title="") == "ALINAKOMMAHER"
assert util.formatp("grml[{title}]") == "grml"
assert util.formatp("[{t}]grml") == "grml"