{"id":28377373,"url":"https://github.com/guillaumeast/strui","last_synced_at":"2025-06-26T18:31:15.669Z","repository":{"id":293619732,"uuid":"984570111","full_name":"guillaumeast/strui","owner":"guillaumeast","description":"Minimal string CLI → Clean, measure \u0026 reshape terminal text (Unicode/ANSI-aware)","archived":false,"fork":false,"pushed_at":"2025-05-16T17:18:07.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-06T01:25:22.901Z","etag":null,"topics":["ansi-escape-codes","cli","cpp17","self-contained","string-utils","text-processing","unicode","unix-philosophy","utf-8"],"latest_commit_sha":null,"homepage":"","language":"C++","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/guillaumeast.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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,"zenodo":null}},"created_at":"2025-05-16T06:34:29.000Z","updated_at":"2025-05-16T17:18:10.000Z","dependencies_parsed_at":"2025-05-16T09:23:39.581Z","dependency_job_id":null,"html_url":"https://github.com/guillaumeast/strui","commit_stats":null,"previous_names":["guillaumeast/strui"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/guillaumeast/strui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guillaumeast%2Fstrui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guillaumeast%2Fstrui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guillaumeast%2Fstrui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guillaumeast%2Fstrui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guillaumeast","download_url":"https://codeload.github.com/guillaumeast/strui/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guillaumeast%2Fstrui/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262122507,"owners_count":23262407,"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":["ansi-escape-codes","cli","cpp17","self-contained","string-utils","text-processing","unicode","unix-philosophy","utf-8"],"created_at":"2025-05-30T01:04:50.216Z","updated_at":"2025-06-26T18:31:15.610Z","avatar_url":"https://github.com/guillaumeast.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🛠️ **`strui` v1.0.0**\n\nTiny Unicode‑aware \u0026 ANSI‑aware **string CLI** – built on top of [`libstrui`](https://github.com/guillaumeast/libstrui).\n\n[![C++](https://img.shields.io/badge/language-C%2B%2B17-blue)](https://en.cppreference.com/)\n[![Type: CLI](https://img.shields.io/badge/type-CLI-lightgrey)](https://en.wikipedia.org/wiki/Command-line_interface)\n[![Platform: Unix](https://img.shields.io/badge/platform-Unix-darkgreen)](https://en.wikipedia.org/wiki/Unix)\n[![Status: v1.0.0](https://img.shields.io/badge/status-v1.0.0-brightgreen)](https://github.com/guillaumeast/strui/releases/tag/v1.0.0)\n\n\u003e **`strui`** is the command‑line face of `libstrui`:  \n\u003e think of it as a minimal, UTF‑8‑smart replacement for `cut`, `wc`, or `tr` that understands emojis and ANSI escapes.\n\n---\n\n## ✨ Features\n\n- Everything from **`libstrui`** available at the tips of your fingers:\n  - clean ANSI escapes\n  - measure *visual* width / height\n  - split / join / repeat helpers\n  - substring count\n- **UTF‑8 aware** (CJK, wide \u0026 combined emojis)\n- **Zero runtime dependencies** – the binary is **fully self-contained**\n- Ships as **one small binary** (`\u003c50 KB`)\n\n---\n\n### 🚀 Quick install\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/guillaumeast/strui/master/install/install.sh | sh\n```\n\nThis will:\n\n- detect your platform (Linux/macOS, x86_64/arm64),\n- download the right binary from the latest release,\n- install it to `~/.local/bin` (or a custom path if you set `$DEST`),\n- add `~/.local/bin` in your `$PATH` if not already in.\n- and verify checksum before running anything.\n\n\u003e 🙈 If you're on `Windows`:  \n\u003e Don’t worry — we all make mistakes.  \n\u003e Fire up `wsl`, and pretend it never happened.  \n\u003e   \n\u003e ✨ Join us on the bright (terminal) side.\n\n---\n\n## 📦 Dependencies\n\n- **Runtime:** None\n- **Build-time:**\n    - [`libunistring`](https://www.gnu.org/software/libunistring/) ≥ 1.1 (**statically linked**)\n    - Any **C++17** compiler (`g++`, `clang++`, …)\n\n---\n\n## 🖥️ Usage\n\n| Command                                                | Description                                   |\n|--------------------------------------------------------|-----------------------------------------------|\n| `strui width \u003cstring\u003e`                                 | Return *visual* width (columns) of `string`   |\n| `strui height \u003cstring\u003e`                                | Return number of *lines* in `string`          |\n| `strui clean \u003cstring\u003e`                                 | Remove ANSI *escape sequences*                |\n| `strui split \u003cstring\u003e \u003cseparator\u003e`                     | Vector‑split `string` on `separator`          |\n| `strui join ?--separator ?\u003cseparator\u003e \u003c...strings...\u003e` | Join `strings` with optional `separator`      |\n| `strui repeat \u003ccount\u003e \u003cstring\u003e ?\u003cseparator\u003e`           | Repeat `string` `count` times                 |\n| `strui count \u003cvalue\u003e \u003cstring\u003e`                         | Count occurrences of `value` in `string`      |\n\n\u003e `Display width` is measured in `columns`, of `characters` or `strings`, when output to a device that uses `non-proportional fonts`.  \n\u003e Note that for some rarely used characters the actual `fonts` or `terminal emulators` can use a different `width`. There is no mechanism for communicating the `display width` of `characters` across a Unix pseudo-terminal (`tty`).  \n\u003e Also, there are scripts with complex rendering, like the `Indic` scripts. For these scripts, there is no such concept as `non-proportional fonts`. Therefore the results of these functions usually work fine on most scripts and on most `characters` but can fail to represent the actual `display width`.  \n\u003e 📚 See [libunistring documentation – Display width \u003cuniwidth.h\u003e](https://www.gnu.org/software/libunistring/manual/libunistring.html#uniwidth_002eh) for details on how display width is computed.\n\n---\n\n## 🧪 Tests\n\n\u003e Requirement: Docker\n\nTests are run locally and **inside an Ubuntu container** to guarantee portability.\n\n```bash\nmake test          # build + tests\n```\n\n---\n\n## 📁 Project structure\n\n```\nstrui/\n├── Makefile\n├── include/strui.hpp   # libstrui header\n├── src/main.cpp        # CLI implementation\n├── build/              # autogenerated binary (can be .gitignored)\n└── tests/\n    ├── volume/         # auto-generated at runtime by `run.sh` (can be .gitignored)\n    ├── run.sh          # test orchestrator (POSIX sh)\n    ├── test.sh         # unit tests (POSIX sh)\n    └── Dockerfile      # ubuntu image description for portability tests\n```\n\n---\n\n## 👤 Author\n\nMade with ❤️ by [@guillaumeast](https://github.com/guillaumeast)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguillaumeast%2Fstrui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguillaumeast%2Fstrui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguillaumeast%2Fstrui/lists"}