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.
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