Compare commits
No commits in common. "7da4e4a29b4c71fb6818888d453bcfd5f57061f3" and "dc9188dffc8e5d3ae712e4da629befd6f673ae93" have entirely different histories.
7da4e4a29b
...
dc9188dffc
@ -1,8 +0,0 @@
|
|||||||
#+CAPTION[foo]: *bar*
|
|
||||||
#+CAPTION[*lorem* ipsum]: dolar
|
|
||||||
1. baz
|
|
||||||
|
|
||||||
|
|
||||||
#+CAPTION[foo]: *bar*
|
|
||||||
#+CAPTION[*lorem* ipsum]: dolar
|
|
||||||
# Comments cannot have affiliated keywords so those become regular keywords.
|
|
@ -416,15 +416,14 @@ where
|
|||||||
///
|
///
|
||||||
/// Org-mode seems to store these as a 3-deep list:
|
/// Org-mode seems to store these as a 3-deep list:
|
||||||
/// - Outer list with 1 element per #+caption keyword (or other parsed keyword).
|
/// - Outer list with 1 element per #+caption keyword (or other parsed keyword).
|
||||||
/// - Middle list which has:
|
/// - Middle list that seems to always have 1 element.
|
||||||
/// - first element is a list of objects representing the value after the colon.
|
/// - Inner list of the objects from each #+caption keyword (or other parsed keyword).
|
||||||
/// - every additional element is a list of objects from inside the square brackets (the optional value).
|
|
||||||
pub(crate) fn compare_property_list_of_list_of_list_of_ast_nodes<
|
pub(crate) fn compare_property_list_of_list_of_list_of_ast_nodes<
|
||||||
'b,
|
'b,
|
||||||
's,
|
's,
|
||||||
'x,
|
'x,
|
||||||
R,
|
R,
|
||||||
RG: Fn(R) -> Option<&'b Vec<(Option<Vec<Object<'s>>>, Vec<Object<'s>>)>>,
|
RG: Fn(R) -> Option<&'b Vec<Vec<Object<'s>>>>,
|
||||||
>(
|
>(
|
||||||
source: &'s str,
|
source: &'s str,
|
||||||
emacs: &'b Token<'s>,
|
emacs: &'b Token<'s>,
|
||||||
@ -460,76 +459,32 @@ pub(crate) fn compare_property_list_of_list_of_list_of_ast_nodes<
|
|||||||
(Some(value), Some(rust_value)) => (value, rust_value),
|
(Some(value), Some(rust_value)) => (value, rust_value),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut full_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(rust_value.len());
|
|
||||||
|
|
||||||
// Iterate the outer lists
|
// Iterate the outer lists
|
||||||
for (value, (rust_optional, rust_value)) in value.iter().zip(rust_value.iter()) {
|
for (value, rust_value) in value.iter().zip(rust_value.iter()) {
|
||||||
let mut middle_value = value.as_list()?.iter();
|
// Assert the middle list is a length of 1 because I've never seen it any other way.
|
||||||
// First element of middle list is the mandatory value (the value past the colon).
|
let value = value.as_list()?;
|
||||||
let mandatory_value = middle_value.next();
|
if value.len() != 1 {
|
||||||
let mandatory_value = match mandatory_value {
|
|
||||||
Some(mandatory_value) => mandatory_value,
|
|
||||||
None => {
|
|
||||||
let this_status = DiffStatus::Bad;
|
|
||||||
let message = Some(format!(
|
|
||||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
emacs_field, value, rust_value
|
|
||||||
));
|
|
||||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compare optional value
|
|
||||||
if let Some(rust_optional) = rust_optional {
|
|
||||||
let mut child_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(rust_value.len());
|
|
||||||
if rust_optional.len() != middle_value.len() {
|
|
||||||
let this_status = DiffStatus::Bad;
|
|
||||||
let message = Some(format!(
|
|
||||||
"{} optional value length mismatch (emacs != rust) {} != {} | {:?}",
|
|
||||||
emacs_field,
|
|
||||||
middle_value.len(),
|
|
||||||
rust_optional.len(),
|
|
||||||
rust_optional
|
|
||||||
));
|
|
||||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
|
||||||
}
|
|
||||||
for (e, r) in middle_value.zip(rust_optional) {
|
|
||||||
child_status.push(compare_ast_node(source, e, r.into())?);
|
|
||||||
}
|
|
||||||
if !child_status.is_empty() {
|
|
||||||
let diff_scope = artificial_diff_scope("optional value", child_status)?;
|
|
||||||
full_status.push(diff_scope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare mandatory value
|
|
||||||
let mut child_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(rust_value.len());
|
|
||||||
let mandatory_value = mandatory_value.as_list()?;
|
|
||||||
if rust_value.len() != mandatory_value.len() {
|
|
||||||
let this_status = DiffStatus::Bad;
|
let this_status = DiffStatus::Bad;
|
||||||
let message = Some(format!(
|
let message = Some(format!(
|
||||||
"{} mandatory value length mismatch (emacs != rust) {} != {} | {:?}",
|
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||||
emacs_field,
|
emacs_field, value, rust_value
|
||||||
mandatory_value.len(),
|
|
||||||
rust_value.len(),
|
|
||||||
rust_value
|
|
||||||
));
|
));
|
||||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||||
}
|
}
|
||||||
for (e, r) in mandatory_value.iter().zip(rust_value) {
|
// Drill past the middle list to the inner list.
|
||||||
|
let value = value
|
||||||
|
.first()
|
||||||
|
.expect("The above if-statement asserts this exists.");
|
||||||
|
let value = value.as_list()?;
|
||||||
|
// Compare inner lists
|
||||||
|
let mut child_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(rust_value.len());
|
||||||
|
for (e, r) in value.iter().zip(rust_value) {
|
||||||
child_status.push(compare_ast_node(source, e, r.into())?);
|
child_status.push(compare_ast_node(source, e, r.into())?);
|
||||||
}
|
}
|
||||||
if !child_status.is_empty() {
|
let diff_scope = artificial_owned_diff_scope(emacs_field, child_status)?;
|
||||||
let diff_scope = artificial_diff_scope("mandatory value", child_status)?;
|
return Ok(ComparePropertiesResult::DiffEntry(diff_scope));
|
||||||
full_status.push(diff_scope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if full_status.is_empty() {
|
|
||||||
Ok(ComparePropertiesResult::NoChange)
|
|
||||||
} else {
|
|
||||||
let diff_scope = artificial_owned_diff_scope(emacs_field, full_status)?;
|
|
||||||
Ok(ComparePropertiesResult::DiffEntry(diff_scope))
|
|
||||||
}
|
}
|
||||||
|
Ok(ComparePropertiesResult::NoChange)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compare_property_number_lines<
|
pub(crate) fn compare_property_number_lines<
|
||||||
|
@ -1,21 +1,9 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use nom::bytes::complete::tag;
|
|
||||||
use nom::bytes::complete::take_until;
|
|
||||||
use nom::character::complete::anychar;
|
|
||||||
use nom::combinator::all_consuming;
|
use nom::combinator::all_consuming;
|
||||||
use nom::combinator::eof;
|
|
||||||
use nom::combinator::map;
|
|
||||||
use nom::combinator::map_parser;
|
|
||||||
use nom::combinator::opt;
|
|
||||||
use nom::combinator::peek;
|
|
||||||
use nom::combinator::recognize;
|
|
||||||
use nom::multi::many0;
|
use nom::multi::many0;
|
||||||
use nom::multi::many_till;
|
|
||||||
use nom::sequence::tuple;
|
|
||||||
|
|
||||||
use super::object_parser::standard_set_object;
|
use super::object_parser::standard_set_object;
|
||||||
use super::util::confine_context;
|
|
||||||
use crate::context::parser_with_context;
|
use crate::context::parser_with_context;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::context::ContextElement;
|
use crate::context::ContextElement;
|
||||||
@ -57,25 +45,6 @@ pub(crate) fn parse_affiliated_keywords<'g, 's>(
|
|||||||
let initial_context = ContextElement::document_context();
|
let initial_context = ContextElement::document_context();
|
||||||
let initial_context = Context::new(global_settings, List::new(&initial_context));
|
let initial_context = Context::new(global_settings, List::new(&initial_context));
|
||||||
|
|
||||||
let (_remaining, optional_objects) = opt(all_consuming(map(
|
|
||||||
tuple((
|
|
||||||
take_until("["),
|
|
||||||
tag("["),
|
|
||||||
map_parser(
|
|
||||||
recognize(many_till(anychar, peek(tuple((tag("]"), eof))))),
|
|
||||||
confine_context(|i| {
|
|
||||||
all_consuming(many0(parser_with_context!(standard_set_object)(
|
|
||||||
&initial_context,
|
|
||||||
)))(i)
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
tag("]"),
|
|
||||||
eof,
|
|
||||||
)),
|
|
||||||
|(_, _, objects, _, _)| objects,
|
|
||||||
)))(kw.key.into())
|
|
||||||
.expect("Object parser should always succeed.");
|
|
||||||
|
|
||||||
// TODO: This should be omitting footnote references
|
// TODO: This should be omitting footnote references
|
||||||
let (_remaining, objects) = all_consuming(many0(parser_with_context!(
|
let (_remaining, objects) = all_consuming(many0(parser_with_context!(
|
||||||
standard_set_object
|
standard_set_object
|
||||||
@ -86,7 +55,7 @@ pub(crate) fn parse_affiliated_keywords<'g, 's>(
|
|||||||
});
|
});
|
||||||
match list_of_lists {
|
match list_of_lists {
|
||||||
AffiliatedKeywordValue::ListOfListsOfObjects(list_of_lists) => {
|
AffiliatedKeywordValue::ListOfListsOfObjects(list_of_lists) => {
|
||||||
list_of_lists.push((optional_objects, objects));
|
list_of_lists.push(objects);
|
||||||
}
|
}
|
||||||
_ => panic!("Invalid AffiliatedKeywordValue type."),
|
_ => panic!("Invalid AffiliatedKeywordValue type."),
|
||||||
}
|
}
|
||||||
@ -106,16 +75,12 @@ pub(crate) fn parse_affiliated_keywords<'g, 's>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn translate_name<'g, 's>(global_settings: &'g GlobalSettings<'g, 's>, name: &'s str) -> String {
|
fn translate_name<'g, 's>(global_settings: &'g GlobalSettings<'g, 's>, name: &'s str) -> String {
|
||||||
let name_until_optval = name
|
|
||||||
.split_once("[")
|
|
||||||
.map(|(before, _after)| before)
|
|
||||||
.unwrap_or(name);
|
|
||||||
for (src, dst) in global_settings.element_keyword_translation_alist {
|
for (src, dst) in global_settings.element_keyword_translation_alist {
|
||||||
if name_until_optval.eq_ignore_ascii_case(src) {
|
if name.eq_ignore_ascii_case(src) {
|
||||||
return dst.to_lowercase();
|
return dst.to_lowercase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name_until_optval.to_lowercase()
|
name.to_lowercase()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_single_string_keyword<'g, 's>(
|
fn is_single_string_keyword<'g, 's>(
|
||||||
|
@ -6,7 +6,7 @@ use super::Object;
|
|||||||
pub enum AffiliatedKeywordValue<'s> {
|
pub enum AffiliatedKeywordValue<'s> {
|
||||||
SingleString(&'s str),
|
SingleString(&'s str),
|
||||||
ListOfStrings(Vec<&'s str>),
|
ListOfStrings(Vec<&'s str>),
|
||||||
ListOfListsOfObjects(Vec<(Option<Vec<Object<'s>>>, Vec<Object<'s>>)>),
|
ListOfListsOfObjects(Vec<Vec<Object<'s>>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user