kramdown 0.14.1 → 0.14.2

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.

@@ -0,0 +1,10 @@
1
+ ---
2
+ title: Options
3
+ ---
4
+ ## Available Options
5
+
6
+ The behaviour of kramdown can be adjusted via the available options. Below is a list of all
7
+ currently available options. Have a look at the documentation of a converter or parser to see
8
+ directly which options they support!
9
+
10
+ {options: {items: all}}
@@ -5,7 +5,7 @@ sort_info: 9
5
5
  --- name:sidebar
6
6
  <h1>Contents</h1>
7
7
 
8
- {menu: {used_nodes: fragments, min_levels: 4, max_levels: 6}}
8
+ {menu: {options: {descendants: true, levels: [2,6]}}}
9
9
  --- name:content
10
10
  # Quick Reference
11
11
 
@@ -23,14 +23,16 @@ text phrases as emphasized, as a link and so on.
23
23
  All examples below feature the kramdown source, the converted HTML source (shown when hovering over
24
24
  the kramdown source) and the output as it appears in the browser. This looks like this:
25
25
 
26
- <div class="kdexample">
27
- <pre class="kdexample-before"><code>kramdown example code</code></pre>
28
- <pre class="kdexample-after-source"><code>Example code converted to HTML</code></pre>
26
+ <table class="kdexample">
27
+ <tr>
28
+ <td><pre class="kdexample-before"><code>kramdown example code</code></pre></td>
29
+ <td><pre class="kdexample-after-source"><code>Example code converted to HTML</code></pre>
29
30
  <div class="kdexample-after-live" style="clear:none">
30
31
  Live browser view of example code
31
32
  </div>
32
- </div>
33
- <div class="clear"></div>
33
+ </td>
34
+ </tr>
35
+ </table>
34
36
 
35
37
 
36
38
  # Block-level Elements - Main Structural Elements
@@ -1,7 +1,7 @@
1
1
  <h2>News</h2>
2
2
 
3
- <p>The latest version of kramdown is <b>0.14.1</b> and it was released
4
- on <b>2012-11-30</b>.</p>
3
+ <p>The latest version of kramdown is <b>0.14.2</b> and it was released
4
+ on <b>2013-01-20</b>.</p>
5
5
 
6
6
  <p>More <a href="{relocatable: news.html}">news</a>…</p>
7
7
 
@@ -5,7 +5,7 @@ sort_info: 10
5
5
  --- name:sidebar
6
6
  <h1>Contents</h1>
7
7
 
8
- {menu: {used_nodes: fragments, min_levels: 4, max_levels: 6}}
8
+ {menu: {options: {descendants: true, levels: [2,6]}}}
9
9
  --- name:content
10
10
 
11
11
  # kramdown Syntax
@@ -1,8 +1,9 @@
1
1
  ---
2
2
  title: Tests and Benchmark
3
3
  ---
4
+ # Tests and Benchmark
4
5
 
5
- # Tests
6
+ ## Tests
6
7
 
7
8
  There exist several test suites for testing the correctness of a Markdown implementation. The
