Mikhail Korobov avatar Mikhail Korobov committed 2540e46

Версия 0.3.5. Возможность указывать части строк, которые нужно склонять. Подправлена документация.

Comments (0)

Files changed (7)

+include AUTHORS
+include INSTALL
+include LICENSE
+include README
+include setup.py
+include docs/Makefile
+include docs/make.bat
+include docs/conf.py
+recursive-include docs *.rst
 # The short X.Y version.
 version = '0.3'
 # The full version, including alpha/beta/rc tags.
-release = '0.3'
+release = '0.3.5'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.

docs/django_api.rst

 Интеграция с django
 ===================
 
-Для django на настоящий момент готовы 2 шаблонных фильтра,
-позволяющие произвольно склонять слова.
+Для django на настоящий момент готово несколько шаблонных фильтров,
+которые позволяют произвольно склонять слова.
 
 Настройка
 ---------
 
 1. Описываем в settings.py установленные словари::
 
-    PYMORPHY_DICTS = {
-        'ru': {
-            'dir': '/usr/share/pymorphy/ru',
-            'backend': 'tcb',
-            'use_cache': True,
-            'default': True
-        },
+       PYMORPHY_DICTS = {
+           'ru': {
+               'dir': '/usr/share/pymorphy/ru',
+               'backend': 'tcb',
+               'use_cache': True,
+               'default': True
+           },
 
-        'en': {
-            'dir': '/usr/share/pymorphy/en',
-        },
-    }
+           'en': {
+               'dir': '/usr/share/pymorphy/en',
+           },
+       }
 
