70 lines
11 KiB
HTML
70 lines
11 KiB
HTML
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Compute the display width of `text` while skipping over ANSI escape sequences."><meta name="keywords" content="rust, rustlang, rust-lang, display_width"><title>display_width in textwrap::core - Rust</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceSerif4-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../FiraSans-Regular.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../FiraSans-Medium.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceCodePro-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceSerif4-Bold.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceCodePro-Semibold.ttf.woff2"><link rel="stylesheet" type="text/css" href="../../normalize.css"><link rel="stylesheet" type="text/css" href="../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../../ayu.css" disabled><link rel="stylesheet" type="text/css" href="../../dark.css" disabled><link rel="stylesheet" type="text/css" href="../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../storage.js"></script><script src="../../crates.js"></script><script defer src="../../main.js"></script>
|
||
<noscript><link rel="stylesheet" href="../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../favicon.svg"></head><body class="rustdoc fn"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="sidebar-menu" role="button">☰</div><a class="sidebar-logo" href="../../textwrap/index.html"><div class="logo-container"><img class="rust-logo" src="../../rust-logo.png" alt="logo"></div>
|
||
</a><div class="sidebar-elems"><h2 class="location">Other items in<br><a href="../index.html">textwrap</a>::<wbr><a href="index.html">core</a></h2><div id="sidebar-vars" data-name="display_width" data-ty="fn" data-relpath=""></div><script defer src="sidebar-items.js"></script></div></nav><main><div class="width-limiter"><div class="sub-container"><a class="sub-logo-container" href="../../textwrap/index.html"><img class="rust-logo" src="../../rust-logo.png" alt="logo"></a><nav class="sub"><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu" title="themes"><img width="18" height="18" alt="Pick another theme!" src="../../brush.svg"></button><div id="theme-choices" role="menu"></div></div><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"></div><button type="button" id="help-button" title="help">?</button><a id="settings-menu" href="../../settings.html" title="settings"><img width="18" height="18" alt="Change settings" src="../../wheel.svg"></a></div></form></nav></div><section id="main-content" class="content"><h1 class="fqn"><span class="in-band">Function <a href="../index.html">textwrap</a>::<wbr><a href="index.html">core</a>::<wbr><a class="fn" href="#">display_width</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></span><span class="out-of-band"><span id="render-detail"><a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span><a class="srclink" href="../../src/textwrap/core.rs.html#175-185" title="goto source code">[src]</a></span></h1><div class="docblock item-decl"><pre class="rust fn"><code>pub fn display_width(text: &<a class="primitive" href="https://doc.rust-lang.org/1.59.0/std/primitive.str.html">str</a>) -> <a class="primitive" href="https://doc.rust-lang.org/1.59.0/std/primitive.usize.html">usize</a></code></pre></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Compute the display width of <code>text</code> while skipping over ANSI
|
||
escape sequences.</p>
|
||
<h2 id="examples" class="section-header"><a href="#examples">Examples</a></h2>
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">textwrap::core::display_width</span>;
|
||
|
||
<span class="macro">assert_eq!</span>(<span class="ident">display_width</span>(<span class="string">"Café Plain"</span>), <span class="number">10</span>);
|
||
<span class="macro">assert_eq!</span>(<span class="ident">display_width</span>(<span class="string">"\u{1b}[31mCafé Rouge\u{1b}[0m"</span>), <span class="number">10</span>);</code></pre></div>
|
||
<p><strong>Note:</strong> When the <code>unicode-width</code> Cargo feature is disabled, the
|
||
width of a <code>char</code> is determined by a crude approximation which
|
||
simply counts chars below U+1100 as 1 column wide, and all other
|
||
characters as 2 columns wide. With the feature enabled, function
|
||
will correctly deal with <a href="https://en.wikipedia.org/wiki/Combining_character">combining characters</a> in their
|
||
decomposed form (see <a href="https://en.wikipedia.org/wiki/Unicode_equivalence">Unicode equivalence</a>).</p>
|
||
<p>An example of a decomposed character is “é”, which can be
|
||
decomposed into: “e” followed by a combining acute accent: “◌́”.
|
||
Without the <code>unicode-width</code> Cargo feature, every <code>char</code> below
|
||
U+1100 has a width of 1. This includes the combining accent:</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">textwrap::core::display_width</span>;
|
||
|
||
<span class="macro">assert_eq!</span>(<span class="ident">display_width</span>(<span class="string">"Cafe Plain"</span>), <span class="number">10</span>);
|
||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">"unicode-width"</span>)]</span>
|
||
<span class="macro">assert_eq!</span>(<span class="ident">display_width</span>(<span class="string">"Cafe\u{301} Plain"</span>), <span class="number">10</span>);
|
||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">not</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">"unicode-width"</span>))]</span>
|
||
<span class="macro">assert_eq!</span>(<span class="ident">display_width</span>(<span class="string">"Cafe\u{301} Plain"</span>), <span class="number">11</span>);</code></pre></div>
|
||
<h3 id="emojis-and-cjk-characters" class="section-header"><a href="#emojis-and-cjk-characters">Emojis and CJK Characters</a></h3>
|
||
<p>Characters such as emojis and <a href="https://en.wikipedia.org/wiki/CJK_characters">CJK characters</a> used in the
|
||
Chinese, Japanese, and Korean langauges are seen as double-width,
|
||
even if the <code>unicode-width</code> feature is disabled:</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">textwrap::core::display_width</span>;
|
||
|
||
<span class="macro">assert_eq!</span>(<span class="ident">display_width</span>(<span class="string">"😂😭🥺🤣✨😍🙏🥰😊🔥"</span>), <span class="number">20</span>);
|
||
<span class="macro">assert_eq!</span>(<span class="ident">display_width</span>(<span class="string">"你好"</span>), <span class="number">4</span>); <span class="comment">// “Nǐ hǎo” or “Hello” in Chinese</span></code></pre></div>
|
||
<h2 id="limitations" class="section-header"><a href="#limitations">Limitations</a></h2>
|
||
<p>The displayed width of a string cannot always be computed from the
|
||
string alone. This is because the width depends on the rendering
|
||
engine used. This is particularly visible with <a href="https://unicode.org/emoji/charts/full-emoji-modifiers.html">emoji modifier
|
||
sequences</a> where a base emoji is modified with, e.g., skin tone or
|
||
hair color modifiers. It is up to the rendering engine to detect
|
||
this and to produce a suitable emoji.</p>
|
||
<p>A simple example is “❤️”, which consists of “❤” (U+2764: Black
|
||
Heart Symbol) followed by U+FE0F (Variation Selector-16). By
|
||
itself, “❤” is a black heart, but if you follow it with the
|
||
variant selector, you may get a wider red heart.</p>
|
||
<p>A more complex example would be “👨🦰” which should depict a man
|
||
with red hair. Here the computed width is too large — and the
|
||
width differs depending on the use of the <code>unicode-width</code> feature:</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">textwrap::core::display_width</span>;
|
||
|
||
<span class="macro">assert_eq!</span>(<span class="string">"👨🦰"</span>.<span class="ident">chars</span>().<span class="ident">collect</span>::<span class="op"><</span><span class="ident">Vec</span><span class="op"><</span><span class="ident">char</span><span class="op">></span><span class="op">></span>(), [<span class="string">'\u{1f468}'</span>, <span class="string">'\u{200d}'</span>, <span class="string">'\u{1f9b0}'</span>]);
|
||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">"unicode-width"</span>)]</span>
|
||
<span class="macro">assert_eq!</span>(<span class="ident">display_width</span>(<span class="string">"👨🦰"</span>), <span class="number">4</span>);
|
||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">not</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">"unicode-width"</span>))]</span>
|
||
<span class="macro">assert_eq!</span>(<span class="ident">display_width</span>(<span class="string">"👨🦰"</span>), <span class="number">6</span>);</code></pre></div>
|
||
<p>This happens because the grapheme consists of three code points:
|
||
“👨” (U+1F468: Man), Zero Width Joiner (U+200D), and “🦰”
|
||
(U+1F9B0: Red Hair). You can see them above in the test. With
|
||
<code>unicode-width</code> enabled, the ZWJ is correctly seen as having zero
|
||
width, without it is counted as a double-width character.</p>
|
||
<h3 id="terminal-support" class="section-header"><a href="#terminal-support">Terminal Support</a></h3>
|
||
<p>Modern browsers typically do a great job at combining characters
|
||
as shown above, but terminals often struggle more. As an example,
|
||
Gnome Terminal version 3.38.1, shows “❤️” as a big red heart, but
|
||
shows “👨🦰” as “👨🦰”.</p>
|
||
</div></details></section><section id="search" class="content hidden"></section></div></main><div id="rustdoc-vars" data-root-path="../../" data-current-crate="textwrap" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.59.0 (9d1b2106e 2022-02-23)" ></div>
|
||
</body></html> |