Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-titlecase for 
openSUSE:Factory checked in at 2022-10-12 18:24:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-titlecase (Old)
 and      /work/SRC/openSUSE:Factory/.python-titlecase.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-titlecase"

Wed Oct 12 18:24:30 2022 rev:6 rq:1009881 version:2.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-titlecase/python-titlecase.changes        
2021-01-13 18:36:28.150349429 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-titlecase.new.2275/python-titlecase.changes  
    2022-10-12 18:26:06.361876509 +0200
@@ -1,0 +2,8 @@
+Tue Oct 11 16:00:24 UTC 2022 - Yogalakshmi Arunachalam <yarunacha...@suse.com>
+
+- Update to version 2.4 
+  * Add `preserve_blank_lines` option (#88)
+  * Add Py3.10, Drop Py3.6
+  * Update unit testing framework
+
+-------------------------------------------------------------------

Old:
----
  titlecase-1.1.1.tar.gz

New:
----
  titlecase-2.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-titlecase.spec ++++++
--- /var/tmp/diff_new_pack.XtCccK/_old  2022-10-12 18:26:06.809877628 +0200
+++ /var/tmp/diff_new_pack.XtCccK/_new  2022-10-12 18:26:06.813877638 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-titlecase
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-titlecase
-Version:        1.1.1
+Version:        2.4
 Release:        0
 Summary:        Python library to capitalize strings
 License:        MIT
@@ -31,7 +31,7 @@
 BuildRequires:  python-rpm-macros
 Requires:       python-regex >= 2020.4.4
 Requires(post): update-alternatives
-Requires(postun): update-alternatives
+Requires(postun):update-alternatives
 BuildArch:      noarch
 # SECTION test requirements
 BuildRequires:  %{python_module pytest}

++++++ titlecase-1.1.1.tar.gz -> titlecase-2.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/.github/workflows/ci.yml 
new/titlecase-2.4/.github/workflows/ci.yml
--- old/titlecase-1.1.1/.github/workflows/ci.yml        1970-01-01 
01:00:00.000000000 +0100
+++ new/titlecase-2.4/.github/workflows/ci.yml  2022-08-09 10:57:43.000000000 
+0200
@@ -0,0 +1,44 @@
+name: ci
+
+on: [pull_request, push]
+
+jobs:
+  build-with-required-deps:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, macos-latest, windows-latest]
+        python-version: ['3.7', '3.8', '3.9', '3.10']
+    steps:
+      - uses: actions/checkout@v2
+      - name: Setup Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Install
+        run: python setup.py install
+      - name: Tests
+        run: |
+          python -m unittest
+
+  build-with-optional-deps:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, macos-latest, windows-latest]
+        python-version: ['3.7', '3.8', '3.9', '3.10']
+    steps:
+      - uses: actions/checkout@v2
+      - name: Setup Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Install with optional dependencies
+        run: |
+          pip install regex
+          python setup.py install
+      - name: Tests
+        run: |
+          python -m unittest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/.github/workflows/coverage.yml 
new/titlecase-2.4/.github/workflows/coverage.yml
--- old/titlecase-1.1.1/.github/workflows/coverage.yml  1970-01-01 
01:00:00.000000000 +0100
+++ new/titlecase-2.4/.github/workflows/coverage.yml    2022-08-09 
10:57:43.000000000 +0200
@@ -0,0 +1,24 @@
+name: CodeCov
+on: [push, pull_request]
+jobs:
+  codecov-build-with-regex:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v2
+      with:
+        fetch-depth: '2'
+
+    - name: Setup Python
+      uses: actions/setup-python@master
+      with:
+        python-version: '3.x'
+    - name: Install Dependencies
+      run: |
+        pip install regex
+        python setup.py install
+    - name: Generate Coverage Report
+      run: |
+        pip install coverage
+        coverage run -m unittest
+    - name: Upload Coverage to Codecov
+      uses: codecov/codecov-action@v2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/.gitignore 
new/titlecase-2.4/.gitignore
--- old/titlecase-1.1.1/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/titlecase-2.4/.gitignore        2016-03-07 18:28:08.000000000 +0100
@@ -0,0 +1,11 @@
+.eggs
+.coverage
+.tox
+build
+dist
+temp
+titlecase.egg-info
+*.swp
+*.swo
+*.pyc
+*$py.class
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/AUTHORS.rst 
new/titlecase-2.4/AUTHORS.rst
--- old/titlecase-1.1.1/AUTHORS.rst     1970-01-01 01:00:00.000000000 +0100
+++ new/titlecase-2.4/AUTHORS.rst       2021-07-01 19:27:34.000000000 +0200
@@ -0,0 +1,8 @@
+************
+Contributors
+************
+
+* John Gruber
+* Stuart Colville
+* Pat Pannuto
+* Sam Brockie
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/LICENSE.txt 
new/titlecase-2.4/LICENSE.txt
--- old/titlecase-1.1.1/LICENSE.txt     1970-01-01 01:00:00.000000000 +0100
+++ new/titlecase-2.4/LICENSE.txt       2021-07-01 19:27:34.000000000 +0200
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2021 Patrick William Pannuto
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/PKG-INFO new/titlecase-2.4/PKG-INFO
--- old/titlecase-1.1.1/PKG-INFO        2020-06-12 19:53:54.000000000 +0200
+++ new/titlecase-2.4/PKG-INFO  2022-08-15 22:09:19.000000000 +0200
@@ -1,139 +1,142 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: titlecase
-Version: 1.1.1
+Version: 2.4
 Summary: Python Port of John Gruber's titlecase.pl
 Home-page: https://github.com/ppannuto/python-titlecase
