motion-markdown-it 0.4.0.3.0 → 4.1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,6 +9,8 @@ module MarkdownIt
9
9
  include MarkdownIt::Common::Utils
10
10
  extend MarkdownIt::Common::Utils
11
11
 
12
+ attr_accessor :rules
13
+
12
14
  # Default Rules
13
15
  #------------------------------------------------------------------------------
14
16
  def self.code_inline(tokens, idx)
@@ -5,7 +5,8 @@
5
5
  module MarkdownIt
6
6
  module RulesCore
7
7
  class Linkify
8
-
8
+ MAILTO_RE = /^mailto\:/
9
+
9
10
  #------------------------------------------------------------------------------
10
11
  def self.isLinkOpen(str)
11
12
  return !(/^<a[>\s]/i =~ str).nil?
@@ -18,119 +19,116 @@ module MarkdownIt
18
19
  def self.linkify(state)
19
20
  blockTokens = state.tokens
20
21
 
21
- return if (!state.md.options[:linkify])
22
+ return if (!state.md.options[:linkify])
22
23
 
23
- (0...blockTokens.length).each do |j|
24
- if (blockTokens[j].type != 'inline' || !state.md.linkify.pretest(blockTokens[j].content))
25
- next
26
- end
24
+ (0...blockTokens.length).each do |j|
25
+ if (blockTokens[j].type != 'inline' || !state.md.linkify.pretest(blockTokens[j].content))
26
+ next
27
+ end
27
28
 
28
- tokens = blockTokens[j].children
29
+ tokens = blockTokens[j].children
29
30
 
30
- htmlLinkLevel = 0
31
+ htmlLinkLevel = 0
31
32
 
32
- # We scan from the end, to keep position when new tags added.
33
- # Use reversed logic in links start/end match
34
- i = tokens.length - 1
35
- while i >= 0
36
- currentToken = tokens[i]
33
+ # We scan from the end, to keep position when new tags added.
34
+ # Use reversed logic in links start/end match
35
+ i = tokens.length - 1
36
+ while i >= 0
37
+ currentToken = tokens[i]
37
38
 
38
- # Skip content of markdown links
39
- if (currentToken.type == 'link_close')
39
+ # Skip content of markdown links
40
+ if (currentToken.type == 'link_close')
41
+ i -= 1
42
+ while (tokens[i].level != currentToken.level && tokens[i].type != 'link_open')
40
43
  i -= 1
41
- while (tokens[i].level != currentToken.level && tokens[i].type != 'link_open')
42
- i -= 1
43
- end
44
- next
45
44
  end
45
+ i -= 1 and next
46
+ end
46
47
 
47
- # Skip content of html tag links
48
- if (currentToken.type == 'html_inline')
49
- if (isLinkOpen(currentToken.content) && htmlLinkLevel > 0)
50
- htmlLinkLevel -= 1
51
- end
52
- if (isLinkClose(currentToken.content))
53
- htmlLinkLevel -= 1
54
- end
48
+ # Skip content of html tag links
49
+ if (currentToken.type == 'html_inline')
50
+ if (isLinkOpen(currentToken.content) && htmlLinkLevel > 0)
51
+ htmlLinkLevel -= 1
55
52
  end
