Skip to content

Commit 79f27a6

Browse files
committed
add Convert2MarkdownTable
1 parent 8f89c16 commit 79f27a6

File tree

6 files changed

+333
-0
lines changed

6 files changed

+333
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88

99
![](./imgs/mvim_settings.png)
1010

11+
## Convert HTML table to Markdown
12+
13+
Copy table from Numbers and CMD-Ctrl-T to paste as Markdown table
14+
15+
1116
### Acknowledge
1217
- [flat vim icon](https://iconverticons.com/icons/92d8febce1d7a304/)
1318
- [Alfred App Community Forum](https://www.alfredforum.com/topic/10547-edit-clipboard-within-macvim/)
19+
- [schmijos/html-table-parser-python3: A small and simple HTML table parser not requiring any external dependency.](https://github.com/schmijos/html-table-parser-python3)

sources/Convert2MarkdownTable/__init__.py

Whitespace-only changes.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import sys
4+
5+
from parser import HTMLTableParser
6+
7+
8+
def generate_markdown_table(table):
9+
table = iter(table[0])
10+
header = next(table)
11+
header = '|'.join(header)
12+
separator = '|'.join(['---']*len(header))
13+
sys.stdout.write(header+'\n')
14+
sys.stdout.write(separator+'\n')
15+
for t in table:
16+
t = '|'.join(t)
17+
sys.stdout.write(t+'\n')
18+
19+
query = sys.argv[1]
20+
21+
parser = HTMLTableParser()
22+
parser.feed(query)
23+
24+
generate_markdown_table(parser.tables)
89.4 KB
Loading
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>bundleid</key>
6+
<string>xyz.cdpath.markdowntable</string>
7+
<key>category</key>
8+
<string>Productivity</string>
9+
<key>connections</key>
10+
<dict>
11+
<key>145D1882-556B-484B-9830-BBE2E7EC3DB4</key>
12+
<array>
13+
<dict>
14+
<key>destinationuid</key>
15+
<string>E244FEC6-9942-4EC6-A9D8-BBE08A039FDB</string>
16+
<key>modifiers</key>
17+
<integer>0</integer>
18+
<key>modifiersubtext</key>
19+
<string></string>
20+
<key>vitoclose</key>
21+
<false/>
22+
</dict>
23+
</array>
24+
<key>364D5B17-7D02-459C-B600-80915440E331</key>
25+
<array>
26+
<dict>
27+
<key>destinationuid</key>
28+
<string>145D1882-556B-484B-9830-BBE2E7EC3DB4</string>
29+
<key>modifiers</key>
30+
<integer>0</integer>
31+
<key>modifiersubtext</key>
32+
<string></string>
33+
<key>vitoclose</key>
34+
<false/>
35+
</dict>
36+
</array>
37+
<key>816667CB-E309-42DA-A6AE-856C215E2717</key>
38+
<array>
39+
<dict>
40+
<key>destinationuid</key>
41+
<string>364D5B17-7D02-459C-B600-80915440E331</string>
42+
<key>modifiers</key>
43+
<integer>0</integer>
44+
<key>modifiersubtext</key>
45+
<string></string>
46+
<key>vitoclose</key>
47+
<false/>
48+
</dict>
49+
</array>
50+
</dict>
51+
<key>createdby</key>
52+
<string>cdpath</string>
53+
<key>description</key>
54+
<string></string>
55+
<key>disabled</key>
56+
<false/>
57+
<key>name</key>
58+
<string>Clipboard::Convert2MarkdownTable</string>
59+
<key>objects</key>
60+
<array>
61+
<dict>
62+
<key>config</key>
63+
<dict>
64+
<key>concurrently</key>
65+
<false/>
66+
<key>escaping</key>
67+
<integer>102</integer>
68+
<key>script</key>
69+
<string>query=$1
70+
71+
osascript -e 'the clipboard as "HTML"'|perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))'</string>
72+
<key>scriptargtype</key>
73+
<integer>1</integer>
74+
<key>scriptfile</key>
75+
<string></string>
76+
<key>type</key>
77+
<integer>0</integer>
78+
</dict>
79+
<key>type</key>
80+
<string>alfred.workflow.action.script</string>
81+
<key>uid</key>
82+
<string>364D5B17-7D02-459C-B600-80915440E331</string>
83+
<key>version</key>
84+
<integer>2</integer>
85+
</dict>
86+
<dict>
87+
<key>config</key>
88+
<dict>
89+
<key>concurrently</key>
90+
<false/>
91+
<key>escaping</key>
92+
<integer>68</integer>
93+
<key>script</key>
94+
<string># -*- coding: utf-8 -*-
95+
96+
import sys
97+
98+
from parser import HTMLTableParser
99+
100+
101+
def generate_markdown_table(table):
102+
table = iter(table[0])
103+
header = next(table)
104+
header = '|'.join(header)
105+
separator = '|'.join(['---']*len(header))
106+
sys.stdout.write(header+'\n')
107+
sys.stdout.write(separator+'\n')
108+
for t in table:
109+
t = '|'.join(t)
110+
sys.stdout.write(t+'\n')
111+
112+
query = sys.argv[1]
113+
114+
parser = HTMLTableParser()
115+
parser.feed(query)
116+
117+
generate_markdown_table(parser.tables)</string>
118+
<key>scriptargtype</key>
119+
<integer>1</integer>
120+
<key>scriptfile</key>
121+
<string></string>
122+
<key>type</key>
123+
<integer>3</integer>
124+
</dict>
125+
<key>type</key>
126+
<string>alfred.workflow.action.script</string>
127+
<key>uid</key>
128+
<string>145D1882-556B-484B-9830-BBE2E7EC3DB4</string>
129+
<key>version</key>
130+
<integer>2</integer>
131+
</dict>
132+
<dict>
133+
<key>config</key>
134+
<dict>
135+
<key>autopaste</key>
136+
<true/>
137+
<key>clipboardtext</key>
138+
<string></string>
139+
<key>transient</key>
140+
<true/>
141+
</dict>
142+
<key>type</key>
143+
<string>alfred.workflow.output.clipboard</string>
144+
<key>uid</key>
145+
<string>E244FEC6-9942-4EC6-A9D8-BBE08A039FDB</string>
146+
<key>version</key>
147+
<integer>2</integer>
148+
</dict>
149+
<dict>
150+
<key>config</key>
151+
<dict>
152+
<key>action</key>
153+
<integer>0</integer>
154+
<key>argument</key>
155+
<integer>2</integer>
156+
<key>focusedappvariable</key>
157+
<false/>
158+
<key>focusedappvariablename</key>
159+
<string>kindle</string>
160+
<key>hotkey</key>
161+
<integer>17</integer>
162+
<key>hotmod</key>
163+
<integer>1310720</integer>
164+
<key>hotstring</key>
165+
<string>T</string>
166+
<key>leftcursor</key>
167+
<false/>
168+
<key>modsmode</key>
169+
<integer>0</integer>
170+
<key>relatedAppsMode</key>
171+
<integer>0</integer>
172+
</dict>
173+
<key>type</key>
174+
<string>alfred.workflow.trigger.hotkey</string>
175+
<key>uid</key>
176+
<string>816667CB-E309-42DA-A6AE-856C215E2717</string>
177+
<key>version</key>
178+
<integer>2</integer>
179+
</dict>
180+
</array>
181+
<key>readme</key>
182+
<string>Acknowledge
183+
184+
1. https://github.com/schmijos/html-table-parser-python3</string>
185+
<key>uidata</key>
186+
<dict>
187+
<key>145D1882-556B-484B-9830-BBE2E7EC3DB4</key>
188+
<dict>
189+
<key>xpos</key>
190+
<integer>370</integer>
191+
<key>ypos</key>
192+
<integer>110</integer>
193+
</dict>
194+
<key>364D5B17-7D02-459C-B600-80915440E331</key>
195+
<dict>
196+
<key>xpos</key>
197+
<integer>220</integer>
198+
<key>ypos</key>
199+
<integer>110</integer>
200+
</dict>
201+
<key>816667CB-E309-42DA-A6AE-856C215E2717</key>
202+
<dict>
203+
<key>xpos</key>
204+
<integer>60</integer>
205+
<key>ypos</key>
206+
<integer>110</integer>
207+
</dict>
208+
<key>E244FEC6-9942-4EC6-A9D8-BBE08A039FDB</key>
209+
<dict>
210+
<key>xpos</key>
211+
<integer>520</integer>
212+
<key>ypos</key>
213+
<integer>110</integer>
214+
</dict>
215+
</dict>
216+
<key>version</key>
217+
<string>0.0.1</string>
218+
<key>webaddress</key>
219+
<string></string>
220+
</dict>
221+
</plist>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# -----------------------------------------------------------------------------
2+
# Name: html_table_parser
3+
# Purpose: Simple class for parsing an (x)html string to extract tables.
4+
# Written in python3
5+
#
6+
# Author: Josua Schmid
7+
#
8+
# Created: 05.03.2014
9+
# Copyright: (c) Josua Schmid 2014
10+
# Licence: AGPLv3
11+
# -----------------------------------------------------------------------------
12+
import sys
13+
14+
if sys.version < '3':
15+
from HTMLParser import HTMLParser
16+
else:
17+
from html.parser import HTMLParser
18+
19+
20+
class HTMLTableParser(HTMLParser):
21+
""" This class serves as a html table parser. It is able to parse multiple
22+
tables which you feed in. You can access the result per .tables field.
23+
"""
24+
def __init__(
25+
self,
26+
decode_html_entities=False,
27+
data_separator=' ',
28+
):
29+
30+
HTMLParser.__init__(self)
31+
32+
self._parse_html_entities = decode_html_entities
33+
self._data_separator = data_separator
34+
35+
self._in_td = False
36+
self._in_th = False
37+
self._current_table = []
38+
self._current_row = []
39+
self._current_cell = []
40+
self.tables = []
41+
42+
def handle_starttag(self, tag, attrs):
43+
""" We need to remember the opening point for the content of interest.
44+
The other tags (<table>, <tr>) are only handled at the closing point.
45+
"""
46+
if tag == 'td':
47+
self._in_td = True
48+
if tag == 'th':
49+
self._in_th = True
50+
51+
def handle_data(self, data):
52+
""" This is where we save content to a cell """
53+
if self._in_td or self._in_th:
54+
self._current_cell.append(data.strip())
55+
56+
def handle_charref(self, name):
57+
""" Handle HTML encoded characters """
58+
59+
if self._parse_html_entities:
60+
self.handle_data(self.unescape('&#{};'.format(name)))
61+
62+
def handle_endtag(self, tag):
63+
""" Here we exit the tags. If the closing tag is </tr>, we know that we
64+
can save our currently parsed cells to the current table as a row and
65+
prepare for a new row. If the closing tag is </table>, we save the
66+
current table and prepare for a new one.
67+
"""
68+
if tag == 'td':
69+
self._in_td = False
70+
elif tag == 'th':
71+
self._in_th = False
72+
73+
if tag in ['td', 'th']:
74+
final_cell = self._data_separator.join(self._current_cell).strip()
75+
self._current_row.append(final_cell)
76+
self._current_cell = []
77+
elif tag == 'tr':
78+
self._current_table.append(self._current_row)
79+
self._current_row = []
80+
elif tag == 'table':
81+
self.tables.append(self._current_table)
82+
self._current_table = []

0 commit comments

Comments
 (0)