-Author: Pat Pannuto, Stuart Colville, John Gruber
-Author-email: pat.pannuto+titlec...@gmail.com
+Author: Stuart Colville
+Maintainer: Pat Pannuto
+Maintainer-email: pat.pannuto+titlec...@gmail.com
 License: MIT
-Description: Titlecase
-        =========
-        
-        .. image:: 
https://travis-ci.org/ppannuto/python-titlecase.svg?branch=master
-            :target: https://travis-ci.org/ppannuto/python-titlecase
-        .. 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 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'.
-        
-        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>`__.
-        
-        Issues, updates, pull requests, etc should be directed
-        `to github <https://github.com/ppannuto/python-titlecase>`__.
-        
-        
-        Installation
-        ------------
-        
-        The easiest method is to simply use pip:
-        
-        ::
-        
-            (sudo) pip install titlecase
-        
-        
-        Usage
-        -----
-        
-        Titlecase provides only one function, simply:
-        
-        .. code-block:: python
-        
-            >>> from titlecase import titlecase
-            >>> titlecase('a thing')
-            'A Thing'
-        
-        A callback function may also be supplied, which will be called for 
every word:
-        
-        .. code-block:: python
-        
-            >>> def abbreviations(word, **kwargs):
-            ...   if word.upper() in ('TCP', 'UDP'):
-            ...     return word.upper()
-            ...
-            >>> titlecase.titlecase('a simple tcp and udp wrapper', 
callback=abbreviations)
-            'A Simple TCP and UDP Wrapper'
-        
-        The callback function is supplied with an ``all_caps`` keyword 
argument, indicating
-        whether the entire line of text was entirely capitalized. Returning 
``None`` from
-        the callback function will allow titlecase to process the word as 
normal.
-        
-        
-        Command Line Usage
-        ------------------
-        
-        Titlecase also provides a command line utility ``titlecase``:
-        
-        ::
-        
-            $ titlecase make me a title
-            Make Me a Title
-            $ echo "Can pipe and/or whatever else" | titlecase
-            Can Pipe and/or Whatever Else
-            # 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
+Project-URL: PyPI, https://pypi.org/project/titlecase/
+Project-URL: conda-forge, https://anaconda.org/conda-forge/titlecase
+Project-URL: Source Code, https://github.com/ppannuto/python-titlecase
+Project-URL: Bug Tracker, https://github.com/ppannuto/python-titlecase/issues
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Intended Audience :: Developers
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 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 :: 3.9
+Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Natural Language :: English
 Classifier: Topic :: Text Processing :: Filters
+Requires-Python: >=3.7
+Description-Content-Type: text/x-rst
+Provides-Extra: regex
+
+Titlecase
+=========
+
+.. image:: 
https://codecov.io/gh/ppannuto/python-titlecase/branch/main/graph/badge.svg?token=J1Li8uhB8q
+    :target: https://codecov.io/gh/ppannuto/python-titlecase
+
+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'.
+
+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/main/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>`__.
+
+Issues, updates, pull requests, etc should be directed
+`to github <https://github.com/ppannuto/python-titlecase>`__.
+
+
+Installation
+------------
+
+The easiest method is to simply use pip:
+
+::
+
+    (sudo) pip install titlecase
+
+
+Usage
+-----
+
+Titlecase provides only one function, simply:
+
+.. code-block:: python
+
+    >>> from titlecase import titlecase
+    >>> titlecase('a thing')
+    'A Thing'
+
+A callback function may also be supplied, which will be called for every word:
+
+.. code-block:: python
+
+    >>> def abbreviations(word, **kwargs):
+    ...   if word.upper() in ('TCP', 'UDP'):
+    ...     return word.upper()
+    ...
+    >>> titlecase.titlecase('a simple tcp and udp wrapper', 
callback=abbreviations)
+    'A Simple TCP and UDP Wrapper'
+
+The callback function is supplied with an ``all_caps`` keyword argument, 
indicating
+whether the entire line of text was entirely capitalized. Returning ``None`` 
from
+the callback function will allow titlecase to process the word as normal.
+
+
+Command Line Usage
+------------------
+
+Titlecase also provides a command line utility ``titlecase``:
+
+::
+
+    $ titlecase make me a title
+    Make Me a Title
+    $ echo "Can pipe and/or whatever else" | titlecase
+    Can Pipe and/or Whatever Else
+    # 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-1.1.1/README.rst 
new/titlecase-2.4/README.rst
--- old/titlecase-1.1.1/README.rst      2020-06-12 18:38:25.000000000 +0200
+++ new/titlecase-2.4/README.rst        2021-07-01 19:42:22.000000000 +0200
@@ -1,10 +1,8 @@
 Titlecase
 =========
 
