adding document mode

I've been thinking a lot about the treehouse and I feel like it's time to say goodbye to the tree format.
This commit is contained in:
りき萌 2025-07-10 16:50:41 +02:00
parent 550c062327
commit 36705e7c1e
31 changed files with 940 additions and 409 deletions

View file

@ -23,10 +23,6 @@ pub struct RootAttributes {
#[serde(default = "default_icon")]
pub icon: String,
/// Summary of the generated .html page.
#[serde(default)]
pub description: Option<String>,
/// ID of picture attached to the page, to be used as a thumbnail.
#[serde(default)]
pub thumbnail: Option<Picture>,
@ -50,7 +46,7 @@ pub struct RootAttributes {
#[serde(default)]
pub timestamps: Option<Timestamps>,
/// When specified, this page will have a corresponding Atom feed under `rss/{feed}.xml`.
/// When specified, this page will have a corresponding Atom feed under `feed/{feed}.atom`.
///
/// In feeds, top-level branches are expected to have a single heading containing the post title.
/// Their children are turned into the post description

94
src/tree/feed.rs Normal file
View file

@ -0,0 +1,94 @@
use crate::{
dirs::Dirs,
html::djot::{self, resolve_link},
sources::Sources,
state::FileId,
};
#[derive(Debug, Clone)]
pub struct ParsedEntry {
pub title: Option<String>,
pub link: Option<String>,
}
pub fn parse_entry(
sources: &Sources,
dirs: &Dirs,
file_id: FileId,
parser: jotdown::Parser,
) -> ParsedEntry {
let mut parser = parser.into_offset_iter();
while let Some((event, span)) = parser.next() {
if let jotdown::Event::Start(jotdown::Container::Heading { .. }, _attrs) = &event {
let mut events = vec![(event, span)];
for (event, span) in parser.by_ref() {
// To my knowledge headings cannot nest, so it's okay not keeping a stack here.
let is_heading = matches!(
event,
jotdown::Event::End(jotdown::Container::Heading { .. })
);
events.push((event, span));
if is_heading {
break;
}
}
let title_events: Vec<_> = events
.iter()
.filter(|(event, _)| {
!matches!(
event,
// A little repetitive, but I don't mind.
// The point of this is not to include extra <h3> and <a> in the link text,
// but preserve other formatting such as bold, italic, code, etc.
jotdown::Event::Start(
jotdown::Container::Link(_, _) | jotdown::Container::Heading { .. },
_
) | jotdown::Event::End(
jotdown::Container::Link(_, _) | jotdown::Container::Heading { .. }
)
)
})
.cloned()
.collect();
let mut title = String::new();
let _render_diagnostics = djot::Renderer {
config: &sources.config,
dirs,
treehouse: &sources.treehouse,
file_id,
// How. Just, stop.
page_id: "liquidex-you-reeeeeal-dummy".into(),
}
.render(&title_events, &mut title);
let link = events.iter().find_map(|(event, _)| {
if let jotdown::Event::Start(jotdown::Container::Link(link, link_type), _) = event {
Some(link_url(sources, dirs, link, *link_type))
} else {
None
}
});
return ParsedEntry {
title: (!title.is_empty()).then_some(title),
link,
};
}
}
ParsedEntry {
title: None,
link: None,
}
}
fn link_url(sources: &Sources, dirs: &Dirs, url: &str, link_type: jotdown::LinkType) -> String {
if let jotdown::LinkType::Span(jotdown::SpanLinkType::Unresolved) = link_type {
if let Some(url) = resolve_link(&sources.config, &sources.treehouse, dirs, url) {
return url;
}
}
url.to_owned()
}