Offline mode (closes #1181) (#2312)

Created a plugin to tackle #1181. Currently have an issue with tikzjax
since it imports some wasm file from its javascript. The rest should
work as expected.

---------

Signed-off-by: George Araujo <george.gcac@gmail.com>
This commit is contained in:
George 2024-04-08 14:51:28 -03:00 committed by GitHub
parent 876d287cc8
commit 08d562a104
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 586 additions and 307 deletions

1
.gitignore vendored
View File

@ -7,5 +7,6 @@ _site
.ruby-version
.tweet-cache
Gemfile.lock
assets/libs/
node_modules/
vendor

View File

@ -1,6 +1,8 @@
**/*.map
**/*.min.css
**/*.min.js
assets/css/main.scss
assets/js/distillpub/template.v2.js
assets/plotly/demo.html
lighthouse_results/**
_posts/2015-10-20-math.md

View File

@ -21,6 +21,7 @@ group :jekyll_plugins do
gem 'webrick'
end
group :other_plugins do
gem 'css_parser'
gem 'feedjira'
gem 'httparty'
end

View File

@ -395,72 +395,164 @@ enable_progressbar: true # enables a horizontal progress bar linked to the verti
# Library versions
# -----------------------------------------------------------------------------
bootstrap-table:
version: "1.22.1"
chartjs:
version: "4.4.1"
d3:
version: "7.8.5"
integrity: "sha256-1rA678n2xEx7x4cTZ5x4wpUCj6kUMZEZ5cxLSVSFWxw="
diff2html:
version: "3.4.47"
integrity:
css: "sha256-IMBK4VNZp0ivwefSn51bswdsrhk0HoMTLc2GqFHFBXg="
js: "sha256-eU2TVHX633T1o/bTQp6iIJByYJEtZThhF9bKz/DcbbY="
echarts:
version: "5.4.3"
integrity:
library: "sha256-EVZCmhajjLhgTcxlGMGUBtQiYULZCPjt0uNTFEPFTRk="
dark_theme: "sha256-UmFIP/4VvOqBDIl2QWl1HBuAJ1XWs/iFZxT5yJRZOKo="
highlightjs:
version: "11.9.0"
integrity:
css:
light: "sha256-Oppd74ucMR5a5Dq96FxjEzGF7tTw2fZ/6ksAqDCM8GY="
dark: "sha256-nyCNAiECsdDHrr/s2OQsp5l9XeY2ZJ0rMepjCT2AkBk="
imagesloaded:
version: "5.0.0"
integrity: "sha256-htrLFfZJ6v5udOG+3kNLINIKh2gvoKqwEhHYfTTMICc="
img-comparison-slider:
version: "8.0.6"
jquery:
version: "3.6.0"
integrity: "sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
leaflet:
version: "1.9.4"
integrity:
css: "sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
js: "sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
mathjax:
version: "3.2.0"
masonry:
version: "4.2.2"
integrity: "sha256-Nn1q/fx0H7SNLZMQ5Hw5JLaTRZp0yILA/FRexe19VdI="
mdb:
version: "4.20.0"
integrity:
css: "sha256-jpjYvU3G3N6nrrBwXJoVEYI/0zw8htfFnhT9ljN3JJw="
js: "sha256-NdbiivsvWt7VYCt6hYNT3h/th9vSTL4EDWeGs5SN3DA="
medium_zoom:
version: "1.1.0"
integrity: "sha256-ZgMyDAIYDYGxbcpJcfUnYwNevG/xi9OHKaR/8GK+jWc="
mermaid:
version: "10.7.0"
integrity: "sha256-TtLOdUA8mstPoO6sGvHIGx2ceXrrX4KgIItO06XOn8A="
swiper:
version: "11.0.5"
integrity:
css: "sha256-yUoNxsvX+Vo8Trj3lZ/Y5ZBf8HlBFsB6Xwm7rH75/9E="
js: "sha256-BPrwikijIybg9OQC5SYFFqhBjERYOn97tCureFgYH1E="
vega:
version: "5.27.0"
integrity: "sha256-Yot/cfgMMMpFwkp/5azR20Tfkt24PFqQ6IQS+80HIZs="
vega-embed:
version: "6.24.0"
integrity: "sha256-FPCJ9JYCC9AZSpvC/t/wHBX7ybueZhIqOMjpWqfl3DU="
vega-lite:
version: "5.16.3"
integrity: "sha256-TvBvIS5jUN4BSy009usRjNzjI1qRrHPYv7xVLJyjUyw="
# Add the url, version and integrity hash of the libraries you use in your site.
third_party_libraries:
download: false # if true, download the versions of the libraries specified below and use the downloaded files
bootstrap-table:
integrity:
css: "sha256-uRX+PiRTR4ysKFRCykT8HLuRCub26LgXJZym3Yeom1c="
js: "sha256-4rppopQE9POKfukn2kEvhJ9Um25Cf6+IDVkARD0xh78="
url:
css: "https://cdn.jsdelivr.net/npm/bootstrap-table@{{version}}/dist/bootstrap-table.min.css"
js: "https://cdn.jsdelivr.net/npm/bootstrap-table@{{version}}/dist/bootstrap-table.min.js"
version: "1.22.4"
chartjs:
url:
js: "https://cdn.jsdelivr.net/npm/chart.js@{{version}}/dist/chart.umd.min.js"
version: "4.4.1"
d3:
integrity:
js: "sha256-1rA678n2xEx7x4cTZ5x4wpUCj6kUMZEZ5cxLSVSFWxw="
url:
js: "https://cdn.jsdelivr.net/npm/d3@{{version}}/dist/d3.min.js"
version: "7.8.5"
diff2html:
integrity:
css: "sha256-IMBK4VNZp0ivwefSn51bswdsrhk0HoMTLc2GqFHFBXg="
js: "sha256-eU2TVHX633T1o/bTQp6iIJByYJEtZThhF9bKz/DcbbY="
url:
css: "https://cdn.jsdelivr.net/npm/diff2html@{{version}}/bundles/css/diff2html.min.css"
js: "https://cdn.jsdelivr.net/npm/diff2html@{{version}}/bundles/js/diff2html-ui.min.js"
version: "3.4.47"
echarts:
integrity:
js:
library: "sha256-QvgynZibb2U53SsVu98NggJXYqwRL7tg3FeyfXvPOUY="
dark_theme: "sha256-sm6Ui9w41++ZCWmIWDLC18a6ki72FQpWDiYTDxEPXwU="
url:
js:
library: "https://cdn.jsdelivr.net/npm/echarts@{{version}}/dist/echarts.min.js"
dark_theme: "https://cdn.jsdelivr.net/npm/echarts@{{version}}/theme/dark-fresh-cut.js"
version: "5.5.0"
google_fonts:
url:
fonts: "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Roboto+Slab:100,300,400,500,700|Material+Icons&display=swap"
highlightjs:
integrity:
css:
light: "sha256-Oppd74ucMR5a5Dq96FxjEzGF7tTw2fZ/6ksAqDCM8GY="
dark: "sha256-nyCNAiECsdDHrr/s2OQsp5l9XeY2ZJ0rMepjCT2AkBk="
url:
css:
light: "https://cdn.jsdelivr.net/npm/highlight.js@{{version}}/styles/github.min.css"
dark: "https://cdn.jsdelivr.net/npm/highlight.js@{{version}}/styles/github-dark.min.css"
version: "11.9.0"
imagesloaded:
integrity:
js: "sha256-htrLFfZJ6v5udOG+3kNLINIKh2gvoKqwEhHYfTTMICc="
url:
js: https://cdn.jsdelivr.net/npm/imagesloaded@{{version}}/imagesloaded.pkgd.min.js
version: "5.0.0"
img-comparison-slider:
url:
css: "https://cdn.jsdelivr.net/npm/img-comparison-slider@{{version}}/dist/styles.min.css"
js: "https://cdn.jsdelivr.net/npm/img-comparison-slider@{{version}}/dist/index.min.js"
version: "8.0.6"
jquery:
integrity:
js: "sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
url:
js: "https://cdn.jsdelivr.net/npm/jquery@{{version}}/dist/jquery.min.js"
version: "3.6.0"
leaflet:
integrity:
css: "sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
js: "sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
js_map: "sha256-YAoQ3FzREN4GmVENMir8vgHHypC0xfSK3CAxTHCqx1M="
url:
css: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.css"
js: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.js"
js_map: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.js.map"
version: "1.9.4"
mathjax:
local:
fonts: "output/chtml/fonts/woff-v2/"
url:
fonts: "https://cdn.jsdelivr.net/npm/mathjax@{{version}}/es5/output/chtml/fonts/woff-v2/"
js: "https://cdn.jsdelivr.net/npm/mathjax@{{version}}/es5/tex-mml-chtml.js"
version: "3.2.0"
masonry:
integrity:
js: "sha256-Nn1q/fx0H7SNLZMQ5Hw5JLaTRZp0yILA/FRexe19VdI="
url:
js: "https://cdn.jsdelivr.net/npm/masonry-layout@{{version}}/dist/masonry.pkgd.min.js"
version: "4.2.2"
mdb:
integrity:
css: "sha256-jpjYvU3G3N6nrrBwXJoVEYI/0zw8htfFnhT9ljN3JJw="
css_map: "sha256-iYYMNfsJdVZjvsebJulg09miBXM4/GMTJgv1u5EZFFM="
js: "sha256-NdbiivsvWt7VYCt6hYNT3h/th9vSTL4EDWeGs5SN3DA="
js_map: "sha256-UPgyn4YNsT0khkBK5553QwhnlbTlU0aa+igyc6qP1bE="
url:
css: "https://cdn.jsdelivr.net/npm/mdbootstrap@{{version}}/css/mdb.min.css"
css_map: "https://cdn.jsdelivr.net/npm/mdbootstrap@{{version}}/css/mdb.min.css.map"
js: "https://cdn.jsdelivr.net/npm/mdbootstrap@{{version}}/js/mdb.min.js"
js_map: "https://cdn.jsdelivr.net/npm/mdbootstrap@{{version}}/js/mdb.min.js.map"
version: "4.20.0"
medium_zoom:
integrity:
js: "sha256-ZgMyDAIYDYGxbcpJcfUnYwNevG/xi9OHKaR/8GK+jWc="
url:
js: "https://cdn.jsdelivr.net/npm/medium-zoom@{{version}}/dist/medium-zoom.min.js"
version: "1.1.0"
mermaid:
integrity:
js: "sha256-TtLOdUA8mstPoO6sGvHIGx2ceXrrX4KgIItO06XOn8A="
url:
js: "https://cdn.jsdelivr.net/npm/mermaid@{{version}}/dist/mermaid.min.js"
version: "10.7.0"
polyfill:
url:
js: "https://cdnjs.cloudflare.com/polyfill/v{{version}}/polyfill.min.js?features=es6"
version: "3"
swiper:
integrity:
css: "sha256-yUoNxsvX+Vo8Trj3lZ/Y5ZBf8HlBFsB6Xwm7rH75/9E="
js: "sha256-BPrwikijIybg9OQC5SYFFqhBjERYOn97tCureFgYH1E="
url:
css: "https://cdn.jsdelivr.net/npm/swiper@{{version}}/swiper-bundle.min.css"
js: "https://cdn.jsdelivr.net/npm/swiper@{{version}}/swiper-element-bundle.min.js"
version: "11.0.5"
swiper-map:
integrity:
js: "sha256-hlZaH8ySXX97bZaetnrtYlKuhx3oEXFz/s2IXchu6vk="
url:
js: "https://cdn.jsdelivr.net/npm/swiper@11.1.0/swiper-element-bundle.min.js.map"
version: "11.0.5"
vega:
integrity:
js: "sha256-Yot/cfgMMMpFwkp/5azR20Tfkt24PFqQ6IQS+80HIZs="
js_map: "sha256-z0x9ICA65dPkZ0JVa9wTImfF6n7AJsKc6WlFE96/wNA="
url:
js: "https://cdn.jsdelivr.net/npm/vega@{{version}}/build/vega.min.js"
js_map: "https://cdn.jsdelivr.net/npm/vega@{{version}}/build/vega.min.js.map"
version: "5.27.0"
vega-embed:
integrity:
js: "sha256-FPCJ9JYCC9AZSpvC/t/wHBX7ybueZhIqOMjpWqfl3DU="
js_map: "sha256-VBbfSEFYSMdX/rTdGrONEHNP6BprCB7H/LpMMNt/cPA="
url:
js: "https://cdn.jsdelivr.net/npm/vega-embed@{{version}}/build/vega-embed.min.js"
js_map: "https://cdn.jsdelivr.net/npm/vega-embed@{{version}}/build/vega-embed.min.js.map"
version: "6.24.0"
vega-lite:
integrity:
js: "sha256-TvBvIS5jUN4BSy009usRjNzjI1qRrHPYv7xVLJyjUyw="
js_map: "sha256-l2I4D5JC23Ulsu6e3sKVe5AJ+r+DFkzkKnZS8nUGz28="
url:
js: "https://cdn.jsdelivr.net/npm/vega-lite@{{version}}/build/vega-lite.min.js"
js_map: "https://cdn.jsdelivr.net/npm/vega-lite@{{version}}/build/vega-lite.min.js.map"
version: "5.16.3"
# -----------------------------------------------------------------------------
# Get external JSON data

View File

@ -3,17 +3,22 @@
<!-- Bootstrap & MDB -->
<link rel="stylesheet" href="{{ '/assets/css/bootstrap.min.css' | relative_url | bust_file_cache }}">
<!-- <link rel="stylesheet" href="{{ '/assets/css/mdb.min.css' | relative_url | bust_file_cache }}"> -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/mdbootstrap@{{ site.mdb.version }}/css/mdb.min.css"
integrity="{{ site.mdb.integrity.css }}"
href="{{ site.third_party_libraries.mdb.url.css }}"
integrity="{{ site.third_party_libraries.mdb.integrity.css }}"
crossorigin="anonymous"
>
<!-- Bootstrap Table -->
{% if page.pretty_table %}
<link defer rel="stylesheet" href="https://unpkg.com/bootstrap-table@{{ site.bootstrap-table.version }}/dist/bootstrap-table.min.css">
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.bootstrap-table.url.css }}"
integrity="{{ site.third_party_libraries.bootstrap-table.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
<!-- Fonts & Icons -->
@ -22,7 +27,7 @@
defer
rel="stylesheet"
type="text/css"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Roboto+Slab:100,300,400,500,700|Material+Icons&display=swap"
href="{{ site.third_party_libraries.google_fonts.url.fonts }}"
>
<!-- Code Syntax Highlighting -->
@ -71,9 +76,9 @@
<link
defer
rel="stylesheet"
href="https://unpkg.com/leaflet@{{ site.leaflet.version }}/dist/leaflet.css"
integrity="{{ site.leaflet.integrity.css }}"
crossorigin=""
href="{{ site.third_party_libraries.leaflet.url.css }}"
integrity="{{ site.third_party_libraries.leaflet.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
@ -82,24 +87,24 @@
<link
defer
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/highlight.js@{{ site.highlightjs.version }}/styles/github.min.css"
integrity="{{ site.highlightjs.integrity.css.light }}"
href="{{ site.third_party_libraries.highlightjs.url.css.light }}"
integrity="{{ site.third_party_libraries.highlightjs.integrity.css.light }}"
crossorigin="anonymous"
media="screen and (prefers-color-scheme: light)"
>
<link
defer
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/highlight.js@{{ site.highlightjs.version }}/styles/github-dark.min.css"
integrity="{{ site.highlightjs.integrity.css.dark }}"
href="{{ site.third_party_libraries.highlightjs.url.css.dark }}"
integrity="{{ site.third_party_libraries.highlightjs.integrity.css.dark }}"
crossorigin="anonymous"
media="screen and (prefers-color-scheme: dark)"
>
<link
defer
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/diff2html@{{ site.diff2html.version }}/bundles/css/diff2html.min.css"
integrity="{{ site.diff2html.integrity.css }}"
href="{{ site.third_party_libraries.diff2html.url.css }}"
integrity="{{ site.third_party_libraries.diff2html.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
@ -110,7 +115,7 @@
<link
defer
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/img-comparison-slider@{{ site.img-comparison-slider.version }}/dist/styles.min.css"
href="{{ site.third_party_libraries.img-comparison-slider.url.css }}"
>
{% endif %}
<!-- Image slider -->
@ -118,8 +123,8 @@
<link
defer
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/swiper@{{ site.swiper.version }}/swiper-bundle.min.css"
integrity="{{ site.swiper.integrity.css }}"
href="{{ site.third_party_libraries.swiper.url.css }}"
integrity="{{ site.third_party_libraries.swiper.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}

View File

@ -2,7 +2,7 @@
<script src="{{ '/assets/js/bootstrap.bundle.min.js' | relative_url }}"></script>
<!-- <script src="{{ '/assets/js/mdb.min.js' | relative_url }}"></script> -->
<script
src="https://cdn.jsdelivr.net/npm/mdbootstrap@{{ site.mdb.version }}/js/mdb.min.js"
integrity="{{ site.mdb.integrity.js }}"
src="{{ site.third_party_libraries.mdb.url.js }}"
integrity="{{ site.third_party_libraries.mdb.integrity.js }}"
crossorigin="anonymous"
></script>

View File

@ -1,5 +1,5 @@
{% if page.chart and page.chart.chartjs %}
<script defer src="https://cdn.jsdelivr.net/npm/chart.js@{{ site.chartjs.version }}/dist/chart.umd.min.js"></script>
<script defer src="{{ site.third_party_libraries.chartjs.url.js }}"></script>
<script>
$(document).ready(function () {
var $canvas = null,

View File

@ -1,9 +1,8 @@
{% if page.code_diff %}
<!-- diff2html doesn't go well with Bootstrap Table -->
<script
defer
src="https://cdn.jsdelivr.net/npm/diff2html@{{ site.diff2html.version }}/bundles/js/diff2html-ui.min.js"
integrity="{{ site.diff2html.integrity.js }}"
src="{{ site.third_party_libraries.diff2html.url.js }}"
integrity="{{ site.third_party_libraries.diff2html.integrity.js }}"
crossorigin="anonymous"
></script>
<script>

View File

@ -1,15 +1,13 @@
{% if page.chart and page.chart.echarts %}
<script
defer
src="https://cdn.jsdelivr.net/npm/echarts@{{ site.echarts.version }}/dist/echarts.min.js"
integrity="{{ site.echarts.integrity.library }}"
src="{{ site.third_party_libraries.echarts.url.js.library }}"
integrity="{{ site.third_party_libraries.echarts.integrity.js.library }}"
crossorigin="anonymous"
></script>
{% if site.enable_darkmode %}
<script
defer
src="https://cdn.jsdelivr.net/npm/echarts@{{ site.echarts.version }}/theme/dark-fresh-cut.js"
integrity="{{ site.echarts.integrity.dark_theme }}"
src="{{ site.third_party_libraries.echarts.url.js.dark_theme }}"
integrity="{{ site.third_party_libraries.echarts.integrity.js.dark_theme }}"
crossorigin="anonymous"
></script>
{% endif %}

View File

@ -1,12 +1,12 @@
{% if page.images %}
{% if page.images.compare %}
<script defer src="https://cdn.jsdelivr.net/npm/img-comparison-slider@{{ site.img-comparison-slider.version }}/dist/index.min.js"></script>
<script defer src="{{ site.third_party_libraries.img-comparison-slider.url.js }}"></script>
{% endif %}
{% if page.images.slider %}
<script
defer
src="https://cdn.jsdelivr.net/npm/swiper@{{ site.swiper.version }}/swiper-element-bundle.min.js"
integrity="{{ site.swiper.integrity.js }}"
src="{{ site.third_party_libraries.swiper.url.js }}"
integrity="{{ site.third_party_libraries.swiper.integrity.js }}"
crossorigin="anonymous"
></script>
{% endif %}

View File

@ -1,6 +1,6 @@
<!-- jQuery -->
<script
src="https://cdn.jsdelivr.net/npm/jquery@{{ site.jquery.version }}/dist/jquery.min.js"
integrity="{{ site.jquery.integrity }}"
src="{{ site.third_party_libraries.jquery.url.js }}"
integrity="{{ site.third_party_libraries.jquery.integrity.js }}"
crossorigin="anonymous"
></script>

View File

@ -1,8 +1,7 @@
{% if page.map %}
<script
defer
src="https://unpkg.com/leaflet@{{ site.leaflet.version }}/dist/leaflet.js"
integrity="{{ site.leaflet.integrity.js }}"
src="{{ site.third_party_libraries.leaflet.url.js }}"
integrity="{{ site.third_party_libraries.leaflet.integrity.js }}"
crossorigin=""
></script>
<script>

View File

@ -2,14 +2,14 @@
<!-- Masonry & imagesLoaded -->
<script
defer
src="https://cdn.jsdelivr.net/npm/masonry-layout@{{ site.masonry.version }}/dist/masonry.pkgd.min.js"
integrity="{{ site.masonry.integrity }}"
src="{{ site.third_party_libraries.masonry.url.js }}"
integrity="{{ site.third_party_libraries.masonry.integrity.js }}"
crossorigin="anonymous"
></script>
<script
defer
src="https://cdn.jsdelivr.net/npm/imagesloaded@{{ site.imagesloaded.version }}/imagesloaded.pkgd.min.js"
integrity="{{ site.imagesloaded.integrity }}"
src="{{ site.third_party_libraries.imagesloaded.url.js }}"
integrity="{{ site.third_party_libraries.imagesloaded.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/masonry.js' | relative_url }}" type="text/javascript"></script>

View File

@ -11,7 +11,7 @@
defer
type="text/javascript"
id="MathJax-script"
src="https://cdn.jsdelivr.net/npm/mathjax@{{ site.mathjax.version }}/es5/tex-mml-chtml.js"
src="{{ site.third_party_libraries.mathjax.url.js }}"
></script>
<script defer src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
<script defer src="{{ site.third_party_libraries.polyfill.url.js }}"></script>
{% endif %}

View File

@ -1,15 +1,15 @@
{% if page.mermaid and page.mermaid.enabled %}
<script
defer
src="https://cdn.jsdelivr.net/npm/mermaid@{{ site.mermaid.version }}/dist/mermaid.min.js"
integrity="{{ site.mermaid.integrity }}"
src="{{ site.third_party_libraries.mermaid.url.js }}"
integrity="{{ site.third_party_libraries.mermaid.integrity.js }}"
crossorigin="anonymous"
></script>
{% if page.mermaid.zoomable %}
<script
defer
src="https://cdn.jsdelivr.net/npm/d3@{{ site.d3.version }}/dist/d3.min.js"
integrity="{{ site.d3.integrity }}"
src="{{ site.third_party_libraries.d3.url.js }}"
integrity="{{ site.third_party_libraries.d3.integrity.js }}"
crossorigin="anonymous"
></script>
{% endif %}

View File

@ -10,8 +10,8 @@
<!-- Medium Zoom JS -->
<script
defer
src="https://cdn.jsdelivr.net/npm/medium-zoom@{{ site.medium_zoom.version }}/dist/medium-zoom.min.js"
integrity="{{ site.medium_zoom.integrity }}"
src="{{ site.third_party_libraries.medium_zoom.url.js }}"
integrity="{{ site.third_party_libraries.medium_zoom.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/zoom.js' | relative_url | bust_file_cache }}"></script>
@ -24,7 +24,12 @@
<!-- Bootstrap Table -->
{% if page.pretty_table %}
<!-- Bootstrap Table doesn't go well with diff2html -->
<script defer src="https://unpkg.com/bootstrap-table@{{ site.bootstrap-table.version }}/dist/bootstrap-table.min.js"></script>
<script
defer
src="{{ site.third_party_libraries.bootstrap-table.url.js }}"
integrity="{{ site.third_party_libraries.bootstrap-table.integrity.js }}"
crossorigin="anonymous"
></script>
{% endif %}
<!-- Load Common JS -->
@ -34,3 +39,5 @@
<!-- Jupyter Open External Links New Tab -->
<script defer src="{{ '/assets/js/jupyter_new_tab.js' | relative_url | bust_file_cache }}"></script>
{% assign site.test-library.url = site.test-library.url | append: 'teste' %}

View File

@ -1,20 +1,20 @@
{% if page.chart and page.chart.vega_lite %}
<script
defer
src="https://cdn.jsdelivr.net/npm/vega@{{ site.vega.version }}/build/vega.min.js"
integrity="{{ site.vega.integrity }}"
src="{{ site.third_party_libraries.vega.url.js }}"
integrity="{{ site.third_party_libraries.vega.integrity.js }}"
crossorigin="anonymous"
></script>
<script
defer
src="https://cdn.jsdelivr.net/npm/vega-lite@{{ site.vega-lite.version }}/build/vega-lite.min.js"
integrity="{{ site.vega-lite.integrity }}"
src="{{ site.third_party_libraries.vega-lite.url.js }}"
integrity="{{ site.third_party_libraries.vega-lite.integrity.js }}"
crossorigin="anonymous"
></script>
<script
defer
src="https://cdn.jsdelivr.net/npm/vega-embed@{{ site.vega-embed.version }}/build/vega-embed.min.js"
integrity="{{ site.vega-embed.integrity }}"
src="{{ site.third_party_libraries.vega-embed.url.js }}"
integrity="{{ site.third_party_libraries.vega-embed.integrity.js }}"
crossorigin="anonymous"
></script>

View File

@ -6,8 +6,8 @@
<!-- Medium Zoom JS -->
<script
defer
src="https://cdn.jsdelivr.net/npm/medium-zoom@{{ site.medium_zoom.version }}/dist/medium-zoom.min.js"
integrity="{{ site.medium_zoom.integrity }}"
src="{{ site.third_party_libraries.medium_zoom.url.js }}"
integrity="{{ site.third_party_libraries.medium_zoom.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/zoom.js' | relative_url | bust_file_cache }}"></script>

View File

@ -1,51 +1,51 @@
# based on https://distresssignal.org/busting-css-cache-with-jekyll-md5-hash
# https://gist.github.com/BryanSchuetz/2ee8c115096d7dd98f294362f6a667db
module Jekyll
module CacheBust
class CacheDigester
require 'digest/md5'
require 'pathname'
module CacheBust
class CacheDigester
require 'digest/md5'
require 'pathname'
attr_accessor :file_name, :directory
attr_accessor :file_name, :directory
def initialize(file_name:, directory: nil)
self.file_name = file_name
self.directory = directory
end
def initialize(file_name:, directory: nil)
self.file_name = file_name
self.directory = directory
end
def digest!
[file_name, '?', Digest::MD5.hexdigest(file_contents)].join
end
def digest!
[file_name, '?', Digest::MD5.hexdigest(file_contents)].join
end
private
private
def directory_files_content
target_path = File.join(directory, '**', '*')
Dir[target_path].map{|f| File.read(f) unless File.directory?(f) }.join
end
def directory_files_content
target_path = File.join(directory, '**', '*')
Dir[target_path].map{|f| File.read(f) unless File.directory?(f) }.join
end
def file_content
local_file_name = file_name.slice((file_name.index('assets/')..-1))
File.read(local_file_name)
end
def file_content
local_file_name = file_name.slice((file_name.index('assets/')..-1))
File.read(local_file_name)
end
def file_contents
is_directory? ? file_content : directory_files_content
end
def file_contents
is_directory? ? file_content : directory_files_content
end
def is_directory?
directory.nil?
end
end
def bust_file_cache(file_name)
CacheDigester.new(file_name: file_name, directory: nil).digest!
end
def bust_css_cache(file_name)
CacheDigester.new(file_name: file_name, directory: 'assets/_sass').digest!
end
def is_directory?
directory.nil?
end
end
def bust_file_cache(file_name)
CacheDigester.new(file_name: file_name, directory: nil).digest!
end
def bust_css_cache(file_name)
CacheDigester.new(file_name: file_name, directory: 'assets/_sass').digest!
end
end
end
Liquid::Template.register_filter(Jekyll::CacheBust)

View File

@ -1,24 +1,23 @@
# Code from http://movb.de/jekyll-details-support.html
module Jekyll
module Tags
class DetailsTag < Liquid::Block
def initialize(tag_name, markup, tokens)
super
@caption = markup
end
def render(context)
site = context.registers[:site]
converter = site.find_converter_instance(::Jekyll::Converters::Markdown)
caption = converter.convert(@caption).gsub(/<\/?p[^>]*>/, '').chomp
body = converter.convert(super(context))
"<details><summary>#{caption}</summary>#{body}</details>"
end
module Tags
class DetailsTag < Liquid::Block
def initialize(tag_name, markup, tokens)
super
@caption = markup
end
def render(context)
site = context.registers[:site]
converter = site.find_converter_instance(::Jekyll::Converters::Markdown)
caption = converter.convert(@caption).gsub(/<\/?p[^>]*>/, '').chomp
body = converter.convert(super(context))
"<details><summary>#{caption}</summary>#{body}</details>"
end
end
end
end
Liquid::Template.register_tag('details', Jekyll::Tags::DetailsTag)
Liquid::Template.register_tag('details', Jekyll::Tags::DetailsTag)

View File

@ -0,0 +1,199 @@
Jekyll::Hooks.register :site, :after_init do |site|
require 'css_parser'
require 'digest'
require 'fileutils'
require 'nokogiri'
require 'open-uri'
require 'uri'
def download_file(url, dest)
# create the directory if it doesn't exist
dir = File.dirname(dest)
unless File.directory?(dir)
FileUtils.mkdir_p(dir)
end
# download the file if it doesn't exist
unless File.file?(dest)
puts "Downloading #{url} to #{dest}"
File.open(dest, "wb") do |saved_file|
URI.open(url, "rb") do |read_file|
saved_file.write(read_file.read)
end
end
# check if the file was downloaded successfully
unless File.file?(dest)
raise "Failed to download #{url} to #{dest}"
end
end
end
def download_fonts(url, dest)
# only download fonts if the directory doesn't exist or is empty
unless File.directory?(dest) && !Dir.empty?(dest)
puts "Downloading fonts from #{url} to #{dest}"
# get available fonts from the url
doc = Nokogiri::HTML(URI.open(url, "User-Agent" => "Ruby/#{RUBY_VERSION}"))
doc.css('a').each do |link|
# get the file name from the url
file_name = link['href'].split('/').last.split('?').first
# verify if the file is a font file
if file_name.end_with?('.woff', '.woff2', '.ttf', '.otf')
# download the file and change the url to the local file
download_file(URI.join(url, link['href']).to_s, File.join(dest, file_name))
end
end
end
end
def download_fonts_from_css(config, url, dest)
# get the file name from the url
file_name = url.split('/').last.split('?').first
if file_name == 'css'
file_name = 'google-fonts.css'
end
# only download the css file if it doesn't exist
unless File.file?(File.join(dest, file_name))
puts "Downloading fonts from #{url} to #{dest}"
# download the css file with a fake user agent to force downloading woff2 fonts instead of ttf
# user agent from https://www.whatismybrowser.com/guides/the-latest-user-agent/chrome
doc = Nokogiri::HTML(URI.open(url, "User-Agent" => "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"))
css = CssParser::Parser.new
css.load_string! doc.document.text
# get the font-face rules
css.each_rule_set do |rule_set|
# check if the rule set has a url
if rule_set['src'].include?('url(')
# get the font file url
font_url = rule_set['src'].split('url(').last.split(')').first
# remove quotes from the url
if font_url.start_with?('"') || font_url.start_with?("'")
font_url = font_url[1..-2]
end
font_file_name = font_url.split('/').last.split('?').first
# verify if the file is a font file
if font_file_name.end_with?('.woff', '.woff2', '.ttf', '.otf')
# fix the font url if it is not an absolute url
unless font_url.start_with?('https://')
font_url = URI.join(url, font_url).to_s
end
# download the file
download_file(font_url, File.join(dest, 'fonts', font_file_name))
# change the font url to the local file, considering baseurl
if config['baseurl']
# add rest of the src attribute if it exists
if rule_set['src'].split(' ').length > 1
rule_set['src'] = "url(#{File.join(config['baseurl'], 'assets', 'libs', 'fonts', font_file_name)}) #{rule_set['src'].split(' ').last}"
else
rule_set['src'] = "url(#{File.join(config['baseurl'], 'assets', 'libs', 'fonts', font_file_name)})"
end
else
# add rest of the src attribute if it exists
if rule_set['src'].split(' ').length > 1
rule_set['src'] = "url(#{File.join('/assets', 'libs', 'fonts', font_file_name)}) #{rule_set['src'].split(' ').last}"
else
rule_set['src'] = "url(#{File.join('/assets', 'libs', 'fonts', font_file_name)})"
end
end
end
end
end
# save the modified css file
File.write(File.join(dest, file_name), css.to_s)
end
return file_name
end
# replace {{version}} with the version number in all 3rd party libraries urls
site.config['third_party_libraries'].each do |key, value|
if key != 'download'
value['url'].each do |type, url|
# check if url is a dictionary
if url.is_a?(Hash)
url.each do |type2, url2|
# replace {{version}} with the version number if it exists
if url2.include?('{{version}}')
site.config['third_party_libraries'][key]['url'][type][type2] = url2.gsub('{{version}}', site.config['third_party_libraries'][key]['version'])
end
end
else
# replace {{version}} with the version number if it exists
if url.include?('{{version}}')
site.config['third_party_libraries'][key]['url'][type] = url.gsub('{{version}}', site.config['third_party_libraries'][key]['version'])
end
end
end
end
end
# download 3rd party libraries if required
if site.config['third_party_libraries']['download']
site.config['third_party_libraries'].each do |key, value|
if key != 'download'
value['url'].each do |type, url|
# check if url is a dictionary
if url.is_a?(Hash)
url.each do |type2, url2|
# get the file name from the url
file_name = url2.split('/').last.split('?').first
# download the file and change the url to the local file
dest = File.join(site.source, 'assets', 'libs', file_name)
download_file(url2, dest)
# change the url to the local file, considering baseurl
if site.config['baseurl']
site.config['third_party_libraries'][key]['url'][type][type2] = File.join(site.config['baseurl'], 'assets', 'libs', file_name)
else
site.config['third_party_libraries'][key]['url'][type][type2] = File.join('/assets', 'libs', file_name)
end
end
else
if type == 'fonts'
# get the file name from the url
file_name = url.split('/').last.split('?').first
if file_name.end_with?('css')
# if the file is a css file, download the css file, the fonts from it, and change information on the css file
file_name = download_fonts_from_css(site.config, url, File.join(site.source, 'assets', 'libs'))
# change the url to the local file, considering baseurl
if site.config['baseurl']
site.config['third_party_libraries'][key]['url'][type] = File.join(site.config['baseurl'], 'assets', 'libs', file_name)
else
site.config['third_party_libraries'][key]['url'][type] = File.join('/assets', 'libs', file_name)
end
else
# download the font files and change the url to the local file
download_fonts(url, File.join(site.source, 'assets', 'libs', site.config['third_party_libraries'][key]['local']['fonts']))
end
else
# get the file name from the url
file_name = url.split('/').last.split('?').first
# download the file and change the url to the local file
dest = File.join(site.source, 'assets', 'libs', file_name)
download_file(url, dest)
# change the url to the local file, considering baseurl
if site.config['baseurl']
site.config['third_party_libraries'][key]['url'][type] = File.join(site.config['baseurl'], 'assets', 'libs', file_name)
else
site.config['third_party_libraries'][key]['url'][type] = File.join('/assets', 'libs', file_name)
end
end
end
end
end
end
end
end

View File

@ -32,5 +32,4 @@ module ExternalPosts
end
end
end
end

View File

@ -1,23 +1,22 @@
module Jekyll
class FileExistsTag < Liquid::Tag
def initialize(tag_name, path, tokens)
super
@path = path
end
def render(context)
# Pipe parameter through Liquid to make additional replacements possible
url = Liquid::Template.parse(@path).render context
# Adds the site source, so that it also works with a custom one
site_source = context.registers[:site].config['source']
file_path = site_source + '/' + url
# Check if file exists (returns true or false)
"#{File.exist?(file_path.strip!)}"
end
class FileExistsTag < Liquid::Tag
def initialize(tag_name, path, tokens)
super
@path = path
end
def render(context)
# Pipe parameter through Liquid to make additional replacements possible
url = Liquid::Template.parse(@path).render context
# Adds the site source, so that it also works with a custom one
site_source = context.registers[:site].config['source']
file_path = site_source + '/' + url
# Check if file exists (returns true or false)
"#{File.exist?(file_path.strip!)}"
end
end
end
Liquid::Template.register_tag('file_exists', Jekyll::FileExistsTag)

View File

@ -3,76 +3,76 @@ require 'nokogiri'
require 'open-uri'
module Helpers
extend ActiveSupport::NumberHelper
extend ActiveSupport::NumberHelper
end
module Jekyll
class GoogleScholarCitationsTag < Liquid::Tag
Citations = { }
class GoogleScholarCitationsTag < Liquid::Tag
Citations = { }
def initialize(tag_name, params, tokens)
super
splitted = params.split(" ").map(&:strip)
@scholar_id = splitted[0]
@article_id = splitted[1]
end
def initialize(tag_name, params, tokens)
super
splitted = params.split(" ").map(&:strip)
@scholar_id = splitted[0]
@article_id = splitted[1]
end
def render(context)
article_id = context[@article_id.strip]
scholar_id = context[@scholar_id.strip]
article_url = "https://scholar.google.com/citations?view_op=view_citation&hl=en&user=#{scholar_id}&citation_for_view=#{scholar_id}:#{article_id}"
def render(context)
article_id = context[@article_id.strip]
scholar_id = context[@scholar_id.strip]
article_url = "https://scholar.google.com/citations?view_op=view_citation&hl=en&user=#{scholar_id}&citation_for_view=#{scholar_id}:#{article_id}"
begin
# If the citation count has already been fetched, return it
if GoogleScholarCitationsTag::Citations[article_id]
return GoogleScholarCitationsTag::Citations[article_id]
end
begin
# If the citation count has already been fetched, return it
if GoogleScholarCitationsTag::Citations[article_id]
return GoogleScholarCitationsTag::Citations[article_id]
end
# Sleep for a random amount of time to avoid being blocked
sleep(rand(1.5..3.5))
# Sleep for a random amount of time to avoid being blocked
sleep(rand(1.5..3.5))
# Fetch the article page
doc = Nokogiri::HTML(URI.open(article_url, "User-Agent" => "Ruby/#{RUBY_VERSION}"))
# Fetch the article page
doc = Nokogiri::HTML(URI.open(article_url, "User-Agent" => "Ruby/#{RUBY_VERSION}"))
# Attempt to extract the "Cited by n" string from the meta tags
citation_count = 0
# Attempt to extract the "Cited by n" string from the meta tags
citation_count = 0
# Look for meta tags with "name" attribute set to "description"
description_meta = doc.css('meta[name="description"]')
og_description_meta = doc.css('meta[property="og:description"]')
# Look for meta tags with "name" attribute set to "description"
description_meta = doc.css('meta[name="description"]')
og_description_meta = doc.css('meta[property="og:description"]')
if !description_meta.empty?
cited_by_text = description_meta[0]['content']
matches = cited_by_text.match(/Cited by (\d+[,\d]*)/)
if !description_meta.empty?
cited_by_text = description_meta[0]['content']
matches = cited_by_text.match(/Cited by (\d+[,\d]*)/)
if matches
citation_count = matches[1].sub(",", "").to_i
end
elsif !og_description_meta.empty?
cited_by_text = og_description_meta[0]['content']
matches = cited_by_text.match(/Cited by (\d+[,\d]*)/)
if matches
citation_count = matches[1].sub(",", "").to_i
end
end
citation_count = Helpers.number_to_human(citation_count, :format => '%n%u', :precision => 2, :units => { :thousand => 'K', :million => 'M', :billion => 'B' })
rescue Exception => e
# Handle any errors that may occur during fetching
citation_count = "N/A"
# Print the error message including the exception class and message
puts "Error fetching citation count for #{article_id}: #{e.class} - #{e.message}"
if matches
citation_count = matches[1].sub(",", "").to_i
end
elsif !og_description_meta.empty?
cited_by_text = og_description_meta[0]['content']
matches = cited_by_text.match(/Cited by (\d+[,\d]*)/)
GoogleScholarCitationsTag::Citations[article_id] = citation_count
return "#{citation_count}"
end
if matches
citation_count = matches[1].sub(",", "").to_i
end
end
citation_count = Helpers.number_to_human(citation_count, :format => '%n%u', :precision => 2, :units => { :thousand => 'K', :million => 'M', :billion => 'B' })
rescue Exception => e
# Handle any errors that may occur during fetching
citation_count = "N/A"
# Print the error message including the exception class and message
puts "Error fetching citation count for #{article_id}: #{e.class} - #{e.message}"
end
GoogleScholarCitationsTag::Citations[article_id] = citation_count
return "#{citation_count}"
end
end
end
Liquid::Template.register_tag('google_scholar_citations', Jekyll::GoogleScholarCitationsTag)

View File

@ -0,0 +1,15 @@
module Jekyll
module HideCustomBibtex
def hideCustomBibtex(input)
keywords = @context.registers[:site].config['filtered_bibtex_keywords']
keywords.each do |keyword|
input = input.gsub(/^.*\b#{keyword}\b *= *\{.*$\n/, '')
end
return input
end
end
end
Liquid::Template.register_filter(Jekyll::HideCustomBibtex)

View File

@ -1,15 +0,0 @@
module Jekyll
module HideCustomBibtex
def hideCustomBibtex(input)
keywords = @context.registers[:site].config['filtered_bibtex_keywords']
keywords.each do |keyword|
input = input.gsub(/^.*\b#{keyword}\b *= *\{.*$\n/, '')
end
return input
end
end
end
Liquid::Template.register_filter(Jekyll::HideCustomBibtex)

View File

@ -1,32 +1,32 @@
# based on https://distresssignal.org/busting-css-cache-with-jekyll-md5-hash
# https://gist.github.com/BryanSchuetz/2ee8c115096d7dd98f294362f6a667db
module Jekyll
module CleanString
class RemoveAccents
require 'i18n'
I18n.config.available_locales = :en
module CleanString
class RemoveAccents
require 'i18n'
I18n.config.available_locales = :en
attr_accessor :string
attr_accessor :string
def initialize(string:)
self.string = string
end
def initialize(string:)
self.string = string
end
def digest!
remove_accents
end
def digest!
remove_accents
end
private
private
def remove_accents
I18n.transliterate(string)
end
end
def remove_accents(string)
RemoveAccents.new(string: string).digest!
end
def remove_accents
I18n.transliterate(string)
end
end
def remove_accents(string)
RemoveAccents.new(string: string).digest!
end
end
end
Liquid::Template.register_filter(Jekyll::CleanString)

20
assets/js/mdb.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long