summaryrefslogtreecommitdiff
path: root/src/html.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/html.rs')
-rw-r--r--src/html.rs91
1 files changed, 78 insertions, 13 deletions
diff --git a/src/html.rs b/src/html.rs
index 7237258..b39872b 100644
--- a/src/html.rs
+++ b/src/html.rs
@@ -72,7 +72,7 @@ impl HtmlPage {
}
/// Parse Markdown text into an HTML element.
-pub fn parse(markdown: &str) -> Result<Element, HtmlError> {
+pub fn parse(filename: &Path, markdown: &str) -> Result<Element, HtmlError> {
let mut options = Options::empty();
options.insert(Options::ENABLE_HEADING_ATTRIBUTES);
options.insert(Options::ENABLE_STRIKETHROUGH);
@@ -85,7 +85,7 @@ pub fn parse(markdown: &str) -> Result<Element, HtmlError> {
for (event, loc) in p {
trace!("event {:?}", event);
let (line, col) = linecol.get(loc.start);
- let loc = Location::new(line, col);
+ let loc = Location::new(filename, line, col);
match event {
Event::Start(tag) => match tag {
Tag::Paragraph => stack.push_tag(ElementTag::P, loc),
@@ -162,7 +162,7 @@ pub fn parse(markdown: &str) -> Result<Element, HtmlError> {
let s = as_plain_text(e.children());
trace!("paragraph text: {:?}", s);
if s.starts_with(": ") || s.contains("\n: ") {
- return Err(HtmlError::DefinitionList(loc.line, loc.col));
+ return Err(HtmlError::DefinitionList(loc));
}
stack.append_child(Content::Elt(e));
}
@@ -254,8 +254,12 @@ impl Element {
}
/// Get location.
- pub fn location(&self) -> &Option<Location> {
- &self.loc
+ pub fn location(&self) -> Location {
+ if let Some(loc) = &self.loc {
+ loc.clone()
+ } else {
+ Location::unknown()
+ }
}
fn set_block_attributes(&mut self, block_attrs: Vec<BlockAttr>) {
@@ -543,15 +547,76 @@ impl Content {
}
/// Location of element in source file.
-#[derive(Debug, Clone, Copy)]
-pub struct Location {
- line: usize,
- col: usize,
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub enum Location {
+ /// A known location.
+ Known {
+ /// Name of file.
+ filename: PathBuf,
+ /// Line in file.
+ line: usize,
+ /// Column in line.
+ col: usize,
+ },
+ /// An unknown location.
+ Unknown,
}
impl Location {
- fn new(line: usize, col: usize) -> Self {
- Self { line, col }
+ fn new(filename: &Path, line: usize, col: usize) -> Self {
+ Self::Known {
+ filename: filename.into(),
+ line,
+ col,
+ }
+ }
+
+ /// Create an unknown location.
+ pub fn unknown() -> Self {
+ Self::Unknown
+ }
+
+ /// Report name of source file from where this element comes from.
+ pub fn filename(&self) -> &Path {
+ if let Self::Known {
+ filename,
+ line: _,
+ col: _,
+ } = self
+ {
+ filename
+ } else {
+ Path::new("")
+ }
+ }
+
+ /// Report row and column in source where this element comes from.
+ pub fn rowcol(&self) -> (usize, usize) {
+ if let Self::Known {
+ filename: _,
+ line,
+ col,
+ } = self
+ {
+ (*line, *col)
+ } else {
+ (0, 0)
+ }
+ }
+}
+
+impl std::fmt::Display for Location {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+ if let Self::Known {
+ filename,
+ line,
+ col,
+ } = self
+ {
+ write!(f, "{}:{}:{}", filename.display(), line, col)
+ } else {
+ write!(f, "(unknown location)")
+ }
}
}
@@ -616,8 +681,8 @@ pub enum HtmlError {
/// Input contains an attempt to use a definition list in
/// Markdown.
- #[error("attempt to use definition lists in Markdown: line {0}, column {1}")]
- DefinitionList(usize, usize),
+ #[error("attempt to use definition lists in Markdown: {0}")]
+ DefinitionList(Location),
/// String formatting error. This is likely a programming error.
#[error("string formatting error: {0}")]