code: @Override
    protected void visitPrintNode(PrintNode node) {
      TranslateToPyExprVisitor translator =
          new TranslateToPyExprVisitor(localVarExprs, pluginValueFactory, errorReporter);
  
      PyExpr pyExpr = translator.exec(node.getExpr());
  
      // Process directives.
      for (PrintDirectiveNode directiveNode : node.getChildren()) {
  
        // Get directive.
        SoyPrintDirective directive = directiveNode.getPrintDirective();
        if (!(directive instanceof SoyPySrcPrintDirective)) {
          errorReporter.report(
              directiveNode.getSourceLocation(),
              UNKNOWN_SOY_PY_SRC_PRINT_DIRECTIVE,
              directiveNode.getName());
          continue;
        }
  
        // Get directive args.
        List<ExprRootNode> args = directiveNode.getArgs();
        // Translate directive args.
        List<PyExpr> argsPyExprs = new ArrayList<>(args.size());
        for (ExprRootNode arg : args) {
          argsPyExprs.add(translator.exec(arg));
        }
  
        // Apply directive.
        pyExpr = ((SoyPySrcPrintDirective) directive).applyForPySrc(pyExpr, argsPyExprs);
      }
  
      pyExprs.add(pyExpr);
    }
docs: Visiting a print node accomplishes 3 basic tasks. It loads data, it performs any operations
  needed, and it executes the appropriate print directives.
  
  <p>TODO(dcphillips): Add support for local variables once LetNode are supported.
  
  <p>Example:
  
  <pre>
  {$boo |changeNewlineToBr}
  {$goo + 5}
  </pre>
  
  might generate
  
  <pre>
  sanitize.change_newline_to_br(data.get('boo'))
  data.get('goo') + 5
  </pre>