diff options
author | Dan Zheng <danielzheng@google.com> | 2021-02-01 11:06:14 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-01 17:06:14 +0100 |
commit | 05a39e520452cbf9b11c55df6a24f0643dfedaf8 (patch) | |
tree | f8ac750711eb9f0ee7fd169dfd7c8c504b80e024 /static | |
parent | 718a86cada3a9287708882fc563e1605f5f24aca (diff) |
Support LaTeX in static rendered HTML. (#487)
* Support LaTeX in static rendered HTML.
Static HTML pages created via `dex script --outfmt html` now support KaTeX,
in addition to `dex web` dynamic notebooks.
* Clean up static and dynamic HTML rendering.
Unify static and dynamic JS files into static/index.js.
The only public API is a `render(renderMode)` function.
Rename static/index.html to static/dynamic.html because it
is used only for dynamic pages.
Diffstat (limited to 'static')
-rw-r--r-- | static/dynamic.html (renamed from static/index.html) | 7 | ||||
-rw-r--r-- | static/dynamic.js | 85 | ||||
-rw-r--r-- | static/index.js | 113 |
3 files changed, 117 insertions, 88 deletions
diff --git a/static/index.html b/static/dynamic.html index d1774f2e..d0567873 100644 --- a/static/index.html +++ b/static/dynamic.html @@ -9,15 +9,16 @@ <!-- KaTeX: LaTeX rendering --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous"> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script> - <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script> + <!-- Do dynamic webpage rendering on-load. --> + <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" onload="render(RENDER_MODE.DYNAMIC);" crossorigin="anonymous"></script> </head> <body> <div id="main-output"></div> -</body> +<script src="/index.js""></script> -<script src="/dynamic.js"></script> +</body> </html> diff --git a/static/dynamic.js b/static/dynamic.js deleted file mode 100644 index 7aeeb952..00000000 --- a/static/dynamic.js +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2019 Google LLC -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -var katexOptions = { - delimiters: [ - {left: "$$", right: "$$", display: true}, - {left: "\\[", right: "\\]", display: true}, - {left: "$", right: "$", display: false}, - {left: "\\(", right: "\\)", display: false} - ], - // Enable commands that load resources or change HTML attributes - // (e.g. hyperlinks): https://katex.org/docs/security.html. - trust: true -}; - -var cells = {}; - -function append_contents(key, contents) { - if (key in cells) { - var cur_cells = cells[key]; - } else { - var cell = document.createElement("div"); - cell.className = "cell"; - cells[key] = [cell]; - var cur_cells = [cell]; - } - for (var i = 0; i < contents.length; i++) { - for (var j = 0; j < cur_cells.length; j++) { - var node = lookup_address(cur_cells[j], contents[i][0]) - node.innerHTML += contents[i][1]; - } - } -} - -function lookup_address(cell, address) { - var node = cell - for (i = 0; i < address.length; i++) { - node = node.children[address[i]] - } - return node -} - -var source = new EventSource("/getnext"); -source.onmessage = function(event) { - var body = document.getElementById("main-output"); - var msg = JSON.parse(event.data); - if (msg == "start") { - body.innerHTML = ""; - cells = {} - return - } - var order = msg[0]; - var contents = msg[1]; - for (var i = 0; i < contents.length; i++) { - append_contents(contents[i][0], contents[i][1]); - } - if (order != null) { - var new_cells = {}; - body.innerHTML = ""; - for (var i = 0; i < order.val.length; i++) { - var key = order.val[i] - var cur_cells = cells[key] - if (cur_cells.length == 0) { - var cur_cell = new_cells[key][0].cloneNode(true) - } else { - var cur_cell = cur_cells.pop() - if (key in new_cells) { - new_cells[key].push(cur_cell); - } else { - new_cells[key] = [cur_cell]; - } - } - body.appendChild(cur_cell); - } - Object.assign(cells, new_cells); - } - // Render LaTeX equations in prose blocks via KaTeX. - var proseBlocks = document.querySelectorAll(".prose-block"); - Array.from(proseBlocks).map((proseBlock) => - renderMathInElement(proseBlock, katexOptions) - ); -}; diff --git a/static/index.js b/static/index.js new file mode 100644 index 00000000..fc592931 --- /dev/null +++ b/static/index.js @@ -0,0 +1,113 @@ +// Copyright 2019 Google LLC +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +var katexOptions = { + delimiters: [ + {left: "$$", right: "$$", display: true}, + {left: "\\[", right: "\\]", display: true}, + {left: "$", right: "$", display: false}, + {left: "\\(", right: "\\)", display: false} + ], + // Enable commands that load resources or change HTML attributes + // (e.g. hyperlinks): https://katex.org/docs/security.html. + trust: true +}; + +var cells = {}; + +function append_contents(key, contents) { + if (key in cells) { + var cur_cells = cells[key]; + } else { + var cell = document.createElement("div"); + cell.className = "cell"; + cells[key] = [cell]; + var cur_cells = [cell]; + } + for (var i = 0; i < contents.length; i++) { + for (var j = 0; j < cur_cells.length; j++) { + var node = lookup_address(cur_cells[j], contents[i][0]) + node.innerHTML += contents[i][1]; + } + } +} + +function lookup_address(cell, address) { + var node = cell + for (i = 0; i < address.length; i++) { + node = node.children[address[i]] + } + return node +} + +function renderLaTeX() { + // Render LaTeX equations in prose blocks via KaTeX. + var proseBlocks = document.querySelectorAll(".prose-block"); + Array.from(proseBlocks).map((proseBlock) => + renderMathInElement(proseBlock, katexOptions) + ); +} + +/** + * HTML rendering mode. + * Static rendering is used for static HTML pages. + * Dynamic rendering is used for dynamic HTML pages via `dex web`. + * + * @enum {string} + */ +var RENDER_MODE = Object.freeze({ + STATIC: "static", + DYNAMIC: "dynamic", +}) + +/** + * Renders the webpage. + * @param {RENDER_MODE} renderMode The render mode, either static or dynamic. + */ +function render(renderMode) { + if (renderMode == RENDER_MODE.STATIC) { + // For static pages, simply call rendering functions once. + renderLaTeX(); + } else { + // For dynamic pages (via `dex web`), listen to update events. + var source = new EventSource("/getnext"); + source.onmessage = function(event) { + var body = document.getElementById("main-output"); + var msg = JSON.parse(event.data); + if (msg == "start") { + body.innerHTML = ""; + cells = {} + return + } + var order = msg[0]; + var contents = msg[1]; + for (var i = 0; i < contents.length; i++) { + append_contents(contents[i][0], contents[i][1]); + } + if (order != null) { + var new_cells = {}; + body.innerHTML = ""; + for (var i = 0; i < order.val.length; i++) { + var key = order.val[i] + var cur_cells = cells[key] + if (cur_cells.length == 0) { + var cur_cell = new_cells[key][0].cloneNode(true) + } else { + var cur_cell = cur_cells.pop() + if (key in new_cells) { + new_cells[key].push(cur_cell); + } else { + new_cells[key] = [cur_cell]; + } + } + body.appendChild(cur_cell); + } + Object.assign(cells, new_cells); + } + renderLaTeX(); + }; + } +} |