class MotionMarkdownItPlugins::Deflist
Public Class Methods
deflist(state, startLine, endLine, silent)
click to toggle source
# File lib/motion-markdown-it-plugins/deflist/deflist.rb, line 58 def self.deflist(state, startLine, endLine, silent) if silent # quirk: validation mode validates a dd block only, not a whole deflist return false if (state.ddIndent < 0) return skipMarker(state, startLine) >= 0 end nextLine = startLine + 1 return false if nextLine >= endLine if state.isEmpty(nextLine) nextLine += 1 return false if nextLine >= endLine end return false if (state.sCount[nextLine] < state.blkIndent) contentStart = skipMarker(state, nextLine) return false if (contentStart < 0) # Start list listTokIdx = state.tokens.length tight = true token = state.push('dl_open', 'dl', 1) token.map = listLines = [ startLine, 0 ] # # Iterate list items # dtLine = startLine ddLine = nextLine # One definition list can contain multiple DTs, # and one DT can be followed by multiple DDs. # # Thus, there is two loops here, and label is # needed to break out of the second one # OUTER: while true break_outer = false prevEmptyEnd = false token = state.push('dt_open', 'dt', 1) token.map = [ dtLine, dtLine ] token = state.push('inline', '', 0) token.map = [ dtLine, dtLine ] token.content = state.getLines(dtLine, dtLine + 1, state.blkIndent, false).strip token.children = [] token = state.push('dt_close', 'dt', -1) while true token = state.push('dd_open', 'dd', 1) token.map = itemLines = [ nextLine, 0 ] pos = contentStart max = state.eMarks[ddLine] offset = state.sCount[ddLine] + contentStart - (state.bMarks[ddLine] + state.tShift[ddLine]) while pos < max ch = charCodeAt(state.src, pos) if isSpace(ch) if ch == 0x09 offset += 4 - offset % 4 else offset += 1 end else break end pos += 1 end contentStart = pos oldTight = state.tight oldDDIndent = state.ddIndent oldIndent = state.blkIndent oldTShift = state.tShift[ddLine] oldSCount = state.sCount[ddLine] oldParentType = state.parentType state.blkIndent = state.ddIndent = state.sCount[ddLine] + 2 state.tShift[ddLine] = contentStart - state.bMarks[ddLine] state.sCount[ddLine] = offset state.tight = true state.parentType = 'deflist' state.md.block.tokenize(state, ddLine, endLine, true) # If any of list item is tight, mark list as tight if (!state.tight || prevEmptyEnd) tight = false end # Item become loose if finish with empty line, # but we should filter last element, because it means list finish prevEmptyEnd = (state.line - ddLine) > 1 && state.isEmpty(state.line - 1) state.tShift[ddLine] = oldTShift state.sCount[ddLine] = oldSCount state.tight = oldTight state.parentType = oldParentType state.blkIndent = oldIndent state.ddIndent = oldDDIndent token = state.push('dd_close', 'dd', -1) itemLines[1] = nextLine = state.line break_outer = true and break if (nextLine >= endLine) break_outer = true and break if (state.sCount[nextLine] < state.blkIndent) contentStart = skipMarker(state, nextLine) break if (contentStart < 0) ddLine = nextLine # go to the next loop iteration: # insert DD tag and repeat checking end break if break_outer break if (nextLine >= endLine) dtLine = nextLine break if (state.isEmpty(dtLine)) break if (state.sCount[dtLine] < state.blkIndent) ddLine = dtLine + 1 break if (ddLine >= endLine) ddLine += 1 if (state.isEmpty(ddLine)) break if (ddLine >= endLine) break if (state.sCount[ddLine] < state.blkIndent) contentStart = skipMarker(state, ddLine) break if (contentStart < 0) # go to the next loop iteration: # insert DT and DD tags and repeat checking end # Finalize list token = state.push('dl_close', 'dl', -1) listLines[1] = nextLine state.line = nextLine # mark paragraphs tight if needed if (tight) markTightParagraphs(state, listTokIdx) end return true end
init_plugin(md)
click to toggle source
# File lib/motion-markdown-it-plugins/deflist/deflist.rb, line 11 def self.init_plugin(md) md.block.ruler.before('paragraph', 'deflist', lambda { |state, startLine, endLine, silent| Deflist.deflist(state, startLine, endLine, silent) }, {alt: ['', 'paragraph', 'reference']}) end
markTightParagraphs(state, idx)
click to toggle source
# File lib/motion-markdown-it-plugins/deflist/deflist.rb, line 43 def self.markTightParagraphs(state, idx) level = state.level + 2 i = idx + 2 l = state.tokens.length - 2 while i < l if (state.tokens[i].level == level && state.tokens[i].type == 'paragraph_open') state.tokens[i + 2].hidden = true state.tokens[i].hidden = true i += 2 end i += 1 end end
skipMarker(state, line)
click to toggle source
Search `[:~][n ]`, returns next pos after marker on success or -1 on fail.
# File lib/motion-markdown-it-plugins/deflist/deflist.rb, line 20 def self.skipMarker(state, line) start = state.bMarks[line] + state.tShift[line] max = state.eMarks[line] return -1 if (start >= max) # Check bullet marker = charCodeAt(state.src, start) start += 1 return -1 if (marker != 0x7E && marker != 0x3A) # '~' ':' pos = state.skipSpaces(start) # require space after ":" return -1 if (start == pos) # no empty definitions, e.g. " : " return -1 if (pos >= max) return start end