{"id":16406148,"url":"https://github.com/alerque/decasify","last_synced_at":"2025-08-09T04:17:13.736Z","repository":{"id":179011702,"uuid":"662618511","full_name":"alerque/decasify","owner":"alerque","description":"A CLI utility, Rust crate, and Lua module to cast strings to title-case according to locale specific style guides including Turkish support.","archived":false,"fork":false,"pushed_at":"2024-05-01T11:16:23.000Z","size":294,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-05-03T01:53:39.718Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alerque.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-05T14:14:27.000Z","updated_at":"2024-07-15T13:41:14.395Z","dependencies_parsed_at":"2024-05-01T11:52:05.641Z","dependency_job_id":"daa9eac0-3a65-4a4b-b4e4-066527b5636f","html_url":"https://github.com/alerque/decasify","commit_stats":null,"previous_names":["alerque/decasify"],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alerque%2Fdecasify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alerque%2Fdecasify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alerque%2Fdecasify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alerque%2Fdecasify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alerque","download_url":"https://codeload.github.com/alerque/decasify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221599881,"owners_count":16850035,"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":[],"created_at":"2024-10-11T06:08:48.742Z","updated_at":"2025-08-09T04:17:13.706Z","avatar_url":"https://github.com/alerque.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# decasify\n\n[![Rust Test Status](https://img.shields.io/github/actions/workflow/status/alerque/decasify/rust_test.yml?branch=master\u0026label=Rust+Test\u0026logo=Rust)](https://github.com/alerque/decasify/actions/workflows/rust_test.yml)\n[![Rust Lint Status](https://img.shields.io/github/actions/workflow/status/alerque/decasify/rust_lint.yml?branch=master\u0026label=Rust+Lint\u0026logo=Rust)](https://github.com/alerque/decasify/actions/workflows/rust_list.yml)\n[![Flake Run Status](https://img.shields.io/github/actions/workflow/status/alerque/decasify/nix.yml?branch=master\u0026label=Flake\u0026logo=NixOS)](https://github.com/alerque/decasify/actions/workflows/nix.yml)\n[![Lua Lint Status](https://img.shields.io/github/actions/workflow/status/alerque/decasify/luacheck.yml?branch=master\u0026label=Luacheck\u0026logo=Lua)](https://github.com/alerque/decasify/actions/workflows/luacheck.yml)\n[![Lua Test Status](https://img.shields.io/github/actions/workflow/status/alerque/decasify/busted.yml?branch=master\u0026label=Busted\u0026logo=Lua)](https://github.com/alerque/decasify/actions/workflows/busted.yml)  \n[![GitHub tag (latest)](https://img.shields.io/github/v/tag/alerque/decasify?logo=github\u0026color=blue)](https://github.com/alerque/decasify/releases)\n[![Crates.io (latest)](https://img.shields.io/crates/v/decasify?logo=rust\u0026color=blue)](https://crates.io/crates/decasify)\n[![LuaRocks (latest)](https://img.shields.io/luarocks/v/alerque/decasify?logo=lua\u0026color=blue)][rock]\n[![PyPi (latest)](https://img.shields.io/pypi/v/decasify?logo=python\u0026color=blue)](https://pypi.org/project/decasify)\n[![NPM Version](https://img.shields.io/npm/v/decasify?logo=npm\u0026color=blue)](https://www.npmjs.com/package/decasify)\n\nA CLI utility, Rust crate, Lua rock, Python module, JavaScript module, Neovim or VIM plugin, SILE package, and Typst package to cast strings to title-case (and other cases) according to locale specific style guides including Turkish support.\n\nThis project was born out of frustration with authors and editors leaving ALL CAPS TITLES in Markdown sources.\nNo tooling I could find properly supported casting these to title-cased strings (which are more versatile for typesetting purposes).\nThe problem was doubly hard because most of my work is adjacent to Turkish, and even less tooling was available and has special issues with case conversions.\nMany tools can handle casing single words, some programmer specific tools handle re-casing tokens and identifiers, and yet a few others can handle *English* strings.\nBut *nothing* seemed to be out there for changing the case of Turkish prose.\n\nThe CLI defaults to titlecase and English, but lower, upper, and sentence case options are also available.\nThe Rust, Lua, Python, and JavaScript library APIs have functions specific to each operation.\nWhere possible the APIs currently default to English rules and (for English) the Gruber style guide, but others are available.\n\nThe Turkish style follows the Turkish Language Institute's [guidelines][tdk].\n\nFor English, three style guides are known: Associated Press (AP), Chicago Manual of Style (CMOS), and John Gruber's Daring Fireball (Gruber).\nThe Gruber style is by far the most complete, being implemented by the [titlecase crate][titlecase_crate].\nThe CMOS style handles a number of parts of speech but has punctuation related issues.\nThe AP style is largely unimplemented.\n\nContributions are welcome for better style guide support or further languages.\n\n[tdk]: https://tdk.gov.tr/icerik/yazim-kurallari/buyuk-harflerin-kullanildigi-yerler/\n[titlecase_crate]: https://crates.io/crates/titlecase\n\n## Use as a CLI tool\n\nUse of the CLI is pretty simple.\nInput may be either shell arguments or STDIN.\nArguments can control the various options.\nFor full usage information check `decasify --help` or `man decasify`.\n\n``` console\n$ decasify -l tr ILIK SU VE İTEN RÜZGARLAR\nIlık Su ve İten Rüzgarlar\n\n$ echo ILIK SU VE İTEN RÜZGARLAR | decasify -l tr\nIlık Su ve İten Rüzgarlar\n\n$ echo foo BAR AND baz: an alter ego | decasify -l en -s gruber\nFoo BAR and Baz: An Alter Ego\n```\n\n### Installation\n\n\u003ca href=\"https://repology.org/project/decasify/versions\"\u003e\u003cimg src=\"https://repology.org/badge/vertical-allrepos/decasify.svg\" align=\"right\" alt=\"Packaging status\"\u003e\u003c/a\u003e\nTo install, first check your distro for packages, e.g. for [Arch Linux](https://archlinux.org/packages/extra/x86_64/decasify/) just install via `pacman -S decasify` or for [Homebrew](https://formulae.brew.sh/formula/decasify) via `brew install decasify`.\n\nOtherwise for many platforms you can run it directly or install it to a shell using Nix Flakes:\n\n``` console\n$ nix run github:alerque/decasify\n```\n\nTo do a full install from source, grab the tarball attached to the [latest release](https://github.com/alerque/decasify/releases/latest) or use Git to clone the repository.\nDon't use the \"source code\" zip/tar.gz files linked from releases, go for the `tar.zst` source file.\nIf you use a Git close, first run `./bootstrap.sh` after checkout.\nThis isn't needed in the source release tarballs.\nNext, configure and install with:\n\n```console\n$ ./configure\n$ make\n$ sudo make install\n```\n\nNote that installing from source has the advantage of include a man page and shell completions.\nAll the usual autotools options apply, see `--help` for details.\nThe most commonly used option especially for distro packagers is probably `--prefix /usr` to change the install location from the default of `/usr/local`.\n\nOf course the bare binary can also be installed directly with Cargo:\n\n```console\n$ cargo install --features cli decasify\n```\n\n## Use as a Rust crate\n\nIn your `Cargo.toml` file.\n\n```toml\n[dependencies]\ndecasify = \"0.10\"\n```\n\nThen use the crate functions and types in your project something like this:\n\n```rust\nuse decasify::titlecase;\nuse decasify::{Locale, StyleGuide, StyleOptions};\n\nfn demo() {\n    let input = \"ILIK SU VE İTEN RÜZGARLAR\";\n    let output = titlecase(input, Locale::TR, StyleGuide::LanguageDefault, StyleOptions::default());\n    eprintln! {\"{output}\"};\n    let input = \"title with a twist: a colon\";\n    let output = titlecase(input, Locale::EN, StyleGuide::DaringFireball, StyleOptions::default());\n    eprintln! {\"{output}\"};\n}\n```\n\n## Use as a Lua Rock\n\nDepend on [the LuaRock][rock] in your project or install with `luarocks install decasify`:\n\n```lua\ndependencies = {\n   \"decasify\"\n}\n```\n\nThen import and use the provided functions:\n\n```lua\nlocal decasify = require(\"decasify\")\nlocal input = \"ILIK SU VE İTEN RÜZGARLAR\"\nlocal output = decasify.titlecase(input, \"tr\")\nprint(output)\ninput = \"title with a twist: a colon\"\noutput  = decasify.titlecase(input, \"en\", \"gruber\")\nprint(output)\n```\n\n## Use as a Python Module\n\nDepend on the Python module in your project or install with `pip install decasify`:\n\n```toml\n[project]\ndependencies = [\n  \"decasify\"\n]\n```\n\nThen import and use the provided functions and type classes:\n\n```python\nfrom decasify import *\n\ninput = \"ILIK SU VE İTEN RÜZGARLAR\"\noutput = titlecase(input, Locale.TR)\nprint(output)\ninput = \"title with a twist: a colon\"\noutput  = titlecase(input, Locale.EN, StyleGuide.DaringFireball)\nprint(output)\n```\n\n## Use as a JavaScript (WASM) Module\n\nDepend on the WASM based JavaScript module in your project with `npm add decasify`:\n\nThen import and use the provided functions and classes:\n\n```javascript\nimport { titlecase, uppercase, lowercase, Locale, StyleGuide } from 'decasify';\n\nvar input = \"ILIK SU VE İTEN RÜZGARLAR\"\nvar output = titlecase(input, Locale.TR)\nconsole.log(output)\n\nvar input = \"title with a twist: a colon\"\nvar output = titlecase(input, Locale.EN, StyleGuide.DaringFireball)\nconsole.log(output)\n```\n\n## Use as a Neovim plugin\n\n* Using [rocks.nvim](https://github.com/nvim-neorocks/rocks.nvim), simply run `:Rocks install decasify.nvim`.\n\n* Using [lazy.nvim](https://lazy.folke.io/), simply add `{ \"alerque/decasify\" }`\n\n* Using other plugin managers that don't automatically detect dependencies, you will need to manually specify the dependency and/or make sure the Lua Rock for [decasify](https://luarocks.org/modules/alerque/decasify) is available, then use this repository as a plugin however your plugin manager handles that.\n\n    ```lua\n    -- for packer.nvim\n    use {\n       \"alerque/decasify\",\n       rocks = { \"decasify\" },\n    }\n    ```\n\n* Using no plugin manager, make sure the [decasify Rock][rock] is installed matching the version of Lua NeoVIM is built with, then copy `plugin/decasify.lua` to wherever your user's plugin directory is.\n  As an alternative to installing the LuaRock, you can also force NeoVIM to use the vimscript plugin that uses the CLI command, in which case you will need to install the CLI tool separately, then `vim.g.decasify_force_cli = true` in your `init.lua`.\n\nA new command `:Decasify` will become available (with optional subcommands for cases other than title case) that transforms the current line or any range of lines.\nThe default case, locale, and style guide can be changed (before or after loading) with global or buffer local variables:\n\n```lua\n-- Set the default target case globally\nvim.g.decasify_case = \"title\"\n-- Change the locale for the current buffer\nvim.b.decasify_locale = \"tr\"\n-- Change the default style guide globally\nvim.g.decasify_style = \"gruber\"\n-- Override casing of specific words\nvim.g.decasify_overrides = { \"NASA\", \"SpaceX\" }\n```\n\n## Use as a VIM plugin\n\nThe VIM plugin depends on having the `decasify` CLI tool available in your system $PATH.\nThis is in contrast to the NeoVIM plugin which loads the Lua Rock directly as a library and never needs to spawn a shell process.\nThis does mean you must install the CLI separately on your own.\n\n* Using a plugin manager such as [vim-plug](https://github.com/junegunn/vim-plug) to enable this repository.\n\n```vim\n\" for vim-plug\nPlug 'alerque/decasify'\n```\n\nA new command `:Decasify` will become available that transforms the current line or any range of lines.\nAny arguments passed to the command will be passed through to the CLI tool.\n\nThe default case, locale, and style guide can be changed (before or after loading) with global or buffer local variables:\n\n```vim\n\" Set the default target case globally\nlet g:decasify_case = \"title\"\n\" Change the locale for the current buffer\nlet g:decasify_locale = \"tr\"\n\" Change the default style guide globally\nlet g:decasify_style = \"gruber\"\n\" Override casing of specific words\nlet g:decasify_overrides = ['NASA', 'SpaceX']\n```\n\n## Use as a SILE package\n\n[The SILE Typesetter](https://sile-typesetter.org/) leverages LuaRocks to manage 3rd party packages.\nThe [decasify.sile][rock.sile] rock can be installed with `luarocks install decasify.sile`.\nTypically you'll want to adjust the Lua version to match your SILE installation, something like:\n\n```console\n$ luarocks --lua $(sile -q \u003c\u003c\u003c SILE.lua_version) install decasify.sile\n```\n\nAdditionally you may want to use `--local` to install to your user account instead of the system root, or `--tree lua_modules` to install locally inside a single project.\nLoading the package in a SILE document uses the usual `\\use[module=package.decasify]` (see notes in the SILE manual about setting package paths if you installed via `--local`).\nOnce loaded, the package exposes a `\\decasify{}` function that can take any combination of `case`, `locale`, and `style` settings and applies the appropriate transformation to the content.\nBy default it will track the language of the document content.\n\n## Use as a Typst package\n\n[Typst](https://typst.app/) has its own [package registry](https://typst.app/universe/).\nThe [decasify](https://typst.app/universe/package/decasify) package can be added to your project with an import line.\nThe exact version must be specified explicitly:\n\n```typst\n#import \"@preview/decasify:0.10.1\": *\n```\n\nSpecific functions for each case should be available throughout the document.\nSee the Typst package [readme](typst/README.md) or the [package listing on Typst universe](https://typst.app/universe/package/decasify) for more details.\n\n[rock]: http://luarocks.org/modules/alerque/decasify\n[rock.sile]: http://luarocks.org/modules/alerque/decasify.sile\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falerque%2Fdecasify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falerque%2Fdecasify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falerque%2Fdecasify/lists"}