quizcomp.external.katex

 1import argparse
 2import logging
 3import os
 4import shutil
 5import subprocess
 6import typing
 7
 8_logger = logging.getLogger(__name__)
 9
10_nodejs_bin_dir: typing.Union[str, None] = None  # pylint: disable=invalid-name
11
12def set_nodejs_bin_dir(path: str) -> None:
13    """ Set the binary path to use for NodeJS (node). """
14
15    global _nodejs_bin_dir  # pylint: disable=global-statement
16    _nodejs_bin_dir = path
17
18def _has_command(command: str, cwd: str = '.') -> bool:
19    """ Check if the given command is found on the current shell. """
20
21    result = subprocess.run(["which", command], cwd = cwd, capture_output = True, check = False)
22    return (result.returncode == 0)
23
24def _has_package(package: str, cwd: str = '.') -> bool:
25    """ Check if the given NodeJS package exists. """
26
27    bin_path = 'npm'
28    if (_nodejs_bin_dir is not None):
29        bin_path = os.path.join(_nodejs_bin_dir, bin_path)
30
31    result = subprocess.run([bin_path, "list", package], cwd = cwd, capture_output = True, check = False)
32    return (result.returncode == 0)
33
34def is_available(cwd: str = '.') -> bool:
35    """ Check if KaTeX is available on this system. """
36
37    if ((_nodejs_bin_dir is None) and (shutil.which('npx') is None)):
38        _logger.warning("Could not find `npx` (usually installed with `npm`), cannot use katex equations.")
39        return False
40
41    if (not _has_package('katex', cwd = cwd)):
42        _logger.warning("Could not find the `katex` NodeJS package, cannot use katex equations.")
43        return False
44
45    return True
46
47def to_html(text: str, cwd: str = '.') -> str:
48    """ Convert the given text (math/equation) to HTML using KaTeX. """
49
50    bin_path = 'npx'
51    if (_nodejs_bin_dir is not None):
52        bin_path = os.path.join(_nodejs_bin_dir, bin_path)
53
54    result = subprocess.run([bin_path, "katex", "--format", "mathml"], cwd = cwd,
55        input = text, text = True, capture_output = True,
56        check = False)
57
58    if (result.returncode != 0):
59        raise ValueError(f"KaTeX did not exit cleanly. Stdout: '{result.stdout}', Stderr: '{result.stderr}'")
60
61    return result.stdout
62
63def set_cli_args(parser: argparse.ArgumentParser, extra_state: typing.Dict[str, typing.Any]) -> None:
64    """ Set KaTeX-related CLI options. """
65
66    parser.add_argument('--nodejs-bin-dir', dest = 'node_bin_dir',
67        action = 'store', type = str, default = None,
68        help = ('A NodeJS binary directory that includes `npm` and `npx`.'
69                + ' If not specified, $PATH will be searched.'
70                + ' Used for HTML equations.'))
71
72def init_from_args(parser: argparse.ArgumentParser, args: argparse.Namespace, extra_state: typing.Dict[str, typing.Any]) -> None:
73    """ Initialize this module from the CLI options set in set_cli_args(). """
74
75    if (args.node_bin_dir is not None):
76        set_nodejs_bin_dir(args.node_bin_dir)
def set_nodejs_bin_dir(path: str) -> None:
13def set_nodejs_bin_dir(path: str) -> None:
14    """ Set the binary path to use for NodeJS (node). """
15
16    global _nodejs_bin_dir  # pylint: disable=global-statement
17    _nodejs_bin_dir = path

Set the binary path to use for NodeJS (node).

def is_available(cwd: str = '.') -> bool:
35def is_available(cwd: str = '.') -> bool:
36    """ Check if KaTeX is available on this system. """
37
38    if ((_nodejs_bin_dir is None) and (shutil.which('npx') is None)):
39        _logger.warning("Could not find `npx` (usually installed with `npm`), cannot use katex equations.")
40        return False
41
42    if (not _has_package('katex', cwd = cwd)):
43        _logger.warning("Could not find the `katex` NodeJS package, cannot use katex equations.")
44        return False
45
46    return True

Check if KaTeX is available on this system.

def to_html(text: str, cwd: str = '.') -> str:
48def to_html(text: str, cwd: str = '.') -> str:
49    """ Convert the given text (math/equation) to HTML using KaTeX. """
50
51    bin_path = 'npx'
52    if (_nodejs_bin_dir is not None):
53        bin_path = os.path.join(_nodejs_bin_dir, bin_path)
54
55    result = subprocess.run([bin_path, "katex", "--format", "mathml"], cwd = cwd,
56        input = text, text = True, capture_output = True,
57        check = False)
58
59    if (result.returncode != 0):
60        raise ValueError(f"KaTeX did not exit cleanly. Stdout: '{result.stdout}', Stderr: '{result.stderr}'")
61
62    return result.stdout

Convert the given text (math/equation) to HTML using KaTeX.

def set_cli_args(parser: argparse.ArgumentParser, extra_state: Dict[str, Any]) -> None:
64def set_cli_args(parser: argparse.ArgumentParser, extra_state: typing.Dict[str, typing.Any]) -> None:
65    """ Set KaTeX-related CLI options. """
66
67    parser.add_argument('--nodejs-bin-dir', dest = 'node_bin_dir',
68        action = 'store', type = str, default = None,
69        help = ('A NodeJS binary directory that includes `npm` and `npx`.'
70                + ' If not specified, $PATH will be searched.'
71                + ' Used for HTML equations.'))

Set KaTeX-related CLI options.

def init_from_args( parser: argparse.ArgumentParser, args: argparse.Namespace, extra_state: Dict[str, Any]) -> None:
73def init_from_args(parser: argparse.ArgumentParser, args: argparse.Namespace, extra_state: typing.Dict[str, typing.Any]) -> None:
74    """ Initialize this module from the CLI options set in set_cli_args(). """
75
76    if (args.node_bin_dir is not None):
77        set_nodejs_bin_dir(args.node_bin_dir)

Initialize this module from the CLI options set in set_cli_args().