56
- next if (htmlLinkLevel > 0)
57
-
58
- if (currentToken.type == 'text' && state.md.linkify =~ currentToken.content)
59
-
60
- text = currentToken.content
61
- links = state.md.linkify.match(text)
62
-
63
- # Now split string to nodes
64
- nodes = []
65
- level = currentToken.level
66
- lastPos = 0
67
-
68
- (0...links.length).each do |ln|
69
- url = links[ln].url
70
- fullUrl = state.md.normalizeLink.call(url)
71
- next if (!state.md.validateLink.call(fullUrl))
72
-
73
- urlText = links[ln].text
74
-
75
- # Linkifier might send raw hostnames like "example.com", where url
76
- # starts with domain name. So we prepend http:// in those cases,
77
- # and remove it afterwards.
78
- #
79
-
80
- # TODO work on this when clearer
81
- puts "Linkify requires work"
82
- # if (!links[ln].schema)
83
- # urlText = state.md.normalizeLinkText.call('http://' + urlText).replace(/^http:\/\//, '')
84
- # elsif (links[ln].schema == 'mailto:' && !Regexp.new('^mailto:/i') =~ urlText)
85
- # urlText = state.md.normalizeLinkText.call('mailto:' + urlText).replace(/^mailto:/, '');
86
- # } else {
87
- # urlText = state.md.normalizeLinkText.call(urlText);
88
- # }
89
-
90
- pos = links[ln].index
91
-
92
- if (pos > lastPos)
93
- token = Token.new('text', '', 0)
94
- token.content = text.slice(lastPos...pos)
95
- token.level = level
96
- nodes.push(token)
97
- end
98
-
99
- token = Token.new('link_open', 'a', 1)
100
- token.attrs = [ [ 'href', fullUrl ] ]
101
- token.level = level
102
- level += 1
103
- token.markup = 'linkify'
104
- token.info = 'auto'
105
- nodes.push(token)
106
-
107
- token = Token.new('text', '', 0)
108
- token.content = urlText
109
- token.level = level
110
- nodes.push(token)
53
+ if (isLinkClose(currentToken.content))
54
+ htmlLinkLevel += 1
55
+ end
56
+ end
57
+ i -= 1 and next if (htmlLinkLevel > 0)
58
+
59
+ if (currentToken.type == 'text' && state.md.linkify.test(currentToken.content))
60
+
61
+ text = currentToken.content
62
+ links = state.md.linkify.match(text)
63
+
64
+ # Now split string to nodes
65
+ nodes = []
66
+ level = currentToken.level
67
+ lastPos = 0
68
+
69
+ (0...links.length).each do |ln|
70
+ url = links[ln].url
71
+ fullUrl = state.md.normalizeLink.call(url)
72
+ next if (!state.md.validateLink.call(fullUrl))
73
+
74
+ urlText = links[ln].text
75
+
76
+ # Linkifier might send raw hostnames like "example.com", where url
77
+ # starts with domain name. So we prepend http:// in those cases,
78
+ # and remove it afterwards.
79
+ if links[ln].schema.empty?
80
+ urlText = state.md.normalizeLinkText.call("http://#{urlText}").sub(/^http:\/\//, '')
81
+ elsif (links[ln].schema == 'mailto:' && !(MAILTO_RE =~ urlText))
82
+ urlText = state.md.normalizeLinkText.call("mailto:#{urlText}").sub(MAILTO_RE, '')
83
+ else
84
+ urlText = state.md.normalizeLinkText.call(urlText)
85
+ end
111
86
 
112
- token = Token.new('link_close', 'a', -1)
113
- level -= 1
114
- token.level = level
115
- token.markup = 'linkify'
116
- token.info = 'auto'
117
- nodes.push(token)
87
+ pos = links[ln].index
118
88
 
119
- lastPos = links[ln].lastIndex
120
- end
121
- if (lastPos < text.length)
89
+ if (pos > lastPos)
122
90
  token = Token.new('text', '', 0)
123
- token.content = text.slice_to_end(lastPos)
91
+ token.content = text.slice(lastPos...pos)
124
92
  token.level = level
125
93
  nodes.push(token)
126
94
  end
127
95
 
128
- # replace current node
129
- blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, nodes)
96
+ token = Token.new('link_open', 'a', 1)
97
+ token.attrs = [ [ 'href', fullUrl ] ]
98
+ token.level = level
99
+ level += 1
100
+ token.markup = 'linkify'
101
+ token.info = 'auto'
102
+ nodes.push(token)
103
+
104
+ token = Token.new('text', '', 0)
105
+ token.content = urlText
106
+ token.level = level
107
+ nodes.push(token)
108
+
109
+ token = Token.new('link_close', 'a', -1)
110
+ level -= 1
111
+ token.level = level
112
+ token.markup = 'linkify'
113
+ token.info = 'auto'
114
+ nodes.push(token)
115
+
116
+ lastPos = links[ln].lastIndex
130
117
  end
131
- i -= 1
118
+ if (lastPos < text.length)
119
+ token = Token.new('text', '', 0)
120
+ token.content = text.slice_to_end(lastPos)
121
+ token.level = level
122
+ nodes.push(token)
123
+ end
124
+
125
+ # replace current node
126
+ tokens[i] = nodes
127
+ blockTokens[j].children = (tokens.flatten!(1))
132
128
  end
129
+ i -= 1
133
130
  end
131
+ end
134
132
  end
