예제 #1
0
 private BlockNode parseYield() {
   nextToken();
   BlockNode block = (BlockNode) new BlockNode();
   block.setLineNumber(lexer.getLineno());
   block.setFileName(filename);
   block.setYield(true);
   return block;
 }
예제 #2
0
 private Node blockExpansion() {
   if (peek() instanceof Colon) {
     Token token = expect(Colon.class);
     Colon colon = (Colon) token;
     BlockNode block = new BlockNode();
     block.setLineNumber(colon.getLineNumber());
     block.setFileName(filename);
     block.getNodes().add(parseExpr());
     return block;
   }
   return block();
 }
예제 #3
0
  private Node parseBlock() {
    Token token = expect(Block.class);
    Block block = (Block) token;
    String mode = block.getMode();
    String name = block.getValue().trim();

    Node blockNode;
    if (peek() instanceof Indent) {
      blockNode = block();
    } else {
      blockNode = new BlockNode();
      blockNode.setLineNumber(block.getLineNumber());
      blockNode.setFileName(filename);
    }

    ((BlockNode) blockNode).setMode(mode);

    if (blocks.containsKey(name)) {
      BlockNode prev = (BlockNode) blocks.get(name);
      if ("append".equals(prev.getMode())) {
        blockNode.getNodes().addAll(prev.getNodes());
      }
      if ("prepend".equals(prev.getMode())) {
        blockNode.getNodes().addAll(0, prev.getNodes());
      }
      if ("replace".equals(prev.getMode())) {
        blockNode = prev;
      }
    }

    blocks.put(name, blockNode);
    return blockNode;
  }
예제 #4
0
 private Node block() {
   BlockNode block = new BlockNode();
   block.setLineNumber(lexer.getLineno());
   block.setFileName(filename);
   expect(Indent.class);
   while (!(peek() instanceof Outdent) && !(peek() instanceof Eos)) {
     if (peek() instanceof Newline) {
       nextToken();
     } else {
       Node parseExpr = this.parseExpr();
       if (parseExpr != null) {
         block.push(parseExpr);
       }
     }
   }
   if (peek() instanceof Outdent) {
     expect(Outdent.class);
   }
   return block;
 }
예제 #5
0
  public Node parse() {
    BlockNode block = new BlockNode();
    block.setLineNumber(lexer.getLineno());
    block.setFileName(filename);
    while (!(peek() instanceof Eos)) {
      if (peek() instanceof Newline) {
        nextToken();
      } else {
        Node expr = parseExpr();
        if (expr != null) {
          block.push(expr);
        }
      }
    }
    if (extending != null) {
      getContexts().push(extending);
      Node rootNode = extending.parse();
      getContexts().pop();
      return rootNode;
    }

    return block;
  }
예제 #6
0
  private Node parseInclude() {
    Token token = expect(Include.class);
    Include includeToken = (Include) token;
    String templateName = includeToken.getValue().trim();

    Parser parser = createParser(templateName);
    parser.setBlocks(blocks);
    contexts.push(parser);
    Node ast = parser.parse();
    contexts.pop();

    if (peek() instanceof Indent && ast instanceof BlockNode) {
      ((BlockNode) ast).getIncludeBlock().push(block());
    }

    return ast;
  }
예제 #7
0
  private Node parseTag() {
    // ast-filter look-ahead
    int i = 2;
    if (lookahead(i) instanceof Attribute) {
      i++;
    }
    if (lookahead(i) instanceof Colon) {
      i++;
      if (lookahead(i) instanceof Indent) {
        return this.parseASTFilter();
      }
    }
    Token token = nextToken();
    String name = token.getValue();
    TagNode tagNode = new TagNode();
    tagNode.setLineNumber(lexer.getLineno());
    tagNode.setFileName(filename);
    tagNode.setName(name);
    tagNode.setValue(name);

    while (true) {
      Token incomingToken = peek();
      if (incomingToken instanceof CssId) {
        Token tok = nextToken();
        tagNode.addAttribute("id", tok.getValue());
        continue;
      } else if (incomingToken instanceof CssClass) {
        Token tok = nextToken();
        tagNode.addAttribute("class", tok.getValue());
        continue;
      } else if (incomingToken instanceof Attribute) {
        Attribute tok = (Attribute) nextToken();
        tagNode.addAttributes(tok.getAttributes());
        continue;
      } else {
        break;
      }
    }

    // check immediate '.'
    boolean dot = false;
    if (peek() instanceof Dot) {
      dot = true;
      tagNode.setTextOnly(true);
      nextToken();
    }

    // (text | code | ':')?
    if (peek() instanceof Text) {
      tagNode.setTextNode(parseText());
    } else if (peek() instanceof Expression) {
      tagNode.setCodeNode(parseCode());
    } else if (peek() instanceof Colon) {
      Token next = nextToken();
      BlockNode block = new BlockNode();
      block.setLineNumber(next.getLineNumber());
      block.setFileName(filename);
      tagNode.setBlock(block);
      block.push(parseExpr());
    }

    // newline*
    while (peek() instanceof Newline) {
      nextToken();
    }

    if (!tagNode.isTextOnly()) {
      if (Arrays.asList(textOnlyTags).contains(tagNode.getName())) {
        tagNode.setTextOnly(true);
      }
    }

    // script special-case
    if ("script".equals(tagNode.getName())) {
      String type = tagNode.getAttribute("type");
      if (!dot && StringUtils.isNotBlank(type)) {
        String cleanType = type.replaceAll("^['\"]|['\"]$", "");
        if (!"text/javascript".equals(cleanType)) {
          tagNode.setTextOnly(false);
        }
      }
    }

    if (peek() instanceof Indent) {
      if (tagNode.isTextOnly()) {
        lexer.setPipeless(true);
        tagNode.setTextNode(parseTextBlock());
        lexer.setPipeless(false);
      } else {
        Node blockNode = block();
        if (tagNode.hasBlock()) {
          tagNode.getBlock().getNodes().addAll(blockNode.getNodes());
        } else {
          tagNode.setBlock(blockNode);
        }
      }
    }

    return tagNode;
  }