8
9
  original [Markdown Test Suite] is the standard which one needs to test against. The [PHP Markdown
@@ -26,19 +27,54 @@ If you believe you have found a bug in the implementation, please follow these s
26
27
  [bug report]: http://rubyforge.org/tracker/?atid=28673&group_id=7403&func=browse
27
28
 
28
29
 
29
- # Benchmark
30
+ ## Benchmark
30
31
 
31
32
  kramdown comes with a small benchmark to test how fast it is in regard to four other Ruby Markdown
32
- implementations: Maruku, BlueFeather, BlueCloth and RDiscount. The first two are written using only
33
- Ruby, the latter two use the C discount library for the actual hard work (which makes them really
34
- fast but they do not provide additional syntax elements). As one can see below, kramdown is
35
- currently (February 2012) ~3-4x faster than Maruku, ~4-5x faster than BlueFeather but ~30x slower
36
- than BlueCloth and rdiscount:
33
+ implementations: Maruku, BlueFeather, BlueCloth, RDiscount and Redcarpet. The first two are written
34
+ using only Ruby, the latter three are written in C and need to be compiled.
35
+
36
+ As one can see below, kramdown is currently (January 2013) ~3-4x faster than Maruku, ~4-5x faster
37
+ than BlueFeather but ~30x slower than BlueCloth and RDiscount and ~100x slower than Redcarpet:
37
38
 
38
39
  <pre><code>
39
- {execute_cmd: {command: "ruby -Ilib -rubygems benchmark/benchmark.rb", process_output: false, escape_html: true}}
40
- </code>
41
- </pre>
40
+ Running tests on 2013-01-13 under ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-linux]
41
+
42
+ Test using file mdsyntax.text and 20 runs
43
+ Rehearsal ----------------------------------------------------
44
+ kramdown 0.14.1 1.400000 0.010000 1.410000 ( 1.428902)
45
+ Maruku 0.6.0 4.520000 0.030000 4.550000 ( 4.578439)
46
+ BlueFeather 0.40 5.680000 0.020000 5.700000 ( 5.707717)
47
+ BlueCloth 2.2.0 0.060000 0.000000 0.060000 ( 0.067857)
48
+ RDiscount 1.6.8 0.030000 0.000000 0.030000 ( 0.027722)
49
+ redcarpet 2.2.2 0.010000 0.000000 0.010000 ( 0.007642)
50
+ ------------------------------------------ total: 11.760000sec
51
+
52
+ user system total real
53
+ kramdown 0.14.1 1.270000 0.000000 1.270000 ( 1.273636)
54
+ Maruku 0.6.0 4.400000 0.020000 4.420000 ( 4.434123)
55
+ BlueFeather 0.40 5.610000 0.000000 5.610000 ( 5.631930)
56
+ BlueCloth 2.2.0 0.070000 0.000000 0.070000 ( 0.069900)
57
+ RDiscount 1.6.8 0.040000 0.000000 0.040000 ( 0.035793)
58
+ redcarpet 2.2.2 0.010000 0.000000 0.010000 ( 0.007520)
59
+
60
+ Test using file mdbasics.text and 20 runs
61
+ Rehearsal ----------------------------------------------------
62
+ kramdown 0.14.1 0.230000 0.000000 0.230000 ( 0.228075)
63
+ Maruku 0.6.0 1.070000 0.000000 1.070000 ( 1.079782)
64
+ BlueFeather 0.40 1.440000 0.000000 1.440000 ( 1.446999)
65
+ BlueCloth 2.2.0 0.020000 0.000000 0.020000 ( 0.019677)
66
+ RDiscount 1.6.8 0.010000 0.000000 0.010000 ( 0.008010)
67
+ redcarpet 2.2.2 0.010000 0.000000 0.010000 ( 0.002431)
68
+ ------------------------------------------- total: 2.780000sec
69
+
70
+ user system total real
71
+ kramdown 0.14.1 0.230000 0.000000 0.230000 ( 0.227214)
72
+ Maruku 0.6.0 1.070000 0.000000 1.070000 ( 1.070332)
73
+ BlueFeather 0.40 1.430000 0.000000 1.430000 ( 1.434958)
74
+ BlueCloth 2.2.0 0.020000 0.000000 0.020000 ( 0.021127)
75
+ RDiscount 1.6.8 0.020000 0.000000 0.020000 ( 0.009714)
76
+ redcarpet 2.2.2 0.000000 0.000000 0.000000 ( 0.002571)
77
+ </code></pre>
42
78
 
43
79
  And here are some graphs which show the execution times of the various kramdown releases on
44
80
  different Ruby interpreters:
@@ -48,7 +84,8 @@ different Ruby interpreters:
48
84
  ![ruby 1.8.7p249]({relocatable: img/graph-ruby-1.8.7-249.png})
49
85
  ![ruby 1.8.7p302]({relocatable: img/graph-ruby-1.8.7-302.png})
50
86
  ![ruby 1.9.2p136]({relocatable: img/graph-ruby-1.9.2p136-136.png})
51
- ![ruby 1.9.3p125]({relocatable: img/graph-ruby-1.9.3p125-125.png})
87
+ ![ruby 1.9.3p327]({relocatable: img/graph-ruby-1.9.3p327-327.png})
88
+ ![ruby 2.0.0dev]({relocatable: img/graph-ruby-2.0.0dev--1.png})
52
89
 
53
90
  [Markdown Test Suite]: http://daringfireball.net/projects/downloads/MarkdownTest_1.0.zip
54
91
  [MDTest]: http://www.michelf.com/docs/projets/mdtest-1.0.zip
@@ -105,7 +105,7 @@ module Kramdown
105
105
  if el.options[:transparent]
106
106
  inner(el, indent)
107
107
  else
108
- "#{' '*indent}<p#{html_attributes(el.attr)}>#{inner(el, indent)}</p>\n"
108
+ format_as_block_html(el.type, el.attr, inner(el, indent), indent)
109
109
  end
