public void decorate()

in src/prettify/parser/Prettify.java [506:593]


    public void decorate(Job job) {
      String sourceCode = job.getSourceCode();
      int basePos = job.getBasePos();
      /** Even entries are positions in source in ascending order.  Odd enties
       * are style markers (e.g., PR_COMMENT) that run from that position until
       * the end.
       * @type {Array.<number|string>}
       */
      List<Object> decorations = new ArrayList<Object>(Arrays.asList(new Object[]{basePos, PR_PLAIN}));
      int pos = 0;  // index into sourceCode
      String[] tokens = Util.match(tokenizer, sourceCode, true);
      Map<String, String> styleCache = new HashMap<String, String>();

      for (int ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
        String token = tokens[ti];
        String style = styleCache.get(token);
        String[] match = null;

        boolean isEmbedded;
        if (style != null) {
          isEmbedded = false;
        } else {
          List<Object> patternParts = shortcuts.get(token.charAt(0));
          if (patternParts != null) {
            match = Util.match((Pattern) patternParts.get(1), token, false);
            style = (String) patternParts.get(0);
          } else {
            for (int i = 0; i < nPatterns; ++i) {
              patternParts = fallthroughStylePatterns.get(i);
              match = Util.match((Pattern) patternParts.get(1), token, false);
              if (match.length != 0) {
                style = (String) patternParts.get(0);
                break;
              }
            }

            if (match.length == 0) {  // make sure that we make progress
              style = PR_PLAIN;
            }
          }

          isEmbedded = style != null && style.length() >= 5 && style.startsWith("lang-");
          if (isEmbedded && !(match.length > 1 && match[1] != null)) {
            isEmbedded = false;
            style = PR_SOURCE;
          }

          if (!isEmbedded) {
            styleCache.put(token, style);
          }
        }

        int tokenStart = pos;
        pos += token.length();

        if (!isEmbedded) {
          decorations.add(basePos + tokenStart);
          decorations.add(style);
        } else {  // Treat group 1 as an embedded block of source code.
          String embeddedSource = match[1];
          int embeddedSourceStart = token.indexOf(embeddedSource);
          int embeddedSourceEnd = embeddedSourceStart + embeddedSource.length();
          if (match.length > 2 && match[2] != null) {
            // If embeddedSource can be blank, then it would match at the
            // beginning which would cause us to infinitely recurse on the
            // entire token, so we catch the right context in match[2].
            embeddedSourceEnd = token.length() - match[2].length();
            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length();
          }
          String lang = style.substring(5);
          // Decorate the left of the embedded source
          appendDecorations(basePos + tokenStart,
                  token.substring(0, embeddedSourceStart),
                  this, decorations);
          // Decorate the embedded source
          appendDecorations(basePos + tokenStart + embeddedSourceStart,
                  embeddedSource,
                  langHandlerForExtension(lang, embeddedSource),
                  decorations);
          // Decorate the right of the embedded section
          appendDecorations(basePos + tokenStart + embeddedSourceEnd,
                  token.substring(embeddedSourceEnd),
                  this, decorations);
        }
      }

      job.setDecorations(Util.removeDuplicates(decorations, job.getSourceCode()));
    }