forked from mars/tml
Layout lists
This commit is contained in:
parent
8ae57a2413
commit
d7c93ee776
|
@ -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()
|
||||
|
|
|
@ -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