motion-markdown-it 8.4.1.1 → 9.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.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +43 -2
  3. data/lib/motion-markdown-it/common/entities.rb +3 -0
  4. data/lib/motion-markdown-it/common/simpleidn.rb +8 -9
  5. data/lib/motion-markdown-it/common/utils.rb +48 -8
  6. data/lib/motion-markdown-it/helpers/parse_link_destination.rb +5 -5
  7. data/lib/motion-markdown-it/helpers/parse_link_label.rb +1 -1
  8. data/lib/motion-markdown-it/helpers/parse_link_title.rb +3 -3
  9. data/lib/motion-markdown-it/parser_core.rb +3 -3
  10. data/lib/motion-markdown-it/ruler.rb +3 -3
  11. data/lib/motion-markdown-it/rules_block/blockquote.rb +8 -8
  12. data/lib/motion-markdown-it/rules_block/fence.rb +5 -3
  13. data/lib/motion-markdown-it/rules_block/heading.rb +4 -4
  14. data/lib/motion-markdown-it/rules_block/hr.rb +2 -2
  15. data/lib/motion-markdown-it/rules_block/html_block.rb +2 -1
  16. data/lib/motion-markdown-it/rules_block/lheading.rb +2 -1
  17. data/lib/motion-markdown-it/rules_block/list.rb +36 -12
  18. data/lib/motion-markdown-it/rules_block/reference.rb +13 -13
  19. data/lib/motion-markdown-it/rules_block/state_block.rb +13 -11
  20. data/lib/motion-markdown-it/rules_block/table.rb +8 -8
  21. data/lib/motion-markdown-it/rules_core/linkify.rb +1 -1
  22. data/lib/motion-markdown-it/rules_core/normalize.rb +2 -2
  23. data/lib/motion-markdown-it/rules_core/replacements.rb +1 -1
  24. data/lib/motion-markdown-it/rules_core/smartquotes.rb +5 -5
  25. data/lib/motion-markdown-it/rules_inline/autolink.rb +3 -2
  26. data/lib/motion-markdown-it/rules_inline/backticks.rb +8 -5
  27. data/lib/motion-markdown-it/rules_inline/balance_pairs.rb +13 -3
  28. data/lib/motion-markdown-it/rules_inline/emphasis.rb +1 -1
  29. data/lib/motion-markdown-it/rules_inline/entity.rb +6 -6
  30. data/lib/motion-markdown-it/rules_inline/escape.rb +3 -3
  31. data/lib/motion-markdown-it/rules_inline/html_inline.rb +5 -5
  32. data/lib/motion-markdown-it/rules_inline/image.rb +8 -8
  33. data/lib/motion-markdown-it/rules_inline/link.rb +7 -7
  34. data/lib/motion-markdown-it/rules_inline/newline.rb +4 -4
  35. data/lib/motion-markdown-it/rules_inline/state_inline.rb +7 -7
  36. data/lib/motion-markdown-it/rules_inline/strikethrough.rb +1 -1
  37. data/lib/motion-markdown-it/rules_inline/text.rb +2 -1
  38. data/lib/motion-markdown-it/rules_inline/text_collapse.rb +10 -2
  39. data/lib/motion-markdown-it/version.rb +1 -3
  40. data/lib/motion-markdown-it.rb +0 -1
  41. data/spec/spec_helper.rb +2 -1
  42. metadata +11 -13
  43. data/lib/motion-markdown-it/common/string.rb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ce02411a4d64cb6e09347db122e59cb409d77316
4
- data.tar.gz: 130993721fe5e59734b17af32a77aa7980d60fcf
2
+ SHA256:
3
+ metadata.gz: 2731c7d392eb70c89a0b583ff854d85ea277e299f86a6a3f02502427b4effdda
4
+ data.tar.gz: 25c49dfc9916421e4ea44878dd499c4e535e26d106f2663a594911002dd6cb21
5
5
  SHA512:
