{"id":15008725,"url":"https://github.com/makukha/caseutil","last_synced_at":"2025-04-09T16:22:54.748Z","repository":{"id":250455928,"uuid":"834496132","full_name":"makukha/caseutil","owner":"makukha","description":"Case convert and verify for Python: snake_case, camelCase, kebab-case, and more.","archived":false,"fork":false,"pushed_at":"2025-02-13T18:25:30.000Z","size":161,"stargazers_count":3,"open_issues_count":5,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-23T18:38:49.453Z","etag":null,"topics":["case","case-converter","cli","python","python2","python3","string-case","text-case","text-case-converter"],"latest_commit_sha":null,"homepage":"http://caseutil.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/makukha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":".github/SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-27T12:50:24.000Z","updated_at":"2025-02-13T18:26:38.000Z","dependencies_parsed_at":"2024-07-29T15:27:02.002Z","dependency_job_id":"9afc18bc-5860-4522-8850-beecefc3d570","html_url":"https://github.com/makukha/caseutil","commit_stats":{"total_commits":31,"total_committers":1,"mean_commits":31.0,"dds":0.0,"last_synced_commit":"7d882a6e0a9952eff169e5c4ef495ef34c3f6322"},"previous_names":["makukha/namecase","makukha/caseutil"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/makukha%2Fcaseutil","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/makukha%2Fcaseutil/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/makukha%2Fcaseutil/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/makukha%2Fcaseutil/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/makukha","download_url":"https://codeload.github.com/makukha/caseutil/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248065690,"owners_count":21041945,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["case","case-converter","cli","python","python2","python3","string-case","text-case","text-case-converter"],"created_at":"2024-09-24T19:20:16.112Z","updated_at":"2025-04-09T16:22:54.739Z","avatar_url":"https://github.com/makukha.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: include docs/part/title.md --\u003e\n# caseutil ⇄ 🐍🐫🍢\n\u003e Case conversion and verification for Python: snake_case, camelCase, kebab-case, etc.\n\u003c!-- docsub: end --\u003e\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: include docs/part/badges.md --\u003e\n[![license](https://img.shields.io/github/license/makukha/caseutil.svg)](https://github.com/makukha/caseutil/blob/main/LICENSE)\n[![pypi](https://img.shields.io/pypi/v/caseutil.svg#v0.7.2)](https://pypi.python.org/pypi/caseutil)\n[![python versions](https://img.shields.io/pypi/pyversions/caseutil.svg)](https://pypi.org/project/caseutil)\n[![tests](https://raw.githubusercontent.com/makukha/caseutil/v0.7.2/docs/badge/tests.svg)](https://github.com/makukha/caseutil)\n[![coverage](https://raw.githubusercontent.com/makukha/caseutil/v0.7.2/docs/badge/coverage.svg)](https://github.com/makukha/caseutil)\n[![tested with multipython](https://img.shields.io/badge/tested_with-multipython-x)](https://github.com/makukha/multipython)\n[![docs status](https://readthedocs.org/projects/caseutil/badge/?version=latest)](https://caseutil.readthedocs.io/en/latest/?badge=latest)\n[![uses docsub](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/makukha/docsub/refs/heads/main/docs/badge/v1.json)](https://github.com/makukha/docsub)\n[![mypy](https://img.shields.io/badge/type_checked-mypy-%231674b1)](http://mypy.readthedocs.io)\n[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/ruff)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n[![openssf best practices](https://www.bestpractices.dev/projects/9342/badge)](https://www.bestpractices.dev/projects/9342)\n\u003c!-- docsub: end --\u003e\n\n# Features\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: include docs/part/features.md --\u003e\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\u003c!-- docsub: end --\u003e\n\n## Supported cases\n\n### [Classification](https://caseutil.readthedocs.io/en/latest/classification/)\n\n![Cases classification](docs/img/classification-dark.svg#gh-dark-mode-only)\n![Cases classification](docs/img/classification-default.svg#gh-light-mode-only)\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: include docs/part/cases-table.md --\u003e\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\u003c!-- docsub: end --\u003e\n\n# Installation\n\n```shell\n$ pip install caseutil\n```\n\n\u003c!-- docsub: begin #usage.md --\u003e\n\u003c!-- docsub: include docs/part/usage.md --\u003e\n## Use cases\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: x caselist tests/test_usage.py --\u003e\n* [Basic usage](#basic-usage)\n* [Cases enum](#cases-enum)\n* [Arbitrary cases](#arbitrary-cases)\n* [Detect cases](#detect-cases)\n* [Custom separators](#custom-separators)\n* [Tokenization](#tokenization)\n* [Unicode support *(not implemented)*](#unicode-support-not-implemented)\n\u003c!-- docsub: end --\u003e\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: x case tests/test_usage.py:BasicUsage --\u003e\n### Basic usage\n\n```pycon\n\u003e\u003e\u003e from caseutil import is_snake, to_snake\n\n\u003e\u003e\u003e is_snake('Foo bar-baz')\nFalse\n\n\u003e\u003e\u003e to_snake('Foo bar-baz')\n'foo_bar_baz'\n```\n\u003c!-- docsub: end --\u003e\n\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: x case tests/test_usage.py:CasesEnum --\u003e\n### Cases enum\n\nAll supported cases are gathered in `Case` enum:\n\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\u003c!-- docsub: end --\u003e\n\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: x case tests/test_usage.py:ArbitraryCases --\u003e\n### Arbitrary cases\n\nUse functions `is_case()` and `to_case()` to deal with arbitrary supported case:\n\n```pycon\n\u003e\u003e\u003e from caseutil import Case, is_case, to_case\n\n\u003e\u003e\u003e is_case(Case.CAMEL, 'myVarName')\nTrue\n\n\u003e\u003e\u003e to_case(Case.CONST, 'myVarName')\n'MY_VAR_NAME'\n```\n\u003c!-- docsub: end --\u003e\n\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: x case tests/test_usage.py:DetectCases --\u003e\n### Detect cases\n\nUse function `get_cases()` to determine case (or cases, if\n[ambiguous](https://caseutil.readthedocs.io/en/latest/classification/#ambiguity)):\n\n```pycon\n\u003e\u003e\u003e from caseutil import get_cases\n\n\u003e\u003e\u003e get_cases('fooBar')\n('camel',)\n\n\u003e\u003e\u003e get_cases('My var-name')  # mixed case\n()\n\n\u003e\u003e\u003e get_cases('Title')  # matches multiple cases\n('ada', 'pascal', 'sentence', 'title', 'train')\n```\n\u003c!-- docsub: end --\u003e\n\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: x case tests/test_usage.py:CustomSeparators --\u003e\n### Custom separators\n\nUse function `words()`:\n\n```pycon\n\u003e\u003e\u003e from caseutil import words, to_lower\n\n\u003e\u003e\u003e '/'.join(words(to_lower('myVarName')))\n'my/var/name'\n\n\u003e\u003e\u003e '.'.join(words('myVarName'))\n'my.Var.Name'\n```\n\u003c!-- docsub: end --\u003e\n\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: x case tests/test_usage.py:Tokenization --\u003e\n### Tokenization\n\nWord separators are non-word characters including underscore, and places where\ntext case is changed from lower to upper. Digits are not treated as separators.\nFor more details, see\n[Tokenization rules](https://caseutil.readthedocs.io/en/latest/tokenize).\n\n```pycon\n\u003e\u003e\u003e from caseutil import words\n\n\u003e\u003e\u003e words('!some_reallyMESsy text--wit4Digits.3VeryWh3re--')\n['some', 'really', 'ME', 'Ssy', 'text', 'wit4', 'Digits', '3Very', 'Wh3re']\n```\n\u003c!-- docsub: end --\u003e\n\n\n\u003c!-- docsub: begin --\u003e\n\u003c!-- docsub: x case tests/test_usage.py:UnicodeSupport --\u003e\n### Unicode support *(not implemented)*\n\nOnly ASCII names are supported. Unicode support is planned.\n\u003c!-- docsub: end --\u003e\n\u003c!-- docsub: end #usage.md --\u003e\n\n\n\u003c!-- docsub: begin #cli.md --\u003e\n\u003c!-- docsub: include docs/part/cli.md --\u003e\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### CLI Reference\n\n\u003c!-- docsub: begin #caseutil-help --\u003e\n\u003c!-- docsub: help caseutil --\u003e\n\u003c!-- docsub: lines after 2 upto -1 --\u003e\n```text\n$ caseutil --help\nusage: caseutil [-h] (--version | -c \u003ccase\u003e | -d) [text]\n\n  Convert, detect, or match text case.\n\n  When stdin is used as input, each line is tokenized and processed separately.\n\ncases:\n  ada,camel,cobol,const,kebab,lower,pascal,sentence,snake,title,train,upper\n\npositional arguments:\n  text                  text to be converted; if missing, stdin is used\n\noptions:\n  -h, --help            show this help message and exit\n  --version             show program's version number and exit\n  -c, --convert \u003ccase\u003e  convert [text] or stdin to \u003ccase\u003e\n  -d, --detect          detect cases in [text] or stdin\n```\n\u003c!-- docsub: end #caseutil-help --\u003e\n\u003c!-- docsub: end #cli.md --\u003e\n\n\n# Alternatives\n\n[70+ packages](https://caseutil.readthedocs.io/en/latest/alternatives/)\n\n# Contributing\n\nSee [Contributing](.github/CONTRIBUTING.md) guidelines.\n\n# Authors\n\n* [Michael Makukha](https://github.com/makukha)\n\n\n## See also\n\n* [Project changelog](https://github.com/makukha/caseutil/tree/main/CHANGELOG.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmakukha%2Fcaseutil","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmakukha%2Fcaseutil","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmakukha%2Fcaseutil/lists"}