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.modules import Module, IntervalModule
from i3pystatus.core.settings import SettingsBase from i3pystatus.core.settings import SettingsBase
from i3pystatus.core.config import Config from i3pystatus.core.config import Config
from i3pystatus.core.util import formatp
__all__ = [ __all__ = [
"SettingsBase", "SettingsBase",
"Module", "IntervalModule", "Module", "IntervalModule",
"Status", "Status",
"formatp",
] ]
def main(): def main():

View File

@ -1,6 +1,7 @@
import collections import collections
import itertools import itertools
import re
from .exceptions import * from .exceptions import *
from .imputil import ClassFinder from .imputil import ClassFinder
@ -106,3 +107,56 @@ def convert_position(pos, json):
if pos < 0: if pos < 0:
pos = len(json) + (pos+1) pos = len(json) + (pos+1)
return pos 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() assert kcd.missing() == set()
del kcd["foo"] del kcd["foo"]
assert kcd.missing() == set(["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"