From b89934d3ac5722dae41b90d52257734fd31baa44 Mon Sep 17 00:00:00 2001
From: CrispyPin
\n"; + continue; + } + + if state == S::Code { + html += line; + html += "\n"; + continue; + } + + if let Some((start, header)) = line.split_once(' ') { + let level = start.len(); + if (1..=6).contains(&level) && start.chars().all(|c| c == '#') { + if state == S::P { + state = S::None; + html += "\n"; + } + let header = &convert_line(header); + html += &format!("\n"; - state = S::None; - continue; - } - if state == S::P { - html += "\n"; - } - state = S::Code; - html += "{header} \n"); + continue; + } + } + + if state == S::P && line.is_empty() { + state = S::None; + html += "\n"; + } else if !line.is_empty() { + if state == S::None { + state = S::P; + html += "\n"; + } + html += &convert_line(line); + html += "
\n"; + } + } + html +} + +fn convert_line(source: &str) -> String { + let mut out = String::new(); + let mut is_em = false; + let mut is_b = false; + let mut is_code = false; + let mut is_ul = false; + let toggle = |state: bool, tag: &str| { + if state { + format!("<{tag}>") + } else { + format!("{tag}>") + } + }; + + let mut link: Option<(String, Option)> = None; + + let mut chars = source.chars().peekable(); + while let Some(c) = chars.next() { + if let Some(link_c) = &mut link { + match link_c { + (link_text, None) => { + if c == ']' { + if chars.peek() == Some(&'(') { + _ = chars.next(); + link_c.1 = Some(String::new()); + } else { + out += &format!("[{link_text}]"); + link = None; + } + } else { + link_text.push(c); + } + } + (link_text, Some(href)) => { + if c == ')' { + out += &format!("{link_text}"); + link = None; + } else { + href.push(c); + } + } + } + continue; + } + if c == '[' { + link = Some((String::new(), None)); + } else if c == '*' { + if chars.peek() == Some(&'*') { + _ = chars.next(); + is_b = !is_b; + out += &toggle(is_b, "strong"); + } else { + is_em = !is_em; + out += &toggle(is_em, "em"); + } + } else if c == '`' { + is_code = !is_code; + out += &toggle(is_code, "code"); + } else if c == '_' { + is_ul = !is_ul; + out += &toggle(is_ul, "u"); + } else { + out.push(c); + } + } + if let Some((link_text, href)) = link { + out += &format!("[{link_text}"); + if let Some(href) = href { + out += &format!("]({href}"); + } + } + + if is_em { + out += ""; + } + if is_b { + out += ""; + } + if is_code { + out += ""; + } + if is_ul { + out += ""; + } + out +} diff --git a/src/main.rs b/src/main.rs index 8681195..13add86 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,9 @@ use std::{ path::{Path, PathBuf}, }; +mod convert; +use convert::convert_document; + const SRC_DIR: &str = "write"; const OUT_DIR: &str = "site"; const CONTENT_MARKER: &str = "CONTENT HERE"; @@ -53,67 +56,12 @@ fn build_file(path: &Path) -> Result { } } -#[derive(Debug, Clone, PartialEq)] -enum S { - None, - P, - Code, -} - fn convert_file(path: &Path) -> Result { - let markdown = read_to_string(path)?; let out_path = PathBuf::from(OUT_DIR).join(path.strip_prefix(SRC_DIR)?); let out_path = out_path.with_extension("html"); - let mut html = String::new(); - let mut state = S::None; - - for line in markdown.lines() { - if line.starts_with("```") { - if state == S::Code { - html += "
\n"; - continue; - } - - if state == S::Code { - html += line; - html += "\n"; - continue; - } - - if let Some((start, header)) = line.split_once(' ') { - let level = start.len(); - if (1..=6).contains(&level) && start.chars().all(|c| c == '#') { - if state == S::P { - state = S::None; - html += "\n"; - } - let header = &convert_line(header); - html += &format!("\n"; state = S::None; - continue; + } else { + if state == S::P { + html += "\n"; + } + state = S::Code; + html += "{header} \n"); - continue; - } - } - - if state == S::P && line.is_empty() { - state = S::None; - html += "\n"; - } else if !line.is_empty() { - if state == S::None { - state = S::P; - html += "\n"; - } - html += &convert_line(line); - html += "
\n"; - } - } + let markdown = read_to_string(path)?; + let html = convert_document(&markdown); let template = read_to_string(TEMPLATE_FILE)?; let html = template.replacen(CONTENT_MARKER, &html, 1); @@ -126,90 +74,3 @@ fn convert_file(path: &Path) -> Result { println!("built {}", out_path.display()); Ok(()) } - -fn convert_line(source: &str) -> String { - let mut out = String::new(); - let mut is_em = false; - let mut is_b = false; - let mut is_code = false; - let mut is_ul = false; - let toggle = |state: bool, tag: &str| { - if state { - format!("<{tag}>") - } else { - format!("{tag}>") - } - }; - - let mut link: Option<(String, Option)> = None; - - let mut chars = source.chars().peekable(); - while let Some(c) = chars.next() { - if let Some(link_c) = &mut link { - match link_c { - (link_text, None) => { - if c == ']' { - if chars.peek() == Some(&'(') { - _ = chars.next(); - link_c.1 = Some(String::new()); - } else { - out += &format!("[{link_text}]"); - link = None; - } - } else { - link_text.push(c); - } - } - (link_text, Some(href)) => { - if c == ')' { - out += &format!("{link_text}"); - link = None; - } else { - href.push(c); - } - } - } - continue; - } - if c == '[' { - link = Some((String::new(), None)); - } else if c == '*' { - if chars.peek() == Some(&'*') { - _ = chars.next(); - is_b = !is_b; - out += &toggle(is_b, "strong"); - } else { - is_em = !is_em; - out += &toggle(is_em, "em"); - } - } else if c == '`' { - is_code = !is_code; - out += &toggle(is_code, "code"); - } else if c == '_' { - is_ul = !is_ul; - out += &toggle(is_ul, "u"); - } else { - out.push(c); - } - } - if let Some((link_text, href)) = link { - out += &format!("[{link_text}"); - if let Some(href) = href { - out += &format!("]({href}"); - } - } - - if is_em { - out += &toggle(false, "em"); - } - if is_b { - out += &toggle(false, "b"); - } - if is_code { - out += &toggle(false, "code"); - } - if is_ul { - out += &toggle(false, "u"); - } - out -} From 07daad708b79d48084a7441796604303ac2f9092 Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Fri, 26 Apr 2024 23:14:06 +0200 Subject: [PATCH 2/3] add filename to template title --- src/convert.rs | 12 ++++++------ src/main.rs | 11 +++++++---- template.html | 4 ++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/convert.rs b/src/convert.rs index 0a211e6..2e81fd2 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -14,13 +14,13 @@ pub fn convert_document(markdown: &str) -> String { if state == S::Code { html += "
\n"; } - if state == S::P { - html += "\n"; - } - state = S::Code; - html += "\n"; continue; } diff --git a/src/main.rs b/src/main.rs index 13add86..2027512 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,8 @@ use convert::convert_document; const SRC_DIR: &str = "write"; const OUT_DIR: &str = "site"; -const CONTENT_MARKER: &str = "CONTENT HERE"; +const CONTENT_MARKER: &str = "{CONTENT}"; +const FILENAME_MARKER: &str = "{FILENAME}"; const TEMPLATE_FILE: &str = "template.html"; const DEFAULT_TEMPLATE: &[u8] = include_bytes!("../template.html"); @@ -61,10 +62,12 @@ fn convert_file(path: &Path) -> Result { let out_path = out_path.with_extension("html"); let markdown = read_to_string(path)?; - let html = convert_document(&markdown); - + let content = convert_document(&markdown); let template = read_to_string(TEMPLATE_FILE)?; - let html = template.replacen(CONTENT_MARKER, &html, 1); + let filename = path.file_stem().unwrap().to_string_lossy().to_string(); + let html = template + .replacen(CONTENT_MARKER, &content, 1) + .replace(FILENAME_MARKER, &filename); DirBuilder::new() .recursive(true) diff --git a/template.html b/template.html index 67f63de..7d852ce 100644 --- a/template.html +++ b/template.html @@ -4,11 +4,11 @@ -TITLE HERE +Title - {FILENAME} - CONTENT HERE + {CONTENT}