Tag interpretation implementation

This commit is contained in:
Jamie Hardt
2019-10-08 13:42:52 -07:00
parent 0162ad9b2e
commit b62724c476
2 changed files with 110 additions and 0 deletions

View File

@@ -1,4 +1,5 @@
from . import broadcast_timecode
from parsimonious import Grammar, NodeVisitor
import math
class Transformation:
@@ -55,3 +56,71 @@ class TimecodeInterpreter(Transformation):
return dict(frame_count=frame_count, logical_fps=lfps, drop_frame=drop_frame)
class TagInterpreter:
tag_grammar = Grammar(
r"""
document = modifier? line? word_sep? tag_list?
line = word (word_sep word)*
tag_list = tag*
tag = key_tag / short_tag / full_text_tag / tag_junk
key_tag = "[" key "]" word_sep?
short_tag = "$" key "=" word
full_text_tag = "{" key "=" value "}" word_sep?
key = ~"[A-Za-z][A-Za-z0-9_]*"
value = ~"[^}]+"
tag_junk = (word word_sep)*
word = ~"[^ \[\{\$][^ ]*"
word_sep = ~" +"
modifier = ("@" / "&") word_sep?
"""
)
class TagListVisitor(NodeVisitor):
def visit_document(self, _, visited_children):
modifier_opt, line_opt, _, tag_list_opt = visited_children
return dict(line= next(iter(line_opt), None),
tags= next(iter(tag_list_opt), None),
mode= next(iter(modifier_opt), 'Normal')
)
def visit_line(self, node, _):
return str.strip(node.text, " ")
def visit_modifier(self, node, _):
if node.text.startswith('@'):
return 'Timespan'
elif node.text.startswith('&'):
return 'Append'
else:
return 'Normal'
def visit_tag_list(self, _, visited_children):
retdict = dict()
for child in visited_children:
k, v = child[0]
retdict[k] = v
return retdict
def visit_key_tag(self, _, children):
return children[1].text, children[1].text
def visit_short_tag(self, _, children):
return children[1].text, children[3].text
def visit_full_text_tag(self, _, children):
return children[1].text, children[3].text
def generic_visit(self, node, visited_children):
return visited_children or node
def __init__(self):
pass
def parse_tags(self, source):
parse_tree = self.tag_grammar.parse(source)
v = TagInterpreter.TagListVisitor()
return v.visit(parse_tree)

View File

@@ -0,0 +1,41 @@
import unittest
from ptulsconv.transformations import TagInterpreter
class MyTestCase(unittest.TestCase):
def test_line(self):
ti = TagInterpreter()
s1 = ti.parse_tags("this is a test")
self.assertEqual(s1['line'], "this is a test")
self.assertEqual(s1['mode'], 'Normal')
self.assertEqual(len(s1['tags']), 0)
s2 = ti.parse_tags("this! IS! Me! ** Typing! 123 <> |||")
self.assertEqual(s2['line'], "this! IS! Me! ** Typing! 123 <> |||")
self.assertEqual(s2['mode'], 'Normal')
self.assertEqual(len(s2['tags']), 0)
def test_tags(self):
ti = TagInterpreter()
s1 = ti.parse_tags("{a=100}")
self.assertIn('tags', s1)
self.assertEqual(s1['tags']['a'], "100")
s2 = ti.parse_tags("{b=This is a test} [option] $X=9")
self.assertEqual(s2['tags']['b'], 'This is a test')
self.assertEqual(s2['tags']['option'], 'option')
self.assertEqual(s2['tags']['X'], "9")
def test_modes(self):
ti = TagInterpreter()
s1 = ti.parse_tags("@ Monday Tuesday {a=1}")
self.assertEqual(s1['mode'], 'Timespan')
s2 = ti.parse_tags("Monday Tuesday {a=1}")
self.assertEqual(s2['mode'], 'Normal')
s3 = ti.parse_tags("&Monday Tuesday {a=1}")
self.assertEqual(s3['mode'], 'Append')
if __name__ == '__main__':
unittest.main()