MCPcopy Create free account
hub / github.com/daisy/MathCAT / context_get_variable

Function context_get_variable

src/navigate.rs:265–311  ·  view source on GitHub ↗

FIX: think of a better place to put this, and maybe a better interface

(context: &Context<'c>, var_name: &str, mathml: Element<'c>)

Source from the content-addressed store, hash-verified

263
264// FIX: think of a better place to put this, and maybe a better interface
265pub fn context_get_variable<'c>(context: &Context<'c>, var_name: &str, mathml: Element<'c>) -> Result<(Option<String>, Option<f64>)> {
266 // First return tuple value is string-value (if string, bool, or single node) or None
267 // Second return tuple value is f64 if variable is a number or None
268 // This is ridiculously complicated for what in the end is a hashmap lookup
269 // There isn't an API that lets us get at the value, so we have to setup/build/evaluate an xpath
270 // Note: mathml can be any node. It isn't really used but some Element needs to be part of Evaluate()
271 let factory = Factory::new();
272 match factory.build(&("$".to_string() + var_name)) {
273 Err(_) => bail!("Could not compile XPath for variable: {}", var_name),
274 Ok(xpath) => match xpath.unwrap().evaluate(context, mathml) {
275 Ok(val) => return Ok( match val {
276 Value::String(s) => (Some(s), None),
277 Value::Number(f) => (None, Some(f)),
278 Value::Boolean(b) => (Some(format!("{}", b)), None),
279 Value::Nodeset(nodes) => {
280 if nodes.size() == 1 {
281 if let Some(attr) = nodes.document_order_first().unwrap().attribute() {
282 return Ok( (Some(attr.value().to_string()), None) );
283 }
284 };
285 let mut error_message = format!("Variable '{}' set somewhere in navigate.yaml is nodeset and not an attribute: ", var_name);
286 if nodes.size() == 0 {
287 error_message += &format!("0 nodes (false) -- {} set to non-existent (following?/preceding?) node", var_name);
288 } else {
289 let singular = nodes.size()==1;
290 error_message += &format!("{} node{}. {}:",
291 nodes.size(),
292 if singular {""} else {"s"},
293 if singular {"Node is"} else {"Nodes are"});
294 nodes.document_order()
295 .iter()
296 .enumerate()
297 .for_each(|(i, node)| {
298 match node {
299 sxd_xpath::nodeset::Node::Element(mathml) =>
300 error_message += &format!("#{}:\n{}",i, mml_to_string(mathml)),
301 _ => error_message += &format!("'{:?}'", node),
302 }
303 })
304 };
305 bail!(error_message);
306 },
307 } ),
308 Err(_) => bail!("Could not find value for navigation variable '{}'", var_name),
309 }
310 }
311}
312
313/// Given a key code along with the modifier keys, the current node is moved accordingly (or value reported in some cases).]
314/// The spoken text for the new current node is returned.

Callers 2

replace_stringMethod · 0.85
apply_navigation_rulesFunction · 0.85

Calls 2

buildMethod · 0.45
evaluateMethod · 0.45

Tested by

no test coverage detected