From e113df738e4d164b1a5bdd0e345a7847c84d29bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Wed, 24 Feb 2016 16:21:12 +0100 Subject: [PATCH] Add position and size for tables --- lib/rules_block/table.js | 73 +++++++++++++++++++++++++++++++++++----- test/annotation.js | 68 +++++++++++++++++++++++++++++++++---- 2 files changed, 126 insertions(+), 15 deletions(-) diff --git a/lib/rules_block/table.js b/lib/rules_block/table.js index 6993928..eaba69a 100644 --- a/lib/rules_block/table.js +++ b/lib/rules_block/table.js @@ -55,7 +55,7 @@ function escapedSplit(str) { module.exports = function table(state, startLine, endLine, silent) { var ch, lineText, pos, i, nextLine, columns, columnCount, token, - aligns, t, tableLines, tbodyLines; + aligns, t, tableLines, tbodyLines, columnVIndex; // should have at least three lines if (startLine + 2 > endLine) { return false; } @@ -110,18 +110,30 @@ module.exports = function table(state, startLine, endLine, silent) { if (silent) { return true; } - token = state.push('table_open', 'table', 1); - token.map = tableLines = [ startLine, 0 ]; + token = state.push('table_open', 'table', 1); + token.map = tableLines = [ startLine, 0 ]; + token.size = 0; + token.position = state.bMarks[startLine]; - token = state.push('thead_open', 'thead', 1); - token.map = [ startLine, startLine + 1 ]; - token = state.push('tr_open', 'tr', 1); - token.map = [ startLine, startLine + 1 ]; + token = state.push('thead_open', 'thead', 1); + token.map = [ startLine, startLine + 1 ]; + token.size = 0; + token.position = state.bMarks[startLine]; + token = state.push('tr_open', 'tr', 1); + token.map = [ startLine, startLine + 1 ]; + token.size = 0; + token.position = state.bMarks[startLine]; + + columnVIndex = state.bMarks[startLine] + state.tShift[startLine]; for (i = 0; i < columns.length; i++) { token = state.push('th_open', 'th', 1); token.map = [ startLine, startLine + 1 ]; + token.size = 1; + token.position = columnVIndex; + columnVIndex = columnVIndex + 1; + if (aligns[i]) { token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ]; } @@ -130,15 +142,33 @@ module.exports = function table(state, startLine, endLine, silent) { token.content = columns[i].trim(); token.map = [ startLine, startLine + 1 ]; token.children = []; + token.position = columnVIndex; + token.size = columns[i].length; + columnVIndex = columnVIndex + columns[i].length; token = state.push('th_close', 'th', -1); + token.position = columnVIndex; + + // Last column? + if (i === (columns.length - 1)) { + token.size = 1; + columnVIndex = columnVIndex + 1; + } + } - token = state.push('tr_close', 'tr', -1); - token = state.push('thead_close', 'thead', -1); + token = state.push('tr_close', 'tr', -1); + token.size = 0; + token.position = state.eMarks[startLine]; + + token = state.push('thead_close', 'thead', -1); + token.size = state.eMarks[startLine + 1] - state.bMarks[startLine + 1]; + token.position = state.bMarks[startLine + 1]; token = state.push('tbody_open', 'tbody', 1); token.map = tbodyLines = [ startLine + 2, 0 ]; + token.size = 0; + token.position = state.bMarks[startLine + 2]; for (nextLine = startLine + 2; nextLine < endLine; nextLine++) { if (state.sCount[nextLine] < state.blkIndent) { break; } @@ -148,8 +178,16 @@ module.exports = function table(state, startLine, endLine, silent) { columns = escapedSplit(lineText.replace(/^\||\|$/g, '')); token = state.push('tr_open', 'tr', 1); + token.size = 0; + token.position = state.bMarks[nextLine]; + + columnVIndex = state.bMarks[nextLine] + state.tShift[nextLine]; for (i = 0; i < columnCount; i++) { token = state.push('td_open', 'td', 1); + token.size = 1; + token.position = columnVIndex; + columnVIndex++; + if (aligns[i]) { token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ]; } @@ -157,13 +195,30 @@ module.exports = function table(state, startLine, endLine, silent) { token = state.push('inline', '', 0); token.content = columns[i] ? columns[i].trim() : ''; token.children = []; + token.size = (columns[i] || '').length; + token.position = columnVIndex; + columnVIndex += token.size; token = state.push('td_close', 'td', -1); + token.position = columnVIndex; + + // Last column? + if (i === (columns.length - 1)) { + token.size = 1; + } } token = state.push('tr_close', 'tr', -1); + token.size = 0; + token.position = state.eMarks[nextLine]; } + token = state.push('tbody_close', 'tbody', -1); + token.size = 0; + token.position = state.eMarks[nextLine]; + token = state.push('table_close', 'table', -1); + token.size = 0; + token.position = state.eMarks[nextLine]; tableLines[1] = tbodyLines[1] = nextLine; state.line = nextLine; diff --git a/test/annotation.js b/test/annotation.js index 811084d..7f88341 100644 --- a/test/annotation.js +++ b/test/annotation.js @@ -2,7 +2,7 @@ var assert = require('chai').assert; -function asertTokenContent(src, token, content) { +function assertTokenContent(src, token, content) { assert.strictEqual(src.slice(token.position, token.position + token.size), content); } @@ -63,15 +63,15 @@ describe.only('Annotation', function() { // First heading assert.strictEqual(tokens[0].position, 0); - asertTokenContent(src, tokens[0], ''); - asertTokenContent(src, tokens[1], 'Hello'); - asertTokenContent(src, tokens[2], '=====\n'); + assertTokenContent(src, tokens[0], ''); + assertTokenContent(src, tokens[1], 'Hello'); + assertTokenContent(src, tokens[2], '=====\n'); // Second heading assert.strictEqual(tokens[3].position, 13); assert.strictEqual(tokens[3].size, 0); - asertTokenContent(src, tokens[4], 'World'); - asertTokenContent(src, tokens[5], '======='); + assertTokenContent(src, tokens[4], 'World'); + assertTokenContent(src, tokens[5], '======='); }); it('should annotate code blocks', function () { @@ -85,6 +85,62 @@ describe.only('Annotation', function() { assert.strictEqual(tokens[4].size, 9); }); + it('should annotate tables', function () { + var src = 'Test:\n\n' + + ' | Type | Message |\n' + + ' | ---- | ------- |\n' + + '| Hello | World\n' + + ' | Bonjour | Monde |\n'; + var tokens = md.parse(src); + assert.strictEqual(tokens.length, 33); + + // Begin + assert.strictEqual(tokens[3].position, 7); + assert.strictEqual(tokens[3].size, 0); + + // head (open) + assert.strictEqual(tokens[4].position, 7); + assert.strictEqual(tokens[4].size, 0); + + // head -> TR (open) + assert.strictEqual(tokens[5].position, 7); + assert.strictEqual(tokens[5].size, 0); + + // head -> columns + assertTokenContent(src, tokens[6], '|'); + assertTokenContent(src, tokens[7], ' Type '); + assertTokenContent(src, tokens[8], ''); + assertTokenContent(src, tokens[9], '|'); + assertTokenContent(src, tokens[10], ' Message '); + assertTokenContent(src, tokens[11], '|'); + + // head -> TR (close) + assert.strictEqual(tokens[12].position, 26); + assert.strictEqual(tokens[12].size, 0); + + // head (close) + assertTokenContent(src, tokens[13], ' | ---- | ------- |'); + + // body (open) + assert.strictEqual(tokens[14].position, 47); + assert.strictEqual(tokens[14].size, 0); + + // body -> rows + assertTokenContent(src, tokens[16], '|'); + assertTokenContent(src, tokens[17], ' Hello '); + assertTokenContent(src, tokens[18], ''); + assertTokenContent(src, tokens[19], '|'); + assertTokenContent(src, tokens[20], ' World'); + assertTokenContent(src, tokens[21], '\n'); + + assertTokenContent(src, tokens[24], '|'); + assertTokenContent(src, tokens[25], ' Bonjour '); + assertTokenContent(src, tokens[26], ''); + assertTokenContent(src, tokens[27], '|'); + assertTokenContent(src, tokens[28], ' Monde '); + assertTokenContent(src, tokens[29], '|'); + }); + });