plint

French poetry validator (local mirror of https://gitlab.com/a3nm/plint)
git clone https://a3nm.net/git/plint/
Log | Files | Refs | README

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)