-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmath-server.js
133 lines (113 loc) · 3.78 KB
/
math-server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2016 T. V. Raman, Volker Sorge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Commentary:
/**
* @fileoverview Server for connecting Emacs to the Speech-Rule-Engine.
* @author [email protected] (T. V. Raman)
*
* Expose a simple REPL as a server to emacspeak-maths.
*
* Usage Model:
*
* The Emacs client sends requests of the form:
* command: arg.
* The server responds with a Lisp S-expression.
* This S-expression is an annotated string.
* Annotations are ACSS property/value specifications.
* At any given time, the server loop is working with a given math expression,
* Emacs issues browse/render commands against that expression.
*/
// Code:
// Load the TCP Library
var net = require('net');
// Initialize Math rendering system.
var mjx = require('mathjax-node');
var sre = require('speech-rule-engine');
sre.setupEngine(
{markup: 'acss', domain: 'emacspeak', rules: ['EmacspeakRules']});
// Auxiliary methods for error handling.
var errorGen = {};
errorGen.parseError = function(error) {
return '(parse-error "' + error.replace(/\\/g, '\\\\') + '")';
};
errorGen.mathjaxErrors = function(errors, socket) {
socket.write(errors.map(errorGen.parseError).join(' '));
};
// table of request handlers:
var handlers = {};
// Add the various handlers:
// Accept a LaTeX math expression:
handlers.enter = function(expr, socket) {
mjx.config({displayErrors: false});
mjx.typeset({math: expr, format: 'TeX', mml: true}, function(data) {
(data.errors && data.errors.length) ?
errorGen.mathjaxErrors(data.errors, socket) :
socket.write(sre.walk(data.mml));
});
};
// Implement Handlers:
handlers.up = function(expr, socket) {
socket.write(sre.move('UP'));
};
handlers.down = function(expr, socket) {
socket.write(sre.move('DOWN'));
};
handlers.left = function(expr, socket) {
socket.write(sre.move('LEFT'));
};
handlers.right = function(expr, socket) {
socket.write(sre.move('RIGHT'));
};
handlers.repeat = function(expr, socket) {
socket.write(sre.move('TAB'));
};
handlers.depth = function(expr, socket) {
socket.write(sre.move('SPACE'));
};
handlers.root = function(expr, socket) {
socket.write(sre.move('HOME'));
};
// Start a TCP Server on port 5000
net.createServer(function(socket) {
// Identify this client
socket.name = socket.remoteAddress + ':' + socket.remotePort;
// Method: respond
function respond(message, sender) {
// message is of the form:
// cmd: args, args, args
var request = message.toString();
var cmd = request.split(':', 1)[0];
var args = request.slice(cmd.length + 1);
var handler = handlers[cmd];
if (handler !== undefined) {
handler.call(null, args, socket);
} else {
process.stdout.write('Handler for ' + request[0] + ' not defined.\n');
}
}
// Announce yourself:
socket.write('(welcome \"Maths Speech Server! \") ');
// Handle incoming messages from Emacs:
socket.on('data', function(data) {
respond(data, socket);
});
// Shutdown server on disconnect:
socket.on('end', function() {
socket.destroy();
process.exit();
});
})
.listen(5000);
// Put a friendly message on the terminal of the server.
console.log('Math server running at port 5000\n');