Markdownのテーブルでもセルの連結をしたかった

[nocd5/md2html](https://github.com/nocd5/md2html)というMarkdownを1ファイルのhtml(jsやcss、画像もbase64で埋め込み)に変換するツールをGo言語で書いて常用しているのですが、
常用すればするほど、セルを連結したい場合も出てきたので実験的に機能を追加してみました
(現在は`develop`ブランチで有効)。

[nocd5/md2html](https://github.com/nocd5/md2html)のMarkdownへの変換部分は[russross/blackfriday](https://github.com/russross/blackfriday)を使っていますが、
QiitaのMarkdownの吐くテーブルでも動くようなので
ここに残しておきます(デバッガのコンソールから下のjsを実行)。

シンタックスは検討中ですが、とりあえず

- カラム方向は`¦ broken bar (U+00A6)`で区切られている場合
  - Vimの場合は`Ctrl+k Shift-b Shift-b`で入力
- ロウ方向は下が空白の場合

それぞれ結合するようにしています。

## 変換スクリプト

```js
// translate column
var recol = new RegExp('\u00a6\\s*', 'g');
var trans_col = function(rows, elm) {
    [].forEach.call(rows, function(row) {
        var cells = row.querySelectorAll(elm);
        var ts = 0;
        Array.prototype.forEach.call(cells, function(cell) {
            var seps = cell.innerHTML.match(recol)
            if (seps != null && seps.length > 0) {
                cell.innerHTML = cell.innerHTML.replace(recol, '');
                ts += seps.length;
                cell.setAttribute('colspan', 1 + seps.length);
            }
        });
        for (var i = 1; i <= ts; i++) {
            cells[cells.length-i].outerHTML = '';
        }
    });
};
// translate row
var get_colpos = function(row, n) {
    var pos = 0;
    var i = 0;
    while (true) {
        var s = row[pos].getAttribute('colspan');
        i += s == null ? 1 : Number(s);
        if (i > n) {
            break;
        }
        pos++;
    }
    return pos;
};
var trans_row = function(rows, elm) {
    var datalist = [];
    var maxcol = 0;
    [].forEach.call(rows, function(row) {
        var cells = row.querySelectorAll(elm);
        datalist.push(cells);
        var col = 0;
        [].forEach.call(cells, function(cell) {
            var s = cell.getAttribute('colspan');
            col += s == null ? 1 : Number(s);
        });
        maxcol = Math.max(maxcol, col);
        i++;
    });
    for (var i = 0; i < maxcol; i++) {
        var span = 0;
        var root = get_colpos(datalist[0], i);
        for (var j = 1; j < datalist.length; j++) {
            var cur = get_colpos(datalist[j], i);
            if (datalist[j][cur] != null && datalist[j][cur].innerHTML == '') {
                span++;
                if (datalist[j - span] != null && datalist[j - span][root] != null) {
                    datalist[j - span][root].setAttribute('rowspan', 1 + span);
                    if (datalist[j][cur].parentNode != null) {
                        datalist[j][cur].outerHTML = '';
                    }
                }
            }
            else {
                root = get_colpos(datalist[j], i);
                span = 0;
            }
        }
    }
};
[].forEach.call(document.querySelectorAll('table'), function(tbl) {
    // thead
    var headrows = tbl.querySelectorAll('thead > tr');
    trans_col(headrows, 'th');
    trans_row(headrows, 'th');
    // tbody
    var rows = tbl.querySelectorAll('tbody > tr');
    trans_col(rows, 'td');
    trans_row(rows, 'td');
});
```

## 変換後のイメージ
![1.png](https://qiita-image-store.s3.amazonaws.com/0/52493/e02bf82d-4060-9064-139e-67f5217971fa.png)

![2.png](https://qiita-image-store.s3.amazonaws.com/0/52493/bbf17e9f-ecd9-1da1-03c0-14abdc43f300.png)

![3.png](https://qiita-image-store.s3.amazonaws.com/0/52493/0c74e181-2caf-7f3a-ff34-4ef919f99624.png)

![4.png](https://qiita-image-store.s3.amazonaws.com/0/52493/f9b611f3-a827-ccc7-6fae-8438db9e946d.png)

## Sampleテーブル
|  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| 11 | 21 ¦    ¦    ¦    ¦    ¦    ¦    ¦    |
|    | 22 | 32 ¦    ¦    ¦    ¦    ¦    | 92 |
|    |    | 33 | 43 ¦    ¦    ¦    | 83 |    |
|    |    |    | 44 | 54 ¦    | 74 |    |    |
|    |    |    |    | 55 | 65 |    |    |    |
|    |    |    |    ¦ 56 |    |    |    |    |
|    |    |    ¦    ¦    ¦ 67 |    |    |    |
|    |    ¦    ¦    ¦    ¦    ¦ 78 |    |    |
|    ¦    ¦    ¦    ¦    ¦    ¦    ¦ 89 |    |

|  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|    ¦    ¦    ¦    ¦    ¦    ¦    ¦ 81 | 91 |
| 12 |    ¦    ¦    ¦    ¦    ¦ 72 | 82 |    |
|    | 23 |    ¦    ¦    ¦ 63 | 73 |    |    |
|    |    | 34 |    ¦ 54 | 64 |    |    |    |
|    |    |    | 45 | 55 |    |    |    |    |
|    |    |    |    | 56 ¦    |    |    |    |
|    |    |    | 47 ¦    ¦    ¦    |    |    |
|    |    | 38 ¦    ¦    ¦    ¦    ¦    |    |
|    | 29 ¦    ¦    ¦    ¦    ¦    ¦    ¦    |

| № |  1 |  2 |  3 |  4 |
|:-:|:--:|:--:|:--:|:--:|
| 1 | 11 ¦    | 31 ¦    |
| 2 |    ¦    |    ¦    |
| 3 | 13 ¦    | 33 ¦    |
| 4 |    ¦    |    ¦    |

| № |  1 |  2 |  3 |  4 |  5 |  6 |
|:-:|:--:|:--:|:--:|:--:|:--:|:--:|
| 1 | 11 ¦    ¦    | 41 ¦    ¦    |
| 2 |    ¦    ¦    |    ¦    ¦    |
| 3 |    ¦    ¦    |    ¦    ¦    |
| 4 | 14 ¦    ¦    | 44 ¦    ¦    |
| 5 |    ¦    ¦    |    ¦    ¦    |
| 6 |    ¦    ¦    |    ¦    ¦    |

## 元Markdown

```md
|  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| 11 | 21 ¦    ¦    ¦    ¦    ¦    ¦    ¦    |
|    | 22 | 32 ¦    ¦    ¦    ¦    ¦    | 92 |
|    |    | 33 | 43 ¦    ¦    ¦    | 83 |    |
|    |    |    | 44 | 54 ¦    | 74 |    |    |
|    |    |    |    | 55 | 65 |    |    |    |
|    |    |    |    ¦ 56 |    |    |    |    |
|    |    |    ¦    ¦    ¦ 67 |    |    |    |
|    |    ¦    ¦    ¦    ¦    ¦ 78 |    |    |
|    ¦    ¦    ¦    ¦    ¦    ¦    ¦ 89 |    |

|  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|    ¦    ¦    ¦    ¦    ¦    ¦    ¦ 81 | 91 |
| 12 |    ¦    ¦    ¦    ¦    ¦ 72 | 82 |    |
|    | 23 |    ¦    ¦    ¦ 63 | 73 |    |    |
|    |    | 34 |    ¦ 54 | 64 |    |    |    |
|    |    |    | 45 | 55 |    |    |    |    |
|    |    |    |    | 56 ¦    |    |    |    |
|    |    |    | 47 ¦    ¦    ¦    |    |    |
|    |    | 38 ¦    ¦    ¦    ¦    ¦    |    |
|    | 29 ¦    ¦    ¦    ¦    ¦    ¦    ¦    |

| № |  1 |  2 |  3 |  4 |
|:-:|:--:|:--:|:--:|:--:|
| 1 | 11 ¦    | 31 ¦    |
| 2 |    ¦    |    ¦    |
| 3 | 13 ¦    | 33 ¦    |
| 4 |    ¦    |    ¦    |

| № |  1 |  2 |  3 |  4 |  5 |  6 |
|:-:|:--:|:--:|:--:|:--:|:--:|:--:|
| 1 | 11 ¦    ¦    | 41 ¦    ¦    |
| 2 |    ¦    ¦    |    ¦    ¦    |
| 3 |    ¦    ¦    |    ¦    ¦    |
| 4 | 14 ¦    ¦    | 44 ¦    ¦    |
| 5 |    ¦    ¦    |    ¦    ¦    |
| 6 |    ¦    ¦    |    ¦    ¦    |
```