From 7345622e8a2fa6912a31144d60d68499d9f43a62 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Thu, 30 Apr 2020 14:42:08 -0400 Subject: [PATCH 1/5] first chunk of vendoring --- .gitignore | 4 ++++ package.json | 7 ++++++- pydata_sphinx_theme/layout.html | 15 +++++++++++---- webpack.common.js | 27 +++++++++++++++++++++++++-- yarn.lock | 25 +++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index e1545372ba..25bd27a638 100644 --- a/.gitignore +++ b/.gitignore @@ -87,6 +87,7 @@ celerybeat-schedule .venv venv/ ENV/ +envs/ # Spyder project settings .spyderproject @@ -103,3 +104,6 @@ ENV/ node_modules/ .vscode + +# vendored js/css +vendor/ diff --git a/package.json b/package.json index 0328fe0bb3..50075f45a6 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,12 @@ "webpack-watch-files-plugin": "^1.0.3" }, "dependencies": { + "@fortawesome/fontawesome-free": "^5.13.0", + "@openfonts/lato_latin-ext": "^1.44.1", + "@openfonts/open-sans_all": "^1.44.1", "bootstrap": "^4.4.1", - "optimize-css-assets-webpack-plugin": "^5.0.3" + "jquery": "^3.5.0", + "optimize-css-assets-webpack-plugin": "^5.0.3", + "popper.js": "^1.16.0" } } diff --git a/pydata_sphinx_theme/layout.html b/pydata_sphinx_theme/layout.html index f3719e77be..23e2671eb8 100644 --- a/pydata_sphinx_theme/layout.html +++ b/pydata_sphinx_theme/layout.html @@ -12,8 +12,12 @@ {% endmacro %} {%- block css %} + {% if use_cdn %} - + {% else %} + + {% endif %} + {{- css() }} {%- endblock %} @@ -21,9 +25,12 @@ - + {% if use_cdn %} - + + {% else %} + + {% endif %} {%- endblock %} {# Silence the sidebar's, relbar's #} @@ -93,4 +100,4 @@ {%- block footer %} {%- include "footer.html" %} -{%- endblock %} \ No newline at end of file +{%- endblock %} diff --git a/webpack.common.js b/webpack.common.js index 6f3e60b59e..42abb37335 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,5 +1,8 @@ const path = require('path'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const CopyPlugin = require('copy-webpack-plugin'); + +const staticPath = path.resolve(__dirname, 'pydata_sphinx_theme/static'); module.exports = { entry: { @@ -7,7 +10,7 @@ module.exports = { }, output: { filename: 'js/[name].js?[hash]', - path: path.resolve(__dirname, 'pydata_sphinx_theme/static'), + path: staticPath, }, module: { rules: [ @@ -40,5 +43,25 @@ module.exports = { }, ], }, - plugins: [new CleanWebpackPlugin()], + plugins: [ + new CleanWebpackPlugin(), + new CopyPlugin([ + { + // includes popper.js + context: './node_modules/bootstrap/dist/js/', + from: 'bootstrap.bundle.min.*', + to: path.resolve(staticPath, 'vendor', 'bootstrap') + }, + { + context: './node_modules/@fortawesome/fontawesome-free/css', + from: 'all.min.css', + to: path.resolve(staticPath, 'vendor', 'fontawesome', 'css') + }, + { + context: './node_modules/@fortawesome/fontawesome-free', + from: 'webfonts', + to: path.resolve(staticPath, 'vendor', 'fontawesome', 'webfonts') + }, + ]) + ], }; diff --git a/yarn.lock b/yarn.lock index 84b97a21d8..5f9c3ba7e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,21 @@ # yarn lockfile v1 +"@fortawesome/fontawesome-free@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.13.0.tgz#fcb113d1aca4b471b709e8c9c168674fbd6e06d9" + integrity sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg== + +"@openfonts/lato_latin-ext@^1.44.1": + version "1.44.1" + resolved "https://registry.yarnpkg.com/@openfonts/lato_latin-ext/-/lato_latin-ext-1.44.1.tgz#b36a9c5905e0143f5f72e25cf635625f645603dd" + integrity sha512-uEhdHlTQtLumrWuKHV3JpzH7H1/gGnwXrNC8PAK6StF/Tq1AQPfdjokqgwrHPVQPooj/LAwujhvBwPDdW4/5eQ== + +"@openfonts/open-sans_all@^1.44.1": + version "1.44.1" + resolved "https://registry.yarnpkg.com/@openfonts/open-sans_all/-/open-sans_all-1.44.1.tgz#4a05c454a89d0a70eb2f17bfa2ea3f21e3aae091" + integrity sha512-/3uxdiRxH1Sk+llrw4o7lunFhM5IwU/LBo2PU6EYw+iMRNuoUqKU7eyeGtFdAbvErjsU9Xvbe75zkqmsBcXGaw== + "@types/anymatch@*": version "1.3.1" resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" @@ -2895,6 +2910,11 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +jquery@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.0.tgz#9980b97d9e4194611c36530e7dc46a58d7340fc9" + integrity sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ== + js-base64@^2.1.8: version "2.5.2" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209" @@ -3919,6 +3939,11 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +popper.js@^1.16.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" + integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== + portfinder@^1.0.25: version "1.0.25" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca" From bed20eddf54e6754122d7b9d732a2a0398b5f904 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Thu, 30 Apr 2020 14:57:47 -0400 Subject: [PATCH 2/5] fonts --- package.json | 1 + pydata_sphinx_theme/layout.html | 3 +++ pydata_sphinx_theme/static/css/index.css | 2 +- src/scss/index.scss | 7 ++---- webpack.common.js | 31 ++++++++++++++++++++---- yarn.lock | 5 ++++ 6 files changed, 38 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 50075f45a6..3ef482883d 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@openfonts/open-sans_all": "^1.44.1", "bootstrap": "^4.4.1", "jquery": "^3.5.0", + "mathjax": "2.7.5", "optimize-css-assets-webpack-plugin": "^5.0.3", "popper.js": "^1.16.0" } diff --git a/pydata_sphinx_theme/layout.html b/pydata_sphinx_theme/layout.html index 23e2671eb8..f6381a2e2b 100644 --- a/pydata_sphinx_theme/layout.html +++ b/pydata_sphinx_theme/layout.html @@ -14,8 +14,11 @@ {%- block css %} {% if use_cdn %} + {% else %} + + {% endif %} {{- css() }} diff --git a/pydata_sphinx_theme/static/css/index.css b/pydata_sphinx_theme/static/css/index.css index eb00f75123..4e238e2e57 100644 --- a/pydata_sphinx_theme/static/css/index.css +++ b/pydata_sphinx_theme/static/css/index.css @@ -1,4 +1,4 @@ -@import url(https://fonts.googleapis.com/css?family=Open+Sans:400|Lato:400);/*! +/*! * Bootstrap v4.4.1 (https://getbootstrap.com/) * Copyright 2011-2019 The Bootstrap Authors * Copyright 2011-2019 Twitter, Inc. diff --git a/src/scss/index.scss b/src/scss/index.scss index dbad77f578..f4906fe602 100644 --- a/src/scss/index.scss +++ b/src/scss/index.scss @@ -10,9 +10,6 @@ $container-max-widths: ( // Include core Bootstrap @import '../../node_modules/bootstrap/scss/bootstrap'; -// Import custom fonts -@import url('https://fonts.googleapis.com/css?family=Open+Sans:400|Lato:400'); - @import './base'; @import './navbar'; @@ -83,8 +80,8 @@ table.field-list { } } -/** - * Styling for autosummary tables +/** + * Styling for autosummary tables */ // The first column (with the signature) should not wrap diff --git a/webpack.common.js b/webpack.common.js index 42abb37335..f8098a88f8 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,8 +1,9 @@ -const path = require('path'); +const { resolve } = require('path'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const CopyPlugin = require('copy-webpack-plugin'); -const staticPath = path.resolve(__dirname, 'pydata_sphinx_theme/static'); +const staticPath = resolve(__dirname, 'pydata_sphinx_theme/static'); +const vendor = resolve(staticPath, 'vendor'); module.exports = { entry: { @@ -50,18 +51,38 @@ module.exports = { // includes popper.js context: './node_modules/bootstrap/dist/js/', from: 'bootstrap.bundle.min.*', - to: path.resolve(staticPath, 'vendor', 'bootstrap') + to: resolve(vendor, 'bootstrap') }, { context: './node_modules/@fortawesome/fontawesome-free/css', from: 'all.min.css', - to: path.resolve(staticPath, 'vendor', 'fontawesome', 'css') + to: resolve(vendor, 'fontawesome', 'css') }, { context: './node_modules/@fortawesome/fontawesome-free', from: 'webfonts', - to: path.resolve(staticPath, 'vendor', 'fontawesome', 'webfonts') + to: resolve(vendor, 'fontawesome', 'webfonts') }, + { + context: './node_modules/@openfonts/open-sans_all', + from: 'files/*-400*', + to: resolve(vendor, 'open-sans_all') + }, + { + context: './node_modules/@openfonts/open-sans_all', + from: 'index.css', + to: resolve(vendor, 'open-sans_all') + }, + { + context: './node_modules/@openfonts/lato_latin-ext', + from: 'files/*-400*', + to: resolve(vendor, 'lato_latin-ext') + }, + { + context: './node_modules/@openfonts/lato_latin-ext', + from: 'index.css', + to: resolve(vendor, 'lato_latin-ext') + } ]) ], }; diff --git a/yarn.lock b/yarn.lock index 5f9c3ba7e7..9f071149c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3139,6 +3139,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +mathjax@2.7.5: + version "2.7.5" + resolved "https://registry.yarnpkg.com/mathjax/-/mathjax-2.7.5.tgz#c9c5947f86f9be31651f5f3667d3c9a8bb01efe4" + integrity sha512-OzsJNitEHAJB3y4IIlPCAvS0yoXwYjlo2Y4kmm9KQzyIBZt2d8yKRalby3uTRNN4fZQiGL2iMXjpdP1u2Rq2DQ== + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" From bb35aef890fe2b5ad0689bc9763db1386a7443c2 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Thu, 30 Apr 2020 15:03:49 -0400 Subject: [PATCH 3/5] lawyer up --- webpack.common.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/webpack.common.js b/webpack.common.js index f8098a88f8..6e68dc7806 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -53,6 +53,11 @@ module.exports = { from: 'bootstrap.bundle.min.*', to: resolve(vendor, 'bootstrap') }, + { + context: './node_modules/bootstrap/', + from: 'LICENSE', + to: resolve(vendor, 'bootstrap') + }, { context: './node_modules/@fortawesome/fontawesome-free/css', from: 'all.min.css', @@ -63,6 +68,11 @@ module.exports = { from: 'webfonts', to: resolve(vendor, 'fontawesome', 'webfonts') }, + { + context: './node_modules/@fortawesome/fontawesome-free', + from: 'LICENSE', + to: resolve(vendor, 'fontawesome') + }, { context: './node_modules/@openfonts/open-sans_all', from: 'files/*-400*', @@ -73,6 +83,11 @@ module.exports = { from: 'index.css', to: resolve(vendor, 'open-sans_all') }, + { + context: './node_modules/@openfonts/open-sans_all', + from: 'LICENSE.md', + to: resolve(vendor, 'open-sans_all') + }, { context: './node_modules/@openfonts/lato_latin-ext', from: 'files/*-400*', @@ -82,7 +97,12 @@ module.exports = { context: './node_modules/@openfonts/lato_latin-ext', from: 'index.css', to: resolve(vendor, 'lato_latin-ext') - } + }, + { + context: './node_modules/@openfonts/lato_latin-ext', + from: 'LICENSE.md', + to: resolve(vendor, 'lato_latin-ext') + }, ]) ], }; From 0e04b2a012b00060692a55bd1a6bf1c43226f0ff Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Thu, 30 Apr 2020 17:03:58 -0400 Subject: [PATCH 4/5] more verbose cdn config name, default to cdn, handle sphinx <3 --- pydata_sphinx_theme/__init__.py | 71 ++++++++++++++++++++++++++++++++- pydata_sphinx_theme/layout.html | 6 +-- webpack.common.js | 30 +++++++++++++- 3 files changed, 102 insertions(+), 5 deletions(-) diff --git a/pydata_sphinx_theme/__init__.py b/pydata_sphinx_theme/__init__.py index d2e0c30bd0..ff7e971c40 100644 --- a/pydata_sphinx_theme/__init__.py +++ b/pydata_sphinx_theme/__init__.py @@ -3,13 +3,24 @@ """ import os +import docutils + +import sphinx +import sphinx.util.logging from sphinx.errors import ExtensionError from .bootstrap_html_translator import BootstrapHTML5Translator -import docutils __version__ = "0.2.2dev0" +name = "pydata_sphinx_theme" + +at_least_sphinx_three = sphinx.__version__ >= '3.0.0' + +logger = sphinx.util.logging.getLogger(__name__) + +warned = {} + def add_toctree_functions(app, pagename, templatename, context, doctree): """Add functions so Jinja templates can add toctree objects. @@ -167,6 +178,58 @@ def get_edit_url(): # ----------------------------------------------------------------------------- +def setup_cdn(app, pagename, templatename, context, doctree): + """hoist the `use_public_cdns` config value to the template context + """ + + use_public_cdns = app.config.use_public_cdns + + context["use_public_cdns"] = use_public_cdns + + if not hasattr(app.config, "mathjax_path") or at_least_sphinx_three or use_public_cdns: + return + + mathjax_path = app.config.mathjax_path + + if "https://cdnjs.cloudflare.com" not in mathjax_path: + return + + if not warned.get("mathjax_path"): + logger.warning( + "`use_public_cdns` is %s, but `mathjax_path` is configured, probably by default, as:\n\n" + " %s\n\n" + "> upgrade to `sphinx >=3`, which supports event `priority`...\n" + "> or configure `mathjax_path` in `conf.py`, e.g.:\n\n" + " import %s\n" + " mathjax_path = %s.get_mathjax_path()\n", + use_public_cdns, + mathjax_path, + name, + name, + type="configuration", + location=pagename + ) + warned["mathjax_path"] = True + + +# ----------------------------------------------------------------------------- + + +def configure_mathjax(app, env): + if not app.config.use_public_cdns: + # TODO: this needs to go in an event handler... maybe `env-before-read-docs` + # because `build_latex` fires on `env-updated`. `priority` is only sphinx 3... + app.config.mathjax_path = get_mathjax_path() + + +# ----------------------------------------------------------------------------- + + +def get_mathjax_path(): + """Return the locally-vendored MathJax path""" + return 'vendor/mathjax/latest.js?config=TeX-AMS-MML_HTMLorMML' + + def get_html_theme_path(): """Return list of HTML theme paths.""" theme_path = os.path.abspath(os.path.dirname(__file__)) @@ -185,5 +248,11 @@ def setup(app): app.set_translator("readthedocsdirhtml", BootstrapHTML5Translator, override=True) app.connect("html-page-context", setup_edit_url) app.connect("html-page-context", add_toctree_functions) + app.connect("html-page-context", setup_cdn) + + app.add_config_value('use_public_cdns', True, 'html') + + if at_least_sphinx_three: + app.connect("env-updated", configure_mathjax, priority=-1) return {"parallel_read_safe": True, "parallel_write_safe": True} diff --git a/pydata_sphinx_theme/layout.html b/pydata_sphinx_theme/layout.html index f6381a2e2b..31a723d068 100644 --- a/pydata_sphinx_theme/layout.html +++ b/pydata_sphinx_theme/layout.html @@ -12,9 +12,9 @@ {% endmacro %} {%- block css %} - {% if use_cdn %} + {% if use_public_cdns %} - + {% else %} @@ -28,7 +28,7 @@ - {% if use_cdn %} + {% if use_public_cdns %} {% else %} diff --git a/webpack.common.js b/webpack.common.js index 6e68dc7806..e462a2e3f6 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -47,6 +47,7 @@ module.exports = { plugins: [ new CleanWebpackPlugin(), new CopyPlugin([ + // bootstrap { // includes popper.js context: './node_modules/bootstrap/dist/js/', @@ -58,6 +59,7 @@ module.exports = { from: 'LICENSE', to: resolve(vendor, 'bootstrap') }, + // fonts { context: './node_modules/@fortawesome/fontawesome-free/css', from: 'all.min.css', @@ -70,7 +72,7 @@ module.exports = { }, { context: './node_modules/@fortawesome/fontawesome-free', - from: 'LICENSE', + from: 'LICENSE.txt', to: resolve(vendor, 'fontawesome') }, { @@ -103,6 +105,32 @@ module.exports = { from: 'LICENSE.md', to: resolve(vendor, 'lato_latin-ext') }, + // mathjax + { + context: './node_modules/mathjax', + from: '*.js', + to: resolve(vendor, 'mathjax') + }, + { + context: './node_modules/mathjax', + from: 'jax/output/HTML-CSS', + to: resolve(vendor, 'mathjax/jax/output/HTML-CSS') + }, + { + context: './node_modules/mathjax', + from: 'fonts/HTML-CSS/TeX', + to: resolve(vendor, 'mathjax/fonts/HTML-CSS/TeX') + }, + { + context: './node_modules/mathjax', + from: 'config/TeX-AMS-MML_HTMLorMML.js', + to: resolve(vendor, 'mathjax/config') + }, + { + context: './node_modules/mathjax', + from: 'LICENSE', + to: resolve(vendor, 'mathjax') + }, ]) ], }; From b486a752ec088266e6216814a7ee2715c08c14ba Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Thu, 30 Apr 2020 17:26:49 -0400 Subject: [PATCH 5/5] some more tweaking to conf --- pydata_sphinx_theme/__init__.py | 42 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/pydata_sphinx_theme/__init__.py b/pydata_sphinx_theme/__init__.py index ff7e971c40..92677400a2 100644 --- a/pydata_sphinx_theme/__init__.py +++ b/pydata_sphinx_theme/__init__.py @@ -13,9 +13,9 @@ __version__ = "0.2.2dev0" -name = "pydata_sphinx_theme" +NAME = "pydata_sphinx_theme" -at_least_sphinx_three = sphinx.__version__ >= '3.0.0' +at_least_sphinx_three = sphinx.__version__ >= "3.0.0" logger = sphinx.util.logging.getLogger(__name__) @@ -186,28 +186,31 @@ def setup_cdn(app, pagename, templatename, context, doctree): context["use_public_cdns"] = use_public_cdns - if not hasattr(app.config, "mathjax_path") or at_least_sphinx_three or use_public_cdns: + if not has_default_mathjax_path(app): return - mathjax_path = app.config.mathjax_path - - if "https://cdnjs.cloudflare.com" not in mathjax_path: + if at_least_sphinx_three or use_public_cdns: return + mathjax_path = app.config.mathjax_path + if not warned.get("mathjax_path"): logger.warning( - "`use_public_cdns` is %s, but `mathjax_path` is configured, probably by default, as:\n\n" + "`use_public_cdns` is %s, but `mathjax_path` is configured," + " probably by default, as:\n\n" " %s\n\n" "> upgrade to `sphinx >=3`, which supports event `priority`...\n" "> or configure `mathjax_path` in `conf.py`, e.g.:\n\n" " import %s\n" - " mathjax_path = %s.get_mathjax_path()\n", + " def setup(app):\n" + " app.config.use_public_cdns = False\n" + " app.config.mathjax_path = %s.get_mathjax_path()\n", use_public_cdns, mathjax_path, - name, - name, + NAME, + NAME, type="configuration", - location=pagename + location=pagename, ) warned["mathjax_path"] = True @@ -216,18 +219,23 @@ def setup_cdn(app, pagename, templatename, context, doctree): def configure_mathjax(app, env): - if not app.config.use_public_cdns: - # TODO: this needs to go in an event handler... maybe `env-before-read-docs` - # because `build_latex` fires on `env-updated`. `priority` is only sphinx 3... + if not app.config.use_public_cdns and has_default_mathjax_path(app): app.config.mathjax_path = get_mathjax_path() # ----------------------------------------------------------------------------- +def has_default_mathjax_path(app): + if "mathjax_path" not in app.config: + return False + + return app.config.mathjax_path == app.config.values["mathjax_path"][0] + + def get_mathjax_path(): """Return the locally-vendored MathJax path""" - return 'vendor/mathjax/latest.js?config=TeX-AMS-MML_HTMLorMML' + return "vendor/mathjax/latest.js?config=TeX-AMS-MML_HTMLorMML" def get_html_theme_path(): @@ -238,7 +246,7 @@ def get_html_theme_path(): def setup(app): theme_path = get_html_theme_path()[0] - app.add_html_theme("pydata_sphinx_theme", theme_path) + app.add_html_theme(NAME, theme_path) app.set_translator("html", BootstrapHTML5Translator) # Read the Docs uses ``readthedocs`` as the name of the build, and also @@ -250,7 +258,7 @@ def setup(app): app.connect("html-page-context", add_toctree_functions) app.connect("html-page-context", setup_cdn) - app.add_config_value('use_public_cdns', True, 'html') + app.add_config_value("use_public_cdns", True, "html") if at_least_sphinx_three: app.connect("env-updated", configure_mathjax, priority=-1)