patcito-maruku 0.6.0

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 (162) hide show
  1. data/AUTHORS +23 -0
  2. data/LICENSE +340 -0
  3. data/README.md +73 -0
  4. data/bin/maruku +196 -0
  5. data/bin/marutex +4 -0
  6. data/data/entities.xml +261 -0
  7. data/docs/changelog.md +334 -0
  8. data/docs/div_syntax.md +36 -0
  9. data/docs/entity_test.md +23 -0
  10. data/docs/markdown_syntax.md +899 -0
  11. data/docs/maruku.md +346 -0
  12. data/docs/math.md +194 -0
  13. data/docs/other_stuff.md +51 -0
  14. data/docs/proposal.md +309 -0
  15. data/docs/website/src/bluecloth.md +25 -0
  16. data/docs/website/src/download.md +31 -0
  17. data/docs/website/src/maruku.md +261 -0
  18. data/docs/website/src/proposal.md +271 -0
  19. data/lib/maruku.rb +132 -0
  20. data/lib/maruku/attributes.rb +138 -0
  21. data/lib/maruku/defaults.rb +69 -0
  22. data/lib/maruku/errors.rb +89 -0
  23. data/lib/maruku/ext/div.rb +121 -0
  24. data/lib/maruku/ext/fenced_code.rb +78 -0
  25. data/lib/maruku/ext/math.rb +37 -0
  26. data/lib/maruku/ext/math/elements.rb +21 -0
  27. data/lib/maruku/ext/math/latex_fix.rb +12 -0
  28. data/lib/maruku/ext/math/mathml_engines/blahtex.rb +93 -0
  29. data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +39 -0
  30. data/lib/maruku/ext/math/mathml_engines/none.rb +21 -0
  31. data/lib/maruku/ext/math/mathml_engines/ritex.rb +24 -0
  32. data/lib/maruku/ext/math/parsing.rb +125 -0
  33. data/lib/maruku/ext/math/to_html.rb +237 -0
  34. data/lib/maruku/ext/math/to_latex.rb +36 -0
  35. data/lib/maruku/ext/yaml.rb +43 -0
  36. data/lib/maruku/helpers.rb +214 -0
  37. data/lib/maruku/input/charsource.rb +326 -0
  38. data/lib/maruku/input/extensions.rb +69 -0
  39. data/lib/maruku/input/html_helper.rb +189 -0
  40. data/lib/maruku/input/linesource.rb +111 -0
  41. data/lib/maruku/input/parse_block.rb +608 -0
  42. data/lib/maruku/input/parse_doc.rb +240 -0
  43. data/lib/maruku/input/parse_span_better.rb +746 -0
  44. data/lib/maruku/input/rubypants.rb +225 -0
  45. data/lib/maruku/input/type_detection.rb +147 -0
  46. data/lib/maruku/input_textile2/t2_parser.rb +163 -0
  47. data/lib/maruku/maruku.rb +31 -0
  48. data/lib/maruku/output/s5/fancy.rb +756 -0
  49. data/lib/maruku/output/s5/to_s5.rb +138 -0
  50. data/lib/maruku/output/to_html.rb +994 -0
  51. data/lib/maruku/output/to_latex.rb +580 -0
  52. data/lib/maruku/output/to_latex_entities.rb +101 -0
  53. data/lib/maruku/output/to_latex_strings.rb +64 -0
  54. data/lib/maruku/output/to_markdown.rb +164 -0
  55. data/lib/maruku/output/to_s.rb +54 -0
  56. data/lib/maruku/string_utils.rb +185 -0
  57. data/lib/maruku/structures.rb +143 -0
  58. data/lib/maruku/structures_inspect.rb +51 -0
  59. data/lib/maruku/structures_iterators.rb +48 -0
  60. data/lib/maruku/textile2.rb +1 -0
  61. data/lib/maruku/toc.rb +214 -0
  62. data/lib/maruku/usage/example1.rb +33 -0
  63. data/lib/maruku/version +0 -0
  64. data/lib/maruku/version.rb +54 -0
  65. data/spec/block_docs/abbreviations.md +52 -0
  66. data/spec/block_docs/alt.md +17 -0
  67. data/spec/block_docs/attributes/att2.md +20 -0
  68. data/spec/block_docs/attributes/att3.md +28 -0
  69. data/spec/block_docs/attributes/attributes.md +57 -0
  70. data/spec/block_docs/attributes/circular.md +26 -0
  71. data/spec/block_docs/attributes/default.md +22 -0
  72. data/spec/block_docs/blank.md +24 -0
  73. data/spec/block_docs/blanks_in_code.md +75 -0
  74. data/spec/block_docs/bug_def.md +16 -0
  75. data/spec/block_docs/bug_table.md +46 -0
  76. data/spec/block_docs/code.md +34 -0
  77. data/spec/block_docs/code2.md +28 -0
  78. data/spec/block_docs/code3.md +71 -0
  79. data/spec/block_docs/data_loss.md +25 -0
  80. data/spec/block_docs/divs/div1.md +167 -0
  81. data/spec/block_docs/divs/div2.md +21 -0
  82. data/spec/block_docs/divs/div3_nest.md +45 -0
  83. data/spec/block_docs/easy.md +15 -0
  84. data/spec/block_docs/email.md +20 -0
  85. data/spec/block_docs/encoding/iso-8859-1.md +23 -0
  86. data/spec/block_docs/encoding/utf-8.md +18 -0
  87. data/spec/block_docs/entities.md +94 -0
  88. data/spec/block_docs/escaping.md +67 -0
  89. data/spec/block_docs/extra_dl.md +52 -0
  90. data/spec/block_docs/extra_header_id.md +63 -0
  91. data/spec/block_docs/extra_table1.md +37 -0
  92. data/spec/block_docs/footnotes.md +97 -0
  93. data/spec/block_docs/headers.md +37 -0
  94. data/spec/block_docs/hex_entities.md +37 -0
  95. data/spec/block_docs/hrule.md +39 -0
  96. data/spec/block_docs/html2.md +22 -0
  97. data/spec/block_docs/html3.md +31 -0
  98. data/spec/block_docs/html4.md +25 -0
  99. data/spec/block_docs/html5.md +23 -0
  100. data/spec/block_docs/ie.md +49 -0
  101. data/spec/block_docs/images.md +90 -0
  102. data/spec/block_docs/images2.md +31 -0
  103. data/spec/block_docs/inline_html.md +152 -0
  104. data/spec/block_docs/inline_html2.md +21 -0
  105. data/spec/block_docs/links.md +152 -0
  106. data/spec/block_docs/links2.md +22 -0
  107. data/spec/block_docs/list1.md +46 -0
  108. data/spec/block_docs/list12.md +28 -0
  109. data/spec/block_docs/list2.md +56 -0
  110. data/spec/block_docs/list3.md +64 -0
  111. data/spec/block_docs/list4.md +89 -0
  112. data/spec/block_docs/lists.md +192 -0
  113. data/spec/block_docs/lists10.md +34 -0
  114. data/spec/block_docs/lists11.md +23 -0
  115. data/spec/block_docs/lists6.md +41 -0
  116. data/spec/block_docs/lists9.md +64 -0
  117. data/spec/block_docs/lists_after_paragraph.md +208 -0
  118. data/spec/block_docs/lists_ol.md +262 -0
  119. data/spec/block_docs/loss.md +16 -0
  120. data/spec/block_docs/math/equations.md +45 -0
  121. data/spec/block_docs/math/inline.md +46 -0
  122. data/spec/block_docs/math/math2.md +45 -0
  123. data/spec/block_docs/math/notmath.md +25 -0
  124. data/spec/block_docs/math/table.md +25 -0
  125. data/spec/block_docs/math/table2.md +42 -0
  126. data/spec/block_docs/misc_sw.md +525 -0
  127. data/spec/block_docs/notyet/escape.md +21 -0
  128. data/spec/block_docs/notyet/header_after_par.md +58 -0
  129. data/spec/block_docs/notyet/ticks.md +18 -0
  130. data/spec/block_docs/notyet/triggering.md +157 -0
  131. data/spec/block_docs/olist.md +45 -0
  132. data/spec/block_docs/one.md +15 -0
  133. data/spec/block_docs/paragraph.md +16 -0
  134. data/spec/block_docs/paragraph_rules/dont_merge_ref.md +42 -0
  135. data/spec/block_docs/paragraph_rules/tab_is_blank.md +24 -0
  136. data/spec/block_docs/paragraphs.md +46 -0
  137. data/spec/block_docs/pending/amps.md +15 -0
  138. data/spec/block_docs/pending/empty_cells.md +37 -0
  139. data/spec/block_docs/pending/link.md +72 -0
  140. data/spec/block_docs/pending/ref.md +21 -0
  141. data/spec/block_docs/recover/recover_links.md +15 -0
  142. data/spec/block_docs/red_tests/abbrev.md +679 -0
  143. data/spec/block_docs/red_tests/lists7.md +32 -0
  144. data/spec/block_docs/red_tests/lists7b.md +65 -0
  145. data/spec/block_docs/red_tests/lists8.md +42 -0
  146. data/spec/block_docs/red_tests/ref.md +23 -0
  147. data/spec/block_docs/red_tests/xml.md +35 -0
  148. data/spec/block_docs/references/long_example.md +71 -0
  149. data/spec/block_docs/references/spaces_and_numbers.md +15 -0
  150. data/spec/block_docs/smartypants.md +114 -0
  151. data/spec/block_docs/syntax_hl.md +52 -0
  152. data/spec/block_docs/table_attributes.md +34 -0
  153. data/spec/block_docs/test.md +19 -0
  154. data/spec/block_docs/underscore_in_words.md +15 -0
  155. data/spec/block_docs/wrapping.md +67 -0
  156. data/spec/block_docs/xml2.md +19 -0
  157. data/spec/block_docs/xml3.md +26 -0
  158. data/spec/block_docs/xml_instruction.md +52 -0
  159. data/spec/block_spec.rb +49 -0
  160. data/spec/span_spec.rb +254 -0
  161. data/spec/spec_helper.rb +6 -0
  162. metadata +247 -0
