Heavy refactor and restructuring of content parser
This commit is contained in:
parent
15a9175afb
commit
984c8bcdcc
7 changed files with 171 additions and 134 deletions
2
src/syntax/content/elements.rs
Normal file
2
src/syntax/content/elements.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
pub(super) mod paragraph;
|
||||
pub(super) mod header;
|
||||
77
src/syntax/content/elements/header.rs
Normal file
77
src/syntax/content/elements/header.rs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
use crate::{
|
||||
dev::log,
|
||||
syntax::content::{Parseable, Lexeme},
|
||||
};
|
||||
use std::fmt::Display;
|
||||
|
||||
enum Level {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
Five,
|
||||
Six,
|
||||
}
|
||||
|
||||
impl Display for Level {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match *self {
|
||||
Level::One => write!(f, "1"),
|
||||
Level::Two => write!(f, "2"),
|
||||
Level::Three => write!(f, "3"),
|
||||
Level::Four => write!(f, "4"),
|
||||
Level::Five => write!(f, "5"),
|
||||
Level::Six => write!(f, "6"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(in crate::syntax::content) struct Header {
|
||||
level: Level,
|
||||
text: String,
|
||||
}
|
||||
|
||||
impl Header {
|
||||
fn new(level: usize, text: &str) -> Self {
|
||||
Self {
|
||||
level: match level {
|
||||
1 => Level::One,
|
||||
2 => Level::Two,
|
||||
3 => Level::Three,
|
||||
4 => Level::Four,
|
||||
5 => Level::Five,
|
||||
6 => Level::Six,
|
||||
_ => {
|
||||
panic!("Attempted to construct a header with invalid level")
|
||||
},
|
||||
},
|
||||
text: text.to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parseable for Header {
|
||||
fn probe(lexeme: &Lexeme) -> bool {
|
||||
!lexeme.first.trim().is_empty()
|
||||
&& lexeme.first.replace("#", "").is_empty()
|
||||
&& lexeme.first.len() <= 6
|
||||
}
|
||||
|
||||
fn lex(lexeme: &Lexeme) -> Self {
|
||||
let header_level = lexeme.first.len();
|
||||
log(&Self::lex, &format!("Header level is {header_level}"));
|
||||
|
||||
let header_text = lexeme.raw.replace(lexeme.first, "");
|
||||
|
||||
Self::new(header_level, &header_text)
|
||||
}
|
||||
|
||||
fn render(&self) -> String {
|
||||
format!("<h{}>{}</h{0}>", &self.level, self.text)
|
||||
}
|
||||
}
|
||||
impl Display for Header {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "Level {} Header: <{}>", &self.level, self.text)
|
||||
}
|
||||
}
|
||||
28
src/syntax/content/elements/paragraph.rs
Normal file
28
src/syntax/content/elements/paragraph.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
use std::fmt::Display;
|
||||
use crate::syntax::content::{Parseable, Lexeme};
|
||||
|
||||
pub(in crate::syntax::content) struct Paragraph {
|
||||
text: String,
|
||||
}
|
||||
|
||||
impl Parseable for Paragraph {
|
||||
fn probe(lexeme: &Lexeme) -> bool {
|
||||
!lexeme.raw.trim().is_empty()
|
||||
}
|
||||
|
||||
fn lex(lexeme: &Lexeme) -> Self {
|
||||
Self {
|
||||
text: lexeme.raw.trim().to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn render(&self) -> String {
|
||||
format!("<p>{}</p>", &self.text)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Paragraph {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "Paragraph: <{}>", &self.text)
|
||||
}
|
||||
}
|
||||
38
src/syntax/content/parser.rs
Normal file
38
src/syntax/content/parser.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
use super::{Parseable as _, Token, Lexeme, LEXMAP};
|
||||
|
||||
pub fn read(text: &str) -> String {
|
||||
parse(&lex(text))
|
||||
}
|
||||
|
||||
fn lex(text: &str) -> Vec<Token> {
|
||||
let mut tokens = Vec::new();
|
||||
|
||||
for line in text
|
||||
.lines()
|
||||
.filter(|x| !x.is_empty())
|
||||
.filter(|x| !x.replace(" ", "").is_empty())
|
||||
{
|
||||
let lexeme = Lexeme::new(line);
|
||||
|
||||
for &(ref matcher, lexer) in LEXMAP {
|
||||
if matcher(&lexeme) {
|
||||
tokens.push(lexer(&lexeme));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tokens
|
||||
}
|
||||
|
||||
fn parse(tokens: &[Token]) -> String {
|
||||
let mut out_text: Vec<String> = Vec::new();
|
||||
for token in tokens {
|
||||
out_text.push(match *token {
|
||||
Token::Paragraph(ref d) => d.render(),
|
||||
Token::Header(ref d) => d.render(),
|
||||
});
|
||||
}
|
||||
|
||||
out_text.join("\n")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue