django-polish-inflection 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_polish_inflection-0.1.0/.github/workflows/ci.yml +52 -0
- django_polish_inflection-0.1.0/.gitignore +14 -0
- django_polish_inflection-0.1.0/.pre-commit-config.yaml +16 -0
- django_polish_inflection-0.1.0/LICENSE +24 -0
- django_polish_inflection-0.1.0/PKG-INFO +273 -0
- django_polish_inflection-0.1.0/README.md +245 -0
- django_polish_inflection-0.1.0/example_project/README.md +49 -0
- django_polish_inflection-0.1.0/example_project/demo/__init__.py +0 -0
- django_polish_inflection-0.1.0/example_project/demo/apps.py +6 -0
- django_polish_inflection-0.1.0/example_project/demo/templates/demo/base.html +56 -0
- django_polish_inflection-0.1.0/example_project/demo/templates/demo/index.html +23 -0
- django_polish_inflection-0.1.0/example_project/demo/templates/demo/odmien.html +50 -0
- django_polish_inflection-0.1.0/example_project/demo/templates/demo/podaj.html +65 -0
- django_polish_inflection-0.1.0/example_project/demo/views.py +86 -0
- django_polish_inflection-0.1.0/example_project/manage.py +16 -0
- django_polish_inflection-0.1.0/example_project/odmieniarka/__init__.py +0 -0
- django_polish_inflection-0.1.0/example_project/odmieniarka/settings.py +65 -0
- django_polish_inflection-0.1.0/example_project/odmieniarka/urls.py +8 -0
- django_polish_inflection-0.1.0/example_project/odmieniarka/wsgi.py +6 -0
- django_polish_inflection-0.1.0/pyproject.toml +58 -0
- django_polish_inflection-0.1.0/src/django_polish_inflection/__init__.py +1 -0
- django_polish_inflection-0.1.0/src/django_polish_inflection/conf.py +30 -0
- django_polish_inflection-0.1.0/src/django_polish_inflection/templatetags/__init__.py +0 -0
- django_polish_inflection-0.1.0/src/django_polish_inflection/templatetags/polish_inflection.py +156 -0
- django_polish_inflection-0.1.0/sshot1.png +0 -0
- django_polish_inflection-0.1.0/tests/test_conf.py +17 -0
- django_polish_inflection-0.1.0/tests/test_frazy.py +114 -0
- django_polish_inflection-0.1.0/tests/test_override.py +89 -0
- django_polish_inflection-0.1.0/tests/test_readme_examples.py +146 -0
- django_polish_inflection-0.1.0/tests/test_smoke.py +7 -0
- django_polish_inflection-0.1.0/tests/test_tags.py +248 -0
- django_polish_inflection-0.1.0/tests/testproject/__init__.py +0 -0
- django_polish_inflection-0.1.0/tests/testproject/settings.py +15 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
13
|
+
cancel-in-progress: true
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
name: py${{ matrix.python-version }} / dj${{ matrix.django-version }}
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
strategy:
|
|
20
|
+
fail-fast: false
|
|
21
|
+
matrix:
|
|
22
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
23
|
+
django-version: ["5.2", "6.0"]
|
|
24
|
+
exclude:
|
|
25
|
+
# Django 6.0 wymaga Pythona >= 3.12
|
|
26
|
+
- python-version: "3.10"
|
|
27
|
+
django-version: "6.0"
|
|
28
|
+
- python-version: "3.11"
|
|
29
|
+
django-version: "6.0"
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
- uses: actions/setup-python@v5
|
|
33
|
+
with:
|
|
34
|
+
python-version: ${{ matrix.python-version }}
|
|
35
|
+
- name: Install
|
|
36
|
+
run: |
|
|
37
|
+
python -m pip install --upgrade pip
|
|
38
|
+
pip install -e .
|
|
39
|
+
pip install "django==${{ matrix.django-version }}.*" pytest pytest-django
|
|
40
|
+
- name: Test
|
|
41
|
+
run: pytest -q
|
|
42
|
+
|
|
43
|
+
lint:
|
|
44
|
+
name: ruff
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
- uses: actions/setup-python@v5
|
|
49
|
+
with:
|
|
50
|
+
python-version: "3.13"
|
|
51
|
+
- run: pip install ruff
|
|
52
|
+
- run: ruff check .
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-toml
|
|
9
|
+
- id: check-added-large-files
|
|
10
|
+
- id: detect-private-key
|
|
11
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
12
|
+
rev: v0.15.20
|
|
13
|
+
hooks:
|
|
14
|
+
- id: ruff-check
|
|
15
|
+
args: [--fix]
|
|
16
|
+
- id: ruff-format
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
BSD 2-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Michał Pasternak
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
16
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
17
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
19
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
20
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
21
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
22
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
23
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
24
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: django-polish-inflection
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Cienka warstwa Django (template tagi i filtry) nad polish-inflection — odmiana rzeczowników przez przypadki.
|
|
5
|
+
Project-URL: Homepage, https://github.com/iplweb/django-polish-inflection
|
|
6
|
+
Project-URL: Repository, https://github.com/iplweb/django-polish-inflection
|
|
7
|
+
Project-URL: Issues, https://github.com/iplweb/django-polish-inflection/issues
|
|
8
|
+
Author-email: Michał Pasternak <m@iplweb.pl>
|
|
9
|
+
License: BSD-2-Clause
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: declension,django,inflection,odmiana,polish,przypadki,templatetags
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Framework :: Django
|
|
14
|
+
Classifier: Framework :: Django :: 5.2
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
17
|
+
Classifier: Natural Language :: Polish
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: django>=5.2
|
|
26
|
+
Requires-Dist: polish-inflection>=0.7.0
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# django-polish-inflection
|
|
30
|
+
|
|
31
|
+
[](https://github.com/iplweb/django-polish-inflection/actions/workflows/ci.yml)
|
|
32
|
+
[](LICENSE)
|
|
33
|
+
|
|
34
|
+
Cienka warstwa Django (template tagi i filtry) nad
|
|
35
|
+
[`polish-inflection`](https://github.com/iplweb/polish-inflection) —
|
|
36
|
+
odmiana polszczyzny wprost w szablonach Django, oparta o słownik SGJP:
|
|
37
|
+
|
|
38
|
+
- **rzeczowniki** przez wszystkie przypadki i obie liczby (`odmien`,
|
|
39
|
+
aliasy pytajne `kogo_czego`/`komu_czemu`/…),
|
|
40
|
+
- **frazy wielowyrazowe** (nazwy własne instytucji, np. „Uniwersytet
|
|
41
|
+
Lubelski") — `odmien_fraze`,
|
|
42
|
+
- **przymiotniki** wg rodzaju głowy — `odmien_przymiotnik`,
|
|
43
|
+
- **dobór formy wg liczebnika** (1 wydział / 2 wydziały / 5 wydziałów) —
|
|
44
|
+
`odmiana_liczebnikowa`.
|
|
45
|
+
|
|
46
|
+
<p align="center">
|
|
47
|
+
<img src="https://raw.githubusercontent.com/iplweb/django-polish-inflection/v0.1.0/sshot1.png" alt="Odmieniarka — przykładowy projekt: pełna tabela odmiany przez przypadki" width="640">
|
|
48
|
+
<br>
|
|
49
|
+
<sub><i>Przykładowy projekt <a href="example_project/">„Odmieniarka"</a> — pełna tabela odmiany przez przypadki wprost w przeglądarce.</i></sub>
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<p align="center">
|
|
53
|
+
<b>Support graciously provided by</b><br><br>
|
|
54
|
+
<a href="https://www.iplweb.pl"><img src="https://www.iplweb.pl/images/ipl-logo-large.png" width="120" alt="IPLweb"></a>
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
## Instalacja
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install django-polish-inflection
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Dodaj do `INSTALLED_APPS`:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
INSTALLED_APPS = [
|
|
67
|
+
...,
|
|
68
|
+
"django_polish_inflection",
|
|
69
|
+
]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Użycie
|
|
73
|
+
|
|
74
|
+
Wczytaj bibliotekę tagów raz na szablon przez `{% load polish_inflection %}` — od
|
|
75
|
+
tej chwili masz w szablonie cztery narzędzia: generyczny `odmien` (dowolny
|
|
76
|
+
przypadek), zestaw czytelnych aliasów pytajnych (`kogo_czego`, `komu_czemu`, …),
|
|
77
|
+
dobór formy wg liczebnika (`odmiana_liczebnikowa`) i odmianę wielowyrazowych nazw
|
|
78
|
+
własnych (`odmien_fraze`). Większość działa i jako **tag** `{% … %}`, i — gdy
|
|
79
|
+
wystarczy sam przypadek — jako **filtr** `|…`; oba warianty zwracają to samo.
|
|
80
|
+
|
|
81
|
+
```django
|
|
82
|
+
{% load polish_inflection %}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Dla przykładowych danych `nazwa_jednostki = "wydział"` i `liczba = 5`
|
|
86
|
+
(w komentarzach `{# → … #}` jest wynik renderowania):
|
|
87
|
+
|
|
88
|
+
**Dowolny przypadek — generyczny `odmien`** (w tym mianownik i wołacz, których
|
|
89
|
+
aliasów pytajnych brak):
|
|
90
|
+
|
|
91
|
+
```django
|
|
92
|
+
{{ nazwa_jednostki|odmien:"dopelniacz" }}
|
|
93
|
+
{# → wydziału #}
|
|
94
|
+
|
|
95
|
+
{% odmien nazwa_jednostki "dopelniacz" %}
|
|
96
|
+
{# → wydziału #}
|
|
97
|
+
|
|
98
|
+
{% odmien nazwa_jednostki "dopelniacz" liczba="mnoga" %}
|
|
99
|
+
{# → wydziałów #}
|
|
100
|
+
|
|
101
|
+
{% odmien nazwa_jednostki "dopelniacz" as forma %}{{ forma }}
|
|
102
|
+
{# → wydziału #}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Aliasy pytajne** — czytają się jak zdanie, wystawiane automatycznie z
|
|
106
|
+
`polish_inflection.pytania`:
|
|
107
|
+
|
|
108
|
+
```django
|
|
109
|
+
Oto lista pracowników {% kogo_czego nazwa_jednostki %}
|
|
110
|
+
{# → Oto lista pracowników wydziału #}
|
|
111
|
+
|
|
112
|
+
Kliknij przycisk z {% z_kim_z_czym nazwa_jednostki %}
|
|
113
|
+
{# → Kliknij przycisk z wydziałem #}
|
|
114
|
+
|
|
115
|
+
{% komu_czemu nazwa_jednostki liczba="mnoga" %}
|
|
116
|
+
{# → wydziałom #}
|
|
117
|
+
|
|
118
|
+
{% podstawowa_forma "wydziałów" %}
|
|
119
|
+
{# → wydział #}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Dobór formy wg liczebnika** — polska zgoda liczebnikowa (1 wydział / 2 wydziały
|
|
123
|
+
/ 5 wydziałów); numer doklejasz sam:
|
|
124
|
+
|
|
125
|
+
```django
|
|
126
|
+
{{ liczba }} {% odmiana_liczebnikowa nazwa_jednostki liczba %}
|
|
127
|
+
{# → 5 wydziałów #}
|
|
128
|
+
|
|
129
|
+
{% odmiana_liczebnikowa nazwa_jednostki liczba "narzednik" %}
|
|
130
|
+
{# → wydziałami #}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Frazy wielowyrazowe i przymiotniki** — nazwy własne instytucji oraz sam
|
|
134
|
+
przymiotnik wg rodzaju:
|
|
135
|
+
|
|
136
|
+
```django
|
|
137
|
+
{% odmien_fraze "Uniwersytet Lubelski" "dopelniacz" %}
|
|
138
|
+
{# → Uniwersytetu Lubelskiego #}
|
|
139
|
+
|
|
140
|
+
{{ "Akademia Medyczna"|odmien_fraze:"narzednik" }}
|
|
141
|
+
{# → Akademią Medyczną #}
|
|
142
|
+
|
|
143
|
+
{% odmien_przymiotnik "lubelski" "dopelniacz" "meski" %}
|
|
144
|
+
{# → lubelskiego #}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Dostępne aliasy pytajne (dokładnie te, które eksportuje zainstalowana wersja
|
|
148
|
+
`polish_inflection.pytania.__all__` — nowe funkcje upstreamu o zgodnej
|
|
149
|
+
sygnaturze `(wyraz, *, liczba=None, default=...)` pojawiają się tu
|
|
150
|
+
automatycznie): `kogo_czego`, `komu_czemu`, `kogo_co`, `z_kim_z_czym`,
|
|
151
|
+
`o_kim_o_czym`, `podstawowa_forma`, oraz skróty `komu`, `czemu`, `z_kim`,
|
|
152
|
+
`z_czym`, `o_kim`, `o_czym`.
|
|
153
|
+
|
|
154
|
+
Mianownik i wołacz nie mają aliasu pytajnego (upstream też ich nie ma) —
|
|
155
|
+
używaj do nich generycznego `{% odmien wyraz "mianownik" %}` / `"wolacz"`.
|
|
156
|
+
|
|
157
|
+
### Odmiana liczebnikowa
|
|
158
|
+
|
|
159
|
+
`{% odmiana_liczebnikowa wyraz liczba %}` zwraca **rzeczownik** w formie
|
|
160
|
+
narzuconej przez liczebnik (polska zgoda liczebnikowa: `1 wydział`,
|
|
161
|
+
`2 wydziały`, `5 wydziałów`). Liczby słownie nie generuje — numer doklejasz
|
|
162
|
+
sam. Rodzaj (w tym męskoosobowy m1, np. `2 studentów` a nie `2 studenci`) jest
|
|
163
|
+
wykrywany automatycznie ze słownika. Opcjonalny trzeci argument to przypadek
|
|
164
|
+
frazy (domyślnie mianownik), np. `{% odmiana_liczebnikowa wyraz liczba "narzednik" %}`
|
|
165
|
+
przy `liczba=5` zwraca `wydziałami` (liczebnik „pięcioma" doklejasz sam).
|
|
166
|
+
Kolejność argumentów jest jak w pozostałych tagach: `wyraz` pierwszy.
|
|
167
|
+
|
|
168
|
+
### Odmiana fraz wielowyrazowych (nazw własnych instytucji)
|
|
169
|
+
|
|
170
|
+
`{% odmien_fraze fraza "przypadek" %}` odmienia **wielowyrazowe nazwy własne**
|
|
171
|
+
instytucji — uczelni, wydziałów, instytutów — a nie tylko pojedyncze
|
|
172
|
+
rzeczowniki. Silnik rozpoznaje głowę frazy, odmienia ją wraz z uzgadniającymi
|
|
173
|
+
się z nią przymiotnikami i **zamraża** dopełniaczowy ogon. Wymaga
|
|
174
|
+
`polish-inflection >= 0.5.2`.
|
|
175
|
+
|
|
176
|
+
```django
|
|
177
|
+
{% load polish_inflection %}
|
|
178
|
+
|
|
179
|
+
{# rzeczownik + przymiotnik — odmieniają się razem #}
|
|
180
|
+
{% odmien_fraze nazwa_uczelni "dopelniacz" %}
|
|
181
|
+
{# "Uniwersytet Lubelski" -> "Uniwersytetu Lubelskiego" #}
|
|
182
|
+
{# "Akademia Medyczna" (narzednik) -> "Akademią Medyczną" #}
|
|
183
|
+
|
|
184
|
+
{# rzeczownik + dopełniacz zależny — odmienia się tylko głowa #}
|
|
185
|
+
{% odmien_fraze nazwa_instytutu "dopelniacz" %}
|
|
186
|
+
{# "Instytut Technologii Stosowanej" -> "Instytutu Technologii Stosowanej" #}
|
|
187
|
+
|
|
188
|
+
{# filtr — gdy wystarcza sam przypadek #}
|
|
189
|
+
Sprawozdanie {{ nazwa_uczelni|odmien_fraze:"dopelniacz" }}
|
|
190
|
+
|
|
191
|
+
{# przypisanie do zmiennej #}
|
|
192
|
+
{% odmien_fraze nazwa_uczelni "miejscownik" as forma %}Konferencja na {{ forma }}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Trafność heurystyki to ok. 85–95% realnych nazw; frazy, których nie łapie (np.
|
|
196
|
+
„Instytut Polski" — przymiotnik czy dopełniacz?), nadpisujesz ręcznie warstwą
|
|
197
|
+
override (patrz [Ustawienia](#ustawienia)). Liczba mnoga fraz jest obsługiwana
|
|
198
|
+
(`liczba="mnoga"`) — przymiotnik uzgadnia się z głową, a zależny ogon
|
|
199
|
+
dopełniaczowy pozostaje zamrożony (wymaga `polish-inflection >= 0.6.0`).
|
|
200
|
+
|
|
201
|
+
Dostępny jest też niższopoziomowy tag `{% odmien_przymiotnik lemat "przypadek"
|
|
202
|
+
"rodzaj" %}` (rodzaj: `"meski"` / `"zenski"` / `"nijaki"`), użyteczny gdy
|
|
203
|
+
składasz formę samodzielnie:
|
|
204
|
+
|
|
205
|
+
```django
|
|
206
|
+
{% odmien_przymiotnik "lubelski" "dopelniacz" "meski" %} {# lubelskiego #}
|
|
207
|
+
{% odmien_przymiotnik "stosowany" "dopelniacz" "zenski" %} {# stosowanej #}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`odmien_przymiotnik` ma wymagany argument `rodzaj`, więc — jak
|
|
211
|
+
`odmiana_liczebnikowa` — jest tylko tagiem (filtr Django przyjmuje jeden
|
|
212
|
+
argument).
|
|
213
|
+
|
|
214
|
+
## Ustawienia
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
# settings.py
|
|
218
|
+
POLISH_INFLECTION_STRICT = False # domyślnie
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
- `False` (domyślnie): nieznane słowo w słowniku SGJP nigdy nie wywala
|
|
222
|
+
renderowania strony — tag/filtr zwraca oryginalne słowo bez zmian.
|
|
223
|
+
- `True`: nieznane słowo podnosi `polish_inflection.BrakOdmiany`. Przydatne
|
|
224
|
+
w testach/CI.
|
|
225
|
+
|
|
226
|
+
### Nadpisania fraz (`POLISH_INFLECTION_PHRASE_OVERRIDES`)
|
|
227
|
+
|
|
228
|
+
Zawór bezpieczeństwa dla fraz, których heurystyka `{% odmien_fraze %}` nie
|
|
229
|
+
rozstrzyga poprawnie. Mapa `{(fraza, "przypadek"): "gotowa forma"}` jest
|
|
230
|
+
konsultowana **przed** silnikiem — jeśli para pasuje, zwracana jest ręczna
|
|
231
|
+
forma, w przeciwnym razie działa silnik.
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
# settings.py
|
|
235
|
+
POLISH_INFLECTION_PHRASE_OVERRIDES = {
|
|
236
|
+
# silnik heurystycznie daje „Instytutu Polski" (czyta jako dopełniacz);
|
|
237
|
+
# wymuszamy czytanie przymiotnikowe:
|
|
238
|
+
("Instytut Polski", "dopelniacz"): "Instytutu Polskiego",
|
|
239
|
+
("Instytut Polski", "miejscownik"): "Instytucie Polskim",
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
- Klucz przypadka to ten sam przyjazny string, którego używasz w tagu
|
|
244
|
+
(`"dopelniacz"`, `"miejscownik"`, …).
|
|
245
|
+
- Dopasowanie frazy ignoruje nadmiarowe białe znaki (trim + collapse spacji);
|
|
246
|
+
wielkość liter jest znacząca.
|
|
247
|
+
- Nadpisanie dotyczy liczby pojedynczej (klucz nie zawiera liczby); przy
|
|
248
|
+
`liczba="mnoga"` używany jest silnik.
|
|
249
|
+
|
|
250
|
+
## Przykładowy projekt
|
|
251
|
+
|
|
252
|
+
W katalogu [`example_project/`](example_project/) jest gotowy do uruchomienia
|
|
253
|
+
projekt Django („Odmieniarka"): wpisujesz słowo lub nazwę własną, a strona
|
|
254
|
+
generuje pełną tabelę odmiany przez przypadki (l.poj. i l.mn.), łącznie z
|
|
255
|
+
działającą warstwą override. Uruchomienie (z korzenia repo, `uv` sam ogarnia
|
|
256
|
+
zależności): `uv run python example_project/manage.py runserver`.
|
|
257
|
+
|
|
258
|
+
## Zakres
|
|
259
|
+
|
|
260
|
+
Ten pakiet odmienia pojedyncze rzeczowniki pospolite obecne w słowniku SGJP
|
|
261
|
+
(np. "wydział", "uczelnia", "instytut") przez wszystkie przypadki i obie liczby.
|
|
262
|
+
|
|
263
|
+
Odmiana wielowyrazowych nazw własnych instytucji (np. "Uniwersytet Lubelski")
|
|
264
|
+
jest dostępna heurystycznie przez `{% odmien_fraze %}` (patrz wyżej) — wymaga
|
|
265
|
+
`polish-inflection >= 0.5.2`.
|
|
266
|
+
|
|
267
|
+
Dobór formy rzeczownika wg liczebnika (1 wydział / 2 wydziały / 5 wydziałów)
|
|
268
|
+
jest dostępny przez `{% odmiana_liczebnikowa %}` (patrz wyżej) — wymaga
|
|
269
|
+
`polish-inflection >= 0.3.0`.
|
|
270
|
+
|
|
271
|
+
## Licencja
|
|
272
|
+
|
|
273
|
+
BSD 2-Clause — patrz [LICENSE](LICENSE). Copyright © 2026 Michał Pasternak.
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# django-polish-inflection
|
|
2
|
+
|
|
3
|
+
[](https://github.com/iplweb/django-polish-inflection/actions/workflows/ci.yml)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
Cienka warstwa Django (template tagi i filtry) nad
|
|
7
|
+
[`polish-inflection`](https://github.com/iplweb/polish-inflection) —
|
|
8
|
+
odmiana polszczyzny wprost w szablonach Django, oparta o słownik SGJP:
|
|
9
|
+
|
|
10
|
+
- **rzeczowniki** przez wszystkie przypadki i obie liczby (`odmien`,
|
|
11
|
+
aliasy pytajne `kogo_czego`/`komu_czemu`/…),
|
|
12
|
+
- **frazy wielowyrazowe** (nazwy własne instytucji, np. „Uniwersytet
|
|
13
|
+
Lubelski") — `odmien_fraze`,
|
|
14
|
+
- **przymiotniki** wg rodzaju głowy — `odmien_przymiotnik`,
|
|
15
|
+
- **dobór formy wg liczebnika** (1 wydział / 2 wydziały / 5 wydziałów) —
|
|
16
|
+
`odmiana_liczebnikowa`.
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<img src="https://raw.githubusercontent.com/iplweb/django-polish-inflection/v0.1.0/sshot1.png" alt="Odmieniarka — przykładowy projekt: pełna tabela odmiany przez przypadki" width="640">
|
|
20
|
+
<br>
|
|
21
|
+
<sub><i>Przykładowy projekt <a href="example_project/">„Odmieniarka"</a> — pełna tabela odmiany przez przypadki wprost w przeglądarce.</i></sub>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<p align="center">
|
|
25
|
+
<b>Support graciously provided by</b><br><br>
|
|
26
|
+
<a href="https://www.iplweb.pl"><img src="https://www.iplweb.pl/images/ipl-logo-large.png" width="120" alt="IPLweb"></a>
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
## Instalacja
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install django-polish-inflection
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Dodaj do `INSTALLED_APPS`:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
INSTALLED_APPS = [
|
|
39
|
+
...,
|
|
40
|
+
"django_polish_inflection",
|
|
41
|
+
]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Użycie
|
|
45
|
+
|
|
46
|
+
Wczytaj bibliotekę tagów raz na szablon przez `{% load polish_inflection %}` — od
|
|
47
|
+
tej chwili masz w szablonie cztery narzędzia: generyczny `odmien` (dowolny
|
|
48
|
+
przypadek), zestaw czytelnych aliasów pytajnych (`kogo_czego`, `komu_czemu`, …),
|
|
49
|
+
dobór formy wg liczebnika (`odmiana_liczebnikowa`) i odmianę wielowyrazowych nazw
|
|
50
|
+
własnych (`odmien_fraze`). Większość działa i jako **tag** `{% … %}`, i — gdy
|
|
51
|
+
wystarczy sam przypadek — jako **filtr** `|…`; oba warianty zwracają to samo.
|
|
52
|
+
|
|
53
|
+
```django
|
|
54
|
+
{% load polish_inflection %}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Dla przykładowych danych `nazwa_jednostki = "wydział"` i `liczba = 5`
|
|
58
|
+
(w komentarzach `{# → … #}` jest wynik renderowania):
|
|
59
|
+
|
|
60
|
+
**Dowolny przypadek — generyczny `odmien`** (w tym mianownik i wołacz, których
|
|
61
|
+
aliasów pytajnych brak):
|
|
62
|
+
|
|
63
|
+
```django
|
|
64
|
+
{{ nazwa_jednostki|odmien:"dopelniacz" }}
|
|
65
|
+
{# → wydziału #}
|
|
66
|
+
|
|
67
|
+
{% odmien nazwa_jednostki "dopelniacz" %}
|
|
68
|
+
{# → wydziału #}
|
|
69
|
+
|
|
70
|
+
{% odmien nazwa_jednostki "dopelniacz" liczba="mnoga" %}
|
|
71
|
+
{# → wydziałów #}
|
|
72
|
+
|
|
73
|
+
{% odmien nazwa_jednostki "dopelniacz" as forma %}{{ forma }}
|
|
74
|
+
{# → wydziału #}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Aliasy pytajne** — czytają się jak zdanie, wystawiane automatycznie z
|
|
78
|
+
`polish_inflection.pytania`:
|
|
79
|
+
|
|
80
|
+
```django
|
|
81
|
+
Oto lista pracowników {% kogo_czego nazwa_jednostki %}
|
|
82
|
+
{# → Oto lista pracowników wydziału #}
|
|
83
|
+
|
|
84
|
+
Kliknij przycisk z {% z_kim_z_czym nazwa_jednostki %}
|
|
85
|
+
{# → Kliknij przycisk z wydziałem #}
|
|
86
|
+
|
|
87
|
+
{% komu_czemu nazwa_jednostki liczba="mnoga" %}
|
|
88
|
+
{# → wydziałom #}
|
|
89
|
+
|
|
90
|
+
{% podstawowa_forma "wydziałów" %}
|
|
91
|
+
{# → wydział #}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Dobór formy wg liczebnika** — polska zgoda liczebnikowa (1 wydział / 2 wydziały
|
|
95
|
+
/ 5 wydziałów); numer doklejasz sam:
|
|
96
|
+
|
|
97
|
+
```django
|
|
98
|
+
{{ liczba }} {% odmiana_liczebnikowa nazwa_jednostki liczba %}
|
|
99
|
+
{# → 5 wydziałów #}
|
|
100
|
+
|
|
101
|
+
{% odmiana_liczebnikowa nazwa_jednostki liczba "narzednik" %}
|
|
102
|
+
{# → wydziałami #}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Frazy wielowyrazowe i przymiotniki** — nazwy własne instytucji oraz sam
|
|
106
|
+
przymiotnik wg rodzaju:
|
|
107
|
+
|
|
108
|
+
```django
|
|
109
|
+
{% odmien_fraze "Uniwersytet Lubelski" "dopelniacz" %}
|
|
110
|
+
{# → Uniwersytetu Lubelskiego #}
|
|
111
|
+
|
|
112
|
+
{{ "Akademia Medyczna"|odmien_fraze:"narzednik" }}
|
|
113
|
+
{# → Akademią Medyczną #}
|
|
114
|
+
|
|
115
|
+
{% odmien_przymiotnik "lubelski" "dopelniacz" "meski" %}
|
|
116
|
+
{# → lubelskiego #}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Dostępne aliasy pytajne (dokładnie te, które eksportuje zainstalowana wersja
|
|
120
|
+
`polish_inflection.pytania.__all__` — nowe funkcje upstreamu o zgodnej
|
|
121
|
+
sygnaturze `(wyraz, *, liczba=None, default=...)` pojawiają się tu
|
|
122
|
+
automatycznie): `kogo_czego`, `komu_czemu`, `kogo_co`, `z_kim_z_czym`,
|
|
123
|
+
`o_kim_o_czym`, `podstawowa_forma`, oraz skróty `komu`, `czemu`, `z_kim`,
|
|
124
|
+
`z_czym`, `o_kim`, `o_czym`.
|
|
125
|
+
|
|
126
|
+
Mianownik i wołacz nie mają aliasu pytajnego (upstream też ich nie ma) —
|
|
127
|
+
używaj do nich generycznego `{% odmien wyraz "mianownik" %}` / `"wolacz"`.
|
|
128
|
+
|
|
129
|
+
### Odmiana liczebnikowa
|
|
130
|
+
|
|
131
|
+
`{% odmiana_liczebnikowa wyraz liczba %}` zwraca **rzeczownik** w formie
|
|
132
|
+
narzuconej przez liczebnik (polska zgoda liczebnikowa: `1 wydział`,
|
|
133
|
+
`2 wydziały`, `5 wydziałów`). Liczby słownie nie generuje — numer doklejasz
|
|
134
|
+
sam. Rodzaj (w tym męskoosobowy m1, np. `2 studentów` a nie `2 studenci`) jest
|
|
135
|
+
wykrywany automatycznie ze słownika. Opcjonalny trzeci argument to przypadek
|
|
136
|
+
frazy (domyślnie mianownik), np. `{% odmiana_liczebnikowa wyraz liczba "narzednik" %}`
|
|
137
|
+
przy `liczba=5` zwraca `wydziałami` (liczebnik „pięcioma" doklejasz sam).
|
|
138
|
+
Kolejność argumentów jest jak w pozostałych tagach: `wyraz` pierwszy.
|
|
139
|
+
|
|
140
|
+
### Odmiana fraz wielowyrazowych (nazw własnych instytucji)
|
|
141
|
+
|
|
142
|
+
`{% odmien_fraze fraza "przypadek" %}` odmienia **wielowyrazowe nazwy własne**
|
|
143
|
+
instytucji — uczelni, wydziałów, instytutów — a nie tylko pojedyncze
|
|
144
|
+
rzeczowniki. Silnik rozpoznaje głowę frazy, odmienia ją wraz z uzgadniającymi
|
|
145
|
+
się z nią przymiotnikami i **zamraża** dopełniaczowy ogon. Wymaga
|
|
146
|
+
`polish-inflection >= 0.5.2`.
|
|
147
|
+
|
|
148
|
+
```django
|
|
149
|
+
{% load polish_inflection %}
|
|
150
|
+
|
|
151
|
+
{# rzeczownik + przymiotnik — odmieniają się razem #}
|
|
152
|
+
{% odmien_fraze nazwa_uczelni "dopelniacz" %}
|
|
153
|
+
{# "Uniwersytet Lubelski" -> "Uniwersytetu Lubelskiego" #}
|
|
154
|
+
{# "Akademia Medyczna" (narzednik) -> "Akademią Medyczną" #}
|
|
155
|
+
|
|
156
|
+
{# rzeczownik + dopełniacz zależny — odmienia się tylko głowa #}
|
|
157
|
+
{% odmien_fraze nazwa_instytutu "dopelniacz" %}
|
|
158
|
+
{# "Instytut Technologii Stosowanej" -> "Instytutu Technologii Stosowanej" #}
|
|
159
|
+
|
|
160
|
+
{# filtr — gdy wystarcza sam przypadek #}
|
|
161
|
+
Sprawozdanie {{ nazwa_uczelni|odmien_fraze:"dopelniacz" }}
|
|
162
|
+
|
|
163
|
+
{# przypisanie do zmiennej #}
|
|
164
|
+
{% odmien_fraze nazwa_uczelni "miejscownik" as forma %}Konferencja na {{ forma }}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Trafność heurystyki to ok. 85–95% realnych nazw; frazy, których nie łapie (np.
|
|
168
|
+
„Instytut Polski" — przymiotnik czy dopełniacz?), nadpisujesz ręcznie warstwą
|
|
169
|
+
override (patrz [Ustawienia](#ustawienia)). Liczba mnoga fraz jest obsługiwana
|
|
170
|
+
(`liczba="mnoga"`) — przymiotnik uzgadnia się z głową, a zależny ogon
|
|
171
|
+
dopełniaczowy pozostaje zamrożony (wymaga `polish-inflection >= 0.6.0`).
|
|
172
|
+
|
|
173
|
+
Dostępny jest też niższopoziomowy tag `{% odmien_przymiotnik lemat "przypadek"
|
|
174
|
+
"rodzaj" %}` (rodzaj: `"meski"` / `"zenski"` / `"nijaki"`), użyteczny gdy
|
|
175
|
+
składasz formę samodzielnie:
|
|
176
|
+
|
|
177
|
+
```django
|
|
178
|
+
{% odmien_przymiotnik "lubelski" "dopelniacz" "meski" %} {# lubelskiego #}
|
|
179
|
+
{% odmien_przymiotnik "stosowany" "dopelniacz" "zenski" %} {# stosowanej #}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`odmien_przymiotnik` ma wymagany argument `rodzaj`, więc — jak
|
|
183
|
+
`odmiana_liczebnikowa` — jest tylko tagiem (filtr Django przyjmuje jeden
|
|
184
|
+
argument).
|
|
185
|
+
|
|
186
|
+
## Ustawienia
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
# settings.py
|
|
190
|
+
POLISH_INFLECTION_STRICT = False # domyślnie
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- `False` (domyślnie): nieznane słowo w słowniku SGJP nigdy nie wywala
|
|
194
|
+
renderowania strony — tag/filtr zwraca oryginalne słowo bez zmian.
|
|
195
|
+
- `True`: nieznane słowo podnosi `polish_inflection.BrakOdmiany`. Przydatne
|
|
196
|
+
w testach/CI.
|
|
197
|
+
|
|
198
|
+
### Nadpisania fraz (`POLISH_INFLECTION_PHRASE_OVERRIDES`)
|
|
199
|
+
|
|
200
|
+
Zawór bezpieczeństwa dla fraz, których heurystyka `{% odmien_fraze %}` nie
|
|
201
|
+
rozstrzyga poprawnie. Mapa `{(fraza, "przypadek"): "gotowa forma"}` jest
|
|
202
|
+
konsultowana **przed** silnikiem — jeśli para pasuje, zwracana jest ręczna
|
|
203
|
+
forma, w przeciwnym razie działa silnik.
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
# settings.py
|
|
207
|
+
POLISH_INFLECTION_PHRASE_OVERRIDES = {
|
|
208
|
+
# silnik heurystycznie daje „Instytutu Polski" (czyta jako dopełniacz);
|
|
209
|
+
# wymuszamy czytanie przymiotnikowe:
|
|
210
|
+
("Instytut Polski", "dopelniacz"): "Instytutu Polskiego",
|
|
211
|
+
("Instytut Polski", "miejscownik"): "Instytucie Polskim",
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
- Klucz przypadka to ten sam przyjazny string, którego używasz w tagu
|
|
216
|
+
(`"dopelniacz"`, `"miejscownik"`, …).
|
|
217
|
+
- Dopasowanie frazy ignoruje nadmiarowe białe znaki (trim + collapse spacji);
|
|
218
|
+
wielkość liter jest znacząca.
|
|
219
|
+
- Nadpisanie dotyczy liczby pojedynczej (klucz nie zawiera liczby); przy
|
|
220
|
+
`liczba="mnoga"` używany jest silnik.
|
|
221
|
+
|
|
222
|
+
## Przykładowy projekt
|
|
223
|
+
|
|
224
|
+
W katalogu [`example_project/`](example_project/) jest gotowy do uruchomienia
|
|
225
|
+
projekt Django („Odmieniarka"): wpisujesz słowo lub nazwę własną, a strona
|
|
226
|
+
generuje pełną tabelę odmiany przez przypadki (l.poj. i l.mn.), łącznie z
|
|
227
|
+
działającą warstwą override. Uruchomienie (z korzenia repo, `uv` sam ogarnia
|
|
228
|
+
zależności): `uv run python example_project/manage.py runserver`.
|
|
229
|
+
|
|
230
|
+
## Zakres
|
|
231
|
+
|
|
232
|
+
Ten pakiet odmienia pojedyncze rzeczowniki pospolite obecne w słowniku SGJP
|
|
233
|
+
(np. "wydział", "uczelnia", "instytut") przez wszystkie przypadki i obie liczby.
|
|
234
|
+
|
|
235
|
+
Odmiana wielowyrazowych nazw własnych instytucji (np. "Uniwersytet Lubelski")
|
|
236
|
+
jest dostępna heurystycznie przez `{% odmien_fraze %}` (patrz wyżej) — wymaga
|
|
237
|
+
`polish-inflection >= 0.5.2`.
|
|
238
|
+
|
|
239
|
+
Dobór formy rzeczownika wg liczebnika (1 wydział / 2 wydziały / 5 wydziałów)
|
|
240
|
+
jest dostępny przez `{% odmiana_liczebnikowa %}` (patrz wyżej) — wymaga
|
|
241
|
+
`polish-inflection >= 0.3.0`.
|
|
242
|
+
|
|
243
|
+
## Licencja
|
|
244
|
+
|
|
245
|
+
BSD 2-Clause — patrz [LICENSE](LICENSE). Copyright © 2026 Michał Pasternak.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Odmieniarka — przykładowy projekt
|
|
2
|
+
|
|
3
|
+
Minimalny projekt Django pokazujący `django-polish-inflection` w akcji. Strona
|
|
4
|
+
startowa (`/`) daje wybór między dwoma narzędziami:
|
|
5
|
+
|
|
6
|
+
- **Odmiana wyrazów** (`/odmien/`) — wpisujesz słowo lub wielowyrazową nazwę
|
|
7
|
+
własną, a strona generuje pełną odmianę przez wszystkie przypadki (liczba
|
|
8
|
+
pojedyncza i mnoga) w szablonie przez tag `{% odmien_fraze %}`.
|
|
9
|
+
- **Podawanie form** (`/podaj/`) — kierunek odwrotny: wpisujesz dowolną formę,
|
|
10
|
+
a widok pokazuje jej analizy (forma podstawowa, przypadek, liczba, rodzaj)
|
|
11
|
+
zarówno jako **rzeczownik** (`podaj()`), jak i **przymiotnik**
|
|
12
|
+
(`podaj_przymiotnik()`) — obie słownikowe (SGJP), łącznie z synkretyzmem
|
|
13
|
+
i homografią.
|
|
14
|
+
|
|
15
|
+
## Uruchomienie
|
|
16
|
+
|
|
17
|
+
Z tego katalogu — `uv` sam znajdzie projekt w katalogu nadrzędnym i ogarnie
|
|
18
|
+
zależności (Django i `django-polish-inflection`) w izolowanym środowisku:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv run python manage.py runserver
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Otwórz http://127.0.0.1:8000/ i wybierz jedno z dwóch narzędzi.
|
|
25
|
+
|
|
26
|
+
Projekt nie używa bazy danych — `runserver` startuje bez migracji.
|
|
27
|
+
|
|
28
|
+
## Co pokazuje
|
|
29
|
+
|
|
30
|
+
- **Odmianę słów i fraz** przez jeden tag `{% odmien_fraze %}` (działa dla obu —
|
|
31
|
+
patrz `demo/templates/demo/odmien.html`).
|
|
32
|
+
- **Odmianę w pętli**: przypadek jest zmienną (`{% odmien_fraze wyraz p.key %}`),
|
|
33
|
+
więc jedna pętla generuje całą tabelę.
|
|
34
|
+
- **Warstwę override**: `odmieniarka/settings.py` zawiera
|
|
35
|
+
`POLISH_INFLECTION_PHRASE_OVERRIDES` dla „Instytut Polski" — wpisz tę frazę
|
|
36
|
+
na stronie odmiany, by zobaczyć ręczną formę zamiast heurystycznej.
|
|
37
|
+
- **Analizę form** jako rzeczownik i przymiotnik: strona „Podawanie form"
|
|
38
|
+
łączy `podaj()` (rzeczowniki) i `podaj_przymiotnik()` (przymiotniki) w widoku
|
|
39
|
+
(`demo/views.py`), bo obie zwracają listy obiektów, nie tekst — dlatego nie są
|
|
40
|
+
tagami szablonu jak odmiana. Od `polish-inflection` 0.7.0 analiza przymiotnika
|
|
41
|
+
jest słownikowa (bazy z SGJP), więc nie nadgeneruje form, które tylko wyglądają
|
|
42
|
+
jak przymiotnik.
|
|
43
|
+
|
|
44
|
+
## Struktura
|
|
45
|
+
|
|
46
|
+
- `odmieniarka/urls.py` — trzy trasy: `/` (wybór), `/odmien/`, `/podaj/`.
|
|
47
|
+
- `demo/views.py` — widoki `index`, `odmien`, `analiza`.
|
|
48
|
+
- `demo/templates/demo/` — `base.html` (wspólny szkielet) + `index`, `odmien`,
|
|
49
|
+
`podaj`.
|
|
File without changes
|