passagemath-repl 10.4.62__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.
Files changed (162) hide show
  1. passagemath_repl-10.4.62.data/scripts/sage-cachegrind +25 -0
  2. passagemath_repl-10.4.62.data/scripts/sage-callgrind +16 -0
  3. passagemath_repl-10.4.62.data/scripts/sage-cleaner +230 -0
  4. passagemath_repl-10.4.62.data/scripts/sage-coverage +327 -0
  5. passagemath_repl-10.4.62.data/scripts/sage-eval +14 -0
  6. passagemath_repl-10.4.62.data/scripts/sage-fixdoctests +708 -0
  7. passagemath_repl-10.4.62.data/scripts/sage-inline-fortran +12 -0
  8. passagemath_repl-10.4.62.data/scripts/sage-ipynb2rst +50 -0
  9. passagemath_repl-10.4.62.data/scripts/sage-ipython +16 -0
  10. passagemath_repl-10.4.62.data/scripts/sage-massif +25 -0
  11. passagemath_repl-10.4.62.data/scripts/sage-notebook +267 -0
  12. passagemath_repl-10.4.62.data/scripts/sage-omega +25 -0
  13. passagemath_repl-10.4.62.data/scripts/sage-preparse +302 -0
  14. passagemath_repl-10.4.62.data/scripts/sage-run +27 -0
  15. passagemath_repl-10.4.62.data/scripts/sage-run-cython +10 -0
  16. passagemath_repl-10.4.62.data/scripts/sage-runtests +9 -0
  17. passagemath_repl-10.4.62.data/scripts/sage-startuptime.py +163 -0
  18. passagemath_repl-10.4.62.data/scripts/sage-valgrind +34 -0
  19. passagemath_repl-10.4.62.dist-info/METADATA +77 -0
  20. passagemath_repl-10.4.62.dist-info/RECORD +162 -0
  21. passagemath_repl-10.4.62.dist-info/WHEEL +5 -0
  22. passagemath_repl-10.4.62.dist-info/top_level.txt +1 -0
  23. sage/all__sagemath_repl.py +119 -0
  24. sage/doctest/__init__.py +4 -0
  25. sage/doctest/__main__.py +236 -0
  26. sage/doctest/all.py +4 -0
  27. sage/doctest/check_tolerance.py +261 -0
  28. sage/doctest/control.py +1727 -0
  29. sage/doctest/external.py +534 -0
  30. sage/doctest/fixtures.py +383 -0
  31. sage/doctest/forker.py +2665 -0
  32. sage/doctest/marked_output.py +102 -0
  33. sage/doctest/parsing.py +1708 -0
  34. sage/doctest/parsing_test.py +79 -0
  35. sage/doctest/reporting.py +733 -0
  36. sage/doctest/rif_tol.py +124 -0
  37. sage/doctest/sources.py +1657 -0
  38. sage/doctest/test.py +584 -0
  39. sage/doctest/tests/1second.rst +4 -0
  40. sage/doctest/tests/99seconds.rst +4 -0
  41. sage/doctest/tests/abort.rst +5 -0
  42. sage/doctest/tests/atexit.rst +7 -0
  43. sage/doctest/tests/fail_and_die.rst +6 -0
  44. sage/doctest/tests/initial.rst +15 -0
  45. sage/doctest/tests/interrupt.rst +7 -0
  46. sage/doctest/tests/interrupt_diehard.rst +14 -0
  47. sage/doctest/tests/keyboardinterrupt.rst +11 -0
  48. sage/doctest/tests/longtime.rst +5 -0
  49. sage/doctest/tests/nodoctest +5 -0
  50. sage/doctest/tests/random_seed.rst +4 -0
  51. sage/doctest/tests/show_skipped.rst +18 -0
  52. sage/doctest/tests/sig_on.rst +9 -0
  53. sage/doctest/tests/simple_failure.rst +8 -0
  54. sage/doctest/tests/sleep_and_raise.rst +106 -0
  55. sage/doctest/tests/tolerance.rst +31 -0
  56. sage/doctest/util.py +750 -0
  57. sage/interfaces/cleaner.py +48 -0
  58. sage/interfaces/quit.py +163 -0
  59. sage/misc/all__sagemath_repl.py +51 -0
  60. sage/misc/banner.py +235 -0
  61. sage/misc/benchmark.py +221 -0
  62. sage/misc/classgraph.py +131 -0
  63. sage/misc/copying.py +22 -0
  64. sage/misc/cython.py +694 -0
  65. sage/misc/dev_tools.py +745 -0
  66. sage/misc/edit_module.py +304 -0
  67. sage/misc/explain_pickle.py +3079 -0
  68. sage/misc/gperftools.py +361 -0
  69. sage/misc/inline_fortran.py +212 -0
  70. sage/misc/messaging.py +86 -0
  71. sage/misc/pager.py +21 -0
  72. sage/misc/profiler.py +179 -0
  73. sage/misc/python.py +70 -0
  74. sage/misc/remote_file.py +53 -0
  75. sage/misc/sage_eval.py +246 -0
  76. sage/misc/sage_input.py +3621 -0
  77. sage/misc/sagedoc.py +1742 -0
  78. sage/misc/sh.py +38 -0
  79. sage/misc/trace.py +90 -0
  80. sage/repl/__init__.py +16 -0
  81. sage/repl/all.py +15 -0
  82. sage/repl/attach.py +625 -0
  83. sage/repl/configuration.py +186 -0
  84. sage/repl/display/__init__.py +1 -0
  85. sage/repl/display/fancy_repr.py +354 -0
  86. sage/repl/display/formatter.py +318 -0
  87. sage/repl/display/jsmol_iframe.py +290 -0
  88. sage/repl/display/pretty_print.py +153 -0
  89. sage/repl/display/util.py +163 -0
  90. sage/repl/image.py +302 -0
  91. sage/repl/inputhook.py +91 -0
  92. sage/repl/interface_magic.py +298 -0
  93. sage/repl/interpreter.py +854 -0
  94. sage/repl/ipython_extension.py +593 -0
  95. sage/repl/ipython_kernel/__init__.py +1 -0
  96. sage/repl/ipython_kernel/__main__.py +4 -0
  97. sage/repl/ipython_kernel/all_jupyter.py +10 -0
  98. sage/repl/ipython_kernel/install.py +301 -0
  99. sage/repl/ipython_kernel/interact.py +278 -0
  100. sage/repl/ipython_kernel/kernel.py +217 -0
  101. sage/repl/ipython_kernel/widgets.py +466 -0
  102. sage/repl/ipython_kernel/widgets_sagenb.py +587 -0
  103. sage/repl/ipython_tests.py +163 -0
  104. sage/repl/load.py +326 -0
  105. sage/repl/preparse.py +2218 -0
  106. sage/repl/prompts.py +90 -0
  107. sage/repl/rich_output/__init__.py +4 -0
  108. sage/repl/rich_output/backend_base.py +648 -0
  109. sage/repl/rich_output/backend_doctest.py +316 -0
  110. sage/repl/rich_output/backend_emacs.py +151 -0
  111. sage/repl/rich_output/backend_ipython.py +596 -0
  112. sage/repl/rich_output/buffer.py +311 -0
  113. sage/repl/rich_output/display_manager.py +829 -0
  114. sage/repl/rich_output/example.avi +0 -0
  115. sage/repl/rich_output/example.canvas3d +1 -0
  116. sage/repl/rich_output/example.dvi +0 -0
  117. sage/repl/rich_output/example.flv +0 -0
  118. sage/repl/rich_output/example.gif +0 -0
  119. sage/repl/rich_output/example.jpg +0 -0
  120. sage/repl/rich_output/example.mkv +0 -0
  121. sage/repl/rich_output/example.mov +0 -0
  122. sage/repl/rich_output/example.mp4 +0 -0
  123. sage/repl/rich_output/example.ogv +0 -0
  124. sage/repl/rich_output/example.pdf +0 -0
  125. sage/repl/rich_output/example.png +0 -0
  126. sage/repl/rich_output/example.svg +54 -0
  127. sage/repl/rich_output/example.webm +0 -0
  128. sage/repl/rich_output/example.wmv +0 -0
  129. sage/repl/rich_output/example_jmol.spt.zip +0 -0
  130. sage/repl/rich_output/example_wavefront_scene.mtl +7 -0
  131. sage/repl/rich_output/example_wavefront_scene.obj +17 -0
  132. sage/repl/rich_output/output_basic.py +391 -0
  133. sage/repl/rich_output/output_browser.py +103 -0
  134. sage/repl/rich_output/output_catalog.py +54 -0
  135. sage/repl/rich_output/output_graphics.py +320 -0
  136. sage/repl/rich_output/output_graphics3d.py +345 -0
  137. sage/repl/rich_output/output_video.py +231 -0
  138. sage/repl/rich_output/preferences.py +432 -0
  139. sage/repl/rich_output/pretty_print.py +339 -0
  140. sage/repl/rich_output/test_backend.py +201 -0
  141. sage/repl/user_globals.py +214 -0
  142. sage/tests/__init__.py +1 -0
  143. sage/tests/all.py +3 -0
  144. sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py +630 -0
  145. sage/tests/arxiv_0812_2725.py +351 -0
  146. sage/tests/benchmark.py +1923 -0
  147. sage/tests/book_schilling_zabrocki_kschur_primer.py +795 -0
  148. sage/tests/book_stein_ent.py +651 -0
  149. sage/tests/book_stein_modform.py +558 -0
  150. sage/tests/cmdline.py +790 -0
  151. sage/tests/combinatorial_hopf_algebras.py +52 -0
  152. sage/tests/finite_poset.py +623 -0
  153. sage/tests/functools_partial_src.py +27 -0
  154. sage/tests/gosper-sum.py +218 -0
  155. sage/tests/lazy_imports.py +28 -0
  156. sage/tests/modular_group_cohomology.py +80 -0
  157. sage/tests/numpy.py +21 -0
  158. sage/tests/parigp.py +76 -0
  159. sage/tests/startup.py +27 -0
  160. sage/tests/symbolic-series.py +76 -0
  161. sage/tests/sympy.py +16 -0
  162. sage/tests/test_deprecation.py +31 -0
