mirror of
https://github.com/TxtDot/dalet-rs.git
synced 2024-11-21 16:26:21 +03:00
feat: daleth parser
This commit is contained in:
parent
9c41541712
commit
9592a8ffba
7 changed files with 134 additions and 38 deletions
|
@ -40,7 +40,7 @@ fn additional_str<'src>(
|
||||||
Token::TextBody(_) => "",
|
Token::TextBody(_) => "",
|
||||||
Token::MLText(_) => "",
|
Token::MLText(_) => "",
|
||||||
Token::MLMSText(_, _) => "",
|
Token::MLMSText(_, _) => "",
|
||||||
Token::RMLText(_) => "",
|
Token::MLRText(_) => "",
|
||||||
|
|
||||||
_ => "\n",
|
_ => "\n",
|
||||||
};
|
};
|
||||||
|
@ -100,7 +100,7 @@ pub fn format<'src>(spanned_tokens: &Vec<Spanned<Token<'src>>>) -> String {
|
||||||
set_indent(t, current_indent + 1),
|
set_indent(t, current_indent + 1),
|
||||||
prepend_indent("}", current_indent)
|
prepend_indent("}", current_indent)
|
||||||
),
|
),
|
||||||
Token::RMLText(t) => format!(" {{#{t}}}\n"),
|
Token::MLRText(t) => format!(" {{#{t}}}\n"),
|
||||||
Token::Comment(c) => format!("{}\n", prepend_indent(&format!("#{c}"), current_indent)),
|
Token::Comment(c) => format!("{}\n", prepend_indent(&format!("#{c}"), current_indent)),
|
||||||
|
|
||||||
Token::TextTag(t) => format!("{}\n", prepend_indent(t, current_indent)),
|
Token::TextTag(t) => format!("{}\n", prepend_indent(t, current_indent)),
|
||||||
|
|
|
@ -159,7 +159,7 @@ fn textual<'src>() -> impl Parser<'src, &'src str, Token<'src>, extra::Err<Rich<
|
||||||
|
|
||||||
let rmltext = multiline_text_body
|
let rmltext = multiline_text_body
|
||||||
.delimited_by(just("{#"), just('}'))
|
.delimited_by(just("{#"), just('}'))
|
||||||
.map(Token::RMLText)
|
.map(Token::MLRText)
|
||||||
.labelled("Raw multiline text");
|
.labelled("Raw multiline text");
|
||||||
|
|
||||||
choice((paragraph, mlmstext, rmltext, mltext, text_body, text_tag))
|
choice((paragraph, mlmstext, rmltext, mltext, text_body, text_tag))
|
||||||
|
|
|
@ -20,8 +20,8 @@ pub enum Token<'src> {
|
||||||
MLText(&'src str),
|
MLText(&'src str),
|
||||||
/// Multi Line with min spaces text
|
/// Multi Line with min spaces text
|
||||||
MLMSText(usize, &'src str),
|
MLMSText(usize, &'src str),
|
||||||
/// Raw Multi line text
|
/// Multi Line raw text
|
||||||
RMLText(&'src str),
|
MLRText(&'src str),
|
||||||
|
|
||||||
// Special
|
// Special
|
||||||
TextTag(&'src str),
|
TextTag(&'src str),
|
||||||
|
|
|
@ -3,8 +3,9 @@ pub mod types;
|
||||||
use super::{
|
use super::{
|
||||||
lexer::types::Token,
|
lexer::types::Token,
|
||||||
types::{Span, Spanned},
|
types::{Span, Spanned},
|
||||||
|
utils::{set_indent, trim_indent},
|
||||||
};
|
};
|
||||||
use crate::typed::{Page, Tag::*};
|
use crate::typed::{AlignArg, Body, Hl, NNArg, NNBody, Page, TNullArg, Tag::*};
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
use types::*;
|
use types::*;
|
||||||
|
|
||||||
|
@ -14,11 +15,133 @@ pub fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
||||||
Spanned<Page>,
|
Spanned<Page>,
|
||||||
extra::Err<Rich<'tokens, Token<'src>, Span>>,
|
extra::Err<Rich<'tokens, Token<'src>, Span>>,
|
||||||
> {
|
> {
|
||||||
let br = just(Token::Br).to(Br);
|
recursive(|tag| {
|
||||||
|
let tags_body = tag
|
||||||
|
.clone()
|
||||||
|
.repeated()
|
||||||
|
.collect()
|
||||||
|
.delimited_by(just(Token::LSquare), just(Token::RSquare));
|
||||||
|
|
||||||
let tag = br;
|
let text_body = select! {
|
||||||
|
Token::TextBody(t) => t.to_owned(),
|
||||||
|
Token::MLText(t) => trim_indent(t).to_owned(),
|
||||||
|
Token::MLMSText(n, t) => set_indent(t, n).to_owned(),
|
||||||
|
Token::MLRText(t) => t.to_owned()
|
||||||
|
};
|
||||||
|
|
||||||
tag.repeated()
|
let nnbody = text_body
|
||||||
.collect()
|
.map(NNBody::Text)
|
||||||
.map_with(|t, e| (Page { data: t }, e.span()))
|
.or(tags_body.clone().map(NNBody::Tags));
|
||||||
|
|
||||||
|
let body = text_body
|
||||||
|
.map(Body::Text)
|
||||||
|
.or(tags_body.clone().map(Body::Tags))
|
||||||
|
.or_not()
|
||||||
|
.to(Body::Null);
|
||||||
|
|
||||||
|
let num_arg = select! {
|
||||||
|
Token::NumberArgument(n) => n
|
||||||
|
};
|
||||||
|
|
||||||
|
let text_arg = select! {
|
||||||
|
Token::TextArgument(t) => t.to_owned()
|
||||||
|
};
|
||||||
|
|
||||||
|
let nnarg = text_arg.map(NNArg::Text).or(num_arg.map(NNArg::Number));
|
||||||
|
let tnullarg = text_arg
|
||||||
|
.map(TNullArg::Text)
|
||||||
|
.or_not()
|
||||||
|
.map(|v| v.unwrap_or(TNullArg::Null));
|
||||||
|
let hlarg = num_arg.try_map(|n, s| Hl::try_from(n).map_err(|e| Rich::custom(s, e)));
|
||||||
|
let alignarg =
|
||||||
|
num_arg.try_map(|n, s| AlignArg::try_from(n).map_err(|e| Rich::custom(s, e)));
|
||||||
|
|
||||||
|
let el = just(Token::El).ignore_then(nnbody.clone()).map(El);
|
||||||
|
let h = just(Token::H)
|
||||||
|
.ignore_then(hlarg)
|
||||||
|
.then(text_body)
|
||||||
|
.map(|(level, body)| H(body, level));
|
||||||
|
let p = just(Token::P).ignore_then(nnbody.clone()).map(P);
|
||||||
|
let br = just(Token::Br).to(Br);
|
||||||
|
let ul = just(Token::Ul).ignore_then(tags_body.clone()).map(Ul);
|
||||||
|
let ol = just(Token::Ol).ignore_then(tags_body.clone()).map(Ol);
|
||||||
|
let row = just(Token::Row)
|
||||||
|
.ignore_then(alignarg.or_not())
|
||||||
|
.then(tags_body.clone())
|
||||||
|
.map(|(arg, body)| Row(body, arg.unwrap_or(AlignArg::Start)));
|
||||||
|
let link = just(Token::Link)
|
||||||
|
.ignore_then(text_arg.clone())
|
||||||
|
.then(body.clone())
|
||||||
|
.map(|(arg, body)| Link(body, arg));
|
||||||
|
let navlink = just(Token::Navlink)
|
||||||
|
.ignore_then(text_arg.clone())
|
||||||
|
.then(body.clone())
|
||||||
|
.map(|(arg, body)| Navlink(body, arg));
|
||||||
|
let btn = just(Token::Btn)
|
||||||
|
.ignore_then(text_arg.clone())
|
||||||
|
.then(body.clone())
|
||||||
|
.map(|(arg, body)| Btn(body, arg));
|
||||||
|
let navbtn = just(Token::Navbtn)
|
||||||
|
.ignore_then(text_arg.clone())
|
||||||
|
.then(body.clone())
|
||||||
|
.map(|(arg, body)| Navbtn(body, arg));
|
||||||
|
let img = just(Token::Img).ignore_then(text_arg.clone()).map(Img);
|
||||||
|
let table = just(Token::Table).ignore_then(tags_body.clone()).map(Table);
|
||||||
|
let tcol = just(Token::Tcol).ignore_then(tags_body.clone()).map(Tcol);
|
||||||
|
let tpcol = just(Token::Tpcol).ignore_then(tags_body.clone()).map(Tpcol);
|
||||||
|
let hr = just(Token::Hr).to(Hr);
|
||||||
|
let b = just(Token::B).ignore_then(text_body.clone()).map(B);
|
||||||
|
let i = just(Token::I).ignore_then(text_body.clone()).map(I);
|
||||||
|
let bq = just(Token::Bq).ignore_then(nnbody.clone()).map(Bq);
|
||||||
|
let footlnk = just(Token::Footlnk).ignore_then(nnarg).map(Footlnk);
|
||||||
|
let footn = just(Token::Footn)
|
||||||
|
.ignore_then(nnarg.clone())
|
||||||
|
.then(text_body.clone())
|
||||||
|
.map(|(arg, body)| Footn(body, arg));
|
||||||
|
let a = just(Token::A).ignore_then(nnarg.clone()).map(A);
|
||||||
|
let s = just(Token::S).ignore_then(text_body.clone()).map(S);
|
||||||
|
let sup = just(Token::Sup).ignore_then(text_body.clone()).map(Sup);
|
||||||
|
let sub = just(Token::Sub).ignore_then(text_body.clone()).map(Sub);
|
||||||
|
let disc = just(Token::Disc).ignore_then(nnbody.clone()).map(Disc);
|
||||||
|
let block = just(Token::Block)
|
||||||
|
.ignore_then(alignarg.or_not())
|
||||||
|
.then(nnbody.clone())
|
||||||
|
.map(|(arg, body)| Block(body, arg.unwrap_or(AlignArg::Start)));
|
||||||
|
let carousel = just(Token::Carousel)
|
||||||
|
.ignore_then(tags_body.clone())
|
||||||
|
.map(Carousel);
|
||||||
|
let code = just(Token::Code)
|
||||||
|
.ignore_then(tnullarg)
|
||||||
|
.then(text_body.clone())
|
||||||
|
.map(|(arg, body)| Code(body, arg));
|
||||||
|
let pre = just(Token::Pre).ignore_then(text_body.clone()).map(Pre);
|
||||||
|
let meta = just(Token::Meta)
|
||||||
|
.ignore_then(text_arg)
|
||||||
|
.then(text_body.clone())
|
||||||
|
.map(|(arg, body)| Meta(body, arg));
|
||||||
|
|
||||||
|
let el_text = select! {
|
||||||
|
Token::TextTag(t) => El(NNBody::Text(t.to_owned()))
|
||||||
|
};
|
||||||
|
|
||||||
|
let el_tags = tag
|
||||||
|
.repeated()
|
||||||
|
.collect()
|
||||||
|
.delimited_by(just(Token::ElOpen), just(Token::ElClose))
|
||||||
|
.map(|v| El(NNBody::Tags(v)));
|
||||||
|
|
||||||
|
let paragraph = select! {
|
||||||
|
Token::Paragraph(t) => P(NNBody::Text(t.replace("\n"," ").trim().to_owned()))
|
||||||
|
};
|
||||||
|
|
||||||
|
choice((
|
||||||
|
el, h, p, br, ul, ol, row, link, navlink, btn, navbtn, img, table, tcol, tpcol, hr, b,
|
||||||
|
i, bq, footlnk, footn, a, s, sup, sub, disc,
|
||||||
|
))
|
||||||
|
.or(choice((block, carousel, code, pre, meta)))
|
||||||
|
.or(choice((el_text, el_tags, paragraph)))
|
||||||
|
})
|
||||||
|
.repeated()
|
||||||
|
.collect()
|
||||||
|
.map_with(|t, e| (Page { data: t }, e.span()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,16 +109,6 @@ impl TryFrom<DlBody> for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DlArgument> for Arg {
|
|
||||||
fn from(value: DlArgument) -> Self {
|
|
||||||
match value {
|
|
||||||
DlArgument::Text(s) => s.into(),
|
|
||||||
DlArgument::Number(n) => n.into(),
|
|
||||||
DlArgument::Null => Self::Null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<DlArgument> for NNArg {
|
impl TryFrom<DlArgument> for NNArg {
|
||||||
type Error = ConversionError;
|
type Error = ConversionError;
|
||||||
|
|
||||||
|
|
|
@ -83,16 +83,6 @@ impl From<Body> for DlBody {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Arg> for DlArgument {
|
|
||||||
fn from(item: Arg) -> DlArgument {
|
|
||||||
match item {
|
|
||||||
Arg::Null => NA,
|
|
||||||
Arg::Number(v) => v.into(),
|
|
||||||
Arg::Text(v) => v.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<NNArg> for DlArgument {
|
impl From<NNArg> for DlArgument {
|
||||||
fn from(item: NNArg) -> DlArgument {
|
fn from(item: NNArg) -> DlArgument {
|
||||||
match item {
|
match item {
|
||||||
|
|
|
@ -65,13 +65,6 @@ pub enum NNBody {
|
||||||
/// Text body
|
/// Text body
|
||||||
pub type TBody = String;
|
pub type TBody = String;
|
||||||
|
|
||||||
#[derive(AutoFrom, Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub enum Arg {
|
|
||||||
Text(String),
|
|
||||||
Number(u8),
|
|
||||||
Null,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(AutoFrom, Debug, Clone, PartialEq, Eq)]
|
#[derive(AutoFrom, Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum TNullArg {
|
pub enum TNullArg {
|
||||||
Text(String),
|
Text(String),
|
||||||
|
|
Loading…
Add table
Reference in a new issue