init: implement lib, test
This commit is contained in:
commit
0e1e674ead
10 changed files with 2586 additions and 0 deletions
21
.eslintrc.js
Normal file
21
.eslintrc.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
module.exports = {
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
extends: [
|
||||
'google',
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
},
|
||||
ignorePatterns: [
|
||||
'node_modules/',
|
||||
'lib/table.js',
|
||||
],
|
||||
rules: {
|
||||
'arrow-parens': ['error', 'as-needed'],
|
||||
'indent': ['error', 2, {'MemberExpression': 1}],
|
||||
},
|
||||
};
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules/
|
22
LICENSE
Normal file
22
LICENSE
Normal file
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2021 sup39[サポミク].
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
245
README.md
Normal file
245
README.md
Normal file
|
@ -0,0 +1,245 @@
|
|||
# markdown-it-raw-table
|
||||
## Feature
|
||||
`td` count is NOT adjusted to `th` count when using this plugin.
|
||||
|
||||
For example,
|
||||
```
|
||||
| abc | def |
|
||||
| --- | --- |
|
||||
| bar |
|
||||
| bar | baz | boo |
|
||||
```
|
||||
is rendered as
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>abc</th>
|
||||
<th>def</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
<td>baz</td>
|
||||
<td>boo</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
```
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>abc</th>
|
||||
<th>def</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
<td>baz</td>
|
||||
<td>boo</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
instead of
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>abc</th>
|
||||
<th>def</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
<td>baz</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Advantage of this version
|
||||
This version works well with [markdown-it-attrs](https://github.com/sup39/markdown-it-attrs) plugin.
|
||||
|
||||
#### rowspan and colspan
|
||||
This version works well with `rowspan` and `colspan`
|
||||
because it does not append extraneous `td`.
|
||||
|
||||
For example,
|
||||
```
|
||||
| h1 | h2 | h3 | h4 |
|
||||
| --- | --- | --- | --- |
|
||||
| x11 | x12 | x13 {rowspan=2} | x14 |
|
||||
| x21 {colspan=2} | x24 |
|
||||
```
|
||||
is rendered as
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>h1</th>
|
||||
<th>h2</th>
|
||||
<th>h3</th>
|
||||
<th>h4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>x11</td>
|
||||
<td>x12</td>
|
||||
<td rowspan="2">x13</td>
|
||||
<td>x14</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">x21</td>
|
||||
<td>x24</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
```
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>h1</th>
|
||||
<th>h2</th>
|
||||
<th>h3</th>
|
||||
<th>h4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>x11</td>
|
||||
<td>x12</td>
|
||||
<td rowspan="2">x13</td>
|
||||
<td>x14</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">x21</td>
|
||||
<td>x24</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
which is intended,
|
||||
|
||||
instead of
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>h1</th>
|
||||
<th>h2</th>
|
||||
<th>h3</th>
|
||||
<th>h4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>x11</td>
|
||||
<td>x12</td>
|
||||
<td rowspan="2">x13</td>
|
||||
<td>x14</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">x21</td>
|
||||
<td>x24</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
```
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>h1</th>
|
||||
<th>h2</th>
|
||||
<th>h3</th>
|
||||
<th>h4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>x11</td>
|
||||
<td>x12</td>
|
||||
<td rowspan="2">x13</td>
|
||||
<td>x14</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">x21</td>
|
||||
<td>x24</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
which produces extraneous `td` because it tries to
|
||||
make `th` count (=4) equal to `td` count in the second `tr` in `tbody`.
|
||||
|
||||
#### markdown-it-attrs for tr
|
||||
This version prevents extra tokens like `{.class}` being eliminating,
|
||||
which makes [markdown-it-attrs](https://github.com/sup39/markdown-it-attrs) for `tr` possible.
|
||||
|
||||
For example,
|
||||
|
||||
```
|
||||
| h1 | h2 |
|
||||
| -- | -- |
|
||||
| x1 {.c3} | x2 | {.c1}
|
||||
| x3 | x4 {.c4} | {.c2}
|
||||
```
|
||||
|
||||
is rendered as
|
||||
|
||||
```
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>h1</th>
|
||||
<th>h2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="c1">
|
||||
<td class="c3">x1</td>
|
||||
<td>x2</td>
|
||||
</tr>
|
||||
<tr class="c2">
|
||||
<td>x3</td>
|
||||
<td class="c4">x4</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
## Usage
|
||||
```js
|
||||
const md = require('markdown-it')();
|
||||
const mrt = require('@sup39/markdown-it-raw-table');
|
||||
md.use(mrt);
|
||||
|
||||
md.parse(`
|
||||
| abc | def |
|
||||
| --- | --- |
|
||||
| bar |
|
||||
| bar | baz | boo |
|
||||
`);
|
||||
```
|
7
lib/index.js
Normal file
7
lib/index.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
const rawTable = require('./table.js');
|
||||
|
||||
module.exports = function rawTablePlugin(md) {
|
||||
md.block.ruler.before('table', 'raw-table', rawTable, {
|
||||
alt: ['paragraph', 'reference'],
|
||||
});
|
||||
};
|
241
lib/table.js
Normal file
241
lib/table.js
Normal file
|
@ -0,0 +1,241 @@
|
|||
/*********************************************************************
|
||||
* Modified from: https://github.com/markdown-it/markdown-it/ *
|
||||
*********************************************************************
|
||||
* Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin. *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person *
|
||||
* obtaining a copy of this software and associated documentation *
|
||||
* files (the "Software"), to deal in the Software without *
|
||||
* restriction, including without limitation the rights to use, *
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell *
|
||||
* copies of the Software, and to permit persons to whom the *
|
||||
* Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be *
|
||||
* included in all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, *
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
|
||||
* OTHER DEALINGS IN THE SOFTWARE. *
|
||||
*********************************************************************/
|
||||
|
||||
'use strict';
|
||||
|
||||
function isSpace(code) {
|
||||
switch (code) {
|
||||
case 0x09:
|
||||
case 0x20:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getLine(state, line) {
|
||||
var pos = state.bMarks[line] + state.tShift[line],
|
||||
max = state.eMarks[line];
|
||||
|
||||
return state.src.substr(pos, max - pos);
|
||||
}
|
||||
|
||||
function escapedSplit(str) {
|
||||
var result = [],
|
||||
pos = 0,
|
||||
max = str.length,
|
||||
ch,
|
||||
isEscaped = false,
|
||||
lastPos = 0,
|
||||
current = '';
|
||||
|
||||
ch = str.charCodeAt(pos);
|
||||
|
||||
while (pos < max) {
|
||||
if (ch === 0x7c/* | */) {
|
||||
if (!isEscaped) {
|
||||
// pipe separating cells, '|'
|
||||
result.push(current + str.substring(lastPos, pos));
|
||||
current = '';
|
||||
lastPos = pos + 1;
|
||||
} else {
|
||||
// escaped pipe, '\|'
|
||||
current += str.substring(lastPos, pos - 1);
|
||||
lastPos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
isEscaped = (ch === 0x5c/* \ */);
|
||||
pos++;
|
||||
|
||||
ch = str.charCodeAt(pos);
|
||||
}
|
||||
|
||||
result.push(current + str.substring(lastPos));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
module.exports = function table(state, startLine, endLine, silent) {
|
||||
var ch, lineText, pos, i, l, nextLine, columns, columnCount, token,
|
||||
aligns, t, tableLines, tbodyLines, oldParentType, terminate,
|
||||
terminatorRules;
|
||||
|
||||
// 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);
|
||||
if (columns.length && columns[0] === '') columns.shift();
|
||||
if (columns.length && columns[columns.length - 1] === '') columns.pop();
|
||||
|
||||
// header row will define an amount of columns in the entire table,
|
||||
// and align row should be exactly the same (the rest of the rows can differ)
|
||||
columnCount = columns.length;
|
||||
if (columnCount === 0 || columnCount !== aligns.length) { return false; }
|
||||
|
||||
if (silent) { return true; }
|
||||
|
||||
oldParentType = state.parentType;
|
||||
state.parentType = 'table';
|
||||
|
||||
// use 'blockquote' lists for termination because it's
|
||||
// the most similar to tables
|
||||
terminatorRules = state.md.block.ruler.getRules('blockquote');
|
||||
|
||||
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);
|
||||
if (aligns[i]) {
|
||||
token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ];
|
||||
}
|
||||
|
||||
token = state.push('inline', '', 0);
|
||||
token.content = columns[i].trim();
|
||||
token.children = [];
|
||||
|
||||
token = state.push('th_close', 'th', -1);
|
||||
}
|
||||
|
||||
token = state.push('tr_close', 'tr', -1);
|
||||
token = state.push('thead_close', 'thead', -1);
|
||||
|
||||
for (nextLine = startLine + 2; nextLine < endLine; nextLine++) {
|
||||
if (state.sCount[nextLine] < state.blkIndent) { break; }
|
||||
|
||||
terminate = false;
|
||||
for (i = 0, l = terminatorRules.length; i < l; i++) {
|
||||
if (terminatorRules[i](state, nextLine, endLine, true)) {
|
||||
terminate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (terminate) { break; }
|
||||
lineText = getLine(state, nextLine).trim();
|
||||
if (!lineText) { break; }
|
||||
if (state.sCount[nextLine] - state.blkIndent >= 4) { break; }
|
||||
columns = escapedSplit(lineText);
|
||||
if (columns.length && columns[0] === '') columns.shift();
|
||||
if (columns.length && columns[columns.length - 1] === '') columns.pop();
|
||||
|
||||
if (nextLine === startLine + 2) {
|
||||
token = state.push('tbody_open', 'tbody', 1);
|
||||
token.map = tbodyLines = [ startLine + 2, 0 ];
|
||||
}
|
||||
|
||||
token = state.push('tr_open', 'tr', 1);
|
||||
token.map = [ nextLine, nextLine + 1 ];
|
||||
|
||||
for (i = 0; i < columns.length; i++) { // disallow omitting |
|
||||
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);
|
||||
}
|
||||
|
||||
if (tbodyLines) {
|
||||
token = state.push('tbody_close', 'tbody', -1);
|
||||
tbodyLines[1] = nextLine;
|
||||
}
|
||||
|
||||
token = state.push('table_close', 'table', -1);
|
||||
tableLines[1] = nextLine;
|
||||
|
||||
state.parentType = oldParentType;
|
||||
state.line = nextLine;
|
||||
return true;
|
||||
};
|
24
package.json
Normal file
24
package.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "@sup39/markdown-it-raw-table",
|
||||
"version": "1.0.0",
|
||||
"description": "Plugin for Markdown-it to use non-GFM table.",
|
||||
"keywords": [
|
||||
"markdown",
|
||||
"markdown-it",
|
||||
"markdown-it-plugin",
|
||||
"table"
|
||||
],
|
||||
"repository": "sup39/markdown-it-raw-table",
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^7.17.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"markdown-it": "^12.0.4",
|
||||
"mocha": "^8.2.1"
|
||||
}
|
||||
}
|
793
test/cases/tables.txt
Normal file
793
test/cases/tables.txt
Normal file
|
@ -0,0 +1,793 @@
|
|||
Simple:
|
||||
.
|
||||
| Heading 1 | Heading 2
|
||||
| --------- | ---------
|
||||
| Cell 1 | Cell 2
|
||||
| Cell 3 | Cell 4
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Heading 1</th>
|
||||
<th>Heading 2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Cell 1</td>
|
||||
<td>Cell 2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell 3</td>
|
||||
<td>Cell 4</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
Column alignment:
|
||||
.
|
||||
| Header 1 | Header 2 | Header 3 | Header 4 |
|
||||
| :------: | -------: | :------- | -------- |
|
||||
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
|
||||
| Cell 5 | Cell 6 | Cell 7 | Cell 8 |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align:center">Header 1</th>
|
||||
<th style="text-align:right">Header 2</th>
|
||||
<th style="text-align:left">Header 3</th>
|
||||
<th>Header 4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:center">Cell 1</td>
|
||||
<td style="text-align:right">Cell 2</td>
|
||||
<td style="text-align:left">Cell 3</td>
|
||||
<td>Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:center">Cell 5</td>
|
||||
<td style="text-align:right">Cell 6</td>
|
||||
<td style="text-align:left">Cell 7</td>
|
||||
<td>Cell 8</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
Nested emphases:
|
||||
.
|
||||
Header 1|Header 2|Header 3|Header 4
|
||||
:-------|:------:|-------:|--------
|
||||
Cell 1 |Cell 2 |Cell 3 |Cell 4
|
||||
*Cell 5*|Cell 6 |Cell 7 |Cell 8
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align:left">Header 1</th>
|
||||
<th style="text-align:center">Header 2</th>
|
||||
<th style="text-align:right">Header 3</th>
|
||||
<th>Header 4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:left">Cell 1</td>
|
||||
<td style="text-align:center">Cell 2</td>
|
||||
<td style="text-align:right">Cell 3</td>
|
||||
<td>Cell 4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:left"><em>Cell 5</em></td>
|
||||
<td style="text-align:center">Cell 6</td>
|
||||
<td style="text-align:right">Cell 7</td>
|
||||
<td>Cell 8</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
Nested tables inside blockquotes:
|
||||
.
|
||||
> foo|foo
|
||||
> ---|---
|
||||
> bar|bar
|
||||
baz|baz
|
||||
.
|
||||
<blockquote>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>foo</th>
|
||||
<th>foo</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
<td>bar</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
<p>baz|baz</p>
|
||||
.
|
||||
|
||||
|
||||
Minimal one-column:
|
||||
.
|
||||
| foo
|
||||
|----
|
||||
| test2
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>foo</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>test2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
This is parsed as one big table:
|
||||
.
|
||||
- foo|foo
|
||||
---|---
|
||||
bar|bar
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>- foo</th>
|
||||
<th>foo</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
<td>bar</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
Second line should not contain symbols except "-", ":", "|" and " ":
|
||||
.
|
||||
foo|foo
|
||||
-----|-----s
|
||||
bar|bar
|
||||
.
|
||||
<p>foo|foo
|
||||
-----|-----s
|
||||
bar|bar</p>
|
||||
.
|
||||
|
||||
|
||||
Second line should contain "|" symbol:
|
||||
.
|
||||
foo|foo
|
||||
-----:-----
|
||||
bar|bar
|
||||
.
|
||||
<p>foo|foo
|
||||
-----:-----
|
||||
bar|bar</p>
|
||||
.
|
||||
|
||||
|
||||
Second line should not have empty columns in the middle:
|
||||
.
|
||||
foo|foo
|
||||
-----||-----
|
||||
bar|bar
|
||||
.
|
||||
<p>foo|foo
|
||||
-----||-----
|
||||
bar|bar</p>
|
||||
.
|
||||
|
||||
|
||||
Wrong alignment symbol position:
|
||||
.
|
||||
foo|foo
|
||||
-----|-::-
|
||||
bar|bar
|
||||
.
|
||||
<p>foo|foo
|
||||
-----|-::-
|
||||
bar|bar</p>
|
||||
.
|
||||
|
||||
|
||||
Title line should contain "|" symbol:
|
||||
.
|
||||
foo
|
||||
-----|-----
|
||||
bar|bar
|
||||
.
|
||||
<p>foo
|
||||
-----|-----
|
||||
bar|bar</p>
|
||||
.
|
||||
|
||||
|
||||
Allow tabs as a separator on 2nd line
|
||||
.
|
||||
| foo | bar |
|
||||
| --- | --- |
|
||||
| baz | quux |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>foo</th>
|
||||
<th>bar</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>baz</td>
|
||||
<td>quux</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
Should terminate paragraph:
|
||||
.
|
||||
paragraph
|
||||
foo|foo
|
||||
---|---
|
||||
bar|bar
|
||||
.
|
||||
<p>paragraph</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>foo</th>
|
||||
<th>foo</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
<td>bar</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
Another complicated backticks case
|
||||
.
|
||||
| Heading 1 | Heading 2
|
||||
| --------- | ---------
|
||||
| Cell 1 | Cell 2
|
||||
| \\\`|\\\`
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Heading 1</th>
|
||||
<th>Heading 2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Cell 1</td>
|
||||
<td>Cell 2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\`</td>
|
||||
<td>\`</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
`\` in tables should not count as escaped backtick
|
||||
.
|
||||
# | 1 | 2
|
||||
--|--|--
|
||||
x | `\` | `x`
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>1</th>
|
||||
<th>2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td><code>\</code></td>
|
||||
<td><code>x</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
Tables should handle escaped backticks
|
||||
.
|
||||
# | 1 | 2
|
||||
--|--|--
|
||||
x | \`\` | `x`
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>1</th>
|
||||
<th>2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>x</td>
|
||||
<td>``</td>
|
||||
<td><code>x</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
An amount of rows might be different across the table (issue #171):
|
||||
.
|
||||
| 1 | 2 |
|
||||
| :-----: | :-----: |
|
||||
| 3 | 4 | 5 | 6 |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align:center">1</th>
|
||||
<th style="text-align:center">2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:center">3</td>
|
||||
<td style="text-align:center">4</td>
|
||||
<td>5</td>
|
||||
<td>6</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
An amount of rows might be different across the table #2:
|
||||
.
|
||||
| 1 | 2 | 3 | 4 |
|
||||
| :-----: | :-----: | :-----: | :-----: |
|
||||
| 5 | 6 |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align:center">1</th>
|
||||
<th style="text-align:center">2</th>
|
||||
<th style="text-align:center">3</th>
|
||||
<th style="text-align:center">4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:center">5</td>
|
||||
<td style="text-align:center">6</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
Allow one-column tables (issue #171):
|
||||
.
|
||||
| foo |
|
||||
:-----:
|
||||
| bar |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align:center">foo</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:center">bar</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
Allow indented tables (issue #325):
|
||||
.
|
||||
| Col1a | Col2a |
|
||||
| ----- | ----- |
|
||||
| Col1b | Col2b |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Col1a</th>
|
||||
<th>Col2a</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Col1b</td>
|
||||
<td>Col2b</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
Tables should not be indented more than 4 spaces (1st line):
|
||||
.
|
||||
| Col1a | Col2a |
|
||||
| ----- | ----- |
|
||||
| Col1b | Col2b |
|
||||
.
|
||||
<pre><code>| Col1a | Col2a |
|
||||
</code></pre>
|
||||
<p>| ----- | ----- |
|
||||
| Col1b | Col2b |</p>
|
||||
.
|
||||
|
||||
|
||||
Tables should not be indented more than 4 spaces (2nd line):
|
||||
.
|
||||
| Col1a | Col2a |
|
||||
| ----- | ----- |
|
||||
| Col1b | Col2b |
|
||||
.
|
||||
<p>| Col1a | Col2a |
|
||||
| ----- | ----- |
|
||||
| Col1b | Col2b |</p>
|
||||
.
|
||||
|
||||
|
||||
Tables should not be indented more than 4 spaces (3rd line):
|
||||
.
|
||||
| Col1a | Col2a |
|
||||
| ----- | ----- |
|
||||
| Col1b | Col2b |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Col1a</th>
|
||||
<th>Col2a</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<pre><code>| Col1b | Col2b |</code></pre>
|
||||
.
|
||||
|
||||
|
||||
Allow tables with empty body:
|
||||
.
|
||||
| Col1a | Col2a |
|
||||
| ----- | ----- |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Col1a</th>
|
||||
<th>Col2a</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
.
|
||||
|
||||
|
||||
Align row should be at least as large as any actual rows:
|
||||
.
|
||||
Col1a | Col1b | Col1c
|
||||
----- | -----
|
||||
Col2a | Col2b | Col2c
|
||||
.
|
||||
<p>Col1a | Col1b | Col1c
|
||||
----- | -----
|
||||
Col2a | Col2b | Col2c</p>
|
||||
.
|
||||
|
||||
Escaped pipes inside backticks don't split cells:
|
||||
.
|
||||
| Heading 1 | Heading 2
|
||||
| --------- | ---------
|
||||
| Cell 1 | Cell 2
|
||||
| `Cell 3\|` | Cell 4
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Heading 1</th>
|
||||
<th>Heading 2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Cell 1</td>
|
||||
<td>Cell 2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Cell 3|</code></td>
|
||||
<td>Cell 4</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
Escape before escaped Pipes inside backticks don't split cells:
|
||||
.
|
||||
| Heading 1 | Heading 2
|
||||
| --------- | ---------
|
||||
| Cell 1 | Cell 2
|
||||
| `Cell 3\\|` | Cell 4
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Heading 1</th>
|
||||
<th>Heading 2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Cell 1</td>
|
||||
<td>Cell 2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Cell 3\|</code></td>
|
||||
<td>Cell 4</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
Regression test for #721, table in a list indented with tabs:
|
||||
.
|
||||
- Level 1
|
||||
|
||||
- Level 2
|
||||
|
||||
| Column 1 | Column 2 |
|
||||
| -------- | -------- |
|
||||
| abcdefgh | ijklmnop |
|
||||
.
|
||||
<ul>
|
||||
<li>
|
||||
<p>Level 1</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>Level 2</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Column 1</th>
|
||||
<th>Column 2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>abcdefgh</td>
|
||||
<td>ijklmnop</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
.
|
||||
|
||||
|
||||
Table without any columns is not a table, #724
|
||||
.
|
||||
|
|
||||
|
|
||||
|
|
||||
.
|
||||
<p>|
|
||||
|
|
||||
|</p>
|
||||
.
|
||||
|
||||
|
||||
GFM 4.10 Tables (extension), Example 198
|
||||
.
|
||||
| foo | bar |
|
||||
| --- | --- |
|
||||
| baz | bim |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>foo</th>
|
||||
<th>bar</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>baz</td>
|
||||
<td>bim</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
GFM 4.10 Tables (extension), Example 199
|
||||
.
|
||||
| abc | defghi |
|
||||
:-: | -----------:
|
||||
bar | baz
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align:center">abc</th>
|
||||
<th style="text-align:right">defghi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:center">bar</td>
|
||||
<td style="text-align:right">baz</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
GFM 4.10 Tables (extension), Example 200
|
||||
.
|
||||
| f\|oo |
|
||||
| ------ |
|
||||
| b `\|` az |
|
||||
| b **\|** im |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>f|oo</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>b <code>|</code> az</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>b <strong>|</strong> im</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
GFM 4.10 Tables (extension), Example 201
|
||||
.
|
||||
| abc | def |
|
||||
| --- | --- |
|
||||
| bar | baz |
|
||||
> bar
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>abc</th>
|
||||
<th>def</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
<td>baz</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<blockquote>
|
||||
<p>bar</p>
|
||||
</blockquote>
|
||||
.
|
||||
|
||||
GFM 4.10 Tables (extension), Example 202
|
||||
.
|
||||
| abc | def |
|
||||
| --- | --- |
|
||||
| bar | baz |
|
||||
bar
|
||||
|
||||
bar
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>abc</th>
|
||||
<th>def</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
<td>baz</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>bar</p>
|
||||
.
|
||||
|
||||
GFM 4.10 Tables (extension), Example 203
|
||||
.
|
||||
| abc | def |
|
||||
| --- |
|
||||
| bar |
|
||||
.
|
||||
<p>| abc | def |
|
||||
| --- |
|
||||
| bar |</p>
|
||||
.
|
||||
|
||||
GFM 4.10 Tables (extension), Example 204
|
||||
.
|
||||
| abc | def |
|
||||
| --- | --- |
|
||||
| bar |
|
||||
| bar | baz | boo |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>abc</th>
|
||||
<th>def</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>bar</td>
|
||||
<td>baz</td>
|
||||
<td>boo</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.
|
||||
|
||||
GFM 4.10 Tables (extension), Example 205
|
||||
.
|
||||
| abc | def |
|
||||
| --- | --- |
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>abc</th>
|
||||
<th>def</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
.
|
19
test/test.js
Normal file
19
test/test.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
const assert = require('assert');
|
||||
const mdi = require('markdown-it');
|
||||
const mrt = require('..');
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const rawCases =
|
||||
fs.readFileSync(path.join(__dirname, 'cases/tables.txt')).toString();
|
||||
|
||||
describe('Raw Table', () => {
|
||||
const md = mdi().use(mrt);
|
||||
const elms = rawCases.split(/\n\.\n/);
|
||||
for (let i=2; i<elms.length; i+=3) {
|
||||
const title = elms[i-2].trim();
|
||||
it(title, () => {
|
||||
assert.equal(md.render(elms[i-1]), elms[i]+'\n');
|
||||
});
|
||||
}
|
||||
});
|
Reference in a new issue