summaryrefslogtreecommitdiff
path: root/src/html.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/html.rs')
-rw-r--r--src/html.rs50
1 files changed, 37 insertions, 13 deletions
diff --git a/src/html.rs b/src/html.rs
index 6d4d009..d023ba4 100644
--- a/src/html.rs
+++ b/src/html.rs
@@ -1,12 +1,10 @@
-use crate::error::SiteError;
-use crate::util::mkdir;
use html_escape::{encode_double_quoted_attribute, encode_text};
use line_col::LineColLookup;
-use log::trace;
+use log::{debug, trace};
use pulldown_cmark::{Event, HeadingLevel, Options, Parser, Tag};
use std::fmt::Write as _;
use std::io::Write;
-use std::path::Path;
+use std::path::{Path, PathBuf};
#[derive(Debug)]
pub struct HtmlPage {
@@ -36,32 +34,34 @@ impl HtmlPage {
&self.body
}
- pub fn serialize(&self) -> Result<String, SiteError> {
+ pub fn serialize(&self) -> Result<String, HtmlError> {
let mut html = Element::new(ElementTag::Html);
html.push_child(Content::Elt(self.head.clone()));
html.push_child(Content::Elt(self.body.clone()));
html.serialize()
}
- pub fn write(&self, filename: &Path) -> Result<(), SiteError> {
+ pub fn write(&self, filename: &Path) -> Result<(), HtmlError> {
if let Some(parent) = filename.parent() {
trace!("parent: {}", parent.display());
if !parent.exists() {
- mkdir(parent)?;
+ debug!("creating directory {}", parent.display());
+ std::fs::create_dir_all(parent)
+ .map_err(|e| HtmlError::CreateDir(parent.into(), e))?;
}
}
trace!("writing HTML: {}", filename.display());
let mut f = std::fs::File::create(filename)
- .map_err(|e| SiteError::CreateFile(filename.into(), e))?;
+ .map_err(|e| HtmlError::CreateFile(filename.into(), e))?;
let html = self.serialize()?;
f.write_all(html.as_bytes())
- .map_err(|e| SiteError::FileWrite(filename.into(), e))?;
+ .map_err(|e| HtmlError::FileWrite(filename.into(), e))?;
Ok(())
}
}
-pub fn parse(markdown: &str) -> Result<Element, SiteError> {
+pub fn parse(markdown: &str) -> Result<Element, HtmlError> {
let mut options = Options::empty();
options.insert(Options::ENABLE_HEADING_ATTRIBUTES);
options.insert(Options::ENABLE_STRIKETHROUGH);
@@ -144,7 +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: ") {
- return Err(SiteError::DefinitionList(loc.line, loc.col));
+ return Err(HtmlError::DefinitionList(loc.line, loc.col));
}
stack.append_child(Content::Elt(e));
}
@@ -258,10 +258,10 @@ impl Element {
}
}
- pub fn serialize(&self) -> Result<String, SiteError> {
+ pub fn serialize(&self) -> Result<String, HtmlError> {
let mut buf = String::new();
self.serialize_to_buf_without_added_newlines(&mut buf)
- .map_err(SiteError::Format)?;
+ .map_err(HtmlError::Format)?;
Ok(buf)
}
@@ -487,3 +487,27 @@ impl Stack {
self.append_child(Content::Elt(e));
}
}
+
+#[derive(Debug, thiserror::Error)]
+pub enum HtmlError {
+ /// Failed to create a directory.
+ #[error("failed to create directory {0}")]
+ CreateDir(PathBuf, #[source] std::io::Error),
+
+ /// Failed to create a file.
+ #[error("failed to create file {0}")]
+ CreateFile(PathBuf, #[source] std::io::Error),
+
+ /// Failed to write to a file.
+ #[error("failed to write to file {0}")]
+ FileWrite(PathBuf, #[source] std::io::Error),
+
+ /// 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),
+
+ /// String formatting error. This is likely a programming error.
+ #[error("string formatting error: {0}")]
+ Format(#[source] std::fmt::Error),
+}