render_tree/
lib.rs

1//! This module defines a tree structure that you can use to build documents
2//! to render with color.
3//!
4//! There are three kinds of nodes in the Render Tree:
5//!
6//! - Lines, which represent content followed by a newline
7//! - Sections, which represent named content that can be targeted by
8//!   style rules.
9//! - Components, which are parameterized chunks of the Render Tree
10//!
11//! The easiest way to build a render tree is using the `tree!` macro:
12//!
13//! ```
14//! #[macro_use]
15//! extern crate render_tree;
16//! extern crate termcolor;
17//! use render_tree::{Document, Line, RenderComponent};
18//! use termcolor::StandardStream;
19//!
20//! fn main() -> std::io::Result<()> {
21//!     let world = "world";
22//!
23//!     let document = tree! {
24//!         <Line as {
25//!             "Hello" {world}
26//!         }>
27//!
28//!         <Line as {
29//!             "Goodbye" {world}
30//!         }>
31//!     };
32//!
33//!     document.write()
34//! }
35//! ```
36//!
37//! This will print out:
38//!
39//! ```text
40//! Hello world
41//! Goodbye world
42//!
43//! ```
44//!
45//! You can use sections and stylesheets to colorize the output:
46//!
47//! ```
48//! #[macro_use]
49//! extern crate render_tree;
50//! extern crate termcolor;
51//! use render_tree::{Document, Line, RenderComponent, Section, Stylesheet};
52//! use render_tree::prelude::*;
53//! use termcolor::StandardStream;
54//!
55//! fn main() -> std::io::Result<()> {
56//!     let world = "world";
57//!
58//!     let document = tree! {
59//!         <Line as {
60//!             <Section name="hello" as { "Hello" }>
61//!             {world}
62//!         }>
63//!
64//!         <Line as {
65//!             <Section name="goodbye" as { "Goodbye"}>
66//!             {world}
67//!         }>
68//!     };
69//!
70//!     let stylesheet = Stylesheet::new()
71//!         .add("hello", "fg: blue")
72//!         .add("goodbye", "fg: red");
73//!
74//!     document.write_styled(&stylesheet)
75//! }
76//! ```
77//!
78//! This will print out:
79//!
80//! ```text
81//! Hello world
82//! Goodbye world
83//!
84//! ```
85//!
86//! with the word "Hello" colored blue and "Goodbye" colored red.
87//!
88//! You can nest sections, which can be targeted by style paths:
89//!
90//!
91//! ```
92//! #[macro_use]
93//! extern crate render_tree;
94//! extern crate termcolor;
95//! use render_tree::{Document, Line, RenderComponent, Section, Stylesheet};
96//! use render_tree::prelude::*;
97//! use termcolor::StandardStream;
98//!
99//! fn main() -> std::io::Result<()> {
100//!     let world = "world";
101//!
102//!     let document = tree! {
103//!         <Line as {
104//!             <Section name="hello-world" as {
105//!                 <Section name="greeting" as { "Hello" }>
106//!                 {world}
107//!             }>
108//!         }>
109//!
110//!         <Line as {
111//!             "Some content in the middle here"
112//!         }>
113//!
114//!         <Line as {
115//!             <Section name="goodbye-world" as {
116//!                 <Section name="greeting" as { "Goodbye" }>
117//!                 {world}
118//!             }>
119//!         }>
120//!     };
121//!
122//!     let stylesheet = Stylesheet::new()
123//!         .add("** greeting", "weight: bold")
124//!         .add("hello-world greeting", "fg: red")
125//!         .add("goodbye-world greeting", "fg: blue");
126//!
127//!     document.write_styled(&stylesheet)
128//! }
129//! ```
130//!
131//! This will print out:
132//!
133//! ```text
134//! Hello world
135//! Some content in the middle here
136//! Goodbye world
137//!
138//! ```
139//!
140//! with the "Hello world" and "Goodbye world" bolded, the word "Hello" colored
141//! red (and bolded, of course), and the word "Goodbye" colored red (and
142//! bolded).
143//!
144//! Globs (`**`) in a rule are superseded by stars (`*`), which are supersede by
145//! literal names. Globs match zero or more section names and stars match exactly
146//! one section name.
147//!
148//! # Using without the `tree!` macro
149//!
150//! It's also easy to build a Render Tree without the macro. Repeating the previous
151//! example without the macro and without the string DSL for the stylesheet:
152//!
153//! ```
154//! #[macro_use]
155//! extern crate render_tree;
156//! extern crate termcolor;
157//! use render_tree::{
158//!     Color,
159//!     Document,
160//!     Line,
161//!     Render,
162//!     RenderComponent,
163//!     Section,
164//!     Selector,
165//!     Segment,
166//!     Style,
167//!     Stylesheet
168//! };
169//! use termcolor::StandardStream;
170//!
171//! fn main() -> std::io::Result<()> {
172//!     let world = "world";
173//!     
174//!     let document = Document::with(
175//!         Line(
176//!             Section("hello-world", |doc|
177//!                 doc.add(
178//!                     Section("greeting", |doc| doc.add("Hello").add(world))
179//!                 )
180//!             )
181//!         )
182//!     ).add(
183//!         Line(
184//!             "Some content in the middle here"
185//!         )
186//!     ).add(
187//!         Line(
188//!             Section("goodbye-world", |doc|
189//!                 doc.add(
190//!                     Section("greeting", |doc| doc.add("Goodbye").add(world))
191//!                 )
192//!             )
193//!         )
194//!     );
195//!
196//!     let stylesheet = Stylesheet::new()
197//!         .add(Selector::glob().add("greeting"), Style::new().bold())
198//!         .add(Selector::name("hello-world").add("greeting"), Style::new().fg(Color::Red))
199//!         .add(Selector::name("goodbye-world").add("greeting"), Style::new().fg(Color::Blue));
200//!
201//!     document.write_styled(&stylesheet)
202//! }
203//! ```
204
205#[macro_use]
206pub mod macros;
207mod component;
208mod debug;
209pub mod document;
210mod helpers;
211pub mod prelude;
212mod render;
213pub mod stylesheet;
214pub(crate) mod utils;
215
216pub use self::component::*;
217pub use self::document::*;
218pub use self::helpers::*;
219pub use self::render::*;
220pub use self::stylesheet::{Color, Segment, Selector, Style, Stylesheet};