Completed
Push — master ( ec1fb6...546b1e )
by Kolen
01:07
created

list2csv()   A

Complexity

Conditions 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
c 1
b 0
f 1
dl 0
loc 6
rs 9.4285
1
#!/usr/bin/env python3
2
3
r"""
4
Panflute filter to convert any native pandoc tables into the CSV table format used by pantable:
5
6
- in code-block with class table
7
- metadata in YAML
8
- table in CSV
9
10
e.g.
11
12
~~~markdown
13
+--------+---------------------+--------------------------+
14
| First  | defaulted to be     | can be disabled          |
15
| row    | header row          |                          |
16
+========+=====================+==========================+
17
| 1      | cell can contain    | It can be aribrary block |
18
|        | **markdown**        | element:                 |
19
|        |                     |                          |
20
|        |                     | -   following standard   |
21
|        |                     |     markdown syntax      |
22
|        |                     | -   like this            |
23
+--------+---------------------+--------------------------+
24
| 2      | Any markdown        | $$E = mc^2$$             |
25
|        | syntax, e.g.        |                          |
26
+--------+---------------------+--------------------------+
27
28
: *Awesome* **Markdown** Table
29
~~~
30
31
becomes
32
33
~~~markdown
34
``` {.table}
35
---
36
alignment: DDD
37
caption: '*Awesome* **Markdown** Table'
38
header: true
39
markdown: true
40
table-width: 0.8055555555555556
41
width: [0.125, 0.3055555555555556, 0.375]
42
---
43
First row,defaulted to be header row,can be disabled
44
1,cell can contain **markdown**,"It can be aribrary block element:
45
46
-   following standard markdown syntax
47
-   like this
48
"
49
2,"Any markdown syntax, e.g.",$$E = mc^2$$
50
```
51
~~~
52
"""
53
54
import csv
55
import io
56
import panflute
57
import yaml
58
59
60
def table2csv(elem, doc):
61
    """
62
    find Table element and return a csv table in code-block with class "table"
63
    """
64
    if isinstance(elem, panflute.Table):
65
        # get options as a dictionary
66
        options = {}
67
        # options: caption: panflute ast to markdown
68
        if elem.caption:
69
            options['caption'] = panflute.convert_text(
70
                panflute.Para(*elem.caption),
71
                input_format='panflute',
72
                output_format='markdown'
73
            )
74
        # options: alignment
75
        parsed_alignment = [("L" if i == "AlignLeft"
76
                             else "C" if i == "AlignCenter"
77
                             else "R" if i == "AlignRight"
78
                             else "D") for i in elem.alignment]
79
        options['alignment'] = "".join(parsed_alignment)
80
        # options: width
81
        options['width'] = elem.width
82
        # options: table-width from width
83
        options['table-width'] = sum(options['width'])
84
        # options: header: False if empty header row, else True
85
        options['header'] = bool(panflute.stringify(elem.header))
86
        # options: markdown
87
        options['markdown'] = True
88
89
        # option in YAML
90
        yaml_metadata = yaml.dump(options)
91
92
        # table in panflute AST
93
        table_body = elem.content
94
        if options['header']:
95
            table_body.insert(0, elem.header)
96
        # table in list
97
        table_list = [
98
            [panflute.convert_text(
99
                cell.content,
100
                input_format='panflute',
101
                output_format='markdown'
102
            ) for cell in row.content]
103
            for row in table_body]
104
        # table in CSV
105
        with io.StringIO() as file:
106
            writer = csv.writer(file)
107
            writer.writerows(table_list)
108
            csv_table = file.getvalue()
109
        return panflute.CodeBlock("---\n" + yaml_metadata + "---\n" + csv_table, classes=["table"])
110
    return None
111
112
113
def main(_=None):
114
    """
115
    Any native pandoc tables will be converted into the CSV table format used by pantable:
116
117
    - in code-block with class table
118
    - metadata in YAML
119
    - table in CSV
120
    """
121
    panflute.run_filter(table2csv)
122
123
if __name__ == '__main__':
124
    main()
125