135
133
 
136
134
  end
@@ -15,7 +15,7 @@ module MarkdownIt
15
15
  module RulesCore
16
16
  class Replacements
17
17
 
18
- # TODO:
18
+ # TODO (from original)
19
19
  # - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾
20
20
  # - miltiplication 2 x 4 -> 2 × 4
21
21
 
@@ -54,8 +54,8 @@ module MarkdownIt
54
54
  lastChar = t.begin(0) - 1 >= 0 ? text.charCodeAt(t.begin(0) - 1) : 0x20
55
55
  nextChar = pos < max ? text.charCodeAt(pos) : 0x20
56
56
 
57
- isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(lastChar.chr)
58
- isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(nextChar.chr)
57
+ isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(lastChar.chr(Encoding::UTF_8))
58
+ isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(nextChar.chr(Encoding::UTF_8))
59
59
 
60
60
  isLastWhiteSpace = isWhiteSpace(lastChar)
61
61
  isNextWhiteSpace = isWhiteSpace(nextChar)
@@ -30,8 +30,8 @@ module MarkdownIt
30
30
  # treat end of the line as a whitespace
31
31
  nextChar = pos < max ? state.src.charCodeAt(pos) : 0x20
32
32
 
33
- isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(lastChar.chr)
34
- isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(nextChar.chr)
33
+ isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(lastChar.chr(Encoding::UTF_8))
34
+ isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(nextChar.chr(Encoding::UTF_8))
35
35
 
36
36
  isLastWhiteSpace = isWhiteSpace(lastChar)
37
37
  isNextWhiteSpace = isWhiteSpace(nextChar)
@@ -1,5 +1,5 @@
1
1
  module MotionMarkdownIt
2
2
 
3
- VERSION = '0.4.0.3.0'
3
+ VERSION = '4.1.0.1'
4
4
 
5
5
  end
@@ -16,6 +16,7 @@ else
16
16
  require 'mdurl-rb'
17
17
  require 'uc.micro-rb'
18
18
  require 'linkify-it-rb'
19
+ require 'motion-markdown-it/version'
19
20
  require 'motion-markdown-it/presets/default'
20
21
  require 'motion-markdown-it/presets/zero'
21
22
  require 'motion-markdown-it/presets/commonmark'
@@ -25,6 +26,7 @@ else
25
26
  require 'motion-markdown-it/common/url_schemas'
26
27
  require 'motion-markdown-it/common/html_re'
27
28
  require 'motion-markdown-it/common/string'
29
+ require 'motion-markdown-it/common/simpleidn'
28
30
  require 'motion-markdown-it/helpers/parse_link_destination'
29
31
  require 'motion-markdown-it/helpers/parse_link_label'
30
32
  require 'motion-markdown-it/helpers/parse_link_title'
@@ -1,5 +1,6 @@
1
- =begin
2
- runs = 1 #50
1
+ require 'kramdown'
2
+
3
+ runs = 50
3
4
  files = ['mdsyntax.text', 'mdbasics.text']
4
5
  benchmark_dir = File.join(File.dirname(__FILE__), '../../benchmark')
5
6
 
@@ -14,10 +15,10 @@ files.each do |file|
14
15
  # results = Benchmark.bmbm do |b|
15
16
  results = Benchmark.bm do |b|
16
17
  b.report("motion-markdown-it 0.1.0") do
17
- parser = MarkdownIt::Parser.new(:commonmark, { html: false })
18
+ parser = MarkdownIt::Parser.new({ html: true, linkify: true, typographer: true })
18
19
  runs.times { parser.render(data) }
19
20
  end
20
- # b.report("kramdown #{Kramdown::VERSION}") { runs.times { Kramdown::Document.new(data).to_html } }
21
+ b.report("kramdown #{Kramdown::VERSION}") { runs.times { Kramdown::Document.new(data).to_html } }
21
22
  # b.report("markdown-it 4.0.1 JS") { runs.times { NSApplication.sharedApplication.delegate.markdown_it(data) } }
22
23
  # b.report(" hoedown 3.0.1") do
23
24
  # runs.times do
@@ -41,4 +42,3 @@ describe "Benchmark Test" do
41
42
  expect(true).to eq true
42
43
  end
43
44
  end
44
- =end
@@ -26,40 +26,39 @@ describe 'API' do
26
26
  }.to raise_error
