diff --git a/README.md b/README.md
index 2143df3..eb5bfb1 100644
--- a/README.md
+++ b/README.md
@@ -19,8 +19,6 @@ It's designed to be as minimal as possible, for constrained use-cases where a fu
- **Tiny:** it's 1kb of gzipped ES3
- **Simple:** pass a Markdown string, get back an HTML string
-> **Note:** Tables are not yet supported. If you love impossible to read regular expressions, submit a PR!
->
> **Note on XSS:** Snarkdown [doesn't sanitize HTML](https://github.com/developit/snarkdown/issues/70), since its primary target usage doesn't require it.
## Demos & Examples
diff --git a/src/index.js b/src/index.js
index 3938c5c..f518aed 100644
--- a/src/index.js
+++ b/src/index.js
@@ -24,7 +24,7 @@ function encodeAttr(str) {
/** Parse Markdown into an HTML String. */
export default function parse(md, prevLinks) {
- let tokenizer = /((?:^|\n+)(?:\n---+|\* \*(?: \*)+)\n)|(?:^``` *(\w*)\n([\s\S]*?)\n```$)|((?:(?:^|\n+)(?:\t| {2,}).+)+\n*)|((?:(?:^|\n)([>*+-]|\d+\.)\s+.*)+)|(?:!\[([^\]]*?)\]\(([^)]+?)\))|(\[)|(\](?:\(([^)]+?)\))?)|(?:(?:^|\n+)([^\s].*)\n(-{3,}|={3,})(?:\n+|$))|(?:(?:^|\n+)(#{1,6})\s*(.+)(?:\n+|$))|(?:`([^`].*?)`)|( \n\n*|\n{2,}|__|\*\*|[_*]|~~)/gm,
+ let tokenizer = /((?:^|\n+)(?:\n---+|\* \*(?: \*)+)\n)|(?:^``` *(\w*)\n([\s\S]*?)\n```$)|((?:(?:^|\n+)(?:\t| {2,}).+)+\n*)|((?:(?:^|\n)([>*+-]|\d+\.)\s+.*)+)|(?:!\[([^\]]*?)\]\(([^)]+?)\))|(\[)|(\](?:\(([^)]+?)\))?)|(?:(?:^|\n+)([^\s].*)\n(-{3,}|={3,})(?:\n+|$))|(?:(?:^|\n+)(#{1,6})\s*(.+)(?:\n+|$))|(?:`([^`].*?)`)|( \n\n*|\n{2,}|__|\*\*|[_*]|~~)|((?:(?:^|\n)\|.+)+)/gm,
context = [],
out = '',
links = prevLinks || {},
@@ -101,6 +101,15 @@ export default function parse(md, prevLinks) {
else if (token[17] || token[1]) {
chunk = tag(token[17] || '--');
}
+ // Tables:
+ else if (token[18]) {
+ t = token[18].trim().split('\n').map(row => row.replace(/^\s*\|\s*|\s*\|\s*$/g, '').split(/\s*\|\s*/));
+ inner = t[1] && t[1].every(cell => /^:?-+:?$/.test(cell)) ? t.splice(1, 1) && 'th' : 'td';
+ chunk = '
' + t.map((row, i) => {
+ let cell = i ? 'td' : inner;
+ return '' + row.map(str => '<'+cell+'>' + parse(str, links) + ''+cell+'>').join('') + '
';
+ }).join('') + '
';
+ }
out += prev;
out += chunk;
}
diff --git a/test/index.js b/test/index.js
index 5262b16..7931e74 100644
--- a/test/index.js
+++ b/test/index.js
@@ -151,6 +151,24 @@ describe('snarkdown()', () => {
});
});
+ describe('tables', () => {
+ it('parses a table with a header', () => {
+ expect(snarkdown('| a | b |\n| --- | --- |\n| 1 | 2 |')).to.equal('');
+ });
+
+ it('parses a table without a header', () => {
+ expect(snarkdown('| 1 | 2 |\n| 3 | 4 |')).to.equal('');
+ });
+
+ it('parses inline formatting within cells', () => {
+ expect(snarkdown('| **a** | [b](#b) |\n| --- | --- |\n| `c` | d |')).to.equal('');
+ });
+
+ it('parses a table surrounded by text', () => {
+ expect(snarkdown('before\n\n| a |\n| --- |\n| 1 |\n\nafter')).to.equal('before
after');
+ });
+ });
+
describe('edge cases', () => {
it('should close unclosed tags', () => {
expect(snarkdown('*foo')).to.equal('foo');