motion-markdown-it 0.4.0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +243 -0
  3. data/lib/motion-markdown-it.rb +71 -0
  4. data/lib/motion-markdown-it/common/entities.rb +1084 -0
  5. data/lib/motion-markdown-it/common/html_blocks.rb +60 -0
  6. data/lib/motion-markdown-it/common/html_re.rb +28 -0
  7. data/lib/motion-markdown-it/common/string.rb +14 -0
  8. data/lib/motion-markdown-it/common/url_schemas.rb +173 -0
  9. data/lib/motion-markdown-it/common/utils.rb +216 -0
  10. data/lib/motion-markdown-it/helpers/parse_link_destination.rb +75 -0
  11. data/lib/motion-markdown-it/helpers/parse_link_label.rb +51 -0
  12. data/lib/motion-markdown-it/helpers/parse_link_title.rb +48 -0
  13. data/lib/motion-markdown-it/index.rb +507 -0
  14. data/lib/motion-markdown-it/parser_block.rb +113 -0
  15. data/lib/motion-markdown-it/parser_core.rb +46 -0
  16. data/lib/motion-markdown-it/parser_inline.rb +121 -0
  17. data/lib/motion-markdown-it/presets/commonmark.rb +76 -0
  18. data/lib/motion-markdown-it/presets/default.rb +42 -0
  19. data/lib/motion-markdown-it/presets/zero.rb +59 -0
  20. data/lib/motion-markdown-it/renderer.rb +286 -0
  21. data/lib/motion-markdown-it/ruler.rb +327 -0
  22. data/lib/motion-markdown-it/rules_block/blockquote.rb +138 -0
  23. data/lib/motion-markdown-it/rules_block/code.rb +35 -0
  24. data/lib/motion-markdown-it/rules_block/fence.rb +94 -0
  25. data/lib/motion-markdown-it/rules_block/heading.rb +56 -0
  26. data/lib/motion-markdown-it/rules_block/hr.rb +45 -0
  27. data/lib/motion-markdown-it/rules_block/html_block.rb +73 -0
  28. data/lib/motion-markdown-it/rules_block/lheading.rb +54 -0
  29. data/lib/motion-markdown-it/rules_block/list.rb +242 -0
  30. data/lib/motion-markdown-it/rules_block/paragraph.rb +51 -0
  31. data/lib/motion-markdown-it/rules_block/reference.rb +161 -0
  32. data/lib/motion-markdown-it/rules_block/state_block.rb +184 -0
  33. data/lib/motion-markdown-it/rules_block/table.rb +161 -0
  34. data/lib/motion-markdown-it/rules_core/block.rb +20 -0
  35. data/lib/motion-markdown-it/rules_core/inline.rb +20 -0
  36. data/lib/motion-markdown-it/rules_core/linkify.rb +138 -0
  37. data/lib/motion-markdown-it/rules_core/normalize.rb +44 -0
  38. data/lib/motion-markdown-it/rules_core/replacements.rb +90 -0
  39. data/lib/motion-markdown-it/rules_core/smartquotes.rb +158 -0
  40. data/lib/motion-markdown-it/rules_core/state_core.rb +20 -0
  41. data/lib/motion-markdown-it/rules_inline/autolink.rb +74 -0
  42. data/lib/motion-markdown-it/rules_inline/backticks.rb +51 -0
  43. data/lib/motion-markdown-it/rules_inline/emphasis.rb +172 -0
  44. data/lib/motion-markdown-it/rules_inline/entity.rb +51 -0
  45. data/lib/motion-markdown-it/rules_inline/escape.rb +55 -0
  46. data/lib/motion-markdown-it/rules_inline/html_inline.rb +49 -0
  47. data/lib/motion-markdown-it/rules_inline/image.rb +158 -0
  48. data/lib/motion-markdown-it/rules_inline/link.rb +153 -0
  49. data/lib/motion-markdown-it/rules_inline/newline.rb +47 -0
  50. data/lib/motion-markdown-it/rules_inline/state_inline.rb +57 -0
  51. data/lib/motion-markdown-it/rules_inline/strikethrough.rb +130 -0
  52. data/lib/motion-markdown-it/rules_inline/text.rb +94 -0
  53. data/lib/motion-markdown-it/token.rb +134 -0
  54. data/lib/motion-markdown-it/version.rb +5 -0
  55. data/spec/motion-markdown-it/bench_mark_spec.rb +44 -0
  56. data/spec/motion-markdown-it/commonmark_spec.rb +16 -0
  57. data/spec/motion-markdown-it/markdown_it_spec.rb +18 -0
  58. data/spec/motion-markdown-it/misc_spec.rb +277 -0
  59. data/spec/motion-markdown-it/ruler_spec.rb +153 -0
  60. data/spec/motion-markdown-it/testgen_helper.rb +68 -0
  61. data/spec/motion-markdown-it/token_spec.rb +17 -0
  62. data/spec/motion-markdown-it/utils_spec.rb +82 -0
  63. data/spec/spec_helper.rb +6 -0
  64. metadata +158 -0
@@ -0,0 +1,75 @@
1
+ # Parse link destination
2
+ #------------------------------------------------------------------------------
3
+ module MarkdownIt
4
+ module Helpers
5
+ module ParseLinkDestination
6
+
7
+ #------------------------------------------------------------------------------
8
+ def parseLinkDestination(str, pos, max)
9
+ lines = 0
10
+ start = pos
11
+ result = {ok: false, pos: 0, lines: 0, str: ''}
12
+
13
+ if (str.charCodeAt(pos) == 0x3C ) # <
14
+ pos += 1
15
+ while (pos < max)
16
+ code = str.charCodeAt(pos)
17
+ return result if (code == 0x0A ) # \n
18
+ if (code == 0x3E) # >
19
+ result[:pos] = pos + 1
20
+ result[:str] = unescapeAll(str.slice((start + 1)...pos))
21
+ result[:ok] = true
22
+ return result
23
+ end
24
+ if (code == 0x5C && pos + 1 < max) # \
25
+ pos += 2
26
+ next
27
+ end
28
+
29
+ pos += 1
30
+ end
31
+
32
+ # no closing '>'
33
+ return result
34
+ end
35
+
36
+ # this should be ... } else { ... branch
37
+
38
+ level = 0
39
+ while (pos < max)
40
+ code = str.charCodeAt(pos)
41
+
42
+ break if (code == 0x20)
43
+
44
+ # ascii control characters
45
+ break if (code < 0x20 || code == 0x7F)
46
+
47
+ if (code == 0x5C && pos + 1 < max) # \
48
+ pos += 2
49
+ next
50
+ end
51
+
52
+ if (code == 0x28) # (
53
+ level += 1
54
+ break if (level > 1)
55
+ end
56
+
57
+ if (code == 0x29) # )
58
+ level -= 1
59
+ break if (level < 0)
60
+ end
61
+
62
+ pos += 1
63
+ end
64
+
65
+ return result if (start == pos)
66
+
67
+ result[:str] = unescapeAll(str.slice(start...pos))
68
+ result[:lines] = lines
69
+ result[:pos] = pos
70
+ result[:ok] = true
71
+ return result
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,51 @@
1
+ # Parse link label
2
+ #
3
+ # this function assumes that first character ("[") already matches;
4
+ # returns the end of the label
5
+ #
6
+ #------------------------------------------------------------------------------
7
+ module MarkdownIt
8
+ module Helpers
9
+ module ParseLinkLabel
10
+ def parseLinkLabel(state, start, disableNested = false)
11
+ labelEnd = -1
12
+ max = state.posMax
13
+ oldPos = state.pos
14
+ state.pos = start + 1
15
+ level = 1
16
+
17
+ while (state.pos < max)
18
+ marker = state.src.charCodeAt(state.pos)
19
+ if (marker == 0x5D) # ]
20
+ level -= 1
21
+ if (level == 0)
22
+ found = true
23
+ break
24
+ end
25
+ end
26
+
27
+ prevPos = state.pos
28
+ state.md.inline.skipToken(state)
29
+ if (marker == 0x5B) # [
30
+ if (prevPos == state.pos - 1)
31
+ # increase level if we find text `[`, which is not a part of any token
32
+ level += 1
33
+ elsif (disableNested)
34
+ state.pos = oldPos
35
+ return -1
36
+ end
37
+ end
38
+ end
39
+
40
+ if (found)
41
+ labelEnd = state.pos
42
+ end
43
+
44
+ # restore old state
45
+ state.pos = oldPos
46
+
47
+ return labelEnd
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,48 @@
1
+ # Parse link title
2
+ #------------------------------------------------------------------------------
3
+ module MarkdownIt
4
+ module Helpers
5
+ module ParseLinkTitle
6
+
7
+ #------------------------------------------------------------------------------
8
+ def parseLinkTitle(str, pos, max)
9
+ lines = 0
10
+ start = pos
11
+ result = {ok: false, pos: 0, lines: 0, str: ''}
12
+
13
+ return result if (pos >= max)
14
+
15
+ marker = str.charCodeAt(pos)
16
+
17
+ return result if (marker != 0x22 && marker != 0x27 && marker != 0x28) # " ' (
18
+
19
+ pos += 1
20
+
21
+ # if opening marker is "(", switch it to closing marker ")"
22
+ marker = 0x29 if (marker == 0x28)
23
+
24
+ while (pos < max)
25
+ code = str.charCodeAt(pos)
26
+ if (code == marker)
27
+ result[:pos] = pos + 1
28
+ result[:lines] = lines
29
+ result[:str] = unescapeAll(str.slice((start + 1)...pos))
30
+ result[:ok] = true
31
+ return result
32
+ elsif (code == 0x0A)
33
+ lines += 1
34
+ elsif (code == 0x5C && pos + 1 < max) # \
35
+ pos += 1
36
+ if (str.charCodeAt(pos) == 0x0A)
37
+ lines += 1
38
+ end
39
+ end
40
+
41
+ pos += 1
42
+ end
43
+
44
+ return result
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,507 @@
1
+ # Main parser class
2
+ #------------------------------------------------------------------------------
3
+
4
+ CONFIG = {
5
+ default: MarkdownIt::Presets::Default.options,
6
+ zero: MarkdownIt::Presets::Zero.options,
7
+ commonmark: MarkdownIt::Presets::Commonmark.options
8
+ }
9
+
10
+
11
+ BAD_PROTOCOLS = [ 'vbscript', 'javascript', 'file' ]
12
+
13
+ VALIDATE_LINK = lambda do |url|
14
+ # url should be normalized at this point, and existing entities are decoded
15
+ #
16
+ str = url.strip.downcase
17
+
18
+ if str.include?(':') && BAD_PROTOCOLS.include?(str.split(':')[0])
19
+ return false
20
+ end
21
+ return true
22
+ end
23
+
24
+ RECODE_HOSTNAME_FOR = [ 'http:', 'https:', 'mailto:' ]
25
+
26
+ # mdurl comes from https://github.com/markdown-it/mdurl
27
+ NORMALIZE_LINK = lambda do |url|
28
+ parsed = MDUrl::Url.urlParse(url, true)
29
+
30
+ # if parsed[:hostname]
31
+ # # Encode hostnames in urls like:
32
+ # # `http://host/`, `https://host/`, `mailto:user@host`, `//host/`
33
+ # #
34
+ # # We don't encode unknown schemas, because it's likely that we encode
35
+ # # something we shouldn't (e.g. `skype:name` treated as `skype:host`)
36
+ # if !parsed[:protocol] || RECODE_HOSTNAME_FOR.include?(parsed[:protocol])
37
+ # # TODO is punycode really needed?
38
+ # # try {
39
+ # # parsed.hostname = punycode.toASCII(parsed.hostname);
40
+ # # } catch(er) {}
41
+ # end
42
+ # end
43
+
44
+ return MDUrl::Encode.encode(MDUrl::Format.format(parsed));
45
+ end
46
+
47
+ NORMALIZE_LINK_TEXT = lambda do |url|
48
+ parsed = MDUrl::Url.urlParse(url, true)
49
+
50
+ # if parsed[:hostname]
51
+ # # Encode hostnames in urls like:
52
+ # # `http://host/`, `https://host/`, `mailto:user@host`, `//host/`
53
+ # #
54
+ # # We don't encode unknown schemas, because it's likely that we encode
55
+ # # something we shouldn't (e.g. `skype:name` treated as `skype:host`)
56
+ # if !parsed[:protocol] || RECODE_HOSTNAME_FOR.include?(parsed[:protocol])
57
+ # # TODO is punycode really needed?
58
+ # # try {
59
+ # # parsed.hostname = punycode.toUnicode(parsed.hostname);
60
+ # # } catch(er) {}
61
+ # end
62
+ # end
63
+
64
+ return MDUrl::Decode.decode(MDUrl::Format.format(parsed))
65
+ end
66
+
67
+
68
+ #------------------------------------------------------------------------------
69
+ # class MarkdownIt
70
+ #
71
+ # Main parser/renderer class.
72
+ #
73
+ # ##### Usage
74
+ #
75
+ # ```javascript
76
+ # // node.js, "classic" way:
77
+ # var MarkdownIt = require('markdown-it'),
78
+ # md = new MarkdownIt();
79
+ # var result = md.render('# markdown-it rulezz!');
80
+ #
81
+ # // node.js, the same, but with sugar:
82
+ # var md = require('markdown-it')();
83
+ # var result = md.render('# markdown-it rulezz!');
84
+ #
85
+ # // browser without AMD, added to "window" on script load
86
+ # // Note, there are no dash.
87
+ # var md = window.markdownit();
88
+ # var result = md.render('# markdown-it rulezz!');
89
+ # ```
90
+ #
91
+ # Single line rendering, without paragraph wrap:
92
+ #
93
+ # ```javascript
94
+ # var md = require('markdown-it')();
95
+ # var result = md.renderInline('__markdown-it__ rulezz!');
96
+ # ```
97
+ #------------------------------------------------------------------------------
98
+ module MarkdownIt
99
+ class Parser
100
+ include MarkdownIt::Common::Utils
101
+
102
+ attr_accessor :inline
103
+ attr_accessor :block
104
+ attr_accessor :core
105
+ attr_accessor :renderer
106
+ attr_accessor :options
107
+ attr_accessor :validateLink
108
+ attr_accessor :normalizeLink
109
+ attr_accessor :normalizeLinkText
110
+ attr_accessor :linkify
111
+
112
+ # new MarkdownIt([presetName, options])
113
+ # - presetName (String): optional, `commonmark` / `zero`
114
+ # - options (Object)
115
+ #
116
+ # Creates parser instanse with given config. Can be called without `new`.
117
+ #
118
+ # ##### presetName
119
+ #
120
+ # MarkdownIt provides named presets as a convenience to quickly
121
+ # enable/disable active syntax rules and options for common use cases.
122
+ #
123
+ # - ["commonmark"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.js) -
124
+ # configures parser to strict [CommonMark](http://commonmark.org/) mode.
125
+ # - [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.js) -
126
+ # similar to GFM, used when no preset name given. Enables all available rules,
127
+ # but still without html, typographer & autolinker.
128
+ # - ["zero"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.js) -
129
+ # all rules disabled. Useful to quickly setup your config via `.enable()`.
130
+ # For example, when you need only `bold` and `italic` markup and nothing else.
131
+ #
132
+ # ##### options:
133
+ #
134
+ # - __html__ - `false`. Set `true` to enable HTML tags in source. Be careful!
135
+ # That's not safe! You may need external sanitizer to protect output from XSS.
136
+ # It's better to extend features via plugins, instead of enabling HTML.
137
+ # - __xhtmlOut__ - `false`. Set `true` to add '/' when closing single tags
138
+ # (`<br />`). This is needed only for full CommonMark compatibility. In real
139
+ # world you will need HTML output.
140
+ # - __breaks__ - `false`. Set `true` to convert `\n` in paragraphs into `<br>`.
141
+ # - __langPrefix__ - `language-`. CSS language class prefix for fenced blocks.
142
+ # Can be useful for external highlighters.
143
+ # - __linkify__ - `false`. Set `true` to autoconvert URL-like text to links.
144
+ # - __typographer__ - `false`. Set `true` to enable [some language-neutral
145
+ # replacement](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.js) +
146
+ # quotes beautification (smartquotes).
147
+ # - __quotes__ - `“”‘’`, string. Double + single quotes replacement pairs, when
148
+ # typographer enabled and smartquotes on. Set doubles to '«»' for Russian,
149
+ # '„“' for German.
150
+ # - __highlight__ - `null`. Highlighter function for fenced code blocks.
151
+ # Highlighter `function (str, lang)` should return escaped HTML. It can also
152
+ # return empty string if the source was not changed and should be escaped externaly.
153
+ #
154
+ # ##### Example
155
+ #
156
+ # ```javascript
157
+ # // commonmark mode
158
+ # var md = require('markdown-it')('commonmark');
159
+ #
160
+ # // default mode
161
+ # var md = require('markdown-it')();
162
+ #
163
+ # // enable everything
164
+ # var md = require('markdown-it')({
165
+ # html: true,
166
+ # linkify: true,
167
+ # typographer: true
168
+ # });
169
+ # ```
170
+ #
171
+ # ##### Syntax highlighting
172
+ #
173
+ # ```js
174
+ # var hljs = require('highlight.js') // https://highlightjs.org/
175
+ #
176
+ # var md = require('markdown-it')({
177
+ # highlight: function (str, lang) {
178
+ # if (lang && hljs.getLanguage(lang)) {
179
+ # try {
180
+ # return hljs.highlight(lang, str).value;
181
+ # } catch (__) {}
182
+ # }
183
+ #
184
+ # try {
185
+ # return hljs.highlightAuto(str).value;
186
+ # } catch (__) {}
187
+ #
188
+ # return ''; // use external default escaping
189
+ # }
190
+ # });
191
+ # ```
192
+ #-----------------------------------------------------------------------------
193
+ def initialize(presetName = :default, options = {})
194
+ if options.empty?
195
+ if presetName.is_a? Hash
196
+ options = presetName
197
+ presetName = :default
198
+ end
199
+ end
200
+
201
+ # MarkdownIt#inline -> ParserInline
202
+ #
203
+ # Instance of [[ParserInline]]. You may need it to add new rules when
204
+ # writing plugins. For simple rules control use [[MarkdownIt.disable]] and
205
+ # [[MarkdownIt.enable]].
206
+ @inline = ParserInline.new
207
+
208
+ # MarkdownIt#block -> ParserBlock
209
+ #
210
+ # Instance of [[ParserBlock]]. You may need it to add new rules when
211
+ # writing plugins. For simple rules control use [[MarkdownIt.disable]] and
212
+ # [[MarkdownIt.enable]].
213
+ @block = ParserBlock.new
214
+
215
+ # MarkdownIt#core -> Core
216
+ #
217
+ # Instance of [[Core]] chain executor. You may need it to add new rules when
218
+ # writing plugins. For simple rules control use [[MarkdownIt.disable]] and
219
+ # [[MarkdownIt.enable]].
220
+ @core = ParserCore.new
221
+
222
+ # MarkdownIt#renderer -> Renderer
223
+ #
224
+ # Instance of [[Renderer]]. Use it to modify output look. Or to add rendering
225
+ # rules for new token types, generated by plugins.
226
+ #
227
+ # ##### Example
228
+ #
229
+ # ```javascript
230
+ # var md = require('markdown-it')();
231
+ #
232
+ # function myToken(tokens, idx, options, env, self) {
233
+ # //...
234
+ # return result;
235
+ # };
236
+ #
237
+ # md.renderer.rules['my_token'] = myToken
238
+ # ```
239
+ #
240
+ # See [[Renderer]] docs and [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js).
241
+ @renderer = Renderer.new
242
+
243
+ # MarkdownIt#linkify -> LinkifyIt
244
+ #
245
+ # [linkify-it](https://github.com/markdown-it/linkify-it) instance.
246
+ # Used by [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js)
247
+ # rule.
248
+ @linkify = ::Linkify.new
249
+
250
+ # MarkdownIt#validateLink(url) -> Boolean
251
+ #
252
+ # Link validation function. CommonMark allows too much in links. By default
253
+ # we disable `javascript:` and `vbscript:` schemas. You can change this
254
+ # behaviour.
255
+ #
256
+ # ```javascript
257
+ # var md = require('markdown-it')();
258
+ # // enable everything
259
+ # md.validateLink = function () { return true; }
260
+ # ```
261
+ @validateLink = VALIDATE_LINK
262
+
263
+ # MarkdownIt#normalizeLink(url) -> String
264
+ #
265
+ # Function used to encode link url to a machine-readable format,
266
+ # which includes url-encoding, punycode, etc.
267
+ @normalizeLink = NORMALIZE_LINK
268
+
269
+ # MarkdownIt#normalizeLinkText(url) -> String
270
+ #
271
+ # Function used to decode link url to a human-readable format`
272
+ @normalizeLinkText = NORMALIZE_LINK_TEXT
273
+
274
+ # Expose utils & helpers for easy acces from plugins
275
+
276
+ # TODO I don't know if these (utils and helpers) are really needed
277
+ # MarkdownIt#utils -> utils
278
+ #
279
+ # Assorted utility functions, useful to write plugins. See details
280
+ # [here](https://github.com/markdown-it/markdown-it/blob/master/lib/common/utils.js).
281
+ # this.utils = utils;
282
+
283
+ # MarkdownIt#helpers -> helpers
284
+ #
285
+ # Link components parser functions, useful to write plugins. See details
286
+ # [here](https://github.com/markdown-it/markdown-it/blob/master/lib/helpers).
287
+ # this.helpers = helpers;
288
+
289
+
290
+ @options = {}
291
+ configure(presetName)
292
+ set(options) if options
293
+ end
294
+
295
+
296
+ # chainable
297
+ # MarkdownIt.set(options)
298
+ #
299
+ # Set parser options (in the same format as in constructor). Probably, you
300
+ # will never need it, but you can change options after constructor call.
301
+ #
302
+ # ##### Example
303
+ #
304
+ # ```javascript
305
+ # var md = require('markdown-it')()
306
+ # .set({ html: true, breaks: true })
307
+ # .set({ typographer, true });
308
+ # ```
309
+ #
310
+ # __Note:__ To achieve the best possible performance, don't modify a
311
+ # `markdown-it` instance options on the fly. If you need multiple configurations
312
+ # it's best to create multiple instances and initialize each with separate
313
+ # config.
314
+ #------------------------------------------------------------------------------
315
+ def set(options)
316
+ assign(@options, options)
317
+ return self
318
+ end
319
+
320
+
321
+ # chainable, internal
322
+ # MarkdownIt.configure(presets)
323
+ #
324
+ # Batch load of all options and compenent settings. This is internal method,
325
+ # and you probably will not need it. But if you with - see available presets
326
+ # and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets)
327
+ #
328
+ # We strongly recommend to use presets instead of direct config loads. That
329
+ # will give better compatibility with next versions.
330
+ #------------------------------------------------------------------------------
331
+ def configure(presets)
332
+ raise(ArgumentError, 'Wrong `markdown-it` preset, can\'t be empty') unless presets
333
+
334
+ unless presets.is_a? Hash
335
+ presetName = presets.to_sym
336
+ presets = CONFIG[presetName]
337
+ raise(ArgumentError, "Wrong `markdown-it` preset #{presetName}, check name") unless presets
338
+ end
339
+ self.set(presets[:options]) if presets[:options]
340
+
341
+ if presets[:components]
342
+ presets[:components].each_key do |name|
343
+ if presets[:components][name][:rules]
344
+ self.send(name).ruler.enableOnly(presets[:components][name][:rules])
345
+ end
346
+ end
347
+ end
348
+ return self
349
+ end
350
+
351
+
352
+ # chainable
353
+ # MarkdownIt.enable(list, ignoreInvalid)
354
+ # - list (String|Array): rule name or list of rule names to enable
355
+ # - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
356
+ #
357
+ # Enable list or rules. It will automatically find appropriate components,
358
+ # containing rules with given names. If rule not found, and `ignoreInvalid`
359
+ # not set - throws exception.
360
+ #
361
+ # ##### Example
362
+ #
363
+ # ```javascript
364
+ # var md = require('markdown-it')()
365
+ # .enable(['sub', 'sup'])
366
+ # .disable('smartquotes');
367
+ # ```
368
+ #------------------------------------------------------------------------------
369
+ def enable(list, ignoreInvalid)
370
+ result = []
371
+
372
+ list = [ list ] if !list.is_a? Array
373
+
374
+ result << @core.ruler.enable(list, true)
375
+ result << @block.ruler.enable(list, true)
376
+ result << @inline.ruler.enable(list, true)
377
+
378
+ missed = list.select {|name| result.include?(name) }
379
+
380
+ if missed.length && !ignoreInvalid
381
+ raise StandardError, "MarkdownIt. Failed to enable unknown rule(s): #{missed}"
382
+ end
383
+
384
+ return self
385
+ end
386
+
387
+
388
+ # chainable
389
+ # MarkdownIt.disable(list, ignoreInvalid)
390
+ # - list (String|Array): rule name or list of rule names to disable.
391
+ # - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
392
+ #
393
+ # The same as [[MarkdownIt.enable]], but turn specified rules off.
394
+ def disable(list, ignoreInvalid)
395
+ result = []
396
+
397
+ list = [ list ] if !list.is_a? Array
398
+
399
+ result << @core.ruler.disable(list, true)
400
+ result << @block.ruler.disable(list, true)
401
+ result << @inline.ruler.disable(list, true)
402
+
403
+ missed = list.select {|name| result.include?(name) }
404
+
405
+ if missed.length && !ignoreInvalid
406
+ raise StandardError, "MarkdownIt. Failed to disable unknown rule(s): #{missed}"
407
+ end
408
+
409
+ return self
410
+ end
411
+
412
+
413
+ # chainable
414
+ # MarkdownIt.use(plugin, params)
415
+ #
416
+ # Load specified plugin with given params into current parser instance.
417
+ # It's just a sugar to call `plugin(md, params)` with curring.
418
+ #
419
+ # ##### Example
420
+ #
421
+ # ```javascript
422
+ # var iterator = require('markdown-it-for-inline');
423
+ # var md = require('markdown-it')()
424
+ # .use(iterator, 'foo_replace', 'text', function (tokens, idx) {
425
+ # tokens[idx].content = tokens[idx].content.replace(/foo/g, 'bar');
426
+ # });
427
+ # ```
428
+ def use(plugin, *args)
429
+ puts "Implement: Parser.use"
430
+ # var args = [ this ].concat(Array.prototype.slice.call(arguments, 1));
431
+ # plugin.call(plugin, args)
432
+ # return self
433
+ end
434
+
435
+
436
+ # internal
437
+ # MarkdownIt.parse(src, env) -> Array
438
+ # - src (String): source string
439
+ # - env (Object): environment sandbox
440
+ #
441
+ # Parse input string and returns list of block tokens (special token type
442
+ # "inline" will contain list of inline tokens). You should not call this
443
+ # method directly, until you write custom renderer (for example, to produce
444
+ # AST).
445
+ #
446
+ # `env` is used to pass data between "distributed" rules and return additional
447
+ # metadata like reference info, needed for for renderer. It also can be used to
448
+ # inject data in specific cases. Usually, you will be ok to pass `{}`,
449
+ # and then pass updated object to renderer.
450
+ #------------------------------------------------------------------------------
451
+ def parse(src, env)
452
+ state = RulesCore::StateCore.new(src, self, env)
453
+ @core.process(state)
454
+ return state.tokens
455
+ end
456
+
457
+ # MarkdownIt.render(src [, env]) -> String
458
+ # - src (String): source string
459
+ # - env (Object): environment sandbox
460
+ #
461
+ # Render markdown string into html. It does all magic for you :).
462
+ #
463
+ # `env` can be used to inject additional metadata (`{}` by default).
464
+ # But you will not need it with high probability. See also comment
465
+ # in [[MarkdownIt.parse]].
466
+ #------------------------------------------------------------------------------
467
+ def render(src, env = {})
468
+ # self.parse(src, { references: {} }).each {|token| pp token.to_json}
469
+
470
+ return @renderer.render(parse(src, env), @options, env)
471
+ end
472
+
473
+ #------------------------------------------------------------------------------
474
+ def to_html(src, env = {})
475
+ render(src, env)
476
+ end
477
+
478
+ # internal
479
+ # MarkdownIt.parseInline(src, env) -> Array
480
+ # - src (String): source string
481
+ # - env (Object): environment sandbox
482
+ #
483
+ # The same as [[MarkdownIt.parse]] but skip all block rules. It returns the
484
+ # block tokens list with the single `inline` element, containing parsed inline
485
+ # tokens in `children` property. Also updates `env` object.
486
+ #------------------------------------------------------------------------------
487
+ def parseInline(src, env)
488
+ state = RulesCore::StateCore.new(src, self, env)
489
+ state.inlineMode = true
490
+ @core.process(state)
491
+ return state.tokens
492
+ end
493
+
494
+
495
+ # MarkdownIt.renderInline(src [, env]) -> String
496
+ # - src (String): source string
497
+ # - env (Object): environment sandbox
498
+ #
499
+ # Similar to [[MarkdownIt.render]] but for single paragraph content. Result
500
+ # will NOT be wrapped into `<p>` tags.
501
+ #------------------------------------------------------------------------------
502
+ def renderInline(src, env = {})
503
+ return @renderer.render(parseInline(src, env), @options, env)
504
+ end
505
+
506
+ end
507
+ end