motion-markdown-it 9.0.1 → 11.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2731c7d392eb70c89a0b583ff854d85ea277e299f86a6a3f02502427b4effdda
4
- data.tar.gz: 25c49dfc9916421e4ea44878dd499c4e535e26d106f2663a594911002dd6cb21
3
+ metadata.gz: '0489d301352f960adaa9978744f1dd22181b74149760ba53056a63dc2822eb71'
4
+ data.tar.gz: 0267606372ae4d745d218301a5f18302ea58b7c2339439aeb79201421d203a31
5
5
  SHA512:
6
- metadata.gz: f8a8d408d9a62779180b1176404c6f0e2f0616e0fd45e95e068eadec6780b1eb68268cda6a4339cd188e442e276f757d5cc54faa6f94eeb18ed5ac8992cbe410
7
- data.tar.gz: f6b204daacb84fb2bd888d1246aab6882810d1c85bf5444bc92a2bc1dc837f750ec42f2df6a806550ae7822f516e2ebfddecbd386ae512f57ebf6105afb53edd
6
+ metadata.gz: b594bb031e89f3f422603096fbf8abc678f7fc065b69c8d8b854f4c8e8e134c38337f5d662daff09e14010951fdf056a96d5467717406e64399378087b1441c7
7
+ data.tar.gz: d247938869b5d43dfd772dbfb5bcf10307f404befce83dba8da65559353d22891e59b8ca811e46e6cdd1748d422de6d0c60ed18034be11af2b7d4bae58278253
data/README.md CHANGED
@@ -7,7 +7,7 @@ Ruby/RubyMotion version of Markdown-it (CommonMark compliant and extendable)
7
7
 
8
8
  This gem is a port of the [markdown-it Javascript package](https://github.com/markdown-it/markdown-it) by Vitaly Puzrin and Alex Kocharin.
9
9
 
10
- _Currently synced with markdown-it 9.0.1_
10
+ _Currently synced with markdown-it 11.0.0_
11
11
 
12
12
  ---
13
13
 
@@ -54,12 +54,15 @@ redcarpet 3.4.0 0.0065
54
54
 
55
55
  ## Table of content
56
56
 
57
- - [Install](#install)
58
- - [Usage examples](#usage-examples)
59
- - [Plugins](#plugins)
60
- - [Upgrading](#upgrading)
61
- - [References / Thanks](#references--thanks)
62
- - [License](#license)
57
+ - [markdown-it](#markdown-it)
58
+ - [Install](#install)
59
+ - [Usage examples](#usage-examples)
60
+ - [Simple](#simple)
61
+ - [Init with presets and options](#init-with-presets-and-options)
62
+ - [Plugins](#plugins)
63
+ - [Upgrading](#upgrading)
64
+ - [References / Thanks](#references--thanks)
65
+ - [License](#license)
63
66
 
64
67
  <!--
65
68
  - [API](#api)
@@ -271,6 +274,10 @@ md = require('markdown-it')({
271
274
  });
272
275
  ```
273
276
 
277
+ You can find all rules in sources:
278
+ [parser_core.js](lib/parser_core.js), [parser_block](lib/parser_block.js),
279
+ [parser_inline](lib/parser_inline.js).
280
+
274
281
 
275
282
  ## Benchmark
276
283
 
@@ -352,7 +352,7 @@ module MarkdownIt
352
352
  # MarkdownIt.configure(presets)
353
353
  #
354
354
  # Batch load of all options and compenent settings. This is internal method,
355
- # and you probably will not need it. But if you with - see available presets
355
+ # and you probably will not need it. But if you will - see available presets
356
356
  # and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets)
357
357
  #
358
358
  # We strongly recommend to use presets instead of direct config loads. That
@@ -474,7 +474,7 @@ module MarkdownIt
474
474
  # - src (String): source string
475
475
  # - env (Object): environment sandbox
476
476
  #
477
- # Parse input string and returns list of block tokens (special token type
477
+ # Parse input string and return list of block tokens (special token type
478
478
  # "inline" will contain list of inline tokens). You should not call this
479
479
  # method directly, until you write custom renderer (for example, to produce
480
480
  # AST).
@@ -542,4 +542,4 @@ module MarkdownIt
542
542
  end
543
543
 
544
544
  end
545
- end
545
+ end
@@ -4,8 +4,9 @@ module MarkdownIt
4
4
  module RulesCore
5
5
  class Normalize
6
6
 
7
- NEWLINES_RE = /\r[\n\u0085]?|[\u2424\u2028\u0085]/
8
- NULL_RE = /\u0000/
7
+ # https://spec.commonmark.org/0.29/#line-ending
8
+ NEWLINES_RE = /\r\n?|\n/
9
+ NULL_RE = /\0/
9
10
 
10
11
  #------------------------------------------------------------------------------
11
12
  def self.normalize(state)
@@ -67,10 +67,10 @@ module MarkdownIt
67
67
  gsub(/\.{2,}/, '…').gsub(/([?!])…/, "\\1..").
68
68
  gsub(/([?!]){4,}/, '\\1\\1\\1').gsub(/,{2,}/, ',').
69
69
  # em-dash
70
- gsub(/(^|[^-])---([^-]|$)/m, "\\1\u2014\\2").
70
+ gsub(/(^|[^-])---(?=[^-]|$)/m, "\\1\u2014").
71
71
  # en-dash
72
- gsub(/(^|\s)--(\s|$)/m, "\\1\u2013\\2").
73
- gsub(/(^|[^-\s])--([^-\s]|$)/m, "\\1\u2013\\2")
72
+ gsub(/(^|\s)--(?=\s|$)/m, "\\1\u2013").
73
+ gsub(/(^|[^-\s])--(?=[^-\s]|$)/m, "\\1\u2013")
74
74
  end
75
75
  end
76
76
 
@@ -113,8 +113,14 @@ module MarkdownIt
113
113
  end
114
114
 
115
115
  if (canOpen && canClose)
116
- # treat this as the middle of the word
117
- canOpen = false
116
+ # Replace quotes in the middle of punctuation sequence, but not
117
+ # in the middle of the words, i.e.:
118
+ #
119
+ # 1. foo " bar " baz - not replaced
120
+ # 2. foo-"-bar-"-baz - replaced
121
+ # 3. foo"bar"baz - not replaced
122
+ #
123
+ canOpen = isLastPunctChar
118
124
  canClose = isNextPunctChar
119
125
  end
120
126
 
@@ -5,51 +5,104 @@ module MarkdownIt
5
5
  class BalancePairs
6
6
 
7
7
  #------------------------------------------------------------------------------
8
- def self.link_pairs(state)
9
- delimiters = state.delimiters
10
- max = state.delimiters.length
11
-
12
- 0.upto(max - 1) do |i|
13
- lastDelim = delimiters[i]
14
-
15
- next if !lastDelim[:close]
16
-
17
- j = i - lastDelim[:jump] - 1
18
-
19
- while j >= 0
20
- currDelim = delimiters[j]
21
-
22
- if currDelim[:open] &&
23
- currDelim[:marker] == lastDelim[:marker] &&
24
- currDelim[:end] < 0 &&
25
- currDelim[:level] == lastDelim[:level]
26
-
27
- odd_match = false
28
-
29
- # typeofs are for backward compatibility with plugins
30
- # not needed: typeof currDelim.length !== 'undefined' &&
31
- # typeof lastDelim.length !== 'undefined' &&
32
- if (currDelim[:close] || lastDelim[:open])
33
- # from spec:
34
- # sum of the lengths [...] must not be a multiple of 3
35
- # unless both lengths are multiples of 3
36
- if ((currDelim[:length] + lastDelim[:length]) % 3) == 0
37
- if (currDelim[:length] % 3 != 0 || lastDelim[:length] % 3 != 0)
38
- odd_match = true
8
+ def self.processDelimiters(state, delimiters)
9
+ openersBottom = {}
10
+ max = delimiters.length
11
+
12
+ 0.upto(max - 1) do |closerIdx|
13
+ closer = delimiters[closerIdx]
14
+
15
+ # Length is only used for emphasis-specific "rule of 3",
16
+ # if it's not defined (in strikethrough or 3rd party plugins),
17
+ # we can default it to 0 to disable those checks.
18
+ #
19
+ closer[:length] = closer[:length] || 0
20
+
21
+ next if (!closer[:close])
22
+
23
+ # Previously calculated lower bounds (previous fails)
24
+ # for each marker and each delimiter length modulo 3.
25
+ unless openersBottom[closer[:marker]]
26
+ openersBottom[closer[:marker]] = [ -1, -1, -1 ]
27
+ end
28
+
29
+ minOpenerIdx = openersBottom[closer[:marker]][closer[:length] % 3]
30
+ newMinOpenerIdx = -1
31
+
32
+ openerIdx = closerIdx - closer[:jump] - 1
33
+
34
+ while openerIdx > minOpenerIdx
35
+ opener = delimiters[openerIdx]
36
+
37
+ (openerIdx -= opener[:jump] + 1) && next if (opener[:marker] != closer[:marker])
38
+
39
+ newMinOpenerIdx = openerIdx if (newMinOpenerIdx == -1)
40
+
41
+ if (opener[:open] &&
42
+ opener[:end] < 0 &&
43
+ opener[:level] == closer[:level])
44
+
45
+ isOddMatch = false
46
+
47
+ # from spec:
48
+ #
49
+ # If one of the delimiters can both open and close emphasis, then the
50
+ # sum of the lengths of the delimiter runs containing the opening and
51
+ # closing delimiters must not be a multiple of 3 unless both lengths
52
+ # are multiples of 3.
53
+ #
54
+ if (opener[:close] || closer[:open])
55
+ if ((opener[:length] + closer[:length]) % 3 == 0)
56
+ if (opener[:length] % 3 != 0 || closer[:length] % 3 != 0)
57
+ isOddMatch = true
39
58
  end
40
59
  end
41
60
  end
42
-
43
- if !odd_match
44
- lastDelim[:jump] = i - j
45
- lastDelim[:open] = false
46
- currDelim[:end] = i
47
- currDelim[:jump] = 0
61
+
62
+ if (!isOddMatch)
63
+ # If previous delimiter cannot be an opener, we can safely skip
64
+ # the entire sequence in future checks. This is required to make
65
+ # sure algorithm has linear complexity (see *_*_*_*_*_... case).
66
+ #
67
+ lastJump = openerIdx > 0 && !delimiters[openerIdx - 1][:open] ?
68
+ delimiters[openerIdx - 1][:jump] + 1 : 0
69
+
70
+ closer[:jump] = closerIdx - openerIdx + lastJump
71
+ closer[:open] = false
72
+ opener[:end] = closerIdx
73
+ opener[:jump] = lastJump
74
+ opener[:close] = false
75
+ newMinOpenerIdx = -1
48
76
  break
49
77
  end
50
78
  end
79
+
80
+ openerIdx -= opener[:jump] + 1
81
+ end
82
+
83
+ if (newMinOpenerIdx != -1)
84
+ # If match for this delimiter run failed, we want to set lower bound for
85
+ # future lookups. This is required to make sure algorithm has linear
86
+ # complexity.
87
+ #
88
+ # See details here:
89
+ # https://github.com/commonmark/cmark/issues/178#issuecomment-270417442
90
+ #
91
+ openersBottom[closer[:marker]][(closer[:length] || 0) % 3] = newMinOpenerIdx
92
+ end
93
+ end
94
+ end
95
+
96
+ #------------------------------------------------------------------------------
97
+ def self.link_pairs(state)
98
+ tokens_meta = state.tokens_meta
99
+ max = state.tokens_meta.length
51
100
 
52
- j -= currDelim[:jump] + 1
101
+ processDelimiters(state, state.delimiters)
102
+
103
+ 0.upto(max - 1) do |curr|
104
+ if (tokens_meta[curr] && tokens_meta[curr][:delimiters])
105
+ processDelimiters(state, tokens_meta[curr][:delimiters])
53
106
  end
54
107
  end
55
108
  end
@@ -43,10 +43,6 @@ module MarkdownIt
43
43
  #
44
44
  token: state.tokens.length - 1,
45
45
 
46
- # Token level.
47
- #
48
- level: state.level,
49
-
50
46
  # If this delimiter is matched as a valid opener, `end` will be
51
47
  # equal to its position, otherwise it's `-1`.
52
48
  #
@@ -65,12 +61,8 @@ module MarkdownIt
65
61
  return true
66
62
  end
67
63
 
68
-
69
- # Walk through delimiter list and replace text tokens with tags
70
- #
71
- def self.postProcess(state)
72
- delimiters = state.delimiters
73
- max = state.delimiters.length
64
+ def self.private_postProcess(state, delimiters)
65
+ max = delimiters.length
74
66
 
75
67
  i = max - 1
76
68
  while i >= 0
@@ -119,6 +111,21 @@ module MarkdownIt
119
111
  i -= 1
120
112
  end
121
113
  end
114
+
115
+ # Walk through delimiter list and replace text tokens with tags
116
+ #
117
+ def self.postProcess(state)
118
+ tokens_meta = state.tokens_meta
119
+ max = state.tokens_meta.length
120
+
121
+ private_postProcess(state, state.delimiters)
122
+
123
+ 0.upto(max - 1) do |curr|
124
+ if (tokens_meta[curr] && tokens_meta[curr][:delimiters])
125
+ private_postProcess(state, tokens_meta[curr][:delimiters])
126
+ end
127
+ end
128
+ end
122
129
  end
123
130
  end
124
131
  end
@@ -5,7 +5,7 @@ module MarkdownIt
5
5
  class StateInline
6
6
  include MarkdownIt::Common::Utils
7
7
 
8
- attr_accessor :src, :env, :md, :tokens, :pos, :posMax, :level
8
+ attr_accessor :src, :env, :md, :tokens, :pos, :posMax, :level, :tokens_meta
9
9
  attr_accessor :pending, :pendingLevel, :cache, :delimiters
10
10
 
11
11
  #------------------------------------------------------------------------------
@@ -14,6 +14,7 @@ module MarkdownIt
14
14
  @env = env
15
15
  @md = md
16
16
  @tokens = outTokens
17
+ @tokens_meta = Array.new(outTokens.length)
17
18
 
18
19
  @pos = 0
19
20
  @posMax = @src.length
@@ -21,9 +22,15 @@ module MarkdownIt
21
22
  @pending = ''
22
23
  @pendingLevel = 0
23
24
 
24
- @cache = {} # Stores { start: end } pairs. Useful for backtrack
25
- # optimization of pairs parse (emphasis, strikes).
26
- @delimiters = []
25
+ # Stores { start: end } pairs. Useful for backtrack
26
+ # optimization of pairs parse (emphasis, strikes).
27
+ @cache = {}
28
+
29
+ # List of emphasis-like delimiters for current tag
30
+ @delimiters = []
31
+
32
+ # Stack of delimiter lists for upper level tags
33
+ @_prev_delimiters = [];
27
34
  end
28
35
 
29
36
 
@@ -44,13 +51,29 @@ module MarkdownIt
44
51
  def push(type, tag, nesting)
45
52
  pushPending unless @pending.empty?
46
53
 
47
- token = Token.new(type, tag, nesting);
48
- @level -= 1 if nesting < 0 # closing tag
54
+ token = Token.new(type, tag, nesting)
55
+ token_meta = nil
56
+
57
+ if nesting < 0
58
+ # closing tag
59
+ @level -= 1
60
+ @delimiters = @_prev_delimiters.pop
61
+ end
62
+
49
63
  token.level = @level
50
- @level += 1 if nesting > 0 # opening tag
64
+
65
+ if nesting > 0
66
+ # opening tag
67
+ @level += 1
68
+ @_prev_delimiters.push(@delimiters)
69
+ @delimiters = []
70
+ token_meta = { delimiters: @delimiters }
71
+ end
51
72
 
52
73
  @pendingLevel = @level
53
74
  @tokens.push(token)
75
+ @tokens_meta.push(token_meta)
76
+
54
77
  return token
55
78
  end
56
79
 
@@ -34,10 +34,9 @@ module MarkdownIt
34
34
 
35
35
  state.delimiters.push({
36
36
  marker: marker,
37
- length: scanned[:length],
37
+ length: 0, # disable "rule of 3" length checks meant for emphasis
38
38
  jump: i,
39
39
  token: state.tokens.length - 1,
40
- level: state.level,
41
40
  end: -1,
42
41
  open: scanned[:can_open],
43
42
  close: scanned[:can_close]
@@ -50,12 +49,9 @@ module MarkdownIt
50
49
  return true
51
50
  end
52
51
 
53
- # Walk through delimiter list and replace text tokens with tags
54
- #------------------------------------------------------------------------------
55
- def self.postProcess(state)
52
+ def self.private_postProcess(state, delimiters)
56
53
  loneMarkers = []
57
- delimiters = state.delimiters
58
- max = state.delimiters.length
54
+ max = delimiters.length
59
55
 
60
56
  0.upto(max - 1) do |i|
61
57
  startDelim = delimiters[i]
@@ -109,6 +105,21 @@ module MarkdownIt
109
105
  end
110
106
  end
111
107
  end
108
+
109
+ # Walk through delimiter list and replace text tokens with tags
110
+ #
111
+ def self.postProcess(state)
112
+ tokens_meta = state.tokens_meta
113
+ max = state.tokens_meta.length
114
+
115
+ private_postProcess(state, state.delimiters)
116
+
117
+ 0.upto(max - 1) do |curr|
118
+ if (tokens_meta[curr] && tokens_meta[curr][:delimiters])
119
+ private_postProcess(state, tokens_meta[curr][:delimiters])
120
+ end
121
+ end
122
+ end
112
123
  end
113
124
  end
114
125
  end
@@ -1,3 +1,3 @@
1
1
  module MotionMarkdownIt
2
- VERSION = '9.0.1'
2
+ VERSION = '11.0.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-markdown-it
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.0.1
4
+ version: 11.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Walker