Skip to content

Commit b722a71

Browse files
Merge branch 'NSoiffer:main' into main
2 parents 038e2da + 1e7f080 commit b722a71

File tree

5 files changed

+73
-47
lines changed

5 files changed

+73
-47
lines changed

PythonScripts/translate-unicode.py

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -404,39 +404,64 @@ def print_set(name, set, orig_dict):
404404
# Strangely, if you copy the '.../en/definitions.yaml' and paste that into translate.google.com, it does it all.
405405
# Rather than waste a bunch more time on this, the code assumes you've translated the file already and stored
406406
# it in 'google-defs.yaml' in the current dir
407-
# It then goes through the English version leaving the English and pulling out only the translated *values*
407+
# It then goes through the English version leaving the English and pulling out only the translated *values*
408408
# from 'google-defs.yaml' writing '[lang]-definitions.yaml'.
409409
def translate_definitions(path_to_mathcat: str, lang: str):
410410
if lang == 'nb' or lang == 'nn':
411411
lang = 'no' # google doesn't know those variants
412412

413-
file_to_translate = "{}/Rules/Languages/en/definitions.yaml".format(path_to_mathcat)
413+
file_to_translate = f'{path_to_mathcat}/Rules/Languages/en/definitions.yaml'
414+
translated_file = f'{path_to_mathcat}/Rules/Languages/{lang}/definitions.yaml'
414415
with open("google-defs.yaml", 'r', encoding='utf8') as google_stream:
415416
translated_lines = google_stream.readlines()
416417
with open(file_to_translate, 'r', encoding='utf8') as in_stream:
417-
with open(f"{lang}/definitions.yaml", 'w', encoding='utf8') as out_stream:
418+
with open(translated_file, 'w', encoding='utf8') as out_stream:
418419
lines = in_stream.readlines()
419-
i = 0
420+
i_en = 0
421+
i_trans = 0
420422
n_lines = len(lines)
421-
while i < n_lines:
422-
if not (lines[i].startswith('#')) and lines[i].find(': [') >= 0:
423+
while i_en < n_lines:
424+
if not (lines[i_en].startswith('#')) and (lines[i_en].find(': [') >= 0 or lines[i_en].find(': {') >= 0):
423425
# handles 'xxx: [' inclusive of the line with the matching ']'
424-
i = translate_definition(i, lines, translated_lines, out_stream)
426+
(i_en, i_trans) = translate_definition(i_en, lines, i_trans, translated_lines, out_stream)
425427
else:
426-
out_stream.write(lines[i])
427-
i += 1
428-
429-
430-
def translate_definition(start: int, lines: list[str], translated_lines: list[str], out_stream):
431-
out_stream.write(lines[start])
432-
i = start+1 # first line is 'name: ['
433-
while i < len(lines):
434-
if lines[i].find(']') >= 0:
435-
out_stream.write(lines[i])
436-
return i
437-
out_stream.write(translated_lines[i].replace("“", "'").replace("”", "'").replace("、", ",")) # Chinese
438-
i += 1
439-
return i
428+
out_stream.write(lines[i_en])
429+
i_en += 1
430+
# i_trans += 1
431+
432+
433+
def translate_definition(i_en: int, lines: list[str], i_trans: int, translated_lines: list[str], out_stream) -> (int, int):
434+
out_stream.write(lines[i_en])
435+
i_en = i_en+1 # first line is 'name: [' or 'name: {'
436+
# sync lines -- find '[' in translation
437+
while not (translated_lines[i_trans].find(': [') >= 0 or translated_lines[i_trans].find(': {') >= 0):
438+
i_trans += 1
439+
i_trans += 1 # skip the [/{ line
440+
while i_en < len(lines):
441+
if (
442+
translated_lines[i_en].strip().startswith('#') or
443+
len(translated_lines[i_en].strip()) == 0 and len(translated_lines[i_trans].strip()) == 0
444+
):
445+
out_stream.write(lines[i_en])
446+
elif lines[i_en].find(']') >= 0 or lines[i_en].find('}') >= 0:
447+
out_stream.write(lines[i_en])
448+
return (i_en, i_trans)
449+
elif len(translated_lines[i_trans].strip()) == 0: # google sometimes adds blank lines
450+
i_trans += 1
451+
continue
452+
else:
453+
print(f'en: {lines[i_en].strip()}\ntr: {translated_lines[i_trans].strip()}')
454+
# get indentation right
455+
i_spaces = lines[i_en].find('"')
456+
cleaned_line = (
457+
translated_lines[i_trans]
458+
.replace("“", '"').replace("”", '"').replace("„", '"').replace("、", ",") # Chinese
459+
.lstrip()
460+
)
461+
out_stream.write(f'{" ".ljust(i_spaces)}' + cleaned_line)
462+
i_en += 1
463+
i_trans += 1
464+
return (i_en, i_trans)
440465

