UNPKG

10.3 kBJavaScriptView Raw
1/*! markdown-it-multimd-table 1.0.0 https://github.com//markdown-it/markdown-it-multimd-table @license MIT */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.markdownitDeflist = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2// Process definition lists
3//
4'use strict';
5
6module.exports = function multimd_table_plugin(md) {
7 function isFilledArray(array) {
8 return typeof array !== 'undefined' && array.length > 0;
9 }
10
11 function getLine(state, line) {
12 var pos = state.bMarks[line] + state.blkIndent,
13 max = state.eMarks[line];
14
15 return state.src.slice(pos, max);
16 }
17
18 function escapedSplit(str) {
19 var result = [],
20 pos = 0,
21 max = str.length,
22 escapes = 0,
23 lastPos = 0,
24 backTicked = false,
25 lastBackTick = 0;
26
27 while (pos < max) {
28 switch (str.charCodeAt(pos)) {
29 case 0x5c/* \ */:
30 escapes++;
31 break;
32 case 0x60/* ` */:
33 if (backTicked || ((escapes & 1) === 0)) {
34 // make \` close code sequence, but not open it;
35 // the reason is: `\` is correct code block
36 backTicked = !backTicked;
37 lastBackTick = pos;
38 }
39 escapes = 0;
40 break;
41 case 0x7c/* | */:
42 if ((escapes & 1) === 0 && !backTicked) {
43 result.push(str.slice(lastPos, pos));
44 lastPos = pos + 1;
45 }
46 escapes = 0;
47 break;
48 default:
49 escapes = 0;
50 break;
51 }
52
53 pos++;
54
55 // If there was an un-closed backtick, go back to just after
56 // the last backtick, but as if it was a normal character
57 if (pos === max && backTicked) {
58 backTicked = false;
59 pos = lastBackTick + 1;
60 }
61 }
62
63 result.push(str.slice(lastPos));
64
65 return result;
66 }
67
68 function countColspan(columns) {
69 var i, emptyCount, colspans;
70
71 emptyCount = 0;
72 colspans = [];
73 for (i = columns.length - 1; i >= 0; i--) {
74 if (columns[i]) {
75 colspans.unshift(emptyCount + 1);
76 emptyCount = 0;
77 } else {
78 emptyCount++;
79 }
80 }
81 if (emptyCount > 0) {
82 colspans.unshift(emptyCount + 1);
83 }
84
85 return colspans;
86 }
87
88 function table(state, startLine, endLine, silent, captionInfo) {
89 var lineText, i, col, captionLine, headerLine, seperatorLine, nextLine,
90 columns, columnCount, token, aligns, wraps, colspans, t, tableLines,
91 tbodyLines, emptyTableBody;
92
93 // should have at least two lines
94 if (startLine + 2 > endLine) { return false; }
95
96 seperatorLine = startLine + 1;
97 if (state.sCount[seperatorLine] < state.blkIndent) { return false; }
98 // if it's indented more than 3 spaces, it should be a code block
99 if (state.sCount[seperatorLine] - state.blkIndent >= 4) { return false; }
100
101 while (!isFilledArray(aligns)) {
102 lineText = getLine(state, seperatorLine);
103 columns = lineText.split('|');
104 if (columns.length === 1 && !/^\||[^\\]\|$/.test(lineText)) { return false; }
105 aligns = [];
106 wraps = [];
107 for (i = 0; i < columns.length; i++) {
108 t = columns[i].trim();
109 if (!t && (i === 0 || i === columns.length - 1)) {
110 continue;
111 } else if (!/^:?(-+|=+):?\+?$/.test(t)) {
112 // might be another header line, so initialize
113 seperatorLine++;
114 aligns = [];
115 wraps = [];
116 break;
117 }
118
119 // pushed as wraps[i]
120 wraps.push(t.charCodeAt(t.length - 1) === 0x2B/* + */);
121 if (wraps[i]) { t = t.slice(0, -1); }
122
123 switch (((t.charCodeAt(0) === 0x3A/* : */) << 4) +
124 (t.charCodeAt(t.length - 1) === 0x3A/* : */)) {
125 case 0x00: aligns.push(''); break;
126 case 0x01: aligns.push('right'); break;
127 case 0x10: aligns.push('left'); break;
128 case 0x11: aligns.push('center'); break;
129 }
130 }
131 }
132
133 for (headerLine = startLine; headerLine < seperatorLine; headerLine++) {
134 lineText = getLine(state, headerLine).trim();
135 if (lineText.indexOf('|') === -1) { return false; }
136 if (state.sCount[startLine] - state.blkIndent >= 4) { return false; }
137
138 // header row will define an amount of columns in the entire table,
139 // and align row shouldn't be smaller than that (the rest of the rows can)
140 columnCount = escapedSplit(lineText.replace(/^\||\|$/g, '')).length;
141 if (columnCount > aligns.length) { return false; }
142 if (columnCount === 1 && !/^\||[^\\]\|$/.test(lineText)) { return false; }
143 }
144
145 if (silent) { return true; }
146
147 token = state.push('table_open', 'table', 1);
148 token.map = tableLines = [ startLine, 0 ];
149
150 if (captionInfo[0]) {
151 captionLine = (captionInfo[2] & 0x10) ? startLine - 1 : endLine + 1;
152
153 token = state.push('caption_open', 'caption', 1);
154 token.map = [ captionLine, captionLine + 1 ];
155 token.attrs = [ [ 'id', captionInfo[1].toLowerCase().replace(/\W+/g, '') ] ];
156
157 token = state.push('inline', '', 0);
158 token.content = captionInfo[0];
159 token.map = [ captionLine, captionLine + 1 ];
160 token.children = [];
161
162 token = state.push('caption_close', 'caption', -1);
163 }
164
165 token = state.push('thead_open', 'thead', 1);
166 token.map = [ startLine, seperatorLine - 1 ];
167
168 for (headerLine = startLine; headerLine < seperatorLine; headerLine++) {
169 lineText = getLine(state, headerLine).trim();
170 columns = escapedSplit(lineText.replace(/^\||\|$/g, ''));
171 colspans = countColspan(columns);
172
173 token = state.push('tr_open', 'tr', 1);
174 token.map = [ startLine, startLine + 1 ];
175
176 for (i = 0, col = 0; col < columns.length; i++) {
177 token = state.push('th_open', 'th', 1);
178 token.map = [ headerLine, headerLine + 1 ];
179 token.attrs = [];
180 if (aligns[col]) { token.attrs.push([ 'style', 'text-align:' + aligns[col] ]); }
181 if (wraps[col]) { token.attrs.push([ 'class', 'extend' ]); }
182 if (colspans[i] > 1) { token.attrs.push([ 'colspan', colspans[i] ]); }
183
184 token = state.push('inline', '', 0);
185 token.content = columns[i].trim();
186 token.map = [ headerLine, headerLine + 1 ];
187 token.children = [];
188
189 token = state.push('th_close', 'th', -1);
190
191 col += colspans[i] || 1;
192 }
193
194 token = state.push('tr_close', 'tr', -1);
195 }
196
197 token = state.push('thead_close', 'thead', -1);
198
199 token = state.push('tbody_open', 'tbody', 1);
200 token.map = tbodyLines = [ seperatorLine + 1, 0 ];
201
202 emptyTableBody = true;
203
204 for (nextLine = seperatorLine + 1; nextLine < endLine; nextLine++) {
205 if (state.sCount[nextLine] < state.blkIndent) { break; }
206
207 lineText = getLine(state, nextLine).trim();
208
209 // HACK: avoid outer while loop
210 if (!lineText && !emptyTableBody) {
211 tbodyLines[1] = nextLine - 1;
212 token = state.push('tbody_close', 'tbody', -1);
213 token = state.push('tbody_open', 'tbody', 1);
214 token.map = tbodyLines = [ nextLine + 1, 0 ];
215 emptyTableBody = true;
216 continue;
217 } else if (!lineText) {
218 break;
219 }
220
221 if (lineText.indexOf('|') === -1) { break; }
222 if (state.sCount[nextLine] - state.blkIndent >= 4) { break; }
223 columns = escapedSplit(lineText.replace(/^\||\|$/g, ''));
224 if (columns.length === 1 && !/^\||[^\\]\|$/.test(lineText)) { break; }
225 colspans = countColspan(columns);
226
227 emptyTableBody = false;
228
229 token = state.push('tr_open', 'tr', 1);
230 for (i = 0, col = 0; col < columnCount; i++) {
231 token = state.push('td_open', 'td', 1);
232 token.attrs = [];
233 if (aligns[col]) { token.attrs.push([ 'style', 'text-align:' + aligns[col] ]); }
234 if (wraps[col]) { token.attrs.push([ 'class', 'extend' ]); }
235 if (colspans[i] > 1) { token.attrs.push([ 'colspan', colspans[i] ]); }
236
237 token = state.push('inline', '', 0);
238 token.content = columns[i] ? columns[i].trim() : '';
239 token.children = [];
240
241 token = state.push('td_close', 'td', -1);
242
243 col += colspans[i] || 1;
244 }
245 token = state.push('tr_close', 'tr', -1);
246 }
247 token = state.push('tbody_close', 'tbody', -1);
248 token = state.push('table_close', 'table', -1);
249
250 tableLines[1] = tbodyLines[1] = nextLine;
251 state.line = nextLine;
252 return true;
253 }
254
255 function tableWithCaption(state, startLine, endLine, silent) {
256 var lineText, result, captionInfo;
257
258 // captionInfo: [ caption, label, captionLinePos ]
259 captionInfo = [ null, null, 0 ];
260
261 lineText = getLine(state, endLine - 1);
262 result = lineText.match(/^\[([^[\]]+)\](\[([^[\]]+)\])?\s*$/);
263 if (result) {
264 captionInfo = [ result[1],
265 result[2] || result[1],
266 captionInfo[2] | 0x01 ];
267 }
268
269 lineText = getLine(state, startLine);
270 result = lineText.match(/^\[([^[\]]+)\](\[([^[\]]+)\])?\s*$/);
271 if (result) {
272 captionInfo = [ result[1],
273 result[2] || result[1],
274 captionInfo[2] | 0x10 ];
275 }
276
277 result = table(state,
278 startLine + ((captionInfo[2] & 0x10) === 0x10),
279 endLine - ((captionInfo[2] & 0x01) === 0x01),
280 silent, captionInfo);
281 if (result && !silent) {
282 state.line += (captionInfo[2] & 0x01);
283 }
284
285 return result;
286 }
287
288 md.block.ruler.at('table', tableWithCaption, { alt: [ 'paragraph', 'reference' ] });
289};
290
291},{}]},{},[1])(1)
292});
\No newline at end of file