diff options
| author | gennyble <gen@nyble.dev> | 2026-07-16 00:05:36 -0500 |
|---|---|---|
| committer | gennyble <gen@nyble.dev> | 2026-07-16 00:05:36 -0500 |
| commit | 31d68ef3c57f05586431f8fbf7bf3e45d94c62be (patch) | |
| tree | 30d5d0e2b2a2b2093abb4569d52ea5b5692cde14 /markup/src/lib.rs | |
| parent | 95bb06aa4462c13333af613f4849ee00a7dc83c5 (diff) | |
move markup to it's own library
Diffstat (limited to 'markup/src/lib.rs')
| -rw-r--r-- | markup/src/lib.rs | 103 |
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"); + } +} |