-.. image:: https://travis-ci.org/ppannuto/python-titlecase.svg?branch=master
-    :target: https://travis-ci.org/ppannuto/python-titlecase
-.. image:: 
https://coveralls.io/repos/github/ppannuto/python-titlecase/badge.svg?branch=master
-    :target: 
https://coveralls.io/github/ppannuto/python-titlecase?branch=master
+.. image:: 
https://codecov.io/gh/ppannuto/python-titlecase/branch/main/graph/badge.svg?token=J1Li8uhB8q
+    :target: https://codecov.io/gh/ppannuto/python-titlecase
 
 This filter changes a given text to Title Caps, and attempts to be clever
 about SMALL words like a/an/the in the input.
@@ -24,7 +22,7 @@
 +------------------+----------------+
 
 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>`__.
+`package test suite 
<https://github.com/ppannuto/python-titlecase/blob/main/titlecase/tests.py>`__.
 
 This library is a resurrection of `Stuart Colville's
 titlecase.py 
<https://muffinresearch.co.uk/titlecasepy-titlecase-in-python/>`__,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/pyproject.toml 
new/titlecase-2.4/pyproject.toml
--- old/titlecase-1.1.1/pyproject.toml  1970-01-01 01:00:00.000000000 +0100
+++ new/titlecase-2.4/pyproject.toml    2021-07-01 19:27:34.000000000 +0200
@@ -0,0 +1,12 @@
+[build-system]
+# The assumed default build requirements from pip are: "setuptools>=40.8.0",
+#     "wheel"
+# See: https://pip.pypa.io/en/stable/reference/pip/#pep-517-and-518-support
+# These are taken from the PyScaffold example
+# See: https://github.com/pyscaffold/pyscaffold-demo
+requires = ["setuptools>=46.1.0", "setuptools_scm[toml]>=5", "wheel"]
+build-backend = "setuptools.build_meta"
+
+[tool.setuptools_scm]
+# See configuration details in https://github.com/pypa/setuptools_scm
+version_scheme = "no-guess-dev"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/setup.cfg new/titlecase-2.4/setup.cfg
--- old/titlecase-1.1.1/setup.cfg       2020-06-12 19:53:54.000000000 +0200
+++ new/titlecase-2.4/setup.cfg 2022-08-15 22:09:19.000000000 +0200
@@ -1,3 +1,57 @@
+[metadata]
+name = titlecase
+author = Stuart Colville
+maintainer = Pat Pannuto
+maintainer_email = pat.pannuto+titlec...@gmail.com
+description = Python Port of John Gruber's titlecase.pl
+long_description = file: README.rst
+long_description_content_type = text/x-rst
+url = https://github.com/ppannuto/python-titlecase
+project_urls = 
+       PyPI = https://pypi.org/project/titlecase/
+       conda-forge = https://anaconda.org/conda-forge/titlecase
+       Source Code = https://github.com/ppannuto/python-titlecase
+       Bug Tracker = https://github.com/ppannuto/python-titlecase/issues
+classifiers = 
+       Development Status :: 5 - Production/Stable
+       Intended Audience :: Developers
+       Operating System :: OS Independent
+       Programming Language :: Python
+       Programming Language :: Python :: 3
+       Programming Language :: Python :: 3.7
+       Programming Language :: Python :: 3.8
+       Programming Language :: Python :: 3.9
+       Programming Language :: Python :: 3.10
+       Programming Language :: Python :: Implementation :: CPython
+       License :: OSI Approved :: MIT License
+       Natural Language :: English
+       Topic :: Text Processing :: Filters
+license = MIT
+license_files = [LICENSE.txt]
+keyword = 
+       string formatting
+
+[options]
+zip_safe = False
+include_package_data = True
+packages = find:
+python_requires = >=3.7
+
+[options.extras_require]
+regex = 
+       regex >=2020.4.4
+
+[options.entry_points]
+console_scripts = 
+       titlecase = titlecase.__init__:cmd
+
+[bdist_wheel]
+universal = 1
+
+[devpi:upload]
+no_vcs = 1
+formats = bdist_wheel
+
 [egg_info]
 tag_build = 
 tag_date = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/setup.py new/titlecase-2.4/setup.py
