custom_directives.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # Originally from:
  2. # github.com/pytorch/tutorials/blob/60d6ef365e36f3ba82c2b61bf32cc40ac4e86c7b/custom_directives.py # noqa
  3. from docutils.parsers.rst import Directive, directives
  4. from docutils.statemachine import StringList
  5. from docutils import nodes
  6. import os
  7. import sphinx_gallery
  8. try:
  9. FileNotFoundError
  10. except NameError:
  11. FileNotFoundError = IOError
  12. GALLERY_TEMPLATE = """
  13. .. raw:: html
  14. <div class="sphx-glr-thumbcontainer" tooltip="{tooltip}">
  15. .. only:: html
  16. .. figure:: {thumbnail}
  17. {description}
  18. .. raw:: html
  19. </div>
  20. """
  21. class CustomGalleryItemDirective(Directive):
  22. """Create a sphinx gallery style thumbnail.
  23. tooltip and figure are self explanatory. Description could be a link to
  24. a document like in below example.
  25. Example usage:
  26. .. customgalleryitem::
  27. :tooltip: I am writing this tutorial to focus specifically on NLP.
  28. :figure: /_static/img/thumbnails/babel.jpg
  29. :description: :doc:`/beginner/deep_learning_nlp_tutorial`
  30. If figure is specified, a thumbnail will be made out of it and stored in
  31. _static/thumbs. Therefore, consider _static/thumbs as a "built" directory.
  32. """
  33. required_arguments = 0
  34. optional_arguments = 0
  35. final_argument_whitespace = True
  36. option_spec = {
  37. "tooltip": directives.unchanged,
  38. "figure": directives.unchanged,
  39. "description": directives.unchanged
  40. }
  41. has_content = False
  42. add_index = False
  43. def run(self):
  44. # Cutoff the `tooltip` after 195 chars.
  45. if "tooltip" in self.options:
  46. tooltip = self.options["tooltip"]
  47. if len(self.options["tooltip"]) > 195:
  48. tooltip = tooltip[:195] + "..."
  49. else:
  50. raise ValueError("Need to provide :tooltip: under "
  51. "`.. customgalleryitem::`.")
  52. # Generate `thumbnail` used in the gallery.
  53. if "figure" in self.options:
  54. env = self.state.document.settings.env
  55. rel_figname, figname = env.relfn2path(self.options["figure"])
  56. thumb_dir = os.path.join(env.srcdir, "_static/thumbs/")
  57. os.makedirs(thumb_dir, exist_ok=True)
  58. image_path = os.path.join(thumb_dir, os.path.basename(figname))
  59. sphinx_gallery.gen_rst.scale_image(figname, image_path, 400, 280)
  60. thumbnail = os.path.relpath(image_path, env.srcdir)
  61. # https://stackoverflow.com/questions/52138336/sphinx-reference-to-an-image-from-different-locations
  62. thumbnail = "/" + thumbnail
  63. else:
  64. # "/" is the top level srcdir
  65. thumbnail = "/_static/img/thumbnails/default.png"
  66. if "description" in self.options:
  67. description = self.options["description"]
  68. else:
  69. raise ValueError("Need to provide :description: under "
  70. "`customgalleryitem::`.")
  71. thumbnail_rst = GALLERY_TEMPLATE.format(
  72. tooltip=tooltip, thumbnail=thumbnail, description=description)
  73. thumbnail = StringList(thumbnail_rst.split("\n"))
  74. thumb = nodes.paragraph()
  75. self.state.nested_parse(thumbnail, self.content_offset, thumb)
  76. return [thumb]