27
27
  end
28
28
 
29
- # TODO #------------------------------------------------------------------------------
30
- # it 'plugin' do
31
- # plugin[0] = false
32
- #
33
- # plugin[1] = lambda {|plugin, opts| plugin[0] = true if (opts == 'bar') }
34
- #
35
- # md = MarkdownIt::Parser.new
36
- #
37
- # md.use(plugin, 'foo');
38
- # expect(@succeeded).to eq false
39
- # md.use(plugin, 'bar')
40
- # expect(@succeeded).to eq true
41
- # end
29
+ #------------------------------------------------------------------------------
30
+ it 'plugin' do
31
+ @success = false
32
+ plugin = lambda {|plugin, opts| @success = true if (opts == 'bar') }
33
+
34
+ md = MarkdownIt::Parser.new
35
+
36
+ md.use(plugin, 'foo')
37
+ expect(@success).to eq false
38
+ md.use(plugin, 'bar')
39
+ expect(@success).to eq true
40
+ end
41
+
42
+ #------------------------------------------------------------------------------
43
+ it 'highlight' do
44
+ md = MarkdownIt::Parser.new({
45
+ highlight: lambda do |str, obj|
46
+ return '==' + str + '=='
47
+ end
48
+ })
49
+
50
+ expect(md.render("```\nhl\n```")).to eq "<pre><code>==hl\n==</code></pre>\n"
51
+ end
42
52
 
43
- # it('highlight', function () {
44
- # var md = markdownit({
45
- # highlight: function (str) {
46
- # return '==' + str + '==';
47
- # }
48
- # });
49
- #
50
- # assert.strictEqual(md.render("```\nhl\n```"), "<pre><code>==hl\n==</code></pre>\n");
51
- # });
52
- #
53
- # it('highlight escape by default', function () {
54
- # var md = markdownit({
55
- # highlight: function () {
56
- # return '';
57
- # }
58
- # });
59
- #
60
- # assert.strictEqual(md.render("```\n&\n```"), "<pre><code>&amp;\n</code></pre>\n");
61
- # });
53
+ #------------------------------------------------------------------------------
54
+ it 'highlight escape by default' do
55
+ md = MarkdownIt::Parser.new({highlight: lambda {|value, obj| return nil }})
56
+
57
+ # assert.strictEqual(md.render("```\n&\n```"), "<pre><code>&amp;\n</code></pre>\n");
58
+ expect(md.render("```\n&\n```")).to eq "<pre><code>&amp;\n</code></pre>\n"
59
+ end
62
60
 
61
+ #------------------------------------------------------------------------------
63
62
  it 'force hardbreaks' do
64
63
  md = MarkdownIt::Parser.new({ breaks: false })
65
64
  expect(md.render("a\nb")).to eq "<p>a\nb</p>\n"
@@ -70,208 +69,229 @@ describe 'API' do
70
69
  expect(md.render("a\nb")).to eq "<p>a<br />\nb</p>\n"
71
70
  end
72
71
 
72
+ #------------------------------------------------------------------------------
73
73
  it 'xhtmlOut enabled' do
74
74
  md = MarkdownIt::Parser.new({ xhtmlOut: true })
75
75
 
76
76
  expect(md.render('---')).to eq "<hr />\n"
77
- # TODO expect(md.render('![]()')).to eq "<p><img src=\"\" alt=\"\" /></p>\n"
77
+ expect(md.render('![]()')).to eq "<p><img src=\"\" alt=\"\" /></p>\n"
78
78
  expect(md.render("a \\\nb")).to eq "<p>a <br />\nb</p>\n"
79
79
  end
80
80
 
81
+ #------------------------------------------------------------------------------
81
82
  it 'xhtmlOut disabled' do
82
83
  md = MarkdownIt::Parser.new
83
84
 
84
85
  expect(md.render('---')).to eq "<hr>\n"
85
- # TODO expect(md.render('![]()')).to eq "<p><img src=\"\" alt=\"\"></p>\n"
86
+ expect(md.render('![]()')).to eq "<p><img src=\"\" alt=\"\"></p>\n"
86
87
  expect(md.render("a \\\nb")).to eq "<p>a <br>\nb</p>\n"
87
88
  end
88
89
 