110
110
  end
111
111
 
@@ -140,7 +140,7 @@ module Kramdown
140
140
  end
141
141
 
142
142
  def convert_blockquote(el, indent)
143
- "#{' '*indent}<blockquote#{html_attributes(el.attr)}>\n#{inner(el, indent)}#{' '*indent}</blockquote>\n"
143
+ format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
144
144
  end
145
145
 
146
146
  def convert_header(el, indent)
@@ -150,7 +150,7 @@ module Kramdown
150
150
  end
151
151
  @toc << [el.options[:level], attr['id'], el.children] if attr['id'] && in_toc?(el)
152
152
  level = output_header_level(el.options[:level])
153
- "#{' '*indent}<h#{level}#{html_attributes(attr)}>#{inner(el, indent)}</h#{level}>\n"
153
+ format_as_block_html("h#{level}", attr, inner(el, indent), indent)
154
154
  end
155
155
 
156
156
  def convert_hr(el, indent)
@@ -162,7 +162,7 @@ module Kramdown
162
162
  @toc_code = [el.type, el.attr, (0..128).to_a.map{|a| rand(36).to_s(36)}.join]
163
163
  @toc_code.last
164
164
  else
165
- "#{' '*indent}<#{el.type}#{html_attributes(el.attr)}>\n#{inner(el, indent)}#{' '*indent}</#{el.type}>\n"
165
+ format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
166
166
  end
167
167
  end
168
168
  alias :convert_ol :convert_ul
@@ -181,7 +181,7 @@ module Kramdown
181
181
  alias :convert_dd :convert_li
182
182
 
183
183
  def convert_dt(el, indent)
184
- "#{' '*indent}<dt#{html_attributes(el.attr)}>#{inner(el, indent)}</dt>\n"
184
+ format_as_block_html(el.type, el.attr, inner(el, indent), indent)
185
185
  end
186
186
 
187
187
  def convert_html_element(el, indent)
@@ -218,15 +218,12 @@ module Kramdown
218
218
  alias :convert_xml_pi :convert_xml_comment
219
219
 
220
220
  def convert_table(el, indent)
221
- "#{' '*indent}<table#{html_attributes(el.attr)}>\n#{inner(el, indent)}#{' '*indent}</table>\n"
221
+ format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
222
222
  end
223
-
224
- def convert_thead(el, indent)
225
- "#{' '*indent}<#{el.type}#{html_attributes(el.attr)}>\n#{inner(el, indent)}#{' '*indent}</#{el.type}>\n"
226
- end
227
- alias :convert_tbody :convert_thead
228
- alias :convert_tfoot :convert_thead
229
- alias :convert_tr :convert_thead
223
+ alias :convert_thead :convert_table
224
+ alias :convert_tbody :convert_table
225
+ alias :convert_tfoot :convert_table
226
+ alias :convert_tr :convert_table
230
227
 
231
228
  ENTITY_NBSP = ::Kramdown::Utils::Entities.entity('nbsp') # :nodoc:
232
229
 
@@ -239,7 +236,7 @@ module Kramdown
239
236
  attr = el.attr.dup
240
237
  attr['style'] = (attr.has_key?('style') ? "#{attr['style']}; ": '') << "text-align: #{alignment}"
241
238
  end
242
- "#{' '*indent}<#{type}#{html_attributes(attr)}>#{res.empty? ? entity_to_str(ENTITY_NBSP) : res}</#{type}>\n"
239
+ format_as_block_html(type, attr, res.empty? ? entity_to_str(ENTITY_NBSP) : res, indent)
243
240
  end
244
241
 
245
242
  def convert_comment(el, indent)
@@ -262,7 +259,7 @@ module Kramdown
262
259
  attr['href'] = obfuscate('mailto') << ":" << obfuscate(mail_addr)
263
260
  res = obfuscate(res) if res == mail_addr
264
261
  end
265
- "<a#{html_attributes(attr)}>#{res}</a>"
262
+ format_as_span_html(el.type, attr, res)
266
263
  end
267
264
 
268
265
  def convert_img(el, indent)
@@ -271,12 +268,12 @@ module Kramdown
271
268
 
272
269
  def convert_codespan(el, indent)
273
270
  lang = extract_code_language(el.attr)