441466

442467
def build_euro(lang: str):
@@ -502,7 +527,7 @@ def write_euro_braille_file():
502527
# (sre_only, mp_only, differ, same) = dict_compare("fr", get_sre_unicode_dict(SRE_Location, "fr"), get_mathplayer_unicode_dict(MP_Location, "fr"))
503528
# (sre_only, mp_only, differ, same) = dict_compare("it", get_sre_unicode_dict(SRE_Location, "it"), get_mathplayer_unicode_dict(MP_Location, "it"))
504529

505-
language = "ru"
530+
language = "pl"
506531
# build_new_translation("..", language, "unicode")
507532
# build_new_translation("..", language, "unicode-full")
508533

Rules/Languages/en/navigate.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@
232232
- name: zoom-in-mrow-in-math
233233
# zooming in only once is meaningless because 'math' has only a single child and it was spoken at the math level -- dig inside and do it again
234234
tag: math
235-
match: "($NavCommand = 'ZoomIn' or $NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom')"
235+
match: "$NavCommand = 'ZoomIn' or $NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom'"
236236
replace:
237237
- test:
238238
if: "$NavCommand = 'MovePreviousZoom'"
@@ -278,7 +278,7 @@
278278
variables: [Move2D: "'in'", Child2D: "*[1]/*[1]"] # phrase('in' the denominator)
279279
replace: [x: "."]
280280
- set_variables: [NavNode: "*[1]/*[1]/@id"] # skip mtd
281-
- else_if: "*[1][self::m:mrow and IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false)]" # auto zoom
281+
- else_if: "*[1][self::m:mrow and (IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false))]" # auto zoom
282282
then:
283283
- with:
284284
variables: [Move2D: "'in'", Child2D: "*[1]"] # phrase('in' the denominator)
@@ -459,7 +459,7 @@
459459
variables: [SayCommand: "string($NavVerbosity = 'Verbose')"]
460460
replace: [x: "."]
461461
- test:
462-
if: "$NavMode='Enhanced' and parent::*[self::m:mrow and IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false)]"
462+
if: "$NavMode='Enhanced' and parent::*[self::m:mrow and (IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false))]"
463463
then: [x: ".."] # auto-zoom: move out a level and retry
464464
else:
465465
- with:
@@ -1659,7 +1659,7 @@
16591659
- t: "inside" # phrase('inside' a big expression)
16601660
- pause: medium
16611661
- test:
1662-
- if: "$NavMode='Enhanced' and parent::*[self::m:mrow and IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false)]"
1662+
- if: "$NavMode='Enhanced' and parent::*[self::m:mrow and (IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false))]"
16631663
then: [x: ".."] # auto-zoom up
16641664
- else_if: "$NavCommand = 'WhereAmI'"
16651665
then: [set_variables: [NavNode: "@id"]]

