Update parse_affiliated_keywords for handling optional pairs.

This commit is contained in:
Tom Alexander 2023-10-16 11:42:20 -04:00
parent f5a6a26c43
commit e352deb989
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 123 additions and 68 deletions

View File

@ -35,75 +35,92 @@ where
let mut ret = BTreeMap::new(); let mut ret = BTreeMap::new();
for kw in input { for kw in input {
let translated_name = translate_name(global_settings, kw.key); let translated_name = translate_name(global_settings, kw.key);
// if is_single_string_keyword(global_settings, translated_name.as_str()) { let keyword_type = identify_keyword_type(global_settings, translated_name.as_str());
// ret.insert( match keyword_type {
// translated_name, AffiliatedKeywordType::SingleString => {
// AffiliatedKeywordValue::SingleString(kw.value), ret.insert(
// ); translated_name,
// } else if is_list_of_single_string_keyword(global_settings, translated_name.as_str()) { AffiliatedKeywordValue::SingleString(kw.value),
// let list_of_strings = ret );
// .entry(translated_name) }
// .or_insert_with(|| AffiliatedKeywordValue::ListOfStrings(Vec::with_capacity(1))); AffiliatedKeywordType::ListOfStrings => {
// match list_of_strings { let list_of_strings = ret.entry(translated_name).or_insert_with(|| {
// AffiliatedKeywordValue::ListOfStrings(list_of_strings) AffiliatedKeywordValue::ListOfStrings(Vec::with_capacity(1))
// if list_of_strings.is_empty() => });
// { match list_of_strings {
// list_of_strings.push(kw.value); AffiliatedKeywordValue::ListOfStrings(list_of_strings)
// } if list_of_strings.is_empty() =>
// AffiliatedKeywordValue::ListOfStrings(list_of_strings) => { {
// list_of_strings.clear(); list_of_strings.push(kw.value);
// list_of_strings.push(kw.value); }
// } AffiliatedKeywordValue::ListOfStrings(list_of_strings) => {
// _ => panic!("Invalid AffiliatedKeywordValue type."), list_of_strings.clear();
// } list_of_strings.push(kw.value);
// } else if is_list_of_objects_keyword(global_settings, translated_name.as_str()) { }
// let initial_context = ContextElement::document_context(); _ => panic!("Invalid AffiliatedKeywordValue type."),
// let initial_context = Context::new(global_settings, List::new(&initial_context)); }
}
AffiliatedKeywordType::OptionalPair => {
let (_remaining, optional_string) = opt(all_consuming(map(
tuple((
take_until::<_, &str, nom::error::Error<_>>("["),
tag("["),
recognize(many_till(anychar, peek(tuple((tag("]"), eof))))),
tag("]"),
eof,
)),
|(_, _, objects, _, _)| objects,
)))(kw.key.into())
.expect("Parser should always succeed.");
ret.insert(
translated_name,
AffiliatedKeywordValue::OptionalPair {
optval: optional_string,
val: kw.value,
},
);
}
AffiliatedKeywordType::ObjectTree => {
let initial_context = ContextElement::document_context();
let initial_context = Context::new(global_settings, List::new(&initial_context));
// let (_remaining, optional_objects) = opt(all_consuming(map( let (_remaining, optional_objects) = opt(all_consuming(map(
// tuple(( tuple((
// take_until("["), take_until("["),
// tag("["), tag("["),
// map_parser( map_parser(
// recognize(many_till(anychar, peek(tuple((tag("]"), eof))))), recognize(many_till(anychar, peek(tuple((tag("]"), eof))))),
// confine_context(|i| { confine_context(|i| {
// all_consuming(many0(parser_with_context!(standard_set_object)( all_consuming(many0(parser_with_context!(standard_set_object)(
// &initial_context, &initial_context,
// )))(i) )))(i)
// }), }),
// ), ),
// tag("]"), tag("]"),
// eof, eof,
// )), )),
// |(_, _, objects, _, _)| objects, |(_, _, objects, _, _)| objects,
// )))(kw.key.into()) )))(kw.key.into())
// .expect("Object parser should always succeed."); .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) =
// standard_set_object all_consuming(many0(parser_with_context!(standard_set_object)(
// )(&initial_context)))(kw.value.into()) &initial_context,
// .expect("Object parser should always succeed."); )))(kw.value.into())
// let list_of_lists = ret.entry(translated_name).or_insert_with(|| { .expect("Object parser should always succeed.");
// AffiliatedKeywordValue::ListOfListsOfObjects(Vec::with_capacity(1))
// }); let entry_per_keyword_list = ret
// match list_of_lists { .entry(translated_name)
// AffiliatedKeywordValue::ListOfListsOfObjects(list_of_lists) => { .or_insert_with(|| AffiliatedKeywordValue::ObjectTree(Vec::with_capacity(1)));
// list_of_lists.push((optional_objects, objects)); match entry_per_keyword_list {
// } AffiliatedKeywordValue::ObjectTree(entry_per_keyword_list) => {
// _ => panic!("Invalid AffiliatedKeywordValue type."), entry_per_keyword_list.push((optional_objects, objects));
// } }
// } else { _ => panic!("Invalid AffiliatedKeywordValue type."),
// let list_of_strings = ret }
// .entry(translated_name) }
// .or_insert_with(|| AffiliatedKeywordValue::ListOfStrings(Vec::with_capacity(1))); };
// match list_of_strings {
// AffiliatedKeywordValue::ListOfStrings(list_of_strings) => {
// list_of_strings.push(kw.value);
// }
// _ => panic!("Invalid AffiliatedKeywordValue type."),
// }
// }
} }
AffiliatedKeywords { keywords: ret } AffiliatedKeywords { keywords: ret }
} }
@ -121,6 +138,40 @@ fn translate_name<'g, 's>(global_settings: &'g GlobalSettings<'g, 's>, name: &'s
name_until_optval.to_lowercase() name_until_optval.to_lowercase()
} }
enum AffiliatedKeywordType {
SingleString,
ListOfStrings,
OptionalPair,
ObjectTree,
}
fn identify_keyword_type<'g, 's>(
global_settings: &'g GlobalSettings<'g, 's>,
name: &'s str,
) -> AffiliatedKeywordType {
let is_multiple = ["CAPTION", "HEADER"]
.into_iter()
.any(|candidate| name.eq_ignore_ascii_case(candidate));
let is_parsed = global_settings
.element_parsed_keywords
.iter()
.any(|candidate| name.eq_ignore_ascii_case(candidate));
let can_have_optval = global_settings
.element_dual_keywords
.iter()
.any(|candidate| name.eq_ignore_ascii_case(candidate));
match (is_multiple, is_parsed, can_have_optval) {
(true, true, true) => AffiliatedKeywordType::ObjectTree,
(true, true, false) => unreachable!("Nothing like this exists in upstream org-mode."),
(true, false, true) => unreachable!("Nothing like this exists in upstream org-mode."),
(true, false, false) => AffiliatedKeywordType::ListOfStrings,
(false, true, true) => unreachable!("Nothing like this exists in upstream org-mode."),
(false, true, false) => unreachable!("Nothing like this exists in upstream org-mode."),
(false, false, true) => AffiliatedKeywordType::OptionalPair,
(false, false, false) => AffiliatedKeywordType::SingleString,
}
}
fn is_single_string_keyword<'g, 's>( fn is_single_string_keyword<'g, 's>(
_global_settings: &'g GlobalSettings<'g, 's>, _global_settings: &'g GlobalSettings<'g, 's>,
name: &'s str, name: &'s str,

View File

@ -6,7 +6,11 @@ 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>>)>), OptionalPair {
optval: Option<&'s str>,
val: &'s str,
},
ObjectTree(Vec<(Option<Vec<Object<'s>>>, Vec<Object<'s>>)>),
} }
#[derive(Debug)] #[derive(Debug)]