Newer
Older
use anyhow::{bail, Context};
use orgize::{elements::Keyword, export::HtmlHandler, Element};
use time::{macros::format_description, Date};
use crate::{
date::parse_org_date,
load::Loadable,
parser::{parse, CustomHtmlHandler, Parser},
util::slugify,
}
impl Post {
pub fn html(&self) -> anyhow::Result<String> {
let title = &self.title;
let content = &self.content;
let mut out = format!(r#"<div class="header-container"><h1>{title}</h1>"#);
if let Some(date) = date {
out.push_str(r#"<div class="header-date">"#);
out.push_str(date);
out.push_str("</div>");
}
out.push_str("</div>");
out.push_str(content);
Ok(out)
let link = match self.date_f()? {
Some(date_f) => format!(
r#"<tr><td><a href="{}">{}</a></td><td>[{}]</td></tr>"#,
self.url, self.title, date_f
),
None => format!(
r#"<tr><td><a href="{}">{}</a></td><td></td></tr>"#,
self.url, self.title
),
};
pub fn link_short(&self) -> String {
format!(
r#"<a href="{}" class="page-link">{}</a>"#,
self.url, self.title
)
}
fn date_f(&self) -> anyhow::Result<Option<String>> {
let date_f = match self.date {
Some(date) => date.format(format_description!("[day] [month repr:short] [year]"))?,
None => return Ok(None),
};
}
}
impl Loadable for Post {
fn load(path: &std::path::Path, slug_prefix: &str) -> anyhow::Result<Self> {
let file_name = path
.file_stem()
.context("Could not get file name")?
.to_str()
.context("Could not convert filename into string")?
.to_owned();
let url = slugify(&format!("/{slug_prefix}/{file_name}"));
parse(PostParser::new(url), &fs::read_to_string(path)?)
impl Ord for Post {
fn cmp(&self, other: &Self) -> Ordering {
self.date.cmp(&other.date)
}
}
impl PartialOrd for Post {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for Post {
fn eq(&self, other: &Self) -> bool {
self.date == other.date
}
}
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
content: vec![],
handler: CustomHtmlHandler::default(),
}
}
}
impl Parser<Post> for PostParser {
fn start(&mut self, e: &Element) -> anyhow::Result<()> {
match e {
Element::Keyword(Keyword { key, value, .. }) if key == "TITLE" => {
if self.title.is_some() {
bail!("Post has more than one title");
}
self.title = Some(value.to_string());
}
Element::Keyword(Keyword { key, value, .. }) if key == "DATE" => {
if self.date.is_some() {
bail!("Post has more than one date");
}
self.date = Some(parse_org_date(value)?);
}
_ => {
self.handler.start(&mut self.content, e)?;
}
}
Ok(())
}
fn end(&mut self, e: &Element) -> anyhow::Result<()> {
self.handler.end(&mut self.content, e)?;
Ok(())
}
fn render(self) -> anyhow::Result<Post> {
let title = self.title.context("Could not find post title")?;