def test_milestone_option(self): """Test that passing a milestone option gives back only the text from the relevant <milestone/> element to the next one.""" tokens = Tokenizer(milestone="401").from_etree(self.testdoc)['tokens'] self.assertEqual(len(tokens), 132) self.assertEqual(tokens[0]['t'], 'Իսկ') self.assertEqual(tokens[-1]['t'], 'ժամկի։') tokens407 = Tokenizer(milestone="407").from_etree( self.testdoc)['tokens'] self.assertEqual(len(tokens407), 76) self.assertEqual(tokens407[0]['t'], 'Դարձլ') self.assertEqual(tokens407[-1]['t'], 'ուռհայ։')
def test_witnessid(self): struct = Tokenizer(id_xpath='//t:msIdentifier/*/text()').from_etree( self.testdoc_noglyphs) self.assertEqual(struct['id'], 'Yerevan Matenadaran 1731') struct = Tokenizer(id_xpath='//t:msDesc/@xml:id').from_etree( self.testdoc_noglyphs) self.assertEqual(struct['id'], 'F') filename = self.testfiles['v913'] struct = Tokenizer(id_xpath='//t:msDesc/@xml:id', milestone="496").from_file(filename) self.assertEquals(struct['id'], "Y")
def test_gap(self): """Test that gaps are handled correctly. At the moment this means that no token should be generated for a gap.""" tokens = Tokenizer(milestone='410').from_file( self.testfiles['xmlreal'])['tokens'] gaptoken = { 't': 'զ', 'n': 'զ', 'lit': 'զ<gap extent="5"/>', 'context': 'text/body/ab', 'page': { 'n': '002r' }, 'column': { 'n': '1' }, 'line': { 'xml:id': 'l101252731', 'n': '26' } } found = False for t in tokens: if t['lit'].find('gap') > 0: self.assertEqual(t, gaptoken) found = True break self.assertTrue(found)
def test_tagend(self): filename = self.testfiles['xmlreal'] tokens = Tokenizer(milestone="401").from_file(filename)['tokens'] self.assertEqual(tokens[1]['t'], "ընդ") self.assertFalse('join_next' in tokens[1]) for t in tokens: self.assertNotEqual(t['t'], "")
def test_debug(self): filename = '/Users/tla/Projects/MatthewEdessa/transcription/tei-xml/M3071-merged.json.tei.xml' tokens = Tokenizer(milestone="401").from_file(filename)['tokens'] self.assertEqual(tokens[14]['t'], "բյց") self.assertFalse('join_next' in tokens[1]) for t in tokens: self.assertNotEqual(t['t'], "")
def test_normalisation(self): """Test that passing a normalisation function works as intended""" orig_count = len( Tokenizer(milestone='401').from_etree(self.testdoc)['tokens']) tok = Tokenizer(milestone='401', normalisation=helpers.normalise) tokens = tok.from_etree(self.testdoc)['tokens'] normal = { 0: 'իսկ', 4: 'այնոսիկ', 8: '401', 13: 'բզմ', 17: 'հարօոյ', 20: 'տաճկաց', 43: 'հռչակօոր' } for i, n in normal.items(): self.assertEqual(tokens[i]['n'], n) # See if our blanked-out token was removed from the stream self.assertEqual(len(tokens), orig_count - 1) tok = Tokenizer(milestone='407', normalisation=helpers.bad_normalise) try: result = tok.from_etree(self.testdoc) self.fail("should have raised an error") except Exception as e: self.assertIsInstance(e, JSONDecodeError)
def test_simple(self): """Test that basic parsing with no specified options works properly.""" tokens = Tokenizer().from_etree(self.testdoc_noglyphs)['tokens'] first = { 't': 'եղբայրն', 'n': 'եղբայրն', 'lit': 'եղբայրն', 'context': 'text/body/ab', 'page': { 'n': '75r' }, 'line': { 'facs': '#z101276867', 'n': '1', 'xml:id': 'l101276867' } } last = { 't': 'զօրա֊', 'n': 'զօրա֊', 'lit': 'զօրա֊', 'context': 'text/body/ab', 'page': { 'n': '75v' }, 'line': { 'break': 'no', 'facs': '#z101276853', 'n': '25', 'xml:id': 'l101276853' } } self.assertEqual(tokens[0], first) self.assertEqual(tokens[-1], last) self.assertEqual(313, len(tokens)) origtext = 'եղբայրն ներսէսի ի կարմիր վանգն. և նա՛ յաջորդեաց ի հոռոմ կլայն. և յետ նր ներսէս մինչև ի ոհաննէս. ' \ 'և յայնմ ժմկի դաւիթ անուն ոմն ձեռնադրեա՛լ մինչև ի ստեփա֊նոս որ գերեցաւ ի յեգիոս և ի սիս ձեռնա֊' \ 'դրեալ կթղս. մինչև ցթումավդպտն. և բաժա֊նեա՛լ նր եղև աթոռն սահմանել յէջմիածին և զբունն ոչ ' \ 'խափանեալ զի դեռևս կենդա֊նի էր կաթղսն սըսա՛. զի ի լուսաւորչէն մինչև ի նայ էր հասեալ կթղսութի. և ' \ 'նա՛ ոչ եղև, քաղաքն զօրավար եդաք և անտի կամեցաք զի նա՛ դեռևս կենդանի էր։ թ. եղբայրք զա֊' \ 'քարիայ և իւանա՛ դարձաւ վրացի և եղբայրըն ոչ. նա՛ խնդրէր վրան զի պատարագ ա֊րասցեն։ Իսկ ընդ ' \ 'աւուրսն ընդ այնոսիկ, և ի ամին ն՟ա՟. եղև սով սաստիկ ի բզմ տեղիս. բայց յաշխարհն հարաւոյ ի յերկրին ' \ 'տաճկա՛ց եղև նեղութի մեծ և առաւել քան զամ ի միջա֊գետս. և ի խստութե սովոյն տագնապ և տատանում ' \ 'լինէր ի բզմ տեղիս, և ի հռչա֊կաւոր մայրաքղքն ուռհայ, զորս կանգընեաց տիգրան արքայ հայոց և կացեալ ' \ 'սովն յա՛յնմ աշխարհին զա՛մս .է՟. և անթիւ լինէր կոտո֊րածն յերեսաց սովոյն այն. և աշխարհին տաճըկաց ' \ 'լինէր անցումն մեծ և քրիստոնէիցն անթիւք մեռան յերեսաց բարկութե սովոյն. և զկնի ե ամի եկեալ մորեխ ' \ 'յայնմ գաւա֊ռէն որպ զաւազ ծովու և ապականեաց, զըերկիր. և սաստկանայր սովն առաւել քան զըառաւեն, և ' \ 'զայրացեալ բազմացան և գա֊զանաբար անողորմ յարձակեալ զմիմեանսս ուտէին, և իշխանքն և մեծամեծքն ' \ 'ընդաւք և մըրգաւք կերակրէին. և եղև անցումն ա֊նասնոցն. բզմ գեղք և գաւառք յանմարդ լինէին, և այլ ոչ ' \ 'շինեցան մինչև ցայսօր ժամկի։ Դարձլ ի թվականութես հայոց ի ն՟ և է՟. ամին զօրա՛ժողով լինէր ազգն ' \ 'արապկաց ուռհայ և ամ եդեսացոց աշխարհն ահա֊գին բազմութբ անցխալ ընդ մեծ գետն եփրատ և եկեա՛լ ի վր ' \ 'ամուր քաղաքին որ կոչի սամուսատ. և ելանէր ի պտզմն, զօրապե֊տըն հոռոմոց, որում անուն ասէին պա֊' \ 'ռակամանոս, ա՛յր զօրաւոր և քաջ. և ի դուռըն քաղաքին բախէին զմիմեանս և աւուր յայնմիկ հարին ' \ 'տաճկունք զօրսն հոռոմոց և արարին կոտորած առ դրան քաղաքին. և յե՛տ աւուրց ինչ առաւ քաղաքն ' \ 'սամուսատ մերձ ի քղք ուռհայ։ Իսկ ի թուակա֊նութես ազգիս հայոց ի դ՟ճ՟ և ի ը՟ ամին, զօրա֊' tokentext = tokens_to_string(tokens) self.assertEqual(tokentext, origtext)
def test_file_input(self): """Make sure we get a result when passing a file path.""" filename = self.testfiles['xmlreal'] tok = Tokenizer(milestone="412") tokens = tok.from_file(filename)['tokens'] first_word = {'t': 'Իսկ', 'n': 'Իսկ', 'lit': '<supplied reason="missing highlight">Ի</supplied>սկ', 'context': 'text/body/ab', 'page': {'n': '002v'}, 'column': {'n': '1'}, 'line': {'xml:id': 'l101252792', 'n': '3'}} last_word = {'t': 'փառւրութբ։', 'n': 'փառւրութբ։', 'lit': 'փառ<abbr>ւ</abbr>րու<abbr>թբ</abbr>։', 'context': 'text/body/ab', 'page': {'n': '002v'}, 'column': {'n': '2'}, 'line': {'xml:id': 'l101252825', 'n': '5'}} self.assertEqual(len(tokens), 155) self.assertEqual(tokens[0], first_word) self.assertEqual(tokens[-1], last_word)
def test_block_xpath(self): # First use the default block expression and see if we get our paragraph-in-note default_tokens = Tokenizer().from_etree(self.doc3519)["tokens"] found_imagine = False for t in default_tokens: self.assertNotEqual("calendar", t.get('t')) if t.get('t') == "Imagine": found_imagine = True self.assertTrue(found_imagine) # Now do it again with a more exclusionary xpath default_tokens = Tokenizer(block_xpath='//t:body/t:p').from_etree( self.doc3519)["tokens"] found_imagine = False for t in default_tokens: self.assertNotEqual("calendar", t.get('t')) if t.get('t') == "Imagine": found_imagine = True self.assertFalse(found_imagine)
def test_substitution_layer(self): """Test that the first_layer option works correctly.""" tokens = Tokenizer(first_layer=True).from_etree(self.testdoc)['tokens'] # Find the token that has our substitution for t in tokens: if t['lit'] != 'դե<subst instant="true"><del>ղ</del><add>ռ</add></subst>ևս': continue self.assertEqual(t['t'], 'դեղևս') break else: self.assertTrue(False, "Did not find the testing token")
def test_substitution(self): """Test that the correct words are picked out of a subst tag.""" tokens = Tokenizer().from_etree(self.testdoc)['tokens'] # Find the token that has our substitution for t in tokens: if t['lit'] != 'դե<subst instant="true"><del>ղ</del><add>ռ</add></subst>ևս': continue self.assertEqual(t['t'], 'դեռևս') break else: self.assertTrue(False, "Did not find the testing token")
def test_file_input(self): """Make sure we get a result when passing a file path.""" filename = self.testfiles['xmlreal'] tok = Tokenizer(milestone="412") tokens = tok.from_file(filename)['tokens'] first_word = { 't': 'Իսկ', 'n': 'Իսկ', 'lit': '<supplied reason="missing highlight">Ի</supplied>սկ', 'context': 'text/body/ab', 'page': { 'n': '002v' }, 'column': { 'n': '1' }, 'line': { 'xml:id': 'l101252792', 'n': '3' } } last_word = { 't': 'փառւրութբ։', 'n': 'փառւրութբ։', 'lit': 'փառ<abbr>ւ</abbr>րու<abbr>թբ</abbr>։', 'context': 'text/body/ab', 'page': { 'n': '002v' }, 'column': { 'n': '2' }, 'line': { 'xml:id': 'l101252825', 'n': '5' } } self.assertEqual(len(tokens), 155) self.assertEqual(tokens[0], first_word) self.assertEqual(tokens[-1], last_word)
def test_token_context(self): """Test that each token has a context, and each 'lit' string is parseable.""" tok = Tokenizer(normalisation=helpers.normalise) tokens = tok.from_file(self.testfiles['xmlreal'])['tokens'] for t in tokens: self.assertTrue('context' in t) self.assertTrue('lit' in t) try: fromstring('<word>' + t['lit'] + '</word>') except XMLSyntaxError: self.fail() # Again, with first layer tok = Tokenizer(normalisation=helpers.normalise, first_layer=True) tokens = tok.from_file(self.testfiles['xmlreal'])['tokens'] for t in tokens: self.assertTrue('context' in t) self.assertTrue('lit' in t) try: fromstring('<word>' + t['lit'] + '</word>') except XMLSyntaxError: self.fail()
def testLegacyTokenization(self): """Test with legacy TEI files from 2009, to make sure the tokenizer works with them.""" testfile = self.testfiles['tei_2009'] with open(self.testfiles['tei_2009_reference'], encoding='utf-8') as rfh: rtext = rfh.read() reference = rtext.rstrip().split(' ') tokens = Tokenizer().from_file(testfile)['tokens'] for i, t in enumerate(tokens): self.assertEqual( t['t'], reference[i], "Mismatch at index %d: %s - %s" % (i, t, reference[i]))
def test_normalisation(self): """Test that passing a normalisation function works as intended""" orig_count = len(Tokenizer(milestone='401').from_etree(self.testdoc)['tokens']) tok = Tokenizer(milestone='401', normalisation=helpers.normalise) tokens = tok.from_etree(self.testdoc)['tokens'] normal = {0: 'իսկ', 4: 'այնոսիկ', 8: '401', 13: 'բզմ', 17: 'հարօոյ', 20: 'տաճկաց', 43: 'հռչակօոր'} for i, n in normal.items(): self.assertEqual(tokens[i]['n'], n) # See if our blanked-out token was removed from the stream self.assertEqual(len(tokens), orig_count - 1) tok = Tokenizer(milestone='407', normalisation=helpers.bad_normalise) try: result = tok.from_etree(self.testdoc) self.fail("should have raised an error") except Exception as e: self.assertIsInstance(e, JSONDecodeError)
def test_location(self): tokens = Tokenizer(milestone='407').from_etree(self.testdoc)['tokens'] self.assertEqual(tokens[0]['page'], {'n': '75v'}) self.assertEqual(tokens[0]['line'], { 'xml:id': 'l101276931', 'facs': '#z101276931', 'n': '12' }) # first token self.assertEqual(tokens[10]['line'], { 'xml:id': 'l101276840', 'facs': '#z101276840', 'n': '13' }) # line broken self.assertEqual(tokens[22]['line'], { 'xml:id': 'l101276843', 'facs': '#z101276843', 'n': '16' }) # beginning of line
def test_glyphs(self): """Test the correct detection and rendering of glyphs. The characters in the resulting token should be the characters that are the content of the g tag. """ testdata_noglyphs = { 'յեգի<g ref="#պտ"/>ոս': 'յեգիոս', 'յ<g ref="աշխարհ">աշխար</g>հն': 'յաշխարհն', '<g ref="asxarh">աշխարհ</g>ին': 'աշխարհին', '<g ref="">աշխարհ</g>ին': 'աշխարհին', 'ար<g ref="">ա</g>պ<lb xml:id="l101276841" facs="#z101276841" n="14" break="no"/>կաց': 'արապկաց', '<g ref="">աշխարհ</g>ն': 'աշխարհն' } testdata_glyphs = { 'յեգի<g ref="#ptlig">պտ</g>ոս': { 'token': 'յեգիպտոս', 'occurrence': 1 }, 'յ<g ref="#asxarh">աշխար</g>հն': { 'token': 'յաշխարհն', 'occurrence': 1 }, '<g ref="#asxarh">աշխարհ</g>ին': { 'token': 'աշխարհին', 'occurrence': 2 }, 'ար<g ref="#avar">ա</g>պ<lb xml:id="l101276841" facs="#z101276841" n="14" break="no"/>կաց': { 'token': 'արապկաց', 'occurrence': 1 }, '<g ref="#asxarh">աշխարհ</g>ն': { 'token': 'աշխարհն', 'occurrence': 1 } } tokens = Tokenizer().from_etree(self.testdoc_noglyphs)['tokens'] # Find the token that has our substitution for t in tokens: if '<g ref="' in t['lit']: self.assertIsNotNone( testdata_noglyphs.get(t['lit']), "Error in rendering glyphs (input data %s not covered by testdata)" % t['lit']) self.assertTrue(t['t'] == testdata_noglyphs.get(t['lit']), "Error in rendering glyphs") del testdata_noglyphs[t['lit']] self.assertEqual(len(testdata_noglyphs), 0, "Did not find any test token") tokens = Tokenizer().from_etree(self.testdoc)['tokens'] # Find the token that has our substitution for t in tokens: if '<g ref="' in t['lit']: self.assertIsNotNone( testdata_glyphs.get(t['lit']), "Error in rendering glyphs (input data %s not covered by testdata)" % t['lit']) self.assertTrue( t['t'] == testdata_glyphs.get(t['lit'])['token'], "Error in rendering glyphs") testdata_glyphs[t['lit']]['occurrence'] -= 1 if testdata_glyphs[t['lit']]['occurrence'] == 0: del testdata_glyphs[t['lit']] self.assertEqual(len(testdata_glyphs), 0, "Did not find any test token")
def test_del_gap_linened(self): filename = self.testfiles['v913'] tokens = Tokenizer(milestone="496").from_file(filename)['tokens'] self.assertEqual("թոռնկա", tokens[177]['t']) self.assertEqual("դնել", tokens[178]['t'])