Source code for nbgrader_jupyterquiz.display.dynamic.loader

"""Load question data from a list, file, URL, or DOM element reference."""

import json
import pathlib
import sys
import urllib.request


try:
    from pyodide.http import open_url
except ImportError:
    try:
        from pyodide import open_url
    except ImportError:
        open_url = None


[docs] def load_questions_script(ref, div_id): """ Build a JavaScript prefix that loads questions into ``questions{div_id}``. Parameters ---------- ref : list or str Question list, DOM element id (starting with ``#``), HTTP URL, or local file path. div_id : str Unique identifier for the quiz container div. Returns ------- script : str JavaScript code that defines the ``questions{div_id}`` variable. static : bool ``True`` when questions are embedded; ``False`` for async URL loading. url : str The source URL when ``static`` is ``False``, otherwise empty string. """ script = "" static = True url = "" if isinstance(ref, list): script = f"var questions{div_id}=" + json.dumps(ref) elif isinstance(ref, str): if ref.startswith("#"): element_id = ref[1:] script = ( f'var element = document.getElementById("{element_id}");\n' f'if (element == null) {{ console.log("ID failed, trying class"); ' f'var elems = document.getElementsByClassName("{element_id}"); ' f"element = elems[0]; }}\n" f'if (element == null) {{ throw new Error("Cannot find element {element_id}"); }}\n' f"var questions{div_id};\n" f"try {{ questions{div_id} = JSON.parse(window.atob(element.innerHTML)); }} " f'catch(err) {{ console.log("Parsing error, using raw innerHTML"); ' f"questions{div_id} = JSON.parse(element.innerHTML); }}\n" f"console.log(questions{div_id});" ) elif ref.lower().startswith("http"): script = f"var questions{div_id}=" url = ref if sys.platform == "emscripten" and open_url: text = open_url(url).read() script += text else: with urllib.request.urlopen(url) as response: for line in response: script += line.decode("utf-8") static = False else: script = f"var questions{div_id}=" with pathlib.Path(ref).open() as f: for line in f: script += line static = True else: raise TypeError("ref must be a list, URL string, or file path string") script += ";\n\nif (typeof Question === 'undefined') {\n" return script, static, url