maruku 0.2.10 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. data/bin/marutex +2 -2
  2. data/docs/maruku.md +25 -15
  3. data/lib/maruku.rb +6 -2
  4. data/lib/maruku/parse_block.rb +5 -87
  5. data/lib/maruku/parse_doc.rb +102 -0
  6. data/lib/maruku/parse_span.rb +9 -0
  7. data/lib/maruku/string_utils.rb +13 -12
  8. data/lib/maruku/to_html.rb +4 -1
  9. data/lib/maruku/to_latex.rb +1 -1
  10. data/lib/maruku/to_latex_entities.rb +301 -0
  11. data/lib/maruku/to_latex_strings.rb +37 -319
  12. data/lib/maruku/version.rb +1 -1
  13. data/tests/{abbreviations.md → others/abbreviations.md} +0 -0
  14. data/tests/{blank.md → others/blank.md} +0 -0
  15. data/tests/{code.md → others/code.md} +0 -0
  16. data/tests/{code2.md → others/code2.md} +0 -0
  17. data/tests/{code3.md → others/code3.md} +0 -0
  18. data/tests/{email.md → others/email.md} +0 -0
  19. data/tests/{entities.md → others/entities.md} +0 -0
  20. data/tests/{escaping.md → others/escaping.md} +0 -0
  21. data/tests/{extra_dl.md → others/extra_dl.md} +0 -0
  22. data/tests/{extra_header_id.md → others/extra_header_id.md} +0 -0
  23. data/tests/{extra_table1.md → others/extra_table1.md} +0 -0
  24. data/tests/{footnotes.md → others/footnotes.md} +0 -0
  25. data/tests/{headers.md → others/headers.md} +0 -0
  26. data/tests/{hrule.md → others/hrule.md} +0 -0
  27. data/tests/{images.md → others/images.md} +0 -0
  28. data/tests/{inline_html.md → others/inline_html.md} +0 -0
  29. data/tests/{links.md → others/links.md} +0 -0
  30. data/tests/{list1.md → others/list1.md} +0 -0
  31. data/tests/{list2.md → others/list2.md} +0 -0
  32. data/tests/{list3.md → others/list3.md} +0 -0
  33. data/tests/{lists.md → others/lists.md} +0 -0
  34. data/tests/{lists_ol.md → others/lists_ol.md} +1 -1
  35. data/tests/{misc_sw.md → others/misc_sw.md} +0 -0
  36. data/tests/{one.md → others/one.md} +0 -0
  37. data/tests/{paragraphs.md → others/paragraphs.md} +0 -0
  38. data/tests/{sss06.md → others/sss06.md} +0 -0
  39. data/tests/{test.md → others/test.md} +0 -0
  40. metadata +30 -28
@@ -23,8 +23,8 @@ if File.basename($0) =~ /^marutex/
23
23
  File.open(filename,'w') do |f| f.puts latex end
24
24
 
25
25
  # run twice for cross references
26
- system "pdflatex '#{job}'"
27
- system "pdflatex '#{job}'"
26
+ system "pdflatex '#{job}' '-output-directory=#{dir}' "
27
+ system "pdflatex '#{job}' '-output-directory=#{dir}' "
28
28
 
29
29
  # system "open #{job}.pdf"
30
30
  end
@@ -197,7 +197,8 @@ to transform to HTML.
197
197
  [^1]: "a different philosophy" stands for "ugly" `:-)`
198
198
 
199
199
  The in-memory representation makes it very easy to export
200
- to various formats (altough, for, now)
200
+ to various formats (at the moment HTML and LaTeX/PDF;
201
+ the next is pretty-printed Markdown).
201
202
 
202
203
  Other improvements over Bluecloth:
203
204
 
@@ -420,23 +421,39 @@ produces:
420
421
 
421
422
  * * *
422
423
 
423
- Other Features
424
+ @ #features
425
+ Other Features
424
426
  --------------
425
427
 
426
428
  ### Automatic generation of the table of contents ###
427
429
 
428
- If you create a list, and the set the `toc` attribute, when rendering
430
+ If you create a list, and then set the `toc` attribute, when rendering
429
431
  Maruku will create an auto-generated table of contents.
430
432
 
431
433
  @ toc
432
- * This will become a table of contents
434
+ * This will become a table of contents (this text will be scraped).
433
435
 
434
436
  You can see an example of this at the beginning of this document.
435
437
 
436
438
  ### This header contains *emphasis* **strong text** and `code` ####
437
439
 
