Commit 5f760677 authored by Michał Góral's avatar Michał Góral

more tags support proof of concept

parent f426db82
Pipeline #56748077 failed with stage
in 1 minute and 32 seconds
......@@ -103,7 +103,7 @@ def _create_default_blocks(cfg):
name='Next tasks',
fmt='<m class=comment>{id: >4}</m> <m class=warning>{priority:<2}</m>{description} <m class=info>{tags:>}</m>', # pylint: disable=line-too-long
fmt=' {description} <surr beg=1 end=2><surr beg="(" end=")"><m class=warning>{priority}</m></surr></surr> <m class=info>{tags:>}</m>', # pylint: disable=line-too-long
......@@ -15,35 +15,75 @@
# You should have received a copy of the GNU General Public License
# along with TWC. If not, see <>.
from collections import deque
from html.parser import HTMLParser
import attr
class _Tag:
def __init__(self, attrs):
for attr, val in attrs:
setattr(self, attr, val)
def markup(self, data):
'''Re-implement in child classes. Returns a non-nested markup object or
objects. If multiple objects are returned via a list), it markup will
be extended'''
raise NotImplemented('markup() not implemented')
class _M(_Tag):
def markup(self, data):
if data:
cl = getattr(self, 'class')
return (cl, data)
class _Surr(_Tag):
def markup(self, data):
if data:
# TODO: extract data lists
return [self.beg, data, self.end]
_tag_classes = {
'm': _M,
'surr': _Surr,
# pylint: disable=abstract-method
class Parser(HTMLParser):
'''Parser of task format markup'''
markup = attr.ib(factory=list)
_curr = attr.ib(None)
tags = attr.ib(factory=deque)
_data = attr.ib(None)
def __attrs_post_init__(self):
def handle_starttag(self, tag, attrs):
if tag == 'm':
self._curr = self._find_attr('class', attrs)
ctor = _tag_classes.get(tag)
if ctor:
def handle_endtag(self, tag):
if tag == 'm':
self._curr = None
ctor = _tag_classes.get(tag)
if ctor and self.tags and isinstance(self.tags[-1], ctor):
tag_obj = self.tags.pop()
newdata = tag_obj.markup(self._data)
self._data = newdata
if self._data and not self.tags:
if isinstance(self._data, list):
self._data = None
def handle_data(self, data):
if self._curr is not None:
self.markup.append((self._curr, data))
if self.tags:
self._data = data
def _find_attr(self, searched, tag_attrs):
for ta in tag_attrs:
if searched == ta[0]:
return ta[1]
return None
......@@ -45,6 +45,7 @@ class TaskView(urwid.Text):
parser = markup.Parser()
......@@ -87,7 +88,6 @@ class BlockView(urwid.BoxAdapter):
stack = deque(list(od.values()))
while len(stack) > 0:
task = stack.pop()
indent = ' ' * task['depth'] * 2
fmt = indent + self.block.fmt
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment