mirror of
				https://github.com/fooflington/selfdefined.git
				synced 2025-10-31 14:18:32 +00:00 
			
		
		
		
	update
This commit is contained in:
		
							
								
								
									
										285
									
								
								node_modules/markdown-it/lib/rules_block/blockquote.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										285
									
								
								node_modules/markdown-it/lib/rules_block/blockquote.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,285 @@ | ||||
| // Block quotes | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| var isSpace = require('../common/utils').isSpace; | ||||
|  | ||||
|  | ||||
| module.exports = function blockquote(state, startLine, endLine, silent) { | ||||
|   var adjustTab, | ||||
|       ch, | ||||
|       i, | ||||
|       initial, | ||||
|       l, | ||||
|       lastLineEmpty, | ||||
|       lines, | ||||
|       nextLine, | ||||
|       offset, | ||||
|       oldBMarks, | ||||
|       oldBSCount, | ||||
|       oldIndent, | ||||
|       oldParentType, | ||||
|       oldSCount, | ||||
|       oldTShift, | ||||
|       spaceAfterMarker, | ||||
|       terminate, | ||||
|       terminatorRules, | ||||
|       token, | ||||
|       wasOutdented, | ||||
|       oldLineMax = state.lineMax, | ||||
|       pos = state.bMarks[startLine] + state.tShift[startLine], | ||||
|       max = state.eMarks[startLine]; | ||||
|  | ||||
|   // if it's indented more than 3 spaces, it should be a code block | ||||
|   if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } | ||||
|  | ||||
|   // check the block quote marker | ||||
|   if (state.src.charCodeAt(pos++) !== 0x3E/* > */) { return false; } | ||||
|  | ||||
|   // we know that it's going to be a valid blockquote, | ||||
|   // so no point trying to find the end of it in silent mode | ||||
|   if (silent) { return true; } | ||||
|  | ||||
|   // skip spaces after ">" and re-calculate offset | ||||
|   initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]); | ||||
|  | ||||
|   // skip one optional space after '>' | ||||
|   if (state.src.charCodeAt(pos) === 0x20 /* space */) { | ||||
|     // ' >   test ' | ||||
|     //     ^ -- position start of line here: | ||||
|     pos++; | ||||
|     initial++; | ||||
|     offset++; | ||||
|     adjustTab = false; | ||||
|     spaceAfterMarker = true; | ||||
|   } else if (state.src.charCodeAt(pos) === 0x09 /* tab */) { | ||||
|     spaceAfterMarker = true; | ||||
|  | ||||
|     if ((state.bsCount[startLine] + offset) % 4 === 3) { | ||||
|       // '  >\t  test ' | ||||
|       //       ^ -- position start of line here (tab has width===1) | ||||
|       pos++; | ||||
|       initial++; | ||||
|       offset++; | ||||
|       adjustTab = false; | ||||
|     } else { | ||||
|       // ' >\t  test ' | ||||
|       //    ^ -- position start of line here + shift bsCount slightly | ||||
|       //         to make extra space appear | ||||
|       adjustTab = true; | ||||
|     } | ||||
|   } else { | ||||
|     spaceAfterMarker = false; | ||||
|   } | ||||
|  | ||||
|   oldBMarks = [ state.bMarks[startLine] ]; | ||||
|   state.bMarks[startLine] = pos; | ||||
|  | ||||
|   while (pos < max) { | ||||
|     ch = state.src.charCodeAt(pos); | ||||
|  | ||||
|     if (isSpace(ch)) { | ||||
|       if (ch === 0x09) { | ||||
|         offset += 4 - (offset + state.bsCount[startLine] + (adjustTab ? 1 : 0)) % 4; | ||||
|       } else { | ||||
|         offset++; | ||||
|       } | ||||
|     } else { | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|     pos++; | ||||
|   } | ||||
|  | ||||
|   oldBSCount = [ state.bsCount[startLine] ]; | ||||
|   state.bsCount[startLine] = state.sCount[startLine] + 1 + (spaceAfterMarker ? 1 : 0); | ||||
|  | ||||
|   lastLineEmpty = pos >= max; | ||||
|  | ||||
|   oldSCount = [ state.sCount[startLine] ]; | ||||
|   state.sCount[startLine] = offset - initial; | ||||
|  | ||||
|   oldTShift = [ state.tShift[startLine] ]; | ||||
|   state.tShift[startLine] = pos - state.bMarks[startLine]; | ||||
|  | ||||
|   terminatorRules = state.md.block.ruler.getRules('blockquote'); | ||||
|  | ||||
|   oldParentType = state.parentType; | ||||
|   state.parentType = 'blockquote'; | ||||
|   wasOutdented = false; | ||||
|  | ||||
|   // Search the end of the block | ||||
|   // | ||||
|   // Block ends with either: | ||||
|   //  1. an empty line outside: | ||||
|   //     ``` | ||||
|   //     > test | ||||
|   // | ||||
|   //     ``` | ||||
|   //  2. an empty line inside: | ||||
|   //     ``` | ||||
|   //     > | ||||
|   //     test | ||||
|   //     ``` | ||||
|   //  3. another tag: | ||||
|   //     ``` | ||||
|   //     > test | ||||
|   //      - - - | ||||
|   //     ``` | ||||
|   for (nextLine = startLine + 1; nextLine < endLine; nextLine++) { | ||||
|     // check if it's outdented, i.e. it's inside list item and indented | ||||
|     // less than said list item: | ||||
|     // | ||||
|     // ``` | ||||
|     // 1. anything | ||||
|     //    > current blockquote | ||||
|     // 2. checking this line | ||||
|     // ``` | ||||
|     if (state.sCount[nextLine] < state.blkIndent) wasOutdented = true; | ||||
|  | ||||
|     pos = state.bMarks[nextLine] + state.tShift[nextLine]; | ||||
|     max = state.eMarks[nextLine]; | ||||
|  | ||||
|     if (pos >= max) { | ||||
|       // Case 1: line is not inside the blockquote, and this line is empty. | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|     if (state.src.charCodeAt(pos++) === 0x3E/* > */ && !wasOutdented) { | ||||
|       // This line is inside the blockquote. | ||||
|  | ||||
|       // skip spaces after ">" and re-calculate offset | ||||
|       initial = offset = state.sCount[nextLine] + pos - (state.bMarks[nextLine] + state.tShift[nextLine]); | ||||
|  | ||||
|       // skip one optional space after '>' | ||||
|       if (state.src.charCodeAt(pos) === 0x20 /* space */) { | ||||
|         // ' >   test ' | ||||
|         //     ^ -- position start of line here: | ||||
|         pos++; | ||||
|         initial++; | ||||
|         offset++; | ||||
|         adjustTab = false; | ||||
|         spaceAfterMarker = true; | ||||
|       } else if (state.src.charCodeAt(pos) === 0x09 /* tab */) { | ||||
|         spaceAfterMarker = true; | ||||
|  | ||||
|         if ((state.bsCount[nextLine] + offset) % 4 === 3) { | ||||
|           // '  >\t  test ' | ||||
|           //       ^ -- position start of line here (tab has width===1) | ||||
|           pos++; | ||||
|           initial++; | ||||
|           offset++; | ||||
|           adjustTab = false; | ||||
|         } else { | ||||
|           // ' >\t  test ' | ||||
|           //    ^ -- position start of line here + shift bsCount slightly | ||||
|           //         to make extra space appear | ||||
|           adjustTab = true; | ||||
|         } | ||||
|       } else { | ||||
|         spaceAfterMarker = false; | ||||
|       } | ||||
|  | ||||
|       oldBMarks.push(state.bMarks[nextLine]); | ||||
|       state.bMarks[nextLine] = pos; | ||||
|  | ||||
|       while (pos < max) { | ||||
|         ch = state.src.charCodeAt(pos); | ||||
|  | ||||
|         if (isSpace(ch)) { | ||||
|           if (ch === 0x09) { | ||||
|             offset += 4 - (offset + state.bsCount[nextLine] + (adjustTab ? 1 : 0)) % 4; | ||||
|           } else { | ||||
|             offset++; | ||||
|           } | ||||
|         } else { | ||||
|           break; | ||||
|         } | ||||
|  | ||||
|         pos++; | ||||
|       } | ||||
|  | ||||
|       lastLineEmpty = pos >= max; | ||||
|  | ||||
|       oldBSCount.push(state.bsCount[nextLine]); | ||||
|       state.bsCount[nextLine] = state.sCount[nextLine] + 1 + (spaceAfterMarker ? 1 : 0); | ||||
|  | ||||
|       oldSCount.push(state.sCount[nextLine]); | ||||
|       state.sCount[nextLine] = offset - initial; | ||||
|  | ||||
|       oldTShift.push(state.tShift[nextLine]); | ||||
|       state.tShift[nextLine] = pos - state.bMarks[nextLine]; | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     // Case 2: line is not inside the blockquote, and the last line was empty. | ||||
|     if (lastLineEmpty) { break; } | ||||
|  | ||||
|     // Case 3: another tag found. | ||||
|     terminate = false; | ||||
|     for (i = 0, l = terminatorRules.length; i < l; i++) { | ||||
|       if (terminatorRules[i](state, nextLine, endLine, true)) { | ||||
|         terminate = true; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (terminate) { | ||||
|       // Quirk to enforce "hard termination mode" for paragraphs; | ||||
|       // normally if you call `tokenize(state, startLine, nextLine)`, | ||||
|       // paragraphs will look below nextLine for paragraph continuation, | ||||
|       // but if blockquote is terminated by another tag, they shouldn't | ||||
|       state.lineMax = nextLine; | ||||
|  | ||||
|       if (state.blkIndent !== 0) { | ||||
|         // state.blkIndent was non-zero, we now set it to zero, | ||||
|         // so we need to re-calculate all offsets to appear as | ||||
|         // if indent wasn't changed | ||||
|         oldBMarks.push(state.bMarks[nextLine]); | ||||
|         oldBSCount.push(state.bsCount[nextLine]); | ||||
|         oldTShift.push(state.tShift[nextLine]); | ||||
|         oldSCount.push(state.sCount[nextLine]); | ||||
|         state.sCount[nextLine] -= state.blkIndent; | ||||
|       } | ||||
|  | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|     oldBMarks.push(state.bMarks[nextLine]); | ||||
|     oldBSCount.push(state.bsCount[nextLine]); | ||||
|     oldTShift.push(state.tShift[nextLine]); | ||||
|     oldSCount.push(state.sCount[nextLine]); | ||||
|  | ||||
|     // A negative indentation means that this is a paragraph continuation | ||||
|     // | ||||
|     state.sCount[nextLine] = -1; | ||||
|   } | ||||
|  | ||||
|   oldIndent = state.blkIndent; | ||||
|   state.blkIndent = 0; | ||||
|  | ||||
|   token        = state.push('blockquote_open', 'blockquote', 1); | ||||
|   token.markup = '>'; | ||||
|   token.map    = lines = [ startLine, 0 ]; | ||||
|  | ||||
|   state.md.block.tokenize(state, startLine, nextLine); | ||||
|  | ||||
|   token        = state.push('blockquote_close', 'blockquote', -1); | ||||
|   token.markup = '>'; | ||||
|  | ||||
|   state.lineMax = oldLineMax; | ||||
|   state.parentType = oldParentType; | ||||
|   lines[1] = state.line; | ||||
|  | ||||
|   // Restore original tShift; this might not be necessary since the parser | ||||
|   // has already been here, but just to make sure we can do that. | ||||
|   for (i = 0; i < oldTShift.length; i++) { | ||||
|     state.bMarks[i + startLine] = oldBMarks[i]; | ||||
|     state.tShift[i + startLine] = oldTShift[i]; | ||||
|     state.sCount[i + startLine] = oldSCount[i]; | ||||
|     state.bsCount[i + startLine] = oldBSCount[i]; | ||||
|   } | ||||
|   state.blkIndent = oldIndent; | ||||
|  | ||||
|   return true; | ||||
| }; | ||||
							
								
								
									
										34
									
								
								node_modules/markdown-it/lib/rules_block/code.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								node_modules/markdown-it/lib/rules_block/code.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| // Code block (4 spaces padded) | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| module.exports = function code(state, startLine, endLine/*, silent*/) { | ||||
|   var nextLine, last, token; | ||||
|  | ||||
|   if (state.sCount[startLine] - state.blkIndent < 4) { return false; } | ||||
|  | ||||
|   last = nextLine = startLine + 1; | ||||
|  | ||||
|   while (nextLine < endLine) { | ||||
|     if (state.isEmpty(nextLine)) { | ||||
|       nextLine++; | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (state.sCount[nextLine] - state.blkIndent >= 4) { | ||||
|       nextLine++; | ||||
|       last = nextLine; | ||||
|       continue; | ||||
|     } | ||||
|     break; | ||||
|   } | ||||
|  | ||||
|   state.line = last; | ||||
|  | ||||
|   token         = state.push('code_block', 'code', 0); | ||||
|   token.content = state.getLines(startLine, last, 4 + state.blkIndent, true); | ||||
|   token.map     = [ startLine, state.line ]; | ||||
|  | ||||
|   return true; | ||||
| }; | ||||
							
								
								
									
										94
									
								
								node_modules/markdown-it/lib/rules_block/fence.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								node_modules/markdown-it/lib/rules_block/fence.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| // fences (``` lang, ~~~ lang) | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| module.exports = function fence(state, startLine, endLine, silent) { | ||||
|   var marker, len, params, nextLine, mem, token, markup, | ||||
|       haveEndMarker = false, | ||||
|       pos = state.bMarks[startLine] + state.tShift[startLine], | ||||
|       max = state.eMarks[startLine]; | ||||
|  | ||||
|   // if it's indented more than 3 spaces, it should be a code block | ||||
|   if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } | ||||
|  | ||||
|   if (pos + 3 > max) { return false; } | ||||
|  | ||||
|   marker = state.src.charCodeAt(pos); | ||||
|  | ||||
|   if (marker !== 0x7E/* ~ */ && marker !== 0x60 /* ` */) { | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   // scan marker length | ||||
|   mem = pos; | ||||
|   pos = state.skipChars(pos, marker); | ||||
|  | ||||
|   len = pos - mem; | ||||
|  | ||||
|   if (len < 3) { return false; } | ||||
|  | ||||
|   markup = state.src.slice(mem, pos); | ||||
|   params = state.src.slice(pos, max); | ||||
|  | ||||
|   if (params.indexOf(String.fromCharCode(marker)) >= 0) { return false; } | ||||
|  | ||||
|   // Since start is found, we can report success here in validation mode | ||||
|   if (silent) { return true; } | ||||
|  | ||||
|   // search end of block | ||||
|   nextLine = startLine; | ||||
|  | ||||
|   for (;;) { | ||||
|     nextLine++; | ||||
|     if (nextLine >= endLine) { | ||||
|       // unclosed block should be autoclosed by end of document. | ||||
|       // also block seems to be autoclosed by end of parent | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|     pos = mem = state.bMarks[nextLine] + state.tShift[nextLine]; | ||||
|     max = state.eMarks[nextLine]; | ||||
|  | ||||
|     if (pos < max && state.sCount[nextLine] < state.blkIndent) { | ||||
|       // non-empty line with negative indent should stop the list: | ||||
|       // - ``` | ||||
|       //  test | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|     if (state.src.charCodeAt(pos) !== marker) { continue; } | ||||
|  | ||||
|     if (state.sCount[nextLine] - state.blkIndent >= 4) { | ||||
|       // closing fence should be indented less than 4 spaces | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     pos = state.skipChars(pos, marker); | ||||
|  | ||||
|     // closing code fence must be at least as long as the opening one | ||||
|     if (pos - mem < len) { continue; } | ||||
|  | ||||
|     // make sure tail has spaces only | ||||
|     pos = state.skipSpaces(pos); | ||||
|  | ||||
|     if (pos < max) { continue; } | ||||
|  | ||||
|     haveEndMarker = true; | ||||
|     // found! | ||||
|     break; | ||||
|   } | ||||
|  | ||||
|   // If a fence has heading spaces, they should be removed from its inner block | ||||
|   len = state.sCount[startLine]; | ||||
|  | ||||
|   state.line = nextLine + (haveEndMarker ? 1 : 0); | ||||
|  | ||||
|   token         = state.push('fence', 'code', 0); | ||||
|   token.info    = params; | ||||
|   token.content = state.getLines(startLine + 1, nextLine, len, true); | ||||
|   token.markup  = markup; | ||||
|   token.map     = [ startLine, state.line ]; | ||||
|  | ||||
|   return true; | ||||
| }; | ||||
							
								
								
									
										55
									
								
								node_modules/markdown-it/lib/rules_block/heading.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								node_modules/markdown-it/lib/rules_block/heading.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| // heading (#, ##, ...) | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| var isSpace = require('../common/utils').isSpace; | ||||
|  | ||||
|  | ||||
| module.exports = function heading(state, startLine, endLine, silent) { | ||||
|   var ch, level, tmp, token, | ||||
|       pos = state.bMarks[startLine] + state.tShift[startLine], | ||||
|       max = state.eMarks[startLine]; | ||||
|  | ||||
|   // if it's indented more than 3 spaces, it should be a code block | ||||
|   if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } | ||||
|  | ||||
|   ch  = state.src.charCodeAt(pos); | ||||
|  | ||||
|   if (ch !== 0x23/* # */ || pos >= max) { return false; } | ||||
|  | ||||
|   // count heading level | ||||
|   level = 1; | ||||
|   ch = state.src.charCodeAt(++pos); | ||||
|   while (ch === 0x23/* # */ && pos < max && level <= 6) { | ||||
|     level++; | ||||
|     ch = state.src.charCodeAt(++pos); | ||||
|   } | ||||
|  | ||||
|   if (level > 6 || (pos < max && !isSpace(ch))) { return false; } | ||||
|  | ||||
|   if (silent) { return true; } | ||||
|  | ||||
|   // Let's cut tails like '    ###  ' from the end of string | ||||
|  | ||||
|   max = state.skipSpacesBack(max, pos); | ||||
|   tmp = state.skipCharsBack(max, 0x23, pos); // # | ||||
|   if (tmp > pos && isSpace(state.src.charCodeAt(tmp - 1))) { | ||||
|     max = tmp; | ||||
|   } | ||||
|  | ||||
|   state.line = startLine + 1; | ||||
|  | ||||
|   token        = state.push('heading_open', 'h' + String(level), 1); | ||||
|   token.markup = '########'.slice(0, level); | ||||
|   token.map    = [ startLine, state.line ]; | ||||
|  | ||||
|   token          = state.push('inline', '', 0); | ||||
|   token.content  = state.src.slice(pos, max).trim(); | ||||
|   token.map      = [ startLine, state.line ]; | ||||
|   token.children = []; | ||||
|  | ||||
|   token        = state.push('heading_close', 'h' + String(level), -1); | ||||
|   token.markup = '########'.slice(0, level); | ||||
|  | ||||
|   return true; | ||||
| }; | ||||
							
								
								
									
										45
									
								
								node_modules/markdown-it/lib/rules_block/hr.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								node_modules/markdown-it/lib/rules_block/hr.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| // Horizontal rule | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| var isSpace = require('../common/utils').isSpace; | ||||
|  | ||||
|  | ||||
| module.exports = function hr(state, startLine, endLine, silent) { | ||||
|   var marker, cnt, ch, token, | ||||
|       pos = state.bMarks[startLine] + state.tShift[startLine], | ||||
|       max = state.eMarks[startLine]; | ||||
|  | ||||
|   // if it's indented more than 3 spaces, it should be a code block | ||||
|   if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } | ||||
|  | ||||
|   marker = state.src.charCodeAt(pos++); | ||||
|  | ||||
|   // Check hr marker | ||||
|   if (marker !== 0x2A/* * */ && | ||||
|       marker !== 0x2D/* - */ && | ||||
|       marker !== 0x5F/* _ */) { | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   // markers can be mixed with spaces, but there should be at least 3 of them | ||||
|  | ||||
|   cnt = 1; | ||||
|   while (pos < max) { | ||||
|     ch = state.src.charCodeAt(pos++); | ||||
|     if (ch !== marker && !isSpace(ch)) { return false; } | ||||
|     if (ch === marker) { cnt++; } | ||||
|   } | ||||
|  | ||||
|   if (cnt < 3) { return false; } | ||||
|  | ||||
|   if (silent) { return true; } | ||||
|  | ||||
|   state.line = startLine + 1; | ||||
|  | ||||
|   token        = state.push('hr', 'hr', 0); | ||||
|   token.map    = [ startLine, state.line ]; | ||||
|   token.markup = Array(cnt + 1).join(String.fromCharCode(marker)); | ||||
|  | ||||
|   return true; | ||||
| }; | ||||
							
								
								
									
										74
									
								
								node_modules/markdown-it/lib/rules_block/html_block.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								node_modules/markdown-it/lib/rules_block/html_block.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| // HTML block | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| var block_names = require('../common/html_blocks'); | ||||
| var HTML_OPEN_CLOSE_TAG_RE = require('../common/html_re').HTML_OPEN_CLOSE_TAG_RE; | ||||
|  | ||||
| // An array of opening and corresponding closing sequences for html tags, | ||||
| // last argument defines whether it can terminate a paragraph or not | ||||
| // | ||||
| var HTML_SEQUENCES = [ | ||||
|   [ /^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true ], | ||||
|   [ /^<!--/,        /-->/,   true ], | ||||
|   [ /^<\?/,         /\?>/,   true ], | ||||
|   [ /^<![A-Z]/,     />/,     true ], | ||||
|   [ /^<!\[CDATA\[/, /\]\]>/, true ], | ||||
|   [ new RegExp('^</?(' + block_names.join('|') + ')(?=(\\s|/?>|$))', 'i'), /^$/, true ], | ||||
|   [ new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + '\\s*$'),  /^$/, false ] | ||||
| ]; | ||||
|  | ||||
|  | ||||
| module.exports = function html_block(state, startLine, endLine, silent) { | ||||
|   var i, nextLine, token, lineText, | ||||
|       pos = state.bMarks[startLine] + state.tShift[startLine], | ||||
|       max = state.eMarks[startLine]; | ||||
|  | ||||
|   // if it's indented more than 3 spaces, it should be a code block | ||||
|   if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } | ||||
|  | ||||
|   if (!state.md.options.html) { return false; } | ||||
|  | ||||
|   if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; } | ||||
|  | ||||
|   lineText = state.src.slice(pos, max); | ||||
|  | ||||
|   for (i = 0; i < HTML_SEQUENCES.length; i++) { | ||||
|     if (HTML_SEQUENCES[i][0].test(lineText)) { break; } | ||||
|   } | ||||
|  | ||||
|   if (i === HTML_SEQUENCES.length) { return false; } | ||||
|  | ||||
|   if (silent) { | ||||
|     // true if this sequence can be a terminator, false otherwise | ||||
|     return HTML_SEQUENCES[i][2]; | ||||
|   } | ||||
|  | ||||
|   nextLine = startLine + 1; | ||||
|  | ||||
|   // If we are here - we detected HTML block. | ||||
|   // Let's roll down till block end. | ||||
|   if (!HTML_SEQUENCES[i][1].test(lineText)) { | ||||
|     for (; nextLine < endLine; nextLine++) { | ||||
|       if (state.sCount[nextLine] < state.blkIndent) { break; } | ||||
|  | ||||
|       pos = state.bMarks[nextLine] + state.tShift[nextLine]; | ||||
|       max = state.eMarks[nextLine]; | ||||
|       lineText = state.src.slice(pos, max); | ||||
|  | ||||
|       if (HTML_SEQUENCES[i][1].test(lineText)) { | ||||
|         if (lineText.length !== 0) { nextLine++; } | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   state.line = nextLine; | ||||
|  | ||||
|   token         = state.push('html_block', '', 0); | ||||
|   token.map     = [ startLine, nextLine ]; | ||||
|   token.content = state.getLines(startLine, nextLine, state.blkIndent, true); | ||||
|  | ||||
|   return true; | ||||
| }; | ||||
							
								
								
									
										83
									
								
								node_modules/markdown-it/lib/rules_block/lheading.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								node_modules/markdown-it/lib/rules_block/lheading.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| // lheading (---, ===) | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| module.exports = function lheading(state, startLine, endLine/*, silent*/) { | ||||
|   var content, terminate, i, l, token, pos, max, level, marker, | ||||
|       nextLine = startLine + 1, oldParentType, | ||||
|       terminatorRules = state.md.block.ruler.getRules('paragraph'); | ||||
|  | ||||
|   // if it's indented more than 3 spaces, it should be a code block | ||||
|   if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } | ||||
|  | ||||
|   oldParentType = state.parentType; | ||||
|   state.parentType = 'paragraph'; // use paragraph to match terminatorRules | ||||
|  | ||||
|   // jump line-by-line until empty one or EOF | ||||
|   for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) { | ||||
|     // this would be a code block normally, but after paragraph | ||||
|     // it's considered a lazy continuation regardless of what's there | ||||
|     if (state.sCount[nextLine] - state.blkIndent > 3) { continue; } | ||||
|  | ||||
|     // | ||||
|     // Check for underline in setext header | ||||
|     // | ||||
|     if (state.sCount[nextLine] >= state.blkIndent) { | ||||
|       pos = state.bMarks[nextLine] + state.tShift[nextLine]; | ||||
|       max = state.eMarks[nextLine]; | ||||
|  | ||||
|       if (pos < max) { | ||||
|         marker = state.src.charCodeAt(pos); | ||||
|  | ||||
|         if (marker === 0x2D/* - */ || marker === 0x3D/* = */) { | ||||
|           pos = state.skipChars(pos, marker); | ||||
|           pos = state.skipSpaces(pos); | ||||
|  | ||||
|           if (pos >= max) { | ||||
|             level = (marker === 0x3D/* = */ ? 1 : 2); | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // quirk for blockquotes, this line should already be checked by that rule | ||||
|     if (state.sCount[nextLine] < 0) { continue; } | ||||
|  | ||||
|     // Some tags can terminate paragraph without empty line. | ||||
|     terminate = false; | ||||
|     for (i = 0, l = terminatorRules.length; i < l; i++) { | ||||
|       if (terminatorRules[i](state, nextLine, endLine, true)) { | ||||
|         terminate = true; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     if (terminate) { break; } | ||||
|   } | ||||
|  | ||||
|   if (!level) { | ||||
|     // Didn't find valid underline | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   content = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); | ||||
|  | ||||
|   state.line = nextLine + 1; | ||||
|  | ||||
|   token          = state.push('heading_open', 'h' + String(level), 1); | ||||
|   token.markup   = String.fromCharCode(marker); | ||||
|   token.map      = [ startLine, state.line ]; | ||||
|  | ||||
|   token          = state.push('inline', '', 0); | ||||
|   token.content  = content; | ||||
|   token.map      = [ startLine, state.line - 1 ]; | ||||
|   token.children = []; | ||||
|  | ||||
|   token          = state.push('heading_close', 'h' + String(level), -1); | ||||
|   token.markup   = String.fromCharCode(marker); | ||||
|  | ||||
|   state.parentType = oldParentType; | ||||
|  | ||||
|   return true; | ||||
| }; | ||||
							
								
								
									
										336
									
								
								node_modules/markdown-it/lib/rules_block/list.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										336
									
								
								node_modules/markdown-it/lib/rules_block/list.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,336 @@ | ||||
| // Lists | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| var isSpace = require('../common/utils').isSpace; | ||||
|  | ||||
|  | ||||
| // Search `[-+*][\n ]`, returns next pos after marker on success | ||||
| // or -1 on fail. | ||||
| function skipBulletListMarker(state, startLine) { | ||||
|   var marker, pos, max, ch; | ||||
|  | ||||
|   pos = state.bMarks[startLine] + state.tShift[startLine]; | ||||
|   max = state.eMarks[startLine]; | ||||
|  | ||||
|   marker = state.src.charCodeAt(pos++); | ||||
|   // Check bullet | ||||
|   if (marker !== 0x2A/* * */ && | ||||
|       marker !== 0x2D/* - */ && | ||||
|       marker !== 0x2B/* + */) { | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   if (pos < max) { | ||||
|     ch = state.src.charCodeAt(pos); | ||||
|  | ||||
|     if (!isSpace(ch)) { | ||||
|       // " -test " - is not a list item | ||||
|       return -1; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return pos; | ||||
| } | ||||
|  | ||||
| // Search `\d+[.)][\n ]`, returns next pos after marker on success | ||||
| // or -1 on fail. | ||||
| function skipOrderedListMarker(state, startLine) { | ||||
|   var ch, | ||||
|       start = state.bMarks[startLine] + state.tShift[startLine], | ||||
|       pos = start, | ||||
|       max = state.eMarks[startLine]; | ||||
|  | ||||
|   // List marker should have at least 2 chars (digit + dot) | ||||
|   if (pos + 1 >= max) { return -1; } | ||||
|  | ||||
|   ch = state.src.charCodeAt(pos++); | ||||
|  | ||||
|   if (ch < 0x30/* 0 */ || ch > 0x39/* 9 */) { return -1; } | ||||
|  | ||||
|   for (;;) { | ||||
|     // EOL -> fail | ||||
|     if (pos >= max) { return -1; } | ||||
|  | ||||
|     ch = state.src.charCodeAt(pos++); | ||||
|  | ||||
|     if (ch >= 0x30/* 0 */ && ch <= 0x39/* 9 */) { | ||||
|  | ||||
|       // List marker should have no more than 9 digits | ||||
|       // (prevents integer overflow in browsers) | ||||
|       if (pos - start >= 10) { return -1; } | ||||
|  | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     // found valid marker | ||||
|     if (ch === 0x29/* ) */ || ch === 0x2e/* . */) { | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   if (pos < max) { | ||||
|     ch = state.src.charCodeAt(pos); | ||||
|  | ||||
|     if (!isSpace(ch)) { | ||||
|       // " 1.test " - is not a list item | ||||
|       return -1; | ||||
|     } | ||||
|   } | ||||
|   return pos; | ||||
| } | ||||
|  | ||||
| function markTightParagraphs(state, idx) { | ||||
|   var i, l, | ||||
|       level = state.level + 2; | ||||
|  | ||||
|   for (i = idx + 2, l = state.tokens.length - 2; i < l; i++) { | ||||
|     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; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| module.exports = function list(state, startLine, endLine, silent) { | ||||
|   var ch, | ||||
|       contentStart, | ||||
|       i, | ||||
|       indent, | ||||
|       indentAfterMarker, | ||||
|       initial, | ||||
|       isOrdered, | ||||
|       itemLines, | ||||
|       l, | ||||
|       listLines, | ||||
|       listTokIdx, | ||||
|       markerCharCode, | ||||
|       markerValue, | ||||
|       max, | ||||
|       nextLine, | ||||
|       offset, | ||||
|       oldIndent, | ||||
|       oldLIndent, | ||||
|       oldParentType, | ||||
|       oldTShift, | ||||
|       oldTight, | ||||
|       pos, | ||||
|       posAfterMarker, | ||||
|       prevEmptyEnd, | ||||
|       start, | ||||
|       terminate, | ||||
|       terminatorRules, | ||||
|       token, | ||||
|       isTerminatingParagraph = false, | ||||
|       tight = true; | ||||
|  | ||||
|   // if it's indented more than 3 spaces, it should be a code block | ||||
|   if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } | ||||
|  | ||||
|   // limit conditions when list can interrupt | ||||
|   // a paragraph (validation mode only) | ||||
|   if (silent && state.parentType === 'paragraph') { | ||||
|     // Next list item should still terminate previous list item; | ||||
|     // | ||||
|     // This code can fail if plugins use blkIndent as well as lists, | ||||
|     // but I hope the spec gets fixed long before that happens. | ||||
|     // | ||||
|     if (state.tShift[startLine] >= state.blkIndent) { | ||||
|       isTerminatingParagraph = true; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Detect list type and position after marker | ||||
|   if ((posAfterMarker = skipOrderedListMarker(state, startLine)) >= 0) { | ||||
|     isOrdered = true; | ||||
|     start = state.bMarks[startLine] + state.tShift[startLine]; | ||||
|     markerValue = Number(state.src.substr(start, posAfterMarker - start - 1)); | ||||
|  | ||||
|     // If we're starting a new ordered list right after | ||||
|     // a paragraph, it should start with 1. | ||||
|     if (isTerminatingParagraph && markerValue !== 1) return false; | ||||
|  | ||||
|   } else if ((posAfterMarker = skipBulletListMarker(state, startLine)) >= 0) { | ||||
|     isOrdered = false; | ||||
|  | ||||
|   } else { | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   // If we're starting a new unordered list right after | ||||
|   // a paragraph, first line should not be empty. | ||||
|   if (isTerminatingParagraph) { | ||||
|     if (state.skipSpaces(posAfterMarker) >= state.eMarks[startLine]) return false; | ||||
|   } | ||||
|  | ||||
|   // We should terminate list on style change. Remember first one to compare. | ||||
|   markerCharCode = state.src.charCodeAt(posAfterMarker - 1); | ||||
|  | ||||
|   // For validation mode we can terminate immediately | ||||
|   if (silent) { return true; } | ||||
|  | ||||
|   // Start list | ||||
|   listTokIdx = state.tokens.length; | ||||
|  | ||||
|   if (isOrdered) { | ||||
|     token       = state.push('ordered_list_open', 'ol', 1); | ||||
|     if (markerValue !== 1) { | ||||
|       token.attrs = [ [ 'start', markerValue ] ]; | ||||
|     } | ||||
|  | ||||
|   } else { | ||||
|     token       = state.push('bullet_list_open', 'ul', 1); | ||||
|   } | ||||
|  | ||||
|   token.map    = listLines = [ startLine, 0 ]; | ||||
|   token.markup = String.fromCharCode(markerCharCode); | ||||
|  | ||||
|   // | ||||
|   // Iterate list items | ||||
|   // | ||||
|  | ||||
|   nextLine = startLine; | ||||
|   prevEmptyEnd = false; | ||||
|   terminatorRules = state.md.block.ruler.getRules('list'); | ||||
|  | ||||
|   oldParentType = state.parentType; | ||||
|   state.parentType = 'list'; | ||||
|  | ||||
|   while (nextLine < endLine) { | ||||
|     pos = posAfterMarker; | ||||
|     max = state.eMarks[nextLine]; | ||||
|  | ||||
|     initial = offset = state.sCount[nextLine] + posAfterMarker - (state.bMarks[startLine] + state.tShift[startLine]); | ||||
|  | ||||
|     while (pos < max) { | ||||
|       ch = state.src.charCodeAt(pos); | ||||
|  | ||||
|       if (ch === 0x09) { | ||||
|         offset += 4 - (offset + state.bsCount[nextLine]) % 4; | ||||
|       } else if (ch === 0x20) { | ||||
|         offset++; | ||||
|       } else { | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|       pos++; | ||||
|     } | ||||
|  | ||||
|     contentStart = pos; | ||||
|  | ||||
|     if (contentStart >= max) { | ||||
|       // trimming space in "-    \n  3" case, indent is 1 here | ||||
|       indentAfterMarker = 1; | ||||
|     } else { | ||||
|       indentAfterMarker = offset - initial; | ||||
|     } | ||||
|  | ||||
|     // If we have more than 4 spaces, the indent is 1 | ||||
|     // (the rest is just indented code block) | ||||
|     if (indentAfterMarker > 4) { indentAfterMarker = 1; } | ||||
|  | ||||
|     // "  -  test" | ||||
|     //  ^^^^^ - calculating total length of this thing | ||||
|     indent = initial + indentAfterMarker; | ||||
|  | ||||
|     // Run subparser & write tokens | ||||
|     token        = state.push('list_item_open', 'li', 1); | ||||
|     token.markup = String.fromCharCode(markerCharCode); | ||||
|     token.map    = itemLines = [ startLine, 0 ]; | ||||
|  | ||||
|     oldIndent = state.blkIndent; | ||||
|     oldTight = state.tight; | ||||
|     oldTShift = state.tShift[startLine]; | ||||
|     oldLIndent = state.sCount[startLine]; | ||||
|     state.blkIndent = indent; | ||||
|     state.tight = true; | ||||
|     state.tShift[startLine] = contentStart - state.bMarks[startLine]; | ||||
|     state.sCount[startLine] = offset; | ||||
|  | ||||
|     if (contentStart >= max && state.isEmpty(startLine + 1)) { | ||||
|       // workaround for this case | ||||
|       // (list item is empty, list terminates before "foo"): | ||||
|       // ~~~~~~~~ | ||||
|       //   - | ||||
|       // | ||||
|       //     foo | ||||
|       // ~~~~~~~~ | ||||
|       state.line = Math.min(state.line + 2, endLine); | ||||
|     } else { | ||||
|       state.md.block.tokenize(state, startLine, endLine, true); | ||||
|     } | ||||
|  | ||||
|     // If any of list item is tight, mark list as tight | ||||
|     if (!state.tight || prevEmptyEnd) { | ||||
|       tight = false; | ||||
|     } | ||||
|     // Item become loose if finish with empty line, | ||||
|     // but we should filter last element, because it means list finish | ||||
|     prevEmptyEnd = (state.line - startLine) > 1 && state.isEmpty(state.line - 1); | ||||
|  | ||||
|     state.blkIndent = oldIndent; | ||||
|     state.tShift[startLine] = oldTShift; | ||||
|     state.sCount[startLine] = oldLIndent; | ||||
|     state.tight = oldTight; | ||||
|  | ||||
|     token        = state.push('list_item_close', 'li', -1); | ||||
|     token.markup = String.fromCharCode(markerCharCode); | ||||
|  | ||||
|     nextLine = startLine = state.line; | ||||
|     itemLines[1] = nextLine; | ||||
|     contentStart = state.bMarks[startLine]; | ||||
|  | ||||
|     if (nextLine >= endLine) { break; } | ||||
|  | ||||
|     // | ||||
|     // Try to check if list is terminated or continued. | ||||
|     // | ||||
|     if (state.sCount[nextLine] < state.blkIndent) { break; } | ||||
|  | ||||
|     // fail if terminating block found | ||||
|     terminate = false; | ||||
|     for (i = 0, l = terminatorRules.length; i < l; i++) { | ||||
|       if (terminatorRules[i](state, nextLine, endLine, true)) { | ||||
|         terminate = true; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     if (terminate) { break; } | ||||
|  | ||||
|     // fail if list has another type | ||||
|     if (isOrdered) { | ||||
|       posAfterMarker = skipOrderedListMarker(state, nextLine); | ||||
|       if (posAfterMarker < 0) { break; } | ||||
|     } else { | ||||
|       posAfterMarker = skipBulletListMarker(state, nextLine); | ||||
|       if (posAfterMarker < 0) { break; } | ||||
|     } | ||||
|  | ||||
|     if (markerCharCode !== state.src.charCodeAt(posAfterMarker - 1)) { break; } | ||||
|   } | ||||
|  | ||||
|   // Finalize list | ||||
|   if (isOrdered) { | ||||
|     token = state.push('ordered_list_close', 'ol', -1); | ||||
|   } else { | ||||
|     token = state.push('bullet_list_close', 'ul', -1); | ||||
|   } | ||||
|   token.markup = String.fromCharCode(markerCharCode); | ||||
|  | ||||
|   listLines[1] = nextLine; | ||||
|   state.line = nextLine; | ||||
|  | ||||
|   state.parentType = oldParentType; | ||||
|  | ||||
|   // mark paragraphs tight if needed | ||||
|   if (tight) { | ||||
|     markTightParagraphs(state, listTokIdx); | ||||
|   } | ||||
|  | ||||
|   return true; | ||||
| }; | ||||
							
								
								
									
										52
									
								
								node_modules/markdown-it/lib/rules_block/paragraph.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								node_modules/markdown-it/lib/rules_block/paragraph.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| // Paragraph | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| module.exports = function paragraph(state, startLine/*, endLine*/) { | ||||
|   var content, terminate, i, l, token, oldParentType, | ||||
|       nextLine = startLine + 1, | ||||
|       terminatorRules = state.md.block.ruler.getRules('paragraph'), | ||||
|       endLine = state.lineMax; | ||||
|  | ||||
|   oldParentType = state.parentType; | ||||
|   state.parentType = 'paragraph'; | ||||
|  | ||||
|   // jump line-by-line until empty one or EOF | ||||
|   for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) { | ||||
|     // this would be a code block normally, but after paragraph | ||||
|     // it's considered a lazy continuation regardless of what's there | ||||
|     if (state.sCount[nextLine] - state.blkIndent > 3) { continue; } | ||||
|  | ||||
|     // quirk for blockquotes, this line should already be checked by that rule | ||||
|     if (state.sCount[nextLine] < 0) { continue; } | ||||
|  | ||||
|     // Some tags can terminate paragraph without empty line. | ||||
|     terminate = false; | ||||
|     for (i = 0, l = terminatorRules.length; i < l; i++) { | ||||
|       if (terminatorRules[i](state, nextLine, endLine, true)) { | ||||
|         terminate = true; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     if (terminate) { break; } | ||||
|   } | ||||
|  | ||||
|   content = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); | ||||
|  | ||||
|   state.line = nextLine; | ||||
|  | ||||
|   token          = state.push('paragraph_open', 'p', 1); | ||||
|   token.map      = [ startLine, state.line ]; | ||||
|  | ||||
|   token          = state.push('inline', '', 0); | ||||
|   token.content  = content; | ||||
|   token.map      = [ startLine, state.line ]; | ||||
|   token.children = []; | ||||
|  | ||||
|   token          = state.push('paragraph_close', 'p', -1); | ||||
|  | ||||
|   state.parentType = oldParentType; | ||||
|  | ||||
|   return true; | ||||
| }; | ||||
							
								
								
									
										198
									
								
								node_modules/markdown-it/lib/rules_block/reference.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								node_modules/markdown-it/lib/rules_block/reference.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,198 @@ | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| var normalizeReference   = require('../common/utils').normalizeReference; | ||||
| var isSpace              = require('../common/utils').isSpace; | ||||
|  | ||||
|  | ||||
| module.exports = function reference(state, startLine, _endLine, silent) { | ||||
|   var ch, | ||||
|       destEndPos, | ||||
|       destEndLineNo, | ||||
|       endLine, | ||||
|       href, | ||||
|       i, | ||||
|       l, | ||||
|       label, | ||||
|       labelEnd, | ||||
|       oldParentType, | ||||
|       res, | ||||
|       start, | ||||
|       str, | ||||
|       terminate, | ||||
|       terminatorRules, | ||||
|       title, | ||||
|       lines = 0, | ||||
|       pos = state.bMarks[startLine] + state.tShift[startLine], | ||||
|       max = state.eMarks[startLine], | ||||
|       nextLine = startLine + 1; | ||||
|  | ||||
|   // if it's indented more than 3 spaces, it should be a code block | ||||
|   if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } | ||||
|  | ||||
|   if (state.src.charCodeAt(pos) !== 0x5B/* [ */) { return false; } | ||||
|  | ||||
|   // Simple check to quickly interrupt scan on [link](url) at the start of line. | ||||
|   // Can be useful on practice: https://github.com/markdown-it/markdown-it/issues/54 | ||||
|   while (++pos < max) { | ||||
|     if (state.src.charCodeAt(pos) === 0x5D /* ] */ && | ||||
|         state.src.charCodeAt(pos - 1) !== 0x5C/* \ */) { | ||||
|       if (pos + 1 === max) { return false; } | ||||
|       if (state.src.charCodeAt(pos + 1) !== 0x3A/* : */) { return false; } | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   endLine = state.lineMax; | ||||
|  | ||||
|   // jump line-by-line until empty one or EOF | ||||
|   terminatorRules = state.md.block.ruler.getRules('reference'); | ||||
|  | ||||
|   oldParentType = state.parentType; | ||||
|   state.parentType = 'reference'; | ||||
|  | ||||
|   for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) { | ||||
|     // this would be a code block normally, but after paragraph | ||||
|     // it's considered a lazy continuation regardless of what's there | ||||
|     if (state.sCount[nextLine] - state.blkIndent > 3) { continue; } | ||||
|  | ||||
|     // quirk for blockquotes, this line should already be checked by that rule | ||||
|     if (state.sCount[nextLine] < 0) { continue; } | ||||
|  | ||||
|     // Some tags can terminate paragraph without empty line. | ||||
|     terminate = false; | ||||
|     for (i = 0, l = terminatorRules.length; i < l; i++) { | ||||
|       if (terminatorRules[i](state, nextLine, endLine, true)) { | ||||
|         terminate = true; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     if (terminate) { break; } | ||||
|   } | ||||
|  | ||||
|   str = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); | ||||
|   max = str.length; | ||||
|  | ||||
|   for (pos = 1; pos < max; pos++) { | ||||
|     ch = str.charCodeAt(pos); | ||||
|     if (ch === 0x5B /* [ */) { | ||||
|       return false; | ||||
|     } else if (ch === 0x5D /* ] */) { | ||||
|       labelEnd = pos; | ||||
|       break; | ||||
|     } else if (ch === 0x0A /* \n */) { | ||||
|       lines++; | ||||
|     } else if (ch === 0x5C /* \ */) { | ||||
|       pos++; | ||||
|       if (pos < max && str.charCodeAt(pos) === 0x0A) { | ||||
|         lines++; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return false; } | ||||
|  | ||||
|   // [label]:   destination   'title' | ||||
|   //         ^^^ skip optional whitespace here | ||||
|   for (pos = labelEnd + 2; pos < max; pos++) { | ||||
|     ch = str.charCodeAt(pos); | ||||
|     if (ch === 0x0A) { | ||||
|       lines++; | ||||
|     } else if (isSpace(ch)) { | ||||
|       /*eslint no-empty:0*/ | ||||
|     } else { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // [label]:   destination   'title' | ||||
|   //            ^^^^^^^^^^^ parse this | ||||
|   res = state.md.helpers.parseLinkDestination(str, pos, max); | ||||
|   if (!res.ok) { return false; } | ||||
|  | ||||
|   href = state.md.normalizeLink(res.str); | ||||
|   if (!state.md.validateLink(href)) { return false; } | ||||
|  | ||||
|   pos = res.pos; | ||||
|   lines += res.lines; | ||||
|  | ||||
|   // save cursor state, we could require to rollback later | ||||
|   destEndPos = pos; | ||||
|   destEndLineNo = lines; | ||||
|  | ||||
|   // [label]:   destination   'title' | ||||
|   //                       ^^^ skipping those spaces | ||||
|   start = pos; | ||||
|   for (; pos < max; pos++) { | ||||
|     ch = str.charCodeAt(pos); | ||||
|     if (ch === 0x0A) { | ||||
|       lines++; | ||||
|     } else if (isSpace(ch)) { | ||||
|       /*eslint no-empty:0*/ | ||||
|     } else { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // [label]:   destination   'title' | ||||
|   //                          ^^^^^^^ parse this | ||||
|   res = state.md.helpers.parseLinkTitle(str, pos, max); | ||||
|   if (pos < max && start !== pos && res.ok) { | ||||
|     title = res.str; | ||||
|     pos = res.pos; | ||||
|     lines += res.lines; | ||||
|   } else { | ||||
|     title = ''; | ||||
|     pos = destEndPos; | ||||
|     lines = destEndLineNo; | ||||
|   } | ||||
|  | ||||
|   // skip trailing spaces until the rest of the line | ||||
|   while (pos < max) { | ||||
|     ch = str.charCodeAt(pos); | ||||
|     if (!isSpace(ch)) { break; } | ||||
|     pos++; | ||||
|   } | ||||
|  | ||||
|   if (pos < max && str.charCodeAt(pos) !== 0x0A) { | ||||
|     if (title) { | ||||
|       // garbage at the end of the line after title, | ||||
|       // but it could still be a valid reference if we roll back | ||||
|       title = ''; | ||||
|       pos = destEndPos; | ||||
|       lines = destEndLineNo; | ||||
|       while (pos < max) { | ||||
|         ch = str.charCodeAt(pos); | ||||
|         if (!isSpace(ch)) { break; } | ||||
|         pos++; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (pos < max && str.charCodeAt(pos) !== 0x0A) { | ||||
|     // garbage at the end of the line | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   label = normalizeReference(str.slice(1, labelEnd)); | ||||
|   if (!label) { | ||||
|     // CommonMark 0.20 disallows empty labels | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   // Reference can not terminate anything. This check is for safety only. | ||||
|   /*istanbul ignore if*/ | ||||
|   if (silent) { return true; } | ||||
|  | ||||
|   if (typeof state.env.references === 'undefined') { | ||||
|     state.env.references = {}; | ||||
|   } | ||||
|   if (typeof state.env.references[label] === 'undefined') { | ||||
|     state.env.references[label] = { title: title, href: href }; | ||||
|   } | ||||
|  | ||||
|   state.parentType = oldParentType; | ||||
|  | ||||
|   state.line = startLine + lines + 1; | ||||
|   return true; | ||||
| }; | ||||
							
								
								
									
										230
									
								
								node_modules/markdown-it/lib/rules_block/state_block.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								node_modules/markdown-it/lib/rules_block/state_block.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,230 @@ | ||||
| // Parser state class | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| var Token = require('../token'); | ||||
| var isSpace = require('../common/utils').isSpace; | ||||
|  | ||||
|  | ||||
| function StateBlock(src, md, env, tokens) { | ||||
|   var ch, s, start, pos, len, indent, offset, indent_found; | ||||
|  | ||||
|   this.src = src; | ||||
|  | ||||
|   // link to parser instance | ||||
|   this.md     = md; | ||||
|  | ||||
|   this.env = env; | ||||
|  | ||||
|   // | ||||
|   // Internal state vartiables | ||||
|   // | ||||
|  | ||||
|   this.tokens = tokens; | ||||
|  | ||||
|   this.bMarks = [];  // line begin offsets for fast jumps | ||||
|   this.eMarks = [];  // line end offsets for fast jumps | ||||
|   this.tShift = [];  // offsets of the first non-space characters (tabs not expanded) | ||||
|   this.sCount = [];  // indents for each line (tabs expanded) | ||||
|  | ||||
|   // An amount of virtual spaces (tabs expanded) between beginning | ||||
|   // of each line (bMarks) and real beginning of that line. | ||||
|   // | ||||
|   // It exists only as a hack because blockquotes override bMarks | ||||
|   // losing information in the process. | ||||
|   // | ||||
|   // It's used only when expanding tabs, you can think about it as | ||||
|   // an initial tab length, e.g. bsCount=21 applied to string `\t123` | ||||
|   // means first tab should be expanded to 4-21%4 === 3 spaces. | ||||
|   // | ||||
|   this.bsCount = []; | ||||
|  | ||||
|   // block parser variables | ||||
|   this.blkIndent  = 0; // required block content indent | ||||
|                        // (for example, if we are in list) | ||||
|   this.line       = 0; // line index in src | ||||
|   this.lineMax    = 0; // lines count | ||||
|   this.tight      = false;  // loose/tight mode for lists | ||||
|   this.ddIndent   = -1; // indent of the current dd block (-1 if there isn't any) | ||||
|  | ||||
|   // can be 'blockquote', 'list', 'root', 'paragraph' or 'reference' | ||||
|   // used in lists to determine if they interrupt a paragraph | ||||
|   this.parentType = 'root'; | ||||
|  | ||||
|   this.level = 0; | ||||
|  | ||||
|   // renderer | ||||
|   this.result = ''; | ||||
|  | ||||
|   // Create caches | ||||
|   // Generate markers. | ||||
|   s = this.src; | ||||
|   indent_found = false; | ||||
|  | ||||
|   for (start = pos = indent = offset = 0, len = s.length; pos < len; pos++) { | ||||
|     ch = s.charCodeAt(pos); | ||||
|  | ||||
|     if (!indent_found) { | ||||
|       if (isSpace(ch)) { | ||||
|         indent++; | ||||
|  | ||||
|         if (ch === 0x09) { | ||||
|           offset += 4 - offset % 4; | ||||
|         } else { | ||||
|           offset++; | ||||
|         } | ||||
|         continue; | ||||
|       } else { | ||||
|         indent_found = true; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (ch === 0x0A || pos === len - 1) { | ||||
|       if (ch !== 0x0A) { pos++; } | ||||
|       this.bMarks.push(start); | ||||
|       this.eMarks.push(pos); | ||||
|       this.tShift.push(indent); | ||||
|       this.sCount.push(offset); | ||||
|       this.bsCount.push(0); | ||||
|  | ||||
|       indent_found = false; | ||||
|       indent = 0; | ||||
|       offset = 0; | ||||
|       start = pos + 1; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Push fake entry to simplify cache bounds checks | ||||
|   this.bMarks.push(s.length); | ||||
|   this.eMarks.push(s.length); | ||||
|   this.tShift.push(0); | ||||
|   this.sCount.push(0); | ||||
|   this.bsCount.push(0); | ||||
|  | ||||
|   this.lineMax = this.bMarks.length - 1; // don't count last fake line | ||||
| } | ||||
|  | ||||
| // Push new token to "stream". | ||||
| // | ||||
| StateBlock.prototype.push = function (type, tag, nesting) { | ||||
|   var token = new Token(type, tag, nesting); | ||||
|   token.block = true; | ||||
|  | ||||
|   if (nesting < 0) { this.level--; } | ||||
|   token.level = this.level; | ||||
|   if (nesting > 0) { this.level++; } | ||||
|  | ||||
|   this.tokens.push(token); | ||||
|   return token; | ||||
| }; | ||||
|  | ||||
| StateBlock.prototype.isEmpty = function isEmpty(line) { | ||||
|   return this.bMarks[line] + this.tShift[line] >= this.eMarks[line]; | ||||
| }; | ||||
|  | ||||
| StateBlock.prototype.skipEmptyLines = function skipEmptyLines(from) { | ||||
|   for (var max = this.lineMax; from < max; from++) { | ||||
|     if (this.bMarks[from] + this.tShift[from] < this.eMarks[from]) { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|   return from; | ||||
| }; | ||||
|  | ||||
| // Skip spaces from given position. | ||||
| StateBlock.prototype.skipSpaces = function skipSpaces(pos) { | ||||
|   var ch; | ||||
|  | ||||
|   for (var max = this.src.length; pos < max; pos++) { | ||||
|     ch = this.src.charCodeAt(pos); | ||||
|     if (!isSpace(ch)) { break; } | ||||
|   } | ||||
|   return pos; | ||||
| }; | ||||
|  | ||||
| // Skip spaces from given position in reverse. | ||||
| StateBlock.prototype.skipSpacesBack = function skipSpacesBack(pos, min) { | ||||
|   if (pos <= min) { return pos; } | ||||
|  | ||||
|   while (pos > min) { | ||||
|     if (!isSpace(this.src.charCodeAt(--pos))) { return pos + 1; } | ||||
|   } | ||||
|   return pos; | ||||
| }; | ||||
|  | ||||
| // Skip char codes from given position | ||||
| StateBlock.prototype.skipChars = function skipChars(pos, code) { | ||||
|   for (var max = this.src.length; pos < max; pos++) { | ||||
|     if (this.src.charCodeAt(pos) !== code) { break; } | ||||
|   } | ||||
|   return pos; | ||||
| }; | ||||
|  | ||||
| // Skip char codes reverse from given position - 1 | ||||
| StateBlock.prototype.skipCharsBack = function skipCharsBack(pos, code, min) { | ||||
|   if (pos <= min) { return pos; } | ||||
|  | ||||
|   while (pos > min) { | ||||
|     if (code !== this.src.charCodeAt(--pos)) { return pos + 1; } | ||||
|   } | ||||
|   return pos; | ||||
| }; | ||||
|  | ||||
| // cut lines range from source. | ||||
| StateBlock.prototype.getLines = function getLines(begin, end, indent, keepLastLF) { | ||||
|   var i, lineIndent, ch, first, last, queue, lineStart, | ||||
|       line = begin; | ||||
|  | ||||
|   if (begin >= end) { | ||||
|     return ''; | ||||
|   } | ||||
|  | ||||
|   queue = new Array(end - begin); | ||||
|  | ||||
|   for (i = 0; line < end; line++, i++) { | ||||
|     lineIndent = 0; | ||||
|     lineStart = first = this.bMarks[line]; | ||||
|  | ||||
|     if (line + 1 < end || keepLastLF) { | ||||
|       // No need for bounds check because we have fake entry on tail. | ||||
|       last = this.eMarks[line] + 1; | ||||
|     } else { | ||||
|       last = this.eMarks[line]; | ||||
|     } | ||||
|  | ||||
|     while (first < last && lineIndent < indent) { | ||||
|       ch = this.src.charCodeAt(first); | ||||
|  | ||||
|       if (isSpace(ch)) { | ||||
|         if (ch === 0x09) { | ||||
|           lineIndent += 4 - (lineIndent + this.bsCount[line]) % 4; | ||||
|         } else { | ||||
|           lineIndent++; | ||||
|         } | ||||
|       } else if (first - lineStart < this.tShift[line]) { | ||||
|         // patched tShift masked characters to look like spaces (blockquotes, list markers) | ||||
|         lineIndent++; | ||||
|       } else { | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|       first++; | ||||
|     } | ||||
|  | ||||
|     if (lineIndent > indent) { | ||||
|       // partially expanding tabs in code blocks, e.g '\t\tfoobar' | ||||
|       // with indent=2 becomes '  \tfoobar' | ||||
|       queue[i] = new Array(lineIndent - indent + 1).join(' ') + this.src.slice(first, last); | ||||
|     } else { | ||||
|       queue[i] = this.src.slice(first, last); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return queue.join(''); | ||||
| }; | ||||
|  | ||||
| // re-export Token class to use in block rules | ||||
| StateBlock.prototype.Token = Token; | ||||
|  | ||||
|  | ||||
| module.exports = StateBlock; | ||||
							
								
								
									
										196
									
								
								node_modules/markdown-it/lib/rules_block/table.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								node_modules/markdown-it/lib/rules_block/table.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,196 @@ | ||||
| // GFM table, non-standard | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| var isSpace = require('../common/utils').isSpace; | ||||
|  | ||||
|  | ||||
| function getLine(state, line) { | ||||
|   var pos = state.bMarks[line] + state.blkIndent, | ||||
|       max = state.eMarks[line]; | ||||
|  | ||||
|   return state.src.substr(pos, max - pos); | ||||
| } | ||||
|  | ||||
| function escapedSplit(str) { | ||||
|   var result = [], | ||||
|       pos = 0, | ||||
|       max = str.length, | ||||
|       ch, | ||||
|       escapes = 0, | ||||
|       lastPos = 0, | ||||
|       backTicked = false, | ||||
|       lastBackTick = 0; | ||||
|  | ||||
|   ch  = str.charCodeAt(pos); | ||||
|  | ||||
|   while (pos < max) { | ||||
|     if (ch === 0x60/* ` */) { | ||||
|       if (backTicked) { | ||||
|         // make \` close code sequence, but not open it; | ||||
|         // the reason is: `\` is correct code block | ||||
|         backTicked = false; | ||||
|         lastBackTick = pos; | ||||
|       } else if (escapes % 2 === 0) { | ||||
|         backTicked = true; | ||||
|         lastBackTick = pos; | ||||
|       } | ||||
|     } else if (ch === 0x7c/* | */ && (escapes % 2 === 0) && !backTicked) { | ||||
|       result.push(str.substring(lastPos, pos)); | ||||
|       lastPos = pos + 1; | ||||
|     } | ||||
|  | ||||
|     if (ch === 0x5c/* \ */) { | ||||
|       escapes++; | ||||
|     } else { | ||||
|       escapes = 0; | ||||
|     } | ||||
|  | ||||
|     pos++; | ||||
|  | ||||
|     // If there was an un-closed backtick, go back to just after | ||||
|     // the last backtick, but as if it was a normal character | ||||
|     if (pos === max && backTicked) { | ||||
|       backTicked = false; | ||||
|       pos = lastBackTick + 1; | ||||
|     } | ||||
|  | ||||
|     ch = str.charCodeAt(pos); | ||||
|   } | ||||
|  | ||||
|   result.push(str.substring(lastPos)); | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| module.exports = function table(state, startLine, endLine, silent) { | ||||
|   var ch, lineText, pos, i, nextLine, columns, columnCount, token, | ||||
|       aligns, t, tableLines, tbodyLines; | ||||
|  | ||||
|   // should have at least two lines | ||||
|   if (startLine + 2 > endLine) { return false; } | ||||
|  | ||||
|   nextLine = startLine + 1; | ||||
|  | ||||
|   if (state.sCount[nextLine] < state.blkIndent) { return false; } | ||||
|  | ||||
|   // if it's indented more than 3 spaces, it should be a code block | ||||
|   if (state.sCount[nextLine] - state.blkIndent >= 4) { return false; } | ||||
|  | ||||
|   // first character of the second line should be '|', '-', ':', | ||||
|   // and no other characters are allowed but spaces; | ||||
|   // basically, this is the equivalent of /^[-:|][-:|\s]*$/ regexp | ||||
|  | ||||
|   pos = state.bMarks[nextLine] + state.tShift[nextLine]; | ||||
|   if (pos >= state.eMarks[nextLine]) { return false; } | ||||
|  | ||||
|   ch = state.src.charCodeAt(pos++); | ||||
|   if (ch !== 0x7C/* | */ && ch !== 0x2D/* - */ && ch !== 0x3A/* : */) { return false; } | ||||
|  | ||||
|   while (pos < state.eMarks[nextLine]) { | ||||
|     ch = state.src.charCodeAt(pos); | ||||
|  | ||||
|     if (ch !== 0x7C/* | */ && ch !== 0x2D/* - */ && ch !== 0x3A/* : */ && !isSpace(ch)) { return false; } | ||||
|  | ||||
|     pos++; | ||||
|   } | ||||
|  | ||||
|   lineText = getLine(state, startLine + 1); | ||||
|  | ||||
|   columns = lineText.split('|'); | ||||
|   aligns = []; | ||||
|   for (i = 0; i < columns.length; i++) { | ||||
|     t = columns[i].trim(); | ||||
|     if (!t) { | ||||
|       // allow empty columns before and after table, but not in between columns; | ||||
|       // e.g. allow ` |---| `, disallow ` ---||--- ` | ||||
|       if (i === 0 || i === columns.length - 1) { | ||||
|         continue; | ||||
|       } else { | ||||
|         return false; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (!/^:?-+:?$/.test(t)) { return false; } | ||||
|     if (t.charCodeAt(t.length - 1) === 0x3A/* : */) { | ||||
|       aligns.push(t.charCodeAt(0) === 0x3A/* : */ ? 'center' : 'right'); | ||||
|     } else if (t.charCodeAt(0) === 0x3A/* : */) { | ||||
|       aligns.push('left'); | ||||
|     } else { | ||||
|       aligns.push(''); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   lineText = getLine(state, startLine).trim(); | ||||
|   if (lineText.indexOf('|') === -1) { return false; } | ||||
|   if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } | ||||
|   columns = escapedSplit(lineText.replace(/^\||\|$/g, '')); | ||||
|  | ||||
|   // header row will define an amount of columns in the entire table, | ||||
|   // and align row shouldn't be smaller than that (the rest of the rows can) | ||||
|   columnCount = columns.length; | ||||
|   if (columnCount > aligns.length) { return false; } | ||||
|  | ||||
|   if (silent) { return true; } | ||||
|  | ||||
|   token     = state.push('table_open', 'table', 1); | ||||
|   token.map = tableLines = [ startLine, 0 ]; | ||||
|  | ||||
|   token     = state.push('thead_open', 'thead', 1); | ||||
|   token.map = [ startLine, startLine + 1 ]; | ||||
|  | ||||
|   token     = state.push('tr_open', 'tr', 1); | ||||
|   token.map = [ startLine, startLine + 1 ]; | ||||
|  | ||||
|   for (i = 0; i < columns.length; i++) { | ||||
|     token          = state.push('th_open', 'th', 1); | ||||
|     token.map      = [ startLine, startLine + 1 ]; | ||||
|     if (aligns[i]) { | ||||
|       token.attrs  = [ [ 'style', 'text-align:' + aligns[i] ] ]; | ||||
|     } | ||||
|  | ||||
|     token          = state.push('inline', '', 0); | ||||
|     token.content  = columns[i].trim(); | ||||
|     token.map      = [ startLine, startLine + 1 ]; | ||||
|     token.children = []; | ||||
|  | ||||
|     token          = state.push('th_close', 'th', -1); | ||||
|   } | ||||
|  | ||||
|   token     = state.push('tr_close', 'tr', -1); | ||||
|   token     = state.push('thead_close', 'thead', -1); | ||||
|  | ||||
|   token     = state.push('tbody_open', 'tbody', 1); | ||||
|   token.map = tbodyLines = [ startLine + 2, 0 ]; | ||||
|  | ||||
|   for (nextLine = startLine + 2; nextLine < endLine; nextLine++) { | ||||
|     if (state.sCount[nextLine] < state.blkIndent) { break; } | ||||
|  | ||||
|     lineText = getLine(state, nextLine).trim(); | ||||
|     if (lineText.indexOf('|') === -1) { break; } | ||||
|     if (state.sCount[nextLine] - state.blkIndent >= 4) { break; } | ||||
|     columns = escapedSplit(lineText.replace(/^\||\|$/g, '')); | ||||
|  | ||||
|     token = state.push('tr_open', 'tr', 1); | ||||
|     for (i = 0; i < columnCount; i++) { | ||||
|       token          = state.push('td_open', 'td', 1); | ||||
|       if (aligns[i]) { | ||||
|         token.attrs  = [ [ 'style', 'text-align:' + aligns[i] ] ]; | ||||
|       } | ||||
|  | ||||
|       token          = state.push('inline', '', 0); | ||||
|       token.content  = columns[i] ? columns[i].trim() : ''; | ||||
|       token.children = []; | ||||
|  | ||||
|       token          = state.push('td_close', 'td', -1); | ||||
|     } | ||||
|     token = state.push('tr_close', 'tr', -1); | ||||
|   } | ||||
|   token = state.push('tbody_close', 'tbody', -1); | ||||
|   token = state.push('table_close', 'table', -1); | ||||
|  | ||||
|   tableLines[1] = tbodyLines[1] = nextLine; | ||||
|   state.line = nextLine; | ||||
|   return true; | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user
	 tatianamac
					tatianamac