/**
  * Constructor
  *
  * @param array $config An array of default values.
  */
 public function __construct($config)
 {
     $this->config = $config;
     ShortcodesTrait::setShortcodesClass($this);
     // Set up Twig environment
     $this->loader = new \Twig_Loader_Array([]);
     $this->twig = new Twig\Environment($this->loader, ['use_strict_variables' => false]);
     // Set up sandbox for parsing shortcodes
     $this->policy = new \Twig_Sandbox_SecurityPolicy();
     $this->twig->addExtension(new \Twig_Extension_Sandbox($this->policy, true));
     $this->policy->setAllowedTags($this->loadShortcodes());
     // Modify lexer to match special shortcode syntax
     $lexer = new \Twig_Lexer($this->twig, array('tag_comment' => ['{#', '#}'], 'tag_block' => ['{{%', '%}}'], 'tag_variable' => ['{#', '#}'], 'interpolation' => ['#{', '}']));
     $this->twig->setLexer($lexer);
 }
 /**
  * Compile the node.
  *
  * @param  \Twig_Compiler $compiler A Twig compiler instance.
  */
 public function compile(\Twig_Compiler $compiler)
 {
     $name = $this->getAttribute('name');
     $shortcode = $compiler->getEnvironment()->getShortcode($name);
     $filter = $compiler->getEnvironment()->getShortcodeFilter($name);
     $this->setAttribute('name', $name);
     $this->setAttribute('type', 'shortcode');
     $this->setAttribute('thing', $shortcode);
     $this->setAttribute('needs_environment', $shortcode->needsEnvironment());
     $this->setAttribute('needs_context', $shortcode->needsContext());
     $this->setAttribute('arguments', $shortcode->getArguments());
     if ($shortcode instanceof \Twig_FunctionCallableInterface || $shortcode instanceof GenericShortcode) {
         $instance = ShortcodesTrait::getShortcodesClass();
         $this->setAttribute('callable', $shortcode->getCallable());
     }
     if ($this->hasNode('node')) {
         $body = $this->getNode('node');
         if (!is_array($body)) {
             $body = [$body];
         }
         $compiler->addDebugInfo($this)->write("ob_start();\n");
         foreach ($body as $key => $node) {
             $compiler->subcompile($node);
         }
         $compiler->write("\$body = ob_get_clean();\n");
     }
     if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) {
         $compiler->write("\$arguments = array(");
         foreach ($this->getNode('arguments') as $key => $node) {
             $compiler->string($key)->raw(" => ")->subcompile($node)->raw(", ");
         }
         $compiler->raw(");\n");
     }
     $compiler->write('$compiled = $context["__shortcodes"](')->string($this->tag)->raw(", \$body, \$arguments);\n")->write($filter ? '$compiled = ' : 'echo ');
     $this->compileCallable($compiler);
     $compiler->raw(";\n");
     // Filter shortcode, if registered filters are present
     if ($filter) {
         $compiler->write('echo $context["__shortcodes_filter"](')->string($name)->raw(', $compiled, $context, $this->env)');
     }
     $compiler->raw(";\n")->write('unset($body, $arguments, $compiled);')->raw("\n");
 }