• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Textwrap
2
3[![](https://github.com/mgeisler/textwrap/workflows/build/badge.svg)][build-status]
4[![](https://codecov.io/gh/mgeisler/textwrap/branch/master/graph/badge.svg)][codecov]
5[![](https://img.shields.io/crates/v/textwrap.svg)][crates-io]
6[![](https://docs.rs/textwrap/badge.svg)][api-docs]
7
8Textwrap is a library for wrapping and indenting text. It is most
9often used by command-line programs to format dynamic output nicely so
10it looks good in a terminal. You can also use Textwrap to wrap text
11set in a proportional font—such as text used to generate PDF files, or
12drawn on a [HTML5 canvas using WebAssembly][wasm-demo].
13
14## Usage
15
16To use the textwrap crate, add this to your `Cargo.toml` file:
17```toml
18[dependencies]
19textwrap = "0.16"
20```
21
22By default, this enables word wrapping with support for Unicode
23strings. Extra features can be enabled with Cargo features—and the
24Unicode support can be disabled if needed. This allows you slim down
25the library and so you will only pay for the features you actually
26use.
27
28Please see the [_Cargo Features_ in the crate
29documentation](https://docs.rs/textwrap/#cargo-features) for a full
30list of the available features as well as their impact on the size of
31your binary.
32
33## Documentation
34
35**[API documentation][api-docs]**
36
37## Getting Started
38
39Word wrapping is easy using the `wrap` and `fill` functions:
40
41```rust
42#[cfg(feature = "smawk")] {
43let text = "textwrap: an efficient and powerful library for wrapping text.";
44assert_eq!(
45    textwrap::wrap(text, 28),
46    vec![
47        "textwrap: an efficient",
48        "and powerful library for",
49        "wrapping text.",
50    ]
51);
52}
53```
54
55Sharp-eyed readers will notice that the first line is 22 columns wide.
56So why is the word “and” put in the second line when there is space
57for it in the first line?
58
59The explanation is that textwrap does not just wrap text one line at a
60time. Instead, it uses an optimal-fit algorithm which looks ahead and
61chooses line breaks which minimize the gaps left at ends of lines.
62This is controlled with the `smawk` Cargo feature, which is why the
63example is wrapped in the `cfg`-block.
64
65Without look-ahead, the first line would be longer and the text would
66look like this:
67
68```rust
69#[cfg(not(feature = "smawk"))] {
70let text = "textwrap: an efficient and powerful library for wrapping text.";
71assert_eq!(
72    textwrap::wrap(text, 28),
73    vec![
74        "textwrap: an efficient and",
75        "powerful library for",
76        "wrapping text.",
77    ]
78);
79}
80```
81
82The second line is now shorter and the text is more ragged. The kind
83of wrapping can be configured via `Options::wrap_algorithm`.
84
85If you enable the `hyphenation` Cargo feature, you get support for
86automatic hyphenation for [about 70 languages][patterns] via
87high-quality TeX hyphenation patterns.
88
89Your program must load the hyphenation pattern and configure
90`Options::word_splitter` to use it:
91
92```rust
93#[cfg(feature = "hyphenation")] {
94use hyphenation::{Language, Load, Standard};
95use textwrap::{fill, Options, WordSplitter};
96
97let dictionary = Standard::from_embedded(Language::EnglishUS).unwrap();
98let options = textwrap::Options::new(28).word_splitter(WordSplitter::Hyphenation(dictionary));
99let text = "textwrap: an efficient and powerful library for wrapping text.";
100
101assert_eq!(
102    textwrap::wrap(text, &options),
103    vec![
104        "textwrap: an efficient and",
105        "powerful library for wrap-",
106        "ping text."
107    ]
108);
109}
110```
111
112The US-English hyphenation patterns are embedded when you enable the
113`hyphenation` feature. They are licensed under a [permissive
114license][en-us license] and take up about 88 KB in your binary. If you
115need hyphenation for other languages, you need to download a
116[precompiled `.bincode` file][bincode] and load it yourself. Please
117see the [`hyphenation` documentation] for details.
118
119## Wrapping Strings at Compile Time
120
121If your strings are known at compile time, please take a look at the
122procedural macros from the [`textwrap-macros` crate].
123
124## Examples
125
126The library comes with [a
127collection](https://github.com/mgeisler/textwrap/tree/master/examples)
128of small example programs that shows various features.
129
130If you want to see Textwrap in action right away, then take a look at
131[`examples/wasm/`], which shows how to wrap sans-serif, serif, and
132monospace text. It uses WebAssembly and is automatically deployed to
133https://mgeisler.github.io/textwrap/.
134
135For the command-line examples, you’re invited to clone the repository
136and try them out for yourself! Of special note is
137[`examples/interactive.rs`]. This is a demo program which demonstrates
138most of the available features: you can enter text and adjust the
139width at which it is wrapped interactively. You can also adjust the
140`Options` used to see the effect of different `WordSplitter`s and wrap
141algorithms.
142
143Run the demo with
144
145```sh
146$ cargo run --example interactive
147```
148
149The demo needs a Linux terminal to function.
150
151## Release History
152
153Please see the [CHANGELOG file] for details on the changes made in
154each release.
155
156## License
157
158Textwrap can be distributed according to the [MIT license][mit].
159Contributions will be accepted under the same license.
160
161[crates-io]: https://crates.io/crates/textwrap
162[build-status]: https://github.com/mgeisler/textwrap/actions?query=workflow%3Abuild+branch%3Amaster
163[codecov]: https://codecov.io/gh/mgeisler/textwrap
164[wasm-demo]: https://mgeisler.github.io/textwrap/
165[`textwrap-macros` crate]: https://crates.io/crates/textwrap-macros
166[`hyphenation` example]: https://github.com/mgeisler/textwrap/blob/master/examples/hyphenation.rs
167[`termwidth` example]: https://github.com/mgeisler/textwrap/blob/master/examples/termwidth.rs
168[patterns]: https://github.com/tapeinosyne/hyphenation/tree/master/patterns-tex
169[en-us license]: https://github.com/hyphenation/tex-hyphen/blob/master/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-en-us.tex
170[bincode]: https://github.com/tapeinosyne/hyphenation/tree/master/dictionaries
171[`hyphenation` documentation]: http://docs.rs/hyphenation
172[`examples/wasm/`]: https://github.com/mgeisler/textwrap/tree/master/examples/wasm
173[`examples/interactive.rs`]: https://github.com/mgeisler/textwrap/tree/master/examples/interactive.rs
174[api-docs]: https://docs.rs/textwrap/
175[CHANGELOG file]: https://github.com/mgeisler/textwrap/blob/master/CHANGELOG.md
176[mit]: LICENSE
177