diff --git a/ovos_workshop/res/text/es/word_connectors.json b/ovos_workshop/res/text/es/word_connectors.json new file mode 100644 index 00000000..090a7c56 --- /dev/null +++ b/ovos_workshop/res/text/es/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "y", + "or": "o" +} diff --git a/ovos_workshop/skills/ovos.py b/ovos_workshop/skills/ovos.py index 288723e4..af2c61bb 100644 --- a/ovos_workshop/skills/ovos.py +++ b/ovos_workshop/skills/ovos.py @@ -2533,6 +2533,11 @@ def join_word_list(items: List[str], connector: str, sep: str, lang: str) -> str Returns: str: the connected list phrase """ + if lang.startswith("it"): + return _join_word_list_it(items, connector, sep) + elif lang.startswith("es"): + return _join_word_list_es(items, connector, sep) + cons = { "and": _get_word(lang, "and"), "or": _get_word(lang, "or") @@ -2549,3 +2554,64 @@ def join_word_list(items: List[str], connector: str, sep: str, lang: str) -> str return (sep.join(str(item) for item in items[:-1]) + " " + cons[connector] + " " + items[-1]) + + +def _join_word_list_it(items: List[str], connector: str, sep: str = ",") -> str: + cons = { + "and": _get_word("it", "and"), + "or": _get_word("it", "or") + } + if not items: + return "" + if len(items) == 1: + return str(items[0]) + + if not sep: + sep = ", " + else: + sep += " " + + final_connector = cons[connector] + if len(items) > 2: + joined_string = sep.join(item for item in items[:-1]) + else: + joined_string = items[0] + + # Check for euphonic transformation cases for "e" and "o" + if cons[connector] == "e" and items[-1][0].lower() == "e": + final_connector = "ed" + elif cons[connector] == "o" and items[-1][0].lower() == "o": + final_connector = "od" + return f"{joined_string} {final_connector} {items[-1]}" + + +def _join_word_list_es(items: List[str], connector: str, sep: str = ",") -> str: + cons = { + "and": _get_word("es", "and"), + "or": _get_word("es", "or") + } + if not items: + return "" + if len(items) == 1: + return str(items[0]) + + if not sep: + sep = ", " + else: + sep += " " + + final_connector = cons[connector] + if len(items) > 2: + joined_string = sep.join(item for item in items[:-1]) + else: + joined_string = items[0] + + # Check for euphonic transformation cases for "y" + w = items[-1].lower().lstrip("h")[0] + if cons[connector] == "y" and w in ["i", "í"]: + final_connector = "e" + # Check for euphonic transformation cases for "o" + if cons[connector] == "o" and w in ["o", "ó"]: + final_connector = "u" + + return f"{joined_string} {final_connector} {items[-1]}" diff --git a/test/unittests/test_euphony.py b/test/unittests/test_euphony.py new file mode 100644 index 00000000..2e9d09d1 --- /dev/null +++ b/test/unittests/test_euphony.py @@ -0,0 +1,76 @@ +import unittest + +from ovos_workshop.skills.ovos import _join_word_list_it, _join_word_list_es + + +class TestJoinWordListIt(unittest.TestCase): + + def test_basic_conjunction_and(self): + # Test without euphonic transformation for "and" + result = _join_word_list_it(["mare", "montagna"], "and") + self.assertEqual(result, "mare e montagna") + + def test_basic_conjunction_or(self): + # Test without euphonic transformation for "or" + result = _join_word_list_it(["mare", "montagna"], "or") + self.assertEqual(result, "mare o montagna") + + def test_euphonic_conjunction_or(self): + # Test euphonic transformation for "or" to "od" + result = _join_word_list_it(["mare", "oceano"], "or") + self.assertEqual(result, "mare od oceano") + + def test_euphonic_conjunction_and(self): + # Test euphonic transformation for "and" to "ed" + result = _join_word_list_it(["inverno", "estate"], "and") + self.assertEqual(result, "inverno ed estate") + + def test_euphonic_conjunction_or_with_other_words(self): + # Test euphonic transformation for "or" to "od" with different words + result = _join_word_list_it(["libro", "orologio"], "or") + self.assertEqual(result, "libro od orologio") + + def test_join_three_words(self): + result = _join_word_list_it(["mare", "estate", "inverno"], "and") + self.assertEqual(result, "mare, estate e inverno") + + def test_empty_list(self): + result = _join_word_list_it([], "and") + self.assertEqual(result, "") + + def test_single_word(self): + result = _join_word_list_it(["mare"], "and") + self.assertEqual(result, "mare") + + def test_multiple_euphonic_transformations(self): + # Test multiple 'ed' transformations in the same list + result = _join_word_list_it(["casa", "estate", "inverno", "autunno"], "and") + self.assertEqual(result, "casa, estate, inverno e autunno") + + def test_mixed_conjunctions(self): + # Test combining 'and' and 'or' conjunctions + result = _join_word_list_it(["mare", "oceano", "isola"], "or") + self.assertEqual(result, "mare, oceano o isola") + + +class TestJoinWordListEs(unittest.TestCase): + + def test_euphonic_conjunction_and(self): + # Test euphonic transformation from "y" to "e" + result = _join_word_list_es(["Juan", "Irene"], "and") + self.assertEqual(result, "Juan e Irene") + result = _join_word_list_es(["vaqueros", "indios"], "and") + self.assertEqual(result, "vaqueros e indios") + result = _join_word_list_es(["Manuel", "Hilario"], "and") + self.assertEqual(result, "Manuel e Hilario") + + def test_euphonic_conjunction_or(self): + # Test euphonic transformation from "o" to "u" + result = _join_word_list_es(["Manuel", "Óscar"], "or") + self.assertEqual(result, "Manuel u Óscar") + result = _join_word_list_es(["unos", "otros"], "or") + self.assertEqual(result, "unos u otros") + + +if __name__ == "__main__": + unittest.main()