6
- metadata.gz: 90fce20e2e664e6ea14def698f0a846c1e7235687164c48a7c0388d495fd431f11c83387534e6e965658e4211b7c55e4650f0a3681f5517f4a36a7c76e6c10a8
7
- data.tar.gz: 77560ecca3754fb7ab767ee6837a69f3b15c0f89c7d966c29c87a937cfa702e5f4728e2127ead479a5dab18673ef264eba3e0b1dfe117aa98044950f5d7da34e
6
+ metadata.gz: f8a8d408d9a62779180b1176404c6f0e2f0616e0fd45e95e068eadec6780b1eb68268cda6a4339cd188e442e276f757d5cc54faa6f94eeb18ed5ac8992cbe410
7
+ data.tar.gz: f6b204daacb84fb2bd888d1246aab6882810d1c85bf5444bc92a2bc1dc837f750ec42f2df6a806550ae7822f516e2ebfddecbd386ae512f57ebf6105afb53edd
data/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # motion-markdown-it
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/motion-markdown-it.svg)](http://badge.fury.io/rb/motion-markdown-it)
4
- [![Build Status](https://travis-ci.org/digitalmoksha/motion-markdown-it.svg?branch=master)](https://travis-ci.org/digitalmoksha/motion-markdown-it)
4
+ [![Build Status](https://github.com/digitalmoksha/motion-markdown-it/actions/workflows/ci.yml/badge.svg)](https://github.com/digitalmoksha/motion-markdown-it/actions/workflows/ci.yml)
5
5
 
6
6
  Ruby/RubyMotion version of Markdown-it (CommonMark compliant and extendable)
7
7
 
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. Currently synced with markdown-it 8.4.1
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
+
10
+ _Currently synced with markdown-it 9.0.1_
9
11
 
10
12
  ---
11
13
 
@@ -55,6 +57,7 @@ redcarpet 3.4.0 0.0065
55
57
  - [Install](#install)
56
58
  - [Usage examples](#usage-examples)
57
59
  - [Plugins](#plugins)
60
+ - [Upgrading](#upgrading)
58
61
  - [References / Thanks](#references--thanks)
59
62
  - [License](#license)
60
63
 
@@ -297,6 +300,44 @@ other implementations.
297
300
 
298
301
  -->
299
302
 
303
+ ## Upgrading
304
+
305
+ Upgrading to `8.4.1.2` could cause some small breakage if you are using any custom plugins. The [motion-markdown-it-plugins](https://github.com/digitalmoksha/motion-markdown-it-plugins) plugins have already been upgraded.
306
+
307
+ #### charCodeAt
308
+
309
+ Make sure you have
310
+
311
+ ```ruby
312
+ include MarkdownIt::Common::Utils
313
+ ```
314
+
315
+ at the top of your plugin file. Then change any references to `charCodeAt`. For example,
316
+
317
+ ```ruby
318
+ state.src.charCodeAt(pos)
319
+ ```
320
+
321
+ would become
322
+
323
+ ```ruby
324
+ charCodeAt(state.src, pos)
325
+ ```
326
+
327
+ #### slice_to_end
328
+
329
+ `slice_to_end` has been removed. Change references like this
330
+
331
+ ```ruby
332
+ state.src.slice_to_end(pos)
333
+ ```
334
+
335
+ to
336
+
337
+ ```ruby
338
+ state.src[pos..-1]
339
+ ```
340
+
300
341
  ## References / Thanks
301
342
 
302
343
  Thanks to the authors of the original implementation in Javascript, [markdown-it](https://github.com/markdown-it/markdown-it):
@@ -3,6 +3,8 @@ module MarkdownIt
3
3
 
4
4
  # TODO this list needs to be brought up to same level as the WC3 document
5
5
  # http://www.w3.org/TR/xml-entity-names/byalpha.html
6
+ # Consider pulling in https://github.com/fb55/entities/blob/master/maps/entities.json,
7
+ # is kept up to date
6
8
  #------------------------------------------------------------------------------
7
9
  class HTMLEntities
8
10
 
@@ -626,6 +628,7 @@ module MarkdownIt
626
628
  'nearr' => 0x2197, # ↗ NORTH EAST ARROW
627
629
  'nequiv' => 0x2262, # ≢ NOT IDENTICAL TO
628
630
  'nexist' => 0x2204, # ∄ THERE DOES NOT EXIST
631
+ 'ngE' => '≧̸', # ≧̸ from https://github.com/fb55/entities/blob/master/maps/entities.json
629
632
  'nge' => 0x2271, # ≱ dup NEITHER GREATER-THAN NOR EQUAL TO
630
633
  'nges' => 0x2271, # ≱ dup skip NEITHER GREATER-THAN NOR EQUAL TO
631
634
  'Ngr' => 0x039d, # Ν dup skip GREEK CAPITAL LETTER NU
@@ -1,11 +1,6 @@
1
1
  # encoding: UTF-8
2
2
  # Borrowed from https://github.com/mmriis/simpleidn
3
3
  #------------------------------------------------------------------------------
4
- class Integer
5
- def to_utf8_character
6
- [self].pack("U*")
7
- end
8
- end
9
4
 
10
5
  module SimpleIDN
11
6
 
@@ -21,7 +16,11 @@ module SimpleIDN
21
16
  SKEW = 38
22
17
  MAXINT = 0x7FFFFFFF
23
18
 
24
- module_function
19
+ module_function
20
+
21
+ def to_utf8_character(int)
22
+ [int].pack("U*")
23
+ end
25
24
 
26
25
  # decode_digit(cp) returns the numeric value of a basic code
27
26
  # point (for use in representing integers) in the range 0 to
@@ -75,7 +74,7 @@ module SimpleIDN
75
74
  # Handle the basic code points: Let basic be the number of input code
76
75
  # points before the last delimiter, or 0 if there is none, then
77
76
  # copy the first basic code points to the output.
78
- basic = input.rindex(DELIMITER.to_utf8_character) || 0
77
+ basic = input.rindex(to_utf8_character(DELIMITER)) || 0
79
78
 
80
79
  input.unpack("U*")[0, basic].each do |char|
81
80
  raise(RangeError, "Illegal input >= 0x80") if char >= 0x80
@@ -126,7 +125,7 @@ module SimpleIDN
126
125
  i %= out
127
126
 
128
127
  # Insert n at position i of the output:
129
- output.insert(i, n.to_utf8_character)
128
+ output.insert(i, to_utf8_character(n))
130
129
  i += 1
131
130
  end
132
131
 
@@ -202,7 +201,7 @@ module SimpleIDN
202
201
  delta += 1
203
202
  n += 1
204
203
  end
205
- return output.collect {|c| c.to_utf8_character}.join
204
+ return output.collect {|c| to_utf8_character(c)}.join
206
205
  end
207
206
 
208
207
  end
@@ -48,7 +48,10 @@ module MarkdownIt
48
48
 
49
49
  #------------------------------------------------------------------------------
50
50
  def fromCodePoint(c)
51
- c.chr(Encoding::UTF_8)
51
+ # Some html entities are mapped directly as characters rather than code points.
52
+ # So if we're passed an Integer, convert to character, otherwise just return
53
+ # the character. For example `≧̸`
54
+ c.is_a?(Integer) ? c.chr(Encoding::UTF_8) : c
52
55
  end
53
56
 
54
57
  #------------------------------------------------------------------------------
@@ -56,6 +59,10 @@ module MarkdownIt
56
59
  c.chr
57
60
  end
58
61
 
62
+ #------------------------------------------------------------------------------
63
+ def charCodeAt(str, ch)
64
+ str[ch].ord unless str[ch].nil?
65
+ end
59
66
 
60
67
  UNESCAPE_MD_RE = /\\([\!\"\#\$\%\&\'\(\)\*\+\,\-.\/:;<=>?@\[\\\]^_`{|}~])/
61
68
 
@@ -70,8 +77,8 @@ module MarkdownIt
70
77
 
71
78
  return fromCodePoint(MarkdownIt::HTMLEntities::MAPPINGS[name]) if MarkdownIt::HTMLEntities::MAPPINGS[name]
72
79
 
73
- if (name.charCodeAt(0) == 0x23 && DIGITAL_ENTITY_TEST_RE =~ name) # '#'
74
- code = name[1].downcase == 'x' ? name.slice_to_end(2).to_i(16) : name.slice_to_end(1).to_i
80
+ if (charCodeAt(name, 0) == 0x23 && DIGITAL_ENTITY_TEST_RE =~ name) # '#'
81
+ code = name[1].downcase == 'x' ? name[2..-1].to_i(16) : name[1..-1].to_i
75
82
  if (isValidEntityCode(code))
76
83
  return fromCodePoint(code)
77
84
  end
@@ -212,11 +219,44 @@ module MarkdownIt
212
219
  # Hepler to unify [reference labels].
213
220
  #------------------------------------------------------------------------------
214
221
  def normalizeReference(str)
215
- # use .toUpperCase() instead of .toLowerCase()
216
- # here to avoid a conflict with Object.prototype
217
- # members (most notably, `__proto__`)
218
- return str.strip.gsub(/\s+/, ' ').upcase
222
+ # Trim and collapse whitespace
223
+ #
224
+ str = str.strip.gsub(/\s+/, ' ')
225
+
226
+ # .toLowerCase().toUpperCase() should get rid of all differences
227
+ # between letter variants.
228
+ #
229
+ # Simple .toLowerCase() doesn't normalize 125 code points correctly,
230
+ # and .toUpperCase doesn't normalize 6 of them (list of exceptions:
231
+ # İ, ϴ, ẞ, Ω, K, Å - those are already uppercased, but have differently
232
+ # uppercased versions).
233
+ #
234
+ # Here's an example showing how it happens. Lets take greek letter omega:
235
+ # uppercase U+0398 (Θ), U+03f4 (ϴ) and lowercase U+03b8 (θ), U+03d1 (ϑ)
236
+ #
237
+ # Unicode entries:
238
+ # 0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;
239
+ # 03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398
240
+ # 03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398
241
+ # 03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;
242
+ #
243
+ # Case-insensitive comparison should treat all of them as equivalent.
244
+ #
245
+ # But .toLowerCase() doesn't change ϑ (it's already lowercase),
246
+ # and .toUpperCase() doesn't change ϴ (already uppercase).
247
+ #
248
+ # Applying first lower then upper case normalizes any character:
249
+ # '\u0398\u03f4\u03b8\u03d1'.toLowerCase().toUpperCase() === '\u0398\u0398\u0398\u0398'
250
+ #
251
+ # Note: this is equivalent to unicode case folding; unicode normalization
252
+ # is a different step that is not required here.
253
+ #
254
+ # Final result should be uppercased, because it's later stored in an object
255
+ # (this avoid a conflict with Object.prototype members,
256
+ # most notably, `__proto__`)
257
+ #
258
+ return str.downcase.upcase
219
259
  end
220
260
  end
221
261
  end
222
- end
262
+ end
@@ -11,11 +11,11 @@ module MarkdownIt
11
11
  start = pos
12
12
  result = {ok: false, pos: 0, lines: 0, str: ''}
13
13
 
14
- if (str.charCodeAt(pos) == 0x3C ) # <
14
+ if (charCodeAt(str, pos) == 0x3C ) # <
15
15
  pos += 1
16
16
  while (pos < max)
17
- code = str.charCodeAt(pos)
18
- return result if (code == 0x0A || isSpace(code)) # \n
17
+ code = charCodeAt(str, pos)
18
+ return result if (code == 0x0A) # \n
19
19
  if (code == 0x3E) # >
20
20
  result[:pos] = pos + 1
21
21
  result[:str] = unescapeAll(str.slice((start + 1)...pos))
@@ -38,7 +38,7 @@ module MarkdownIt
38
38
 
39
39
  level = 0
40
40
  while (pos < max)
41
- code = str.charCodeAt(pos)
41
+ code = charCodeAt(str, pos)
42
42
 
43
43
  break if (code == 0x20)
44
44
 
@@ -73,4 +73,4 @@ module MarkdownIt
73
73
  end
74
74
  end
75
75
  end
76
- end
76
+ end
@@ -15,7 +15,7 @@ module MarkdownIt
15
15
  level = 1
16
16
 
17
17
  while (state.pos < max)
18
- marker = state.src.charCodeAt(state.pos)
18
+ marker = charCodeAt(state.src, state.pos)
19
19
  if (marker == 0x5D) # ]
20
20
  level -= 1
21
21
  if (level == 0)
@@ -12,7 +12,7 @@ module MarkdownIt
12
12
 
13
13
  return result if (pos >= max)
14
14
 
15
- marker = str.charCodeAt(pos)
15
+ marker = charCodeAt(str, pos)
16
16
 
17
17
  return result if (marker != 0x22 && marker != 0x27 && marker != 0x28) # " ' (
18
18
 
@@ -22,7 +22,7 @@ module MarkdownIt
22
22
  marker = 0x29 if (marker == 0x28)
23
23
 
24
24
  while (pos < max)
25
- code = str.charCodeAt(pos)
25
+ code = charCodeAt(str, pos)
26
26
  if (code == marker)
27
27
  result[:pos] = pos + 1
28
28
  result[:lines] = lines
@@ -33,7 +33,7 @@ module MarkdownIt
33
33
  lines += 1
34
34
  elsif (code == 0x5C && pos + 1 < max) # \
35
35
  pos += 1
36
- if (str.charCodeAt(pos) == 0x0A)
36
+ if (charCodeAt(str, pos) == 0x0A)
37
37
  lines += 1
38
38
  end
39
39
  end
@@ -8,9 +8,9 @@ module MarkdownIt
8
8
  class ParserCore
9
9
 
10
10
  attr_accessor :ruler
11
-
11
+
12
12
  RULES = [
13
- [ 'normalize', lambda { |state| RulesCore::Normalize.inline(state) } ],
13
+ [ 'normalize', lambda { |state| RulesCore::Normalize.normalize(state) } ],
14
14
  [ 'block', lambda { |state| RulesCore::Block.block(state) } ],
15
15
  [ 'inline', lambda { |state| RulesCore::Inline.inline(state) } ],
16
16
  [ 'linkify', lambda { |state| RulesCore::Linkify.linkify(state) } ],
@@ -43,4 +43,4 @@ module MarkdownIt
43
43
  end
44
44
  end
45
45
  end
46
- end
46
+ end
@@ -16,7 +16,7 @@
16
16
  #------------------------------------------------------------------------------
17
17
 
18
18
  module MarkdownIt
19
- class Ruler
19
+ class Ruler
20
20
 
21
21
  def initialize
22
22
  # // List of added rules. Each element is:
@@ -94,7 +94,7 @@ module MarkdownIt
94
94
  # *
95
95
  # * ##### Example
96
96
  # *
97
- # * Replace existing typorgapher replacement rule with new one:
97
+ # * Replace existing typographer replacement rule with new one:
98
98
  # *
99
99
  # * ```javascript
100
100
  # * var md = require('markdown-it')();
@@ -108,7 +108,7 @@ module MarkdownIt
108
108
  index = __find__(name)
109
109
 
110
110
  raise(StandardError, "Parser rule not found: #{name}") if index == -1
111
-
111
+
112
112
  @__rules__[index][:fn] = fn
113
113
  @__rules__[index][:alt] = opt[:alt] || ['']
114
114
  @__cache__ = nil
@@ -15,7 +15,7 @@ module MarkdownIt
15
15
  return false if (state.sCount[startLine] - state.blkIndent >= 4)
16
16
 
17
17
  # check the block quote marker
18
- return false if state.src.charCodeAt(pos) != 0x3E # >
18
+ return false if charCodeAt(state.src, pos) != 0x3E # >
19
19
  pos += 1
20
20
 
21
21
  # we know that it's going to be a valid blockquote,
@@ -26,7 +26,7 @@ module MarkdownIt
26
26
  initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine])
27
27
 
28
28
  # skip one optional space after '>'
29
- if state.src.charCodeAt(pos) == 0x20 # space
29
+ if charCodeAt(state.src, pos) == 0x20 # space
30
30
  # ' > test '
31
31
  # ^ -- position start of line here:
32
32
  pos += 1
@@ -34,7 +34,7 @@ module MarkdownIt
34
34
  offset +=1
35
35
  adjustTab = false
36
36
  spaceAfterMarker = true
37
- elsif state.src.charCodeAt(pos) == 0x09 # tab
37
+ elsif charCodeAt(state.src, pos) == 0x09 # tab
38
38
  spaceAfterMarker = true
39
39
 
40
40
  if ((state.bsCount[startLine] + offset) % 4 == 3)
@@ -58,7 +58,7 @@ module MarkdownIt
58
58
  state.bMarks[startLine] = pos
59
59
 
60
60
  while pos < max
61
- ch = state.src.charCodeAt(pos)
61
+ ch = charCodeAt(state.src, pos)
62
62
 
63
63
  if isSpace(ch)
64
64
  if ch == 0x09
@@ -128,7 +128,7 @@ module MarkdownIt
128
128
  break
129
129
  end
130
130
 
131
- if state.src.charCodeAt(pos) == 0x3E && !wasOutdented # >
131
+ if charCodeAt(state.src, pos) == 0x3E && !wasOutdented # >
132
132
  pos += 1
133
133
  # This line is inside the blockquote.
134
134
 
@@ -136,7 +136,7 @@ module MarkdownIt
136
136
  initial = offset = state.sCount[nextLine] + pos - (state.bMarks[nextLine] + state.tShift[nextLine])
137
137
 
138
138
  # skip one optional space after '>'
139
- if state.src.charCodeAt(pos) == 0x20 # space
139
+ if charCodeAt(state.src, pos) == 0x20 # space
140
140
  # ' > test '
141
141
  # ^ -- position start of line here:
142
142
  pos += 1
@@ -144,7 +144,7 @@ module MarkdownIt
144
144
  offset += 1
145
145
  adjustTab = false
146
146
  spaceAfterMarker = true
147
- elsif state.src.charCodeAt(pos) == 0x09 # tab
147
+ elsif charCodeAt(state.src, pos) == 0x09 # tab
148
148
  spaceAfterMarker = true
149
149
 
150
150
  if ((state.bsCount[nextLine] + offset) % 4 == 3)
@@ -168,7 +168,7 @@ module MarkdownIt
168
168
  state.bMarks[nextLine] = pos
169
169
 
170
170
  while pos < max
171
- ch = state.src.charCodeAt(pos)
171
+ ch = charCodeAt(state.src, pos)
172
172
 
173
173
  if isSpace(ch)
174
174
  if ch == 0x09
@@ -16,7 +16,7 @@ module MarkdownIt
16
16
 
17
17
  return false if pos + 3 > max
18
18
 
19
- marker = state.src.charCodeAt(pos)
19
+ marker = charCodeAt(state.src, pos)
20
20
 
21
21
  if marker != 0x7E && marker != 0x60 # != ~ && != `
22
22
  return false
@@ -32,7 +32,9 @@ module MarkdownIt
32
32
  markup = state.src.slice(mem...pos)
33
33
  params = state.src.slice(pos...max)
34
34
 
35
- return false if params.include?(fromCharCode(marker))
35
+ if (marker == 0x60) # `
36
+ return false if params.include?(fromCharCode(marker))
37
+ end
36
38
 
37
39
  # Since start is found, we can report success here in validation mode
38
40
  return true if silent
@@ -58,7 +60,7 @@ module MarkdownIt
58
60
  break
59
61
  end
60
62
 
61
- next if state.src.charCodeAt(pos) != marker
63
+ next if charCodeAt(state.src, pos) != marker
62
64
 
63
65
  if state.sCount[nextLine] - state.blkIndent >= 4
64
66
  # closing fence should be indented less than 4 spaces
@@ -13,18 +13,18 @@ module MarkdownIt
13
13
  # if it's indented more than 3 spaces, it should be a code block
14
14
  return false if state.sCount[startLine] - state.blkIndent >= 4
15
15
 
16
- ch = state.src.charCodeAt(pos)
16
+ ch = charCodeAt(state.src, pos)
17
17
 
18
18
  return false if (ch != 0x23 || pos >= max)
19
19
 
20
20
  # count heading level
21
21
  level = 1
22
22
  pos += 1
23
- ch = state.src.charCodeAt(pos)
23
+ ch = charCodeAt(state.src, pos)
24
24
  while (ch == 0x23 && pos < max && level <= 6) # '#'
25
25
  level += 1
26
26
  pos += 1
27
- ch = state.src.charCodeAt(pos)
27
+ ch = charCodeAt(state.src, pos)
28
28
  end
29
29
 
30
30
  return false if (level > 6 || (pos < max && !isSpace(ch)))
@@ -35,7 +35,7 @@ module MarkdownIt
35
35
 
36
36
  max = state.skipSpacesBack(max, pos)
37
37
  tmp = state.skipCharsBack(max, 0x23, pos) # '#'
38
- if (tmp > pos && isSpace(state.src.charCodeAt(tmp - 1)))
38
+ if (tmp > pos && isSpace(charCodeAt(state.src, tmp - 1)))
39
39
  max = tmp
40
40
  end
41
41
 
@@ -13,7 +13,7 @@ module MarkdownIt
13
13
  # if it's indented more than 3 spaces, it should be a code block
14
14
  return false if (state.sCount[startLine] - state.blkIndent >= 4)
15
15
 
16
- marker = state.src.charCodeAt(pos)
16
+ marker = charCodeAt(state.src, pos)
17
17
  pos += 1
18
18
 
19
19
  # Check hr marker
@@ -27,7 +27,7 @@ module MarkdownIt
27
27
 
28
28
  cnt = 1
29
29
  while (pos < max)
30
- ch = state.src.charCodeAt(pos)
30
+ ch = charCodeAt(state.src, pos)
31
31
  pos += 1
32
32
  return false if ch != marker && !isSpace(ch)
33
33
  cnt += 1 if ch == marker
@@ -3,6 +3,7 @@
3
3
  module MarkdownIt
4
4
  module RulesBlock
5
5
  class HtmlBlock
6
+ extend Common::Utils
6
7
 
7
8
  HTML_OPEN_CLOSE_TAG_RE = MarkdownIt::Common::HtmlRe::HTML_OPEN_CLOSE_TAG_RE
8
9
 
@@ -28,7 +29,7 @@ module MarkdownIt
28
29
  return false if state.sCount[startLine] - state.blkIndent >= 4
29
30
 
30
31
  return false if !state.md.options[:html]
31
- return false if state.src.charCodeAt(pos) != 0x3C # <
32
+ return false if charCodeAt(state.src, pos) != 0x3C # <
32
33
 
33
34
  lineText = state.src.slice(pos...max)
34
35
 
@@ -3,6 +3,7 @@
3
3
  module MarkdownIt
4
4
  module RulesBlock
5
5
  class Lheading
6
+ extend Common::Utils
6
7
 
7
8
  #------------------------------------------------------------------------------
8
9
  def self.lheading(state, startLine, endLine, silent = true)
@@ -29,7 +30,7 @@ module MarkdownIt
29
30
  max = state.eMarks[nextLine]
30
31
 
31
32
  if pos < max
32
- marker = state.src.charCodeAt(pos)
33
+ marker = charCodeAt(state.src, pos)
33
34
 
34
35
  if marker == 0x2D || marker == 0x3D # - or =
35
36
  pos = state.skipChars(pos, marker)
@@ -12,7 +12,7 @@ module MarkdownIt
12
12
  pos = state.bMarks[startLine] + state.tShift[startLine]
13
13
  max = state.eMarks[startLine]
14
14
 
15
- marker = state.src.charCodeAt(pos)
15
+ marker = charCodeAt(state.src, pos)
16
16
  pos += 1
17
17
  # Check bullet
18
18
  if (marker != 0x2A && # *
@@ -22,7 +22,7 @@ module MarkdownIt
22
22
  end
23
23
 
24
24
  if pos < max
25
- ch = state.src.charCodeAt(pos)
25
+ ch = charCodeAt(state.src, pos)
26
26
 
27
27
  if !isSpace(ch)
28
28
  # " -test " - is not a list item
@@ -44,7 +44,7 @@ module MarkdownIt
44
44
  # List marker should have at least 2 chars (digit + dot)
45
45
  return -1 if (pos + 1 >= max)
46
46
 
47
- ch = state.src.charCodeAt(pos)
47
+ ch = charCodeAt(state.src, pos)
48
48
  pos += 1
49
49
 
50
50
  return -1 if ch.nil?
@@ -54,7 +54,7 @@ module MarkdownIt
54
54
  # EOL -> fail
55
55
  return -1 if (pos >= max)
56
56
 
57
- ch = state.src.charCodeAt(pos)
57
+ ch = charCodeAt(state.src, pos)
58
58
  pos += 1
59
59
 
60
60
  if (ch >= 0x30 && ch <= 0x39) # >= 0 && <= 9
@@ -75,7 +75,7 @@ module MarkdownIt
75
75
  end
76
76
 
77
77
  if pos < max
78
- ch = state.src.charCodeAt(pos)
78
+ ch = charCodeAt(state.src, pos)
79
79
 
80
80
  if !isSpace(ch)
81
81
  # " 1.test " - is not a list item
@@ -109,6 +109,18 @@ module MarkdownIt
109
109
  # if it's indented more than 3 spaces, it should be a code block
110
110
  return false if (state.sCount[startLine] - state.blkIndent >= 4)
111
111
 
112
+ # Special case:
113
+ # - item 1
114
+ # - item 2
115
+ # - item 3
116
+ # - item 4
117
+ # - this one is a paragraph continuation
118
+ if (state.listIndent >= 0 &&
119
+ state.sCount[startLine] - state.listIndent >= 4 &&
120
+ state.sCount[startLine] < state.blkIndent)
121
+ return false
122
+ end
123
+
112
124
  # limit conditions when list can interrupt
113
125
  # a paragraph (validation mode only)
114
126
  if silent && state.parentType == 'paragraph'
@@ -144,7 +156,7 @@ module MarkdownIt
144
156
  end
145
157
 
146
158
  # We should terminate list on style change. Remember first one to compare.
147
- markerCharCode = state.src.charCodeAt(posAfterMarker - 1)
159
+ markerCharCode = charCodeAt(state.src, posAfterMarker - 1)
148
160
 
149
161
  # For validation mode we can terminate immediately
150
162
  return true if (silent)
@@ -185,7 +197,7 @@ module MarkdownIt
185
197
  initial = offset = state.sCount[nextLine] + posAfterMarker - (state.bMarks[startLine] + state.tShift[startLine])
186
198
 
187
199
  while pos < max
188
- ch = state.src.charCodeAt(pos)
200
+ ch = charCodeAt(state.src, pos)
189
201
 
190
202
  if ch == 0x09
191
203
  offset += 4 - (offset + state.bsCount[nextLine]) % 4
@@ -220,11 +232,19 @@ module MarkdownIt
220
232
  token.markup = markerCharCode.chr
221
233
  token.map = itemLines = [ startLine, 0 ]
222
234
 
223
- oldIndent = state.blkIndent
235
+ # change current state, then restore it after parser subcall
224
236
  oldTight = state.tight
225
237
  oldTShift = state.tShift[startLine]
226
- oldLIndent = state.sCount[startLine]
238
+ oldSCount = state.sCount[startLine]
239
+
240
+ # - example list
241
+ # ^ listIndent position will be here
242
+ # ^ blkIndent position will be here
243
+ #
244
+ oldListIndent = state.listIndent
245
+ state.listIndent = state.blkIndent
227
246
  state.blkIndent = indent
247
+
228
248
  state.tight = true
229
249
  state.tShift[startLine] = contentStart - state.bMarks[startLine]
230
250
  state.sCount[startLine] = offset
@@ -250,9 +270,10 @@ module MarkdownIt
250
270
  # but we should filter last element, because it means list finish
251
271
  prevEmptyEnd = (state.line - startLine) > 1 && state.isEmpty(state.line - 1)
252
272
 
253
- state.blkIndent = oldIndent
273
+ state.blkIndent = state.listIndent
274
+ state.listIndent = oldListIndent
254
275
  state.tShift[startLine] = oldTShift
255
- state.sCount[startLine] = oldLIndent
276
+ state.sCount[startLine] = oldSCount
256
277
  state.tight = oldTight
257
278
 
258
279
  token = state.push('list_item_close', 'li', -1)
@@ -269,6 +290,9 @@ module MarkdownIt
269
290
  #
270
291
  break if (state.sCount[nextLine] < state.blkIndent)
271
292
 
293
+ # if it's indented more than 3 spaces, it should be a code block
294
+ break if (state.sCount[startLine] - state.blkIndent >= 4)
295
+
272
296
  # fail if terminating block found
273
297
  terminate = false
274
298
  (0...terminatorRules.length).each do |i|
@@ -288,7 +312,7 @@ module MarkdownIt
288
312
  break if (posAfterMarker < 0)
289
313
  end
290
314
 
291
- break if (markerCharCode != state.src.charCodeAt(posAfterMarker - 1))
315
+ break if (markerCharCode != charCodeAt(state.src, posAfterMarker - 1))
292
316
  end
293
317
 
294
318
  # Finalize list