diff --git a/docs/cli.rst b/docs/cli.rst index bf32dd2..a61d5bf 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -74,6 +74,15 @@ Options These are same from options for :ref:`cli-rst2typst` command. +--font-paths + List of directories where custom fonts are stored. + + :Type: List of string + :Default: Empty list ( ``[]`` ) + + This option specifies folders that contain custom font files in addition to the system font folders. + You should pass a folder path if you want to use extra fonts when generating a PDF. + Examples ======== diff --git a/src/rst2typst/pdf.py b/src/rst2typst/pdf.py index 269e526..d56dea3 100644 --- a/src/rst2typst/pdf.py +++ b/src/rst2typst/pdf.py @@ -1,8 +1,9 @@ """PDF handler.""" +import os import typst -from docutils.frontend import validate_boolean +from docutils.frontend import validate_boolean, validate_comma_separated_list from .package import install_package, package_dir from .writer import Writer as BaseWriter @@ -25,6 +26,17 @@ class Writer(BaseWriter): "validator": validate_boolean, }, ), + ( + "List of directories where custom fonts are stored.", + ["--font-paths"], + { + "action": "append", + "dest": "font_paths", + "metavar": "", + "default": [], + "validator": validate_comma_separated_list, + }, + ), ), ) @@ -36,7 +48,15 @@ def translate(self): "rst2typst", force=self.document.settings.force_install_package, ) - self.output = typst.compile(self.output.encode()) + font_paths = self.document.settings.font_paths + if isinstance(font_paths, str): + font_paths = [font_paths] + else: + font_paths = list(font_paths) + env_font_paths = os.environ.get("TYPST_FONT_PATHS") + if env_font_paths: + font_paths += env_font_paths.split(os.pathsep) + self.output = typst.compile(self.output.encode(), font_paths=font_paths) def display_warnings(self): pass diff --git a/tests/test_pdf.py b/tests/test_pdf.py new file mode 100644 index 0000000..99952e7 --- /dev/null +++ b/tests/test_pdf.py @@ -0,0 +1,57 @@ +import os +from unittest.mock import patch, MagicMock + +import pytest +from docutils.core import publish_string + +from rst2typst import pdf + + +@pytest.fixture(autouse=True) +def _clear_font_paths_env(monkeypatch: pytest.MonkeyPatch): + monkeypatch.delenv("TYPST_FONT_PATHS", raising=False) + + +def _publish(**settings_overrides) -> MagicMock: + with patch.object(pdf.typst, "compile") as mock: + publish_string( + "", + writer=pdf.Writer(), + settings_overrides=settings_overrides, + ) + return mock + + +def test_font_paths_is_not_set(): + mock = _publish() + assert mock.call_args.kwargs["font_paths"] == [] + + +def test_font_paths_from_args(): + mock = _publish(font_paths=["/tmp/fonts"]) + assert mock.call_args.kwargs["font_paths"] == ["/tmp/fonts"] + + +def test_font_paths_from_args_str(): + mock = _publish(font_paths="/tmp/fonts") + assert mock.call_args.kwargs["font_paths"] == ["/tmp/fonts"] + + +def test_font_paths_from_env(monkeypatch: pytest.MonkeyPatch): + monkeypatch.setenv( + "TYPST_FONT_PATHS", os.pathsep.join(["/opt/fonts", "/tmp/fonts"]) + ) + mock = _publish() + assert mock.call_args.kwargs["font_paths"] == [ + "/opt/fonts", + "/tmp/fonts", + ] + + +def test_font_paths_from_args_and_env(monkeypatch: pytest.MonkeyPatch): + monkeypatch.setenv("TYPST_FONT_PATHS", "/opt/fonts") + mock = _publish(font_paths=["/tmp/fonts"]) + assert mock.call_args.kwargs["font_paths"] == [ + "/tmp/fonts", + "/opt/fonts", + ]