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,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/list'
27
+ require 'kramdown/parser/kramdown/html'
28
+
29
+ module Kramdown
30
+ module Parser
31
+ class Kramdown
32
+
33
+ LAZY_END_HTML_SPAN_ELEMENTS = HTML_SPAN_ELEMENTS + %w{script}
34
+ LAZY_END_HTML_START = /<(?>(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR})\s*(?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}\s*=\s*(["']).*?\1)*\s*\/?>/m
35
+ LAZY_END_HTML_STOP = /<\/(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR}\s*>/m
36
+
37
+ LAZY_END = /#{BLANK_LINE}|#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START}|\Z/
38
+
39
+ PARAGRAPH_START = /^#{OPT_SPACE}[^ \t].*?\n/
40
+ PARAGRAPH_MATCH = /^.*?\n/
41
+ PARAGRAPH_END = /#{LAZY_END}|#{DEFINITION_LIST_START}/
42
+
43
+ # Parse the paragraph at the current location.
44
+ def parse_paragraph
45
+ result = @src.scan(PARAGRAPH_MATCH)
46
+ while !@src.match?(self.class::PARAGRAPH_END)
47
+ result << @src.scan(PARAGRAPH_MATCH)
48
+ end
49
+ result.chomp!
50
+ if @tree.children.last && @tree.children.last.type == :p
51
+ @tree.children.last.children.first.value << "\n" << result
52
+ else
53
+ @tree.children << new_block_el(:p)
54
+ result.lstrip!
55
+ @tree.children.last.children << Element.new(@text_type, result)
56
+ end
57
+ true
58
+ end
59
+ define_parser(:paragraph, PARAGRAPH_START)
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,214 @@
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
+ # Parts of this file are based on code from Maruku by Andrea Censi.
24
+ # The needed license statements follow:
25
+ #
26
+ # Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
27
+ #
28
+ # Maruku is free software; you can redistribute it and/or modify
29
+ # it under the terms of the GNU General Public License as published by
30
+ # the Free Software Foundation; either version 2 of the License, or
31
+ # (at your option) any later version.
32
+ #
33
+ # Maruku is distributed in the hope that it will be useful,
34
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36
+ # GNU General Public License for more details.
37
+ #
38
+ # You should have received a copy of the GNU General Public License
39
+ # along with Maruku; if not, write to the Free Software
40
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
41
+ #
42
+ # NOTA BENE:
43
+ #
44
+ # The following algorithm is a rip-off of RubyPants written by
45
+ # Christian Neukirchen.
46
+ #
47
+ # RubyPants is a Ruby port of SmartyPants written by John Gruber.
48
+ #
49
+ # This file is distributed under the GPL, which I guess is compatible
50
+ # with the terms of the RubyPants license.
51
+ #
52
+ # -- Andrea Censi
53
+ #
54
+ # = RubyPants -- SmartyPants ported to Ruby
55
+ #
56
+ # Ported by Christian Neukirchen <mailto:chneukirchen@gmail.com>
57
+ # Copyright (C) 2004 Christian Neukirchen
58
+ #
59
+ # Incooporates ideas, comments and documentation by Chad Miller
60
+ # Copyright (C) 2004 Chad Miller
61
+ #
62
+ # Original SmartyPants by John Gruber
63
+ # Copyright (C) 2003 John Gruber
64
+ #
65
+ #
66
+ # = RubyPants -- SmartyPants ported to Ruby
67
+ #
68
+ #
69
+ # [snip]
70
+ #
71
+ # == Authors
72
+ #
73
+ # John Gruber did all of the hard work of writing this software in
74
+ # Perl for Movable Type and almost all of this useful documentation.
75
+ # Chad Miller ported it to Python to use with Pyblosxom.
76
+ #
77
+ # Christian Neukirchen provided the Ruby port, as a general-purpose
78
+ # library that follows the *Cloth API.
79
+ #
80
+ #
81
+ # == Copyright and License
82
+ #
83
+ # === SmartyPants license:
84
+ #
85
+ # Copyright (c) 2003 John Gruber
86
+ # (http://daringfireball.net)
87
+ # All rights reserved.
88
+ #
89
+ # Redistribution and use in source and binary forms, with or without
90
+ # modification, are permitted provided that the following conditions
91
+ # are met:
92
+ #
93
+ # * Redistributions of source code must retain the above copyright
94
+ # notice, this list of conditions and the following disclaimer.
95
+ #
96
+ # * Redistributions in binary form must reproduce the above copyright
97
+ # notice, this list of conditions and the following disclaimer in
98
+ # the documentation and/or other materials provided with the
99
+ # distribution.
100
+ #
101
+ # * Neither the name "SmartyPants" nor the names of its contributors
102
+ # may be used to endorse or promote products derived from this
103
+ # software without specific prior written permission.
104
+ #
105
+ # This software is provided by the copyright holders and contributors
106
+ # "as is" and any express or implied warranties, including, but not
107
+ # limited to, the implied warranties of merchantability and fitness
108
+ # for a particular purpose are disclaimed. In no event shall the
109
+ # copyright owner or contributors be liable for any direct, indirect,
110
+ # incidental, special, exemplary, or consequential damages (including,
111
+ # but not limited to, procurement of substitute goods or services;
112
+ # loss of use, data, or profits; or business interruption) however
113
+ # caused and on any theory of liability, whether in contract, strict
114
+ # liability, or tort (including negligence or otherwise) arising in
115
+ # any way out of the use of this software, even if advised of the
116
+ # possibility of such damage.
117
+ #
118
+ # === RubyPants license
119
+ #
120
+ # RubyPants is a derivative work of SmartyPants and smartypants.py.
121
+ #
122
+ # Redistribution and use in source and binary forms, with or without
123
+ # modification, are permitted provided that the following conditions
124
+ # are met:
125
+ #
126
+ # * Redistributions of source code must retain the above copyright
127
+ # notice, this list of conditions and the following disclaimer.
128
+ #
129
+ # * Redistributions in binary form must reproduce the above copyright
130
+ # notice, this list of conditions and the following disclaimer in
131
+ # the documentation and/or other materials provided with the
132
+ # distribution.
133
+ #
134
+ # This software is provided by the copyright holders and contributors
135
+ # "as is" and any express or implied warranties, including, but not
136
+ # limited to, the implied warranties of merchantability and fitness
137
+ # for a particular purpose are disclaimed. In no event shall the
138
+ # copyright owner or contributors be liable for any direct, indirect,
139
+ # incidental, special, exemplary, or consequential damages (including,
140
+ # but not limited to, procurement of substitute goods or services;
141
+ # loss of use, data, or profits; or business interruption) however
142
+ # caused and on any theory of liability, whether in contract, strict
143
+ # liability, or tort (including negligence or otherwise) arising in
144
+ # any way out of the use of this software, even if advised of the
145
+ # possibility of such damage.
146
+ #
147
+ # == Links
148
+ #
149
+ # John Gruber:: http://daringfireball.net
150
+ # SmartyPants:: http://daringfireball.net/projects/smartypants
151
+ #
152
+ # Chad Miller:: http://web.chad.org
153
+ #
154
+ # Christian Neukirchen:: http://kronavita.de/chris
155
+ #
156
+ #++
157
+ #
158
+
159
+ module Kramdown
160
+ module Parser
161
+ class Kramdown
162
+
163
+ SQ_PUNCT = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]'
164
+ SQ_CLOSE = %![^\ \\\\\t\r\n\\[{(-]!
165
+
166
+ SQ_RULES = [
167
+ [/("|')(?=#{SQ_PUNCT}\B)/, [:rquote1]],
168
+ # Special case for double sets of quotes, e.g.:
169
+ # <p>He said, "'Quoted' words in a larger quote."</p>
170
+ [/(\s?)"'(?=\w)/, [1, :ldquo, :lsquo]],
171
+ [/(\s?)'"(?=\w)/, [1, :lsquo, :ldquo]],
172
+ # Special case for decade abbreviations (the '80s):
173
+ [/(\s?)'(?=\d\ds)/, [1, :rsquo]],
174
+
175
+ # Get most opening single/double quotes:
176
+ [/(\s)('|")(?=\w)/, [1, :lquote2]],
177
+ # Single/double closing quotes:
178
+ [/(#{SQ_CLOSE})('|")/, [1, :rquote2]],
179
+ # Special case for e.g. "<i>Custer</i>'s Last Stand."
180
+ [/("|')(\s|s\b|$)/, [:rquote1, 2]],
181
+ # Any remaining single quotes should be opening ones:
182
+ [/(.?)'/m, [1, :lsquo]],
183
+ [/(.?)"/m, [1, :ldquo]],
184
+ ] #'"
185
+
186
+ SQ_SUBSTS = {
187
+ [:rquote1, '"'] => :rdquo,
188
+ [:rquote1, "'"] => :rsquo,
189
+ [:rquote2, '"'] => :rdquo,
190
+ [:rquote2, "'"] => :rsquo,
191
+ [:lquote1, '"'] => :ldquo,
192
+ [:lquote1, "'"] => :lsquo,
193
+ [:lquote2, '"'] => :ldquo,
194
+ [:lquote2, "'"] => :lsquo,
195
+ }
196
+ SMART_QUOTES_RE = /[^\\]?["']/
197
+
198
+ # Parse the smart quotes at current location.
199
+ def parse_smart_quotes
200
+ substs = SQ_RULES.find {|reg, subst| @src.scan(reg)}[1]
201
+ substs.each do |subst|
202
+ if subst.kind_of?(Integer)
203
+ add_text(@src[subst])
204
+ else
205
+ val = SQ_SUBSTS[[subst, @src[subst.to_s[-1,1].to_i]]] || subst
206
+ @tree.children << Element.new(:smart_quote, val)
207
+ end
208
+ end
209
+ end
210
+ define_parser(:smart_quotes, SMART_QUOTES_RE, '[^\\\\]?["\']')
211
+
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,178 @@
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
+ TABLE_SEP_LINE = /^([+|: -]*?-[+|: -]*?)[ \t]*\n/
30
+ TABLE_HSEP_ALIGN = /[ ]?(:?)-+(:?)[ ]?/
31
+ TABLE_FSEP_LINE = /^[+|: =]*?=[+|: =]*?[ \t]*\n/
32
+ TABLE_ROW_LINE = /^(.*?)[ \t]*\n/
33
+ TABLE_PIPE_CHECK = /(?:\||.*?[^\\\n]\|)/
34
+ TABLE_LINE = /#{TABLE_PIPE_CHECK}.*?\n/
35
+ TABLE_START = /^#{OPT_SPACE}(?=\S)#{TABLE_LINE}/
36
+
37
+ # Parse the table at the current location.
38
+ def parse_table
39
+ return false if !after_block_boundary?
40
+
41
+ orig_pos = @src.pos
42
+ table = new_block_el(:table, nil, nil, :alignment => [])
43
+ leading_pipe = (@src.check(TABLE_LINE) =~ /^\s*\|/)
44
+ @src.scan(TABLE_SEP_LINE)
45
+
46
+ rows = []
47
+ has_footer = false
48
+ columns = 0
49
+
50
+ add_container = lambda do |type, force|
51
+ if !has_footer || type != :tbody || force
52
+ cont = Element.new(type)
53
+ cont.children, rows = rows, []
54
+ table.children << cont
55
+ end
56
+ end
57
+
58
+ while !@src.eos?
59
+ break if !@src.check(TABLE_LINE)
60
+ if @src.scan(TABLE_SEP_LINE) && !rows.empty?
61
+ if table.options[:alignment].empty? && !has_footer
62
+ add_container.call(:thead, false)
63
+ table.options[:alignment] = @src[1].scan(TABLE_HSEP_ALIGN).map do |left, right|
64
+ (left.empty? && right.empty? && :default) || (right.empty? && :left) || (left.empty? && :right) || :center
65
+ end
66
+ else # treat as normal separator line
67
+ add_container.call(:tbody, false)
68
+ end
69
+ elsif @src.scan(TABLE_FSEP_LINE)
70
+ add_container.call(:tbody, true) if !rows.empty?
71
+ has_footer = true
72
+ elsif @src.scan(TABLE_ROW_LINE)
73
+ trow = Element.new(:tr)
74
+
75
+ # parse possible code spans on the line and correctly split the line into cells
76
+ env = save_env
77
+ cells = []
78
+ @src[1].split(/(<code.*?>.*?<\/code>)/).each_with_index do |str, i|
79
+ if i % 2 == 1
80
+ (cells.empty? ? cells : cells.last) << str
81
+ else
82
+ reset_env(:src => StringScanner.new(str))
83
+ root = Element.new(:root)
84
+ parse_spans(root, nil, [:codespan])
85
+
86
+ root.children.each do |c|
87
+ if c.type == :raw_text
88
+ # Only on Ruby 1.9: f, *l = c.value.split(/(?<!\\)\|/).map {|t| t.gsub(/\\\|/, '|')}
89
+ f, *l = c.value.split(/\\\|/, -1).map {|t| t.split(/\|/, -1)}.inject([]) do |memo, t|
90
+ memo.last << "|#{t.shift}" if memo.size > 0
91
+ memo.concat(t)
92
+ end
93
+ (cells.empty? ? cells : cells.last) << f
94
+ cells.concat(l)
95
+ else
96
+ delim = (c.value.scan(/`+/).max || '') + '`'
97
+ tmp = "#{delim}#{' ' if delim.size > 1}#{c.value}#{' ' if delim.size > 1}#{delim}"
98
+ (cells.empty? ? cells : cells.last) << tmp
99
+ end
100
+ end
101
+ end
102
+ end
103
+ restore_env(env)
104
+
105
+ cells.shift if leading_pipe && cells.first.strip.empty?
106
+ cells.pop if cells.last.strip.empty?
107
+ cells.each do |cell_text|
108
+ tcell = Element.new(:td)
109
+ tcell.children << Element.new(:raw_text, cell_text.strip)
110
+ trow.children << tcell
111
+ end
112
+ columns = [columns, cells.length].max
113
+ rows << trow
114
+ else
115
+ break
116
+ end
117
+ end
118
+
119
+ if !before_block_boundary?
120
+ @src.pos = orig_pos
121
+ return false
122
+ end
123
+
124
+ # Parse all lines of the table with the code span parser
125
+ env = save_env
126
+ reset_env(:src => StringScanner.new(extract_string(orig_pos...(@src.pos-1), @src)))
127
+ root = Element.new(:root)
128
+ parse_spans(root, nil, [:codespan])
129
+ restore_env(env)
130
+
131
+ # Check if each line has at least one unescaped backslash that is not inside a code span
132
+ pipe_on_line = false
133
+ while (c = root.children.shift)
134
+ lines = c.value.split(/\n/)
135
+ if c.type == :codespan
136
+ if lines.size > 2 || (lines.size == 2 && !pipe_on_line)
137
+ break
138
+ elsif lines.size == 2 && pipe_on_line
139
+ pipe_on_line = false
140
+ end
141
+ else
142
+ break if lines.size > 1 && !pipe_on_line && lines.first !~ /^#{TABLE_PIPE_CHECK}/
143
+ pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/)
144
+ end
145
+ end
146
+ @src.pos = orig_pos and return false if !pipe_on_line
147
+
148
+ add_container.call(has_footer ? :tfoot : :tbody, false) if !rows.empty?
149
+
150
+ if !table.children.any? {|el| el.type == :tbody}
151
+ warning("Found table without body - ignoring it")
152
+ @src.pos = orig_pos
153
+ return false
154
+ end
155
+
156
+ # adjust all table rows to have equal number of columns, same for alignment defs
157
+ table.children.each do |kind|
158
+ kind.children.each do |row|
159
+ (columns - row.children.length).times do
160
+ row.children << Element.new(:td)
161
+ end
162
+ end
163
+ end
164
+ if table.options[:alignment].length > columns
165
+ table.options[:alignment] = table.options[:alignment][0...columns]
166
+ else
167
+ table.options[:alignment] += [:default] * (columns - table.options[:alignment].length)
168
+ end
169
+
170
+ @tree.children << table
171
+
172
+ true
173
+ end
174
+ define_parser(:table, TABLE_START)
175
+
176
+ end
177
+ end
178
+ end