123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- 'use strict'
- var whitespace = require('is-whitespace-character')
- module.exports = table
- var tab = '\t'
- var lineFeed = '\n'
- var space = ' '
- var dash = '-'
- var colon = ':'
- var backslash = '\\'
- var verticalBar = '|'
- var minColumns = 1
- var minRows = 2
- var left = 'left'
- var center = 'center'
- var right = 'right'
- function table(eat, value, silent) {
- var self = this
- var index
- var alignments
- var alignment
- var subvalue
- var row
- var length
- var lines
- var queue
- var character
- var hasDash
- var align
- var cell
- var preamble
- var now
- var position
- var lineCount
- var line
- var rows
- var table
- var lineIndex
- var pipeIndex
- var first
- // Exit when not in gfm-mode.
- if (!self.options.gfm) {
- return
- }
- // Get the rows.
- // Detecting tables soon is hard, so there are some checks for performance
- // here, such as the minimum number of rows, and allowed characters in the
- // alignment row.
- index = 0
- lineCount = 0
- length = value.length + 1
- lines = []
- while (index < length) {
- lineIndex = value.indexOf(lineFeed, index)
- pipeIndex = value.indexOf(verticalBar, index + 1)
- if (lineIndex === -1) {
- lineIndex = value.length
- }
- if (pipeIndex === -1 || pipeIndex > lineIndex) {
- if (lineCount < minRows) {
- return
- }
- break
- }
- lines.push(value.slice(index, lineIndex))
- lineCount++
- index = lineIndex + 1
- }
- // Parse the alignment row.
- subvalue = lines.join(lineFeed)
- alignments = lines.splice(1, 1)[0] || []
- index = 0
- length = alignments.length
- lineCount--
- alignment = false
- align = []
- while (index < length) {
- character = alignments.charAt(index)
- if (character === verticalBar) {
- hasDash = null
- if (alignment === false) {
- if (first === false) {
- return
- }
- } else {
- align.push(alignment)
- alignment = false
- }
- first = false
- } else if (character === dash) {
- hasDash = true
- alignment = alignment || null
- } else if (character === colon) {
- if (alignment === left) {
- alignment = center
- } else if (hasDash && alignment === null) {
- alignment = right
- } else {
- alignment = left
- }
- } else if (!whitespace(character)) {
- return
- }
- index++
- }
- if (alignment !== false) {
- align.push(alignment)
- }
- // Exit when without enough columns.
- if (align.length < minColumns) {
- return
- }
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true
- }
- // Parse the rows.
- position = -1
- rows = []
- table = eat(subvalue).reset({type: 'table', align: align, children: rows})
- while (++position < lineCount) {
- line = lines[position]
- row = {type: 'tableRow', children: []}
- // Eat a newline character when this is not the first row.
- if (position) {
- eat(lineFeed)
- }
- // Eat the row.
- eat(line).reset(row, table)
- length = line.length + 1
- index = 0
- queue = ''
- cell = ''
- preamble = true
- while (index < length) {
- character = line.charAt(index)
- if (character === tab || character === space) {
- if (cell) {
- queue += character
- } else {
- eat(character)
- }
- index++
- continue
- }
- if (character === '' || character === verticalBar) {
- if (preamble) {
- eat(character)
- } else {
- if ((cell || character) && !preamble) {
- subvalue = cell
- if (queue.length > 1) {
- if (character) {
- subvalue += queue.slice(0, -1)
- queue = queue.charAt(queue.length - 1)
- } else {
- subvalue += queue
- queue = ''
- }
- }
- now = eat.now()
- eat(subvalue)(
- {type: 'tableCell', children: self.tokenizeInline(cell, now)},
- row
- )
- }
- eat(queue + character)
- queue = ''
- cell = ''
- }
- } else {
- if (queue) {
- cell += queue
- queue = ''
- }
- cell += character
- if (character === backslash && index !== length - 2) {
- cell += line.charAt(index + 1)
- index++
- }
- }
- preamble = false
- index++
- }
- // Eat the alignment row.
- if (!position) {
- eat(lineFeed + alignments)
- }
- }
- return table
- }
|