text: """
  Sphinx custom directives.
  
  | Copyright 2017-2022, Voxel51, Inc.
  | `voxel51.com <https://voxel51.com/>`_
  |
  """
  from docutils.parsers.rst import Directive, directives
  from docutils.statemachine import StringList
  from docutils import nodes
  
  
  class CustomCardItemDirective(Directive):
      """A custom card item for use on pages that contain a list of links with
      short descriptions and optional images.
  
      The card item provides a heading, a description, and an optional image to
      the right. The entire card is clickable and links to the provided link.
  
      Example usage::
  
          .. customcarditem::
              :header: Custom card
              :description: This is a custom card. Click to learn more.
              :link: other/page.html
              :image: ../_static/images/custom-image.jpg
              :tags: Custom-Tag
      """
  
      option_spec = {
          "header": directives.unchanged,
          "description": directives.unchanged,
          "link": directives.unchanged,
          "image": directives.unchanged,
          "tags": directives.unchanged,
      }
  
      def run(self):
          header = self.options.get("header", "")
          description = self.options.get("description", "")
          link = self.options.get("link", "")
          image = self.options.get("image", "")
          tags = self.options.get("tags", "")
  
          if image:
              card_rst = _CUSTOM_CARD_TEMPLATE.format(
                  header=header,
                  description=description,
                  link=link,
                  image='<img src="%s">' % image,
                  tags=tags,
              )
          else:
              # No image
              template = _CUSTOM_CARD_TEMPLATE.replace(
                  '<div class="tutorials-image">{image}</div>', ""
              )
  
              card_rst = template.format(
                  header=header,
                  description=description,
                  link=link,
                  tags=tags,
              )
  
          card_list = StringList(card_rst.split("\n"))
          card = nodes.paragraph()
          self.state.nested_parse(card_list, self.content_offset, card)
          return [card]
  
  
  _CUSTOM_CARD_TEMPLATE = """
  .. raw:: html
  
      <div class="col-md-12 tutorials-card-container" data-tags={tags}>
  
      <div class="card tutorials-card" link={link}>
  
      <div class="card-body">
  
      <div class="card-title-container">
          <h4>{header}</h4>
      </div>
  
      <p class="card-summary">{description}</p>
  
      <p class="tags">{tags}</p>
  
      <div class="tutorials-image">{image}</div>
  
      </div>
  
      </div>
  
      </div>
  """
  
  
  class CustomCalloutItemDirective(Directive):
      """A custom callout for use on table of contents-style pages that link into
      other pages.
  
      The callout contains a header, a body, a clickable button that links to
      the provided link, and an optional image.
  
      Example usage::
  
          .. customcalloutitem::
              :header: Custom header
              :description: Custom body
              :button_text: Custom button
              :button_link: other/page.html
              :image: ../_static/images/custom-image.jpg
      """
  
      option_spec = {
          "header": directives.unchanged,
          "description": directives.unchanged,
          "button_text": directives.unchanged,
          "button_link": directives.unchanged,
          "image": directives.unchanged,
      }
  
      def run(self):
          header = self.options.get("header", "")
          description = self.options.get("description", "")
          button_text = self.options.get("button_text", "")
          button_link = self.options.get("button_link", "")
          image = self.options.get("image", "")
  
          classes = "with-right-arrow" if button_link else ""
          attributes = (
              ""
              if button_link
              else 'onclick="return false;" style="pointer-events:none;cursor:default;"'
          )
  
          if image:
              callout_rst = _CUSTOM_CALLOUT_TEMPLATE.format(
                  header=header,
                  description=description,
                  button_text=button_text,
                  button_link=button_link,
                  classes=classes,
                  attributes=attributes,
                  image='<img src="%s">' % image,
              )
  
          else:
              # No image
              template = _CUSTOM_CALLOUT_TEMPLATE.replace(
                  "<div>{image}</div>", ""
              )
  
              callout_rst = template.format(
                  header=header,
                  description=description,
                  button_text=button_text,
                  button_link=button_link,
                  classes=classes,
                  attributes=attributes,
              )
  
          button_list = StringList(callout_rst.split("\n"))
          button = nodes.paragraph()
          self.state.nested_parse(button_list, self.content_offset, button)
          return [button]
  
  
  _CUSTOM_CALLOUT_TEMPLATE = """
  .. raw:: html
  
      <div class="col-md-6">
          <div class="text-container">
              <h3>{header}</h3>
              <p class="body-paragraph">{description}</p>
              <p><a class="btn {classes} callout-button" href="{button_link}"{attributes}>{button_text}</a></p>
              <div>{image}</div>
          </div>
      </div>
  """
  
  
  class CustomButtonDirective(Directive):
      """A custom button for use on table of contents-style pages that link into
      other pages.
  
      The button is clickable and links to the provided link.
  
      Example usage::
          .. custombutton::
              :button_text: Custom button
              :button_link: other/page.html
      """
  
      option_spec = {
          "button_text": directives.unchanged,
          "button_link": directives.unchanged,
      }
  
      def run(self):
          button_text = self.options.get("button_text", "")
          button_link = self.options.get("button_link", "")
  
          classes = "with-right-arrow" if button_link else ""
          attributes = (
              ""
              if button_link
              else 'onclick="return false;" style="pointer-events:none;cursor:default;"'
          )
  
          callout_rst = _CUSTOM_BUTTON_TEMPLATE.format(
              button_text=button_text,
              button_link=button_link,
              classes=classes,
              attributes=attributes,
          )
  
          button_list = StringList(callout_rst.split("\n"))
          button = nodes.paragraph()
          self.state.nested_parse(button_list, self.content_offset, button)
          return [button]
  
  
  _CUSTOM_BUTTON_TEMPLATE = """
  .. raw:: html
  
      <div class="tutorials-callout-container">
          <a class="btn {classes} callout-button" href="{button_link}"{attributes}>{button_text}</a>
      </div>
  """
  
  
  class CustomImageLinkDirective(Directive):
      """A custom image within a link nested in a div. Styling can be done via
      a parent container.
  
  
      Example usage::
          .. customimagelink::
              :image_link: other/page.html
              :image_src: images/image.png
              :image_src: My image
      """
  
      option_spec = {
          "image_link": directives.unchanged,
          "image_src": directives.unchanged,
          "image_title": directives.unchanged,
      }
  
      def run(self):
          image_link = self.options.get("image_link", "")
          image_src = self.options.get("image_src", "")
          image_title = self.options.get("image_title", "")
  
          callout_rst = _CUSTOM_IMAGE_LINK_TEMPLATE.format(
              image_link=image_link,
              image_src=image_src,
              image_title=image_title,
          )
  
          image_list = StringList(callout_rst.split("\n"))
          image = nodes.paragraph()
          self.state.nested_parse(image_list, self.content_offset, image)
          return [image]
  
  
  _CUSTOM_IMAGE_LINK_TEMPLATE = """
  .. raw:: html
  
      <div>
          <a href="{image_link}" title="{image_title}">
            <img src="{image_src}" alt="{image_title}"/>
          </a>
      </div>
  """
  