1"""LaTeX Exporter class"""
2
3# Copyright (c) Jupyter Development Team.
4# Distributed under the terms of the Modified BSD License.
5
6import os
7
8from traitlets import default
9from traitlets.config import Config
10
11from nbconvert.filters.filter_links import resolve_references
12from nbconvert.filters.highlight import Highlight2Latex
13from nbconvert.filters.pandoc import ConvertExplicitlyRelativePaths
14
15from .templateexporter import TemplateExporter
16
17
18class LatexExporter(TemplateExporter):
19 """
20 Exports to a Latex template. Inherit from this class if your template is
21 LaTeX based and you need custom transformers/filters.
22 If you don't need custom transformers/filters, just change the
23 'template_file' config option. Place your template in the special "/latex"
24 subfolder of the "../templates" folder.
25 """
26
27 export_from_notebook = "LaTeX"
28
29 @default("file_extension")
30 def _file_extension_default(self):
31 return ".tex"
32
33 @default("template_name")
34 def _template_name_default(self):
35 return "latex"
36
37 output_mimetype = "text/latex"
38
39 def default_filters(self):
40 """Get the default filters."""
41 yield from super().default_filters()
42 yield ("resolve_references", resolve_references)
43
44 @property
45 def default_config(self):
46 c = Config(
47 {
48 "NbConvertBase": {
49 "display_data_priority": [
50 "text/latex",
51 "application/pdf",
52 "image/png",
53 "image/jpeg",
54 "image/svg+xml",
55 "text/markdown",
56 "text/plain",
57 ]
58 },
59 "ExtractAttachmentsPreprocessor": {"enabled": True},
60 "ExtractOutputPreprocessor": {"enabled": True},
61 "SVG2PDFPreprocessor": {"enabled": True},
62 "LatexPreprocessor": {"enabled": True},
63 "SphinxPreprocessor": {"enabled": True},
64 "HighlightMagicsPreprocessor": {"enabled": True},
65 }
66 )
67 if super().default_config:
68 c2 = super().default_config.copy()
69 c2.merge(c)
70 c = c2
71 return c
72
73 def from_notebook_node(self, nb, resources=None, **kw):
74 """Convert from notebook node."""
75 langinfo = nb.metadata.get("language_info", {})
76 lexer = langinfo.get("pygments_lexer", langinfo.get("name", None))
77 highlight_code = self.filters.get(
78 "highlight_code", Highlight2Latex(pygments_lexer=lexer, parent=self)
79 )
80 self.register_filter("highlight_code", highlight_code)
81
82 # Need to make sure explicit relative paths are visible to latex for pdf conversion
83 # https://github.com/jupyter/nbconvert/issues/1998
84 nb_path = resources.get("metadata", {}).get("path") if resources else None
85 texinputs = os.path.abspath(nb_path) if nb_path else os.getcwd()
86 convert_explicitly_relative_paths = self.filters.get(
87 "convert_explicitly_relative_paths",
88 ConvertExplicitlyRelativePaths(texinputs=texinputs, parent=self),
89 )
90 self.register_filter("convert_explicitly_relative_paths", convert_explicitly_relative_paths)
91
92 return super().from_notebook_node(nb, resources, **kw)
93
94 def _create_environment(self):
95 environment = super()._create_environment()
96
97 # Set special Jinja2 syntax that will not conflict with latex.
98 environment.block_start_string = "((*"
99 environment.block_end_string = "*))"
100 environment.variable_start_string = "((("
101 environment.variable_end_string = ")))"
102 environment.comment_start_string = "((="
103 environment.comment_end_string = "=))"
104
105 return environment