# caseutil ⇄ 🐍🐫🍢
> Case conversion and verification for Python: snake_case, camelCase, kebab-case, etc.
[![versions](https://img.shields.io/pypi/pyversions/caseutil.svg)](https://pypi.org/project/caseutil)
[![pypi](https://img.shields.io/pypi/v/caseutil.svg#v0.7.0)](https://pypi.python.org/pypi/caseutil)
[![Tests](https://raw.githubusercontent.com/makukha/caseutil/v0.7.0/docs/badge/tests.svg)](https://github.com/makukha/caseutil)
[![Coverage](https://raw.githubusercontent.com/makukha/caseutil/v0.7.0/docs/badge/coverage.svg)](https://github.com/makukha/caseutil)
[![PyPI - Downloads](https://img.shields.io/pypi/dw/caseutil)](https://pypistats.org/packages/caseutil)
[![license](https://img.shields.io/github/license/makukha/caseutil.svg)](https://github.com/makukha/caseutil/blob/main/LICENSE)
[![Documentation Status](https://readthedocs.org/projects/caseutil/badge/?version=latest)](https://caseutil.readthedocs.io/en/latest/?badge=latest)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9342/badge)](https://www.bestpractices.dev/projects/9342)
## Features
* Verify and convert between most popular cases
* Custom separators: `'foo.bar.baz'`, `'foo/bar/baz'`
* Case detection
* Command line utility `caseutil`
* Pure Python 2.7 to 3.14+
* No dependencies
* 100% test coverage
### Supported cases
| Case | Verify | Convert |
|---------------|---------------|---------------|
| snake_case | `is_snake` | `to_snake` |
| Ada_Case | `is_ada` | `to_ada` |
| CONST_CASE | `is_const` | `to_const` |
| camelCase | `is_camel` | `to_camel` |
| PascalCase | `is_pascal` | `to_pascal` |
| kebab-case | `is_kebab` | `to_kebab` |
| Train-Case | `is_train` | `to_train` |
| COBOL-CASE | `is_cobol` | `to_cobol` |
| lower case | `is_lower` | `to_lower` |
| UPPER CASE | `is_upper` | `to_upper` |
| Title Case | `is_title` | `to_title` |
| Sentence case | `is_sentence` | `to_sentence` |
For more details about cases and their relations, see [Cases classification](https://caseutil.readthedocs.io/en/latest/classification/).
## Installation
```shell
$ pip install caseutil
```
## Command line
```shell
$ caseutil -c const "hi there"
HI_THERE
```
Invoke as Python module:
```shell
$ python -m caseutil -c const "hi there"
HI_THERE
```
When reading from stdin, each line is processed separately:
```shell
$ echo "hi_there\nsee you" | python -m caseutil -c camel
hiThere
seeYou
```
## Simple usage
```doctest
>>> from caseutil import *
>>> is_snake('Foo bar-baz')
False
>>> to_snake('Foo bar-baz')
'foo_bar_baz'
```
## Advanced usage
### Cases enum
All supported cases are gathered in `Case` enum:
```python
class Case(StrEnum):
ADA = 'ada'
CAMEL = 'camel'
COBOL = 'cobol'
CONST = 'const'
KEBAB = 'kebab'
LOWER = 'lower'
PASCAL = 'pascal'
SENTENCE = 'sentence'
SNAKE = 'snake'
TITLE = 'title'
TRAIN = 'train'
UPPER = 'upper'
```
### Universal operations
Use functions `is_case()` and `to_case()` to deal with any supported case:
```doctest
>>> is_case(Case.CAMEL, 'myVarName')
True
>>> to_case(Case.CONST, 'myVarName')
'MY_VAR_NAME'
```
### Cases detection
Use `get_cases()` function to determine case (or cases, if [ambiguous](https://caseutil.readthedocs.io/en/latest/classification/#ambiguity)):
```doctest
>>> get_cases('fooBar')
('camel',)
>>> get_cases('My var-name') # mixed case
()
>>> get_cases('Title')
('ada', 'pascal', 'sentence', 'title', 'train')
```
### Custom separators
Use `words()` function:
```doctest
>>> '/'.join(words(to_lower('myVarName')))
'my/var/name'
>>> '.'.join(words('myVarName'))
'my.Var.Name'
```
### Tokenization
Word separators are non-word characters including underscore, and places where text case is changed from lower to upper. Digits are not treated as separators. For more details, see [Tokenization rules](https://caseutil.readthedocs.io/en/latest/tokenize/).
```doctest
>>> words('!some_reallyMESsy text--wit4Digits.3VeryWh3re--')
['some', 'really', 'ME', 'Ssy', 'text', 'wit4', 'Digits', '3Very', 'Wh3re']
```
### Unicode support
Only ASCII names are supported. Unicode support is planned.
## Development
This project requires [Docker](https://www.docker.com).
```shell
git clone https://github.com/makukha/caseutil.git
cd caseutil
task dev
```
```shell
root@caseutil:/project# task lint
root@caseutil:/project# task format
root@caseutil:/project# task test
```
## Contributing
See [Contributing](.github/CONTRIBUTING.md) guidelines.
## Authors
* [Michael Makukha](https://github.com/makukha)
## License
[MIT License](https://github.com/makukha/caseutil/blob/main/LICENSE)
Raw data
{
"_id": null,
"home_page": null,
"name": "caseutil",
"maintainer": null,
"docs_url": null,
"requires_python": "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7",
"maintainer_email": null,
"keywords": "case, convert, case converter, string case, text case, text case converter, camel case, pascal case, snake case, kebab case, screaming snake case",
"author": "Michael Makukha",
"author_email": "Michael Makukha <m.makukha@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/60/00/033034c5f28aa02b7dcac2b6bda827d1e2cef89e183845c3f615ca797537/caseutil-0.7.0.tar.gz",
"platform": null,
"description": "# caseutil \u21c4 \ud83d\udc0d\ud83d\udc2b\ud83c\udf62\n> Case conversion and verification for Python: snake_case, camelCase, kebab-case, etc.\n\n[![versions](https://img.shields.io/pypi/pyversions/caseutil.svg)](https://pypi.org/project/caseutil) \n[![pypi](https://img.shields.io/pypi/v/caseutil.svg#v0.7.0)](https://pypi.python.org/pypi/caseutil)\n[![Tests](https://raw.githubusercontent.com/makukha/caseutil/v0.7.0/docs/badge/tests.svg)](https://github.com/makukha/caseutil)\n[![Coverage](https://raw.githubusercontent.com/makukha/caseutil/v0.7.0/docs/badge/coverage.svg)](https://github.com/makukha/caseutil)\n[![PyPI - Downloads](https://img.shields.io/pypi/dw/caseutil)](https://pypistats.org/packages/caseutil) \n[![license](https://img.shields.io/github/license/makukha/caseutil.svg)](https://github.com/makukha/caseutil/blob/main/LICENSE)\n[![Documentation Status](https://readthedocs.org/projects/caseutil/badge/?version=latest)](https://caseutil.readthedocs.io/en/latest/?badge=latest)\n[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9342/badge)](https://www.bestpractices.dev/projects/9342)\n\n## Features\n\n* Verify and convert between most popular cases\n* Custom separators: `'foo.bar.baz'`, `'foo/bar/baz'`\n* Case detection\n* Command line utility `caseutil`\n* Pure Python 2.7 to 3.14+\n* No dependencies\n* 100% test coverage\n\n### Supported cases\n\n| Case | Verify | Convert |\n|---------------|---------------|---------------|\n| snake_case | `is_snake` | `to_snake` |\n| Ada_Case | `is_ada` | `to_ada` |\n| CONST_CASE | `is_const` | `to_const` |\n| camelCase | `is_camel` | `to_camel` |\n| PascalCase | `is_pascal` | `to_pascal` |\n| kebab-case | `is_kebab` | `to_kebab` |\n| Train-Case | `is_train` | `to_train` |\n| COBOL-CASE | `is_cobol` | `to_cobol` |\n| lower case | `is_lower` | `to_lower` |\n| UPPER CASE | `is_upper` | `to_upper` |\n| Title Case | `is_title` | `to_title` |\n| Sentence case | `is_sentence` | `to_sentence` |\n\nFor more details about cases and their relations, see [Cases classification](https://caseutil.readthedocs.io/en/latest/classification/).\n\n## Installation\n\n```shell\n$ pip install caseutil\n```\n\n## Command line\n\n```shell\n$ caseutil -c const \"hi there\"\nHI_THERE\n```\n\nInvoke as Python module:\n```shell\n$ python -m caseutil -c const \"hi there\"\nHI_THERE\n```\n\nWhen reading from stdin, each line is processed separately:\n```shell\n$ echo \"hi_there\\nsee you\" | python -m caseutil -c camel\nhiThere\nseeYou\n```\n\n## Simple usage\n\n```doctest\n>>> from caseutil import *\n\n>>> is_snake('Foo bar-baz')\nFalse\n\n>>> to_snake('Foo bar-baz')\n'foo_bar_baz'\n```\n\n## Advanced usage\n\n### Cases enum\n\nAll supported cases are gathered in `Case` enum:\n```python\nclass Case(StrEnum):\n ADA = 'ada'\n CAMEL = 'camel'\n COBOL = 'cobol'\n CONST = 'const'\n KEBAB = 'kebab'\n LOWER = 'lower'\n PASCAL = 'pascal'\n SENTENCE = 'sentence'\n SNAKE = 'snake'\n TITLE = 'title'\n TRAIN = 'train'\n UPPER = 'upper'\n```\n\n### Universal operations\n\nUse functions `is_case()` and `to_case()` to deal with any supported case:\n\n```doctest\n>>> is_case(Case.CAMEL, 'myVarName')\nTrue\n>>> to_case(Case.CONST, 'myVarName')\n'MY_VAR_NAME'\n```\n\n### Cases detection\n\nUse `get_cases()` function to determine case (or cases, if [ambiguous](https://caseutil.readthedocs.io/en/latest/classification/#ambiguity)):\n\n```doctest\n>>> get_cases('fooBar')\n('camel',)\n>>> get_cases('My var-name') # mixed case\n()\n>>> get_cases('Title')\n('ada', 'pascal', 'sentence', 'title', 'train')\n```\n\n### Custom separators\n\nUse `words()` function:\n\n```doctest\n>>> '/'.join(words(to_lower('myVarName')))\n'my/var/name'\n>>> '.'.join(words('myVarName'))\n'my.Var.Name'\n```\n\n### Tokenization\n\nWord separators are non-word characters including underscore, and places where text case is changed from lower to upper. Digits are not treated as separators. For more details, see [Tokenization rules](https://caseutil.readthedocs.io/en/latest/tokenize/).\n\n```doctest\n>>> words('!some_reallyMESsy text--wit4Digits.3VeryWh3re--')\n['some', 'really', 'ME', 'Ssy', 'text', 'wit4', 'Digits', '3Very', 'Wh3re']\n```\n\n### Unicode support\n\nOnly ASCII names are supported. Unicode support is planned.\n\n## Development\n\nThis project requires [Docker](https://www.docker.com).\n\n```shell\ngit clone https://github.com/makukha/caseutil.git\ncd caseutil\ntask dev\n```\n\n```shell\nroot@caseutil:/project# task lint\nroot@caseutil:/project# task format\nroot@caseutil:/project# task test\n```\n\n## Contributing\n\nSee [Contributing](.github/CONTRIBUTING.md) guidelines.\n\n## Authors\n\n* [Michael Makukha](https://github.com/makukha)\n\n## License\n\n[MIT License](https://github.com/makukha/caseutil/blob/main/LICENSE)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Case convert and verify for Python: snake_case, camelCase, kebab-case, and more.",
"version": "0.7.0",
"project_urls": {
"Changelog": "https://github.com/makukha/caseutil/releases",
"Documentation": "https://caseutil.readthedocs.io",
"Issues": "https://github.com/makukha/caseutil/issues",
"Repository": "https://github.com/makukha/caseutil"
},
"split_keywords": [
"case",
" convert",
" case converter",
" string case",
" text case",
" text case converter",
" camel case",
" pascal case",
" snake case",
" kebab case",
" screaming snake case"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "4d21daf27db01eb6fd6d603637fe5b974711c382150d7dc44c631431ef138c6c",
"md5": "efdcaf6822e92f2b3501ec75e87d1963",
"sha256": "87899060d17b4c43ea4ce876d867372cbf38650bc925cbb47d22e5380c4075b9"
},
"downloads": -1,
"filename": "caseutil-0.7.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "efdcaf6822e92f2b3501ec75e87d1963",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7",
"size": 7185,
"upload_time": "2024-11-26T07:37:06",
"upload_time_iso_8601": "2024-11-26T07:37:06.910177Z",
"url": "https://files.pythonhosted.org/packages/4d/21/daf27db01eb6fd6d603637fe5b974711c382150d7dc44c631431ef138c6c/caseutil-0.7.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "6000033034c5f28aa02b7dcac2b6bda827d1e2cef89e183845c3f615ca797537",
"md5": "aa0091b778e8421b24707d1154bb1684",
"sha256": "c61a4c96cbd334cde2e682f76d47ec6bc8a77f5283af7f36ca51495bc0940763"
},
"downloads": -1,
"filename": "caseutil-0.7.0.tar.gz",
"has_sig": false,
"md5_digest": "aa0091b778e8421b24707d1154bb1684",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7",
"size": 8793,
"upload_time": "2024-11-26T07:37:08",
"upload_time_iso_8601": "2024-11-26T07:37:08.637190Z",
"url": "https://files.pythonhosted.org/packages/60/00/033034c5f28aa02b7dcac2b6bda827d1e2cef89e183845c3f615ca797537/caseutil-0.7.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-26 07:37:08",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "makukha",
"github_project": "caseutil",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"tox": true,
"lcname": "caseutil"
}