diff options
author | metamuffin <metamuffin@disroot.org> | 2022-08-29 16:10:49 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2022-08-29 16:10:49 +0200 |
commit | 18f53568b43380665686dc9e7785790f9921ce8f (patch) | |
tree | 8b32f2bfda532c77601fcd22fca2fce8761035ea /tools | |
parent | 9ca6cc8c0acdd68d2c79f1f990c9dd81dd9fef4b (diff) | |
download | metamuffin-blog-18f53568b43380665686dc9e7785790f9921ce8f.tar metamuffin-blog-18f53568b43380665686dc9e7785790f9921ce8f.tar.bz2 metamuffin-blog-18f53568b43380665686dc9e7785790f9921ce8f.tar.zst |
a
Diffstat (limited to 'tools')
-rw-r--r-- | tools/.gitignore | 1 | ||||
-rw-r--r-- | tools/makefile | 13 | ||||
-rw-r--r-- | tools/src/main.rs | 57 | ||||
-rw-r--r-- | tools/src/markdown.rs | 54 |
4 files changed, 65 insertions, 60 deletions
diff --git a/tools/.gitignore b/tools/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/tools/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/tools/makefile b/tools/makefile index acd0717..15b8a45 100644 --- a/tools/makefile +++ b/tools/makefile @@ -1,5 +1,14 @@ TOOL := ../tools/target/debug/blog-tool -out/%.html: articles/%.html $(TOOL) - $(TOOL) render -i $< -o $@ +SRC_ARTICLES := $(shell find articles -type f) +OUT_ARTICLES := $(SRC_ARTICLES:articles/%.md=out/%.html) + +all: $(OUT_ARTICLES) + +out/%.html: articles/%.md $(TOOL) + mkdir -p out + $(TOOL) render-article $< > $@ + +$(TOOL): $(shell find ../tools/src -type f) + sh -c 'cd ../tools; cargo build' diff --git a/tools/src/main.rs b/tools/src/main.rs index 396d148..3f3c065 100644 --- a/tools/src/main.rs +++ b/tools/src/main.rs @@ -1,11 +1,11 @@ - use std::{ fs::{read_to_string, File}, io::Write, }; use clap::{Parser, Subcommand}; -use laby::{html, internal::Buffer, Render}; +use laby::{html, internal::Buffer, raw, Render}; +use markdown::{Block, Span}; #[derive(Parser)] struct Args { @@ -45,6 +45,57 @@ fn scaffold(title: String, body: impl Render) -> impl Render { html!(head!(title!(title)), body!(body)) } -fn article(md_source: String) { +fn article(md_source: String) -> impl Render { + scaffold( + "blub".to_string(), + raw!(blocks_to_html(markdown::tokenize(&md_source))), + ) +} + +fn span_to_html(ss: Vec<Span>) -> String { + let mut out = String::new(); + for s in ss { + out += match s { + Span::Break => format!("<br/>"), + Span::Text(t) => escape(&t), + Span::Code(c) => format!("<pre><code>{}</code></pre>", escape(&c)), + Span::Link(text, url, _) => { + format!("<a href=\"{}\">{}</a>", escape(&url), escape(&text)) + } + Span::Image(_, _, _) => todo!(), + Span::Emphasis(c) => format!("<i>{}</i>", span_to_html(c)), + Span::Strong(c) => format!("<b>{}</b>", span_to_html(c)), + } + .as_str() + } + out +} +fn blocks_to_html(blocks: Vec<Block>) -> String { + let mut out = String::new(); + for e in blocks { + out += match e { + markdown::Block::Header(text, level) => { + format!("<h{level}>{}</h{level}>", span_to_html(text)) + } + markdown::Block::Paragraph(p) => span_to_html(p), + markdown::Block::Blockquote(q) => format!("<quote>{}</quote>", blocks_to_html(q)), + markdown::Block::CodeBlock(_syntax, content) => { + format!("<pre><code>{}</code></pre>", escape(&content)) // TODO syntax highlighting + } + markdown::Block::OrderedList(_, _) => todo!(), + markdown::Block::UnorderedList(_) => todo!(), + markdown::Block::Raw(r) => r, + markdown::Block::Hr => format!("<hr/>"), + } + .as_str(); + } + out +} +fn escape(text: &str) -> String { + text.replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace("'", "’") + .replace("\"", """) } diff --git a/tools/src/markdown.rs b/tools/src/markdown.rs deleted file mode 100644 index af3798e..0000000 --- a/tools/src/markdown.rs +++ /dev/null @@ -1,54 +0,0 @@ -pub struct Markdown(Vec<MdElement>); - -pub enum MdElement { - Heading(u8, Vec<RichText>), - Paragraph(Vec<RichText>), - Code { syntax: String, content: String }, -} - -pub enum RichText { - Text(String), - Bold(Box<RichText>), - Strike(Box<RichText>), - Italic(Box<RichText>), - Code(Box<RichText>), - Link(String, Vec<RichText>), -} - -impl Markdown { - pub fn parse(s: &str) -> anyhow::Result<Self> { - let mut c = vec![]; - let mut lines = s.lines(); - while let Some(line) = lines.next() { - if line.starts_with("#") { - let (hashes, h) = line.split_once(' ').unwrap(); - c.push(MdElement::Heading(hashes.len() as u8, RichText::parse(h)?)); - } else if line.starts_with("```") { - todo!() - } else { - let mut block = line.to_string(); - while let Some(line) = lines.next() { - if line == "" { - break; - } - block += line; - } - c.push(MdElement::Paragraph(RichText::parse(&block)?)) - } - } - Ok(Markdown(c)) - } -} -impl RichText { - pub fn parse(s: &str) -> anyhow::Result<Vec<Self>> { - let mut before = String::new(); - let mut after = String::new(); - let mut after_el = false; - for c in s.chars() { - match c { - _ => {} - } - } - Ok(segs) - } -} |