89
- # it('bulk enable/disable rules in different chains', function () {
90
- # var md = markdownit();
91
- #
92
- # var was = {
93
- # core: md.core.ruler.getRules('').length,
94
- # block: md.block.ruler.getRules('').length,
95
- # inline: md.inline.ruler.getRules('').length
96
- # };
97
- #
98
- # // Disable 2 rule in each chain & compare result
99
- # md.disable([ 'block', 'inline', 'code', 'fence', 'emphasis', 'entity' ]);
100
- #
101
- # var now = {
102
- # core: md.core.ruler.getRules('').length + 2,
103
- # block: md.block.ruler.getRules('').length + 2,
104
- # inline: md.inline.ruler.getRules('').length + 2
105
- # };
106
- #
107
- # assert.deepEqual(was, now);
108
- #
109
- # // Enable the same rules back
110
- # md.enable([ 'block', 'inline', 'code', 'fence', 'emphasis', 'entity' ]);
111
- #
112
- # var back = {
113
- # core: md.core.ruler.getRules('').length,
114
- # block: md.block.ruler.getRules('').length,
115
- # inline: md.inline.ruler.getRules('').length
116
- # };
117
- #
118
- # assert.deepEqual(was, back);
119
- # });
120
- #
121
- # it('bulk enable/disable with errors control', function () {
122
- # var md = markdownit();
123
- #
124
- # assert.throws(function () {
125
- # md.enable([ 'link', 'code', 'invalid' ]);
126
- # });
127
- # assert.throws(function () {
128
- # md.disable([ 'link', 'code', 'invalid' ]);
129
- # });
130
- # assert.doesNotThrow(function () {
131
- # md.enable([ 'link', 'code' ]);
132
- # });
133
- # assert.doesNotThrow(function () {
134
- # md.disable([ 'link', 'code' ]);
135
- # });
136
- # });
137
- #
138
- # it('bulk enable/disable should understand strings', function () {
139
- # var md = markdownit();
140
- #
141
- # md.disable('emphasis');
142
- # assert(md.renderInline('_foo_'), '_foo_');
143
- #
144
- # md.enable('emphasis');
145
- # assert(md.renderInline('_foo_'), '<em>foo</em>');
146
- # });
147
- #
148
- # });
149
- #
150
- #
151
- # describe('Misc', function () {
152
- #
153
- # it('Should replace NULL characters', function () {
154
- # var md = markdownit();
155
- #
156
- # assert.strictEqual(md.render('foo\u0000bar'), '<p>foo\uFFFDbar</p>\n');
157
- # });
158
- #
159
- # it('Should correctly parse strings without tailing \\n', function () {
160
- # var md = markdownit();
161
- #
162
- # assert.strictEqual(md.render('123'), '<p>123</p>\n');
163
- # assert.strictEqual(md.render('123\n'), '<p>123</p>\n');
164
- # });
165
- #
166
- # it('Should quickly exit on empty string', function () {
167
- # var md = markdownit();
168
- #
169
- # assert.strictEqual(md.render(''), '');
170
- # });
171
- #
172
- # it('Should parse inlines only', function () {
173
- # var md = markdownit();
174
- #
175
- # assert.strictEqual(md.renderInline('a *b* c'), 'a <em>b</em> c');
176
- # });
177
- #
178
- # it('Renderer should have pluggable inline and block rules', function () {
179
- # var md = markdownit();
180
- #
181
- # md.renderer.rules.em_open = function () { return '<it>'; };
182
- # md.renderer.rules.em_close = function () { return '</it>'; };
183
- # md.renderer.rules.paragraph_open = function () { return '<par>'; };
184
- # md.renderer.rules.paragraph_close = function () { return '</par>'; };
185
- #
186
- # assert.strictEqual(md.render('*b*'), '<par><it>b</it></par>');
187
- # });
188
- #
189
- # it('Zero preset should disable everything', function () {
190
- # var md = markdownit('zero');
191
- #
192
- # assert.strictEqual(md.render('___foo___'), '<p>___foo___</p>\n');
193
- # assert.strictEqual(md.renderInline('___foo___'), '___foo___');
194
- #
195
- # md.enable('emphasis');
196
- #
197
- # assert.strictEqual(md.render('___foo___'), '<p><strong><em>foo</em></strong></p>\n');
198
- # assert.strictEqual(md.renderInline('___foo___'), '<strong><em>foo</em></strong>');
199
- # });
200
- #
201
- # it('Should correctly check block termination rules when those are disabled (#13)', function () {
202
- # var md = markdownit('zero');
203
- #
204
- # assert.strictEqual(md.render('foo\nbar'), '<p>foo\nbar</p>\n');
205
- # });
206
- #
207
- # it('Should render link target attr', function () {
208
- # var md = markdownit()
209
- # .use(require('markdown-it-for-inline'), 'target', 'link_open', function (tokens, idx) {
210
- # tokens[idx].attrs.push([ 'target', '_blank' ]);
211
- # });
212
- #
213
- # assert.strictEqual(md.render('[foo](bar)'), '<p><a href="bar" target="_blank">foo</a></p>\n');
214
- # });
215
- #
216
- # });
217
- #
218
- #
219
- # describe('Url normalization', function () {
220
- #
221
- # it('Should be overridable', function () {
222
- # var md = markdownit({ linkify: true });
223
- #
224
- # md.normalizeLink = function (url) {
225
- # assert(url.match(/example\.com/), 'wrong url passed');
226
- # return 'LINK';
227
- # };
228
- # md.normalizeLinkText = function (url) {
229
- # assert(url.match(/example\.com/), 'wrong url passed');
230
- # return 'TEXT';
231
- # };
232
- #
233
- # assert.strictEqual(md.render('foo@example.com'), '<p><a href="LINK">TEXT</a></p>\n');
234
- # assert.strictEqual(md.render('http://example.com'), '<p><a href="LINK">TEXT</a></p>\n');
235
- # assert.strictEqual(md.render('<foo@example.com>'), '<p><a href="LINK">TEXT</a></p>\n');
236
- # assert.strictEqual(md.render('<http://example.com>'), '<p><a href="LINK">TEXT</a></p>\n');
237
- # assert.strictEqual(md.render('[test](http://example.com)'), '<p><a href="LINK">test</a></p>\n');
238
- # assert.strictEqual(md.render('![test](http://example.com)'), '<p><img src="LINK" alt="test"></p>\n');
239
- # });
240
- #
241
- # });
242
- #
243
- #
244
- # describe('Links validation', function () {
245
- #
246
- # it('Override validator, disable everything', function () {
247
- # var md = markdownit({ linkify: true });
248
- #
249
- # md.validateLink = function () { return false; };
250
- #
251
- # assert.strictEqual(md.render('foo@example.com'), '<p>foo@example.com</p>\n');
252
- # assert.strictEqual(md.render('http://example.com'), '<p>http://example.com</p>\n');
253
- # assert.strictEqual(md.render('<foo@example.com>'), '<p>&lt;foo@example.com&gt;</p>\n');
254
- # assert.strictEqual(md.render('<http://example.com>'), '<p>&lt;http://example.com&gt;</p>\n');
255
- # assert.strictEqual(md.render('[test](http://example.com)'), '<p>[test](http://example.com)</p>\n');
256
- # assert.strictEqual(md.render('![test](http://example.com)'), '<p>![test](http://example.com)</p>\n');
257
- # });
258
- #
259
- # });
260
- #
261
- #
262
- # describe('maxNesting', function () {
263
- #
264
- # it('Inline parser should not nest above limit', function () {
265
- # var md = markdownit({ maxNesting: 2 });
266
- # assert.strictEqual(md.render('*foo *bar *baz* bar* foo*'), '<p><em>foo <em>bar *baz* bar</em> foo</em></p>\n');
267
- # });
268
- #
269
- # it('Block parser should not nest above limit', function () {
270
- # var md = markdownit({ maxNesting: 2 });
271
- # assert.strictEqual(
272
- # md.render('>foo\n>>bar\n>>>baz'),
273
- # '<blockquote>\n<p>foo</p>\n<blockquote></blockquote>\n</blockquote>\n'
274
- # );
275
- # });
90
+ #------------------------------------------------------------------------------
91
+ it 'bulk enable/disable rules in different chains' do
92
+ md = MarkdownIt::Parser.new
93
+
94
+ was = {
95
+ core: md.core.ruler.getRules('').length,
96
+ block: md.block.ruler.getRules('').length,
97
+ inline: md.inline.ruler.getRules('').length
98
+ }
99
+
100
+ # Disable 2 rule in each chain & compare result
101
+ md.disable([ 'block', 'inline', 'code', 'fence', 'emphasis', 'entity' ])
102
+
103
+ now = {
104
+ core: md.core.ruler.getRules('').length + 2,
105
+ block: md.block.ruler.getRules('').length + 2,
106
+ inline: md.inline.ruler.getRules('').length + 2
107
+ }
108
+
109
+ expect(was).to eq now
110
+
111
+ # Enable the same rules back
112
+ md.enable([ 'block', 'inline', 'code', 'fence', 'emphasis', 'entity' ])
113
+
114
+ back = {
115
+ core: md.core.ruler.getRules('').length,
116
+ block: md.block.ruler.getRules('').length,
117
+ inline: md.inline.ruler.getRules('').length
118
+ }
119
+
120
+ expect(was).to eq back
121
+ end
122
+
123
+ #------------------------------------------------------------------------------
124
+ it 'bulk enable/disable with errors control' do
125
+ md = MarkdownIt::Parser.new
126
+ expect {
127
+ md.enable([ 'link', 'code', 'invalid' ])
128
+ }.to raise_error
129
+
130
+ expect {
131
+ md.disable([ 'link', 'code', 'invalid' ])
132
+ }.to raise_error
133
+
134
+ expect {
135
+ md.enable([ 'link', 'code' ])
136
+ }.to_not raise_error
137
+
138
+ expect {
139
+ md.disable([ 'link', 'code' ])
140
+ }.to_not raise_error
141
+ end
142
+
143
+ #------------------------------------------------------------------------------
144
+ it 'bulk enable/disable should understand strings' do
145
+ md = MarkdownIt::Parser.new
146
+
147
+ md.disable('emphasis')
148
+ expect(md.renderInline('_foo_')).to eq '_foo_'
149
+
150
+ md.enable('emphasis')
151
+ expect(md.renderInline('_foo_')).to eq '<em>foo</em>'
152
+ end
153
+
154
+ end
155
+
156
+
157
+ #------------------------------------------------------------------------------
158
+ describe 'Misc' do
159
+
160
+ #------------------------------------------------------------------------------
161
+ it 'Should replace NULL characters' do
162
+ md = MarkdownIt::Parser.new
163
+
164
+ expect(md.render("foo\u0000bar")).to eq "<p>foo\\uFFFDbar</p>\n"
165
+ end
166
+
167
+ #------------------------------------------------------------------------------
168
+ it 'Should correctly parse strings without tailing \\n' do
169
+ md = MarkdownIt::Parser.new
170
+
171
+ expect(md.render('123')).to eq "<p>123</p>\n"
172
+ expect(md.render("123\n")).to eq "<p>123</p>\n"
173
+ end
174
+
175
+ #------------------------------------------------------------------------------
176
+ it 'Should quickly exit on empty string' do
177
+ md = MarkdownIt::Parser.new
178
+
179
+ expect(md.render('')).to eq ''
180
+ end
181
+
182
+ #------------------------------------------------------------------------------
183
+ it 'Should parse inlines only' do
184
+ md = MarkdownIt::Parser.new
185
+
186
+ expect(md.renderInline('a *b* c')).to eq 'a <em>b</em> c'
187
+ end
188
+
189
+ #------------------------------------------------------------------------------
190
+ it 'Renderer should have pluggable inline and block rules' do
191
+ md = MarkdownIt::Parser.new
192
+
193
+ md.renderer.rules['em_open'] = lambda {|tokens, idx, options, env, renderer| return '<it>' }
194
+ md.renderer.rules['em_close'] = lambda {|tokens, idx, options, env, renderer| return '</it>' }
195
+ md.renderer.rules['paragraph_open'] = lambda {|tokens, idx, options, env, renderer| return '<par>' }
196
+ md.renderer.rules['paragraph_close'] = lambda {|tokens, idx, options, env, renderer| return '</par>' }
197
+
198
+ expect(md.render('*b*')).to eq '<par><it>b</it></par>'
199
+ end
200
+
201
+ #------------------------------------------------------------------------------
202
+ it 'Zero preset should disable everything' do
203
+ md = MarkdownIt::Parser.new(:zero)
204
+
205
+ expect(md.render('___foo___')).to eq "<p>___foo___</p>\n"
206
+ expect(md.renderInline('___foo___')).to eq '___foo___'
207
+
208
+ md.enable('emphasis')
209
+
210
+ expect(md.render('___foo___')).to eq "<p><strong><em>foo</em></strong></p>\n"
211
+ expect(md.renderInline('___foo___')).to eq '<strong><em>foo</em></strong>'
212
+ end
213
+
214
+ #------------------------------------------------------------------------------
215
+ it 'Should correctly check block termination rules when those are disabled (#13)' do
216
+ md = MarkdownIt::Parser.new(:zero)
217
+
218
+ expect(md.render("foo\nbar")).to eq "<p>foo\nbar</p>\n"
219
+ end
220
+
221
+ # TODO ------------------------------------------------------------------------------
222
+ # it 'Should render link target attr' do
223
+ # md = MarkdownIt::Parser.new.
224
+ # use(require('markdown-it-for-inline'), 'target', 'link_open', function (tokens, idx) {
225
+ # tokens[idx].attrs.push([ 'target', '_blank' ]);
226
+ # });
227
+ #
228
+ # assert.strictEqual(md.render('[foo](bar)'), '<p><a href="bar" target="_blank">foo</a></p>\n');
229
+ # end
230
+
231
+ end
232
+
233
+
234
+ #------------------------------------------------------------------------------
235
+ describe 'Url normalization' do
236
+
237
+ #------------------------------------------------------------------------------
238
+ it 'Should be overridable' do
239
+ md = MarkdownIt::Parser.new({ linkify: true })
240
+
241
+ md.normalizeLink = lambda do |url|
242
+ expect(/example\.com/ =~ url).to_not eq nil
243
+ return 'LINK'
244
+ end
245
+
246
+ md.normalizeLinkText = lambda do |url|
247
+ expect(/example\.com/ =~ url).to_not eq nil
248
+ return 'TEXT'
249
+ end
250
+
251
+ expect(md.render('foo@example.com')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
252
+ expect(md.render('http://example.com')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
253
+ expect(md.render('<foo@example.com>')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
254
+ expect(md.render('<http://example.com>')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
255
+ expect(md.render('[test](http://example.com)')).to eq "<p><a href=\"LINK\">test</a></p>\n"
256
+ expect(md.render('![test](http://example.com)')).to eq "<p><img src=\"LINK\" alt=\"test\"></p>\n"
257
+ end
258
+
259
+ end
260
+
261
+
262
+ #------------------------------------------------------------------------------
263
+ describe 'Links validation' do
264
+
265
+ #------------------------------------------------------------------------------
266
+ it 'Override validator, disable everything' do
267
+ md = MarkdownIt::Parser.new({ linkify: true })
268
+
269
+ md.validateLink = lambda { |url| return false }
270
+
271
+ expect(md.render('foo@example.com')).to eq "<p>foo@example.com</p>\n"
272
+ expect(md.render('http://example.com')).to eq "<p>http://example.com</p>\n"
273
+ expect(md.render('<foo@example.com>')).to eq "<p>&lt;foo@example.com&gt;</p>\n"
274
+ expect(md.render('<http://example.com>')).to eq "<p>&lt;http://example.com&gt;</p>\n"
275
+ expect(md.render('[test](http://example.com)')).to eq "<p>[test](http://example.com)</p>\n"
276
+ expect(md.render('![test](http://example.com)')).to eq "<p>![test](http://example.com)</p>\n"
277
+ end
278
+
279
+ end
280
+
281
+
282
+ #------------------------------------------------------------------------------
283
+ describe 'maxNesting' do
284
+
285
+ #------------------------------------------------------------------------------
286
+ it 'Inline parser should not nest above limit' do
287
+ md = MarkdownIt::Parser.new({ maxNesting: 2 })
288
+ expect(md.render('*foo *bar *baz* bar* foo*')).to eq "<p><em>foo <em>bar *baz* bar</em> foo</em></p>\n"
289
+ end
290
+
291
+ #------------------------------------------------------------------------------
292
+ it 'Block parser should not nest above limit' do
293
+ md = MarkdownIt::Parser.new({ maxNesting: 2 })
294
+ expect(md.render(">foo\n>>bar\n>>>baz")).to eq "<blockquote>\n<p>foo</p>\n<blockquote></blockquote>\n</blockquote>\n"
295
+ end
276
296
 
277
297
  end