Commit 41e8f35bc94668dc4ebf5d6d8620241d14a91684
1 parent
9632de87
added prototype phrase expansions page
Showing
9 changed files
with
414 additions
and
95 deletions
locale/en/LC_MESSAGES/django.mo
No preview for this file type
locale/en/LC_MESSAGES/django.po
... | ... | @@ -8,7 +8,7 @@ msgid "" |
8 | 8 | msgstr "" |
9 | 9 | "Project-Id-Version: PACKAGE VERSION\n" |
10 | 10 | "Report-Msgid-Bugs-To: \n" |
11 | -"POT-Creation-Date: 2020-11-09 11:31+0100\n" | |
11 | +"POT-Creation-Date: 2020-11-13 12:05+0100\n" | |
12 | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
13 | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
14 | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" |
... | ... | @@ -348,7 +348,7 @@ msgstr " with possible realisations: " |
348 | 348 | #: entries/phrase_descriptions/descriptions.py:225 |
349 | 349 | #, python-brace-format |
350 | 350 | msgid "frazeologizm w postaci {phrase} zamrożony w postaci <i>{phraseo}</i>" |
351 | -msgstr "a phraseologizm {phrase} frozen in the form <i>{phraseo}</i>" | |
351 | +msgstr "{phrase} phraseologism frozen in the form <i>{phraseo}</i>" | |
352 | 352 | |
353 | 353 | #: entries/phrase_descriptions/polish_strings.py:9 |
354 | 354 | #: entries/phrase_descriptions/polish_strings.py:336 |
... | ... | @@ -1826,25 +1826,38 @@ msgstr "Source" |
1826 | 1826 | msgid "Brak przykładów" |
1827 | 1827 | msgstr "No examples" |
1828 | 1828 | |
1829 | -#: phrase_expansions/templates/phrase_expansions.html:17 | |
1830 | -msgid "advp (frazy przysłówkowe)" | |
1831 | -msgstr "advp (adverbial phrases)" | |
1829 | +#: phrase_expansions/views.py:11 | |
1830 | +msgid "potoczne" | |
1831 | +msgstr "colloquial" | |
1832 | + | |
1833 | +#: phrase_expansions/views.py:12 | |
1834 | +msgid "archaiczne" | |
1835 | +msgstr "archaic" | |
1836 | + | |
1837 | +#: phrase_expansions/views.py:13 | |
1838 | +msgid "wątpliwe" | |
1839 | +msgstr "uncertain" | |
1840 | + | |
1841 | +#: phrase_expansions/views.py:14 | |
1842 | +msgid "pewne" | |
1843 | +msgstr "certain" | |
1844 | + | |
1845 | +#: phrase_expansions/views.py:49 | |
1846 | +msgid "frazy przysłówkowe" | |
1847 | +msgstr "adverbial phrases" | |
1832 | 1848 | |
1833 | -#: phrase_expansions/templates/phrase_expansions.html:17 | |
1834 | -#: phrase_expansions/templates/phrase_expansions.html:32 | |
1835 | -#: phrase_expansions/templates/phrase_expansions.html:47 | |
1836 | -#: phrase_expansions/templates/phrase_expansions.html:62 | |
1837 | -msgid "rozwiń" | |
1838 | -msgstr "expand" | |
1849 | +#: phrase_expansions/views.py:50 | |
1850 | +msgid "frazy okolicznikowe" | |
1851 | +msgstr "adjunct phrases" | |
1839 | 1852 | |
1840 | -#: phrase_expansions/templates/phrase_expansions.html:32 | |
1841 | -msgid "xp (frazy okolicznikowe)" | |
1842 | -msgstr "xp (adjunct phrases)" | |
1853 | +#: phrase_expansions/views.py:51 | |
1854 | +msgid "frazy przyimkowe z przyimkiem złożonym" | |
1855 | +msgstr "prepositional phrases with complex preposition" | |
1843 | 1856 | |
1844 | -#: phrase_expansions/templates/phrase_expansions.html:47 | |
1845 | -msgid "comprepnp (frazy przyimkowe z przyimkiem złożonym)" | |
1846 | -msgstr "comprepnp (prepositional phrases with complex preposition)" | |
1857 | +#: phrase_expansions/views.py:52 | |
1858 | +msgid "fraza dystrybutywna" | |
1859 | +msgstr "distributive phrase" | |
1847 | 1860 | |
1848 | -#: phrase_expansions/templates/phrase_expansions.html:62 | |
1849 | -msgid "pozostałe frazy" | |
1850 | -msgstr "other phrases" | |
1861 | +#: phrase_expansions/views.py:53 | |
1862 | +msgid "fraza posesywna" | |
1863 | +msgstr "possesive phrase" | |
... | ... |
locale/en/LC_MESSAGES/djangojs.po
... | ... | @@ -8,7 +8,7 @@ msgid "" |
8 | 8 | msgstr "" |
9 | 9 | "Project-Id-Version: PACKAGE VERSION\n" |
10 | 10 | "Report-Msgid-Bugs-To: \n" |
11 | -"POT-Creation-Date: 2020-11-09 11:31+0100\n" | |
11 | +"POT-Creation-Date: 2020-11-13 12:05+0100\n" | |
12 | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
13 | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
14 | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" |
... | ... | @@ -48,50 +48,50 @@ msgstr "Remove" |
48 | 48 | msgid "Opinia" |
49 | 49 | msgstr "Opinion" |
50 | 50 | |
51 | -#: entries/static/entries/js/entries.js:325 | |
51 | +#: entries/static/entries/js/entries.js:326 | |
52 | 52 | #: entries/static/entries/js/entries2.js:331 |
53 | 53 | msgid "Funkcja" |
54 | 54 | msgstr "Function" |
55 | 55 | |
56 | -#: entries/static/entries/js/entries.js:328 | |
56 | +#: entries/static/entries/js/entries.js:329 | |
57 | 57 | #: entries/static/entries/js/entries2.js:334 |
58 | 58 | msgid "Typy fraz" |
59 | 59 | msgstr "Phrase types" |
60 | 60 | |
61 | -#: entries/static/entries/js/entries.js:385 | |
61 | +#: entries/static/entries/js/entries.js:386 | |
62 | 62 | #: entries/static/entries/js/entries2.js:394 |
63 | 63 | msgid "brak schematów" |
64 | 64 | msgstr "no schemata" |
65 | 65 | |
66 | -#: entries/static/entries/js/entries.js:409 | |
66 | +#: entries/static/entries/js/entries.js:411 | |
67 | 67 | msgid "nowa jednostka spoza <i>Słowosieci</i>" |
68 | 68 | msgstr "new lexical unit not in <i>plWordnet</i>" |
69 | 69 | |
70 | -#: entries/static/entries/js/entries.js:415 | |
70 | +#: entries/static/entries/js/entries.js:418 | |
71 | 71 | msgid "Przejdź do strony tej jednostki w <i>Słowosieci</i>" |
72 | 72 | msgstr "Go to this lexical unit’s <i>plWordnet</i> page" |
73 | 73 | |
74 | -#: entries/static/entries/js/entries.js:431 | |
74 | +#: entries/static/entries/js/entries.js:434 | |
75 | 75 | #: entries/static/entries/js/entries2.js:412 |
76 | 76 | msgid "Rola" |
77 | 77 | msgstr "Role" |
78 | 78 | |
79 | -#: entries/static/entries/js/entries.js:433 | |
79 | +#: entries/static/entries/js/entries.js:436 | |
80 | 80 | #: entries/static/entries/js/entries2.js:414 |
81 | 81 | msgid "Preferencje selekcyjne" |
82 | 82 | msgstr "Selectional preferences" |
83 | 83 | |
84 | -#: entries/static/entries/js/entries.js:466 | |
84 | +#: entries/static/entries/js/entries.js:469 | |
85 | 85 | #: entries/static/entries/js/entries2.js:450 |
86 | 86 | msgid "brak ram" |
87 | 87 | msgstr "no frames" |
88 | 88 | |
89 | -#: entries/static/entries/js/entries.js:483 | |
89 | +#: entries/static/entries/js/entries.js:486 | |
90 | 90 | #: entries/static/entries/js/entries2.js:467 |
91 | 91 | msgid "Kliknij, aby wyświetlić przykłady dla tego schematu." |
92 | 92 | msgstr "Click to show examples for this schema." |
93 | 93 | |
94 | -#: entries/static/entries/js/entries.js:538 | |
94 | +#: entries/static/entries/js/entries.js:541 | |
95 | 95 | #: entries/static/entries/js/entries2.js:517 |
96 | 96 | msgid "" |
97 | 97 | "Kliknij, aby wyświetlić przykłady dla tej ramy oraz jej realizacje " |
... | ... | @@ -99,63 +99,63 @@ msgid "" |
99 | 99 | msgstr "" |
100 | 100 | "Click to show examples linked to this frame and its syntactic realisations." |
101 | 101 | |
102 | -#: entries/static/entries/js/entries.js:604 | |
102 | +#: entries/static/entries/js/entries.js:612 | |
103 | 103 | msgid "" |
104 | 104 | "Kliknij, aby cofnąć ograniczenie wyświetlanych przykładów do powiązanych z " |
105 | 105 | "tym znaczeniem." |
106 | 106 | msgstr "Click to undo restriction to examples linked to this meaning." |
107 | 107 | |
108 | -#: entries/static/entries/js/entries.js:606 | |
108 | +#: entries/static/entries/js/entries.js:614 | |
109 | 109 | msgid "Kliknij, aby wyświetlić wyłącznie przykłady powiązane z tym znaczeniem." |
110 | 110 | msgstr "Click to show only examples linked to this meaning." |
111 | 111 | |
112 | -#: entries/static/entries/js/entries.js:636 | |
112 | +#: entries/static/entries/js/entries.js:644 | |
113 | 113 | #: entries/static/entries/js/entries2.js:578 |
114 | 114 | msgid "" |
115 | 115 | "Kliknij, aby cofnąć ograniczenie wyświetlanych przykładów do powiązanych z " |
116 | 116 | "tą rolą." |
117 | 117 | msgstr "Click to undo restriction to examples linked to this role." |
118 | 118 | |
119 | -#: entries/static/entries/js/entries.js:638 | |
119 | +#: entries/static/entries/js/entries.js:646 | |
120 | 120 | #: entries/static/entries/js/entries2.js:580 |
121 | 121 | msgid "Kliknij, aby wyświetlić wyłącznie przykłady powiązane z tą rolą." |
122 | 122 | msgstr "Click to show only examples linked to this role." |
123 | 123 | |
124 | -#: entries/static/entries/js/entries.js:676 | |
124 | +#: entries/static/entries/js/entries.js:684 | |
125 | 125 | #: entries/static/entries/js/entries2.js:616 |
126 | 126 | msgid "" |
127 | 127 | "Kliknij, aby cofnąć ograniczenie wyświetlanych przykładów do powiązanych z " |
128 | 128 | "tym schematem." |
129 | 129 | msgstr "Click to undo restriction to examples linked to this schema." |
130 | 130 | |
131 | -#: entries/static/entries/js/entries.js:678 | |
131 | +#: entries/static/entries/js/entries.js:686 | |
132 | 132 | #: entries/static/entries/js/entries2.js:618 |
133 | 133 | msgid "Kliknij, aby wyświetlić wyłącznie przykłady powiązane z tym schematem." |
134 | 134 | msgstr "Click to show only examples linked to this schema." |
135 | 135 | |
136 | -#: entries/static/entries/js/entries.js:706 | |
136 | +#: entries/static/entries/js/entries.js:714 | |
137 | 137 | #: entries/static/entries/js/entries2.js:647 |
138 | 138 | msgid "Kliknij, aby cofnąć wybór tej ramy." |
139 | 139 | msgstr "Click to undo choice if this frame." |
140 | 140 | |
141 | -#: entries/static/entries/js/entries.js:794 | |
141 | +#: entries/static/entries/js/entries.js:802 | |
142 | 142 | #: entries/static/entries/js/entries2.js:725 |
143 | 143 | msgid "Komentarz" |
144 | 144 | msgstr "Comment" |
145 | 145 | |
146 | -#: entries/static/entries/js/entries.js:802 | |
146 | +#: entries/static/entries/js/entries.js:810 | |
147 | 147 | #: entries/static/entries/js/entries2.js:733 |
148 | 148 | msgid "" |
149 | 149 | "Kliknij, aby cofnąć wyświetlanie argumentów i fraz powiązanych z tym " |
150 | 150 | "przykładem." |
151 | 151 | msgstr "Click to undo showing arguments and phrases linked to this example." |
152 | 152 | |
153 | -#: entries/static/entries/js/entries.js:804 | |
153 | +#: entries/static/entries/js/entries.js:812 | |
154 | 154 | #: entries/static/entries/js/entries2.js:735 |
155 | 155 | msgid "Kliknij, aby wyświetlić argumenty i frazy powiązane z tym przykładem." |
156 | 156 | msgstr "Click to show arguments and phrases linked to this example." |
157 | 157 | |
158 | -#: entries/static/entries/js/entries.js:884 | |
158 | +#: entries/static/entries/js/entries.js:892 | |
159 | 159 | #: entries/static/entries/js/entries2.js:815 |
160 | 160 | msgid "brak haseł" |
161 | 161 | msgstr "no entries" |
... | ... |
phrase_expansions/admin.py
1 | 1 | from django.contrib import admin |
2 | 2 | |
3 | -# Register your models here. | |
3 | +from .models import ExpansionOpinion, PhraseExpansionType, PhraseExpansion, ExpansionPosition, ExpansionPhrase, ExpansionPhraseDescription | |
4 | + | |
5 | +admin.site.register(ExpansionOpinion) | |
6 | +admin.site.register(PhraseExpansionType) | |
7 | +admin.site.register(PhraseExpansion) | |
8 | +admin.site.register(ExpansionPosition) | |
9 | +admin.site.register(ExpansionPhrase) | |
10 | +admin.site.register(ExpansionPhraseDescription) | |
... | ... |
phrase_expansions/management/commands/import_expansions.py
0 → 100644
1 | +import os | |
2 | + | |
3 | +from xml.sax import handler, make_parser | |
4 | + | |
5 | +from django.core.management.base import BaseCommand | |
6 | + | |
7 | +from importer.Phrase import phrase_from_tree | |
8 | +from importer.Position import Position | |
9 | +from importer.WalentyXML import XMLNode | |
10 | +from shellvalier.settings import BASE_DIR | |
11 | + | |
12 | +from phrase_expansions.models import ExpansionOpinion, PhraseExpansionType, PhraseExpansion, ExpansionPosition, ExpansionPhrase, ExpansionPhraseDescription | |
13 | + | |
14 | +from entries.phrase_descriptions.descriptions import phrase_description2 | |
15 | + | |
16 | +class Command(BaseCommand): | |
17 | + args = 'none' | |
18 | + help = '' | |
19 | + | |
20 | + def handle(self, **options): | |
21 | + import_expansions() | |
22 | + | |
23 | +OPINION_MAP = { | |
24 | + 'archaiczna' : 'dat', | |
25 | + 'pewna' : 'cer', | |
26 | + 'potoczna' : 'col', | |
27 | + 'wątpliwa' : 'unc', | |
28 | +} | |
29 | + | |
30 | +def import_expansions(): | |
31 | + xml_file = os.path.join(BASE_DIR, 'data', 'walenty', 'phrase_types_expand_20200926.xml') | |
32 | + xml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), xml_file) | |
33 | + | |
34 | + parser = make_parser() | |
35 | + | |
36 | + parser.setContentHandler(ExpansionsTeiHandler()) | |
37 | + parser.parse(xml_path) | |
38 | + | |
39 | + expansions = parser.getContentHandler()._expansions | |
40 | + | |
41 | + for cls in (ExpansionOpinion, PhraseExpansion, ExpansionPosition, ExpansionPhrase, ExpansionPhraseDescription): | |
42 | + cls.objects.all().delete() | |
43 | + | |
44 | + opinions = [(50, u'col'), (40, u'dat'), (20, u'unc'), (10, u'cer'),] | |
45 | + for pri, short in opinions: | |
46 | + opinion = ExpansionOpinion(key=short, priority=pri) | |
47 | + opinion.save() | |
48 | + | |
49 | + for (phrase_type, phrase_subtype), exps in expansions.items(): | |
50 | + expansion_type = PhraseExpansionType.objects.create(phrase_type=phrase_type, | |
51 | + phrase_subtype=phrase_subtype) | |
52 | + expansion_type.save() | |
53 | + print(expansion_type) | |
54 | + for i, (positions, opinion) in enumerate(exps): | |
55 | + opinion = ExpansionOpinion.objects.get(key=OPINION_MAP[opinion]) | |
56 | + expansion = PhraseExpansion.objects.create(expansion_type=expansion_type, | |
57 | + opinion=opinion, | |
58 | + priority=(i + 1)) | |
59 | + expansion.save() | |
60 | + expansion_type.max_positions = max(expansion_type.max_positions, len(positions)) | |
61 | + for j, pos in enumerate(positions): | |
62 | + position = ExpansionPosition(expansion=expansion, priority=(j + 1)) | |
63 | + position.save() | |
64 | + for k, (text_rep, desc_pl, desc_en) in enumerate(pos): | |
65 | + phrase = ExpansionPhrase(position=position, text_rep=text_rep) | |
66 | + phrase.save() | |
67 | + d_pl = ExpansionPhraseDescription(phrase=phrase, lang='pl', description=desc_pl) | |
68 | + d_en = ExpansionPhraseDescription(phrase=phrase, lang='en', description=desc_en) | |
69 | + d_pl.save() | |
70 | + d_en.save() | |
71 | + expansion_type.save() | |
72 | + print(sum(map(len, expansions.values()))) | |
73 | + | |
74 | +class ExpansionsTeiHandler(handler.ContentHandler): | |
75 | + | |
76 | + def __init__(self): | |
77 | + handler.ContentHandler.__init__(self) | |
78 | + self._subtree = None | |
79 | + self._current = None | |
80 | + self._constructing = False | |
81 | + self._content = "" | |
82 | + self._expansions = dict() | |
83 | + | |
84 | + def startElement(self, name, attrs): | |
85 | + if name == 'entry': | |
86 | + self._constructing = True | |
87 | + self._content = "" | |
88 | + if (self._constructing): | |
89 | + node = XMLNode(name, attrs, self._current) | |
90 | + if self._current is not None: | |
91 | + self._current.addChild(node) | |
92 | + else: | |
93 | + self._subtree = node | |
94 | + self._current = node | |
95 | + | |
96 | + def endElement(self, name): | |
97 | + if self._current is not None: | |
98 | + self._current.setContent(self._content.strip()) | |
99 | + self._current = self._current._parent | |
100 | + if name == 'entry': | |
101 | + if self._current is not None: | |
102 | + raise TEIStructureError() | |
103 | + typ = self._subtree._children[0]._attrs['type'] | |
104 | + self.get_expansions(self._subtree, typ) | |
105 | + self._content = '' | |
106 | + | |
107 | + def characters(self, content): | |
108 | + self._content += content | |
109 | + | |
110 | + def get_expansions(self, tree, phrase_type): | |
111 | + dummy_position = Position(None, None, None, None, None) | |
112 | + if phrase_type == 'advp': | |
113 | + subtype = tree._children[0]._children[0]._children[0]._attrs['value'] | |
114 | + elif phrase_type == 'xp': | |
115 | + subtype = tree._children[0]._children[0]._children[0]._children[0]._children[0]._attrs['value'] | |
116 | + elif phrase_type == 'comprepnp': | |
117 | + subtype = tree._children[0]._children[0]._children[0]._content | |
118 | + elif phrase_type in ('distrp', 'possp'): | |
119 | + subtype = None | |
120 | + #print('{}({})'.format(phrase_type, subtype)) | |
121 | + assert((phrase_type, subtype) not in self._expansions) | |
122 | + expansions = [] | |
123 | + for exp in tree._children[1]._children[0]._children: | |
124 | + expansion_positions = [] | |
125 | + opinion = exp._children[0]._children[0]._attrs['value'] | |
126 | + if exp._children[1]._attrs['name'] == 'phrases': | |
127 | + positions = [exp._children[1]] | |
128 | + elif exp._children[1]._attrs['name'] == 'positions': | |
129 | + positions = [pos._children[0] for pos in exp._children[1]._children[0]._children] | |
130 | + for position in positions: | |
131 | + expansion_position = [] | |
132 | + for phrase in position._children[0]._children: | |
133 | + typ = phrase._attrs['type'] | |
134 | + if typ == 'adverb': | |
135 | + adverb = phrase._children[0]._children[0]._attrs['value'] | |
136 | + expansion_position.append((adverb, 'przysłówek <i>{}</i>'.format(adverb), '<i>{}</i> adverb'.format(adverb))) | |
137 | + elif typ == 'advp': | |
138 | + # xp realised by advp(cat) | |
139 | + advpcat = phrase._children[-1]._children[0]._attrs['value'] | |
140 | + expansion_position.append(('advp({})'.format(advpcat), '???', '???')) | |
141 | + elif typ == 'comprepnp': | |
142 | + prep = phrase._children[1]._children[0]._content | |
143 | + expansion_position.append(('comprepnp({})'.format(prep), 'fraza rzeczownikowo-przyimkowa z przyimkiem złożonym <i>{}</i>'.format(prep), 'nominal-prepositional phrase with <i>{}</i> complex preposition'.format(prep))) | |
144 | + else: | |
145 | + phr = phrase_from_tree(phrase) | |
146 | + if False:#str(phr) == 'lex(adjp(agr),agr,agr,pos,OR(cudzy;czyj;czyjkolwiek;czyjś;mój;nasz;niczyj;pański;swój;twój;wasz),natr)': | |
147 | + desc_pl, desc_en = None, None | |
148 | + else: | |
149 | + desc_pl, desc_en = phrase_description2(phr, dummy_position, None, 'pl'), phrase_description2(phr, dummy_position, None, 'en') | |
150 | + expansion_position.append((str(phr), desc_pl, desc_en)) | |
151 | + expansion_positions.append(expansion_position) | |
152 | + assert(expansion_positions) | |
153 | + expansions.append((expansion_positions, opinion)) | |
154 | + self._expansions[(phrase_type, subtype)] = expansions | |
... | ... |
phrase_expansions/models.py
1 | 1 | from django.db import models |
2 | 2 | |
3 | -# Create your models here. | |
3 | + | |
4 | +class ExpansionOpinion(models.Model): | |
5 | + key = models.CharField(max_length=16, unique=True) | |
6 | + priority = models.PositiveIntegerField() | |
7 | + | |
8 | + class Meta: | |
9 | + ordering = ['priority'] | |
10 | + | |
11 | + def __str__(self): | |
12 | + return self.key | |
13 | + | |
14 | +class PhraseExpansionType(models.Model): | |
15 | + phrase_type = models.CharField(max_length=16) | |
16 | + phrase_subtype = models.CharField(max_length=32, null=True) | |
17 | + max_positions = models.PositiveIntegerField(default=1) | |
18 | + | |
19 | + class Meta: | |
20 | + ordering = ['phrase_type', 'phrase_subtype'] | |
21 | + | |
22 | + def __str__(self): | |
23 | + return '{}({})'.format(self.phrase_type, self.phrase_subtype) if self.phrase_subtype else self.phrase_type | |
24 | + | |
25 | +class PhraseExpansion(models.Model): | |
26 | + expansion_type = models.ForeignKey(PhraseExpansionType, on_delete=models.PROTECT, related_name='expansions') | |
27 | + opinion = models.ForeignKey(ExpansionOpinion, on_delete=models.PROTECT) | |
28 | + priority = models.PositiveIntegerField() | |
29 | + | |
30 | + class Meta: | |
31 | + ordering = ['priority'] | |
32 | + | |
33 | + def __str__(self): | |
34 | + return '{}: {}'.format(self.opinion, ' + '.join([str(pos) for pos in self.positions.all()])) | |
35 | + | |
36 | +class ExpansionPosition(models.Model): | |
37 | + expansion = models.ForeignKey(PhraseExpansion, on_delete=models.PROTECT, related_name='positions') | |
38 | + priority = models.PositiveIntegerField() | |
39 | + | |
40 | + class Meta: | |
41 | + ordering = ['priority'] | |
42 | + | |
43 | + def __str__(self): | |
44 | + return '{%s}' % (';'.join([str(pt) for pt in self.phrases.all()])) | |
45 | + | |
46 | +class ExpansionPhrase(models.Model): | |
47 | + position = models.ForeignKey(ExpansionPosition, on_delete=models.PROTECT, related_name='phrases') | |
48 | + text_rep = models.TextField() | |
49 | + | |
50 | + class Meta: | |
51 | + ordering = ['text_rep'] | |
52 | + | |
53 | + def __str__(self): | |
54 | + return self.text_rep | |
55 | + | |
56 | +class ExpansionPhraseDescription(models.Model): | |
57 | + phrase = models.ForeignKey(ExpansionPhrase, on_delete=models.PROTECT, related_name='descriptions') | |
58 | + lang = models.CharField(max_length=2, choices=[('pl', 'pl'), ('en', 'en')]) | |
59 | + description = models.TextField(null=True) | |
... | ... |
phrase_expansions/static/phrase_expansions/js/expansions.js
0 → 100644
1 | +"use strict"; | |
2 | + | |
3 | +$(document).ready(function() { | |
4 | + | |
5 | + $('[data-toggle="tooltip"]').tooltip(); | |
6 | + | |
7 | + $('.collapse').on('show.bs.collapse', function() { | |
8 | + $('a[href="#' + $(this).attr('id') + '"]').find('.action').html('-'); | |
9 | + }).on('hide.bs.collapse', function() { | |
10 | + $('a[href="#' + $(this).attr('id') + '"]').find('.action').html('+'); | |
11 | + }) | |
12 | + | |
13 | +}); | |
... | ... |
phrase_expansions/templates/phrase_expansions.html
... | ... | @@ -6,68 +6,92 @@ |
6 | 6 | {% block title %}{% endblock %} |
7 | 7 | |
8 | 8 | {% block scripts %} |
9 | + <script src="{% static 'phrase_expansions/js/expansions.js' %}"></script> | |
9 | 10 | {% endblock %} |
10 | 11 | |
11 | 12 | {% block content2 %} |
12 | 13 | |
13 | -<div class="card mt-3"> | |
14 | - <div class="card-header" id="heading-advp"> | |
15 | - <h2 class="mb-0"> | |
16 | - <button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#advp" aria-expanded="false" aria-controls="advp"> | |
17 | - {% trans "advp (frazy przysłówkowe)" %} [<span class="action">{% trans "rozwiń" %}</span>] | |
18 | - </button> | |
19 | - </h2> | |
20 | - </div> | |
21 | - <div id="advp" class="collapse" aria-labelledby="heading-advp"> | |
22 | - <div class="card-body"> | |
23 | - ... | |
24 | - </div> | |
25 | - </div> | |
26 | -</div> | |
14 | +<div class="accordion my-3" id="accordion"> | |
27 | 15 | |
28 | -<div class="card mt-3"> | |
29 | - <div class="card-header" id="heading-xp"> | |
30 | - <h2 class="mb-0"> | |
31 | - <button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#xp" aria-expanded="false" aria-controls="xp"> | |
32 | - {% trans "xp (frazy okolicznikowe)" %} [<span class="action">{% trans "rozwiń" %}</span>] | |
33 | - </button> | |
34 | - </h2> | |
35 | - </div> | |
36 | - <div id="xp" class="collapse" aria-labelledby="heading-xp"> | |
37 | - <div class="card-body"> | |
38 | - ... | |
39 | - </div> | |
40 | - </div> | |
41 | -</div> | |
16 | +{% for phrase_expansions in expansions %} | |
42 | 17 | |
43 | -<div class="card mt-3"> | |
44 | - <div class="card-header" id="heading-comprepnp"> | |
45 | - <h2 class="mb-0"> | |
46 | - <button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#comprepnp" aria-expanded="false" aria-controls="comprepnp"> | |
47 | - {% trans "comprepnp (frazy przyimkowe z przyimkiem złożonym)" %} [<span class="action">{% trans "rozwiń" %}</span>] | |
48 | - </button> | |
49 | - </h2> | |
18 | +<div class="card"> | |
19 | + <div class="card-header p-3" id="heading-{{ phrase_expansions.phrase_type }}"> | |
20 | + <h5 class="mb-0"> | |
21 | + <a data-toggle="collapse" href="#{{ phrase_expansions.phrase_type }}" role="button" aria-expanded="false" aria-controls="{{ phrase_expansions.phrase_type }}"> | |
22 | + {{ phrase_expansions.title }}<span class="float-right">[<span class="action">+</span>]</span> | |
23 | + </a> | |
24 | + </h5> | |
50 | 25 | </div> |
51 | - <div id="comprepnp" class="collapse" aria-labelledby="heading-comprepnp"> | |
26 | + <div id="{{ phrase_expansions.phrase_type }}" class="collapse" aria-labelledby="heading-{{ phrase_expansions.phrase_type }}" data-parent="#accordion"> | |
52 | 27 | <div class="card-body"> |
53 | - ... | |
28 | + {% if phrase_expansions.phrase_subtypes|length > 1 and phrase_expansions.phrase_type != 'comprepnp' %} | |
29 | + <div class="accordion" id="accordion-{{ phrase_expansions.phrase_type }}"> | |
30 | + {% endif %} | |
31 | + {% for subtype_expansions in phrase_expansions.phrase_subtypes %} | |
32 | + {% if phrase_expansions.phrase_subtypes|length > 1 and phrase_expansions.phrase_type != 'comprepnp' %} | |
33 | + <div class="card"> | |
34 | + <div class="card-header p-2" id="heading-{{ phrase_expansions.phrase_type }}-{{ subtype_expansions.phrase_subtype|slugify }}"> | |
35 | + <h6 class="mb-0"> | |
36 | + <a data-toggle="collapse" href="#{{ phrase_expansions.phrase_type }}-{{ subtype_expansions.phrase_subtype|slugify }}" role="button" aria-expanded="false" aria-controls="{{ phrase_expansions.phrase_type }}-{{ subtype_expansions.phrase_subtype|slugify }}"> | |
37 | + {{ subtype_expansions.title }}<span class="float-right">[<span class="action">+</span>]</span> | |
38 | + </a> | |
39 | + </h6> | |
40 | + </div> | |
41 | + <div | |
42 | + id="{{ phrase_expansions.phrase_type }}-{{ subtype_expansions.phrase_subtype|slugify }}" | |
43 | + class="collapse" | |
44 | + aria-labelledby="heading-{{ phrase_expansions.phrase_type }}-{{ subtype_expansions.phrase_subtype|slugify }}" | |
45 | + data-parent="#accordion-{{ phrase_expansions.phrase_type }}" | |
46 | + > | |
47 | + <div class="card-body"> | |
48 | + {% endif %} | |
49 | + <table class="table table-sm table-borderless border border-secondary text-dark mb-1"> | |
50 | + <tbody> | |
51 | + {% for expansion in subtype_expansions.expansions %} | |
52 | + <tr> | |
53 | + {% if phrase_expansions.phrase_type == 'comprepnp' and forloop.counter == 1 %} | |
54 | + <th class="py-2 px-1" style="width: 13em;" scope="row" rowspan="{{ subtype_expansions.expansions|length }}"> | |
55 | + {{ subtype_expansions.phrase_subtype }} | |
56 | + </th> | |
57 | + {% endif %} | |
58 | + <td class="py-2 px-1" style="width: 7em;"><img src="/static/entries/img/{{ expansion.opinion_sym }}.svg" alt="{{ expansion.opinion_str }}" width="12" height="12"> | |
59 | + {{ expansion.opinion_str }} | |
60 | + </td> | |
61 | + {% for position in expansion.positions %} | |
62 | + <td class="px-0 py-0 border-top border-left border-secondary text-break"> | |
63 | + {% for phrase in position.phrases %} | |
64 | + <div class="phrase px-1 py-2{% if forloop.counter > 1 %} border-top{% endif %}"> | |
65 | + {% if phrase.desc %} | |
66 | + <span data-toggle="tooltip" data-placement="bottom" data-html="true" title="{{ phrase.desc }}"> | |
67 | + {{ phrase.str }} | |
68 | + </span> | |
69 | + {% else %} | |
70 | + {{ phrase.str }} | |
71 | + {% endif %} | |
72 | + </div> | |
73 | + {% endfor %} | |
74 | + </td> | |
75 | + {% endfor %} | |
76 | + </tr> | |
77 | + {% endfor %} | |
78 | + </tbody> | |
79 | + </table> | |
80 | + {% if phrase_expansions.phrase_subtypes|length > 1 and phrase_expansions.phrase_type != 'comprepnp' %} | |
81 | + </div> | |
82 | + </div> | |
83 | + </div> | |
84 | + {% endif %} | |
85 | + {% endfor %} | |
86 | + {% if phrase_expansions.phrase_subtypes|length > 1 and phrase_expansions.phrase_type != 'comprepnp' %} | |
87 | + </div><!-- accordion --> | |
88 | + {% endif %} | |
54 | 89 | </div> |
55 | 90 | </div> |
56 | 91 | </div> |
57 | 92 | |
58 | -<div class="card mt-4"> | |
59 | - <div class="card-header" id="heading-other"> | |
60 | - <h2 class="mb-0"> | |
61 | - <button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#other" aria-expanded="false" aria-controls="other"> | |
62 | - {% trans "pozostałe frazy" %} [<span class="action">{% trans "rozwiń" %}</span>] | |
63 | - </button> | |
64 | - </h2> | |
65 | - </div> | |
66 | - <div id="other" class="collapse" aria-labelledby="heading-other"> | |
67 | - <div class="card-body"> | |
68 | - ... | |
69 | - </div> | |
70 | - </div> | |
93 | +{% endfor %} | |
94 | + | |
71 | 95 | </div> |
72 | 96 | |
73 | 97 | {% endblock %} |
... | ... |
phrase_expansions/views.py
1 | +from collections import defaultdict | |
2 | + | |
1 | 3 | from django.shortcuts import render |
2 | 4 | |
5 | +from django.utils.translation import gettext as _ | |
6 | + | |
7 | +from phrase_expansions.models import PhraseExpansionType, PhraseExpansion | |
8 | + | |
9 | +def EXPANSION_OPINION(): | |
10 | + return { | |
11 | + 'col' : _('potoczne'), | |
12 | + 'dat' : _('archaiczne'), | |
13 | + 'unc' : _('wątpliwe'), | |
14 | + 'cer' : _('pewne'), | |
15 | + } | |
16 | + | |
3 | 17 | def phrase_expansions(request): |
4 | - return render(request, 'phrase_expansions.html', { }) | |
18 | + expansions = defaultdict(list) | |
19 | + expansions = [ | |
20 | + { | |
21 | + 'phrase_type' : phrase_type, | |
22 | + 'title' : '{} – {}'.format(phrase_type, title), | |
23 | + 'max_positions' : max(exp_type.max_positions for exp_type in PhraseExpansionType.objects.filter(phrase_type=phrase_type)), | |
24 | + 'phrase_subtypes' : [ | |
25 | + { | |
26 | + 'phrase_subtype' : exp_type.phrase_subtype, | |
27 | + 'title' : '{}({})'.format(phrase_type, exp_type.phrase_subtype), | |
28 | + 'max_positions' : exp_type.max_positions, | |
29 | + 'expansions' : [ | |
30 | + { | |
31 | + 'opinion_str' : EXPANSION_OPINION()[exp.opinion.key], | |
32 | + 'opinion_sym' : exp.opinion.key, | |
33 | + 'num_positions' : len(exp.positions.all()), | |
34 | + 'positions' : [ | |
35 | + { | |
36 | + 'phrases' : [ | |
37 | + { | |
38 | + 'str' : phr.text_rep, | |
39 | + 'desc' : phr.descriptions.get(lang=request.LANGUAGE_CODE).description, | |
40 | + } for phr in pos.phrases.all() | |
41 | + ] | |
42 | + } for pos in exp.positions.all() | |
43 | + ], | |
44 | + } for exp in exp_type.expansions.all() | |
45 | + ], | |
46 | + } for exp_type in PhraseExpansionType.objects.filter(phrase_type=phrase_type) | |
47 | + ], | |
48 | + } for phrase_type, title in ( | |
49 | + ('advp', _('frazy przysłówkowe')), | |
50 | + ('xp', _('frazy okolicznikowe')), | |
51 | + ('comprepnp', _('frazy przyimkowe z przyimkiem złożonym')), | |
52 | + ('distrp', _('fraza dystrybutywna')), | |
53 | + ('possp', _('fraza posesywna')), | |
54 | + ) | |
55 | + ] | |
56 | + return render(request, 'phrase_expansions.html', { 'expansions' : expansions }) | |
... | ... |