.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / markdown-table / index.js
1 'use strict'
2
3 module.exports = markdownTable
4
5 var dotRe = /\./
6 var lastDotRe = /\.[^.]*$/
7
8 // Characters.
9 var space = ' '
10 var lineFeed = '\n'
11 var dash = '-'
12 var dot = '.'
13 var colon = ':'
14 var lowercaseC = 'c'
15 var lowercaseL = 'l'
16 var lowercaseR = 'r'
17 var verticalBar = '|'
18
19 var minCellSize = 3
20
21 // Create a table from a matrix of strings.
22 function markdownTable(table, options) {
23   var settings = options || {}
24   var delimiter = settings.delimiter
25   var start = settings.start
26   var end = settings.end
27   var alignment = settings.align
28   var calculateStringLength = settings.stringLength || lengthNoop
29   var cellCount = 0
30   var rowIndex = -1
31   var rowLength = table.length
32   var sizes = []
33   var align
34   var rule
35   var rows
36   var row
37   var cells
38   var index
39   var position
40   var size
41   var value
42   var spacing
43   var before
44   var after
45
46   alignment = alignment ? alignment.concat() : []
47
48   if (delimiter === null || delimiter === undefined) {
49     delimiter = space + verticalBar + space
50   }
51
52   if (start === null || start === undefined) {
53     start = verticalBar + space
54   }
55
56   if (end === null || end === undefined) {
57     end = space + verticalBar
58   }
59
60   while (++rowIndex < rowLength) {
61     row = table[rowIndex]
62
63     index = -1
64
65     if (row.length > cellCount) {
66       cellCount = row.length
67     }
68
69     while (++index < cellCount) {
70       position = row[index] ? dotindex(row[index]) : null
71
72       if (!sizes[index]) {
73         sizes[index] = minCellSize
74       }
75
76       if (position > sizes[index]) {
77         sizes[index] = position
78       }
79     }
80   }
81
82   if (typeof alignment === 'string') {
83     alignment = pad(cellCount, alignment).split('')
84   }
85
86   // Make sure only valid alignments are used.
87   index = -1
88
89   while (++index < cellCount) {
90     align = alignment[index]
91
92     if (typeof align === 'string') {
93       align = align.charAt(0).toLowerCase()
94     }
95
96     if (
97       align !== lowercaseL &&
98       align !== lowercaseR &&
99       align !== lowercaseC &&
100       align !== dot
101     ) {
102       align = ''
103     }
104
105     alignment[index] = align
106   }
107
108   rowIndex = -1
109   rows = []
110
111   while (++rowIndex < rowLength) {
112     row = table[rowIndex]
113
114     index = -1
115     cells = []
116
117     while (++index < cellCount) {
118       value = row[index]
119
120       value = stringify(value)
121
122       if (alignment[index] === dot) {
123         position = dotindex(value)
124
125         size =
126           sizes[index] +
127           (dotRe.test(value) ? 0 : 1) -
128           (calculateStringLength(value) - position)
129
130         cells[index] = value + pad(size - 1)
131       } else {
132         cells[index] = value
133       }
134     }
135
136     rows[rowIndex] = cells
137   }
138
139   sizes = []
140   rowIndex = -1
141
142   while (++rowIndex < rowLength) {
143     cells = rows[rowIndex]
144
145     index = -1
146
147     while (++index < cellCount) {
148       value = cells[index]
149
150       if (!sizes[index]) {
151         sizes[index] = minCellSize
152       }
153
154       size = calculateStringLength(value)
155
156       if (size > sizes[index]) {
157         sizes[index] = size
158       }
159     }
160   }
161
162   rowIndex = -1
163
164   while (++rowIndex < rowLength) {
165     cells = rows[rowIndex]
166
167     index = -1
168
169     if (settings.pad !== false) {
170       while (++index < cellCount) {
171         value = cells[index]
172
173         position = sizes[index] - (calculateStringLength(value) || 0)
174         spacing = pad(position)
175
176         if (alignment[index] === lowercaseR || alignment[index] === dot) {
177           value = spacing + value
178         } else if (alignment[index] === lowercaseC) {
179           position /= 2
180
181           if (position % 1 === 0) {
182             before = position
183             after = position
184           } else {
185             before = position + 0.5
186             after = position - 0.5
187           }
188
189           value = pad(before) + value + pad(after)
190         } else {
191           value += spacing
192         }
193
194         cells[index] = value
195       }
196     }
197
198     rows[rowIndex] = cells.join(delimiter)
199   }
200
201   if (settings.rule !== false) {
202     index = -1
203     rule = []
204
205     while (++index < cellCount) {
206       // When `pad` is false, make the rule the same size as the first row.
207       if (settings.pad === false) {
208         value = table[0][index]
209         spacing = calculateStringLength(stringify(value))
210         spacing = spacing > minCellSize ? spacing : minCellSize
211       } else {
212         spacing = sizes[index]
213       }
214
215       align = alignment[index]
216
217       // When `align` is left, don't add colons.
218       value = align === lowercaseR || align === '' ? dash : colon
219       value += pad(spacing - 2, dash)
220       value += align !== lowercaseL && align !== '' ? colon : dash
221
222       rule[index] = value
223     }
224
225     rows.splice(1, 0, rule.join(delimiter))
226   }
227
228   return start + rows.join(end + lineFeed + start) + end
229 }
230
231 function stringify(value) {
232   return value === null || value === undefined ? '' : String(value)
233 }
234
235 // Get the length of `value`.
236 function lengthNoop(value) {
237   return String(value).length
238 }
239
240 // Get a string consisting of `length` `character`s.
241 function pad(length, character) {
242   return new Array(length + 1).join(character || space)
243 }
244
245 // Get the position of the last dot in `value`.
246 function dotindex(value) {
247   var match = lastDotRe.exec(value)
248
249   return match ? match.index + 1 : value.length
250 }