-.. glossary::
-
-    dir
-        обязательный параметр, путь до папки с файлами
-    backend
-        используемое key-value хранилище ('shelve' по умолчанию)
-    use_cache
-        использовать ли кэш (True по умолчанию),
-    default
-        является ли словарь словарем по умолчанию (который будет
-        использоваться в template-tag'ах). Пока довольно бесполезен.
+   :dir: обязательный параметр, путь до папки с файлами
+   :backend: используемое key-value хранилище ('shelve' по умолчанию)
+   :use_cache: использовать ли кэш (True по умолчанию),
+   :default: является ли словарь словарем по умолчанию (который будет
+             использоваться в template-tag'ах). Пока довольно бесполезен.
 
 2. Добавляем pymorphy в INSTALLED_APPS
 
 3. Подключаем в шаблоне библиотеку тегов::
 
-    {% load pymorphy_tags %}
+   {% load pymorphy_tags %}
 
 
 Шаблонные фильтры
 
 Если по какой-то причине смена формы не удалась, возвращают исходную строку.
 
-Если известно, что часть строки склонять не нужно, ее следует заключить
-в двойные квадратные скобки. Можно указать другие разделители, определив в
-settings.py переменные PYMORPHY_NOINFLECT_OPEN и PYMORPHY_NOINFLECT_CLOSE.
+Фильтры inflect и plural не склоняют все, что заключено
+в двойные квадратные скобки. Фильтр inflect_marked наоборот, работает
+только с тем, что в двойных квадратных скобках.
+Можно указать другие разделители (обязательно 2х-символьные),
+определив в settings.py переменные PYMORPHY_MARKER_OPEN и
+PYMORPHY_MARKER_CLOSE.
 
 
 inflect
    {# выведет "Не осталось у нас лошадей Пржевальского" #}
 
 
+inflect_marked
+^^^^^^^^^^^^^^
+Идентичен фильтру inflect за исключением того, что противоположным образом
+трактует [[ ]] ::
+
+   {% load pymorphy_tags %}
+   Не осталось у нас {{ "[[лошадь]] Пржевальского"|inflect_marked:"рд,мн" }}.
+   {# выведет "Не осталось у нас лошадей Пржевальского" #}
+
+
 plural
 ^^^^^^
 

pymorphy/django_conf.py

 except AttributeError:
     raise ImproperlyConfigured('correct settings.PYMORPHY_DICTS is required for pymorphy template tags.')
 
-NOINFLECT_OPEN = getattr(settings, 'PYMORPHY_NOINFLECT_OPEN', '\[\[')
-NOINFLECT_CLOSE = getattr(settings, 'PYMORPHY_NOINFLECT_CLOSE', '\]\]')
+MARKER_OPEN = getattr(settings, 'PYMORPHY_MARKER_OPEN', '\[\[')
+MARKER_CLOSE = getattr(settings, 'PYMORPHY_MARKER_CLOSE', '\]\]')

pymorphy/templatetags/pymorphy_tags.py

 import re
 from django import template
 
-from pymorphy.django_conf import default_morph, NOINFLECT_OPEN, NOINFLECT_CLOSE
+from pymorphy.django_conf import default_morph, MARKER_OPEN, MARKER_CLOSE
 
 register = template.Library()
 
 word_split_re = re.compile('([\W+-])', re.U)
-markup_re = re.compile('(%s.+?%s)' % (NOINFLECT_OPEN, NOINFLECT_CLOSE), re.U)
+markup_re = re.compile('(%s.+?%s)' % (MARKER_OPEN, MARKER_CLOSE), re.U)
 
 def _restore_register(morphed_word, word):
     """ Восстановить регистр слова """
         return phrase
     return result
 
+
 def _process_marked_phrase(phrase, process_func, *args, **kwargs):
+    """ Обработать фразу. В фразе обрабатываются только куски, заключенные
+        в двойные квадратные скобки (например, "[[лошадь]] Пржевальского").
+    """
+    def process(m):
+        return _process_phrase(m.group(1)[2:-2],
+                               process_func, *args, **kwargs)
+    return re.sub(markup_re, process, phrase)
+
+
+def _process_unmarked_phrase(phrase, process_func, *args, **kwargs):
     """ Обработать фразу. В фразе не обрабатываются куски, заключенные
         в двойные квадратные скобки (например, "лошадь [[Пржевальского]]").
     """
 
 @register.filter
 def inflect(phrase, form):
-    return _process_marked_phrase(phrase, default_morph.inflect_ru, form)
+    return _process_unmarked_phrase(unicode(phrase), default_morph.inflect_ru, form)
+
+@register.filter
+def inflect_marked(phrase, form):
+    return _process_marked_phrase(unicode(phrase), default_morph.inflect_ru, form)
 
 @register.filter
 def plural(phrase, amount):
-    return _process_marked_phrase(phrase, default_morph.pluralize_inflected_ru, amount)
+    return _process_unmarked_phrase(phrase, default_morph.pluralize_inflected_ru, amount)
 

pymorphy/tests.py

 
 from unittest import TestCase
 
-from templatetags.pymorphy_tags import inflect, plural
+from templatetags.pymorphy_tags import inflect, plural, inflect_marked
+
+
+class InflectMarkedTagTest(TestCase):
+
+    def assertInflected(self, phrase, form, result):
+        inflected_word = inflect_marked(phrase, form)
+        self.assertEqual(inflected_word, result, u"%s != %s" % (inflected_word, result))
+
+    def testBasicNoinflect(self):
+        self.assertInflected(u'[[лошадь]] Пржевальского', u'дт', u'лошади Пржевальского')
+        self.assertInflected(u'Москва', u'пр', u'Москва')
+        self.assertInflected(u'[[Москва]]', u'пр', u'Москве')
+        self.assertInflected(u'[[Москва]]-сити', u'пр', u'Москве-сити')
+
+    def testTwoWordsNoinflect(self):
+        self.assertInflected(u'[[лошадь]] Пржевальского и [[красный конь]] Кузьмы Петрова-Водкина',
+                             u'дт',
+                             u'лошади Пржевальского и красному коню Кузьмы Петрова-Водкина')
+
 
 class InflectTagTest(TestCase):
 
 
 
 
+
 class PluralTagTest(TestCase):
     def assertPlural(self, phrase, amount, result):
         morphed = plural(phrase, amount)
 
 setup(
     name     = 'pymorphy',
-    version  = '0.3',
+    version  = '0.3.5',
     author='Mikhail Korobov',
     author_email='kmike84@gmail.com',
     url='http://bitbucket.org/kmike/pymorphy/',
                 'pymorphy.backends',
                 'pymorphy.backends.shelve_source',
                 'pymorphy.templatetags'],
+
     requires = ['python (>=2.5)'],
 
     classifiers=[
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.