438
- Note that this header contains formatting and it still works, also
439
- in the table of contents.
440
+ Note that this header contains formatting and it still works, also in the table of contents.
441
+
442
+ And [This is a *link* with **all** ***sort*** of `weird stuff`](#features) in the text.
443
+
444
+ ### Use HTML entities ###
445
+
446
+ If you want to use HTML entities, go on! We will take care
447
+ of the translation to LaTeX:
448
+
449
+ Entity | Result
450
+ ------------|----------
451
+ `©` | ©
452
+ `£` | £
453
+ `a b` | a b
454
+ `λ` | λ
455
+ `—` | —
456
+
440
457
 
441
458
  TODO list
442
459
  --------------------------
@@ -473,8 +490,8 @@ I would love to have an equivalent in Ruby.
473
490
 
474
491
  Maybe something like this:
475
492
 
476
- This is a paragraph. The second line of this paragraph has
477
- the last element {with meta data}@ class: important_span
493
+ This is a paragraph. Really, a normal paragraph. The second
494
+ line of this paragraph has the last element {with meta data}@ class: important_span
478
495
  and the paragraph continues...
479
496
 
480
497
  So the idea is:
@@ -486,13 +503,6 @@ So the idea is:
486
503
  3. Closing brace and at-symbol `}@`.
487
504
  4. Attributes specification like the block-level metadata.
488
505
 
489
- Other examples:
490
-
491
- Lorem ipsum dolor sit amet, consectetuer adipiscing
492
- elit. Donec sit amet sapien vitae augue {interdum hendrerit.}@ id: special
493
- Maecenas tempor ultrices nisl. Praesent laoreet tortor sit
494
- amet est. Praesent in nisl eu libero sodales bibendum.
495
-
496
506
  Or, we could allow metadata specified **after the text**.
497
507
  In the following, three fragments are marked as "special",
498
508
  and, after their containing block-level elements, their
@@ -19,10 +19,13 @@
19
19
  # Structures definition
20
20
  require 'maruku/structures'
21
21
 
22
- # Code for parsing block-level elements
22
+ # Code for parsing whole Markdown documents
23
+ require 'maruku/parse_doc'
24
+
25
+ # Code for parsing Markdown block-level elements
23
26
  require 'maruku/parse_block'
24
27
 
25
- # Code for parsing span-level elements
28
+ # Code for parsing Markdown span-level elements
26
29
  require 'maruku/parse_span'
27
30
 
28
31
  # Ugly things kept in a closet
@@ -41,6 +44,7 @@ require 'maruku/to_html'
41
44
  # Exporting to latex
42
45
  require 'maruku/to_latex'
43
46
  require 'maruku/to_latex_strings'
47
+ require 'maruku/to_latex_entities'
44
48
 
45
49
  # Exporting to text: strips all formatting (not complete)
46
50
  require 'maruku/to_s'
@@ -17,89 +17,6 @@
17
17
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
18
 
19
19
  class Maruku
20
- def initialize(s=nil)
21
- @node_type = :document
22
- @doc = self
23
-
24
- @refs = {}
25
- @footnotes = {}
26
- @abbreviations = {}
27
-
28
- parse_doc(s) if s
29
- end
30
-
31
- def parse_doc(s)
32
- # setup initial stack
33
- @stack = []
34
-
35
- @meta = parse_email_headers(s)
36
- lines = split_lines(@meta[:data])
37
- @children = parse_lines_as_markdown(lines)
38
-
39
- self.search_abbreviations
40
- self.substitute_markdown_inside_raw_html
41
-
42
- toc = create_toc
43
-
44
- # use title if not set
45
- if not self.meta[:title] and toc.header_element
46
- title = toc.header_element.to_s
47
- self.meta[:title] = title
48
- puts "Set document title to #{title}"
49
- end
50
-
51
- # save for later use
52
- self.toc = toc
53
-
54
- #puts toc.inspect
55
- end
56
-
57
- def search_abbreviations
58
- @abbreviations.each do |abbrev, title|
59
- # puts "#{abbrev} => #{title}"
60
- self.map_match(Regexp.new(Regexp.escape(abbrev))) {
61
- e = create_md_element(:abbreviation)
62
- e.children = [abbrev.dup]
63
- e.meta[:title] = title.dup if title
64
- e
65
- }
66
- end
67
- end
68
-
69
- # (PHP Markdown extra) Search for elements that have
70
- # markdown=1 or markdown=block defined
71
- def substitute_markdown_inside_raw_html
72
- self.each_element(:raw_html) do |e|
73
- doc = e.meta[:parsed_html]
74
- if doc # valid html
75
- # parse block-level markdown elements in these HTML tags
76
- block_tags = ['div']
77
- # use xpath to find elements with 'markdown' attribute
78
- doc.elements.to_a( "//*[attribute::markdown]" ).each do |e|
79
- # should we parse block-level or span-level?
80
- parse_blocks = (e.attributes['markdown'] == 'block') ||
81
- block_tags.include?(e.name)
82
- # remove 'markdown' attribute
83
- e.delete_attribute 'markdown'
84
- # Select all text elements of e
85
- e.texts.each do |original_text|
86
- # puts "parse_blocks = #{parse_blocks} found = #{original_text} "
87
- s = original_text.to_s.strip # XXX
88
- el = create_md_element(:dummy,
89
- parse_blocks ? parse_text_as_markdown(s) :
90
- parse_lines_as_span(s) )
91
- el.children_to_html.each do |x|
92
- e.insert_before(original_text, x)
93
- end
94
- e.delete(original_text)
95
- end
96
-
97
- end
98
- end
99
- end
100
- end
101
-
102
-
103
20
  # Splits the string and calls parse_lines_as_markdown
104
21
  def parse_text_as_markdown(text)
105
22
  lines = split_lines(text)
@@ -317,7 +234,7 @@ class Maruku
317
234
  read_indented_content(indentation, break_list, item_type)
318
235
 
319
236
  # add first line
320
- # Strip first '*' or '-' from first line
237
+ # Strip first '*', '-', '+' from first line
321
238
  stripped = first[indentation, first.size-1]
322
239
  lines.unshift stripped
323
240
 
@@ -507,6 +424,7 @@ class Maruku
507
424
  stuff.split.each do |couple|
508
425
  # puts "found #{couple}"
509
426
  k, v = couple.split('=')
427
+ v ||= ""
510
428
  if v[0,1]=='"' then v = v[1, v.size-2] end
511
429
  # puts "key:_#{k}_ value=_#{v}_"
512
430
  hash[k.to_sym] = v
@@ -595,15 +513,15 @@ class Maruku
595
513
 
596
514
  want_paragraph = false
597
515
 
598
- raise "Bug!Bug" if not cur_line
599
-
516
+ raise "Chunky Bacon!" if not cur_line
517
+
600
518
  # one optional empty
601
519
  if cur_line_node_type == :empty
602
520
  want_my_paragraph = true
603
521
  shift_line
604
522
  end
605
523
 
606
- raise "Bug!Bug" if cur_line_node_type != :definition
524
+ raise "Chunky Bacon!" if cur_line_node_type != :definition
607
525
 
608
526
  # Read one or more definitions
609
527
  definitions = []
@@ -0,0 +1,102 @@
1
+ # Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
2
+ #
3
+ # This file is part of Maruku.
4
+ #
5
+ # Maruku is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Maruku is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Maruku; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
+
19
+ class Maruku
20
+ def initialize(s=nil)
21
+ @node_type = :document
22
+ @doc = self
23
+
24
+ @refs = {}
25
+ @footnotes = {}
26
+ @abbreviations = {}
27
+
28
+ parse_doc(s) if s
29
+ end
30
+
31
+ def parse_doc(s)
32
+ # setup initial stack
33
+ @stack = []
34
+
35
+ @meta = parse_email_headers(s)
36
+ lines = split_lines(@meta[:data])
37
+ @children = parse_lines_as_markdown(lines)
38
+
39
+ self.search_abbreviations
40
+ self.substitute_markdown_inside_raw_html
41
+
42
+ toc = create_toc
43
+
44
+ # use title if not set
45
+ if not self.meta[:title] and toc.header_element
46
+ title = toc.header_element.to_s
47
+ self.meta[:title] = title
48
+ puts "Set document title to #{title}"
49
+ end
50
+
51
+ # save for later use
52
+ self.toc = toc
53
+
54
+ #puts toc.inspect
55
+ end
56
+
57
+ def search_abbreviations
58
+ @abbreviations.each do |abbrev, title|
59
+ # puts "#{abbrev} => #{title}"
60
+ self.map_match(Regexp.new(Regexp.escape(abbrev))) {
61
+ e = create_md_element(:abbreviation)
62
+ e.children = [abbrev.dup]
63
+ e.meta[:title] = title.dup if title
64
+ e
65
+ }
66
+ end
67
+ end
68
+
69
+ # (PHP Markdown extra) Search for elements that have
70
+ # markdown=1 or markdown=block defined
71
+ def substitute_markdown_inside_raw_html
72
+ self.each_element(:raw_html) do |e|
73
+ doc = e.meta[:parsed_html]
74
+ if doc # valid html
75
+ # parse block-level markdown elements in these HTML tags
76
+ block_tags = ['div']
77
+ # use xpath to find elements with 'markdown' attribute
78
+ doc.elements.to_a( "//*[attribute::markdown]" ).each do |e|
79
+ # should we parse block-level or span-level?
80
+ parse_blocks = (e.attributes['markdown'] == 'block') ||
81
+ block_tags.include?(e.name)
82
+ # remove 'markdown' attribute
83
+ e.delete_attribute 'markdown'
84
+ # Select all text elements of e
85
+ e.texts.each do |original_text|
86
+ # puts "parse_blocks = #{parse_blocks} found = #{original_text} "
87
+ s = original_text.to_s.strip # XXX
88
+ el = create_md_element(:dummy,
89
+ parse_blocks ? parse_text_as_markdown(s) :
90
+ parse_lines_as_span(s) )
91
+ el.children_to_html.each do |x|
92
+ e.insert_before(original_text, x)
93
+ end
94
+ e.delete(original_text)
95
+ end
96
+
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ end
@@ -267,6 +267,15 @@ class Maruku
267
267
  e.meta[:email] = email
268
268
  e
269
269
  }
