{"id":32143147,"url":"https://github.com/john-mueller/hyphenation","last_synced_at":"2025-10-21T07:53:09.984Z","repository":{"id":63913054,"uuid":"246181936","full_name":"john-mueller/Hyphenation","owner":"john-mueller","description":"Knuth-Liang hyphenation for Swift","archived":false,"fork":false,"pushed_at":"2021-10-13T19:55:51.000Z","size":5377,"stargazers_count":34,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-21T07:53:00.638Z","etag":null,"topics":["hyphenation","knuth-liang"],"latest_commit_sha":null,"homepage":null,"language":"Swift","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/john-mueller.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}},"created_at":"2020-03-10T01:41:50.000Z","updated_at":"2025-02-25T05:20:56.000Z","dependencies_parsed_at":"2023-01-14T13:16:03.954Z","dependency_job_id":null,"html_url":"https://github.com/john-mueller/Hyphenation","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/john-mueller/Hyphenation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/john-mueller%2FHyphenation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/john-mueller%2FHyphenation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/john-mueller%2FHyphenation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/john-mueller%2FHyphenation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/john-mueller","download_url":"https://codeload.github.com/john-mueller/Hyphenation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/john-mueller%2FHyphenation/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280225806,"owners_count":26293888,"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","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["hyphenation","knuth-liang"],"created_at":"2025-10-21T07:53:09.142Z","updated_at":"2025-10-21T07:53:09.979Z","avatar_url":"https://github.com/john-mueller.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hyphenation\n\nEfficient and flexible automatic hyphenation using the Knuth-Liang algorithm.\n\nSee full documentation at [https://john-mueller.github.io/Hyphenation](https://john-mueller.github.io/Hyphenation).\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Installation](#installation)\n- [Usage](#usage)\n    - [Exceptions](#exceptions)\n    - [Custom Patterns](#custom-patterns)\n    - [Thread Safety](#thread-safety)\n    - [HTML/Code](#htmlcode)\n- [Contributing](#contributing)\n- [License](#license)\n- [Credits](#credits)\n\n## Introduction\n\nThe primary purpose of this library is to automatically insert soft hyphens into text to improve its layout flow. Consider the following example from [Butterick's Practical Typography](https://practicaltypography.com/justified-text.html):\n\n![Text without hyphenation](img/no-hyphenation.png)\n\nAs line length decreases, justified text often displays large gaps between words, while left- or right-aligned text displays increasingly uneven margins. By inserting soft hyphens into words (which are only displayed when they fall at the end of a line), the text can be split more naturally across multiple lines, improving the text's aesthetic appearance:\n\n![Text with hyphenation](img/with-hyphenation.png)\n\nThis proves useful in HTML (since the `hyphens` CSS property is [not universally supported](https://caniuse.com/#search=hyphen)), and will even work in UIKit and SwiftUI text components.\n\n## Installation\n\nHyphenation is installed via the [Swift Package Manager](https://swift.org/package-manager/). First, add it to your dependencies:\n\n```swift\nlet package = Package(\n    ...\n    dependencies: [\n        .package(url: \"https://github.com/john-mueller/Hyphenation.git\", from: \"0.2.0\")\n    ],\n    ...\n)\n```\n\nThen import the Hyphenation module wherever it is needed:\n\n```swift\nimport Hyphenation\n```\n\n## Usage\n\nBasic usage just requires creating a `Hyphenator` instance and calling its `hyphenate(text:)` method:\n\n```swift\nlet hyphenator = Hyphenator()\nhyphenator.separator = \"-\"\n\nlet text = \"This algorithm identifies likely hyphenation points.\"\nprint(hyphenator.hyphenate(text: text))\n// This al-go-rithm iden-ti-fies like-ly hy-phen-ation points.\n```\n\nYou can also remove the `separator` character from a string by calling `unhyphenate(text:)`:\n\n```swift\nlet hyphenatedText = \"This al-go-rithm iden-ti-fies like-ly hy-phen-ation points.\"\nprint(hyphenator.unhyphenate(text: hyphenatedText))\n// This algorithm identifies likely hyphenation points.\n```\n\nNote that if the original string contained the `separator` character, the `unhyphenate(text:)` method will remove those instances as well, so hyphenating and unhyphenating a string may not recover the original string.\n\n### Exceptions\n\nThe algorithm is designed to prioritize the prevention of incorrect hyphenations over finding every correct hyphenation—missing a single hyphenation rarely effects text flow meaningfully, but bad hyphenation can be rather noticable. Because the patterns were derived from a English dictionary, it can make good guesses about many words that do not appear in a dictionary.\n\n```swift\nlet hyphenator = Hyphenator()\nhyphenator.separator = \"-\"\n\nprint(hyphenator.hyphenate(text: \"swiftlang supercalifragilisticexpialidocious\"))\n// swift-lang su-per-cal-ifrag-ilis-tic-ex-pi-ali-do-cious\n```\n\nNevertheless, the algorithm may occasionally produce unexpected results for brand names or other unusual words. In this case, you may manually specify a desired hyphenation using exceptions.\n\n```swift\nprint(hyphenator.hyphenate(text: \"Microsoft sesquipedalian\"))\n// Mi-crosoft sesquipedalian\n\nhyphenator.addCustomExceptions([\"Micro-soft\", \"ses-qui-pe-da-li-an\"])\n\nprint(hyphenator.hyphenate(text: \"Microsoft sesquipedalian\"))\n// Micro-soft ses-qui-pe-da-li-an\n```\n\nTo remove custom exceptions, use the following methods:\n\n```swift\nhyphenator.removeCustomExceptions([\"sesquipedalian\"])\nhyphenator.removeAllCustomExceptions()\n```\n\n### Customizable Properties\n\nThere are several properties you can modify to adjust how words are hyphenated.\n\nThe `separator` property sets the character inserted at hyphenation points. By default, this is U+00AD (soft hyphen). \n\nThe `minLength`, `minLeading`, and `minTrailing` properties adjust where the separator character may be inserted in a word.\n\n- Words shorter than `minLength` will not be hyphenated.\n- Hyphenation will not occur within the first `minLeading` characters.\n- Hyphenation will not occur within the last `minTrailing` characters.\n\n### Custom Patterns\n\nThis library includes American English hyphenation patterns by default, but you can easily initialize a `Hyphenator` instance using patterns for many other languages. The patterns can be passed via `String` or `URL`:\n\n```swift\nlet hyphenator1 = Hyphenator(patterns: patternsString, exceptions: exceptionsString)\nlet hyphenator2 = Hyphenator(patternFile: patternsURL, exceptions: exceptionsURL)\n```\n\nPatterns for a wide variety of languages can be found in the [TeX hyphenation repo](https://github.com/hyphenation/tex-hyphen/tree/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt). *Please check the license under which each set of patterns is released* at the [TeX hyphenation patterns website](http://www.hyphenation.org/tex#languages). This page also lists the proper `minLeading` and `minTrailing` for each language.\n\nWhen initializing a new `Hyphenator` instance, it is assumed that patterns are separated by newlines or whitespace.\n\n### Thread Safety\n\nThe Hyphenator class is thread-safe, and can be used to hyphenate on multiple threads simultaneously (although the performance benefits over using two instances are negligible).\n\nThe `copy()` method provides an efficient way to create a new `Hyphenator` instance with the same properties and patterns as an existing instance.\n\n### HTML/Code\n\nYou should not apply the `hyphenate(text:)` method directly to strings containing HTML or code, as the code elements may be erroneously hyphenated. A safer approach is to use another tool capable of identifying HTML or code elements and applying hyphenation only to plain text content within the markup.\n\nSee [HyphenationPublishPlugin](https://github.com/john-mueller/HyphenationPublishPlugin) for an example hyphenating HTML using [SwiftSoup](https://github.com/scinfu/SwiftSoup).\n\n## Contributing\n\nIf you encounter an issue using Hyphenation, please let me know by filing an issue or submitting a pull request!\n\nWhen filing an issue, please do your best to provide reproducable steps and an explanation of the expected behavior.\n\nIn the case of a pull request, please take note of the following steps:\n\n1. `swiftlint` should produce no warnings when run in the project directory. This is checked by CI, but I also recommend linting locally if possible (instructions for installation in the [SwiftLint repo](https://github.com/realm/SwiftLint#installation)).\n2. Make sure `make test` results in no errors. This runs the tests in the `CorrectnessTests` and `ThreadSafetyTests` files.\n3. If changing any internal implementations, please run `make bench` both with and without your changes, to check for any speed regressions. This runs the tests in the `PerformanceTests` file.\n\n## License\n\nHyphenation is provided under the MIT license (see [LICENSE.md](LICENSE.md)).\n\nThe English hyphenation patterns are provided under the [original custom license](https://github.com/hyphenation/tex-hyphen/blob/master/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-en-us.tex), and are sourced from the [TeX hyphenation repo](https://github.com/hyphenation/tex-hyphen/tree/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt).\n\n[The texts](Tests/PerformanceTests/TestHelpers/) used for performance testing are in the public domain, and are attributed in their headers.\n\nThe example paragraphs in the Introduction are from [Butterick's Practical Typography](https://practicaltypography.com), and are used with permission.\n\n## Credits\n\nThis library was inspired by the pages on [justified text](https://practicaltypography.com/justified-text.html) and [optional hyphens](https://practicaltypography.com/optional-hyphens.html) in [Butterick's Practical Typography](https://practicaltypography.com) and the author's [implementation in Racket](https://github.com/mbutterick/hyphenate). It's worth a read!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohn-mueller%2Fhyphenation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohn-mueller%2Fhyphenation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohn-mueller%2Fhyphenation/lists"}