--- old/titlecase-1.1.1/setup.py        2020-06-12 19:52:37.000000000 +0200
+++ new/titlecase-2.4/setup.py  2021-07-01 19:41:16.000000000 +0200
@@ -1,57 +1,21 @@
-import os
-import sys
+"""Setup file for Titlecase.
 
-from setuptools import setup, find_packages
+This is based on the example from PyScaffold (https://pyscaffold.org/).
+`setup.cfg` is used to configure the project.
 
-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()
+"""
 
-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=read_version('titlecase/__init__.py'),
-    description="Python Port of John Gruber's titlecase.pl",
-    long_description=read_file('README.rst'),
-    classifiers=[
-        "Development Status :: 5 - Production/Stable",
-        "Intended Audience :: Developers",
-        "Operating System :: OS Independent",
-        "Programming Language :: Python",
-        "Programming Language :: Python :: 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",
-        "License :: OSI Approved :: MIT License",
-        "Natural Language :: English",
-        "Topic :: Text Processing :: Filters",
-    ],
-    keywords='string formatting',
-    author="Pat Pannuto, Stuart Colville, John Gruber",
-    author_email="pat.pannuto+titlec...@gmail.com",
-    url="https://github.com/ppannuto/python-titlecase";,
-    license="MIT",
-    packages=find_packages(),
-    include_package_data=True,
-    zip_safe=False,
-    tests_require=['nose>=1.0', 'regex>=2020.4.4'],
-    install_requires=['regex>=2020.4.4'],
-    test_suite="titlecase.tests",
-    entry_points = {
-        'console_scripts': [
-            'titlecase = titlecase.__init__:cmd',
-            ],
-        },
-)
+from setuptools import setup
 
+if __name__ == "__main__":
+    try:
+        setup(use_scm_version={"version_scheme": "no-guess-dev"})
+    except Exception:
+        msg = (
+            "\n\nAn error occurred while building the project, "
+            "please ensure you have the most updated version of setuptools, "
+            "setuptools_scm and wheel with:\n"
+            "   pip install -U setuptools setuptools_scm wheel\n\n"
+        )
+        print(msg)
+        raise
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/titlecase/__init__.py 
new/titlecase-2.4/titlecase/__init__.py
--- old/titlecase-1.1.1/titlecase/__init__.py   2020-06-12 19:52:57.000000000 
+0200
+++ new/titlecase-2.4/titlecase/__init__.py     2022-08-15 22:02:33.000000000 
+0200
@@ -11,28 +11,43 @@
 import logging
 logger = logging.getLogger(__name__)
 import os
-import re
 import string
 import sys
 
-import regex
+try:
+    import regex
+except ImportError:
+    import re as regex
+    REGEX_AVAILABLE = False
+else:
+    REGEX_AVAILABLE = True
 
 __all__ = ['titlecase']
-__version__ = '1.1.1'
+__version__ = '2.4.0'
 
 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 = 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.+)")
+MR_MRS_MS_DR = regex.compile(r"^((m((rs?)|s))|Dr)$", regex.I)
+
+if REGEX_AVAILABLE:
+    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)
+    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})+$")
+else:
+    INLINE_PERIOD = regex.compile(r'[\w][.][\w]', regex.I)
+    UC_ELSEWHERE = regex.compile(r'[%s]*?[a-zA-Z]+[A-Z]+?' % PUNCT)
+    CAPFIRST = regex.compile(r"^[%s]*?([\w])" % PUNCT)
+    APOS_SECOND = regex.compile(r"^[dol]['???][\w]+(?:['s]{2})?$", regex.I)
+    UC_INITIALS = regex.compile(r"^(?:[A-Z]\.|[A-Z]\.[A-Z])+$")
 
 
 class Immutable(object):
@@ -62,28 +77,7 @@
     SUBPHRASE = regex.compile(r'([:.;?!][ ])(%s)' % small)
 
 
-def create_wordlist_filter(path_to_config=None):
-    """
-    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):
+def titlecase(text, callback=None, small_first_last=True, 
preserve_blank_lines=False):
     """
     :param text: Titlecases input text
     :param callback: Callback function that returns the titlecase version of a 
