summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-10-26 08:40:31 +0000
committerLars Wirzenius <liw@liw.fi>2022-10-26 08:40:31 +0000
commitdcc3be6246a51c788f31faa8ccd1be6a36d8af8e (patch)
treeed84f691b4b3eda8083108d90eff2fc2a033eb51
parent46ce99780d3bd6d35ddb60321ac16a4da4dd900d (diff)
parente4014b2138267a3eea131e11284628a313db2235 (diff)
downloadriki-dcc3be6246a51c788f31faa8ccd1be6a36d8af8e.tar.gz
Merge branch 'element-location' into 'main'
feat: store start location of each element See merge request larswirzenius/riki!65
-rw-r--r--src/html.rs54
1 files changed, 37 insertions, 17 deletions
diff --git a/src/html.rs b/src/html.rs
index abbe71d..6605333 100644
--- a/src/html.rs
+++ b/src/html.rs
@@ -73,9 +73,11 @@ pub fn parse(markdown: &str) -> Result<Element, SiteError> {
stack.push(Element::new(ElementTag::Body));
for (event, loc) in p {
trace!("event {:?}", event);
+ let (line, col) = linecol.get(loc.start);
+ let loc = Location::new(line, col);
match event {
Event::Start(tag) => match tag {
- Tag::Paragraph => stack.push_tag(ElementTag::P),
+ Tag::Paragraph => stack.push_tag(ElementTag::P, loc),
Tag::Heading(level, id, classes) => {
let tag = match level {
HeadingLevel::H1 => ElementTag::H1,
@@ -101,23 +103,23 @@ pub fn parse(markdown: &str) -> Result<Element, SiteError> {
}
stack.push(h);
}
- Tag::BlockQuote => stack.push_tag(ElementTag::Blockquote),
- Tag::CodeBlock(_) => stack.push_tag(ElementTag::Pre),
- Tag::List(None) => stack.push_tag(ElementTag::Ul),
+ Tag::BlockQuote => stack.push_tag(ElementTag::Blockquote, loc),
+ Tag::CodeBlock(_) => stack.push_tag(ElementTag::Pre, loc),
+ Tag::List(None) => stack.push_tag(ElementTag::Ul, loc),
Tag::List(Some(start)) => {
- let mut e = Element::new(ElementTag::Ol);
+ let mut e = Element::new(ElementTag::Ol).with_location(loc);
e.push_attribute(Attribute::new("start", &format!("{}", start)));
stack.push(e);
}
- Tag::Item => stack.push_tag(ElementTag::Li),
+ Tag::Item => stack.push_tag(ElementTag::Li, loc),
Tag::FootnoteDefinition(_) => unreachable!("{:?}", tag),
- Tag::Table(_) => stack.push_tag(ElementTag::Table),
- Tag::TableHead => stack.push_tag(ElementTag::Th),
- Tag::TableRow => stack.push_tag(ElementTag::Tr),
- Tag::TableCell => stack.push_tag(ElementTag::Td),
- Tag::Emphasis => stack.push_tag(ElementTag::Em),
- Tag::Strong => stack.push_tag(ElementTag::Strong),
- Tag::Strikethrough => stack.push_tag(ElementTag::Del),
+ Tag::Table(_) => stack.push_tag(ElementTag::Table, loc),
+ Tag::TableHead => stack.push_tag(ElementTag::Th, loc),
+ Tag::TableRow => stack.push_tag(ElementTag::Tr, loc),
+ Tag::TableCell => stack.push_tag(ElementTag::Td, loc),
+ Tag::Emphasis => stack.push_tag(ElementTag::Em, loc),
+ Tag::Strong => stack.push_tag(ElementTag::Strong, loc),
+ Tag::Strikethrough => stack.push_tag(ElementTag::Del, loc),
Tag::Link(_, url, title) => {
let mut link = Element::new(ElementTag::A);
link.push_attribute(Attribute::new("href", url.as_ref()));
@@ -142,8 +144,7 @@ pub fn parse(markdown: &str) -> Result<Element, SiteError> {
let s = as_plain_text(e.children());
trace!("paragraph text: {:?}", s);
if s.starts_with(": ") || s.contains("\n: ") {
- let (line, col) = linecol.get(loc.start);
- return Err(SiteError::DefinitionList(line, col));
+ return Err(SiteError::DefinitionList(loc.line, loc.col));
}
stack.append_child(Content::Elt(e));
}
@@ -206,6 +207,7 @@ fn as_plain_text(content: &[Content]) -> String {
#[derive(Debug, Clone)]
pub struct Element {
+ loc: Option<Location>,
tag: ElementTag,
attrs: Vec<Attribute>,
children: Vec<Content>,
@@ -214,12 +216,18 @@ pub struct Element {
impl Element {
pub fn new(tag: ElementTag) -> Self {
Self {
+ loc: None,
tag,
attrs: vec![],
children: vec![],
}
}
+ fn with_location(mut self, loc: Location) -> Self {
+ self.loc = Some(loc);
+ self
+ }
+
fn push_attribute(&mut self, attr: Attribute) {
self.attrs.push(attr);
}
@@ -420,6 +428,18 @@ pub enum Content {
Html(String),
}
+#[derive(Debug, Clone, Copy)]
+struct Location {
+ line: usize,
+ col: usize,
+}
+
+impl Location {
+ fn new(line: usize, col: usize) -> Self {
+ Self { line, col }
+ }
+}
+
struct Stack {
stack: Vec<Element>,
}
@@ -438,8 +458,8 @@ impl Stack {
self.stack.push(e);
}
- fn push_tag(&mut self, tag: ElementTag) {
- self.push(Element::new(tag));
+ fn push_tag(&mut self, tag: ElementTag, loc: Location) {
+ self.push(Element::new(tag).with_location(loc));
}
fn pop(&mut self) -> Element {