README.md
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.14"
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. Please see the [_Cargo Features_ in the crate
27documentation](https://docs.rs/textwrap/#cargo-features) for a full
28list of the available features.
29
30## Documentation
31
32**[API documentation][api-docs]**
33
34## Getting Started
35
36Word wrapping is easy using the `fill` function:
37
38```rust
39fn main() {
40 let text = "textwrap: an efficient and powerful library for wrapping text.";
41 println!("{}", textwrap::fill(text, 28));
42}
43```
44
45The output is wrapped within 28 columns:
46
47```
48textwrap: an efficient
49and powerful library for
50wrapping text.
51```
52
53Sharp-eyed readers will notice that the first line is 22 columns wide.
54So why is the word “and” put in the second line when there is space
55for it in the first line?
56
57The explanation is that textwrap does not just wrap text one line at a
58time. Instead, it uses an optimal-fit algorithm which looks ahead and
59chooses line breaks which minimize the gaps left at ends of lines.
60
61Without look-ahead, the first line would be longer and the text would
62look like this:
63
64```
65textwrap: an efficient and
66powerful library for
67wrapping text.
68```
69
70The second line is now shorter and the text is more ragged. The kind
71of wrapping can be configured via `Options::wrap_algorithm`.
72
73If you enable the `hyphenation` Cargo feature, you get support for
74automatic hyphenation for [about 70 languages][patterns] via
75high-quality TeX hyphenation patterns.
76
77Your program must load the hyphenation pattern and configure
78`Options::word_splitter` to use it:
79
80```rust
81use hyphenation::{Language, Load, Standard};
82use textwrap::Options;
83
84fn main() {
85 let hyphenator = Standard::from_embedded(Language::EnglishUS).unwrap();
86 let options = Options::new(28).word_splitter(hyphenator);
87 let text = "textwrap: an efficient and powerful library for wrapping text.";
88 println!("{}", fill(text, &options);
89}
90```
91
92The output now looks like this:
93```
94textwrap: an efficient and
95powerful library for wrap-
96ping text.
97```
98
99The US-English hyphenation patterns are embedded when you enable the
100`hyphenation` feature. They are licensed under a [permissive
101license][en-us license] and take up about 88 KB in your binary. If you
102need hyphenation for other languages, you need to download a
103[precompiled `.bincode` file][bincode] and load it yourself. Please
104see the [`hyphenation` documentation] for details.
105
106## Wrapping Strings at Compile Time
107
108If your strings are known at compile time, please take a look at the
109procedural macros from the [`textwrap-macros` crate].
110
111## Examples
112
113The library comes with [a
114collection](https://github.com/mgeisler/textwrap/tree/master/examples)
115of small example programs that shows various features.
116
117If you want to see Textwrap in action right away, then take a look at
118[`examples/wasm/`], which shows how to wrap sans-serif, serif, and
119monospace text. It uses WebAssembly and is automatically deployed to
120https://mgeisler.github.io/textwrap/.
121
122For the command-line examples, you’re invited to clone the repository
123and try them out for yourself! Of special note is
124[`examples/interactive.rs`]. This is a demo program which demonstrates
125most of the available features: you can enter text and adjust the
126width at which it is wrapped interactively. You can also adjust the
127`Options` used to see the effect of different `WordSplitter`s and wrap
128algorithms.
129
130Run the demo with
131
132```sh
133$ cargo run --example interactive
134```
135
136The demo needs a Linux terminal to function.
137
138## Release History
139
140Please see the [CHANGELOG file] for details on the changes made in
141each release.
142
143## License
144
145Textwrap can be distributed according to the [MIT license][mit].
146Contributions will be accepted under the same license.
147
148[crates-io]: https://crates.io/crates/textwrap
149[build-status]: https://github.com/mgeisler/textwrap/actions?query=workflow%3Abuild+branch%3Amaster
150[codecov]: https://codecov.io/gh/mgeisler/textwrap
151[wasm-demo]: https://mgeisler.github.io/textwrap/
152[`textwrap-macros` crate]: https://crates.io/crates/textwrap-macros
153[`hyphenation` example]: https://github.com/mgeisler/textwrap/blob/master/examples/hyphenation.rs
154[`termwidth` example]: https://github.com/mgeisler/textwrap/blob/master/examples/termwidth.rs
155[patterns]: https://github.com/tapeinosyne/hyphenation/tree/master/patterns-tex
156[en-us license]: https://github.com/hyphenation/tex-hyphen/blob/master/hyph-utf8/tex/generic/hyph-utf8/patterns/tex/hyph-en-us.tex
157[bincode]: https://github.com/tapeinosyne/hyphenation/tree/master/dictionaries
158[`hyphenation` documentation]: http://docs.rs/hyphenation
159[`examples/wasm/`]: https://github.com/mgeisler/textwrap/tree/master/examples/wasm
160[`examples/interactive.rs`]: https://github.com/mgeisler/textwrap/tree/master/examples/interactive.rs
161[api-docs]: https://docs.rs/textwrap/
162[CHANGELOG file]: https://github.com/mgeisler/textwrap/blob/master/CHANGELOG.md
163[mit]: LICENSE
164