Compare commits
6 Commits
3d86e75059
...
444d6758aa
Author | SHA1 | Date | |
---|---|---|---|
![]() |
444d6758aa | ||
![]() |
6c7203410e | ||
![]() |
bfe67b1f75 | ||
![]() |
fd41ad9c29 | ||
![]() |
7f751d4f28 | ||
![]() |
52a4dab67c |
@ -0,0 +1,5 @@
|
||||
#+begin_quote
|
||||
|
||||
foo
|
||||
|
||||
#+end_quote
|
@ -14,7 +14,9 @@ use crate::LocalFileAccessInterface;
|
||||
pub fn run_anonymous_compare<P: AsRef<str>>(
|
||||
org_contents: P,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let org_contents = org_contents.as_ref();
|
||||
// TODO: This is a work-around to pretend that dos line endings do not exist. It would be better to handle the difference in line endings.
|
||||
let org_contents = org_contents.as_ref().replace("\r\n", "\n");
|
||||
let org_contents = org_contents.as_str();
|
||||
eprintln!("Using emacs version: {}", get_emacs_version()?.trim());
|
||||
eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim());
|
||||
let rust_parsed = parse(org_contents)?;
|
||||
@ -44,6 +46,8 @@ pub fn run_compare_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn st
|
||||
.parent()
|
||||
.ok_or("Should be contained inside a directory.")?;
|
||||
let org_contents = std::fs::read_to_string(org_path)?;
|
||||
// TODO: This is a work-around to pretend that dos line endings do not exist. It would be better to handle the difference in line endings.
|
||||
let org_contents = org_contents.replace("\r\n", "\n");
|
||||
let org_contents = org_contents.as_str();
|
||||
let file_access_interface = LocalFileAccessInterface {
|
||||
working_directory: Some(parent_directory.to_path_buf()),
|
||||
|
@ -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,
|
||||
|
@ -4,11 +4,14 @@ use nom::bytes::complete::tag_no_case;
|
||||
use nom::character::complete::line_ending;
|
||||
use nom::character::complete::space0;
|
||||
use nom::character::complete::space1;
|
||||
use nom::combinator::consumed;
|
||||
use nom::combinator::eof;
|
||||
use nom::combinator::not;
|
||||
use nom::combinator::opt;
|
||||
use nom::combinator::verify;
|
||||
use nom::multi::many0;
|
||||
use nom::multi::many_till;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
@ -80,25 +83,23 @@ pub(crate) fn greater_block<'b, 'g, 'r, 's>(
|
||||
|
||||
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
// Check for a completely empty block
|
||||
let (remaining, children) = match tuple((
|
||||
not(exit_matcher),
|
||||
not(exit_matcher)(remaining)?;
|
||||
let (remaining, leading_blank_lines) = opt(consumed(tuple((
|
||||
blank_line,
|
||||
many_till(blank_line, exit_matcher),
|
||||
))(remaining)
|
||||
{
|
||||
Ok((remain, (_not_immediate_exit, first_line, (_trailing_whitespace, _exit_contents)))) => {
|
||||
many0(preceded(not(exit_matcher), blank_line)),
|
||||
))))(remaining)?;
|
||||
let leading_blank_lines =
|
||||
leading_blank_lines.map(|(source, (first_line, _remaining_lines))| {
|
||||
let mut element = Element::Paragraph(Paragraph::of_text(first_line.into()));
|
||||
let source = get_consumed(remaining, remain);
|
||||
element.set_source(source.into());
|
||||
(remain, vec![element])
|
||||
}
|
||||
Err(_) => {
|
||||
let (remaining, (children, _exit_contents)) =
|
||||
many_till(element_matcher, exit_matcher)(remaining)?;
|
||||
(remaining, children)
|
||||
}
|
||||
};
|
||||
element
|
||||
});
|
||||
let (remaining, (mut children, _exit_contents)) =
|
||||
many_till(element_matcher, exit_matcher)(remaining)?;
|
||||
if let Some(lines) = leading_blank_lines {
|
||||
children.insert(0, lines);
|
||||
}
|
||||
|
||||
let (remaining, _end) = exit_with_name(&parser_context, remaining)?;
|
||||
|
||||
// Not checking if parent exit matcher is causing exit because the greater_block_end matcher asserts we matched a full greater block
|
||||
|
@ -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>,
|
||||
|
@ -1,16 +1,16 @@
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::is_not;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::complete::tag_no_case;
|
||||
use nom::character::complete::line_ending;
|
||||
use nom::character::complete::space0;
|
||||
use nom::character::complete::space1;
|
||||
use nom::combinator::eof;
|
||||
use nom::multi::separated_list1;
|
||||
use nom::multi::many1;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::timestamp::timestamp;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::util::org_line_ending;
|
||||
use super::util::org_spaces0;
|
||||
use super::util::org_spaces1;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::util::get_consumed;
|
||||
@ -23,9 +23,10 @@ pub(crate) fn planning<'b, 'g, 'r, 's>(
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Planning<'s>> {
|
||||
start_of_line(input)?;
|
||||
let (remaining, _leading_whitespace) = space0(input)?;
|
||||
let (remaining, _planning_parameters) = separated_list1(space1, planning_parameter)(remaining)?;
|
||||
let (remaining, _trailing_ws) = tuple((space0, alt((line_ending, eof))))(remaining)?;
|
||||
let (remaining, _leading_whitespace) = org_spaces0(input)?;
|
||||
let (remaining, _planning_parameters) =
|
||||
many1(parser_with_context!(planning_parameter)(context))(remaining)?;
|
||||
let (remaining, _trailing_ws) = tuple((org_spaces0, org_line_ending))(remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
@ -40,15 +41,17 @@ pub(crate) fn planning<'b, 'g, 'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn planning_parameter<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
fn planning_parameter<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _planning_type) = alt((
|
||||
tag_no_case("DEADLINE"),
|
||||
tag_no_case("SCHEDULED"),
|
||||
tag_no_case("CLOSED"),
|
||||
))(input)?;
|
||||
let (remaining, _gap) = tuple((tag(":"), space1))(remaining)?;
|
||||
// TODO: Make this invoke the real timestamp parser.
|
||||
let (remaining, _timestamp) = tuple((tag("<"), is_not("\r\n>"), tag(">")))(remaining)?;
|
||||
let (remaining, _gap) = tuple((tag(":"), org_spaces1))(remaining)?;
|
||||
let (remaining, _timestamp) = timestamp(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((remaining, source))
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::anychar;
|
||||
use nom::character::complete::digit0;
|
||||
use nom::character::complete::digit1;
|
||||
use nom::character::complete::one_of;
|
||||
use nom::character::complete::space1;
|
||||
@ -414,7 +415,7 @@ fn repeater<'b, 'g, 'r, 's>(
|
||||
// ++ for catch-up type
|
||||
// .+ for restart type
|
||||
let (remaining, _mark) = alt((tag("++"), tag("+"), tag(".+")))(input)?;
|
||||
let (remaining, _value) = digit1(remaining)?;
|
||||
let (remaining, _value) = digit0(remaining)?;
|
||||
// h = hour, d = day, w = week, m = month, y = year
|
||||
let (remaining, _unit) = recognize(one_of("hdwmy"))(remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
@ -429,7 +430,7 @@ fn warning_delay<'b, 'g, 'r, 's>(
|
||||
// - for all type
|
||||
// -- for first type
|
||||
let (remaining, _mark) = alt((tag("--"), tag("-")))(input)?;
|
||||
let (remaining, _value) = digit1(remaining)?;
|
||||
let (remaining, _value) = digit0(remaining)?;
|
||||
// h = hour, d = day, w = week, m = month, y = year
|
||||
let (remaining, _unit) = recognize(one_of("hdwmy"))(remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user