274
- if @coderay_enabled && lang
275
- result = CodeRay.scan(el.value, lang.to_sym).html(:wrap => :span, :css => @options[:coderay_css]).chomp
276
- "<code#{html_attributes(el.attr)}>#{result}</code>"
277
- else
278
- "<code#{html_attributes(el.attr)}>#{escape_html(el.value)}</code>"
279
- end
271
+ result = if @coderay_enabled && lang
272
+ CodeRay.scan(el.value, lang.to_sym).html(:wrap => :span, :css => @options[:coderay_css]).chomp
273
+ else
274
+ escape_html(el.value)
275
+ end
276
+ format_as_span_html('code', el.attr, result)
280
277
  end
281
278
 
282
279
  def convert_footnote(el, indent)
@@ -295,7 +292,7 @@ module Kramdown
295
292
  end
296
293
 
297
294
  def convert_em(el, indent)
298
- "<#{el.type}#{html_attributes(el.attr)}>#{inner(el, indent)}</#{el.type}>"
295
+ format_as_span_html(el.type, el.attr, inner(el, indent))
299
296
  end
300
297
  alias :convert_strong :convert_em
301
298
 
@@ -323,12 +320,17 @@ module Kramdown
323
320
  def convert_math(el, indent)
324
321
  block = (el.options[:category] == :block)
325
322
  value = (el.value =~ /<|&/ ? "% <![CDATA[\n#{el.value} %]]>" : el.value)
326
- "<script type=\"math/tex#{block ? '; mode=display' : ''}\">#{value}</script>#{block ? "\n" : ''}"
323
+ type = {:type => "math/tex#{block ? '; mode=display' : ''}"}
324
+ if block
325
+ format_as_block_html('script', type, value, indent)
326
+ else
327
+ format_as_span_html('script', type, value)
328
+ end
327
329
  end
328
330
 
329
331
  def convert_abbreviation(el, indent)
330
332
  title = @root.options[:abbrev_defs][el.value]
331
- "<abbr#{!title.empty? ? html_attributes(:title => title) : ''}>#{el.value}</abbr>"
333
+ format_as_span_html("abbr", {:title => (title.empty? ? nil : title)}, el.value)
332
334
  end
333
335
 
334
336
  def convert_root(el, indent)
@@ -346,6 +348,22 @@ module Kramdown
346
348
  result
347
349
  end
348
350
 
351
+ # Format the given element as span HTML.
352
+ def format_as_span_html(name, attr, body)
353
+ "<#{name}#{html_attributes(attr)}>#{body}</#{name}>"
354
+ end
355
+
356
+ # Format the given element as block HTML.
357
+ def format_as_block_html(name, attr, body, indent)
358
+ "#{' '*indent}<#{name}#{html_attributes(attr)}>#{body}</#{name}>\n"
359
+ end
360
+
361
+ # Format the given element as block HTML with a newline after the start tag and indentation
362
+ # before the end tag.
363
+ def format_as_indented_block_html(name, attr, body, indent)
364
+ "#{' '*indent}<#{name}#{html_attributes(attr)}>\n#{body}#{' '*indent}</#{name}>\n"
365
+ end
366
+
349
367
  # Generate and return an element tree for the table of contents.
350
368
  def generate_toc_tree(toc, type, attr)
351
369
  sections = Element.new(type, nil, attr)
@@ -417,7 +435,7 @@ module Kramdown
417
435
  end
418
436
  para.children << ref
419
437
  end
420
- (ol.children.empty? ? '' : "<div class=\"footnotes\">\n#{convert(ol, 2)}</div>\n")
438
+ (ol.children.empty? ? '' : format_as_indented_block_html('div', {:class => "footnotes"}, convert(ol, 2), 0))
421
439
  end
422
440
 
423
441
  end
@@ -48,7 +48,7 @@ module Kramdown
48
48
  if el.type == :header && in_toc?(el)
49
49
  attr = el.attr.dup
50
50
  attr['id'] = generate_id(el.options[:raw_text]) if @options[:auto_ids] && !attr['id']
51
- add_to_toc(el, attr['id'], @toc) if attr['id']
51
+ add_to_toc(el, attr['id']) if attr['id']
52
52
  else
53
53
  el.children.each {|child| convert(child)}
54
54
  end
@@ -57,7 +57,7 @@ module Kramdown
57
57
 
58
58
  private
59
59
 
60
- def add_to_toc(el, id, toc)
60
+ def add_to_toc(el, id)
61
61
  toc_element = Element.new(:toc, el, :id => id)
62
62
 
63
63
  success = false