270
+
271
+ # Detect HTML entitis
272
+ span.map_match(/&([\w\d]+);/) { |match|
273
+ entity_name = match[1]
274
+
275
+ e = create_md_element(:entity, [])
276
+ e.meta[:entity_name] = entity_name
277
+ e
278
+ }
270
279
 
271
280
 
272
281
  # And now the easy stuff
@@ -102,17 +102,12 @@ class Maruku
102
102
  case line_node_type(s)
103
103
  when :ulist
104
104
  i=0;
105
- # skip whitespace
105
+ # skip whitespace if present
106
106
  while s[i,1] =~ /\s/; i+=1 end
107
- # skip indicator
107
+ # skip indicator (+, -, *)
108
108
  i+=1
109
- # skip whitespace
109
+ # skip optional whitespace
110
110
  while s[i,1] =~ /\s/; i+=1 end
111
- #
112
- # while i < s.size
113
- # break if not [' ',"\t",'*','-'].include? s[i,1]
114
- # i += 1
115
- # end
116
111
  return i
117
112
  when :olist
118
113
  i=0;
@@ -125,6 +120,9 @@ class Maruku
125
120
  # skip whitespace
126
121
  while s[i,1] =~ /\s/; i+=1 end
127
122
  return i
123
+ else
124
+ $stderr.puts "Error: #{s} is not a list"
125
+ 0
128
126
  end
