Compare label format, retain labels, and use labels.

This commit is contained in:
Tom Alexander 2023-10-04 12:36:38 -04:00
parent 1503054994
commit b56d847cfa
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
4 changed files with 135 additions and 39 deletions

View File

@ -1,3 +1,3 @@
#+BEGIN_SRC elisp -n -r -l "((%s))" #+BEGIN_SRC elisp -n -r -l "((%s))"
foo foo
#+END_SRC #+END_SRC

View File

@ -1547,8 +1547,6 @@ fn compare_example_block<'b, 's>(
let mut this_status = DiffStatus::Good; let mut this_status = DiffStatus::Good;
let mut message = None; let mut message = None;
// TODO: Compare :preserve-indent :retain-labels :use-labels :label-fmt
// Compare value // Compare value
let contents = get_property_quoted_string(emacs, ":value")?.unwrap_or(String::new()); let contents = get_property_quoted_string(emacs, ":value")?.unwrap_or(String::new());
if contents != rust.contents { if contents != rust.contents {
@ -1609,6 +1607,49 @@ fn compare_example_block<'b, 's>(
} }
}; };
// Compare preserve-indent
let preserve_indent = get_property_boolean(emacs, ":preserve-indent")?;
if preserve_indent {
// I don't know what :preserve-indent is for, but it seems to always be nil. This is here to alert me to value being non-nil so I can investigate.
this_status = DiffStatus::Bad;
message = Some(format!("Non-nil :preserve-indent {:?}", preserve_indent));
}
// Compare retain-labels
let retain_labels = get_property_boolean(emacs, ":retain-labels")?;
if retain_labels != rust.retain_labels {
this_status = DiffStatus::Bad;
message = Some(format!(
"Retain labels mismatch (emacs != rust) {:?} != {:?}",
retain_labels, rust.retain_labels
));
}
// Compare use-labels
let use_labels = get_property_boolean(emacs, ":use-labels")?;
if use_labels != rust.use_labels {
this_status = DiffStatus::Bad;
message = Some(format!(
"Use labels mismatch (emacs != rust) {:?} != {:?}",
use_labels, rust.use_labels
));
}
// Compare label-fmt
let label_format = get_property_quoted_string(emacs, ":label-fmt")?;
match (label_format.as_ref(), rust.label_format) {
(None, None) => {}
(Some(emacs_label_format), Some(rust_label_format))
if emacs_label_format == rust_label_format => {}
_ => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Label format mismatch (emacs != rust) {:?} != {:?}",
label_format, rust.label_format
));
}
}
Ok(DiffResult { Ok(DiffResult {
status: this_status, status: this_status,
name: rust.get_elisp_name(), name: rust.get_elisp_name(),

View File

@ -1,5 +1,6 @@
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::is_not; use nom::bytes::complete::is_not;
use nom::bytes::complete::tag;
use nom::bytes::complete::tag_no_case; use nom::bytes::complete::tag_no_case;
use nom::character::complete::line_ending; use nom::character::complete::line_ending;
use nom::character::complete::space0; use nom::character::complete::space0;
@ -154,11 +155,17 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?; let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
let source = get_consumed(input, remaining); let source = get_consumed(input, remaining);
let (switches, number_lines) = { let (switches, number_lines, retain_labels, use_labels, label_format) = {
if let Some(parameters) = parameters { if let Some(parameters) = parameters {
(Some(parameters.source), parameters.number_lines) (
Some(parameters.source),
parameters.number_lines,
parameters.retain_labels,
parameters.use_labels,
parameters.label_format,
)
} else { } else {
(None, None) (None, None, true, true, None)
} }
}; };
Ok(( Ok((
@ -168,6 +175,9 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
name: source.into(), name: source.into(),
switches, switches,
number_lines, number_lines,
retain_labels,
use_labels,
label_format,
contents: contents.into(), contents: contents.into(),
}, },
)) ))
@ -317,58 +327,86 @@ fn _lesser_block_begin<'b, 'g, 'r, 's, 'c>(
struct ExampleSwitches<'s> { struct ExampleSwitches<'s> {
source: &'s str, source: &'s str,
number_lines: Option<SwitchNumberLines>, number_lines: Option<SwitchNumberLines>,
retain_labels: bool,
use_labels: bool,
label_format: Option<&'s str>,
} }
enum SwitchState { enum SwitchState {
Normal, Normal,
NewLineNumber, NewLineNumber,
ContinuedLineNumber, ContinuedLineNumber,
LabelFormat,
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn example_switches<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ExampleSwitches<'s>> { fn example_switches<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ExampleSwitches<'s>> {
let mut number_lines = None; let mut number_lines = None;
let mut retain_labels = true;
let mut use_labels = true;
let mut label_format = None;
let (remaining, (source, (words, _))) = consumed(tuple(( let (remaining, (source, (words, _))) = consumed(tuple((
separated_list1( separated_list1(space1, map(switch_word, |val| Into::<&str>::into(val))),
space1,
map(is_not(" \t\r\n"), |val| Into::<&str>::into(val)),
),
space0, space0,
)))(input)?; )))(input)?;
let mut state = SwitchState::Normal; let mut state = SwitchState::Normal;
for word in words { for word in words {
state = match (state, word) { loop {
(SwitchState::Normal, "-n") => SwitchState::NewLineNumber, match (&state, word) {
(SwitchState::Normal, "+n") => SwitchState::ContinuedLineNumber, (SwitchState::Normal, "-n") => {
state = SwitchState::NewLineNumber;
}
(SwitchState::Normal, "+n") => {
state = SwitchState::ContinuedLineNumber;
}
(SwitchState::Normal, "-r") => {
retain_labels = false;
use_labels = false;
}
(SwitchState::Normal, "-l") => {
state = SwitchState::LabelFormat;
}
(SwitchState::NewLineNumber, _) => { (SwitchState::NewLineNumber, _) => {
let val = match word.parse::<LineNumber>() { let val = word.parse::<LineNumber>();
Ok(val) => val, if let Ok(val) = val {
Err(_) => 1,
};
if val < 0 { if val < 0 {
number_lines = Some(SwitchNumberLines::New(0)); number_lines = Some(SwitchNumberLines::New(0));
} else { } else {
// Note that this can result in a negative 1 if the val is originally 0. // Note that this can result in a negative 1 if the val is originally 0.
number_lines = Some(SwitchNumberLines::New(val - 1)); number_lines = Some(SwitchNumberLines::New(val - 1));
} }
SwitchState::Normal state = SwitchState::Normal;
} else {
number_lines = Some(SwitchNumberLines::New(0));
state = SwitchState::Normal;
continue; // Re-processes the word
}
} }
(SwitchState::ContinuedLineNumber, _) => { (SwitchState::ContinuedLineNumber, _) => {
let val = match word.parse::<LineNumber>() { let val = word.parse::<LineNumber>();
Ok(val) => val, if let Ok(val) = val {
Err(_) => 1,
};
if val < 0 { if val < 0 {
number_lines = Some(SwitchNumberLines::Continued(0)); number_lines = Some(SwitchNumberLines::Continued(0));
} else { } else {
// Note that this can result in a negative 1 if the val is originally 0. // Note that this can result in a negative 1 if the val is originally 0.
number_lines = Some(SwitchNumberLines::Continued(val - 1)); number_lines = Some(SwitchNumberLines::Continued(val - 1));
} }
SwitchState::Normal state = SwitchState::Normal;
} else {
number_lines = Some(SwitchNumberLines::Continued(0));
state = SwitchState::Normal;
continue; // Re-processes the word
} }
(state @ SwitchState::Normal, _) => state, }
(SwitchState::LabelFormat, _) => {
label_format = Some(word);
state = SwitchState::Normal;
}
(SwitchState::Normal, _) => {}
}; };
break;
}
} }
Ok(( Ok((
@ -376,6 +414,20 @@ fn example_switches<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ExampleSwitc
ExampleSwitches { ExampleSwitches {
source: Into::<&str>::into(source), source: Into::<&str>::into(source),
number_lines, number_lines,
retain_labels,
use_labels,
label_format,
}, },
)) ))
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn switch_word<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
alt((
map(
tuple((tag(r#"""#), is_not("\"\r\n"), tag(r#"""#))),
|(_, contents, _)| contents,
),
is_not(" \t\r\n"),
))(input)
}

View File

@ -42,6 +42,9 @@ pub struct ExampleBlock<'s> {
pub name: &'s str, pub name: &'s str,
pub switches: Option<&'s str>, pub switches: Option<&'s str>,
pub number_lines: Option<SwitchNumberLines>, pub number_lines: Option<SwitchNumberLines>,
pub retain_labels: bool,
pub use_labels: bool,
pub label_format: Option<&'s str>,
pub contents: &'s str, pub contents: &'s str,
} }