@@ -20,6 +20,8 @@
20
20
  #++
21
21
  #
22
22
 
23
+ require 'yaml'
24
+
23
25
  module Kramdown
24
26
 
25
27
  # This module defines all options that are used by parsers and/or converters as well as providing
@@ -233,6 +235,36 @@ Default: false
233
235
  Used by: kramdown parser
234
236
  EOF
235
237
 
238
+ define(:link_defs, Object, {}, <<EOF) do |val|
239
+ Pre-defines link definitions
240
+
241
+ This option can be used to pre-define link definitions. The value needs
242
+ to be a Hash where the keys are the link identifiers and the values are
243
+ two element Arrays with the link URL and the link title.
244
+
245
+ If the value is a String, it has to contain a valid YAML hash and the
246
+ hash has to follow the above guidelines.
247
+
248
+ Default: {}
249
+ Used by: kramdown parser
250
+ EOF
251
+ if String === val
252
+ begin
253
+ val = YAML.load(val)
254
+ rescue RuntimeError, ArgumentError, SyntaxError
255
+ raise Kramdown::Error, "Invalid YAML value for option link_defs"
256
+ end
257
+ end
258
+ raise Kramdown::Error, "Invalid type #{val.class} for option #{name}" if !(Hash === val)
259
+ val.each do |k,v|
260
+ if !(Array === v) || v.size > 2 || v.size < 1
261
+ raise Kramdown::Error, "Invalid structure for hash value of option #{name}"
262
+ end
263
+ v << nil if v.size == 1
264
+ end
265
+ val
266
+ end
267
+
236
268
  define(:footnote_nr, Integer, 1, <<EOF)
237
269
  The number of the first footnote
238
270
 
@@ -82,6 +82,7 @@ module Kramdown
82
82
  @root.options[:abbrev_defs] = {}
83
83
  @alds = {}
84
84
  @link_defs = {}
85
+ @options[:link_defs].each {|k,v| @link_defs[normalize_link_id(k)] = v}
85
86
  @footnotes = {}
86
87
 
87
88
  @block_parsers = [:blank_line, :codeblock, :codeblock_fenced, :blockquote, :atx_header,
@@ -52,9 +52,11 @@ module Kramdown
52
52
  def parse_atx_header
53
53
  return false if !after_block_boundary?
54
54
 
55
- @src.scan(ATX_HEADER_MATCH)
56
- level, text, id = @src[1], @src[2], @src[3]
57
- text.strip!
55
+ @src.check(ATX_HEADER_MATCH)
56
+ level, text, id = @src[1], @src[2].to_s.strip, @src[3]
57
+ return false if text.empty?
58
+
59
+ @src.pos += @src.matched_size
58
60
  el = new_block_el(:header, nil, nil, :level => level.length, :raw_text => text)
59
61
  add_text(text, el)
60
62
  el.attr['id'] = id if id
@@ -23,6 +23,6 @@
23
23
  module Kramdown
24
24
 
25
25
  # The kramdown version.
26
- VERSION = '0.14.1'
26
+ VERSION = '0.14.2'
27
27
 
28
28
  end
@@ -126,6 +126,22 @@ Default: false
126
126
  Used by: kramdown parser
127
127
 
128
128
 
129
+ .TP
130
+ .B \-\-link-defs ARG
131
+
132
+ Pre-defines link definitions
133
+
134
+ This option can be used to pre-define link definitions. The value needs
135
+ to be a Hash where the keys are the link identifiers and the values are
136
+ two element Arrays with the link URL and the link title.
137
+
138
+ If the value is a String, it has to contain a valid YAML hash and the
139
+ hash has to follow the above guidelines.
140
+
141
+ Default: {}
142
+ Used by: kramdown parser
143
+
144
+
129
145
  .TP
130
146
  .B \-\-footnote-nr ARG
131
147
 
@@ -26,6 +26,12 @@
26
26
  ### not a header</p>
27
27
  </blockquote>
28
28
 
29
+ <h1>header</h1>
30
+
31
+ <p># </p>
32
+
33
+ <p>#</p>
34
+
29
35
  <h3 id="id">Header</h3>
30
36
 
31
37
  <h3 id="id">Header</h3>
@@ -23,6 +23,13 @@ paragraph
23
23
  > blockquote
24
24
  ### not a header
25
25
 
26
+
27
+ # header
28
+
29
+ #
30
+
31
+ #
32
+
26
33
  ### Header {#id}
27
34
 
28
35
  ### Header ## {#id}