Skip to content
This repository has been archived by the owner on Feb 20, 2024. It is now read-only.

Commit

Permalink
Merge pull request arnog#207 from NSoiffer/speech-text
Browse files Browse the repository at this point in the history
Speech text
  • Loading branch information
NSoiffer authored May 21, 2019
2 parents 8050ee8 + 5be3c4a commit dff1494
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 13 deletions.
46 changes: 37 additions & 9 deletions src/addons/outputMathML.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function scanIdentifier(stream, final, options) {

if (stream.index < final &&
(atom.type === 'mord' || atom.type === 'textord') &&
'0123456789,.'.indexOf(atom.latex) < 0) {
'0123456789,.'.indexOf(atom.body) < 0) {
body = atom.toMathML(options);
if (atom.superscript) {
superscript = stream.index;
Expand Down Expand Up @@ -128,6 +128,7 @@ function scanIdentifier(stream, final, options) {

if ((stream.lastType === 'mi' ||
stream.lastType === 'mn' ||
stream.lastType === 'mtext' ||
stream.lastType === 'fence') &&
!/^<mo>(.*)<\/mo>$/.test(mathML)) {
mathML = '<mo>&#x2062;</mo>' + mathML; // INVISIBLE TIMES
Expand Down Expand Up @@ -179,7 +180,7 @@ function indexOfSuperscriptInNumber(stream) {
let found = false;
while (i < stream.atoms.length && !done && !found) {
done = stream.atoms[i].type !== 'mord' ||
'0123456789,.'.indexOf(stream.atoms[i].latex) < 0;
'0123456789,.'.indexOf(stream.atoms[i].body) < 0;
found = !done && stream.atoms[i].superscript;
i++
}
Expand Down Expand Up @@ -232,6 +233,28 @@ function parseSubsup(base, stream, options) {
}


function scanText(stream, final, options) {
let result = false;
final = final || stream.atoms.length;
const initial = stream.index;
let mathML = '';
while (stream.index < final &&
stream.atoms[stream.index].mode === 'text'
) {
mathML += stream.atoms[stream.index].body ? stream.atoms[stream.index].body : ' ';
stream.index += 1;
}

if (mathML.length > 0) {
result = true;
mathML = '<mtext' + makeID(stream.atoms[initial].id, options) + '>' + mathML + '</mtext>';

stream.mathML += mathML;
stream.lastType = 'mtext';
}

return result;
}

function scanNumber(stream, final, options) {
let result = false;
Expand All @@ -246,9 +269,9 @@ function scanNumber(stream, final, options) {

while (stream.index < final &&
stream.atoms[stream.index].type === 'mord' &&
'0123456789,.'.indexOf(stream.atoms[stream.index].latex) >= 0
'0123456789,.'.indexOf(stream.atoms[stream.index].body) >= 0
) {
mathML += stream.atoms[stream.index].latex;
mathML += stream.atoms[stream.index].body;
stream.index += 1;
}

Expand Down Expand Up @@ -376,7 +399,11 @@ function scanOperator(stream, final, options) {
lastType = 'mo';

} else {
const op = toMo(stream.atoms[stream.index], options);
const atom = stream.atoms[stream.index];
const isUnit = atom.latex.indexOf('\\operatorname') === 0;
const op = isUnit ?
'<mi class="MathML-Unit"' + makeID(atom.id, options) + '>' + toString(atom.body) + '</mi>' :
toMo(atom, options);
mathML += op;
stream.index += 1;
if (parseSubsup(mathML, stream, options)) {
Expand All @@ -385,12 +412,12 @@ function scanOperator(stream, final, options) {
mathML = '';
}
stream.index -= 1;
if (!/^<mo>(.*)<\/mo>$/.test(op)) {
if (!isUnit && !/^<mo>(.*)<\/mo>$/.test(op)) {
mathML += '<mo>&#x2061;</mo>'; // APPLY FUNCTION
// mathML += scanArgument(stream);
lastType = 'applyfunction';
} else {
lastType = 'mo';
lastType = isUnit ? 'mi' : 'mo';
}
}
// mathML += '</mrow>';
Expand Down Expand Up @@ -440,7 +467,8 @@ function toMathML(input, initial, final, options) {
let count = 0;

while (result.index < final) {
if (scanNumber(result, final, options) ||
if (scanText(result, final, options) ||
scanNumber(result, final, options) ||
scanIdentifier(result, final, options) ||
scanOperator(result, final, options) ||
scanFence(result, final, options)) {
Expand Down Expand Up @@ -729,7 +757,7 @@ MathAtom.MathAtom.prototype.toMathML = function(options) {
} else if (typeof this.body === 'string') {
result = this.body.charAt(0);
} else {
result = this.latex;
result = this.body;
}
}
result = '<mi' + variant + makeID(this.id, options) + '>' + xmlEscape(result) + '</mi>';
Expand Down
19 changes: 16 additions & 3 deletions src/addons/outputSpokenText.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ const PRONUNCIATION = {
'\\prod': 'Product ',


'+': 'plus ',
'-': 'minus ',
';': '<break time="150ms"/> semi-colon <break time="150ms"/>',
',': '<break time="150ms"/> comma <break time="150ms"/>',
'|': '<break time="150ms"/>Vertical bar<break time="150ms"/>',
Expand Down Expand Up @@ -104,6 +106,15 @@ const PRONUNCIATION = {
// '\\rbrack': 'right bracket',
'\\lbrack': '<break time="150ms"/> open square bracket <break time="150ms"/>',
'\\rbrack': '<break time="150ms"/> close square bracket <break time="150ms"/>',

// need to add code to detect singluar/plural. Until then spoken as plural since that is vastly more common
// note: need to worry about intervening &InvisibleTimes;.
// note: need to also do this when in numerator of fraction and number preceeds fraction
// note: need to do this for <msup>
'mm': 'millimeters',
'cm': 'centimeters',
'km': 'kilometers',
'kg': 'kilograms',
}


Expand Down Expand Up @@ -231,9 +242,11 @@ MathAtom.toSpeakableFragment = function(atom, options) {
i += 2;
// '.' and ',' should only be allowed if prev/next entry is a digit
// However, if that isn't the case, this still works because 'toSpeakableFragment' is called in either case.
} else if (atom[i].type === 'mord' && /[0123456789,.]/.test(atom[i].latex)) {
if (isInDigitRun) {
result += atom[i].latex;
} else if (atom[i].mode === 'text') {
result += atom[i].body ? atom[i].body : ' ';
} else if (atom[i].type === 'mord' && /[0123456789,.]/.test(atom[i].body)) {
if (isInDigitRun) {
result += atom[i].body;
} else {
isInDigitRun = true;
result += MathAtom.toSpeakableFragment(atom[i], options);
Expand Down
2 changes: 1 addition & 1 deletion src/editor/editor-mathfield.js
Original file line number Diff line number Diff line change
Expand Up @@ -3636,7 +3636,7 @@ MathField.prototype.speak_ = function(amount, speakOptions) {
}

const options = this.config;
if (speakOptions.withHighlighting) {
if (speakOptions.withHighlighting | options.speechEngine === 'amazon') {
options.textToSpeechMarkup = (window.sre && options.textToSpeechRules === 'sre') ? 'ssml_step' : 'ssml';
}
const text = MathAtom.toSpeakableText(atoms, options)
Expand Down

0 comments on commit dff1494

Please sign in to comment.