mirror of
https://github.com/zyllian/webdog.git
synced 2025-07-31 19:38:37 -07:00
Compare commits
10 commits
e555f437c7
...
9125738498
Author | SHA1 | Date | |
---|---|---|---|
9125738498 | |||
230e22dbf8 | |||
abd591c8fa | |||
2330648b69 | |||
05d66c2143 | |||
0dbe284d57 | |||
f51af1ad74 | |||
e05f040c38 | |||
3daa80f8af | |||
b4088fb397 |
7 changed files with 532 additions and 564 deletions
986
Cargo.lock
generated
986
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
43
Cargo.toml
43
Cargo.toml
|
@ -1,47 +1,42 @@
|
|||
[package]
|
||||
description = "static site generator fit for a dog"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
homepage = "https://webdog.zyl.gay"
|
||||
license = "AGPL-3.0-or-later"
|
||||
name = "webdog"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/zyllian/webdog"
|
||||
version = "0.1.1"
|
||||
version = "0.1.3"
|
||||
|
||||
[dependencies]
|
||||
clap = {version = "4", features = ["derive"]}
|
||||
color-eyre = {version = "0.6", optional = true}
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
color-eyre = { version = "0.6", optional = true }
|
||||
extract-frontmatter = "4"
|
||||
eyre = "0.6"
|
||||
fs_extra = "1.2"
|
||||
futures = {version = "0.3", optional = true}
|
||||
grass = {version = "0.13", default-features = false}
|
||||
hotwatch = {version = "0.5", optional = true}
|
||||
html5ever = "0.29"
|
||||
futures = { version = "0.3", optional = true }
|
||||
grass = { version = "0.13", default-features = false }
|
||||
hotwatch = { version = "0.5", optional = true }
|
||||
html5ever = "0.31"
|
||||
include_dir = "0.7"
|
||||
itertools = "0.14"
|
||||
kuchikiki = "0.8.6-speedreader"
|
||||
kuchikiki = "0.8.8-speedreader"
|
||||
lol_html = "2"
|
||||
minifier = {version = "0.3", features = ["html"]}
|
||||
percent-encoding = {version = "2", optional = true}
|
||||
pulldown-cmark = {version = "0.12", default-features = false, features = [
|
||||
minifier = { version = "0.3", features = ["html"] }
|
||||
percent-encoding = { version = "2", optional = true }
|
||||
pulldown-cmark = { version = "0.13", default-features = false, features = [
|
||||
"simd",
|
||||
"html",
|
||||
]}
|
||||
] }
|
||||
rayon = "1"
|
||||
rss = {version = "2", features = ["validation"]}
|
||||
serde = {version = "1", features = ["derive"]}
|
||||
rss = { version = "2", features = ["validation"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_yaml_ng = "0.10"
|
||||
syntect = "5"
|
||||
tera = "1"
|
||||
time = {version = "0.3", features = ["serde-human-readable"]}
|
||||
tokio = {version = "1", features = [
|
||||
"macros",
|
||||
"rt-multi-thread",
|
||||
], optional = true}
|
||||
url = {version = "2", features = ["serde"]}
|
||||
time = { version = "0.3", features = ["serde-human-readable"] }
|
||||
tokio = { version = "1", features = ["rt-multi-thread"], optional = true }
|
||||
url = { version = "2", features = ["serde"] }
|
||||
walkdir = "2"
|
||||
warp = {version = "0.3", optional = true}
|
||||
warp = { version = "0.3", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["serve", "color-eyre"]
|
||||
|
|
|
@ -37,6 +37,10 @@ list of sass/scss stylesheets in the site's `sass` directory to treat as root st
|
|||
|
||||
base url for the various cdn url transformation features of webdog.
|
||||
|
||||
## `webdog_path`
|
||||
|
||||
optional custom path for webdog's static resources.
|
||||
|
||||
## `code_theme`
|
||||
|
||||
the theme to use for code blocks. valid options: `base16-ocean.dark`, `base16-eighties.dark`, `base16-mocha.dark`, `base16-ocean.light`, `InspiredGitHub`, `Solarized (dark)`, and `Solarized (light)`
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use eyre::{eyre, Context, OptionExt};
|
||||
use lol_html::{element, html_content::ContentType, HtmlRewriter, Settings};
|
||||
use eyre::{Context, OptionExt, eyre};
|
||||
use lol_html::{HtmlRewriter, Settings, element, html_content::ContentType};
|
||||
use rayon::prelude::*;
|
||||
use serde::Serialize;
|
||||
use syntect::{highlighting::ThemeSet, parsing::SyntaxSet};
|
||||
use tera::Tera;
|
||||
use url::Url;
|
||||
|
||||
use crate::{resource::ResourceBuilder, util, PageMetadata, Site, ROOT_PATH, SASS_PATH};
|
||||
use crate::{PageMetadata, ROOT_PATH, SASS_PATH, Site, resource::ResourceBuilder, util};
|
||||
|
||||
/// Path for static webdog resources included with the site build.
|
||||
const WEBDOG_PATH: &str = "webdog";
|
||||
/// Default path for static webdog resources included with the site build.
|
||||
const WEBDOG_DEFAULT_PATH: &str = "webdog";
|
||||
|
||||
/// Struct containing data to be sent to templates when rendering them.
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -96,7 +96,13 @@ impl SiteBuilder {
|
|||
std::fs::create_dir(&self.build_path).wrap_err("Failed to create build directory")?;
|
||||
}
|
||||
|
||||
let webdog_path = self.build_path.join(WEBDOG_PATH);
|
||||
let webdog_path = self.build_path.join(
|
||||
self.site
|
||||
.config
|
||||
.webdog_path
|
||||
.clone()
|
||||
.unwrap_or_else(|| WEBDOG_DEFAULT_PATH.to_string()),
|
||||
);
|
||||
std::fs::create_dir(&webdog_path)?;
|
||||
std::fs::write(
|
||||
webdog_path.join("webdog.js"),
|
||||
|
@ -155,6 +161,7 @@ impl SiteBuilder {
|
|||
}
|
||||
|
||||
/// Function to rewrite HTML wow.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn rewrite_html(
|
||||
&self,
|
||||
html: String,
|
||||
|
@ -163,6 +170,7 @@ impl SiteBuilder {
|
|||
scripts: &[String],
|
||||
styles: &[String],
|
||||
is_partial: bool,
|
||||
webdog_path: &str,
|
||||
) -> eyre::Result<String> {
|
||||
use kuchikiki::traits::*;
|
||||
|
||||
|
@ -251,7 +259,9 @@ impl SiteBuilder {
|
|||
);
|
||||
}
|
||||
el.append(
|
||||
r#"<script type="text/javascript" src="/webdog/webdog.js" defer></script>"#,
|
||||
&format!(
|
||||
r#"<script type="text/javascript" src="/{webdog_path}/webdog.js" defer></script>"#
|
||||
),
|
||||
ContentType::Html,
|
||||
);
|
||||
if self.serving {
|
||||
|
@ -377,6 +387,12 @@ impl SiteBuilder {
|
|||
&page_metadata.scripts,
|
||||
&page_metadata.styles,
|
||||
page_metadata.is_partial,
|
||||
&self
|
||||
.site
|
||||
.config
|
||||
.webdog_path
|
||||
.clone()
|
||||
.unwrap_or_else(|| WEBDOG_DEFAULT_PATH.to_string()),
|
||||
)?;
|
||||
|
||||
if let Some(data) = extra {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use itertools::Itertools;
|
||||
use lol_html::{element, RewriteStrSettings};
|
||||
use lol_html::{RewriteStrSettings, element};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{builder::SiteBuilder, resource::ResourceTemplateData};
|
||||
|
@ -111,10 +110,12 @@ fn resource_list_outside(
|
|||
)
|
||||
.map(|ts| (id, v, ts))
|
||||
})
|
||||
.map_ok(|(id, v, ts)| ResourceTemplateData {
|
||||
resource: v,
|
||||
id: id.clone(),
|
||||
readable_timestamp: ts,
|
||||
.map(|v| {
|
||||
v.map(|(id, v, ts)| ResourceTemplateData {
|
||||
resource: v,
|
||||
id: id.clone(),
|
||||
readable_timestamp: ts,
|
||||
})
|
||||
})
|
||||
.collect::<eyre::Result<Vec<_>>>()?,
|
||||
})?,
|
||||
|
|
|
@ -49,6 +49,8 @@ pub struct SiteConfig {
|
|||
pub sass_styles: Vec<PathBuf>,
|
||||
/// URL to the CDN used for the site's images.
|
||||
pub cdn_url: Url,
|
||||
/// The path to output webdog static resources to. Defaults to "webdog"
|
||||
pub webdog_path: Option<String>,
|
||||
/// The theme to use for the site's code blocks.
|
||||
/// TODO: dark/light themes
|
||||
/// TODO: export themes as CSS instead of styling HTML directly
|
||||
|
@ -73,6 +75,7 @@ impl SiteConfig {
|
|||
build: None,
|
||||
sass_styles: vec!["index.scss".into()],
|
||||
cdn_url,
|
||||
webdog_path: None,
|
||||
code_theme: "base16-ocean.dark".to_string(),
|
||||
resources: Default::default(),
|
||||
}
|
||||
|
|
|
@ -4,17 +4,16 @@ use std::{
|
|||
};
|
||||
|
||||
use eyre::Context;
|
||||
use itertools::Itertools;
|
||||
use rss::{validation::Validate, ChannelBuilder, ItemBuilder};
|
||||
use rss::{ChannelBuilder, ItemBuilder, validation::Validate};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::{format_description::well_known::Rfc2822, OffsetDateTime};
|
||||
use time::{OffsetDateTime, format_description::well_known::Rfc2822};
|
||||
|
||||
use crate::{
|
||||
PageMetadata,
|
||||
builder::SiteBuilder,
|
||||
frontmatter::FrontMatterRequired,
|
||||
link_list::Link,
|
||||
util::{self, format_timestamp},
|
||||
PageMetadata,
|
||||
};
|
||||
|
||||
/// Metadata for resources.
|
||||
|
@ -319,7 +318,7 @@ impl ResourceBuilder {
|
|||
let page_max = list.len() / items_per_page + (list.len() % items_per_page).min(1);
|
||||
let mut previous = None;
|
||||
let mut next;
|
||||
for (page, iter) in list.iter().chunks(items_per_page).into_iter().enumerate() {
|
||||
for (page, iter) in list.chunks(items_per_page).enumerate() {
|
||||
next = (page + 1 != page_max).then_some(page + 2);
|
||||
let out = builder.build_page_raw(
|
||||
PageMetadata {
|
||||
|
@ -329,7 +328,7 @@ impl ResourceBuilder {
|
|||
},
|
||||
"",
|
||||
ResourceListTemplateData {
|
||||
resources: iter.copied().collect(),
|
||||
resources: iter.to_vec(),
|
||||
tag,
|
||||
rss_enabled: config.rss.is_some(),
|
||||
page: page + 1,
|
||||
|
@ -372,7 +371,7 @@ impl ResourceBuilder {
|
|||
|
||||
// Build list of tags
|
||||
{
|
||||
let links = tags
|
||||
let mut links: Vec<_> = tags
|
||||
.iter()
|
||||
.map(|(tag, data)| {
|
||||
let count = data.len();
|
||||
|
@ -384,9 +383,9 @@ impl ResourceBuilder {
|
|||
count,
|
||||
)
|
||||
})
|
||||
.sorted_by(|(_, a), (_, b)| b.cmp(a))
|
||||
.map(|(l, _)| l)
|
||||
.collect();
|
||||
links.sort_by(|(_, a), (_, b)| b.cmp(a));
|
||||
let links = links.into_iter().map(|(l, _)| l).collect();
|
||||
let out = crate::link_list::render_basic_link_list(
|
||||
builder,
|
||||
&self.config.tag_list_template,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue