motion-markdown-it 0.4.0.3.0 → 4.1.0.1

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.
@@ -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