@@ -0,0 +1,318 @@
1
+ # sage_setup: distribution = sagemath-repl
2
+ r"""
3
+ IPython Displayhook Formatters
4
+
5
+ The classes in this module can be used as IPython displayhook
6
+ formatters. It has two main features, by default the displayhook
7
+ contains a new facility for displaying lists of matrices in an easier
8
+ to read format::
9
+
10
+ sage: [identity_matrix(i) for i in range(2, 5)] # needs sage.modules
11
+ [
12
+ [1 0 0 0]
13
+ [1 0 0] [0 1 0 0]
14
+ [1 0] [0 1 0] [0 0 1 0]
15
+ [0 1], [0 0 1], [0 0 0 1]
16
+ ]
17
+
18
+ This facility uses :meth:`_repr_` (and a simple string) to try do a nice read
19
+ format (see :meth:`sage.structure.parent.Parent._repr_option` for details).
20
+
21
+ With this displayhook there exists an other way for displaying object and more
22
+ generally, all sage expression as an ASCII art object::
23
+
24
+ sage: from sage.repl.interpreter import get_test_shell
25
+ sage: shell = get_test_shell()
26
+ sage: shell.run_cell('%display ascii_art')
27
+ sage: shell.run_cell('integral(x^2/pi^x, x)') # needs sage.symbolic
28
+ -x / 2 2 \
29
+ -pi *\x *log (pi) + 2*x*log(pi) + 2/
30
+ --------------------------------------
31
+ 3
32
+ log (pi)
33
+ sage: shell.run_cell("i = var('i')") # needs sage.symbolic
34
+ sage: shell.run_cell('sum(i*x^i, i, 0, 10)') # needs sage.symbolic
35
+ 10 9 8 7 6 5 4 3 2
36
+ 10*x + 9*x + 8*x + 7*x + 6*x + 5*x + 4*x + 3*x + 2*x + x
37
+ sage: shell.run_cell('StandardTableaux(4).list()') # needs sage.combinat
38
+ [
39
+ [ 1 4 1 3
40
+ [ 1 3 4 1 2 4 1 2 3 1 3 1 2 2 2
41
+ [ 1 2 3 4, 2 , 3 , 4 , 2 4, 3 4, 3 , 4 ,
42
+ <BLANKLINE>
43
+ 1 ]
44
+ 1 2 2 ]
45
+ 3 3 ]
46
+ 4 , 4 ]
47
+ sage: shell.run_cell('%display default')
48
+ sage: shell.quit()
49
+
50
+ This other facility uses a simple
51
+ :class:`~sage.typeset.ascii_art.AsciiArt` object (see and
52
+ :meth:`sage.structure.sage_object.SageObject._ascii_art_`). """
53
+
54
+ # ****************************************************************************
55
+ # Copyright (C) 2014 Volker Braun <vbraun.name@gmail.com>
56
+ #
57
+ # Distributed under the terms of the GNU General Public License (GPL)
58
+ # as published by the Free Software Foundation; either version 2 of
59
+ # the License, or (at your option) any later version.
60
+ # https://www.gnu.org/licenses/
61
+ # ****************************************************************************
62
+
63
+ from io import StringIO
64
+
65
+ from IPython.core.formatters import DisplayFormatter, PlainTextFormatter
66
+ from IPython.utils.py3compat import unicode_to_str
67
+ from IPython.core.display import DisplayObject
68
+
69
+ from ipywidgets import Widget
70
+
71
+ from sage.repl.display.pretty_print import SagePrettyPrinter
72
+ from sage.misc.lazy_import import lazy_import
73
+
74
+ IPYTHON_NATIVE_TYPES = (DisplayObject, Widget)
75
+
76
+ PLAIN_TEXT = 'text/plain'
77
+ TEXT_LATEX = 'text/latex'
78
+ TEXT_HTML = 'text/html'
79
+
80
+ lazy_import('matplotlib.figure', 'Figure')
81
+
82
+
83
+ class SageDisplayFormatter(DisplayFormatter):
84
+
85
+ def __init__(self, *args, **kwds):
86
+ """
87
+ This is where the Sage rich objects are translated to IPython.
88
+
89
+ INPUT/OUTPUT: see the IPython documentation
90
+
91
+ EXAMPLES:
92
+
93
+ This is part of how Sage works with the IPython output
94
+ system. It cannot be used in doctests::
95
+
96
+ sage: from sage.repl.display.formatter import SageDisplayFormatter
97
+ sage: fmt = SageDisplayFormatter()
98
+ Traceback (most recent call last):
99
+ ...
100
+ RuntimeError: check failed: current backend is invalid
101
+ """
102
+ super().__init__(*args, **kwds)
103
+ from sage.repl.rich_output.display_manager import get_display_manager
104
+ self.dm = get_display_manager()
105
+ from sage.repl.rich_output.backend_ipython import BackendIPython
106
+ self.dm.check_backend_class(BackendIPython)
107
+
108
+ pt_formatter = self.formatters[PLAIN_TEXT]
109
+ pt_formatter.observe(self._ipython_float_precision_changed,
110
+ names=['float_precision'])
111
+
112
+ def format(self, obj, include=None, exclude=None):
113
+ r"""
114
+ Use the Sage rich output instead of IPython.
115
+
116
+ INPUT/OUTPUT: see the IPython documentation
117
+
118
+ EXAMPLES::
119
+
120
+ sage: [identity_matrix(i) for i in range(3,7)] # needs sage.modules
121
+ [
122
+ [1 0 0 0 0 0]
123
+ [1 0 0 0 0] [0 1 0 0 0 0]
124
+ [1 0 0 0] [0 1 0 0 0] [0 0 1 0 0 0]
125
+ [1 0 0] [0 1 0 0] [0 0 1 0 0] [0 0 0 1 0 0]
126
+ [0 1 0] [0 0 1 0] [0 0 0 1 0] [0 0 0 0 1 0]
127
+ [0 0 1], [0 0 0 1], [0 0 0 0 1], [0 0 0 0 0 1]
128
+ ]
129
+ sage: from sage.repl.interpreter import get_test_shell
130
+ sage: shell = get_test_shell()
131
+ sage: shell.run_cell('%display ascii_art') # indirect doctest
132
+ sage: shell.run_cell("i = var('i')") # needs sage.symbolic
133
+ sage: shell.run_cell('sum(i*x^i, i, 0, 10)') # needs sage.symbolic
134
+ 10 9 8 7 6 5 4 3 2
135
+ 10*x + 9*x + 8*x + 7*x + 6*x + 5*x + 4*x + 3*x + 2*x + x
136
+ sage: shell.run_cell('%display default')
137
+ sage: shell.quit()
138
+
139
+ TESTS::
140
+
141
+ sage: import os
142
+ sage: import importlib.resources
143
+ sage: import warnings
144
+ sage: warnings.filterwarnings('ignore', category=DeprecationWarning,
145
+ ....: message=r'path is deprecated\. Use files\(\) instead\.')
146
+ sage: from sage.repl.rich_output.backend_ipython import BackendIPython
147
+ sage: backend = BackendIPython()
148
+ sage: shell = get_test_shell()
149
+ sage: backend.install(shell=shell)
150
+ sage: shell.run_cell('get_ipython().display_formatter')
151
+ <sage.repl.display.formatter.SageDisplayFormatter object at 0x...>
152
+ sage: shell.run_cell('from IPython.display import Image')
153
+ sage: with importlib.resources.path(sage.repl.rich_output, 'example.png') as example_png:
154
+ ....: shell.run_cell('ipython_image = Image("{0}")'.format(example_png))
155
+ sage: shell.run_cell('ipython_image')
156
+ <IPython.core.display.Image object>
157
+ sage: shell.run_cell('get_ipython().display_formatter.format(ipython_image)')
158
+ ({'image/png': ...,
159
+ 'text/plain': '<IPython.core.display.Image object>'},
160
+ {})
161
+
162
+ Test that IPython images and widgets still work even in latex output mode::
163
+
164
+ sage: shell.run_cell('%display latex') # indirect doctest
165
+ sage: shell.run_cell('set(get_ipython().display_formatter.format(ipython_image)[0].keys())'
166
+ ....: ' == set(["text/plain", "image/png"])')
167
+ True
168
+
169
+ sage: shell.run_cell('import ipywidgets')
170
+ sage: shell.run_cell('slider = ipywidgets.IntSlider()')
171
+ sage: shell.run_cell('get_ipython().display_formatter.format(slider)')
172
+ ...IntSlider(value=0)..., {})
173
+
174
+ sage: shell.run_cell('%display default')
175
+ sage: shell.quit()
176
+
177
+ Test that ``__repr__`` is only called once when generating text output::
178
+
179
+ sage: class Repper():
180
+ ....: def __repr__(self):
181
+ ....: print('__repr__ called')
182
+ ....: return 'I am repper'
183
+ sage: Repper()
184
+ __repr__ called
185
+ I am repper
186
+ """
187
+ sage_format, sage_metadata = self.dm.displayhook(obj)
188
+ assert PLAIN_TEXT in sage_format, 'plain text is always present'
189
+
190
+ # use Sage rich output for any except those native to IPython, but only
191
+ # if it is not plain and dull
192
+ if (not isinstance(obj, IPYTHON_NATIVE_TYPES) and
193
+ not set(sage_format.keys()).issubset([PLAIN_TEXT]) and
194
+ not isinstance(obj, Figure)):
195
+ return sage_format, sage_metadata
196
+
197
+ if self.ipython_display_formatter(obj):
198
+ # object handled itself, don't proceed
199
+ return {}, {}
200
+
201
+ # try IPython display formatter
202
+ if exclude is not None:
203
+ exclude = list(exclude) + [PLAIN_TEXT]
204
+ else:
205
+ exclude = [PLAIN_TEXT]
206
+ ipy_format, ipy_metadata = super().format(obj, include=include, exclude=exclude)
207
+ if not ipy_format:
208
+ return sage_format, sage_metadata
209
+ ipy_format[PLAIN_TEXT] = sage_format[PLAIN_TEXT]
210
+ if PLAIN_TEXT in sage_metadata:
211
+ ipy_metadata[PLAIN_TEXT] = sage_metadata[PLAIN_TEXT]
212
+ return ipy_format, ipy_metadata
213
+
214
+ @staticmethod
215
+ def _ipython_float_precision_changed(change):
216
+ """
217
+ Update the current float precision for the display of matrices in Sage.
218
+
219
+ This function is called when the IPython ``%precision`` magic is
220
+ invoked.
221
+
222
+ TESTS::
223
+
224
+ sage: from sage.repl.interpreter import get_test_shell
225
+ sage: shell = get_test_shell()
226
+ sage: shell.run_cell('%precision 4')
227
+ '%.4f'
228
+ sage: shell.run_cell('matrix.options.precision') # indirect doctest # needs sage.modules
229
+ 4
230
+ sage: shell.run_cell('%precision')
231
+ '%r'
232
+ sage: shell.run_cell('matrix.options.precision') # indirect doctest # needs sage.modules
233
+ None
234
+ """
235
+ try:
236
+ from sage.matrix.constructor import options
237
+ except ImportError:
238
+ pass
239
+ else:
240
+ s = change.new
241
+ if not s:
242
+ # unset the precision
243
+ options.precision = None
244
+ else:
245
+ try:
246
+ prec = int(s)
247
+ if prec >= 0:
248
+ options.precision = prec
249
+ # otherwise ignore the change
250
+ except ValueError:
251
+ pass
252
+
253
+
254
+ class SagePlainTextFormatter(PlainTextFormatter):
255
+
256
+ def __init__(self, *args, **kwds):
257
+ r"""
258
+ Improved plain text IPython formatter.
259
+
260
+ In particular, it correctly print lists of matrices or other
261
+ objects (see
262
+ :meth:`sage.structure.parent.Parent._repr_option`).
263
+
264
+ .. warning::
265
+
266
+ This IPython formatter is NOT used. You could use it to
267
+ enable Sage formatting in IPython, but Sage uses its own
268
+ rich output system that is more flexible and supports
269
+ different backends.
270
+
271
+ INPUT/OUTPUT: see the IPython documentation
272
+
273
+ EXAMPLES::
274
+
275
+ sage: from sage.repl.interpreter import get_test_shell
276
+ sage: shell = get_test_shell()
277
+ sage: shell.display_formatter.formatters['text/plain']
278
+ <IPython.core.formatters.PlainTextFormatter object at 0x...>
279
+ sage: shell.quit()
280
+ """
281
+ super().__init__(*args, **kwds)
282
+
283
+ def __call__(self, obj):
284
+ r"""
285
+ Compute the pretty representation of the object.
286
+
287
+ Adapted from ``IPython.core.formatters.PlainTextPrettyPrint``.
288
+
289
+ INPUT:
290
+
291
+ - ``obj`` -- anything
292
+
293
+ OUTPUT: string; the plain text representation
294
+
295
+ EXAMPLES::
296
+
297
+ sage: from sage.repl.display.formatter import SagePlainTextFormatter
298
+ sage: fmt = SagePlainTextFormatter()
299
+ sage: fmt
300
+ <sage.repl.display.formatter.SagePlainTextFormatter object at 0x...>
301
+ sage: fmt(2)
302
+ ---- calling ipython formatter ----
303
+ '2'
304
+ sage: a = identity_matrix(ZZ, 2) # needs sage.modules
305
+ sage: fmt([a, a]) # needs sage.modules
306
+ ---- calling ipython formatter ----
307
+ '[\n[1 0] [1 0]\n[0 1], [0 1]\n]'
308
+ """
309
+ from sage.doctest import DOCTEST_MODE
310
+ if DOCTEST_MODE:
311
+ # Just to show that this is never executed in any other doctests in the Sage library
312
+ print('---- calling ipython formatter ----')
313
+ stream = StringIO()
314
+ printer = SagePrettyPrinter(
315
+ stream, self.max_width, unicode_to_str(self.newline))
316
+ printer.pretty(obj)
317
+ printer.flush()
318
+ return stream.getvalue()
@@ -0,0 +1,290 @@
1
+ # sage_setup: distribution = sagemath-repl
2
+ """
3
+ HTML Generator for JSmol
4
+
5
+ This is all an evil iframe hack to get JSmol to display 3-d graphics
6
+ while separating JSmol's j2s machinery from your actual web page.
7
+
8
+ There are some caveats for how to load JSmol, in particular it cannot
9
+ just load its code from a ``file://`` uri. To use a html file
10
+ generated by this module, you need
11
+
12
+ * A web server,
13
+
14
+ * The JSmol directory tree must be served by your web server,
15
+
16
+ * The output of :meth:`JSMolHtml.inner_html` or
17
+ :meth:`JSMolHtml.outer_html` must be served by the same web server.
18
+
19
+ See https://github.com/phetsims/molecule-polarity/issues/6 for a
20
+ discussion of loading JSMol.
21
+ """
22
+
23
+ import io
24
+ import os
25
+ import zipfile
26
+
27
+ from sage.cpython.string import bytes_to_str
28
+ from sage.structure.sage_object import SageObject
29
+ from sage.misc.cachefunc import cached_method
30
+
31
+
32
+ INNER_HTML_TEMPLATE = """
33
+ <html>
34
+ <head>
35
+ <style>
36
+ * {{
37
+ margin: 0;
38
+ padding: 0;
39
+ overflow: hidden;
40
+ }}
41
+ body, html {{
42
+ height: 100%;
43
+ width: 100%;
44
+ }}
45
+ </style>
46
+ <script type="text/javascript" src="{path_to_jsmol}/JSmol.min.js"></script>
47
+ </head>
48
+ <body>
49
+ <script type="text/javascript">
50
+ delete Jmol._tracker; // Prevent JSmol from phoning home.
51
+ var script = {script};
52
+ var Info = {{
53
+ width: '{width}',
54
+ height: '{height}',
55
+ debug: false,
56
+ disableInitialConsole: true, // very slow when used with inline mesh
57
+ color: '#3131ff',
58
+ addSelectionOptions: false,
59
+ use: 'HTML5',
60
+ j2sPath: '{path_to_jsmol}/j2s',
61
+ script: script,
62
+ }};
63
+ var jmolApplet0 = Jmol.getApplet('jmolApplet0', Info);
64
+ </script>
65
+ </body>
66
+ </html>
67
+ """
68
+
69
+
70
+ IFRAME_TEMPLATE = """
71
+ <iframe srcdoc="{escaped_inner_html}"
72
+ width="{width}"
73
+ height="{height}"
74
+ style="border: 0;">
75
+ </iframe>
76
+ """
77
+
78
+
79
+ OUTER_HTML_TEMPLATE = """
80
+ <html>
81
+ <head>
82
+ <title>JSmol 3D Scene</title>
83
+ </head>
84
+ </body>
85
+ {iframe}
86
+ </body>
87
+ </html>
88
+ """.format(iframe=IFRAME_TEMPLATE)
89
+
90
+
91
+ class JSMolHtml(SageObject):
92
+
93
+ def __init__(self, jmol, path_to_jsmol=None, width='100%', height='100%'):
94
+ """
95
+ INPUT:
96
+
97
+ - ``jmol`` -- 3-d graphics or
98
+ :class:`sage.repl.rich_output.output_graphics3d.OutputSceneJmol`
99
+ instance. The 3-d scene to show.
100
+
101
+ - ``path_to_jsmol`` -- string (default:
102
+ ``'/nbextensions/jupyter-jsmol/jsmol'``). The path (relative or absolute)
103
+ where ``JSmol.min.js`` is served on the web server.
104
+
105
+ - ``width`` -- integer or string (default:
106
+ ``'100%'``). The width of the JSmol applet using CSS
107
+ dimensions.
108
+
109
+ - ``height`` -- integer or string (default:
110
+ ``'100%'``). The height of the JSmol applet using CSS
111
+ dimensions.
112
+
113
+ EXAMPLES::
114
+
115
+ sage: from sage.repl.display.jsmol_iframe import JSMolHtml
116
+ sage: JSMolHtml(sphere(), width=500, height=300) # needs sage.plot
117
+ JSmol Window 500x300
118
+ """
119
+ from sage.repl.rich_output.output_graphics3d import OutputSceneJmol
120
+ if not isinstance(jmol, OutputSceneJmol):
121
+ jmol = jmol._rich_repr_jmol()
122
+ self._jmol = jmol
123
+ self._zip = zipfile.ZipFile(io.BytesIO(self._jmol.scene_zip.get()))
124
+ if path_to_jsmol is None:
125
+ self._path = os.path.join('/', 'nbextensions', 'jupyter-jsmol', 'jsmol')
126
+ else:
127
+ self._path = path_to_jsmol
128
+ self._width = width
129
+ self._height = height
130
+
131
+ @cached_method
132
+ def script(self):
133
+ r"""
134
+ Return the JMol script file.
135
+
136
+ This method extracts the Jmol script from the Jmol spt file (a
137
+ zip archive) and inlines meshes.
138
+
139
+ OUTPUT: string
140
+
141
+ EXAMPLES::
142
+
143
+ sage: from sage.repl.display.jsmol_iframe import JSMolHtml
144
+ sage: from sage.repl.rich_output.output_graphics3d import OutputSceneJmol
145
+ sage: jsmol = JSMolHtml(OutputSceneJmol.example(), width=500, height=300)
146
+ sage: jsmol.script()
147
+ 'data "model list"\n10\nempt...aliasdisplay on;\n'
148
+ """
149
+ script = []
150
+ with self._zip.open('SCRIPT') as SCRIPT:
151
+ for line in SCRIPT:
152
+ if line.startswith(b'pmesh'):
153
+ command, obj, meshfile = line.split(b' ', 3)
154
+ assert command == b'pmesh'
155
+ if meshfile not in [b'dots\n', b'mesh\n']:
156
+ assert (meshfile.startswith(b'"') and
157
+ meshfile.endswith(b'"\n'))
158
+ meshfile = bytes_to_str(meshfile[1:-2]) # strip quotes
159
+ script += [
160
+ 'pmesh {0} inline "'.format(bytes_to_str(obj)),
161
+ bytes_to_str(self._zip.open(meshfile).read()),
162
+ '"\n'
163
+ ]
164
+ continue
165
+ script += [bytes_to_str(line)]
166
+ return ''.join(script)
167
+
168
+ def js_script(self):
169
+ r"""
170
+ The :meth:`script` as Javascript string.
171
+
172
+ Since the many shortcomings of Javascript include multi-line
173
+ strings, this actually returns Javascript code to reassemble
174
+ the script from a list of strings.
175
+
176
+ OUTPUT:
177
+
178
+ String. Javascript code that evaluates to :meth:`script` as
179
+ Javascript string.
180
+
181
+ EXAMPLES::
182
+
183
+ sage: from sage.repl.display.jsmol_iframe import JSMolHtml
184
+ sage: from sage.repl.rich_output.output_graphics3d import OutputSceneJmol
185
+ sage: jsmol = JSMolHtml(OutputSceneJmol.example(), width=500, height=300)
186
+ sage: print(jsmol.js_script())
187
+ [
188
+ 'data "model list"',
189
+ ...
190
+ 'isosurface fullylit; pmesh o* fullylit; set antialiasdisplay on;',
191
+ ].join('\n');
192
+ """
193
+ script = [r"["]
194
+ for line in self.script().splitlines():
195
+ script += [r" '{0}',".format(line)]
196
+ script += [r"].join('\n');"]
197
+ return '\n'.join(script)
198
+
199
+ def _repr_(self):
200
+ """
201
+ Return as string representation.
202
+
203
+ OUTPUT: string
204
+
205
+ EXAMPLES::
206
+
207
+ sage: from sage.repl.display.jsmol_iframe import JSMolHtml
208
+ sage: from sage.repl.rich_output.output_graphics3d import OutputSceneJmol
209
+ sage: JSMolHtml(OutputSceneJmol.example(), width=500, height=300)._repr_()
210
+ 'JSmol Window 500x300'
211
+ """
212
+ return 'JSmol Window {0}x{1}'.format(self._width, self._height)
213
+
214
+ def inner_html(self):
215
+ """
216
+ Return a HTML document containing a JSmol applet.
217
+
218
+ EXAMPLES::
219
+
220
+ sage: from sage.repl.display.jsmol_iframe import JSMolHtml
221
+ sage: from sage.repl.rich_output.output_graphics3d import OutputSceneJmol
222
+ sage: jmol = JSMolHtml(OutputSceneJmol.example(), width=500, height=300)
223
+ sage: print(jmol.inner_html())
224
+ <html>
225
+ <head>
226
+ <style>
227
+ * {
228
+ margin: 0;
229
+ padding: 0;
230
+ ...
231
+ </html>
232
+ """
233
+ return INNER_HTML_TEMPLATE.format(
234
+ script=self.js_script(),
235
+ width=self._width,
236
+ height=self._height,
237
+ path_to_jsmol=self._path,
238
+ )
239
+
240
+ def iframe(self):
241
+ """
242
+ Return HTML iframe.
243
+
244
+ OUTPUT: string
245
+
246
+ EXAMPLES::
247
+
248
+ sage: from sage.repl.display.jsmol_iframe import JSMolHtml
249
+ sage: from sage.repl.rich_output.output_graphics3d import OutputSceneJmol
250
+ sage: jmol = JSMolHtml(OutputSceneJmol.example())
251
+ sage: print(jmol.iframe())
252
+ <iframe srcdoc="
253
+ ...
254
+ </iframe>
255
+ """
256
+ escaped_inner_html = self.inner_html().replace('"', '&quot;')
257
+ return IFRAME_TEMPLATE.format(width=self._width,
258
+ height=self._height,
259
+ escaped_inner_html=escaped_inner_html)
260
+
261
+ def outer_html(self):
262
+ """
263
+ Return a HTML document containing an iframe with a JSmol applet.
264
+
265
+ OUTPUT: string
266
+
267
+ EXAMPLES::
268
+
269
+ sage: from sage.repl.display.jsmol_iframe import JSMolHtml
270
+ sage: from sage.repl.rich_output.output_graphics3d import OutputSceneJmol
271
+ sage: jmol = JSMolHtml(OutputSceneJmol.example(), width=500, height=300)
272
+ sage: print(jmol.outer_html())
273
+ <html>
274
+ <head>
275
+ <title>JSmol 3D Scene</title>
276
+ </head>
277
+ </body>
278
+ <BLANKLINE>
279
+ <iframe srcdoc="
280
+ ...
281
+ </html>
282
+ """
283
+ escaped_inner_html = self.inner_html().replace('"', '&quot;')
284
+ outer = OUTER_HTML_TEMPLATE.format(
285
+ script=self.js_script(),
286
+ width=self._width,
287
+ height=self._height,
288
+ escaped_inner_html=escaped_inner_html,
289
+ )
290
+ return outer