kramdown 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of kramdown might be problematic. Click here for more details.
- data/CONTRIBUTERS +2 -1
- data/ChangeLog +454 -0
- data/README +1 -1
- data/VERSION +1 -1
- data/doc/{default.less.css → default.scss.css} +12 -9
- data/doc/documentation.page +1 -1
- data/doc/index.page +37 -3
- data/doc/syntax.page +10 -7
- data/lib/kramdown/converter.rb +1 -0
- data/lib/kramdown/converter/html.rb +61 -67
- data/lib/kramdown/converter/kramdown.rb +398 -0
- data/lib/kramdown/converter/latex.rb +274 -276
- data/lib/kramdown/document.rb +2 -0
- data/lib/kramdown/options.rb +16 -15
- data/lib/kramdown/parser/base.rb +0 -1
- data/lib/kramdown/parser/html.rb +122 -27
- data/lib/kramdown/parser/kramdown.rb +2 -0
- data/lib/kramdown/parser/kramdown/attribute_list.rb +2 -0
- data/lib/kramdown/parser/kramdown/extension.rb +2 -1
- data/lib/kramdown/parser/kramdown/html.rb +2 -2
- data/lib/kramdown/parser/kramdown/html_entity.rb +1 -1
- data/lib/kramdown/parser/kramdown/link.rb +5 -2
- data/lib/kramdown/parser/kramdown/list.rb +13 -9
- data/lib/kramdown/parser/kramdown/math.rb +1 -1
- data/lib/kramdown/parser/kramdown/typographic_symbol.rb +4 -4
- data/lib/kramdown/utils.rb +36 -0
- data/lib/kramdown/utils/entities.rb +338 -0
- data/lib/kramdown/utils/html.rb +72 -0
- data/lib/kramdown/version.rb +1 -1
- data/man/man1/kramdown.1 +20 -17
- data/test/run_tests.rb +1 -1
- data/test/test_files.rb +60 -3
- data/test/testcases/block/06_codeblock/whitespace.html +2 -2
- data/test/testcases/block/07_horizontal_rule/error.html.19 +7 -0
- data/test/testcases/block/09_html/html_to_native/code.html +1 -1
- data/test/testcases/block/09_html/html_to_native/code.text +1 -1
- data/test/testcases/block/09_html/html_to_native/table_simple.html +38 -2
- data/test/testcases/block/09_html/html_to_native/table_simple.text +42 -0
- data/test/testcases/block/09_html/html_to_native/typography.html.19 +1 -0
- data/test/testcases/block/09_html/simple.html.19 +62 -0
- data/test/testcases/block/11_ial/simple.html +3 -2
- data/test/testcases/block/12_extension/comment.html +3 -2
- data/test/testcases/block/12_extension/options.html +0 -3
- data/test/testcases/block/12_extension/options.text +0 -6
- data/test/testcases/block/13_definition_list/item_ial.html +14 -0
- data/test/testcases/block/13_definition_list/item_ial.text +8 -0
- data/test/testcases/block/16_toc/no_toc_depth.html +33 -0
- data/test/testcases/block/16_toc/no_toc_depth.options +1 -0
- data/test/testcases/block/16_toc/no_toc_depth.text +16 -0
- data/test/testcases/block/16_toc/toc_depth_2.html +24 -0
- data/test/testcases/block/16_toc/toc_depth_2.options +1 -0
- data/test/testcases/block/16_toc/toc_depth_2.text +16 -0
- data/test/testcases/span/01_link/empty.html +2 -0
- data/test/testcases/span/01_link/empty.text +2 -0
- data/test/testcases/span/01_link/imagelinks.html +2 -0
- data/test/testcases/span/01_link/imagelinks.text +2 -0
- data/test/testcases/span/01_link/inline.html.19 +40 -0
- data/test/testcases/span/01_link/reference.html.19 +32 -0
- data/test/testcases/span/extension/comment.html +3 -3
- data/test/testcases/span/text_substitutions/entities.html.19 +4 -0
- data/test/testcases/span/text_substitutions/entities_numeric.html +1 -0
- data/test/testcases/span/text_substitutions/entities_numeric.html.19 +1 -0
- data/test/testcases/span/text_substitutions/entities_numeric.options +1 -0
- data/test/testcases/span/text_substitutions/entities_numeric.text +1 -0
- data/test/testcases/span/text_substitutions/typography.html.19 +18 -0
- metadata +30 -10
- data/test/testcases/block/09_html/filtered_html.html +0 -1
- data/test/testcases/block/09_html/filtered_html.options +0 -1
- data/test/testcases/block/09_html/filtered_html.text +0 -1
data/README
CHANGED
@@ -21,7 +21,7 @@ kramdown has a basic *Cloth API, so using kramdown is as easy as
|
|
21
21
|
Just clone the git repository as described in doc/installation.page you are good to go. You probably
|
22
22
|
want to install `rake` so that you can use the provided rake tasks. Aside from that:
|
23
23
|
|
24
|
-
* The `tidy` binary needs to be installed for the
|
24
|
+
* The `tidy` binary needs to be installed for the automatically derived tests to work.
|
25
25
|
* The `latex` binary needs to be installed for the latex-compilation tests to work.
|
26
26
|
|
27
27
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.9.0
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
$text-color: #354146;
|
2
|
+
$link-color: #1666A3;
|
3
3
|
|
4
4
|
* {
|
5
5
|
padding: 0;
|
@@ -32,7 +32,7 @@ body, table, code {
|
|
32
32
|
}
|
33
33
|
|
34
34
|
#header {
|
35
|
-
.with-margin;
|
35
|
+
@extend .with-margin;
|
36
36
|
|
37
37
|
position: relative;
|
38
38
|
padding: 0 0 0 30px;
|
@@ -66,7 +66,7 @@ body, table, code {
|
|
66
66
|
}
|
67
67
|
|
68
68
|
#nav {
|
69
|
-
.with-margin;
|
69
|
+
@extend .with-margin;
|
70
70
|
|
71
71
|
ul {
|
72
72
|
height: 40px;
|
@@ -120,7 +120,8 @@ body, table, code {
|
|
120
120
|
}
|
121
121
|
|
122
122
|
#intro {
|
123
|
-
.with-margin;
|
123
|
+
@extend .with-margin;
|
124
|
+
|
124
125
|
background: #e6e8e9;
|
125
126
|
height: auto;
|
126
127
|
|
@@ -133,7 +134,7 @@ body, table, code {
|
|
133
134
|
}
|
134
135
|
|
135
136
|
a {
|
136
|
-
color:
|
137
|
+
color: $link-color;
|
137
138
|
background-color: inherit;
|
138
139
|
text-decoration: underline;
|
139
140
|
}
|
@@ -146,7 +147,8 @@ body, table, code {
|
|
146
147
|
|
147
148
|
/* content */
|
148
149
|
#container {
|
149
|
-
.with-margin;
|
150
|
+
@extend .with-margin;
|
151
|
+
|
150
152
|
position: relative;
|
151
153
|
clear: both;
|
152
154
|
background-color: #fff;
|
@@ -154,7 +156,7 @@ body, table, code {
|
|
154
156
|
background-image: -webkit-gradient(linear, 0 0, 0 200, from(#eee), to(#fff));
|
155
157
|
|
156
158
|
a {
|
157
|
-
color:
|
159
|
+
color: $link-color;
|
158
160
|
background-color: inherit;
|
159
161
|
text-decoration: underline;
|
160
162
|
}
|
@@ -462,7 +464,8 @@ body, table, code {
|
|
462
464
|
|
463
465
|
/* footer */
|
464
466
|
#footer {
|
465
|
-
.with-margin;
|
467
|
+
@extend .with-margin;
|
468
|
+
|
466
469
|
clear: both;
|
467
470
|
margin-top: 20px;
|
468
471
|
padding: 5px 20px 30px;
|
data/doc/documentation.page
CHANGED
@@ -10,7 +10,7 @@ HTML. However, due to its modular architecture it is able to support additional
|
|
10
10
|
formats. The following input and output formats are currently supported:
|
11
11
|
|
12
12
|
* Input: [kramdown](parser/kramdown.html) (a superset of Markdown), [html](parser/html.html)
|
13
|
-
* Output: [HTML](converter/html.html), [LaTeX](converter/latex.html)
|
13
|
+
* Output: [HTML](converter/html.html), [LaTeX](converter/latex.html), [kramdown](converter/kramdown.html)
|
14
14
|
|
15
15
|
|
16
16
|
## Usage
|
data/doc/index.page
CHANGED
@@ -8,8 +8,42 @@ sort_info: 1
|
|
8
8
|
If you want to get started with kramdown, have a look at the [installation page](installation.html)
|
9
9
|
to see how you can install it on your system. Then look through the
|
10
10
|
[documentation](documentation.html) for finding information about how to actually use kramdown and
|
11
|
-
|
12
|
-
|
11
|
+
its parsers/converters. The [syntax](syntax.html) provides a detailed description of the superset of
|
12
|
+
Markdown which kramdown supports.
|
13
|
+
|
14
|
+
{tikz:: path: overview.png
|
15
|
+
img_attr: {style: 'background:transparent'}
|
16
|
+
libraries: [mindmap, trees, arrows]
|
17
|
+
transparent: true
|
18
|
+
resolution: 300 100
|
19
|
+
opts: |
|
20
|
+
mindmap, concept color=black, text=white,
|
21
|
+
root concept/.append style={font=\Large},
|
22
|
+
level 1 concept/.append style={font=\Large, minimum size=2.6cm},
|
23
|
+
level 2 concept/.append style={font=\Large},
|
24
|
+
}
|
25
|
+
\node[concept, font=\Large] (lib) {kramdown's internal representation}
|
26
|
+
child[concept color=orange, grow=150, ->] {node[concept] (i-kramdown) {kramdown}}
|
27
|
+
child[concept color=orange, grow=210] {node[concept] (i-html) {HTML}}
|
28
|
+
child[concept color=green!50!black, grow=40] {node[concept] (o-html) {HTML}}
|
29
|
+
child[concept color=green!50!black, grow=0] {node[concept] (o-kramdown) {kramdown}}
|
30
|
+
child[concept color=green!50!black, grow=-45] {
|
31
|
+
node[concept] (o-latex) {\LaTeX}
|
32
|
+
child[grow=0] {
|
33
|
+
node[concept] (o-latex-pdf) {PDF}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
child[concept color=green!50!black, grow=-45] {node[concept] {\LaTeX}}
|
37
|
+
;
|
38
|
+
\draw [dash pattern=on 0pt off 2pt,line width=5pt,arrows=-angle 60,shorten >=15pt,shorten <=10pt,color=orange]
|
39
|
+
(i-kramdown) edge(lib)
|
40
|
+
(i-html) edge (lib);
|
41
|
+
\draw [dash pattern=on 0pt off 2pt,line width=5pt,arrows=-angle 60,shorten >=10pt,shorten <=15pt,color=green!50!black]
|
42
|
+
(lib) edge(o-html)
|
43
|
+
(lib) edge (o-kramdown)
|
44
|
+
(lib) edge (o-latex);
|
45
|
+
{tikz}
|
46
|
+
{: style="text-align: center"}
|
13
47
|
|
14
48
|
|
15
49
|
## Bugs, Forums, Mailing Lists
|
@@ -55,7 +89,7 @@ It is probably the fastest pure-Ruby Markdown converter available (June 2010), b
|
|
55
89
|
than [Maruku] and about 9x faster than [BlueFeather].
|
56
90
|
|
57
91
|
<p class="a-center">
|
58
|
-
The latest version of kramdown is <b>0.
|
92
|
+
The latest version of kramdown is <b>0.9.0</b> and it was released on <b>2010-06-23</b>.
|
59
93
|
</p>
|
60
94
|
|
61
95
|
[PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/
|
data/doc/syntax.page
CHANGED
@@ -530,8 +530,9 @@ after the list item marker:
|
|
530
530
|
Definition lists allow you to assign one or more definitions to one or more terms.
|
531
531
|
|
532
532
|
A definition list is started when a normal paragraph is followed by a line with a definition marker
|
533
|
-
(a colon which may be optionally indented up to three spaces), then at least one tab or one space
|
534
|
-
|
533
|
+
(a colon which may be optionally indented up to three spaces), then at least one tab or one space,
|
534
|
+
optionally followed by an [IAL](#inline-attribute-lists) that should be applied to the list item and
|
535
|
+
then the first part of the definition. The line with the definition marker may optionally be
|
535
536
|
separated from the preceding paragraph by a blank line. The leading tabs or spaces are stripped away
|
536
537
|
from this first line of the definition to allow for a nice alignment with the following definition
|
537
538
|
content. Each line of the preceding paragraph is taken to be a term and the lines separately parsed
|
@@ -984,9 +985,9 @@ As the wording suggests, inline links provide all information inline in the text
|
|
984
985
|
style links only provide the link text in the text flow and everything else is defined
|
985
986
|
elsewhere. This also allows you to reuse link definitions.
|
986
987
|
|
987
|
-
An inline style link can be created by surrounding the link text
|
988
|
-
immediately by the link URL (and an optional title in
|
989
|
-
one space) in normal parentheses. For example:
|
988
|
+
An inline style link can be created by surrounding the link text which must contain at least one
|
989
|
+
character with square brackets, followed immediately by the link URL (and an optional title in
|
990
|
+
single or double quotes preceded by at least one space) in normal parentheses. For example:
|
990
991
|
|
991
992
|
This is [a link](http://rubyforge.org) to a page.
|
992
993
|
A [link](../test "local URI") can also have a title.
|
@@ -1049,11 +1050,13 @@ The link definition has the following structure:
|
|
1049
1050
|
|
1050
1051
|
Images can be specified via a syntax that is similar to the one used by links. The difference is
|
1051
1052
|
that you have to use an exclamation mark before the first square bracket and that the link text of a
|
1052
|
-
normal link
|
1053
|
-
written inline or reference style. For
|
1053
|
+
normal link, which may also be the empty string in case of image links, becomes the alternative text
|
1054
|
+
of the image link. As with normal links, image links can be written inline or reference style. For
|
1055
|
+
example:
|
1054
1056
|
|
1055
1057
|
Here comes a ![smiley](../images/smiley.png)! And here
|
1056
1058
|
![too](../images/other.png 'Title text'). Or ![here].
|
1059
|
+
With empty alt text ![](see.jpg)
|
1057
1060
|
|
1058
1061
|
The link definition for images is exactly the same as the link definition for normal links.
|
1059
1062
|
|
data/lib/kramdown/converter.rb
CHANGED
@@ -29,6 +29,14 @@ module Kramdown
|
|
29
29
|
# Converts a Kramdown::Document to HTML.
|
30
30
|
class Html < Base
|
31
31
|
|
32
|
+
include ::Kramdown::Utils::HTML
|
33
|
+
|
34
|
+
# DEPRECATED: use #html_attributes
|
35
|
+
def options_for_element(el)
|
36
|
+
warn("DEPRECATION WARNING: this method will be deprecated in the next release, use #html_attributes instead")
|
37
|
+
html_attributes(el)
|
38
|
+
end
|
39
|
+
|
32
40
|
# :stopdoc:
|
33
41
|
|
34
42
|
# Defines the amount of indentation used when nesting HTML tags.
|
@@ -73,41 +81,41 @@ module Kramdown
|
|
73
81
|
escape_html(el.value, :text)
|
74
82
|
end
|
75
83
|
|
76
|
-
def convert_eob(el, indent, opts)
|
77
|
-
''
|
78
|
-
end
|
79
|
-
|
80
84
|
def convert_p(el, indent, opts)
|
81
|
-
|
85
|
+
if el.options[:transparent]
|
86
|
+
"#{inner(el, indent, opts)}"
|
87
|
+
else
|
88
|
+
"#{' '*indent}<p#{html_attributes(el)}>#{inner(el, indent, opts)}</p>\n"
|
89
|
+
end
|
82
90
|
end
|
83
91
|
|
84
92
|
def convert_codeblock(el, indent, opts)
|
85
|
-
if el.
|
93
|
+
if el.options[:attr] && el.options[:attr]['lang'] && HIGHLIGHTING_AVAILABLE
|
86
94
|
el = Marshal.load(Marshal.dump(el)) # so that the original is not changed
|
87
95
|
opts = {:wrap => @doc.options[:coderay_wrap], :line_numbers => @doc.options[:coderay_line_numbers],
|
88
96
|
:line_number_start => @doc.options[:coderay_line_number_start], :tab_width => @doc.options[:coderay_tab_width],
|
89
97
|
:bold_every => @doc.options[:coderay_bold_every], :css => @doc.options[:coderay_css]}
|
90
98
|
result = CodeRay.scan(el.value, el.options[:attr].delete('lang').to_sym).html(opts).chomp + "\n"
|
91
|
-
"#{' '*indent}<div#{
|
99
|
+
"#{' '*indent}<div#{html_attributes(el)}>#{result}#{' '*indent}</div>\n"
|
92
100
|
else
|
93
|
-
result =
|
101
|
+
result = escape_html(el.value)
|
94
102
|
if el.options[:attr] && el.options[:attr].has_key?('class') && el.options[:attr]['class'] =~ /\bshow-whitespaces\b/
|
95
103
|
result.gsub!(/(?:(^[ \t]+)|([ \t]+$)|([ \t]+))/) do |m|
|
96
104
|
suffix = ($1 ? '-l' : ($2 ? '-r' : ''))
|
97
105
|
m.scan(/./).map do |c|
|
98
106
|
case c
|
99
107
|
when "\t" then "<span class=\"ws-tab#{suffix}\">\t</span>"
|
100
|
-
when " " then "<span class=\"ws-space#{suffix}\"
|
108
|
+
when " " then "<span class=\"ws-space#{suffix}\">⋅</span>"
|
101
109
|
end
|
102
110
|
end.join('')
|
103
111
|
end
|
104
112
|
end
|
105
|
-
"#{' '*indent}<pre#{
|
113
|
+
"#{' '*indent}<pre#{html_attributes(el)}><code>#{result}#{result =~ /\n\Z/ ? '' : "\n"}</code></pre>\n"
|
106
114
|
end
|
107
115
|
end
|
108
116
|
|
109
117
|
def convert_blockquote(el, indent, opts)
|
110
|
-
"#{' '*indent}<blockquote#{
|
118
|
+
"#{' '*indent}<blockquote#{html_attributes(el)}>\n#{inner(el, indent, opts)}#{' '*indent}</blockquote>\n"
|
111
119
|
end
|
112
120
|
|
113
121
|
def convert_header(el, indent, opts)
|
@@ -115,8 +123,12 @@ module Kramdown
|
|
115
123
|
if @doc.options[:auto_ids] && !(el.options[:attr] && el.options[:attr]['id'])
|
116
124
|
(el.options[:attr] ||= {})['id'] = generate_id(el.options[:raw_text])
|
117
125
|
end
|
118
|
-
@toc << [el.options[:level], el.options[:attr]['id'], el.children] if el.options[:attr] && el.options[:attr]['id']
|
119
|
-
"#{' '*indent}<h#{el.options[:level]}#{
|
126
|
+
@toc << [el.options[:level], el.options[:attr]['id'], el.children] if el.options[:attr] && el.options[:attr]['id'] && within_toc_depth?(el)
|
127
|
+
"#{' '*indent}<h#{el.options[:level]}#{html_attributes(el)}>#{inner(el, indent, opts)}</h#{el.options[:level]}>\n"
|
128
|
+
end
|
129
|
+
|
130
|
+
def within_toc_depth?(el)
|
131
|
+
@doc.options[:toc_depth] <= 0 || el.options[:level] <= @doc.options[:toc_depth]
|
120
132
|
end
|
121
133
|
|
122
134
|
def convert_hr(el, indent, opts)
|
@@ -128,16 +140,16 @@ module Kramdown
|
|
128
140
|
@toc_code = [el.type, el.options[:attr], (0..128).to_a.map{|a| rand(36).to_s(36)}.join]
|
129
141
|
@toc_code.last
|
130
142
|
else
|
131
|
-
"#{' '*indent}<#{el.type}#{
|
143
|
+
"#{' '*indent}<#{el.type}#{html_attributes(el)}>\n#{inner(el, indent, opts)}#{' '*indent}</#{el.type}>\n"
|
132
144
|
end
|
133
145
|
end
|
134
146
|
alias :convert_ol :convert_ul
|
135
147
|
alias :convert_dl :convert_ul
|
136
148
|
|
137
149
|
def convert_li(el, indent, opts)
|
138
|
-
output = ' '*indent << "<#{el.type}" <<
|
150
|
+
output = ' '*indent << "<#{el.type}" << html_attributes(el) << ">"
|
139
151
|
res = inner(el, indent, opts)
|
140
|
-
if el.children.empty? || el.children.first.options[:
|
152
|
+
if el.children.empty? || (el.children.first.type == :p && el.children.first.options[:transparent])
|
141
153
|
output << res << (res =~ /\n\Z/ ? ' '*indent : '')
|
142
154
|
else
|
143
155
|
output << "\n" << res << ' '*indent
|
@@ -147,22 +159,19 @@ module Kramdown
|
|
147
159
|
alias :convert_dd :convert_li
|
148
160
|
|
149
161
|
def convert_dt(el, indent, opts)
|
150
|
-
"#{' '*indent}<dt#{
|
162
|
+
"#{' '*indent}<dt#{html_attributes(el)}>#{inner(el, indent, opts)}</dt>\n"
|
151
163
|
end
|
152
164
|
|
153
165
|
HTML_TAGS_WITH_BODY=['div', 'script']
|
154
166
|
|
155
167
|
def convert_html_element(el, indent, opts)
|
156
168
|
res = inner(el, indent, opts)
|
157
|
-
if
|
158
|
-
|
159
|
-
res.chomp + (el.options[:category] == :block ? "\n" : '')
|
160
|
-
elsif el.options[:category] == :span
|
161
|
-
"<#{el.value}#{options_for_element(el)}" << (!res.empty? ? ">#{res}</#{el.value}>" : " />")
|
169
|
+
if el.options[:category] == :span
|
170
|
+
"<#{el.value}#{html_attributes(el)}" << (!res.empty? ? ">#{res}</#{el.value}>" : " />")
|
162
171
|
else
|
163
172
|
output = ''
|
164
173
|
output << ' '*indent if !el.options[:parent_is_raw]
|
165
|
-
output << "<#{el.value}#{
|
174
|
+
output << "<#{el.value}#{html_attributes(el)}"
|
166
175
|
if !res.empty? && el.options[:parse_type] != :block
|
167
176
|
output << ">#{res}</#{el.value}>"
|
168
177
|
elsif !res.empty?
|
@@ -195,11 +204,11 @@ module Kramdown
|
|
195
204
|
"#{' '*(indent + INDENTATION)}" + (a == :default ? "<col />" : "<col align=\"#{a}\" />") + "\n"
|
196
205
|
end.join('')
|
197
206
|
end
|
198
|
-
"#{' '*indent}<table#{
|
207
|
+
"#{' '*indent}<table#{html_attributes(el)}>\n#{alignment}#{inner(el, indent, opts)}#{' '*indent}</table>\n"
|
199
208
|
end
|
200
209
|
|
201
210
|
def convert_thead(el, indent, opts)
|
202
|
-
"#{' '*indent}<#{el.type}#{
|
211
|
+
"#{' '*indent}<#{el.type}#{html_attributes(el)}>\n#{inner(el, indent, opts)}#{' '*indent}</#{el.type}>\n"
|
203
212
|
end
|
204
213
|
alias :convert_tbody :convert_thead
|
205
214
|
alias :convert_tfoot :convert_thead
|
@@ -207,10 +216,18 @@ module Kramdown
|
|
207
216
|
|
208
217
|
def convert_td(el, indent, opts)
|
209
218
|
res = inner(el, indent, opts)
|
210
|
-
"#{' '*indent}<#{el.type}#{
|
219
|
+
"#{' '*indent}<#{el.type}#{html_attributes(el)}>#{res.empty? ? " " : res}</#{el.type}>\n"
|
211
220
|
end
|
212
221
|
alias :convert_th :convert_td
|
213
222
|
|
223
|
+
def convert_comment(el, indent, opts)
|
224
|
+
if el.options[:category] == :block
|
225
|
+
"#{' '*indent}<!-- #{el.value} -->\n"
|
226
|
+
else
|
227
|
+
"<!-- #{el.value} -->"
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
214
231
|
def convert_br(el, indent, opts)
|
215
232
|
"<br />"
|
216
233
|
end
|
@@ -225,15 +242,15 @@ module Kramdown
|
|
225
242
|
end
|
226
243
|
res = inner(el, indent, opts)
|
227
244
|
res = obfuscate(res) if do_obfuscation
|
228
|
-
"<a#{
|
245
|
+
"<a#{html_attributes(el)}>#{res}</a>"
|
229
246
|
end
|
230
247
|
|
231
248
|
def convert_img(el, indent, opts)
|
232
|
-
"<img#{
|
249
|
+
"<img#{html_attributes(el)} />"
|
233
250
|
end
|
234
251
|
|
235
252
|
def convert_codespan(el, indent, opts)
|
236
|
-
"<code#{
|
253
|
+
"<code#{html_attributes(el)}>#{escape_html(el.value)}</code>"
|
237
254
|
end
|
238
255
|
|
239
256
|
def convert_footnote(el, indent, opts)
|
@@ -244,29 +261,33 @@ module Kramdown
|
|
244
261
|
end
|
245
262
|
|
246
263
|
def convert_raw(el, indent, opts)
|
247
|
-
el.value
|
264
|
+
el.value + (el.options[:category] == :block ? "\n" : '')
|
248
265
|
end
|
249
266
|
|
250
267
|
def convert_em(el, indent, opts)
|
251
|
-
"<#{el.type}#{
|
268
|
+
"<#{el.type}#{html_attributes(el)}>#{inner(el, indent, opts)}</#{el.type}>"
|
252
269
|
end
|
253
270
|
alias :convert_strong :convert_em
|
254
271
|
|
255
272
|
def convert_entity(el, indent, opts)
|
256
|
-
|
273
|
+
entity_to_str(el.value)
|
257
274
|
end
|
258
275
|
|
259
276
|
TYPOGRAPHIC_SYMS = {
|
260
|
-
:mdash => '
|
261
|
-
:
|
262
|
-
:
|
277
|
+
:mdash => [::Kramdown::Utils::Entities.entity('mdash')],
|
278
|
+
:ndash => [::Kramdown::Utils::Entities.entity('ndash')],
|
279
|
+
:hellip => [::Kramdown::Utils::Entities.entity('hellip')],
|
280
|
+
:laquo_space => [::Kramdown::Utils::Entities.entity('laquo'), ::Kramdown::Utils::Entities.entity('nbsp')],
|
281
|
+
:raquo_space => [::Kramdown::Utils::Entities.entity('nbsp'), ::Kramdown::Utils::Entities.entity('raquo')],
|
282
|
+
:laquo => [::Kramdown::Utils::Entities.entity('laquo')],
|
283
|
+
:raquo => [::Kramdown::Utils::Entities.entity('raquo')]
|
263
284
|
}
|
264
285
|
def convert_typographic_sym(el, indent, opts)
|
265
|
-
TYPOGRAPHIC_SYMS[el.value]
|
286
|
+
TYPOGRAPHIC_SYMS[el.value].map {|e| entity_to_str(e)}.join('')
|
266
287
|
end
|
267
288
|
|
268
289
|
def convert_smart_quote(el, indent, opts)
|
269
|
-
|
290
|
+
entity_to_str(::Kramdown::Utils::Entities.entity(el.value.to_s))
|
270
291
|
end
|
271
292
|
|
272
293
|
def convert_math(el, indent, opts)
|
@@ -276,7 +297,7 @@ module Kramdown
|
|
276
297
|
el.options[:attr]['class'] += (el.options[:attr]['class'].empty? ? '' : ' ') + 'math'
|
277
298
|
type = 'span'
|
278
299
|
type = 'div' if el.options[:category] == :block
|
279
|
-
"<#{type}#{
|
300
|
+
"<#{type}#{html_attributes(el)}>#{escape_html(el.value)}</#{type}>#{type == 'div' ? "\n" : ''}"
|
280
301
|
end
|
281
302
|
|
282
303
|
def convert_abbreviation(el, indent, opts)
|
@@ -305,9 +326,10 @@ module Kramdown
|
|
305
326
|
stack = []
|
306
327
|
toc.each do |level, id, children|
|
307
328
|
li = Element.new(:li, nil, {:level => level})
|
329
|
+
li.children << Element.new(:p, nil, {:transparent => true})
|
308
330
|
a = Element.new(:a, nil, {:attr => {:href => "##{id}"}})
|
309
331
|
a.children += children
|
310
|
-
li.children << a
|
332
|
+
li.children.last.children << a
|
311
333
|
li.children << Element.new(type)
|
312
334
|
|
313
335
|
success = false
|
@@ -363,34 +385,6 @@ module Kramdown
|
|
363
385
|
(ol.children.empty? ? '' : "<div class=\"footnotes\">\n#{convert(ol, 2)}</div>\n")
|
364
386
|
end
|
365
387
|
|
366
|
-
# Return the string with the attributes of the element +el+.
|
367
|
-
def options_for_element(el)
|
368
|
-
(el.options[:attr] || {}).map {|k,v| v.nil? ? '' : " #{k}=\"#{escape_html(v.to_s, :no_entities)}\"" }.sort.join('')
|
369
|
-
end
|
370
|
-
|
371
|
-
ESCAPE_MAP = {
|
372
|
-
'<' => '<',
|
373
|
-
'>' => '>',
|
374
|
-
'&' => '&',
|
375
|
-
'"' => '"'
|
376
|
-
}
|
377
|
-
ESCAPE_ALL_RE = Regexp.union(*ESCAPE_MAP.collect {|k,v| k})
|
378
|
-
ESCAPE_NO_ENTITIES_RE = Regexp.union(REXML::Parsers::BaseParser::REFERENCE_RE, ESCAPE_ALL_RE)
|
379
|
-
ESCAPE_NORMAL = Regexp.union(REXML::Parsers::BaseParser::REFERENCE_RE, /<|>|&/)
|
380
|
-
ESCAPE_RE_FROM_TYPE = {
|
381
|
-
:all => ESCAPE_ALL_RE,
|
382
|
-
:no_entities => ESCAPE_NO_ENTITIES_RE,
|
383
|
-
:text => ESCAPE_NORMAL
|
384
|
-
}
|
385
|
-
|
386
|
-
# Escape the special HTML characters in the string +str+. The parameter +type+ specifies what
|
387
|
-
# is escaped: <tt>:all</tt> - all special HTML characters as well as entities,
|
388
|
-
# <tt>:no_entities</tt> - all special HTML characters but no entities, <tt>:text</tt> - all
|
389
|
-
# special HTML characters except the quotation mark but no entities.
|
390
|
-
def escape_html(str, type = :all)
|
391
|
-
str.gsub(ESCAPE_RE_FROM_TYPE[type]) {|m| ESCAPE_MAP[m] || m}
|
392
|
-
end
|
393
|
-
|
394
388
|
end
|
395
389
|
|
396
390
|
end
|