docs: private int _recursiveEmitLine (final MarkdownHCStack aOut,
                                    final String sIn,
                                    final int nStart,
                                    final EMarkToken eToken)
    {
      int nPos = nStart;
      int a;
      int b;
      final MarkdownHCStack aTmp = new MarkdownHCStack ();
      final StringBuilder aTmpSB = new StringBuilder ();
      while (nPos < sIn.length ())
      {
        final EMarkToken eCurToken = _getToken (sIn, nPos);
        if (eToken != EMarkToken.NONE)
          if (eCurToken.equals (eToken) ||
              (eToken == EMarkToken.EM_STAR && eCurToken == EMarkToken.STRONG_STAR) ||
              (eToken == EMarkToken.EM_UNDERSCORE && eCurToken == EMarkToken.STRONG_UNDERSCORE))
            return nPos;
  
        switch (eCurToken)
        {
          case IMAGE:
          case LINK:
            b = _checkInlineLink (aOut, sIn, nPos, eCurToken);
            if (b > 0)
              nPos = b;
            else
              aOut.append (sIn.charAt (nPos));
            break;
          case EM_STAR:
          case EM_UNDERSCORE:
            aTmp.reset ();
            b = _recursiveEmitLine (aTmp, sIn, nPos + 1, eCurToken);
            if (b > 0)
            {
              m_aConfig.getDecorator ().openEmphasis (aOut);
              aOut.append (aTmp.getRoot ());
              m_aConfig.getDecorator ().closeEmphasis (aOut);
              nPos = b;
            }
            else
            {
              aOut.append (sIn.charAt (nPos));
            }
            break;
          case STRONG_STAR:
          case STRONG_UNDERSCORE:
            aTmp.reset ();
            b = _recursiveEmitLine (aTmp, sIn, nPos + 2, eCurToken);
            if (b > 0)
            {
              m_aConfig.getDecorator ().openStrong (aOut);
              aOut.append (aTmp.getRoot ());
              m_aConfig.getDecorator ().closeStrong (aOut);
              nPos = b + 1;
            }
            else
            {
              aOut.append (sIn.charAt (nPos));
            }
            break;
          case STRIKE:
            aTmp.reset ();
            b = _recursiveEmitLine (aTmp, sIn, nPos + 2, eCurToken);
            if (b > 0)
            {
              m_aConfig.getDecorator ().openStrike (aOut);
              aOut.append (aTmp.getRoot ());
              m_aConfig.getDecorator ().closeStrike (aOut);
              nPos = b + 1;
            }
            else
            {
              aOut.append (sIn.charAt (nPos));
            }
            break;
          case SUPER:
            aTmp.reset ();
            b = _recursiveEmitLine (aTmp, sIn, nPos + 1, eCurToken);
            if (b > 0)
            {
              m_aConfig.getDecorator ().openSuper (aOut);
              aOut.append (aTmp.getRoot ());
              m_aConfig.getDecorator ().closeSuper (aOut);
              nPos = b;
            }
            else
            {
              aOut.append (sIn.charAt (nPos));
            }
            break;
          case CODE_SINGLE:
          case CODE_DOUBLE:
            a = nPos + (eCurToken == EMarkToken.CODE_DOUBLE ? 2 : 1);
            b = _findInlineToken (sIn, a, eCurToken);
            if (b > 0)
            {
              nPos = b + (eCurToken == EMarkToken.CODE_DOUBLE ? 1 : 0);
              while (a < b && sIn.charAt (a) == ' ')
                a++;
              if (a < b)
              {
                while (sIn.charAt (b - 1) == ' ')
                  b--;
                final HCCode aCode = m_aConfig.getDecorator ().openCodeSpan (aOut);
                aCode.addChild (sIn.substring (a, b));
                m_aConfig.getDecorator ().closeCodeSpan (aOut);
              }
            }
            else
            {
              aOut.append (sIn.charAt (nPos));
            }
            break;
          case HTML:
            b = _checkInlineHtml (aOut, sIn, nPos);
            if (b > 0)
            {
              nPos = b;
            }
            else
            {
              aOut.append ('<');
            }
            break;
          case ENTITY:
            aTmpSB.setLength (0);
            b = _checkInlineEntity (aTmpSB, sIn, nPos);
            if (b > 0)
            {
              // Remove leading '&' and trailing ';'
              aOut.append (new HCEntityNode (new HTMLEntity (aTmpSB.substring (1, aTmpSB.length () - 1)), " "));
              nPos = b;
            }
            else
            {
              aOut.append ('&');
            }
            break;
          case X_LINK_OPEN:
            aTmp.reset ();
            b = _recursiveEmitLine (aTmp, sIn, nPos + 2, EMarkToken.X_LINK_CLOSE);
            if (b > 0 && m_aConfig.getSpecialLinkEmitter () != null)
            {
              m_aConfig.getSpecialLinkEmitter ().emitSpan (aOut, aTmp);
              nPos = b + 1;
            }
            else
            {
              aOut.append (sIn.charAt (nPos));
            }
            break;
          case X_COPY:
            aOut.append (HCEntityNode.newCopy ());
            nPos += 2;
            break;
          case X_REG:
            aOut.append (new HCEntityNode (EHTMLEntity.copy, "(r)"));
            nPos += 2;
            break;
          case X_TRADE:
            aOut.append (new HCEntityNode (EHTMLEntity.trade, "TM"));
            nPos += 3;
            break;
          case X_NDASH:
            aOut.append (new HCEntityNode (EHTMLEntity.ndash, "--"));
            nPos++;
            break;
          case X_MDASH:
            aOut.append (new HCEntityNode (EHTMLEntity.mdash, "---"));
            nPos += 2;
            break;
          case X_HELLIP:
            aOut.append (new HCEntityNode (EHTMLEntity.hellip, "..."));
            nPos += 2;
            break;
          case X_LAQUO:
            aOut.append (new HCEntityNode (EHTMLEntity.laquo, "<<"));
            nPos++;
            break;
          case X_RAQUO:
            aOut.append (new HCEntityNode (EHTMLEntity.raquo, ">>"));
            nPos++;
            break;
          case X_RDQUO:
            aOut.append (new HCEntityNode (EHTMLEntity.rdquo, "\""));
            break;
          case X_LDQUO:
            aOut.append (new HCEntityNode (EHTMLEntity.ldquo, "\""));
            break;
          case ESCAPE:
            nPos++;
            aOut.append (sIn.charAt (nPos));
            break;
          default:
            aOut.append (sIn.charAt (nPos));
            break;
        }
        nPos++;
      }
      return -1;
    }