pax_global_header00006660000000000000000000000064140556637750014534gustar00rootroot0000000000000052 comment=11fdd4da49748a2e698d8125222730894670c09e jupyter_server_mathjax-0.2.3/000077500000000000000000000000001405566377500163425ustar00rootroot00000000000000jupyter_server_mathjax-0.2.3/.github/000077500000000000000000000000001405566377500177025ustar00rootroot00000000000000jupyter_server_mathjax-0.2.3/.github/workflows/000077500000000000000000000000001405566377500217375ustar00rootroot00000000000000jupyter_server_mathjax-0.2.3/.github/workflows/pythonpackage.yml000066400000000000000000000026251405566377500253240ustar00rootroot00000000000000name: Testing on: push: branches: - main pull_request: branches: '*' jobs: build: runs-on: ${{ matrix.os }}-latest strategy: fail-fast: false matrix: os: [ubuntu, macos, windows] python-version: ['3.6', '3.7', '3.8', '3.9', 'pypy3'] exclude: - os: windows python-version: pypy3 steps: - uses: actions/checkout@v1 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 with: python-version: ${{ matrix.python-version }} - name: Upgrade pip, etc. run: | python -m pip install --user --upgrade pip setuptools wheel - name: Get pip cache dir id: pip-cache run: | echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip uses: actions/cache@v1 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('setup.py') }} restore-keys: | ${{ runner.os }}-pip-${{ matrix.python-version }}- ${{ runner.os }}-pip- - name: Install pip dependencies run: | pip install -v -e ".[test]" pytest-cov - name: Check pip environment run: | pip freeze pip check - name: Test with pytest run: | pytest -vv --cov jupyter_server_mathjax --cov-report term-missing:skip-covered jupyter_server_mathjax-0.2.3/.gitignore000066400000000000000000000034371405566377500203410ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class .vscode/ # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # npm files package-lock.json node_modules # Static files jupyter_server_mathjax/static jupyter_server_mathjax-0.2.3/LICENSE000066400000000000000000000027771405566377500173640ustar00rootroot00000000000000BSD 3-Clause License Copyright (c) 2020 Project Jupyter Contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jupyter_server_mathjax-0.2.3/MANIFEST.in000066400000000000000000000002541405566377500201010ustar00rootroot00000000000000include LICENSE include pyproject.toml include README.md include RELEASE.md include MANIFEST.in include pytest.ini include package.json include copyAssets.js graft tests jupyter_server_mathjax-0.2.3/README.md000066400000000000000000000007001405566377500176160ustar00rootroot00000000000000# MathJax resources endpoints for Jupyter Server ![Testing](https://github.com/jupyter-server/jupyter_server_mathjax/workflows/Testing/badge.svg) ## Basic Usage Install from PyPI: ```sh > pip install jupyter_server_mathjax ``` This will automatically enable the extension in Jupyter Server. To test the installation, you can run Jupyter Server and visit the `/static/jupyter_server_mathjax/MathJax.js` endpoint: ```sh > jupyter server ``` jupyter_server_mathjax-0.2.3/RELEASE.md000066400000000000000000000006071405566377500177470ustar00rootroot00000000000000To create a release, update the version number in `jupyter_server_mathjax/__version__.py`, then run the following: ``` git clean -dffx python setup.py sdist bdist_wheel export script_version=`python setup.py --version 2>/dev/null` git commit -a -m "Release $script_version" git tag $script_version pip install twine twine check dist/* twine upload dist/* git push --all git push --tags ``` jupyter_server_mathjax-0.2.3/copyAssets.js000066400000000000000000000041531405566377500210400ustar00rootroot00000000000000const fse = require("fs-extra"); const path = require("path"); const srcDir = path.join(__dirname, "node_modules", "mathjax"); const dstDir = path.join(__dirname, "jupyter_server_mathjax", "static"); /* * Copy MathJax static assets, but trim which assets in a similar way to what * notebook does on dist (in setupbase). */ const rps = path.sep.replace("\\", "\\\\"); function re_join(parts) { return parts.join(rps); } const include = [ ["MathJax.js"], ["LICENSE"], ["config", "TeX-AMS-MML_HTMLorMML-full.js"], ["config", "Safe.js"], ]; const re_include = [ ["jax", "output", `[^${rps}]+.js$`], ["jax", "output", "autoload", ".*"], ["localization", ".*"], ["fonts", "HTML-CSS", "STIX-Web", "woff", ".*"], ["extensions", ".*"], ["jax", "input", "TeX", ".*"], ["jax", "output", "HTML-CSS", "fonts", "STIX-Web", ".*"], ["jax", "output", "SVG", "fonts", "STIX-Web", ".*"], ["jax", "element", "mml", ".*"], ]; function isPartial(parts, candidate) { return parts.length <= candidate.length; } function partialPathMatch(parts, candidate) { const np = Math.min(candidate.length, parts.length); for (let i = 0; i < np; ++i) { if (candidate[i] !== parts[i]) { return false; } } return true; } function pathOk(p) { if (!p) { return true; } const parts = p.split(path.sep); for (let c of include) { if (isPartial(parts, c)) { // Check for partial matches (to ensure dirs get included) if (partialPathMatch(parts, c)) { return true; } } else { if (c.join(path.sep) == p) { return true; } } } for (let c of re_include) { const lead = c.slice(0, c.length - 1); if (isPartial(parts, lead)) { // Check for partial matches (to ensure dirs get included) if (partialPathMatch(parts, lead)) { return true; } } else { const re = new RegExp(re_join(c)); if (re.test(p)) { return true; } } } return false; } function filterFunc(src, dest) { const relative = path.relative(srcDir, src); return pathOk(relative); } fse.copy(srcDir, dstDir, { filter: filterFunc }); jupyter_server_mathjax-0.2.3/jupyter_server_config.d/000077500000000000000000000000001405566377500232015ustar00rootroot00000000000000jupyter_server_mathjax-0.2.3/jupyter_server_config.d/jupyter_server_mathjax.json000066400000000000000000000001631405566377500307000ustar00rootroot00000000000000{ "ServerApp": { "jpserver_extensions": { "jupyter_server_mathjax": true } } } jupyter_server_mathjax-0.2.3/jupyter_server_mathjax/000077500000000000000000000000001405566377500231465ustar00rootroot00000000000000jupyter_server_mathjax-0.2.3/jupyter_server_mathjax/__init__.py000066400000000000000000000004141405566377500252560ustar00rootroot00000000000000# Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .app import MathJaxExtension def _jupyter_server_extension_points(): return [ {"module": "jupyter_server_mathjax", "app": MathJaxExtension}, ] jupyter_server_mathjax-0.2.3/jupyter_server_mathjax/__version__.py000066400000000000000000000001101405566377500257710ustar00rootroot00000000000000version_info = (0, 2, 3) __version__ = ".".join(map(str, version_info)) jupyter_server_mathjax-0.2.3/jupyter_server_mathjax/app.py000066400000000000000000000046271405566377500243110ustar00rootroot00000000000000# Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from pathlib import Path from traitlets import default, observe, Unicode from tornado.web import RedirectHandler from jupyter_server.extension.application import ExtensionApp from jupyter_server.utils import url_path_join from jupyter_server.transutils import _ STATIC_ASSETS_PATH = Path(__file__).parent / "static" class DeprecatedRedirectHandler(RedirectHandler): def get(self, *args, **kwargs): import warnings warnings.warn( "Redirecting old Notebook MathJax URL to new one. This will be removed in a future release.", PendingDeprecationWarning, ) super().get(*args, **kwargs) class MathJaxExtension(ExtensionApp): name = "jupyter_server_mathjax" # By listing the path to the assets here, jupyter_server # automatically creates a static file handler at # /static/jupyter_server_mathjax/... static_paths = [str(STATIC_ASSETS_PATH)] mathjax_config = Unicode( "TeX-AMS-MML_HTMLorMML-full,Safe", config=True, help=_("""The MathJax.js configuration file that is to be used."""), ) @observe("mathjax_config") def _update_mathjax_config(self, change): self.log.info(_("Using MathJax configuration file: %s"), change["new"]) def initialize_settings(self): # Add settings specific to this extension to the # tornado webapp settings. self.settings.update( { "mathjax_config": self.mathjax_config, "mathjax_url": url_path_join(self.static_url_prefix, "MathJax.js"), } ) def initialize_handlers(self): webapp = self.serverapp.web_app base_url = self.serverapp.base_url host_pattern = ".*$" # Add a deprecated redirect for all MathJax paths from the classic # notebook to the static endpoint created for this extension. webapp.add_handlers( host_pattern, [ ( url_path_join(base_url, "/static/components/MathJax/(.*)"), DeprecatedRedirectHandler, { "url": url_path_join( self.static_url_prefix, "/{0}" # {0} = group 0 in url path ) }, ) ], ) jupyter_server_mathjax-0.2.3/jupyter_server_mathjax/tests/000077500000000000000000000000001405566377500243105ustar00rootroot00000000000000jupyter_server_mathjax-0.2.3/jupyter_server_mathjax/tests/__init__.py000066400000000000000000000000001405566377500264070ustar00rootroot00000000000000jupyter_server_mathjax-0.2.3/jupyter_server_mathjax/tests/conftest.py000066400000000000000000000005341405566377500265110ustar00rootroot00000000000000# Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import io import logging import pytest from traitlets import default pytest_plugins = ["jupyter_server.pytest_plugin"] @pytest.fixture def jp_server_config(): return {"ServerApp": {"jpserver_extensions": {"jupyter_server_mathjax": True}}} jupyter_server_mathjax-0.2.3/jupyter_server_mathjax/tests/test_api.py000066400000000000000000000026751405566377500265040ustar00rootroot00000000000000# Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. """Basic tests for the notebook handlers. """ import pytest from tornado.httpclient import HTTPClientError from jupyter_server.utils import url_path_join as ujoin async def test_mathjax_mainjs_handler(jp_fetch): r = await jp_fetch("static", "jupyter_server_mathjax", "MathJax.js") assert r.code == 200 async def test_mathjax_conf_handler(jp_fetch): r = await jp_fetch( "static", "jupyter_server_mathjax", "config", "TeX-AMS-MML_HTMLorMML-full.js" ) assert r.code == 200 r = await jp_fetch("static", "jupyter_server_mathjax", "config", "Safe.js") assert r.code == 200 @pytest.mark.parametrize( "asset_file", ["MathJax.js", "config/TeX-AMS-MML_HTMLorMML-full.js", "config/Safe.js"], ) async def test_redirects_from_classic_notebook_endpoints( jp_fetch, jp_base_url, asset_file ): old_prefix = ujoin("static", "components", "MathJax") new_prefix = ujoin("static", "jupyter_server_mathjax") # Verify that the redirect is in place with pytest.raises(HTTPClientError) as error_info, pytest.deprecated_call( match="Redirecting old Notebook MathJax URL .*" ): await jp_fetch(old_prefix, asset_file, follow_redirects=False) err = error_info.value assert err.code == 301 assert err.response.headers["Location"] == ujoin( jp_base_url, new_prefix, asset_file ) jupyter_server_mathjax-0.2.3/package.json000066400000000000000000000003431405566377500206300ustar00rootroot00000000000000{ "dependencies": { "mathjax": "^2.7.4" }, "devDependencies": { "fs-extra": "^9.0.1", "rimraf": "^3.0.2" }, "scripts": { "build": "rimraf ./jupyter_server_mathjax/static && node ./copyAssets.js" } } jupyter_server_mathjax-0.2.3/pyproject.toml000066400000000000000000000002471405566377500212610ustar00rootroot00000000000000[build-system] # Minimum requirements for the build system to execute. requires = ["setuptools", "wheel", "jupyter_packaging"] build-backend = "setuptools.build_meta" jupyter_server_mathjax-0.2.3/pytest.ini000066400000000000000000000003341405566377500203730ustar00rootroot00000000000000[pytest] norecursedirs = .git node_modules htmlcov .ipynb_checkpoints testpaths = jupyter_server_mathjax/tests # Work around for https://github.com/pytest-dev/pytest/issues/4039 addopts = --pyargs jupyter_server_mathjax jupyter_server_mathjax-0.2.3/setup.cfg000066400000000000000000000003541405566377500201650ustar00rootroot00000000000000 [manifix] known-excludes = .git* .git/**/* **/node_modules/**/* **/__py_cache__/**/* **/*.pyc .pytest_cache/**/* package-lock.json *.egg-info/**/* .vscode/**/* jupyter_server_mathjax/static/**/* jupyter_server_mathjax-0.2.3/setup.py000066400000000000000000000045271405566377500200640ustar00rootroot00000000000000# Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from pathlib import Path from setuptools import find_packages, setup from jupyter_packaging import ( combine_commands, create_cmdclass, ensure_targets, get_version, install_npm, ) NAME = "jupyter_server_mathjax" here = Path(__file__).absolute().parent project_slug = NAME.lower().replace("-", "_").replace(" ", "_") version = get_version(here / NAME / "__version__.py") with open("README.md", "r") as fh: long_description = fh.read() jstargets = [ here.joinpath(NAME, "static", "MathJax.js"), # if we are distributing MathJax, we need to include its license: here.joinpath(NAME, "static", "LICENSE"), ] # Handle datafiles cmdclass = create_cmdclass( "js", data_files_spec=[ ("etc/jupyter/jupyter_server_config.d", "jupyter_server_config.d", "*.json") ], package_data_spec={NAME: ["static/**/*"]}, ) cmdclass["js"] = combine_commands( install_npm(here), ensure_targets(jstargets), ) setup_args = dict( name=NAME, description="MathJax resources as a Jupyter Server Extension.", long_description=long_description, long_description_content_type="text/markdown", version=version, packages=find_packages(exclude=["tests*"]), author="Jupyter Development Team", author_email="jupyter@googlegroups.com", url="http://jupyter.org", license="BSD", platforms="Linux, Mac OS X, Windows", keywords=["ipython", "jupyter", "jupyter-server"], classifiers=[ "Intended Audience :: Developers", "Intended Audience :: System Administrators", "Intended Audience :: Science/Research", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", ], cmdclass=cmdclass, zip_safe=False, python_requires=">=3.6", include_package_data=True, install_requires=[ "jupyter_server~=1.1", ], extras_require={ "test": [ "jupyter_server[test]", "pytest", ], }, ) if __name__ == "__main__": setup(**setup_args)