refactor(org): cleanup
This commit is contained in:
parent
05cfe17f6a
commit
74fd77dba2
|
@ -25,5 +25,6 @@ memchr = "2.2.0"
|
||||||
serde = { version = "1.0.93", optional = true }
|
serde = { version = "1.0.93", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
pretty_assertions = "0.6.1"
|
||||||
serde_json = "1.0.39"
|
serde_json = "1.0.39"
|
||||||
slugify = "0.1.0"
|
slugify = "0.1.0"
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
||||||
extern crate orgize;
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
use orgize::Org;
|
use orgize::Org;
|
||||||
|
|
|
@ -121,10 +121,9 @@ pub trait HtmlHandler<E: From<Error>> {
|
||||||
}
|
}
|
||||||
fn snippet<W: Write>(&mut self, mut w: W, snippet: &Snippet<'_>) -> Result<(), E> {
|
fn snippet<W: Write>(&mut self, mut w: W, snippet: &Snippet<'_>) -> Result<(), E> {
|
||||||
if snippet.name.eq_ignore_ascii_case("HTML") {
|
if snippet.name.eq_ignore_ascii_case("HTML") {
|
||||||
Ok(write!(w, "{}", snippet.value)?)
|
write!(w, "{}", snippet.value)?;
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
fn target<W: Write>(&mut self, mut w: W, target: &Target<'_>) -> Result<(), E> {
|
fn target<W: Write>(&mut self, mut w: W, target: &Target<'_>) -> Result<(), E> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -415,6 +415,9 @@ impl<'a> Iterator for Iter<'a> {
|
||||||
if let Some(child_node) = node.first_child() {
|
if let Some(child_node) = node.first_child() {
|
||||||
self.node = child_node;
|
self.node = child_node;
|
||||||
self.start_event()
|
self.start_event()
|
||||||
|
} else if let Some(sibling_node) = node.next_sibling() {
|
||||||
|
self.node = sibling_node;
|
||||||
|
self.start_event()
|
||||||
} else if let Some(parent_node) = node.parent() {
|
} else if let Some(parent_node) = node.parent() {
|
||||||
self.node = parent_node;
|
self.node = parent_node;
|
||||||
self.end_event()
|
self.end_event()
|
||||||
|
|
162
src/org.rs
162
src/org.rs
|
@ -4,7 +4,7 @@ use crate::iter::Iter;
|
||||||
|
|
||||||
use indextree::{Arena, NodeId};
|
use indextree::{Arena, NodeId};
|
||||||
use jetscii::bytes;
|
use jetscii::bytes;
|
||||||
use memchr::{memchr_iter, memrchr_iter};
|
use memchr::{memchr, memchr_iter, memrchr_iter};
|
||||||
use std::io::{Error, Write};
|
use std::io::{Error, Write};
|
||||||
|
|
||||||
pub struct Org<'a> {
|
pub struct Org<'a> {
|
||||||
|
@ -206,53 +206,60 @@ impl<'a> Org<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_elements_children(&mut self, mut begin: usize, end: usize, node: NodeId) {
|
fn parse_elements_children(&mut self, begin: usize, end: usize, node: NodeId) {
|
||||||
'out: while begin < end {
|
|
||||||
let text = &self.text[begin..end];
|
let text = &self.text[begin..end];
|
||||||
|
let mut pos = 0;
|
||||||
|
|
||||||
if let Some((ty, off)) = self.parse_element(begin, end) {
|
if let Some((ty, off)) = self.parse_element(begin, end) {
|
||||||
let new_node = self.arena.new_node(ty);
|
let new_node = self.arena.new_node(ty);
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
begin += off;
|
pos += off;
|
||||||
continue 'out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pos = 0;
|
let mut last_end = pos;
|
||||||
for i in memchr_iter(b'\n', text.as_bytes()) {
|
|
||||||
if text.as_bytes()[pos..i].iter().all(u8::is_ascii_whitespace) {
|
while pos < text.len() {
|
||||||
let (end, _) = skip_empty_lines(&text[i..]);
|
let i = memchr(b'\n', &text.as_bytes()[pos..]).unwrap_or(text.len() - pos);
|
||||||
|
if text.as_bytes()[pos..pos + i]
|
||||||
|
.iter()
|
||||||
|
.all(u8::is_ascii_whitespace)
|
||||||
|
{
|
||||||
|
let (end, _) = skip_empty_lines(&text[pos + i..]);
|
||||||
let new_node = self.arena.new_node(Element::Paragraph {
|
let new_node = self.arena.new_node(Element::Paragraph {
|
||||||
begin,
|
begin: begin + last_end,
|
||||||
end: begin + i + end,
|
end: begin + pos + 1 + i + end,
|
||||||
contents_begin: begin,
|
contents_begin: begin + last_end,
|
||||||
contents_end: begin + pos,
|
contents_end: begin + pos,
|
||||||
});
|
});
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
begin += i + end;
|
pos += i + end + 1;
|
||||||
continue 'out;
|
last_end = pos;
|
||||||
} else if let Some((ty, off)) = self.parse_element(begin + pos, end) {
|
} else if let Some((ty, off)) = self.parse_element(begin + pos, end) {
|
||||||
|
if last_end != pos {
|
||||||
let new_node = self.arena.new_node(Element::Paragraph {
|
let new_node = self.arena.new_node(Element::Paragraph {
|
||||||
begin,
|
begin: begin + last_end,
|
||||||
end: begin + pos,
|
end: begin + pos,
|
||||||
contents_begin: begin,
|
contents_begin: begin + last_end,
|
||||||
contents_end: begin + pos,
|
contents_end: begin + pos,
|
||||||
});
|
});
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
|
}
|
||||||
let new_node = self.arena.new_node(ty);
|
let new_node = self.arena.new_node(ty);
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
begin += pos + off;
|
pos += off;
|
||||||
continue 'out;
|
last_end = pos;
|
||||||
|
} else {
|
||||||
|
pos += i + 1;
|
||||||
}
|
}
|
||||||
pos = i + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if begin + last_end < end {
|
||||||
let new_node = self.arena.new_node(Element::Paragraph {
|
let new_node = self.arena.new_node(Element::Paragraph {
|
||||||
begin,
|
begin: begin + last_end,
|
||||||
end,
|
end,
|
||||||
contents_begin: begin,
|
contents_begin: begin + last_end,
|
||||||
contents_end: if text.ends_with('\n') { end - 1 } else { end },
|
contents_end: if text.ends_with('\n') { end - 1 } else { end },
|
||||||
});
|
});
|
||||||
begin = end;
|
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,80 +393,99 @@ impl<'a> Org<'a> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_objects_children(&mut self, mut begin: usize, end: usize, node: NodeId) {
|
fn parse_objects_children(&mut self, begin: usize, end: usize, node: NodeId) {
|
||||||
'out: while begin < end {
|
if begin >= end {
|
||||||
let bytes = self.text[begin..end].as_bytes();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut pos = 0;
|
||||||
|
|
||||||
match bytes[0] {
|
|
||||||
b'{' | b' ' | b'"' | b',' | b'(' | b'\n' => {
|
|
||||||
if let Some((ty, off)) = self.parse_object(begin + 1, end) {
|
|
||||||
let new_node = self.arena.new_node(Element::Text {
|
|
||||||
value: &self.text[begin..=begin],
|
|
||||||
begin,
|
|
||||||
end,
|
|
||||||
});
|
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
|
||||||
let new_node = self.arena.new_node(ty);
|
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
|
||||||
begin += 1 + off;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
if let Some((ty, off)) = self.parse_object(begin, end) {
|
if let Some((ty, off)) = self.parse_object(begin, end) {
|
||||||
let new_node = self.arena.new_node(ty);
|
let new_node = self.arena.new_node(ty);
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
begin += off;
|
pos += off;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let bs = bytes!(b'@', b' ', b'"', b'(', b'\n', b'{', b'<', b'[');
|
let mut last_end = pos;
|
||||||
let mut pos = 0;
|
let text = &self.text[begin..end];
|
||||||
while let Some(off) = bs.find(&bytes[pos..]) {
|
while let Some(off) = bytes!(b'@', b'<', b'[', b' ', b'(', b'{', b'\'', b'"', b'\n')
|
||||||
|
.find(&text[pos..].as_bytes())
|
||||||
|
{
|
||||||
pos += off;
|
pos += off;
|
||||||
assert!(begin + pos <= end);
|
match text.as_bytes()[pos] {
|
||||||
match bytes[pos] {
|
b'{' => {
|
||||||
b'{' | b' ' | b'"' | b',' | b'(' | b'\n' => {
|
if let Some((ty, off)) = self.parse_object(begin + pos, end) {
|
||||||
if let Some((ty, off)) = self.parse_object(begin + pos + 1, end) {
|
if last_end != pos {
|
||||||
let new_node = self.arena.new_node(Element::Text {
|
let new_node = self.arena.new_node(Element::Text {
|
||||||
value: &self.text[begin..=begin + pos],
|
value: &text[last_end..pos],
|
||||||
begin,
|
begin: begin + last_end,
|
||||||
end,
|
end: begin + pos,
|
||||||
|
});
|
||||||
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
|
}
|
||||||
|
let new_node = self.arena.new_node(ty);
|
||||||
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
|
pos += off;
|
||||||
|
last_end = pos;
|
||||||
|
} else if let Some((ty, off)) = self.parse_object(begin + pos + 1, end) {
|
||||||
|
let new_node = self.arena.new_node(Element::Text {
|
||||||
|
value: &text[last_end..=pos],
|
||||||
|
begin: begin + last_end,
|
||||||
|
end: begin + pos + 1,
|
||||||
});
|
});
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
let new_node = self.arena.new_node(ty);
|
let new_node = self.arena.new_node(ty);
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
begin += pos + 1 + off;
|
pos += off + 1;
|
||||||
continue 'out;
|
last_end = pos;
|
||||||
|
} else {
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b' ' | b'(' | b'\'' | b'"' | b'\n' => {
|
||||||
|
if let Some((ty, off)) = self.parse_object(begin + pos + 1, end) {
|
||||||
|
let new_node = self.arena.new_node(Element::Text {
|
||||||
|
value: &text[last_end..=pos],
|
||||||
|
begin: begin + last_end,
|
||||||
|
end: begin + pos + 1,
|
||||||
|
});
|
||||||
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
|
let new_node = self.arena.new_node(ty);
|
||||||
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
|
pos += off + 1;
|
||||||
|
last_end = pos;
|
||||||
|
} else {
|
||||||
|
pos += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if let Some((ty, off)) = self.parse_object(begin + pos, end) {
|
if let Some((ty, off)) = self.parse_object(begin + pos, end) {
|
||||||
|
if last_end != pos {
|
||||||
let new_node = self.arena.new_node(Element::Text {
|
let new_node = self.arena.new_node(Element::Text {
|
||||||
value: &self.text[begin..begin + pos],
|
value: &text[last_end..pos],
|
||||||
begin,
|
begin: begin + last_end,
|
||||||
end,
|
end: begin + pos,
|
||||||
});
|
});
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
|
}
|
||||||
let new_node = self.arena.new_node(ty);
|
let new_node = self.arena.new_node(ty);
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
begin += pos + off;
|
pos += off;
|
||||||
continue 'out;
|
last_end = pos;
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
}
|
|
||||||
pos += 1;
|
pos += 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if begin + last_end < end {
|
||||||
let new_node = self.arena.new_node(Element::Text {
|
let new_node = self.arena.new_node(Element::Text {
|
||||||
value: &self.text[begin..end],
|
value: &text[last_end..],
|
||||||
begin,
|
begin: begin + last_end,
|
||||||
end,
|
end,
|
||||||
});
|
});
|
||||||
node.append(new_node, &mut self.arena).unwrap();
|
node.append(new_node, &mut self.arena).unwrap();
|
||||||
begin = end;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
extern crate orgize;
|
|
||||||
|
|
||||||
use orgize::Org;
|
use orgize::Org;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
macro_rules! html_test {
|
macro_rules! test_suite {
|
||||||
($name:ident, $content:expr, $expected:expr) => {
|
($name:ident, $content:expr, $expected:expr) => {
|
||||||
#[test]
|
#[test]
|
||||||
fn $name() {
|
fn $name() {
|
||||||
|
@ -16,13 +15,14 @@ macro_rules! html_test {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
html_test!(
|
test_suite!(
|
||||||
emphasis,
|
emphasis,
|
||||||
"*bold*, /italic/,_underlined_, =verbatim= and ~code~",
|
"*bold*, /italic/,\n_underlined_, =verbatim= and ~code~",
|
||||||
"<main><section><p><b>bold</b>, <i>italic</i>,<u>underlined</u>, <code>verbatim</code> and <code>code</code></p></section></main>"
|
"<main><section><p><b>bold</b>, <i>italic</i>,\n<u>underlined</u>, \
|
||||||
|
<code>verbatim</code> and <code>code</code></p></section></main>"
|
||||||
);
|
);
|
||||||
|
|
||||||
html_test!(
|
test_suite!(
|
||||||
section_and_headline,
|
section_and_headline,
|
||||||
r#"* Title 1
|
r#"* Title 1
|
||||||
*Section 1*
|
*Section 1*
|
||||||
|
@ -42,7 +42,7 @@ _Section 2_
|
||||||
<section><p><code>Section 4</code></p></section></main>"
|
<section><p><code>Section 4</code></p></section></main>"
|
||||||
);
|
);
|
||||||
|
|
||||||
html_test!(
|
test_suite!(
|
||||||
list,
|
list,
|
||||||
r#"+ 1
|
r#"+ 1
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ html_test!(
|
||||||
</ul></section></main>"
|
</ul></section></main>"
|
||||||
);
|
);
|
||||||
|
|
||||||
html_test!(
|
test_suite!(
|
||||||
snippet,
|
snippet,
|
||||||
"@@html:<del>@@delete this@@html:</del>@@",
|
"@@html:<del>@@delete this@@html:</del>@@",
|
||||||
"<main><section><p><del>delete this</del></p></section></main>"
|
"<main><section><p><del>delete this</del></p></section></main>"
|
||||||
|
|
Loading…
Reference in a new issue