Switch over to WebAssembly, Rust and Yew #35

Merged
BlakeRain merged 87 commits from yew-static into main 2023-08-30 18:01:40 +00:00
4 changed files with 118 additions and 12 deletions
Showing only changes of commit 026216cc3d - Show all commits

View File

@ -158,6 +158,11 @@ where
} }
} }
fn get_footnote_ix(&mut self, name: CowStr<'a>) -> usize {
let next = self.footnotes.len() + 1;
*self.footnotes.entry(name).or_insert(next)
}
fn output<N: Into<RenderNode>>(&mut self, node: N) { fn output<N: Into<RenderNode>>(&mut self, node: N) {
if let Some(top) = self.stack.last_mut() { if let Some(top) = self.stack.last_mut() {
top.add_child(node) top.add_child(node)
@ -342,7 +347,7 @@ where
} }
} }
fn start(&mut self, tag: Tag) { fn start(&mut self, tag: Tag<'a>) {
match tag { match tag {
Tag::Paragraph => self.enter(RenderElement::new(TagName::P)), Tag::Paragraph => self.enter(RenderElement::new(TagName::P)),
@ -491,7 +496,23 @@ where
p.map(|p| self.enter(p)); p.map(|p| self.enter(p));
} }
_ => {} Tag::FootnoteDefinition(name) => {
let mut div = RenderElement::new(TagName::Div);
div.add_attribute(AttributeName::Class, "footnote");
div.add_attribute(AttributeName::Id, name.to_string());
let index = self.get_footnote_ix(name);
let mut left = RenderElement::new(TagName::Div);
left.add_attribute(AttributeName::Class, "footnote-index");
left.add_child(RenderText::new(index.to_string()));
div.add_child(left);
let mut right = RenderElement::new(TagName::Div);
right.add_attribute(AttributeName::Class, "footnote-def");
self.enter(div);
self.enter(right);
}
} }
} }
@ -587,8 +608,12 @@ where
Tag::Strong => self.leave(TagName::Strong), Tag::Strong => self.leave(TagName::Strong),
Tag::Strikethrough => self.leave(TagName::S), Tag::Strikethrough => self.leave(TagName::S),
Tag::Link(_, _, _) => self.leave(TagName::A), Tag::Link(_, _, _) => self.leave(TagName::A),
Tag::Image(_, _, _) => {}
_ => {} Tag::FootnoteDefinition(_) => {
self.leave(TagName::Div); // <div .right>
self.leave(TagName::Div); // <div .footnote>
}
} }
} }
@ -611,9 +636,12 @@ where
Event::SoftBreak | Event::HardBreak | Event::Rule => output.push(' '), Event::SoftBreak | Event::HardBreak | Event::Rule => output.push(' '),
Event::FootnoteReference(name) => { Event::FootnoteReference(name) => {
let ix = {
let next = self.footnotes.len() + 1; let next = self.footnotes.len() + 1;
let footnote = *self.footnotes.entry(name).or_insert(next); *self.footnotes.entry(name).or_insert(next)
output.push_str(&format!("[{footnote}]")); };
output.push_str(&format!("[{ix}]"));
} }
Event::TaskListMarker(true) => output.push_str("[x]"), Event::TaskListMarker(true) => output.push_str("[x]"),
@ -624,7 +652,7 @@ where
output output
} }
fn event(&mut self, event: Event) { fn event(&mut self, event: Event<'a>) {
match event { match event {
Event::Start(tag) => self.start(tag), Event::Start(tag) => self.start(tag),
Event::End(tag) => self.end(tag), Event::End(tag) => self.end(tag),
@ -659,7 +687,34 @@ where
self.output(RenderElement::new(TagName::Br)); self.output(RenderElement::new(TagName::Br));
} }
_ => {} Event::Rule => {
self.output(RenderElement::new(TagName::Hr));
}
Event::FootnoteReference(name) => {
let mut sup = RenderElement::new(TagName::Sup);
let mut anchor = RenderElement::new(TagName::A);
anchor.add_attribute(AttributeName::Href, format!("#{name}"));
let ix = self.get_footnote_ix(name);
anchor.add_child(RenderText::new(ix.to_string()));
sup.add_child(anchor);
self.output(sup);
}
Event::TaskListMarker(checked) => {
let mut input = RenderElement::new(TagName::Input);
input.add_attribute(AttributeName::Type, "checkbox");
input.add_attribute(AttributeName::Disabled, "");
input.add_attribute(AttributeName::Class, "mr-2");
if checked {
input.add_attribute(AttributeName::Checked, "");
}
self.output(input);
}
} }
} }