129
127
  end
130
128
 
@@ -193,8 +191,8 @@ class Maruku
193
191
  # line that were mistaken for raw_html
194
192
  return :text if l=~EMailAddress or l=~ URL
195
193
  return :raw_html if l =~ %r{^[ ]?[ ]?[ ]?</?\s*\w+}
196
- return :ulist if l =~ /^\s?([\*-\+])\s+.*\w+/
197
- return :olist if l =~ /^\s?\d\..*\w+/
194
+ return :ulist if l =~ /^\s?([\*\-\+])\s+.*\w+/
195
+ return :olist if l =~ /^\s?\d+\..*\w+/
198
196
  return :empty if l.strip.size == 0
199
197
  return :header1 if l =~ /^(=)+/
200
198
  return :header2 if l =~ /^([-\s])+$/
@@ -298,8 +296,10 @@ class String
298
296
 
299
297
  # But if you surround an * or _ with spaces,
300
298
  # it’ll be treated as a literal asterisk or underscore.
301
- gsub!(/\s\*(\s|$)/, [S+2].pack('c'))
302
- gsub!(/\s_(\s|$)/, [S+2].pack('c'))
299
+ escaped_ast = [S+2].pack('c')
300
+ gsub!(/(\s)\*(\s|$)/, '\1%s\2' % [escaped_ast] )
301
+ escaped_under = [S+3].pack('c')
302
+ gsub!(/(\s)_(\s|$)/, '\1%s\2' % [escaped_under])
303
303
 
304
304
  self
305
305
  end
@@ -315,6 +315,7 @@ class String
315
315
  self
316
316
  end
317
317
 
318
+ # Resubstitute '\<char>' as this was a code block
318
319
  def it_was_a_code_block
319
320
  s = ""; tmp =" "
320
321
  each_byte do |b|
@@ -504,7 +504,10 @@ class MDElement
504
504
  def to_html_head_cell; wrap_as_element('th') end
505
505
  def to_html_cell; wrap_as_element('td') end
506
506
 
507
-
507
+ def to_html_entity
508
+ entity_name = @meta[:entity_name]
509
+ Text.new('&%s;' % [entity_name])
510
+ end
508
511
  end
509
512
 
510
513
  # We only want to output the children in Maruku::to_html
@@ -90,7 +90,7 @@ class MDElement
90
90
  g = g / 255.0
91
91
  b = b / 255.0
92
92
 
93
- "\\#{command}[rgb]{#{r},#{g},#{b}}"
93
+ "\\#{command}[rgb]{%0.2f,%0.2f,%0.2f}" % [r,g,b]
94
94
  else
95
95
  "\\#{command}{#{s}}"
96
96
  end
