Hello community,
here is the log from the commit of package python-titlecase for
openSUSE:Factory checked in at 2020-07-26 16:19:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-titlecase (Old)
and /work/SRC/openSUSE:Factory/.python-titlecase.new.3592 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-titlecase"
Sun Jul 26 16:19:02 2020 rev:4 rq:822656 version:1.1.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-titlecase/python-titlecase.changes
2020-05-19 14:48:53.384124037 +0200
+++
/work/SRC/openSUSE:Factory/.python-titlecase.new.3592/python-titlecase.changes
2020-07-26 16:19:50.868836557 +0200
@@ -1,0 +2,16 @@
+Fri Jul 24 08:17:11 UTC 2020 - Marketa Calabkova <[email protected]>
+
+- Update to 1.1.1
+ * This adds support for user-customized wordlists
+ * This adds a new keyword argument to the `titlecase()` method.
+ * This adds environment checks for a wordlist file in the home directory.
+ * This drops Py2k support and add 3.8
+ * #35: Add fancy double quote to punctuation; Thanks @dwaynebailey!
+ * #45: Fix deprecation warning regarding invalid escape sequences. Thanks
@tirkarthi
+ * #46: Add support for titlecasing non-ASCII letters; Thanks @acabal!
+ * #47: Add sphinx documentation to titlecase function; Thanks @1kastner!
+ * #49: Remove closing bracket in parser help text; Thanks @1kastner!
+ * #53: Add table with examples; Thanks @1kastner!
+ * #53: Terms with only consonants should be ALL CAPS; Thanks @Garret-R!
+
+-------------------------------------------------------------------
Old:
----
titlecase-0.12.0.tar.gz
New:
----
titlecase-1.1.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-titlecase.spec ++++++
--- /var/tmp/diff_new_pack.QrcL0b/_old 2020-07-26 16:19:51.324836984 +0200
+++ /var/tmp/diff_new_pack.QrcL0b/_new 2020-07-26 16:19:51.328836988 +0200
@@ -18,16 +18,18 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-titlecase
-Version: 0.12.0
+Version: 1.1.1
Release: 0
Summary: Python library to capitalize strings
License: MIT
Group: Development/Languages/Python
URL: https://github.com/ppannuto/python-titlecase
Source:
https://files.pythonhosted.org/packages/source/t/titlecase/titlecase-%{version}.tar.gz
+BuildRequires: %{python_module regex >= 2020.4.4}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
+Requires: python-regex >= 2020.4.4
Requires(post): update-alternatives
Requires(postun): update-alternatives
BuildArch: noarch
@@ -55,7 +57,7 @@
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%check
-%python_exec setup.py test
+%python_expand nosetests-%{$python_bin_suffix} titlecase.tests
%post
%python_install_alternative titlecase
++++++ titlecase-0.12.0.tar.gz -> titlecase-1.1.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/titlecase-0.12.0/PKG-INFO
new/titlecase-1.1.1/PKG-INFO
--- old/titlecase-0.12.0/PKG-INFO 2017-09-19 18:39:50.000000000 +0200
+++ new/titlecase-1.1.1/PKG-INFO 2020-06-12 19:53:54.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: titlecase
-Version: 0.12.0
+Version: 1.1.1
Summary: Python Port of John Gruber's titlecase.pl
Home-page: https://github.com/ppannuto/python-titlecase
Author: Pat Pannuto, Stuart Colville, John Gruber
@@ -14,13 +14,27 @@
.. image::
https://coveralls.io/repos/github/ppannuto/python-titlecase/badge.svg?branch=master
:target:
https://coveralls.io/github/ppannuto/python-titlecase?branch=master
- This filter changes all words to Title Caps, and attempts to be clever
+ This filter changes a given text to Title Caps, and attempts to be
clever
about SMALL words like a/an/the in the input.
-
The list of "SMALL words" which are not capped comes from the New York
Times Manual of Style, plus some others like 'vs' and 'v'.
- This is a resurrection of `Stuart Colville's
+ The filter employs some heuristics to guess abbreviations that don't
need conversion.
+
+ +------------------+----------------+
+ | Original | Conversion |
+ +==================+================+
+ | this is a test | This Is a Test |
+ +------------------+----------------+
+ | THIS IS A TEST | This Is a Test |
+ +------------------+----------------+
+ | this is a TEST | This Is a TEST |
+ +------------------+----------------+
+
+ More examples and expected behavior for corner cases are available in
the
+ `package test suite
<https://github.com/ppannuto/python-titlecase/blob/master/titlecase/tests.py>`__.
+
+ This library is a resurrection of `Stuart Colville's
titlecase.py
<https://muffinresearch.co.uk/titlecasepy-titlecase-in-python/>`__,
which was in turn a port of `John Gruber's
titlecase.pl <http://daringfireball.net/2008/05/title_case>`__.
@@ -71,7 +85,7 @@
Titlecase also provides a command line utility ``titlecase``:
- .. code-block:: python
+ ::
$ titlecase make me a title
Make Me a Title
@@ -80,22 +94,46 @@
# Or read/write files:
$ titlecase -f infile -o outfile
+ In addition, commonly used acronyms can be kept in a local file
+ at `~/.titlecase.txt`. This file contains one acronym per line.
+ The acronym will be maintained in the title as it is provided.
+ Once there is e.g. one line saying `TCP`, then it will be automatically
+ used when used from the command line.
+
+ ::
+
+ $ titlecase I LOVE TCP
+ I Love TCP
+
+
+ Limitations
+ -----------
+
+ This is a best-effort library that uses regexes to try to do
intelligent
+ things, but will have limitations. For example, it does not have the
contextual
+ awareness to distinguish acronyms from words: us (we) versus US
(United States).
+
+ The regexes and titlecasing rules were written for American English.
While
+ there is basic support for Unicode characters, such that something like
+ "El Niño" will work, it is likely that accents or non-English phrases
will
+ not be handled correctly.
+
+ If anyone has concrete solutions to improve these or other
shortcomings of the
+ library, pull requests are very welcome!
Keywords: string formatting
Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Topic :: Text Processing :: Filters
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/titlecase-0.12.0/README.rst
new/titlecase-1.1.1/README.rst
--- old/titlecase-0.12.0/README.rst 2017-07-14 16:00:10.000000000 +0200
+++ new/titlecase-1.1.1/README.rst 2020-06-12 18:38:25.000000000 +0200
@@ -6,13 +6,27 @@
.. image::
https://coveralls.io/repos/github/ppannuto/python-titlecase/badge.svg?branch=master
:target:
https://coveralls.io/github/ppannuto/python-titlecase?branch=master
-This filter changes all words to Title Caps, and attempts to be clever
+This filter changes a given text to Title Caps, and attempts to be clever
about SMALL words like a/an/the in the input.
-
The list of "SMALL words" which are not capped comes from the New York
Times Manual of Style, plus some others like 'vs' and 'v'.
-This is a resurrection of `Stuart Colville's
+The filter employs some heuristics to guess abbreviations that don't need
conversion.
+
++------------------+----------------+
+| Original | Conversion |
++==================+================+
+| this is a test | This Is a Test |
++------------------+----------------+
+| THIS IS A TEST | This Is a Test |
++------------------+----------------+
+| this is a TEST | This Is a TEST |
++------------------+----------------+
+
+More examples and expected behavior for corner cases are available in the
+`package test suite
<https://github.com/ppannuto/python-titlecase/blob/master/titlecase/tests.py>`__.
+
+This library is a resurrection of `Stuart Colville's
titlecase.py
<https://muffinresearch.co.uk/titlecasepy-titlecase-in-python/>`__,
which was in turn a port of `John Gruber's
titlecase.pl <http://daringfireball.net/2008/05/title_case>`__.
@@ -63,7 +77,7 @@
Titlecase also provides a command line utility ``titlecase``:
-.. code-block:: python
+::
$ titlecase make me a title
Make Me a Title
@@ -72,3 +86,29 @@
# Or read/write files:
$ titlecase -f infile -o outfile
+In addition, commonly used acronyms can be kept in a local file
+at `~/.titlecase.txt`. This file contains one acronym per line.
+The acronym will be maintained in the title as it is provided.
+Once there is e.g. one line saying `TCP`, then it will be automatically
+used when used from the command line.
+
+::
+
+ $ titlecase I LOVE TCP
+ I Love TCP
+
+
+Limitations
+-----------
+
+This is a best-effort library that uses regexes to try to do intelligent
+things, but will have limitations. For example, it does not have the contextual
+awareness to distinguish acronyms from words: us (we) versus US (United
States).
+
+The regexes and titlecasing rules were written for American English. While
+there is basic support for Unicode characters, such that something like
+"El Niño" will work, it is likely that accents or non-English phrases will
+not be handled correctly.
+
+If anyone has concrete solutions to improve these or other shortcomings of the
+library, pull requests are very welcome!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/titlecase-0.12.0/setup.cfg
new/titlecase-1.1.1/setup.cfg
--- old/titlecase-0.12.0/setup.cfg 2017-09-19 18:39:50.000000000 +0200
+++ new/titlecase-1.1.1/setup.cfg 2020-06-12 19:53:54.000000000 +0200
@@ -1,5 +1,4 @@
[egg_info]
tag_build =
tag_date = 0
-tag_svn_revision = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/titlecase-0.12.0/setup.py
new/titlecase-1.1.1/setup.py
--- old/titlecase-0.12.0/setup.py 2017-02-28 08:33:02.000000000 +0100
+++ new/titlecase-1.1.1/setup.py 2020-06-12 19:52:37.000000000 +0200
@@ -3,30 +3,36 @@
from setuptools import setup, find_packages
-def readme():
- with open('README.rst') as f:
+def read_file(rel_path):
+ abs_dir_path = os.path.abspath(os.path.dirname(__file__))
+ abs_path = os.path.join(abs_dir_path, rel_path)
+ with open(abs_path) as f:
return f.read()
-from titlecase import __version__
+def read_version(rel_path):
+ for line in read_file(rel_path).splitlines():
+ if line.startswith('__version__'):
+ delim = '"' if '"' in line else "'"
+ return line.split(delim)[1]
+ else:
+ raise RuntimeError('No version string found')
setup(name='titlecase',
- version=__version__,
+ version=read_version('titlecase/__init__.py'),
description="Python Port of John Gruber's titlecase.pl",
- long_description=readme(),
+ long_description=read_file('README.rst'),
classifiers=[
- "Development Status :: 4 - Beta",
+ "Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: Implementation :: CPython",
- "Programming Language :: Python :: Implementation :: PyPy",
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Topic :: Text Processing :: Filters",
@@ -39,8 +45,8 @@
packages=find_packages(),
include_package_data=True,
zip_safe=False,
- tests_require=['nose'],
- setup_requires=['nose>=1.0'],
+ tests_require=['nose>=1.0', 'regex>=2020.4.4'],
+ install_requires=['regex>=2020.4.4'],
test_suite="titlecase.tests",
entry_points = {
'console_scripts': [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/titlecase-0.12.0/titlecase/__init__.py
new/titlecase-1.1.1/titlecase/__init__.py
--- old/titlecase-0.12.0/titlecase/__init__.py 2017-09-19 18:36:24.000000000
+0200
+++ new/titlecase-1.1.1/titlecase/__init__.py 2020-06-12 19:52:57.000000000
+0200
@@ -7,41 +7,40 @@
License: http://www.opensource.org/licenses/mit-license.php
"""
-from __future__ import unicode_literals
-
import argparse
+import logging
+logger = logging.getLogger(__name__)
+import os
import re
+import string
import sys
+import regex
+
__all__ = ['titlecase']
-__version__ = '0.12.0'
+__version__ = '1.1.1'
-SMALL = 'a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v\.?|via|vs\.?'
-PUNCT = r"""!"#$%&'‘()*+,\-–‒—―./:;?@[\\\]_`{|}~"""
+SMALL = r'a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v\.?|via|vs\.?'
+PUNCT = r"""!"“#$%&'‘()*+,\-–‒—―./:;?@[\\\]_`{|}~"""
-SMALL_WORDS = re.compile(r'^(%s)$' % SMALL, re.I)
-INLINE_PERIOD = re.compile(r'[a-z][.][a-z]', re.I)
-UC_ELSEWHERE = re.compile(r'[%s]*?[a-zA-Z]+[A-Z]+?' % PUNCT)
-CAPFIRST = re.compile(r"^[%s]*?([A-Za-z])" % PUNCT)
-SMALL_FIRST = re.compile(r'^([%s]*)(%s)\b' % (PUNCT, SMALL), re.I)
-SMALL_LAST = re.compile(r'\b(%s)[%s]?$' % (SMALL, PUNCT), re.I)
-SUBPHRASE = re.compile(r'([:.;?!\-–‒—―][ ])(%s)' % SMALL)
-APOS_SECOND = re.compile(r"^[dol]{1}['‘]{1}[a-z]+(?:['s]{2})?$", re.I)
-UC_INITIALS = re.compile(r"^(?:[A-Z]{1}\.{1}|[A-Z]{1}\.{1}[A-Z]{1})+$")
-MAC_MC = re.compile(r"^([Mm]c|MC)(\w.+)")
+SMALL_WORDS = regex.compile(r'^(%s)$' % SMALL, regex.I)
+INLINE_PERIOD = regex.compile(r'[\p{Letter}][.][\p{Letter}]', regex.I)
+UC_ELSEWHERE = regex.compile(r'[%s]*?[\p{Letter}]+[\p{Uppercase_Letter}]+?' %
PUNCT)
+CAPFIRST = regex.compile(r"^[%s]*?([\p{Letter}])" % PUNCT)
+SMALL_FIRST = regex.compile(r'^([%s]*)(%s)\b' % (PUNCT, SMALL), regex.I)
+SMALL_LAST = regex.compile(r'\b(%s)[%s]?$' % (SMALL, PUNCT), regex.I)
+SUBPHRASE = regex.compile(r'([:.;?!\-–‒—―][ ])(%s)' % SMALL)
+APOS_SECOND = regex.compile(r"^[dol]{1}['‘]{1}[\p{Letter}]+(?:['s]{2})?$",
regex.I)
+UC_INITIALS =
regex.compile(r"^(?:[\p{Uppercase_Letter}]{1}\.{1}|[\p{Uppercase_Letter}]{1}\.{1}[\p{Uppercase_Letter}]{1})+$")
+MAC_MC = regex.compile(r"^([Mm]c|MC)(\w.+)")
class Immutable(object):
pass
-
-text_type = unicode if sys.version_info < (3,) else str
-
-
-class ImmutableString(text_type, Immutable):
+class ImmutableString(str, Immutable):
pass
-
class ImmutableBytes(bytes, Immutable):
pass
@@ -57,15 +56,41 @@
global SMALL_FIRST
global SMALL_LAST
global SUBPHRASE
- SMALL_WORDS = re.compile(r'^(%s)$' % small, re.I)
- SMALL_FIRST = re.compile(r'^([%s]*)(%s)\b' % (PUNCT, small), re.I)
- SMALL_LAST = re.compile(r'\b(%s)[%s]?$' % (small, PUNCT), re.I)
- SUBPHRASE = re.compile(r'([:.;?!][ ])(%s)' % small)
+ SMALL_WORDS = regex.compile(r'^(%s)$' % small, regex.I)
+ SMALL_FIRST = regex.compile(r'^([%s]*)(%s)\b' % (PUNCT, small), regex.I)
+ SMALL_LAST = regex.compile(r'\b(%s)[%s]?$' % (small, PUNCT), regex.I)
+ SUBPHRASE = regex.compile(r'([:.;?!][ ])(%s)' % small)
-def titlecase(text, callback=None, small_first_last=True):
+def create_wordlist_filter(path_to_config=None):
"""
- Titlecases input text
+ This function checks for a default list of abbreviations which need to
+ remain as they are (e.g. uppercase only or mixed case).
+ The file is retrieved from ~/.titlecase.txt (platform independent)
+ """
+ if path_to_config is None:
+ path_to_config = os.path.join(os.path.expanduser('~'),
".titlecase.txt")
+ if not os.path.isfile(str(path_to_config)):
+ logger.debug('No config file found at ' + str(path_to_config))
+ return lambda word, **kwargs : None
+ with open(str(path_to_config)) as f:
+ logger.debug('Config file used from ' + str(path_to_config))
+ abbreviations = [abbr.strip() for abbr in f.read().splitlines() if
abbr]
+ abbreviations_capitalized = [abbr.upper() for abbr in abbreviations]
+ for abbr in abbreviations:
+ logger.debug("This acronym will be kept as written here: " + abbr)
+ return lambda word, **kwargs :
(abbreviations[abbreviations_capitalized.index(word.upper())]
+ if word.upper() in
abbreviations_capitalized else None)
+
+
+def titlecase(text, callback=None, small_first_last=True, wordlist_file=None):
+ """
+ :param text: Titlecases input text
+ :param callback: Callback function that returns the titlecase version of a
specific word
+ :param small_first_last: Capitalize small words (e.g. 'A') at the
beginning; disabled when recursing
+ :type text: str
+ :type callback: function
+ :type small_first_last: bool
This filter changes all words to Title Caps, and attempts to be clever
about *un*capitalizing SMALL words like a/an/the in the input.
@@ -74,12 +99,13 @@
the New York Times Manual of Style, plus 'vs' and 'v'.
"""
+ wordlist_filter = create_wordlist_filter(wordlist_file)
- lines = re.split('[\r\n]+', text)
+ lines = regex.split('[\r\n]+', text)
processed = []
for line in lines:
all_caps = line.upper() == line
- words = re.split('[\t ]', line)
+ words = regex.split('[\t ]', line)
tc_line = []
for word in words:
if callback:
@@ -90,6 +116,12 @@
tc_line.append(_mark_immutable(new_word))
continue
+ # If the user has a custom wordlist, defer to that
+ new_word = wordlist_filter(word, all_caps=all_caps)
+ if new_word:
+ tc_line.append(_mark_immutable(new_word))
+ continue
+
if all_caps:
if UC_INITIALS.match(word):
tc_line.append(word)
@@ -106,7 +138,7 @@
match = MAC_MC.match(word)
if match:
tc_line.append("%s%s" % (match.group(1).capitalize(),
-
titlecase(match.group(2),callback,small_first_last)))
+ titlecase(match.group(2), callback,
small_first_last)))
continue
if INLINE_PERIOD.search(word) or (not all_caps and
UC_ELSEWHERE.match(word)):
@@ -126,7 +158,7 @@
if '-' in word:
hyphenated = map(
- lambda t: titlecase(t,callback,small_first_last),
+ lambda t: titlecase(t, callback, small_first_last),
word.split('-')
)
tc_line.append("-".join(hyphenated))
@@ -135,6 +167,17 @@
if all_caps:
word = word.lower()
+
+ # A term with all consonants should be considered an acronym. But
if it's
+ # too short (like "St", don't apply this)
+ CONSONANTS = ''.join(set(string.ascii_lowercase)
+ - {'a', 'e', 'i', 'o', 'u', 'y'})
+ is_all_consonants = regex.search('\A[' + CONSONANTS + ']+\Z', word,
+ flags=regex.IGNORECASE)
+ if is_all_consonants and len(word) > 2:
+ tc_line.append(word.upper())
+ continue
+
# Just a normal word that needs to be capitalized
tc_line.append(CAPFIRST.sub(lambda m: m.group(0).upper(), word))
@@ -159,7 +202,9 @@
processed.append(result)
- return "\n".join(processed)
+ result = "\n".join(processed)
+ logger.debug(result)
+ return result
def cmd():
@@ -176,7 +221,9 @@
in_group.add_argument('-f', '--input-file',
help='File to read from to titlecase')
parser.add_argument('-o', '--output-file',
- help='File to write titlecased output to)')
+ help='File to write titlecased output to')
+ parser.add_argument('-w', '--wordlist',
+ help='Wordlist for acronyms')
args = parser.parse_args()
@@ -203,4 +250,4 @@
in_string = ifile.read()
with ofile:
- ofile.write(titlecase(in_string))
+ ofile.write(titlecase(in_string, wordlist_file=args.wordlist))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/titlecase-0.12.0/titlecase/tests.py
new/titlecase-1.1.1/titlecase/tests.py
--- old/titlecase-0.12.0/titlecase/tests.py 2017-09-19 18:33:57.000000000
+0200
+++ new/titlecase-1.1.1/titlecase/tests.py 2020-06-12 18:38:25.000000000
+0200
@@ -7,10 +7,13 @@
import os
import sys
+import tempfile
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../'))
from titlecase import titlecase, set_small_word_list
+
+# (executed by `test_input_output` below)
TEST_DATA = (
(
"",
@@ -45,6 +48,10 @@
"Apple Deal With AT&T Falls Through"
),
(
+ "Words with all consonants like cnn are acronyms",
+ "Words With All Consonants Like CNN Are Acronyms"
+ ),
+ (
"this v that",
"This v That"
),
@@ -259,7 +266,31 @@
(
"‘QUOTE’ A GREAT",
"‘Quote’ a Great",
- )
+ ),
+ (
+ "“YOUNG AND RESTLESS”",
+ "“Young and Restless”",
+ ),
+ (
+ "EL NIÑO A ARRIVÉ HIER",
+ "El Niño a Arrivé Hier",
+ ),
+ (
+ "YEA NO",
+ "Yea No",
+ ),
+ (
+ "ÝÆ ÑØ",
+ "Ýæ Ñø",
+ ),
+ (
+ "yea no",
+ "Yea No",
+ ),
+ (
+ "ýæ ñø",
+ "Ýæ Ñø",
+ ),
)
@@ -309,7 +340,9 @@
if word.upper() in ('TCP', 'UDP'):
return word.upper()
s = 'a simple tcp and udp wrapper'
- assert titlecase(s) == 'A Simple Tcp and Udp Wrapper'
+ # Note: this library is able to guess that all-consonant words are
acronyms, so TCP
+ # works naturally, but others will require the custom list
+ assert titlecase(s) == 'A Simple TCP and Udp Wrapper'
assert titlecase(s, callback=abbreviation) == 'A Simple TCP and UDP
Wrapper'
assert titlecase(s.upper(), callback=abbreviation) == 'A Simple TCP and
UDP Wrapper'
assert titlecase(u'crème brûlée', callback=lambda x, **kw: x.upper()) ==
u'CRÈME BRÛLÉE'
@@ -321,6 +354,18 @@
assert titlecase('playing the game "words with friends"') == 'Playing the
Game "Words with Friends"'
+def test_custom_abbreviations():
+ with tempfile.NamedTemporaryFile(mode='w') as f:
+ f.write('UDP\nPPPoE\n')
+ f.flush()
+ # This works without a wordlist, because it begins mixed case
+ assert titlecase('sending UDP packets over PPPoE works great') ==
'Sending UDP Packets Over PPPoE Works Great'
+ # Without a wordlist, this will do the "wrong" thing for the context
+ assert titlecase('SENDING UDP PACKETS OVER PPPOE WORKS GREAT') ==
'Sending Udp Packets Over Pppoe Works Great'
+ # A wordlist can provide custom acronyms
+ assert titlecase('sending UDP packets over PPPoE works great',
wordlist_file=f.name) == 'Sending UDP Packets Over PPPoE Works Great'
+
+
if __name__ == "__main__":
import nose
nose.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/titlecase-0.12.0/titlecase.egg-info/PKG-INFO
new/titlecase-1.1.1/titlecase.egg-info/PKG-INFO
--- old/titlecase-0.12.0/titlecase.egg-info/PKG-INFO 2017-09-19
18:39:50.000000000 +0200
+++ new/titlecase-1.1.1/titlecase.egg-info/PKG-INFO 2020-06-12
19:53:54.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: titlecase
-Version: 0.12.0
+Version: 1.1.1
Summary: Python Port of John Gruber's titlecase.pl
Home-page: https://github.com/ppannuto/python-titlecase
Author: Pat Pannuto, Stuart Colville, John Gruber
@@ -14,13 +14,27 @@
.. image::
https://coveralls.io/repos/github/ppannuto/python-titlecase/badge.svg?branch=master
:target:
https://coveralls.io/github/ppannuto/python-titlecase?branch=master
- This filter changes all words to Title Caps, and attempts to be clever
+ This filter changes a given text to Title Caps, and attempts to be
clever
about SMALL words like a/an/the in the input.
-
The list of "SMALL words" which are not capped comes from the New York
Times Manual of Style, plus some others like 'vs' and 'v'.
- This is a resurrection of `Stuart Colville's
+ The filter employs some heuristics to guess abbreviations that don't
need conversion.
+
+ +------------------+----------------+
+ | Original | Conversion |
+ +==================+================+
+ | this is a test | This Is a Test |
+ +------------------+----------------+
+ | THIS IS A TEST | This Is a Test |
+ +------------------+----------------+
+ | this is a TEST | This Is a TEST |
+ +------------------+----------------+
+
+ More examples and expected behavior for corner cases are available in
the
+ `package test suite
<https://github.com/ppannuto/python-titlecase/blob/master/titlecase/tests.py>`__.
+
+ This library is a resurrection of `Stuart Colville's
titlecase.py
<https://muffinresearch.co.uk/titlecasepy-titlecase-in-python/>`__,
which was in turn a port of `John Gruber's
titlecase.pl <http://daringfireball.net/2008/05/title_case>`__.
@@ -71,7 +85,7 @@
Titlecase also provides a command line utility ``titlecase``:
- .. code-block:: python
+ ::
$ titlecase make me a title
Make Me a Title
@@ -80,22 +94,46 @@
# Or read/write files:
$ titlecase -f infile -o outfile
+ In addition, commonly used acronyms can be kept in a local file
+ at `~/.titlecase.txt`. This file contains one acronym per line.
+ The acronym will be maintained in the title as it is provided.
+ Once there is e.g. one line saying `TCP`, then it will be automatically
+ used when used from the command line.
+
+ ::
+
+ $ titlecase I LOVE TCP
+ I Love TCP
+
+
+ Limitations
+ -----------
+
+ This is a best-effort library that uses regexes to try to do
intelligent
+ things, but will have limitations. For example, it does not have the
contextual
+ awareness to distinguish acronyms from words: us (we) versus US
(United States).
+
+ The regexes and titlecasing rules were written for American English.
While
+ there is basic support for Unicode characters, such that something like
+ "El Niño" will work, it is likely that accents or non-English phrases
will
+ not be handled correctly.
+
+ If anyone has concrete solutions to improve these or other
shortcomings of the
+ library, pull requests are very welcome!
Keywords: string formatting
Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Topic :: Text Processing :: Filters
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/titlecase-0.12.0/titlecase.egg-info/SOURCES.txt
new/titlecase-1.1.1/titlecase.egg-info/SOURCES.txt
--- old/titlecase-0.12.0/titlecase.egg-info/SOURCES.txt 2017-09-19
18:39:50.000000000 +0200
+++ new/titlecase-1.1.1/titlecase.egg-info/SOURCES.txt 2020-06-12
19:53:54.000000000 +0200
@@ -7,4 +7,5 @@
titlecase.egg-info/dependency_links.txt
titlecase.egg-info/entry_points.txt
titlecase.egg-info/not-zip-safe
+titlecase.egg-info/requires.txt
titlecase.egg-info/top_level.txt
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/titlecase-0.12.0/titlecase.egg-info/requires.txt
new/titlecase-1.1.1/titlecase.egg-info/requires.txt
--- old/titlecase-0.12.0/titlecase.egg-info/requires.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/titlecase-1.1.1/titlecase.egg-info/requires.txt 2020-06-12
19:53:54.000000000 +0200
@@ -0,0 +1 @@
+regex>=2020.4.4