passagemath-repl 10.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_repl-10.5.1.data/scripts/sage-cachegrind +25 -0
- passagemath_repl-10.5.1.data/scripts/sage-callgrind +16 -0
- passagemath_repl-10.5.1.data/scripts/sage-cleaner +230 -0
- passagemath_repl-10.5.1.data/scripts/sage-coverage +327 -0
- passagemath_repl-10.5.1.data/scripts/sage-eval +14 -0
- passagemath_repl-10.5.1.data/scripts/sage-fixdoctests +710 -0
- passagemath_repl-10.5.1.data/scripts/sage-inline-fortran +12 -0
- passagemath_repl-10.5.1.data/scripts/sage-ipynb2rst +50 -0
- passagemath_repl-10.5.1.data/scripts/sage-ipython +16 -0
- passagemath_repl-10.5.1.data/scripts/sage-massif +25 -0
- passagemath_repl-10.5.1.data/scripts/sage-notebook +267 -0
- passagemath_repl-10.5.1.data/scripts/sage-omega +25 -0
- passagemath_repl-10.5.1.data/scripts/sage-preparse +302 -0
- passagemath_repl-10.5.1.data/scripts/sage-run +27 -0
- passagemath_repl-10.5.1.data/scripts/sage-run-cython +10 -0
- passagemath_repl-10.5.1.data/scripts/sage-runtests +9 -0
- passagemath_repl-10.5.1.data/scripts/sage-startuptime.py +163 -0
- passagemath_repl-10.5.1.data/scripts/sage-valgrind +34 -0
- passagemath_repl-10.5.1.dist-info/METADATA +77 -0
- passagemath_repl-10.5.1.dist-info/RECORD +162 -0
- passagemath_repl-10.5.1.dist-info/WHEEL +5 -0
- passagemath_repl-10.5.1.dist-info/top_level.txt +1 -0
- sage/all__sagemath_repl.py +119 -0
- sage/doctest/__init__.py +4 -0
- sage/doctest/__main__.py +236 -0
- sage/doctest/all.py +4 -0
- sage/doctest/check_tolerance.py +261 -0
- sage/doctest/control.py +1727 -0
- sage/doctest/external.py +534 -0
- sage/doctest/fixtures.py +383 -0
- sage/doctest/forker.py +2665 -0
- sage/doctest/marked_output.py +102 -0
- sage/doctest/parsing.py +1708 -0
- sage/doctest/parsing_test.py +79 -0
- sage/doctest/reporting.py +733 -0
- sage/doctest/rif_tol.py +124 -0
- sage/doctest/sources.py +1657 -0
- sage/doctest/test.py +584 -0
- sage/doctest/tests/1second.rst +4 -0
- sage/doctest/tests/99seconds.rst +4 -0
- sage/doctest/tests/abort.rst +5 -0
- sage/doctest/tests/atexit.rst +7 -0
- sage/doctest/tests/fail_and_die.rst +6 -0
- sage/doctest/tests/initial.rst +15 -0
- sage/doctest/tests/interrupt.rst +7 -0
- sage/doctest/tests/interrupt_diehard.rst +14 -0
- sage/doctest/tests/keyboardinterrupt.rst +11 -0
- sage/doctest/tests/longtime.rst +5 -0
- sage/doctest/tests/nodoctest +5 -0
- sage/doctest/tests/random_seed.rst +4 -0
- sage/doctest/tests/show_skipped.rst +18 -0
- sage/doctest/tests/sig_on.rst +9 -0
- sage/doctest/tests/simple_failure.rst +8 -0
- sage/doctest/tests/sleep_and_raise.rst +106 -0
- sage/doctest/tests/tolerance.rst +31 -0
- sage/doctest/util.py +750 -0
- sage/interfaces/cleaner.py +48 -0
- sage/interfaces/quit.py +163 -0
- sage/misc/all__sagemath_repl.py +51 -0
- sage/misc/banner.py +235 -0
- sage/misc/benchmark.py +221 -0
- sage/misc/classgraph.py +134 -0
- sage/misc/copying.py +22 -0
- sage/misc/cython.py +694 -0
- sage/misc/dev_tools.py +745 -0
- sage/misc/edit_module.py +304 -0
- sage/misc/explain_pickle.py +3079 -0
- sage/misc/gperftools.py +361 -0
- sage/misc/inline_fortran.py +212 -0
- sage/misc/messaging.py +86 -0
- sage/misc/pager.py +21 -0
- sage/misc/profiler.py +179 -0
- sage/misc/python.py +70 -0
- sage/misc/remote_file.py +53 -0
- sage/misc/sage_eval.py +249 -0
- sage/misc/sage_input.py +3621 -0
- sage/misc/sagedoc.py +1742 -0
- sage/misc/sh.py +38 -0
- sage/misc/trace.py +90 -0
- sage/repl/__init__.py +16 -0
- sage/repl/all.py +15 -0
- sage/repl/attach.py +625 -0
- sage/repl/configuration.py +186 -0
- sage/repl/display/__init__.py +1 -0
- sage/repl/display/fancy_repr.py +354 -0
- sage/repl/display/formatter.py +318 -0
- sage/repl/display/jsmol_iframe.py +290 -0
- sage/repl/display/pretty_print.py +153 -0
- sage/repl/display/util.py +163 -0
- sage/repl/image.py +302 -0
- sage/repl/inputhook.py +91 -0
- sage/repl/interface_magic.py +298 -0
- sage/repl/interpreter.py +854 -0
- sage/repl/ipython_extension.py +593 -0
- sage/repl/ipython_kernel/__init__.py +1 -0
- sage/repl/ipython_kernel/__main__.py +4 -0
- sage/repl/ipython_kernel/all_jupyter.py +10 -0
- sage/repl/ipython_kernel/install.py +301 -0
- sage/repl/ipython_kernel/interact.py +278 -0
- sage/repl/ipython_kernel/kernel.py +217 -0
- sage/repl/ipython_kernel/widgets.py +466 -0
- sage/repl/ipython_kernel/widgets_sagenb.py +587 -0
- sage/repl/ipython_tests.py +163 -0
- sage/repl/load.py +326 -0
- sage/repl/preparse.py +2218 -0
- sage/repl/prompts.py +90 -0
- sage/repl/rich_output/__init__.py +4 -0
- sage/repl/rich_output/backend_base.py +648 -0
- sage/repl/rich_output/backend_doctest.py +316 -0
- sage/repl/rich_output/backend_emacs.py +151 -0
- sage/repl/rich_output/backend_ipython.py +596 -0
- sage/repl/rich_output/buffer.py +311 -0
- sage/repl/rich_output/display_manager.py +829 -0
- sage/repl/rich_output/example.avi +0 -0
- sage/repl/rich_output/example.canvas3d +1 -0
- sage/repl/rich_output/example.dvi +0 -0
- sage/repl/rich_output/example.flv +0 -0
- sage/repl/rich_output/example.gif +0 -0
- sage/repl/rich_output/example.jpg +0 -0
- sage/repl/rich_output/example.mkv +0 -0
- sage/repl/rich_output/example.mov +0 -0
- sage/repl/rich_output/example.mp4 +0 -0
- sage/repl/rich_output/example.ogv +0 -0
- sage/repl/rich_output/example.pdf +0 -0
- sage/repl/rich_output/example.png +0 -0
- sage/repl/rich_output/example.svg +54 -0
- sage/repl/rich_output/example.webm +0 -0
- sage/repl/rich_output/example.wmv +0 -0
- sage/repl/rich_output/example_jmol.spt.zip +0 -0
- sage/repl/rich_output/example_wavefront_scene.mtl +7 -0
- sage/repl/rich_output/example_wavefront_scene.obj +17 -0
- sage/repl/rich_output/output_basic.py +391 -0
- sage/repl/rich_output/output_browser.py +103 -0
- sage/repl/rich_output/output_catalog.py +54 -0
- sage/repl/rich_output/output_graphics.py +320 -0
- sage/repl/rich_output/output_graphics3d.py +345 -0
- sage/repl/rich_output/output_video.py +231 -0
- sage/repl/rich_output/preferences.py +432 -0
- sage/repl/rich_output/pretty_print.py +339 -0
- sage/repl/rich_output/test_backend.py +201 -0
- sage/repl/user_globals.py +214 -0
- sage/tests/all.py +0 -0
- sage/tests/all__sagemath_repl.py +3 -0
- sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py +630 -0
- sage/tests/arxiv_0812_2725.py +351 -0
- sage/tests/benchmark.py +1925 -0
- sage/tests/book_schilling_zabrocki_kschur_primer.py +795 -0
- sage/tests/book_stein_ent.py +651 -0
- sage/tests/book_stein_modform.py +558 -0
- sage/tests/cmdline.py +796 -0
- sage/tests/combinatorial_hopf_algebras.py +52 -0
- sage/tests/finite_poset.py +623 -0
- sage/tests/functools_partial_src.py +27 -0
- sage/tests/gosper-sum.py +218 -0
- sage/tests/lazy_imports.py +28 -0
- sage/tests/modular_group_cohomology.py +80 -0
- sage/tests/numpy.py +21 -0
- sage/tests/parigp.py +76 -0
- sage/tests/startup.py +27 -0
- sage/tests/symbolic-series.py +76 -0
- sage/tests/sympy.py +16 -0
- sage/tests/test_deprecation.py +31 -0
@@ -0,0 +1,320 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-repl
|
2
|
+
r"""
|
3
|
+
Graphics Output Types
|
4
|
+
|
5
|
+
This module defines the rich output types for 2-d images, both vector
|
6
|
+
and raster graphics.
|
7
|
+
"""
|
8
|
+
|
9
|
+
# ****************************************************************************
|
10
|
+
# Copyright (C) 2015 Volker Braun <vbraun.name@gmail.com>
|
11
|
+
#
|
12
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
13
|
+
# as published by the Free Software Foundation; either version 2 of
|
14
|
+
# the License, or (at your option) any later version.
|
15
|
+
# https://www.gnu.org/licenses/
|
16
|
+
# ****************************************************************************
|
17
|
+
import base64
|
18
|
+
import importlib.resources
|
19
|
+
|
20
|
+
from sage.cpython.string import bytes_to_str
|
21
|
+
from sage.repl.rich_output.output_basic import OutputBase
|
22
|
+
from sage.repl.rich_output.buffer import OutputBuffer
|
23
|
+
|
24
|
+
|
25
|
+
class OutputImagePng(OutputBase):
|
26
|
+
|
27
|
+
def __init__(self, png):
|
28
|
+
"""
|
29
|
+
PNG Image.
|
30
|
+
|
31
|
+
.. NOTE::
|
32
|
+
|
33
|
+
Every backend that is capable of displaying any kind of
|
34
|
+
graphics is supposed to support the PNG format at least.
|
35
|
+
|
36
|
+
INPUT:
|
37
|
+
|
38
|
+
- ``png`` --
|
39
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively,
|
40
|
+
a string (bytes) can be passed directly which will then be
|
41
|
+
converted into an
|
42
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. The
|
43
|
+
PNG image data.
|
44
|
+
|
45
|
+
EXAMPLES::
|
46
|
+
|
47
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImagePng
|
48
|
+
sage: OutputImagePng.example() # indirect doctest
|
49
|
+
OutputImagePng container
|
50
|
+
"""
|
51
|
+
self.png = OutputBuffer(png)
|
52
|
+
|
53
|
+
@classmethod
|
54
|
+
def example(cls):
|
55
|
+
r"""
|
56
|
+
Construct a sample PNG output container.
|
57
|
+
|
58
|
+
This static method is meant for doctests, so they can easily
|
59
|
+
construct an example.
|
60
|
+
|
61
|
+
OUTPUT: an instance of :class:`OutputImagePng`
|
62
|
+
|
63
|
+
EXAMPLES::
|
64
|
+
|
65
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImagePng
|
66
|
+
sage: OutputImagePng.example()
|
67
|
+
OutputImagePng container
|
68
|
+
sage: OutputImagePng.example().png
|
69
|
+
buffer containing 608 bytes
|
70
|
+
sage: OutputImagePng.example().png.get().startswith(b'\x89PNG')
|
71
|
+
True
|
72
|
+
"""
|
73
|
+
return cls(importlib.resources.read_binary(__package__, 'example.png'))
|
74
|
+
|
75
|
+
|
76
|
+
class OutputImageGif(OutputBase):
|
77
|
+
|
78
|
+
def __init__(self, gif):
|
79
|
+
"""
|
80
|
+
GIF Image (possibly animated).
|
81
|
+
|
82
|
+
INPUT:
|
83
|
+
|
84
|
+
- ``gif`` --
|
85
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively,
|
86
|
+
a string (bytes) can be passed directly which will then be
|
87
|
+
converted into an
|
88
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. The
|
89
|
+
GIF image data.
|
90
|
+
|
91
|
+
EXAMPLES::
|
92
|
+
|
93
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImageGif
|
94
|
+
sage: OutputImageGif.example() # indirect doctest
|
95
|
+
OutputImageGif container
|
96
|
+
"""
|
97
|
+
self.gif = OutputBuffer(gif)
|
98
|
+
|
99
|
+
@classmethod
|
100
|
+
def example(cls):
|
101
|
+
r"""
|
102
|
+
Construct a sample GIF output container.
|
103
|
+
|
104
|
+
This static method is meant for doctests, so they can easily
|
105
|
+
construct an example.
|
106
|
+
|
107
|
+
OUTPUT: an instance of :class:`OutputImageGif`
|
108
|
+
|
109
|
+
EXAMPLES::
|
110
|
+
|
111
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImageGif
|
112
|
+
sage: OutputImageGif.example()
|
113
|
+
OutputImageGif container
|
114
|
+
sage: OutputImageGif.example().gif
|
115
|
+
buffer containing 408 bytes
|
116
|
+
sage: OutputImageGif.example().gif.get().startswith(b'GIF89a')
|
117
|
+
True
|
118
|
+
"""
|
119
|
+
return cls(importlib.resources.read_binary(__package__, 'example.gif'))
|
120
|
+
|
121
|
+
def html_fragment(self):
|
122
|
+
"""
|
123
|
+
Return a self-contained HTML fragment displaying the image.
|
124
|
+
|
125
|
+
This is a workaround for the Jupyter notebook which doesn't support GIF directly.
|
126
|
+
|
127
|
+
OUTPUT: string. HTML fragment for displaying the GIF image
|
128
|
+
|
129
|
+
EXAMPLES::
|
130
|
+
|
131
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImageGif
|
132
|
+
sage: OutputImageGif.example().html_fragment()
|
133
|
+
'<img src="data:image/gif;base64,R0lGODl...zd3t/g4eLj5OVDQQA7"/>'
|
134
|
+
"""
|
135
|
+
b64 = bytes_to_str(base64.b64encode(self.gif.get()), 'ascii')
|
136
|
+
return '<img src="data:image/gif;base64,{0}"/>'.format(b64)
|
137
|
+
|
138
|
+
|
139
|
+
class OutputImageJpg(OutputBase):
|
140
|
+
|
141
|
+
def __init__(self, jpg):
|
142
|
+
"""
|
143
|
+
JPEG Image.
|
144
|
+
|
145
|
+
INPUT:
|
146
|
+
|
147
|
+
- ``jpg`` --
|
148
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively,
|
149
|
+
a string (bytes) can be passed directly which will then be
|
150
|
+
converted into an
|
151
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. The
|
152
|
+
JPEG image data.
|
153
|
+
|
154
|
+
EXAMPLES::
|
155
|
+
|
156
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImageJpg
|
157
|
+
sage: OutputImageJpg.example() # indirect doctest
|
158
|
+
OutputImageJpg container
|
159
|
+
"""
|
160
|
+
self.jpg = OutputBuffer(jpg)
|
161
|
+
|
162
|
+
@classmethod
|
163
|
+
def example(cls):
|
164
|
+
r"""
|
165
|
+
Construct a sample JPEG output container.
|
166
|
+
|
167
|
+
This static method is meant for doctests, so they can easily
|
168
|
+
construct an example.
|
169
|
+
|
170
|
+
OUTPUT: an instance of :class:`OutputImageJpg`
|
171
|
+
|
172
|
+
EXAMPLES::
|
173
|
+
|
174
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImageJpg
|
175
|
+
sage: OutputImageJpg.example()
|
176
|
+
OutputImageJpg container
|
177
|
+
sage: OutputImageJpg.example().jpg
|
178
|
+
buffer containing 978 bytes
|
179
|
+
sage: OutputImageJpg.example().jpg.get().startswith(b'\xff\xd8\xff\xe0\x00\x10JFIF')
|
180
|
+
True
|
181
|
+
"""
|
182
|
+
return cls(importlib.resources.read_binary(__package__, 'example.jpg'))
|
183
|
+
|
184
|
+
|
185
|
+
class OutputImageSvg(OutputBase):
|
186
|
+
|
187
|
+
def __init__(self, svg):
|
188
|
+
"""
|
189
|
+
SVG Image.
|
190
|
+
|
191
|
+
INPUT:
|
192
|
+
|
193
|
+
- ``svg`` --
|
194
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively,
|
195
|
+
a string (bytes) can be passed directly which will then be
|
196
|
+
converted into an
|
197
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. The
|
198
|
+
SVG image data.
|
199
|
+
|
200
|
+
EXAMPLES::
|
201
|
+
|
202
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImageSvg
|
203
|
+
sage: OutputImageSvg.example() # indirect doctest
|
204
|
+
OutputImageSvg container
|
205
|
+
"""
|
206
|
+
self.svg = OutputBuffer(svg)
|
207
|
+
|
208
|
+
@classmethod
|
209
|
+
def example(cls):
|
210
|
+
r"""
|
211
|
+
Construct a sample SVG output container.
|
212
|
+
|
213
|
+
This static method is meant for doctests, so they can easily
|
214
|
+
construct an example.
|
215
|
+
|
216
|
+
OUTPUT: an instance of :class:`OutputImageSvg`
|
217
|
+
|
218
|
+
EXAMPLES::
|
219
|
+
|
220
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImageSvg
|
221
|
+
sage: OutputImageSvg.example()
|
222
|
+
OutputImageSvg container
|
223
|
+
sage: OutputImageSvg.example().svg
|
224
|
+
buffer containing 1422 bytes
|
225
|
+
sage: b'</svg>' in OutputImageSvg.example().svg.get()
|
226
|
+
True
|
227
|
+
"""
|
228
|
+
return cls(importlib.resources.read_binary(__package__, 'example.svg'))
|
229
|
+
|
230
|
+
|
231
|
+
class OutputImagePdf(OutputBase):
|
232
|
+
|
233
|
+
def __init__(self, pdf):
|
234
|
+
"""
|
235
|
+
PDF Image.
|
236
|
+
|
237
|
+
INPUT:
|
238
|
+
|
239
|
+
- ``pdf`` --
|
240
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively,
|
241
|
+
a string (bytes) can be passed directly which will then be
|
242
|
+
converted into an
|
243
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. The
|
244
|
+
PDF data.
|
245
|
+
|
246
|
+
EXAMPLES::
|
247
|
+
|
248
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImagePdf
|
249
|
+
sage: OutputImagePdf.example() # indirect doctest
|
250
|
+
OutputImagePdf container
|
251
|
+
"""
|
252
|
+
self.pdf = OutputBuffer(pdf)
|
253
|
+
|
254
|
+
@classmethod
|
255
|
+
def example(cls):
|
256
|
+
r"""
|
257
|
+
Construct a sample PDF output container.
|
258
|
+
|
259
|
+
This static method is meant for doctests, so they can easily
|
260
|
+
construct an example.
|
261
|
+
|
262
|
+
OUTPUT: an instance of :class:`OutputImagePdf`
|
263
|
+
|
264
|
+
EXAMPLES::
|
265
|
+
|
266
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImagePdf
|
267
|
+
sage: OutputImagePdf.example()
|
268
|
+
OutputImagePdf container
|
269
|
+
sage: OutputImagePdf.example().pdf
|
270
|
+
buffer containing 4285 bytes
|
271
|
+
sage: OutputImagePdf.example().pdf.get().startswith(b'%PDF-1.4')
|
272
|
+
True
|
273
|
+
"""
|
274
|
+
return cls(importlib.resources.read_binary(__package__, 'example.pdf'))
|
275
|
+
|
276
|
+
|
277
|
+
class OutputImageDvi(OutputBase):
|
278
|
+
|
279
|
+
def __init__(self, dvi):
|
280
|
+
"""
|
281
|
+
DVI Image.
|
282
|
+
|
283
|
+
INPUT:
|
284
|
+
|
285
|
+
- ``dvi`` --
|
286
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively,
|
287
|
+
a string (bytes) can be passed directly which will then be
|
288
|
+
converted into an
|
289
|
+
:class:`~sage.repl.rich_output.buffer.OutputBuffer`. The
|
290
|
+
DVI data.
|
291
|
+
|
292
|
+
EXAMPLES::
|
293
|
+
|
294
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImageDvi
|
295
|
+
sage: OutputImageDvi.example() # indirect doctest
|
296
|
+
OutputImageDvi container
|
297
|
+
"""
|
298
|
+
self.dvi = OutputBuffer(dvi)
|
299
|
+
|
300
|
+
@classmethod
|
301
|
+
def example(cls):
|
302
|
+
r"""
|
303
|
+
Construct a sample DVI output container.
|
304
|
+
|
305
|
+
This static method is meant for doctests, so they can easily
|
306
|
+
construct an example.
|
307
|
+
|
308
|
+
OUTPUT: an instance of :class:`OutputImageDvi`
|
309
|
+
|
310
|
+
EXAMPLES::
|
311
|
+
|
312
|
+
sage: from sage.repl.rich_output.output_catalog import OutputImageDvi
|
313
|
+
sage: OutputImageDvi.example()
|
314
|
+
OutputImageDvi container
|
315
|
+
sage: OutputImageDvi.example().dvi
|
316
|
+
buffer containing 212 bytes
|
317
|
+
sage: b'TeX output' in OutputImageDvi.example().dvi.get()
|
318
|
+
True
|
319
|
+
"""
|
320
|
+
return cls(importlib.resources.read_binary(__package__, 'example.dvi'))
|
@@ -0,0 +1,345 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-repl
|
2
|
+
r"""
|
3
|
+
Three-Dimensional Graphics Output Types
|
4
|
+
|
5
|
+
This module defines the rich output types for 3-d scenes.
|
6
|
+
"""
|
7
|
+
# ****************************************************************************
|
8
|
+
# Copyright (C) 2015 Volker Braun <vbraun.name@gmail.com>
|
9
|
+
#
|
10
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
11
|
+
# as published by the Free Software Foundation; either version 2 of
|
12
|
+
# the License, or (at your option) any later version.
|
13
|
+
# https://www.gnu.org/licenses/
|
14
|
+
# ****************************************************************************
|
15
|
+
import os
|
16
|
+
import importlib.resources
|
17
|
+
|
18
|
+
from sage.cpython.string import bytes_to_str, FS_ENCODING
|
19
|
+
from sage.repl.rich_output.output_basic import OutputBase
|
20
|
+
from sage.repl.rich_output.buffer import OutputBuffer
|
21
|
+
|
22
|
+
|
23
|
+
class OutputSceneJmol(OutputBase):
|
24
|
+
|
25
|
+
def __init__(self, scene_zip, preview_png):
|
26
|
+
"""
|
27
|
+
JMol Scene.
|
28
|
+
|
29
|
+
By our (Sage) convention, the actual scene is called ``SCENE``
|
30
|
+
inside the zip archive.
|
31
|
+
|
32
|
+
INPUT:
|
33
|
+
|
34
|
+
- ``scene_zip`` -- string/bytes; the jmol scene (a zip archive)
|
35
|
+
|
36
|
+
- ``preview_png`` -- string/bytes; preview as png file
|
37
|
+
|
38
|
+
EXAMPLES::
|
39
|
+
|
40
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneJmol
|
41
|
+
sage: OutputSceneJmol.example()
|
42
|
+
OutputSceneJmol container
|
43
|
+
"""
|
44
|
+
self.scene_zip = OutputBuffer(scene_zip)
|
45
|
+
self.preview_png = OutputBuffer(preview_png)
|
46
|
+
|
47
|
+
def launch_script_filename(self):
|
48
|
+
"""
|
49
|
+
Return a launch script suitable to display the scene.
|
50
|
+
|
51
|
+
This method saves the scene to disk and creates a launch
|
52
|
+
script. The latter contains an absolute path to the scene
|
53
|
+
file. The launch script is often necessary to make jmol
|
54
|
+
render the 3d scene.
|
55
|
+
|
56
|
+
OUTPUT: string; the file name of a suitable launch script
|
57
|
+
|
58
|
+
EXAMPLES::
|
59
|
+
|
60
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneJmol
|
61
|
+
sage: rich_output = OutputSceneJmol.example(); rich_output
|
62
|
+
OutputSceneJmol container
|
63
|
+
sage: filename = rich_output.launch_script_filename(); filename
|
64
|
+
'/.../scene.spt'
|
65
|
+
sage: with open(filename) as fobj:
|
66
|
+
....: print(fobj.read())
|
67
|
+
set defaultdirectory "/.../scene.spt.zip"
|
68
|
+
script SCRIPT
|
69
|
+
"""
|
70
|
+
from sage.misc.temporary_file import tmp_dir
|
71
|
+
basedir = tmp_dir()
|
72
|
+
scene_filename = os.path.join(basedir, 'scene.spt.zip')
|
73
|
+
script_filename = os.path.join(basedir, 'scene.spt')
|
74
|
+
self.scene_zip.save_as(scene_filename)
|
75
|
+
with open(script_filename, 'w') as f:
|
76
|
+
f.write('set defaultdirectory "{0}"\n'.format(scene_filename))
|
77
|
+
f.write('script SCRIPT\n')
|
78
|
+
return script_filename
|
79
|
+
|
80
|
+
@classmethod
|
81
|
+
def example(cls):
|
82
|
+
r"""
|
83
|
+
Construct a sample Jmol output container.
|
84
|
+
|
85
|
+
This static method is meant for doctests, so they can easily
|
86
|
+
construct an example.
|
87
|
+
|
88
|
+
OUTPUT: an instance of :class:`OutputSceneJmol`
|
89
|
+
|
90
|
+
EXAMPLES::
|
91
|
+
|
92
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneJmol
|
93
|
+
sage: rich_output = OutputSceneJmol.example(); rich_output
|
94
|
+
OutputSceneJmol container
|
95
|
+
|
96
|
+
sage: rich_output.scene_zip
|
97
|
+
buffer containing 654 bytes
|
98
|
+
sage: rich_output.scene_zip.get().startswith(b'PK')
|
99
|
+
True
|
100
|
+
|
101
|
+
sage: rich_output.preview_png
|
102
|
+
buffer containing 608 bytes
|
103
|
+
sage: rich_output.preview_png.get().startswith(b'\x89PNG')
|
104
|
+
True
|
105
|
+
"""
|
106
|
+
example_png = importlib.resources.read_binary(__package__, 'example.png')
|
107
|
+
scene_zip = importlib.resources.read_binary(__package__, 'example_jmol.spt.zip')
|
108
|
+
return cls(scene_zip, example_png)
|
109
|
+
|
110
|
+
|
111
|
+
class OutputSceneCanvas3d(OutputBase):
|
112
|
+
|
113
|
+
def __init__(self, canvas3d):
|
114
|
+
"""
|
115
|
+
Canvas3d Scene.
|
116
|
+
|
117
|
+
INPUT:
|
118
|
+
|
119
|
+
- ``canvas3d`` -- string/bytes; the canvas3d data
|
120
|
+
|
121
|
+
EXAMPLES::
|
122
|
+
|
123
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneCanvas3d
|
124
|
+
sage: OutputSceneCanvas3d.example()
|
125
|
+
OutputSceneCanvas3d container
|
126
|
+
"""
|
127
|
+
self.canvas3d = OutputBuffer(canvas3d)
|
128
|
+
|
129
|
+
@classmethod
|
130
|
+
def example(cls):
|
131
|
+
r"""
|
132
|
+
Construct a sample Canvas3D output container.
|
133
|
+
|
134
|
+
This static method is meant for doctests, so they can easily
|
135
|
+
construct an example.
|
136
|
+
|
137
|
+
OUTPUT: an instance of :class:`OutputSceneCanvas3d`
|
138
|
+
|
139
|
+
EXAMPLES::
|
140
|
+
|
141
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneCanvas3d
|
142
|
+
sage: rich_output = OutputSceneCanvas3d.example(); rich_output
|
143
|
+
OutputSceneCanvas3d container
|
144
|
+
|
145
|
+
sage: rich_output.canvas3d
|
146
|
+
buffer containing 829 bytes
|
147
|
+
sage: rich_output.canvas3d.get_str()
|
148
|
+
'[{"vertices":[{"x":1,"y":1,"z":1},...{"x":1,"y":-1,"z":-1}],"faces":[[0,1,2,3]],"color":"008000"}]'
|
149
|
+
"""
|
150
|
+
with importlib.resources.path(__package__, 'example.canvas3d') as filename:
|
151
|
+
return cls(OutputBuffer.from_file(filename))
|
152
|
+
|
153
|
+
|
154
|
+
class OutputSceneThreejs(OutputBase):
|
155
|
+
|
156
|
+
def __init__(self, html):
|
157
|
+
"""
|
158
|
+
Three.js Scene.
|
159
|
+
|
160
|
+
INPUT:
|
161
|
+
|
162
|
+
- ``html`` -- string/bytes; the Three.js HTML data
|
163
|
+
|
164
|
+
EXAMPLES::
|
165
|
+
|
166
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneThreejs
|
167
|
+
sage: OutputSceneThreejs('<html></html>')
|
168
|
+
OutputSceneThreejs container
|
169
|
+
"""
|
170
|
+
self.html = OutputBuffer(html)
|
171
|
+
|
172
|
+
|
173
|
+
class OutputSceneWavefront(OutputBase):
|
174
|
+
|
175
|
+
def __init__(self, obj, mtl):
|
176
|
+
"""
|
177
|
+
Wavefront `*.obj` Scene.
|
178
|
+
|
179
|
+
The Wavefront format consists of two files, an ``.obj`` file
|
180
|
+
defining the geometry data (mesh points, normal vectors, ...)
|
181
|
+
together with a ``.mtl`` file defining texture data.
|
182
|
+
|
183
|
+
INPUT:
|
184
|
+
|
185
|
+
- ``obj`` -- bytes; the Wavefront obj file format describing
|
186
|
+
the mesh shape
|
187
|
+
|
188
|
+
- ``mtl`` -- bytes; the Wavefront mtl file format describing
|
189
|
+
textures
|
190
|
+
|
191
|
+
EXAMPLES::
|
192
|
+
|
193
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront
|
194
|
+
sage: OutputSceneWavefront.example()
|
195
|
+
OutputSceneWavefront container
|
196
|
+
"""
|
197
|
+
self.obj = OutputBuffer(obj)
|
198
|
+
self.mtl = OutputBuffer(mtl)
|
199
|
+
self._check_no_directory(self.mtllib())
|
200
|
+
|
201
|
+
def _check_no_directory(self, filename):
|
202
|
+
"""
|
203
|
+
Verify that ``filename`` does not contain a path.
|
204
|
+
|
205
|
+
We disallow anything but plain filenames since it is a
|
206
|
+
potential security issue to point :meth:`mtllib` at random
|
207
|
+
paths.
|
208
|
+
|
209
|
+
INPUT:
|
210
|
+
|
211
|
+
- ``filename`` -- string; a filename
|
212
|
+
|
213
|
+
OUTPUT:
|
214
|
+
|
215
|
+
This method returns nothing. A :exc:`ValueError` is raised if
|
216
|
+
``filename`` is not just a plain filename but contains a
|
217
|
+
directory (relative or absolute).
|
218
|
+
|
219
|
+
EXAMPLES::
|
220
|
+
|
221
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront
|
222
|
+
sage: rich_output = OutputSceneWavefront.example()
|
223
|
+
sage: rich_output._check_no_directory('scene.mtl')
|
224
|
+
sage: rich_output._check_no_directory('/scene.mtl')
|
225
|
+
Traceback (most recent call last):
|
226
|
+
...
|
227
|
+
ValueError: must be pure filename, got directory component: /scene.mtl
|
228
|
+
sage: rich_output._check_no_directory('relative/scene.mtl')
|
229
|
+
Traceback (most recent call last):
|
230
|
+
...
|
231
|
+
ValueError: must be pure filename, got directory component: relative/scene.mtl
|
232
|
+
sage: rich_output._check_no_directory('/absolute/scene.mtl')
|
233
|
+
Traceback (most recent call last):
|
234
|
+
...
|
235
|
+
ValueError: must be pure filename, got directory component: /absolute/scene.mtl
|
236
|
+
"""
|
237
|
+
if os.path.split(filename)[0]:
|
238
|
+
raise ValueError('must be pure filename, got directory component: {0}'
|
239
|
+
.format(filename))
|
240
|
+
|
241
|
+
def mtllib(self):
|
242
|
+
"""
|
243
|
+
Return the ``mtllib`` filename.
|
244
|
+
|
245
|
+
The ``mtllib`` line in the Wavefront file format (``*.obj``)
|
246
|
+
is the name of the separate texture file.
|
247
|
+
|
248
|
+
OUTPUT:
|
249
|
+
|
250
|
+
String. The filename under which ``mtl`` is supposed to be
|
251
|
+
saved.
|
252
|
+
|
253
|
+
EXAMPLES::
|
254
|
+
|
255
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront
|
256
|
+
sage: rich_output = OutputSceneWavefront.example()
|
257
|
+
sage: rich_output.mtllib()
|
258
|
+
'scene.mtl'
|
259
|
+
"""
|
260
|
+
marker = b'mtllib '
|
261
|
+
for line in self.obj.get().splitlines():
|
262
|
+
if line.startswith(marker):
|
263
|
+
return bytes_to_str(line[len(marker):], FS_ENCODING,
|
264
|
+
'surrogateescape')
|
265
|
+
return 'scene.mtl'
|
266
|
+
|
267
|
+
def obj_filename(self):
|
268
|
+
"""
|
269
|
+
Return the file name of the ``.obj`` file.
|
270
|
+
|
271
|
+
This method saves the object and texture to separate files in
|
272
|
+
a temporary directory and returns the object file name. This
|
273
|
+
is often used to launch a 3d viewer.
|
274
|
+
|
275
|
+
OUTPUT:
|
276
|
+
|
277
|
+
String. The file name (absolute path) of the saved obj file.
|
278
|
+
|
279
|
+
EXAMPLES::
|
280
|
+
|
281
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront
|
282
|
+
sage: rich_output = OutputSceneWavefront.example(); rich_output
|
283
|
+
OutputSceneWavefront container
|
284
|
+
sage: obj = rich_output.obj_filename(); obj
|
285
|
+
'/.../scene.obj'
|
286
|
+
sage: with open(obj) as fobj:
|
287
|
+
....: print(fobj.read())
|
288
|
+
mtllib scene.mtl
|
289
|
+
g obj_1
|
290
|
+
...
|
291
|
+
f 3 2 6 8
|
292
|
+
|
293
|
+
sage: path = os.path.dirname(obj)
|
294
|
+
sage: mtl = os.path.join(path, 'scene.mtl'); mtl
|
295
|
+
'/.../scene.mtl'
|
296
|
+
sage: os.path.exists(mtl)
|
297
|
+
True
|
298
|
+
sage: os.path.dirname(obj) == os.path.dirname(mtl)
|
299
|
+
True
|
300
|
+
sage: with open(mtl) as fobj:
|
301
|
+
....: print(fobj.read())
|
302
|
+
newmtl texture177
|
303
|
+
Ka 0.2 0.2 0.5
|
304
|
+
...
|
305
|
+
d 1
|
306
|
+
"""
|
307
|
+
from sage.misc.temporary_file import tmp_dir
|
308
|
+
basedir = tmp_dir()
|
309
|
+
obj_filename = os.path.join(basedir, 'scene.obj')
|
310
|
+
mtl_filename = os.path.join(basedir, self.mtllib())
|
311
|
+
self.obj.save_as(obj_filename)
|
312
|
+
self.mtl.save_as(mtl_filename)
|
313
|
+
return os.path.abspath(obj_filename)
|
314
|
+
|
315
|
+
@classmethod
|
316
|
+
def example(cls):
|
317
|
+
r"""
|
318
|
+
Construct a sample Canvas3D output container.
|
319
|
+
|
320
|
+
This static method is meant for doctests, so they can easily
|
321
|
+
construct an example.
|
322
|
+
|
323
|
+
OUTPUT: an instance of :class:`OutputSceneCanvas3d`
|
324
|
+
|
325
|
+
EXAMPLES::
|
326
|
+
|
327
|
+
sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront
|
328
|
+
sage: rich_output = OutputSceneWavefront.example(); rich_output
|
329
|
+
OutputSceneWavefront container
|
330
|
+
|
331
|
+
sage: rich_output.obj
|
332
|
+
buffer containing 227 bytes
|
333
|
+
sage: rich_output.obj.get_str()
|
334
|
+
'mtllib scene.mtl\ng obj_1\n...\nf 1 5 6 2\nf 1 4 7 5\nf 6 5 7 8\nf 7 4 3 8\nf 3 2 6 8\n'
|
335
|
+
|
336
|
+
sage: rich_output.mtl
|
337
|
+
buffer containing 80 bytes
|
338
|
+
sage: rich_output.mtl.get_str()
|
339
|
+
'newmtl texture177\nKa 0.2 0.2 0.5\nKd 0.4 0.4 1.0\nKs 0.0 0.0 0.0\nillum 1\nNs 1\nd 1\n'
|
340
|
+
"""
|
341
|
+
with importlib.resources.path(__package__, 'example_wavefront_scene.obj') as filename:
|
342
|
+
scene_obj = OutputBuffer.from_file(filename)
|
343
|
+
with importlib.resources.path(__package__, 'example_wavefront_scene.mtl') as filename:
|
344
|
+
scene_mtl = OutputBuffer.from_file(filename)
|
345
|
+
return cls(scene_obj, scene_mtl)
|