Add core.util.formatp (this is going to be good)
This commit is contained in:
parent
e848fc4a6f
commit
d5d0b19330
@ -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():
|
||||
|
@ -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"(?<!\\)\]")
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user