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