More bindings
This commit is contained in:
parent
fcc401f203
commit
cd54479618
1 changed files with 113 additions and 1 deletions
|
@ -4,6 +4,7 @@ use crate::document::document::Document;
|
||||||
use crate::document::document::DocumentAccessors;
|
use crate::document::document::DocumentAccessors;
|
||||||
use crate::document::element::ElemKind;
|
use crate::document::element::ElemKind;
|
||||||
use crate::document::element::Element;
|
use crate::document::element::Element;
|
||||||
|
use crate::lua::kernel::CTX;
|
||||||
use crate::parser::parser::ParserState;
|
use crate::parser::parser::ParserState;
|
||||||
use crate::parser::rule::RegexRule;
|
use crate::parser::rule::RegexRule;
|
||||||
use crate::parser::source::Source;
|
use crate::parser::source::Source;
|
||||||
|
@ -14,11 +15,13 @@ use ariadne::Fmt;
|
||||||
use ariadne::Label;
|
use ariadne::Label;
|
||||||
use ariadne::Report;
|
use ariadne::Report;
|
||||||
use ariadne::ReportKind;
|
use ariadne::ReportKind;
|
||||||
|
use mlua::Function;
|
||||||
use regex::Captures;
|
use regex::Captures;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use super::paragraph::Paragraph;
|
use super::paragraph::Paragraph;
|
||||||
|
|
||||||
|
@ -42,7 +45,7 @@ impl Style {
|
||||||
impl Element for Style {
|
impl Element for Style {
|
||||||
fn location(&self) -> &Token { &self.location }
|
fn location(&self) -> &Token { &self.location }
|
||||||
fn kind(&self) -> ElemKind { ElemKind::Inline }
|
fn kind(&self) -> ElemKind { ElemKind::Inline }
|
||||||
fn element_name(&self) -> &'static str { "Section" }
|
fn element_name(&self) -> &'static str { "Style" }
|
||||||
fn compile(&self, compiler: &Compiler, _document: &dyn Document) -> Result<String, String> {
|
fn compile(&self, compiler: &Compiler, _document: &dyn Document) -> Result<String, String> {
|
||||||
match compiler.target() {
|
match compiler.target() {
|
||||||
Target::HTML => {
|
Target::HTML => {
|
||||||
|
@ -205,6 +208,74 @@ impl RegexRule for StyleRule {
|
||||||
|
|
||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn register_bindings<'lua>(&self, lua: &'lua mlua::Lua) -> Vec<(String, Function<'lua>)> {
|
||||||
|
let mut bindings = vec![];
|
||||||
|
|
||||||
|
bindings.push((
|
||||||
|
"toggle".to_string(),
|
||||||
|
lua.create_function(|_, style: String| {
|
||||||
|
let kind = match style.as_str() {
|
||||||
|
"bold" | "Bold" => 0,
|
||||||
|
"italic" | "Italic" => 1,
|
||||||
|
"underline" | "Underline" => 2,
|
||||||
|
"emphasis" | "Emphasis" => 3,
|
||||||
|
_ => {
|
||||||
|
return Err(mlua::Error::BadArgument {
|
||||||
|
to: Some("toggle".to_string()),
|
||||||
|
pos: 1,
|
||||||
|
name: Some("style".to_string()),
|
||||||
|
cause: Arc::new(mlua::Error::external(format!(
|
||||||
|
"Unknown style specified"
|
||||||
|
))),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CTX.with_borrow(|ctx| {
|
||||||
|
ctx.as_ref().map(|ctx| {
|
||||||
|
let query = ctx.state.shared.rule_state.borrow().get(STATE_NAME);
|
||||||
|
let style_state = match query {
|
||||||
|
Some(state) => state,
|
||||||
|
None => {
|
||||||
|
// Insert as a new state
|
||||||
|
match ctx.state.shared.rule_state.borrow_mut().insert(
|
||||||
|
STATE_NAME.into(),
|
||||||
|
Rc::new(RefCell::new(StyleState::new())),
|
||||||
|
) {
|
||||||
|
Err(_) => panic!("Unknown error"),
|
||||||
|
Ok(state) => state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(style_state) =
|
||||||
|
style_state.borrow_mut().downcast_mut::<StyleState>()
|
||||||
|
{
|
||||||
|
style_state.toggled[kind] = style_state.toggled[kind]
|
||||||
|
.clone()
|
||||||
|
.map_or(Some(ctx.location.clone()), |_| None);
|
||||||
|
ctx.state.push(
|
||||||
|
ctx.document,
|
||||||
|
Box::new(Style::new(
|
||||||
|
ctx.location.clone(),
|
||||||
|
kind,
|
||||||
|
!style_state.toggled[kind].is_some(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
panic!("Invalid state at `{STATE_NAME}`");
|
||||||
|
};
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
));
|
||||||
|
|
||||||
|
bindings
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -257,4 +328,45 @@ __`UNDERLINE+EM`__
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lua() {
|
||||||
|
let source = Rc::new(SourceFile::with_content(
|
||||||
|
"".to_string(),
|
||||||
|
r#"
|
||||||
|
Some %<nml.style.toggle("italic")>%style
|
||||||
|
terminated here%<nml.style.toggle("Italic")>%
|
||||||
|
|
||||||
|
%<nml.style.toggle("Bold")>%NOLD + %<nml.style.toggle("italic")>%italic%<nml.style.toggle("bold") nml.style.toggle("italic")>%
|
||||||
|
%<nml.style.toggle("Underline") nml.style.toggle("Emphasis")>%UNDERLINE+EM%<nml.style.toggle("emphasis")>%%<nml.style.toggle("underline")>%
|
||||||
|
"#
|
||||||
|
.to_string(),
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
let parser = LangParser::default();
|
||||||
|
let (doc, _) = parser.parse(ParserState::new(&parser, None), source, None);
|
||||||
|
|
||||||
|
validate_document!(doc.content().borrow(), 0,
|
||||||
|
Paragraph {
|
||||||
|
Text;
|
||||||
|
Style { kind == 1, close == false };
|
||||||
|
Text;
|
||||||
|
Style { kind == 1, close == true };
|
||||||
|
};
|
||||||
|
Paragraph {
|
||||||
|
Style { kind == 0, close == false }; // **
|
||||||
|
Text;
|
||||||
|
Style { kind == 1, close == false }; // *
|
||||||
|
Text;
|
||||||
|
Style { kind == 0, close == true }; // **
|
||||||
|
Style { kind == 1, close == true }; // *
|
||||||
|
|
||||||
|
Style { kind == 2, close == false }; // __
|
||||||
|
Style { kind == 3, close == false }; // `
|
||||||
|
Text;
|
||||||
|
Style { kind == 3, close == true }; // `
|
||||||
|
Style { kind == 2, close == true }; // __
|
||||||
|
};
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue