def __init__(self, obj, mtl): """ Wavefront `*.obj` Scene The Wavefront format consists of two files, an ``.obj`` file defining the geometry data (mesh points, normal vectors, ...) together with a ``.mtl`` file defining texture data. INPUT: - ``obj`` -- bytes. The Wavefront obj file format describing the mesh shape. - ``mtl`` -- bytes. The Wavefront mtl file format describing textures. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: OutputSceneWavefront.example() OutputSceneWavefront container """ self.obj = OutputBuffer(obj) self.mtl = OutputBuffer(mtl) self._check_no_directory(self.mtllib())
def __init__(self, latex): """ LaTeX Output .. note:: The LaTeX commands will only use a subset of LaTeX that can be displayed by MathJax. INPUT: - ``latex`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. String containing the latex equation code. Excludes the surrounding dollar signs / LaTeX equation environment. Also excludes the surrounding MathJax ``<html>`` tag. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: OutputLatex('<html><script type="math/tex; mode=display">1</script></html>') OutputLatex container """ self.latex = OutputBuffer(latex)
def __init__(self, plain_text): """ Plain Text Output INPUT: - ``plain_text`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a bytes (string in Python 2.x) or string (unicode in Python 2.x) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The plain text output. This should always be exactly the same as the (non-rich) output from the ``_repr_`` method. Every backend object must support plain text output as fallback. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputPlainText sage: OutputPlainText('foo') OutputPlainText container """ self.text = OutputBuffer(plain_text)
def __init__(self, html): """ HTML Output INPUT: - ``html`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. String containing the html fragment code. Excludes the surrounding ``<body>`` and ``<html>`` tag. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputHtml sage: OutputHtml('<div>Foo<b>B</b>ar</div>') OutputHtml container """ self.html = OutputBuffer(html) # if the html is a simple wrapper of latex for mathjax rendering, then # the latex string is saved for possible latex output such as Jupyter's # pdf export of a notebook m = latex_re.match(html) if m: mathjax_string = m.group('latex') latex_string = mathjax_string.replace('<', '<') if m.group('mathstart') == r'\[' and m.group('mathend') == r'\]': self.latex = OutputBuffer('$$' + latex_string + '$$') else: self.latex = OutputBuffer('$' + latex_string + '$') else: self.latex = None
def example(cls): r""" Construct a sample Canvas3D output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputSceneCanvas3d`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: rich_output = OutputSceneWavefront.example(); rich_output OutputSceneWavefront container sage: rich_output.obj buffer containing 227 bytes sage: rich_output.obj.get_str() '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' sage: rich_output.mtl buffer containing 80 bytes sage: rich_output.mtl.get_str() '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' """ from sage.env import SAGE_EXTCODE with_path = lambda x: os.path.join( SAGE_EXTCODE, 'doctest', 'rich_output', 'example_wavefront', x) return cls( OutputBuffer.from_file(with_path('scene.obj')), OutputBuffer.from_file(with_path('scene.mtl')), )
def example(cls): r""" Construct a sample Canvas3D output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputSceneCanvas3d`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: rich_output = OutputSceneWavefront.example(); rich_output OutputSceneWavefront container sage: rich_output.obj buffer containing 227 bytes sage: rich_output.obj.get() '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' sage: rich_output.mtl buffer containing 80 bytes sage: rich_output.mtl.get() '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' """ from sage.env import SAGE_EXTCODE with_path = lambda x: os.path.join( SAGE_EXTCODE, 'doctest', 'rich_output', 'example_wavefront', x) return cls( OutputBuffer.from_file(with_path('scene.obj')), OutputBuffer.from_file(with_path('scene.mtl')), )
def __init__(self, unicode_art): """ Unicode Art Output Similar to :class:`OutputAsciiArt` but using the entire unicode range. INPUT: - ``unicode_art`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (unicode in Python 2.x) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Unicode art rendered into a string. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputUnicodeArt sage: OutputUnicodeArt(u':-}') OutputUnicodeArt container """ # Internally, all buffers store bytes. Unicode is always utf-8 # encoded. if not isinstance(unicode_art, bytes): unicode_art = unicode_art.encode('utf-8') self.unicode_art = OutputBuffer(unicode_art)
def __init__(self, plain_text): """ Plain Text Output INPUT: - ``plain_text`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a bytes (string in Python 2.x) or string (unicode in Python 2.x) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The plain text output. This should always be exactly the same as the (non-rich) output from the ``_repr_`` method. Every backend object must support plain text output as fallback. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputPlainText sage: OutputPlainText('foo') OutputPlainText container """ # Internally, all buffers store bytes. Strings/Unicode is always utf-8 # encoded. if isinstance(plain_text, unicode): plain_text = plain_text.encode('utf-8') self.text = OutputBuffer(plain_text)
def example(cls): r""" Construct a sample video output container This static method is meant for doctests, so they can easily construct an example. The method is implemented in the abstract :class:`OutputVideoBase` class, but should get invoked on a concrete subclass for which an actual example can exist. OUTPUT: An instance of the class on which this method is called. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputVideoOgg sage: OutputVideoOgg.example() OutputVideoOgg container sage: OutputVideoOgg.example().video buffer containing 5612 bytes sage: OutputVideoOgg.example().ext '.ogv' sage: OutputVideoOgg.example().mimetype 'video/ogg' """ from sage.env import SAGE_EXTCODE filename = os.path.join(SAGE_EXTCODE, 'doctest', 'rich_output', 'example' + cls.ext) return cls(OutputBuffer.from_file(filename), {'controls': True, 'loop': False})
def example(cls): r""" Construct a sample Canvas3D output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputSceneCanvas3d`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneCanvas3d sage: rich_output = OutputSceneCanvas3d.example(); rich_output OutputSceneCanvas3d container sage: rich_output.canvas3d buffer containing 829 bytes sage: rich_output.canvas3d.get() '[{"vertices":[{"x":1,"y":1,"z":1},...{"x":1,"y":-1,"z":-1}],"faces":[[0,1,2,3]],"color":"008000"}]' """ from sage.env import SAGE_EXTCODE filename = os.path.join(SAGE_EXTCODE, 'doctest', 'rich_output', 'example.canvas3d') return cls(OutputBuffer.from_file(filename))
def example(cls): r""" Construct a sample video output container This static method is meant for doctests, so they can easily construct an example. The method is implemented in the abstract :class:`OutputVideoBase` class, but should get invoked on a concrete subclass for which an actual example can exist. OUTPUT: An instance of the class on which this method is called. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputVideoOgg sage: OutputVideoOgg.example() OutputVideoOgg container sage: OutputVideoOgg.example().video buffer containing 5612 bytes sage: OutputVideoOgg.example().ext '.ogv' sage: OutputVideoOgg.example().mimetype 'video/ogg' """ from sage.env import SAGE_EXTCODE filename = os.path.join(SAGE_EXTCODE, 'doctest', 'rich_output', 'example' + cls.ext) return cls(OutputBuffer.from_file(filename), { 'controls': True, 'loop': False })
def __init__(self, png): """ PNG Image .. NOTE:: Every backend that is capable of displaying any kind of graphics is supposed to support the PNG format at least. INPUT: - ``png`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The PNG image data. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImagePng sage: OutputImagePng.example() # indirect doctest OutputImagePng container """ self.png = OutputBuffer(png)
def __init__(self, unicode_art): """ Unicode Art Output Similar to :class:`OutputAsciiArt` but using the entire unicode range. INPUT: - ``unicode_art`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (unicode in Python 2.x) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Unicode art rendered into a string. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputUnicodeArt sage: OutputUnicodeArt(u':-}') OutputUnicodeArt container """ # Internally, all buffers store bytes. Unicode is always utf-8 # encoded. if isinstance(unicode_art, unicode): unicode_art = unicode_art.encode('utf-8') self.unicode_art = OutputBuffer(unicode_art)
def example(cls): r""" Construct a sample Canvas3D output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputSceneCanvas3d`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneCanvas3d sage: rich_output = OutputSceneCanvas3d.example(); rich_output OutputSceneCanvas3d container sage: rich_output.canvas3d buffer containing 829 bytes sage: rich_output.canvas3d.get_str() '[{"vertices":[{"x":1,"y":1,"z":1},...{"x":1,"y":-1,"z":-1}],"faces":[[0,1,2,3]],"color":"008000"}]' """ from sage.env import SAGE_EXTCODE filename = os.path.join( SAGE_EXTCODE, 'doctest', 'rich_output', 'example.canvas3d') return cls(OutputBuffer.from_file(filename))
def __init__(self, gif): """ GIF Image (possibly animated) INPUT: - ``gif`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The GIF image data. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImageGif sage: OutputImageGif.example() # indirect doctest OutputImageGif container """ self.gif = OutputBuffer(gif)
def __init__(self, ascii_art): """ ASCII Art Output INPUT: - ``ascii_art`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Ascii art rendered into a string. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputAsciiArt sage: OutputAsciiArt(':-}') OutputAsciiArt container """ self.ascii_art = OutputBuffer(ascii_art)
def __init__(self, scene_zip, preview_png): """ JMol Scene By our (Sage) convention, the actual scene is called ``SCENE`` inside the zip archive. INPUT: - ``scene_zip`` -- string/bytes. The jmol scene (a zip archive). - ``preview_png`` -- string/bytes. Preview as png file. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneJmol sage: OutputSceneJmol.example() OutputSceneJmol container """ self.scene_zip = OutputBuffer(scene_zip) self.preview_png = OutputBuffer(preview_png)
def __init__(self, html): """ HTML Output INPUT: - ``html`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. String containing the html fragment code. Excludes the surrounding ``<body>`` and ``<html>`` tag. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputHtml sage: OutputHtml('<div>Foo<b>B</b>ar</div>') OutputHtml container """ self.html = OutputBuffer(html)
def __init__(self, html): """ Three.js Scene INPUT: - ``html`` -- string/bytes. The Three.js HTML data. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneThreejs sage: OutputSceneThreejs('<html></html>') OutputSceneThreejs container """ self.html = OutputBuffer(html)
def __init__(self, canvas3d): """ Canvas3d Scene INPUT: - ``canvas3d`` -- string/bytes. The canvas3d data. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneCanvas3d sage: OutputSceneCanvas3d.example() OutputSceneCanvas3d container """ self.canvas3d = OutputBuffer(canvas3d)
def __init__(self, dvi): """ DVI Image INPUT: - ``dvi`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The DVI data. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImageDvi sage: OutputImageDvi.example() # indirect doctest OutputImageDvi container """ self.dvi = OutputBuffer(dvi)
def __init__(self, pdf): """ PDF Image INPUT: - ``pdf`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The PDF data. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImagePdf sage: OutputImagePdf.example() # indirect doctest OutputImagePdf container """ self.pdf = OutputBuffer(pdf)
def __init__(self, svg): """ SVG Image INPUT: - ``svg`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The SVG image data. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImageSvg sage: OutputImageSvg.example() # indirect doctest OutputImageSvg container """ self.svg = OutputBuffer(svg)
def _rich_repr_(self, display_manager, **kwds): """ Rich Output Magic Method See :mod:`sage.repl.rich_output` for details. EXAMPLES:: sage: from sage.repl.image import Image sage: img = Image('1', (16, 16), 'white') sage: from sage.repl.rich_output import get_display_manager sage: dm = get_display_manager() sage: img._rich_repr_(dm) OutputImagePng container sage: img = Image('F', (16, 16), 'white') # not supported in PNG sage: img._rich_repr_(dm) OutputImageGif container """ if display_manager.preferences.graphics == 'disable': return types = display_manager.types preferred = ( ('PNG', types.OutputImagePng), ('JPEG', types.OutputImageJpg), ('GIF', types.OutputImageGif), ) import StringIO from sage.repl.rich_output.buffer import OutputBuffer for format, output_container in preferred: if output_container in display_manager.supported_output(): stream = StringIO.StringIO() try: self.pil.save(stream, format=format) except IOError: # not all formats support all modes, e.g. no alpha support in gif continue buf = OutputBuffer(stream.getvalue()) return output_container(buf)
def __init__(self, plain_text): """ Plain Text Output INPUT: - ``plain_text`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The plain text output. This should always be exactly the same as the (non-rich) output from the ``_repr_`` method. Every backend object must support plain text output as fallback. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputPlainText sage: OutputPlainText('foo') OutputPlainText container """ self.text = OutputBuffer(plain_text)
class OutputLatex(OutputBase): def __init__(self, latex): """ LaTeX Output .. note:: The LaTeX commands will only use a subset of LaTeX that can be displayed by MathJax. INPUT: - ``latex`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. String containing the latex equation code. Excludes the surrounding dollar signs / LaTeX equation environment. Also excludes the surrounding MathJax ``<html>`` tag. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: OutputLatex('<html><script type="math/tex; mode=display">1</script></html>') OutputLatex container """ self.latex = OutputBuffer(latex) def mathjax(self, display=True): r""" Return the LaTeX with a surrounding MathJax HTML code. INPUT: - ``display`` -- boolean. Whether to return display (as opposed to inline) TeX. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: rich_output = OutputLatex('1') sage: rich_output.latex buffer containing 1 bytes sage: rich_output.latex.get() '1' sage: rich_output.mathjax() '<html><script type="math/tex; mode=display">1</script></html>' sage: rich_output.mathjax(display=False) '<html><script type="math/tex">1</script></html>' """ if display: template = r'<html><script type="math/tex; mode=display">{0}</script></html>' else: template = r'<html><script type="math/tex">{0}</script></html>' return template.format(self.latex.get()) def display_equation(self): r""" Return the LaTeX code for a display equation OUTPUT: String. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: rich_output = OutputLatex('1') sage: rich_output.latex buffer containing 1 bytes sage: rich_output.latex.get() '1' sage: rich_output.display_equation() '\\begin{equation}\n1\n\\end{equation}' """ return '\n'.join([r'\begin{equation}', self.latex.get(), r'\end{equation}']) def inline_equation(self): r""" Return the LaTeX code for an inline equation OUTPUT: String. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: rich_output = OutputLatex('1') sage: rich_output.latex buffer containing 1 bytes sage: rich_output.latex.get() '1' sage: rich_output.inline_equation() '\\begin{math}\n1\n\\end{math}' """ return '\n'.join([r'\begin{math}', self.latex.get(), r'\end{math}']) @classmethod def example(cls): r""" Construct a sample LaTeX output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputLatex`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: OutputLatex.example() OutputLatex container sage: OutputLatex.example().latex.get() '\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\int \\sin\\left(x\\right)\\,{d x}' """ return cls(r'\newcommand{\Bold}[1]{\mathbf{#1}}' r'\int \sin\left(x\right)\,{d x}') def print_to_stdout(self): r""" Write the data to stdout. This is just a convenience method to help with debugging. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: rich_output = OutputLatex.example() sage: rich_output.print_to_stdout() \newcommand{\Bold}[1]{\mathbf{#1}}\int \sin\left(x\right)\,{d x} """ print(self.latex.get())
class OutputPlainText(OutputBase): def __init__(self, plain_text): """ Plain Text Output INPUT: - ``plain_text`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a bytes (string in Python 2.x) or string (unicode in Python 2.x) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The plain text output. This should always be exactly the same as the (non-rich) output from the ``_repr_`` method. Every backend object must support plain text output as fallback. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputPlainText sage: OutputPlainText('foo') OutputPlainText container """ # Internally, all buffers store bytes. Strings/Unicode is always utf-8 # encoded. if isinstance(plain_text, unicode): plain_text = plain_text.encode('utf-8') self.text = OutputBuffer(plain_text) @classmethod def example(cls): """ Construct a sample plain text output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputPlainText`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputPlainText sage: OutputPlainText.example() OutputPlainText container sage: OutputPlainText.example().text.get() 'Example plain text output' """ return cls('Example plain text output') def print_to_stdout(self): """ Write the data to stdout. This is just a convenience method to help with debugging. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputPlainText sage: plain_text = OutputPlainText.example() sage: plain_text.print_to_stdout() Example plain text output """ print(self.text.get())
class OutputImageGif(OutputBase): def __init__(self, gif): """ GIF Image (possibly animated) INPUT: - ``gif`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The GIF image data. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImageGif sage: OutputImageGif.example() # indirect doctest OutputImageGif container """ self.gif = OutputBuffer(gif) @classmethod def example(cls): r""" Construct a sample GIF output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputImageGif`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImageGif sage: OutputImageGif.example() OutputImageGif container sage: OutputImageGif.example().gif buffer containing 408 bytes sage: OutputImageGif.example().gif.get().startswith(b'GIF89a') True """ from sage.env import SAGE_EXTCODE filename = os.path.join(SAGE_EXTCODE, 'doctest', 'rich_output', 'example.gif') with open(filename, 'rb') as f: return cls(f.read()) def html_fragment(self): """ Return a self-contained HTML fragment displaying the image This is a workaround for the Jupyter notebook which doesn't support GIF directly. OUTPUT: String. HTML fragment for displaying the GIF image. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImageGif sage: OutputImageGif.example().html_fragment() '<img src="data:image/gif;base64,R0lGODl...zd3t/g4eLj5OVDQQA7"/>' """ b64 = bytes_to_str(base64.b64encode(self.gif.get()), 'ascii') return '<img src="data:image/gif;base64,{0}"/>'.format(b64)
class OutputSceneWavefront(OutputBase): def __init__(self, obj, mtl): """ Wavefront `*.obj` Scene The Wavefront format consists of two files, an ``.obj`` file defining the geometry data (mesh points, normal vectors, ...) together with a ``.mtl`` file defining texture data. INPUT: - ``obj`` -- bytes. The Wavefront obj file format describing the mesh shape. - ``mtl`` -- bytes. The Wavefront mtl file format describing textures. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: OutputSceneWavefront.example() OutputSceneWavefront container """ self.obj = OutputBuffer(obj) self.mtl = OutputBuffer(mtl) self._check_no_directory(self.mtllib()) def _check_no_directory(self, filename): """ Verify that ``filename`` does not contain a path. We disallow anything but plain filenames since it is a potential security issue to point :meth:`mtllib` at random paths. INPUT: - ``filename`` -- string. A filename. OUTPUT: This method returns nothing. A ``ValueError`` is raised if ``filename`` is not just a plain filename but contains a directory (relative or absolute). EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: rich_output = OutputSceneWavefront.example() sage: rich_output._check_no_directory('scene.mtl') sage: rich_output._check_no_directory('/scene.mtl') Traceback (most recent call last): ... ValueError: must be pure filename, got directory component: /scene.mtl sage: rich_output._check_no_directory('relative/scene.mtl') Traceback (most recent call last): ... ValueError: must be pure filename, got directory component: relative/scene.mtl sage: rich_output._check_no_directory('/absolute/scene.mtl') Traceback (most recent call last): ... ValueError: must be pure filename, got directory component: /absolute/scene.mtl """ if os.path.split(filename)[0]: raise ValueError( 'must be pure filename, got directory component: {0}'.format( filename)) def mtllib(self): """ Return the ``mtllib`` filename The ``mtllib`` line in the Wavefront file format (``*.obj``) is the name of the separate texture file. OUTPUT: String. The filename under which ``mtl`` is supposed to be saved. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: rich_output = OutputSceneWavefront.example() sage: rich_output.mtllib() 'scene.mtl' """ marker = 'mtllib ' for line in self.obj.get().splitlines(): if line.startswith(marker): return line[len(marker):] return 'scene.mtl' def obj_filename(self): """ Return the file name of the ``.obj`` file This method saves the object and texture to separate files in a temporary directory and returns the object file name. This is often used to launch a 3d viewer. OUTPUT: String. The file name (absolute path) of the saved obj file. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: rich_output = OutputSceneWavefront.example(); rich_output OutputSceneWavefront container sage: obj = rich_output.obj_filename(); obj '/.../scene.obj' sage: print(open(obj).read()) mtllib scene.mtl g obj_1 ... f 3 2 6 8 sage: path = os.path.dirname(obj) sage: mtl = os.path.join(path, 'scene.mtl'); mtl '/.../scene.mtl' sage: os.path.exists(mtl) True sage: os.path.dirname(obj) == os.path.dirname(mtl) True sage: print(open(mtl).read()) newmtl texture177 Ka 0.2 0.2 0.5 ... d 1 """ from sage.misc.temporary_file import tmp_dir basedir = tmp_dir() obj_filename = os.path.join(basedir, 'scene.obj') mtl_filename = os.path.join(basedir, self.mtllib()) self.obj.save_as(obj_filename) self.mtl.save_as(mtl_filename) return os.path.abspath(obj_filename) @classmethod def example(cls): r""" Construct a sample Canvas3D output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputSceneCanvas3d`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: rich_output = OutputSceneWavefront.example(); rich_output OutputSceneWavefront container sage: rich_output.obj buffer containing 227 bytes sage: rich_output.obj.get() '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' sage: rich_output.mtl buffer containing 80 bytes sage: rich_output.mtl.get() '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' """ from sage.env import SAGE_EXTCODE with_path = lambda x: os.path.join( SAGE_EXTCODE, 'doctest', 'rich_output', 'example_wavefront', x) return cls( OutputBuffer.from_file(with_path('scene.obj')), OutputBuffer.from_file(with_path('scene.mtl')), )
class OutputImageGif(OutputBase): def __init__(self, gif): """ GIF Image (possibly animated) INPUT: - ``gif`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The GIF image data. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImageGif sage: OutputImageGif.example() # indirect doctest OutputImageGif container """ self.gif = OutputBuffer(gif) @classmethod def example(cls): r""" Construct a sample GIF output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputImageGif`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImageGif sage: OutputImageGif.example() OutputImageGif container sage: OutputImageGif.example().gif buffer containing 408 bytes sage: OutputImageGif.example().gif.get().startswith('GIF89a') True """ from sage.env import SAGE_EXTCODE filename = os.path.join(SAGE_EXTCODE, 'doctest', 'rich_output', 'example.gif') with open(filename) as f: return cls(f.read()) def html_fragment(self): """ Return a self-contained HTML fragment displaying the image This is a workaround for the Jupyter notebook which doesn't support GIF directly. OUTPUT: String. HTML fragment for displaying the GIF image. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputImageGif sage: OutputImageGif.example().html_fragment() '<img src="data:image/gif;base64,R0lGODl...zd3t/g4eLj5OVDQQA7"/>' """ return '<img src="data:image/gif;base64,{0}"/>'.format( base64.b64encode(self.gif.get()))
class OutputLatex(OutputBase): def __init__(self, latex): """ LaTeX Output .. note:: The LaTeX commands will only use a subset of LaTeX that can be displayed by MathJax. INPUT: - ``latex`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. String containing the latex equation code. Excludes the surrounding dollar signs / LaTeX equation environment. Also excludes the surrounding MathJax ``<html>`` tag. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: OutputLatex('<html><script type="math/tex; mode=display">1</script></html>') OutputLatex container """ self.latex = OutputBuffer(latex) def mathjax(self, display=True): r""" Return the LaTeX with a surrounding MathJax HTML code. INPUT: - ``display`` -- boolean. Whether to return display (as opposed to inline) TeX. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: rich_output = OutputLatex('1') sage: rich_output.latex buffer containing 1 bytes sage: rich_output.latex.get_str() '1' sage: rich_output.mathjax() '<html><script type="math/tex; mode=display">1</script></html>' sage: rich_output.mathjax(display=False) '<html><script type="math/tex">1</script></html>' """ if display: template = r'<html><script type="math/tex; mode=display">{0}</script></html>' else: template = r'<html><script type="math/tex">{0}</script></html>' return template.format(self.latex.get_str()) def display_equation(self): r""" Return the LaTeX code for a display equation OUTPUT: String. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: rich_output = OutputLatex('1') sage: rich_output.latex buffer containing 1 bytes sage: rich_output.latex.get_str() '1' sage: rich_output.display_equation() '\\begin{equation}\n1\n\\end{equation}' """ return '\n'.join( [r'\begin{equation}', self.latex.get_str(), r'\end{equation}']) def inline_equation(self): r""" Return the LaTeX code for an inline equation OUTPUT: String. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: rich_output = OutputLatex('1') sage: rich_output.latex buffer containing 1 bytes sage: rich_output.latex.get_str() '1' sage: rich_output.inline_equation() '\\begin{math}\n1\n\\end{math}' """ return '\n'.join( [r'\begin{math}', self.latex.get_str(), r'\end{math}']) @classmethod def example(cls): r""" Construct a sample LaTeX output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputLatex`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: OutputLatex.example() OutputLatex container sage: OutputLatex.example().latex.get_str() '\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\int \\sin\\left(x\\right)\\,{d x}' """ return cls(r'\newcommand{\Bold}[1]{\mathbf{#1}}' r'\int \sin\left(x\right)\,{d x}') def print_to_stdout(self): r""" Write the data to stdout. This is just a convenience method to help with debugging. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex sage: rich_output = OutputLatex.example() sage: rich_output.print_to_stdout() \newcommand{\Bold}[1]{\mathbf{#1}}\int \sin\left(x\right)\,{d x} """ print(self.latex.get_str())
class OutputSceneJmol(OutputBase): def __init__(self, scene_zip, preview_png): """ JMol Scene By our (Sage) convention, the actual scene is called ``SCENE`` inside the zip archive. INPUT: - ``scene_zip`` -- string/bytes. The jmol scene (a zip archive). - ``preview_png`` -- string/bytes. Preview as png file. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneJmol sage: OutputSceneJmol.example() OutputSceneJmol container """ self.scene_zip = OutputBuffer(scene_zip) self.preview_png = OutputBuffer(preview_png) def launch_script_filename(self): """ Return a launch script suitable to display the scene. This method saves the scene to disk and creates a launch script. The latter contains an absolute path to the scene file. The launch script is often necessary to make jmol render the 3d scene. OUTPUT: String. The file name of a suitable launch script. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneJmol sage: rich_output = OutputSceneJmol.example(); rich_output OutputSceneJmol container sage: filename = rich_output.launch_script_filename(); filename '/.../scene.spt' sage: print(open(filename).read()) set defaultdirectory "/.../scene.spt.zip" script SCRIPT """ from sage.misc.temporary_file import tmp_dir basedir = tmp_dir() scene_filename = os.path.join(basedir, 'scene.spt.zip') script_filename = os.path.join(basedir, 'scene.spt') self.scene_zip.save_as(scene_filename) with open(script_filename, 'w') as f: f.write('set defaultdirectory "{0}"\n'.format(scene_filename)) f.write('script SCRIPT\n') return script_filename @classmethod def example(cls): r""" Construct a sample Jmol output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputSceneJmol`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneJmol sage: rich_output = OutputSceneJmol.example(); rich_output OutputSceneJmol container sage: rich_output.scene_zip buffer containing 654 bytes sage: rich_output.scene_zip.get().startswith('PK') True sage: rich_output.preview_png buffer containing 608 bytes sage: rich_output.preview_png.get().startswith('\x89PNG') True """ from sage.env import SAGE_EXTCODE example_png_filename = os.path.join(SAGE_EXTCODE, 'doctest', 'rich_output', 'example.png') with open(example_png_filename) as f: example_png = f.read() scene_zip_filename = os.path.join(SAGE_EXTCODE, 'doctest', 'rich_output', 'example_jmol.spt.zip') with open(scene_zip_filename) as f: scene_zip = f.read() return cls(scene_zip, example_png)
def graphics_from_save(self, save_function, save_kwds, file_extension, output_container, figsize=None, dpi=None): r""" Helper to construct graphics. This method can be used to simplify the implementation of a ``_rich_repr_`` method of a graphics object if there is already a function to save graphics to a file. INPUT: - ``save_function`` -- callable that can save graphics to a file and accepts options like :meth:`sage.plot.graphics.Graphics.save`. - ``save_kwds`` -- dictionary. Keyword arguments that are passed to the save function. - ``file_extension`` -- string starting with ``'.'``. The file extension of the graphics file. - ``output_container`` -- subclass of :class:`sage.repl.rich_output.output_basic.OutputBase`. The output container to use. Must be one of the types in :meth:`supported_output`. - ``figsize`` -- pair of integers (optional). The desired graphics size in pixels. Suggested, but need not be respected by the output. - ``dpi`` -- integer (optional). The desired resolution in dots per inch. Suggested, but need not be respected by the output. OUTPUT: Return an instance of ``output_container``. EXAMPLES:: sage: from sage.repl.rich_output import get_display_manager sage: dm = get_display_manager() sage: plt = plot(sin) sage: out = dm.graphics_from_save(plt.save, dict(), '.png', dm.types.OutputImagePng) sage: out OutputImagePng container sage: out.png.get().startswith('\x89PNG') True sage: out.png.filename() # random '/home/user/.sage/temp/localhost.localdomain/23903/tmp_pu5woK.png' """ import os if not file_extension.startswith(os.path.extsep): raise ValueError('file_extension must start with a period') if output_container not in self.supported_output(): raise OutputTypeException( 'output_container is not supported by backend') from sage.misc.temporary_file import tmp_filename filename = tmp_filename(ext=file_extension) # Call the save_function with the right arguments kwds = dict(save_kwds) if figsize is not None: kwds['figsize'] = figsize if dpi is not None: kwds['dpi'] = dpi save_function(filename, **kwds) from sage.repl.rich_output.buffer import OutputBuffer buf = OutputBuffer.from_file(filename) return output_container(buf)
def graphics_from_save(self, save_function, save_kwds, file_extension, output_container, figsize=None, dpi=None): r""" Helper to construct graphics. This method can be used to simplify the implementation of a ``_rich_repr_`` method of a graphics object if there is already a function to save graphics to a file. INPUT: - ``save_function`` -- callable that can save graphics to a file and accepts options like :meth:`sage.plot.graphics.Graphics.save`. - ``save_kwds`` -- dictionary. Keyword arguments that are passed to the save function. - ``file_extension`` -- string starting with ``'.'``. The file extension of the graphics file. - ``output_container`` -- subclass of :class:`sage.repl.rich_output.output_basic.OutputBase`. The output container to use. Must be one of the types in :meth:`supported_output`. - ``figsize`` -- pair of integers (optional). The desired graphics size in pixels. Suggested, but need not be respected by the output. - ``dpi`` -- integer (optional). The desired resolution in dots per inch. Suggested, but need not be respected by the output. OUTPUT: Return an instance of ``output_container``. EXAMPLES:: sage: from sage.repl.rich_output import get_display_manager sage: dm = get_display_manager() sage: plt = plot(sin) sage: out = dm.graphics_from_save(plt.save, dict(), '.png', dm.types.OutputImagePng) sage: out OutputImagePng container sage: out.png.get().startswith('\x89PNG') True sage: out.png.filename() # random '/home/user/.sage/temp/localhost.localdomain/23903/tmp_pu5woK.png' """ import os if not file_extension.startswith(os.path.extsep): raise ValueError('file_extension must start with a period') if output_container not in self.supported_output(): raise OutputTypeException('output_container is not supported by backend') from sage.misc.temporary_file import tmp_filename filename = tmp_filename(ext=file_extension) # Call the save_function with the right arguments kwds = dict(save_kwds) if figsize is not None: kwds['figsize'] = figsize if dpi is not None: kwds['dpi'] = dpi save_function(filename, **kwds) from sage.repl.rich_output.buffer import OutputBuffer buf = OutputBuffer.from_file(filename) return output_container(buf)
class OutputAsciiArt(OutputBase): def __init__(self, ascii_art): """ ASCII Art Output INPUT: - ``ascii_art`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Ascii art rendered into a string. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputAsciiArt sage: OutputAsciiArt(':-}') OutputAsciiArt container """ self.ascii_art = OutputBuffer(ascii_art) @classmethod def example(cls): r""" Construct a sample ascii art output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputAsciiArt`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputAsciiArt sage: OutputAsciiArt.example() OutputAsciiArt container sage: OutputAsciiArt.example().ascii_art.get() '[ * * * * ]\n[ ** ** * * * * * * ]\n[ ***, * , * , **, ** , *, * , * , * ]' """ return cls('[ * * * * ]\n' '[ ** ** * * * * * * ]\n' '[ ***, * , * , **, ** , *, * , * , * ]') def print_to_stdout(self): """ Write the data to stdout. This is just a convenience method to help with debugging. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputAsciiArt sage: ascii_art = OutputAsciiArt.example() sage: ascii_art.print_to_stdout() [ * * * * ] [ ** ** * * * * * * ] [ ***, * , * , **, ** , *, * , * , * ] """ print(self.ascii_art.get())
class OutputAsciiArt(OutputBase): def __init__(self, ascii_art): """ ASCII Art Output INPUT: - ``ascii_art`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Ascii art rendered into a string. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputAsciiArt sage: OutputAsciiArt(':-}') OutputAsciiArt container """ self.ascii_art = OutputBuffer(ascii_art) @classmethod def example(cls): r""" Construct a sample ascii art output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputAsciiArt`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputAsciiArt sage: OutputAsciiArt.example() OutputAsciiArt container sage: OutputAsciiArt.example().ascii_art.get_str() '[ * * * * ]\n[ ** ** * * * * * * ]\n[ ***, * , * , **, ** , *, * , * , * ]' """ return cls('[ * * * * ]\n' '[ ** ** * * * * * * ]\n' '[ ***, * , * , **, ** , *, * , * , * ]') def print_to_stdout(self): """ Write the data to stdout. This is just a convenience method to help with debugging. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputAsciiArt sage: ascii_art = OutputAsciiArt.example() sage: ascii_art.print_to_stdout() [ * * * * ] [ ** ** * * * * * * ] [ ***, * , * , **, ** , *, * , * , * ] """ print(self.ascii_art.get_str())
class OutputSceneJmol(OutputBase): def __init__(self, scene_zip, preview_png): """ JMol Scene By our (Sage) convention, the actual scene is called ``SCENE`` inside the zip archive. INPUT: - ``scene_zip`` -- string/bytes. The jmol scene (a zip archive). - ``preview_png`` -- string/bytes. Preview as png file. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneJmol sage: OutputSceneJmol.example() OutputSceneJmol container """ self.scene_zip = OutputBuffer(scene_zip) self.preview_png = OutputBuffer(preview_png) def launch_script_filename(self): """ Return a launch script suitable to display the scene. This method saves the scene to disk and creates a launch script. The latter contains an absolute path to the scene file. The launch script is often necessary to make jmol render the 3d scene. OUTPUT: String. The file name of a suitable launch script. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneJmol sage: rich_output = OutputSceneJmol.example(); rich_output OutputSceneJmol container sage: filename = rich_output.launch_script_filename(); filename '/.../scene.spt' sage: with open(filename) as fobj: ....: print(fobj.read()) set defaultdirectory "/.../scene.spt.zip" script SCRIPT """ from sage.misc.temporary_file import tmp_dir basedir = tmp_dir() scene_filename = os.path.join(basedir, 'scene.spt.zip') script_filename = os.path.join(basedir, 'scene.spt') self.scene_zip.save_as(scene_filename) with open(script_filename, 'w') as f: f.write('set defaultdirectory "{0}"\n'.format(scene_filename)) f.write('script SCRIPT\n') return script_filename @classmethod def example(cls): r""" Construct a sample Jmol output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputSceneJmol`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneJmol sage: rich_output = OutputSceneJmol.example(); rich_output OutputSceneJmol container sage: rich_output.scene_zip buffer containing 654 bytes sage: rich_output.scene_zip.get().startswith(b'PK') True sage: rich_output.preview_png buffer containing 608 bytes sage: rich_output.preview_png.get().startswith(b'\x89PNG') True """ from sage.env import SAGE_EXTCODE example_png_filename = os.path.join( SAGE_EXTCODE, 'doctest', 'rich_output', 'example.png') with open(example_png_filename, 'rb') as f: example_png = f.read() scene_zip_filename = os.path.join( SAGE_EXTCODE, 'doctest', 'rich_output', 'example_jmol.spt.zip') with open(scene_zip_filename, 'rb') as f: scene_zip = f.read() return cls(scene_zip, example_png)
class OutputUnicodeArt(OutputBase): def __init__(self, unicode_art): """ Unicode Art Output Similar to :class:`OutputAsciiArt` but using the entire unicode range. INPUT: - ``unicode_art`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (unicode in Python 2.x) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Unicode art rendered into a string. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputUnicodeArt sage: OutputUnicodeArt(u':-}') OutputUnicodeArt container """ # Internally, all buffers store bytes. Unicode is always utf-8 # encoded. if not isinstance(unicode_art, bytes): unicode_art = unicode_art.encode('utf-8') self.unicode_art = OutputBuffer(unicode_art) @classmethod def example(cls): r""" Construct a sample unicode art output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputUnicodeArt`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputUnicodeArt sage: OutputUnicodeArt.example() OutputUnicodeArt container sage: print(OutputUnicodeArt.example().unicode_art.get_unicode()) ⎛-11 0 1⎞ ⎜ 3 -1 0⎟ ⎝ -1 -1 0⎠ """ return cls(u'⎛-11 0 1⎞\n' u'⎜ 3 -1 0⎟\n' u'⎝ -1 -1 0⎠') def print_to_stdout(self): """ Write the data to stdout. This is just a convenience method to help with debugging. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputUnicodeArt sage: unicode_art = OutputUnicodeArt.example() sage: unicode_art.print_to_stdout() ⎛-11 0 1⎞ ⎜ 3 -1 0⎟ ⎝ -1 -1 0⎠ """ print(self.unicode_art.get_unicode())
class OutputSceneWavefront(OutputBase): def __init__(self, obj, mtl): """ Wavefront `*.obj` Scene The Wavefront format consists of two files, an ``.obj`` file defining the geometry data (mesh points, normal vectors, ...) together with a ``.mtl`` file defining texture data. INPUT: - ``obj`` -- bytes. The Wavefront obj file format describing the mesh shape. - ``mtl`` -- bytes. The Wavefront mtl file format describing textures. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: OutputSceneWavefront.example() OutputSceneWavefront container """ self.obj = OutputBuffer(obj) self.mtl = OutputBuffer(mtl) self._check_no_directory(self.mtllib()) def _check_no_directory(self, filename): """ Verify that ``filename`` does not contain a path. We disallow anything but plain filenames since it is a potential security issue to point :meth:`mtllib` at random paths. INPUT: - ``filename`` -- string. A filename. OUTPUT: This method returns nothing. A ``ValueError`` is raised if ``filename`` is not just a plain filename but contains a directory (relative or absolute). EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: rich_output = OutputSceneWavefront.example() sage: rich_output._check_no_directory('scene.mtl') sage: rich_output._check_no_directory('/scene.mtl') Traceback (most recent call last): ... ValueError: must be pure filename, got directory component: /scene.mtl sage: rich_output._check_no_directory('relative/scene.mtl') Traceback (most recent call last): ... ValueError: must be pure filename, got directory component: relative/scene.mtl sage: rich_output._check_no_directory('/absolute/scene.mtl') Traceback (most recent call last): ... ValueError: must be pure filename, got directory component: /absolute/scene.mtl """ if os.path.split(filename)[0]: raise ValueError('must be pure filename, got directory component: {0}' .format(filename)) def mtllib(self): """ Return the ``mtllib`` filename The ``mtllib`` line in the Wavefront file format (``*.obj``) is the name of the separate texture file. OUTPUT: String. The filename under which ``mtl`` is supposed to be saved. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: rich_output = OutputSceneWavefront.example() sage: rich_output.mtllib() 'scene.mtl' """ marker = b'mtllib ' for line in self.obj.get().splitlines(): if line.startswith(marker): return bytes_to_str(line[len(marker):], FS_ENCODING, 'surrogateescape') return 'scene.mtl' def obj_filename(self): """ Return the file name of the ``.obj`` file This method saves the object and texture to separate files in a temporary directory and returns the object file name. This is often used to launch a 3d viewer. OUTPUT: String. The file name (absolute path) of the saved obj file. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: rich_output = OutputSceneWavefront.example(); rich_output OutputSceneWavefront container sage: obj = rich_output.obj_filename(); obj '/.../scene.obj' sage: with open(obj) as fobj: ....: print(fobj.read()) mtllib scene.mtl g obj_1 ... f 3 2 6 8 sage: path = os.path.dirname(obj) sage: mtl = os.path.join(path, 'scene.mtl'); mtl '/.../scene.mtl' sage: os.path.exists(mtl) True sage: os.path.dirname(obj) == os.path.dirname(mtl) True sage: with open(mtl) as fobj: ....: print(fobj.read()) newmtl texture177 Ka 0.2 0.2 0.5 ... d 1 """ from sage.misc.temporary_file import tmp_dir basedir = tmp_dir() obj_filename = os.path.join(basedir, 'scene.obj') mtl_filename = os.path.join(basedir, self.mtllib()) self.obj.save_as(obj_filename) self.mtl.save_as(mtl_filename) return os.path.abspath(obj_filename) @classmethod def example(cls): r""" Construct a sample Canvas3D output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputSceneCanvas3d`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputSceneWavefront sage: rich_output = OutputSceneWavefront.example(); rich_output OutputSceneWavefront container sage: rich_output.obj buffer containing 227 bytes sage: rich_output.obj.get_str() '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' sage: rich_output.mtl buffer containing 80 bytes sage: rich_output.mtl.get_str() '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' """ from sage.env import SAGE_EXTCODE with_path = lambda x: os.path.join( SAGE_EXTCODE, 'doctest', 'rich_output', 'example_wavefront', x) return cls( OutputBuffer.from_file(with_path('scene.obj')), OutputBuffer.from_file(with_path('scene.mtl')), )
class OutputUnicodeArt(OutputBase): def __init__(self, unicode_art): """ Unicode Art Output Similar to :class:`OutputAsciiArt` but using the entire unicode range. INPUT: - ``unicode_art`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (unicode in Python 2.x) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Unicode art rendered into a string. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputUnicodeArt sage: OutputUnicodeArt(u':-}') OutputUnicodeArt container """ # Internally, all buffers store bytes. Unicode is always utf-8 # encoded. if isinstance(unicode_art, unicode): unicode_art = unicode_art.encode('utf-8') self.unicode_art = OutputBuffer(unicode_art) @classmethod def example(cls): r""" Construct a sample unicode art output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputUnicodeArt`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputUnicodeArt sage: OutputUnicodeArt.example() OutputUnicodeArt container sage: OutputUnicodeArt.example().unicode_art.get() '\xe2\x8e\x9b-11 0 1\xe2\x8e\x9e\n\xe2\x8e\x9c 3 -1 0\xe2\x8e\x9f\n\xe2\x8e\x9d -1 -1 0\xe2\x8e\xa0' """ return cls(u'⎛-11 0 1⎞\n' u'⎜ 3 -1 0⎟\n' u'⎝ -1 -1 0⎠') def print_to_stdout(self): """ Write the data to stdout. This is just a convenience method to help with debugging. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputUnicodeArt sage: unicode_art = OutputUnicodeArt.example() sage: unicode_art.print_to_stdout() ⎛-11 0 1⎞ ⎜ 3 -1 0⎟ ⎝ -1 -1 0⎠ """ print(self.unicode_art.get())
class OutputHtml(OutputBase): def __init__(self, html): """ HTML Output INPUT: - ``html`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. String containing the html fragment code. Excludes the surrounding ``<body>`` and ``<html>`` tag. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputHtml sage: OutputHtml('<div>Foo<b>B</b>ar</div>') OutputHtml container """ self.html = OutputBuffer(html) # if the html is a simple wrapper of latex for mathjax rendering, then # the latex string is saved for possible latex output such as Jupyter's # pdf export of a notebook m = latex_re.match(html) if m: mathjax_string = m.group('latex') latex_string = mathjax_string.replace('<', '<') if m.group('mathstart') == r'\[' and m.group('mathend') == r'\]': self.latex = OutputBuffer('$$' + latex_string + '$$') else: self.latex = OutputBuffer('$' + latex_string + '$') else: self.latex = None @classmethod def example(cls): r""" Construct a sample Html output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputHtml`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputHtml sage: OutputHtml.example() OutputHtml container sage: OutputHtml.example().html.get_str() '<div>Hello World!</div>' """ return cls('<div>Hello World!</div>') def print_to_stdout(self): r""" Write the data to stdout. This is just a convenience method to help with debugging. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputHtml sage: rich_output = OutputHtml.example() sage: rich_output.print_to_stdout() <div>Hello World!</div> """ print(self.html.get_unicode()) def with_html_tag(self): r""" Return the HTML code surrounded by ``<html>`` tag This is just a convenience method. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputHtml sage: rich_output = OutputHtml.example() sage: rich_output.print_to_stdout() <div>Hello World!</div> sage: rich_output.with_html_tag() '<html><div>Hello World!</div></html>' """ return '<html>{0}</html>'.format(self.html.get_unicode())
class OutputHtml(OutputBase): def __init__(self, html): """ HTML Output INPUT: - ``html`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a string (bytes) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. String containing the html fragment code. Excludes the surrounding ``<body>`` and ``<html>`` tag. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputHtml sage: OutputHtml('<div>Foo<b>B</b>ar</div>') OutputHtml container """ self.html = OutputBuffer(html) @classmethod def example(cls): r""" Construct a sample Html output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputHtml`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputHtml sage: OutputHtml.example() OutputHtml container sage: OutputHtml.example().html.get_str() '<div>Hello World!</div>' """ return cls('<div>Hello World!</div>') def print_to_stdout(self): r""" Write the data to stdout. This is just a convenience method to help with debugging. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputHtml sage: rich_output = OutputHtml.example() sage: rich_output.print_to_stdout() <div>Hello World!</div> """ print(self.html.get_unicode()) def with_html_tag(self): r""" Return the HTML code surrounded by ``<html>`` tag This is just a convenience method. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputHtml sage: rich_output = OutputHtml.example() sage: rich_output.print_to_stdout() <div>Hello World!</div> sage: rich_output.with_html_tag() '<html><div>Hello World!</div></html>' """ return '<html>{0}</html>'.format(self.html.get_unicode())
class OutputPlainText(OutputBase): def __init__(self, plain_text): """ Plain Text Output INPUT: - ``plain_text`` -- :class:`~sage.repl.rich_output.buffer.OutputBuffer`. Alternatively, a bytes (string in Python 2.x) or string (unicode in Python 2.x) can be passed directly which will then be converted into an :class:`~sage.repl.rich_output.buffer.OutputBuffer`. The plain text output. This should always be exactly the same as the (non-rich) output from the ``_repr_`` method. Every backend object must support plain text output as fallback. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputPlainText sage: OutputPlainText('foo') OutputPlainText container """ self.text = OutputBuffer(plain_text) @classmethod def example(cls): """ Construct a sample plain text output container This static method is meant for doctests, so they can easily construct an example. OUTPUT: An instance of :class:`OutputPlainText`. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputPlainText sage: OutputPlainText.example() OutputPlainText container sage: OutputPlainText.example().text.get_str() 'Example plain text output' """ return cls('Example plain text output') def print_to_stdout(self): """ Write the data to stdout. This is just a convenience method to help with debugging. EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputPlainText sage: plain_text = OutputPlainText.example() sage: plain_text.print_to_stdout() Example plain text output """ print(self.text.get_str())