Skip to content

Commit 6db2dde

Browse files
authored
Replace ansi feature with plugin (#138)
* Replace ansi feature with plugin * Don't depend on ansi parser types in the core
1 parent 2f88bbf commit 6db2dde

File tree

16 files changed

+310
-327
lines changed

16 files changed

+310
-327
lines changed

.github/workflows/rust.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,14 @@ jobs:
104104
compare -metric AE ./assets/alignment-vertical.png ./target/screenshots/alignment-vertical.png result.png
105105
EG_SIMULATOR_DUMP="./target/screenshots/paragraph_spacing.png" cargo run --example paragraph_spacing
106106
compare -metric AE ./assets/paragraph_spacing.png ./target/screenshots/paragraph_spacing.png result.png
107+
EG_SIMULATOR_DUMP="./target/screenshots/plugin-ansi.png" cargo run --example plugin-ansi
108+
compare -metric AE ./assets/plugin-ansi.png ./target/screenshots/plugin-ansi.png result.png
107109
EG_SIMULATOR_DUMP="./target/screenshots/plugin-tail.png" cargo run --example plugin-tail
108110
compare -metric AE ./assets/plugin-tail.png ./target/screenshots/plugin-tail.png result.png
109111
EG_SIMULATOR_DUMP="./target/screenshots/special-characters.png" cargo run --example special-characters
110112
compare -metric AE ./assets/special-characters.png ./target/screenshots/special-characters.png result.png
111113
EG_SIMULATOR_DUMP="./target/screenshots/special-characters-tabs.png" cargo run --example special-characters-tabs
112114
compare -metric AE ./assets/special-characters-tabs.png ./target/screenshots/special-characters-tabs.png result.png
113-
EG_SIMULATOR_DUMP="./target/screenshots/styles-ansi.png" cargo run --example styles-ansi
114-
compare -metric AE ./assets/styles-ansi.png ./target/screenshots/styles-ansi.png result.png
115115
EG_SIMULATOR_DUMP="./target/screenshots/styles-plugin.png" cargo run --example styles-plugin --features=plugin
116116
compare -metric AE ./assets/styles-plugin.png ./target/screenshots/styles-plugin.png result.png
117117
EG_SIMULATOR_DUMP="./target/screenshots/styles-static.png" cargo run --example styles-static

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Unreleased
1212
* [#137] Allow using multiple plugins.
1313
* [#136] `Cursor` is now public.
1414
* [#136] Added `TextBox::take_plugins()`.
15+
* [#138] `Ansi` plugin to parse ANSI escape sequences.
16+
* [#138] `Token::MoveCursor` and `Token::ChangeTextStyle`
1517

1618
## Changed:
1719

@@ -26,13 +28,15 @@ Unreleased
2628
## Removed:
2729

2830
* [#134] `Scrolling` vertical alignment
31+
* [#138] `ansi` feature flag
2932

3033
[#133]: https://github.com/embedded-graphics/embedded-text/pull/133
3134
[#134]: https://github.com/embedded-graphics/embedded-text/pull/134
3235
[#135]: https://github.com/embedded-graphics/embedded-text/pull/135
3336
[#136]: https://github.com/embedded-graphics/embedded-text/pull/136
3437
[#137]: https://github.com/embedded-graphics/embedded-text/pull/137
3538
[#140]: https://github.com/embedded-graphics/embedded-text/pull/140
39+
[#138]: https://github.com/embedded-graphics/embedded-text/pull/138
3640

3741
0.5.0-beta.2 (2021-07-10)
3842
==========================

Cargo.toml

+3-4
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ exclude = [
1515
]
1616

1717
[features]
18-
ansi = ["ansi-parser", "as-slice"]
1918
plugin = []
20-
default = ["ansi"]
19+
default = []
2120

2221
[[example]]
2322
name = "interactive-editor"
@@ -34,8 +33,8 @@ required-features = ["plugin"]
3433
[dependencies]
3534
az = "1.1"
3635
embedded-graphics = "0.7.0"
37-
ansi-parser = { version = "0.8.0", default-features = false, optional = true }
38-
as-slice = { version = "0.1.4", optional = true }
36+
ansi-parser = { version = "0.8.0", default-features = false }
37+
as-slice = { version = "0.1.4" }
3938
object-chain = "0.1"
4039

4140
[dev-dependencies]

README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ This crate provides a configurable `TextBox` to render multiline text inside a b
2323
- carriage return (`\r`)
2424
- tab (`\t`) with configurable tab size
2525

26-
`TextBox` also supports text coloring using [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code).
26+
`TextBox` also supports text coloring using [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) via the `Ansi` plugin.
2727

2828
### Example
2929

@@ -32,7 +32,7 @@ The examples are based on [the embedded-graphics simulator]. The simulator is bu
3232

3333
![embedded-text example](https://raw.githubusercontent.com/embedded-graphics/embedded-text/master/assets/paragraph_spacing.png)
3434

35-
![embedded-text example with colored text](https://raw.githubusercontent.com/embedded-graphics/embedded-text/master/assets/styles-ansi.png)
35+
![embedded-text example with colored text](https://raw.githubusercontent.com/embedded-graphics/embedded-text/master/assets/plugin-ansi.png)
3636

3737
```rust
3838
use embedded_graphics::{
@@ -93,7 +93,6 @@ fn main() {
9393

9494
## Cargo features
9595

96-
* `ansi`: enables ANSI sequence support. This feature is enabled by default.
9796
* `plugin` (*experimental*): allows the user to implement plugins.
9897

9998
[embedded-graphics]: https://github.com/embedded-graphics/embedded-graphics/
File renamed without changes.

examples/styles-ansi.rs renamed to examples/plugin-ansi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use embedded_graphics::{
1111
text::LineHeight,
1212
};
1313
use embedded_graphics_simulator::{OutputSettingsBuilder, SimulatorDisplay, Window};
14-
use embedded_text::{style::TextBoxStyleBuilder, TextBox};
14+
use embedded_text::{plugin::ansi::Ansi, style::TextBoxStyleBuilder, TextBox};
1515
use std::convert::Infallible;
1616

1717
fn main() -> Result<(), Infallible> {
@@ -52,6 +52,7 @@ fn main() -> Result<(), Infallible> {
5252
character_style,
5353
textbox_style,
5454
)
55+
.add_plugin(Ansi::new())
5556
.draw(&mut display)?;
5657

5758
// Set up the window and show the display's contents.

examples/special-characters-tabs.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use embedded_graphics_simulator::{
1313
BinaryColorTheme, OutputSettingsBuilder, SimulatorDisplay, Window,
1414
};
1515
use embedded_text::{
16+
plugin::ansi::Ansi,
1617
style::{HeightMode, TabSize, TextBoxStyleBuilder},
1718
TextBox,
1819
};
@@ -46,7 +47,8 @@ fn main() {
4647
let bounds = Rectangle::new(Point::zero(), Size::new(180, 0));
4748

4849
// Create the text box and apply styling options.
49-
let text_box = TextBox::with_textbox_style(text, bounds, character_style, textbox_style);
50+
let text_box = TextBox::with_textbox_style(text, bounds, character_style, textbox_style)
51+
.add_plugin(Ansi::new());
5052

5153
// Create a simulated display with the dimensions of the text box.
5254
let mut display = SimulatorDisplay::new(text_box.bounding_box().size);

src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@
9191
//!
9292
//! ## Cargo features
9393
//!
94-
//! * `ansi`: enables ANSI sequence support. This feature is enabled by default.
9594
//! * `plugin` (*experimental*): allows the user to implement plugins.
9695
//!
9796
//! [embedded-graphics]: https://github.com/embedded-graphics/embedded-graphics/

src/parser/mod.rs

+8-89
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
//! tokens
1717
//! );
1818
//! ```
19-
#[cfg(feature = "ansi")]
20-
use ansi_parser::AnsiSequence;
2119
use core::{marker::PhantomData, str::Chars};
2220
use embedded_graphics::{prelude::PixelColor, text::DecorationColor};
2321

@@ -70,9 +68,13 @@ where
7068
/// Change of text style.
7169
ChangeTextStyle(ChangeTextStyle<C>),
7270

73-
/// An ANSI escape sequence
74-
#[cfg(feature = "ansi")]
75-
EscapeSequence(AnsiSequence),
71+
/// Move the cursor by a number of characters.
72+
MoveCursor {
73+
/// Number of characters to move.
74+
chars: i32,
75+
/// True to draw over the area of movement with the background color.
76+
draw_background: bool,
77+
},
7678
}
7779

7880
/// Text parser. Turns a string into a stream of [`Token`] objects.
@@ -90,13 +92,11 @@ where
9092
pub(crate) const SPEC_CHAR_NBSP: char = '\u{a0}';
9193
pub(crate) const SPEC_CHAR_ZWSP: char = '\u{200b}';
9294
pub(crate) const SPEC_CHAR_SHY: char = '\u{ad}';
93-
pub(crate) const SPEC_CHAR_ESCAPE: char = '\x1b';
9495

9596
fn is_word_char(c: char) -> bool {
9697
// Word tokens are terminated when a whitespace, zwsp or shy character is found. An exception
9798
// to this rule is the nbsp, which is whitespace but is included in the word.
98-
(!c.is_whitespace() || c == SPEC_CHAR_NBSP)
99-
&& ![SPEC_CHAR_ZWSP, SPEC_CHAR_SHY, SPEC_CHAR_ESCAPE].contains(&c)
99+
(!c.is_whitespace() || c == SPEC_CHAR_NBSP) && ![SPEC_CHAR_ZWSP, SPEC_CHAR_SHY].contains(&c)
100100
}
101101

102102
fn is_space_char(c: char) -> bool {
@@ -185,14 +185,6 @@ where
185185
string.get_unchecked(0..c.len_utf8())
186186
},
187187
)),
188-
#[cfg(feature = "ansi")]
189-
SPEC_CHAR_ESCAPE => ansi_parser::parse_escape(string).map_or(
190-
Some(Token::EscapeSequence(AnsiSequence::Escape)),
191-
|(string, output)| {
192-
self.inner = string.chars();
193-
Some(Token::EscapeSequence(output))
194-
},
195-
),
196188

197189
// count consecutive whitespace
198190
_ => {
@@ -320,76 +312,3 @@ mod test {
320312
);
321313
}
322314
}
323-
324-
#[cfg(all(feature = "ansi", test))]
325-
mod ansi_parser_tests {
326-
327-
use super::{test::assert_tokens, Token};
328-
use ansi_parser::AnsiSequence;
329-
use heapless::Vec;
330-
331-
#[test]
332-
fn escape_char_ignored_if_not_ansi_sequence() {
333-
assert_tokens(
334-
"foo\x1bbar",
335-
vec![
336-
Token::Word("foo"),
337-
Token::EscapeSequence(AnsiSequence::Escape),
338-
Token::Word("bar"),
339-
],
340-
);
341-
342-
assert_tokens(
343-
"foo\x1b[bar",
344-
vec![
345-
Token::Word("foo"),
346-
Token::EscapeSequence(AnsiSequence::Escape),
347-
Token::Word("[bar"),
348-
],
349-
);
350-
351-
// can escape the escape char
352-
assert_tokens(
353-
"foo\x1b\x1bbar",
354-
vec![
355-
Token::Word("foo"),
356-
Token::EscapeSequence(AnsiSequence::Escape),
357-
Token::Word("bar"),
358-
],
359-
);
360-
}
361-
362-
#[test]
363-
fn escape_char_colors() {
364-
assert_tokens(
365-
"foo\x1b[34mbar",
366-
vec![
367-
Token::Word("foo"),
368-
Token::EscapeSequence(AnsiSequence::SetGraphicsMode(
369-
Vec::from_slice(&[34]).unwrap(),
370-
)),
371-
Token::Word("bar"),
372-
],
373-
);
374-
assert_tokens(
375-
"foo\x1b[95mbar",
376-
vec![
377-
Token::Word("foo"),
378-
Token::EscapeSequence(AnsiSequence::SetGraphicsMode(
379-
Vec::from_slice(&[95]).unwrap(),
380-
)),
381-
Token::Word("bar"),
382-
],
383-
);
384-
assert_tokens(
385-
"foo\x1b[48;5;16mbar",
386-
vec![
387-
Token::Word("foo"),
388-
Token::EscapeSequence(AnsiSequence::SetGraphicsMode(
389-
Vec::from_slice(&[48, 5, 16]).unwrap(),
390-
)),
391-
Token::Word("bar"),
392-
],
393-
);
394-
}
395-
}

0 commit comments

Comments
 (0)