feat(elements): comment and fixed width elements
This commit is contained in:
parent
bd1fc756bd
commit
275fbfad34
|
@ -349,4 +349,18 @@ pub enum Element<'a> {
|
||||||
end: usize,
|
end: usize,
|
||||||
value: &'a str,
|
value: &'a str,
|
||||||
},
|
},
|
||||||
|
Comment {
|
||||||
|
#[cfg_attr(all(feature = "serde", not(feature = "extra-serde-info")), serde(skip))]
|
||||||
|
begin: usize,
|
||||||
|
#[cfg_attr(all(feature = "serde", not(feature = "extra-serde-info")), serde(skip))]
|
||||||
|
end: usize,
|
||||||
|
value: &'a str,
|
||||||
|
},
|
||||||
|
FixedWidth {
|
||||||
|
#[cfg_attr(all(feature = "serde", not(feature = "extra-serde-info")), serde(skip))]
|
||||||
|
begin: usize,
|
||||||
|
#[cfg_attr(all(feature = "serde", not(feature = "extra-serde-info")), serde(skip))]
|
||||||
|
end: usize,
|
||||||
|
value: &'a str,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,18 @@ pub trait HtmlHandler<E: From<Error>> {
|
||||||
fn fn_def<W: Write>(&mut self, mut w: W, fn_def: &FnDef<'_>) -> Result<(), E> {
|
fn fn_def<W: Write>(&mut self, mut w: W, fn_def: &FnDef<'_>) -> Result<(), E> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn comment<W: Write>(&mut self, mut w: W, value: &str) -> Result<(), E> {
|
||||||
|
write!(&mut w, "<!--\n")?;
|
||||||
|
self.text(&mut w, value)?;
|
||||||
|
write!(&mut w, "\n-->")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn fixed_width<W: Write>(&mut self, mut w: W, value: &str) -> Result<(), E> {
|
||||||
|
write!(&mut w, "<pre>")?;
|
||||||
|
self.text(&mut w, value)?;
|
||||||
|
write!(&mut w, "</pre>")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DefaultHtmlHandler;
|
pub struct DefaultHtmlHandler;
|
||||||
|
|
124
src/iter.rs
124
src/iter.rs
|
@ -22,6 +22,8 @@ pub enum Container<'a> {
|
||||||
pub enum Event<'a> {
|
pub enum Event<'a> {
|
||||||
Start(Container<'a>),
|
Start(Container<'a>),
|
||||||
End(Container<'a>),
|
End(Container<'a>),
|
||||||
|
Rule,
|
||||||
|
BabelCall(&'a BabelCall<'a>),
|
||||||
Clock(&'a Clock<'a>),
|
Clock(&'a Clock<'a>),
|
||||||
Cookie(&'a Cookie<'a>),
|
Cookie(&'a Cookie<'a>),
|
||||||
Drawer(&'a Drawer<'a>),
|
Drawer(&'a Drawer<'a>),
|
||||||
|
@ -34,14 +36,14 @@ pub enum Event<'a> {
|
||||||
Macros(&'a Macros<'a>),
|
Macros(&'a Macros<'a>),
|
||||||
Planning(Planning<'a>),
|
Planning(Planning<'a>),
|
||||||
RadioTarget(&'a RadioTarget<'a>),
|
RadioTarget(&'a RadioTarget<'a>),
|
||||||
Rule,
|
|
||||||
Snippet(&'a Snippet<'a>),
|
Snippet(&'a Snippet<'a>),
|
||||||
Target(&'a Target<'a>),
|
Target(&'a Target<'a>),
|
||||||
Timestamp(&'a Timestamp<'a>),
|
Timestamp(&'a Timestamp<'a>),
|
||||||
Text(&'a str),
|
|
||||||
Code(&'a str),
|
Code(&'a str),
|
||||||
|
Comment(&'a str),
|
||||||
|
FixedWidth(&'a str),
|
||||||
|
Text(&'a str),
|
||||||
Verbatim(&'a str),
|
Verbatim(&'a str),
|
||||||
BabelCall(&'a BabelCall<'a>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -277,6 +279,14 @@ impl<'a> Iter<'a> {
|
||||||
self.state = State::Start;
|
self.state = State::Start;
|
||||||
Some(Event::Timestamp(timestamp))
|
Some(Event::Timestamp(timestamp))
|
||||||
}
|
}
|
||||||
|
Element::FixedWidth { value, .. } => {
|
||||||
|
self.state = State::Start;
|
||||||
|
Some(Event::FixedWidth(value))
|
||||||
|
}
|
||||||
|
Element::Comment { value, .. } => {
|
||||||
|
self.state = State::Start;
|
||||||
|
Some(Event::Comment(value))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,22 +297,6 @@ impl<'a> Iter<'a> {
|
||||||
self.state = State::Finished;
|
self.state = State::Finished;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Element::BabelCall { call, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::BabelCall(call))
|
|
||||||
}
|
|
||||||
Element::Verbatim { value, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Verbatim(value))
|
|
||||||
}
|
|
||||||
Element::Code { value, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Code(value))
|
|
||||||
}
|
|
||||||
Element::Text { value, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Text(value))
|
|
||||||
}
|
|
||||||
Element::Block { block, .. } => {
|
Element::Block { block, .. } => {
|
||||||
self.state = State::End;
|
self.state = State::End;
|
||||||
Some(Event::End(Container::Block(block)))
|
Some(Event::End(Container::Block(block)))
|
||||||
|
@ -351,97 +345,7 @@ impl<'a> Iter<'a> {
|
||||||
self.state = State::End;
|
self.state = State::End;
|
||||||
Some(Event::End(Container::Underline))
|
Some(Event::End(Container::Underline))
|
||||||
}
|
}
|
||||||
Element::Clock { clock, .. } => {
|
_ => unreachable!(),
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Clock(clock))
|
|
||||||
}
|
|
||||||
Element::Cookie { cookie, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Cookie(cookie))
|
|
||||||
}
|
|
||||||
Element::Drawer { drawer, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Drawer(drawer))
|
|
||||||
}
|
|
||||||
Element::FnDef { fn_def, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::FnDef(fn_def))
|
|
||||||
}
|
|
||||||
Element::FnRef { fn_ref, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::FnRef(fn_ref))
|
|
||||||
}
|
|
||||||
Element::InlineCall { inline_call, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::InlineCall(inline_call))
|
|
||||||
}
|
|
||||||
Element::InlineSrc { inline_src, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::InlineSrc(inline_src))
|
|
||||||
}
|
|
||||||
Element::Keyword { keyword, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Keyword(keyword))
|
|
||||||
}
|
|
||||||
Element::Link { link, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Link(link))
|
|
||||||
}
|
|
||||||
Element::Macros { macros, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Macros(macros))
|
|
||||||
}
|
|
||||||
Element::Planning {
|
|
||||||
deadline,
|
|
||||||
scheduled,
|
|
||||||
closed,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Planning(Planning {
|
|
||||||
deadline: deadline.and_then(|id| {
|
|
||||||
if let Element::Timestamp { timestamp, .. } = &self.arena[id].data {
|
|
||||||
Some(timestamp)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
scheduled: scheduled.and_then(|id| {
|
|
||||||
if let Element::Timestamp { timestamp, .. } = &self.arena[id].data {
|
|
||||||
Some(timestamp)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
closed: closed.and_then(|id| {
|
|
||||||
if let Element::Timestamp { timestamp, .. } = &self.arena[id].data {
|
|
||||||
Some(timestamp)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Element::RadioTarget { radio_target, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::RadioTarget(radio_target))
|
|
||||||
}
|
|
||||||
Element::Rule { .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Rule)
|
|
||||||
}
|
|
||||||
Element::Snippet { snippet, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Snippet(snippet))
|
|
||||||
}
|
|
||||||
Element::Target { target, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Target(target))
|
|
||||||
}
|
|
||||||
Element::Timestamp { timestamp, .. } => {
|
|
||||||
self.state = State::End;
|
|
||||||
Some(Event::Timestamp(timestamp))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
71
src/org.rs
71
src/org.rs
|
@ -73,6 +73,8 @@ impl<'a> Org<'a> {
|
||||||
Verbatim(e) => handler.verbatim(&mut writer, e)?,
|
Verbatim(e) => handler.verbatim(&mut writer, e)?,
|
||||||
BabelCall(e) => handler.babel_call(&mut writer, e)?,
|
BabelCall(e) => handler.babel_call(&mut writer, e)?,
|
||||||
Rule => handler.rule(&mut writer)?,
|
Rule => handler.rule(&mut writer)?,
|
||||||
|
Comment(e) => handler.comment(&mut writer, e)?,
|
||||||
|
FixedWidth(e) => handler.fixed_width(&mut writer, e)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,12 +273,12 @@ impl<'a> Org<'a> {
|
||||||
let (end, _) = skip_empty_lines(&text[pos + i..]);
|
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 + last_end,
|
begin: begin + last_end,
|
||||||
end: begin + pos + 1 + i + end,
|
end: begin + pos + i + end,
|
||||||
contents_begin: begin + last_end,
|
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();
|
||||||
pos += i + end + 1;
|
pos += i + end;
|
||||||
last_end = pos;
|
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 {
|
if last_end != pos {
|
||||||
|
@ -346,8 +348,7 @@ impl<'a> Org<'a> {
|
||||||
// TODO: LaTeX environment
|
// TODO: LaTeX environment
|
||||||
if tail.starts_with("\\begin{") {}
|
if tail.starts_with("\\begin{") {}
|
||||||
|
|
||||||
// rule
|
if tail.starts_with('-') {
|
||||||
if tail.starts_with("-----") {
|
|
||||||
if let Some(end) = Rule::parse(tail) {
|
if let Some(end) = Rule::parse(tail) {
|
||||||
let rule = Element::Rule {
|
let rule = Element::Rule {
|
||||||
begin,
|
begin,
|
||||||
|
@ -370,30 +371,48 @@ impl<'a> Org<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fixed width
|
if tail == ":" || tail.starts_with(": ") || tail.starts_with(":\n") {
|
||||||
if tail.starts_with(": ") || tail.starts_with(":\n") {
|
let mut last_end = 1; // ":"
|
||||||
// let end = line_ends
|
for i in memchr_iter(b'\n', text.as_bytes()) {
|
||||||
// .skip_while(|&i| {
|
last_end = i + 1;
|
||||||
// text[i + 1..].starts_with(": ") || text[i + 1..].starts_with(":\n")
|
let line = &text[last_end..];
|
||||||
// })
|
if !(line == ":" || line.starts_with(": ") || line.starts_with(":\n")) {
|
||||||
// .next()
|
let fixed_width = Element::FixedWidth {
|
||||||
// .map(|i| i + 1)
|
value: &text[0..i + 1],
|
||||||
// .unwrap_or_else(|| text.len());
|
begin,
|
||||||
// let off = end - pos;
|
end: begin + i + 1,
|
||||||
// brk!(Element::FixedWidth(&tail[0..off]), off);
|
};
|
||||||
|
return Some((fixed_width, i + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let fixed_width = Element::FixedWidth {
|
||||||
|
value: &text[0..last_end],
|
||||||
|
begin,
|
||||||
|
end: begin + last_end,
|
||||||
|
};
|
||||||
|
return Some((fixed_width, last_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
// comment
|
if tail == "#" || tail.starts_with("# ") || tail.starts_with("#\n") {
|
||||||
if tail.starts_with("# ") || tail.starts_with("#\n") {
|
let mut last_end = 1; // "#"
|
||||||
// let end = line_ends
|
for i in memchr_iter(b'\n', text.as_bytes()) {
|
||||||
// .skip_while(|&i| {
|
last_end = i + 1;
|
||||||
// text[i + 1..].starts_with("# ") || text[i + 1..].starts_with("#\n")
|
let line = &text[last_end..];
|
||||||
// })
|
if !(line == "#" || line.starts_with("# ") || line.starts_with("#\n")) {
|
||||||
// .next()
|
let fixed_width = Element::Comment {
|
||||||
// .map(|i| i + 1)
|
value: &text[0..i + 1],
|
||||||
// .unwrap_or_else(|| text.len());
|
begin,
|
||||||
// let off = end - pos;
|
end: begin + i + 1,
|
||||||
// brk!(Element::Comment(&tail[0..off]), off);
|
};
|
||||||
|
return Some((fixed_width, i + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let fixed_width = Element::Comment {
|
||||||
|
value: &text[0..last_end],
|
||||||
|
begin,
|
||||||
|
end: begin + last_end,
|
||||||
|
};
|
||||||
|
return Some((fixed_width, last_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
if tail.starts_with("#+") {
|
if tail.starts_with("#+") {
|
||||||
|
|
Loading…
Reference in a new issue