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,43 @@
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
+ BLANK_LINE = /(?:^\s*\n)+/
28
+
29
+ # Parse the blank line at the current postition.
30
+ def parse_blank_line
31
+ @src.pos += @src.matched_size
32
+ if @tree.children.last && @tree.children.last.type == :blank
33
+ @tree.children.last.value << @src.matched
34
+ else
35
+ @tree.children << new_block_el(:blank, @src.matched)
36
+ end
37
+ true
38
+ end
39
+ define_parser(:blank_line, BLANK_LINE)
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,46 @@
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/extensions'
24
+ require 'kramdown/parser/kramdown/blank_line'
25
+ require 'kramdown/parser/kramdown/eob'
26
+
27
+ module Kramdown
28
+ module Parser
29
+ class Kramdown
30
+
31
+ BLOCK_BOUNDARY = /#{BLANK_LINE}|#{EOB_MARKER}|#{IAL_BLOCK_START}|\Z/
32
+
33
+ # Return +true+ if we are after a block boundary.
34
+ def after_block_boundary?
35
+ !@tree.children.last || @tree.children.last.type == :blank ||
36
+ (@tree.children.last.type == :eob && @tree.children.last.value.nil?) || @block_ial
37
+ end
38
+
39
+ # Return +true+ if we are before a block boundary.
40
+ def before_block_boundary?
41
+ @src.check(self.class::BLOCK_BOUNDARY)
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,51 @@
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/extensions'
25
+ require 'kramdown/parser/kramdown/eob'
26
+
27
+ module Kramdown
28
+ module Parser
29
+ class Kramdown
30
+
31
+ BLOCKQUOTE_START = /^#{OPT_SPACE}> ?/
32
+
33
+ # Parse the blockquote at the current location.
34
+ def parse_blockquote
35
+ result = @src.scan(PARAGRAPH_MATCH)
36
+ while !@src.match?(self.class::LAZY_END)
37
+ result << @src.scan(PARAGRAPH_MATCH)
38
+ end
39
+ result.gsub!(BLOCKQUOTE_START, '')
40
+
41
+ el = new_block_el(:blockquote)
42
+ @tree.children << el
43
+ parse_blocks(el, result)
44
+ true
45
+ end
46
+ define_parser(:blockquote, BLOCKQUOTE_START)
47
+
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,63 @@
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/extensions'
25
+ require 'kramdown/parser/kramdown/eob'
26
+ require 'kramdown/parser/kramdown/paragraph'
27
+
28
+ module Kramdown
29
+ module Parser
30
+ class Kramdown
31
+
32
+ CODEBLOCK_START = INDENT
33
+ CODEBLOCK_MATCH = /(?:#{BLANK_LINE}?(?:#{INDENT}[ \t]*\S.*\n)+(?:(?!#{BLANK_LINE} {0,3}\S|#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START})^[ \t]*\S.*\n)*)*/
34
+
35
+ # Parse the indented codeblock at the current location.
36
+ def parse_codeblock
37
+ data = @src.scan(self.class::CODEBLOCK_MATCH)
38
+ data.gsub!(/\n( {0,3}\S)/, ' \\1')
39
+ data.gsub!(INDENT, '')
40
+ @tree.children << new_block_el(:codeblock, data)
41
+ true
42
+ end
43
+ define_parser(:codeblock, CODEBLOCK_START)
44
+
45
+
46
+ FENCED_CODEBLOCK_START = /^~{3,}/
47
+ FENCED_CODEBLOCK_MATCH = /^(~{3,})\s*?\n(.*?)^\1~*\s*?\n/m
48
+
49
+ # Parse the fenced codeblock at the current location.
50
+ def parse_codeblock_fenced
51
+ if @src.check(FENCED_CODEBLOCK_MATCH)
52
+ @src.pos += @src.matched_size
53
+ @tree.children << new_block_el(:codeblock, @src[2])
54
+ true
55
+ else
56
+ false
57
+ end
58
+ end
59
+ define_parser(:codeblock_fenced, FENCED_CODEBLOCK_START)
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,56 @@
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
+ CODESPAN_DELIMITER = /`+/
28
+
29
+ # Parse the codespan at the current scanner location.
30
+ def parse_codespan
31
+ result = @src.scan(CODESPAN_DELIMITER)
32
+ simple = (result.length == 1)
33
+ reset_pos = @src.pos
34
+
35
+ if simple && @src.pre_match =~ /\s\Z/ && @src.match?(/\s/)
36
+ add_text(result)
37
+ return
38
+ end
39
+
40
+ if text = @src.scan_until(/#{result}/)
41
+ text.sub!(/#{result}\Z/, '')
42
+ if !simple
43
+ text = text[1..-1] if text[0..0] == ' '
44
+ text = text[0..-2] if text[-1..-1] == ' '
45
+ end
46
+ @tree.children << Element.new(:codespan, text)
47
+ else
48
+ @src.pos = reset_pos
49
+ add_text(result)
50
+ end
51
+ end
52
+ define_parser(:codespan, CODESPAN_DELIMITER, '`')
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,70 @@
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
+ EMPHASIS_START = /(?:\*\*?|__?)/
28
+
29
+ # Parse the emphasis at the current location.
30
+ def parse_emphasis
31
+ result = @src.scan(EMPHASIS_START)
32
+ element = (result.length == 2 ? :strong : :em)
33
+ type = result[0..0]
34
+ reset_pos = @src.pos
35
+
36
+ if (type == '_' && @src.pre_match =~ /[[:alpha:]]\z/ && @src.check(/[[:alpha:]]/)) || @src.check(/\s/) ||
37
+ @tree.type == element || @stack.any? {|el, _| el.type == element}
38
+ add_text(result)
39
+ return
40
+ end
41
+
42
+ sub_parse = lambda do |delim, elem|
43
+ el = Element.new(elem)
44
+ stop_re = /#{Regexp.escape(delim)}/
45
+ found = parse_spans(el, stop_re) do
46
+ (@src.pre_match[-1, 1] !~ /\s/) &&
47
+ (elem != :em || !@src.match?(/#{Regexp.escape(delim*2)}(?!#{Regexp.escape(delim)})/)) &&
48
+ (type != '_' || !@src.match?(/#{Regexp.escape(delim)}[[:alpha:]]/)) && el.children.size > 0
49
+ end
50
+ [found, el, stop_re]
51
+ end
52
+
53
+ found, el, stop_re = sub_parse.call(result, element)
54
+ if !found && element == :strong && @tree.type != :em
55
+ @src.pos = reset_pos - 1
56
+ found, el, stop_re = sub_parse.call(type, :em)
57
+ end
58
+ if found
59
+ @src.scan(stop_re)
60
+ @tree.children << el
61
+ else
62
+ @src.pos = reset_pos
63
+ add_text(result)
64
+ end
65
+ end
66
+ define_parser(:emphasis, EMPHASIS_START, '\*|_')
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,39 @@
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
+ EOB_MARKER = /^\^\s*?\n/
28
+
29
+ # Parse the EOB marker at the current location.
30
+ def parse_eob_marker
31
+ @src.pos += @src.matched_size
32
+ @tree.children << new_block_el(:eob)
33
+ true
34
+ end
35
+ define_parser(:eob_marker, EOB_MARKER)
36
+
37
+ end
38
+ end
39
+ end
@@ -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
+ ESCAPED_CHARS = /\\([\\.*_+`<>()\[\]{}#!:|"'\$=-])/
28
+
29
+ # Parse the backslash-escaped character at the current location.
30
+ def parse_escaped_chars
31
+ @src.pos += @src.matched_size
32
+ add_text(@src[1])
33
+ end
34
+ define_parser(:escaped_chars, ESCAPED_CHARS, '\\\\')
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,204 @@
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
+ IAL_CLASS_ATTR = 'class'
28
+
29
+ # Parse the string +str+ and extract all attributes and add all found attributes to the hash
30
+ # +opts+.
31
+ def parse_attribute_list(str, opts)
32
+ str.scan(ALD_TYPE_ANY).each do |key, sep, val, id_attr, class_attr, ref|
33
+ if ref
34
+ (opts[:refs] ||= []) << ref
35
+ elsif class_attr
36
+ opts[IAL_CLASS_ATTR] = (opts[IAL_CLASS_ATTR] || '') << " #{class_attr}"
37
+ opts[IAL_CLASS_ATTR].lstrip!
38
+ elsif id_attr
39
+ opts['id'] = id_attr
40
+ else
41
+ val.gsub!(/\\(\}|#{sep})/, "\\1")
42
+ opts[key] = val
43
+ end
44
+ end
45
+ end
46
+
47
+ # Update the +ial+ with the information from the inline attribute list +opts+.
48
+ def update_ial_with_ial(ial, opts)
49
+ (ial[:refs] ||= []) << opts[:refs]
50
+ opts.each do |k,v|
51
+ if k == IAL_CLASS_ATTR
52
+ ial[k] = (ial[k] || '') << " #{v}"
53
+ ial[k].lstrip!
54
+ elsif k.kind_of?(String)
55
+ ial[k] = v
56
+ end
57
+ end
58
+ end
59
+
60
+ # Parse the generic extension at the current point. The parameter +type+ can either be :block
61
+ # or :span depending whether we parse a block or span extension tag.
62
+ def parse_extension_start_tag(type)
63
+ orig_pos = @src.pos
64
+ @src.pos += @src.matched_size
65
+
66
+ error_block = lambda do |msg|
67
+ warning(msg)
68
+ @src.pos = orig_pos
69
+ add_text(@src.getch) if type == :span
70
+ false
71
+ end
72
+
73
+ if @src[4] || @src.matched == '{:/}'
74
+ name = (@src[4] ? "for '#{@src[4]}' " : '')
75
+ return error_block.call("Invalid extension stop tag #{name}found - ignoring it")
76
+ end
77
+
78
+ ext = @src[1]
79
+ opts = {}
80
+ body = nil
81
+ parse_attribute_list(@src[2] || '', opts)
82
+
83
+ if !@src[3]
84
+ stop_re = (type == :block ? /#{EXT_BLOCK_STOP_STR % ext}/ : /#{EXT_STOP_STR % ext}/)
85
+ if result = @src.scan_until(stop_re)
86
+ body = result.sub!(stop_re, '')
87
+ body.chomp! if type == :block
88
+ else
89
+ return error_block.call("No stop tag for extension '#{ext}' found - ignoring it")
90
+ end
91
+ end
92
+
93
+ if !handle_extension(ext, opts, body, type)
94
+ error_block.call("Invalid extension with name '#{ext}' specified - ignoring it")
95
+ else
96
+ true
97
+ end
98
+ end
99
+
100
+ def handle_extension(name, opts, body, type)
101
+ case name
102
+ when 'comment'
103
+ @tree.children << Element.new(:comment, body, nil, :category => type) if body.kind_of?(String)
104
+ true
105
+ when 'nomarkdown'
106
+ @tree.children << Element.new(:raw, body, nil, :category => type, :type => opts['type'].to_s.split(/\s+/)) if body.kind_of?(String)
107
+ true
108
+ when 'options'
109
+ opts.select do |k,v|
110
+ k = k.to_sym
111
+ if Kramdown::Options.defined?(k)
112
+ begin
113
+ val = Kramdown::Options.parse(k, v)
114
+ @options[k] = val
115
+ (@root.options[:options] ||= {})[k] = val
116
+ rescue
117
+ end
118
+ false
119
+ else
120
+ true
121
+ end
122
+ end.each do |k,v|
123
+ warning("Unknown kramdown option '#{k}'")
124
+ end
125
+ @tree.children << Element.new(:eob, :extension) if type == :block
126
+ true
127
+ else
128
+ false
129
+ end
130
+ end
131
+
132
+
133
+ ALD_ID_CHARS = /[\w-]/
134
+ ALD_ANY_CHARS = /\\\}|[^\}]/
135
+ ALD_ID_NAME = /\w#{ALD_ID_CHARS}*/
136
+ ALD_TYPE_KEY_VALUE_PAIR = /(#{ALD_ID_NAME})=("|')((?:\\\}|\\\2|[^\}\2])*?)\2/
137
+ ALD_TYPE_CLASS_NAME = /\.(#{ALD_ID_NAME})/
138
+ ALD_TYPE_ID_NAME = /#(\w[\w:-]*)/
139
+ ALD_TYPE_REF = /(#{ALD_ID_NAME})/
140
+ ALD_TYPE_ANY = /(?:\A|\s)(?:#{ALD_TYPE_KEY_VALUE_PAIR}|#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME}|#{ALD_TYPE_REF})(?=\s|\Z)/
141
+ ALD_START = /^#{OPT_SPACE}\{:(#{ALD_ID_NAME}):(#{ALD_ANY_CHARS}+)\}\s*?\n/
142
+
143
+ EXT_STOP_STR = "\\{:/(%s)?\\}"
144
+ EXT_START_STR = "\\{::(\\w+)(?:\\s(#{ALD_ANY_CHARS}*?)|)(\\/)?\\}"
145
+ EXT_BLOCK_START = /^#{OPT_SPACE}(?:#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME})\s*?\n/
146
+ EXT_BLOCK_STOP_STR = "^#{OPT_SPACE}#{EXT_STOP_STR}\s*?\n"
147
+
148
+ IAL_BLOCK = /\{:(?!:|\/)(#{ALD_ANY_CHARS}+)\}\s*?\n/
149
+ IAL_BLOCK_START = /^#{OPT_SPACE}#{IAL_BLOCK}/
150
+
151
+ BLOCK_EXTENSIONS_START = /^#{OPT_SPACE}\{:/
152
+
153
+ # Parse one of the block extensions (ALD, block IAL or generic extension) at the current
154
+ # location.
155
+ def parse_block_extensions
156
+ if @src.scan(ALD_START)
157
+ parse_attribute_list(@src[2], @alds[@src[1]] ||= Utils::OrderedHash.new)
158
+ @tree.children << Element.new(:eob, :ald)
159
+ true
160
+ elsif @src.check(EXT_BLOCK_START)
161
+ parse_extension_start_tag(:block)
162
+ elsif @src.scan(IAL_BLOCK_START)
163
+ if @tree.children.last && @tree.children.last.type != :blank && @tree.children.last.type != :eob
164
+ parse_attribute_list(@src[1], @tree.children.last.options[:ial] ||= Utils::OrderedHash.new)
165
+ @tree.children << Element.new(:eob, :ial) unless @src.check(IAL_BLOCK_START)
166
+ else
167
+ parse_attribute_list(@src[1], @block_ial = Utils::OrderedHash.new)
168
+ end
169
+ true
170
+ else
171
+ false
172
+ end
173
+ end
174
+ define_parser(:block_extensions, BLOCK_EXTENSIONS_START)
175
+
176
+
177
+ EXT_SPAN_START = /#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME}/
178
+ IAL_SPAN_START = /\{:(#{ALD_ANY_CHARS}+)\}/
179
+ SPAN_EXTENSIONS_START = /\{:/
180
+
181
+ # Parse the extension span at the current location.
182
+ def parse_span_extensions
183
+ if @src.check(EXT_SPAN_START)
184
+ parse_extension_start_tag(:span)
185
+ elsif @src.check(IAL_SPAN_START)
186
+ if @tree.children.last && @tree.children.last.type != :text
187
+ @src.pos += @src.matched_size
188
+ attr = Utils::OrderedHash.new
189
+ parse_attribute_list(@src[1], attr)
190
+ update_ial_with_ial(@tree.children.last.options[:ial] ||= Utils::OrderedHash.new, attr)
191
+ update_attr_with_ial(@tree.children.last.attr, attr)
192
+ else
193
+ warning("Found span IAL after text - ignoring it")
194
+ add_text(@src.getch)
195
+ end
196
+ else
197
+ add_text(@src.getch)
198
+ end
199
+ end
200
+ define_parser(:span_extensions, SPAN_EXTENSIONS_START, '\{:')
201
+
202
+ end
203
+ end
204
+ end