@@ -0,0 +1,301 @@
1
+ require 'rexml/document'
2
+
3
+ class MDElement
4
+ include REXML
5
+
6
+ def to_latex_entity
7
+ entity_name = @meta[:entity_name]
8
+
9
+ MDElement.init_tables
10
+
11
+ replace = @@entity_to_latex[entity_name]
12
+ if replace
13
+ # puts "#{entity_name} -> #{replace.inspect}"
14
+ return replace
15
+ else
16
+ $stderr.puts "Cannot translate #{entity_name}"
17
+ return entity_name
18
+ end
19
+ end
20
+
21
+
22
+ # create hash @@entity_to_latex
23
+ def MDElement.init_tables
24
+ ## why can't I use a class variable?
25
+ if not $conversion_table_inited
26
+ doc = Document.new XML_TABLE
27
+ @@entity_to_latex = {}
28
+ doc.elements.each("//char") do |c|
29
+ num = c.attributes['num']
30
+ name = c.attributes['name']
31
+ convert = c.attributes['convertTo']
32
+ @@entity_to_latex["#{num}"] = convert
33
+ @@entity_to_latex["#{name}"] = convert
34
+ end
35
+ # puts @@entity_to_latex.inspect
36
+ $conversion_table_inited = true
37
+ end
38
+ end
39
+
40
+ # The following is a conversion chart for html elements, courtesy of
41
+ # text2html
42
+
43
+ XML_TABLE ="
44
+ <chars>
45
+ <char num='913' name='Alpha' convertTo='$A$' />
46
+ <char num='914' name='Beta' convertTo='$B$' />
47
+ <char num='915' name='Gamma' convertTo='$\\Gamma$' />
48
+ <char num='916' name='Delta' convertTo='$\\Delta$' />
49
+ <char num='917' name='Epsilon' convertTo='$E$' />
50
+ <char num='918' name='Zeta' convertTo='$Z$' />
51
+ <char num='919' name='Eta' convertTo='$H$' />
52
+ <char num='920' name='Theta' convertTo='$\\Theta$' />
53
+ <char num='921' name='Iota' convertTo='$I$' />
54
+ <char num='922' name='Kappa' convertTo='$K$' />
55
+ <char num='923' name='Lambda' convertTo='$\\Lambda$' />
56
+ <char num='924' name='Mu' convertTo='$M$' />
57
+ <char num='925' name='Nu' convertTo='$N$' />
58
+ <char num='926' name='Xi' convertTo='$\\Xi$' />
59
+ <char num='927' name='Omicron' convertTo='$O$' />
60
+ <char num='928' name='Pi' convertTo='$\\Pi$' />
61
+ <char num='929' name='Rho' convertTo='$P$' />
62
+ <char num='931' name='Sigma' convertTo='$\\Sigma$' />
63
+ <char num='932' name='Tau' convertTo='$T$' />
64
+ <char num='933' name='Upsilon' convertTo='$Y$' />
65
+ <char num='934' name='Phi' convertTo='$\\Phi$' />
66
+ <char num='935' name='Chi' convertTo='$X$' />
67
+ <char num='936' name='Psi' convertTo='$\\Psi$' />
68
+ <char num='937' name='Omega' convertTo='$\\Omega$' />
69
+ <char num='945' name='alpha' convertTo='$\\alpha$' />
70
+ <char num='946' name='beta' convertTo='$\\beta$' />
71
+ <char num='947' name='gamma' convertTo='$\\gamma$' />
72
+ <char num='948' name='delta' convertTo='$\\delta$' />
73
+ <char num='949' name='epsilon' convertTo='$\\epsilon$' />
74
+ <char num='950' name='zeta' convertTo='$\\zeta$' />
75
+ <char num='951' name='eta' convertTo='$\\eta$' />
76
+ <char num='952' name='theta' convertTo='$\\theta$' />
77
+ <char num='953' name='iota' convertTo='$\\iota$' />
78
+ <char num='954' name='kappa' convertTo='$\\kappa$' />
79
+ <char num='955' name='lambda' convertTo='$\\lambda$' />
80
+ <char num='956' name='mu' convertTo='$\\mu$' />
81
+
82
+ <char num='957' name='nu' convertTo='$\\nu$' />
83
+ <char num='958' name='xi' convertTo='$\\xi$' />
84
+ <char num='959' name='omicron' convertTo='$o$' />
85
+ <char num='960' name='pi' convertTo='$\\pi$' />
86
+ <char num='961' name='rho' convertTo='$\\rho$' />
87
+ <char num='963' name='sigma' convertTo='$\\sigma$' />
88
+ <char num='964' name='tau' convertTo='$\\tau$' />
89
+ <char num='965' name='upsilon' convertTo='$\\upsilon$' />
90
+ <char num='966' name='phi' convertTo='$\\phi$' />
91
+
92
+ <char num='967' name='chi' convertTo='$\\chi$' />
93
+ <char num='968' name='psi' convertTo='$\\psi$' />
94
+ <char num='969' name='omega' convertTo='$\\omega$' />
95
+ <char num='962' name='sigmaf' convertTo='$\\varsigma$' />
96
+ <char num='977' name='thetasym' convertTo='$\\vartheta$' />
97
+ <char num='982' name='piv' convertTo='$\\varpi$' />
98
+ <char num='8230' name='hellip' convertTo='\\ldots' />
99
+ <char num='8242' name='prime' convertTo='$\\prime$' />
100
+ <char num='8254' name='oline' convertTo='-' />
101
+
102
+ <char num='8260' name='frasl' convertTo='/' />
103
+ <char num='8472' name='weierp' convertTo='$\\wp$' />
104
+ <char num='8465' name='image' convertTo='$\\Im$' />
105
+ <char num='8476' name='real' convertTo='$\\Re$' />
106
+ <char num='8501' name='alefsym' convertTo='$\\aleph$' />
107
+ <char num='8226' name='bull' convertTo='$\\bullet$' />
108
+ <char num='8482' name='trade' convertTo='$^{\\rm TM}$' /> <!-- \texttrademark -->
109
+ <char num='8592' name='larr' convertTo='$\\leftarrow$' />
110
+
111
+ <char num='8594' name='rarr' convertTo='$\\rightarrow$' />
112
+ <char num='8593' name='uarr' convertTo='$\\uparrow$' />
113
+ <char num='8595' name='darr' convertTo='$\\downarrow$' />
114
+ <char num='8596' name='harr' convertTo='$\\leftrightarrow$' />
115
+ <char num='8629' name='crarr' convertTo='$\\hookleftarrow$' />
116
+ <char num='8657' name='uArr' convertTo='$\\Uparrow$' />
117
+ <char num='8659' name='dArr' convertTo='$\\Downarrow$' />
118
+ <char num='8656' name='lArr' convertTo='$\\Leftarrow$' />
119
+ <char num='8658' name='rArr' convertTo='$\\Rightarrow$' />
120
+
121
+ <char num='8660' name='hArr' convertTo='$\\Leftrightarrow$' />
122
+ <char num='8704' name='forall' convertTo='$\\forall$' />
123
+ <char num='8706' name='part' convertTo='$\\partial$' />
124
+ <char num='8707' name='exist' convertTo='$\\exists$' />
125
+ <char num='8709' name='empty' convertTo='$\\emptyset$' />
126
+ <char num='8711' name='nabla' convertTo='$\\nabla$' />
127
+ <char num='8712' name='isin' convertTo='$\\in$' />
128
+ <char num='8715' name='ni' convertTo='$\\ni$' />
129
+ <char num='8713' name='notin' convertTo='$\\notin$' />
130
+
131
+ <char num='8721' name='sum' convertTo='$\\sum$' />
132
+ <char num='8719' name='prod' convertTo='$\\prod$' />
133
+ <char num='8722' name='minus' convertTo='$-$' />
134
+ <char num='8727' name='lowast' convertTo='$\\ast$' />
135
+ <char num='8730' name='radic' convertTo='$\\surd$' />
136
+ <char num='8733' name='prop' convertTo='$\\propto$' />
137
+ <char num='8734' name='infin' convertTo='$\\infty$' />
138
+ <char num='8736' name='ang' convertTo='$\\angle$' />
139
+ <char num='8743' name='and' convertTo='$\\wedge$' />
140
+
141
+ <char num='8744' name='or' convertTo='$\\vee$' />
142
+ <char num='8745' name='cup' convertTo='$\\cup$' />
143
+ <char num='8746' name='cap' convertTo='$\\cap$' />
144
+ <char num='8747' name='int' convertTo='$\\int$' />
145
+ <char num='8756' name='there4' convertTo='$\\therefore$' /> <!-- only AMS -->
146
+ <char num='8764' name='sim' convertTo='$\\sim$' />
147
+ <char num='8776' name='asymp' convertTo='$\\approx$' />
148
+ <char num='8773' name='cong' convertTo='$\\cong$' />
149
+
150
+ <char num='8800' name='ne' convertTo='$\\neq$' />
151
+ <char num='8801' name='equiv' convertTo='$\\equiv$' />
152
+ <char num='8804' name='le' convertTo='$\\leq$' />
153
+ <char num='8805' name='ge' convertTo='$\\geq$' />
154
+ <char num='8834' name='sub' convertTo='$\\subset$' />
155
+ <char num='8835' name='sup' convertTo='$\\supset$' />
156
+ <char num='8838' name='sube' convertTo='$\\subseteq$' />
157
+ <char num='8839' name='supe' convertTo='$\\supseteq$' />
158
+ <char num='8836' name='nsub' convertTo='$\\nsubset$' /> <!-- only AMS -->
159
+
160
+ <char num='8853' name='oplus' convertTo='$\\oplus$' />
161
+ <char num='8855' name='otimes' convertTo='$\\otimes$' />
162
+ <char num='8869' name='perp' convertTo='$\\perp$' />
163
+ <char num='8901' name='sdot' convertTo='$\\cdot$' />
164
+ <char num='8968' name='rceil' convertTo='$\\rceil$' />
165
+ <char num='8969' name='lceil' convertTo='$\\lceil$' />
166
+ <char num='8970' name='lfloor' convertTo='$\\lfloor$' />
167
+ <char num='8971' name='rfloor' convertTo='$\\rfloor$' />
168
+ <char num='9001' name='rang' convertTo='$\\rangle$' />
169
+
170
+ <char num='9002' name='lang' convertTo='$\\langle$' />
171
+ <char num='9674' name='loz' convertTo='$\\lozenge$' /> <!-- only AMS -->
172
+ <char num='9824' name='spades' convertTo='$\\spadesuit$' />
173
+ <char num='9827' name='clubs' convertTo='$\\clubsuit$' />
174
+ <char num='9829' name='hearts' convertTo='$\\heartsuit$' />
175
+ <char num='9830' name='diams' convertTo='$\\diamondsuit$' />
176
+ <char num='38' name='amp' convertTo='\\@AMP' />
177
+ <char num='34' name='quot' convertTo='@DOUBLEQUOT' />
178
+ <char num='169' name='copy' convertTo='\\copyright' />
179
+
180
+ <char num='60' name='lt' convertTo='$@LT$' />
181
+ <char num='62' name='gt' convertTo='$@GT$' />
182
+ <char num='338' name='OElig' convertTo='\\OE' />
183
+ <char num='339' name='oelig' convertTo='\\oe' />
184
+ <char num='352' name='Scaron' convertTo='\\v{S}' />
185
+ <char num='353' name='scaron' convertTo='\\v{s}' />
186
+ <char num='376' name='Yuml' convertTo='\\\"Y' />
187
+ <char num='710' name='circ' convertTo='\\textasciicircum' />
188
+ <char num='732' name='tilde' convertTo='\\textasciitilde' />
189
+
190
+ <char num='8211' name='ndash' convertTo='--' />
191
+ <char num='8212' name='mdash' convertTo='---' />
192
+ <char num='8216' name='lsquo' convertTo='`' />
193
+ <char num='8217' name='rsquo' convertTo='@QUOT' />
194
+ <char num='8220' name='ldquo' convertTo='``' />
195
+ <char num='8221' name='rdquo' convertTo='@QUOT@QUOT' />
196
+ <char num='8224' name='dagger' convertTo='\\dag' />
197
+ <char num='8225' name='Dagger' convertTo='\\ddag' />
198
+ <char num='8240' name='permil' convertTo='\\permil' /> <!-- wasysym package -->
199
+
200
+ <char num='8364' name='euro' convertTo='\\euro' /> <!-- eurosym package -->
201
+ <char num='8249' name='lsaquo' convertTo='\\guilsinglleft' />
202
+ <char num='8250' name='rsaquo' convertTo='\\guilsinglright' />
203
+ <!-- <char num='160' name='nbsp' convertTo='\\nolinebreak' />-->
204
+ <char num='160' name='nbsp' convertTo='~' />
205
+ <char num='161' name='iexcl' convertTo='\\textexclamdown' />
206
+ <char num='163' name='pound' convertTo='\\pounds' />
207
+ <char num='164' name='curren' convertTo='\\currency' /> <!-- wasysym package -->
208
+ <char num='165' name='yen' convertTo='\\textyen' /> <!-- textcomp -->
209
+
210
+ <char num='166' name='brvbar' convertTo='\\brokenvert' /> <!-- wasysym -->
211
+ <char num='167' name='sect' convertTo='\\S' />
212
+ <char num='171' name='laquo' convertTo='\\guillemotleft' />
213
+ <char num='187' name='raquo' convertTo='\\guillemotright' />
214
+ <char num='174' name='reg' convertTo='\\textregistered' />
215
+ <char num='170' name='ordf' convertTo='\\textordfeminine' />
216
+ <char num='172' name='not' convertTo='$\\neg$' />
217
+ <char num='176' name='deg' convertTo='$\\degree$' /> <!-- mathabx -->
218
+
219
+ <char num='177' name='plusmn' convertTo='$\\pm$' />
220
+ <char num='180' name='acute' convertTo='@QUOT' />
221
+ <char num='181' name='micro' convertTo='$\\mu$' />
222
+ <char num='182' name='para' convertTo='\\P' />
223
+ <char num='183' name='middot' convertTo='$\\cdot$' />
224
+ <char num='186' name='ordm' convertTo='\\textordmasculine' />
225
+ <char num='162' name='cent' convertTo='\\cent' /> <!-- wasysym -->
226
+ <char num='185' name='sup1' convertTo='$^1$' />
227
+
228
+ <char num='178' name='sup2' convertTo='$^2$' />
229
+ <char num='179' name='sup3' convertTo='$^3$' />
230
+ <char num='189' name='frac12' convertTo='$\\frac{1}{2}$' />
231
+ <char num='188' name='frac14' convertTo='$\\frac{1}{4}$' />
232
+ <char num='190' name='frac34' convertTo='$\\frac{3}{4}' />
233
+ <char num='192' name='Agrave' convertTo='\\`A' />
234
+ <char num='193' name='Aacute' convertTo='\\@QUOTA' />
235
+ <char num='194' name='Acirc' convertTo='\\^A' />
236
+ <char num='195' name='Atilde' convertTo='\\~A' />
237
+
238
+ <char num='196' name='Auml' convertTo='\\@DOUBLEQUOTA' />
239
+ <char num='197' name='Aring' convertTo='\\AA' />
240
+ <char num='198' name='AElig' convertTo='\\AE' />
241
+ <char num='199' name='Ccedil' convertTo='\\cC' />
242
+ <char num='200' name='Egrave' convertTo='\\`E' />
243
+ <char num='201' name='Eacute' convertTo='\\@QUOTE' />
244
+ <char num='202' name='Ecirc' convertTo='\\^E' />
245
+ <char num='203' name='Euml' convertTo='\\@DOUBLEQUOTE' />
246
+ <char num='204' name='Igrave' convertTo='\\`I' />
247
+ <char num='205' name='Iacute' convertTo='\\@QUOTI' />
248
+ <char num='206' name='Icirc' convertTo='\\^I' />
249
+ <char num='207' name='Iuml' convertTo='\\\"I' />
250
+ <char num='208' name='ETH' convertTo='$\\eth$' /> <!-- AMS -->
251
+ <char num='209' name='Ntilde' convertTo='\\~N' />
252
+ <char num='210' name='Ograve' convertTo='\\`O' />
253
+ <char num='211' name='Oacute' convertTo='\\@QUOTO' />
254
+ <char num='212' name='Ocirc' convertTo='\\^O' />
255
+ <char num='213' name='Otilde' convertTo='\\~O' />
256
+ <char num='214' name='Ouml' convertTo='\\@DOUBLEQUOTO' />
257
+ <char num='215' name='times' convertTo='$\\times$' />
258
+ <char num='216' name='Oslash' convertTo='\\O' />
259
+ <char num='217' name='Ugrave' convertTo='\\`U' />
260
+ <char num='218' name='Uacute' convertTo='\\@QUOTU' />
261
+ <char num='219' name='Ucirc' convertTo='\\^U' />
262
+ <char num='220' name='Uuml' convertTo='\\@DOUBLEQUOTU' />
263
+ <char num='221' name='Yacute' convertTo='\\@QUOTY' />
264
+ <char num='222' name='THORN' convertTo='\\Thorn' /> <!-- wasysym -->
265
+ <char num='223' name='szlig' convertTo='\\ss' />
266
+ <char num='224' name='agrave' convertTo='\\`a' />
267
+ <char num='225' name='aacute' convertTo='\\@QUOTa' />
268
+ <char num='226' name='acirc' convertTo='\\^a' />
269
+ <char num='227' name='atilde' convertTo='\\~a' />
270
+ <char num='228' name='auml' convertTo='\\@DOUBLEQUOTa' />
271
+ <char num='229' name='aring' convertTo='\\aa' />
272
+ <char num='230' name='aelig' convertTo='\\ae' />
273
+ <char num='231' name='ccedil' convertTo='\\cc' />
274
+ <char num='232' name='egrave' convertTo='\\`e' />
275
+ <char num='233' name='eacute' convertTo='\\@QUOTe' />
276
+ <char num='234' name='ecirc' convertTo='\\^e' />
277
+ <char num='235' name='euml' convertTo='\\@DOUBLEQUOTe' />
278
+ <char num='236' name='igrave' convertTo='\\`i' />
279
+ <char num='237' name='iacute' convertTo='\\@QUOTi' />
280
+ <char num='238' name='icirc' convertTo='\\^i' />
281
+ <char num='239' name='iuml' convertTo='\\@DOUBLEQUOTi' />
282
+ <char num='240' name='eth' convertTo='$\\eth$' /> <!-- -->
283
+ <char num='241' name='ntilde' convertTo='\\~n' />
284
+ <char num='242' name='ograve' convertTo='\\`o' />
285
+ <char num='243' name='oacute' convertTo='\\@QUOTo' />
286
+ <char num='244' name='ocirc' convertTo='\\^o' />
287
+ <char num='245' name='otilde' convertTo='\\~o' />
288
+ <char num='246' name='ouml' convertTo='\\@DOUBLEQUOTo' />
289
+ <char num='247' name='divide' convertTo='$\\divide$' />
290
+ <char num='248' name='oslash' convertTo='\\o' />
291
+ <char num='249' name='ugrave' convertTo='\\`u' />
292
+ <char num='250' name='uacute' convertTo='\\@QUOTu' />
293
+ <char num='251' name='ucirc' convertTo='\\^u' />
294
+ <char num='252' name='uuml' convertTo='\\@DOUBLEQUOTu' />
295
+ <char num='253' name='yacute' convertTo='\\@QUOTy' />
296
+ <char num='254' name='thorn' convertTo='\\thorn' /> <!-- wasysym -->
297
+ <char num='255' name='yuml' convertTo='\\@DOUBLEQUOTy' />
298
+ </chars>"
299
+
300
+ end
301
+