latex.py 3.8 KB

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