diff options
author | Val Neekman <un33kvu@gmail.com> | 2018-12-25 18:00:44 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-25 18:00:44 -0500 |
commit | 76f4eabe323653555d11702c3e53b66ebf352683 (patch) | |
tree | deebed86a83e9710786a4ffd706f7cd5f32e0559 | |
parent | f4462bb64278e091011e6612feac295bf46d1136 (diff) | |
download | python-slugify-2.0.0.tar.gz |
Proper fallback to text-unidecode, favoring Unidecode, drop support for py 2.6, 3.3. (#63)2.0.0
* enable raw re pattern
* conditional text_unidecode install
* update readme, changelog, manifest
* update ci
* readme
* drop test for py 2.6 and 3.3
* clean up readme
* readme
-rw-r--r-- | .travis.yml | 7 | ||||
-rw-r--r-- | .vscode/settings.json | 4 | ||||
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | MANIFEST.in | 2 | ||||
-rw-r--r-- | README.md | 144 | ||||
-rw-r--r-- | README.rst | 231 | ||||
-rwxr-xr-x | setup.py | 10 | ||||
-rw-r--r-- | slugify/__init__.py | 2 | ||||
-rw-r--r-- | slugify/slugify.py | 10 |
9 files changed, 163 insertions, 250 deletions
diff --git a/.travis.yml b/.travis.yml index 4bf2dd4..685386f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,21 +2,14 @@ sudo: false language: python python: - - "2.6" - "2.7" - - "3.3" - "3.4" - "3.5" - "3.6" - pypy -env: - - SLUGIFY_USES_TEXT_UNIDECODE=yes - - SLUGIFY_USES_UNIDECODE=yes # dummy: tell travis to run more than one build types - install: - pip install pip -U - - if [[ -z "${SLUGIFY_USES_TEXT_UNIDECODE}" ]]; then pip install -q -r requirements.txt; else pip install -q -r requirements_alt.txt; fi - pip install -e . - pip install pycodestyle - pip install coveralls diff --git a/.vscode/settings.json b/.vscode/settings.json index 20d15cb..32531ea 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,5 @@ { - "python.linting.pylintEnabled": false + "python.linting.pylintEnabled": false, + "restructuredtext.confPath": "", + "python.pythonPath": "/usr/local/opt/python/bin/python3.6" }
\ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 84f3436..cd80bf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2.0.0 + - Fix alternative dependency installation + ## 1.2.6 - Add support for case sensitive slugs (@s-m-e) diff --git a/MANIFEST.in b/MANIFEST.in index a755e2e..067e13a 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,3 @@ include CHANGELOG.md include LICENSE -include README.rst +include README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..96116e8 --- /dev/null +++ b/README.md @@ -0,0 +1,144 @@ +Python Slugify +==================== + +**A Python slugify application that handles unicode**. + +[![status-image]][status-link] +[![version-image]][version-link] +[![coverage-image]][coverage-link] + +Overview +==================== + +**Best attempt** to create slugs from unicode strings while keeping it **DRY**. + +Notice +==================== + +By default, this modules installs and uses [Unidecode](https://github.com/avian2/unidecode) *(GPL)* for its decoding needs. However if you wish to use [text-unidecode](https://github.com/kmike/text-unidecode) *(GPL & Perl Artistic)* instead, plesea ensure it is installed prior to `python-slugify` installation. + +In cases where both `Unidecode` and `text-unidecode` are installed, the `Unidecode` is used as the default decoding module. + + +How to install +==================== + + 1. easy_install python-slugify + 2. pip install python-slugify + 3. git clone http://github.com/un33k/python-slugify + a. cd python-slugify + b. python setup.py install + 4. wget https://github.com/un33k/python-slugify/zipball/master + a. unzip the downloaded file + b. cd python-slugify-* + c. python setup.py install + + +How to use +==================== + + ```python + from slugify import slugify + + txt = "This is a test ---" + r = slugify(txt) + self.assertEqual(r, "this-is-a-test") + + txt = '影師嗎' + r = slugify(txt) + self.assertEqual(r, "ying-shi-ma") + + txt = 'C\'est déjà l\'été.' + r = slugify(txt) + self.assertEqual(r, "c-est-deja-l-ete") + + txt = 'Nín hǎo. Wǒ shì zhōng guó rén' + r = slugify(txt) + self.assertEqual(r, "nin-hao-wo-shi-zhong-guo-ren") + + txt = 'Компьютер' + r = slugify(txt) + self.assertEqual(r, "kompiuter") + + txt = 'jaja---lol-méméméoo--a' + r = slugify(txt, max_length=9) + self.assertEqual(r, "jaja-lol") + + txt = 'jaja---lol-méméméoo--a' + r = slugify(txt, max_length=15, word_boundary=True) + self.assertEqual(r, "jaja-lol-a") + + txt = 'jaja---lol-méméméoo--a' + r = slugify(txt, max_length=20, word_boundary=True, separator=".") + self.assertEqual(r, "jaja.lol.mememeoo.a") + + txt = 'one two three four five' + r = slugify(txt, max_length=13, word_boundary=True, save_order=True) + self.assertEqual(r, "one-two-three") + + txt = 'the quick brown fox jumps over the lazy dog' + r = slugify(txt, stopwords=['the']) + self.assertEqual(r, 'quick-brown-fox-jumps-over-lazy-dog') + + txt = 'the quick brown fox jumps over the lazy dog in a hurry' + r = slugify(txt, stopwords=['the', 'in', 'a', 'hurry']) + self.assertEqual(r, 'quick-brown-fox-jumps-over-lazy-dog') + + txt = 'thIs Has a stopword Stopword' + r = slugify(txt, stopwords=['Stopword'], lowercase=False) + self.assertEqual(r, 'thIs-Has-a-stopword') + + txt = "___This is a test___" + regex_pattern = r'[^-a-z0-9_]+' + r = slugify(txt, regex_pattern=regex_pattern) + self.assertEqual(r, "___this-is-a-test___") + + txt = "___This is a test___" + regex_pattern = r'[^-a-z0-9_]+' + r = slugify(txt, separator='_', regex_pattern=regex_pattern) + self.assertNotEqual(r, "_this_is_a_test_") + + ``` + +For more examples, have a look at the [test.py](test.py) file. + + +Running the tests +==================== + +To run the tests against the current environment: + + python test.py + + +License +==================== + +Released under a ([MIT](LICENSE)) license. + + +Version +==================== +X.Y.Z Version + + `MAJOR` version -- when you make incompatible API changes, + `MINOR` version -- when you add functionality in a backwards-compatible manner, and + `PATCH` version -- when you make backwards-compatible bug fixes. + +[status-image]: https://secure.travis-ci.org/un33k/python-slugify.png?branch=master +[status-link]: http://travis-ci.org/un33k/python-slugify?branch=master + +[version-image]: https://img.shields.io/pypi/v/python-slugify.svg +[version-link]: https://pypi.python.org/pypi/python-slugify + +[coverage-image]: https://coveralls.io/repos/un33k/python-slugify/badge.svg +[coverage-link]: https://coveralls.io/r/un33k/python-slugify + +[download-image]: https://img.shields.io/pypi/dm/python-slugify.svg +[download-link]: https://pypi.python.org/pypi/python-slugify + + +Sponsors +==================== + +[![Surge](https://www.surgeforward.com/wp-content/themes/understrap-master/images/logo.png)](https://github.com/surgeforward)
\ No newline at end of file diff --git a/README.rst b/README.rst deleted file mode 100644 index e02375f..0000000 --- a/README.rst +++ /dev/null @@ -1,231 +0,0 @@ -Python Slugify -============== - -|status-image| |version-image| |coverage-image| - -Overview --------- - -A Python **slugify** application that handles **unicode**. - - -How to install --------------- - -Via ``pip``: - -.. code:: bash - - $ pip install python-slugify - -Via ``easy_install``: - -.. code:: bash - - $ easy_install python-slugify - -From sources via ``git``: - -.. code:: bash - - $ git clone http://github.com/un33k/python-slugify - $ cd python-slugify - $ python setup.py install - -From sources: - -.. code:: bash - - $ wget https://github.com/un33k/python-slugify/zipball/master - # unzip the downloaded file - # cd into python-slugify-* directory - $ python setup.py install - -Note: - -By default *python-slugify* installs **unidecode** (GPL) for its decoding needs. - -Alternatively *python-slugify* can install and use **text-unidecode** (GPL & Perl Artistic) instead. This is done by setting up -an environment variable *SLUGIFY_USES_TEXT_UNIDECODE=yes* prior to installing and/or upgrading `python-slugify`. - -In cases where both **unidecode** and **text-unidecode** are installed, *python-slugify* always defaults to using **unidecode** regardless of the *SLUGIFY_USES_TEXT_UNIDECODE=yes* environment variable. - - -How to use ----------- - -.. code:: python - - from slugify import slugify - - txt = "This is a test ---" - r = slugify(txt) - self.assertEqual(r, "this-is-a-test") - - txt = "___This is a test ---" - r = slugify(txt) - self.assertEqual(r, "this-is-a-test") - - txt = "___This is a test___" - r = slugify(txt) - self.assertEqual(r, "this-is-a-test") - - txt = "This -- is a ## test ---" - r = slugify(txt) - self.assertEqual(r, "this-is-a-test") - - txt = '影師嗎' - r = slugify(txt) - self.assertEqual(r, "ying-shi-ma") - - txt = 'C\'est déjà l\'été.' - r = slugify(txt) - self.assertEqual(r, "c-est-deja-l-ete") - - txt = 'Nín hǎo. Wǒ shì zhōng guó rén' - r = slugify(txt) - self.assertEqual(r, "nin-hao-wo-shi-zhong-guo-ren") - - txt = 'jaja---lol-méméméoo--a' - r = slugify(txt) - self.assertEqual(r, "jaja-lol-mememeoo-a") - - txt = 'Компьютер' - r = slugify(txt) - self.assertEqual(r, "kompiuter") - - txt = 'jaja---lol-méméméoo--a' - r = slugify(txt, max_length=9) - self.assertEqual(r, "jaja-lol") - - txt = 'jaja---lol-méméméoo--a' - r = slugify(txt, max_length=15) - self.assertEqual(r, "jaja-lol-mememe") - - txt = 'jaja---lol-méméméoo--a' - r = slugify(txt, max_length=50) - self.assertEqual(r, "jaja-lol-mememeoo-a") - - txt = 'jaja---lol-méméméoo--a' - r = slugify(txt, max_length=15, word_boundary=True) - self.assertEqual(r, "jaja-lol-a") - - txt = 'jaja---lol-méméméoo--a' - r = slugify(txt, max_length=17, word_boundary=True) - self.assertEqual(r, "jaja-lol-mememeoo") - - txt = 'jaja---lol-méméméoo--a' - r = slugify(txt, max_length=18, word_boundary=True) - self.assertEqual(r, "jaja-lol-mememeoo") - - txt = 'jaja---lol-méméméoo--a' - r = slugify(txt, max_length=19, word_boundary=True) - self.assertEqual(r, "jaja-lol-mememeoo-a") - - txt = 'jaja---lol-méméméoo--a' - r = slugify(txt, max_length=20, word_boundary=True, separator=".") - self.assertEqual(r, "jaja.lol.mememeoo.a") - - txt = 'one two three four five' - r = slugify(txt, max_length=13, word_boundary=True, save_order=True) - self.assertEqual(r, "one-two-three") - - txt = 'one two three four five' - r = slugify(txt, max_length=13, word_boundary=True, save_order=False) - self.assertEqual(r, "one-two-three") - - txt = 'one two three four five' - r = slugify(txt, max_length=12, word_boundary=True, save_order=False) - self.assertEqual(r, "one-two-four") - - txt = 'one two three four five' - r = slugify(txt, max_length=12, word_boundary=True, save_order=True) - self.assertEqual(r, "one-two") - - txt = 'this has a stopword' - r = slugify(txt, stopwords=['stopword']) - self.assertEqual(r, 'this-has-a') - - txt = 'the quick brown fox jumps over the lazy dog' - r = slugify(txt, stopwords=['the']) - self.assertEqual(r, 'quick-brown-fox-jumps-over-lazy-dog') - - txt = 'Foo A FOO B foo C' - r = slugify(txt, stopwords=['foo']) - self.assertEqual(r, 'a-b-c') - - txt = 'Foo A FOO B foo C' - r = slugify(txt, stopwords=['FOO']) - self.assertEqual(r, 'a-b-c') - - txt = 'the quick brown fox jumps over the lazy dog in a hurry' - r = slugify(txt, stopwords=['the', 'in', 'a', 'hurry']) - self.assertEqual(r, 'quick-brown-fox-jumps-over-lazy-dog') - - txt = 'thIs Has a stopword Stopword' - r = slugify(txt, stopwords=['Stopword'], lowercase=False) - self.assertEqual(r, 'thIs-Has-a-stopword') - - txt = 'foo & bar' - r = slugify(txt) - self.assertEqual(r, 'foo-bar') - - txt = "___This is a test___" - regex_pattern = r'[^-a-z0-9_]+' - r = slugify(txt, regex_pattern=regex_pattern) - self.assertEqual(r, "___this-is-a-test___") - - txt = "___This is a test___" - regex_pattern = r'[^-a-z0-9_]+' - r = slugify(txt, separator='_', regex_pattern=regex_pattern) - self.assertNotEqual(r, "_this_is_a_test_") - -For more examples, have a look at the (`TEST`_) file. - -Running the tests ------------------ - -To run the tests against the current environment: - -.. code:: bash - - python test.py - - -License -------- - -Released under a (`MIT`_) license. - -**Note:** - -*python-slugify* relies on thirdparty **API** for decoding unicode strings. This dependency is kept at the public **API** ONLY in -order to ensure that *python-slugify* never becomes a **derivative work** of any other packages. MIT license holds. - - -Version -------- - -X.Y.Z Version - -:: - - `MAJOR` version -- when you make incompatible API changes, - `MINOR` version -- when you add functionality in a backwards-compatible manner, and - `PATCH` version -- when you make backwards-compatible bug fixes. - -.. |status-image| image:: https://secure.travis-ci.org/un33k/python-slugify.png?branch=master - :target: http://travis-ci.org/un33k/python-slugify?branch=master - -.. |version-image| image:: https://img.shields.io/pypi/v/python-slugify.svg - :target: https://pypi.python.org/pypi/python-slugify - -.. |coverage-image| image:: https://coveralls.io/repos/un33k/python-slugify/badge.svg - :target: https://coveralls.io/r/un33k/python-slugify - -.. |download-image| image:: https://img.shields.io/pypi/dm/python-slugify.svg - :target: https://pypi.python.org/pypi/python-slugify - -.. _MIT: https://github.com/un33k/python-slugify/blob/master/LICENSE - -.. _TEST: https://github.com/un33k/python-slugify/blob/master/test.py @@ -7,6 +7,11 @@ import os import sys import codecs +install_requires = [] +try: + import text_unidecode +except ImportError: + install_requires.append('Unidecode>=0.04.16') name = 'python-slugify' package = 'slugify' @@ -15,10 +20,7 @@ url = 'https://github.com/un33k/python-slugify' author = 'Val Neekman' author_email = 'info@neekware.com' license = 'MIT' -if "SLUGIFY_USES_TEXT_UNIDECODE" in os.environ: - install_requires = ['text-unidecode>=1.2'] -else: - install_requires = ['Unidecode>=0.04.16'] + classifiers = [ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', diff --git a/slugify/__init__.py b/slugify/__init__.py index 1a02a3e..81849b9 100644 --- a/slugify/__init__.py +++ b/slugify/__init__.py @@ -3,4 +3,4 @@ from .slugify import * __author__ = 'Val Neekman @ Neekware Inc. [@vneekman]' __description__ = 'A Python slugify application that also handles Unicode' -__version__ = '1.2.6' +__version__ = '2.0.0' diff --git a/slugify/slugify.py b/slugify/slugify.py index 192bbd3..8569233 100644 --- a/slugify/slugify.py +++ b/slugify/slugify.py @@ -21,14 +21,14 @@ except ImportError: __all__ = ['slugify', 'smart_truncate'] -CHAR_ENTITY_PATTERN = re.compile('&(%s);' % '|'.join(name2codepoint)) -DECIMAL_PATTERN = re.compile('&#(\d+);') -HEX_PATTERN = re.compile('&#x([\da-fA-F]+);') +CHAR_ENTITY_PATTERN = re.compile(r'&(%s);' % '|'.join(name2codepoint)) +DECIMAL_PATTERN = re.compile(r'&#(\d+);') +HEX_PATTERN = re.compile(r'&#x([\da-fA-F]+);') QUOTE_PATTERN = re.compile(r'[\']+') ALLOWED_CHARS_PATTERN = re.compile(r'[^-a-z0-9]+') ALLOWED_CHARS_PATTERN_WITH_UPPERCASE = re.compile(r'[^-a-zA-Z0-9]+') -DUPLICATE_DASH_PATTERN = re.compile('-{2,}') -NUMBERS_PATTERN = re.compile('(?<=\d),(?=\d)') +DUPLICATE_DASH_PATTERN = re.compile(r'-{2,}') +NUMBERS_PATTERN = re.compile(r'(?<=\d),(?=\d)') DEFAULT_SEPARATOR = '-' |