kramdown 0.12.0 → 0.13.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of kramdown might be problematic. Click here for more details.

Files changed (41) hide show
  1. data/CONTRIBUTERS +2 -1
  2. data/ChangeLog +278 -0
  3. data/README +3 -0
  4. data/Rakefile +24 -0
  5. data/VERSION +1 -1
  6. data/benchmark/benchmark.sh +11 -2
  7. data/doc/documentation.page +2 -3
  8. data/doc/index.page +4 -4
  9. data/doc/installation.page +10 -11
  10. data/doc/syntax.page +17 -7
  11. data/doc/tests.page +1 -1
  12. data/lib/kramdown/converter/base.rb +9 -6
  13. data/lib/kramdown/converter/html.rb +2 -2
  14. data/lib/kramdown/converter/latex.rb +46 -26
  15. data/lib/kramdown/options.rb +42 -20
  16. data/lib/kramdown/parser/html.rb +50 -11
  17. data/lib/kramdown/parser/kramdown.rb +4 -4
  18. data/lib/kramdown/parser/kramdown/html_entity.rb +7 -2
  19. data/lib/kramdown/parser/kramdown/link.rb +9 -7
  20. data/lib/kramdown/parser/kramdown/list.rb +5 -4
  21. data/lib/kramdown/parser/kramdown/table.rb +24 -19
  22. data/lib/kramdown/utils/entities.rb +4 -0
  23. data/lib/kramdown/version.rb +1 -1
  24. data/man/man1/kramdown.1 +15 -14
  25. data/test/testcases/block/08_list/item_ial.html +3 -0
  26. data/test/testcases/block/08_list/item_ial.text +3 -0
  27. data/test/testcases/block/09_html/html_to_native/emphasis.html +2 -0
  28. data/test/testcases/block/09_html/html_to_native/emphasis.text +3 -0
  29. data/test/testcases/block/09_html/parse_as_raw.html +2 -0
  30. data/test/testcases/block/09_html/parse_as_raw.text +2 -0
  31. data/test/testcases/block/14_table/simple.html +19 -0
  32. data/test/testcases/block/14_table/simple.html.19 +19 -0
  33. data/test/testcases/block/14_table/simple.text +5 -0
  34. data/test/testcases/span/01_link/reference.html +3 -2
  35. data/test/testcases/span/01_link/reference.html.19 +3 -2
  36. data/test/testcases/span/01_link/reference.text +4 -1
  37. data/test/testcases/span/05_html/normal.html +2 -0
  38. data/test/testcases/span/05_html/normal.text +2 -0
  39. data/test/testcases/span/text_substitutions/entities.html +2 -0
  40. data/test/testcases/span/text_substitutions/entities.text +2 -0
  41. metadata +4 -4
@@ -84,10 +84,10 @@ module Kramdown
84
84
  @link_defs = {}
85
85
  @footnotes = {}
86
86
 
87
- @block_parsers = [:blank_line, :codeblock, :codeblock_fenced, :blockquote, :table, :atx_header,
88
- :setext_header, :horizontal_rule, :list, :definition_list, :link_definition, :block_html,
89
- :footnote_definition, :abbrev_definition, :block_extensions, :block_math,
90
- :eob_marker, :paragraph]
87
+ @block_parsers = [:blank_line, :codeblock, :codeblock_fenced, :blockquote, :atx_header,
88
+ :setext_header, :horizontal_rule, :list, :definition_list, :block_html,
89
+ :table, :footnote_definition, :link_definition, :abbrev_definition,
90
+ :block_extensions, :block_math, :eob_marker, :paragraph]
91
91
  @span_parsers = [:emphasis, :codespan, :autolink, :span_html, :footnote_marker, :link, :smart_quotes, :inline_math,
92
92
  :span_extensions, :html_entity, :typographic_syms, :line_break, :escaped_chars]
93
93
 
@@ -29,8 +29,13 @@ module Kramdown
29
29
  # Parse the HTML entity at the current location.
30
30
  def parse_html_entity
31
31
  @src.pos += @src.matched_size
