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 <[email protected]>
+
+- 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: [email protected]
+Author: Stuart Colville
+Maintainer: Pat Pannuto
+Maintainer-email: [email protected]
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 = [email protected]
+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="[email protected]",
- 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.
[email protected]("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: [email protected]
+Author: Stuart Colville
+Maintainer: Pat Pannuto
+Maintainer-email: [email protected]
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}