docs: protected void processLink(Tag tag, String attr, CmsRelationType type) {
  
          if (tag.getAttribute(attr) == null) {
              return;
          }
          CmsLink link = null;
          switch (m_mode) {
              case PROCESS_LINKS:
                  // macros are replaced with links
                  link = m_linkTable.getLink(CmsMacroResolver.stripMacro(tag.getAttribute(attr)));
                  if (link != null) {
                      // link management check
                      String l = link.getLink(m_cms);
                      if (TAG_PARAM.equals(tag.getTagName())) {
                          // HACK: to distinguish link parameters the link itself has to end with '&' or '?'
                          // another solution should be a kind of macro...
                          if (!l.endsWith(CmsRequestUtil.URL_DELIMITER)
                              && !l.endsWith(CmsRequestUtil.PARAMETER_DELIMITER)) {
                              if (l.indexOf(CmsRequestUtil.URL_DELIMITER) > 0) {
                                  l += CmsRequestUtil.PARAMETER_DELIMITER;
                              } else {
                                  l += CmsRequestUtil.URL_DELIMITER;
                              }
                          }
                      }
                      // set the real target
                      tag.setAttribute(attr, CmsEncoder.escapeXml(l));
                  }
                  break;
              case REPLACE_LINKS:
                  // links are replaced with macros
                  String targetUri = tag.getAttribute(attr);
                  if (CmsStringUtil.isNotEmpty(targetUri)) {
                      String internalUri = null;
                      if (!CmsMacroResolver.isMacro(targetUri)) {
                          m_cms.getRequestContext().setAttribute(
                              CmsDefaultLinkSubstitutionHandler.DONT_USE_CURRENT_SITE_FOR_WORKPLACE_REQUESTS,
                              "true");
                          internalUri = OpenCms.getLinkManager().getRootPath(m_cms, targetUri, m_relativePath);
                      }
                      // HACK: to distinguish link parameters the link itself has to end with '&' or '?'
                      // another solution should be a kind of macro...
                      if (!TAG_PARAM.equals(tag.getTagName())
                          || targetUri.endsWith(CmsRequestUtil.URL_DELIMITER)
                          || targetUri.endsWith(CmsRequestUtil.PARAMETER_DELIMITER)) {
                          if (internalUri != null) {
                              internalUri = rewriteUri(internalUri);
                              // this is an internal link
                              link = m_linkTable.addLink(type, internalUri, true);
                              // link management check
                              link.checkConsistency(m_cms);
  
                              if ("IMG".equals(tag.getTagName()) || TAG_AREA.equals(tag.getTagName())) {
                                  // now ensure the image has the "alt" attribute set
                                  setAltAttributeFromTitle(tag, internalUri);
                              }
                          } else {
                              // this is an external link
                              link = m_linkTable.addLink(type, targetUri, false);
                          }
                      }
                      if (link != null) {
                          tag.setAttribute(attr, CmsMacroResolver.formatMacro(link.getName()));
                      }
                  }
                  break;
              default: // empty
          }
      }