32
- @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity(@src[1] || (@src[2] && @src[2].to_i) || @src[3].hex),
33
- nil, :original => @src.matched)
32
+ begin
33
+ @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity(@src[1] || (@src[2] && @src[2].to_i) || @src[3].hex),
34
+ nil, :original => @src.matched)
35
+ rescue ::Kramdown::Error
36
+ @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('amp'))
37
+ add_text(@src.matched[1..-1])
38
+ end
34
39
  end
35
40
  define_parser(:html_entity, Kramdown::Parser::Html::Constants::HTML_ENTITY_RE, '&')
36
41
 
@@ -24,15 +24,17 @@ module Kramdown
24
24
  module Parser
25
25
  class Kramdown
26
26
 
27
- PUNCTUATION_CHARS = "_.:,;!?-"
28
- LINK_ID_CHARS = /[a-zA-Z0-9 #{PUNCTUATION_CHARS}]/
29
- LINK_ID_NON_CHARS = /[^a-zA-Z0-9 #{PUNCTUATION_CHARS}]/
30
- LINK_DEFINITION_START = /^#{OPT_SPACE}\[(#{LINK_ID_CHARS}+)\]:[ \t]*(?:<(.*?)>|([^'"\n]*?\S[^'"\n]*?))[ \t]*?(?:\n?[ \t]*?(["'])(.+?)\4[ \t]*?)?\n/
27
+ # Normalize the link identifier.
28
+ def normalize_link_id(id)
29
+ id.gsub(/(\s|\n)+/, ' ').downcase
30
+ end
31
+
32
+ LINK_DEFINITION_START = /^#{OPT_SPACE}\[([^\n\]]+)\]:[ \t]*(?:<(.*?)>|([^'"\n]*?\S[^'"\n]*?))[ \t]*?(?:\n?[ \t]*?(["'])(.+?)\4[ \t]*?)?\n/
31
33
 
32
34
  # Parse the link definition at the current location.
33
35
  def parse_link_definition
34
36
  @src.pos += @src.matched_size
35
- link_id, link_url, link_title = @src[1].downcase, @src[2] || @src[3], @src[5]
37
+ link_id, link_url, link_title = normalize_link_id(@src[1]), @src[2] || @src[3], @src[5]
36
38
  warning("Duplicate link ID '#{link_id}' - overwriting") if @link_defs[link_id]
37
39
  @link_defs[link_id] = [link_url, link_title]
38
40
  @tree.children << Element.new(:eob, :link_def)
@@ -57,7 +59,7 @@ module Kramdown
57
59
 
58
60
  LINK_BRACKET_STOP_RE = /(\])|!?\[/
59
61
  LINK_PAREN_STOP_RE = /(\()|(\))|\s(?=['"])/
60
- LINK_INLINE_ID_RE = /\s*?\[(#{LINK_ID_CHARS}+)?\]/
62
+ LINK_INLINE_ID_RE = /\s*?\[([^\]]+)?\]/
61
63
  LINK_INLINE_TITLE_RE = /\s*?(["'])(.+?)\1\s*?\)/
62
64
  LINK_START = /!?\[(?=[^^])/
63
65
 
@@ -91,7 +93,7 @@ module Kramdown
91
93
 
92
94
  # reference style link or no link url
93
95
  if @src.scan(LINK_INLINE_ID_RE) || !@src.check(/\(/)
94
- link_id = (@src[1] || alt_text.gsub(/(\s|\n)+/, ' ').gsub(LINK_ID_NON_CHARS, '')).downcase
96
+ link_id = normalize_link_id(@src[1] || alt_text)
95
97
  if @link_defs.has_key?(link_id)
96
98
  add_link(el, @link_defs[link_id].first, @link_defs[link_id].last, alt_text)
97
99
  else
@@ -29,12 +29,13 @@ module Kramdown
29
29
  module Parser
30
30
  class Kramdown
31
31
 
32
- LIST_ITEM_IAL = /^\s*(#{IAL_SPAN_START})?\s*\n/
32
+ LIST_ITEM_IAL = /^\s*(?:\{:(?!(?:#{ALD_ID_NAME})?:|\/)(#{ALD_ANY_CHARS}+)\})\s*/
33
+ LIST_ITEM_IAL_CHECK = /^#{LIST_ITEM_IAL}?\s*\n/
33
34
 
34
35
  # Used for parsing the first line of a list item or a definition, i.e. the line with list item
35
36
  # marker or the definition marker.
36
37
  def parse_first_list_line(indentation, content)
37
- if content =~ self.class::LIST_ITEM_IAL
38
+ if content =~ self.class::LIST_ITEM_IAL_CHECK
38
39
  indentation = 4
39
40
  else
40
41
  while content =~ /^ *\t/
@@ -77,7 +78,7 @@ module Kramdown
77
78
  item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
78
79
  list.children << item
79
80
 
80
- item.value.sub!(/^#{self.class::IAL_SPAN_START}\s*/) do |match|
81
+ item.value.sub!(self.class::LIST_ITEM_IAL) do |match|
81
82
  parse_attribute_list($1, item.options[:ial] ||= {})
82
83
  ''
83
84
  end
@@ -175,7 +176,7 @@ module Kramdown
175
176
  item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
176
177
  deflist.children << item
177
178
 
178
- item.value.sub!(/^#{IAL_SPAN_START}\s*/) do |match|
179
+ item.value.sub!(self.class::LIST_ITEM_IAL) do |match|
179
180
  parse_attribute_list($1, item.options[:ial] ||= {})
180
181
  ''
181
182
  end
@@ -72,30 +72,35 @@ module Kramdown
72
72
  elsif @src.scan(TABLE_ROW_LINE)
73
73
  trow = Element.new(:tr)
74
74
 
75
- # parse possible code spans on the line
75
+ # parse possible code spans on the line and correctly split the line into cells
76
76
  env = save_env
77
- reset_env(:src => StringScanner.new(@src[1] + ' '))
78
- root = Element.new(:root)
79
- parse_spans(root, nil, [:codespan])
80
- restore_env(env)
81
-
82
- # correctly split the line into cells
83
77
  cells = []
84
- root.children.each do |c|
85
- if c.type == :raw_text
86
- # Only on Ruby 1.9: f, *l = c.value.split(/(?<!\\)\|/).map {|t| t.gsub(/\\\|/, '|')}
87
- f, *l = c.value.split(/\\\|/).map {|t| t.split(/\|/)}.inject([]) do |memo, t|
88
- memo.last << "|" << t.shift if memo.size > 0
89
- memo.concat(t)
90
- end
91
- (cells.empty? ? cells : cells.last) << f
92
- cells.concat(l)
78
+ (@src[1] + ' ').split(/(<code.*?>.*?<\/code>)/).each_with_index do |str, i|
79
+ if i % 2 == 1
80
+ (cells.empty? ? cells : cells.last) << str
93
81
  else
94
- delim = (c.value.scan(/`+/).max || '') + '`'
95
- tmp = "#{delim}#{' ' if delim.size > 1}#{c.value}#{' ' if delim.size > 1}#{delim}"
96
- (cells.empty? ? cells : cells.last) << tmp
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(/\\\|/).map {|t| t.split(/\|/)}.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
97
101
  end
98
102
  end
103
+ restore_env(env)
99
104
 
100
105
  cells.shift if leading_pipe && cells.first.strip.empty?
101
106
  cells.pop if cells.last.strip.empty?
@@ -310,6 +310,10 @@ module Kramdown
310
310
  [156, 339],
311
311
  [158, 382],
312
312
  [159, 376],
313
+
314
+ [8194, 'ensp'],
315
+ [8195, 'emsp'],
316
+ [8201, 'thinsp'],
313
317
  ]
314
318
 
315
319
  # Contains the mapping of code point (or name) to the actual Entity object.
@@ -23,6 +23,6 @@
23
23
  module Kramdown
24
24
 
25
25
  # The kramdown version.
26
- VERSION = '0.12.0'
26
+ VERSION = '0.13.1'
27
27
 
28
28
  end
data/man/man1/kramdown.1 CHANGED
@@ -50,7 +50,7 @@ file still cannot be found, the templates name is interpreted as a
50
50
  template name that is provided by kramdown (without the converter
51
51
  extension).
52
52
 
53
- kramdown provides a default template named 'default' for each converter.
53
+ kramdown provides a default template named 'document' for each converter.
54
54
 
55
55
  Default: ''
56
56
  Used by: all converters
@@ -214,19 +214,6 @@ Default: :as_char
214
214
  Used by: HTML converter, kramdown converter
215
215
 
216
216
 
217
- .TP
218
- .B \-\-toc-depth ARG
219
-
220
- DEPRECATED: Defines the maximum level of headers which will be used to generate the table of
221
- contents. For instance, with a value of 2, toc entries will be generated for h1
222
- and h2 headers but not for h3, h4, etc. A value of 0 uses all header levels.
223
-
224
- Use option toc_levels instead!
225
-
226
- Default: -1
227
- Used by: HTML/Latex converter
228
-
229
-
230
217
  .TP
231
218
  .B \-\-toc-levels ARG
232
219
 
@@ -261,6 +248,20 @@ Default: section,subsection,subsubsection,paragraph,subparagraph,subsubparagraph
261
248
  Used by: Latex converter
262
249
 
263
250
 
251
+ .TP
252
+ .B \-\-smart-quotes ARG
253
+
254
+ Defines the HTML entity names or code points for smart quote output
255
+
256
+ The entities identified by entity name or code point that should be
257
+ used for, in order, a left single quote, a right single quote, a left
258
+ double and a right double quote are specified by separating them with
259
+ commas.
260
+
261
+ Default: lsquo,rsquo,ldquo,rdquo
262
+ Used by: HTML/Latex converter
263
+
264
+
264
265
  .SH EXIT STATUS
265
266
  The exit status is 0 if no error happened. Otherwise it is 1.
266
267
  .SH SEE ALSO
@@ -4,4 +4,7 @@ continued</li>
4
4
  <li>another {:.cls}</li>
5
5
  <li class="cls">IAL at last
6
6
  code</li>
7
+ <li>X
8
+ test</li>
9
+ <li>X OK</li>
7
10
  </ul>
@@ -3,3 +3,6 @@
3
3
  * another {:.cls}
4
4
  * {:.cls} IAL at last
5
5
  code
6
+ * {::nomarkdown type="html"}X{:/nomarkdown}
7
+ test
8
+ * {::nomarkdown type="html"}X{:/nomarkdown} OK
@@ -1,3 +1,5 @@
1
1
  <p>This is <em>sized<strong>hallo</strong></em>.</p>
2
2
 
3
3
  <p>This is <strong>strong<em>italic</em>, yes!</strong>.</p>
4
+
5
+ <p>This is <em> not</em> converted, as <em>is </em> this.</p>
@@ -1,3 +1,6 @@
1
1
  This is <em>sized<strong>hallo</strong></em>.
2
2
 
3
3
  This is <b>strong<i>italic</i>, yes!</b>.
4
+
5
+ This is <em> not</em> converted, as <em>is
6
+ </em> this.
@@ -1,3 +1,5 @@
1
+ <p>baz { |qux| quux }</p>
2
+
1
3
  <p>This is some para.
2
4
  <script type="javascript">
3
5
  This *text* must not be converted.
@@ -1,3 +1,5 @@
1
+ <p>baz { |qux| quux }</p>
2
+
1
3
  This is some para.
2
4
  <script type="javascript">
3
5
  This *text* must not be converted.
@@ -60,6 +60,25 @@
60
60
  </tbody>
61
61
  </table>
62
62
 
63
+ <p>Table with code elements</p>
64
+
65
+ <table>
66
+ <tbody>
67
+ <tr>
68
+ <td>This is a <code>span | with</code> a pipe.</td>
69
+ <td>&nbsp;</td>
70
+ <td>&nbsp;</td>
71
+ <td>&nbsp;</td>
72
+ </tr>
73
+ <tr>
74
+ <td>Some <em>span</em></td>
75
+ <td>&lt;/em&gt; here</td>
76
+ <td>a <code>span | with</code> a</td>
77
+ <td>pipe.</td>
78
+ </tr>
79
+ </tbody>
80
+ </table>
81
+
63
82
  <table class="cls">
64
83
  <tbody>
65
84
  <tr>
@@ -60,6 +60,25 @@
60
60
  </tbody>
61
61
  </table>
62
62
 
63
+ <p>Table with code elements</p>
64
+
65
+ <table>
66
+ <tbody>
67
+ <tr>
68
+ <td>This is a <code>span | with</code> a pipe.</td>
69
+ <td> </td>
70
+ <td> </td>
71
+ <td> </td>
72
+ </tr>
73
+ <tr>
74
+ <td>Some <em>span</em></td>
75
+ <td>&lt;/em&gt; here</td>
76
+ <td>a <code>span | with</code> a</td>
77
+ <td>pipe.</td>
78
+ </tr>
79
+ </tbody>
80
+ </table>
81
+
63
82
  <table class="cls">
64
83
  <tbody>
65
84
  <tr>
@@ -15,6 +15,11 @@ Escaped pipe characters
15
15
  | cell1 | cell2 \|
16
16
  | cell1 `|` con | cell2
17
17
 
18
+ Table with code elements
19
+
20
+ | This is a <code>span | with</code> a pipe.
21
+ | Some <em>span | </em> here | a <code>span | with</code> a | pipe.
22
+
18
23
  {:.cls}
19
24
  | table | with | ial
20
25
 
@@ -20,8 +20,7 @@ the text</a></p>
20
20
 
21
21
  <p>bad [no URL] d <a href="someurl.html">isurl</a></p>
22
22
 
23
- <p>[no % url]: invalid.html
24
- [no url] invalid.html
23
+ <p>[no url] invalid.html
25
24
  [no url]:</p>
26
25
 
27
26
  <p>&ldquo;title&rdquo;</p>
@@ -33,3 +32,5 @@ test [urldef]</p>
33
32
 
34
33
  <p>some <a href="with spaces.html" title="title">with spaces</a></p>
35
34
 
35
+ <p>this <a href="occasion.html">is a &lsquo;special&rsquo; occasion for /all/ of us</a></p>
36
+
@@ -20,8 +20,7 @@ the text</a></p>
20
20
 
21
21
  <p>bad [no URL] d <a href="someurl.html">isurl</a></p>
22
22
 
23
- <p>[no % url]: invalid.html
24
- [no url] invalid.html
23
+ <p>[no url] invalid.html
25
24
  [no url]:</p>
26
25
 
27
26
  <p>“title”</p>
@@ -33,3 +32,5 @@ test [urldef]</p>
33
32
 
34
33
  <p>some <a href="with spaces.html" title="title">with spaces</a></p>
35
34
 
35
+ <p>this <a href="occasion.html">is a ‘special’ occasion for /all/ of us</a></p>
36
+
@@ -28,7 +28,6 @@ a [Link with_BIG] letters
28
28
 
29
29
  bad [no URL] d [isurl]
30
30
 
31
- [no % url]: invalid.html
32
31
  [no url] invalid.html
33
32
  [no url]:
34
33
 
@@ -45,3 +44,7 @@ test [urldef]
45
44
  some [with spaces]
46
45
 
47
46
  [with spaces]: with spaces.html "title"
47
+
48
+ this [is a 'special' occasion for /all/ of us]
49
+
50
+ [is a 'special' occasion for /all/ of us]: occasion.html
@@ -1,3 +1,5 @@
1
+ <p>Empty <a name="anchor" id="anchor"></a>!</p>
2
+
1
3
  <p><a href="test">title</a> is a title.</p>
2
4
 
3
5
  <p>This is <? a PI ?>.</p>
@@ -1,3 +1,5 @@
1
+ Empty <a name="anchor" id="anchor"></a>!
2
+
1
3
  <a href="test">title</a> is a title.
2
4
 
3
5
  This is <? a PI ?>.
@@ -2,3 +2,5 @@
2
2
  As well \&amp; as this. Some &#343; other
3
3
  values may &#xAF; may also show but
4
4
  not st. like &amp;#xYZ;.</p>
5
+
6
+ <p>This is BS&amp;T; done!</p>
@@ -2,3 +2,5 @@ This is the A&O. &copy; 2008 by me
2
2
  As well \& as this. Some &#343; other
3
3
  values may &#xAF; may also show but
4
4
  not st. like &#xYZ;.
5
+
6
+ This is BS&T; done!
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 12
8
- - 0
9
- version: 0.12.0
7
+ - 13
8
+ - 1
9
+ version: 0.13.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Thomas Leitner
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-11-01 00:00:00 +01:00
17
+ date: 2011-01-22 00:00:00 +01:00
18
18
  default_executable: kramdown
19
19
  dependencies: []
20
20