Skip to content

Commit a6d09c8

Browse files
committed
Mainly works.
1 parent 6010adc commit a6d09c8

3 files changed

Lines changed: 126 additions & 64 deletions

File tree

speech/action.js

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,46 @@ function removeSemanticData(math) {
2020

2121

2222
//
23-
// Moves a speech element into the description element for SVG output.
23+
// Moves all speech elements into aria-labels for SVG output. This allows for
24+
// elements without containers some limited exploration.
2425
//
2526
// Note, that here we cannot walk the source tree, as we alterations are to be
2627
// done on the typeset element, if it is a SVG node.
2728
//
28-
function speechToDescription(math) {
29+
function speechToRoles(math) {
2930
const root = math.typesetRoot;
3031
const adaptor = math.adaptor;
3132
const svg = adaptor.childNodes(root)[0];
3233
if (!svg || adaptor.kind(svg) !== 'svg') return;
34+
adaptor.removeAttribute(svg, 'aria-hidden');
35+
adaptor.removeAttribute(svg, 'role');
3336
const children = [svg];
3437
while (children.length) {
3538
let child = children.shift();
3639
if (adaptor.kind(child) === '#text') continue;
3740
if (adaptor.hasAttribute(child, 'data-semantic-speech')) {
38-
let desc = adaptor.create('desc');
39-
let text = adaptor.text(adaptor.getAttribute(child, 'data-semantic-speech'));
40-
adaptor.append(desc, text);
41-
adaptor.append(child, desc);
41+
let text = adaptor.getAttribute(child, 'data-semantic-speech');
42+
adaptor.setAttribute(child, 'aria-label', text);
43+
adaptor.setAttribute(child, 'role', 'img');
4244
adaptor.removeAttribute(child, 'data-semantic-speech');
4345
}
4446
children.push(...adaptor.childNodes(child));
4547
}
4648
}
4749

50+
//
51+
// Sets the rendered roots role to image if their is an aria-label to speak
52+
// custom elements.
53+
//
54+
function roleImg(math) {
55+
const adaptor = math.adaptor;
56+
const root = math.typesetRoot;
57+
if (adaptor.hasAttribute(root, 'aria-label')) {
58+
adaptor.setAttribute(root, 'role', 'img');
59+
}
60+
}
61+
62+
4863
//
4964
// Configures SRE from key value pairs by populating MathJax's config options.
5065
//
@@ -61,12 +76,6 @@ exports.dataPairs = function(data) {
6176

6277
exports.sreconfig = function(data) {
6378
const config = exports.dataPairs(data);
64-
if (data) {
65-
for (let i = 0, key; key = data[i]; i++) {
66-
let value = data[++i];
67-
config[key] = value || false;
68-
}
69-
}
7079
if (!MathJax.config.options) {
7180
MathJax.config.options = {};
7281
}
@@ -95,15 +104,26 @@ exports.speechAction = {
95104
removeSemanticData(math);
96105
}
97106
],
98-
describe: [
107+
role: [
99108
1000,
100109
(doc) => {
101110
for (const math of doc.math) {
102-
speechToDescription(math);
111+
roleImg(math);
112+
}
113+
},
114+
(math, doc) => {
115+
roleImg(math);
116+
}
117+
],
118+
describe: [
119+
1001,
120+
(doc) => {
121+
for (const math of doc.math) {
122+
speechToRoles(math);
103123
}
104124
},
105125
(math, doc) => {
106-
speechToDescription(math);
126+
speechToRoles(math);
107127
}
108128
]
109129

speech/tex2svg

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ MathJax = {
130130
startup: {
131131
typeset: false
132132
}
133-
}
133+
};
134134

135135
//
136136
// Load the MathJax startup module
@@ -146,11 +146,11 @@ action.sreconfig(argv.sre);
146146
// Wait for MathJax to start up, and then typeset the math
147147
//
148148
MathJax.startup.promise.then(() => {
149-
MathJax.tex2svgPromise(argv._[0] || '', {
149+
MathJax.tex2svgPromise(argv._[0] || '', {
150150
display: !argv.inline,
151151
em: argv.em,
152152
ex: argv.ex,
153-
containerWidth: argv.width
153+
containerWidth: argv.width,
154154
}).then((node) => {
155155
const adaptor = MathJax.startup.adaptor;
156156
//
@@ -160,8 +160,8 @@ MathJax.startup.promise.then(() => {
160160
if (argv.css) {
161161
console.log(adaptor.textContent(MathJax.svgStylesheet()));
162162
} else {
163-
let html = (argv.container ? adaptor.outerHTML(node) : adaptor.innerHTML(node));
164-
console.log(argv.styles ? html.replace(/<defs>/, `<defs><style>${CSS}</style>`) : html);
163+
let html = argv.container ? adaptor.outerHTML(node) : adaptor.innerHTML(node);
164+
console.log(argv.styles ? html.replace(/<defs>/, `<defs><style aria-hidden="true">${CSS}</style>`) : html);
165165
};
166166
});
167167
}).catch(err => console.log(err));

speech/tex2svg-page

Lines changed: 86 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,53 @@ const {TeX} = require('mathjax-full/js/input/tex.js');
3131
const {MathML} = require('mathjax-full/js/input/mathml.js');
3232
const {SVG} = require('mathjax-full/js/output/svg.js');
3333
const {liteAdaptor} = require('mathjax-full/js/adaptors/liteAdaptor.js');
34-
// const {jsdomAdaptor} = require('mathjax-full/js/adaptors/jsdomAdaptor.js');
3534
const {RegisterHTMLHandler} = require('mathjax-full/js/handlers/html.js');
3635
const {EnrichHandler} = require('mathjax-full/js/a11y/semantic-enrich.js');
37-
// const {Sre} = require('mathjax-full/js/a11y/sre.js');
38-
3936
const {AllPackages} = require('mathjax-full/js/input/tex/AllPackages.js');
4037

41-
// const {JSDOM} = require('jsdom');
42-
4338
require('mathjax-full/js/util/entities/all.js');
4439

4540

4641
//
4742
// Get the command-line arguments
4843
//
4944
const argv = require('yargs')
50-
.demand(1).strict()
51-
.usage('$0 [options] file.html > converted.html')
52-
.options({
53-
packages: {
54-
default: AllPackages.sort().join(', '),
55-
describe: 'the packages to use, e.g. "base, ams"'
56-
},
57-
fontCache: {
58-
default: 'global',
59-
describe: 'cache type: local, global, none'
60-
}
61-
})
62-
.argv;
45+
.demand(1).strict()
46+
.usage('$0 [options] file.html > converted.html')
47+
.options({
48+
em: {
49+
default: 16,
50+
describe: 'em-size in pixels'
51+
},
52+
ex: {
53+
default: 8,
54+
describe: 'ex-size in pixels'
55+
},
56+
packages: {
57+
default: AllPackages.sort().join(', '),
58+
describe: 'the packages to use, e.g. "base, ams"'
59+
},
60+
sre: {
61+
array: true,
62+
nargs: 2,
63+
describe: 'SRE flags as key value pairs, e.g., "--sre locale de --sre domain clearspeak" generates speech in German with clearspeak rules'
64+
},
65+
speech: {
66+
default: 'shallow',
67+
describe: 'level of speech: deep, shallow, none'
68+
},
69+
container: {
70+
boolean: true,
71+
describe: 'include <mjx-container> element'
72+
},
73+
fontCache: {
74+
default: 'global',
75+
describe: 'cache type: local, global, none'
76+
}
77+
})
78+
.argv;
79+
80+
const action = require('./action.js');
6381

6482
//
6583
// Read the HTML file
@@ -70,9 +88,37 @@ const htmlfile = require('fs').readFileSync(argv._[0], 'utf8');
7088
// Create DOM adaptor and register it for HTML documents
7189
//
7290
const adaptor = liteAdaptor({fontSize: argv.em});
73-
// const adaptor = jsdomAdaptor(JSDOM);
7491
EnrichHandler(RegisterHTMLHandler(adaptor), new MathML());
75-
// RegisterHTMLHandler(adaptor);
92+
93+
//
94+
// Get feature vector for SRE setup. If necessary, compute the path to the
95+
// locale JSON files explicitly.
96+
//
97+
const feature = action.dataPairs(argv.sre);
98+
feature.speech = argv.speech;
99+
feature.json = feature.json ? feature.json :
100+
require.resolve('mathjax-full/es5/sre/mathmaps/base.json').replace(/\/base\.json$/, '');
101+
102+
//
103+
// Remove container elements for all math items, by setting the typesetting
104+
// root to the svg element directly.
105+
//
106+
if (!argv.container) {
107+
action.speechAction.container = [
108+
199,
109+
(doc) => {
110+
for (let math of doc.math) {
111+
console.log(math);
112+
math.typesetRoot = adaptor.childNodes(math.typesetRoot)[0];
113+
}
114+
},
115+
(math, doc) => {
116+
math.typesetRoot = adaptor.childNodes(math.typesetRoot)[0];
117+
}
118+
];
119+
}
120+
121+
76122

77123

78124
//
@@ -82,35 +128,31 @@ const tex = new TeX({packages: argv.packages.split(/\s*,\s*/)});
82128
const svg = new SVG({fontCache: argv.fontCache});
83129
const html = mathjax.document(htmlfile, {InputJax: tex, OutputJax: svg,
84130
enableEnrichment: true,
85-
sre: {
86-
json: '/home/sorge/git/MathJax/MathJax-src/es5/sre/mathmaps',
87-
speech: 'deep'
88-
},
89-
renderActions: require('./action.js').speechAction
131+
sre: feature,
132+
renderActions: action.speechAction
90133
}
91134
);
92135

136+
console.log(html.renderActions);
93137

94138
//
95139
// Typeset the document
96140
//
97-
html.render();
98-
99-
100-
//
101-
// If no math was found on the page, remove the stylesheet and font cache (if any)
102-
//
103-
if (Array.from(html.math).length === 0) {
104-
adaptor.remove(html.outputJax.svgStyles);
105-
const cache = adaptor.elementById(adaptor.body(html.document), 'MJX-SVG-global-cache');
106-
if (cache) adaptor.remove(cache);
107-
}
141+
mathjax.handleRetriesFor(() => html.render()).then(
142+
() => {
143+
//
144+
// If no math was found on the page, remove the stylesheet and font cache (if any)
145+
//
146+
if (Array.from(html.math).length === 0) {
147+
adaptor.remove(html.outputJax.svgStyles);
148+
const cache = adaptor.elementById(adaptor.body(html.document), 'MJX-SVG-global-cache');
149+
if (cache) adaptor.remove(cache);
150+
}
108151

109-
//
110-
// Output the resulting HTML
111-
//
112-
console.log(adaptor.doctype(html.document));
113-
console.log(adaptor.outerHTML(adaptor.root(html.document)));
114-
// Sre.setupEngine({json: '/home/sorge/git/MathJax/MathJax-src/es5/sre/mathmaps'})
115-
// .then(() => Sre.sreReady())
116-
// .then(() => { });
152+
//
153+
// Output the resulting HTML
154+
//
155+
console.log(adaptor.doctype(html.document));
156+
console.log(adaptor.outerHTML(adaptor.root(html.document)));
157+
}
158+
);

0 commit comments

Comments
 (0)