123 lines
4.4 KiB
Rust
123 lines
4.4 KiB
Rust
use std::collections::BTreeMap;
|
|
|
|
use nom::combinator::all_consuming;
|
|
use nom::multi::many0;
|
|
|
|
use super::object_parser::standard_set_object;
|
|
use crate::context::parser_with_context;
|
|
use crate::context::Context;
|
|
use crate::context::ContextElement;
|
|
use crate::context::GlobalSettings;
|
|
use crate::context::List;
|
|
use crate::types::AffiliatedKeywordValue;
|
|
use crate::types::AffiliatedKeywords;
|
|
use crate::types::Keyword;
|
|
|
|
pub(crate) fn parse_affiliated_keywords<'g, 's>(
|
|
global_settings: &'g GlobalSettings<'g, 's>,
|
|
input: Vec<Keyword<'s>>,
|
|
) -> AffiliatedKeywords<'s> {
|
|
let mut ret = BTreeMap::new();
|
|
for kw in input.into_iter() {
|
|
let translated_name = translate_name(global_settings, kw.key);
|
|
if is_single_string_keyword(global_settings, translated_name.as_str()) {
|
|
ret.insert(
|
|
translated_name,
|
|
AffiliatedKeywordValue::SingleString(kw.value),
|
|
);
|
|
} else if is_list_of_single_string_keyword(global_settings, translated_name.as_str()) {
|
|
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)
|
|
if list_of_strings.is_empty() =>
|
|
{
|
|
list_of_strings.push(kw.value);
|
|
}
|
|
AffiliatedKeywordValue::ListOfStrings(list_of_strings) => {
|
|
list_of_strings.clear();
|
|
list_of_strings.push(kw.value);
|
|
}
|
|
_ => panic!("Invalid AffiliatedKeywordValue type."),
|
|
}
|
|
} else if is_list_of_objects_keyword(global_settings, translated_name.as_str()) {
|
|
let initial_context = ContextElement::document_context();
|
|
let initial_context = Context::new(global_settings, List::new(&initial_context));
|
|
|
|
// TODO: This should be omitting footnote references
|
|
let (_remaining, objects) = all_consuming(many0(parser_with_context!(
|
|
standard_set_object
|
|
)(&initial_context)))(kw.value.into())
|
|
.expect("Object parser should always succeed.");
|
|
let list_of_lists = ret.entry(translated_name).or_insert_with(|| {
|
|
AffiliatedKeywordValue::ListOfListsOfObjects(Vec::with_capacity(1))
|
|
});
|
|
match list_of_lists {
|
|
AffiliatedKeywordValue::ListOfListsOfObjects(list_of_lists) => {
|
|
list_of_lists.push(objects);
|
|
}
|
|
_ => panic!("Invalid AffiliatedKeywordValue type."),
|
|
}
|
|
} else {
|
|
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 }
|
|
}
|
|
|
|
fn translate_name<'g, 's>(global_settings: &'g GlobalSettings<'g, 's>, name: &'s str) -> String {
|
|
for (src, dst) in global_settings.element_keyword_translation_alist {
|
|
if name.eq_ignore_ascii_case(src) {
|
|
return dst.to_lowercase();
|
|
}
|
|
}
|
|
name.to_lowercase()
|
|
}
|
|
|
|
fn is_single_string_keyword<'g, 's>(
|
|
_global_settings: &'g GlobalSettings<'g, 's>,
|
|
name: &'s str,
|
|
) -> bool {
|
|
// TODO: Is this defined by an elisp variable?
|
|
for single_string_name in ["plot", "name"] {
|
|
if name.eq_ignore_ascii_case(single_string_name) {
|
|
return true;
|
|
}
|
|
}
|
|
false
|
|
}
|
|
|
|
fn is_list_of_single_string_keyword<'g, 's>(
|
|
_global_settings: &'g GlobalSettings<'g, 's>,
|
|
name: &'s str,
|
|
) -> bool {
|
|
// TODO: Is this defined by an elisp variable?
|
|
for single_string_name in ["results"] {
|
|
if name.eq_ignore_ascii_case(single_string_name) {
|
|
return true;
|
|
}
|
|
}
|
|
false
|
|
}
|
|
|
|
fn is_list_of_objects_keyword<'g, 's>(
|
|
global_settings: &'g GlobalSettings<'g, 's>,
|
|
name: &'s str,
|
|
) -> bool {
|
|
for parsed_keyword in global_settings.element_parsed_keywords {
|
|
if name.eq_ignore_ascii_case(parsed_keyword) {
|
|
return true;
|
|
}
|
|
}
|
|
false
|
|
}
|