Skip to content

Commit

Permalink
Backport list fix (#181)
Browse files Browse the repository at this point in the history
* Add tests for elements nested in a list item (#176)

* Backport fix for element nested in numbered list

* Fix list prefix for footnotes

* Try to get link anchor before using open to open it

---------

Co-authored-by: Lucas Timmins <timmins.s.lucas@gmail.com>

---------

Co-authored-by: Lucas Timmins <timmins.s.lucas@gmail.com>
  • Loading branch information
CosmicHorrorDev and trimental committed Dec 2, 2023
1 parent 0ce0297 commit 9956692
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 48 deletions.
1 change: 0 additions & 1 deletion src/interpreter/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ pub struct TextOptions {

pub enum Element {
List(List),
ListItem,
Input,
Table(Table),
TableRow(Vec<TextBox>),
Expand Down
76 changes: 37 additions & 39 deletions src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct State {
span_color: [f32; 4],
// Stores the row and a counter of newlines after each image
inline_images: Option<(Row, usize)>,
pending_list_prefix: Option<String>,
}

// Images are loaded in a separate thread and use a callback to indicate when they're finished
Expand Down Expand Up @@ -415,7 +416,31 @@ impl TokenSink for HtmlInterpreter {
"bold" | "strong" => self.state.text_options.bold += 1,
"code" => self.state.text_options.code += 1,
"li" => {
self.state.element_stack.push(html::Element::ListItem);
// Push a pending list prefix based on the list type
let mut list = None;
for element in self.state.element_stack.iter_mut().rev() {
if let html::Element::List(html_list) = element {
list = Some(html_list);
break;
}
}
let list = list.expect("List ended unexpectedly");
if self.current_textbox.texts.is_empty() {
if let html::List {
list_type: html::ListType::Ordered(index),
..
} = list
{
self.state.pending_list_prefix = Some(format!("{}. ", index));
*index += 1;
} else if let html::List {
list_type: html::ListType::Unordered,
..
} = list
{
self.state.pending_list_prefix = Some("· ".to_owned());
}
}
}
"ul" => {
self.push_current_textbox();
Expand Down Expand Up @@ -523,6 +548,9 @@ impl TokenSink for HtmlInterpreter {
if &name.local == "type" {
let value = value.to_string();
if value == "checkbox" {
// Checkbox uses a custom prefix, so remove pending text
// prefix
let _ = self.state.pending_list_prefix.take();
self.push_current_textbox();
self.current_textbox.set_checkbox(Some(
tag.attrs
Expand Down Expand Up @@ -631,7 +659,6 @@ impl TokenSink for HtmlInterpreter {
}
"li" => {
self.push_current_textbox();
self.state.element_stack.pop();
}
"input" => {
self.push_current_textbox();
Expand Down Expand Up @@ -742,45 +769,16 @@ impl TokenSink for HtmlInterpreter {
self.hidpi_scale,
native_color(self.theme.text_color, &self.surface_format),
);
if let Some(html::Element::ListItem) = self.state.element_stack.last() {
let mut list = None;
for element in self.state.element_stack.iter_mut().rev() {
if let html::Element::List(html_list) = element {
list = Some(html_list);
break;
}
}
let list = list.expect("List ended unexpectedly");

if let Some(prefix) = self.state.pending_list_prefix.take() {
if self.current_textbox.texts.is_empty() {
if let html::List {
list_type: html::ListType::Ordered(index),
..
} = list
{
self.current_textbox.texts.push(
Text::new(
format!("{}. ", index),
self.hidpi_scale,
native_color(self.theme.text_color, &self.surface_format),
)
.make_bold(true),
);
*index += 1;
} else if let html::List {
list_type: html::ListType::Unordered,
..
} = list
{
self.current_textbox.texts.push(
Text::new(
"· ".to_string(),
self.hidpi_scale,
native_color(self.theme.text_color, &self.surface_format),
)
.make_bold(true),
self.current_textbox.texts.push(
Text::new(
prefix,
self.hidpi_scale,
native_color(self.theme.text_color, &self.surface_format),
)
}
.make_bold(true),
);
}
}
if self.state.text_options.block_quote >= 1 {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
source: src/interpreter/tests.rs
expression: interpret_md(text)
---
[
TextBox(
TextBox {
indent: 50.0,
texts: [
Text {
text: "1. ",
default_color: Color(BLACK),
style: BOLD ,
..
},
Text {
text: "1st item",
default_color: Color(BLACK),
..
},
],
..
},
),
Spacer(
InvisibleSpacer(5),
),
TextBox(
TextBox {
indent: 50.0,
background_color: Some(Color { r: 0.86, g: 0.88, b: 0.91 }),
is_code_block: true,
texts: [
Text {
text: "fn ",
size: 18.0,
color: Some(Color { r: 0.46, g: 0.27, b: 0.42 }),
..
},
Text {
text: "main",
size: 18.0,
color: Some(Color { r: 0.27, g: 0.36, b: 0.45 }),
..
},
Text {
text: "() {}",
size: 18.0,
color: Some(Color { r: 0.08, g: 0.10, b: 0.13 }),
..
},
],
..
},
),
Spacer(
InvisibleSpacer(5),
),
TextBox(
TextBox {
indent: 50.0,
texts: [
Text {
text: "2. ",
default_color: Color(BLACK),
style: BOLD ,
..
},
Text {
text: "2nd item",
default_color: Color(BLACK),
..
},
],
..
},
),
Spacer(
InvisibleSpacer(5),
),
Spacer(
InvisibleSpacer(5),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
source: src/interpreter/tests.rs
description: " --- md\n\n1. 1st item\n\n Nested paragraph\n\n2. 2nd item\n\n\n --- html\n\n<ol>\n<li>\n<p>1st item</p>\n<p>Nested paragraph</p>\n</li>\n<li>\n<p>2nd item</p>\n</li>\n</ol>\n"
expression: interpret_md(text)
---
[
TextBox(
TextBox {
indent: 50.0,
texts: [
Text {
text: "1. ",
default_color: Color(BLACK),
style: BOLD ,
..
},
Text {
text: "1st item",
default_color: Color(BLACK),
..
},
],
..
},
),
Spacer(
InvisibleSpacer(5),
),
TextBox(
TextBox {
indent: 50.0,
texts: [
Text {
text: "Nested paragraph",
default_color: Color(BLACK),
..
},
],
..
},
),
Spacer(
InvisibleSpacer(5),
),
TextBox(
TextBox {
indent: 50.0,
texts: [
Text {
text: "2. ",
default_color: Color(BLACK),
style: BOLD ,
..
},
Text {
text: "2nd item",
default_color: Color(BLACK),
..
},
],
..
},
),
Spacer(
InvisibleSpacer(5),
),
Spacer(
InvisibleSpacer(5),
),
]
20 changes: 20 additions & 0 deletions src/interpreter/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,24 @@ const ORDERED_LIST_IN_UNORDERED: &str = "\
- bullet
";

const PARA_IN_ORDERED_LIST: &str = "\
1. 1st item
Nested paragraph
2. 2nd item
";

const CODE_IN_ORDERED_LIST: &str = "\
1. 1st item
```rust
fn main() {}
```
2. 2nd item
";

snapshot_interpreted_elements!(
(sanity, SANITY),
(checklist_has_no_text_prefix, CHECKLIST_HAS_NO_TEXT_PREFIX),
Expand All @@ -167,6 +185,8 @@ snapshot_interpreted_elements!(
(unordered_list_in_ordered, UNORDERED_LIST_IN_ORDERED),
(nested_ordered_list, NESTED_ORDERED_LIST),
(ordered_list_in_unordered, ORDERED_LIST_IN_UNORDERED),
(para_in_ordered_list, PARA_IN_ORDERED_LIST),
(code_in_ordered_list, CODE_IN_ORDERED_LIST),
);

/// Spin up a server, so we can test network requests without external services
Expand Down
16 changes: 8 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -536,14 +536,14 @@ impl Inlyne {
}
}
}
} else if open::that(link).is_err() {
if let Some(anchor_pos) =
self.renderer.positioner.anchors.get(link)
{
self.renderer.set_scroll_y(*anchor_pos);
self.window.request_redraw();
self.window.set_cursor_icon(CursorIcon::Default);
}
} else if let Some(anchor_pos) =
self.renderer.positioner.anchors.get(link)
{
self.renderer.set_scroll_y(*anchor_pos);
self.window.request_redraw();
self.window.set_cursor_icon(CursorIcon::Default);
} else {
open::that(link).unwrap();
}
} else if self.renderer.selection.is_none() {
// Only set selection when not over link
Expand Down

0 comments on commit 9956692

Please sign in to comment.