Make default element generic

This commit is contained in:
Juno Takano 2025-12-16 19:01:20 -03:00
commit 5d28a2e707
6 changed files with 92 additions and 53 deletions

View file

@ -1,2 +1,3 @@
pub(super) mod paragraph;
pub(super) mod header;
pub mod header;
pub mod paragraph;
pub mod span;

View file

@ -1,7 +1,7 @@
use std::fmt::Display;
use crate::syntax::content::{Parseable, Lexeme};
pub(in crate::syntax::content) struct Paragraph {
pub struct Paragraph {
text: String,
}

View file

@ -1,16 +1,17 @@
use super::{Parseable as _, Token, Lexeme, LEXMAP};
use crate::syntax::content::{Parseable, Token, Lexeme, make_lexmap};
pub fn read(text: &str) -> String {
parse(&lex(text))
pub fn read<DefaultToken: Parseable>(text: &str) -> String {
let escaped_text = tera::escape_html(text);
parse(&lex(&escaped_text, &make_lexmap::<DefaultToken>()))
}
fn lex(text: &str) -> Vec<Token> {
let mut tokens = Vec::new();
fn lex(text: &str, map: super::LexMap) -> Vec<Token> {
let mut tokens: Vec<Token> = Vec::new();
for line in text.lines().filter(|x| !x.trim().is_empty()) {
let lexeme = Lexeme::new(line);
for &(ref matcher, lexer) in LEXMAP {
for &(ref matcher, lexer) in map {
if matcher(&lexeme) {
tokens.push(lexer(&lexeme));
break;
@ -22,13 +23,9 @@ fn lex(text: &str) -> Vec<Token> {
}
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")
tokens
.iter()
.map(Token::render)
.collect::<Vec<_>>()
.join("\n")
}

View file

@ -0,0 +1,54 @@
use crate::syntax::content::Parseable as _;
use crate::syntax::content::elements::{
paragraph::Paragraph, header::Header, span::Span,
};
pub enum Token {
Paragraph(Paragraph),
Header(Header),
Span(Span),
}
impl Token {
pub fn render(&self) -> String {
match *self {
Token::Paragraph(ref d) => d.render(),
Token::Header(ref d) => d.render(),
Token::Span(ref d) => d.render(),
}
}
}
impl From<Paragraph> for Token {
fn from(d: Paragraph) -> Self {
Token::Paragraph(d)
}
}
impl From<Header> for Token {
fn from(d: Header) -> Self {
Token::Header(d)
}
}
impl From<Span> for Token {
fn from(d: Span) -> Self {
Token::Span(d)
}
}
pub struct Lexeme<'l> {
pub raw: &'l str,
pub first: &'l str,
}
impl<'l> Lexeme<'l> {
pub fn new(text: &'l str) -> Lexeme<'l> {
let vec: Vec<&'l str> = text.split(" ").collect();
Self {
raw: text,
first: vec.first().unwrap_or_else(|| unreachable!()),
}
}
}