Skip to content

Commit b9b2548

Browse files
committed
feat: wire new lexer to pdf and epub
1 parent f7de192 commit b9b2548

6 files changed

Lines changed: 60 additions & 12 deletions

File tree

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ swift_book_epub = "swift_book_pdf.epub.cli.command:epub"
3535
swift_book_style = "swift_book_pdf.pdf.latex.preamble.styles:CustomSwiftBookStyle"
3636
swift_book_dark_style = "swift_book_pdf.pdf.latex.preamble.styles:CustomSwiftBookDarkStyle"
3737

38+
[project.entry-points."pygments.lexers"]
39+
swift_book_swift = "swift_book_pdf.lexer.swift:SwiftLexer"
40+
3841
[dependency-groups]
3942
dev = [
4043
"filelock>=3.25.2,<4.0.0",

src/swift_book_pdf/epub/render/code_blocks.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
from pygments import highlight
2323
from pygments.formatters import HtmlFormatter
24-
from pygments.lexers import SwiftLexer
24+
from pygments.lexers import get_lexer_by_name
2525

2626
WRAPPING_PLACEHOLDER_MIN_LENGTH = 28
2727
CODE_PLACEHOLDER_PATTERN = re.compile(r"<#(.*?)#>")
@@ -47,7 +47,7 @@ def render_code_block(code_lines: list[str]) -> str:
4747
else:
4848
highlighted_lines = highlight(
4949
"\n".join(code_lines),
50-
SwiftLexer(),
50+
get_lexer_by_name("swift-book-swift"),
5151
HtmlFormatter(nowrap=True),
5252
).splitlines()
5353
if not highlighted_lines:
@@ -132,5 +132,7 @@ def _highlight_swift_fragment(fragment: str) -> str:
132132
Pygments-generated inline XHTML with trailing newlines removed.
133133
"""
134134
return highlight(
135-
fragment, SwiftLexer(), HtmlFormatter(nowrap=True)
135+
fragment,
136+
get_lexer_by_name("swift-book-swift"),
137+
HtmlFormatter(nowrap=True),
136138
).rstrip("\n")

src/swift_book_pdf/lexer/swift.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ class SwiftLexer(Lexer):
709709
"""
710710

711711
name = "Swift"
712-
aliases: ClassVar[list[str]] = ["swift"]
712+
aliases: ClassVar[list[str]] = ["swift-book-swift"]
713713
filenames: ClassVar[list[str]] = ["*.swift"]
714714
mimetypes: ClassVar[list[str]] = ["text/x-swift"]
715715

src/swift_book_pdf/pdf/latex/templates/preamble.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@
360360
listing only,
361361
breakable,
362362
whole on next page if possible,
363-
minted language=swift,
363+
minted language=swift-book-swift,
364364
minted options={
365365
fontsize=\customsmall,
366366
style=$code_style,

tests/cli/test_cli.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,7 @@ def test_command_help_exposes_only_relevant_options(
160160

161161

162162
def test_pygments_style_entry_points_load() -> None:
163-
if sys.version_info >= (3, 11):
164-
import tomllib
165-
else:
166-
tomllib = pytest.importorskip("tomli")
167-
168-
pyproject = Path(__file__).parents[2] / "pyproject.toml"
169-
project_config = tomllib.loads(pyproject.read_text(encoding="utf-8"))
163+
project_config = _load_pyproject_config()
170164
entry_points = project_config["project"]["entry-points"]["pygments.styles"]
171165

172166
for entry_point in entry_points.values():
@@ -176,6 +170,28 @@ def test_pygments_style_entry_points_load() -> None:
176170
assert getattr(module, attribute_name) is not None
177171

178172

173+
def test_pygments_lexer_entry_points_load() -> None:
174+
project_config = _load_pyproject_config()
175+
entry_points = project_config["project"]["entry-points"]["pygments.lexers"]
176+
177+
for entry_point in entry_points.values():
178+
module_name, attribute_name = entry_point.split(":", maxsplit=1)
179+
module = import_module(module_name)
180+
181+
assert getattr(module, attribute_name) is not None
182+
183+
184+
def _load_pyproject_config() -> dict[str, object]:
185+
toml = (
186+
import_module("tomllib")
187+
if sys.version_info >= (3, 11)
188+
else pytest.importorskip("tomli")
189+
)
190+
191+
pyproject = Path(__file__).parents[2] / "pyproject.toml"
192+
return toml.loads(pyproject.read_text(encoding="utf-8"))
193+
194+
179195
def test_pdf_command_builds_pdf_config_and_calls_pdf_builder(
180196
runner: CliRunner,
181197
monkeypatch: pytest.MonkeyPatch,

tests/epub/test_render.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
from pathlib import Path
1616

17+
import pytest
18+
from pygments.lexer import Lexer
19+
from pygments.token import Text
20+
1721
from swift_book_pdf.core.document import DocumentEntry
1822
from swift_book_pdf.epub.cover.svg import (
1923
CoverPageOptions,
@@ -24,6 +28,7 @@
2428
)
2529
from swift_book_pdf.epub.render import (
2630
LinkResolver,
31+
code_blocks,
2732
normalize_prose_punctuation,
2833
render_inline,
2934
)
@@ -81,6 +86,28 @@ def test_render_inline_supports_code_inside_markdown_link_labels() -> None:
8186
)
8287

8388

89+
def test_render_code_block_uses_project_swift_lexer(
90+
monkeypatch: pytest.MonkeyPatch,
91+
) -> None:
92+
requested_lexers = []
93+
94+
class StubLexer(Lexer):
95+
def get_tokens_unprocessed(
96+
self, text: str
97+
) -> list[tuple[int, Text, str]]:
98+
return [(0, Text, text)]
99+
100+
def get_stub_lexer(alias: str) -> StubLexer:
101+
requested_lexers.append(alias)
102+
return StubLexer()
103+
104+
monkeypatch.setattr(code_blocks, "get_lexer_by_name", get_stub_lexer)
105+
106+
code_blocks.render_code_block(["let x = 1"])
107+
108+
assert requested_lexers == ["swift-book-swift"]
109+
110+
84111
def test_render_cover_text_emits_configured_letter_spacing() -> None:
85112
rendered = render_cover_text(
86113
"Swift",

0 commit comments

Comments
 (0)