src/chemistry.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -789,11 +789,12 @@ fn likely_chem_equation(mathml: Element) -> isize {
789789
// debug!("start likely_chem_equation:\n{}", mml_to_string(mathml));
790790
// mrow -- check the children to see if we are likely to be a chemical equation
791791

792-
// concentrations should either be unscripted or have a superscript
792+
// concentrations should either be unscripted or have a superscript that isn't a charge
793793
// they occur in mrows or mfracs
794794
if IsBracketed::is_bracketed(mathml, "[", "]", false, true) {
795795
let parent_name = name(get_parent(mathml));
796-
if parent_name == "mfrac" || parent_name == "mrow" || parent_name == "msup" || parent_name == "math" {
796+
if parent_name == "mfrac" || parent_name == "mrow" || parent_name == "math" ||
797+
(parent_name == "msup" && likely_chem_superscript(as_element(mathml.following_siblings()[0])) < 0){
797798
return if as_element(mathml.children()[0]).attribute(CHEM_FORMULA).is_some() {CHEMISTRY_THRESHOLD} else {NOT_CHEMISTRY};
798799
}
799800
}
@@ -2294,6 +2295,7 @@ mod chem_tests {
22942295

22952296
#[test]
22962297
fn dichlorine_hexoxide() {
2298+
init_logger();
22972299
let test = "<math><mrow>
22982300
<msup>
22992301
<mrow><mo>[</mo><mi>Cl</mi><msub><mi>O</mi><mn>2</mn></msub><mo>]</mo></mrow>

src/speech.rs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -661,23 +661,21 @@ impl Intent {
661661
/// "lift" up the children any "TEMP_NAME" child -- could short circuit when only one child
662662
fn lift_children(result: Element) -> Element {
663663
// debug!("lift_children:\n{}", mml_to_string(result));
664-
result.replace_children(
665-
result.children().iter()
666-
.map(|&child_of_element| {
667-
match child_of_element {
668-
ChildOfElement::Element(child) => {
669-
if name(child) == "TEMP_NAME" {
670-
assert_eq!(child.children().len(), 1);
671-
child.children()[0]
672-
} else {
673-
child_of_element
674-
}
675-
},
676-
_ => child_of_element, // text()
664+
// most likely there will be the same number of new children as result has, but there could be more
665+
let mut new_children = Vec::with_capacity(2*result.children().len());
666+
for child_of_element in result.children() {
667+
match child_of_element {
668+
ChildOfElement::Element(child) => {
669+
if name(child) == "TEMP_NAME" {
670+
new_children.append(&mut child.children()); // almost always just one
671+
} else {
672+
new_children.push(child_of_element);
677673
}
678-
})
679-
.collect::<Vec<ChildOfElement>>()
680-
);
674+
},
675+
_ => new_children.push(child_of_element), // text()
676+
}
677+
}
678+
result.replace_children(new_children);
681679
return result;
682680
}
683681
}
@@ -983,7 +981,7 @@ pub struct MyXPath {
983981

984982
impl fmt::Display for MyXPath {
985983
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
986-
return write!(f, "x: \"{}\"", self.rc.string);
984+
return write!(f, "\"{}\"", self.rc.string);
987985
}
988986
}
989987

@@ -1195,6 +1193,7 @@ impl MyXPath {
11951193
return match result {
11961194
Ok(val) => Ok( val ),
11971195
Err(e) => {
1196+
debug!("MyXPath::trying to evaluate:\n '{}'\n caused the error\n'{}'", self, e.to_string().replace("OwnedPrefixedName { prefix: None, local_part:", "").replace(" }", ""));
11981197
bail!( "{}\n\n",
11991198
// remove confusing parts of error message from xpath
12001199
e.to_string().replace("OwnedPrefixedName { prefix: None, local_part:", "").replace(" }", "") );
@@ -2706,7 +2705,7 @@ mod tests {
27062705
assert_eq!(speech_pattern.tag_name, "math", "\ntag name failure");
27072706
assert_eq!(speech_pattern.pattern.rc.string, ".", "\npattern failure");
27082707
assert_eq!(speech_pattern.replacements.replacements.len(), 1, "\nreplacement failure");
2709-
assert_eq!(speech_pattern.replacements.replacements[0].to_string(), r#"x: "./*""#, "\nreplacement failure");
2708+
assert_eq!(speech_pattern.replacements.replacements[0].to_string(), r#""./*""#, "\nreplacement failure");
27102709
}
27112710

27122711
#[test]

src/xpath_functions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ struct BaseNode;
753753
/// Recursively find the base node
754754
/// The base node of a non scripted element is the element itself
755755
fn base_node(node: Element) -> Element {
756-
let name = name(node);
756+
let name = node.attribute_value(MATHML_FROM_NAME_ATTR).unwrap_or(name(node));
757757
if ["msub", "msup", "msubsup", "munder", "mover", "munderover", "mmultiscripts"].contains(&name) {
758758
return BaseNode::base_node(as_element(node.children()[0]));
759759
} else {

0 commit comments

Comments
 (0)