Parse plain list item checkboxes.

This commit is contained in:
Tom Alexander 2023-09-15 15:30:13 -04:00
parent fd41ad9c29
commit bfe67b1f75
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
4 changed files with 49 additions and 2 deletions

View File

@ -8,6 +8,7 @@ use super::util::assert_name;
use super::util::get_property;
use crate::types::AngleLink;
use crate::types::Bold;
use crate::types::CheckboxType;
use crate::types::Citation;
use crate::types::CitationReference;
use crate::types::Clock;
@ -799,7 +800,26 @@ fn compare_plain_list_item<'s>(
contents_status,
)?);
// TODO: compare :bullet :checkbox :counter :pre-blank
// TODO: compare :bullet :counter :pre-blank
// Compare checkbox
let checkbox = get_property(emacs, ":checkbox")?
.map(Token::as_atom)
.map_or(Ok(None), |r| r.map(Some))?
.unwrap_or("nil");
match (checkbox, &rust.checkbox) {
("nil", None) => {}
("off", Some((CheckboxType::Off, _))) => {}
("trans", Some((CheckboxType::Trans, _))) => {}
("on", Some((CheckboxType::On, _))) => {}
_ => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Checkbox mismatch (emacs != rust) {:?} != {:?}",
checkbox, rust.checkbox
));
}
};
Ok(DiffResult {
status: this_status,

View File

@ -7,6 +7,7 @@ use nom::character::complete::one_of;
use nom::character::complete::space0;
use nom::character::complete::space1;
use nom::combinator::eof;
use nom::combinator::map;
use nom::combinator::not;
use nom::combinator::opt;
use nom::combinator::peek;
@ -35,7 +36,9 @@ use crate::parser::util::blank_line;
use crate::parser::util::exit_matcher_parser;
use crate::parser::util::get_consumed;
use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting;
use crate::parser::util::org_space;
use crate::parser::util::start_of_line;
use crate::types::CheckboxType;
use crate::types::Object;
use crate::types::PlainList;
use crate::types::PlainListItem;
@ -160,7 +163,7 @@ fn plain_list_item<'b, 'g, 'r, 's>(
tag("]"),
)))(remaining)?;
// TODO: parse checkbox
let (remaining, maybe_checkbox) = opt(tuple((space1, item_checkbox)))(remaining)?;
let (remaining, maybe_tag) =
opt(tuple((space1, parser_with_context!(item_tag)(context))))(remaining)?;
@ -178,6 +181,7 @@ fn plain_list_item<'b, 'g, 'r, 's>(
source: source.into(),
indentation: indent_level,
bullet: bull.into(),
checkbox: None,
tag: maybe_tag
.map(|(_ws, item_tag)| item_tag)
.unwrap_or(Vec::new()),
@ -227,6 +231,8 @@ fn plain_list_item<'b, 'g, 'r, 's>(
source: source.into(),
indentation: indent_level,
bullet: bull.into(),
checkbox: maybe_checkbox
.map(|(_, (checkbox_type, source))| (checkbox_type, Into::<&str>::into(source))),
tag: maybe_tag
.map(|(_ws, item_tag)| item_tag)
.unwrap_or(Vec::new()),
@ -389,6 +395,18 @@ fn item_tag_post_gap<'b, 'g, 'r, 's>(
)(input)
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn item_checkbox<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, (CheckboxType, OrgSource<'s>)> {
alt((
map(
recognize(tuple((tag("["), org_space, tag("]")))),
|capture| (CheckboxType::Off, capture),
),
map(tag("[-]"), |capture| (CheckboxType::Trans, capture)),
map(tag("[X]"), |capture| (CheckboxType::On, capture)),
))(input)
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn detect_contentless_item_contents<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>,

View File

@ -15,10 +15,18 @@ pub struct PlainListItem<'s> {
pub source: &'s str,
pub indentation: usize,
pub bullet: &'s str,
pub checkbox: Option<(CheckboxType, &'s str)>,
pub tag: Vec<Object<'s>>,
pub children: Vec<Element<'s>>,
}
#[derive(Debug)]
pub enum CheckboxType {
On,
Trans,
Off,
}
#[derive(Debug)]
pub struct GreaterBlock<'s> {
pub source: &'s str,

View File

@ -11,6 +11,7 @@ pub use document::PriorityCookie;
pub use document::Section;
pub use document::TodoKeywordType;
pub use element::Element;
pub use greater_element::CheckboxType;
pub use greater_element::Drawer;
pub use greater_element::DynamicBlock;
pub use greater_element::FootnoteDefinition;