verse.py (2767B)
1 #!/usr/bin/python3 2 3 from plint import error 4 from plint.chunks import Chunks 5 6 7 # the writing is designed to make frhyme succeed 8 # end vowels will be elided 9 # missing letters have a default case 10 11 12 class Verse: 13 14 @property 15 def line(self): 16 return self.chunks.get_line() 17 18 @property 19 def normalized(self): 20 return self.chunks.normalized() 21 22 def __init__(self, input_line, template, pattern, threshold=None): 23 self.template = template 24 self.pattern = pattern 25 self.threshold = threshold 26 self.phon = None 27 self.possible = None 28 self.input_line = input_line 29 self.chunks = Chunks(self) 30 31 def annotate(self): 32 self.chunks.annotate(self.template, self.threshold) 33 34 def parse(self): 35 self.annotate() 36 self.possible = self.chunks.fit(self.pattern.hemistiches) 37 38 def get_last_count(self): 39 """return min number of syllables for last word""" 40 return self.chunks.get_last_count() 41 42 def problems(self): 43 errors = self.chunks.get_errors_set(self.template.options['forbidden_ok'], self.template.options['hiatus_ok']) 44 result = [] 45 if len(self.possible) == 0: 46 result.append(error.ErrorBadMetric()) 47 for k in errors: 48 result.append(k()) 49 return result 50 51 def valid(self): 52 return len(self.problems()) == 0 53 54 def genders(self): 55 result = set() 56 for p in self.possible: 57 result.update(set(self.chunks.get_feminine(self.template, self.threshold, p))) 58 if len(self.possible) == 0: 59 # try to infer gender even when metric is wrong 60 result.update(set(self.chunks.get_feminine(self.template, self.threshold, None))) 61 return result 62 63 def print_n_syllables(self, n_syllables, offset, output_file): 64 self.annotate() 65 # only generate a context with the prescribed final weight 66 # where "final" is the offset-th chunk with a weight from the end 67 self.chunks.print_n_syllables(n_syllables, offset, output_file) 68 69 def align(self, fmt="text"): 70 keys = ['original', 'error'] 71 if self.possible is not None and len(self.possible) == 0: 72 keys.append('weights') 73 if len(self.pattern.hemistiches) > 0: 74 keys.append('hemis') 75 return self.chunks.align_from_keys(keys, fmt=fmt) 76 77 def print_possible(self, output_file): 78 if not output_file: 79 return 80 possible = self.possible 81 if len(possible) == 1: 82 for i, chunk in enumerate(possible[0]): 83 chunks_before = possible[0][:i] 84 chunks_after = possible[0][i + 1:] 85 chunk.print_query(chunks_after, chunks_before, output_file)