@@ -288,6 +288,14 @@ splitOutside = (text, re) ->
288
288
parts .push text[start.. ]
289
289
parts
290
290
291
+ colStyle =
292
+ c : ' text-align: center;'
293
+ l : ' text-align: left;'
294
+ r : ' text-align: right;'
295
+ p : ' vertical-align: top;'
296
+ m : ' vertical-align: middle;'
297
+ b : ' vertical-align: bottom;'
298
+
291
299
# # Process all commands starting with \ followed by a letter a-z.
292
300
# # This is not a valid escape sequence in Markdown, so can be safely supported
293
301
# # in Markdown too.
@@ -299,17 +307,31 @@ latex2htmlCommandsAlpha = (tex, math) ->
299
307
(match , char , verb ) => " <code>#{ latexEscape verb} </code>"
300
308
# # Process tabular environments first in order to split cells at &
301
309
# # (so e.g. \bf is local to the cell)
302
- .replace / \\ begin\s * {tabular}\s * {((?:[^ {}] | {[^ {}] * })* )}([^ ] *? )\\ end\s * {tabular}/ g , (m , cols , body ) ->
310
+ .replace / \\ begin\s * {tabular}\s * {((?:[^ {}] | {(?: [^ {}] | { [ ^ {}] * }) * })* )}([^ ] *? )\\ end\s * {tabular}/ g , (m , cols , body ) ->
303
311
cols = cols .replace / \| / g , ' ' # not yet supported
304
312
body = body .replace / \\ hline\s * | \\ cline\s * {[^ {}] * }/ g , ' ' # not yet supported
305
- cols = cols .replace / \* (\d | {\d + }) ([^ {}] | {(?:[^ {}] | {[^ {}] * })* })/ g ,
313
+ cols = cols .replace / \* \s * (\d | {\s * \d + \s * }) \s * ([^ {}\s ] | {(?:[^ {}] | {[^ {}] * })* })/ g ,
306
314
(match , repeat , body ) =>
307
315
body = body[1 ... - 1 ] if body[0 ] == ' {'
308
- repeat = parseInt (repeat .replace / [{}] / g , ' ' ), 10
316
+ repeat = repeat[1 ... - 1 ] if repeat .startsWith ' {'
317
+ repeat = parseInt repeat, 10
309
318
repeat = 0 if repeat < 0
310
319
repeat = 1000 if repeat > 1000
311
320
body .repeat repeat
312
- skip = (0 for colnum in [0 ... cols .length ])
321
+ parseAlign = (pattern ) =>
322
+ pattern = pattern[1 ... - 1 ] if pattern .startsWith ' {'
323
+ align = pattern[0 ]
324
+ width = pattern[1 .. ]
325
+ width = width[1 ... - 1 ] if width .startsWith ' {'
326
+ style = ' '
327
+ if align of colStyle
328
+ style += colStyle[align]
329
+ if width
330
+ style += " width: #{ width} ;"
331
+ style
332
+ colStyles = []
333
+ cols .replace / (\w )({[^ {}] * })? / g , (match ) => colStyles .push parseAlign match
334
+ skip = {}
313
335
' <table>' +
314
336
(for row in splitOutside body, / (?:\\\\ | \[ DOUBLEBACKSLASH\] )/ # (?:\s*\\(?:hline|cline\s*{[^{}]*}))?/
315
337
# console.log row
@@ -321,38 +343,31 @@ latex2htmlCommandsAlpha = (tex, math) ->
321
343
skip[colnum]--
322
344
colnum++
323
345
continue
324
- align = cols[colnum]
325
346
attrs = ' '
326
- style = ' '
347
+ style = colStyles[colnum]
327
348
# # "If you want to use both \multirow and \multicolumn on the same
328
349
# # entry, you must put the \multirow inside the \multicolumn"
329
350
# # [http://ctan.mirrors.hoobly.com/macros/latex/contrib/multirow/multirow.pdf]
330
- if (match = / \\ multicolumn\s * (\d + | {\s * ( \d + ) \s * })\s * (\w | {( [^ {}] * ) })\s * {((?:[^ {}] | {(?:[^ {}] | {[^ {}] * })* })* )}/ .exec col)?
331
- colspan = parseInt match[2 ] ? match[ 1 ] , 10
351
+ if (match = / \\ multicolumn\s * (\d | {\s * \d + \s * })\s * (\w | {[^ {}] * })\s * {((?:[^ {}] | {(?:[^ {}] | {[^ {}] * })* })* )}/ .exec col)?
352
+ colspan = parseInt ( match[1 ]. replace / [{}] / g , ' ' ) , 10
332
353
attrs += " colspan=\" #{ colspan} \" "
333
- align = match[ 4 ] ? match[3 ]
334
- col = match[5 ]
354
+ style = parseAlign match[2 ]
355
+ col = match[3 ]
335
356
else
336
357
colspan = 1
337
358
# # In HTML, rowspan means that later rows shouldn't specify <td>s
338
359
# # for that column, while in LaTeX, they are still present.
339
- if (match = / \\ multirow\s * (\d + | {\s * (\d + )\s * })\s * (\* | {([^ {}] * )})\s * {((?:[^ {}] | {(?:[^ {}] | {[^ {}] * })* })* )}/ .exec col)?
340
- rowspan = parseInt match[2 ] ? match[1 ]
360
+ if (match = / \\ multirow\s * (\d | {\s * \d + \s * })\s * ([\w \* ] | {[^ {}] * })\s * {((?:[^ {}] | {(?:[^ {}] | {[^ {}] * })* })* )}/ .exec col)?
361
+ rowspan = parseInt (match[1 ].replace / [{}] / g , ' ' ), 10
362
+ skip[colnum] ?= 0
341
363
skip[colnum] += rowspan - 1
342
364
attrs += " rowspan=\" #{ rowspan} \" "
343
- style = ' vertical-align: middle; '
344
- # width = match[4] ? match[3]
345
- col = match[5 ]
346
- attrs +=
347
- switch align
348
- when ' c'
349
- " style=\" #{ style} text-align: center\" "
350
- when ' l'
351
- " style=\" #{ style} text-align: left\" "
352
- when ' r'
353
- " style=\" #{ style} text-align: right\" "
354
- else
355
- style
365
+ style += ' vertical-align: middle;'
366
+ if (width = match[2 ]) and width != ' *'
367
+ width = width[1 ... - 1 ] if width .startsWith ' {'
368
+ style += " width: #{ width} ;"
369
+ col = match[3 ]
370
+ attrs += " style=\" #{ style} \" " if style
356
371
colnum += colspan
357
372
" <td#{ attrs} >#{ col} </td>\n "
358
373
).join (' ' ) +
0 commit comments