Compare commits
2 Commits
b7684c5f24
...
d7c93ee776
Author | SHA1 | Date |
---|---|---|
mars | d7c93ee776 | |
mars | 8ae57a2413 |
|
@ -41,6 +41,18 @@ lines.")
|
|||
|
||||
(ol
|
||||
(li "List entry 1")
|
||||
(ul
|
||||
(li "Unordered list subentry")
|
||||
(li "Unordered list subentry")
|
||||
(li "Unordered list subentry")
|
||||
(li "Unordered list subentry"))
|
||||
(li "List entry 2")
|
||||
(li "List entry 3"))
|
||||
(ol
|
||||
(li "Ordered list subentry")
|
||||
(li "Ordered list subentry"))
|
||||
(li "List entry 3")
|
||||
(ul
|
||||
(li "Super long list item: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
|
||||
))
|
||||
)
|
||||
|
||||
|
|
|
@ -2,9 +2,13 @@ use crate::style::Stylesheet;
|
|||
use crate::tag::*;
|
||||
|
||||
impl TextTag {
|
||||
pub fn layout(&self, style: &Stylesheet, available_width: usize) -> Vec<String> {
|
||||
pub fn layout<'a>(
|
||||
&self,
|
||||
style: &Stylesheet,
|
||||
options: impl Into<textwrap::Options<'a>>,
|
||||
) -> Vec<String> {
|
||||
let styled = self.style(style);
|
||||
textwrap::wrap(&styled, available_width)
|
||||
textwrap::wrap(&styled, options)
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
|
@ -88,13 +92,75 @@ impl BlockTag {
|
|||
.collect()
|
||||
}
|
||||
P => self.layout_text_children(style, available_width),
|
||||
Ul => self.layout_list_items(style, available_width, false),
|
||||
Ol => self.layout_list_items(style, available_width, true),
|
||||
Li | Tr | Td => panic!("{:?} tag cannot be directly laid out", self.kind),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn layout_text_children(&self, style: &Stylesheet, available_width: usize) -> Vec<String> {
|
||||
pub fn layout_list_items(
|
||||
&self,
|
||||
style: &Stylesheet,
|
||||
available_width: usize,
|
||||
ordered: bool,
|
||||
) -> Vec<String> {
|
||||
let indent = style.list_indent;
|
||||
let mut lines = Vec::new();
|
||||
let mut index = 1;
|
||||
let spacer: String = std::iter::repeat(" ").take(indent).collect();
|
||||
let mut prefix = format!("{:>width$} ", style.ul_prefix, width = indent - 2);
|
||||
|
||||
let available_width = if available_width > indent {
|
||||
available_width - indent
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
for child in self.children.iter() {
|
||||
if ordered {
|
||||
prefix = format!("{:>width$}. ", index, width = indent - 2);
|
||||
}
|
||||
|
||||
let options = textwrap::Options::new(available_width)
|
||||
.initial_indent(&prefix)
|
||||
.subsequent_indent(&spacer);
|
||||
|
||||
match child {
|
||||
BlockNode::Text(tag) => {
|
||||
index += 1;
|
||||
let mut li = tag.layout(style, options);
|
||||
lines.append(&mut li);
|
||||
}
|
||||
BlockNode::Block(tag) => {
|
||||
let li = match tag.kind {
|
||||
BlockTagKind::Ol => tag.layout_list_items(style, available_width, true),
|
||||
BlockTagKind::Ul => tag.layout_list_items(style, available_width, false),
|
||||
BlockTagKind::Li => {
|
||||
index += 1;
|
||||
let mut li = tag.layout_text_children(style, options);
|
||||
lines.append(&mut li);
|
||||
continue;
|
||||
}
|
||||
_ => panic!("Unexpected {:?} in {:?}", tag.kind, self.kind),
|
||||
};
|
||||
|
||||
lines.extend(li.into_iter().map(|line| format!("{}{}", spacer, line)));
|
||||
}
|
||||
BlockNode::Leaf(_) => panic!("Unexpected leaf tag in {:?}", self.kind),
|
||||
}
|
||||
}
|
||||
|
||||
lines
|
||||
}
|
||||
|
||||
pub fn layout_text_children<'a>(
|
||||
&self,
|
||||
style: &Stylesheet,
|
||||
options: impl Into<textwrap::Options<'a>>,
|
||||
) -> Vec<String> {
|
||||
let styled = self.style_text_children(style);
|
||||
textwrap::wrap(&styled, available_width)
|
||||
textwrap::wrap(&styled, options)
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
|
|
|
@ -20,7 +20,7 @@ fn main() {
|
|||
|
||||
let dom = parse::Parser::parse(&expr);
|
||||
let style = Stylesheet::default();
|
||||
let width = 4;
|
||||
let width = 40;
|
||||
|
||||
for tag in dom.tags.iter() {
|
||||
for line in tag.layout(&style, width) {
|
||||
|
|
|
@ -29,7 +29,7 @@ impl Default for Stylesheet {
|
|||
italic: Style::new().italic(),
|
||||
strikethrough: Style::new().strikethrough(),
|
||||
bullet: Black.into(),
|
||||
ul_prefix: "* ".to_string(),
|
||||
ul_prefix: "*".to_string(),
|
||||
list_indent: 4,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue