Skip to content

Commit 7dfff8b

Browse files
committed
threejs: access files through features, for simpler configuration
1 parent 7cecbff commit 7dfff8b

File tree

5 files changed

+81
-26
lines changed

5 files changed

+81
-26
lines changed

src/sage/env.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st
214214
JMOL_DIR = var("JMOL_DIR")
215215
MATHJAX_DIR = var("MATHJAX_DIR", join(SAGE_SHARE, "mathjax"))
216216
MTXLIB = var("MTXLIB", join(SAGE_SHARE, "meataxe"))
217-
THREEJS_DIR = var("THREEJS_DIR", join(SAGE_SHARE, "threejs-sage"))
217+
THREEJS_DIR = var("THREEJS_DIR")
218218
PPLPY_DOCS = var("PPLPY_DOCS", join(SAGE_SHARE, "doc", "pplpy"))
219219
MAXIMA = var("MAXIMA", "maxima")
220220
MAXIMA_FAS = var("MAXIMA_FAS")

src/sage/features/threejs.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import os
2+
3+
from . import StaticFile
4+
5+
6+
class Threejs(StaticFile):
7+
r"""
8+
A :class:`~sage.features.Feature` which describes the presence of
9+
threejs-sage in a few standard locations.
10+
11+
EXAMPLES::
12+
13+
sage: from sage.features.threejs import Threejs
14+
sage: bool(Threejs().is_present()) # needs threejs
15+
True
16+
"""
17+
18+
def __init__(self):
19+
r"""
20+
TESTS::
21+
22+
sage: from sage.features.threejs import Threejs
23+
sage: isinstance(Threejs(), Threejs)
24+
True
25+
"""
26+
from sage.env import SAGE_SHARE, THREEJS_DIR
27+
28+
version = self.required_version()
29+
30+
threejs_search_path = THREEJS_DIR or (
31+
os.path.join(SAGE_SHARE, "jupyter", "nbextensions", "threejs-sage"),
32+
os.path.join(SAGE_SHARE, "sagemath", "threejs-sage"),
33+
os.path.join(SAGE_SHARE, "sage", "threejs"),
34+
os.path.join(SAGE_SHARE, "threejs-sage")
35+
)
36+
37+
StaticFile.__init__(
38+
self, name="threejs",
39+
filename=os.path.join(version, "three.min.js"),
40+
spkg="threejs",
41+
type="standard",
42+
search_path=threejs_search_path,
43+
description="JavaScript library to display 3D graphics")
44+
45+
def required_version(self):
46+
"""
47+
Return the version of threejs that Sage requires.
48+
49+
EXAMPLES::
50+
51+
sage: from sage.features.threejs import Threejs
52+
sage: Threejs().required_version()
53+
'r...'
54+
"""
55+
from sage.env import SAGE_EXTCODE
56+
57+
filename = os.path.join(SAGE_EXTCODE, 'threejs', 'threejs-version.txt')
58+
59+
with open(filename) as f:
60+
return f.read().strip()
61+
62+
63+
def all_features():
64+
return [Threejs()]

src/sage/repl/ipython_kernel/install.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
SAGE_EXTCODE,
2424
SAGE_VENV,
2525
SAGE_VERSION,
26-
THREEJS_DIR,
2726
)
2827

2928

@@ -123,14 +122,18 @@ def use_local_threejs(self):
123122
124123
EXAMPLES::
125124
125+
sage: # needs threejs
126126
sage: from sage.repl.ipython_kernel.install import SageKernelSpec
127127
sage: spec = SageKernelSpec(prefix=tmp_dir())
128128
sage: spec.use_local_threejs()
129129
sage: threejs = os.path.join(spec.nbextensions_dir, 'threejs-sage')
130130
sage: os.path.isdir(threejs)
131131
True
132132
"""
133-
src = THREEJS_DIR
133+
from sage.features.threejs import Threejs
134+
if not Threejs().is_present():
135+
return
136+
src = os.path.dirname(os.path.dirname(Threejs().absolute_filename()))
134137
dst = os.path.join(self.nbextensions_dir, 'threejs-sage')
135138
self.symlink(src, dst)
136139

src/sage/repl/rich_output/backend_ipython.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -409,15 +409,18 @@ def threejs_offline_scripts(self):
409409
410410
EXAMPLES::
411411
412+
sage: # needs threejs
412413
sage: from sage.repl.rich_output.backend_ipython import BackendIPythonCommandline
413414
sage: backend = BackendIPythonCommandline()
414-
sage: backend.threejs_offline_scripts() # needs sage.plot
415+
sage: backend.threejs_offline_scripts()
415416
'...<script ...</script>...'
416417
"""
417-
from sage.env import THREEJS_DIR
418-
from sage.repl.rich_output.display_manager import _required_threejs_version
418+
from sage.features.threejs import Threejs
419+
420+
if not Threejs().is_present():
421+
return ''
419422

420-
script = os.path.join(THREEJS_DIR, '{}/three.min.js'.format(_required_threejs_version()))
423+
script = Threejs().absolute_filename()
421424

422425
return '\n<script src="{0}"></script>'.format(script)
423426

@@ -596,12 +599,12 @@ def threejs_offline_scripts(self):
596599
'...<script src="/nbextensions/threejs-sage/r.../three.min.js...<\\/script>...'
597600
"""
598601
from sage.repl.rich_output import get_display_manager
599-
from sage.repl.rich_output.display_manager import _required_threejs_version
602+
from sage.features.threejs import Threejs
600603
CDN_script = get_display_manager().threejs_scripts(online=True)
601604
CDN_script = CDN_script.replace('</script>', r'<\/script>').replace('\n', ' \\\n')
602605
return """
603606
<script src="/nbextensions/threejs-sage/{}/three.min.js"></script>
604607
<script>
605608
if ( !window.THREE ) document.write('{}');
606609
</script>
607-
""".format(_required_threejs_version(), CDN_script)
610+
""".format(Threejs().required_version(), CDN_script)

src/sage/repl/rich_output/display_manager.py

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,6 @@
4646
from sage.repl.rich_output.preferences import DisplayPreferences
4747

4848

49-
def _required_threejs_version():
50-
"""
51-
Return the version of threejs that Sage requires.
52-
53-
EXAMPLES::
54-
55-
sage: from sage.repl.rich_output.display_manager import _required_threejs_version
56-
sage: _required_threejs_version() # needs sage.plot
57-
'r...'
58-
"""
59-
import os
60-
import sage.env
61-
with open(os.path.join(sage.env.SAGE_EXTCODE, 'threejs', 'threejs-version.txt')) as f:
62-
return f.read().strip()
63-
64-
6549
class DisplayException(Exception):
6650
"""
6751
Base exception for all rich output-related exceptions.
@@ -768,8 +752,9 @@ def threejs_scripts(self, online):
768752
ValueError: current backend does not support
769753
offline threejs graphics
770754
"""
755+
from sage.features.threejs import Threejs
771756
if online:
772-
version = _required_threejs_version()
757+
version = Threejs().required_version()
773758
return """
774759
<script src="https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@{0}/build/three.min.js"></script>
775760
""".format(version)

0 commit comments

Comments
 (0)