#!/usr/bin/env python3 ''' Created on 2014-10-20 @author: Thomas 'PointedEars' Lahn ''' from sys import argv, stderr from re import findall, DOTALL, match, sub, compile, \ escape, search from os.path import basename from functools import cmp_to_key from Dictionary import Dictionary, dmsg, \ sort_dict_alnum_english_key dictionary = {} prepositions = { "fi'": 'on', "na'": 'at|to', "t'": 'of' } def cli_help(): print('Usage: {0} TEXT...'.format(basename(argv[0]))) def get_sort_dict_alnum_vulcan_key(): letters = list(map(str.lower, [ " ", 'S', 'T', 'P', 'K', 'R', 'L', 'A', 'Sh', 'O', 'U', 'D', 'V', 'Kh', 'E', 'H', 'G', 'Ch', 'I', 'N', 'Zh', 'M', 'Y', 'F', 'Z', 'Th', 'W', 'B', "'", '-'])) letter_values = dict(map(lambda x: (x[1], x[0]), enumerate(letters))) letters_re = compile(r'(?:{0})'.format('|'.join(sorted(letters, key=lambda char:-len(char))))) def sort_dict_alnum_vulcan (a, b): # split into Vulcan letters a = findall(letters_re, sort_dict_alnum_english_key(a)) b = findall(letters_re, sort_dict_alnum_english_key(b)) if len(a) < len(b): for index, char in enumerate(a): diff = letter_values[char] - letter_values[b[index]] if diff != 0: return diff return -1 # len(b) <= len(a) for index, char in enumerate(b): diff = letter_values[a[index]] - letter_values[char] if diff != 0: return diff return 1 if len(b) < len(a) else 0 return cmp_to_key(sort_dict_alnum_vulcan) class VulcanDictionary(Dictionary): def translate (self, phrase, search_prefix=True, search_plural=True): dictionary = self translation = dictionary.get(phrase.lower(), None) if translation is not None: translation['vuh'] = phrase return translation else: if search_prefix: # find prefix for preposition in prepositions: prefix = match(escape(preposition), phrase) if prefix is not None: prefix_translation = self.translate(prefix.group(0)) if prefix_translation is not None: tail = sub(preposition, '', phrase) tail_translation = self.translate(tail, search_prefix=False) if tail_translation is not None: return [prefix_translation, tail_translation] elif search_plural: # find plural suffix = search(r'lar$', phrase) if suffix is not None: head = sub(r'lar$', '', phrase) head_translation = self.translate(head, search_prefix=False, search_plural=False) if head_translation is not None: head_translation = dict(head_translation) head_translation['en'] += ' (pl.)' return head_translation return None if __name__ == '__main__': if len(argv) < 2: print('Nothing to translate.', end='\n\n', file=stderr) cli_help() exit(1) text = argv[1] dictionary = VulcanDictionary(dictionary) dictionary.load('vuh-gol-en.dict.zdb.txt', 'vuh') dictionary.clean() # try: # for phrase, data in OrderedDict(sorted( # dictionary.items(), # key=get_sort_dict_alnum_vulcan_key() # )).items(): # print(phrase, "=", data) # except BrokenPipeError: # pass dmsg("text:", text, min_level=2) sentences = findall(r'(?!\s+)(?:.+?\.{1,3}|.+$)', text, DOTALL) dmsg("sentences:", sentences, min_level=2) for sentence in sentences: dmsg("sentence:", sentence, min_level=2) clauses = findall(r'(?!\s+)(?:.+?(?:\s+-\s*|\s*[–—]\s*|\.{1,3}|.+$))', sentence, DOTALL) dmsg("clauses:", clauses, min_level=2) for clause in clauses: dmsg("clause:", clause, min_level=2) words = findall(r'[^\s.]+', clause) dmsg("words:", words, min_level=2) offset = 0 while offset < len(words): translation = None for i in range(len(words), offset, -1): dmsg("words[{0}:{1}] = {2}".format(offset, i, words[offset:i]), min_level=2) phrase = ' '.join(words[offset:i]) dmsg("phrase:", phrase, min_level=2) translation = dictionary.translate(phrase) if translation is not None: dmsg("phrase-translation:", translation, min_level=2) dmsg("words[{0}:{1}] = [\"{2}\"]".format(offset, i, translation), min_level=2) words[offset:i] = [translation] offset += i - offset break if translation is None: dmsg("phrase-translation:", translation, min_level=2) offset += 1 dmsg("words-translation:", words, min_level=2)