View File

@ -138,7 +138,9 @@ pub enum TagName {
H4, H4,
H5, H5,
H6, H6,
Hr,
Img, Img,
Input,
Li, Li,
Ol, Ol,
P, P,
@ -146,6 +148,7 @@ pub enum TagName {
S, S,
Span, Span,
Strong, Strong,
Sup,
TBody, TBody,
THead, THead,
Table, Table,
@ -173,7 +176,9 @@ impl TagName {
TagName::H4 => "h4", TagName::H4 => "h4",
TagName::H5 => "h5", TagName::H5 => "h5",
TagName::H6 => "h6", TagName::H6 => "h6",
TagName::Hr => "hr",
TagName::Img => "img", TagName::Img => "img",
TagName::Input => "input",
TagName::Li => "li", TagName::Li => "li",
TagName::Ol => "ol", TagName::Ol => "ol",
TagName::P => "p", TagName::P => "p",
@ -181,6 +186,7 @@ impl TagName {
TagName::S => "s", TagName::S => "s",
TagName::Span => "span", TagName::Span => "span",
TagName::Strong => "strong", TagName::Strong => "strong",
TagName::Sup => "sup",
TagName::TBody => "tbody", TagName::TBody => "tbody",
TagName::THead => "thead", TagName::THead => "thead",
TagName::Table => "table", TagName::Table => "table",
@ -201,8 +207,10 @@ pub struct RenderAttribute {
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum AttributeName { pub enum AttributeName {
Alt, Alt,
Checked,
Class, Class,
Decoding, Decoding,
Disabled,
Href, Href,
Id, Id,
Loading, Loading,
@ -210,14 +218,17 @@ pub enum AttributeName {
Start, Start,
Style, Style,
Title, Title,
Type,
} }
impl AttributeName { impl AttributeName {
pub fn as_str(&self) -> &'static str { pub fn as_str(&self) -> &'static str {
match self { match self {
AttributeName::Alt => "alt", AttributeName::Alt => "alt",
AttributeName::Checked => "checked",
AttributeName::Class => "class", AttributeName::Class => "class",
AttributeName::Decoding => "decoding", AttributeName::Decoding => "decoding",
AttributeName::Disabled => "disabled",
AttributeName::Href => "href", AttributeName::Href => "href",
AttributeName::Id => "id", AttributeName::Id => "id",
AttributeName::Loading => "loading", AttributeName::Loading => "loading",
@ -225,6 +236,7 @@ impl AttributeName {
AttributeName::Start => "start", AttributeName::Start => "start",
AttributeName::Style => "style", AttributeName::Style => "style",
AttributeName::Title => "title", AttributeName::Title => "title",
AttributeName::Type => "type",
} }
} }
} }

View File

@ -4,15 +4,32 @@ fn main() {
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
wasm_logger::init(wasm_logger::Config::default()); wasm_logger::init(wasm_logger::Config::default());
log::info!(
"blakerain.com {}, {} {} build",
env!("CARGO_PKG_VERSION"),
if cfg!(debug_assertions) {
"debug"
} else {
"release"
},
if cfg!(feature = "hydration") {
"hydration"
} else {
"standard"
}
);
let app = yew::Renderer::<App>::new();
#[cfg(feature = "hydration")] #[cfg(feature = "hydration")]
{ {
log::info!("Hydration build; hydrating application"); log::info!("Hydrating application");
yew::Renderer::<App>::new().hydrate(); app.hydrate();
} }
#[cfg(not(feature = "hydration"))] #[cfg(not(feature = "hydration"))]
{ {
log::info!("Standard build; rendering application"); log::info!("Rendering application");
yew::Renderer::<App>::new().render(); app.render();
} }
} }

View File

@ -58,6 +58,28 @@
@apply hover:text-blue-600 dark:hover:text-blue-300; @apply hover:text-blue-600 dark:hover:text-blue-300;
} }
.footnote {
@apply mb-8 flex flex-row gap-1 text-base text-gray-500 dark:text-gray-400;
&:has(+ .footnote) {
@apply mb-0;
}
div.footnote-index {
@apply leading-relaxed mr-2;
&:after {
content: ".";
}
}
p {
&:last-child {
@apply mb-0;
}
}
}
dl, dl,
ul, ul,
ol { ol {