-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkatex-server.js
More file actions
142 lines (124 loc) · 4.25 KB
/
katex-server.js
File metadata and controls
142 lines (124 loc) · 4.25 KB
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
134
135
136
137
138
139
140
141
const net = require("net");
const process = require("process");
let value = null;
let katex_options = {};
let socket = null;
let port = null;
// this is the downloaded katex javascript library.
// need to keep it updated
// path to the downloaded katex javascript library `katex.js`.
let katex_path = "./katex";
process.argv.forEach(function(arg) {
if (value == "katex_path") {
katex_path = arg;
value = null;
} else if (value == "socket_path") {
socket = arg;
value = null;
} else if (value == "socket_port") {
port = arg;
value = null;
} else {
if (arg == "--katex") {
value = "katex_path";
} else if (arg == "--socket") {
value = "socket_path";
} else if (arg == "--port") {
value = "socket_port";
} else {
// Ignore unknown/unexpected arguments, for example the path to this
// script
}
}
});
const katex = require(katex_path);
let listen_options = {};
if (socket !== null) {
listen_options["path"] = socket;
} else if (port !== null) {
listen_options["port"] = port;
// Do not expose the rendering server on the network
listen_options["host"] = "127.0.0.1";
}
// Start the network server for processing our sphinx's latex's math equations
const server = net.createServer();
server.on("connection", setupClient);
server.listen(listen_options);
function setupClient(client) {
// Split the input stream into individual rendering requests
// How many bytes are still left in the current request
let bytesLeft = null;
// List of chunks belonging to the current request
let buffer = [];
// Any undecoded bytes from the previous chunk, for example we were expecting
// a 4-byte integer but only received 2 bytes
let undecodedBytes = null;
client.on("data", function(chunk) {
// If there are any undecoded bytes left from the previous chunk, prepend
// them to the current one
if (undecodedBytes !== null) {
chunk = Buffer.concat([undecodedBytes, chunk]);
undecodedBytes = null;
}
let start = 0;
while (start < chunk.length) {
let remainingBytes = chunk.length - start;
if (bytesLeft === null) {
if (remainingBytes >= 4) {
bytesLeft = chunk.readInt32LE(start);
start += 4;
} else {
undecodedBytes = chunk.slice(start);
break;
}
} else {
if (remainingBytes >= bytesLeft) {
let end = start + bytesLeft;
buffer.push(chunk.slice(start, end));
var all = Buffer.concat(buffer);
handleRequest(client, all.toString());
bytesLeft = null;
buffer = [];
start = end;
} else {
buffer.push(chunk.slice(start));
bytesLeft -= remainingBytes;
break;
}
}
}
});
client.on("end", function() {
buffer = [];
});
}
function handleRequest(client, serialized) {
try {
var request = JSON.parse(serialized);
} catch (e) {
let response = { "error": `Could not deserialize ${serialized}: ${e.message}` };
sendMessage(client, JSON.stringify(response));
return;
}
try {
let latex = request["latex"];
let options = request["katex_options"] || {};
// this is where math latex equation is processed
let html = katex.renderToString(latex, options);
let response = { "html": html };
sendMessage(client, JSON.stringify(response));
} catch (e) {
let response = { "error": e.message };
sendMessage(client, JSON.stringify(response));
}
}
function sendMessage(client, message) {
// Encode the message string into bytes
let msgBuffer = Buffer.from(message, "utf-8");
// Tell the client how many bytes we are going to send
let lengthBuffer = Buffer.alloc(4);
lengthBuffer.writeInt32LE(msgBuffer.length, 0);
client.write(lengthBuffer);
// Send the actual message
client.write(msgBuffer);
}