@@ -0,0 +1,138 @@
1
+ # This module groups all functions related to HTML export.
2
+ module MaRuKu
3
+
4
+ begin
5
+ require 'rexml/formatters/pretty'
6
+ require 'rexml/formatters/default'
7
+ $rexml_new_version = true
8
+ rescue LoadError
9
+ $rexml_new_version = false
10
+ end
11
+
12
+ class MDDocument
13
+
14
+ def s5_theme
15
+ html_escape(self.attributes[:slide_theme] || "default")
16
+ end
17
+
18
+ def html_escape(string)
19
+ string.gsub( /&/, "&" ).
20
+ gsub( /</, "&lt;" ).
21
+ gsub( />/, "&gt;" ).
22
+ gsub( /'/, "&#39;" ).
23
+ gsub( /"/, "&quot;" )
24
+ end
25
+
26
+ # Render as an HTML fragment (no head, just the content of BODY). (returns a string)
27
+ def to_s5(context={})
28
+ indent = context[:indent] || -1
29
+ ie_hack = !context[:ie_hack].kind_of?(FalseClass)
30
+ content_only = !context[:content_only].kind_of?(FalseClass)
31
+
32
+ doc = Document.new(nil,{:respect_whitespace =>:all})
33
+
34
+ if content_only
35
+ body = Element.new('div', doc)
36
+ else
37
+ html = Element.new('html', doc)
38
+ html.add_namespace('http://www.w3.org/1999/xhtml')
39
+ html.add_namespace('svg', "http://www.w3.org/2000/svg" )
40
+
41
+ head = Element.new('head', html)
42
+ me = Element.new 'meta', head
43
+ me.attributes['http-equiv'] = 'Content-type'
44
+ me.attributes['content'] = 'text/html;charset=utf-8'
45
+
46
+ # Create title element
47
+ doc_title = self.attributes[:title] || self.attributes[:subject] || ""
48
+ title = Element.new 'title', head
49
+ title << Text.new(doc_title)
50
+ body = Element.new('body', html)
51
+
52
+ end
53
+
54
+ slide_header = self.attributes[:slide_header]
55
+ slide_footer = self.attributes[:slide_footer]
56
+ slide_subfooter = self.attributes[:slide_subfooter]
57
+ slide_topleft = self.attributes[:slide_topleft]
58
+ slide_topright = self.attributes[:slide_topright]
59
+ slide_bottomleft = self.attributes[:slide_bottomleft]
60
+ slide_bottomright = self.attributes[:slide_bottomright]
61
+
62
+ dummy_layout_slide =
63
+ "
64
+ <div class='layout'>
65
+ <div id='controls'> </div>
66
+ <div id='currentSlide'> </div>
67
+ <div id='header'> #{slide_header}</div>
68
+ <div id='footer'>
69
+ <h1>#{slide_footer}</h1>
70
+ <h2>#{slide_subfooter}</h2>
71
+ </div>
72
+ <div class='topleft'> #{slide_topleft}</div>
73
+ <div class='topright'> #{slide_topright}</div>
74
+ <div class='bottomleft'> #{slide_bottomleft}</div>
75
+ <div class='bottomright'> #{slide_bottomright}</div>
76
+ </div>
77
+ "
78
+ body.add_element Document.new(dummy_layout_slide, {:respect_whitespace =>:all}).root
79
+
80
+ presentation = Element.new 'div', body
81
+ presentation.attributes['class'] = 'presentation'
82
+
83
+ first_slide="
84
+ <div class='slide'>
85
+ <h1> #{self.attributes[:title] ||context[:title]}</h1>
86
+ <h2> #{self.attributes[:subtitle] ||context[:subtitle]}</h2>
87
+ <h3> #{self.attributes[:author] ||context[:author]}</h3>
88
+ <h4> #{self.attributes[:company] ||context[:company]}</h4>
89
+ </div>
90
+ "
91
+ presentation.add_element Document.new(first_slide).root
92
+
93
+ slide_num = 0
94
+ self.toc.section_children.each do |slide|
95
+ slide_num += 1
96
+ @doc.attributes[:doc_prefix] = "s#{slide_num}"
97
+
98
+ puts "Slide #{slide_num}: " + slide.header_element.to_s
99
+ div = Element.new('div', presentation)
100
+ div.attributes['class'] = 'slide'
101
+
102
+ h1 = Element.new 'h1', div
103
+ slide.header_element.children_to_html.each do |e| h1 << e; end
104
+
105
+ array_to_html(slide.immediate_children).each do |e| div << e end
106
+
107
+ # render footnotes
108
+ if @doc.footnotes_order.size > 0
109
+ div << render_footnotes
110
+ @doc.footnotes_order = []
111
+ end
112
+ end
113
+
114
+ xml = ""
115
+ if (content_only)
116
+ if $rexml_new_version
117
+ formatter = REXML::Formatters::Default.new(ie_hack)
118
+ formatter.write(body, xml)
119
+ else
120
+ body.write(xml,indent,transitive=true,ie_hack);
121
+ end
122
+ else
123
+ doc2 = Document.new("<div>"+S5_external+"</div>",{:respect_whitespace =>:all})
124
+ doc2.root.children.each{ |child| head << child }
125
+
126
+ add_css_to(head)
127
+
128
+ # REXML Bug? if indent!=-1 whitespace is not respected for 'pre' elements
129
+ # containing code.
130
+ html.write(xml,indent,transitive=true,ie_hack);
131
+ Xhtml11_mathml2_svg11 + xml
132
+ end
133
+ end
134
+
135
+ end
136
+
137
+
138
+ end
@@ -0,0 +1,994 @@
1
+ #--
2
+ # Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
3
+ #
4
+ # This file is part of Maruku.
5
+ #
6
+ # Maruku is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Maruku is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Maruku; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #++
20
+
21
+ require 'rexml/document'
22
+
23
+ begin
24
+ require 'rexml/formatters/pretty'
25
+ require 'rexml/formatters/default'
26
+ $rexml_new_version = true
27
+ rescue LoadError
28
+ $rexml_new_version = false
29
+ end
30
+
31
+ class String
32
+ # A string is rendered into HTML by creating
33
+ # a REXML::Text node. REXML takes care of all the encoding.
34
+ def to_html
35
+ REXML::Text.new(self)
36
+ end
37
+ end
38
+
39
+
40
+ # This module groups all functions related to HTML export.
41
+ module MaRuKu; module Out; module HTML
42
+ include REXML
43
+
44
+ # Render as an HTML fragment (no head, just the content of BODY). (returns a string)
45
+ def to_html(context={})
46
+ indent = context[:indent] || -1
47
+ ie_hack = context[:ie_hack] || true
48
+
49
+ div = Element.new 'dummy'
50
+ children_to_html.each do |e|
51
+ div << e
52
+ end
53
+
54
+ # render footnotes
55
+ if @doc.footnotes_order.size > 0
56
+ div << render_footnotes
57
+ end
58
+
59
+ doc = Document.new(nil,{:respect_whitespace =>:all})
60
+ doc << div
61
+
62
+ # REXML Bug? if indent!=-1 whitespace is not respected for 'pre' elements
63
+ # containing code.
64
+ xml =""
65
+
66
+ if $rexml_new_version
67
+ formatter = if indent > -1
68
+ REXML::Formatters::Pretty.new( indent, ie_hack )
69
+ else
70
+ REXML::Formatters::Default.new( ie_hack )
71
+ end
72
+ formatter.write( div, xml)
73
+ else
74
+ div.write(xml,indent,transitive=true,ie_hack)
75
+ end
76
+
77
+ xml.gsub!(/\A<dummy>\s*/,'')
78
+ xml.gsub!(/\s*<\/dummy>\Z/,'')
79
+ xml.gsub!(/\A<dummy\s*\/>/,'')
80
+ xml
81
+ end
82
+
83
+ # Render to a complete HTML document (returns a string)
84
+ def to_html_document(context={})
85
+ indent = context[:indent] || -1
86
+ ie_hack = context[:ie_hack] ||true
87
+ doc = to_html_document_tree
88
+ xml = ""
89
+
90
+ # REXML Bug? if indent!=-1 whitespace is not respected for 'pre' elements
91
+ # containing code.
92
+ doc.write(xml,indent,transitive=true,ie_hack);
93
+
94
+ Xhtml11_mathml2_svg11 + xml
95
+ end
96
+
97
+
98
+ Xhtml10strict =
99
+ "<?xml version='1.0' encoding='utf-8'?>
100
+ <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
101
+ 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>\n"
102
+
103
+ Xhtml11strict_mathml2 = '<?xml version="1.0" encoding="utf-8"?>
104
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN"
105
+ "http://www.w3.org/TR/MathML2/dtd/xhtml-math11-f.dtd" [
106
+ <!ENTITY mathml "http://www.w3.org/1998/Math/MathML">
107
+ ]>
108
+ '
109
+
110
+ Xhtml11_mathml2_svg11 =
111
+ '<?xml version="1.0" encoding="utf-8"?>
112
+ <!DOCTYPE html PUBLIC
113
+ "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
114
+ "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
115
+ '
116
+
117
+
118
+ def xml_newline() Text.new("\n") end
119
+
120
+
121
+ =begin maruku_doc
122
+ Attribute: title
123
+ Scope: document
124
+
125
+ Sets the title of the document.
126
+ If a title is not specified, the first header will be used.
127
+
128
+ These should be equivalent:
129
+
130
+ Title: my document
131
+
132
+ Content
133
+
134
+ and
135
+
136
+ my document
137
+ ===========
138
+
139
+ Content
140
+
141
+ In both cases, the title is set to "my document".
142
+ =end
143
+
144
+ =begin maruku_doc
145
+ Attribute: doc_prefix
146
+ Scope: document
147
+
148
+ String to disambiguate footnote links.
149
+ =end
150
+
151
+
152
+ =begin maruku_doc
153
+ Attribute: subject
154
+ Scope: document
155
+
156
+ Synonim for `title`.
157
+ =end
158
+
159
+
160
+ # Render to an HTML fragment (returns a REXML document tree)
161
+ def to_html_tree
162
+ div = Element.new 'div'
163
+ div.attributes['class'] = 'maruku_wrapper_div'
164
+ children_to_html.each do |e|
165
+ div << e
166
+ end
167
+
168
+ # render footnotes
169
+ if @doc.footnotes_order.size > 0
170
+ div << render_footnotes
171
+ end
172
+
173
+ doc = Document.new(nil,{:respect_whitespace =>:all})
174
+ doc << div
175
+ end
176
+
177
+ =begin maruku_doc
178
+ Attribute: css
179
+ Scope: document
180
+ Output: HTML
181
+ Summary: Activates CSS stylesheets for HTML.
182
+
183
+ `css` should be a space-separated list of urls.
184
+
185
+ Example:
186
+
187
+ CSS: style.css math.css
188
+
189
+ =end
190
+
191
+ METAS = %w{description keywords author revised}
192
+
193
+ # Render to a complete HTML document (returns a REXML document tree)
194
+ def to_html_document_tree
195
+ doc = Document.new(nil,{:respect_whitespace =>:all})
196
+ # doc << XMLDecl.new
197
+
198
+ root = Element.new('html', doc)
199
+ root.add_namespace('http://www.w3.org/1999/xhtml')
200
+ root.add_namespace('svg', "http://www.w3.org/2000/svg" )
201
+ lang = self.attributes[:lang] || 'en'
202
+ root.attributes['xml:lang'] = lang
203
+
204
+ root << xml_newline
205
+ head = Element.new 'head', root
206
+
207
+ #<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
208
+ me = Element.new 'meta', head
209
+ me.attributes['http-equiv'] = 'Content-type'
210
+ # me.attributes['content'] = 'text/html;charset=utf-8'
211
+ me.attributes['content'] = 'application/xhtml+xml;charset=utf-8'
212
+
213
+ METAS.each do |m|
214
+ if value = self.attributes[m.to_sym]
215
+ meta = Element.new 'meta', head
216
+ meta.attributes['name'] = m
217
+ meta.attributes['content'] = value.to_s
218
+ end
219
+ end
220
+
221
+
222
+ self.attributes.each do |k,v|
223
+ if k.to_s =~ /\Ameta-(.*)\Z/
224
+ meta = Element.new 'meta', head
225
+ meta.attributes['name'] = $1
226
+ meta.attributes['content'] = v.to_s
227
+ end
228
+ end
229
+
230
+
231
+
232
+ # Create title element
233
+ doc_title = self.attributes[:title] || self.attributes[:subject] || ""
234
+ title = Element.new 'title', head
235
+ title << Text.new(doc_title)
236
+
237
+ add_css_to(head)
238
+
239
+
240
+ root << xml_newline
241
+
242
+ body = Element.new 'body'
243
+
244
+ children_to_html.each do |e|
245
+ body << e
246
+ end
247
+
248
+ # render footnotes
249
+ if @doc.footnotes_order.size > 0
250
+ body << render_footnotes
251
+ end
252
+
253
+ # When we are rendering a whole document, we add a signature
254
+ # at the bottom.
255
+ if get_setting(:maruku_signature)
256
+ body << maruku_html_signature
257
+ end
258
+
259
+ root << body
260
+
261
+ doc
262
+ end
263
+
264
+ def add_css_to(head)
265
+ if css_list = self.attributes[:css]
266
+ css_list.split.each do |css|
267
+ # <link type="text/css" rel="stylesheet" href="..." />
268
+ link = Element.new 'link'
269
+ link.attributes['type'] = 'text/css'
270
+ link.attributes['rel'] = 'stylesheet'
271
+ link.attributes['href'] = css
272
+ head << link
273
+ head << xml_newline
274
+ end
275
+ end
276
+ end
277
+
278
+ # returns "st","nd","rd" or "th" as appropriate
279
+ def day_suffix(day)
280
+ s = {
281
+ 1 => 'st',
282
+ 2 => 'nd',
283
+ 3 => 'rd',
284
+ 21 => 'st',
285
+ 22 => 'nd',
286
+ 23 => 'rd',
287
+ 31 => 'st'
288
+ }
289
+ return s[day] || 'th';
290
+ end
291
+
292
+ # formats a nice date
293
+ def nice_date
294
+ t = Time.now
295
+ t.strftime(" at %H:%M on ")+
296
+ t.strftime("%A, %B %d")+
297
+ day_suffix(t.day)+
298
+ t.strftime(", %Y")
299
+ end
300
+
301
+ def maruku_html_signature
302
+ div = Element.new 'div'
303
+ div.attributes['class'] = 'maruku_signature'
304
+ Element.new 'hr', div
305
+ span = Element.new 'span', div
306
+ span.attributes['style'] = 'font-size: small; font-style: italic'
307
+ span << Text.new('Created by ')
308
+ a = Element.new('a', span)
309
+ a.attributes['href'] = 'http://maruku.rubyforge.org'
310
+ a.attributes['title'] = 'Maruku: a Markdown-superset interpreter for Ruby'
311
+ a << Text.new('Maruku')
312
+ span << Text.new(nice_date+".")
313
+ div
314
+ end
315
+
316
+ def render_footnotes()
317
+ div = Element.new 'div'
318
+ div.attributes['class'] = 'footnotes'
319
+ div << Element.new('hr')
320
+ ol = Element.new 'ol'
321
+ @doc.footnotes_order.each_with_index do |fid, i| num = i+1
322
+ f = self.footnotes[fid]
323
+ if f
324
+ li = f.wrap_as_element('li')
325
+ li.attributes['id'] = "#{get_setting(:doc_prefix)}fn:#{num}"
326
+
327
+ a = Element.new 'a'
328
+ a.attributes['href'] = "\##{get_setting(:doc_prefix)}fnref:#{num}"
329
+ a.attributes['rev'] = 'footnote'
330
+ a<< Text.new('&#8617;', true, nil, true)
331
+ li.insert_after(li.children.last, a)
332
+ ol << li
333
+ else
334
+ maruku_error "Could not find footnote id '#{fid}' among ["+
335
+ self.footnotes.keys.map{|s|"'"+s+"'"}.join(', ')+"]."
336
+ end
337
+ end
338
+ div << ol
339
+ div
340
+ end
341
+
342
+
343
+ def to_html_hrule; create_html_element 'hr' end
344
+ def to_html_linebreak; Element.new 'br' end
345
+
346
+ # renders children as html and wraps into an element of given name
347
+ #
348
+ # Sets 'id' if meta is set
349
+ def wrap_as_element(name, attributes_to_copy=[])
350
+ m = create_html_element(name, attributes_to_copy)
351
+ children_to_html.each do |e| m << e; end
352
+
353
+ # m << Comment.new( "{"+self.al.to_md+"}") if not self.al.empty?
354
+ # m << Comment.new( @attributes.inspect) if not @attributes.empty?
355
+ m
356
+ end
357
+
358
+ =begin maruku_doc
359
+ Attribute: id
360
+ Scope: element
361
+ Output: LaTeX, HTML
362
+
363
+ It is copied as a standard HTML attribute.
364
+
365
+ Moreover, it used as a label name for hyperlinks in both HTML and
366
+ in PDF.
367
+
368
+ =end
369
+
370
+ =begin maruku_doc
371
+ Attribute: class
372
+ Scope: element
373
+ Output: HTML
374
+
375
+ It is copied as a standard HTML attribute.
376
+ =end
377
+
378
+ =begin maruku_doc
379
+ Attribute: style
380
+ Scope: element
381
+ Output: HTML
382
+
383
+ It is copied as a standard HTML attribute.
384
+ =end
385
+
386
+
387
+
388
+
389
+
390
+ HTML4Attributes = {}
391
+
392
+ coreattrs = [:id, :class, :style, :title, :accesskey, :contenteditable, :dir, :draggable, :spellcheck, :tabindex]
393
+ i18n = [:lang, 'xml:lang'.to_sym]
394
+ events = [
395
+ :onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover,
396
+ :onmousemove, :onmouseout,
397
+ :onkeypress, :onkeydown, :onkeyup]
398
+ attrs = coreattrs + i18n + events
399
+ cellhalign = [:align, :char, :charoff]
400
+ cellvalign = [:valign]
401
+ [
402
+ ['body', attrs + [:onload, :onunload]],
403
+ ['address', attrs],
404
+ ['div', attrs],
405
+ ['a', attrs+[:charset, :type, :name, :rel, :rev, :accesskey, :shape, :coords, :tabindex,
406
+ :onfocus,:onblur]],
407
+ ['img', attrs + [:longdesc, :name, :height, :width, :alt] ],
408
+ ['p', attrs],
409
+ [['h1','h2','h3','h4','h5','h6'], attrs],
410
+ [['pre'], attrs],
411
+ [['q', 'blockquote'], attrs+[:cite]],
412
+ [['ins','del'], attrs+[:cite,:datetime]],
413
+ [['ol'], attrs+[:reversed, :start]],
414
+ [['ul'], attrs],
415
+ [['li'], attrs+[:value]],
416
+ ['table',attrs+[:summary, :width, :frame, :rules, :border, :cellspacing, :cellpadding]],
417
+ ['caption',attrs],
418
+ [['colgroup','col'],attrs+[:span, :width]+cellhalign+cellvalign],
419
+ [['thead','tbody','tfoot'], attrs+cellhalign+cellvalign],
420
+ [['td','td','th'], attrs+[:abbr, :axis, :headers, :scope, :rowspan, :colspan, :cellvalign, :cellhalign]],
421
+
422
+ # altri
423
+ [['em','code','strong','hr','span','dl','dd','dt'], attrs]
424
+ ].each do |el, a| [*el].each do |e| HTML4Attributes[e] = a end end
425
+
426
+
427
+ def create_html_element(name, attributes_to_copy=[])
428
+ m = Element.new name
429
+ if atts = HTML4Attributes[name] then
430
+ atts.each do |att|
431
+ if v = @attributes[att] then
432
+ m.attributes[att.to_s] = v.to_s
433
+ end
434
+ end
435
+ else
436
+ # puts "not atts for #{name.inspect}"
437
+ end
438
+ m
439
+ end
440
+
441
+
442
+ def to_html_ul
443
+ if @attributes[:toc]
444
+ # render toc
445
+ html_toc = @doc.toc.to_html
446
+ return html_toc
447
+ else
448
+ add_ws wrap_as_element('ul')
449
+ end
450
+ end
451
+
452
+
453
+ def to_html_paragraph; add_ws wrap_as_element('p') end
454
+ def to_html_ol; add_ws wrap_as_element('ol') end
455
+ def to_html_li; add_ws wrap_as_element('li') end
456
+ def to_html_li_span; add_ws wrap_as_element('li') end
457
+ def to_html_quote; add_ws wrap_as_element('blockquote') end
458
+ def to_html_strong; wrap_as_element('strong') end
459
+ def to_html_emphasis; wrap_as_element('em') end
460
+
461
+ =begin maruku_doc
462
+ Attribute: use_numbered_headers
463
+ Scope: document
464
+ Summary: Activates the numbering of headers.
465
+
466
+ If `true`, section headers will be numbered.
467
+
468
+ In LaTeX export, the numbering of headers is managed
469
+ by Maruku, to have the same results in both HTML and LaTeX.
470
+ =end
471
+
472
+ # nil if not applicable, else string
473
+ def section_number
474
+ return nil if not get_setting(:use_numbered_headers)
475
+
476
+ n = @attributes[:section_number]
477
+ if n && (not n.empty?)
478
+ n.join('.')+". "
479
+ else
480
+ nil
481
+ end
482
+ end
483
+
484
+ # nil if not applicable, else SPAN element
485
+ def render_section_number
486
+ # if we are bound to a section, add section number
487
+ if num = section_number
488
+ span = Element.new 'span'
489
+ span.attributes['class'] = 'maruku_section_number'
490
+ span << Text.new(section_number)
491
+ span
492
+ else
493
+ nil
494
+ end
495
+ end
496
+
497
+ def to_html_header
498
+ element_name = "h#{self.level}"
499
+ h = wrap_as_element element_name
500
+
501
+ if span = render_section_number
502
+ h.insert_before(h.children.first, span)
503
+ end
504
+ add_ws h
505
+ end
506
+
507
+ def source2html(source)
508
+ # source = source.gsub(/&/,'&amp;')
509
+ source = Text.normalize(source)
510
+ source = source.gsub(/\&apos;/,'&#39;') # IE bug
511
+ source = source.gsub(/'/,'&#39;') # IE bug
512
+ Text.new(source, true, nil, true )
513
+ end
514
+
515
+ =begin maruku_doc
516
+ Attribute: html_use_syntax
517
+ Scope: global, document, element
518
+ Output: HTML
519
+ Summary: Enables the use of the `syntax` package.
520
+ Related: lang, code_lang
521
+ Default: <?mrk md_code(Globals[:html_use_syntax].to_s) ?>
522
+
523
+ If true, the `syntax` package is used. It supports the `ruby` and `xml`
524
+ languages. Remember to set the `lang` attribute of the code block.
525
+
526
+ Examples:
527
+
528
+ require 'maruku'
529
+ {:lang=ruby html_use_syntax=true}
530
+
531
+ and
532
+
533
+ <div style="text-align:center">Div</div>
534
+ {:lang=html html_use_syntax=true}
535
+
536
+ produces:
537
+
538
+ require 'maruku'
539
+ {:lang=ruby html_use_syntax=true}
540
+
541
+ and
542
+
543
+ <div style="text-align:center">Div</div>
544
+ {:lang=html html_use_syntax=true}
545
+
546
+ =end
547
+
548
+ $syntax_loaded = false
549
+ def to_html_code;
550
+ source = self.raw_code
551
+
552
+ lang = self.attributes[:lang] || @doc.attributes[:code_lang]
553
+
554
+ lang = 'xml' if lang=='html'
555
+ lang = 'css21' if lang == 'css'
556
+
557
+ use_syntax = get_setting :html_use_syntax
558
+
559
+ element =
560
+ if use_syntax && lang
561
+ begin
562
+ if not $syntax_loaded
563
+ require 'rubygems'
564
+ require 'syntax'
565
+ require 'syntax/convertors/html'
566
+ $syntax_loaded = true
567
+ end
568
+ convertor = Syntax::Convertors::HTML.for_syntax lang
569
+
570
+ # eliminate trailing newlines otherwise Syntax crashes
571
+ source = source.gsub(/\n*\Z/,'')
572
+
573
+ html = convertor.convert( source )
574
+ html = html.gsub(/\&apos;/,'&#39;') # IE bug
575
+ html = html.gsub(/'/,'&#39;') # IE bug
576
+ # html = html.gsub(/&/,'&amp;')
577
+
578
+ code = Document.new(html, {:respect_whitespace =>:all}).root
579
+ code.name = 'code'
580
+ code.attributes['lang'] = lang
581
+
582
+ pre = Element.new 'pre'
583
+ pre.attributes['class'] = lang
584
+ pre << code
585
+ pre
586
+ rescue LoadError => e
587
+ maruku_error "Could not load package 'syntax'.\n"+
588
+ "Please install it, for example using 'gem install syntax'."
589
+ to_html_code_using_pre(source)
590
+ rescue Object => e
591
+ maruku_error"Error while using the syntax library for code:\n#{source.inspect}"+
592
+ "Lang is #{lang} object is: \n"+
593
+ self.inspect +
594
+ "\nException: #{e.class}: #{e.message}\n\t#{e.backtrace.join("\n\t")}"
595
+
596
+ tell_user("Using normal PRE because the syntax library did not work.")
597
+ to_html_code_using_pre(source)
598
+ end
599
+ else
600
+ to_html_code_using_pre(source)
601
+ end
602
+
603
+ color = get_setting(:code_background_color)
604
+ if color != Globals[:code_background_color]
605
+ element.attributes['style'] = "background-color: #{color};"
606
+ end
607
+ add_ws element
608
+ end
609
+
610
+ =begin maruku_doc
611
+ Attribute: code_background_color
612
+ Scope: global, document, element
613
+ Summary: Background color for code blocks.
614
+
615
+ The format is either a named color (`green`, `red`) or a CSS color
616
+ of the form `#ff00ff`.
617
+
618
+ * for **HTML output**, the value is put straight in the `background-color` CSS
619
+ property of the block.
620
+
621
+ * for **LaTeX output**, if it is a named color, it must be a color accepted
622
+ by the LaTeX `color` packages. If it is of the form `#ff00ff`, Maruku
623
+ defines a color using the `\color[rgb]{r,g,b}` macro.
624
+
625
+ For example, for `#0000ff`, the macro is called as: `\color[rgb]{0,0,1}`.
626
+
627
+ =end
628
+
629
+
630
+ def to_html_code_using_pre(source)
631
+ pre = create_html_element 'pre'
632
+ code = Element.new 'code', pre
633
+ s = source
634
+
635
+ # s = s.gsub(/&/,'&amp;')
636
+ s = Text.normalize(s)
637
+ s = s.gsub(/\&apos;/,'&#39;') # IE bug
638
+ s = s.gsub(/'/,'&#39;') # IE bug
639
+
640
+ if get_setting(:code_show_spaces)
641
+ # 187 = raquo
642
+ # 160 = nbsp
643
+ # 172 = not
644
+ s.gsub!(/\t/,'&#187;'+'&#160;'*3)
645
+ s.gsub!(/ /,'&#172;')
646
+ end
647
+
648
+ text = Text.new(s, respect_ws=true, parent=nil, raw=true )
649
+
650
+ if lang = self.attributes[:lang]
651
+ code.attributes['lang'] = lang
652
+ code.attributes['class'] = lang
653
+ end
654
+ code << text
655
+ pre
656
+ end
657
+
658
+ def to_html_inline_code;
659
+ pre = create_html_element 'code'
660
+ source = self.raw_code
661
+ pre << source2html(source)
662
+
663
+ color = get_setting(:code_background_color)
664
+ if color != Globals[:code_background_color]
665
+ pre.attributes['style'] = "background-color: #{color};"+(pre.attributes['style']||"")
666
+ end
667
+
668
+ pre
669
+ end
670
+
671
+ def add_class_to(el, cl)
672
+ el.attributes['class'] =
673
+ if already = el.attributes['class']
674
+ already + " " + cl
675
+ else
676
+ cl
677
+ end
678
+ end
679
+
680
+ def add_class_to_link(a)
681
+ return # not ready yet
682
+
683
+ # url = a.attributes['href']
684
+ # return if not url
685
+ #
686
+ # if url =~ /^#/
687
+ # add_class_to(a, 'maruku-link-samedoc')
688
+ # elsif url =~ /^http:/
689
+ # add_class_to(a, 'maruku-link-external')
690
+ # else
691
+ # add_class_to(a, 'maruku-link-local')
692
+ # end
693
+ #
694
+ # puts a.attributes['class']
695
+ end
696
+
697
+
698
+ def to_html_immediate_link
699
+ a = create_html_element 'a'
700
+ url = self.url
701
+ text = url.gsub(/^mailto:/,'') # don't show mailto
702
+ a << Text.new(text)
703
+ a.attributes['href'] = url
704
+ add_class_to_link(a)
705
+ a
706
+ end
707
+
708
+ def to_html_link
709
+ a = wrap_as_element 'a'
710
+ id = self.ref_id
711
+
712
+ if ref = @doc.refs[id]
713
+ url = ref[:url]
714
+ title = ref[:title]
715
+ a.attributes['href'] = url if url
716
+ a.attributes['title'] = title if title
717
+ else
718
+ maruku_error "Could not find ref_id = #{id.inspect} for #{self.inspect}\n"+
719
+ "Available refs are #{@doc.refs.keys.inspect}"
720
+ tell_user "Not creating a link for ref_id = #{id.inspect}."
721
+ return wrap_as_element('span')
722
+ end
723
+
724
+ # add_class_to_link(a)
725
+ return a
726
+ end
727
+
728
+ def to_html_im_link
729
+ if url = self.url
730
+ title = self.title
731
+ a = wrap_as_element 'a'
732
+ a.attributes['href'] = url
733
+ a.attributes['title'] = title if title
734
+ return a
735
+ else
736
+ maruku_error"Could not find url in #{self.inspect}"
737
+ tell_user "Not creating a link for ref_id = #{id.inspect}."
738
+ return wrap_as_element('span')
739
+ end
740
+ end
741
+
742
+ def add_ws(e)
743
+ [Text.new("\n"), e, Text.new("\n")]
744
+ end
745
+ ##### Email address
746
+
747
+ def obfuscate(s)
748
+ res = ''
749
+ s.each_byte do |char|
750
+ res += "&#%03d;" % char
751
+ end
752
+ res
753
+ end
754
+
755
+ def to_html_email_address
756
+ email = self.email
757
+ a = create_html_element 'a'
758
+ #a.attributes['href'] = Text.new("mailto:"+obfuscate(email),false,nil,true)
759
+ #a.attributes.add Attribute.new('href',Text.new(
760
+ #"mailto:"+obfuscate(email),false,nil,true))
761
+ # Sorry, for the moment it doesn't work
762
+ a.attributes['href'] = "mailto:#{email}"
763
+
764
+ a << Text.new(obfuscate(email),false,nil,true)
765
+ a
766
+ end
767
+
768
+ ##### Images
769
+
770
+ def to_html_image
771
+ a = create_html_element 'img'
772
+ id = self.ref_id
773
+ if ref = @doc.refs[id]
774
+ url = ref[:url]
775
+ title = ref[:title]
776
+ a.attributes['src'] = url.to_s
777
+ a.attributes['alt'] = children_to_s
778
+ else
779
+ maruku_error"Could not find id = #{id.inspect} for\n #{self.inspect}"
780
+ tell_user "Could not create image with ref_id = #{id.inspect};"+
781
+ " Using SPAN element as replacement."
782
+ return wrap_as_element('span')
783
+ end
784
+ return a
785
+ end
786
+
787
+ def to_html_im_image
788
+ if not url = self.url
789
+ maruku_error "Image with no url: #{self.inspect}"
790
+ tell_user "Could not create image with ref_id = #{id.inspect};"+
791
+ " Using SPAN element as replacement."
792
+ return wrap_as_element('span')
793
+ end
794
+ title = self.title
795
+ a = create_html_element 'img'
796
+ a.attributes['src'] = url.to_s
797
+ a.attributes['alt'] = children_to_s
798
+ return a
799
+ end
800
+
801
+ =begin maruku_doc
802
+ Attribute: filter_html
803
+ Scope: document
804
+
805
+ If true, raw HTML is discarded from the output.
806
+
807
+ =end
808
+
809
+ def to_html_raw_html
810
+ return [] if get_setting(:filter_html)
811
+
812
+ raw_html = self.raw_html
813
+ if rexml_doc = @parsed_html
814
+ root = rexml_doc.root
815
+ if root.nil?
816
+ s = "Bug in REXML: root() of Document is nil: \n#{rexml_doc.inspect}\n"+
817
+ "Raw HTML:\n#{raw_html.inspect}"
818
+ maruku_error s
819
+ tell_user 'The REXML version you have has a bug, omitting HTML'
820
+ div = Element.new 'div'
821
+ #div << Text.new(s)
822
+ return div
823
+ end
824
+
825
+ # copies the @children array (FIXME is it deep?)
826
+ elements = root.to_a
827
+ return elements
828
+ else # invalid
829
+ # Creates red box with offending HTML
830
+ tell_user "Wrapping bad html in a PRE with class 'markdown-html-error'\n"+
831
+ raw_html.gsub(/^/, '|')
832
+ pre = Element.new('pre')
833
+ pre.attributes['style'] = 'border: solid 3px red; background-color: pink'
834
+ pre.attributes['class'] = 'markdown-html-error'
835
+ pre << Text.new("REXML could not parse this XML/HTML: \n#{raw_html}", true)
836
+ return pre
837
+ end
838
+ end
839
+
840
+ def to_html_abbr
841
+ abbr = Element.new 'abbr'
842
+ abbr << Text.new(children[0])
843
+ abbr.attributes['title'] = self.title if self.title
844
+ abbr
845
+ end
846
+
847
+ def to_html_footnote_reference
848
+ id = self.footnote_id
849
+
850
+ # save the order of used footnotes
851
+ order = @doc.footnotes_order
852
+
853
+ if order.include? id
854
+ # footnote has already been used
855
+ return []
856
+ end
857
+
858
+ if not @doc.footnotes[id]
859
+ return []
860
+ end
861
+
862
+ # take next number
863
+ order << id
864
+
865
+ #num = order.size;
866
+ num = order.index(id) + 1
867
+
868
+ sup = Element.new 'sup'
869
+ sup.attributes['id'] = "#{get_setting(:doc_prefix)}fnref:#{num}"
870
+ a = Element.new 'a'
871
+ a << Text.new(num.to_s)
872
+ a.attributes['href'] = "\##{get_setting(:doc_prefix)}fn:#{num}"
873
+ a.attributes['rel'] = 'footnote'
874
+ sup << a
875
+
876
+ sup
877
+ end
878
+
879
+ ## Definition lists ###
880
+ def to_html_definition_list() add_ws wrap_as_element('dl') end
881
+ def to_html_definition() children_to_html end
882
+ def to_html_definition_term() add_ws wrap_as_element('dt') end
883
+ def to_html_definition_data() add_ws wrap_as_element('dd') end
884
+
885
+ # FIXME: Ugly code
886
+ def to_html_table
887
+ align = self.align
888
+ num_columns = align.size
889
+
890
+ head = @children.slice(0, num_columns)
891
+ rows = []
892
+ i = num_columns
893
+ while i<@children.size
894
+ rows << @children.slice(i, num_columns)
895
+ i += num_columns
896
+ end
897
+
898
+ table = create_html_element 'table'
899
+ thead = Element.new 'thead'
900
+ tr = Element.new 'tr'
901
+ array_to_html(head).each do |x| tr<<x end
902
+ thead << tr
903
+ table << thead
904
+
905
+ tbody = Element.new 'tbody'
906
+ rows.each do |row|
907
+ tr = Element.new 'tr'
908
+ array_to_html(row).each_with_index do |x,i|
909
+ x.attributes['style'] ="text-align: #{align[i].to_s};"
910
+ tr<<x
911
+ end
912
+
913
+ tbody << tr << Text.new("\n")
914
+ end
915
+ table << tbody
916
+ table
917
+ end
918
+
919
+ def to_html_head_cell; wrap_as_element('th') end
920
+ def to_html_cell
921
+ if @attributes[:scope]
922
+ wrap_as_element('th', [:scope])
923
+ else
924
+ wrap_as_element('td')
925
+ end
926
+ end
927
+
928
+ def to_html_entity
929
+ MaRuKu::Out::Latex.need_entity_table
930
+
931
+ entity_name = self.entity_name
932
+
933
+ if (e = MaRuKu::Out::Latex::ENTITY_TABLE[entity_name]) && e.html_num
934
+ entity_name = e.html_num
935
+ end
936
+
937
+ # Fix for Internet Explorer
938
+ if entity_name == 'apos'
939
+ entity_name = 39
940
+ end
941
+
942
+
943
+ if entity_name.kind_of? Fixnum
944
+ # Entity.new(entity_name)
945
+ Text.new('&#%d;' % [entity_name], false, nil, true)
946
+ else
947
+ Text.new('&%s;' % [entity_name], false, nil, true)
948
+ end
949
+ end
950
+
951
+ def to_html_xml_instr
952
+ target = self.target || ''
953
+ code = self.code || ''
954
+ REXML::Instruction.new(target, code)
955
+ end
956
+
957
+ # Convert each child to html
958
+ def children_to_html
959
+ array_to_html(@children)
960
+ end
961
+
962
+ def array_to_html(array)
963
+ e = []
964
+ array.each do |c|
965
+ method = c.kind_of?(MDElement) ?
966
+ "to_html_#{c.node_type}" : "to_html"
967
+
968
+ if not c.respond_to?(method)
969
+ #raise "Object does not answer to #{method}: #{c.class} #{c.inspect}"
970
+ next
971
+ end
972
+
973
+ h = c.send(method)
974
+
975
+ if h.nil?
976
+ raise "Nil html created by method #{method}:\n#{h.inspect}\n"+
977
+ " for object #{c.inspect[0,300]}"
978
+ end
979
+
980
+ if h.kind_of?Array
981
+ e = e + h #h.each do |hh| e << hh end
982
+ else
983
+ e << h
984
+ end
985
+ end
986
+ e
987
+ end
988
+
989
+ def to_html_ref_definition; [] end
990
+ def to_latex_ref_definition; [] end
991
+
992
+ end # HTML
993
+ end # out
994
+ end # MaRuKu