aboutsummaryrefslogtreecommitdiff
path: root/tools/src
diff options
context:
space:
mode:
Diffstat (limited to 'tools/src')
-rw-r--r--tools/src/main.rs57
-rw-r--r--tools/src/markdown.rs54
2 files changed, 54 insertions, 57 deletions
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("&", "&amp;")
+ .replace("<", "&lt;")
+ .replace(">", "&gt;")
+ .replace("'", "&#8217;")
+ .replace("\"", "&quot;")
}
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)
- }
-}