Class: MarkdownIt::RulesInline::BalancePairs
- Inherits:
-
Object
- Object
- MarkdownIt::RulesInline::BalancePairs
- Defined in:
- lib/motion-markdown-it/rules_inline/balance_pairs.rb
Class Method Summary collapse
-
.link_pairs(state) ⇒ Object
——————————————————————————.
-
.processDelimiters(state, delimiters) ⇒ Object
——————————————————————————.
Class Method Details
.link_pairs(state) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/motion-markdown-it/rules_inline/balance_pairs.rb', line 97 def self.link_pairs(state) = state. max = state..length processDelimiters(state, state.delimiters) 0.upto(max - 1) do |curr| if ([curr] && [curr][:delimiters]) processDelimiters(state, [curr][:delimiters]) end end end |
.processDelimiters(state, delimiters) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/motion-markdown-it/rules_inline/balance_pairs.rb', line 8 def self.processDelimiters(state, delimiters) openersBottom = {} max = delimiters.length 0.upto(max - 1) do |closerIdx| closer = delimiters[closerIdx] # Length is only used for emphasis-specific "rule of 3", # if it's not defined (in strikethrough or 3rd party plugins), # we can default it to 0 to disable those checks. # closer[:length] = closer[:length] || 0 next if (!closer[:close]) # Previously calculated lower bounds (previous fails) # for each marker and each delimiter length modulo 3. unless openersBottom[closer[:marker]] openersBottom[closer[:marker]] = [ -1, -1, -1 ] end minOpenerIdx = openersBottom[closer[:marker]][closer[:length] % 3] newMinOpenerIdx = -1 openerIdx = closerIdx - closer[:jump] - 1 while openerIdx > minOpenerIdx opener = delimiters[openerIdx] (openerIdx -= opener[:jump] + 1) && next if (opener[:marker] != closer[:marker]) newMinOpenerIdx = openerIdx if (newMinOpenerIdx == -1) if (opener[:open] && opener[:end] < 0 && opener[:level] == closer[:level]) isOddMatch = false # from spec: # # If one of the delimiters can both open and close emphasis, then the # sum of the lengths of the delimiter runs containing the opening and # closing delimiters must not be a multiple of 3 unless both lengths # are multiples of 3. # if (opener[:close] || closer[:open]) if ((opener[:length] + closer[:length]) % 3 == 0) if (opener[:length] % 3 != 0 || closer[:length] % 3 != 0) isOddMatch = true end end end if (!isOddMatch) # If previous delimiter cannot be an opener, we can safely skip # the entire sequence in future checks. This is required to make # sure algorithm has linear complexity (see *_*_*_*_*_... case). # lastJump = openerIdx > 0 && !delimiters[openerIdx - 1][:open] ? delimiters[openerIdx - 1][:jump] + 1 : 0 closer[:jump] = closerIdx - openerIdx + lastJump closer[:open] = false opener[:end] = closerIdx opener[:jump] = lastJump opener[:close] = false newMinOpenerIdx = -1 break end end openerIdx -= opener[:jump] + 1 end if (newMinOpenerIdx != -1) # If match for this delimiter run failed, we want to set lower bound for # future lookups. This is required to make sure algorithm has linear # complexity. # # See details here: # https://github.com/commonmark/cmark/issues/178#issuecomment-270417442 # openersBottom[closer[:marker]][(closer[:length] || 0) % 3] = newMinOpenerIdx end end end |