Open10

markdown list を table に変換する

zakkiezakkie

元データ

- parent1
  - child1
  - child2
- parent2

こういうテーブルを作りたい

csv だとこんな感じ

parent1,child1
'',child2
parent2,''
zakkiezakkie

pandoc の AST に変換

pandoc -o output.json test.md
jq . output.json
{
  "pandoc-api-version": [
    1,
    23
  ],
  "meta": {},
  "blocks": [
    {
      "t": "BulletList",
      "c": [
        [
          {
            "t": "Plain",
            "c": [
              {
                "t": "Str",
                "c": "parent1"
              }
            ]
          },
          {
            "t": "BulletList",
            "c": [
              [
                {
                  "t": "Plain",
                  "c": [
                    {
                      "t": "Str",
                      "c": "child1"
                    }
                  ]
                }
              ],
              [
                {
                  "t": "Plain",
                  "c": [
                    {
                      "t": "Str",
                      "c": "child2"
                    }
                  ]
                }
              ]
            ]
          }
        ],
        [
          {
            "t": "Plain",
            "c": [
              {
                "t": "Str",
                "c": "parent2"
              }
            ]
          }
        ]
      ]
    }
  ]
}
zakkiezakkie

pandoc の AST を python のリストに変換

import json
from pprint import pprint

src = 'output.json'

def convert(block):
    contents, _type = block['c'], block['t']
    if _type == 'Plain':
        return contents[0]['c']
    elif _type == 'BulletList':
        res = []
        for c1 in contents:
            for c2 in c1:
                c = convert(c2)
                if type(c) is list:
                    res[-1] = [res[-1], c]
                else:
                    res.append(c)
        #pprint(res)
        #print('--')
        return res


def main():
    with open(src) as f:
        data = json.load(f)
    blocks = data['blocks']
    res = convert(blocks[0])
    print('--')
    pprint(res)

main()
zakkiezakkie

結果

[['parent1', ['child1', 'child2']], 'parent2']
zakkiezakkie

python は標準ライブラリに csv モジュールがある。便利だ。

zakkiezakkie
import csv
with open('eggs.csv', 'w', newline='') as csvfile:
    spamwriter = csv.writer(csvfile)
    spamwriter.writerow(['Spam'] * 5 + ['Baked Beans'])
    spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])

zakkiezakkie
[['parent1', ['child1', 'child2']], 'parent2']

これをテーブルにするにはどうしたものか。numpy の行列を使ったらそれっぽいのができないかな

zakkiezakkie
['parent1', ['child1', 'child2']]

ではなく
[
  ['parent1', 'child1'],
  ['','child2']
]

を作ればよさそう
zakkiezakkie

tree を table にするのは一般的な方法があったような気がするけど、なんだったかな。