Start new design

This commit is contained in:
Shadowfacts 2025-01-04 14:59:15 -05:00
parent a9a6b85c5f
commit 657f90c39c
22 changed files with 665 additions and 119 deletions

View File

@ -0,0 +1,27 @@
<!--<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>-->
<svg
width="13.333401"
height="13.3334"
viewBox="0 0 13.333401 13.3334"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
xmlns="http://www.w3.org/2000/svg">
<path
d="M 10.66672,7.3333701 V 11.33339 A 1.33334,1.33334 0 0 1 9.33338,12.66673 H 2.00001 A 1.33334,1.33334 0 0 1 0.66667002,11.33339 V 4.0000201 A 1.33334,1.33334 0 0 1 2.00001,2.6666801 h 4.00002"
id="path1"
style="stroke-width:1.33334" />
<polyline
points="15 3 21 3 21 9"
id="polyline1"
transform="matrix(0.66667,0,0,0.66667,-1.33334,-1.3333399)" />
<line
x1="5.3333602"
y1="8.0000401"
x2="12.666731"
y2="0.66667002"
id="line1"
style="stroke-width:1.33334" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

49
site_test/css/fonts.scss Normal file
View File

@ -0,0 +1,49 @@
@font-face {
font-family: "Valkyrie A";
font-style: normal;
font-weight: normal;
font-stretch: normal;
font-display: auto;
src: url("data:font/woff2;base64," + $valkyrie-a-regular) format("woff2");
}
@font-face {
font-family: "Valkyrie A";
font-style: italic;
font-weight: normal;
font-stretch: normal;
font-display: auto;
src: url("data:font/woff2;base64," + $valkyrie-a-italic) format("woff2");
}
@font-face {
font-family: "Valkyrie A";
font-style: normal;
font-weight: bold;
font-stretch: normal;
font-display: auto;
src: url("data:font/woff2;base64," + $valkyrie-a-bold) format("woff2");
}
@font-face {
font-family: "Valkyrie A";
font-style: italic;
font-weight: bold;
font-stretch: normal;
font-display: auto;
src: url("data:font/woff2;base64," + $valkyrie-a-bold-italic)
format("woff2");
}
@font-face {
font-family: "Berkeley Mono";
src: url("data:font/woff2;base64," + $berkeley-mono-regular) format("woff2");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Berkeley Mono";
src: url("data:font/woff2;base64," + $berkeley-mono-italic) format("woff2");
font-weight: normal;
font-style: italic;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,35 +1,105 @@
@font-face {
font-family: "Equity A";
font-style: normal;
font-weight: normal;
font-stretch: normal;
font-display: auto;
src: url("data:font/woff2;base64," + $equity-a-regular) format("woff2");
@import "normalize.scss";
@import "fonts.scss";
:root {
--background-color: #f8e7cf;
--text-color: black;
--link-color: blue;
--page-vertical-margin: 3rem;
--page-horizontal-margin: 2rem;
}
@font-face {
font-family: "Equity A";
.container {
max-width: 768px;
}
a,
a:visited {
color: var(--link-color);
text-decoration-thickness: 0.05em;
}
a:hover {
text-decoration-thickness: 0.1em;
}
a[href^="http://"]::after,
a[href^="https://"]::after
{
background-color: currentColor;
content: "";
width: calc(max(0.667em, 12px));
height: calc(max(0.667em, 12px));
margin-left: 0.333em;
display: inline-block;
mask: url("data:image/svg+xml;base64," + $external-link) no-repeat 50% 50%;
mask-size: cover;
}
pre,
code {
font-family: "Berkeley Mono";
}
body {
font-family: "Valkyrie A", Charter, serif;
font-size: 16px;
/* background-color: #dfd3c3; */
background-color: var(--background-color);
/* background-color: #e8dbc5; */
color: var(--text-color);
}
header {
margin-top: var(--page-vertical-margin);
font-style: italic;
font-weight: normal;
font-stretch: normal;
font-display: auto;
src: url("data:font/woff2;base64," + $equity-a-italic) format("woff2");
h1 {
font-size: 5rem;
margin: 0;
text-underline-offset: 0.5rem;
a {
color: var(--text-color) !important;
transition: text-decoration-thickness 0.1s ease-in-out;
}
}
p {
margin-top: 0.25rem;
font-size: 1.5rem;
font-weight: lighter;
}
}
@font-face {
font-family: "Equity A";
font-style: normal;
font-weight: bold;
font-stretch: normal;
font-display: auto;
src: url("data:font/woff2;base64," + $equity-a-bold) format("woff2");
.article-content {
font-size: 1.25rem;
}
@font-face {
font-family: "Equity A";
.header-anchor {
text-decoration: none;
font-size: 1rem;
vertical-align: middle;
// drag it up so it's more in the middle
padding-bottom: 0.25rem;
color: gray !important;
&:hover {
color: var(--link-color) !important;
}
}
.footnote-reference > a {
text-decoration: none;
}
footer {
margin-bottom: var(--page-vertical-margin);
font-style: italic;
font-weight: bold;
font-stretch: normal;
font-display: auto;
src: url("data:font/woff2;base64," + $equity-a-bold-italic) format("woff2");
font-size: 1.5rem;
ul {
padding: 0;
list-style: none;
}
}
@media (min-width: calc(768px + 2rem)) {
.container {
margin-left: var(--page-horizontal-margin);
margin-right: var(--page-horizontal-margin);
}
}

351
site_test/css/normalize.scss vendored Normal file
View File

@ -0,0 +1,351 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input {
/* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select {
/* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

Binary file not shown.

View File

@ -2,8 +2,8 @@
{% block content -%}
hello
<a href="{{ latest_post_permalink }}">
{{ latest_post.metadata.title }}
</a>
{%- endblock %}

View File

@ -31,6 +31,16 @@
<article itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<meta itemprop="mainEntityOfPage" content="https://{{ _domain }}{{ _permalink }}">
<h1 class="article-title" itemprop="name headline">
{% if metadata.html_title %}
{{ metadata.html_title }}
{% else %}
{{ metadata.title }}
{% endif %}
</h1>
<div class="article-content" itemprop="articleBody">
{{ content }}
</div>
</article>
{%- endblock %}

View File

@ -33,7 +33,29 @@
</head>
<body itemscope itemtype="https://schema.org/Blog">
<header>
<div class="container">
<h1><a href="/">Shadowfacts</a></h1>
<p>The outer part of a shadow is called the penumbra.</p>
</div>
</header>
<main>
<div class="container">
{% block content %}{% endblock %}
</div>
</main>
<footer>
<div class="container">
<ul>
<li><a href="/archive/">Archive</a></li>
<li><a href="/elsewhere/">Contact</a></li>
<!-- TODO: webring -->
<li>Generated on {{ _generated_at | pretty_date }} by <a href="https://git.shadowfacts.net/shadowfacts/v7">v7</a>.</li>
</ul>
</div>
</footer>
<script data-goatcounter="https://shadowfacts.goatcounter.com/count" async src="//gc.zgo.at/count.v3.js" crossorigin="anonymous"></script>

View File

@ -27,15 +27,36 @@ pub fn make_graph(
watcher: Rc<RefCell<FileWatcher>>,
) -> Input<()> {
let mut watcher_ = watcher.borrow_mut();
let mut fonts = HashMap::<&'static str, Input<String>>::new();
let filenames: &[&str] = &[
"equity-a-regular",
"equity-a-bold",
"equity-a-italic",
"equity-a-bold-italic",
let mut files = HashMap::<&'static str, Input<String>>::new();
let filenames = [
(
"valkyrie-a-regular",
content_path("css/fonts/valkyrie_a_regular.woff2"),
),
(
"valkyrie-a-bold",
content_path("css/fonts/valkyrie_a_bold.woff2"),
),
(
"valkyrie-a-italic",
content_path("css/fonts/valkyrie_a_italic.woff2"),
),
(
"valkyrie-a-bold-italic",
content_path("css/fonts/valkyrie_a_bold_italic.woff2"),
),
("external-link", content_path("css/external-link.svg")),
(
"berkeley-mono-regular",
content_path("css/fonts/BerkeleyMono-Regular.woff2"),
),
(
"berkeley-mono-italic",
content_path("css/fonts/BerkeleyMono-Italic.woff2"),
),
];
for name in filenames {
fonts.insert(name, read_font(name, builder, &mut *watcher_));
for (name, path) in filenames.into_iter() {
files.insert(name, read_file(path, builder, &mut *watcher_));
}
drop(watcher_);
@ -44,21 +65,18 @@ pub fn make_graph(
watcher,
watched: HashSet::new(),
invalidate: Rc::clone(&invalidate_css_box),
fonts,
fonts: files,
});
invalidate_css_box.replace(Some(invalidate_css));
css
}
fn read_font(
name: &'static str,
fn read_file(
path: PathBuf,
builder: &mut GraphBuilder<(), Asynchronous>,
watcher: &mut FileWatcher,
) -> Input<String> {
let mut path = content_path("fonts");
path.push(name);
path.set_extension("woff2");
let (font, invalidate) = builder.add_invalidatable_rule(ReadFont(path.clone()));
let (font, invalidate) = builder.add_invalidatable_rule(ReadFile(path.clone()));
watcher.watch(path, move || invalidate.invalidate());
font
}
@ -139,8 +157,8 @@ impl<'a> Fs for TrackingFs<'a> {
}
#[derive(InputVisitable)]
struct ReadFont(PathBuf);
impl Rule for ReadFont {
struct ReadFile(PathBuf);
impl Rule for ReadFile {
type Output = String;
fn evaluate(&mut self) -> Self::Output {
match std::fs::read(&self.0) {

View File

@ -36,6 +36,7 @@ pub fn make_graph(
latest_post,
|latest_post, ctx| {
ctx.insert("latest_post", latest_post);
ctx.insert("latest_post_permalink", &latest_post.permalink());
ctx.insert("latest_post_content", latest_post.content.html());
},
));

View File

@ -3,7 +3,7 @@ use std::iter::empty;
use crate::generator::util::one_more::OneMore;
use crate::generator::util::slugify::slugify_iter;
use State::*;
use pulldown_cmark::{CowStr, Event, HeadingLevel, Tag, TagEnd, html};
use pulldown_cmark::{CowStr, Event, Tag, TagEnd, html};
pub struct HeadingAnchors<'a, I: Iterator<Item = Event<'a>>> {
iter: I,
@ -42,14 +42,11 @@ impl<'a, I: Iterator<Item = Event<'a>>> HeadingAnchors<'a, I> {
let slug = slugify_events(&inside_heading);
let mut inner = String::new();
html::push_html(&mut inner, inside_heading.into_iter());
let hash_marks = level_hash_marks(level);
let heading_html = format!(
"\
<{} id=\"{}\">\
<a href=\"#{}\" class=\"header-anchor\" aria-hidden=\"true\" role=\"presentation\">{}</a> \
{}\
</{}>",
level, slug, slug, hash_marks, inner, level
<{level} id=\"{slug}\">\
{inner} <a href=\"#{slug}\" class=\"header-anchor\" aria-hidden=\"true\" role=\"presentation\">&sect;</a> \
</{level}>",
);
Event::Html(CowStr::Boxed(heading_html.into_boxed_str()))
}
@ -82,17 +79,6 @@ fn slugify_events<'a>(events: &[Event<'a>]) -> String {
slugify_iter(chars)
}
fn level_hash_marks(level: HeadingLevel) -> &'static str {
match level {
HeadingLevel::H1 => "#",
HeadingLevel::H2 => "##",
HeadingLevel::H3 => "###",
HeadingLevel::H4 => "####",
HeadingLevel::H5 => "#####",
HeadingLevel::H6 => "######",
}
}
enum State {
TakeEvent,
Done,

View File

@ -8,7 +8,7 @@ use compute_graph::{
};
use log::error;
use once_cell::sync::Lazy;
use tera::{Context, Tera};
use tera::{Context, Filter, Tera};
use crate::generator::util::output_writer;
@ -18,7 +18,10 @@ pub fn make_graph(
builder: &mut GraphBuilder<(), Asynchronous>,
watcher: &mut FileWatcher,
) -> Input<Templates> {
let empty_templates = builder.add_value(Templates::default());
let mut empty_templates = Templates::default();
empty_templates.register_filter("pretty_date", filters::pretty_date);
empty_templates.register_filter("pretty_datetime", filters::pretty_datetime);
let empty_templates = builder.add_value(empty_templates);
let default_path = content_path("layout/default.html");
let (default, invalidate_default) = builder.add_invalidatable_rule(AddTemplate::new(
@ -64,6 +67,12 @@ impl NodeValue for Templates {
}
}
impl Templates {
fn register_filter(&mut self, name: &str, filter: impl Filter + 'static) {
self.tera.register_filter(name, filter);
}
}
static DOMAIN: Lazy<String> =
Lazy::new(|| std::env::var("DOMAIN").unwrap_or("shadowfacts.net".to_owned()));
static CB: Lazy<u64> = Lazy::new(|| {
@ -128,5 +137,60 @@ impl Rule for RenderTemplate {
fn node_label(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.output_path.display())
pub mod filters {
use chrono::{DateTime, Datelike, Local};
use serde::Deserialize;
use std::collections::HashMap;
use tera::{Result, Value};
// pub fn iso_date(date: &NaiveDate) -> String {
// Utc::from_utc_datetime(&Utc, &date.and_hms_opt(12, 0, 0).unwrap())
// .format("%+:0")
// .to_string()
// }
// pub fn iso_datetime<Tz>(datetime: &DateTime<Tz>) -> String
// where
// Tz: TimeZone,
// Tz::Offset: Display,
// {
// datetime.format("%+:0").to_string()
// }
const MONTHS: &[&str; 12] = &[
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
];
pub fn pretty_date(value: &Value, _args: &HashMap<String, Value>) -> Result<Value> {
let date = DateTime::<Local>::deserialize(value)?;
Ok(Value::String(format_pretty_date(date)))
}
fn format_pretty_date(date: DateTime<Local>) -> String {
let month = MONTHS[date.month0() as usize];
let suffix = match date.day() {
1 | 21 | 31 => "st",
2 | 22 => "nd",
3 | 23 => "rd",
_ => "th",
};
format!("{} {}{}, {}", month, date.day(), suffix, date.year())
}
pub fn pretty_datetime(value: &Value, _args: &HashMap<String, Value>) -> Result<Value> {
dbg!(value);
let datetime = DateTime::<Local>::deserialize(value)?;
dbg!(&datetime);
let s = format!(
"{} {}",
datetime.format("%-I:%M:%S %p"),
format_pretty_date(datetime)
);
Ok(Value::String(s))
}
// pub fn reading_time(words: &u32) -> u32 {
// let wpm = 225.0;
// (*words as f32 / wpm).max(1.0) as u32
// }
}

View File

@ -23,55 +23,3 @@
// &*GENERATED_AT
// }
// }
pub mod filters {
use std::fmt::Display;
use chrono::{DateTime, Datelike, NaiveDate, TimeZone, Utc};
pub fn iso_date(date: &NaiveDate) -> String {
Utc::from_utc_datetime(&Utc, &date.and_hms_opt(12, 0, 0).unwrap())
.format("%+:0")
.to_string()
}
pub fn iso_datetime<Tz>(datetime: &DateTime<Tz>) -> String
where
Tz: TimeZone,
Tz::Offset: Display,
{
datetime.format("%+:0").to_string()
}
const MONTHS: &[&str; 12] = &[
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
];
pub fn pretty_date(date: &impl Datelike) -> String {
let month = MONTHS[date.month0() as usize];
let suffix = match date.day() {
1 | 21 | 31 => "st",
2 | 22 => "nd",
3 | 23 => "rd",
_ => "th",
};
format!("{} {}{}, {}", month, date.day(), suffix, date.year())
}
pub fn pretty_datetime<Tz>(datetime: &DateTime<Tz>) -> String
where
Tz: TimeZone,
Tz::Offset: Display,
{
format!(
"{} {}",
datetime.format("%-I:%M:%S %p"),
pretty_date(datetime)
)
}
pub fn reading_time(words: &u32) -> u32 {
let wpm = 225.0;
(*words as f32 / wpm).max(1.0) as u32
}
}