code: def apply(self):
          
          # In this phase, we look for hyperlinks (references nodes)
          # that contain substitutions (of the form "|foo|").
          # We then add actual "substitution"s nodes to those references,
          # so that they can be replaced by the substitution processor.
          subst_re = re.compile(self.subst_pattern)
  
          for link in self.document.traverse(self._maybe_hyperlink):
              if 'refuri' not in link:
                  continue
  
              # Note: "target" nodes do not have a "name" attribute.
              if '|' not in link['refuri'] and '|' not in link.get('name', ''):
                  continue
  
              # This list acts as a cache so that only one substitution node
              # is added as a child for each substitution name.
              substitutions = []
  
              matches = subst_re.findall(link['refuri']) + \
                  subst_re.findall(link.get('name', ''))
              for subref_text in matches:
                  if subref_text in substitutions:
                      continue
  
                  substitutions.append(subref_text)
                  subref_node = nodes.substitution_reference(subref_text)
                  link.append(subref_node)
                  self.document.note_substitution_ref(subref_node, subref_text)
  
              # Build a map of substitutions names to child indices
              # (minus one since the actual link label is in link[0]).
              link['varlinks'] = \
                  dict(zip(substitutions, range(len(substitutions))))
docs: Create substitution nodes for hyperlinks