mirror of
https://github.com/iluvcapra/ptulsconv.git
synced 2025-12-31 08:50:48 +00:00
Tag interpretation implementation
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
41
tests/test_tag_interpreter.py
Normal file
41
tests/test_tag_interpreter.py
Normal 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()
|
||||
Reference in New Issue
Block a user