commit ac34ae80c3be3f9f6b3569420478fb6b536c7a19
parent feed537f31169cea5f9c79556fe0c3ee91f19e99
Author: Antoine Amarilli <a3nm@a3nm.net>
Date: Sun, 11 Aug 2019 01:12:22 +0200
fix handling of single-syllable words at end
concerns both rhyme gender and metric (when there are hyphens)
Diffstat:
verse.py | | | 51 | ++++++++++++++++++++++++++++++++++++++------------- |
versetest.py | | | 56 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 94 insertions(+), 13 deletions(-)
diff --git a/verse.py b/verse.py
@@ -1,7 +1,7 @@
#!/usr/bin/python3
import common
-from common import apostrophes, consonants, normalize, is_consonants, is_vowels, sure_end_fem, strip_accents_one
+from common import apostrophes, consonants, normalize, is_consonants, is_vowels, sure_end_fem, strip_accents_one, strip_accents
import re
import vowels
import haspirater
@@ -203,10 +203,22 @@ class Verse:
# remove leading and trailing crap
for w in self.chunks:
for p in range(len(w)):
+ seen_space = False
+ seen_hyphen = False
while len(w[p]['text']) > 0 and w[p]['text'][0] in ' -':
+ if w[p]['text'][0] == ' ':
+ seen_space = True
+ else:
+ seen_hyphen = True
w[p]['text'] = w[p]['text'][1:]
while len(w[p]['text']) > 0 and w[p]['text'][-1] in ' -':
+ if w[p]['text'][-1] == ' ':
+ seen_space = True
+ else:
+ seen_hyphen = True
w[p]['text'] = w[p]['text'][:-1]
+ if seen_hyphen and not seen_space:
+ w[p]['had_hyphen'] = True
# collapse empty chunks created by simplifications
for i, w in enumerate(self.chunks):
@@ -417,7 +429,7 @@ class Verse:
self.possible = self.fit(0, 0, self.pattern.hemistiches)
def contains_break(self, chunk):
- return '-' in chunk['text'] or 'wordend' in chunk
+ return '-' in chunk['text'] or 'wordend' in chunk.keys() or 'had_hyphen' in chunk.keys()
def possible_weights(self, pos):
if self.template.options['diaeresis'] == "classical":
@@ -455,8 +467,12 @@ class Verse:
return possible
return self.possible_weights(pos)
if (pos == len(self.chunks) - 1 and self.chunks[pos]['text'] == 'e' and
- pos > 0 and (self.chunks[pos-1]['text'].endswith('-c') or
- self.chunks[pos-1]['text'].endswith('-j'))):
+ pos > 0 and (self.chunks[pos-1]['text'].endswith('-c')
+ or self.chunks[pos-1]['text'].endswith('-j')
+ or (self.chunks[pos-1]['text'] == 'c'
+ and 'had_hyphen' in self.chunks[pos-1].keys())
+ or (self.chunks[pos-1]['text'] == 'j'
+ and 'had_hyphen' in self.chunks[pos-1].keys()))):
return [0] # -ce and -je are elided
if (pos >= len(self.chunks) - 1
and self.chunks[pos]['text'] in ['ie', 'ée']):
@@ -476,17 +492,26 @@ class Verse:
if self.text.endswith(a):
# if vowel before, it must be fem
try:
- if self.text[-len(a)-1] in common.vowels:
+ if strip_accents(self.text[-len(a)-1]) in common.vowels:
return ['F']
except IndexError:
- return ['M', 'F']
- # check that this isn't a one-syllabe word
- for i in range(4):
- try:
- if '-' in self.chunks[-i-1]['text'] or 'wordend' in self.chunks[-i-1]:
- return ['M', 'F']
- except IndexError:
- return ['M', 'F']
+ # too short
+ if self.text == "es":
+ return ['M']
+ else:
+ return ['F']
+ # check that this isn't a one-syllabe word that ends with "es"
+ # => must be masculine as '-es' cannot be mute then
+ # => except if there is another vowel before ("fées")
+ if (self.text.endswith("es") and (len(self.text) == 2 or
+ strip_accents(self.text[-3]) not in common.vowels)):
+ for i in range(4):
+ try:
+ if ('had_hyphen' in self.chunks[-i-1].keys() or 'wordend' in
+ self.chunks[-i-1].keys()):
+ return ['M']
+ except IndexError:
+ return ['M']
return ['F']
if not self.text.endswith('ent'):
return ['M']
diff --git a/versetest.py b/versetest.py
@@ -326,6 +326,62 @@ class SanityCheck2(unittest.TestCase):
self.assertEqual(1, len(gend))
self.assertEqual('F', next(iter(gend)))
+class Genders(unittest.TestCase):
+ def testSingleSyllJe(self):
+ text = "Patati patata patatatah où suis-je"
+ v = verse.Verse(text, template.Template(), template.Pattern("12"))
+ v.parse()
+ gend = v.genders()
+ self.assertTrue(v.valid())
+ self.assertEqual(1, len(gend))
+ self.assertEqual('F', next(iter(gend)))
+
+ def testSingleSyllJeBis(self):
+ text = "Patati patata patatah la verrai-je"
+ v = verse.Verse(text, template.Template(), template.Pattern("12"))
+ v.parse()
+ gend = v.genders()
+ self.assertTrue(v.valid())
+ self.assertEqual(1, len(gend))
+ self.assertEqual('F', next(iter(gend)))
+
+ def testSingleSyllLe(self):
+ text = "Patati patata patatata prends-le"
+ v = verse.Verse(text, template.Template(), template.Pattern("12"))
+ v.parse()
+ gend = v.genders()
+ self.assertTrue(v.valid())
+ self.assertEqual(1, len(gend))
+ self.assertEqual('F', next(iter(gend)))
+
+ def testSingleSyllCe(self):
+ text = "Patati patata patatata mais qu'est-ce"
+ v = verse.Verse(text, template.Template(), template.Pattern("12"))
+ v.parse()
+ gend = v.genders()
+ self.assertTrue(v.valid())
+ self.assertEqual(1, len(gend))
+ self.assertEqual('F', next(iter(gend)))
+
+ def testSingleSyllHyphen(self):
+ text = "Patati patata patata mange-les"
+ v = verse.Verse(text, template.Template(), template.Pattern("12"))
+ v.parse()
+ gend = v.genders()
+ self.assertTrue(v.valid())
+ self.assertEqual(1, len(gend))
+ self.assertEqual('M', next(iter(gend)))
+
+ def testSingleSyllNoHyphen(self):
+ text = "Patati patata patata mange les"
+ v = verse.Verse(text, template.Template(), template.Pattern("12"))
+ v.parse()
+ gend = v.genders()
+ self.assertTrue(v.valid())
+ self.assertEqual(1, len(gend))
+ self.assertEqual('M', next(iter(gend)))
+
+
class TemplateTest(unittest.TestCase):
def testSingleHyphens(self):
t = template.Template("12")