forked from matplotlib/matplotlib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathembed_js.py
102 lines (85 loc) · 3.36 KB
/
embed_js.py
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
"""
Script to embed JavaScript dependencies in mpl.js.
"""
from collections import namedtuple
from pathlib import Path
import re
import shutil
import subprocess
import sys
Package = namedtuple('Package', [
# The package to embed, in some form that `npm install` can use.
'name',
# The path to the source file within the package to embed.
'source',
# The path to the license file within the package to embed.
'license'])
# The list of packages to embed, in some form that `npm install` can use.
JAVASCRIPT_PACKAGES = [
# Polyfill/ponyfill for ResizeObserver.
Package('@jsxtools/resize-observer', 'index.js', 'LICENSE.md'),
]
# This is the magic line that must exist in mpl.js, after which the embedded
# JavaScript will be appended.
MPLJS_MAGIC_HEADER = (
"///////////////// REMAINING CONTENT GENERATED BY embed_js.py "
"/////////////////\n")
def safe_name(name):
"""
Make *name* safe to use as a JavaScript variable name.
"""
return '_'.join(re.split(r'[@/-]', name)).upper()
def prep_package(web_backend_path, pkg):
source = web_backend_path / 'node_modules' / pkg.name / pkg.source
license = web_backend_path / 'node_modules' / pkg.name / pkg.license
if not source.exists():
# Exact version should already be saved in package.json, so we use
# --no-save here.
try:
subprocess.run(['npm', 'install', '--no-save', pkg.name],
cwd=web_backend_path)
except FileNotFoundError as err:
raise ValueError(
f'npm must be installed to fetch {pkg.name}') from err
if not source.exists():
raise ValueError(
f'{pkg.name} package is missing source in {pkg.source}')
elif not license.exists():
raise ValueError(
f'{pkg.name} package is missing license in {pkg.license}')
return source, license
def gen_embedded_lines(pkg, source):
name = safe_name(pkg.name)
print('Embedding', source, 'as', name)
yield '// prettier-ignore\n'
for line in source.read_text().splitlines():
yield (line.replace('module.exports=function', f'var {name}=function')
+ ' // eslint-disable-line\n')
def build_mpljs(web_backend_path, license_path):
mpljs_path = web_backend_path / "js/mpl.js"
mpljs_orig = mpljs_path.read_text().splitlines(keepends=True)
try:
mpljs_orig = mpljs_orig[:mpljs_orig.index(MPLJS_MAGIC_HEADER) + 1]
except IndexError as err:
raise ValueError(
f'The mpl.js file *must* have the exact line: {MPLJS_MAGIC_HEADER}'
) from err
with mpljs_path.open('w') as mpljs:
mpljs.writelines(mpljs_orig)
for pkg in JAVASCRIPT_PACKAGES:
source, license = prep_package(web_backend_path, pkg)
mpljs.writelines(gen_embedded_lines(pkg, source))
shutil.copy(license,
license_path / f'LICENSE{safe_name(pkg.name)}')
if __name__ == '__main__':
# Write the mpl.js file.
if len(sys.argv) > 1:
web_backend_path = Path(sys.argv[1])
else:
web_backend_path = (Path(__file__).parent.parent /
"lib/matplotlib/backends/web_backend")
if len(sys.argv) > 2:
license_path = Path(sys.argv[2])
else:
license_path = Path(__file__).parent.parent / "LICENSE"
build_mpljs(web_backend_path, license_path)