bean-kramdown 0.13.5
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.
- data/AUTHORS +1 -0
- data/CONTRIBUTERS +11 -0
- data/COPYING +24 -0
- data/ChangeLog +6683 -0
- data/GPL +674 -0
- data/README +43 -0
- data/VERSION +1 -0
- data/bin/kramdown +78 -0
- data/lib/kramdown.rb +23 -0
- data/lib/kramdown/compatibility.rb +49 -0
- data/lib/kramdown/converter.rb +41 -0
- data/lib/kramdown/converter/base.rb +169 -0
- data/lib/kramdown/converter/bean_html.rb +71 -0
- data/lib/kramdown/converter/html.rb +411 -0
- data/lib/kramdown/converter/kramdown.rb +428 -0
- data/lib/kramdown/converter/latex.rb +607 -0
- data/lib/kramdown/converter/toc.rb +82 -0
- data/lib/kramdown/document.rb +119 -0
- data/lib/kramdown/element.rb +524 -0
- data/lib/kramdown/error.rb +30 -0
- data/lib/kramdown/options.rb +373 -0
- data/lib/kramdown/parser.rb +39 -0
- data/lib/kramdown/parser/base.rb +136 -0
- data/lib/kramdown/parser/bean_kramdown.rb +25 -0
- data/lib/kramdown/parser/bean_kramdown/info_box.rb +52 -0
- data/lib/kramdown/parser/bean_kramdown/oembed.rb +230 -0
- data/lib/kramdown/parser/html.rb +570 -0
- data/lib/kramdown/parser/kramdown.rb +339 -0
- data/lib/kramdown/parser/kramdown/abbreviation.rb +71 -0
- data/lib/kramdown/parser/kramdown/autolink.rb +53 -0
- data/lib/kramdown/parser/kramdown/blank_line.rb +43 -0
- data/lib/kramdown/parser/kramdown/block_boundary.rb +46 -0
- data/lib/kramdown/parser/kramdown/blockquote.rb +51 -0
- data/lib/kramdown/parser/kramdown/codeblock.rb +63 -0
- data/lib/kramdown/parser/kramdown/codespan.rb +56 -0
- data/lib/kramdown/parser/kramdown/emphasis.rb +70 -0
- data/lib/kramdown/parser/kramdown/eob.rb +39 -0
- data/lib/kramdown/parser/kramdown/escaped_chars.rb +38 -0
- data/lib/kramdown/parser/kramdown/extensions.rb +204 -0
- data/lib/kramdown/parser/kramdown/footnote.rb +74 -0
- data/lib/kramdown/parser/kramdown/header.rb +68 -0
- data/lib/kramdown/parser/kramdown/horizontal_rule.rb +39 -0
- data/lib/kramdown/parser/kramdown/html.rb +169 -0
- data/lib/kramdown/parser/kramdown/html_entity.rb +44 -0
- data/lib/kramdown/parser/kramdown/image.rb +157 -0
- data/lib/kramdown/parser/kramdown/line_break.rb +38 -0
- data/lib/kramdown/parser/kramdown/link.rb +154 -0
- data/lib/kramdown/parser/kramdown/list.rb +240 -0
- data/lib/kramdown/parser/kramdown/math.rb +65 -0
- data/lib/kramdown/parser/kramdown/paragraph.rb +63 -0
- data/lib/kramdown/parser/kramdown/smart_quotes.rb +214 -0
- data/lib/kramdown/parser/kramdown/table.rb +178 -0
- data/lib/kramdown/parser/kramdown/typographic_symbol.rb +52 -0
- data/lib/kramdown/parser/markdown.rb +69 -0
- data/lib/kramdown/utils.rb +42 -0
- data/lib/kramdown/utils/entities.rb +348 -0
- data/lib/kramdown/utils/html.rb +85 -0
- data/lib/kramdown/utils/ordered_hash.rb +100 -0
- data/lib/kramdown/version.rb +28 -0
- metadata +140 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2012 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
module Kramdown
|
24
|
+
module Parser
|
25
|
+
class Kramdown
|
26
|
+
|
27
|
+
LINE_BREAK = /( |\\\\)(?=\n)/
|
28
|
+
|
29
|
+
# Parse the line break at the current location.
|
30
|
+
def parse_line_break
|
31
|
+
@src.pos += @src.matched_size
|
32
|
+
@tree.children << Element.new(:br)
|
33
|
+
end
|
34
|
+
define_parser(:line_break, LINE_BREAK, '( |\\\\)(?=\n)')
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2012 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
#
|
24
|
+
# This file has been edited to suit the needs of The Beans Group Ltd. Changes were made to the types of media availbable
|
25
|
+
# images keep their ! however new types are ? for oembedd etc
|
26
|
+
# If you wish to change the types of media you need to change the LINK_START constant to include your special symbol
|
27
|
+
# for the new media object as well as change the reg ex on the parser definition towards the bottom of this file.
|
28
|
+
#
|
29
|
+
|
30
|
+
module Kramdown
|
31
|
+
module Parser
|
32
|
+
class Kramdown
|
33
|
+
|
34
|
+
# Normalize the link identifier.
|
35
|
+
def normalize_link_id(id)
|
36
|
+
id.gsub(/(\s|\n)+/, ' ').downcase
|
37
|
+
end
|
38
|
+
|
39
|
+
LINK_DEFINITION_START = /^#{OPT_SPACE}\[([^\n\]]+)\]:[ \t]*(?:<(.*?)>|([^'"\n]*?\S[^'"\n]*?))[ \t]*?(?:\n?[ \t]*?(["'])(.+?)\4[ \t]*?)?\n/
|
40
|
+
|
41
|
+
# Parse the link definition at the current location.
|
42
|
+
def parse_link_definition
|
43
|
+
@src.pos += @src.matched_size
|
44
|
+
link_id, link_url, link_title = normalize_link_id(@src[1]), @src[2] || @src[3], @src[5]
|
45
|
+
warning("Duplicate link ID '#{link_id}' - overwriting") if @link_defs[link_id]
|
46
|
+
@link_defs[link_id] = [link_url, link_title]
|
47
|
+
@tree.children << Element.new(:eob, :link_def)
|
48
|
+
true
|
49
|
+
end
|
50
|
+
define_parser(:link_definition, LINK_DEFINITION_START)
|
51
|
+
|
52
|
+
|
53
|
+
# This helper methods adds the approriate attributes to the element +el+ of type +a+ or +img+
|
54
|
+
# and the element itself to the @tree.
|
55
|
+
def add_link(el, href, title, alt_text = nil)
|
56
|
+
if el.type == :a
|
57
|
+
el.attr['href'] = href
|
58
|
+
else
|
59
|
+
el.attr['src'] = href
|
60
|
+
el.attr['alt'] = alt_text
|
61
|
+
el.children.clear
|
62
|
+
end
|
63
|
+
el.attr['title'] = title if title
|
64
|
+
@tree.children << el
|
65
|
+
end
|
66
|
+
|
67
|
+
LINK_BRACKET_STOP_RE = /(\])|!?\[/
|
68
|
+
LINK_PAREN_STOP_RE = /(\()|(\))|\s(?=['"])/
|
69
|
+
LINK_INLINE_ID_RE = /\s*?\[([^\]]+)?\]/
|
70
|
+
LINK_INLINE_TITLE_RE = /\s*?(["'])(.+?)\1\s*?\)/
|
71
|
+
LINK_START = /\[(?=[^^])/
|
72
|
+
|
73
|
+
# Parse the link at the current scanner position. This method is used to parse normal links as
|
74
|
+
# well as image links.
|
75
|
+
def parse_link
|
76
|
+
result = @src.scan(LINK_START)
|
77
|
+
reset_pos = @src.pos
|
78
|
+
link_type = :a
|
79
|
+
|
80
|
+
# no nested links allowed
|
81
|
+
if link_type == :a && (@tree.type == :img || @tree.type == :a || @stack.any? {|t,s| t && (t.type == :img || t.type == :a)})
|
82
|
+
add_text(result)
|
83
|
+
return
|
84
|
+
end
|
85
|
+
el = Element.new(link_type)
|
86
|
+
|
87
|
+
count = 1
|
88
|
+
found = parse_spans(el, LINK_BRACKET_STOP_RE) do
|
89
|
+
count = count + (@src[1] ? -1 : 1)
|
90
|
+
count - el.children.select {|c| c.type == :img}.size == 0
|
91
|
+
end
|
92
|
+
if !found || (link_type == :a && el.children.empty?)
|
93
|
+
@src.pos = reset_pos
|
94
|
+
add_text(result)
|
95
|
+
return
|
96
|
+
end
|
97
|
+
alt_text = extract_string(reset_pos...@src.pos, @src)
|
98
|
+
@src.scan(LINK_BRACKET_STOP_RE)
|
99
|
+
|
100
|
+
# reference style link or no link url
|
101
|
+
if @src.scan(LINK_INLINE_ID_RE) || !@src.check(/\(/)
|
102
|
+
link_id = normalize_link_id(@src[1] || alt_text)
|
103
|
+
if @link_defs.has_key?(link_id)
|
104
|
+
add_link(el, @link_defs[link_id].first, @link_defs[link_id].last, alt_text)
|
105
|
+
else
|
106
|
+
warning("No link definition for link ID '#{link_id}' found")
|
107
|
+
@src.pos = reset_pos
|
108
|
+
add_text(result)
|
109
|
+
end
|
110
|
+
return
|
111
|
+
end
|
112
|
+
|
113
|
+
# link url in parentheses
|
114
|
+
if @src.scan(/\(<(.*?)>/)
|
115
|
+
link_url = @src[1]
|
116
|
+
if @src.scan(/\)/)
|
117
|
+
add_link(el, link_url, nil, alt_text)
|
118
|
+
return
|
119
|
+
end
|
120
|
+
else
|
121
|
+
link_url = ''
|
122
|
+
nr_of_brackets = 0
|
123
|
+
while temp = @src.scan_until(LINK_PAREN_STOP_RE)
|
124
|
+
link_url << temp
|
125
|
+
if @src[2]
|
126
|
+
nr_of_brackets -= 1
|
127
|
+
break if nr_of_brackets == 0
|
128
|
+
elsif @src[1]
|
129
|
+
nr_of_brackets += 1
|
130
|
+
else
|
131
|
+
break
|
132
|
+
end
|
133
|
+
end
|
134
|
+
link_url = link_url[1..-2]
|
135
|
+
link_url.strip!
|
136
|
+
|
137
|
+
if nr_of_brackets == 0
|
138
|
+
add_link(el, link_url, nil, alt_text)
|
139
|
+
return
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
if @src.scan(LINK_INLINE_TITLE_RE)
|
144
|
+
add_link(el, link_url, @src[2], alt_text)
|
145
|
+
else
|
146
|
+
@src.pos = reset_pos
|
147
|
+
add_text(result)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
define_parser(:link, LINK_START, '\[')
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,240 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2012 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'kramdown/parser/kramdown/blank_line'
|
24
|
+
require 'kramdown/parser/kramdown/eob'
|
25
|
+
require 'kramdown/parser/kramdown/horizontal_rule'
|
26
|
+
require 'kramdown/parser/kramdown/extensions'
|
27
|
+
|
28
|
+
module Kramdown
|
29
|
+
module Parser
|
30
|
+
class Kramdown
|
31
|
+
|
32
|
+
LIST_ITEM_IAL = /^\s*(?:\{:(?!(?:#{ALD_ID_NAME})?:|\/)(#{ALD_ANY_CHARS}+)\})\s*/
|
33
|
+
LIST_ITEM_IAL_CHECK = /^#{LIST_ITEM_IAL}?\s*\n/
|
34
|
+
|
35
|
+
# Used for parsing the first line of a list item or a definition, i.e. the line with list item
|
36
|
+
# marker or the definition marker.
|
37
|
+
def parse_first_list_line(indentation, content)
|
38
|
+
if content =~ self.class::LIST_ITEM_IAL_CHECK
|
39
|
+
indentation = 4
|
40
|
+
else
|
41
|
+
while content =~ /^ *\t/
|
42
|
+
temp = content.scan(/^ */).first.length + indentation
|
43
|
+
content.sub!(/^( *)(\t+)/) {$1 << " "*(4 - (temp % 4) + ($2.length - 1)*4)}
|
44
|
+
end
|
45
|
+
indentation += content.scan(/^ */).first.length
|
46
|
+
end
|
47
|
+
content.sub!(/^\s*/, '')
|
48
|
+
|
49
|
+
indent_re = /^ {#{indentation}}/
|
50
|
+
content_re = /^(?:(?:\t| {4}){#{indentation / 4}} {#{indentation % 4}}|(?:\t| {4}){#{indentation / 4 + 1}}).*\S.*\n/
|
51
|
+
lazy_re = /(?!^ {0,#{[indentation, 3].min}}(?:#{IAL_BLOCK}|#{LAZY_END_HTML_STOP}|#{LAZY_END_HTML_START})).*\S.*\n/
|
52
|
+
[content, indentation, content_re, lazy_re, indent_re]
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
LIST_START_UL = /^(#{OPT_SPACE}[+*-])([\t| ].*?\n)/
|
57
|
+
LIST_START_OL = /^(#{OPT_SPACE}\d+\.)([\t| ].*?\n)/
|
58
|
+
LIST_START = /#{LIST_START_UL}|#{LIST_START_OL}/
|
59
|
+
|
60
|
+
# Parse the ordered or unordered list at the current location.
|
61
|
+
def parse_list
|
62
|
+
type, list_start_re = (@src.check(LIST_START_UL) ? [:ul, LIST_START_UL] : [:ol, LIST_START_OL])
|
63
|
+
list = new_block_el(type)
|
64
|
+
|
65
|
+
item = nil
|
66
|
+
content_re, lazy_re, indent_re = nil
|
67
|
+
eob_found = false
|
68
|
+
nested_list_found = false
|
69
|
+
last_is_blank = false
|
70
|
+
while !@src.eos?
|
71
|
+
if last_is_blank && @src.check(HR_START)
|
72
|
+
break
|
73
|
+
elsif @src.scan(EOB_MARKER)
|
74
|
+
eob_found = true
|
75
|
+
break
|
76
|
+
elsif @src.scan(list_start_re)
|
77
|
+
item = Element.new(:li)
|
78
|
+
item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
|
79
|
+
list.children << item
|
80
|
+
|
81
|
+
item.value.sub!(self.class::LIST_ITEM_IAL) do |match|
|
82
|
+
parse_attribute_list($1, item.options[:ial] ||= {})
|
83
|
+
''
|
84
|
+
end
|
85
|
+
|
86
|
+
list_start_re = (type == :ul ? /^( {0,#{[3, indentation - 1].min}}[+*-])([\t| ].*?\n)/ :
|
87
|
+
/^( {0,#{[3, indentation - 1].min}}\d+\.)([\t| ].*?\n)/)
|
88
|
+
nested_list_found = (item.value =~ LIST_START)
|
89
|
+
last_is_blank = false
|
90
|
+
elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re)))
|
91
|
+
result.sub!(/^(\t+)/) { " "*($1 ? 4*$1.length : 0) }
|
92
|
+
result.sub!(indent_re, '')
|
93
|
+
if !nested_list_found && result =~ LIST_START
|
94
|
+
item.value << "^\n"
|
95
|
+
nested_list_found = true
|
96
|
+
end
|
97
|
+
item.value << result
|
98
|
+
last_is_blank = false
|
99
|
+
elsif result = @src.scan(BLANK_LINE)
|
100
|
+
nested_list_found = true
|
101
|
+
last_is_blank = true
|
102
|
+
item.value << result
|
103
|
+
else
|
104
|
+
break
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
@tree.children << list
|
109
|
+
|
110
|
+
last = nil
|
111
|
+
list.children.each do |it|
|
112
|
+
temp = Element.new(:temp)
|
113
|
+
parse_blocks(temp, it.value)
|
114
|
+
it.children = temp.children
|
115
|
+
it.value = nil
|
116
|
+
next if it.children.size == 0
|
117
|
+
|
118
|
+
# Handle the case where an EOB marker is inserted by a block IAL for the first paragraph
|
119
|
+
it.children.delete_at(1) if it.children.first.type == :p &&
|
120
|
+
it.children.length >= 2 && it.children[1].type == :eob && it.children.first.options[:ial]
|
121
|
+
|
122
|
+
if it.children.first.type == :p &&
|
123
|
+
(it.children.length < 2 || it.children[1].type != :blank ||
|
124
|
+
(it == list.children.last && it.children.length == 2 && !eob_found)) &&
|
125
|
+
(list.children.last != it || list.children.size == 1 ||
|
126
|
+
list.children[0..-2].any? {|cit| cit.children.first.type != :p || cit.children.first.options[:transparent]})
|
127
|
+
it.children.first.children.first.value << "\n" if it.children.size > 1 && it.children[1].type != :blank
|
128
|
+
it.children.first.options[:transparent] = true
|
129
|
+
end
|
130
|
+
|
131
|
+
if it.children.last.type == :blank
|
132
|
+
last = it.children.pop
|
133
|
+
else
|
134
|
+
last = nil
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
@tree.children << last if !last.nil? && !eob_found
|
139
|
+
|
140
|
+
true
|
141
|
+
end
|
142
|
+
define_parser(:list, LIST_START)
|
143
|
+
|
144
|
+
|
145
|
+
DEFINITION_LIST_START = /^(#{OPT_SPACE}:)([\t| ].*?\n)/
|
146
|
+
|
147
|
+
# Parse the ordered or unordered list at the current location.
|
148
|
+
def parse_definition_list
|
149
|
+
children = @tree.children
|
150
|
+
if !children.last || (children.length == 1 && children.last.type != :p ) ||
|
151
|
+
(children.length >= 2 && children[-1].type != :p && (children[-1].type != :blank || children[-1].value != "\n" || children[-2].type != :p))
|
152
|
+
return false
|
153
|
+
end
|
154
|
+
|
155
|
+
first_as_para = false
|
156
|
+
deflist = new_block_el(:dl)
|
157
|
+
para = @tree.children.pop
|
158
|
+
if para.type == :blank
|
159
|
+
para = @tree.children.pop
|
160
|
+
first_as_para = true
|
161
|
+
end
|
162
|
+
para.children.first.value.split(/\n/).each do |term|
|
163
|
+
el = Element.new(:dt)
|
164
|
+
el.children << Element.new(:raw_text, term)
|
165
|
+
deflist.children << el
|
166
|
+
end
|
167
|
+
|
168
|
+
item = nil
|
169
|
+
content_re, lazy_re, indent_re = nil
|
170
|
+
def_start_re = DEFINITION_LIST_START
|
171
|
+
last_is_blank = false
|
172
|
+
while !@src.eos?
|
173
|
+
if @src.scan(def_start_re)
|
174
|
+
item = Element.new(:dd)
|
175
|
+
item.options[:first_as_para] = first_as_para
|
176
|
+
item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
|
177
|
+
deflist.children << item
|
178
|
+
|
179
|
+
item.value.sub!(self.class::LIST_ITEM_IAL) do |match|
|
180
|
+
parse_attribute_list($1, item.options[:ial] ||= {})
|
181
|
+
''
|
182
|
+
end
|
183
|
+
|
184
|
+
def_start_re = /^( {0,#{[3, indentation - 1].min}}:)([\t| ].*?\n)/
|
185
|
+
first_as_para = false
|
186
|
+
last_is_blank = false
|
187
|
+
elsif @src.check(EOB_MARKER)
|
188
|
+
break
|
189
|
+
elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re)))
|
190
|
+
result.sub!(/^(\t+)/) { " "*($1 ? 4*$1.length : 0) }
|
191
|
+
result.sub!(indent_re, '')
|
192
|
+
item.value << result
|
193
|
+
first_as_para = false
|
194
|
+
last_is_blank = false
|
195
|
+
elsif result = @src.scan(BLANK_LINE)
|
196
|
+
first_as_para = true
|
197
|
+
item.value << result
|
198
|
+
last_is_blank = true
|
199
|
+
else
|
200
|
+
break
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
last = nil
|
205
|
+
deflist.children.each do |it|
|
206
|
+
next if it.type == :dt
|
207
|
+
|
208
|
+
parse_blocks(it, it.value)
|
209
|
+
it.value = nil
|
210
|
+
next if it.children.size == 0
|
211
|
+
|
212
|
+
if it.children.last.type == :blank
|
213
|
+
last = it.children.pop
|
214
|
+
else
|
215
|
+
last = nil
|
216
|
+
end
|
217
|
+
if it.children.first.type == :p && !it.options.delete(:first_as_para)
|
218
|
+
it.children.first.children.first.value << "\n" if it.children.size > 1
|
219
|
+
it.children.first.options[:transparent] = true
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
if @tree.children.length >= 1 && @tree.children.last.type == :dl
|
224
|
+
@tree.children[-1].children.concat(deflist.children)
|
225
|
+
elsif @tree.children.length >= 2 && @tree.children[-1].type == :blank && @tree.children[-2].type == :dl
|
226
|
+
@tree.children.pop
|
227
|
+
@tree.children[-1].children.concat(deflist.children)
|
228
|
+
else
|
229
|
+
@tree.children << deflist
|
230
|
+
end
|
231
|
+
|
232
|
+
@tree.children << last if !last.nil?
|
233
|
+
|
234
|
+
true
|
235
|
+
end
|
236
|
+
define_parser(:definition_list, DEFINITION_LIST_START)
|
237
|
+
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2012 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'kramdown/parser/kramdown/block_boundary'
|
24
|
+
|
25
|
+
module Kramdown
|
26
|
+
module Parser
|
27
|
+
class Kramdown
|
28
|
+
|
29
|
+
BLOCK_MATH_START = /^#{OPT_SPACE}(\\)?\$\$(.*?)\$\$(\s*?\n)?/m
|
30
|
+
|
31
|
+
# Parse the math block at the current location.
|
32
|
+
def parse_block_math
|
33
|
+
if !after_block_boundary?
|
34
|
+
return false
|
35
|
+
elsif @src[1]
|
36
|
+
@src.scan(/^#{OPT_SPACE}\\/) if @src[3]
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
orig_pos = @src.pos
|
41
|
+
@src.pos += @src.matched_size
|
42
|
+
data = @src[2]
|
43
|
+
if before_block_boundary?
|
44
|
+
@tree.children << new_block_el(:math, data, nil, :category => :block)
|
45
|
+
true
|
46
|
+
else
|
47
|
+
@src.pos = orig_pos
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
define_parser(:block_math, BLOCK_MATH_START)
|
52
|
+
|
53
|
+
|
54
|
+
INLINE_MATH_START = /\$\$(.*?)\$\$/
|
55
|
+
|
56
|
+
# Parse the inline math at the current location.
|
57
|
+
def parse_inline_math
|
58
|
+
@src.pos += @src.matched_size
|
59
|
+
@tree.children << Element.new(:math, @src[1], nil, :category => :span)
|
60
|
+
end
|
61
|
+
define_parser(:inline_math, INLINE_MATH_START, '\$')
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|