1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#!/usr/bin/env python3
import glob
import html
import json
import os
import re
import shutil
import toml
def get_features(dirname):
features = {}
for feature in sorted(os.listdir('caniuse.rs/data/' + dirname)):
with open('caniuse.rs/data/' + dirname + '/' + feature) as f:
name = feature.split('.')[0]
features[name] = toml.load(f)
return features
with open('caniuse.rs/data/versions.toml') as f:
versions = toml.load(f)
for version, data in versions.items():
try:
data['features'] = get_features(version)
except FileNotFoundError:
pass
unstable_features = get_features('unstable')
os.makedirs('target', exist_ok=True)
shutil.copy('style.css', 'target')
with open('target/data.json', 'w') as f:
json.dump(dict(unstable=unstable_features, versions=versions), f)
def write_features(f, feature_data):
features = {}
for feat, data in feature_data.items():
key = data['flag'] if 'flag' in data else feat
# caniuse.rs sometimes has several .toml files for one feature flag e.g.
# For the const_io feature flag it has 6 .toml files, all with the same
# tracking_issue_id and the following titles:
#
# * `io::Cursor::get_ref` as `const fn`
# * `io::Cursor::new` as `const fn`
# * `io::Cursor::position` as `const fn`
# * `io::empty` as `const fn`
# * `io::repeat` as `const fn`
# * `io::sink` as `const fn`
#
# That makes sense for a search-centric application. Not so much for a
# static-site generator since showing the same link 6 times is confusing.
url = None
if 'tracking_issue_id' in data:
url = 'https://github.com/rust-lang/rust/issues/{}'.format(
data['tracking_issue_id']
)
elif 'impl_pr_id' in data:
url = 'https://github.com/rust-lang/rust/pull/{}'.format(data['impl_pr_id'])
data['url'] = url
data['filename'] = feat
if data['title'].startswith('the '):
data['title'] = data['title'][len('the '):]
data['title'] = data['title'].replace('implementation', 'impl')
if key in features:
data['title'] = data['flag'].replace('_', ' ')
if key in features and features[key]['url'] != url:
print(
'different urls for feature {}:\n* {}: {}\n* {}: {}'.format(
key,
data['filename'],
data['url'],
features[key]['filename'],
features[key]['url'],
)
)
features[key] = data
features = sorted(features.items(), key=lambda t: t[1]['title'].replace('`', '').lower())
f.write('<ul>')
for feat, data in features:
f.write('<li><a')
url = data['url']
if url:
f.write(f' href="{url}"')
f.write('>')
title = html.escape(data['title'])
title = re.sub('`(.+?)`', lambda m: '<code>{}</code>'.format(m.group(1)), title)
f.write(title)
f.write('</a></li>')
f.write('</ul>')
with open('target/index.html', 'w') as f:
f.write('<!doctype html>')
f.write('<meta charset=utf-8>')
f.write('<title>Rust features</title>')
f.write('<h1>Rust features</h1>')
f.write('<link rel="stylesheet" href="style.css" />')
# TODO: sort by T-lang and T-lib
f.write('<h2>Unstable features</h2>')
write_features(f, unstable_features)
for version, data in reversed(list(versions.items())):
f.write('<h2>{}</h2>'.format(version))
if 'features' in data:
write_features(f, data['features'])
# TODO: generate HTML
|