class_docstr: Transform :kbd: role to more detailed form.
  
  Before::
  
      <literal class="kbd">
          Control-x
  
  After::
  
      <literal class="kbd compound">
          <literal class="kbd">
              Control
          -
          <literal class="kbd">
              x
class_docstr_tok: ["Transform",":","kbd",":","role","to","more","detailed","form",".","Before",":",":","<","literal","class=","''","kbd","''",">","Control-x","After",":",":","<","literal","class=","''","kbd","compound","''",">","<","literal","class=","''","kbd","''",">","Control","-","<","literal","class=","''","kbd","''",">","x"]
code: def run(self, **kwargs: Any) -> None:
      matcher = NodeMatcher(nodes.literal, classes=["kbd"])
      # this list must be pre-created as during iteration new nodes
      # are added which match the condition in the NodeMatcher.
      for node in list(
          self.document.findall(matcher)
      ):  # type: nodes.literal
          parts = self.pattern.split(node[-1].astext())
          if len(parts) == 1 or self.is_multiwords_key(parts):
              continue
  
          node["classes"].append("compound")
          node.pop()
          while parts:
              if self.is_multiwords_key(parts):
                  key = "".join(parts[:3])
                  parts[:3] = []
              else:
                  key = parts.pop(0)
              node += nodes.literal("", key, classes=["kbd"])
  
              try:
                  # key separator (ex. -, +, ^)
                  sep = parts.pop(0)
                  node += nodes.Text(sep)
              except IndexError:
                  pass
  
file_path: sphinx/sphinx/builders/html/transforms.py
imports: from __future__ import annotations
  import re
  from typing import TYPE_CHECKING, Any
  from docutils import nodes
  from sphinx.transforms.post_transforms import SphinxPostTransform
  from sphinx.util.nodes import NodeMatcher
label_desc: Use image node_id 1 for calling the KeyboardTransform obj's underlying member method code with example usage: obj.run() without return types