Implement checkbox
This commit is contained in:
parent
b60151556e
commit
dfdc631600
5 changed files with 75 additions and 5 deletions
|
|
@ -52,7 +52,7 @@
|
|||
- [x] Inline code
|
||||
- [x] Lists
|
||||
- [ ] Nested lists
|
||||
- [ ] Checkboxes
|
||||
- [x] Checkboxes
|
||||
- [ ] Move this roadmap to en
|
||||
- [ ] Full-text search
|
||||
- [ ] Begin centralizing state
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ use crate::{
|
|||
lexeme::Lexeme,
|
||||
state::State,
|
||||
token::{
|
||||
Token, header::Header, preformat::PreFormat,
|
||||
paragraph::Paragraph, literal::Literal, list::List, item::Item,
|
||||
Token, checkbox::CheckBox, header::Header, item::Item, list::List, literal::Literal, paragraph::Paragraph, preformat::PreFormat
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -98,7 +97,13 @@ pub fn parse(
|
|||
}
|
||||
},
|
||||
Block::Item(ordered) => {
|
||||
if Item::probe_end(lexeme) {
|
||||
if CheckBox::probe(lexeme) {
|
||||
log!("Probed CheckBox: {lexeme}");
|
||||
tokens.push(Token::CheckBox(CheckBox::lex(lexeme)));
|
||||
iterator.next();
|
||||
iterator.next();
|
||||
return true
|
||||
} else if Item::probe_end(lexeme) {
|
||||
tokens.push(Token::Item(Item::new(false)));
|
||||
log!("Block Context: Item -> List on {lexeme}");
|
||||
state.context.block = Block::List(ordered);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub mod delimiter {
|
|||
Delimiters {
|
||||
atomic: vec!['`', '|', '\\'],
|
||||
double: vec!['_', '~'],
|
||||
flanking: vec!['_', '*', '~', '(', ')', '\'', '"'],
|
||||
flanking: vec!['_', '*', '~', '(', ')', '[', ']', '\'', '"'],
|
||||
punctuation: vec![',', '.', ';', ':', '?', '!'],
|
||||
whitespace: vec!['\n', ' '],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use crate::syntax::content::Parseable as _;
|
|||
|
||||
pub mod anchor;
|
||||
pub mod bold;
|
||||
pub mod checkbox;
|
||||
pub mod code;
|
||||
pub mod header;
|
||||
pub mod item;
|
||||
|
|
@ -19,6 +20,7 @@ pub mod underline;
|
|||
pub enum Token {
|
||||
Anchor(anchor::Anchor),
|
||||
Bold(bold::Bold),
|
||||
CheckBox(checkbox::CheckBox),
|
||||
Code(code::Code),
|
||||
Strike(strike::Strike),
|
||||
Header(header::Header),
|
||||
|
|
@ -38,6 +40,7 @@ impl Token {
|
|||
match *self {
|
||||
Token::Anchor(ref d) => d.render(),
|
||||
Token::Bold(ref d) => d.render(),
|
||||
Token::CheckBox(ref d) => d.render(),
|
||||
Token::Code(ref d) => d.render(),
|
||||
Token::Strike(ref d) => d.render(),
|
||||
Token::Header(ref d) => d.render(),
|
||||
|
|
@ -59,6 +62,7 @@ impl std::fmt::Display for Token {
|
|||
let data = match *self {
|
||||
Token::Anchor(ref d) => format!("{d}"),
|
||||
Token::Bold(ref d) => format!("{d}"),
|
||||
Token::CheckBox(ref d) => format!("{d}"),
|
||||
Token::Code(ref d) => format!("{d}"),
|
||||
Token::Strike(ref d) => format!("{d}"),
|
||||
Token::Header(ref d) => format!("{d}"),
|
||||
|
|
|
|||
61
src/syntax/content/parser/token/checkbox.rs
Normal file
61
src/syntax/content/parser/token/checkbox.rs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
use crate::{
|
||||
syntax::content::{Parseable, Lexeme},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct CheckBox {
|
||||
checked: bool,
|
||||
}
|
||||
|
||||
impl CheckBox {
|
||||
pub fn new(checked: bool) -> CheckBox {
|
||||
CheckBox { checked }
|
||||
}
|
||||
}
|
||||
|
||||
impl Parseable for CheckBox {
|
||||
fn probe(lexeme: &Lexeme) -> bool {
|
||||
lexeme.match_triple_as_char(('[', ' ', ']'))
|
||||
|| lexeme.match_triple_as_char(('[', 'x', ']'))
|
||||
}
|
||||
|
||||
fn lex(lexeme: &Lexeme) -> CheckBox {
|
||||
use crate::prelude::*;
|
||||
log!("Lexing: {lexeme}");
|
||||
if lexeme.match_next_as_char('x') {
|
||||
CheckBox::new(true)
|
||||
} else {
|
||||
CheckBox::new(false)
|
||||
}
|
||||
}
|
||||
|
||||
fn render(&self) -> String {
|
||||
let toggle = if self.checked {
|
||||
" checked "
|
||||
} else {
|
||||
""
|
||||
};
|
||||
format!(r#"<input type="checkbox"{toggle}/>"#)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for CheckBox {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let display_state = if self.checked { "checked" } else { "empty" };
|
||||
write!(f, "CheckBox [{display_state}]")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn render() {
|
||||
let code_open = CheckBox::new(true);
|
||||
assert_eq!(code_open.render(), r#"<input type="checkbox" checked />"#);
|
||||
|
||||
let code_closed = CheckBox::new(false);
|
||||
assert_eq!(code_closed.render(), r#"<input type="checkbox"/>"#);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue