lib wip
This commit is contained in:
parent
c53988cc47
commit
a994228bb5
2 changed files with 55 additions and 32 deletions
10
src/html.rs
10
src/html.rs
|
@ -68,7 +68,13 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<I, W> {
|
||||||
Container::Footnote { .. } => todo!(),
|
Container::Footnote { .. } => todo!(),
|
||||||
Container::Table => self.out.write_str("<table>")?,
|
Container::Table => self.out.write_str("<table>")?,
|
||||||
Container::TableRow => self.out.write_str("<tr>")?,
|
Container::TableRow => self.out.write_str("<tr>")?,
|
||||||
Container::Div => self.out.write_str("<div>")?,
|
Container::Div { class } => {
|
||||||
|
if let Some(c) = class {
|
||||||
|
write!(self.out, r#"<div class="{}">"#, c)?;
|
||||||
|
} else {
|
||||||
|
self.out.write_str("<div>")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
Container::Span => self.out.write_str("<span>")?,
|
Container::Span => self.out.write_str("<span>")?,
|
||||||
Container::Paragraph => self.out.write_str("<p>")?,
|
Container::Paragraph => self.out.write_str("<p>")?,
|
||||||
Container::Heading { level } => write!(self.out, "<h{}>", level)?,
|
Container::Heading { level } => write!(self.out, "<h{}>", level)?,
|
||||||
|
@ -108,7 +114,7 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<I, W> {
|
||||||
Container::Footnote { .. } => todo!(),
|
Container::Footnote { .. } => todo!(),
|
||||||
Container::Table => self.out.write_str("</table>")?,
|
Container::Table => self.out.write_str("</table>")?,
|
||||||
Container::TableRow => self.out.write_str("</tr>")?,
|
Container::TableRow => self.out.write_str("</tr>")?,
|
||||||
Container::Div => self.out.write_str("</div>")?,
|
Container::Div { .. } => self.out.write_str("</div>")?,
|
||||||
Container::Paragraph => self.out.write_str("</p>")?,
|
Container::Paragraph => self.out.write_str("</p>")?,
|
||||||
Container::Heading { level } => write!(self.out, "</h{}>", level)?,
|
Container::Heading { level } => write!(self.out, "</h{}>", level)?,
|
||||||
Container::TableCell => self.out.write_str("</td>")?,
|
Container::TableCell => self.out.write_str("</td>")?,
|
||||||
|
|
77
src/lib.rs
77
src/lib.rs
|
@ -47,7 +47,7 @@ pub enum Container<'s> {
|
||||||
/// A row element of a table.
|
/// A row element of a table.
|
||||||
TableRow,
|
TableRow,
|
||||||
/// A block-level divider element.
|
/// A block-level divider element.
|
||||||
Div,
|
Div { class: Option<&'s str> },
|
||||||
/// A paragraph.
|
/// A paragraph.
|
||||||
Paragraph,
|
Paragraph,
|
||||||
/// A heading.
|
/// A heading.
|
||||||
|
@ -98,7 +98,7 @@ impl<'s> Container<'s> {
|
||||||
| Self::Footnote { .. }
|
| Self::Footnote { .. }
|
||||||
| Self::Table
|
| Self::Table
|
||||||
| Self::TableRow
|
| Self::TableRow
|
||||||
| Self::Div
|
| Self::Div { .. }
|
||||||
| Self::Paragraph
|
| Self::Paragraph
|
||||||
| Self::Heading { .. }
|
| Self::Heading { .. }
|
||||||
| Self::DescriptionTerm
|
| Self::DescriptionTerm
|
||||||
|
@ -131,7 +131,7 @@ impl<'s> Container<'s> {
|
||||||
| Self::Footnote { .. }
|
| Self::Footnote { .. }
|
||||||
| Self::Table
|
| Self::Table
|
||||||
| Self::TableRow
|
| Self::TableRow
|
||||||
| Self::Div => true,
|
| Self::Div { .. } => true,
|
||||||
Self::Paragraph
|
Self::Paragraph
|
||||||
| Self::Heading { .. }
|
| Self::Heading { .. }
|
||||||
| Self::TableCell
|
| Self::TableCell
|
||||||
|
@ -204,8 +204,6 @@ pub enum Atom {
|
||||||
EmDash,
|
EmDash,
|
||||||
/// A thematic break, typically a horizontal rule.
|
/// A thematic break, typically a horizontal rule.
|
||||||
ThematicBreak,
|
ThematicBreak,
|
||||||
/// A blank line.
|
|
||||||
Blankline,
|
|
||||||
/// A space that may not break a line.
|
/// A space that may not break a line.
|
||||||
NonBreakingSpace,
|
NonBreakingSpace,
|
||||||
/// A newline that may or may not break a line in the output format.
|
/// A newline that may or may not break a line in the output format.
|
||||||
|
@ -214,6 +212,8 @@ pub enum Atom {
|
||||||
Hardbreak,
|
Hardbreak,
|
||||||
/// An escape character, not visible in output.
|
/// An escape character, not visible in output.
|
||||||
Escape,
|
Escape,
|
||||||
|
/// A blank line, not visible in output.
|
||||||
|
Blankline,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> Event<'s> {
|
impl<'s> Event<'s> {
|
||||||
|
@ -278,7 +278,7 @@ impl<'s> Container<'s> {
|
||||||
},
|
},
|
||||||
block::Block::Container(c) => match c {
|
block::Block::Container(c) => match c {
|
||||||
block::Container::Blockquote => Self::Blockquote,
|
block::Container::Blockquote => Self::Blockquote,
|
||||||
block::Container::Div { .. } => Self::Div,
|
block::Container::Div { .. } => Self::Div { class: None },
|
||||||
block::Container::Footnote { .. } => Self::Footnote { tag: todo!() },
|
block::Container::Footnote { .. } => Self::Footnote { tag: todo!() },
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
},
|
||||||
|
@ -297,13 +297,16 @@ impl<'s> Attributes<'s> {
|
||||||
Self(None)
|
Self(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn take(&mut self) -> Self {
|
||||||
|
Self(self.0.take())
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn valid(src: &str) -> bool {
|
pub fn valid(src: &str) -> bool {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
pub fn parse(&mut self, src: &'s str) {
|
||||||
pub fn parse(src: &'s str) -> Self {
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,6 +316,7 @@ pub struct Parser<'s> {
|
||||||
tree: block::Tree,
|
tree: block::Tree,
|
||||||
parser: Option<inline::Parser<'s>>,
|
parser: Option<inline::Parser<'s>>,
|
||||||
inline_start: usize,
|
inline_start: usize,
|
||||||
|
attributes: Attributes<'s>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> Parser<'s> {
|
impl<'s> Parser<'s> {
|
||||||
|
@ -323,6 +327,7 @@ impl<'s> Parser<'s> {
|
||||||
tree: block::parse(src),
|
tree: block::parse(src),
|
||||||
parser: None,
|
parser: None,
|
||||||
inline_start: 0,
|
inline_start: 0,
|
||||||
|
attributes: Attributes::none(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -351,29 +356,42 @@ impl<'s> Iterator for Parser<'s> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tree.next().map(|ev| match ev.kind {
|
for ev in &mut self.tree {
|
||||||
tree::EventKind::Element(atom) => {
|
let content = ev.span.of(self.src);
|
||||||
assert_eq!(atom, block::Atom::Blankline);
|
let event = match ev.kind {
|
||||||
Event::Atom(Atom::Blankline)
|
tree::EventKind::Element(atom) => match atom {
|
||||||
}
|
block::Atom::Inline => panic!("inline outside leaf block"),
|
||||||
tree::EventKind::Enter(block) => {
|
block::Atom::Blankline => Event::Atom(Atom::Blankline),
|
||||||
if matches!(block, block::Block::Leaf(l)) {
|
block::Atom::Attributes => {
|
||||||
self.parser = Some(inline::Parser::new());
|
self.attributes.parse(content);
|
||||||
}
|
continue;
|
||||||
match block {
|
|
||||||
block::Block::Leaf(block::Leaf::Paragraph) => self.inline_start = ev.span.end(),
|
|
||||||
block::Block::Leaf(block::Leaf::CodeBlock { .. }) => {
|
|
||||||
let lang = self.tree.next().unwrap();
|
|
||||||
self.inline_start = lang.span.end();
|
|
||||||
let lang = (!lang.span.is_empty()).then(|| lang.span.of(self.src).trim());
|
|
||||||
return Event::Start(Container::CodeBlock { lang }, Attributes::none());
|
|
||||||
}
|
}
|
||||||
_ => {}
|
},
|
||||||
|
tree::EventKind::Enter(block) => {
|
||||||
|
if matches!(block, block::Block::Leaf(_)) {
|
||||||
|
self.parser = Some(inline::Parser::new());
|
||||||
|
self.inline_start = ev.span.end();
|
||||||
|
}
|
||||||
|
let container = match block {
|
||||||
|
block::Block::Leaf(block::Leaf::CodeBlock { .. }) => {
|
||||||
|
self.inline_start += 1; // skip newline
|
||||||
|
Container::CodeBlock {
|
||||||
|
lang: (!ev.span.is_empty()).then(|| ev.span.of(self.src)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
block::Block::Container(block::Container::Div { .. }) => Container::Div {
|
||||||
|
class: (!ev.span.is_empty()).then(|| ev.span.of(self.src)),
|
||||||
|
},
|
||||||
|
b => Container::from_block(self.src, b),
|
||||||
|
};
|
||||||
|
Event::Start(container, self.attributes.take())
|
||||||
}
|
}
|
||||||
Event::Start(Container::from_block(self.src, block), Attributes::none())
|
tree::EventKind::Exit(block) => Event::End(Container::from_block(self.src, block)),
|
||||||
}
|
};
|
||||||
tree::EventKind::Exit(block) => Event::End(Container::from_block(self.src, block)),
|
return Some(event);
|
||||||
})
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +465,6 @@ mod test {
|
||||||
Start(Paragraph, Attributes::none()),
|
Start(Paragraph, Attributes::none()),
|
||||||
Str("para0"),
|
Str("para0"),
|
||||||
End(Paragraph),
|
End(Paragraph),
|
||||||
Atom(Blankline),
|
|
||||||
Start(Paragraph, Attributes::none()),
|
Start(Paragraph, Attributes::none()),
|
||||||
Str("para1"),
|
Str("para1"),
|
||||||
End(Paragraph),
|
End(Paragraph),
|
||||||
|
|
Loading…
Reference in a new issue