Source code for algebraixlib.util.html
r"""Utilities that present `MathObject`\s as HTML pages."""
# $Id: html.py 22800 2015-08-14 14:59:01Z gfiedler $
# Copyright Algebraix Data Corporation 2015 - $Date: 2015-08-14 09:59:01 -0500 (Fri, 14 Aug 2015) $
#
# This file is part of algebraixlib <http://github.com/AlgebraixData/algebraixlib>.
#
# algebraixlib is free software: you can redistribute it and/or modify it under the terms of version
# 3 of the GNU Lesser General Public License as published by the Free Software Foundation.
#
# algebraixlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with algebraixlib.
# If not, see <http://www.gnu.org/licenses/>.
# --------------------------------------------------------------------------------------------------
import collections as _collections
import html as _html
import io as _io
import algebraixlib.mathobjects as _mo
import algebraixlib.util.latexprinter as _latexprinter
# --------------------------------------------------------------------------------------------------
#: Named `tuple` for collecting information about a `MathObject`.
#: It contains:
#: - ``input_title``: (Optional) A string that can serve as a name, origin expression or title.
#: - ``data_algebra_construct``: The `MathObject` or container of `MathObject`\s.
#: - ``description_brief``: (Optional) A string to display more detail.
DataAlgebraHtmlDescriptor = _collections.namedtuple(
'DataAlgebraHtmlDescriptor',
'input_title data_algebra_construct description_brief')
[docs]def math_object_as_html(title: str, data_algebra_html_descriptors: [],
header_template: str=None, footer_template: str=None,
mathobject_template: str=None) -> str:
r"""Return the contents of an HTML webpage representing a `MathObject`, using templates.
:param title: The title for this page of `MathObject`\s.
:param data_algebra_html_descriptors: An array of `DataAlgebraHtmlDescriptor` instances
(containing math objects and their related descriptive strings).
:param header_template: HTML markup that starts the webpage. May contain the template variable
``page_title``; it is set to the value of ``title``.
:param footer_template: HTML markup that ends the page.
:param mathobject_template: The HTML markup that is emited for each math object. May contain
the template variables ``input_title``, ``description_brief`` and
``data_algebra_construct``, which are replaced with the respective values in the
associated ``DataAlgebraHtmlDescriptor``.
"""
# The default header template. Start the web page and set up some basic styles for the various
# display elements. Requires the template argument 'page_title' (the title for the document that
# is being created).
default_header_template = """\
<html>
<head>
<script
src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'>
</script>
<script type="text/javascript">
//<![CDATA[ //]]>
</script>
<style>
body {{background-color: #F8F8FF}}
#page_title{{}}
#input_title{{}}
#description_brief{{
border: 1px solid black;
padding: 5px;
background-color: white;
}}
#data_algebra_construct{{
border: 1px solid black;
padding: 5px;
background-color: white;
}}
</style>
</head>
<body>
<h1 id="page_title">{page_title}</h1>
"""
if header_template is None:
header_template = default_header_template
# The default footer. Only closes the body and html tags, assumed to have been opened by the
# header. It is not an actual template.
default_footer = """</body></html>"""
if footer_template is None:
footer_template = default_footer
# The default math object template. Add a section to the page that displays a math object with
# associated descriptive text. Requires three template arguments (the names match the members of
# DataAlgebraHtmlDescriptor):
# - input_title: A string naming the math object, displayed in an h2 header. May contain HTML
# markup, but it needs to be consistent with being used in an h2 header.
# - description_brief: A description of the mathobject, displayed in a preformatted section. May
# contain HTML markup, but it needs to be consistent with being used in preformatted text.
# - data_algebra_construct: Normally the LaTeX representation of the mathobject, but could also
# be HTML markup, or a simple string representation of the math object. Is shown as standard
# text.
default_mathobject_template = """\
<h2 id="input_title">{input_title}</h2>
<div id="description_brief"><pre>{description_brief}</pre></div>
<div id="data_algebra_construct">{data_algebra_construct}</div>
"""
if mathobject_template is None:
mathobject_template = default_mathobject_template
writer = _io.StringIO()
# Start the web page by appending the header, and injecting the title.
writer.write(header_template.format(page_title=as_html_handle_basic_parameter(title)))
# Appends the template, with replaced elements from the descriptors, for each description.
# Makes use of delegate functions for rendering the different parameters.
writer.write(''.join(
[mathobject_template.format(
input_title=as_html_handle_basic_parameter(dataAlgebraDescriptor.input_title),
description_brief=as_html_handle_basic_parameter(
dataAlgebraDescriptor.description_brief),
data_algebra_construct=as_html_handle_data_algebra(
dataAlgebraDescriptor.data_algebra_construct))
for dataAlgebraDescriptor in data_algebra_html_descriptors]))
# Ends the web page with the provided footer.
writer.write(footer_template)
html_out = writer.getvalue()
# print(html_out)
return html_out
[docs]def as_html_handle_basic_parameter(html_input: str) -> str:
"""Return the string of ``html_input``, properly escaped for using it in HTML."""
return _html.escape(str(html_input))
[docs]def as_html_handle_data_algebra(mathobj):
r"""Return ``mathobj`` converted into a string safe to be used in HTML.
- If ``mathobj`` is a `MathObject`, it will be represented as LaTeX markup and wrapped in the
mathjax escape token.
- If it is a container of `MathObject`\s, then each one will be represented as LaTeX
markup and displayed on its own line.
- If it is not a `MathObject` then the ``str`` function will be invoked.
"""
if isinstance(mathobj, _mo.MathObject):
# print this one math object
return "$$" + _html.escape(_latexprinter.math_object_to_latex(mathobj)) + "$$"
elif isinstance(mathobj, _collections.Iterable):
temp = ""
for elem in mathobj:
if isinstance(elem, _mo.MathObject):
# latex
temp += r"$$\(\require{color}\)\(\require{xcolor}\)" + \
_html.escape(_latexprinter.math_object_to_latex(elem)) + "$$ <br //>"
else:
# str
temp += _html.escape(str(elem)) + "<br //>"
return temp
else:
# print this one non-math object using str(mathobjects)
return _html.escape(str(mathobj))
[docs]def build_descriptors_from_math_obj(mathobjects):
"""Return an array of simple `DataAlgebraHtmlDescriptor` of the objects in ``mathobjects``.
:param mathobjects: List of objects from which to create descriptors.
"""
data_alg_descriptors = []
for mathobj in mathobjects:
data_alg_descriptors.append(
DataAlgebraHtmlDescriptor(str(mathobj), mathobj, "No Description,"))
return data_alg_descriptors
[docs]def create_simple_web_page(mathobj: _mo.MathObject) -> str:
"""Return an HTML string for a simple HTML page from a single `MathObject`."""
web_template = r"""\
<html>
<head>
<script
src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'>
</script>
<script type="text/javascript">
//<![CDATA[ //]]>
</script>
<style>
body {{background-color: #F8F8FF}}
#latexArea, #dataAlgebraArea{{
width: 1000px;
height: 200px;
border: 1px solid black;
padding: 5px;
overflow: scroll;
background-color: white;
resize: both;
}}
</style>
</head>
<body>
<h1>MathJax is Easy!</h1>
<h2>Input:</h2>
<div id="dataAlgebraArea">{data_algebra_in!s}</div>
<h2>Output:</h2>
<div id="latexArea">$$\(\require{color}\){latex_out}$$</div>
</body></html>
"""
web_out = web_template.format(
data_algebra_in=mathobj, latex_out=_latexprinter.math_object_to_latex(mathobj))
print(web_out)
return web_out