specific word
@@ -99,9 +93,10 @@
     the New York Times Manual of Style, plus 'vs' and 'v'.
 
     """
-    wordlist_filter = create_wordlist_filter(wordlist_file)
-
-    lines = regex.split('[\r\n]+', text)
+    if preserve_blank_lines:
+        lines = regex.split('[\r\n]', text)
+    else:
+        lines = regex.split('[\r\n]+', text)
     processed = []
     for line in lines:
         all_caps = line.upper() == line
@@ -116,12 +111,6 @@
                     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)
@@ -138,7 +127,13 @@
             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, 
True)))
+                continue
+
+            match = MR_MRS_MS_DR.match(word)
+            if match:
+                word = word[0].upper() + word[1:]
+                tc_line.append(word)
                 continue
 
             if INLINE_PERIOD.search(word) or (not all_caps and 
UC_ELSEWHERE.match(word)):
@@ -158,7 +153,7 @@
 
             if '-' in word:
                 hyphenated = map(
-                    lambda t: titlecase(t, callback, small_first_last),
+                    lambda t: titlecase(t, callback, False),
                     word.split('-')
                 )
                 tc_line.append("-".join(hyphenated))
@@ -207,6 +202,30 @@
     return result
 
 
+def create_wordlist_filter_from_file(file_path):
+    '''
+    Load a list of abbreviations from the file with the provided path,
+    reading one abbreviation from each line, and return a callback to
+    be passed to the `titlecase` function for preserving their given
+    canonical capitalization during title-casing.
+    '''
+    if file_path is None:
+        logger.debug('No abbreviations file path given')
+        return lambda word, **kwargs: None
+    file_path_str = str(file_path)
+    if not os.path.isfile(file_path_str):
+        logger.debug('No abbreviations file found at ' + file_path_str)
+        return lambda word, **kwargs: None
+    with open(file_path_str) as f:
+        logger.debug('Reading abbreviations from file ' + file_path_str)
+        abbrevs_gen = (line.strip() for line in f.read().splitlines() if line)
+        abbrevs = {abbr.upper(): abbr for abbr in abbrevs_gen}
+        if logger.isEnabledFor(logging.DEBUG):
+            for abbr in abbrevs.values():
+                logger.debug('Registered abbreviation: ' + abbr)
+        return lambda word, **kwargs: abbrevs.get(word.upper())
+
+
 def cmd():
     '''Handler for command line invocation'''
 
@@ -214,7 +233,7 @@
     # Consume '-f' and '-o' as input/output, allow '-' for stdin/stdout
     # and treat any subsequent arguments as a space separated string to
     # be titlecased (so it still works if people forget quotes)
-    parser = argparse.ArgumentParser()
+    parser = argparse.ArgumentParser(allow_abbrev=False)
     in_group = parser.add_mutually_exclusive_group()
     in_group.add_argument('string', nargs='*', default=[],
             help='String to titlecase')
@@ -224,6 +243,8 @@
             help='File to write titlecased output to')
     parser.add_argument('-w', '--wordlist',
             help='Wordlist for acronyms')
+    parser.add_argument('--preserve-blank-lines', action='store_true',
+            help='Do not skip blank lines in input')
 
     args = parser.parse_args()
 
@@ -249,5 +270,12 @@
         with ifile:
             in_string = ifile.read()
 
+    if args.wordlist is not None:
+        wordlist_file = args.wordlist
+    else:
+        wordlist_file = os.path.join(os.path.expanduser('~'), '.titlecase.txt')
+    wordlist_filter = create_wordlist_filter_from_file(wordlist_file)
+
     with ofile:
-        ofile.write(titlecase(in_string, wordlist_file=args.wordlist))
+        ofile.write(titlecase(in_string, callback=wordlist_filter,
+            preserve_blank_lines=args.preserve_blank_lines))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/titlecase/tests.py 
new/titlecase-2.4/titlecase/tests.py
--- old/titlecase-1.1.1/titlecase/tests.py      2020-06-12 18:38:25.000000000 
+0200
+++ new/titlecase-2.4/titlecase/tests.py        2022-08-09 10:32:57.000000000 
+0200
@@ -3,14 +3,13 @@
 
 """Tests for titlecase"""
 
-from __future__ import print_function, unicode_literals
-
 import os
 import sys
 import tempfile
-sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../'))
+import unittest
 
-from titlecase import titlecase, set_small_word_list
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../'))
+from titlecase import titlecase, set_small_word_list, 
create_wordlist_filter_from_file
 
 
 # (executed by `test_input_output` below)
@@ -32,6 +31,10 @@
         "Dance With Me/Let???s Face the Music and Dance"
     ),
     (
+        "a-b end-to-end two-not-three/three-by-four/five-and",
+        "A-B End-to-End Two-Not-Three/Three-by-Four/Five-And"
+    ),
+    (
         "34th 3rd 2nd",
         "34th 3rd 2nd"
     ),
@@ -247,6 +250,14 @@
         "o'melveny/o'doyle o'Melveny/o'doyle O'melveny/o'doyle 
o'melveny/o'Doyle o'melveny/O'doyle",
         "O'Melveny/O'Doyle O'Melveny/O'Doyle O'Melveny/O'Doyle 
O'Melveny/O'Doyle O'Melveny/O'Doyle",
     ),
+    # These 'Mc' cases aim to ensure more consistent/predictable behavior.
+    # The examples here are somewhat contrived, and are subject to change
+    # if there is a compelling argument for updating their behavior.
+    # See https://github.com/ppannuto/python-titlecase/issues/64
+    (
+        "mccay-mcbut-mcdo mcdonalds/mcby",
+        "McCay-McBut-McDo McDonalds/McBy"
+    ),
     (
         "oblon, spivak, mcclelland, maier & neustadt",
         "Oblon, Spivak, McClelland, Maier & Neustadt",
@@ -291,81 +302,133 @@
         "???? ????",
         "???? ????",
     ),
+    # https://github.com/ppannuto/python-titlecase/pull/67
+    (
+        "Mr mr Mrs Ms Mss Dr dr , Mr. and Mrs. Person",
+        "Mr Mr Mrs Ms MSS Dr Dr , Mr. And Mrs. Person",
+    ),
 )
 
 
-def test_initials_regex():
-    """Test - uppercase initials regex with A.B"""
-    from titlecase import UC_INITIALS
-    assert bool(UC_INITIALS.match('A.B')) is True
+class TestStringSuite(unittest.TestCase):
+    """Generated tests from strings"""
 
+    def test_specific_string(self):
+        for data in TEST_DATA:
+            with self.subTest():
+                self.assertEqual(titlecase(data[0]), data[1])
+
+
+class TestInitialsRegex(unittest.TestCase):
+    def test_initials_regex(self):
+        """Test - uppercase initials regex with A.B"""
+        from titlecase import UC_INITIALS
+        #assert bool(UC_INITIALS.match('A.B')) is True
+        self.assertRegex('A.B', UC_INITIALS)
+
+    def test_initials_regex_2(self):
+        """Test - uppercase initials regex with A.B."""
+        from titlecase import UC_INITIALS
+        #assert bool(UC_INITIALS.match('A.B.')) is True
+        self.assertRegex('A.B.', UC_INITIALS)
+
+    def test_initials_regex_3(self):
+        """Test - uppercase initials regex with ABCD"""
+        from titlecase import UC_INITIALS
+        #assert bool(UC_INITIALS.match('ABCD')) is False
+        self.assertNotRegex('ABCD', UC_INITIALS)
 
-def test_initials_regex_2():
-    """Test - uppercase initials regex with A.B."""
-    from titlecase import UC_INITIALS
-    assert bool(UC_INITIALS.match('A.B.')) is True
 
-
-def test_initials_regex_3():
-    """Test - uppercase initials regex with ABCD"""
-    from titlecase import UC_INITIALS
-    assert bool(UC_INITIALS.match('ABCD')) is False
-
-
-def check_input_matches_expected_output(in_, out):
-    """Function yielded by test generator"""
-    try:
-        assert titlecase(in_) == out
-    except AssertionError:
-        print("{0} != {1}".format(titlecase(in_), out))
-        raise
-
-
-def test_at_and_t():
+class TestSymbols(unittest.TestCase):
+    @staticmethod
     def at_n_t(word, **kwargs):
         if word.upper() == "AT&T":
             return word.upper()
-    print(titlecase("at&t", callback=at_n_t))
-    assert titlecase("at&t", callback=at_n_t) == "AT&T"
-
 
-def test_input_output():
-    """Generated tests"""
-    for data in TEST_DATA:
-        yield check_input_matches_expected_output, data[0], data[1]
+    def test_at_n_t(self):
+        self.assertEqual(titlecase("at&t", callback=TestSymbols.at_n_t), 
"AT&T")
 
 
-def test_callback():
+class TestCallback(unittest.TestCase):
+    @staticmethod
     def abbreviation(word, **kwargs):
         if word.upper() in ('TCP', 'UDP'):
             return word.upper()
-    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'
-
-
-def test_set_small_word_list():
-    assert titlecase('playing the game "words with friends"') == 'Playing the 
Game "Words With Friends"'
-    set_small_word_list('a|an|the|with')
-    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()
+
+    def test_callback(self):
+        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
+        self.assertEqual(titlecase(s),
+                'A Simple TCP and Udp Wrapper')
+        self.assertEqual(titlecase(s, callback=TestCallback.abbreviation),
+                'A Simple TCP and UDP Wrapper')
+        self.assertEqual(titlecase(s.upper(), 
callback=TestCallback.abbreviation),
+                'A Simple TCP and UDP Wrapper')
+        self.assertEqual(titlecase(u'cr??me br??l??e', callback=lambda x, 
**kw: x.upper()),
+                u'CR??ME BR??L??E')
+
+
+# It looks like set_small_word_list uses different regexs that the original
+# setup code path :/. It really should be the case that one could call
+# titlecase.set_small_word_list() and reset to the original behavior (it
+# _really_ should be the case that there aren't all these ugly globals around).
+#
+# It seems that `nose` ran every test in isolation, or just in a different
+# order, so the global state bug wasn't caught before. This should be fixed,
+# but one thingg at a time.
+@unittest.skip("FIXME: Converting to unittest exposed a bug")
+class TestSmallWordList(unittest.TestCase):
+    def test_set_small_word_list(self):
+        self.assertEqual(titlecase('playing the game "words with friends"'),
+                'Playing the Game "Words With Friends"')
+        set_small_word_list('a|an|the|with')
+        self.assertEqual(titlecase('playing the game "words with friends"'),
+                'Playing the Game "Words with Friends"')
+
+
+class TestCustomAbbreviations(unittest.TestCase):
+    def setUp(self):
+        # Do not delete on close, instead do manually for Windows (see #86).
+        self.f = tempfile.NamedTemporaryFile(mode='w', delete=False)
+        self.f.write('UDP\nPPPoE\n')
+        self.f.flush()
+
+    def tearDown(self):
+        self.f.close()  # manually close
+        os.unlink(self.f.name)  # manually delete
+
+    def test_technical_acronyms(self):
         # 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'
+        self.assertEqual(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'
+        self.assertEqual(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'
+        self.assertEqual(titlecase(
+            'sending UDP packets over PPPoE works great',
+            callback=create_wordlist_filter_from_file(self.f.name)),
+            'Sending UDP Packets Over PPPoE Works Great')
+
+
+class TestBlankLines(unittest.TestCase):
+    # Really, it's a bit odd that the default behavior is to delete blank 
lines,
+    # but that's what it was from day one, so we're kind of stuck with that.
+    # This ensures folks can opt-out of that behavior if they want.
+
+    def test_one_blank(self):
+        s = 'Line number one\n\nand Line three\n'
+        self.assertEqual(titlecase(s), 'Line Number One\nAnd Line Three\n')
+        self.assertEqual(titlecase(s, preserve_blank_lines=True), 'Line Number 
One\n\nAnd Line Three\n')
+
+    def test_complex_blanks(self):
+        s = '\n\nLeading blank\n\n\nMulti-blank\n\n\n\n\nTrailing Blank\n\n'
+        self.assertEqual(titlecase(s),
+                '\nLeading Blank\nMulti-Blank\nTrailing Blank\n')
+        self.assertEqual(titlecase(s, preserve_blank_lines=True),
+                '\n\nLeading Blank\n\n\nMulti-Blank\n\n\n\n\nTrailing 
Blank\n\n')
 
 
-if __name__ == "__main__":
-    import nose
-    nose.main()
+if __name__ == '__main__':
+    unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/titlecase.egg-info/PKG-INFO 
new/titlecase-2.4/titlecase.egg-info/PKG-INFO
--- old/titlecase-1.1.1/titlecase.egg-info/PKG-INFO     2020-06-12 
19:53:54.000000000 +0200
+++ new/titlecase-2.4/titlecase.egg-info/PKG-INFO       2022-08-15 
22:09:19.000000000 +0200
@@ -1,139 +1,142 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: titlecase
-Version: 1.1.1
+Version: 2.4
 Summary: Python Port of John Gruber's titlecase.pl
 Home-page: https://github.com/ppannuto/python-titlecase
-Author: Pat Pannuto, Stuart Colville, John Gruber
-Author-email: pat.pannuto+titlec...@gmail.com
+Author: Stuart Colville
+Maintainer: Pat Pannuto
+Maintainer-email: pat.pannuto+titlec...@gmail.com
 License: MIT
-Description: Titlecase
-        =========
-        
-        .. image:: 
https://travis-ci.org/ppannuto/python-titlecase.svg?branch=master
-            :target: https://travis-ci.org/ppannuto/python-titlecase
-        .. 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 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'.
-        
-        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>`__.
-        
-        Issues, updates, pull requests, etc should be directed
-        `to github <https://github.com/ppannuto/python-titlecase>`__.
-        
-        
-        Installation
-        ------------
-        
-        The easiest method is to simply use pip:
-        
-        ::
-        
-            (sudo) pip install titlecase
-        
-        
-        Usage
-        -----
-        
-        Titlecase provides only one function, simply:
-        
-        .. code-block:: python
-        
-            >>> from titlecase import titlecase
-            >>> titlecase('a thing')
-            'A Thing'
-        
-        A callback function may also be supplied, which will be called for 
every word:
-        
-        .. code-block:: python
-        
-            >>> def abbreviations(word, **kwargs):
-            ...   if word.upper() in ('TCP', 'UDP'):
-            ...     return word.upper()
-            ...
-            >>> titlecase.titlecase('a simple tcp and udp wrapper', 
callback=abbreviations)
-            'A Simple TCP and UDP Wrapper'
-        
-        The callback function is supplied with an ``all_caps`` keyword 
argument, indicating
-        whether the entire line of text was entirely capitalized. Returning 
``None`` from
-        the callback function will allow titlecase to process the word as 
normal.
-        
-        
-        Command Line Usage
-        ------------------
-        
-        Titlecase also provides a command line utility ``titlecase``:
-        
-        ::
-        
-            $ titlecase make me a title
-            Make Me a Title
-            $ echo "Can pipe and/or whatever else" | titlecase
-            Can Pipe and/or Whatever Else
-            # 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
+Project-URL: PyPI, https://pypi.org/project/titlecase/
+Project-URL: conda-forge, https://anaconda.org/conda-forge/titlecase
+Project-URL: Source Code, https://github.com/ppannuto/python-titlecase
+Project-URL: Bug Tracker, https://github.com/ppannuto/python-titlecase/issues
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Intended Audience :: Developers
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 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 :: 3.9
+Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Natural Language :: English
 Classifier: Topic :: Text Processing :: Filters
+Requires-Python: >=3.7
+Description-Content-Type: text/x-rst
+Provides-Extra: regex
+
+Titlecase
+=========
+
+.. image:: 
https://codecov.io/gh/ppannuto/python-titlecase/branch/main/graph/badge.svg?token=J1Li8uhB8q
+    :target: https://codecov.io/gh/ppannuto/python-titlecase
+
+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'.
+
+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/main/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>`__.
+
+Issues, updates, pull requests, etc should be directed
+`to github <https://github.com/ppannuto/python-titlecase>`__.
+
+
+Installation
+------------
+
+The easiest method is to simply use pip:
+
+::
+
+    (sudo) pip install titlecase
+
+
+Usage
+-----
+
+Titlecase provides only one function, simply:
+
+.. code-block:: python
+
+    >>> from titlecase import titlecase
+    >>> titlecase('a thing')
+    'A Thing'
+
+A callback function may also be supplied, which will be called for every word:
+
+.. code-block:: python
+
+    >>> def abbreviations(word, **kwargs):
+    ...   if word.upper() in ('TCP', 'UDP'):
+    ...     return word.upper()
+    ...
+    >>> titlecase.titlecase('a simple tcp and udp wrapper', 
callback=abbreviations)
+    'A Simple TCP and UDP Wrapper'
+
+The callback function is supplied with an ``all_caps`` keyword argument, 
indicating
+whether the entire line of text was entirely capitalized. Returning ``None`` 
from
+the callback function will allow titlecase to process the word as normal.
+
+
+Command Line Usage
+------------------
+
+Titlecase also provides a command line utility ``titlecase``:
+
+::
+
+    $ titlecase make me a title
+    Make Me a Title
+    $ echo "Can pipe and/or whatever else" | titlecase
+    Can Pipe and/or Whatever Else
+    # 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-1.1.1/titlecase.egg-info/SOURCES.txt 
new/titlecase-2.4/titlecase.egg-info/SOURCES.txt
--- old/titlecase-1.1.1/titlecase.egg-info/SOURCES.txt  2020-06-12 
19:53:54.000000000 +0200
+++ new/titlecase-2.4/titlecase.egg-info/SOURCES.txt    2022-08-15 
22:09:19.000000000 +0200
@@ -1,5 +1,13 @@
+.gitignore
+AUTHORS.rst
+LICENSE.txt
 README.rst
+pyproject.toml
+setup.cfg
 setup.py
+tox.ini
+.github/workflows/ci.yml
+.github/workflows/coverage.yml
 titlecase/__init__.py
 titlecase/tests.py
 titlecase.egg-info/PKG-INFO
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/titlecase.egg-info/entry_points.txt 
new/titlecase-2.4/titlecase.egg-info/entry_points.txt
--- old/titlecase-1.1.1/titlecase.egg-info/entry_points.txt     2020-06-12 
19:53:54.000000000 +0200
+++ new/titlecase-2.4/titlecase.egg-info/entry_points.txt       2022-08-15 
22:09:19.000000000 +0200
@@ -1,3 +1,2 @@
 [console_scripts]
 titlecase = titlecase.__init__:cmd
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/titlecase.egg-info/requires.txt 
new/titlecase-2.4/titlecase.egg-info/requires.txt
--- old/titlecase-1.1.1/titlecase.egg-info/requires.txt 2020-06-12 
19:53:54.000000000 +0200
+++ new/titlecase-2.4/titlecase.egg-info/requires.txt   2022-08-15 
22:09:19.000000000 +0200
@@ -1 +1,3 @@
+
+[regex]
 regex>=2020.4.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/titlecase-1.1.1/tox.ini new/titlecase-2.4/tox.ini
--- old/titlecase-1.1.1/tox.ini 1970-01-01 01:00:00.000000000 +0100
+++ new/titlecase-2.4/tox.ini   2022-08-09 10:32:57.000000000 +0200
@@ -0,0 +1,23 @@
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = py36, py37, py38, py39, py310
+
+[base]
+deps =
+    coveralls >=1.1
+commands =
+    coverage run -m unittest
+    coveralls
+
+[testenv:re]
+deps =
+    {[base]deps}
+
+[testenv:regex]
+deps =
+    regex >=2020.4.4
+    {[base]deps}

Reply via email to