about summary refs log tree commit diff
path: root/markup/src/lib.rs
diff options
context:
space:
mode:
authorgennyble <gen@nyble.dev>2026-07-16 00:05:36 -0500
committergennyble <gen@nyble.dev>2026-07-16 00:05:36 -0500
commit31d68ef3c57f05586431f8fbf7bf3e45d94c62be (patch)
tree30d5d0e2b2a2b2093abb4569d52ea5b5692cde14 /markup/src/lib.rs
parent95bb06aa4462c13333af613f4849ee00a7dc83c5 (diff)
move markup to it's own library
Diffstat (limited to 'markup/src/lib.rs')
-rw-r--r--markup/src/lib.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/markup/src/lib.rs b/markup/src/lib.rs
new file mode 100644
index 0000000..1594d5b
--- /dev/null
+++ b/markup/src/lib.rs
@@ -0,0 +1,103 @@
+mod state;
+
+use std::ops::Deref;
+
+use bempline::{Document, Options};
+
+use crate::state::State;
+
+pub fn process(raw: &str) -> Markup {
+	let mut state = State::default();
+
+	for line in raw.lines() {
+		state.process_line(line)
+	}
+
+	state.done()
+}
+
+pub struct Markup {
+	content: String,
+	fill: Vec<Fill>,
+}
+
+impl Markup {
+	pub fn fill(&self) -> &[Fill] {
+		&self.fill
+	}
+
+	pub fn content(&self) -> &str {
+		&self.content
+	}
+
+	pub fn into_content(self) -> String {
+		self.content
+	}
+
+	pub fn into_document(self) -> Result<Document, String> {
+		let Ok(mut doc) = Document::from_str(&self.content, Options::default()) else {
+			return Err(self.content);
+		};
+
+		self.fill_document(&mut doc);
+
+		Ok(doc)
+	}
+
+	pub fn fill_document(&self, doc: &mut Document) {
+		for fill in &self.fill {
+			doc.set(&fill.key, &fill.content);
+		}
+	}
+}
+
+impl Deref for Markup {
+	type Target = String;
+
+	fn deref(&self) -> &Self::Target {
+		&self.content
+	}
+}
+
+#[derive(Clone, Debug, PartialEq)]
+pub struct Fill {
+	pub key: String,
+	pub content: String,
+}
+
+#[cfg(test)]
+mod document_test {
+	use crate::process;
+
+	const BASE: &str = "test/markup";
+	fn test_files(test: &str) {
+		let input_path = format!("{BASE}/{test}/input.html");
+		let output_path = format!("{BASE}/{test}/output.html");
+
+		let input = std::fs::read_to_string(input_path).unwrap();
+		let output = std::fs::read_to_string(output_path).unwrap();
+
+		let actual = process(&input).into_document().unwrap().compile();
+
+		assert_eq!(actual, output)
+	}
+
+	#[test]
+	fn inserts_fill() {
+		let input = "[@fill main]\nwords!\n[@fill-end]\n{main}";
+		let expected = "<p>\nwords!\n</p>";
+		let markup = process(input);
+		let doc = markup.into_document().unwrap().compile();
+		assert_eq!(doc, expected)
+	}
+
+	#[test]
+	fn fill_restores_paragraphs() {
+		test_files("fill paragraphs");
+	}
+
+	#[test]
+	fn parses_complicated_fill() {
+		test_files("complicated fill");
+	}
+}