PageRenderTime 91ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/plugins/rtex/vendor/instiki/redcloth_for_tex.rb

https://bitbucket.org/mumbly/openbrewcomp
Ruby | 736 lines | 572 code | 103 blank | 61 comment | 53 complexity | 71d5ebfb304a18c96e623d5c1c38f66f MD5 | raw file
Possible License(s): GPL-3.0
  1. # This is RedCloth (http://www.whytheluckystiff.net/ruby/redcloth/)
  2. # converted by David Heinemeier Hansson to emit Tex
  3. class String
  4. # Flexible HTML escaping
  5. def texesc!( mode )
  6. gsub!( '&', '\\\\&' )
  7. gsub!( '%', '\%' )
  8. gsub!( '$', '\$' )
  9. gsub!( '~', '$\sim$' )
  10. end
  11. end
  12. def table_of_contents(text, pages)
  13. text.gsub( /^([#*]+? .*?)$(?![^#*])/m ) do |match|
  14. lines = match.split( /\n/ )
  15. last_line = -1
  16. depth = []
  17. lines.each_with_index do |line, line_id|
  18. if line =~ /^([#*]+) (.*)$/m
  19. tl,content = $~[1..2]
  20. content.gsub! /[\[\]]/, ""
  21. content.strip!
  22. if depth.last
  23. if depth.last.length > tl.length
  24. (depth.length - 1).downto(0) do |i|
  25. break if depth[i].length == tl.length
  26. lines[line_id - 1] << "" # "\n\t\\end{#{ lT( depth[i] ) }}\n\t"
  27. depth.pop
  28. end
  29. end
  30. if !depth.last.nil? && !tl.length.nil? && depth.last.length == tl.length
  31. lines[line_id - 1] << ''
  32. end
  33. end
  34. depth << tl unless depth.last == tl
  35. subsection_depth = [depth.length - 1, 2].min
  36. lines[line_id] = "\n\\#{ "sub" * subsection_depth }section{#{ content }}"
  37. lines[line_id] += "\n#{pages[content]}" if pages.keys.include?(content)
  38. lines[line_id] = "\\pagebreak\n#{lines[line_id]}" if subsection_depth == 0
  39. last_line = line_id
  40. elsif line =~ /^\s+\S/
  41. last_line = line_id
  42. elsif line_id - last_line < 2 and line =~ /^\S/
  43. last_line = line_id
  44. end
  45. if line_id - last_line > 1 or line_id == lines.length - 1
  46. depth.delete_if do |v|
  47. lines[last_line] << "" # "\n\t\\end{#{ lT( v ) }}"
  48. end
  49. end
  50. end
  51. lines.join( "\n" )
  52. end
  53. end
  54. class RedClothForTex < String
  55. VERSION = '2.0.7'
  56. #
  57. # Mapping of 8-bit ASCII codes to HTML numerical entity equivalents.
  58. # (from PyTextile)
  59. #
  60. TEXTILE_TAGS =
  61. [[128, 8364], [129, 0], [130, 8218], [131, 402], [132, 8222], [133, 8230],
  62. [134, 8224], [135, 8225], [136, 710], [137, 8240], [138, 352], [139, 8249],
  63. [140, 338], [141, 0], [142, 0], [143, 0], [144, 0], [145, 8216], [146, 8217],
  64. [147, 8220], [148, 8221], [149, 8226], [150, 8211], [151, 8212], [152, 732],
  65. [153, 8482], [154, 353], [155, 8250], [156, 339], [157, 0], [158, 0], [159, 376]].
  66. collect! do |a, b|
  67. [a.chr, ( b.zero? and "" or "&#{ b };" )]
  68. end
  69. #
  70. # Regular expressions to convert to HTML.
  71. #
  72. A_HLGN = /(?:(?:<>|<|>|\=|[()]+)+)/
  73. A_VLGN = /[\-^~]/
  74. C_CLAS = '(?:\([^)]+\))'
  75. C_LNGE = '(?:\[[^\]]+\])'
  76. C_STYL = '(?:\{[^}]+\})'
  77. S_CSPN = '(?:\\\\\d+)'
  78. S_RSPN = '(?:/\d+)'
  79. A = "(?:#{A_HLGN}?#{A_VLGN}?|#{A_VLGN}?#{A_HLGN}?)"
  80. S = "(?:#{S_CSPN}?#{S_RSPN}|#{S_RSPN}?#{S_CSPN}?)"
  81. C = "(?:#{C_CLAS}?#{C_STYL}?#{C_LNGE}?|#{C_STYL}?#{C_LNGE}?#{C_CLAS}?|#{C_LNGE}?#{C_STYL}?#{C_CLAS}?)"
  82. # PUNCT = Regexp::quote( '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' )
  83. PUNCT = Regexp::quote( '!"#$%&\'*+,-./:;=?@\\^_`|~' )
  84. HYPERLINK = '(\S+?)([^\w\s/;=\?]*?)(\s|$)'
  85. GLYPHS = [
  86. # [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1&#8217;\2' ], # single closing
  87. [ /([^\s\[{(>])\'/, '\1&#8217;' ], # single closing
  88. [ /\'(?=\s|s\b|[#{PUNCT}])/, '&#8217;' ], # single closing
  89. [ /\'/, '&#8216;' ], # single opening
  90. # [ /([^\s\[{(])?"(\s|:|$)/, '\1&#8221;\2' ], # double closing
  91. [ /([^\s\[{(>])"/, '\1&#8221;' ], # double closing
  92. [ /"(?=\s|[#{PUNCT}])/, '&#8221;' ], # double closing
  93. [ /"/, '&#8220;' ], # double opening
  94. [ /\b( )?\.{3}/, '\1&#8230;' ], # ellipsis
  95. [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
  96. [ /(^|[^"][>\s])([A-Z][A-Z0-9 ]{2,})([^<a-z0-9]|$)/, '\1<span class="caps">\2</span>\3' ], # 3+ uppercase caps
  97. [ /(\.\s)?\s?--\s?/, '\1&#8212;' ], # em dash
  98. [ /\s->\s/, ' &rarr; ' ], # en dash
  99. [ /\s-\s/, ' &#8211; ' ], # en dash
  100. [ /(\d+) ?x ?(\d+)/, '\1&#215;\2' ], # dimension sign
  101. [ /\b ?[(\[]TM[\])]/i, '&#8482;' ], # trademark
  102. [ /\b ?[(\[]R[\])]/i, '&#174;' ], # registered
  103. [ /\b ?[(\[]C[\])]/i, '&#169;' ] # copyright
  104. ]
  105. I_ALGN_VALS = {
  106. '<' => 'left',
  107. '=' => 'center',
  108. '>' => 'right'
  109. }
  110. H_ALGN_VALS = {
  111. '<' => 'left',
  112. '=' => 'center',
  113. '>' => 'right',
  114. '<>' => 'justify'
  115. }
  116. V_ALGN_VALS = {
  117. '^' => 'top',
  118. '-' => 'middle',
  119. '~' => 'bottom'
  120. }
  121. QTAGS = [
  122. ['**', 'bf'],
  123. ['*', 'bf'],
  124. ['??', 'cite'],
  125. ['-', 'del'],
  126. ['__', 'underline'],
  127. ['_', 'em'],
  128. ['%', 'span'],
  129. ['+', 'ins'],
  130. ['^', 'sup'],
  131. ['~', 'sub']
  132. ]
  133. def self.available?
  134. if not defined? @@available
  135. begin
  136. @@available = system "pdflatex -version"
  137. rescue Errno::ENOENT
  138. @@available = false
  139. end
  140. end
  141. @@available
  142. end
  143. #
  144. # Two accessor for setting security restrictions.
  145. #
  146. # This is a nice thing if you're using RedCloth for
  147. # formatting in public places (e.g. Wikis) where you
  148. # don't want users to abuse HTML for bad things.
  149. #
  150. # If +:filter_html+ is set, HTML which wasn't
  151. # created by the Textile processor will be escaped.
  152. #
  153. # If +:filter_styles+ is set, it will also disable
  154. # the style markup specifier. ('{color: red}')
  155. #
  156. attr_accessor :filter_html, :filter_styles
  157. #
  158. # Accessor for toggling line folding.
  159. #
  160. # If +:fold_lines+ is set, single newlines will
  161. # not be converted to break tags.
  162. #
  163. attr_accessor :fold_lines
  164. def initialize( string, restrictions = [] )
  165. restrictions.each { |r| method( "#{ r }=" ).call( true ) }
  166. super( string )
  167. end
  168. #
  169. # Generate tex.
  170. #
  171. def to_tex( lite = false )
  172. # make our working copy
  173. text = self.dup
  174. @urlrefs = {}
  175. @shelf = []
  176. # incoming_entities text
  177. fix_entities text
  178. clean_white_space text
  179. get_refs text
  180. no_textile text
  181. unless lite
  182. lists text
  183. table text
  184. end
  185. glyphs text
  186. unless lite
  187. fold text
  188. block text
  189. end
  190. retrieve text
  191. encode_entities text
  192. text.gsub!(/\[\[(.*?)\]\]/, "\\1")
  193. text.gsub!(/_/, "\\_")
  194. text.gsub!( /<\/?notextile>/, '' )
  195. # text.gsub!( /x%x%/, '&#38;' )
  196. # text.gsub!( /<br \/>/, "<br />\n" )
  197. text.strip!
  198. text
  199. end
  200. def pgl( text )
  201. GLYPHS.each do |re, resub|
  202. text.gsub! re, resub
  203. end
  204. end
  205. def pba( text_in, element = "" )
  206. return '' unless text_in
  207. style = []
  208. text = text_in.dup
  209. if element == 'td'
  210. colspan = $1 if text =~ /\\(\d+)/
  211. rowspan = $1 if text =~ /\/(\d+)/
  212. style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN
  213. end
  214. style << "#{ $1 };" if not @filter_styles and
  215. text.sub!( /\{([^}]*)\}/, '' )
  216. lang = $1 if
  217. text.sub!( /\[([^)]+?)\]/, '' )
  218. cls = $1 if
  219. text.sub!( /\(([^()]+?)\)/, '' )
  220. style << "padding-left:#{ $1.length }em;" if
  221. text.sub!( /([(]+)/, '' )
  222. style << "padding-right:#{ $1.length }em;" if text.sub!( /([)]+)/, '' )
  223. style << "text-align:#{ h_align( $& ) };" if text =~ A_HLGN
  224. cls, id = $1, $2 if cls =~ /^(.*?)#(.*)$/
  225. atts = ''
  226. atts << " style=\"#{ style.join }\"" unless style.empty?
  227. atts << " class=\"#{ cls }\"" unless cls.to_s.empty?
  228. atts << " lang=\"#{ lang }\"" if lang
  229. atts << " id=\"#{ id }\"" if id
  230. atts << " colspan=\"#{ colspan }\"" if colspan
  231. atts << " rowspan=\"#{ rowspan }\"" if rowspan
  232. atts
  233. end
  234. def table( text )
  235. text << "\n\n"
  236. text.gsub!( /^(?:table(_?#{S}#{A}#{C})\. ?\n)?^(#{A}#{C}\.? ?\|.*?\|)\n\n/m ) do |matches|
  237. tatts, fullrow = $~[1..2]
  238. tatts = pba( tatts, 'table' )
  239. rows = []
  240. fullrow.
  241. split( /\|$/m ).
  242. delete_if { |x| x.empty? }.
  243. each do |row|
  244. ratts, row = pba( $1, 'tr' ), $2 if row =~ /^(#{A}#{C}\. )(.*)/m
  245. cells = []
  246. row.split( '|' ).each do |cell|
  247. ctyp = 'd'
  248. ctyp = 'h' if cell =~ /^_/
  249. catts = ''
  250. catts, cell = pba( $1, 'td' ), $2 if cell =~ /^(_?#{S}#{A}#{C}\. )(.*)/
  251. unless cell.strip.empty?
  252. cells << "\t\t\t<t#{ ctyp }#{ catts }>#{ cell }</t#{ ctyp }>"
  253. end
  254. end
  255. rows << "\t\t<tr#{ ratts }>\n#{ cells.join( "\n" ) }\n\t\t</tr>"
  256. end
  257. "\t<table#{ tatts }>\n#{ rows.join( "\n" ) }\n\t</table>\n\n"
  258. end
  259. end
  260. def lists( text )
  261. text.gsub!( /^([#*]+?#{C} .*?)$(?![^#*])/m ) do |match|
  262. lines = match.split( /\n/ )
  263. last_line = -1
  264. depth = []
  265. lines.each_with_index do |line, line_id|
  266. if line =~ /^([#*]+)(#{A}#{C}) (.*)$/m
  267. tl,atts,content = $~[1..3]
  268. if depth.last
  269. if depth.last.length > tl.length
  270. (depth.length - 1).downto(0) do |i|
  271. break if depth[i].length == tl.length
  272. lines[line_id - 1] << "\n\t\\end{#{ lT( depth[i] ) }}\n\t"
  273. depth.pop
  274. end
  275. end
  276. if !depth.last.nil? && !tl.length.nil? && depth.last.length == tl.length
  277. lines[line_id - 1] << ''
  278. end
  279. end
  280. unless depth.last == tl
  281. depth << tl
  282. atts = pba( atts )
  283. lines[line_id] = "\t\\begin{#{ lT(tl) }}\n\t\\item #{ content }"
  284. else
  285. lines[line_id] = "\t\t\\item #{ content }"
  286. end
  287. last_line = line_id
  288. elsif line =~ /^\s+\S/
  289. last_line = line_id
  290. elsif line_id - last_line < 2 and line =~ /^\S/
  291. last_line = line_id
  292. end
  293. if line_id - last_line > 1 or line_id == lines.length - 1
  294. depth.delete_if do |v|
  295. lines[last_line] << "\n\t\\end{#{ lT( v ) }}"
  296. end
  297. end
  298. end
  299. lines.join( "\n" )
  300. end
  301. end
  302. def lT( text )
  303. text =~ /\#$/ ? 'enumerate' : 'itemize'
  304. end
  305. def fold( text )
  306. text.gsub!( /(.+)\n(?![#*\s|])/, "\\1\\\\\\\\" )
  307. # text.gsub!( /(.+)\n(?![#*\s|])/, "\\1#{ @fold_lines ? ' ' : '<br />' }" )
  308. end
  309. def block( text )
  310. pre = false
  311. find = ['bq','h[1-6]','fn\d+']
  312. regexp_cue = []
  313. lines = text.split( /\n/ ) + [' ']
  314. new_text =
  315. lines.collect do |line|
  316. pre = true if line =~ /<(pre|notextile)>/i
  317. find.each do |tag|
  318. line.gsub!( /^(#{ tag })(#{A}#{C})\.(?::(\S+))? (.*)$/ ) do |m|
  319. tag,atts,cite,content = $~[1..4]
  320. atts = pba( atts )
  321. if tag =~ /fn(\d+)/
  322. # tag = 'p';
  323. # atts << " id=\"fn#{ $1 }\""
  324. regexp_cue << [ /footnote\{#{$1}}/, "footnote{#{content}}" ]
  325. content = ""
  326. end
  327. if tag =~ /h([1-6])/
  328. section_type = "sub" * [$1.to_i - 1, 2].min
  329. start = "\t\\#{section_type}section*{"
  330. tend = "}"
  331. end
  332. if tag == "bq"
  333. cite = check_refs( cite )
  334. cite = " cite=\"#{ cite }\"" if cite
  335. start = "\t\\begin{quotation}\n\\noindent {\\em ";
  336. tend = "}\n\t\\end{quotation}";
  337. end
  338. "#{ start }#{ content }#{ tend }"
  339. end unless pre
  340. end
  341. #line.gsub!( /^(?!\t|<\/?pre|<\/?notextile|<\/?code|$| )(.*)/, "\t<p>\\1</p>" )
  342. #line.gsub!( "<br />", "\n" ) if pre
  343. # pre = false if line =~ /<\/(pre|notextile)>/i
  344. line
  345. end.join( "\n" )
  346. text.replace( new_text )
  347. regexp_cue.each { |pair| text.gsub!(pair.first, pair.last) }
  348. end
  349. def span( text )
  350. QTAGS.each do |tt, ht|
  351. ttr = Regexp::quote( tt )
  352. text.gsub!(
  353. /(^|\s|\>|[#{PUNCT}{(\[])
  354. #{ttr}
  355. (#{C})
  356. (?::(\S+?))?
  357. ([^\s#{ttr}]+?(?:[^\n]|\n(?!\n))*?)
  358. ([#{PUNCT}]*?)
  359. #{ttr}
  360. (?=[\])}]|[#{PUNCT}]+?|<|\s|$)/xm
  361. ) do |m|
  362. start,atts,cite,content,tend = $~[1..5]
  363. atts = pba( atts )
  364. atts << " cite=\"#{ cite }\"" if cite
  365. "#{ start }{\\#{ ht } #{ content }#{ tend }}"
  366. end
  367. end
  368. end
  369. def links( text )
  370. text.gsub!( /
  371. ([\s\[{(]|[#{PUNCT}])? # $pre
  372. " # start
  373. (#{C}) # $atts
  374. ([^"]+?) # $text
  375. \s?
  376. (?:\(([^)]+?)\)(?="))? # $title
  377. ":
  378. (\S+?) # $url
  379. (\/)? # $slash
  380. ([^\w\/;]*?) # $post
  381. (?=\s|$)
  382. /x ) do |m|
  383. pre,atts,text,title,url,slash,post = $~[1..7]
  384. url.gsub!(/(\\)(.)/, '\2')
  385. url = check_refs( url )
  386. atts = pba( atts )
  387. atts << " title=\"#{ title }\"" if title
  388. atts = shelve( atts ) if atts
  389. "#{ pre }\\textit{#{ text }} \\footnote{\\texttt{\\textless #{ url }#{ slash }" +
  390. "\\textgreater}#{ post }}"
  391. end
  392. end
  393. def get_refs( text )
  394. text.gsub!( /(^|\s)\[(.+?)\]((?:http:\/\/|javascript:|ftp:\/\/|\/)\S+?)(?=\s|$)/ ) do |m|
  395. flag, url = $~[1..2]
  396. @urlrefs[flag] = url
  397. end
  398. end
  399. def check_refs( text )
  400. @urlrefs[text] || text
  401. end
  402. def image( text )
  403. text.gsub!( /
  404. \! # opening
  405. (\<|\=|\>)? # optional alignment atts
  406. (#{C}) # optional style,class atts
  407. (?:\. )? # optional dot-space
  408. ([^\s(!]+?) # presume this is the src
  409. \s? # optional space
  410. (?:\(((?:[^\(\)]|\([^\)]+\))+?)\))? # optional title
  411. \! # closing
  412. (?::#{ HYPERLINK })? # optional href
  413. /x ) do |m|
  414. algn,atts,url,title,href,href_a1,href_a2 = $~[1..7]
  415. atts = pba( atts )
  416. atts << " align=\"#{ i_align( algn ) }\"" if algn
  417. atts << " title=\"#{ title }\"" if title
  418. atts << " alt=\"#{ title }\""
  419. # size = @getimagesize($url);
  420. # if($size) $atts.= " $size[3]";
  421. href = check_refs( href ) if href
  422. url = check_refs( url )
  423. out = ''
  424. out << "<a href=\"#{ href }\">" if href
  425. out << "<img src=\"#{ url }\"#{ atts } />"
  426. out << "</a>#{ href_a1 }#{ href_a2 }" if href
  427. out
  428. end
  429. end
  430. def code( text )
  431. text.gsub!( /
  432. (?:^|([\s\(\[{])) # 1 open bracket?
  433. @ # opening
  434. (?:\|(\w+?)\|)? # 2 language
  435. (\S(?:[^\n]|\n(?!\n))*?) # 3 code
  436. @ # closing
  437. (?:$|([\]})])|
  438. (?=[#{PUNCT}]{1,2}|
  439. \s)) # 4 closing bracket?
  440. /x ) do |m|
  441. before,lang,code,after = $~[1..4]
  442. lang = " language=\"#{ lang }\"" if lang
  443. "#{ before }<code#{ lang }>#{ code }</code>#{ after }"
  444. end
  445. end
  446. def shelve( val )
  447. @shelf << val
  448. " <#{ @shelf.length }>"
  449. end
  450. def retrieve( text )
  451. @shelf.each_with_index do |r, i|
  452. text.gsub!( " <#{ i + 1 }>", r )
  453. end
  454. end
  455. def incoming_entities( text )
  456. ## turn any incoming ampersands into a dummy character for now.
  457. ## This uses a negative lookahead for alphanumerics followed by a semicolon,
  458. ## implying an incoming html entity, to be skipped
  459. text.gsub!( /&(?![#a-z0-9]+;)/i, "x%x%" )
  460. end
  461. def encode_entities( text )
  462. ## Convert high and low ascii to entities.
  463. # if $-K == "UTF-8"
  464. # encode_high( text )
  465. # else
  466. text.texesc!( :NoQuotes )
  467. # end
  468. end
  469. def fix_entities( text )
  470. ## de-entify any remaining angle brackets or ampersands
  471. text.gsub!( "\&", "&" )
  472. text.gsub!( "\%", "%" )
  473. end
  474. def clean_white_space( text )
  475. text.gsub!( /\r\n/, "\n" )
  476. text.gsub!( /\t/, '' )
  477. text.gsub!( /\n{3,}/, "\n\n" )
  478. text.gsub!( /\n *\n/, "\n\n" )
  479. text.gsub!( /"$/, "\" " )
  480. end
  481. def no_textile( text )
  482. text.gsub!( /(^|\s)==(.*?)==(\s|$)?/,
  483. '\1<notextile>\2</notextile>\3' )
  484. end
  485. def footnote_ref( text )
  486. text.gsub!( /\[([0-9]+?)\](\s)?/,
  487. '\footnote{\1}\2')
  488. #'<sup><a href="#fn\1">\1</a></sup>\2' )
  489. end
  490. def inline( text )
  491. image text
  492. links text
  493. code text
  494. span text
  495. end
  496. def glyphs_deep( text )
  497. codepre = 0
  498. offtags = /(?:code|pre|kbd|notextile)/
  499. if text !~ /<.*>/
  500. # pgl text
  501. footnote_ref text
  502. else
  503. used_offtags = {}
  504. text.gsub!( /(?:[^<].*?(?=<[^\n]*?>|$)|<[^\n]*?>+)/m ) do |line|
  505. tagline = ( line =~ /^<.*>/ )
  506. ## matches are off if we're between <code>, <pre> etc.
  507. if tagline
  508. if line =~ /<(#{ offtags })>/i
  509. codepre += 1
  510. used_offtags[$1] = true
  511. line.texesc!( :NoQuotes ) if codepre - used_offtags.length > 0
  512. elsif line =~ /<\/(#{ offtags })>/i
  513. line.texesc!( :NoQuotes ) if codepre - used_offtags.length > 0
  514. codepre -= 1 unless codepre.zero?
  515. used_offtags = {} if codepre.zero?
  516. elsif @filter_html or codepre > 0
  517. line.texesc!( :NoQuotes )
  518. ## line.gsub!( /&lt;(\/?#{ offtags })&gt;/, '<\1>' )
  519. end
  520. ## do htmlspecial if between <code>
  521. elsif codepre > 0
  522. line.texesc!( :NoQuotes )
  523. ## line.gsub!( /&lt;(\/?#{ offtags })&gt;/, '<\1>' )
  524. elsif not tagline
  525. inline line
  526. glyphs_deep line
  527. end
  528. line
  529. end
  530. end
  531. end
  532. def glyphs( text )
  533. text.gsub!( /"\z/, "\" " )
  534. ## if no html, do a simple search and replace...
  535. if text !~ /<.*>/
  536. inline text
  537. end
  538. glyphs_deep text
  539. end
  540. def i_align( text )
  541. I_ALGN_VALS[text]
  542. end
  543. def h_align( text )
  544. H_ALGN_VALS[text]
  545. end
  546. def v_align( text )
  547. V_ALGN_VALS[text]
  548. end
  549. def encode_high( text )
  550. ## mb_encode_numericentity($text, $cmap, $charset);
  551. end
  552. def decode_high( text )
  553. ## mb_decode_numericentity($text, $cmap, $charset);
  554. end
  555. def textile_popup_help( name, helpvar, windowW, windowH )
  556. ' <a target="_blank" href="http://www.textpattern.com/help/?item=' + helpvar + '" onclick="window.open(this.href, \'popupwindow\', \'width=' + windowW + ',height=' + windowH + ',scrollbars,resizable\'); return false;">' + name + '</a><br />'
  557. end
  558. CMAP = [
  559. 160, 255, 0, 0xffff,
  560. 402, 402, 0, 0xffff,
  561. 913, 929, 0, 0xffff,
  562. 931, 937, 0, 0xffff,
  563. 945, 969, 0, 0xffff,
  564. 977, 978, 0, 0xffff,
  565. 982, 982, 0, 0xffff,
  566. 8226, 8226, 0, 0xffff,
  567. 8230, 8230, 0, 0xffff,
  568. 8242, 8243, 0, 0xffff,
  569. 8254, 8254, 0, 0xffff,
  570. 8260, 8260, 0, 0xffff,
  571. 8465, 8465, 0, 0xffff,
  572. 8472, 8472, 0, 0xffff,
  573. 8476, 8476, 0, 0xffff,
  574. 8482, 8482, 0, 0xffff,
  575. 8501, 8501, 0, 0xffff,
  576. 8592, 8596, 0, 0xffff,
  577. 8629, 8629, 0, 0xffff,
  578. 8656, 8660, 0, 0xffff,
  579. 8704, 8704, 0, 0xffff,
  580. 8706, 8707, 0, 0xffff,
  581. 8709, 8709, 0, 0xffff,
  582. 8711, 8713, 0, 0xffff,
  583. 8715, 8715, 0, 0xffff,
  584. 8719, 8719, 0, 0xffff,
  585. 8721, 8722, 0, 0xffff,
  586. 8727, 8727, 0, 0xffff,
  587. 8730, 8730, 0, 0xffff,
  588. 8733, 8734, 0, 0xffff,
  589. 8736, 8736, 0, 0xffff,
  590. 8743, 8747, 0, 0xffff,
  591. 8756, 8756, 0, 0xffff,
  592. 8764, 8764, 0, 0xffff,
  593. 8773, 8773, 0, 0xffff,
  594. 8776, 8776, 0, 0xffff,
  595. 8800, 8801, 0, 0xffff,
  596. 8804, 8805, 0, 0xffff,
  597. 8834, 8836, 0, 0xffff,
  598. 8838, 8839, 0, 0xffff,
  599. 8853, 8853, 0, 0xffff,
  600. 8855, 8855, 0, 0xffff,
  601. 8869, 8869, 0, 0xffff,
  602. 8901, 8901, 0, 0xffff,
  603. 8968, 8971, 0, 0xffff,
  604. 9001, 9002, 0, 0xffff,
  605. 9674, 9674, 0, 0xffff,
  606. 9824, 9824, 0, 0xffff,
  607. 9827, 9827, 0, 0xffff,
  608. 9829, 9830, 0, 0xffff,
  609. 338, 339, 0, 0xffff,
  610. 352, 353, 0, 0xffff,
  611. 376, 376, 0, 0xffff,
  612. 710, 710, 0, 0xffff,
  613. 732, 732, 0, 0xffff,
  614. 8194, 8195, 0, 0xffff,
  615. 8201, 8201, 0, 0xffff,
  616. 8204, 8207, 0, 0xffff,
  617. 8211, 8212, 0, 0xffff,
  618. 8216, 8218, 0, 0xffff,
  619. 8218, 8218, 0, 0xffff,
  620. 8220, 8222, 0, 0xffff,
  621. 8224, 8225, 0, 0xffff,
  622. 8240, 8240, 0, 0xffff,
  623. 8249, 8250, 0, 0xffff,
  624. 8364, 8364, 0, 0xffff
  625. ]
  626. end