forked from yeyanchao/oer.exports
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathstep1.coffee
executable file
·301 lines (241 loc) · 10.2 KB
/
step1.coffee
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
system = require('system')
fs = require('fs')
page = require("webpage").create()
# Set the page height and width
page.viewportSize = { width: 1024, height: 768 }
page.settings.localToRemoteUrlAccessEnabled = true
page.settings.ignoreSslErrors = true
page.onConsoleMessage = (msg, line, source) ->
console.log "console> " + msg # + " @ line: " + line
if system.args.length < 3
console.error "This program takes exactly 2 arguments:"
console.error "The absolute path to this directory (I know, it's annoying but I need it to load the jquery, mathjax, and the like)"
console.error "URL to the HTML file"
console.error "URL to post the output (X)HTML file"
console.error "URL to submit xincluded URLs to (and translate)"
phantom.exit 1
programDir = system.args[1]
inputUrl = system.args[2]
outputUrl = system.args[3]
depositUrl = system.args[4]
LOCALHOST = system.args[5]
id = system.args[6]
page.onConsoleMessage = (message, url, lineNumber) ->
console.error message
page.onError = (msg, trace) ->
console.error(msg)
trace.forEach (item) ->
console.error(' ', item.file, ':', item.line);
phantom.exit(1)
#if (!/^file:\/\/|http(s?):\/\//.test(appLocation)) {
# appLocation = 'file:///' + fs.absolute(appLocation).replace(/\\/g, '/');
#}
console.error "Opening page at: #{inputUrl}"
page.onAlert = (msg) ->
if msg
phantom.exit(1)
else
console.error "All good, closing PhantomJS"
phantom.exit(0)
page.open encodeURI(inputUrl), (status) ->
if status != 'success'
console.error "File not FOUND!!"
phantom.exit(1)
loadScript = (path) ->
if page.injectJs(path)
else
console.error "Could not find #{path}"
phantom.exit(1)
#loadScript(programDir + '/static/lib/jquery-latest.js')
needToKeepWaiting = page.evaluate((outputUrl, depositUrl, LOCALHOST, id) ->
loadScript = (src) ->
$script = $('<script></script>')
$script.attr('type', 'text/javascript')
$script.attr('src', src)
$('body').append $script
# Can't load MathJax using jQuery either. It doesn't process the entire document.
#script = document.createElement('script')
#script.setAttribute('src', "#{LOCALHOST}/lib/mathjax/MathJax.js?config=TeX-AMS-MML_SVG-full")
#document.getElementsByTagName('body')[0].appendChild(script)
#loadScript "#{LOCALHOST}/lib/d3.js"
#loadScript "#{LOCALHOST}/lib/nv.d3.js"
#loadScript "#{LOCALHOST}/lib/Tangle/Tangle.js"
#loadScript "#{LOCALHOST}/lib/Tangle/TangleKit/mootools.js"
#loadScript "#{LOCALHOST}/lib/Tangle/TangleKit/sprintf.js"
#loadScript "#{LOCALHOST}/lib/Tangle/TangleKit/BVTouchable.js"
#loadScript "#{LOCALHOST}/lib/Tangle/TangleKit/TangleKit.js"
loadScript "#{LOCALHOST}/lib/dom-to-xhtml.js"
loadScript "#{LOCALHOST}/lib/rasterize.js"
#loadScript "#{LOCALHOST}/lib/injector.js"
callback = () ->
# We need to convert all the canvas elements and images with dataURI's to images
rasterizer = new (window.Rasterize)()
rasterizer.convert()
# Rewrite the URLs for XIncluded documents and begin processing them
# Given the <base> element in <head> we can resolve relative URLs
base = $('head meta[href]').attr('href')
baseHref = base.replace(/\/[^\/]*$/, '')
baseDomain = base.split('/')[0] + '//' + base.split('/')[2] # ie http://cnx.org:1234/
toAbsoluteUrl = (href) ->
# TODO: Fix up ".." in relative paths
if href.charAt(0) == '#'
# It's an internal link. No change necessary
href
else if href.search(/^https?:\/\//) >= 0
# It's already absolute
href
else if href.search(/^\//) >= 0
# It starts with a "/"
baseDomain + href
else
# It's a relative path
baseHref + '/' + href
# Make URLs absolute instead of relative
$('a[href]').each () ->
$a = $(@)
href = toAbsoluteUrl($a.attr('href'))
$a.attr('href', href)
$('img[src]').each () ->
$a = $(@)
href = toAbsoluteUrl($a.attr('src'))
$a.attr('src', href)
serializeHtml = (callback) ->
# Hack to serialize out the HTML (sent to the console)
console.log 'Serializing (X)HTML back out from WebKit...'
$('script').remove()
xhtmlAry = []
xhtmlAry.push '<html xmlns="http://www.w3.org/1999/xhtml">'
# Keep the base element in there
xhtmlAry.push '<head>'
window.dom2xhtml.serialize($('head meta')[0], xhtmlAry)
xhtmlAry.push '</head>'
window.dom2xhtml.serialize($('body')[0], xhtmlAry)
xhtmlAry.push '</html>'
console.log 'Submitting (X)HTML back to the server...'
params =
contents: xhtmlAry.join('')
config =
url: outputUrl
type: 'POST'
data : params
$.ajax(config)
.fail () ->
alert "Submit Failed" # Problem.
.done (text) ->
console.log "Sent XHTML back to server with response: #{text}"
alert '' # All OK to close up
recurseXincludes = (callback) ->
xincludes = $('a[href].xinclude')
leftToProcess = xincludes.length
console.log "Remote deposit count #{leftToProcess}"
if leftToProcess == 0
callback()
xincludes.each () ->
$a = $(@)
href = $a.attr('href')
# PHIL href = href + "/index_auto_generated.cnxml"
console.log "Depositing #{href} via #{depositUrl} wrt #{id}"
# Perform the ajax call
params = { new: href, original: id }
options =
url: depositUrl
type: 'POST'
data: params
$.ajax(options)
.fail () ->
console.error "Problem Converting #{href}"
.done (text) ->
console.log "Converted #{href} to #{text}"
$a.attr('data-url', href)
$a.attr('href', text)
.always () ->
leftToProcess--
if leftToProcess == 0
callback()
svg2png = (callback) ->
$nodes = $('svg')
leftToProcess = $nodes.length
console.log "svg2png count #{leftToProcess}"
if leftToProcess == 0
callback()
$nodes.each () ->
$node = $(@)
node = @
# MathJax doesn't translate the images and explicitly set width/height attributes.
# This causes rsvg-convert to only render slivers of the graphic on the top of the image.
# MathJax sets the width and height of the image in a style attribute but
# rsvg-convert requires them to be set explicitly
# Also, dom-to-xhtml.js needs to use camelcase for the viewBox attribute (that's what caused the slivers)
# If no width is explicitly set on the SVG graphic then use the width in the browser
$node.attr('width', "#{ $node.innerWidth() }px") if not $node.attr('width')?
$node.attr('height', "#{ $node.innerHeight() }px") if not $node.attr('height')?
xmlAry = []
window.dom2xhtml.serialize(node, xmlAry)
svg = xmlAry.join('')
# Perform the ajax call
params = { contents: svg }
options =
url: '/svg-to-png'
type: 'POST'
data: params
$.ajax(options)
.fail () ->
console.error "Problem Converting SVG"
.done (resourceHref) ->
console.log "Queued SVG2PNG at #{resourceHref}"
$node.attr('data-png-url', resourceHref)
#$img = $('<img></img>').addClass('svg-image').attr('src', resourceHref)
#$node.replaceWith $img
.always () ->
leftToProcess--
if leftToProcess == 0
callback()
recurseXincludes(serializeHtml)
# Configure MathJax
console.log "Waiting to finish processing math..."
mathJaxHack = () ->
console.error "Could not load MathJax" if not window.MathJax
try # Fails if MathJax isn't loaded into the page. So far, it's up to the HTML file to find/include MathJax
MathJax.Hub.Queue () ->
console.log "Found #{$('.MathJax_SVG').length} SVG elements"
$('.MathJax_SVG').each (i, node) =>
# ChromeVox reads one word at a time and finishes "speaking"
# by sending the string "math".
accumulator = ''
# Read the MathML and squirrel it away in the MathML
cvox.AndroidTts.prototype.speak = (textString, foo, pers) =>
accumulator += textString + ' '
# if textString == 'math'
$(node).children().attr('role', 'region')
$(node).children().attr('aria-label', accumulator)
id = $(node).attr('id')
jax = MathJax.Hub.getJaxFor(id)
if jax
$math = jQuery(jax.root.toMathML())
cvox.Api.syncToNode($math[0], true)
console.log "Finished Processing math! "
$('#MathJax_Message').remove() # This function gets called before MathJax removes the "Typesetting 100%" message
# Copy all the SVG glyphs to multiple SVG elmeents
# See http://www.w3.org/TR/SVG11/struct.html#UseElement
$uses = $('.MathJax_SVG svg use')
$uses.each () ->
$use = $(@)
x = $use.attr('x') or 0
y = $use.attr('y') or 0
transform = $use.attr('transform') or ''
$g = $("<g transform='#{transform} translate(#{x}, #{y})'></g>")
$g.append $($use.attr('href'))[0].cloneNode(true)
$use.replaceWith $g
# MathJax doesn't translate the images and explicitly set width/height attributes.
# This causes rsvg-convert to only render slivers of the graphic on the top of the image.
# We have to do this _only_ for the SVG2PNG conversion. Otherwise the images look bad online
# Remove the hidden MathJax elements
$('#MathJax_SVG_Hidden').remove()
$('#MathJax_SVG_glyphs').parent().remove()
callback()
catch e
console.error "ERROR Happened"
console.error e
alert e
setTimeout mathJaxHack, 10000
, outputUrl, depositUrl, LOCALHOST, id)