class TestOutputErrorFunctions(unittest.TestCase): def setUp(self): # Instantiate an Output Error object self.error = OutputError("This is an output error.") def tearDown(self): # Release instantiated objects del self.error def test_init(self): self.assertEqual(self.error.msg, "This is an output error.") self.assertIsNone(self.error.expr) # The caller is the OutputError instantiation of the setUp() function, so please update these lines if needed self.assertEqual(self.error.frame_info.filename, utest_path + 'test_utils_error_handling.py') self.assertEqual(self.error.frame_info.lineno, 86) self.assertEqual(self.error.frame_info.function, 'setUp') self.assertListEqual(self.error.frame_info.code_context, [' self.error = OutputError("This is an output error.")\n']) def test_str(self): self.assertEqual(str(self.error), " File \"" + utest_path + "test_utils_error_handling.py\", line 86, in setUp" + EOL + " Error: This is an output error.") def test_handle(self): test = False try: print self.error.handle() except SystemExit: test = True self.assertTrue(test)
class TestOutputErrorFunctions(unittest.TestCase): def setUp(self): # Instantiate an Output Error object self.error = OutputError("This is an output error.") def tearDown(self): # Release instantiated objects del self.error def test_init(self): self.assertEqual(self.error.msg, "This is an output error.") self.assertIsNone(self.error.expr) # The caller is the OutputError instantiation of the setUp() function, so please update these lines if needed self.assertEqual(self.error.frame_info.filename, utest_path + 'test_utils_error_handling.py') self.assertEqual(self.error.frame_info.lineno, 86) self.assertEqual(self.error.frame_info.function, 'setUp') self.assertListEqual( self.error.frame_info.code_context, [' self.error = OutputError("This is an output error.")\n']) def test_str(self): self.assertEqual( str(self.error), " File \"" + utest_path + "test_utils_error_handling.py\", line 86, in setUp" + EOL + " Error: This is an output error.") def test_handle(self): test = False try: print self.error.handle() except SystemExit: test = True self.assertTrue(test)
def odt_write(object, filename, introduction=None, lmf2odt=lmf_to_odt, items=lambda lexical_entry: lexical_entry.get_lexeme(), sort_order=None, paradigms=False, reverse=False): """! @brief Write a document file. @param object The LMF instance to convert into document output format. @param filename The name of the document file to write with full path, for instance 'user/output.odt'. @param introduction The name of the text file with full path containing the introduction of the document, for instance 'user/config/introduction.txt'. Default value is None. @param lmf2odt A function giving the mapping from LMF representation information that must be written to ODT commands, in a defined order. Default value is 'lmf_to_odt' function defined in 'pylmflib/config/odt.py'. Please refer to it as an example. @param items Lambda function giving the item to sort. Default value is 'lambda lexical_entry: lexical_entry.get_lexeme()', which means that the items to sort are lexemes. @param sort_order Python list. Default value is 'None', which means that the document output is alphabetically ordered. @param paradigms A boolean value to introduce paradigms in document or not. @param reverse A boolean value to set if a reverse dictionary is wanted. """ import string if sort_order is None: # Lowercase and uppercase letters must have the same rank sort_order = dict([(c, ord(c)) for c in string.lowercase]) up = dict([(c, ord(c) + 32) for c in string.uppercase]) sort_order.update(up) sort_order.update({'':0, ' ':0}) textdoc = OpenDocumentText() # Styles s = textdoc.styles h1style = Style(name="Heading 1", family="paragraph") h1style.addElement(TextProperties(attributes={'fontsize':"24pt", 'fontweight':"bold" })) s.addElement(h1style) # An automatic style boldstyle = Style(name="Bold", family="text") boldprop = TextProperties(fontweight="bold", fontname="Arial", fontsize="8pt") boldstyle.addElement(boldprop) textdoc.automaticstyles.addElement(boldstyle) # Parse LMF values if object.__class__.__name__ == "LexicalResource": for lexicon in object.get_lexicons(): # Document title h = H(outlinelevel=1, stylename=h1style, text=lexicon.get_id()) textdoc.text.addElement(h) # Plain paragraph p = P(text=lexicon.get_label()) # Text boldpart = Span(stylename=boldstyle, text="Test. ") p.addElement(boldpart) # Introduction if introduction is not None: p.addText(file_read(introduction)) textdoc.text.addElement(p) # Page break # # Text body lmf2odt(lexicon, textdoc, items, sort_order, paradigms, reverse) else: raise OutputError(object, "Object to write must be a Lexical Resource.") textdoc.save(filename)
def doc_write(object, filename, introduction=None, lmf2doc=lmf_to_doc, items=lambda lexical_entry: lexical_entry.get_lexeme(), sort_order=None, paradigms=False, reverse=False): """! @brief Write a document file. @param object The LMF instance to convert into document output format. @param filename The name of the document file to write with full path, for instance 'user/output.doc'. @param introduction The name of the text file with full path containing the introduction of the document, for instance 'user/config/introduction.txt'. Default value is None. @param lmf2doc A function giving the mapping from LMF representation information that must be written to docx commands, in a defined order. Default value is 'lmf_to_doc' function defined in 'pylmflib/config/doc.py'. Please refer to it as an example. @param items Lambda function giving the item to sort. Default value is 'lambda lexical_entry: lexical_entry.get_lexeme()', which means that the items to sort are lexemes. @param sort_order Python list. Default value is 'None', which means that the document output is alphabetically ordered. @param paradigms A boolean value to introduce paradigms in document or not. @param reverse A boolean value to set if a reverse dictionary is wanted. """ import string if sort_order is None: # Lowercase and uppercase letters must have the same rank sort_order = dict([(c, ord(c)) for c in string.lowercase]) up = dict([(c, ord(c) + 32) for c in string.uppercase]) sort_order.update(up) sort_order.update({'': 0, ' ': 0}) document = Document() # Adjust margins to 1 cm section = document.sections[0] section.top_margin = Cm(1) section.bottom_margin = Cm(1) section.left_margin = Cm(1) section.right_margin = Cm(1) # Parse LMF values if object.__class__.__name__ == "LexicalResource": for lexicon in object.get_lexicons(): # Document title document.add_heading(lexicon.get_id(), 0) # Plain paragraph document.add_paragraph(lexicon.get_label()) # Page break document.add_page_break() # Introduction if introduction is not None: document.add_paragraph(file_read(introduction)) # Text body lmf2doc(lexicon, document, items, sort_order, paradigms, reverse) else: raise OutputError(object, "Object to write must be a Lexical Resource.") document.save(filename)
def mdf_write(object, filename, lmf2mdf=lmf_mdf, order=mdf_order): """! @brief Write an MDF file. @param object The LMF instance to convert into MDF output format. @param filename The name of the MDF file to write with full path, for instance 'user/output.txt'. @param lmf2mdf A Python dictionary describing the mapping between LMF representation and MDF markers. Default value is 'lmf_mdf' dictionary defined in 'pylmflib/config/mdf.py'. Please refer to it as an example. @param order A Python list defining the order in which MDF markers must be written, for instance ["lx", "ps"]. Default value is 'mdf_order' list defined in 'pylmflib/config/mdf.py'. """ mdf_file = open_write(filename) # For each MDF marker, get the corresponding LMF value if object.__class__.__name__ == "Lexicon": for lexical_entry in object.get_lexical_entries(): for marker in order: if type(marker) is list: # Parse group of markers parse_list(mdf_file, lmf2mdf, marker, lexical_entry) else: value = lmf2mdf[marker](lexical_entry) write_line(mdf_file, marker, value) # Separate lexical entries from each others with a blank line mdf_file.write(EOL) else: raise OutputError(object, "Object to write must be a Lexicon.") mdf_file.close()
def lmf_to_doc(lexicon, document, items=lambda lexical_entry: lexical_entry.get_lexeme(), sort_order=None, paradigms=False, reverse=False): """! @brief Function to convert LMF lexical entry information to be written into docx commands. @param lexicon The Lexicon LMF instance to display. @param document The docx document to fill in. @param items Lambda function giving the item to sort. Default value is 'lambda lexical_entry: lexical_entry.get_lexeme()', which means that the items to sort are lexemes. @param sort_order Python list. Default value is 'None', which means that the document output is alphabetically ordered. @param paradigms A boolean value to introduce paradigms in document or not. @param reverse A boolean value to set if a reverse dictionary is wanted. """ # Lexicon is already ordered level = 0 previous_character = '' current_character = '' for lexical_entry in lexicon.get_lexical_entries(): if type(sort_order) is type(dict()) or type(sort_order) is type(lambda l:l): # Check if current element is a lexeme starting with a different character than previous lexeme try: current_character = items(lexical_entry)[0] if sort_order[items(lexical_entry)[0:1]]: current_character = items(lexical_entry)[0:1] if sort_order[items(lexical_entry)[0:2]]: current_character = items(lexical_entry)[0:2] except IndexError: pass except KeyError: pass except TypeError: pass try: if ( (type(sort_order) is not type(dict())) and ((previous_character == '') or (sort_order(current_character) != sort_order(previous_character))) ) \ or ( (type(sort_order) is type(dict())) and (int(sort_order[current_character]) != int(sort_order[previous_character])) ): # Do not consider special characters if previous_character != '': document.add_page_break() previous_character = current_character title = '' if type(sort_order) is not type(dict()): title += ' ' + current_character else: for key,value in sorted(sort_order.items(), key=lambda x: x[1]): if int(value) == int(sort_order[current_character]): title += ' ' + key document.add_heading("-" + title + " -".decode(ENCODING), level=level+1) except KeyError: print Warning("Cannot sort item %s" % items(lexical_entry).encode(ENCODING)) except IndexError: # Item is an empty string pass else: raise OutputError(object, "Sort order must be a dictionary.") if not reverse: # Lexeme lexeme = lexical_entry.get_lexeme() if lexical_entry.get_homonymNumber() is not None: # Add homonym number to lexeme lexeme += " (" + str(lexical_entry.get_homonymNumber()) + ")" # Add morphology if any morph = "" for morphology in lexical_entry.get_morphologies(): morph += " " + morphology # Add dialect if any dialect = "" for sense in lexical_entry.get_senses(): for usage_note in sense.find_usage_notes(language=config.xml.vernacular): dialect += " [" + usage_note + "]" p = document.add_paragraph() p.add_run(lexeme).bold = True if morph != "": p.add_run(" Morph. :").italic = True p.add_run(morph) p.add_run(dialect) # Dialectal variants write_title = True for repr in lexical_entry.get_form_representations(): if repr.get_geographicalVariant() is not None: if write_title: p.add_run(" Var. : ") write_title = False else: p.add_run(" ; ") p.add_run(repr.get_geographicalVariant()).bold = True if repr.get_dialect() is not None: p.add_run(" [" + repr.get_dialect() + "]") # Part of speech in italic if lexical_entry.get_partOfSpeech() is not None: p.add_run(". ") p.add_run(lexical_entry.get_partOfSpeech()).italic = True p.add_run(".") # Note grammaticale if len(lexical_entry.find_notes(type="grammar")) != 0: p = document.add_paragraph() p.add_run(" ") p.add_run("[Note grammaticale :") for note in lexical_entry.find_notes(type="grammar", language=config.xml.regional): p.add_run(" ") p.add_run(note).bold = True try: for note in lexical_entry.find_notes(type="grammar", language=config.xml.French): p.add_run(" ") p.add_run(note) except AttributeError: for note in lexical_entry.find_notes(type="grammar", language=config.xml.English): p.add_run(" ") p.add_run(note) for note in lexical_entry.find_notes(type="grammar", language=config.xml.vernacular): p.add_run(" ") p.add_run(note) for note in lexical_entry.find_notes(type="grammar", language=config.xml.national): p.add_run(" ") p.add_run(note) # Italic for note in lexical_entry.find_notes(type="grammar"): p.add_run(" ") p.add_run(note).italic = True p.add_run("].") for sense in lexical_entry.get_senses(): # Glosses glosses = "" if sense.get_senseNumber() is not None: p = document.add_paragraph() p.add_run(" " + sense.get_senseNumber() + ")") for gloss in sense.find_glosses(language=config.xml.vernacular): glosses += " " + gloss + "." if glosses == "": glosses = glosses.rstrip(".") try: for gloss in sense.find_glosses(language=config.xml.French): glosses += " " + gloss + "." except AttributeError: for gloss in sense.find_glosses(language=config.xml.English): glosses += " " + gloss + "." glosses = glosses.rstrip(".") if glosses != "" and glosses[-1] != '.' and glosses[-1] != '!' and glosses[-1] != '?': glosses += "." p.add_run(glosses) # Scientific name if lexical_entry.get_scientific_name() is not None: p.add_run(" ") p.add_run(lexical_entry.get_scientific_name()).italic = True p.add_run(".") # Examples for context in sense.get_contexts(): p = document.add_paragraph() examples = "" vernacular_forms = context.find_written_forms(language=config.xml.vernacular) for example in vernacular_forms: p.add_run(" ") p.add_run(example.split('[')[0]).bold = True for element in example.split('[')[1:]: p.add_run('[' + element) try: fra_forms = context.find_written_forms(language=config.xml.French) if len(vernacular_forms) != 0 and len(fra_forms) != 0: p.add_run(" ") for example in fra_forms: p.add_run(example) if len(fra_forms) != 0 and fra_forms[0][-1] != '!' and fra_forms[0][-1] != '?': p.add_run(".") except AttributeError: pass # Links if len(lexical_entry.get_related_forms("simple link")) != 0: p = document.add_paragraph() p.add_run(" Voir :").italic = True for related_form in lexical_entry.get_related_forms("simple link"): if related_form.get_lexical_entry() is not None: # TODO : hyperlink pass p.add_run(" ") p.add_run(related_form.get_lexeme().split('[')[0]).bold = True for element in related_form.get_lexeme().split('[')[1:]: p.add_run('[' + element) try: for written_form in related_form.find_written_forms(language=config.xml.French): p.add_run(" " + written_form) except AttributeError: for written_form in related_form.find_written_forms(language=config.xml.English): p.add_run(" " + written_form) p.add_run(".") # Notes if len(lexical_entry.find_notes(type="general")) != 0: p = document.add_paragraph() p.add_run(" ") p.add_run("[Note :") for note in lexical_entry.find_notes(type="general"): p.add_run(" ") p.add_run(note) p.add_run("].") # Note phonologique if len(lexical_entry.find_notes(type="phonology")) != 0: p = document.add_paragraph() p.add_run(" ") p.add_run("[Note phonologique :") for note in lexical_entry.find_notes(type="phonology"): p.add_run(" ") p.add_run(note) p.add_run("].") # Note anthropologique if len(lexical_entry.find_notes(type="anthropology")) != 0: p = document.add_paragraph() p.add_run(" ") p.add_run("[Note anthropologique :") for note in lexical_entry.find_notes(type="anthropology"): p.add_run(" ") p.add_run(note) p.add_run("].") if paradigms: if len(lexical_entry.get_word_forms()) != 0: # Intense quote document.add_paragraph('Paradigms', style='IntenseQuote') # Table table = document.add_table(rows=1, cols=2) hdr_cells = table.rows[0].cells hdr_cells[0].text = 'Paradigm' hdr_cells[1].text = 'Form' for item in lexical_entry.find_paradigms(grammatical_number=pd_grammaticalNumber["sg"]): row_cells = table.add_row().cells row_cells[0].text = "sg" row_cells[1].text = item for item in lexical_entry.find_paradigms(grammatical_number=pd_grammaticalNumber["pl"]): row_cells = table.add_row().cells row_cells[0].text = "pl" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[1], grammatical_number=pd_grammaticalNumber['s']): row_cells = table.add_row().cells row_cells[0].text = "1s" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[2], grammatical_number=pd_grammaticalNumber['s']): row_cells = table.add_row().cells row_cells[0].text = "2s" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[3], grammatical_number=pd_grammaticalNumber['s']): row_cells = table.add_row().cells row_cells[0].text = "3s" row_cells[1].text = item for item in lexical_entry.find_paradigms(anymacy=pd_anymacy[4], grammatical_number=pd_grammaticalNumber['s']): row_cells = table.add_row().cells row_cells[0].text = "4s" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[1], grammatical_number=pd_grammaticalNumber['d']): row_cells = table.add_row().cells row_cells[0].text = "1d" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[2], grammatical_number=pd_grammaticalNumber['d']): row_cells = table.add_row().cells row_cells[0].text = "2d" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[3], grammatical_number=pd_grammaticalNumber['d']): row_cells = table.add_row().cells row_cells[0].text = "3d" row_cells[1].text = item for item in lexical_entry.find_paradigms(anymacy=pd_anymacy[4], grammatical_number=pd_grammaticalNumber['d']): row_cells = table.add_row().cells row_cells[0].text = "4d" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[1], grammatical_number=pd_grammaticalNumber['p']): row_cells = table.add_row().cells row_cells[0].text = "1p" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[1], grammatical_number=pd_grammaticalNumber['p'], clusivity=pd_clusivity['e']): row_cells = table.add_row().cells row_cells[0].text = "1e" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[1], grammatical_number=pd_grammaticalNumber['p'], clusivity=pd_clusivity['i']): row_cells = table.add_row().cells row_cells[0].text = "1i" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[2], grammatical_number=pd_grammaticalNumber['p']): row_cells = table.add_row().cells row_cells[0].text = "2p" row_cells[1].text = item for item in lexical_entry.find_paradigms(person=pd_person[3], grammatical_number=pd_grammaticalNumber['p']): row_cells = table.add_row().cells row_cells[0].text = "3p" row_cells[1].text = item for item in lexical_entry.find_paradigms(anymacy=pd_anymacy[4], grammatical_number=pd_grammaticalNumber['p']): row_cells = table.add_row().cells row_cells[0].text = "4p" row_cells[1].text = item if len(lexical_entry.get_word_forms()) != 0: p = document.add_paragraph() # Handle subentries for related_form in lexical_entry.get_related_forms("subentry"): if related_form.get_lexical_entry() is not None: p = document.add_paragraph() p.add_run(" ") p.add_run(related_form.get_lexeme().split('[')[0]).bold = True for element in related_form.get_lexeme().split('[')[1:]: p.add_run('[' + element.replace("GO(s)", "GOs").replace("GO(n)", "GOn").replace("WEM", "WE")) for sense in related_form.get_lexical_entry().get_senses(): glosses = "" for gloss in sense.find_glosses(language=config.xml.vernacular): glosses += " " + gloss + "." if glosses == "": glosses = glosses.rstrip(".") try: for gloss in sense.find_glosses(language=config.xml.French): glosses += " " + gloss + "." except AttributeError: for gloss in sense.find_glosses(language=config.xml.English): glosses += " " + gloss + "." if glosses == "": glosses = glosses.rstrip(".") p.add_run(glosses) p.add_run(EOL) else: # reverse # English gloss is_gloss = False for sense in lexical_entry.get_senses(): for gloss in sense.find_glosses(language=config.xml.English): if not is_gloss: # Paragraph p = document.add_paragraph() # Write gloss in bold, except characters that are between brackets or square brackets brackets = 0 bold = True for c in gloss: if c == '(' or c == '[': # Write following characters in non-bold brackets += 1 if brackets > 0: bold = False else: bold = True p.add_run(c).bold = bold elif c == ')' or c == ']': # Write following characters in bold p.add_run(c).bold = bold brackets -= 1 if brackets > 0: bold = False else: bold = True else: p.add_run(c).bold = bold if gloss[-1] != '?' and gloss[-1] != '!' and gloss[-1] != '.': p.add_run(".") p.add_run(" ") is_gloss = True if is_gloss: # Scientific name if lexical_entry.get_scientific_name() is not None: p.add_run(lexical_entry.get_scientific_name()).italic = True p.add_run(". ") # Lexeme p.add_run(lexical_entry.get_lexeme()) if lexical_entry.get_lexeme()[-1] != '?' and lexical_entry.get_lexeme()[-1] != '!' and lexical_entry.get_lexeme()[-1] != '.': p.add_run(".")
def setUp(self): # Instantiate an Output Error object self.error = OutputError("This is an output error.")
def tex_write(object, filename, preamble=None, introduction=None, lmf2tex=lmf_to_tex, font=None, items=lambda lexical_entry: lexical_entry.get_lexeme(), sort_order=None, paradigms=[], tables=[], title=None, tex_language=None): """! @brief Write a LaTeX file. Note that the lexicon must already be ordered at this point. Here, parameters 'items' and 'sort_order' are only used to define chapters. @param object The LMF instance to convert into LaTeX output format. @param filename The name of the LaTeX file to write with full path, for instance 'user/output.tex'. @param preamble The name of the LaTeX file with full path containing the LaTeX header of the document, for instance 'user/config/japhug.tex'. Default value is None. @param introduction The name of the LaTeX file with full path containing the LaTeX introduction of the document, for instance 'user/config/introduction.tex'. Default value is None. @param lmf2tex A function giving the mapping from LMF representation information that must be written to LaTeX commands, in a defined order. Default value is 'lmf_to_tex' function defined in 'pylmflib/config/tex.py'. Please refer to it as an example. @param font A Python dictionary giving the vernacular, national, regional fonts to apply to a text in LaTeX format. @param items Lambda function giving the item to sort. Default value is 'lambda lexical_entry: lexical_entry.get_lexeme()', which means that the items to sort are lexemes. @param sort_order Default value is 'None', which means that the LaTeX output is alphabetically ordered. @param paradigms A Python list of LaTeX filenames with full path containing the paradigms in LaTeX format. Default value is an empty list. @param tables The name of the LaTeX file with full path containing some notes to add at the end of the LaTeX document, for instance 'user/config/conclusion.tex'. Default value is None. @param title A Python string containing the title of the LaTeX document. Default value is None. @param tex_language A Python string giving the default language to set in LaTeX. """ import string, os # Define font if font is None: font = config.xml.font tex_file = open_write(filename) # Add file header if any tex_file.write(file_read(preamble)) # Continue the header if needed if title is not None: tex_file.write("\\title{" + unicode(title, "utf-8") + "}" + EOL) if tex_language is not None: tex_file.write("\setdefaultlanguage{" + tex_language + "}" + EOL) # Insert LaTeX commands to create a document tex_file.write(EOL + "\\begin{document}" + EOL) tex_file.write("\\maketitle" + EOL) tex_file.write("\\newpage" + EOL) # Add introduction if any if introduction is not None: tex_file.write("\\markboth{INTRODUCTION}{}" + EOL * 2) tex_file.write(file_read(introduction)) # Add command for small caps tex_file.write(EOL + "\\def\\mytextsc{\\bgroup\\obeyspaces\\mytextscaux}" + EOL) tex_file.write( "\\def\\mytextscaux#1{\\mytextscauxii #1\\relax\\relax\\egroup}" + EOL) tex_file.write("\\def\\mytextscauxii#1{%" + EOL) tex_file.write( "\\ifx\\relax#1\\else \\ifcat#1\\@sptoken{} \\expandafter\\expandafter\\expandafter\\mytextscauxii\\else" + EOL) tex_file.write( "\\ifnum`#1=\\uccode`#1 {\\normalsize #1}\\else {\\footnotesize \\uppercase{#1}}\\fi \\expandafter\\expandafter\\expandafter\\mytextscauxii\\expandafter\\fi\\fi}" + EOL * 2) # Configure space indent tex_file.write("\\setlength\\parindent{0cm}" + EOL) # Insert data path configuration # Unix-style paths audio_path = config.xml.audio_path graphic_path = os.path.abspath('.') if os.name != 'posix': # Windows-style paths audio_path = audio_path.replace("\\", "/") graphic_path = graphic_path.replace("\\", "/") tex_file.write(EOL + "\\addmediapath{" + audio_path.rstrip("/") + "}" + EOL) tex_file.write("\\addmediapath{" + audio_path + "mp3}" + EOL) tex_file.write("\\addmediapath{" + audio_path + "wav}" + EOL) tex_file.write("\\graphicspath{{" + graphic_path + "/pylmflib/output/img/}}" + EOL * 2) # Configure 2 columns tex_file.write("\\newpage" + EOL) tex_file.write("\\begin{multicols}{2}" + EOL * 2) if sort_order is None: # Lowercase and uppercase letters must have the same rank sort_order = dict([(c, ord(c)) for c in string.lowercase]) up = dict([(c, ord(c) + 32) for c in string.uppercase]) sort_order.update(up) sort_order.update({'': 0, ' ': 0}) # For each element to write, get the corresponding LMF value if object.__class__.__name__ == "LexicalResource": for lexicon in object.get_lexicons(): previous_character = '' current_character = '' # Lexicon is already ordered for lexical_entry in lexicon.get_lexical_entries(): # Consider only main entries (subentries and components will be written as parts of the main entry) if lexical_entry.find_related_forms( "main entry" ) == [] and lexical_entry.get_independentWord() is not False: # Check if current element is a lexeme starting with a different character than previous lexeme try: current_character = items(lexical_entry)[0] if sort_order[items(lexical_entry)[0:1]]: current_character = items(lexical_entry)[0:1] if sort_order[items(lexical_entry)[0:2]]: current_character = items(lexical_entry)[0:2] except IndexError: pass except KeyError: pass except TypeError: pass try: if ( (type(sort_order) is not type(dict())) and ((previous_character == '') or (sort_order(current_character) != sort_order(previous_character))) ) \ or ( (type(sort_order) is type(dict())) and (int(sort_order[current_character]) != int(sort_order[previous_character])) ): # Do not consider special characters previous_character = current_character tex_file.write("\\newpage" + EOL) title = '' if type(sort_order) is not type(dict()): title += ' ' + font[NATIONAL]( current_character) else: for key, value in sorted(sort_order.items(), key=lambda x: x[1]): if int(value) == int( sort_order[current_character]): title += ' ' + font[VERNACULAR](key) tex_file.write("\\section*{\\centering-" + handle_reserved(title) + " -}" + EOL) #tex_file.write("\\pdfbookmark[1]{" + title + " }{" + title + " }" + EOL) tex_file.write(lmf2tex(lexical_entry, font)) if len(paradigms) != 0: tex_file.write(insert_references(lexical_entry)) # tex_file.write("\\lhead{\\firstmark}" + EOL) # tex_file.write("\\rhead{\\botmark}" + EOL) # Separate lexical entries from each others with a blank line tex_file.write(EOL) # Handle subentries for related_form in lexical_entry.get_related_forms( "subentry"): if related_form.get_lexical_entry() is not None: tex_file.write( lmf2tex(related_form.get_lexical_entry(), font)) if len(paradigms) != 0: tex_file.write( insert_references( related_form.get_lexical_entry())) # Separate sub-entries from each others with a blank line tex_file.write(EOL) except KeyError: print Warning("Cannot sort item %s" % items(lexical_entry).encode(ENCODING)) except IndexError: # Item is an empty string pass else: raise OutputError(object, "Object to write must be a Lexical Resource.") # Insert LaTeX commands to finish the document properly tex_file.write("\end{multicols}" + EOL) # Insert paradigms if any for filename in paradigms: tex_file.write(EOL) tex_file.write("\\newpage" + EOL) tex_file.write("\markboth{paradigms}{}" + EOL) tex_file.write(file_read(filename)) tex_file.write(EOL) # Insert other tables if any for filename in tables: tex_file.write(EOL) tex_file.write("\\newpage" + EOL) tex_file.write(file_read(filename)) tex_file.write(EOL) tex_file.write("\end{document}" + EOL) tex_file.close()