diff options
author | Lars Wirzenius <liw@liw.fi> | 2011-08-31 16:12:12 +0100 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2011-08-31 16:12:12 +0100 |
commit | 95da407b5e2ada81b02fe002c913904c62d7c3da (patch) | |
tree | f1e464c38f2517636dd3c10c0746f3859b9678fd | |
parent | 74988226cae019734fc114eda2a326ec298045f6 (diff) | |
download | python-ttystatus-95da407b5e2ada81b02fe002c913904c62d7c3da.tar.gz |
Implement format string parsing.
-rw-r--r-- | ttystatus/fmt.py | 51 | ||||
-rw-r--r-- | ttystatus/fmt_tests.py | 44 |
2 files changed, 90 insertions, 5 deletions
diff --git a/ttystatus/fmt.py b/ttystatus/fmt.py index 16b2fe0..16b69de 100644 --- a/ttystatus/fmt.py +++ b/ttystatus/fmt.py @@ -14,10 +14,53 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. +import inspect +import re + import ttystatus -widgets = [getattr(ttystatus, x) - for x in dir(ttystatus) - if isinstance(getattr(ttystatus, x), ttystatus.Widget) and - getattr(ttystatus, x) != ttystatus.Widget] +def _find_widgets(): + names = dir(ttystatus) + objs = [getattr(ttystatus, x) for x in names] + classes = [o for o in objs if inspect.isclass(o)] + widgets = [c for c in classes if issubclass(c, ttystatus.Widget)] + subclasses = [w for w in widgets if w != ttystatus.Widget] + return subclasses + +widgets = _find_widgets() + + +def parse(fmt): + '''Parse format string.''' + + names = [x.__name__ for x in widgets] + namespat = '|'.join(names) + argspat = r'[0-9a-zA-Z,_-]*' + pat = r'%%(?P<class>%s)\((?P<args>%s)\)' % (namespat, argspat) + pat = re.compile(pat) + + result = [] + prefix = '' + while fmt: + m = pat.match(fmt) + if m: + klass = getattr(ttystatus, m.group('class')) + argnames = m.group('args').split(',') + argnames = [x for x in argnames if x] + if prefix: + result.append(ttystatus.Literal(prefix)) + prefix = '' + result.append(klass(*argnames)) + fmt = fmt[m.end():] + elif fmt.startswith('%%'): + prefix += '%' + fmt = fmt[2:] + else: + prefix += fmt[0] + fmt = fmt[1:] + + if prefix: + result.append(ttystatus.Literal(prefix)) + return result + diff --git a/ttystatus/fmt_tests.py b/ttystatus/fmt_tests.py index 1848114..af39948 100644 --- a/ttystatus/fmt_tests.py +++ b/ttystatus/fmt_tests.py @@ -23,7 +23,49 @@ class FormatTests(unittest.TestCase): def test_knows_widgets(self): self.assertEqual(type(ttystatus.fmt.widgets), list) + self.assert_(len(ttystatus.fmt.widgets) > 0) for widget in ttystatus.fmt.widgets: - self.assert_(isinstance(widget, ttystatus.Widget)) + self.assert_(issubclass(widget, ttystatus.Widget)) self.assertNotEqual(widget, ttystatus.Widget) + def test_parses_string_without_widgets(self): + x = ttystatus.fmt.parse('hello, world') + self.assertEqual(len(x), 1) + self.assertEqual(type(x[0]), ttystatus.Literal) + self.assertEqual(str(x[0]), 'hello, world') + + def test_parses_escaped_pecent(self): + x = ttystatus.fmt.parse('%%') + self.assertEqual(len(x), 1) + self.assertEqual(type(x[0]), ttystatus.Literal) + self.assertEqual(str(x[0]), '%') + + def test_parses_parameterless_widget(self): + x = ttystatus.fmt.parse('%ElapsedTime()') + + self.assertEqual(len(x), 1) + self.assertEqual(type(x[0]), ttystatus.ElapsedTime) + + def test_parses_widget_with_one_parameter(self): + x = ttystatus.fmt.parse('%String(name)') + + self.assertEqual(len(x), 1) + + self.assertEqual(type(x[0]), ttystatus.String) + self.assertEqual(x[0]._key, 'name') + + def test_parses_some_widgets(self): + x = ttystatus.fmt.parse('hello, %String(name): %ElapsedTime()') + + self.assertEqual(len(x), 4) + + self.assertEqual(type(x[0]), ttystatus.Literal) + self.assertEqual(str(x[0]), 'hello, ') + + self.assertEqual(type(x[1]), ttystatus.String) + + self.assertEqual(type(x[2]), ttystatus.Literal) + self.assertEqual(str(x[2]), ': ') + + self.assertEqual(type(x[3]), ttystatus.ElapsedTime) + |