bean-kramdown 0.13.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/AUTHORS +1 -0
  2. data/CONTRIBUTERS +11 -0
  3. data/COPYING +24 -0
  4. data/ChangeLog +6683 -0
  5. data/GPL +674 -0
  6. data/README +43 -0
  7. data/VERSION +1 -0
  8. data/bin/kramdown +78 -0
  9. data/lib/kramdown.rb +23 -0
  10. data/lib/kramdown/compatibility.rb +49 -0
  11. data/lib/kramdown/converter.rb +41 -0
  12. data/lib/kramdown/converter/base.rb +169 -0
  13. data/lib/kramdown/converter/bean_html.rb +71 -0
  14. data/lib/kramdown/converter/html.rb +411 -0
  15. data/lib/kramdown/converter/kramdown.rb +428 -0
  16. data/lib/kramdown/converter/latex.rb +607 -0
  17. data/lib/kramdown/converter/toc.rb +82 -0
  18. data/lib/kramdown/document.rb +119 -0
  19. data/lib/kramdown/element.rb +524 -0
  20. data/lib/kramdown/error.rb +30 -0
  21. data/lib/kramdown/options.rb +373 -0
  22. data/lib/kramdown/parser.rb +39 -0
  23. data/lib/kramdown/parser/base.rb +136 -0
  24. data/lib/kramdown/parser/bean_kramdown.rb +25 -0
  25. data/lib/kramdown/parser/bean_kramdown/info_box.rb +52 -0
  26. data/lib/kramdown/parser/bean_kramdown/oembed.rb +230 -0
  27. data/lib/kramdown/parser/html.rb +570 -0
  28. data/lib/kramdown/parser/kramdown.rb +339 -0
  29. data/lib/kramdown/parser/kramdown/abbreviation.rb +71 -0
  30. data/lib/kramdown/parser/kramdown/autolink.rb +53 -0
  31. data/lib/kramdown/parser/kramdown/blank_line.rb +43 -0
  32. data/lib/kramdown/parser/kramdown/block_boundary.rb +46 -0
  33. data/lib/kramdown/parser/kramdown/blockquote.rb +51 -0
  34. data/lib/kramdown/parser/kramdown/codeblock.rb +63 -0
  35. data/lib/kramdown/parser/kramdown/codespan.rb +56 -0
  36. data/lib/kramdown/parser/kramdown/emphasis.rb +70 -0
  37. data/lib/kramdown/parser/kramdown/eob.rb +39 -0
  38. data/lib/kramdown/parser/kramdown/escaped_chars.rb +38 -0
  39. data/lib/kramdown/parser/kramdown/extensions.rb +204 -0
  40. data/lib/kramdown/parser/kramdown/footnote.rb +74 -0
  41. data/lib/kramdown/parser/kramdown/header.rb +68 -0
  42. data/lib/kramdown/parser/kramdown/horizontal_rule.rb +39 -0
  43. data/lib/kramdown/parser/kramdown/html.rb +169 -0
  44. data/lib/kramdown/parser/kramdown/html_entity.rb +44 -0
  45. data/lib/kramdown/parser/kramdown/image.rb +157 -0
  46. data/lib/kramdown/parser/kramdown/line_break.rb +38 -0
  47. data/lib/kramdown/parser/kramdown/link.rb +154 -0
  48. data/lib/kramdown/parser/kramdown/list.rb +240 -0
  49. data/lib/kramdown/parser/kramdown/math.rb +65 -0
  50. data/lib/kramdown/parser/kramdown/paragraph.rb +63 -0
  51. data/lib/kramdown/parser/kramdown/smart_quotes.rb +214 -0
  52. data/lib/kramdown/parser/kramdown/table.rb +178 -0
  53. data/lib/kramdown/parser/kramdown/typographic_symbol.rb +52 -0
  54. data/lib/kramdown/parser/markdown.rb +69 -0
  55. data/lib/kramdown/utils.rb +42 -0
  56. data/lib/kramdown/utils/entities.rb +348 -0
  57. data/lib/kramdown/utils/html.rb +85 -0
  58. data/lib/kramdown/utils/ordered_hash.rb +100 -0
  59. data/lib/kramdown/version.rb +28 -0
  60. 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