Full Code of twigphp/Twig for AI

3.x 76688da07c9e cached
1117 files
1.8 MB
499.5k tokens
2527 symbols
1 requests
Download .txt
Showing preview only (2,084K chars total). Download the full file or copy to clipboard to get everything.
Repository: twigphp/Twig
Branch: 3.x
Commit: 76688da07c9e
Files: 1117
Total size: 1.8 MB

Directory structure:
gitextract_my2eswkz/

├── .editorconfig
├── .gitattributes
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       ├── documentation.yml
│       └── fabbot.yml
├── .gitignore
├── .php-cs-fixer.dist.php
├── CHANGELOG
├── LICENSE
├── README.rst
├── bin/
│   └── generate_operators_precedence.php
├── composer.json
├── doc/
│   ├── .doctor-rst.yaml
│   ├── _build/
│   │   ├── build.php
│   │   └── composer.json
│   ├── advanced.rst
│   ├── api.rst
│   ├── coding_standards.rst
│   ├── deprecated.rst
│   ├── filters/
│   │   ├── abs.rst
│   │   ├── batch.rst
│   │   ├── capitalize.rst
│   │   ├── column.rst
│   │   ├── convert_encoding.rst
│   │   ├── country_name.rst
│   │   ├── currency_name.rst
│   │   ├── currency_symbol.rst
│   │   ├── data_uri.rst
│   │   ├── date.rst
│   │   ├── date_modify.rst
│   │   ├── default.rst
│   │   ├── escape.rst
│   │   ├── filter.rst
│   │   ├── find.rst
│   │   ├── first.rst
│   │   ├── format.rst
│   │   ├── format_currency.rst
│   │   ├── format_date.rst
│   │   ├── format_datetime.rst
│   │   ├── format_number.rst
│   │   ├── format_time.rst
│   │   ├── html_attr_merge.rst
│   │   ├── html_attr_type.rst
│   │   ├── html_to_markdown.rst
│   │   ├── index.rst
│   │   ├── inky_to_html.rst
│   │   ├── inline_css.rst
│   │   ├── invoke.rst
│   │   ├── join.rst
│   │   ├── json_encode.rst
│   │   ├── keys.rst
│   │   ├── language_name.rst
│   │   ├── last.rst
│   │   ├── length.rst
│   │   ├── locale_name.rst
│   │   ├── lower.rst
│   │   ├── map.rst
│   │   ├── markdown_to_html.rst
│   │   ├── merge.rst
│   │   ├── nl2br.rst
│   │   ├── number_format.rst
│   │   ├── plural.rst
│   │   ├── raw.rst
│   │   ├── reduce.rst
│   │   ├── replace.rst
│   │   ├── reverse.rst
│   │   ├── round.rst
│   │   ├── shuffle.rst
│   │   ├── singular.rst
│   │   ├── slice.rst
│   │   ├── slug.rst
│   │   ├── sort.rst
│   │   ├── spaceless.rst
│   │   ├── split.rst
│   │   ├── striptags.rst
│   │   ├── timezone_name.rst
│   │   ├── title.rst
│   │   ├── trim.rst
│   │   ├── u.rst
│   │   ├── upper.rst
│   │   └── url_encode.rst
│   ├── functions/
│   │   ├── attribute.rst
│   │   ├── block.rst
│   │   ├── constant.rst
│   │   ├── country_names.rst
│   │   ├── country_timezones.rst
│   │   ├── currency_names.rst
│   │   ├── cycle.rst
│   │   ├── date.rst
│   │   ├── dump.rst
│   │   ├── enum.rst
│   │   ├── enum_cases.rst
│   │   ├── html_attr.rst
│   │   ├── html_classes.rst
│   │   ├── html_cva.rst
│   │   ├── include.rst
│   │   ├── index.rst
│   │   ├── language_names.rst
│   │   ├── locale_names.rst
│   │   ├── max.rst
│   │   ├── min.rst
│   │   ├── parent.rst
│   │   ├── random.rst
│   │   ├── range.rst
│   │   ├── script_names.rst
│   │   ├── source.rst
│   │   ├── template_from_string.rst
│   │   └── timezone_names.rst
│   ├── index.rst
│   ├── installation.rst
│   ├── internals.rst
│   ├── intro.rst
│   ├── operators_precedence.rst
│   ├── recipes.rst
│   ├── sandbox.rst
│   ├── tags/
│   │   ├── apply.rst
│   │   ├── autoescape.rst
│   │   ├── block.rst
│   │   ├── cache.rst
│   │   ├── deprecated.rst
│   │   ├── do.rst
│   │   ├── embed.rst
│   │   ├── extends.rst
│   │   ├── flush.rst
│   │   ├── for.rst
│   │   ├── from.rst
│   │   ├── guard.rst
│   │   ├── if.rst
│   │   ├── import.rst
│   │   ├── include.rst
│   │   ├── index.rst
│   │   ├── macro.rst
│   │   ├── sandbox.rst
│   │   ├── set.rst
│   │   ├── types.rst
│   │   ├── use.rst
│   │   ├── verbatim.rst
│   │   └── with.rst
│   ├── templates.rst
│   └── tests/
│       ├── constant.rst
│       ├── defined.rst
│       ├── divisibleby.rst
│       ├── empty.rst
│       ├── even.rst
│       ├── index.rst
│       ├── iterable.rst
│       ├── mapping.rst
│       ├── null.rst
│       ├── odd.rst
│       ├── sameas.rst
│       └── sequence.rst
├── extra/
│   ├── cache-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── CacheExtension.php
│   │   ├── CacheRuntime.php
│   │   ├── LICENSE
│   │   ├── Node/
│   │   │   └── CacheNode.php
│   │   ├── README.md
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   ├── cache.test
│   │   │   │   ├── cache_complex.test
│   │   │   │   ├── cache_with_blocks.test
│   │   │   │   └── macro.test
│   │   │   ├── FunctionalTest.php
│   │   │   └── IntegrationTest.php
│   │   ├── TokenParser/
│   │   │   └── CacheTokenParser.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── cssinliner-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── CssInlinerExtension.php
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── Resources/
│   │   │   └── functions.php
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   └── inline_css.test
│   │   │   ├── IntegrationTest.php
│   │   │   └── LegacyFunctionsTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── html-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── Cva.php
│   │   ├── HtmlAttr/
│   │   │   ├── AttributeValueInterface.php
│   │   │   ├── InlineStyle.php
│   │   │   ├── MergeableInterface.php
│   │   │   └── SeparatedTokenList.php
│   │   ├── HtmlExtension.php
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── Resources/
│   │   │   └── functions.php
│   │   ├── Tests/
│   │   │   ├── CvaTest.php
│   │   │   ├── Fixtures/
│   │   │   │   ├── data_uri.test
│   │   │   │   ├── html_attr.test
│   │   │   │   ├── html_attr_merge.test
│   │   │   │   ├── html_classes.test
│   │   │   │   ├── html_classes_with_unsupported_arg.test
│   │   │   │   ├── html_classes_with_unsupported_key.test
│   │   │   │   ├── html_cva.test
│   │   │   │   └── html_cva_pass_to_template.test
│   │   │   ├── HtmlAttrMergeTest.php
│   │   │   ├── HtmlAttrTest.php
│   │   │   ├── IntegrationTest.php
│   │   │   └── LegacyFunctionsTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── inky-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── InkyExtension.php
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── Resources/
│   │   │   └── functions.php
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   └── inky.test
│   │   │   ├── IntegrationTest.php
│   │   │   └── LegacyFunctionsTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── intl-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── IntlExtension.php
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   ├── country_name.test
│   │   │   │   ├── country_names.test
│   │   │   │   ├── country_timezones.test
│   │   │   │   ├── currency_name.test
│   │   │   │   ├── currency_names.test
│   │   │   │   ├── currency_symbol.test
│   │   │   │   ├── format_currency.test
│   │   │   │   ├── format_date.test
│   │   │   │   ├── format_date_ICU72.test
│   │   │   │   ├── format_date_php8.test
│   │   │   │   ├── format_date_php8_ICU72.test
│   │   │   │   ├── format_number.test
│   │   │   │   ├── language_name.test
│   │   │   │   ├── language_names.test
│   │   │   │   ├── locale_name.test
│   │   │   │   ├── locale_names.test
│   │   │   │   ├── script_names.test
│   │   │   │   ├── timezone_name.test
│   │   │   │   └── timezone_names.test
│   │   │   ├── IntegrationTest.php
│   │   │   └── IntlExtensionTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── markdown-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── DefaultMarkdown.php
│   │   ├── ErusevMarkdown.php
│   │   ├── LICENSE
│   │   ├── LeagueMarkdown.php
│   │   ├── MarkdownExtension.php
│   │   ├── MarkdownInterface.php
│   │   ├── MarkdownRuntime.php
│   │   ├── MichelfMarkdown.php
│   │   ├── README.md
│   │   ├── Resources/
│   │   │   └── functions.php
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   └── html_to_markdown.test
│   │   │   ├── FunctionalTest.php
│   │   │   ├── IntegrationTest.php
│   │   │   └── LegacyFunctionsTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── string-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── StringExtension.php
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   ├── plural-invalid-language.test
│   │   │   │   ├── plural.test
│   │   │   │   ├── plural_es.test
│   │   │   │   ├── singular-invalid-language.test
│   │   │   │   ├── singular.test
│   │   │   │   ├── singular_es.test
│   │   │   │   ├── slug.test
│   │   │   │   └── string.test
│   │   │   └── IntegrationTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   └── twig-extra-bundle/
│       ├── .gitattributes
│       ├── .gitignore
│       ├── DependencyInjection/
│       │   ├── Compiler/
│       │   │   └── MissingExtensionSuggestorPass.php
│       │   ├── Configuration.php
│       │   └── TwigExtraExtension.php
│       ├── Extensions.php
│       ├── LICENSE
│       ├── LeagueCommonMarkConverterFactory.php
│       ├── MissingExtensionSuggestor.php
│       ├── README.md
│       ├── Resources/
│       │   └── config/
│       │       ├── cache.php
│       │       ├── cssinliner.php
│       │       ├── html.php
│       │       ├── inky.php
│       │       ├── intl.php
│       │       ├── markdown.php
│       │       ├── markdown_league.php
│       │       ├── string.php
│       │       └── suggestor.php
│       ├── Tests/
│       │   ├── DependencyInjection/
│       │   │   └── TwigExtraExtensionTest.php
│       │   ├── Fixture/
│       │   │   ├── Kernel.php
│       │   │   └── views/
│       │   │       └── markdown_to_html.html.twig
│       │   └── IntegrationTest.php
│       ├── TwigExtraBundle.php
│       ├── composer.json
│       └── phpunit.xml.dist
├── phpstan-baseline.neon
├── phpstan.neon.dist
├── phpunit.xml.dist
├── splitsh.json
├── src/
│   ├── AbstractTwigCallable.php
│   ├── Attribute/
│   │   ├── AsTwigFilter.php
│   │   ├── AsTwigFunction.php
│   │   ├── AsTwigTest.php
│   │   ├── FirstClassTwigCallableReady.php
│   │   └── YieldReady.php
│   ├── Cache/
│   │   ├── CacheInterface.php
│   │   ├── ChainCache.php
│   │   ├── FilesystemCache.php
│   │   ├── NullCache.php
│   │   ├── ReadOnlyFilesystemCache.php
│   │   └── RemovableCacheInterface.php
│   ├── Compiler.php
│   ├── DeprecatedCallableInfo.php
│   ├── Environment.php
│   ├── Error/
│   │   ├── Error.php
│   │   ├── LoaderError.php
│   │   ├── RuntimeError.php
│   │   └── SyntaxError.php
│   ├── ExpressionParser/
│   │   ├── AbstractExpressionParser.php
│   │   ├── ExpressionParserDescriptionInterface.php
│   │   ├── ExpressionParserInterface.php
│   │   ├── ExpressionParserType.php
│   │   ├── ExpressionParsers.php
│   │   ├── Infix/
│   │   │   ├── ArgumentsTrait.php
│   │   │   ├── ArrowExpressionParser.php
│   │   │   ├── AssignmentExpressionParser.php
│   │   │   ├── BinaryOperatorExpressionParser.php
│   │   │   ├── ConditionalTernaryExpressionParser.php
│   │   │   ├── DotExpressionParser.php
│   │   │   ├── FilterExpressionParser.php
│   │   │   ├── FunctionExpressionParser.php
│   │   │   ├── IsExpressionParser.php
│   │   │   ├── IsNotExpressionParser.php
│   │   │   └── SquareBracketExpressionParser.php
│   │   ├── InfixAssociativity.php
│   │   ├── InfixExpressionParserInterface.php
│   │   ├── PrecedenceChange.php
│   │   ├── Prefix/
│   │   │   ├── GroupingExpressionParser.php
│   │   │   ├── LiteralExpressionParser.php
│   │   │   └── UnaryOperatorExpressionParser.php
│   │   └── PrefixExpressionParserInterface.php
│   ├── ExpressionParser.php
│   ├── Extension/
│   │   ├── AbstractExtension.php
│   │   ├── AttributeExtension.php
│   │   ├── CoreExtension.php
│   │   ├── DebugExtension.php
│   │   ├── EscaperExtension.php
│   │   ├── ExtensionInterface.php
│   │   ├── GlobalsInterface.php
│   │   ├── LastModifiedExtensionInterface.php
│   │   ├── OptimizerExtension.php
│   │   ├── ProfilerExtension.php
│   │   ├── RuntimeExtensionInterface.php
│   │   ├── SandboxExtension.php
│   │   ├── StagingExtension.php
│   │   ├── StringLoaderExtension.php
│   │   └── YieldNotReadyExtension.php
│   ├── ExtensionSet.php
│   ├── FileExtensionEscapingStrategy.php
│   ├── Lexer.php
│   ├── Loader/
│   │   ├── ArrayLoader.php
│   │   ├── ChainLoader.php
│   │   ├── FilesystemLoader.php
│   │   └── LoaderInterface.php
│   ├── Markup.php
│   ├── Node/
│   │   ├── AutoEscapeNode.php
│   │   ├── BlockNode.php
│   │   ├── BlockReferenceNode.php
│   │   ├── BodyNode.php
│   │   ├── CaptureNode.php
│   │   ├── CheckSecurityCallNode.php
│   │   ├── CheckSecurityNode.php
│   │   ├── CheckToStringNode.php
│   │   ├── DeprecatedNode.php
│   │   ├── DoNode.php
│   │   ├── EmbedNode.php
│   │   ├── EmptyNode.php
│   │   ├── Expression/
│   │   │   ├── AbstractExpression.php
│   │   │   ├── ArrayExpression.php
│   │   │   ├── ArrowFunctionExpression.php
│   │   │   ├── AssignNameExpression.php
│   │   │   ├── Binary/
│   │   │   │   ├── AbstractBinary.php
│   │   │   │   ├── AddBinary.php
│   │   │   │   ├── AndBinary.php
│   │   │   │   ├── BinaryInterface.php
│   │   │   │   ├── BitwiseAndBinary.php
│   │   │   │   ├── BitwiseOrBinary.php
│   │   │   │   ├── BitwiseXorBinary.php
│   │   │   │   ├── ConcatBinary.php
│   │   │   │   ├── DivBinary.php
│   │   │   │   ├── ElvisBinary.php
│   │   │   │   ├── EndsWithBinary.php
│   │   │   │   ├── EqualBinary.php
│   │   │   │   ├── FloorDivBinary.php
│   │   │   │   ├── GreaterBinary.php
│   │   │   │   ├── GreaterEqualBinary.php
│   │   │   │   ├── HasEveryBinary.php
│   │   │   │   ├── HasSomeBinary.php
│   │   │   │   ├── InBinary.php
│   │   │   │   ├── LessBinary.php
│   │   │   │   ├── LessEqualBinary.php
│   │   │   │   ├── MatchesBinary.php
│   │   │   │   ├── ModBinary.php
│   │   │   │   ├── MulBinary.php
│   │   │   │   ├── NotEqualBinary.php
│   │   │   │   ├── NotInBinary.php
│   │   │   │   ├── NotSameAsBinary.php
│   │   │   │   ├── NullCoalesceBinary.php
│   │   │   │   ├── ObjectDestructuringSetBinary.php
│   │   │   │   ├── OrBinary.php
│   │   │   │   ├── PowerBinary.php
│   │   │   │   ├── RangeBinary.php
│   │   │   │   ├── SameAsBinary.php
│   │   │   │   ├── SequenceDestructuringSetBinary.php
│   │   │   │   ├── SetBinary.php
│   │   │   │   ├── SpaceshipBinary.php
│   │   │   │   ├── StartsWithBinary.php
│   │   │   │   ├── SubBinary.php
│   │   │   │   └── XorBinary.php
│   │   │   ├── BlockReferenceExpression.php
│   │   │   ├── CallExpression.php
│   │   │   ├── ConditionalExpression.php
│   │   │   ├── ConstantExpression.php
│   │   │   ├── EmptyExpression.php
│   │   │   ├── Filter/
│   │   │   │   ├── DefaultFilter.php
│   │   │   │   └── RawFilter.php
│   │   │   ├── FilterExpression.php
│   │   │   ├── FunctionExpression.php
│   │   │   ├── FunctionNode/
│   │   │   │   ├── EnumCasesFunction.php
│   │   │   │   └── EnumFunction.php
│   │   │   ├── GetAttrExpression.php
│   │   │   ├── InlinePrint.php
│   │   │   ├── ListExpression.php
│   │   │   ├── MacroReferenceExpression.php
│   │   │   ├── MethodCallExpression.php
│   │   │   ├── NameExpression.php
│   │   │   ├── NullCoalesceExpression.php
│   │   │   ├── OperatorEscapeInterface.php
│   │   │   ├── ParentExpression.php
│   │   │   ├── ReturnArrayInterface.php
│   │   │   ├── ReturnBoolInterface.php
│   │   │   ├── ReturnNumberInterface.php
│   │   │   ├── ReturnPrimitiveTypeInterface.php
│   │   │   ├── ReturnStringInterface.php
│   │   │   ├── SupportDefinedTestDeprecationTrait.php
│   │   │   ├── SupportDefinedTestInterface.php
│   │   │   ├── SupportDefinedTestTrait.php
│   │   │   ├── TempNameExpression.php
│   │   │   ├── Ternary/
│   │   │   │   └── ConditionalTernary.php
│   │   │   ├── Test/
│   │   │   │   ├── ConstantTest.php
│   │   │   │   ├── DefinedTest.php
│   │   │   │   ├── DivisiblebyTest.php
│   │   │   │   ├── EvenTest.php
│   │   │   │   ├── NullTest.php
│   │   │   │   ├── OddTest.php
│   │   │   │   ├── SameasTest.php
│   │   │   │   └── TrueTest.php
│   │   │   ├── TestExpression.php
│   │   │   ├── Unary/
│   │   │   │   ├── AbstractUnary.php
│   │   │   │   ├── NegUnary.php
│   │   │   │   ├── NotUnary.php
│   │   │   │   ├── PosUnary.php
│   │   │   │   ├── SpreadUnary.php
│   │   │   │   ├── StringCastUnary.php
│   │   │   │   └── UnaryInterface.php
│   │   │   ├── Variable/
│   │   │   │   ├── AssignContextVariable.php
│   │   │   │   ├── AssignTemplateVariable.php
│   │   │   │   ├── ContextVariable.php
│   │   │   │   ├── LocalVariable.php
│   │   │   │   └── TemplateVariable.php
│   │   │   └── VariadicExpression.php
│   │   ├── FlushNode.php
│   │   ├── ForElseNode.php
│   │   ├── ForLoopNode.php
│   │   ├── ForNode.php
│   │   ├── IfNode.php
│   │   ├── ImportNode.php
│   │   ├── IncludeNode.php
│   │   ├── MacroNode.php
│   │   ├── ModuleNode.php
│   │   ├── NameDeprecation.php
│   │   ├── Node.php
│   │   ├── NodeCaptureInterface.php
│   │   ├── NodeOutputInterface.php
│   │   ├── Nodes.php
│   │   ├── PrintNode.php
│   │   ├── SandboxNode.php
│   │   ├── SetNode.php
│   │   ├── TextNode.php
│   │   ├── TypesNode.php
│   │   └── WithNode.php
│   ├── NodeTraverser.php
│   ├── NodeVisitor/
│   │   ├── AbstractNodeVisitor.php
│   │   ├── EscaperNodeVisitor.php
│   │   ├── NodeVisitorInterface.php
│   │   ├── OptimizerNodeVisitor.php
│   │   ├── SafeAnalysisNodeVisitor.php
│   │   ├── SandboxNodeVisitor.php
│   │   └── YieldNotReadyNodeVisitor.php
│   ├── OperatorPrecedenceChange.php
│   ├── Parser.php
│   ├── Profiler/
│   │   ├── Dumper/
│   │   │   ├── BaseDumper.php
│   │   │   ├── BlackfireDumper.php
│   │   │   ├── HtmlDumper.php
│   │   │   └── TextDumper.php
│   │   ├── Node/
│   │   │   ├── EnterProfileNode.php
│   │   │   └── LeaveProfileNode.php
│   │   ├── NodeVisitor/
│   │   │   └── ProfilerNodeVisitor.php
│   │   └── Profile.php
│   ├── Resources/
│   │   ├── core.php
│   │   ├── debug.php
│   │   ├── escaper.php
│   │   └── string_loader.php
│   ├── Runtime/
│   │   └── EscaperRuntime.php
│   ├── RuntimeLoader/
│   │   ├── ContainerRuntimeLoader.php
│   │   ├── FactoryRuntimeLoader.php
│   │   └── RuntimeLoaderInterface.php
│   ├── Sandbox/
│   │   ├── SecurityError.php
│   │   ├── SecurityNotAllowedFilterError.php
│   │   ├── SecurityNotAllowedFunctionError.php
│   │   ├── SecurityNotAllowedMethodError.php
│   │   ├── SecurityNotAllowedPropertyError.php
│   │   ├── SecurityNotAllowedTagError.php
│   │   ├── SecurityPolicy.php
│   │   ├── SecurityPolicyInterface.php
│   │   └── SourcePolicyInterface.php
│   ├── Source.php
│   ├── Template.php
│   ├── TemplateWrapper.php
│   ├── Test/
│   │   ├── IntegrationTestCase.php
│   │   └── NodeTestCase.php
│   ├── Token.php
│   ├── TokenParser/
│   │   ├── AbstractTokenParser.php
│   │   ├── ApplyTokenParser.php
│   │   ├── AutoEscapeTokenParser.php
│   │   ├── BlockTokenParser.php
│   │   ├── DeprecatedTokenParser.php
│   │   ├── DoTokenParser.php
│   │   ├── EmbedTokenParser.php
│   │   ├── ExtendsTokenParser.php
│   │   ├── FlushTokenParser.php
│   │   ├── ForTokenParser.php
│   │   ├── FromTokenParser.php
│   │   ├── GuardTokenParser.php
│   │   ├── IfTokenParser.php
│   │   ├── ImportTokenParser.php
│   │   ├── IncludeTokenParser.php
│   │   ├── MacroTokenParser.php
│   │   ├── SandboxTokenParser.php
│   │   ├── SetTokenParser.php
│   │   ├── TokenParserInterface.php
│   │   ├── TypesTokenParser.php
│   │   ├── UseTokenParser.php
│   │   └── WithTokenParser.php
│   ├── TokenStream.php
│   ├── TwigCallableInterface.php
│   ├── TwigFilter.php
│   ├── TwigFunction.php
│   ├── TwigTest.php
│   └── Util/
│       ├── CallableArgumentsExtractor.php
│       ├── DeprecationCollector.php
│       ├── ReflectionCallable.php
│       └── TemplateDirIterator.php
└── tests/
    ├── Cache/
    │   ├── ChainTest.php
    │   ├── FilesystemTest.php
    │   └── ReadOnlyFilesystemTest.php
    ├── CompilerTest.php
    ├── ContainerRuntimeLoaderTest.php
    ├── CustomExtensionTest.php
    ├── DeprecatedCallableInfoTest.php
    ├── DummyBackedEnum.php
    ├── DummyUnitEnum.php
    ├── EnvironmentTest.php
    ├── ErrorTest.php
    ├── ExpressionParserTest.php
    ├── Extension/
    │   ├── AttributeExtensionTest.php
    │   ├── CoreTest.php
    │   ├── EscaperTest.php
    │   ├── Fixtures/
    │   │   ├── ExtensionWithAttributes.php
    │   │   ├── FilterWithoutValue.php
    │   │   └── TestWithoutValue.php
    │   ├── LegacyDebugFunctionsTest.php
    │   ├── LegacyStringLoaderFunctionsTest.php
    │   ├── SandboxTest.php
    │   └── StringLoaderExtensionTest.php
    ├── FactoryRuntimeLoaderTest.php
    ├── FileExtensionEscapingStrategyTest.php
    ├── FilesystemHelper.php
    ├── Fixtures/
    │   ├── autoescape/
    │   │   ├── block.test
    │   │   └── name.test
    │   ├── errors/
    │   │   ├── base.html
    │   │   ├── extends/
    │   │   │   ├── include.twig
    │   │   │   └── index.twig
    │   │   ├── index.html
    │   │   ├── no_line_and_context_exception.twig
    │   │   ├── no_line_and_context_exception_include_line_1.twig
    │   │   └── no_line_and_context_exception_include_line_5.twig
    │   ├── exceptions/
    │   │   ├── child_contents_outside_blocks.test
    │   │   ├── exception_in_extension_extends.test
    │   │   ├── exception_in_extension_include.test
    │   │   ├── multiline_array_with_undefined_variable.test
    │   │   ├── multiline_array_with_undefined_variable_again.test
    │   │   ├── multiline_function_with_undefined_variable.test
    │   │   ├── multiline_function_with_unknown_argument.test
    │   │   ├── multiline_tag_with_undefined_variable.test
    │   │   ├── syntax_error_in_reused_template.test
    │   │   ├── unclosed_tag.test
    │   │   ├── undefined_parent.test
    │   │   ├── undefined_template_in_child_template.test
    │   │   └── undefined_trait.test
    │   ├── expressions/
    │   │   ├── _self.test
    │   │   ├── array.test
    │   │   ├── array_call.test
    │   │   ├── attributes.test
    │   │   ├── binary.test
    │   │   ├── bitwise.test
    │   │   ├── call_argument_defined_twice.test
    │   │   ├── call_argument_unpacking.test
    │   │   ├── call_argument_unpacking_before_normal.test
    │   │   ├── call_positional_arg_after_named_arg.test
    │   │   ├── comparison.test
    │   │   ├── comparison_precedence.test
    │   │   ├── const.test
    │   │   ├── divisibleby.test
    │   │   ├── dot_as_concatenation.test
    │   │   ├── dotdot.test
    │   │   ├── dynamic_attribute.test
    │   │   ├── ends_with.test
    │   │   ├── exponential_numbers.test
    │   │   ├── floats.test
    │   │   ├── grouping.test
    │   │   ├── has_every.test
    │   │   ├── has_some.test
    │   │   ├── literals.test
    │   │   ├── magic_call.test
    │   │   ├── matches.test
    │   │   ├── matches_error_compilation.test
    │   │   ├── matches_error_runtime.test
    │   │   ├── method_call.test
    │   │   ├── negative_numbers.test
    │   │   ├── not.test
    │   │   ├── not_arrow_fn.test
    │   │   ├── operators_as_variables.test
    │   │   ├── postfix.test
    │   │   ├── power.test
    │   │   ├── sameas.test
    │   │   ├── set.test
    │   │   ├── spread_array_operator.test
    │   │   ├── spread_mapping_operator.test
    │   │   ├── spread_ternary_precedence.test
    │   │   ├── starts_with.test
    │   │   ├── string_operator_as_var_assignment.test
    │   │   ├── strings.test
    │   │   ├── ternary_operator.test
    │   │   ├── ternary_operator_noelse.test
    │   │   ├── ternary_operator_nothen.test
    │   │   ├── two_word_operators_as_variables.test
    │   │   ├── unary.test
    │   │   ├── unary_macro_arguments.test
    │   │   ├── unary_precedence.test
    │   │   ├── underscored_numbers.test
    │   │   └── underscored_numbers_error.test
    │   ├── extensions/
    │   │   └── anonymous_functions.test
    │   ├── filters/
    │   │   ├── abs.test
    │   │   ├── arrow_reserved_names.test
    │   │   ├── batch.test
    │   │   ├── batch_float.test
    │   │   ├── batch_with_empty_fill.test
    │   │   ├── batch_with_exact_elements.test
    │   │   ├── batch_with_fill.test
    │   │   ├── batch_with_keys.test
    │   │   ├── batch_with_more_elements.test
    │   │   ├── batch_with_zero_elements.test
    │   │   ├── capitalize.test
    │   │   ├── column.test
    │   │   ├── convert_encoding.test
    │   │   ├── date.test
    │   │   ├── date_default_format.test
    │   │   ├── date_default_format_interval.test
    │   │   ├── date_immutable.test
    │   │   ├── date_interval.test
    │   │   ├── date_modify.test
    │   │   ├── date_namedargs.test
    │   │   ├── date_time_zone_conversion.test
    │   │   ├── default.test
    │   │   ├── dynamic_filter.test
    │   │   ├── escape.test
    │   │   ├── escape_html_attr.test
    │   │   ├── escape_html_attr_relaxed.test
    │   │   ├── escape_javascript.test
    │   │   ├── escape_non_supported_charset.test
    │   │   ├── filter.test
    │   │   ├── find.test
    │   │   ├── first.test
    │   │   ├── force_escape.test
    │   │   ├── format.test
    │   │   ├── invoke.test
    │   │   ├── join.test
    │   │   ├── json_encode.test
    │   │   ├── last.test
    │   │   ├── length.test
    │   │   ├── length_utf8.test
    │   │   ├── lower.test
    │   │   ├── map.test
    │   │   ├── merge.test
    │   │   ├── nl2br.test
    │   │   ├── number_format.test
    │   │   ├── number_format_default.test
    │   │   ├── raw.test
    │   │   ├── reduce.test
    │   │   ├── reduce_key.test
    │   │   ├── replace.test
    │   │   ├── replace_invalid_arg.test
    │   │   ├── reverse.test
    │   │   ├── round.test
    │   │   ├── shuffle.test
    │   │   ├── slice.test
    │   │   ├── sort.test
    │   │   ├── sort_with_arrow.test
    │   │   ├── spaceless.legacy.test
    │   │   ├── special_chars.test
    │   │   ├── split.test
    │   │   ├── split_utf8.test
    │   │   ├── static_calls.test
    │   │   ├── striptags.test
    │   │   ├── title.test
    │   │   ├── trailing_commas.test
    │   │   ├── trim.test
    │   │   ├── upper.test
    │   │   └── urlencode.test
    │   ├── functions/
    │   │   ├── attribute.legacy.test
    │   │   ├── attribute_with_wrong_args.legacy.test
    │   │   ├── block.test
    │   │   ├── block_with_template.test
    │   │   ├── block_without_name.test
    │   │   ├── block_without_parent.test
    │   │   ├── constant.test
    │   │   ├── cycle.test
    │   │   ├── cycle_empty_mapping.test
    │   │   ├── cycle_empty_sequence.test
    │   │   ├── cycle_without_enough_args.test
    │   │   ├── date.test
    │   │   ├── date_namedargs.test
    │   │   ├── deprecated.test
    │   │   ├── dump.test
    │   │   ├── dump_array.test
    │   │   ├── dynamic_function.test
    │   │   ├── enum/
    │   │   │   ├── invalid_dynamic_enum.test
    │   │   │   ├── invalid_enum.test
    │   │   │   ├── invalid_enum_escaping.test
    │   │   │   ├── invalid_literal_type.test
    │   │   │   └── valid.test
    │   │   ├── enum_cases/
    │   │   │   ├── invalid_dynamic_enum.test
    │   │   │   ├── invalid_enum.test
    │   │   │   ├── invalid_enum_escaping.test
    │   │   │   ├── invalid_literal_type.test
    │   │   │   └── valid.test
    │   │   ├── include/
    │   │   │   ├── assignment.test
    │   │   │   ├── autoescaping.test
    │   │   │   ├── basic.test
    │   │   │   ├── expression.test
    │   │   │   ├── ignore_missing.test
    │   │   │   ├── ignore_missing_exists.test
    │   │   │   ├── include_missing_extends.test
    │   │   │   ├── missing.test
    │   │   │   ├── missing_nested.test
    │   │   │   ├── sandbox.test
    │   │   │   ├── sandbox_disabling.test
    │   │   │   ├── sandbox_disabling_ignore_missing.test
    │   │   │   ├── template_instance.test
    │   │   │   ├── templates_as_array.test
    │   │   │   ├── with_context.test
    │   │   │   └── with_variables.test
    │   │   ├── include_template_from_string.test
    │   │   ├── magic_call.test
    │   │   ├── magic_static_call.test
    │   │   ├── max.test
    │   │   ├── max_without_args.test
    │   │   ├── min.test
    │   │   ├── parent_in_condition.test
    │   │   ├── parent_outside_of_a_block.test
    │   │   ├── range.test
    │   │   ├── recursive_block_with_inheritance.test
    │   │   ├── source.test
    │   │   ├── special_chars.test
    │   │   ├── static_calls.test
    │   │   ├── template_from_string.test
    │   │   ├── template_from_string_error.test
    │   │   ├── template_from_string_error_php80.test
    │   │   ├── trailing_commas.test
    │   │   ├── undefined_block.test
    │   │   └── undefined_block_deep.test
    │   ├── macros/
    │   │   ├── arrow_as_arg.test
    │   │   ├── default_values.test
    │   │   ├── macro_with_capture.test
    │   │   ├── nested_calls.test
    │   │   ├── reserved_variables.test
    │   │   ├── simple.test
    │   │   ├── trailing_commas.test
    │   │   ├── unknown_macro.test
    │   │   ├── unknown_macro_different_template.test
    │   │   ├── varargs.test
    │   │   ├── varargs_argument.test
    │   │   └── with_filters.test
    │   ├── operators/
    │   │   ├── concat_vs_add_sub.test
    │   │   ├── contat_vs_add_sub.legacy.test
    │   │   ├── minus_vs_pipe.legacy.test
    │   │   ├── not_precedence.legacy.test
    │   │   └── not_precedence.test
    │   ├── regression/
    │   │   ├── 4029-iterator_to_array.test
    │   │   ├── 4033-missing-unwrap.test
    │   │   ├── 4701-block-inheritance-issue.test
    │   │   ├── block_names_unicity.test
    │   │   ├── combined_debug_info.test
    │   │   ├── empty_token.test
    │   │   ├── markup_test.test
    │   │   ├── multi_word_tests.test
    │   │   ├── simple_xml_element.test
    │   │   └── strings_like_numbers.test
    │   ├── tags/
    │   │   ├── apply/
    │   │   │   ├── basic.test
    │   │   │   ├── json_encode.test
    │   │   │   ├── multiple.test
    │   │   │   ├── nested.test
    │   │   │   ├── scope.test
    │   │   │   ├── with_for_tag.test
    │   │   │   └── with_if_tag.test
    │   │   ├── autoescape/
    │   │   │   ├── basic.test
    │   │   │   ├── blocks.test
    │   │   │   ├── double_escaping.test
    │   │   │   ├── functions.test
    │   │   │   ├── literal.test
    │   │   │   ├── nested.test
    │   │   │   ├── objects.test
    │   │   │   ├── raw.test
    │   │   │   ├── strategy.test
    │   │   │   ├── type.test
    │   │   │   ├── with_filters.test
    │   │   │   ├── with_filters_arguments.test
    │   │   │   ├── with_pre_escape_filters.test
    │   │   │   └── with_preserves_safety_filters.test
    │   │   ├── block/
    │   │   │   ├── basic.test
    │   │   │   ├── block_unique_name.test
    │   │   │   ├── conditional_block.test
    │   │   │   └── special_chars.test
    │   │   ├── deprecated/
    │   │   │   ├── block.legacy.test
    │   │   │   ├── macro.legacy.test
    │   │   │   ├── template.legacy.test
    │   │   │   ├── with_package.legacy.test
    │   │   │   └── with_package_version.legacy.test
    │   │   ├── embed/
    │   │   │   ├── basic.test
    │   │   │   ├── complex_dynamic_parent.test
    │   │   │   ├── dynamic_parent.test
    │   │   │   ├── embed_ignore_missing.test
    │   │   │   ├── error_line.test
    │   │   │   ├── multiple.test
    │   │   │   ├── nested.test
    │   │   │   └── with_extends.test
    │   │   ├── for/
    │   │   │   ├── context.test
    │   │   │   ├── else.test
    │   │   │   ├── for_on_strings.test
    │   │   │   ├── inner_variables.test
    │   │   │   ├── keys.test
    │   │   │   ├── keys_and_values.test
    │   │   │   ├── loop_context.test
    │   │   │   ├── loop_context_local.test
    │   │   │   ├── nested_else.test
    │   │   │   ├── objects.test
    │   │   │   ├── objects_countable.test
    │   │   │   ├── recursive.test
    │   │   │   ├── reserved_names.test
    │   │   │   └── values.test
    │   │   ├── from.test
    │   │   ├── guard/
    │   │   │   ├── basic.test
    │   │   │   ├── exception.test
    │   │   │   ├── nested.test
    │   │   │   └── throwing_handler.test
    │   │   ├── if/
    │   │   │   ├── basic.test
    │   │   │   ├── empty_body.test
    │   │   │   └── expression.test
    │   │   ├── include/
    │   │   │   ├── basic.test
    │   │   │   ├── expression.test
    │   │   │   ├── ignore_missing.test
    │   │   │   ├── ignore_missing_exists.test
    │   │   │   ├── include_missing_extends.test
    │   │   │   ├── missing.test
    │   │   │   ├── missing_nested.test
    │   │   │   ├── only.test
    │   │   │   ├── template_instance.test
    │   │   │   ├── templates_as_array.test
    │   │   │   └── with_variables.test
    │   │   ├── inheritance/
    │   │   │   ├── basic.test
    │   │   │   ├── block_expr.test
    │   │   │   ├── block_expr2.test
    │   │   │   ├── capturing_block.test
    │   │   │   ├── conditional.test
    │   │   │   ├── conditional_block.test
    │   │   │   ├── conditional_block_nested.test
    │   │   │   ├── dynamic.test
    │   │   │   ├── dynamic_parent_from_include.test
    │   │   │   ├── empty.test
    │   │   │   ├── extends_as_array.test
    │   │   │   ├── extends_as_array_with_empty_name.test
    │   │   │   ├── extends_as_array_with_nested_blocks.test
    │   │   │   ├── extends_in_block.test
    │   │   │   ├── extends_in_macro.test
    │   │   │   ├── extends_with_nested_blocks.test
    │   │   │   ├── multiple.test
    │   │   │   ├── multiple_dynamic.test
    │   │   │   ├── nested_blocks.test
    │   │   │   ├── nested_blocks_parent_only.test
    │   │   │   ├── nested_inheritance.test
    │   │   │   ├── parent.test
    │   │   │   ├── parent_as_template_wrapper.test
    │   │   │   ├── parent_change.test
    │   │   │   ├── parent_isolation.test
    │   │   │   ├── parent_nested.test
    │   │   │   ├── parent_without_extends.test
    │   │   │   ├── parent_without_extends_but_traits.test
    │   │   │   ├── template_instance.test
    │   │   │   └── use.test
    │   │   ├── macro/
    │   │   │   ├── argument_reserved_names.test
    │   │   │   ├── auto_import.test
    │   │   │   ├── auto_import_blocks.test
    │   │   │   ├── auto_import_without_blocks.test
    │   │   │   ├── basic.test
    │   │   │   ├── colon_not_supported_as_default_separator.test
    │   │   │   ├── endmacro_name.test
    │   │   │   ├── external.test
    │   │   │   ├── from.test
    │   │   │   ├── from_embed_with_global_macro.test
    │   │   │   ├── from_in_block_is_local.test
    │   │   │   ├── from_local_override.test
    │   │   │   ├── from_macro_in_a_macro.test
    │   │   │   ├── from_macros_in_parent.test
    │   │   │   ├── from_nested_blocks.test
    │   │   │   ├── from_nested_blocks_with_global_macro.test
    │   │   │   ├── from_recursive.test
    │   │   │   ├── from_reserved_names.test
    │   │   │   ├── from_self_parent.test
    │   │   │   ├── from_syntax_error.test
    │   │   │   ├── global.test
    │   │   │   ├── import_and_blocks.test
    │   │   │   ├── import_embed_with_global_macro.test
    │   │   │   ├── import_from_string_template.test
    │   │   │   ├── import_in_block_is_local.test
    │   │   │   ├── import_local_override.test
    │   │   │   ├── import_macro_in_a_macro.test
    │   │   │   ├── import_macros_in_parent.test
    │   │   │   ├── import_nested_blocks.test
    │   │   │   ├── import_nested_blocks_with_global_macro.test
    │   │   │   ├── import_reserved_names.test
    │   │   │   ├── import_same_parent_and_child.test
    │   │   │   ├── import_self_parent.test
    │   │   │   ├── import_syntax_error.test
    │   │   │   ├── named_arguments.test
    │   │   │   ├── self_import.test
    │   │   │   ├── special_chars.test
    │   │   │   └── super_globals.test
    │   │   ├── sandbox/
    │   │   │   ├── array.legacy.test
    │   │   │   ├── not_valid1.legacy.test
    │   │   │   ├── not_valid2.legacy.test
    │   │   │   └── simple.legacy.test
    │   │   ├── set/
    │   │   │   ├── basic.test
    │   │   │   ├── capture-empty.test
    │   │   │   ├── capture.test
    │   │   │   ├── capture_scope.test
    │   │   │   ├── expression.test
    │   │   │   ├── inheritance.test
    │   │   │   ├── inheritance_overriding.test
    │   │   │   ├── mutating.test
    │   │   │   └── reserved_names.test
    │   │   ├── special_chars.test
    │   │   ├── use/
    │   │   │   ├── aliases.test
    │   │   │   ├── basic.test
    │   │   │   ├── deep.test
    │   │   │   ├── deep_empty.test
    │   │   │   ├── inheritance.test
    │   │   │   ├── inheritance2.test
    │   │   │   ├── multiple.test
    │   │   │   ├── multiple_aliases.test
    │   │   │   ├── parent_block.test
    │   │   │   ├── parent_block2.test
    │   │   │   ├── parent_block3.test
    │   │   │   ├── use_aliased_block_overridden.test
    │   │   │   └── use_with_parent.test
    │   │   ├── verbatim/
    │   │   │   ├── basic.test
    │   │   │   └── whitespace_control.test
    │   │   └── with/
    │   │       ├── basic.test
    │   │       ├── expression.test
    │   │       ├── globals.test
    │   │       ├── iterable.test
    │   │       ├── nested.test
    │   │       ├── with_no_mapping.test
    │   │       └── with_only.test
    │   ├── tests/
    │   │   ├── array.test
    │   │   ├── constant.test
    │   │   ├── defined.test
    │   │   ├── defined_for_attribute.legacy.test
    │   │   ├── defined_for_attribute.test
    │   │   ├── defined_for_blocks.test
    │   │   ├── defined_for_blocks_with_template.test
    │   │   ├── defined_for_constants.test
    │   │   ├── defined_for_macros.test
    │   │   ├── defined_on_complex_expr.test
    │   │   ├── dynamic_test.test
    │   │   ├── empty.test
    │   │   ├── even.test
    │   │   ├── in.test
    │   │   ├── in_with_iterator.test
    │   │   ├── in_with_objects.test
    │   │   ├── iterable.test
    │   │   ├── mapping.test
    │   │   ├── null_coalesce.legacy.test
    │   │   ├── null_coalesce.test
    │   │   ├── null_coalesce_block.test
    │   │   ├── odd.test
    │   │   └── sequence.test
    │   └── whitespace/
    │       ├── trim_block.test
    │       ├── trim_delimiter_as_strings.test
    │       ├── trim_left.test
    │       ├── trim_line_left.test
    │       ├── trim_line_right.test
    │       └── trim_right.test
    ├── IntegrationTest.php
    ├── LexerTest.php
    ├── Loader/
    │   ├── ArrayTest.php
    │   ├── ChainTest.php
    │   ├── FilesystemTest.php
    │   └── Fixtures/
    │       ├── inheritance/
    │       │   ├── array_inheritance_empty_parent.html.twig
    │       │   ├── array_inheritance_nonexistent_parent.html.twig
    │       │   ├── array_inheritance_valid_parent.html.twig
    │       │   ├── parent.html.twig
    │       │   └── spare_parent.html.twig
    │       ├── named/
    │       │   └── index.html
    │       ├── named_bis/
    │       │   └── index.html
    │       ├── named_final/
    │       │   └── index.html
    │       ├── named_quater/
    │       │   └── named_absolute.html
    │       ├── named_ter/
    │       │   └── index.html
    │       ├── normal/
    │       │   └── index.html
    │       ├── normal_bis/
    │       │   └── index.html
    │       ├── normal_final/
    │       │   └── index.html
    │       ├── normal_ter/
    │       │   └── index.html
    │       ├── phar/
    │       │   └── phar-sample.phar
    │       └── themes/
    │           ├── theme1/
    │           │   └── blocks.html.twig
    │           └── theme2/
    │               └── blocks.html.twig
    ├── Node/
    │   ├── AutoEscapeTest.php
    │   ├── BlockReferenceTest.php
    │   ├── BlockTest.php
    │   ├── DeprecatedTest.php
    │   ├── DoTest.php
    │   ├── EmbedTest.php
    │   ├── Expression/
    │   │   ├── ArrayTest.php
    │   │   ├── Binary/
    │   │   │   ├── AddTest.php
    │   │   │   ├── AndTest.php
    │   │   │   ├── ConcatTest.php
    │   │   │   ├── DivTest.php
    │   │   │   ├── FloorDivTest.php
    │   │   │   ├── ModTest.php
    │   │   │   ├── MulTest.php
    │   │   │   ├── NullCoalesceTest.php
    │   │   │   ├── OrTest.php
    │   │   │   └── SubTest.php
    │   │   ├── CallTest.php
    │   │   ├── ConditionalTest.php
    │   │   ├── ConstantTest.php
    │   │   ├── Filter/
    │   │   │   └── RawTest.php
    │   │   ├── FilterTest.php
    │   │   ├── FilterTestExtension.php
    │   │   ├── FunctionTest.php
    │   │   ├── GetAttrTest.php
    │   │   ├── NullCoalesceTest.php
    │   │   ├── ParentTest.php
    │   │   ├── Ternary/
    │   │   │   └── ConditionalTernaryTest.php
    │   │   ├── TestTest.php
    │   │   ├── Unary/
    │   │   │   ├── NegTest.php
    │   │   │   ├── NotTest.php
    │   │   │   └── PosTest.php
    │   │   └── Variable/
    │   │       ├── AssignContextVariableTest.php
    │   │       └── ContextVariableTest.php
    │   ├── ForTest.php
    │   ├── IfTest.php
    │   ├── ImportTest.php
    │   ├── IncludeTest.php
    │   ├── MacroTest.php
    │   ├── ModuleTest.php
    │   ├── NodeTest.php
    │   ├── PrintTest.php
    │   ├── SandboxTest.php
    │   ├── SetTest.php
    │   ├── TextTest.php
    │   └── TypesTest.php
    ├── NodeVisitor/
    │   ├── OptimizerTest.php
    │   └── SandboxTest.php
    ├── ParserTest.php
    ├── Profiler/
    │   ├── Dumper/
    │   │   ├── BlackfireTest.php
    │   │   ├── HtmlTest.php
    │   │   ├── ProfilerTestCase.php
    │   │   └── TextTest.php
    │   └── ProfileTest.php
    ├── Runtime/
    │   └── EscaperRuntimeTest.php
    ├── TemplateTest.php
    ├── TemplateWrapperTest.php
    ├── TokenParser/
    │   ├── GuardTokenParserTest.php
    │   └── TypesTokenParserTest.php
    ├── TokenStreamTest.php
    ├── Util/
    │   ├── CallableArgumentsExtractorTest.php
    │   └── DeprecationCollectorTest.php
    └── drupal_test.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
; top-most EditorConfig file
root = true

; Unix-style newlines
[*]
end_of_line = LF

[*.php]
indent_style = space
indent_size = 4

[*.test]
indent_style = space
indent_size = 4

[*.rst]
indent_style = space
indent_size = 4


================================================
FILE: .gitattributes
================================================
/bin/ export-ignore
/doc/ export-ignore
/extra/ export-ignore
/tests/ export-ignore
/.editorconfig export-ignore
/.git* export-ignore
/.php-cs-fixer.dist.php export-ignore
/phpunit.xml.dist export-ignore
/phpstan.neon.dist export-ignore
/phpstan-baseline.neon export-ignore
/splitsh.json export-ignore


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"


================================================
FILE: .github/workflows/ci.yml
================================================
name: "CI"

on:
    pull_request:
    push:

env:
    SYMFONY_PHPUNIT_DISABLE_RESULT_CACHE: 1

permissions:
  contents: read

jobs:
    tests:
        name: "PHP ${{ matrix.php-version }}"

        runs-on: 'ubuntu-latest'

        strategy:
            matrix:
                php-version:
                    - '8.1'
                    - '8.2'
                    - '8.3'
                    - '8.4'

        steps:
            - name: "Checkout code"
              uses: actions/checkout@v4

            - name: "Install PHP with extensions"
              uses: shivammathur/setup-php@v2
              with:
                  coverage: "none"
                  php-version: ${{ matrix.php-version }}
                  ini-values: memory_limit=-1

            - name: "Add PHPUnit matcher"
              run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"

            - run: composer install

            - name: "Switch use_yield to true on PHP ${{ matrix.php-version }}"
              if: "matrix.php-version == '8.2'"
              run: |
                  sed -i -e "s/'use_yield' => false/'use_yield' => true/" src/Environment.php

            - name: "Install PHPUnit"
              run: vendor/bin/simple-phpunit install

            - name: "PHPUnit version"
              run: vendor/bin/simple-phpunit --version

            - name: "Run tests"
              run: vendor/bin/simple-phpunit

    extension-tests:
        needs:
            - 'tests'

        name: "${{ matrix.extension }} PHP ${{ matrix.php-version }}"

        runs-on: 'ubuntu-latest'

        continue-on-error: true

        strategy:
            matrix:
                php-version:
                    - '8.1'
                    - '8.2'
                    - '8.3'
                    - '8.4'
                extension:
                    - 'cache-extra'
                    - 'cssinliner-extra'
                    - 'html-extra'
                    - 'inky-extra'
                    - 'intl-extra'
                    - 'markdown-extra'
                    - 'string-extra'
                    - 'twig-extra-bundle'

        steps:
            - name: "Checkout code"
              uses: actions/checkout@v4

            - name: "Install PHP with extensions"
              uses: shivammathur/setup-php@v2
              with:
                  coverage: "none"
                  php-version: ${{ matrix.php-version }}
                  ini-values: memory_limit=-1

            - name: "Add PHPUnit matcher"
              run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"

            - name: "Composer install Twig"
              run: composer install

            - name: "Install PHPUnit"
              run: vendor/bin/simple-phpunit install

            - name: "PHPUnit version"
              run: vendor/bin/simple-phpunit --version

            - name: "Prevent installing symfony/translation-contracts 3.0"
              if: "matrix.extension == 'twig-extra-bundle'"
              working-directory: extra/${{ matrix.extension }}
              run: "composer require --no-update 'symfony/translation-contracts:^1.1|^2.0'"

            - name: "Composer install ${{ matrix.extension }}"
              working-directory: extra/${{ matrix.extension }}
              run: composer install

            - name: "Switch use_yield to true"
              if: "matrix.php-version == '8.2'"
              run: |
                  sed -i -e "s/'use_yield' => false/'use_yield' => true/" extra/${{ matrix.extension }}/vendor/twig/twig/src/Environment.php

            - name: "Run tests for ${{ matrix.extension }}"
              working-directory: extra/${{ matrix.extension }}
              run: ../../vendor/bin/simple-phpunit

    integration-tests:
        needs:
            - 'tests'

        name: "Integration tests with PHP ${{ matrix.php-version }}"

        runs-on: 'ubuntu-latest'

        continue-on-error: true

        strategy:
            matrix:
                php-version:
                    - '8.2'

        steps:
            - name: "Checkout code"
              uses: actions/checkout@v4

            - name: "Install PHP with extensions"
              uses: shivammathur/setup-php@v2
              with:
                  coverage: "none"
                  extensions: "gd, pdo_sqlite, uuid"
                  php-version: ${{ matrix.php-version }}
                  ini-values: memory_limit=-1
                  tools: composer:v2

            - run: bash ./tests/drupal_test.sh
              shell: "bash"

    phpstan:
        name: "PHPStan"

        runs-on: 'ubuntu-latest'

        strategy:
            matrix:
                php-version:
                    - '8.4'

        steps:
            - name: "Checkout code"
              uses: actions/checkout@v4

            - name: "Install PHP with extensions"
              uses: shivammathur/setup-php@v2
              with:
                  coverage: "none"
                  php-version: ${{ matrix.php-version }}
                  ini-values: memory_limit=-1

            - run: composer install

            - name: "Run tests"
              run: vendor/bin/phpstan


================================================
FILE: .github/workflows/documentation.yml
================================================
name: "Documentation"

on:
    pull_request:
    push:

permissions:
  contents: read

jobs:
    build:
        name: "Build"

        runs-on: ubuntu-latest

        steps:
            -   name: "Checkout code"
                uses: actions/checkout@v4

            -   name: "Set-up PHP"
                uses: shivammathur/setup-php@v2
                with:
                    php-version: 8.2
                    coverage: none
                    tools: "composer:v2"

            -   name: Get composer cache directory
                id: composercache
                working-directory: doc/_build
                run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

            -   name: Cache dependencies
                uses: actions/cache@v4
                with:
                    path: ${{ steps.composercache.outputs.dir }}
                    key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
                    restore-keys: ${{ runner.os }}-composer-

            -   name: "Install dependencies"
                working-directory: doc/_build
                run: composer install --prefer-dist --no-progress

            -   name: "Build the docs"
                working-directory: doc/_build
                run: php build.php --disable-cache

    doctor-rst:
        name: "DOCtor-RST"

        runs-on: ubuntu-latest

        steps:
            - name: "Checkout code"
              uses: actions/checkout@v4

            - name: "Run DOCtor-RST"
              uses: docker://oskarstark/doctor-rst
              with:
                  args: --short
              env:
                  DOCS_DIR: 'doc/'


================================================
FILE: .github/workflows/fabbot.yml
================================================
name: CS

on:
  pull_request:

permissions:
  contents: read

jobs:
  call-fabbot:
    name: Fabbot
    uses: symfony-tools/fabbot/.github/workflows/fabbot.yml@main
    with:
      package: Twig


================================================
FILE: .gitignore
================================================
/doc/_build/vendor
/doc/_build/output
/composer.lock
/phpunit.xml
/vendor
.phpunit.result.cache


================================================
FILE: .php-cs-fixer.dist.php
================================================
<?php

use PhpCsFixer\Config;
use PhpCsFixer\Finder;
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;

return (new Config())
    ->setRules([
        '@Symfony' => true,
        '@Symfony:risky' => true,
        '@PHPUnit75Migration:risky' => true,
        'php_unit_dedicate_assert' => ['target' => '5.6'],
        'array_syntax' => ['syntax' => 'short'],
        'php_unit_fqcn_annotation' => true,
        'no_unreachable_default_argument_value' => false,
        'braces' => ['allow_single_line_closure' => true],
        'heredoc_to_nowdoc' => false,
        'single_line_throw' => false,
        'ordered_imports' => true,
        'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
        'no_superfluous_phpdoc_tags' => ['allow_mixed' => true],
    ])
    ->setRiskyAllowed(true)
    ->setParallelConfig(ParallelConfigFactory::detect())
    ->setFinder((new Finder())->in(__DIR__))
;


================================================
FILE: CHANGELOG
================================================
# 3.24.1 (2026-XX-XX)

 * n/a

# 3.24.0 (2026-03-17)

 * Deprecate not implementing the `getOperatorTokens()` method in `ExpressionParserInterface` implementations
 * Deprecate passing a non-`AbstractExpression` node to `Twig\Node\Expression\Binary\MatchesBinary` constructor
 * Deprecate passing a non-`AbstractExpression` node to `Parser::setParent()`
 * Add support for renaming variables in object destructuring (`{name: userName} = user`)
 * Add `html_attr_relaxed` escaping strategy that preserves :, @, [, and ] for front-end framework attribute names
 * Add support for short-circuiting in null-safe operator chains
 * Add the `html_attr` function and `html_attr_merge` as well as `html_attr_type` filters

# 3.23.0 (2026-01-23)

 * Add `=` assignment operator (allows to set variables in expression or to replace the short-form of the set tag)
 * Add sequence, mapping, and object destructuring
 * Add `?.` null-safe operator
 * Add `===` and `!==` operators (equivalent to the `same as` and `not same as` tests)
 * Fix opcache preload warning for unlinked anonymous class
 * Fix spread operator behavior

# 3.22.2 (2025-12-14)

 * Fix "cycle" with non-countable ArrayAccess + Traversable objects
 * Use "getShareDir" as an indicator of Symfony version in Symfony bundle
 * Fix escaper compatibility with PHP 8.5

# 3.22.1 (2025-11-16)

 * Add support for Symfony 8

# 3.22.0 (2025-10-29)

 * Add support for two words test in guard tag
 * Add `Environment::registerUndefinedTestCallback()`
 * Fix compatibility with Symfony 8
 * Fix accessing arrays with stringable objects as key
 * Avoid errors when failing to guess the template info for an error
 * Fix expression parser compatibility layer
 * Fix compiling 'index' with repr (not string) in EmbedNode
 * Update configuration keys + allow extra keys for CommonMark extensions
 * Allow usage of other Markdown converters than CommonMark in LeagueMarkdown

# 3.21.1 (2025-05-03)

 * Fix ExtensionSet usage of BinaryOperatorExpressionParser

# 3.21.0 (2025-05-02)

 * Fix wrong array index
 * Deprecate `Template::loadTemplate()`
 * Fix testing and expression when it evaluates to an instance of `Markup`
 * Add `ReturnPrimitiveTypeInterface` (and sub-interfaces for number, boolean, string, and array)
 * Add `SupportDefinedTestInterface` for expression nodes supporting the `defined` test
 * Deprecate using the `|` operator in an expression with `+` or `-` without using parentheses to clarify precedence
 * Deprecate operator precedence outside of the [0, 512] range
 * Introduce expression parser classes to describe operators and operands provided by extensions
   instead of arrays (it comes with many deprecations that are documented in
   the ``deprecated`` documentation chapter)
 * Deprecate the `Twig\ExpressionParser`, and `Twig\OperatorPrecedenceChange` classes
 * Add attributes `AsTwigFilter`, `AsTwigFunction`, and `AsTwigTest` to ease extension development

# 3.20.0 (2025-02-13)

 * Fix support for ignoring syntax errors in an undefined handler in guard
 * Add configuration for Commonmark
 * Fix wrong array index
 * Bump minimum PHP version to 8.1
 * Add support for registering callbacks for undefined functions, filters or token parsers in the IntegrationTestCase
 * Use correct line number for `ForElseNode`
 * Fix timezone conversion on strings

# 3.19.0 (2025-01-28)

 * Fix a security issue where escaping was missing when using `??`
 * Deprecate `Token::getType()`, use `Token::test()` instead
 * Add `Token::toEnglish()`
 * Add `ForElseNode`
 * Deprecate `Twig\ExpressionParser::parseOnlyArguments()` and
  `Twig\ExpressionParser::parseArguments()` (use
  `Twig\ExpressionParser::parseNamedArguments()` instead)
 * Fix `constant()` behavior when used with `??`
 * Add the `invoke` filter
 * Make `{}` optional for the `types` tag
 * Add `LastModifiedExtensionInterface` and implementation in `AbstractExtension` to track modification of runtime classes
 * Ignore static properties when using the dot operator

# 3.18.0 (2024-12-29)

 * Support for invoking closures
 * Fix unary operator precedence change
 * Ignore `SyntaxError` exceptions from undefined handlers when using the `guard` tag
 * Add a way to stream template rendering (`TemplateWrapper::stream()` and `TemplateWrapper::streamBlock()`)

# 3.17.1 (2024-12-12)

 * Fix the null coalescing operator when the test returns null
 * Fix the Elvis operator when used as '? :' instead of '?:'

# 3.17.0 (2024-12-10)

 * Fix ArrayAccess with objects as keys
 * Support underscores in number literals
 * Deprecate `ConditionalExpression` and `NullCoalesceExpression` (use `ConditionalTernary` and `NullCoalesceBinary` instead)

# 3.16.0 (2024-11-29)

 * Deprecate `InlinePrint`
 * Fix having macro variables starting with an underscore
 * Deprecate not passing a `Source` instance to `TokenStream`
 * Deprecate returning `null` from `TwigFilter::getSafe()` and `TwigFunction::getSafe()`, return `[]` instead

# 3.15.0 (2024-11-17)

 * [BC BREAK] Add support for accessing class constants with the dot operator;
   this can be a BC break if you don't use UPPERCASE constant names
 * Add Spanish inflector support for the `plural` and `singular` filters in the String extension
 * Deprecate `TempNameExpression` in favor of `LocalVariable`
 * Deprecate `NameExpression` in favor of `ContextVariable`
 * Deprecate `AssignNameExpression` in favor of `AssignContextVariable`
 * Remove `MacroAutoImportNodeVisitor`
 * Deprecate `MethodCallExpression` in favor of `MacroReferenceExpression`
 * Fix support for the "is defined" test on `_self.xxx` (auto-imported) macros
 * Fix support for the "is defined" test on inherited macros
 * Add named arguments support for the dot operator arguments (`foo.bar(some: arg)`)
 * Add named arguments support for macros
 * Add a new `guard` tag that allows to test if some Twig callables are available at compilation time
 * Allow arrow functions everywhere
 * Deprecate passing a string or an array to Twig callable arguments accepting arrow functions (pass a `\Closure`)
 * Add support for triggering deprecations for future operator precedence changes
 * Deprecate using the `not` unary operator in an expression with ``*``, ``/``, ``//``, or ``%`` without using explicit parentheses to clarify precedence
 * Deprecate using the `??` binary operator without explicit parentheses
 * Deprecate using the `~` binary operator in an expression with `+` or `-` without using parentheses to clarify precedence
 * Deprecate not passing `AbstractExpression` args to most constructor arguments for classes extending `AbstractExpression`
 * Fix `power` expressions with a negative number in parenthesis (`(-1) ** 2`)
 * Deprecate instantiating `Node` directly. Use `EmptyNode` or `Nodes` instead.
 * Add support for inline comments
 * Add `Profile::getStartTime()` and `Profile::getEndTime()`
 * Fix "ignore missing" when used on an "embed" tag
 * Fix the possibility to override an aliased block (via use)
 * Add template cache hot reload
 * Allow Twig callable argument names to be free-form (snake-case or camelCase) independently of the PHP callable signature
   They were automatically converted to snake-cased before
 * Deprecate the `attribute` function; use the `.` notation and wrap the name with parenthesis instead
 * Add support for argument unpackaging
 * Add JSON support for the file extension escaping strategy
 * Support Markup instances (and any other \Stringable) as dynamic mapping keys
 * Deprecate the `sandbox` tag
 * Improve the way one can deprecate a Twig callable (use `deprecation_info` instead of the other callable options)
 * Add the `enum` function
 * Add support for logical `xor` operator

# 3.14.2 (2024-11-07)

 * Fix an infinite recursion in the sandbox code

# 3.14.1 (2024-11-06)

 * [BC BREAK] Fix a security issue in the sandbox mode allowing an attacker to call attributes on Array-like objects
   They are now checked via the property policy
 * Fix a security issue in the sandbox mode allowing an attacker to be able to call `toString()`
   under some circumstances on an object even if the `__toString()` method is not allowed by the security policy

# 3.14.0 (2024-09-09)

 * Fix a security issue when an included sandboxed template has been loaded before without the sandbox context
 * Add the possibility to reset globals via `Environment::resetGlobals()`
 * Deprecate `Environment::mergeGlobals()`

# 3.13.0 (2024-09-07)

 * Add the `types` tag (experimental)
 * Deprecate the `Twig\Test\NodeTestCase::getTests()` data provider, override `provideTests()` instead.
 * Mark `Twig\Test\NodeTestCase::getEnvironment()` as final, override `createEnvironment()` instead.
 * Deprecate `Twig\Test\NodeTestCase::getVariableGetter()`, call `createVariableGetter()` instead.
 * Deprecate `Twig\Test\NodeTestCase::getAttributeGetter()`, call `createAttributeGetter()` instead.
 * Deprecate not overriding `Twig\Test\IntegrationTestCase::getFixturesDirectory()`, this method will be abstract in 4.0
 * Marked `Twig\Test\IntegrationTestCase::getTests()` and `getLegacyTests()` as final

# 3.12.0 (2024-08-29)

 * Deprecate the fact that the `extends` and `use` tags are always allowed in a sandboxed template.
   This behavior will change in 4.0 where these tags will need to be explicitly allowed like any other tag.
 * Deprecate the "tag" constructor argument of the "Twig\Node\Node" class as the tag is now automatically set by the Parser when needed
 * Fix precedence of two-word tests when the first word is a valid test
 * Deprecate the `spaceless` filter
 * Deprecate some internal methods from `Parser`: `getBlockStack()`, `hasBlock()`, `getBlock()`, `hasMacro()`, `hasTraits()`, `getParent()`
 * Deprecate passing `null` to `Twig\Parser::setParent()`
 * Update `Node::__toString()` to include the node tag if set
 * Add support for integers in methods of `Twig\Node\Node` that take a Node name
 * Deprecate not passing a `BodyNode` instance as the body of a `ModuleNode` or `MacroNode` constructor
 * Deprecate returning "null" from "TokenParserInterface::parse()".
 * Deprecate `OptimizerNodeVisitor::OPTIMIZE_TEXT_NODES`
 * Fix performance regression when `use_yield` is `false` (which is the default)
 * Improve compatibility when `use_yield` is `false` (as extensions still using `echo` will work as is)
 * Accept colons (`:`) in addition to equals (`=`) to separate argument names and values in named arguments
 * Add the `html_cva` function (in the HTML extra package)
 * Add support for named arguments to the `block` and `attribute` functions
 * Throw a SyntaxError exception at compile time when a Twig callable has not the minimum number of required arguments
 * Add a `CallableArgumentsExtractor` class
 * Deprecate passing a name to `FunctionExpression`, `FilterExpression`, and `TestExpression`;
   pass a `TwigFunction`, `TwigFilter`, or `TestFilter` instead
 * Deprecate all Twig callable attributes on `FunctionExpression`, `FilterExpression`, and `TestExpression`
 * Deprecate the `filter` node of `FilterExpression`
 * Add the notion of Twig callables (functions, filters, and tests)
 * Bump minimum PHP version to 8.0
 * Fix integration tests when a test has more than one data/expect section and deprecations
 * Add the `enum_cases` function

# 3.11.2 (2024-11-06)

 * [BC BREAK] Fix a security issue in the sandbox mode allowing an attacker to call attributes on Array-like objects
   They are now checked via the property policy
 * Fix a security issue in the sandbox mode allowing an attacker to be able to call `toString()`
   under some circumstances on an object even if the `__toString()` method is not allowed by the security policy

# 3.11.1 (2024-09-10)

 * Fix a security issue when an included sandboxed template has been loaded before without the sandbox context

# 3.11.0 (2024-08-08)

 * Deprecate `OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER`
 * Add `Twig\Cache\ChainCache` and `Twig\Cache\ReadOnlyFilesystemCache`
 * Add the possibility to deprecate attributes and nodes on `Node`
 * Add the possibility to add a package and a version to the `deprecated` tag
 * Add the possibility to add a package for filter/function/test deprecations
 * Mark `ConstantExpression` as being `@final`
 * Add the `find` filter
 * Fix optimizer mode validation in `OptimizerNodeVisitor`
 * Add the possibility to yield from a generator in `PrintNode`
 * Add the `shuffle` filter
 * Add the `singular` and `plural` filters in `StringExtension`
 * Deprecate the second argument of `Twig\Node\Expression\CallExpression::compileArguments()`
 * Deprecate `Twig\ExpressionParser\parseHashExpression()` in favor of
   `Twig\ExpressionParser::parseMappingExpression()`
 * Deprecate `Twig\ExpressionParser\parseArrayExpression()` in favor of
   `Twig\ExpressionParser::parseSequenceExpression()`
 * Add `sequence` and `mapping` tests
 * Deprecate `Twig\Node\Expression\NameExpression::isSimple()` and
    `Twig\Node\Expression\NameExpression::isSpecial()`

# 3.10.3 (2024-05-16)

 * Fix missing ; in generated code

# 3.10.2 (2024-05-14)

 * Fix support for the deprecated escaper signature

# 3.10.1 (2024-05-12)

 * Fix BC break on escaper extension
 * Fix constant return type

# 3.10.0 (2024-05-11)

 * Make `CoreExtension::formatDate`, `CoreExtension::convertDate`, and
   `CoreExtension::formatNumber` part of the public API
 * Add `needs_charset` option for filters and functions
 * Extract the escaping logic from the `EscaperExtension` class to a new
   `EscaperRuntime` class.

   The following methods from ``Twig\\Extension\\EscaperExtension`` are
   deprecated: ``setEscaper()``, ``getEscapers()``, ``setSafeClasses``,
   ``addSafeClasses()``. Use the same methods on the
   ``Twig\\Runtime\\EscaperRuntime`` class instead.
  * Fix capturing output from extensions that still use echo
  * Fix a PHP warning in the Lexer on malformed templates
  * Fix blocks not available under some circumstances
  * Synchronize source context in templates when setting a Node on a Node

# 3.9.3 (2024-04-18)

 * Add missing `twig_escape_filter_is_safe` deprecated function
 * Fix yield usage with CaptureNode
 * Add missing unwrap call when using a TemplateWrapper instance internally
 * Ensure Lexer is initialized early on

# 3.9.2 (2024-04-17)

 * Fix usage of display_end hook

# 3.9.1 (2024-04-17)

 * Fix missing `$blocks` variable in `CaptureNode`

# 3.9.0 (2024-04-16)

 * Add support for PHP 8.4
 * Deprecate AbstractNodeVisitor
 * Deprecate passing Template to Environment::resolveTemplate(), Environment::load(), and Template::loadTemplate()
 * Add a new "yield" mode for output generation;
   Node implementations that use "echo" or "print" should use "yield" instead;
   all Node implementations should be flagged with `#[YieldReady]` once they've been made ready for "yield";
   the "use_yield" Environment option can be turned on when all nodes have been made `#[YieldReady]`;
   "yield" will be the only strategy supported in the next major version
 * Add return type for Symfony 7 compatibility
 * Fix premature loop exit in Security Policy lookup of allowed methods/properties
 * Deprecate all internal extension functions in favor of methods on the extension classes
 * Mark all extension functions as @internal
 * Add SourcePolicyInterface to selectively enable the Sandbox based on a template's Source
 * Throw a proper Twig exception when using cycle on an empty array

# 3.8.0 (2023-11-21)

 * Catch errors thrown during template rendering
 * Fix IntlExtension::formatDateTime use of date formatter prototype
 * Fix premature loop exit in Security Policy lookup of allowed methods/properties
 * Remove NumberFormatter::TYPE_CURRENCY (deprecated in PHP 8.3)
 * Restore return type annotations
 * Allow Symfony 7 packages to be installed
 * Deprecate `twig_test_iterable` function. Use the native `is_iterable` instead.

# 3.7.1 (2023-08-28)

 * Fix some phpdocs

# 3.7.0 (2023-07-26)

 * Add support for the ...spread operator on arrays and hashes

# 3.6.1 (2023-06-08)

 * Suppress some native return type deprecation messages

# 3.6.0 (2023-05-03)

 * Allow psr/container 2.0
 * Add the new PHP 8.0 IntlDateFormatter::RELATIVE_* constants for date formatting
 * Make the Lexer initialize itself lazily

# 3.5.1 (2023-02-08)

 * Arrow functions passed to the "reduce" filter now accept the current key as a third argument
 * Restores the leniency of the matches twig comparison
 * Fix error messages in sandboxed mode for "has some" and "has every"

# 3.5.0 (2022-12-27)

 * Make Twig\ExpressionParser non-internal
 * Add "has some" and "has every" operators
 * Add Compile::reset()
 * Throw a better runtime error when the "matches" regexp is not valid
 * Add "twig *_names" intl functions
 * Fix optimizing closures callbacks
 * Add a better exception when getting an undefined constant via `constant`
 * Fix `if` nodes when outside of a block and with an empty body

# 3.4.3 (2022-09-28)

 * Fix a security issue on filesystem loader (possibility to load a template outside a configured directory)

# 3.4.2 (2022-08-12)

 * Allow inherited magic method to still run with calling class
 * Fix CallExpression::reflectCallable() throwing TypeError
 * Fix typo in naming (currency_code)

# 3.4.1 (2022-05-17)

* Fix optimizing non-public named closures

# 3.4.0 (2022-05-22)

 * Add support for named closures

# 3.3.10 (2022-04-06)

 * Enable bytecode invalidation when auto_reload is enabled

# 3.3.9 (2022-03-25)

 * Fix custom escapers when using multiple Twig environments
 * Add support for "constant('class', object)"
 * Do not reuse internally generated variable names during parsing

# 3.3.8 (2022-02-04)

 * Fix a security issue when in a sandbox: the `sort` filter must require a Closure for the `arrow` parameter
 * Fix deprecation notice on `round`
 * Fix call to deprecated `convertToHtml` method

# 3.3.7 (2022-01-03)

* Allow more null support when Twig expects a string (for better 8.1 support)
* Only use Commonmark extensions if markdown enabled

# 3.3.6 (2022-01-03)

* Only use Commonmark extensions if markdown enabled

# 3.3.5 (2022-01-03)

* Allow CommonMark extensions to easily be added
* Allow null when Twig expects a string (for better 8.1 support)
* Make some performance optimizations
* Allow Symfony translation contract v3+

# 3.3.4 (2021-11-25)

 * Bump minimum supported Symfony component versions
 * Fix a deprecated message

# 3.3.3 (2021-09-17)

 * Allow Symfony 6
 * Improve compatibility with PHP 8.1
 * Explicitly specify the encoding for mb_ord in JS escaper

# 3.3.2 (2021-05-16)

 * Revert "Throw a proper exception when a template name is an absolute path (as it has never been supported)"

# 3.3.1 (2021-05-12)

 * Fix PHP 8.1 compatibility
 * Throw a proper exception when a template name is an absolute path (as it has never been supported)

# 3.3.0 (2021-02-08)

 * Fix macro calls in a "cache" tag
 * Add the slug filter
 * Allow extra bundle to be compatible with Twig 2

# 3.2.1 (2021-01-05)

 * Fix extra bundle compat with older versions of Symfony

# 3.2.0 (2021-01-05)

 * Add the Cache extension in the "extra" repositories: "cache" tag
 * Add "registerUndefinedTokenParserCallback"
 * Mark built-in node visitors as @internal
 * Fix "odd" not working for negative numbers

# 3.1.1 (2020-10-27)

 * Fix "include(template_from_string())"

# 3.1.0 (2020-10-21)

 * Fix sandbox support when using "include(template_from_string())"
 * Make round brackets optional for one argument tests like "same as" or "divisible by"
 * Add support for ES2015 style object initialisation shortcut { a } is the same as { 'a': a }

# 3.0.5 (2020-08-05)

 * Fix twig_compare w.r.t. whitespace trimming
 * Fix sandbox not disabled if syntax error occurs within {% sandbox %} tag
 * Fix a regression when not using a space before an operator
 * Restrict callables to closures in filters
 * Allow trailing commas in argument lists (in calls as well as definitions)

# 3.0.4 (2020-07-05)

 * Fix comparison operators
 * Fix options not taken into account when using "Michelf\MarkdownExtra"
 * Fix "Twig\Extra\Intl\IntlExtension::getCountryName()" to accept "null" as a first argument
 * Throw exception in case non-Traversable data is passed to "filter"
 * Fix context optimization on PHP 7.4
 * Fix PHP 8 compatibility
 * Fix ambiguous syntax parsing

# 3.0.3 (2020-02-11)

 * Add a check to ensure that iconv() is defined

# 3.0.2 (2020-02-11)

 * Avoid exceptions when an intl resource is not found
 * Fix implementation of case-insensitivity for method names

# 3.0.1 (2019-12-28)

 * fixed Symfony 5.0 support for the HTML extra extension

# 3.0.0 (2019-11-15)

 * fixed number formatter in Intl extra extension when using a formatter prototype

# 3.0.0-BETA1 (2019-11-11)

 * removed the "if" condition support on the "for" tag
 * made the in, <, >, <=, >=, ==, and != operators more strict when comparing strings and integers/floats
 * removed the "filter" tag
 * added type hints everywhere
 * changed Environment::resolveTemplate() to always return a TemplateWrapper instance
 * removed Template::__toString()
 * removed Parser::isReservedMacroName()
 * removed SanboxedPrintNode
 * removed Node::setTemplateName()
 * made classes marked as "@final" final
 * removed InitRuntimeInterface, ExistsLoaderInterface, and SourceContextLoaderInterface
 * removed the "spaceless" tag
 * removed Twig\Environment::getBaseTemplateClass() and Twig\Environment::setBaseTemplateClass()
 * removed the "base_template_class" option on Twig\Environment
 * bumped minimum PHP version to 7.2
 * removed PSR-0 classes


================================================
FILE: LICENSE
================================================
Copyright (c) 2009-present by the Twig Team.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
    * Neither the name of Twig nor the names of its contributors
      may be used to endorse or promote products derived from this software
      without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: README.rst
================================================
Twig, the flexible, fast, and secure template language for PHP
==============================================================

Twig is a template language for PHP.

Twig uses a syntax similar to the Django and Jinja template languages which
inspired the Twig runtime environment.

Sponsors
--------

.. raw:: html

    <a href="https://docs.blackfire.io/introduction?utm_source=twig&utm_medium=github_readme&utm_campaign=logo">
        <img src="https://static.blackfire.io/assets/intemporals/logo/png/blackfire-io_secondary_horizontal_transparent.png?1" width="255px" alt="Blackfire.io">
    </a>

More Information
----------------

Read the `documentation`_ for more information.

.. _documentation: https://twig.symfony.com/documentation


================================================
FILE: bin/generate_operators_precedence.php
================================================
<?php

/*
 * This file is part of Twig.
 *
 * (c) Fabien Potencier
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Twig\Environment;
use Twig\ExpressionParser\ExpressionParserDescriptionInterface;
use Twig\ExpressionParser\ExpressionParserType;
use Twig\ExpressionParser\InfixAssociativity;
use Twig\ExpressionParser\InfixExpressionParserInterface;
use Twig\Loader\ArrayLoader;

require_once dirname(__DIR__).'/vendor/autoload.php';

$output = fopen(dirname(__DIR__).'/doc/operators_precedence.rst', 'w');

$twig = new Environment(new ArrayLoader([]));
$descriptionLength = 11;
$expressionParsers = [];
$seen = new SplObjectStorage();
foreach ($twig->getExpressionParsers() as $expressionParser) {
    if (!$seen->offsetExists($expressionParser)) {
        $expressionParsers[] = $expressionParser;
        $seen->offsetSet($expressionParser, true);
        $descriptionLength = max($descriptionLength, $expressionParser instanceof ExpressionParserDescriptionInterface ? strlen($expressionParser->getDescription()) : '');
    }
}

fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n");
fwrite($output, '| Precedence | Operator         | Type    | Associativity | Description'.str_repeat(' ', $descriptionLength - 11)." |\n");
fwrite($output, '+============+==================+=========+===============+'.str_repeat('=', $descriptionLength + 2).'+');

usort($expressionParsers, static fn ($a, $b) => $b->getPrecedence() <=> $a->getPrecedence());

$previous = null;
foreach ($expressionParsers as $expressionParser) {
    if (null !== $previous) {
        fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2).'+');
    }
    $precedence = $expressionParser->getPrecedence();
    $previousPrecedence = $previous ? $previous->getPrecedence() : \PHP_INT_MAX;
    $associativity = $expressionParser instanceof InfixExpressionParserInterface ? (InfixAssociativity::Left === $expressionParser->getAssociativity() ? 'Left' : 'Right') : 'n/a';
    $previousAssociativity = $previous ? ($previous instanceof InfixExpressionParserInterface ? (InfixAssociativity::Left === $previous->getAssociativity() ? 'Left' : 'Right') : 'n/a') : 'n/a';
    if ($previousPrecedence !== $precedence) {
        $previous = null;
    }
    $operatorName = '``'.$expressionParser->getName().'``';
    if ($expressionParser->getAliases()) {
        $operatorName .= ', ``'.implode('``, ``', $expressionParser->getAliases()).'``';
    }
    fwrite($output, rtrim(sprintf("\n| %-10s | %-16s | %-7s | %-13s | %-{$descriptionLength}s |\n",
        (!$previous || $previousPrecedence !== $precedence ? $precedence : '').($expressionParser->getPrecedenceChange() ? ' => '.$expressionParser->getPrecedenceChange()->getNewPrecedence() : ''),
        $operatorName,
        !$previous || ExpressionParserType::getType($previous) !== ExpressionParserType::getType($expressionParser) ? ExpressionParserType::getType($expressionParser)->value : '',
        !$previous || $previousAssociativity !== $associativity ? $associativity : '',
        $expressionParser instanceof ExpressionParserDescriptionInterface ? $expressionParser->getDescription() : '',
    )));
    $previous = $expressionParser;
}
fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n");
fwrite($output, "\nWhen a precedence will change in 4.0, the new precedence is indicated by the arrow ``=>``.\n");

fwrite($output, "\nHere is the same table for Twig 4.0 with adjusted precedences:\n");

fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n");
fwrite($output, '| Precedence | Operator         | Type    | Associativity | Description'.str_repeat(' ', $descriptionLength - 11)." |\n");
fwrite($output, '+============+==================+=========+===============+'.str_repeat('=', $descriptionLength + 2).'+');

usort($expressionParsers, static function ($a, $b) {
    $aPrecedence = $a->getPrecedenceChange() ? $a->getPrecedenceChange()->getNewPrecedence() : $a->getPrecedence();
    $bPrecedence = $b->getPrecedenceChange() ? $b->getPrecedenceChange()->getNewPrecedence() : $b->getPrecedence();

    return $bPrecedence - $aPrecedence;
});

$previous = null;
foreach ($expressionParsers as $expressionParser) {
    if (null !== $previous) {
        fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2).'+');
    }
    $precedence = $expressionParser->getPrecedenceChange() ? $expressionParser->getPrecedenceChange()->getNewPrecedence() : $expressionParser->getPrecedence();
    $previousPrecedence = $previous ? ($previous->getPrecedenceChange() ? $previous->getPrecedenceChange()->getNewPrecedence() : $previous->getPrecedence()) : \PHP_INT_MAX;
    $associativity = $expressionParser instanceof InfixExpressionParserInterface ? (InfixAssociativity::Left === $expressionParser->getAssociativity() ? 'Left' : 'Right') : 'n/a';
    $previousAssociativity = $previous ? ($previous instanceof InfixExpressionParserInterface ? (InfixAssociativity::Left === $previous->getAssociativity() ? 'Left' : 'Right') : 'n/a') : 'n/a';
    if ($previousPrecedence !== $precedence) {
        $previous = null;
    }
    $operatorName = '``'.$expressionParser->getName().'``';
    if ($expressionParser->getAliases()) {
        $operatorName .= ', ``'.implode('``, ``', $expressionParser->getAliases()).'``';
    }
    fwrite($output, rtrim(sprintf("\n| %-10s | %-16s | %-7s | %-13s | %-{$descriptionLength}s |\n",
        !$previous || $previousPrecedence !== $precedence ? $precedence : '',
        $operatorName,
        !$previous || ExpressionParserType::getType($previous) !== ExpressionParserType::getType($expressionParser) ? ExpressionParserType::getType($expressionParser)->value : '',
        !$previous || $previousAssociativity !== $associativity ? $associativity : '',
        $expressionParser instanceof ExpressionParserDescriptionInterface ? $expressionParser->getDescription() : '',
    )));
    $previous = $expressionParser;
}
fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n");

fclose($output);


================================================
FILE: composer.json
================================================
{
    "name": "twig/twig",
    "type": "library",
    "description": "Twig, the flexible, fast, and secure template language for PHP",
    "keywords": ["templating"],
    "homepage": "https://twig.symfony.com",
    "license": "BSD-3-Clause",
    "minimum-stability": "dev",
    "authors": [
        {
            "name": "Fabien Potencier",
            "email": "fabien@symfony.com",
            "homepage": "http://fabien.potencier.org",
            "role": "Lead Developer"
        },
        {
            "name": "Twig Team",
            "role": "Contributors"
        },
        {
            "name": "Armin Ronacher",
            "email": "armin.ronacher@active-4.com",
            "role": "Project Founder"
        }
    ],
    "require": {
        "php": ">=8.1.0",
        "symfony/deprecation-contracts": "^2.5|^3",
        "symfony/polyfill-mbstring": "^1.3",
        "symfony/polyfill-ctype": "^1.8"
    },
    "require-dev": {
        "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0",
        "psr/container": "^1.0|^2.0",
        "phpstan/phpstan": "^2.0@stable",
        "php-cs-fixer/shim": "^3.0@stable"
    },
    "autoload": {
        "files": [
            "src/Resources/core.php",
            "src/Resources/debug.php",
            "src/Resources/escaper.php",
            "src/Resources/string_loader.php"
        ],
        "psr-4" : {
            "Twig\\" : "src/"
        }
    },
    "autoload-dev": {
        "psr-4" : {
            "Twig\\Tests\\" : "tests/"
        }
    }
}


================================================
FILE: doc/.doctor-rst.yaml
================================================
rules:
    american_english: ~
    avoid_repetetive_words: ~
    blank_line_after_directive: ~
    blank_line_before_directive: ~
    composer_dev_option_not_at_the_end: ~
    correct_code_block_directive_based_on_the_content: ~
    deprecated_directive_should_have_version: ~
    ensure_order_of_code_blocks_in_configuration_block: ~
    extension_xlf_instead_of_xliff: ~
    indention: ~
    lowercase_as_in_use_statements: ~
    max_blank_lines:
        max: 2
    no_blank_line_after_filepath_in_php_code_block: ~
    no_blank_line_after_filepath_in_twig_code_block: ~
    no_blank_line_after_filepath_in_xml_code_block: ~
    no_blank_line_after_filepath_in_yaml_code_block: ~
    no_composer_req: ~
    no_explicit_use_of_code_block_php: ~
    no_inheritdoc: ~
    no_namespace_after_use_statements: ~
    no_php_open_tag_in_code_block_php_directive: ~
    no_space_before_self_xml_closing_tag: ~
    ordered_use_statements: ~
    php_prefix_before_bin_console: ~
    replace_code_block_types: ~
    replacement: ~
    short_array_syntax: ~
    typo: ~
    unused_links: ~
    use_deprecated_directive_instead_of_versionadded: ~
    use_https_xsd_urls: ~
    valid_inline_highlighted_namespaces: ~
    valid_use_statements: ~
    versionadded_directive_should_have_version: ~
    yaml_instead_of_yml_suffix: ~
    yarn_dev_option_at_the_end: ~

    versionadded_directive_major_version:
        major_version: 3

    versionadded_directive_min_version:
        min_version: '3.0'

    deprecated_directive_major_version:
        major_version: 3

    deprecated_directive_min_version:
        min_version: '3.0'

whitelist:
    lines:
        - 'I like Twig.<br />'


================================================
FILE: doc/_build/build.php
================================================
#!/usr/bin/env php
<?php

/*
 * This file is part of Twig.
 *
 * (c) Fabien Potencier
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

require __DIR__.'/vendor/autoload.php';

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use SymfonyDocsBuilder\BuildConfig;
use SymfonyDocsBuilder\DocBuilder;

(new Application('Twig docs Builder', '1.0'))
    ->register('build-docs')
    ->addOption('disable-cache', null, InputOption::VALUE_NONE, 'Use this option to force a full regeneration of all doc contents')
    ->setCode(static function (InputInterface $input, OutputInterface $output) {
        $io = new SymfonyStyle($input, $output);
        $io->text('Building all Twig docs...');

        $outputDir = __DIR__.'/output';
        $buildConfig = (new BuildConfig())
            ->setContentDir(__DIR__.'/..')
            ->setOutputDir($outputDir)
            ->setImagesDir(__DIR__.'/output/_images')
            ->setImagesPublicPrefix('_images')
            ->setTheme('rtd')
        ;

        $buildConfig->setExcludedPaths(['vendor/']);
        $buildConfig->disableJsonFileGeneration();
        $buildConfig->disableBuildCache();

        $result = (new DocBuilder())->build($buildConfig);

        if ($result->isSuccessful()) {
            // fix assets URLs to make them absolute (otherwise, they don't work in subdirectories)
            foreach (glob($outputDir.'/**/*.html') as $htmlFilePath) {
                $htmlContents = file_get_contents($htmlFilePath);
                file_put_contents($htmlFilePath, str_replace('href="assets/', 'href="/assets/', $htmlContents));
            }

            $io->success(sprintf('The Twig docs were successfully built at %s', realpath($outputDir)));
        } else {
            $io->error(sprintf("There were some errors while building the docs:\n\n%s\n", $result->getErrorTrace()));
            $io->newLine();
            $io->comment('Tip: you can add the -v, -vv or -vvv flags to this command to get debug information.');

            return 1;
        }

        return 0;
    })
    ->getApplication()
    ->setDefaultCommand('build-docs', true)
    ->run();


================================================
FILE: doc/_build/composer.json
================================================
{
    "minimum-stability": "dev",
    "prefer-stable": true,
    "config": {
        "platform": {
            "php": "8.1.0"
        },
        "preferred-install": {
            "*": "dist"
        },
        "sort-packages": true
    },
    "require": {
        "php": ">=8.1",
        "symfony/console": "^5.4",
        "symfony/process": "^5.4",
        "symfony-tools/docs-builder": "^0.18"
    }
}


================================================
FILE: doc/advanced.rst
================================================
Extending Twig
==============

Twig can be extended in many ways; you can add extra tags, filters, tests,
operators, global variables, and functions. You can even extend the parser
itself with node visitors.

.. note::

    The first section of this chapter describes how to extend Twig. If you want
    to reuse your changes in different projects or if you want to share them
    with others, you should then create an extension as described in the
    following section.

.. caution::

    When extending Twig without creating an extension, Twig won't be able to
    recompile your templates when the PHP code is updated. To see your changes
    in real-time, either disable template caching or package your code into an
    extension (see the next section of this chapter).

Before extending Twig, you must understand the differences between all the
different possible extension points and when to use them.

First, remember that Twig has two main language constructs:

* ``{{ }}``: used to print the result of an expression evaluation;

* ``{% %}``: used to execute statements.

To understand why Twig exposes so many extension points, let's see how to
implement a *Lorem ipsum* generator (it needs to know the number of words to
generate).

You can use a ``lipsum`` *tag*:

.. code-block:: twig

    {% lipsum 40 %}

That works, but using a tag for ``lipsum`` is not a good idea for at least
three main reasons:

* ``lipsum`` is not a language construct;
* The tag outputs something;
* The tag is not flexible as you cannot use it in an expression:

  .. code-block:: twig

      {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }}

In fact, you rarely need to create tags; and that's good news because tags are
the most complex extension point.

Now, let's use a ``lipsum`` *filter*:

.. code-block:: twig

    {{ 40|lipsum }}

Again, it works. But a filter should transform the passed value to something
else. Here, we use the value to indicate the number of words to generate (so,
``40`` is an argument of the filter, not the value we want to transform).

Next, let's use a ``lipsum`` *function*:

.. code-block:: twig

    {{ lipsum(40) }}

Here we go. For this specific example, the creation of a function is the
extension point to use. And you can use it anywhere an expression is accepted:

.. code-block:: twig

    {{ 'some text' ~ lipsum(40) ~ 'some more text' }}

    {% set lipsum = lipsum(40) %}

Lastly, you can also use a *global* object with a method able to generate lorem
ipsum text:

.. code-block:: twig

    {{ text.lipsum(40) }}

As a rule of thumb, use functions for frequently used features and global
objects for everything else.

Keep in mind the following when you want to extend Twig:

========== ========================== ========== =========================
What?      Implementation difficulty? How often? When?
========== ========================== ========== =========================
*macro*    simple                     frequent   Content generation
*global*   simple                     frequent   Helper object
*function* simple                     frequent   Content generation
*filter*   simple                     frequent   Value transformation
*tag*      complex                    rare       DSL language construct
*test*     simple                     rare       Boolean decision
*operator* simple                     rare       Values transformation
========== ========================== ========== =========================

Globals
-------

Global variables are available in all templates and macros. Use ``addGlobal()``
to add a global variable to a Twig environment::

    $twig = new \Twig\Environment($loader);
    $twig->addGlobal('text', new Text());

You can then use the ``text`` variable anywhere in a template:

.. code-block:: twig

    {{ text.lipsum(40) }}

Filters
-------

Creating a filter consists of associating a name with a PHP callable::

    // an anonymous function
    $filter = new \Twig\TwigFilter('rot13', function ($string) {
        return str_rot13($string);
    });

    // or a simple PHP function
    $filter = new \Twig\TwigFilter('rot13', 'str_rot13');

    // or a class static method
    $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);
    $filter = new \Twig\TwigFilter('rot13', 'SomeClass::rot13Filter');

    // or a class method
    $filter = new \Twig\TwigFilter('rot13', [$this, 'rot13Filter']);
    // the one below needs a runtime implementation (see below for more information)
    $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);

The first argument passed to the ``\Twig\TwigFilter`` constructor is the name of the
filter you will use in templates and the second one is the PHP callable to
associate with it.

Then, add the filter to the Twig environment::

    $twig = new \Twig\Environment($loader);
    $twig->addFilter($filter);

And here is how to use it in a template:

.. code-block:: twig

    {{ 'Twig'|rot13 }}

    {# will output Gjvt #}

When called by Twig, the PHP callable receives the left side of the filter
(before the pipe ``|``) as the first argument and the extra arguments passed
to the filter (within parentheses ``()``) as extra arguments.

For instance, the following code:

.. code-block:: twig

    {{ 'TWIG'|lower }}
    {{ now|date('d/m/Y') }}

is compiled to something like the following::

    <?php echo strtolower('TWIG') ?>
    <?php echo twig_date_format_filter($now, 'd/m/Y') ?>

The ``\Twig\TwigFilter`` class takes an array of options as its last argument::

    $filter = new \Twig\TwigFilter('rot13', 'str_rot13', $options);

Charset-aware Filters
~~~~~~~~~~~~~~~~~~~~~

If you want to access the default charset in your filter, set the
``needs_charset`` option to ``true``; Twig will pass the default charset as the
first argument to the filter call::

    $filter = new \Twig\TwigFilter('rot13', function (string $charset, $string) {
        return str_rot13($string);
    }, ['needs_charset' => true]);

Environment-aware Filters
~~~~~~~~~~~~~~~~~~~~~~~~~

If you want to access the current environment instance in your filter, set the
``needs_environment`` option to ``true``; Twig will pass the current
environment as the first argument to the filter call::

    $filter = new \Twig\TwigFilter('rot13', function (\Twig\Environment $env, $string) {
        // get the current charset for instance
        $charset = $env->getCharset();

        return str_rot13($string);
    }, ['needs_environment' => true]);

Context-aware Filters
~~~~~~~~~~~~~~~~~~~~~

If you want to access the current context in your filter, set the
``needs_context`` option to ``true``; Twig will pass the current context as
the first argument to the filter call (or the second one if
``needs_environment`` is also set to ``true``)::

    $filter = new \Twig\TwigFilter('rot13', function ($context, $string) {
        // ...
    }, ['needs_context' => true]);

    $filter = new \Twig\TwigFilter('rot13', function (\Twig\Environment $env, $context, $string) {
        // ...
    }, ['needs_context' => true, 'needs_environment' => true]);

Automatic Escaping
~~~~~~~~~~~~~~~~~~

If automatic escaping is enabled, the output of the filter may be escaped
before printing. If your filter acts as an escaper (or explicitly outputs HTML
or JavaScript code), you will want the raw output to be printed. In such a
case, set the ``is_safe`` option::

    $filter = new \Twig\TwigFilter('nl2br', 'nl2br', ['is_safe' => ['html']]);

Some filters may need to work on input that is already escaped or safe, for
example when adding (safe) HTML tags to originally unsafe output. In such a
case, set the ``pre_escape`` option to escape the input data before it is run
through your filter::

    $filter = new \Twig\TwigFilter('somefilter', 'somefilter', ['pre_escape' => 'html', 'is_safe' => ['html']]);

Variadic Filters
~~~~~~~~~~~~~~~~

When a filter should accept an arbitrary number of arguments, set the
``is_variadic`` option to ``true``; Twig will pass the extra arguments as the
last argument to the filter call as an array::

    $filter = new \Twig\TwigFilter('thumbnail', function ($file, array $options = []) {
        // ...
    }, ['is_variadic' => true]);

Be warned that :ref:`named arguments <named-arguments>` passed to a variadic
filter cannot be checked for validity as they will automatically end up in the
option array.

Dynamic Filters
~~~~~~~~~~~~~~~

A filter name containing the special ``*`` character is a dynamic filter and
the ``*`` part will match any string::

    $filter = new \Twig\TwigFilter('*_path', function ($name, $arguments) {
        // ...
    });

The following filters are matched by the above defined dynamic filter:

* ``product_path``
* ``category_path``

A dynamic filter can define more than one dynamic parts::

    $filter = new \Twig\TwigFilter('*_path_*', function ($name, $suffix, $arguments) {
        // ...
    });

The filter receives all dynamic part values before the normal filter arguments,
but after the environment and the context. For instance, a call to
``'Paris'|a_path_b()`` will result in the following arguments to be passed to the
filter: ``('a', 'b', 'Paris')``.

Deprecated Filters
~~~~~~~~~~~~~~~~~~

.. versionadded:: 3.15

    The ``deprecation_info`` option was added in Twig 3.15.

You can mark a filter as being deprecated by setting the ``deprecation_info``
option::

    $filter = new \Twig\TwigFilter('obsolete', function () {
        // ...
    }, ['deprecation_info' => new DeprecatedCallableInfo('twig/twig', '3.11', 'new_one')]);

The ``DeprecatedCallableInfo`` constructor takes the following parameters:

* The Composer package name that defines the filter;
* The version when the filter was deprecated.

Optionally, you can also provide the following parameters about an alternative:

* The package name that contains the alternative filter;
* The alternative filter name that replaces the deprecated one;
* The package version that added the alternative filter.

When a filter is deprecated, Twig emits a deprecation notice when compiling a
template using it. See :ref:`deprecation-notices` for more information.

.. note::

    Before Twig 3.15, you can mark a filter as being deprecated by setting the
    ``deprecated`` option to ``true``. You can also give an alternative filter
    that replaces the deprecated one when that makes sense::

        $filter = new \Twig\TwigFilter('obsolete', function () {
            // ...
        }, ['deprecated' => true, 'alternative' => 'new_one']);

    .. versionadded:: 3.11

        The ``deprecating_package`` option was added in Twig 3.11.

    You can also set the ``deprecating_package`` option to specify the package
    that is deprecating the filter, and ``deprecated`` can be set to the
    package version when the filter was deprecated::

        $filter = new \Twig\TwigFilter('obsolete', function () {
            // ...
        }, ['deprecated' => '1.1', 'deprecating_package' => 'twig/some-package']);

Functions
---------

Functions are defined in the exact same way as filters, but you need to create
an instance of ``\Twig\TwigFunction``::

    $twig = new \Twig\Environment($loader);
    $function = new \Twig\TwigFunction('function_name', function () {
        // ...
    });
    $twig->addFunction($function);

Functions support the same features as filters, except for the ``pre_escape``
and ``preserves_safety`` options.

Tests
-----

Tests are defined in the exact same way as filters and functions, but you need
to create an instance of ``\Twig\TwigTest``::

    $twig = new \Twig\Environment($loader);
    $test = new \Twig\TwigTest('test_name', function () {
        // ...
    });
    $twig->addTest($test);

Tests allow you to create custom application specific logic for evaluating
boolean conditions. As a simple example, let's create a Twig test that checks if
objects are 'red'::

    $twig = new \Twig\Environment($loader);
    $test = new \Twig\TwigTest('red', function ($value) {
        if (isset($value->color) && $value->color == 'red') {
            return true;
        }
        if (isset($value->paint) && $value->paint == 'red') {
            return true;
        }
        return false;
    });
    $twig->addTest($test);

Test functions must always return ``true``/``false``.

When creating tests you can use the ``node_class`` option to provide custom test
compilation. This is useful if your test can be compiled into PHP primitives.
This is used by many of the tests built into Twig::

    namespace App;

    use Twig\Environment;
    use Twig\Node\Expression\TestExpression;
    use Twig\TwigTest;

    $twig = new Environment($loader);
    $test = new TwigTest(
        'odd',
        null,
        ['node_class' => OddTestExpression::class]);
    $twig->addTest($test);

    class OddTestExpression extends TestExpression
    {
        public function compile(\Twig\Compiler $compiler)
        {
            $compiler
                ->raw('(')
                ->subcompile($this->getNode('node'))
                ->raw(' % 2 != 0')
                ->raw(')')
            ;
        }
    }

The above example shows how you can create tests that use a node class. The node
class has access to one sub-node called ``node``. This sub-node contains the
value that is being tested. When the ``odd`` filter is used in code such as:

.. code-block:: twig

    {% if my_value is odd %}

The ``node`` sub-node will contain an expression of ``my_value``. Node-based
tests also have access to the ``arguments`` node. This node will contain the
various other arguments that have been provided to your test.

If you want to pass a variable number of positional or named arguments to the
test, set the ``is_variadic`` option to ``true``. Tests support dynamic
names (see dynamic filters for the syntax).

Tags
----

One of the most exciting features of a template engine like Twig is the
possibility to define new **language constructs**. This is also the most complex
feature as you need to understand how Twig's internals work.

Most of the time though, a tag is not needed:

* If your tag generates some output, use a **function** instead.

* If your tag modifies some content and returns it, use a **filter** instead.

  For instance, if you want to create a tag that converts a Markdown formatted
  text to HTML, create a ``markdown`` filter instead:

  .. code-block:: twig

      {{ '**markdown** text'|markdown }}

  If you want use this filter on large amounts of text, wrap it with the
  :doc:`apply <tags/apply>` tag:

  .. code-block:: twig

      {% apply markdown %}
      Title
      =====

      Much better than creating a tag as you can **compose** filters.
      {% endapply %}

* If your tag does not output anything, but only exists because of a side
  effect, create a **function** that returns nothing and call it via the
  :doc:`do <tags/do>` tag.

  For instance, if you want to create a tag that logs text, create a ``log``
  function instead and call it via the :doc:`do <tags/do>` tag:

  .. code-block:: twig

      {% do log('Log some things') %}

If you still want to create a tag for a new language construct, great!

Let's create a ``set`` tag that allows the definition of simple variables from
within a template. The tag can be used like follows:

.. code-block:: twig

    {% set name = "value" %}

    {{ name }}

    {# should output value #}

.. note::

    The ``set`` tag is part of the Core extension and as such is always
    available. The built-in version is slightly more powerful and supports
    multiple assignments by default.

Three steps are needed to define a new tag:

* Defining a Token Parser class (responsible for parsing the template code);

* Defining a Node class (responsible for converting the parsed code to PHP);

* Registering the tag.

Registering a new tag
~~~~~~~~~~~~~~~~~~~~~

Add a tag by calling the ``addTokenParser`` method on the ``\Twig\Environment``
instance::

    $twig = new \Twig\Environment($loader);
    $twig->addTokenParser(new CustomSetTokenParser());

Defining a Token Parser
~~~~~~~~~~~~~~~~~~~~~~~

Now, let's see the actual code of this class::

    class CustomSetTokenParser extends \Twig\TokenParser\AbstractTokenParser
    {
        public function parse(\Twig\Token $token)
        {
            $parser = $this->parser;
            $lineno = $token->getLine();
            $stream = $parser->getStream();

            $name = $stream->expect(\Twig\Token::NAME_TYPE)->getValue();
            $stream->expect(\Twig\Token::OPERATOR_TYPE, '=');
            $value = $parser->getExpressionParser()->parseExpression();
            $stream->expect(\Twig\Token::BLOCK_END_TYPE);

            return new CustomSetNode($name, $value, $lineno);
        }

        public function getTag()
        {
            return 'set';
        }
    }

The ``getTag()`` method must return the tag we want to parse, here ``set``.

The ``parse()`` method is invoked whenever the parser encounters a ``set``
tag. It should return a ``\Twig\Node\Node`` instance that represents the node (the
``CustomSetNode`` calls creating is explained in the next section).

The parsing process is simplified thanks to a bunch of methods you can call
from the token stream (``$this->parser->getStream()``):

* ``getCurrent()``: Gets the current token in the stream.

* ``next()``: Moves to the next token in the stream, *but returns the old one*.

* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether
  the current token is of a particular type or value (or both). The value may be an
  array of several possible values.

* ``expect($type[, $value[, $message]])``: If the current token isn't of the given
  type/value a syntax error is thrown. Otherwise, if the type and value are correct,
  the token is returned and the stream moves to the next token.

* ``look()``: Looks at the next token without consuming it.

Parsing expressions is done by calling the ``parseExpression()`` like we did for
the ``set`` tag.

When encountering a syntax error during parsing, throw an exception::

    throw new SyntaxError('Some error message.', $stream->getCurrent()->getLine(), $stream->getSourceContext());

For better error reporting to the user, follow these recommendations:

 * Use ``\Twig\Error\SyntaxError``;

 * **Always** pass the line number of the node and the source context;

 * End the exception message with a dot.

.. tip::

    Reading the existing ``TokenParser`` classes is the best way to learn all
    the nitty-gritty details of the parsing process.

Defining a Node
~~~~~~~~~~~~~~~

The ``CustomSetNode`` class itself is quite short::

    class CustomSetNode extends \Twig\Node\Node
    {
        public function __construct($name, \Twig\Node\Expression\AbstractExpression $value, $line)
        {
            parent::__construct(['value' => $value], ['name' => $name], $line);
        }

        public function compile(\Twig\Compiler $compiler)
        {
            $compiler
                ->addDebugInfo($this)
                ->write('$context[\''.$this->getAttribute('name').'\'] = ')
                ->subcompile($this->getNode('value'))
                ->raw(";\n")
            ;
        }
    }

The compiler implements a fluid interface and provides methods that help the
developer generate beautiful and readable PHP code:

* ``subcompile()``: Compiles a node.

* ``raw()``: Writes the given string as is.

* ``write()``: Writes the given string by adding indentation at the beginning
  of each line.

* ``string()``: Writes a quoted string.

* ``repr()``: Writes a PHP representation of a given value (see
  ``\Twig\Node\ForNode`` for a usage example).

* ``addDebugInfo()``: Adds the line of the original template file related to
  the current node as a comment. It's highly recommended to call this method
  when implementing custom nodes.

* ``indent()``: Indents the generated code (see ``\Twig\Node\BlockNode`` for a
  usage example).

* ``outdent()``: Outdents the generated code (see ``\Twig\Node\BlockNode`` for a
  usage example).

For structural nodes, always call ``addDebugInfo()`` early on in the
compilation process to improve error reporting to the user in case the code
would throw an exception.

.. _creating_extensions:

Creating an Extension
---------------------

The main motivation for writing an extension is to move often used code into a
reusable class like adding support for internationalization. An extension can
define tags, filters, tests, operators, functions, and node visitors.

Most of the time, it is useful to create a single extension for your project,
to host all the specific tags and filters you want to add to Twig.

.. tip::

    When packaging your code into an extension, Twig is smart enough to
    recompile your templates whenever you make a change to it (when
    ``auto_reload`` is enabled).

An extension is a class that implements the following interface::

    interface \Twig\Extension\ExtensionInterface
    {
        /**
         * Returns the token parser instances to add to the existing list.
         *
         * @return \Twig\TokenParser\TokenParserInterface[]
         */
        public function getTokenParsers();

        /**
         * Returns the node visitor instances to add to the existing list.
         *
         * @return \Twig\NodeVisitor\NodeVisitorInterface[]
         */
        public function getNodeVisitors();

        /**
         * Returns a list of filters to add to the existing list.
         *
         * @return \Twig\TwigFilter[]
         */
        public function getFilters();

        /**
         * Returns a list of tests to add to the existing list.
         *
         * @return \Twig\TwigTest[]
         */
        public function getTests();

        /**
         * Returns a list of functions to add to the existing list.
         *
         * @return \Twig\TwigFunction[]
         */
        public function getFunctions();

        /**
         * Returns a list of expression parsers to add to the existing list.
         *
         * @return \Twig\ExpressionParser\ExpressionParserInterface[]
         */
        public function getExpressionParsers();
    }

To keep your extension class clean and lean, inherit from the built-in
``\Twig\Extension\AbstractExtension`` class instead of implementing the interface as it provides
empty implementations for all methods::

    class CustomTwigExtension extends \Twig\Extension\AbstractExtension
    {
    }

This extension does nothing for now. We will customize it in the next sections.

You can save your extension anywhere on the filesystem, as all extensions must
be registered explicitly to be available in your templates.

You can register an extension by using the ``addExtension()`` method on your
main ``Environment`` object::

    $twig = new \Twig\Environment($loader);
    $twig->addExtension(new CustomTwigExtension());

.. tip::

    The Twig core extensions are great examples of how extensions work.

Globals
~~~~~~~

Global variables can be registered in an extension via the ``getGlobals()``
method::

    class CustomTwigExtension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface
    {
        public function getGlobals(): array
        {
            return [
                'text' => new Text(),
            ];
        }

        // ...
    }

.. caution::

    Globals are fetched once from extensions and then cached for the lifetime
    of the Twig environment. It means that globals should not be used to store
    values that can change during the lifetime of the Twig environment. For
    instance, if you're using an application server like RoadRunner or
    FrankenPHP, you should not store values related to the current context (like
    the HTTP request). If you do so, don't forget to reset the cache between
    requests by calling ``Environment::resetGlobals()``.

Functions
~~~~~~~~~

Functions can be registered in an extension via the ``getFunctions()``
method::

    class CustomTwigExtension extends \Twig\Extension\AbstractExtension
    {
        public function getFunctions()
        {
            return [
                new \Twig\TwigFunction('lipsum', 'generate_lipsum'),
            ];
        }

        // ...
    }

Filters
~~~~~~~

To add a filter to an extension, you need to override the ``getFilters()``
method. This method must return an array of filters to add to the Twig
environment::

    class CustomTwigExtension extends \Twig\Extension\AbstractExtension
    {
        public function getFilters()
        {
            return [
                new \Twig\TwigFilter('rot13', 'str_rot13'),
            ];
        }

        // ...
    }

Tags
~~~~

Adding a tag in an extension can be done by overriding the
``getTokenParsers()`` method. This method must return an array of tags to add
to the Twig environment::

    class CustomTwigExtension extends \Twig\Extension\AbstractExtension
    {
        public function getTokenParsers()
        {
            return [new CustomSetTokenParser()];
        }

        // ...
    }

In the above code, we have added a single new tag, defined by the
``CustomSetTokenParser`` class. The ``CustomSetTokenParser`` class is
responsible for parsing the tag and compiling it to PHP.

Operators
~~~~~~~~~

.. versionadded:: 3.21

    The ``getExpressionParsers()`` method was added in Twig 3.21.

.. deprecated:: 3.21

    The ``getExpressionParsers()`` method replaces the now deprecated
    ``getOperators()`` method. See the :doc:`deprecated <deprecated>` page for
    details on how to upgrade from ``getOperators()`` to
    ``getExpressionParsers()``.

The ``getExpressionParsers()`` method lets you add new operators. To implement
a new one, have a look at the default operators provided by
``Twig\Extension\CoreExtension``.

Tests
~~~~~

The ``getTests()`` method lets you add new test functions::

    class CustomTwigExtension extends \Twig\Extension\AbstractExtension
    {
        public function getTests()
        {
            return [
                new \Twig\TwigTest('even', 'twig_test_even'),
            ];
        }

        // ...
    }

Using PHP Attributes to define Extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 3.21

    The attribute classes were added in Twig 3.21.

You can add the ``#[AsTwigFilter]``, ``#[AsTwigFunction]``, and ``#[AsTwigTest]``
attributes to public methods of any class to define filters, functions, and tests.

Create a class using these attributes::

    use Twig\Attribute\AsTwigFilter;
    use Twig\Attribute\AsTwigFunction;
    use Twig\Attribute\AsTwigTest;

    class ProjectExtension
    {
        #[AsTwigFilter('rot13')]
        public static function rot13(string $string): string
        {
            // ...
        }

        #[AsTwigFunction('lipsum')]
        public static function lipsum(int $count): string
        {
            // ...
        }

        #[AsTwigTest('even')]
        public static function isEven(int $number): bool
        {
            // ...
        }
    }

Then register the ``Twig\Extension\AttributeExtension`` with the class name::

    $twig = new \Twig\Environment($loader);
    $twig->addExtension(new \Twig\Extension\AttributeExtension(ProjectExtension::class));

If all the methods are static, you are done. The ``ProjectExtension`` class will
never be instantiated and the class attributes will be scanned only when a template
is compiled.

Otherwise, if some methods are not static, you need to register the class as
a runtime extension using one of the runtime loaders::

    use Twig\Attribute\AsTwigFunction;

    class ProjectExtension
    {
        // Inject hypothetical dependencies
        public function __construct(private LipsumProvider $lipsumProvider) {}

        #[AsTwigFunction('lipsum')]
        public function lipsum(int $count): string
        {
            return $this->lipsumProvider->lipsum($count);
        }
    }

    $twig = new \Twig\Environment($loader);
    $twig->addExtension(new \Twig\Extension\AttributeExtension(ProjectExtension::class);
    $twig->addRuntimeLoader(new \Twig\RuntimeLoader\FactoryLoader([
        ProjectExtension::class => function () use ($lipsumProvider) {
            return new ProjectExtension($lipsumProvider);
        },
    ]));

If you want to access the current environment instance in your filter or function,
add the ``Twig\Environment`` type to the first argument of the method::

    class ProjectExtension
    {
        #[AsTwigFunction('lipsum')]
        public function lipsum(\Twig\Environment $env, int $count): string
        {
            // ...
        }
    }

``#[AsTwigFilter]`` and ``#[AsTwigFunction]`` support variadic arguments
automatically when applied to variadic methods::

    class ProjectExtension
    {
        #[AsTwigFilter('thumbnail')]
        public function thumbnail(string $file, mixed ...$options): string
        {
            // ...
        }
    }

The attributes support other options used to configure the Twig Callables:

 * ``AsTwigFilter``: ``needsCharset``, ``needsEnvironment``, ``needsContext``, ``isSafe``, ``isSafeCallback``, ``preEscape``, ``preservesSafety``, ``deprecationInfo``
 * ``AsTwigFunction``: ``needsCharset``, ``needsEnvironment``, ``needsContext``, ``isSafe``, ``isSafeCallback``, ``deprecationInfo``
 * ``AsTwigTest``: ``needsCharset``, ``needsEnvironment``, ``needsContext``, ``deprecationInfo``

Definition vs Runtime
~~~~~~~~~~~~~~~~~~~~~

Twig filters, functions, and tests runtime implementations can be defined as
any valid PHP callable:

* **functions/static methods**: Simple to implement and fast (used by all Twig
  core extensions); but it is hard for the runtime to depend on external
  objects;

* **closures**: Simple to implement;

* **object methods**: More flexible and required if your runtime code depends
  on external objects.

The simplest way to use methods is to define them on the extension itself::

    class CustomTwigExtension extends \Twig\Extension\AbstractExtension
    {
        private $rot13Provider;

        public function __construct($rot13Provider)
        {
            $this->rot13Provider = $rot13Provider;
        }

        public function getFunctions()
        {
            return [
                new \Twig\TwigFunction('rot13', [$this, 'rot13']),
            ];
        }

        public function rot13($value)
        {
            return $this->rot13Provider->rot13($value);
        }
    }

This is very convenient but not recommended as it makes template compilation
depend on runtime dependencies even if they are not needed (think for instance
as a dependency that connects to a database engine).

You can decouple the extension definitions from their runtime implementations by
registering a ``\Twig\RuntimeLoader\RuntimeLoaderInterface`` instance on the
environment that knows how to instantiate such runtime classes (runtime classes
must be autoload-able)::

    class RuntimeLoader implements \Twig\RuntimeLoader\RuntimeLoaderInterface
    {
        public function load($class)
        {
            // implement the logic to create an instance of $class
            // and inject its dependencies
            // most of the time, it means using your dependency injection container
            if ('CustomTwigRuntime' === $class) {
                return new $class(new Rot13Provider());
            } else {
                // ...
            }
        }
    }

    $twig->addRuntimeLoader(new RuntimeLoader());

.. note::

    Twig comes with a PSR-11 compatible runtime loader
    (``\Twig\RuntimeLoader\ContainerRuntimeLoader``).

It is now possible to move the runtime logic to a new
``CustomTwigRuntime`` class and use it directly in the extension::

    class CustomTwigRuntime
    {
        private $rot13Provider;

        public function __construct($rot13Provider)
        {
            $this->rot13Provider = $rot13Provider;
        }

        public function rot13($value)
        {
            return $this->rot13Provider->rot13($value);
        }
    }

    class CustomTwigExtension extends \Twig\Extension\AbstractExtension
    {
        public function getFunctions()
        {
            return [
                new \Twig\TwigFunction('rot13', ['CustomTwigRuntime', 'rot13']),
                // or
                new \Twig\TwigFunction('rot13', 'CustomTwigRuntime::rot13'),
            ];
        }
    }

.. note::

    The extension class should implement the ``Twig\Extension\LastModifiedExtensionInterface``
    interface to invalidate the template cache when the runtime class is modified.
    The ``AbstractExtension`` class implements this interface and tracks the
    runtime class if its name is the same as the extension class but ends with
    ``Runtime`` instead of ``Extension``.

Testing an Extension
--------------------

Functional Tests
~~~~~~~~~~~~~~~~

You can create functional tests for extensions by creating the following file
structure in your test directory::

    Fixtures/
        filters/
            lower.test
            upper.test
        functions/
            date.test
            format.test
        tags/
            for.test
            if.test
    IntegrationTest.php

The ``IntegrationTest.php`` file should look like this::

    namespace Project\Tests;

    use Twig\Test\IntegrationTestCase;

    class IntegrationTest extends IntegrationTestCase
    {
        public function getExtensions()
        {
            return [
                new CustomTwigExtension1(),
                new CustomTwigExtension2(),
            ];
        }

        public function getFixturesDir()
        {
            return __DIR__.'/Fixtures/';
        }
    }

Fixtures examples can be found within the Twig repository
`tests/Twig/Fixtures`_ directory.

Node Tests
~~~~~~~~~~

Testing the node visitors can be complex, so extend your test cases from
``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository
`tests/Twig/Node`_ directory.

.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/3.x/tests/Fixtures
.. _`tests/Twig/Node`:     https://github.com/twigphp/Twig/tree/3.x/tests/Node


================================================
FILE: doc/api.rst
================================================
Twig for Developers
===================

This chapter describes the API to Twig and not the template language. It will
be most useful as reference to those implementing the template interface to
the application and not those who are creating Twig templates.

Basics
------

Twig uses a central object called the **environment** (of class
``\Twig\Environment``). Instances of this class are used to store the
configuration and extensions, and are used to load templates.

Most applications create one ``\Twig\Environment`` object on application
initialization and use that to load templates. In some cases, it might be useful
to have multiple environments side by side, with different configurations.

The typical way to configure Twig to load templates for an application looks
roughly like this::

    require_once '/path/to/vendor/autoload.php';

    $loader = new \Twig\Loader\FilesystemLoader('/path/to/templates');
    $twig = new \Twig\Environment($loader, [
        'cache' => '/path/to/compilation_cache',
    ]);

This creates a template environment with a default configuration and a loader
that looks up templates in the ``/path/to/templates/`` directory. Different
loaders are available and you can also write your own if you want to load
templates from a database or other resources.

.. note::

    Notice that the second argument of the environment is an array of options.
    The ``cache`` option is a compilation cache directory, where Twig caches
    the compiled templates to avoid the parsing phase for subsequent
    requests. It is very different from the cache you might want to add for
    the evaluated templates. For such a need, you can use any available PHP
    cache library.

Loading Templates
-----------------

To load a template, call the ``load()`` method on a Twig environment which
returns a ``\Twig\TemplateWrapper`` instance::

    $template = $twig->load('index.html.twig');

Rendering Templates
-------------------

To render a template with some variables, call the ``render()`` method::

    echo $template->render(['the' => 'variables', 'go' => 'here']);

.. note::

    The ``display()`` method is a shortcut to output the rendered template.

You can also load and render the template directly via the Environment::

    echo $twig->render('index.html.twig', ['the' => 'variables', 'go' => 'here']);

If a template defines blocks, they can be rendered individually via the
``renderBlock()`` call::

    echo $template->renderBlock('block_name', ['the' => 'variables', 'go' => 'here']);

Streaming Templates
-------------------

.. versionadded:: 3.18

To stream a template, call the ``stream()`` method::

    $template->stream(['the' => 'variables', 'go' => 'here']);

To stream a specific template block, call the ``streamBlock()`` method::

    $template->streamBlock('block_name', ['the' => 'variables', 'go' => 'here']);

.. note::

    The ``stream()`` and ``streamBlock()`` methods return an iterable.

.. _environment_options:

Environment Options
-------------------

When creating a new ``\Twig\Environment`` instance, you can pass an array of
options as the constructor second argument::

    $twig = new \Twig\Environment($loader, ['debug' => true]);

The following options are available:

* ``debug`` *boolean*

  When set to ``true``, the generated templates have a
  ``__toString()`` method that you can use to display the generated nodes
  (default to ``false``).

* ``charset`` *string* (defaults to ``utf-8``)

  The charset used by the templates.

* ``cache`` *string* or ``false``

  An absolute path where to store the compiled templates, or
  ``false`` to disable caching (which is the default).

* ``auto_reload`` *boolean*

  When developing with Twig, it's useful to recompile the
  template whenever the source code changes. If you don't provide a value for
  the ``auto_reload`` option, it will be determined automatically based on the
  ``debug`` value.

.. _environment_options_strict_variables:

* ``strict_variables`` *boolean*

  If set to ``false``, Twig will silently ignore invalid
  variables (variables and or attributes/methods that do not exist) and
  replace them with a ``null`` value. When set to ``true``, Twig throws an
  exception instead (default to ``false``).

* ``autoescape`` *string*

  Sets the default auto-escaping strategy (``name``, ``html``, ``js``, ``css``, ``url``,
  ``html_attr``, ``html_attr_relaxed``, or a PHP callback that takes the template "filename"
  and returns the escaping strategy to use -- the callback cannot be a function
  name to avoid collision with built-in escaping strategies); set it to
  ``false`` to disable auto-escaping. The ``name`` escaping strategy determines
  the escaping strategy to use for a template based on the template filename
  extension (this strategy does not incur any overhead at runtime as
  auto-escaping is done at compilation time.)

* ``optimizations`` *integer*

  A flag that indicates which optimizations to apply
  (default to ``-1`` -- all optimizations are enabled; set it to ``0`` to
  disable).

* ``use_yield`` *boolean*

  ``true``: forces templates to exclusively use ``yield`` instead of ``echo``
  (all extensions must be yield ready)

  ``false`` (default): allows templates to use a mix of ``yield`` and ``echo``
  calls to allow for a progressive migration.
  
  Switch to ``true`` when possible as this will be the only supported mode in
  Twig 4.0.

Loaders
-------

Loaders are responsible for loading templates from a resource such as the file
system.

Compilation Cache
~~~~~~~~~~~~~~~~~

All template loaders can cache the compiled templates on the filesystem for
future reuse. It speeds up Twig a lot as templates are only compiled once.

Built-in Loaders
~~~~~~~~~~~~~~~~

Here is a list of the built-in loaders:

``\Twig\Loader\FilesystemLoader``
.................................

``\Twig\Loader\FilesystemLoader`` loads templates from the file system. This loader
can find templates in folders on the file system and is the preferred way to
load them::

    $loader = new \Twig\Loader\FilesystemLoader($templateDir);

It can also look for templates in an array of directories::

    $loader = new \Twig\Loader\FilesystemLoader([$templateDir1, $templateDir2]);

With such a configuration, Twig will first look for templates in
``$templateDir1`` and if they do not exist, it will fallback to look for them
in the ``$templateDir2``.

You can add or prepend paths via the ``addPath()`` and ``prependPath()``
methods::

    $loader->addPath($templateDir3);
    $loader->prependPath($templateDir4);

The filesystem loader also supports namespaced templates. This allows you to group
your templates under different namespaces which have their own template paths.

When using the ``setPaths()``, ``addPath()``, and ``prependPath()`` methods,
specify the namespace as the second argument (when not specified, these
methods act on the "main" namespace)::

    $loader->addPath($templateDir, 'admin');

Namespaced templates can be accessed via the special
``@namespace_name/template_path`` notation::

    $twig->render('@admin/index.html.twig', []);

``\Twig\Loader\FilesystemLoader`` supports absolute and relative paths. Using relative
paths is preferred as it makes the cache keys independent of the project root
directory (for instance, it allows warming the cache from a build server where
the directory might be different from the one used on production servers)::

    $loader = new \Twig\Loader\FilesystemLoader('templates', getcwd().'/..');

.. note::

    When not passing the root path as a second argument, Twig uses ``getcwd()``
    for relative paths.

``\Twig\Loader\ArrayLoader``
............................

``\Twig\Loader\ArrayLoader`` loads a template from a PHP array. It is passed an
array of strings bound to template names::

    $loader = new \Twig\Loader\ArrayLoader([
        'index.html.twig' => 'Hello {{ name }}!',
    ]);
    $twig = new \Twig\Environment($loader);

    echo $twig->render('index.html.twig', ['name' => 'Fabien']);

This loader is very useful for unit testing. It can also be used for small
projects where storing all templates in a single PHP file might make sense.

.. tip::

    When using the ``Array`` loader with a cache mechanism, you should know that
    a new cache key is generated each time a template content "changes" (the
    cache key being the source code of the template). If you don't want to see
    your cache grows out of control, you need to take care of clearing the old
    cache file by yourself.

``\Twig\Loader\ChainLoader``
............................

``\Twig\Loader\ChainLoader`` delegates the loading of templates to other loaders::

    $loader1 = new \Twig\Loader\ArrayLoader([
        'base.html.twig' => '{% block content %}{% endblock %}',
    ]);
    $loader2 = new \Twig\Loader\ArrayLoader([
        'index.html.twig' => '{% extends "base.html.twig" %}{% block content %}Hello {{ name }}{% endblock %}',
        'base.html.twig'  => 'Will never be loaded',
    ]);

    $loader = new \Twig\Loader\ChainLoader([$loader1, $loader2]);

    $twig = new \Twig\Environment($loader);

When looking for a template, Twig tries each loader in turn and returns as soon
as the template is found. When rendering the ``index.html.twig`` template from the
above example, Twig will load it with ``$loader2`` but the ``base.html.twig``
template will be loaded from ``$loader1``.

.. note::

    You can also add loaders via the ``addLoader()`` method.

Create your own Loader
~~~~~~~~~~~~~~~~~~~~~~

All loaders implement the ``\Twig\Loader\LoaderInterface``::

    interface \Twig\Loader\LoaderInterface
    {
        /**
         * Returns the source context for a given template logical name.
         *
         * @param string $name The template logical name
         *
         * @return \Twig\Source
         *
         * @throws \Twig\Error\LoaderError When $name is not found
         */
        public function getSourceContext($name);

        /**
         * Gets the cache key to use for the cache for a given template name.
         *
         * @param string $name The name of the template to load
         *
         * @return string The cache key
         *
         * @throws \Twig\Error\LoaderError When $name is not found
         */
        public function getCacheKey($name);

        /**
         * Returns true if the template is still fresh.
         *
         * @param string    $name The template name
         * @param timestamp $time The last modification time of the cached template
         *
         * @return bool    true if the template is fresh, false otherwise
         *
         * @throws \Twig\Error\LoaderError When $name is not found
         */
        public function isFresh($name, $time);

        /**
         * Check if we have the source code of a template, given its name.
         *
         * @param string $name The name of the template to check if we can load
         *
         * @return bool    If the template source code is handled by this loader or not
         */
        public function exists($name);
    }

The ``isFresh()`` method must return ``true`` if the current cached template
is still fresh, given the last modification time, or ``false`` otherwise.

The ``getSourceContext()`` method must return an instance of ``\Twig\Source``.

Using Extensions
----------------

Twig extensions are packages that add new features to Twig. Register an
extension via the ``addExtension()`` method::

    $twig->addExtension(new \Twig\Extension\SandboxExtension());

Twig comes bundled with the following extensions:

* ``\Twig\Extension\CoreExtension``: Defines all the core features of Twig.

* ``\Twig\Extension\DebugExtension``: Defines the ``dump`` function to help debug
  template variables.

* ``\Twig\Extension\EscaperExtension``: Adds automatic output-escaping and the
  possibility to escape/unescape blocks of code.

* ``\Twig\Extension\SandboxExtension``: Adds a sandbox mode to the default Twig
  environment, making it safe to evaluate untrusted code.

* ``\Twig\Extension\ProfilerExtension``: Enables the built-in Twig profiler.

* ``\Twig\Extension\OptimizerExtension``: Optimizes the node tree before
  compilation.

* ``\Twig\Extension\StringLoaderExtension``: Defines the ``template_from_string``
   function to allow loading templates from string in a template.

The Core, Escaper, and Optimizer extensions are registered by default.

Built-in Extensions
-------------------

This section describes the features added by the built-in extensions.

.. tip::

    Read the chapter about :doc:`extending Twig <advanced>` to learn how to
    create your own extensions.

Core Extension
~~~~~~~~~~~~~~

The ``core`` extension defines all the core features of Twig:

* :doc:`Tags <tags/index>`;
* :doc:`Filters <filters/index>`;
* :doc:`Functions <functions/index>`;
* :doc:`Tests <tests/index>`.

Escaper Extension
~~~~~~~~~~~~~~~~~

The ``escaper`` extension adds automatic output escaping to Twig. It defines a
tag, ``autoescape``, and a filter, ``raw``.

When creating the escaper extension, you can switch on or off the global
output escaping strategy::

    $escaper = new \Twig\Extension\EscaperExtension('html');
    $twig->addExtension($escaper);

If set to ``html``, all variables in templates are escaped (using the ``html``
escaping strategy), except those using the ``raw`` filter:

.. code-block:: twig

    {{ article.to_html|raw }}

You can also change the escaping mode locally by using the ``autoescape`` tag:

.. code-block:: twig

    {% autoescape 'html' %}
        {{ var }}
        {{ var|raw }}      {# var won't be escaped #}
        {{ var|escape }}   {# var won't be double-escaped #}
    {% endautoescape %}

.. warning::

    The ``autoescape`` tag has no effect on included files.

The escaping rules are implemented as follows:

* Literals (integers, booleans, arrays, ...) used in the template directly as
  variables or filter arguments are never automatically escaped:

  .. code-block:: html+twig

        {{ "Twig<br/>" }} {# won't be escaped #}

        {% set text = "Twig<br/>" %}
        {{ text }} {# will be escaped #}

* Expressions which the result is a literal or a variable marked safe
  are never automatically escaped:

  .. code-block:: html+twig

        {{ any_value ? "Twig<br/>" : "<br/>Twig" }} {# won't be escaped #}

        {% set text = "Twig<br/>" %}
        {{ true ? text : "<br/>Twig" }} {# will be escaped #}
        {{ false ? text : "<br/>Twig" }} {# won't be escaped #}

        {% set text = "Twig<br/>" %}
        {{ any_value ? text|raw : "<br/>Twig" }} {# won't be escaped #}

* Objects with a ``__toString`` method are converted to strings and
  escaped. You can mark some classes and/or interfaces as being safe for some
  strategies via ``EscaperExtension::addSafeClass()``:

  .. code-block:: twig

        // mark objects of class "HtmlGenerator" as safe for the HTML strategy
        $escaper->addSafeClass('HtmlGenerator', ['html']);

        // mark objects of interface "HtmlGeneratorInterface" as safe for the HTML strategy
        $escaper->addSafeClass('HtmlGeneratorInterface', ['html']);

        // mark objects of class "HtmlGenerator" as safe for the HTML and JS strategies
        $escaper->addSafeClass('HtmlGenerator', ['html', 'js']);

        // mark objects of class "HtmlGenerator" as safe for all strategies
        $escaper->addSafeClass('HtmlGenerator', ['all']);

* Escaping is applied before printing, after any other filter is applied:

  .. code-block:: twig

        {{ var|upper }} {# is equivalent to {{ var|upper|escape }} #}

* The ``raw`` filter should only be used at the end of the filter chain:

  .. code-block:: twig

        {{ var|raw|upper }} {# will be escaped #}

        {{ var|upper|raw }} {# won't be escaped #}

* Automatic escaping is not applied if the last filter in the chain is marked
  safe for the current context (e.g. ``html`` or ``js``). ``escape`` and
  ``escape('html')`` are marked safe for HTML, ``escape('js')`` is marked
  safe for JavaScript, ``raw`` is marked safe for everything.

  .. code-block:: twig

        {% autoescape 'js' %}
            {{ var|escape('html') }} {# will be escaped for HTML and JavaScript #}
            {{ var }} {# will be escaped for JavaScript #}
            {{ var|escape('js') }} {# won't be double-escaped #}
        {% endautoescape %}

.. note::

    Note that autoescaping has some limitations as escaping is applied on
    expressions after evaluation. For instance, when working with
    concatenation, ``{{ value|raw ~ other }}`` won't give the expected result
    as escaping is applied on the result of the concatenation, not on the
    individual variables (so, the ``raw`` filter won't have any effect here).

Sandbox Extension
~~~~~~~~~~~~~~~~~

The ``sandbox`` extension can be used to evaluate untrusted code. Read more
about it in the :doc:`sandbox` chapter.

Profiler Extension
~~~~~~~~~~~~~~~~~~

The ``profiler`` extension enables a profiler for Twig templates; it should
only be used on your development machines as it adds some overhead::

    $profile = new \Twig\Profiler\Profile();
    $twig->addExtension(new \Twig\Extension\ProfilerExtension($profile));

    $dumper = new \Twig\Profiler\Dumper\TextDumper();
    echo $dumper->dump($profile);

A profile contains information about time and memory consumption for template,
block, and macro executions.

You can also dump the data in a `Blackfire.io <https://blackfire.io/>`_
compatible format::

    $dumper = new \Twig\Profiler\Dumper\BlackfireDumper();
    file_put_contents('/path/to/profile.prof', $dumper->dump($profile));

Upload the profile to visualize it (create a `free account
<https://blackfire.io/signup?utm_source=twig&utm_medium=doc&utm_campaign=profiler>`_
first):

.. code-block:: sh

    blackfire --slot=7 upload /path/to/profile.prof

Optimizer Extension
~~~~~~~~~~~~~~~~~~~

The ``optimizer`` extension optimizes the node tree before compilation::

    $twig->addExtension(new \Twig\Extension\OptimizerExtension());

By default, all optimizations are turned on. You can select the ones you want
to enable by passing them to the constructor::

    $optimizer = new \Twig\Extension\OptimizerExtension(\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR);

    $twig->addExtension($optimizer);

Twig supports the following optimizations:

* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_ALL``, enables all optimizations
  (this is the default value).

* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_NONE``, disables all optimizations.
  This reduces the compilation time, but it can increase the execution time
  and the consumed memory.

* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR``, optimizes the ``for`` tag by
  removing the ``loop`` variable creation whenever possible.

Exceptions
----------

Twig can throw exceptions:

* ``\Twig\Error\Error``: The base exception for all errors.

* ``\Twig\Error\SyntaxError``: Thrown to tell the user that there is a problem with
  the template syntax.

* ``\Twig\Error\RuntimeError``: Thrown when an error occurs at runtime (when a filter
  does not exist for instance).

* ``\Twig\Error\LoaderError``: Thrown when an error occurs during template loading.

* ``\Twig\Sandbox\SecurityError``: Thrown when an unallowed tag, filter, or
  method is called in a sandboxed template.


================================================
FILE: doc/coding_standards.rst
================================================
Coding Standards
================

.. note::

    The `Twig CS fixer tool <https://github.com/VincentLanglet/Twig-CS-Fixer>`_
    uses the coding standards described in this document to automatically fix
    your templates.

When writing Twig templates, we recommend you to follow these official coding
standards:

* Put exactly one space after the start of a delimiter (``{{``, ``{%``,
  and ``{#``) and before the end of a delimiter (``}}``, ``%}``, and ``#}``)
  if the content is non empty:

  .. code-block:: twig

    {{ user }}
    {# comment #} {##}
    {% if user %}{% endif %}

  When using the whitespace control character, do not put any spaces between
  it and the delimiter:

  .. code-block:: twig

    {{- user -}}
    {#- comment -#} {#--#}
    {%- if user -%}{%- endif -%}

* Put exactly one space before and after the following operators:
  comparison operators (``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``), math
  operators (``+``, ``-``, ``/``, ``*``, ``%``, ``//``, ``**``), logic
  operators (``not``, ``and``, ``or``), ``~``, ``is``, ``in``, and the ternary
  operator (``?:``):

  .. code-block:: twig

    {{ 1 + 2 }}
    {{ first_name ~ ' ' ~ last_name }}
    {{ is_correct ? true : false }}

* Put exactly one space after the ``:`` sign in mappings and ``,`` in sequences
  and mappings:

  .. code-block:: twig

    [1, 2, 3]
    {'name': 'Fabien'}

* Do not put any spaces after an opening parenthesis and before a closing
  parenthesis in expressions:

  .. code-block:: twig

    {{ 1 + (2 * 3) }}

* Do not put any spaces before and after string delimiters:

  .. code-block:: twig

    {{ 'Twig' }}
    {{ "Twig" }}

* Do not put any spaces before and after the following operators: ``|``,
  ``.``, ``..``, ``[]``:

  .. code-block:: twig

    {{ name|upper|lower }}
    {{ user.name }}
    {{ user[name] }}
    {% for i in 1..12 %}{% endfor %}

* Do not put any spaces before and after the parenthesis used for filter and
  function calls:

  .. code-block:: twig

    {{ name|default('Fabien') }}
    {{ range(1..10) }}

* Do not put any spaces before and after the opening and the closing of
  sequences and mappings:

  .. code-block:: twig

    [1, 2, 3]
    {'name': 'Fabien'}

* Put exactly one space before and after ``=`` in macro argument declarations:

  .. code-block:: twig

    {% macro html_input(class = "input") %}

* Put exactly one space after the ``:`` sign when using named arguments:

  .. code-block:: twig

    {{ html_input(class: "input") }}

* Use snake case for all variable names (provided by the application and
  created in templates), function/filter/test names, argument names and named
  arguments:

  .. code-block:: twig

    {% set name = 'Fabien' %}
    {% set first_name = 'Fabien' %}

    {{ 'Fabien Potencier'|to_lower_case }}
    {{ generate_random_number() }}

    {% macro html_input(class_name) %}

    {{ html_input(class_name: 'pwd') }}

* Indent your code inside tags (use the same indentation as the one used for
  the target language of the rendered template):

  .. code-block:: twig

    {% block content %}
        {% if true %}
            true
        {% endif %}
    {% endblock %}

* Use ``:`` instead of ``=`` to separate argument names and values:

  .. code-block:: twig

    {{ data|convert_encoding(from: 'iso-2022-jp', to: 'UTF-8') }}


================================================
FILE: doc/deprecated.rst
================================================
Deprecated Features
===================

This document lists deprecated features in Twig 3.x. Deprecated features are
kept for backward compatibility and removed in the next major release (a
feature that was deprecated in Twig 3.x is removed in Twig 4.0).

Functions
---------

* The ``twig_test_iterable`` function is deprecated; use the native PHP
  ``is_iterable`` function instead.

* The ``attribute`` function is deprecated as of Twig 3.15. Use the ``.``
  operator instead and wrap the name with parenthesis:

  .. code-block:: twig

    {# before #}
    {{ attribute(object, method) }}
    {{ attribute(object, method, arguments) }}
    {{ attribute(array, item) }}

    {# after #}
    {{ object.(method) }}
    {{ object.(method)(arguments) }}
    {{ array[item] }}

  Note that it won't be removed in 4.0 to allow a smoother upgrade path.

Extensions
----------

* All functions defined in Twig extensions are marked as internal as of Twig
  3.9.0, and will be removed in Twig 4.0. They have been replaced by internal
  methods on their respective extension classes.

  If you were using the ``twig_escape_filter()`` function in your code, use
  ``$env->getRuntime(EscaperRuntime::class)->escape()`` instead.

* The following methods from ``Twig\Extension\EscaperExtension`` are
  deprecated: ``setEscaper()``, ``getEscapers()``, ``setSafeClasses``,
  ``addSafeClasses()``. Use the same methods on the
  ``Twig\Runtime\EscaperRuntime`` class instead:
  
  Before:
  ``$twig->getExtension(EscaperExtension::class)->METHOD();``
  
  After:
  ``$twig->getRuntime(EscaperRuntime::class)->METHOD();``

Nodes
-----

* The "tag" constructor parameter of the ``Twig\Node\Node`` class is deprecated
  as of Twig 3.12 as the tag is now automatically set by the Parser when
  needed.

* The following ``Twig\Node\Node`` methods will take a string or an integer
  (instead of just a string) in Twig 4.0 for their "name" argument:
  ``getNode()``, ``hasNode()``, ``setNode()``, ``removeNode()``, and
  ``deprecateNode()``.

* Not passing a ``BodyNode`` instance as the body of a ``ModuleNode`` or
  ``MacroNode`` constructor is deprecated as of Twig 3.12.

* Returning ``null`` from ``TokenParserInterface::parse()`` is deprecated as of
  Twig 3.12 (as forbidden by the interface).

* The second argument of the
  ``Twig\Node\Expression\CallExpression::compileArguments()`` method is
  deprecated.

* The ``Twig\Node\Expression\NameExpression::isSimple()`` and
  ``Twig\Node\Expression\NameExpression::isSpecial()`` methods are deprecated as
  of Twig 3.11 and will be removed in Twig 4.0.

* The ``filter`` node of ``Twig\Node\Expression\FilterExpression`` is
  deprecated as of Twig 3.12 and will be removed in 4.0. Use the ``filter``
  attribute instead to get the filter:

  Before:
  ``$node->getNode('filter')->getAttribute('value')``

  After:
  ``$node->getAttribute('twig_callable')->getName()``

* Passing a name to ``Twig\Node\Expression\FunctionExpression``,
  ``Twig\Node\Expression\FilterExpression``, and
  ``Twig\Node\Expression\TestExpression`` is deprecated as of Twig 3.12.
  As of Twig 4.0, you need to pass a ``TwigFunction``, ``TwigFilter``, or
  ``TestFilter`` instead.

  Let's take a ``FunctionExpression`` as an example.

  If you have a node that extends ``FunctionExpression`` and if you don't
  override the constructor, you don't need to do anything. But if you override
  the constructor, then you need to change the type hint of the name and mark
  the constructor with the ``Twig\Attribute\FirstClassTwigCallableReady`` attribute.

  Before::

      class NotReadyFunctionExpression extends FunctionExpression
      {
          public function __construct(string $function, Node $arguments, int $lineno)
          {
              parent::__construct($function, $arguments, $lineno);
          }
      }

      class NotReadyFilterExpression extends FilterExpression
      {
          public function __construct(Node $node, ConstantExpression $filter, Node $arguments, int $lineno)
          {
              parent::__construct($node, $filter, $arguments, $lineno);
          }
      }

      class NotReadyTestExpression extends TestExpression
      {
          public function __construct(Node $node, string $test, ?Node $arguments, int $lineno)
          {
              parent::__construct($node, $test, $arguments, $lineno);
          }
      }

  After::

      class ReadyFunctionExpression extends FunctionExpression
      {
          #[FirstClassTwigCallableReady]
          public function __construct(TwigFunction|string $function, Node $arguments, int $lineno)
          {
              parent::__construct($function, $arguments, $lineno);
          }
      }

      class ReadyFilterExpression extends FilterExpression
      {
          #[FirstClassTwigCallableReady]
          public function __construct(Node $node, TwigFilter|ConstantExpression $filter, Node $arguments, int $lineno)
          {
              parent::__construct($node, $filter, $arguments, $lineno);
          }
      }

      class ReadyTestExpression extends TestExpression
      {
          #[FirstClassTwigCallableReady]
          public function __construct(Node $node, TwigTest|string $test, ?Node $arguments, int $lineno)
          {
              parent::__construct($node, $test, $arguments, $lineno);
          }
      }

* The following ``Twig\Node\Expression\FunctionExpression`` attributes are
  deprecated as of Twig 3.12: ``needs_charset``,  ``needs_environment``,
  ``needs_context``,  ``arguments``,  ``callable``,  ``is_variadic``,
  and ``dynamic_name``.

* The following ``Twig\Node\Expression\FilterExpression`` attributes are
  deprecated as of Twig 3.12: ``needs_charset``,  ``needs_environment``,
  ``needs_context``,  ``arguments``,  ``callable``,  ``is_variadic``,
  and ``dynamic_name``.

* The following ``Twig\Node\Expression\TestExpression`` attributes are
  deprecated as of Twig 3.12: ``arguments``,  ``callable``,  ``is_variadic``,
  and ``dynamic_name``.

* The ``MethodCallExpression`` class is deprecated as of Twig 3.15, use
  ``MacroReferenceExpression`` instead.

* The ``Twig\Node\Expression\TempNameExpression`` class is deprecated as of
  Twig 3.15; use ``Twig\Node\Expression\Variable\LocalVariable`` instead.

* The ``Twig\Node\Expression\NameExpression`` class is deprecated as of Twig
  3.15; use ``Twig\Node\Expression\Variable\ContextVariable`` instead.

* The ``Twig\Node\Expression\AssignNameExpression`` class is deprecated as of
  Twig 3.15; use ``Twig\Node\Expression\Variable\AssignContextVariable``
  instead.

* Node implementations that use ``echo`` or ``print`` should use ``yield``
  instead; all Node implementations should use the
  ``#[\Twig\Attribute\YieldReady]`` attribute on their class once they've been
  made ready for ``yield``; the ``use_yield`` Environment option can be turned
  on when all nodes use the ``#[\Twig\Attribute\YieldReady]`` attribute.

 * The ``Twig\Node\InlinePrint`` class is deprecated as of Twig 3.16 with no
   replacement.

 * The ``Twig\Node\Expression\NullCoalesceExpression`` class is deprecated as
   of Twig 3.17, use ``Twig\Node\Expression\Binary\NullCoalesceBinary``
   instead.

 * The ``Twig\Node\Expression\ConditionalExpression`` class is deprecated as of
   Twig 3.17, use ``Twig\Node\Expression\Ternary\ConditionalTernary`` instead.

 * The ``is_defined_test`` attribute is deprecated as of Twig 3.21, use
   ``Twig\Node\Expression\SupportDefinedTestInterface`` instead.

* Instantiating ``Twig\Node\Node`` directly is deprecated as of Twig 3.15. Use
  ``EmptyNode`` or ``Nodes`` instead depending on the use case. The
  ``Twig\Node\Node`` class will be abstract in Twig 4.0.

* Not passing ``AbstractExpression`` arguments to the following ``Node`` class
  constructors is deprecated as of Twig 3.15:

  * ``AbstractBinary``
  * ``AbstractUnary``
  * ``BlockReferenceExpression``
  * ``TestExpression``
  * ``DefinedTest``
  * ``FilterExpression``
  * ``RawFilter``
  * ``DefaultFilter``
  * ``InlinePrint``
  * ``NullCoalesceExpression``

Node Visitors
-------------

* The ``Twig\NodeVisitor\AbstractNodeVisitor`` class is deprecated, implement the
  ``Twig\NodeVisitor\NodeVisitorInterface`` interface instead.

* The ``Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER`` and the
  ``Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_TEXT_NODES`` options are
  deprecated as of Twig 3.12 and will be removed in Twig 4.0; they don't do
  anything anymore.

Parser
------

* The following methods from ``Twig\Parser`` are deprecated as of Twig 3.12:
  ``getBlockStack()``, ``hasBlock()``, ``getBlock()``, ``hasMacro()``,
  ``hasTraits()``, ``getParent()``.

* Passing ``null`` to ``Twig\Parser::setParent()`` is deprecated as of Twig
  3.12.

* Passing a non-``AbstractExpression`` node to ``Twig\Parser::setParent()`` is
  deprecated as of Twig 3.24; the method will require an ``AbstractExpression``
  instance in Twig 4.0.

* Passing non-``AbstractExpression`` nodes to
  ``Twig\Node\Expression\Binary\MatchesBinary`` constructor is deprecated as of
  Twig 3.24; the constructor will require an ``AbstractExpression`` instance in Twig
  4.0.

* The ``Twig\Parser::getExpressionParser()`` method is deprecated as of Twig
  3.21, use ``Twig\Parser::parseExpression()`` instead.

* The ``Twig\ExpressionParser`` class is deprecated as of Twig 3.21:

  * ``parseExpression()``, use ``Parser::parseExpression()``
  * ``parsePrimaryExpression()``, use ``Parser::parseExpression()``
  * ``parseStringExpression()``, use ``Parser::parseExpression()``
  * ``parseHashExpression()``, use ``Parser::parseExpression()``
  * ``parseMappingExpression()``, use ``Parser::parseExpression()``
  * ``parseArrayExpression()``, use ``Parser::parseExpression()``
  * ``parseSequenceExpression()``, use ``Parser::parseExpression()``
  * ``parsePostfixExpression``
  * ``parseSubscriptExpression``
  * ``parseFilterExpression``
  * ``parseFilterExpressionRaw``
  * ``parseArguments()``, use ``Twig\ExpressionParser\Infix\ArgumentsTrait::parseNamedArguments()``
  * ``parseAssignmentExpression``, use ``AbstractTokenParser::parseAssignmentExpression``
  * ``parseMultitargetExpression``
  * ``parseOnlyArguments()``, use ``Twig\ExpressionParser\Infix\ArgumentsTrait::parseNamedArguments()``

Token
-----

* Not passing a ``Source`` instance to ``Twig\TokenStream`` constructor is
  deprecated as of Twig 3.16.

* The ``Token::getType()`` method is deprecated as of Twig 3.19, use
  ``Token::test()`` instead.

* The ``Token::ARROW_TYPE`` constant is deprecated as of Twig 3.21, the arrow
  ``=>`` is now an operator (``Token::OPERATOR_TYPE``).

* The ``Token::PUNCTUATION_TYPE`` with values ``(``, ``[``, ``|``, ``.``,
  ``?``, or ``?:`` are now of the ``Token::OPERATOR_TYPE`` type.

Templates
---------

* The method ``Template::loadTemplate()`` is deprecated.
* Passing ``Twig\Template`` instances to Twig public API is deprecated (like
  in ``Environment::resolveTemplate()`` and ``Environment::load()``); pass
  instances of ``Twig\TemplateWrapper`` instead.

Filters
-------

* The ``spaceless`` filter is deprecated as of Twig 3.12 and will be removed in
  Twig 4.0.

Sandbox
-------

* Having the ``extends`` and ``use`` tags allowed by default in a sandbox is
  deprecated as of Twig 3.12. You will need to explicitly allow them if needed
  in 4.0.

* Deprecate the ``sandbox`` tag, use the ``sandboxed`` option of the
  ``include`` function instead:

  Before::

    {% sandbox %}
      {% include 'user_defined.html.twig' %}
    {% endsandbox %}

  After::

    {{ include('user_defined.html.twig', sandboxed: true) }}

Testing Utilities
-----------------

* Implementing the data provider method ``Twig\Test\NodeTestCase::getTests()``
  is deprecated as of Twig 3.13. Instead, implement the static data provider
  ``provideTests()``.

* In order to make their functionality available for static data providers, the
  helper methods ``getVariableGetter()`` and ``getAttributeGetter()`` on
  ``Twig\Test\NodeTestCase`` have been deprecated. Call the new methods
  ``createVariableGetter()`` and ``createAttributeGetter()`` instead.

* The method ``Twig\Test\NodeTestCase::getEnvironment()`` is considered final
  as of Twig 3.13. If you want to override how the Twig environment is
  constructed, override ``createEnvironment()`` instead.

* The method ``getFixturesDir()`` on ``Twig\Test\IntegrationTestCase`` is
  deprecated, implement the new static method ``getFixturesDirectory()``
  instead, which will be abstract in 4.0.

* The data providers ``getTests()`` and ``getLegacyTests()`` on
  ``Twig\Test\IntegrationTestCase`` are considered final as of Twig 3.13.

Environment
-----------

* The ``Twig\Environment::mergeGlobals()`` method is deprecated as of Twig 3.14
  and will be removed in Twig 4.0:

  Before::

      $context = $twig->mergeGlobals($context);

  After::

      $context += $twig->getGlobals();

Functions/Filters/Tests
-----------------------

* The ``deprecated``, ``deprecating_package``, ``alternative`` options on Twig
  functions/filters/Tests are deprecated as of Twig 3.15, and will be removed
  in Twig 4.0. Use the ``deprecation_info`` option instead:

  Before::

      $twig->addFunction(new TwigFunction('upper', 'upper', [
          'deprecated' => '3.12', 'deprecating_package' => 'twig/twig',
      ]));

  After::

      $twig->addFunction(new TwigFunction('upper', 'upper', [
          'deprecation_info' => new DeprecatedCallableInfo('twig/twig', '3.12'),
      ]));

* For variadic arguments, use snake-case for the argument name to ease the
  transition to 4.0.

* Passing a ``string`` or an ``array`` to Twig callable arguments accepting
  arrow functions is deprecated as of Twig 3.15; these arguments will have a
  ``\Closure`` type hint in 4.0.

* Returning ``null`` from ``TwigFilter::getSafe()`` and
  ``TwigFunction::getSafe()`` is deprecated as of Twig 3.16; return ``[]``
  instead.

Operators
---------

* An operator precedence must be part of the [0, 512] range as of Twig 3.21.

* The ``.`` operator allows accessing class constants as of Twig 3.15.
  This can be a BC break if you don't use UPPERCASE constant names.

* Using ``~`` in an expression with the ``+`` or ``-`` operators without using
  parentheses to clarify precedence triggers a deprecation as of Twig 3.15 (in
  Twig 4.0, ``+`` / ``-`` will have a higher precedence than ``~``).

  For example, the following expression will trigger a deprecation in Twig 3.15::

    {{ '42' ~ 1 + 41 }}

  To avoid the deprecation, wrap the concatenation in parentheses to clarify
  the precedence::

    {{ ('42' ~ 1) + 41 }} {# this is equivalent to what Twig 3.x does without the parentheses #}

    {# or #}

    {{ '42' ~ (1 + 41) }} {# this is equivalent to what Twig 4.x will do without the parentheses #}

* Using ``??`` without explicit parentheses to clarify precedence triggers a
  deprecation as of Twig 3.15 (in Twig 4.0, ``??`` will have the lowest
  precedence).

  For example, the following expression will trigger a deprecation in Twig 3.15::

    {{ 'notnull' ?? 'foo' ~ '_bar' }}

  To avoid the deprecation, wrap the ``??`` expression in parentheses to clarify
  the precedence::

    {{ ('notnull' ?? 'foo') ~ '_bar' }} {# this is equivalent to what Twig 3.x does without the parentheses #}

    {# or #}

    {{ 'notnull' ?? ('foo' ~ '_bar') }} {# this is equivalent to what Twig 4.x will do without the parentheses #}

* Using the ``not`` unary operator in an expression with ``*``, ``/``, ``//``,
  or ``%`` operators without explicit parentheses to clarify precedence
  triggers a deprecation as of Twig 3.15 (in Twig 4.0, ``not`` will have a
  higher precedence than ``*``, ``/``, ``//``, and ``%``).

  For example, the following expression will trigger a deprecation in Twig 3.15::

    {{ not 1 * 2 }}

  To avoid the deprecation, wrap the concatenation in parentheses to clarify
  the precedence::

    {{ (not 1 * 2) }} {# this is equivalent to what Twig 3.x does without the parentheses #}

    {# or #}

    {{ (not 1) * 2 }} {# this is equivalent to what Twig 4.x will do without the parentheses #}

* Using the ``|`` operator in an expression with ``+`` or ``-`` without explicit
  parentheses to clarify precedence triggers a deprecation as of Twig 3.21 (in
  Twig 4.0, ``|`` will have a higher precedence than ``+`` and ``-``).

  For example, the following expression will trigger a deprecation in Twig 3.21::

    {{ -1|abs }}

  To avoid the deprecation, add parentheses to clarify the precedence::

    {{ -(1|abs) }} {# this is equivalent to what Twig 3.x does without the parentheses #}

    {# or #}

    {{ (-1)|abs }} {# this is equivalent to what Twig 4.x will do without the parentheses #}

* The ``Twig\Extension\ExtensionInterface::getOperators()`` method is deprecated
  as of Twig 3.21, use ``Twig\Extension\ExtensionInterface::getExpressionParsers()``
  instead:

  Before::

      public function getOperators(): array {
          return [
              'not' => [
                  'precedence' => 10,
                  'class' => NotUnary::class,
              ],
          ];
      }

  After::

      public function getExpressionParsers(): array {
          return [
              new UnaryOperatorExpressionParser(NotUnary::class, 'not', 10),
          ];
      }

* The ``Twig\OperatorPrecedenceChange`` class is deprecated as of Twig 3.21,
  use ``Twig\ExpressionParser\PrecedenceChange`` instead.

* Not implementing the ``getOperatorTokens()`` method in
  ``Twig\ExpressionParser\ExpressionParserInterface`` implementations is
  deprecated as of Twig 3.24. This method will be added to the interface in
  Twig 4.0. It returns the operator token strings that the expression parser
  handles (used by the Lexer and the parser registry). If your custom
  expression parser extends ``Twig\ExpressionParser\AbstractExpressionParser``,
  the default implementation returns ``[$this->getName(), ...$this->getAliases()]``.
  Override it if your parser doesn't handle operator tokens (return ``[]``) or if
  the operator tokens differ from the parser name.


================================================
FILE: doc/filters/abs.rst
================================================
``abs``
=======

The ``abs`` filter returns the absolute value.

.. code-block:: twig

    {# number = -5 #}

    {{ number|abs }}

    {# outputs 5 #}

.. note::

    Internally, Twig uses the PHP `abs`_ function.

.. _`abs`: https://www.php.net/abs


================================================
FILE: doc/filters/batch.rst
================================================
``batch``
=========

The ``batch`` filter "batches" items by returning a list of lists with the
given number of items. A second parameter can be provided and used to fill in
missing items:

.. code-block:: html+twig

    {% set items = ['a', 'b', 'c', 'd'] %}

    <table>
        {% for row in items|batch(3, 'No item') %}
            <tr>
                {% for index, column in row %}
                    <td>{{ index }} - {{ column }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
    </table>

The above example will be rendered as:

.. code-block:: html+twig

    <table>
        <tr>
            <td>0 - a</td>
            <td>1 - b</td>
            <td>2 - c</td>
        </tr>
        <tr>
            <td>3 - d</td>
            <td>4 - No item</td>
            <td>5 - No item</td>
        </tr>
    </table>

If you choose to set the third parameter ``preserve_keys`` to ``false``, the keys will be reset in each loop.

.. code-block:: html+twig

    {% set items = ['a', 'b', 'c', 'd'] %}

    <table>
        {% for row in items|batch(3, 'No item', false) %}
            <tr>
                {% for index, column in row %}
                    <td>{{ index }} - {{ column }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
    </table>

The above example will be rendered as:

.. code-block:: html+twig

    <table>
        <tr>
            <td>0 - a</td>
            <td>1 - b</td>
            <td>2 - c</td>
        </tr>
        <tr>
            <td>0 - d</td>
            <td>1 - No item</td>
            <td>2 - No item</td>
        </tr>
    </table>

Arguments
---------

* ``size``: The size of the batch; fractional numbers will be rounded up
* ``fill``: Used to fill in missing items
* ``preserve_keys``: Whether to preserve keys or not (defaults to ``true``)


================================================
FILE: doc/filters/capitalize.rst
================================================
``capitalize``
==============

The ``capitalize`` filter capitalizes a value. The first character will be
uppercase, all others lowercase:

.. code-block:: twig

    {{ 'my first car'|capitalize }}

    {# outputs 'My first car' #}


================================================
FILE: doc/filters/column.rst
================================================
``column``
==========

The ``column`` filter returns the values from a single column in the input
array.

.. code-block:: twig

    {% set items = [{ 'fruit' : 'apple'}, {'fruit' : 'orange' }] %}

    {% set fruits = items|column('fruit') %}

    {# fruits now contains ['apple', 'orange'] #}

.. note::

    Internally, Twig uses the PHP `array_column`_ function.

Arguments
---------

* ``name``: The column name to extract

.. _`array_column`: https://www.php.net/array_column


================================================
FILE: doc/filters/convert_encoding.rst
================================================
``convert_encoding``
====================

The ``convert_encoding`` filter converts a string from one encoding to
another. The first argument is the expected output charset and the second one
is the input charset:

.. code-block:: twig

    {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}

.. note::

    This filter relies on the `iconv`_ extension.

Arguments
---------

* ``to``:   The output charset
* ``from``: The input charset

.. _`iconv`: https://www.php.net/iconv


================================================
FILE: doc/filters/country_name.rst
================================================
``country_name``
================

The ``country_name`` filter returns the country name given its ISO-3166 code:

.. code-block:: twig

    {# France #}
    {{ 'FR'|country_name }}

By default, the filter uses the current locale. You can pass it explicitly:

.. code-block:: twig

    {# États-Unis #}
    {{ 'US'|country_name('fr') }}

    {# 美國 #}
    {{ 'US'|country_name('zh_Hant_HK') }}

.. note::

    The ``country_name`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());

Arguments
---------

* ``locale``: The locale code as defined in `RFC 5646`_

.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646


================================================
FILE: doc/filters/currency_name.rst
================================================
``currency_name``
=================

The ``currency_name`` filter returns the currency name given its ISO 4217 code:

.. code-block:: twig

    {# Euro #}
    {{ 'EUR'|currency_name }}

    {# Japanese Yen #}
    {{ 'JPY'|currency_name }}

By default, the filter uses the current locale. You can pass it explicitly:

.. code-block:: twig

    {# yen japonais #}
    {{ 'JPY'|currency_name('fr_FR') }}

.. note::

    The ``currency_name`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());

Arguments
---------

* ``locale``: The locale code as defined in `RFC 5646`_

.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646


================================================
FILE: doc/filters/currency_symbol.rst
================================================
``currency_symbol``
===================

The ``currency_symbol`` filter returns the currency symbol given its ISO 4217
code:

.. code-block:: twig

    {# € #}
    {{ 'EUR'|currency_symbol }}

    {# ¥ #}
    {{ 'JPY'|currency_symbol }}

By default, the filter uses the current locale. You can pass it explicitly:

.. code-block:: twig

    {# ¥ #}
    {{ 'JPY'|currency_symbol('fr') }}

.. note::

    The ``currency_symbol`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());

Arguments
---------

* ``locale``: The locale code as defined in `RFC 5646`_

.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646


================================================
FILE: doc/filters/data_uri.rst
================================================
``data_uri``
============

The ``data_uri`` filter generates a URL using the data scheme as defined in
`RFC 2397`_:

.. code-block:: html+twig

    {{ image_data|data_uri }}

    {{ source('path_to_image')|data_uri }}

    {# force the mime type, disable the guessing of the mime type #}
    {{ image_data|data_uri(mime: "image/svg") }}

    {# also works with plain text #}
    {{ '<b>foobar</b>'|data_uri(mime: "text/html") }}

    {# add some extra parameters #}
    {{ '<b>foobar</b>'|data_uri(mime: "text/html", parameters: {charset: "ascii"}) }}

.. note::

    The ``data_uri`` filter is part of the ``HtmlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/html-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Html\HtmlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new HtmlExtension());

.. note::

    The filter does not perform any length validation on purpose (limit depends
    on the usage context), validation should be done before calling this filter.

Arguments
---------

* ``mime``: The mime type
* ``parameters``: A mapping of parameters

.. _RFC 2397: https://tools.ietf.org/html/rfc2397


================================================
FILE: doc/filters/date.rst
================================================
``date``
========

The ``date`` filter formats a date to a given format:

.. code-block:: twig

    {{ post.published_at|date("m/d/Y") }}

The format specifier is the same as supported by `date`_,
except when the filtered data is of type `DateInterval`_, when the format must conform to
`DateInterval::format`_ instead.

The ``date`` filter accepts strings (it must be in a format supported by the
`strtotime`_ function), `DateTime`_ instances, or `DateInterval`_ instances. For
instance, to display the current date, filter the word "now":

.. code-block:: twig

    {{ "now"|date("m/d/Y") }}

To escape words and characters in the date format use ``\\`` in front of each
character:

.. code-block:: twig

    {{ post.published_at|date("F jS \\a\\t g:ia") }}

If the value passed to the ``date`` filter is ``null``, it will return the
current date by default. If an empty string is desired instead of the current
date, use a ternary operator:

.. code-block:: twig

    {{ post.published_at is empty ? "" : post.published_at|date("m/d/Y") }}

If no format is provided, Twig will use the default one: ``F j, Y H:i``. This
default can be changed by calling the ``setDateFormat()`` method on the
``core`` extension instance. The first argument is the default format for
dates and the second one is the default format for date intervals::

    $twig = new \Twig\Environment($loader);
    $twig->getExtension(\Twig\Extension\CoreExtension::class)->setDateFormat('d/m/Y', '%d days');

Timezone
--------

By default, the date is displayed by applying the default timezone (the one
specified in php.ini or declared in Twig -- see below), but you can override
it by explicitly specifying a supported `timezone`_:

.. code-block:: twig

    {{ post.published_at|date("m/d/Y", "Europe/Paris") }}

If the date is already a DateTime object, and if you want to keep its current
timezone, pass ``false`` as the timezone value:

.. code-block:: twig

    {{ post.published_at|date("m/d/Y", false) }}

The default timezone can also be set globally by calling ``setTimezone()``::

    $twig = new \Twig\Environment($loader);
    $twig->getExtension(\Twig\Extension\CoreExtension::class)->setTimezone('Europe/Paris');

Arguments
---------

* ``format``:   The date format (default format is ``F j, Y H:i``, which will render as ``January 11, 2024 15:17``)
* ``timezone``: The date timezone

.. _`strtotime`:            https://www.php.net/strtotime
.. _`DateTime`:             https://www.php.net/DateTime
.. _`DateInterval`:         https://www.php.net/DateInterval
.. _`date`:                 https://www.php.net/date
.. _`DateInterval::format`: https://www.php.net/DateInterval.format
.. _`timezone`:            https://www.php.net/manual/en/timezones.php


================================================
FILE: doc/filters/date_modify.rst
================================================
``date_modify``
===============

The ``date_modify`` filter modifies a date with a given modifier string:

.. code-block:: twig

    {{ post.published_at|date_modify("+1 day")|date("m/d/Y") }}

The ``date_modify`` filter accepts strings (it must be in a format supported
by the `strtotime`_ function) or `DateTime`_ instances. You can combine
it with the :doc:`date<date>` filter for formatting.

Arguments
---------

* ``modifier``: The modifier

.. _`strtotime`: https://www.php.net/strtotime
.. _`DateTime`:  https://www.php.net/DateTime


================================================
FILE: doc/filters/default.rst
================================================
``default``
===========

The ``default`` filter returns the passed default value if the value is
undefined or empty, otherwise the value of the variable:

.. code-block:: twig

    {{ var|default('var is not defined') }}

    {{ user.name|default('name item on user is not defined') }}

    {{ user['name']|default('name item on user is not defined') }}

    {{ ''|default('passed var is empty')  }}

When using the ``default`` filter on an expression that uses variables in some
method calls, be sure to use the ``default`` filter whenever a variable can be
undefined:

.. code-block:: twig

    {{ user.value(name|default('username'))|default('not defined') }}
    
Using the ``default`` filter on a boolean variable might trigger unexpected
behavior, as ``false`` is treated as an empty value. Consider using ``??``
instead:

.. code-block:: twig

    {% set value = false %}
    {{ value|default(true) }} {# true #}
    {{ value ?? true }} {# false #}

.. note::

    Read the documentation for the :doc:`defined<../tests/defined>` and
    :doc:`empty<../tests/empty>` tests to learn more about their semantics.

Arguments
---------

* ``default``: The default value


================================================
FILE: doc/filters/escape.rst
================================================
``escape``
==========

The ``escape`` filter escapes a string using strategies that depend on the
context.

By default, it uses the HTML escaping strategy:

.. code-block:: html+twig

    <p>
        {{ user.username|escape }}
    </p>

For convenience, the ``e`` filter is defined as an alias:

.. code-block:: html+twig

    <p>
        {{ user.username|e }}
    </p>

The ``escape`` filter can also be used in other contexts than HTML thanks to
an optional argument which defines the escaping strategy to use:

.. code-block:: twig

    {{ user.username|e }}
    {# is equivalent to #}
    {{ user.username|e('html') }}

And here is how to escape variables included in JavaScript code:

.. code-block:: twig

    {{ user.username|escape('js') }}
    {{ user.username|e('js') }}

The ``escape`` filter supports the following escaping strategies for HTML
documents:

* ``html``: escapes a string for the **HTML body** context,
  or for HTML attributes values **inside quotes**.

* ``js``: escapes a string for the **JavaScript** context. This is intended for
  use in JavaScript or JSON strings, and encodes values using backslash escape
  sequences.

* ``css``: escapes a string for the **CSS** context. CSS escaping can be
  applied to any string being inserted into CSS and escapes everything except
  alphanumerics.

* ``url``: escapes a string for the **URI or parameter** contexts. This should
  not be used to escape an entire URI; only a subcomponent being inserted.

* ``html_attr``: escapes a string when used as an **HTML attribute** name, and
  also when used as the value of an HTML attribute **without quotes**
  (e.g. ``data-attribute={{ some_value }}``).

* ``html_attr_relaxed``: like ``html_attr``, but **does not** escape the ``@``, ``:``,
  ``[`` and ``]`` characters. You may want to use this in combination with front-end
  frameworks that use attribute names like ``v-bind:href`` or ``@click``. But, be
  aware that in some processing contexts like XML, characters like the colon ``:``
  may have meaning like for XML namespace separation.

.. versionadded:: 3.24

    The ``html_attr_relaxed`` strategy has been added in 3.23.

Note that doing contextual escaping in HTML documents is hard and choosing the
right escaping strategy depends on a lot of factors. Please, read related
documentation like `the OWASP prevention cheat sheet
<https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.md>`_
to learn more about this topic.

.. note::

    Internally, ``escape`` uses the PHP native `htmlspecialchars`_ function
    for the HTML escaping strategy.

.. caution::

    When using automatic escaping, Twig tries to not double-escape a variable
    when the automatic escaping strategy is the same as the one applied by the
    escape filter; but that does not work when using a variable as the
    escaping strategy:

    .. code-block:: twig

        {% set strategy = 'html' %}

        {% autoescape 'html' %}
            {{ var|escape('html') }}   {# won't be double-escaped #}
            {{ var|escape(strategy) }} {# will be double-escaped #}
        {% endautoescape %}

    When using a variable as the escaping strategy, you should disable
    automatic escaping:

    .. code-block:: twig

        {% set strategy = 'html' %}

        {% autoescape 'html' %}
            {{ var|escape(strategy)|raw }} {# won't be double-escaped #}
        {% endautoescape %}

.. tip::

    The ``html_attr`` escaping strategy can be useful when you need to escape a
    **dynamic HTML attribute name**:

    .. code-block:: html+twig

        <p {{ your_html_attr|e('html_attr') }}="attribute value">
    
    It can also be used for escaping a **dynamic HTML attribute value** if it is
    not quoted, but this is **less performant**. Instead, it is recommended to
    quote the HTML attribute value and use the ``html`` escaping strategy:

    .. code-block:: html+twig

        <p data-content="{{ content|e('html') }}">

        {# this is equivalent, but less performant #}
        <p data-content={{ content|e('html_attr') }}>

Custom Escapers
---------------

.. versionadded:: 3.10

    The ``EscaperRuntime`` class has been added in 3.10. On previous versions,
    you can define custom escapers by calling the ``setEscaper()`` method on
    the escaper extension instance. The first argument is the escaper strategy
    (to be used in the ``escape`` call) and the second one must be a valid PHP
    callable::

        use Twig\Extension\EscaperExtension;

        $twig = new \Twig\Environment($loader);
        $twig->getExtension(EscaperExtension::class)->setEscaper('csv', 'csv_escaper');

    When called by Twig, the callable receives the Twig environment instance,
    the string to escape, and the charset.

You can define custom escapers by calling the ``setEscaper()`` method on the
escaper runtime instance. It accepts two arguments: the strategy name and a PHP
callable that accepts a string to escape and the charset::

    use Twig\Runtime\EscaperRuntime;

    $twig = new \Twig\Environment($loader);
    $escaper = fn ($string, $charset) => $string;
    $twig->getRuntime(EscaperRuntime::class)->setEscaper('identity', $escaper);

    # Usage in a template:
    # {{ 'Twig'|escape('identity') }}

.. note::

    Built-in escapers cannot be overridden mainly because they should be
    considered as the final implementation and also for better performance.

Arguments
---------

* ``strategy``: The escaping strategy
* ``charset``:  The string charset

.. _`htmlspecialchars`: https://www.php.net/htmlspecialchars


================================================
FILE: doc/filters/filter.rst
================================================
``filter``
==========

The ``filter`` filter filters elements of a sequence or a mapping using an arrow
function. The arrow function receives the value of the sequence or mapping:

.. code-block:: twig

    {% set sizes = [34, 36, 38, 40, 42] %}

    {{ sizes|filter(v => v > 38)|join(', ') }}
    {# output 40, 42 #}

Combined with the ``for`` tag, it allows you to filter the items to iterate over:

.. code-block:: twig

    {% for v in sizes|filter(v => v > 38) -%}
        {{ v }}
    {% endfor %}
    {# output 40 42 #}

It also works with mappings:

.. code-block:: twig

    {% set sizes = {
        xs: 34,
        s:  36,
        m:  38,
        l:  40,
        xl: 42,
    } %}

    {% for k, v in sizes|filter(v => v > 38) -%}
        {{ k }} = {{ v }}
    {% endfor %}
    {# output l = 40 xl = 42 #}

The arrow function also receives the key as a second argument:

.. code-block:: twig

    {% for k, v in sizes|filter((v, k) => v > 38 and k != "xl") -%}
        {{ k }} = {{ v }}
    {% endfor %}
    {# output l = 40 #}

Note that the arrow function has access to the current context.

Arguments
---------

* ``array``: The sequence or mapping
* ``arrow``: The arrow function


================================================
FILE: doc/filters/find.rst
================================================
``find``
========

.. versionadded:: 3.11

    The ``find`` filter was added in Twig 3.11.

The ``find`` filter returns the first element of a sequence matching an arrow
function. The arrow function receives the value of the sequence:

.. code-block:: twig

    {% set sizes = [34, 36, 38, 40, 42] %}

    {{ sizes|find(v => v > 38) }}
    {# output 40 #}

It also works with mappings:

.. code-block:: twig

    {% set sizes = {
        xxs: 32,
        xs:  34,
        s:   36,
        m:   38,
        l:   40,
        xl:  42,
    } %}

    {{ sizes|find(v => v > 38) }}

    {# output 40 #}

The arrow function also receives the key as a second argument:

.. code-block:: twig

    {{ sizes|find((v, k) => 's' not in k) }}

    {# output 38 #}

Note that the arrow function has access to the current context:

.. code-block:: twig

    {% set my_size = 39 %}

    {{ sizes|find(v => v >= my_size) }}

    {# output 40 #}

Arguments
---------

* ``array``: The sequence or mapping
* ``arrow``: The arrow function


================================================
FILE: doc/filters/first.rst
================================================
``first``
=========

The ``first`` filter returns the first "element" of a sequence, a mapping, or
a string:

.. code-block:: twig

    {{ [1, 2, 3, 4]|first }}
    {# outputs 1 #}

    {{ {a: 1, b: 2, c: 3, d: 4}|first }}
    {# outputs 1 #}

    {{ '1234'|first }}
    {# outputs 1 #}

.. note::

    It also works with objects implementing the `Traversable`_ interface.

.. _`Traversable`: https://www.php.net/manual/en/class.traversable.php


================================================
FILE: doc/filters/format.rst
================================================
``format``
==========

The ``format`` filter formats a given string by replacing the placeholders
(placeholders follows the `sprintf`_ notation):

.. code-block:: twig

    {% set fruit = 'apples' %}
    {{ "I like %s and %s."|format(fruit, "oranges") }}

    {# outputs I like apples and oranges #}

.. seealso::

    :doc:`replace<replace>`

.. _`sprintf`: https://www.php.net/sprintf


================================================
FILE: doc/filters/format_currency.rst
================================================
``format_currency``
===================

The ``format_currency`` filter formats a number as a currency:

.. code-block:: twig

    {# €1,000,000.00 #}
    {{ '1000000'|format_currency('EUR') }}

You can pass attributes to tweak the output:

.. code-block:: twig

    {# €12.34 #}
    {{ '12.345'|format_currency('EUR', {rounding_mode: 'floor'}) }}

    {# €1,000,000.0000 #}
    {{ '1000000'|format_currency('EUR', {fraction_digit: 4}) }}

The list of supported options:

* ``grouping_used``: Specifies whether to use grouping separator for thousands::

        {# €1,234,567.89 #}
        {{ 1234567.89 | format_currency('EUR', {grouping_used:true}, 'en') }}

* ``decimal_always_shown``: Specifies whether to always show the decimal part, even if it's zero::

        {# €123.00 #}
        {{ 123 | format_currency('EUR', {decimal_always_shown:true}, 'en') }}

* ``max_integer_digit``:
* ``min_integer_digit``:
* ``integer_digit``: Define constraints on the integer part::

        {# €345.68 #}
        {{ 12345.6789 | format_currency('EUR', {max_integer_digit:3, min_integer_digit:2}, 'en') }}

* ``max_fraction_digit``:
* ``min_fraction_digit``:
* ``fraction_digit``: Define constraints on the fraction part::

        {# €123.46 #}
        {{ 123.456789 | format_currency('EUR', {max_fraction_digit:2, min_fraction_digit:1}, 'en') }}

* ``multiplier``: Multiplies the value before formatting::

        {# €123,000.00 #}
        {{ 123 | format_currency('EUR', {multiplier:1000}, 'en') }}

* ``grouping_size``:
* ``secondary_grouping_size``: Set the size of the primary and secondary grouping separators::

        {# €1,23,45,678.00 #}
        {{ 12345678 | format_currency('EUR', {grouping_size:3, secondary_grouping_size:2}, 'en') }}

* ``rounding_mode``:
* ``rounding_increment``: Control rounding behavior, here is a list of all rounding_mode available:

    * ``ceil``: Ceiling rounding
    * ``floor``: Floor rounding
    * ``down``: Rounding towards zero
    * ``up``: Rounding away from zero
    * ``half_even``: Round halves to the nearest even integer
    * ``half_up``: Round halves up
    * ``half_down``: Round halves down

    .. code-block:: twig

      {# €123.50 #}
      {{ 123.456 | format_currency('EUR', {rounding_mode:'ceiling', rounding_increment:0.05}, 'en') }}

* ``format_width``:
* ``padding_position``: Set width and padding for the formatted number, here is a list of all padding_position available:

    * ``before_prefix``: Pad before the currency symbol
    * ``after_prefix``: Pad after the currency symbol
    * ``before_suffix``: Pad before the suffix (currency symbol)
    * ``after_suffix``: Pad after the suffix (currency symbol)

    .. code-block:: twig

        {# €123.00 #}
        {{ 123 | format_currency('EUR', {format_width:10, padding_position:'before_suffix'}, 'en') }}

* ``significant_digits_used``:
* ``min_significant_digits_used``:
* ``max_significant_digits_used``: Control significant digits in formatting::

        {# €123.4568 #}
        {{ 123.456789 | format_currency('EUR', {significant_digits_used:true, min_significant_digits_used:4, max_significant_digits_used:7}, 'en') }}

* ``lenient_parse``: If true, allows lenient parsing of the input::

        {# €123.00 #}
        {{ 123 | format_currency('EUR', {lenient_parse:true}, 'en') }}

By default, the filter uses the current locale. You can pass it explicitly::

    {# 1.000.000,00 € #}
    {{ '1000000'|format_currency('EUR', locale: 'de') }}

.. note::

    The ``format_currency`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());

Arguments
---------

* ``currency``: The currency (ISO 4217 code)
* ``attrs``: A map of attributes
* ``locale``: The locale code as defined in `RFC 5646`_

.. note::

    Internally, Twig uses the PHP `NumberFormatter::formatCurrency`_ function.

.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646
.. _`NumberFormatter::formatCurrency`: https://www.php.net/manual/en/numberformatter.formatcurrency.php


================================================
FILE: doc/filters/format_date.rst
================================================
``format_date``
===============

The ``format_date`` filter formats a date. It behaves in the exact same way as
the :doc:`format_datetime<format_datetime>` filter, but without the time.

.. note::

    The ``format_date`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());

Arguments
---------

* ``locale``: The locale code as defined in `RFC 5646`_
* ``dateFormat``: The date format
* ``pattern``: A date time pattern
* ``timezone``: The date timezone
* ``calendar``: The calendar ("gregorian" by default)

.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646


================================================
FILE: doc/filters/format_datetime.rst
================================================
``format_datetime``
===================

The ``format_datetime`` filter formats a date time:

.. code-block:: twig

    {# Aug 7, 2019, 11:39:12 PM #}
    {{ '2019-08-07 23:39:12'|format_datetime() }}

.. note::

    The ``format_datetime`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());


Format
------

You can tweak the output for the date part and the time part:

.. code-block:: twig

    {# 23:39 #}
    {{ '2019-08-07 23:39:12'|format_datetime('none', 'short', locale: 'fr') }}

    {# 07/08/2019 #}
    {{ '2019-08-07 23:39:12'|format_datetime('short', 'none', locale: 'fr') }}

    {# mercredi 7 août 2019 23:39:12 UTC #}
    {{ '2019-08-07 23:39:12'|format_datetime('full', 'full', locale: 'fr') }}

Supported values are: ``none``, ``short``, ``medium``, ``long``, and ``full``.

.. versionadded:: 3.6

    ``relative_short``, ``relative_medium``, ``relative_long``, and ``relative_full`` are also supported when running on
    PHP 8.0 and superior or when using a polyfill that define the ``IntlDateFormatter::RELATIVE_*`` constants and
    associated behavior.

For greater flexibility, you can even define your own pattern
(see the `ICU user guide`_ for supported patterns).

.. code-block:: twig

    {# 11 oclock PM, GMT #}
    {{ '2019-08-07 23:39:12'|format_datetime(pattern: "hh 'oclock' a, zzzz") }}

Locale
------

By default, the filter uses the current locale. You can pass it explicitly:

.. code-block:: twig

    {# 7 août 2019 23:39:12 #}
    {{ '2019-08-07 23:39:12'|format_datetime(locale: 'fr') }}

Timezone
--------

By default, the date is displayed by applying the default timezone (the one
specified in php.ini or declared in Twig -- see below), but you can override
it by explicitly specifying a timezone:

.. code-block:: twig

    {{ datetime|format_datetime(locale: 'en', timezone: 'Pacific/Midway') }}

If the date is already a DateTime object, and if you want to keep its current
timezone, pass ``false`` as the timezone value:

.. code-block:: twig

    {{ datetime|format_datetime(locale: 'en', timezone: false) }}

The default timezone can also be set globally by calling ``setTimezone()``::

    $twig = new \Twig\Environment($loader);
    $twig->getExtension(\Twig\Extension\CoreExtension::class)->setTimezone('Europe/Paris');

.. note::

    The ``format_datetime`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());

Arguments
---------

* ``locale``: The locale code as defined in `RFC 5646`_
* ``dateFormat``: The date format
* ``timeFormat``: The time format
* ``pattern``: A date time pattern
* ``timezone``: The date timezone name
* ``calendar``: The calendar ("gregorian" by default)

.. _ICU user guide: https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax
.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646


================================================
FILE: doc/filters/format_number.rst
================================================
``format_number``
=================

The ``format_number`` filter formats a number:

.. code-block:: twig

    {{ '12.345'|format_number }}

You can pass attributes to tweak the output:

.. code-block:: twig

    {# 12.34 #}
    {{ '12.345'|format_number({rounding_mode: 'floor'}) }}

    {# 1000000.0000 #}
    {{ '1000000'|format_number({fraction_digit: 4}) }}

The list of supported options:

* ``grouping_used``: Specifies whether to use grouping separator for thousands::

        {# 1,234,567.89 #}
        {{ 1234567.89|format_number({grouping_used:true}, locale: 'en') }}

* ``decimal_always_shown``: Specifies whether to always show the decimal part, even if it's zero::

        {# 123. #}
        {{ 123|format_number({decimal_always_shown:true}, locale: 'en') }}

* ``max_integer_digit``:
* ``min_integer_digit``:
* ``integer_digit``: Define constraints on the integer part::

        {# 345.679 #}
        {{ 12345.6789|format_number({max_integer_digit:3, min_integer_digit:2}, locale: 'en') }}

* ``max_fraction_digit``:
* ``min_fraction_digit``:
* ``fraction_digit``: Define constraints on the fraction part::

        {# 123.46 #}
        {{ 123.456789|format_number({max_fraction_digit:2, min_fraction_digit:1}, locale: 'en') }}

* ``multiplier``: Multiplies the value before formatting::

        {# 123,000 #}
        {{ 123|format_number({multiplier:1000}, locale: 'en') }}

* ``grouping_size``:
* ``secondary_grouping_size``: Set the size of the primary and secondary grouping separators::

        {# 1,23,45,678 #}
        {{ 12345678|format_number({grouping_size:3, secondary_grouping_size:2}, locale: 'en') }}

* ``rounding_mode``:
* ``rounding_increment``: Control rounding behavior, here is a list of all rounding_mode available:
    * ``ceil``: Ceiling rounding
    * ``floor``: Floor rounding
    * ``down``: Rounding towards zero
    * ``up``: Rounding away from zero
    * ``halfeven``: Round halves to the nearest even integer
    * ``halfup``: Round halves up
    * ``halfdown``: Round halves down

    .. code-block:: twig

        {# 123.5 #}
        {{ 123.456|format_number({rounding_mode:'ceiling', rounding_increment:0.05}, locale: 'en') }}

* ``format_width``:
* ``padding_position``: Set width and padding for the formatted number, here is a list of all padding_position available:
    * ``before_prefix``: Pad before the currency symbol
    * ``after_prefix``: Pad after the currency symbol
    * ``before_suffix``: Pad before the suffix (currency symbol)
    * ``after_suffix``: Pad after the suffix (currency symbol)

    .. code-block:: twig

        {# 123 #}
        {{ 123|format_number({format_width:10, padding_position:'before_suffix'}, locale: 'en') }}

* ``significant_digits_used``:
* ``min_significant_digits_used``:
* ``max_significant_digits_used``: Control significant digits in formatting::

        {# 123.4568 #}
        {{ 123.456789|format_number({significant_digits_used:true, min_significant_digits_used:4, max_significant_digits_used:7}, locale: 'en') }}

* ``lenient_parse``: If true, allows lenient parsing of the input::

        {# 123 #}
        {{ 123|format_number({lenient_parse:true}, locale: 'en') }}

Besides plain numbers, the filter can also format numbers in various styles::

    {# 1,234% #}
    {{ '12.345'|format_number(style: 'percent') }}

    {# twelve point three four five #}
    {{ '12.345'|format_number(style: 'spellout') }}

    {# 12 sec. #}
    {{ '12'|format_duration_number }}

The list of supported styles:

* ``decimal``::

        {# 1,234.568 #}
        {{ 1234.56789 | format_number(style: 'decimal', locale: 'en') }}

* ``currency``::

        {# $1,234.56 #}
        {{ 1234.56 | format_number(style: 'currency', locale: 'en') }}

* ``percent``::

        {# 12% #}
        {{ 0.1234 | format_number(style: 'percent', locale: 'en') }}

* ``scientific``::

        {# 1.23456789e+3 #}
        {{ 1234.56789 | format_number(style: 'scientific', locale: 'en') }}

* ``spellout``::

        {# one thousand two hundred thirty-four point five six seven eight nine #}
        {{ 1234.56789 | format_number(style: 'spellout', locale: 'en') }}

* ``ordinal``::

        {# 1st #}
        {{ 1 | format_number(style: 'ordinal', locale: 'en') }}

* ``duration``::

        {# 2:30:00 #}
        {{ 9000 | format_number(style: 'duration', locale: 'en') }}

As a shortcut, you can use the ``format_*_number`` filters by replacing ``*``
with a style::

    {# 1,234% #}
    {{ '12.345'|format_percent_number }}

    {# twelve point three four five #}
    {{ '12.345'|format_spellout_number }}

You can pass attributes to tweak the output::

    {# 12.3% #}
    {{ '0.12345'|format_percent_number({rounding_mode: 'floor', fraction_digit: 1}) }}

By default, the filter uses the current locale. You can pass it explicitly::

    {# 12,345 #}
    {{ '12.345'|format_number(locale: 'fr') }}

.. note::

    The ``format_number`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: sh

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: sh

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());

Arguments
---------

* ``locale``: The locale code as defined in `RFC 5646`_
* ``attrs``: A map of attributes
* ``style``: The style of the number output

.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646


================================================
FILE: doc/filters/format_time.rst
================================================
``format_time``
===============

The ``format_time`` filter formats a time. It behaves in the exact same way as
the :doc:`format_datetime<format_datetime>` filter, but without the date.

.. note::

    The ``format_time`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());

Arguments
---------

* ``locale``: The locale code as defined in `RFC 5646`_
* ``timeFormat``: The time format
* ``pattern``: A date time pattern
* ``timezone``: The date timezone
* ``calendar``: The calendar ("gregorian" by default)

.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646


================================================
FILE: doc/filters/html_attr_merge.rst
================================================
``html_attr_merge``
===================

.. _html_attr_merge:

.. versionadded:: 3.24

    The ``html_attr_merge`` filter was added in Twig 3.24.

The ``html_attr_merge`` filter merges multiple mappings that represent
HTML attribute values. Such mappings contain the names of the HTML attributes
as keys, and the corresponding values represent the attributes' values.

It is primarily designed for working with arrays that are passed to the
:ref:`html_attr` function. It closely resembles the :doc:`merge <../filters/merge>`
filter, but has different merge behavior for values that are iterables
themselves, as it will merge such values in turn.

The filter returns a new merged array:

.. code-block:: twig

    {% set base = {class: ['btn'], type: 'button'} %}
    {% set variant = {class: ['btn-primary'], disabled: true} %}

    {% set merged = base|html_attr_merge(variant) %}

    {# merged is now: {
        class: ['btn', 'btn-primary'],
        type: 'button',
        disabled: true
    } #}

The filter accepts multiple arrays as arguments and merges them from left to right:

.. code-block:: twig

    {% set merged = base|html_attr_merge(variant1, variant2, variant3) %}

A common use case is to build attribute mappings conditionally by merging multiple
parts based on conditions. To make this conditional merging more convenient, filter
arguments that are ``false``, ``null`` or empty arrays are ignored:

.. code-block:: twig

    {% set button_attrs = {
        type: 'button',
        class: ['btn']
    }|html_attr_merge(
        variant == 'primary' ? { class: ['btn-primary'] },
        variant == 'secondary' ? { class: ['btn-secondary'] },
        size == 'large' ? { class: ['btn-lg'] },
        size == 'small' ? { class: ['btn-sm'] },
        disabled ? { disabled: true, class: ['btn-disabled'] },
        loading ? { 'aria-busy': 'true', class: ['btn-loading'] },
    ) %}

    {# Example with variant='primary', size='large', disabled=false, loading=true:

       The false values (secondary variant, small size, disabled state) are ignored.

       button_attrs is:
       {
           type: 'button',
           class: ['btn', 'btn-primary', 'btn-lg', 'btn-loading'],
           'aria-busy': 'true'
       }
    #}

Merging Rules
-------------

The filter follows these rules when merging attribute values:

**Scalar values**: Later values override earlier ones.

.. code-block:: twig

    {% set result = {id: 'old'}|html_attr_merge({id: 'new'}) %}
    {# result: {id: 'new'} #}

**Array values**: Arrays are merged like in PHP's ``array_merge`` function - numeric keys are
appended, non-numeric keys replace.

.. code-block:: twig

    {# Numeric keys (appended): #}
    {% set result = {class: ['btn']}|html_attr_merge({class: ['btn-primary']}) %}
    {# result: {class: ['btn', 'btn-primary']} #}

    {# Non-numeric keys (replaced): #}
    {% set result = {class: {base: 'btn', size: 'small'}}|html_attr_merge({class: {variant: 'primary', size: 'large'}}) %}
    {# result: {class: {base: 'btn', size: 'large', variant: 'primary'}} #}

.. note::

    Remember, attribute mappings passed to or returned from this filter are regular
    Twig mappings after all. If you want to completely replace an attribute value
    that is an iterable with another value, you can use the :doc:`merge <../filters/merge>`
    filter to do that.

**``MergeableInterface`` implementations**: For advanced use cases, attribute values can be objects
that implement the ``MergeableInterface``. These objects can define their own, custom merge
behavior that takes precedence over the default rules. See the docblocks in that interface
for details.

.. note::

    The ``html_attr_merge`` filter is part of the ``HtmlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/html-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Html\HtmlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new HtmlExtension());

Arguments
---------

The filter accepts a variadic list of arguments to merge. Each argument can be:

* A map of attributes
* ``false`` or ``null`` (ignored, useful for conditional merging)
* An empty string ``''`` (ignored, to support implicit else in ternary operators)

.. seealso::

    :ref:`html_attr`,
    :doc:`html_attr_type`


================================================
FILE: doc/filters/html_attr_type.rst
================================================
``html_attr_type``
==================

.. _html_attr_type:

.. versionadded:: 3.24

    The ``html_attr_type`` filter was added in Twig 3.24.

The ``html_attr_type`` filter converts arrays into specialized attribute value
objects that implement custom rendering logic. It is designed for use
with the :ref:`html_attr` function for attributes where
the attribute value follows special formatting rules.

.. code-block:: html+twig

    <img {{ html_attr({
        srcset: ['small.jpg 480w', 'large.jpg 1200w']|html_attr_type('cst')
    }) }}>

    {# Output: <img srcset="small.jpg 480w, large.jpg 1200w"> #}

Available Types
---------------

Space-Separated Token List (``sst``)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Used for attributes that expect space-separated values, like ``class`` or
``aria-labelledby``:

.. code-block:: html+twig

    {% set classes = ['btn', 'btn-primary']|html_attr_type('sst') %}

    <button {{ html_attr({class: classes}) }}>
        Click me
    </button>

    {# Output: <button class="btn btn-primary">Click me</button> #}

This is the default type used when the :ref:`html_attr` function encounters an
array value (except for ``style`` attributes).

Comma-Separated Token List (``cst``)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Used for attributes that expect comma-separated values, like ``srcset`` or
``sizes``:

.. code-block:: html+twig

    <img {{ html_attr({
        srcset: ['image-1x.jpg 1x', 'image-2x.jpg 2x', 'image-3x.jpg 3x']|html_attr_type('cst'),
        sizes: ['(max-width: 600px) 100vw', '50vw']|html_attr_type('cst')
    }) }}>

    {# Output: <img srcset="image-1x.jpg 1x, image-2x.jpg 2x, image-3x.jpg 3x" sizes="(max-width: 600px) 100vw, 50vw"> #}

Inline Style (``style``)
~~~~~~~~~~~~~~~~~~~~~~~~

Used for style attributes. Handles both maps (property - value pairs) and sequences (CSS declarations):

.. code-block:: html+twig

    {# Associative array #}
    {% set styles = {color: 'red', 'font-size': '14px'}|html_attr_type('style') %}

    <div {{ html_attr({style: styles}) }}>
        Styled content
    </div>

    {# Output: <div style="color: red; font-size: 14px;">Styled content</div> #}

    {# Numeric array #}
    {% set styles = ['color: red', 'font-size: 14px']|html_attr_type('style') %}

    <div {{ html_attr({style: styles}) }}>
        Styled content
    </div>

    {# Output: <div style="color: red; font-size: 14px;">Styled content</div> #}

The ``style`` type is automatically applied by the :ref:`html_attr` function when
it encounters an array value for the ``style`` attribute.

.. note::

    The ``html_attr_type`` filter is part of the ``HtmlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/html-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Html\HtmlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new HtmlExtension());

Arguments
---------

* ``value``: The sequence of attributes to convert
* ``type``: The attribute type. One of:

  * ``sst`` (default): Space-separated token list
  * ``cst``: Comma-separated token list
  * ``style``: Inline CSS styles

.. seealso::

    :ref:`html_attr`,
    :ref:`html_attr_merge`


================================================
FILE: doc/filters/html_to_markdown.rst
================================================
``html_to_markdown``
====================

The ``html_to_markdown`` filter converts a block of HTML to Markdown:

.. code-block:: html+twig

    {% apply html_to_markdown %}
        <html>
            <h1>Hello!</h1>
        </html>
    {% endapply %}

You can also use the filter on an entire template which you ``include``:

.. code-block:: twig

    {{ include('some_template.html.twig')|html_to_markdown }}

.. note::

    The ``html_to_markdown`` filter is part of the ``MarkdownExtension`` which
    is not installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/markdown-extra

    On Symfony projects, you can automatically enable it by installing the
    ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Or add the extension explicitly on the Twig environment::

        use Twig\Extra\Markdown\MarkdownExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new MarkdownExtension());

    If you are not using Symfony, you must also register the extension runtime::

        use Twig\Extra\Markdown\DefaultMarkdown;
        use Twig\Extra\Markdown\MarkdownRuntime;
        use Twig\RuntimeLoader\RuntimeLoaderInterface;

        $twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
            public function load($class) {
                if (MarkdownRuntime::class === $class) {
                    return new MarkdownRuntime(new DefaultMarkdown());
                }
            }
        });

``html_to_markdown`` is just a frontend; the actual conversion is done by one of
the following compatible libraries, from which you can choose:

* `league/html-to-markdown`_
* `michelf/php-markdown`_
* `erusev/parsedown`_

Depending on the library, you can also add some options by passing them as an argument
to the filter. Example for ``league/html-to-markdown``:

.. code-block:: html+twig

    {% apply html_to_markdown({hard_break: false}) %}
        <html>
            <h1>Hello!</h1>
        </html>
    {% endapply %}
    
.. _league/html-to-markdown: https://github.com/thephpleague/html-to-markdown
.. _michelf/php-markdown: https://github.com/michelf/php-markdown
.. _erusev/parsedown: https://github.com/erusev/parsedown


================================================
FILE: doc/filters/index.rst
================================================
Filters
=======

.. toctree::
    :maxdepth: 1

    abs
    batch
    capitalize
    column
    convert_encoding
    country_name
    currency_name
    currency_symbol
    data_uri
    date
    date_modify
    default
    escape
    filter
    find
    first
    format
    format_currency
    format_date
    format_datetime
    format_number
    format_time
    html_attr_merge
    html_attr_type
    html_to_markdown
    inline_css
    inky_to_html
    invoke
    join
    json_encode
    keys
    language_name
    last
    length
    locale_name
    lower
    map
    markdown_to_html
    merge
    nl2br
    number_format
    plural
    raw
    reduce
    replace
    reverse
    round
    shuffle
    singular
    slice
    slug
    sort
    spaceless
    split
    striptags
    timezone_name
    title
    trim
    u
    upper
    url_encode


================================================
FILE: doc/filters/inky_to_html.rst
================================================
``inky_to_html``
================

The ``inky_to_html`` filter processes an `inky email template
<https://github.com/foundation/inky>`_:

.. code-block:: html+twig

    {% apply inky_to_html %}
        <row>
            <columns large="6"></columns>
            <columns large="6"></columns>
        </row>
    {% endapply %}

You can also use the filter on an included file:

.. code-block:: twig

    {{ include('some_template.inky.twig')|inky_to_html }}

.. note::

    The ``inky_to_html`` filter is part of the ``InkyExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/inky-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Inky\InkyExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new InkyExtension());


================================================
FILE: doc/filters/inline_css.rst
================================================
``inline_css``
==============

The ``inline_css`` filter inlines CSS styles in HTML documents:

.. code-block:: html+twig

    {% apply inline_css %}
        <html>
            <head>
                <style>
                    p { color: red; }
                </style>
            </head>
            <body>
                <p>Hello CSS!</p>
            </body>
        </html>
    {% endapply %}

You can also add some stylesheets by passing them as arguments to the filter:

.. code-block:: html+twig

    {% apply inline_css(source("some_styles.css"), source("another.css")) %}
        <html>
            <body>
                <p>Hello CSS!</p>
            </body>
        </html>
    {% endapply %}

Styles loaded via the filter override the styles defined in the ``<style>`` tag
of the HTML document.

You can also use the filter on an included file:

.. code-block:: twig

    {{ include('some_template.html.twig')|inline_css }}

    {{ include('some_template.html.twig')|inline_css(source("some_styles.css")) }}

Note that the CSS inliner works on an entire HTML document, not a fragment.

.. note::

    The ``inline_css`` filter is part of the ``CssInlinerExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/cssinliner-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\CssInliner\CssInlinerExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new CssInlinerExtension());


================================================
FILE: doc/filters/invoke.rst
================================================
``invoke``
==========

.. versionadded:: 3.19

    The ``invoke`` filter has been added in Twig 3.19.

The ``invoke`` filter invokes an arrow function with the given arguments:

.. code-block:: twig

    {% set person = { first: "Bob", last: "Smith" } %}
    {% set func = p => "#{p.first} #{p.last}" %}

    {{ func|invoke(person) }}
    {# outputs Bob Smith #}


================================================
FILE: doc/filters/join.rst
================================================
``join``
========

The ``join`` filter returns a string which is the concatenation of the items
of a sequence:

.. code-block:: twig

    {{ [1, 2, 3]|join }}
    {# returns 123 #}

The separator between elements is an empty string per default, but you can
define it with the optional first parameter:

.. code-block:: twig

    {{ [1, 2, 3]|join('|') }}
    {# outputs 1|2|3 #}

A second parameter can also be provided that will be the separator used between
the last two items of the sequence:

.. code-block:: twig

    {{ [1, 2, 3]|join(', ', ' and ') }}
    {# outputs 1, 2 and 3 #}

Arguments
---------

* ``glue``: The separator
* ``and``: The separator for the last pair of input items


================================================
FILE: doc/filters/json_encode.rst
================================================
``json_encode``
===============

The ``json_encode`` filter returns the JSON representation of a value:

.. code-block:: twig

    {{ data|json_encode() }}

.. note::

    Internally, Twig uses the PHP `json_encode`_ function.

Arguments
---------

* ``options``: A bitmask of `json_encode options`_: ``{{
  data|json_encode(constant('JSON_PRETTY_PRINT')) }}``.
  Combine constants using :ref:`bitwise operators<template_logic>`:
  ``{{ data|json_encode(constant('JSON_PRETTY_PRINT') b-or constant('JSON_HEX_QUOT')) }}``

.. _`json_encode`: https://www.php.net/json_encode
.. _`json_encode options`: https://www.php.net/manual/en/json.constants.php


================================================
FILE: doc/filters/keys.rst
================================================
``keys``
========

The ``keys`` filter returns the keys of a sequence or a mapping. It is useful
when you want to iterate over the keys of a sequence or a mapping:

.. code-block:: twig

    {% for key in ['a', 'b', 'c', 'd']|keys %}
        {{ key }}
    {% endfor %}
    {# outputs: 0 1 2 3 #}

    {% for key in {a: 'a_value', b: 'b_value'}|keys %}
        {{ key }}
    {% endfor %}
    {# outputs: a b #}

.. note::

    Internally, Twig uses the PHP `array_keys`_ function.

.. _`array_keys`: https://www.php.net/array_keys


================================================
FILE: doc/filters/language_name.rst
================================================
``language_name``
=================

The ``language_name`` filter returns the language name based on its ISO 639-1
code, ISO 639-2 code, or other specific localized code:

.. code-block:: twig

    {# German #}
    {{ 'de'|language_name }}

By default, the filter uses the current locale. You can pass it explicitly:

.. code-block:: twig

    {# allemand #}
    {{ 'de'|language_name('fr') }}

    {# français canadien #}
    {{ 'fr_CA'|language_name('fr_FR') }}

.. note::

    The ``language_name`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());

Arguments
---------

* ``locale``: The locale code as defined in `RFC 5646`_

.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646


================================================
FILE: doc/filters/last.rst
================================================
``last``
========

The ``last`` filter returns the last "element" of a sequence, a mapping, or
a string:

.. code-block:: twig

    {{ [1, 2, 3, 4]|last }}
    {# outputs 4 #}

    {{ {a: 1, b: 2, c: 3, d: 4}|last }}
    {# outputs 4 #}

    {{ '1234'|last }}
    {# outputs 4 #}

.. note::

    It also works with objects implementing the `Traversable`_ interface.

.. _`Traversable`: https://www.php.net/manual/en/class.traversable.php


================================================
FILE: doc/filters/length.rst
================================================
``length``
==========

The ``length`` filter returns the number of items of a sequence or mapping, or
the length of a string.

For objects that implement the ``Countable`` interface, ``length`` will use the
return value of the ``count()`` method.

For objects that implement the ``__toString()`` magic method (and not ``Countable``),
it will return the length of the string provided by that method.

For objects that implement the ``Traversable`` interface, ``length`` will use the return value of the ``iterator_count()`` method.

For strings, `mb_strlen()`_ is used.

.. code-block:: twig

    {% if users|length > 10 %}
        ...
    {% endif %}

.. _mb_strlen(): https://www.php.net/manual/function.mb-strlen.php


================================================
FILE: doc/filters/locale_name.rst
================================================
``locale_name``
===============

The ``locale_name`` filter returns the locale name given its code:

.. code-block:: twig

    {# German #}
    {{ 'de'|locale_name }}

By default, the filter uses the current locale. You can pass it explicitly:

.. code-block:: twig

    {# allemand #}
    {{ 'de'|locale_name('fr') }}

    {# français (Canada) #}
    {{ 'fr_CA'|locale_name('fr_FR') }}

.. note::

    The ``locale_name`` filter is part of the ``IntlExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/intl-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Intl\IntlExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new IntlExtension());

Arguments
---------

* ``locale``: The locale code as defined in `RFC 5646`_

.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646


================================================
FILE: doc/filters/lower.rst
================================================
``lower``
=========

The ``lower`` filter converts a value to lowercase:

.. code-block:: twig

    {{ 'WELCOME'|lower }}

    {# outputs 'welcome' #}

.. note::

    Internally, Twig uses the PHP `mb_strtolower`_ function.

.. _`mb_strtolower`: https://www.php.net/manual/fr/function.mb-strtolower.php


================================================
FILE: doc/filters/map.rst
================================================
``map``
=======

The ``map`` filter applies an arrow function to the elements of a sequence or a
mapping. The arrow function receives the value of the sequence or mapping:

.. code-block:: twig

    {% set people = [
        {first: "Bob", last: "Smith"},
        {first: "Alice", last: "Dupond"},
    ] %}

    {{ people|map(p => "#{p.first} #{p.last}")|join(', ') }}
    {# outputs Bob Smith, Alice Dupond #}

The arrow function also receives the key as a second argument:

.. code-block:: twig

    {% set people = {
        "Bob": "Smith",
        "Alice": "Dupond",
    } %}

    {{ people|map((value, key) => "#{key} #{value}")|join(', ') }}
    {# outputs Bob Smith, Alice Dupond #}

Note that the arrow function has access to the current context.

Arguments
---------

* ``arrow``: The arrow function


================================================
FILE: doc/filters/markdown_to_html.rst
================================================
``markdown_to_html``
====================

The ``markdown_to_html`` filter converts a block of Markdown to HTML:

.. code-block:: twig

    {% apply markdown_to_html %}
    Title
    =====

    Hello!
    {% endapply %}

Note that you can indent the Markdown content as leading whitespaces will be
removed consistently before conversion:

.. code-block:: twig

    {% apply markdown_to_html %}
        Title
        =====

        Hello!
    {% endapply %}

You can also use the filter on an included file or a variable:

.. code-block:: twig

    {{ include('some_template.markdown.twig')|markdown_to_html }}

    {{ changelog|markdown_to_html }}

.. note::

    The ``markdown_to_html`` filter is part of the ``MarkdownExtension`` which
    is not installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/markdown-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\Markdown\MarkdownExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new MarkdownExtension());

    If you are not using Symfony, you must also register the extension runtime::

        use Twig\Extra\Markdown\DefaultMarkdown;
        use Twig\Extra\Markdown\MarkdownRuntime;
        use Twig\RuntimeLoader\RuntimeLoaderInterface;

        $twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
            public function load($class) {
                if (MarkdownRuntime::class === $class) {
                    return new MarkdownRuntime(new DefaultMarkdown());
                }
            }
        });

    Afterwards you need to install a markdown library of your choice. Some of them are
    mentioned in the ``require-dev`` section of the ``twig/markdown-extra`` package.

.. note::

    If using Symfony (full-stack), ``twig/extra-bundle`` with ``league/commonmark`` as
    your Markdown library you can configure CommonMark extensions. Register the desired
    extension(s) as a service, then tag the service with
    ``twig.markdown.league_extension``.


================================================
FILE: doc/filters/merge.rst
================================================
``merge``
=========

The ``merge`` filter merges sequences and mappings:

For sequences, new values are added at the end of the existing ones:

.. code-block:: twig

    {% set values = [1, 2] %}

    {% set values = values|merge(['apple', 'orange']) %}

    {# values now contains [1, 2, 'apple', 'orange'] #}

For mappings, the merging process occurs on the keys; if the key does not
already exist, it is added but if the key already exists, its value is
overridden:

.. code-block:: twig

    {% set items = {'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown'} %}

    {% set items = items|merge({ 'peugeot': 'car', 'renault': 'car' }) %}

    {# items now contains {'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car', 'renault': 'car'} #}

.. tip::

    If you want to ensure that some values are defined in a mapping (by given
    default values), reverse the two elements in the call:

    .. code-block:: twig

        {% set items = {'apple': 'fruit', 'orange': 'fruit'} %}

        {% set items = {'apple': 'unknown'}|merge(items) %}

        {# items now contains {'apple': 'fruit', 'orange': 'fruit'} #}

.. note::

    Internally, Twig uses the PHP `array_merge`_ function. It supports
    Traversable objects by transforming those to arrays.

.. _`array_merge`: https://www.php.net/array_merge


================================================
FILE: doc/filters/nl2br.rst
================================================
``nl2br``
=========

The ``nl2br`` filter inserts HTML line breaks before all newlines in a string:

.. code-block:: html+twig

    {{ "I like Twig.\nYou will like it too."|nl2br }}
    {# outputs

        I like Twig.<br />
        You will like it too.

    #}

.. note::

    The ``nl2br`` filter pre-escapes the input before applying the
    transformation.


================================================
FILE: doc/filters/number_format.rst
================================================
``number_format``
=================

The ``number_format`` filter formats numbers.  It is a wrapper around PHP's
`number_format`_ function:

.. code-block:: twig

    {{ 200.35|number_format }}

You can control the number of decimal places, decimal point, and thousands
separator using the additional arguments:

.. code-block:: twig

    {{ 9800.333|number_format(2, '.', ',') }}

To format negative numbers, wrap the previous statement with parentheses (note
that as of Twig 3.21, not using parentheses is deprecated as the filter
operator will change precedence in Twig 4.0):

.. code-block:: twig

    {{ -9800.333|number_format(2, '.', ',') }} {# outputs : -9 #}
    {{ (-9800.333)|number_format(2, '.', ',') }} {# outputs : -9,800.33 #}

To format math calculation, wrap the previous statement with parentheses
(needed because of Twig's :ref:`precedence of operators -<twig-expressions>`):

.. code-block:: twig

    {{ 1 + 0.2|number_format(2) }} {# outputs : 1.2 #}
    {{ (1 + 0.2)|number_format(2) }} {# outputs : 1.20 #}

If no formatting options are provided then Twig will use the default formatting
options of:

* 0 decimal places.
* ``.`` as the decimal point.
* ``,`` as the thousands separator.

These defaults can be changed through the core extension::

    $twig = new \Twig\Environment($loader);
    $twig->getExtension(\Twig\Extension\CoreExtension::class)->setNumberFormat(3, '.', ',');

The defaults set for ``number_format`` can be over-ridden upon each call using the
additional parameters.

Arguments
---------

* ``decimal``:       The number of decimal points to display
* ``decimal_point``: The character(s) to use for the decimal point
* ``thousand_sep``:   The character(s) to use for the thousands separator

.. _`number_format`: https://www.php.net/number_format


================================================
FILE: doc/filters/plural.rst
================================================
``plural``
==========

.. versionadded:: 3.11

    The ``plural`` filter was added in Twig 3.11.

The ``plural`` filter transforms a given noun in its singular form into its
plural version:

.. code-block:: twig

    {# English (en) rules are used by default #}
    {{ 'animal'|plural() }}
    animals

    {{ 'animal'|plural('fr') }}
    animaux

.. note::

    The ``plural`` filter is part of the ``StringExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/string-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\String\StringExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new StringExtension());

Arguments
---------

* ``locale``: The locale of the original string (limited to languages supported by the from Symfony `inflector`_, part of the String component)
* ``all``: Whether to return all possible plurals as an array, default is ``false``

.. note::

    Internally, Twig uses the `pluralize`_ method from the Symfony String component.

.. _`inflector`: https://symfony.com/doc/current/components/string.html#inflector
.. _`pluralize`: https://symfony.com/doc/current/components/string.html#inflector


================================================
FILE: doc/filters/raw.rst
================================================
``raw``
=======

The ``raw`` filter marks the value as being "safe", which means that in an
environment with automatic escaping enabled this variable will not be escaped
if ``raw`` is the last filter applied to it:

.. code-block:: twig

    {% autoescape %}
        {{ var|raw }} {# var won't be escaped #}
    {% endautoescape %}


================================================
FILE: doc/filters/reduce.rst
================================================
``reduce``
==========

The ``reduce`` filter iteratively reduces a sequence or a mapping to a single
value using an arrow function, so as to reduce it to a single value. The arrow
function receives the return value of the previous iteration and the current
value and key of the sequence or mapping:

.. code-block:: twig

    {% set numbers = [1, 2, 3] %}

    {{ numbers|reduce((carry, value, key) => carry + value * key) }}
    {# output 8 #}

The ``reduce`` filter takes an ``initial`` value as a second argument:

.. code-block:: twig

    {{ numbers|reduce((carry, value, key) => carry + value * key, 10) }}
    {# output 18 #}

Note that the arrow function has access to the current context.

Arguments
---------

* ``arrow``: The arrow function
* ``initial``: The initial value


================================================
FILE: doc/filters/replace.rst
================================================
``replace``
===========

The ``replace`` filter replaces placeholders in a string (the placeholder
format is free-form):

.. code-block:: twig

    {% set fruit = 'apples' %}

    {{ "I like %this% and %that%."|replace({'%this%': fruit, '%that%': "oranges"}) }}
    {# if the "fruit" variable is set to "apples", #}
    {# it outputs "I like apples and oranges" #}

    {# using % as a delimiter is purely conventional and optional #}
    {{ "I like this and --that--."|replace({'this': fruit, '--that--': "oranges"}) }}
    {# outputs "I like apples and oranges" #}

Arguments
---------

* ``from``: The placeholder values as a mapping

.. seealso::

    :doc:`format<format>`


================================================
FILE: doc/filters/reverse.rst
================================================
``reverse``
===========

The ``reverse`` filter reverses a sequence, a mapping, or a string:

.. code-block:: twig

    {% for user in users|reverse %}
        ...
    {% endfor %}

    {{ '1234'|reverse }}

    {# outputs 4321 #}

.. tip::

    For sequences and mappings, numeric keys are not preserved. To reverse
    them as well, pass ``true`` as an argument to the ``reverse`` filter:

    .. code-block:: twig

        {% for key, value in {1: "a", 2: "b", 3: "c"}|reverse %}
            {{ key }}: {{ value }}
        {%- endfor %}

        {# output: 0: c    1: b    2: a #}

        {% for key, value in {1: "a", 2: "b", 3: "c"}|reverse(true) %}
            {{ key }}: {{ value }}
        {%- endfor %}

        {# output: 3: c    2: b    1: a #}

.. note::

    It also works with objects implementing the `Traversable`_ interface.

Arguments
---------

* ``preserve_keys``: Preserve keys when reversing a mapping or a sequence.

.. _`Traversable`: https://www.php.net/Traversable


================================================
FILE: doc/filters/round.rst
================================================
``round``
=========

The ``round`` filter rounds a number to a given precision:

.. code-block:: twig

    {{ 42.55|round }}
    {# outputs 43 #}

    {{ 42.55|round(1, 'floor') }}
    {# outputs 42.5 #}

The ``round`` filter takes two optional arguments; the first one specifies the
precision (default is ``0``) and the second the rounding method (default is
``common``):

* ``common`` rounds either up or down (rounds the value up to precision decimal
  places away from zero, when it is half way there -- making 1.5 into 2 and
  -1.5 into -2);

* ``ceil`` always rounds up;

* ``floor`` always rounds down.

.. note::

    The ``//`` operator is equivalent to ``|round(0, 'floor')``.

Arguments
---------

* ``precision``: The rounding precision
* ``method``: The rounding method


================================================
FILE: doc/filters/shuffle.rst
================================================
``shuffle``
===========

.. versionadded:: 3.11

    The ``shuffle`` filter was added in Twig 3.11.

The ``shuffle`` filter shuffles a sequence, a mapping, or a string:

.. code-block:: twig

    {% for user in users|shuffle %}
        ...
    {% endfor %}

.. caution::

    The shuffled array does not preserve keys. So if the input had not
    sequential keys but indexed keys (using the user id for instance), it is
    not the case anymore after shuffling it.

Example 1:

.. code-block:: html+twig

    {% set items = [
        'a',
        'b',
        'c',
    ] %}

    <ul>
        {% for item in items|shuffle %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>

The above example will be rendered as:

.. code-block:: html

    <ul>
        <li>a</li>
        <li>c</li>
        <li>b</li>
    </ul>

The result can also be: "a, b, c" or "b, a, c" or "b, c, a" or "c, a, b" or
"c, b, a".

Example 2:

.. code-block:: html+twig

    {% set items = {
        'a': 'd',
        'b': 'e',
        'c': 'f',
    } %}

    <ul>
        {% for index, item in items|shuffle %}
            <li>{{ index }} - {{ item }}</li>
        {% endfor %}
    </ul>

The above example will be rendered as:

.. code-block:: html

    <ul>
        <li>0 - d</li>
        <li>1 - f</li>
        <li>2 - e</li>
    </ul>

The result can also be: "d, e, f" or "e, d, f" or "e, f, d" or "f, d, e" or
"f, e, d".

.. code-block:: html+twig

    {% set string = 'ghi' %}

    <p>{{ string|shuffle }}</p>

The above example will be rendered as:

.. code-block:: html

    <p>gih</p>

The result can also be: "ghi" or "hgi" or "hig" or "igh" or "ihg".


================================================
FILE: doc/filters/singular.rst
================================================
``singular``
============

.. versionadded:: 3.11

    The ``singular`` filter was added in Twig 3.11.

The ``singular`` filter transforms a given noun in its plural form into its
singular version:

.. code-block:: twig

    {# English (en) rules are used by default #}
    {{ 'partitions'|singular() }}
    partition

    {{ 'partitions'|singular('fr') }}
    partition

.. note::

    The ``singular`` filter is part of the ``StringExtension`` which is not
    installed by default. Install it first:

    .. code-block:: bash

        $ composer require twig/string-extra

    Then, on Symfony projects, install the ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Otherwise, add the extension explicitly on the Twig environment::

        use Twig\Extra\String\StringExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new StringExtension());

Arguments
---------

* ``locale``: The locale of the original string (limited to languages supported by the from Symfony `inflector`_,
Download .txt
gitextract_my2eswkz/

├── .editorconfig
├── .gitattributes
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       ├── documentation.yml
│       └── fabbot.yml
├── .gitignore
├── .php-cs-fixer.dist.php
├── CHANGELOG
├── LICENSE
├── README.rst
├── bin/
│   └── generate_operators_precedence.php
├── composer.json
├── doc/
│   ├── .doctor-rst.yaml
│   ├── _build/
│   │   ├── build.php
│   │   └── composer.json
│   ├── advanced.rst
│   ├── api.rst
│   ├── coding_standards.rst
│   ├── deprecated.rst
│   ├── filters/
│   │   ├── abs.rst
│   │   ├── batch.rst
│   │   ├── capitalize.rst
│   │   ├── column.rst
│   │   ├── convert_encoding.rst
│   │   ├── country_name.rst
│   │   ├── currency_name.rst
│   │   ├── currency_symbol.rst
│   │   ├── data_uri.rst
│   │   ├── date.rst
│   │   ├── date_modify.rst
│   │   ├── default.rst
│   │   ├── escape.rst
│   │   ├── filter.rst
│   │   ├── find.rst
│   │   ├── first.rst
│   │   ├── format.rst
│   │   ├── format_currency.rst
│   │   ├── format_date.rst
│   │   ├── format_datetime.rst
│   │   ├── format_number.rst
│   │   ├── format_time.rst
│   │   ├── html_attr_merge.rst
│   │   ├── html_attr_type.rst
│   │   ├── html_to_markdown.rst
│   │   ├── index.rst
│   │   ├── inky_to_html.rst
│   │   ├── inline_css.rst
│   │   ├── invoke.rst
│   │   ├── join.rst
│   │   ├── json_encode.rst
│   │   ├── keys.rst
│   │   ├── language_name.rst
│   │   ├── last.rst
│   │   ├── length.rst
│   │   ├── locale_name.rst
│   │   ├── lower.rst
│   │   ├── map.rst
│   │   ├── markdown_to_html.rst
│   │   ├── merge.rst
│   │   ├── nl2br.rst
│   │   ├── number_format.rst
│   │   ├── plural.rst
│   │   ├── raw.rst
│   │   ├── reduce.rst
│   │   ├── replace.rst
│   │   ├── reverse.rst
│   │   ├── round.rst
│   │   ├── shuffle.rst
│   │   ├── singular.rst
│   │   ├── slice.rst
│   │   ├── slug.rst
│   │   ├── sort.rst
│   │   ├── spaceless.rst
│   │   ├── split.rst
│   │   ├── striptags.rst
│   │   ├── timezone_name.rst
│   │   ├── title.rst
│   │   ├── trim.rst
│   │   ├── u.rst
│   │   ├── upper.rst
│   │   └── url_encode.rst
│   ├── functions/
│   │   ├── attribute.rst
│   │   ├── block.rst
│   │   ├── constant.rst
│   │   ├── country_names.rst
│   │   ├── country_timezones.rst
│   │   ├── currency_names.rst
│   │   ├── cycle.rst
│   │   ├── date.rst
│   │   ├── dump.rst
│   │   ├── enum.rst
│   │   ├── enum_cases.rst
│   │   ├── html_attr.rst
│   │   ├── html_classes.rst
│   │   ├── html_cva.rst
│   │   ├── include.rst
│   │   ├── index.rst
│   │   ├── language_names.rst
│   │   ├── locale_names.rst
│   │   ├── max.rst
│   │   ├── min.rst
│   │   ├── parent.rst
│   │   ├── random.rst
│   │   ├── range.rst
│   │   ├── script_names.rst
│   │   ├── source.rst
│   │   ├── template_from_string.rst
│   │   └── timezone_names.rst
│   ├── index.rst
│   ├── installation.rst
│   ├── internals.rst
│   ├── intro.rst
│   ├── operators_precedence.rst
│   ├── recipes.rst
│   ├── sandbox.rst
│   ├── tags/
│   │   ├── apply.rst
│   │   ├── autoescape.rst
│   │   ├── block.rst
│   │   ├── cache.rst
│   │   ├── deprecated.rst
│   │   ├── do.rst
│   │   ├── embed.rst
│   │   ├── extends.rst
│   │   ├── flush.rst
│   │   ├── for.rst
│   │   ├── from.rst
│   │   ├── guard.rst
│   │   ├── if.rst
│   │   ├── import.rst
│   │   ├── include.rst
│   │   ├── index.rst
│   │   ├── macro.rst
│   │   ├── sandbox.rst
│   │   ├── set.rst
│   │   ├── types.rst
│   │   ├── use.rst
│   │   ├── verbatim.rst
│   │   └── with.rst
│   ├── templates.rst
│   └── tests/
│       ├── constant.rst
│       ├── defined.rst
│       ├── divisibleby.rst
│       ├── empty.rst
│       ├── even.rst
│       ├── index.rst
│       ├── iterable.rst
│       ├── mapping.rst
│       ├── null.rst
│       ├── odd.rst
│       ├── sameas.rst
│       └── sequence.rst
├── extra/
│   ├── cache-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── CacheExtension.php
│   │   ├── CacheRuntime.php
│   │   ├── LICENSE
│   │   ├── Node/
│   │   │   └── CacheNode.php
│   │   ├── README.md
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   ├── cache.test
│   │   │   │   ├── cache_complex.test
│   │   │   │   ├── cache_with_blocks.test
│   │   │   │   └── macro.test
│   │   │   ├── FunctionalTest.php
│   │   │   └── IntegrationTest.php
│   │   ├── TokenParser/
│   │   │   └── CacheTokenParser.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── cssinliner-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── CssInlinerExtension.php
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── Resources/
│   │   │   └── functions.php
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   └── inline_css.test
│   │   │   ├── IntegrationTest.php
│   │   │   └── LegacyFunctionsTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── html-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── Cva.php
│   │   ├── HtmlAttr/
│   │   │   ├── AttributeValueInterface.php
│   │   │   ├── InlineStyle.php
│   │   │   ├── MergeableInterface.php
│   │   │   └── SeparatedTokenList.php
│   │   ├── HtmlExtension.php
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── Resources/
│   │   │   └── functions.php
│   │   ├── Tests/
│   │   │   ├── CvaTest.php
│   │   │   ├── Fixtures/
│   │   │   │   ├── data_uri.test
│   │   │   │   ├── html_attr.test
│   │   │   │   ├── html_attr_merge.test
│   │   │   │   ├── html_classes.test
│   │   │   │   ├── html_classes_with_unsupported_arg.test
│   │   │   │   ├── html_classes_with_unsupported_key.test
│   │   │   │   ├── html_cva.test
│   │   │   │   └── html_cva_pass_to_template.test
│   │   │   ├── HtmlAttrMergeTest.php
│   │   │   ├── HtmlAttrTest.php
│   │   │   ├── IntegrationTest.php
│   │   │   └── LegacyFunctionsTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── inky-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── InkyExtension.php
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── Resources/
│   │   │   └── functions.php
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   └── inky.test
│   │   │   ├── IntegrationTest.php
│   │   │   └── LegacyFunctionsTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── intl-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── IntlExtension.php
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   ├── country_name.test
│   │   │   │   ├── country_names.test
│   │   │   │   ├── country_timezones.test
│   │   │   │   ├── currency_name.test
│   │   │   │   ├── currency_names.test
│   │   │   │   ├── currency_symbol.test
│   │   │   │   ├── format_currency.test
│   │   │   │   ├── format_date.test
│   │   │   │   ├── format_date_ICU72.test
│   │   │   │   ├── format_date_php8.test
│   │   │   │   ├── format_date_php8_ICU72.test
│   │   │   │   ├── format_number.test
│   │   │   │   ├── language_name.test
│   │   │   │   ├── language_names.test
│   │   │   │   ├── locale_name.test
│   │   │   │   ├── locale_names.test
│   │   │   │   ├── script_names.test
│   │   │   │   ├── timezone_name.test
│   │   │   │   └── timezone_names.test
│   │   │   ├── IntegrationTest.php
│   │   │   └── IntlExtensionTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── markdown-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── DefaultMarkdown.php
│   │   ├── ErusevMarkdown.php
│   │   ├── LICENSE
│   │   ├── LeagueMarkdown.php
│   │   ├── MarkdownExtension.php
│   │   ├── MarkdownInterface.php
│   │   ├── MarkdownRuntime.php
│   │   ├── MichelfMarkdown.php
│   │   ├── README.md
│   │   ├── Resources/
│   │   │   └── functions.php
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   └── html_to_markdown.test
│   │   │   ├── FunctionalTest.php
│   │   │   ├── IntegrationTest.php
│   │   │   └── LegacyFunctionsTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   ├── string-extra/
│   │   ├── .gitattributes
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── StringExtension.php
│   │   ├── Tests/
│   │   │   ├── Fixtures/
│   │   │   │   ├── plural-invalid-language.test
│   │   │   │   ├── plural.test
│   │   │   │   ├── plural_es.test
│   │   │   │   ├── singular-invalid-language.test
│   │   │   │   ├── singular.test
│   │   │   │   ├── singular_es.test
│   │   │   │   ├── slug.test
│   │   │   │   └── string.test
│   │   │   └── IntegrationTest.php
│   │   ├── composer.json
│   │   └── phpunit.xml.dist
│   └── twig-extra-bundle/
│       ├── .gitattributes
│       ├── .gitignore
│       ├── DependencyInjection/
│       │   ├── Compiler/
│       │   │   └── MissingExtensionSuggestorPass.php
│       │   ├── Configuration.php
│       │   └── TwigExtraExtension.php
│       ├── Extensions.php
│       ├── LICENSE
│       ├── LeagueCommonMarkConverterFactory.php
│       ├── MissingExtensionSuggestor.php
│       ├── README.md
│       ├── Resources/
│       │   └── config/
│       │       ├── cache.php
│       │       ├── cssinliner.php
│       │       ├── html.php
│       │       ├── inky.php
│       │       ├── intl.php
│       │       ├── markdown.php
│       │       ├── markdown_league.php
│       │       ├── string.php
│       │       └── suggestor.php
│       ├── Tests/
│       │   ├── DependencyInjection/
│       │   │   └── TwigExtraExtensionTest.php
│       │   ├── Fixture/
│       │   │   ├── Kernel.php
│       │   │   └── views/
│       │   │       └── markdown_to_html.html.twig
│       │   └── IntegrationTest.php
│       ├── TwigExtraBundle.php
│       ├── composer.json
│       └── phpunit.xml.dist
├── phpstan-baseline.neon
├── phpstan.neon.dist
├── phpunit.xml.dist
├── splitsh.json
├── src/
│   ├── AbstractTwigCallable.php
│   ├── Attribute/
│   │   ├── AsTwigFilter.php
│   │   ├── AsTwigFunction.php
│   │   ├── AsTwigTest.php
│   │   ├── FirstClassTwigCallableReady.php
│   │   └── YieldReady.php
│   ├── Cache/
│   │   ├── CacheInterface.php
│   │   ├── ChainCache.php
│   │   ├── FilesystemCache.php
│   │   ├── NullCache.php
│   │   ├── ReadOnlyFilesystemCache.php
│   │   └── RemovableCacheInterface.php
│   ├── Compiler.php
│   ├── DeprecatedCallableInfo.php
│   ├── Environment.php
│   ├── Error/
│   │   ├── Error.php
│   │   ├── LoaderError.php
│   │   ├── RuntimeError.php
│   │   └── SyntaxError.php
│   ├── ExpressionParser/
│   │   ├── AbstractExpressionParser.php
│   │   ├── ExpressionParserDescriptionInterface.php
│   │   ├── ExpressionParserInterface.php
│   │   ├── ExpressionParserType.php
│   │   ├── ExpressionParsers.php
│   │   ├── Infix/
│   │   │   ├── ArgumentsTrait.php
│   │   │   ├── ArrowExpressionParser.php
│   │   │   ├── AssignmentExpressionParser.php
│   │   │   ├── BinaryOperatorExpressionParser.php
│   │   │   ├── ConditionalTernaryExpressionParser.php
│   │   │   ├── DotExpressionParser.php
│   │   │   ├── FilterExpressionParser.php
│   │   │   ├── FunctionExpressionParser.php
│   │   │   ├── IsExpressionParser.php
│   │   │   ├── IsNotExpressionParser.php
│   │   │   └── SquareBracketExpressionParser.php
│   │   ├── InfixAssociativity.php
│   │   ├── InfixExpressionParserInterface.php
│   │   ├── PrecedenceChange.php
│   │   ├── Prefix/
│   │   │   ├── GroupingExpressionParser.php
│   │   │   ├── LiteralExpressionParser.php
│   │   │   └── UnaryOperatorExpressionParser.php
│   │   └── PrefixExpressionParserInterface.php
│   ├── ExpressionParser.php
│   ├── Extension/
│   │   ├── AbstractExtension.php
│   │   ├── AttributeExtension.php
│   │   ├── CoreExtension.php
│   │   ├── DebugExtension.php
│   │   ├── EscaperExtension.php
│   │   ├── ExtensionInterface.php
│   │   ├── GlobalsInterface.php
│   │   ├── LastModifiedExtensionInterface.php
│   │   ├── OptimizerExtension.php
│   │   ├── ProfilerExtension.php
│   │   ├── RuntimeExtensionInterface.php
│   │   ├── SandboxExtension.php
│   │   ├── StagingExtension.php
│   │   ├── StringLoaderExtension.php
│   │   └── YieldNotReadyExtension.php
│   ├── ExtensionSet.php
│   ├── FileExtensionEscapingStrategy.php
│   ├── Lexer.php
│   ├── Loader/
│   │   ├── ArrayLoader.php
│   │   ├── ChainLoader.php
│   │   ├── FilesystemLoader.php
│   │   └── LoaderInterface.php
│   ├── Markup.php
│   ├── Node/
│   │   ├── AutoEscapeNode.php
│   │   ├── BlockNode.php
│   │   ├── BlockReferenceNode.php
│   │   ├── BodyNode.php
│   │   ├── CaptureNode.php
│   │   ├── CheckSecurityCallNode.php
│   │   ├── CheckSecurityNode.php
│   │   ├── CheckToStringNode.php
│   │   ├── DeprecatedNode.php
│   │   ├── DoNode.php
│   │   ├── EmbedNode.php
│   │   ├── EmptyNode.php
│   │   ├── Expression/
│   │   │   ├── AbstractExpression.php
│   │   │   ├── ArrayExpression.php
│   │   │   ├── ArrowFunctionExpression.php
│   │   │   ├── AssignNameExpression.php
│   │   │   ├── Binary/
│   │   │   │   ├── AbstractBinary.php
│   │   │   │   ├── AddBinary.php
│   │   │   │   ├── AndBinary.php
│   │   │   │   ├── BinaryInterface.php
│   │   │   │   ├── BitwiseAndBinary.php
│   │   │   │   ├── BitwiseOrBinary.php
│   │   │   │   ├── BitwiseXorBinary.php
│   │   │   │   ├── ConcatBinary.php
│   │   │   │   ├── DivBinary.php
│   │   │   │   ├── ElvisBinary.php
│   │   │   │   ├── EndsWithBinary.php
│   │   │   │   ├── EqualBinary.php
│   │   │   │   ├── FloorDivBinary.php
│   │   │   │   ├── GreaterBinary.php
│   │   │   │   ├── GreaterEqualBinary.php
│   │   │   │   ├── HasEveryBinary.php
│   │   │   │   ├── HasSomeBinary.php
│   │   │   │   ├── InBinary.php
│   │   │   │   ├── LessBinary.php
│   │   │   │   ├── LessEqualBinary.php
│   │   │   │   ├── MatchesBinary.php
│   │   │   │   ├── ModBinary.php
│   │   │   │   ├── MulBinary.php
│   │   │   │   ├── NotEqualBinary.php
│   │   │   │   ├── NotInBinary.php
│   │   │   │   ├── NotSameAsBinary.php
│   │   │   │   ├── NullCoalesceBinary.php
│   │   │   │   ├── ObjectDestructuringSetBinary.php
│   │   │   │   ├── OrBinary.php
│   │   │   │   ├── PowerBinary.php
│   │   │   │   ├── RangeBinary.php
│   │   │   │   ├── SameAsBinary.php
│   │   │   │   ├── SequenceDestructuringSetBinary.php
│   │   │   │   ├── SetBinary.php
│   │   │   │   ├── SpaceshipBinary.php
│   │   │   │   ├── StartsWithBinary.php
│   │   │   │   ├── SubBinary.php
│   │   │   │   └── XorBinary.php
│   │   │   ├── BlockReferenceExpression.php
│   │   │   ├── CallExpression.php
│   │   │   ├── ConditionalExpression.php
│   │   │   ├── ConstantExpression.php
│   │   │   ├── EmptyExpression.php
│   │   │   ├── Filter/
│   │   │   │   ├── DefaultFilter.php
│   │   │   │   └── RawFilter.php
│   │   │   ├── FilterExpression.php
│   │   │   ├── FunctionExpression.php
│   │   │   ├── FunctionNode/
│   │   │   │   ├── EnumCasesFunction.php
│   │   │   │   └── EnumFunction.php
│   │   │   ├── GetAttrExpression.php
│   │   │   ├── InlinePrint.php
│   │   │   ├── ListExpression.php
│   │   │   ├── MacroReferenceExpression.php
│   │   │   ├── MethodCallExpression.php
│   │   │   ├── NameExpression.php
│   │   │   ├── NullCoalesceExpression.php
│   │   │   ├── OperatorEscapeInterface.php
│   │   │   ├── ParentExpression.php
│   │   │   ├── ReturnArrayInterface.php
│   │   │   ├── ReturnBoolInterface.php
│   │   │   ├── ReturnNumberInterface.php
│   │   │   ├── ReturnPrimitiveTypeInterface.php
│   │   │   ├── ReturnStringInterface.php
│   │   │   ├── SupportDefinedTestDeprecationTrait.php
│   │   │   ├── SupportDefinedTestInterface.php
│   │   │   ├── SupportDefinedTestTrait.php
│   │   │   ├── TempNameExpression.php
│   │   │   ├── Ternary/
│   │   │   │   └── ConditionalTernary.php
│   │   │   ├── Test/
│   │   │   │   ├── ConstantTest.php
│   │   │   │   ├── DefinedTest.php
│   │   │   │   ├── DivisiblebyTest.php
│   │   │   │   ├── EvenTest.php
│   │   │   │   ├── NullTest.php
│   │   │   │   ├── OddTest.php
│   │   │   │   ├── SameasTest.php
│   │   │   │   └── TrueTest.php
│   │   │   ├── TestExpression.php
│   │   │   ├── Unary/
│   │   │   │   ├── AbstractUnary.php
│   │   │   │   ├── NegUnary.php
│   │   │   │   ├── NotUnary.php
│   │   │   │   ├── PosUnary.php
│   │   │   │   ├── SpreadUnary.php
│   │   │   │   ├── StringCastUnary.php
│   │   │   │   └── UnaryInterface.php
│   │   │   ├── Variable/
│   │   │   │   ├── AssignContextVariable.php
│   │   │   │   ├── AssignTemplateVariable.php
│   │   │   │   ├── ContextVariable.php
│   │   │   │   ├── LocalVariable.php
│   │   │   │   └── TemplateVariable.php
│   │   │   └── VariadicExpression.php
│   │   ├── FlushNode.php
│   │   ├── ForElseNode.php
│   │   ├── ForLoopNode.php
│   │   ├── ForNode.php
│   │   ├── IfNode.php
│   │   ├── ImportNode.php
│   │   ├── IncludeNode.php
│   │   ├── MacroNode.php
│   │   ├── ModuleNode.php
│   │   ├── NameDeprecation.php
│   │   ├── Node.php
│   │   ├── NodeCaptureInterface.php
│   │   ├── NodeOutputInterface.php
│   │   ├── Nodes.php
│   │   ├── PrintNode.php
│   │   ├── SandboxNode.php
│   │   ├── SetNode.php
│   │   ├── TextNode.php
│   │   ├── TypesNode.php
│   │   └── WithNode.php
│   ├── NodeTraverser.php
│   ├── NodeVisitor/
│   │   ├── AbstractNodeVisitor.php
│   │   ├── EscaperNodeVisitor.php
│   │   ├── NodeVisitorInterface.php
│   │   ├── OptimizerNodeVisitor.php
│   │   ├── SafeAnalysisNodeVisitor.php
│   │   ├── SandboxNodeVisitor.php
│   │   └── YieldNotReadyNodeVisitor.php
│   ├── OperatorPrecedenceChange.php
│   ├── Parser.php
│   ├── Profiler/
│   │   ├── Dumper/
│   │   │   ├── BaseDumper.php
│   │   │   ├── BlackfireDumper.php
│   │   │   ├── HtmlDumper.php
│   │   │   └── TextDumper.php
│   │   ├── Node/
│   │   │   ├── EnterProfileNode.php
│   │   │   └── LeaveProfileNode.php
│   │   ├── NodeVisitor/
│   │   │   └── ProfilerNodeVisitor.php
│   │   └── Profile.php
│   ├── Resources/
│   │   ├── core.php
│   │   ├── debug.php
│   │   ├── escaper.php
│   │   └── string_loader.php
│   ├── Runtime/
│   │   └── EscaperRuntime.php
│   ├── RuntimeLoader/
│   │   ├── ContainerRuntimeLoader.php
│   │   ├── FactoryRuntimeLoader.php
│   │   └── RuntimeLoaderInterface.php
│   ├── Sandbox/
│   │   ├── SecurityError.php
│   │   ├── SecurityNotAllowedFilterError.php
│   │   ├── SecurityNotAllowedFunctionError.php
│   │   ├── SecurityNotAllowedMethodError.php
│   │   ├── SecurityNotAllowedPropertyError.php
│   │   ├── SecurityNotAllowedTagError.php
│   │   ├── SecurityPolicy.php
│   │   ├── SecurityPolicyInterface.php
│   │   └── SourcePolicyInterface.php
│   ├── Source.php
│   ├── Template.php
│   ├── TemplateWrapper.php
│   ├── Test/
│   │   ├── IntegrationTestCase.php
│   │   └── NodeTestCase.php
│   ├── Token.php
│   ├── TokenParser/
│   │   ├── AbstractTokenParser.php
│   │   ├── ApplyTokenParser.php
│   │   ├── AutoEscapeTokenParser.php
│   │   ├── BlockTokenParser.php
│   │   ├── DeprecatedTokenParser.php
│   │   ├── DoTokenParser.php
│   │   ├── EmbedTokenParser.php
│   │   ├── ExtendsTokenParser.php
│   │   ├── FlushTokenParser.php
│   │   ├── ForTokenParser.php
│   │   ├── FromTokenParser.php
│   │   ├── GuardTokenParser.php
│   │   ├── IfTokenParser.php
│   │   ├── ImportTokenParser.php
│   │   ├── IncludeTokenParser.php
│   │   ├── MacroTokenParser.php
│   │   ├── SandboxTokenParser.php
│   │   ├── SetTokenParser.php
│   │   ├── TokenParserInterface.php
│   │   ├── TypesTokenParser.php
│   │   ├── UseTokenParser.php
│   │   └── WithTokenParser.php
│   ├── TokenStream.php
│   ├── TwigCallableInterface.php
│   ├── TwigFilter.php
│   ├── TwigFunction.php
│   ├── TwigTest.php
│   └── Util/
│       ├── CallableArgumentsExtractor.php
│       ├── DeprecationCollector.php
│       ├── ReflectionCallable.php
│       └── TemplateDirIterator.php
└── tests/
    ├── Cache/
    │   ├── ChainTest.php
    │   ├── FilesystemTest.php
    │   └── ReadOnlyFilesystemTest.php
    ├── CompilerTest.php
    ├── ContainerRuntimeLoaderTest.php
    ├── CustomExtensionTest.php
    ├── DeprecatedCallableInfoTest.php
    ├── DummyBackedEnum.php
    ├── DummyUnitEnum.php
    ├── EnvironmentTest.php
    ├── ErrorTest.php
    ├── ExpressionParserTest.php
    ├── Extension/
    │   ├── AttributeExtensionTest.php
    │   ├── CoreTest.php
    │   ├── EscaperTest.php
    │   ├── Fixtures/
    │   │   ├── ExtensionWithAttributes.php
    │   │   ├── FilterWithoutValue.php
    │   │   └── TestWithoutValue.php
    │   ├── LegacyDebugFunctionsTest.php
    │   ├── LegacyStringLoaderFunctionsTest.php
    │   ├── SandboxTest.php
    │   └── StringLoaderExtensionTest.php
    ├── FactoryRuntimeLoaderTest.php
    ├── FileExtensionEscapingStrategyTest.php
    ├── FilesystemHelper.php
    ├── Fixtures/
    │   ├── autoescape/
    │   │   ├── block.test
    │   │   └── name.test
    │   ├── errors/
    │   │   ├── base.html
    │   │   ├── extends/
    │   │   │   ├── include.twig
    │   │   │   └── index.twig
    │   │   ├── index.html
    │   │   ├── no_line_and_context_exception.twig
    │   │   ├── no_line_and_context_exception_include_line_1.twig
    │   │   └── no_line_and_context_exception_include_line_5.twig
    │   ├── exceptions/
    │   │   ├── child_contents_outside_blocks.test
    │   │   ├── exception_in_extension_extends.test
    │   │   ├── exception_in_extension_include.test
    │   │   ├── multiline_array_with_undefined_variable.test
    │   │   ├── multiline_array_with_undefined_variable_again.test
    │   │   ├── multiline_function_with_undefined_variable.test
    │   │   ├── multiline_function_with_unknown_argument.test
    │   │   ├── multiline_tag_with_undefined_variable.test
    │   │   ├── syntax_error_in_reused_template.test
    │   │   ├── unclosed_tag.test
    │   │   ├── undefined_parent.test
    │   │   ├── undefined_template_in_child_template.test
    │   │   └── undefined_trait.test
    │   ├── expressions/
    │   │   ├── _self.test
    │   │   ├── array.test
    │   │   ├── array_call.test
    │   │   ├── attributes.test
    │   │   ├── binary.test
    │   │   ├── bitwise.test
    │   │   ├── call_argument_defined_twice.test
    │   │   ├── call_argument_unpacking.test
    │   │   ├── call_argument_unpacking_before_normal.test
    │   │   ├── call_positional_arg_after_named_arg.test
    │   │   ├── comparison.test
    │   │   ├── comparison_precedence.test
    │   │   ├── const.test
    │   │   ├── divisibleby.test
    │   │   ├── dot_as_concatenation.test
    │   │   ├── dotdot.test
    │   │   ├── dynamic_attribute.test
    │   │   ├── ends_with.test
    │   │   ├── exponential_numbers.test
    │   │   ├── floats.test
    │   │   ├── grouping.test
    │   │   ├── has_every.test
    │   │   ├── has_some.test
    │   │   ├── literals.test
    │   │   ├── magic_call.test
    │   │   ├── matches.test
    │   │   ├── matches_error_compilation.test
    │   │   ├── matches_error_runtime.test
    │   │   ├── method_call.test
    │   │   ├── negative_numbers.test
    │   │   ├── not.test
    │   │   ├── not_arrow_fn.test
    │   │   ├── operators_as_variables.test
    │   │   ├── postfix.test
    │   │   ├── power.test
    │   │   ├── sameas.test
    │   │   ├── set.test
    │   │   ├── spread_array_operator.test
    │   │   ├── spread_mapping_operator.test
    │   │   ├── spread_ternary_precedence.test
    │   │   ├── starts_with.test
    │   │   ├── string_operator_as_var_assignment.test
    │   │   ├── strings.test
    │   │   ├── ternary_operator.test
    │   │   ├── ternary_operator_noelse.test
    │   │   ├── ternary_operator_nothen.test
    │   │   ├── two_word_operators_as_variables.test
    │   │   ├── unary.test
    │   │   ├── unary_macro_arguments.test
    │   │   ├── unary_precedence.test
    │   │   ├── underscored_numbers.test
    │   │   └── underscored_numbers_error.test
    │   ├── extensions/
    │   │   └── anonymous_functions.test
    │   ├── filters/
    │   │   ├── abs.test
    │   │   ├── arrow_reserved_names.test
    │   │   ├── batch.test
    │   │   ├── batch_float.test
    │   │   ├── batch_with_empty_fill.test
    │   │   ├── batch_with_exact_elements.test
    │   │   ├── batch_with_fill.test
    │   │   ├── batch_with_keys.test
    │   │   ├── batch_with_more_elements.test
    │   │   ├── batch_with_zero_elements.test
    │   │   ├── capitalize.test
    │   │   ├── column.test
    │   │   ├── convert_encoding.test
    │   │   ├── date.test
    │   │   ├── date_default_format.test
    │   │   ├── date_default_format_interval.test
    │   │   ├── date_immutable.test
    │   │   ├── date_interval.test
    │   │   ├── date_modify.test
    │   │   ├── date_namedargs.test
    │   │   ├── date_time_zone_conversion.test
    │   │   ├── default.test
    │   │   ├── dynamic_filter.test
    │   │   ├── escape.test
    │   │   ├── escape_html_attr.test
    │   │   ├── escape_html_attr_relaxed.test
    │   │   ├── escape_javascript.test
    │   │   ├── escape_non_supported_charset.test
    │   │   ├── filter.test
    │   │   ├── find.test
    │   │   ├── first.test
    │   │   ├── force_escape.test
    │   │   ├── format.test
    │   │   ├── invoke.test
    │   │   ├── join.test
    │   │   ├── json_encode.test
    │   │   ├── last.test
    │   │   ├── length.test
    │   │   ├── length_utf8.test
    │   │   ├── lower.test
    │   │   ├── map.test
    │   │   ├── merge.test
    │   │   ├── nl2br.test
    │   │   ├── number_format.test
    │   │   ├── number_format_default.test
    │   │   ├── raw.test
    │   │   ├── reduce.test
    │   │   ├── reduce_key.test
    │   │   ├── replace.test
    │   │   ├── replace_invalid_arg.test
    │   │   ├── reverse.test
    │   │   ├── round.test
    │   │   ├── shuffle.test
    │   │   ├── slice.test
    │   │   ├── sort.test
    │   │   ├── sort_with_arrow.test
    │   │   ├── spaceless.legacy.test
    │   │   ├── special_chars.test
    │   │   ├── split.test
    │   │   ├── split_utf8.test
    │   │   ├── static_calls.test
    │   │   ├── striptags.test
    │   │   ├── title.test
    │   │   ├── trailing_commas.test
    │   │   ├── trim.test
    │   │   ├── upper.test
    │   │   └── urlencode.test
    │   ├── functions/
    │   │   ├── attribute.legacy.test
    │   │   ├── attribute_with_wrong_args.legacy.test
    │   │   ├── block.test
    │   │   ├── block_with_template.test
    │   │   ├── block_without_name.test
    │   │   ├── block_without_parent.test
    │   │   ├── constant.test
    │   │   ├── cycle.test
    │   │   ├── cycle_empty_mapping.test
    │   │   ├── cycle_empty_sequence.test
    │   │   ├── cycle_without_enough_args.test
    │   │   ├── date.test
    │   │   ├── date_namedargs.test
    │   │   ├── deprecated.test
    │   │   ├── dump.test
    │   │   ├── dump_array.test
    │   │   ├── dynamic_function.test
    │   │   ├── enum/
    │   │   │   ├── invalid_dynamic_enum.test
    │   │   │   ├── invalid_enum.test
    │   │   │   ├── invalid_enum_escaping.test
    │   │   │   ├── invalid_literal_type.test
    │   │   │   └── valid.test
    │   │   ├── enum_cases/
    │   │   │   ├── invalid_dynamic_enum.test
    │   │   │   ├── invalid_enum.test
    │   │   │   ├── invalid_enum_escaping.test
    │   │   │   ├── invalid_literal_type.test
    │   │   │   └── valid.test
    │   │   ├── include/
    │   │   │   ├── assignment.test
    │   │   │   ├── autoescaping.test
    │   │   │   ├── basic.test
    │   │   │   ├── expression.test
    │   │   │   ├── ignore_missing.test
    │   │   │   ├── ignore_missing_exists.test
    │   │   │   ├── include_missing_extends.test
    │   │   │   ├── missing.test
    │   │   │   ├── missing_nested.test
    │   │   │   ├── sandbox.test
    │   │   │   ├── sandbox_disabling.test
    │   │   │   ├── sandbox_disabling_ignore_missing.test
    │   │   │   ├── template_instance.test
    │   │   │   ├── templates_as_array.test
    │   │   │   ├── with_context.test
    │   │   │   └── with_variables.test
    │   │   ├── include_template_from_string.test
    │   │   ├── magic_call.test
    │   │   ├── magic_static_call.test
    │   │   ├── max.test
    │   │   ├── max_without_args.test
    │   │   ├── min.test
    │   │   ├── parent_in_condition.test
    │   │   ├── parent_outside_of_a_block.test
    │   │   ├── range.test
    │   │   ├── recursive_block_with_inheritance.test
    │   │   ├── source.test
    │   │   ├── special_chars.test
    │   │   ├── static_calls.test
    │   │   ├── template_from_string.test
    │   │   ├── template_from_string_error.test
    │   │   ├── template_from_string_error_php80.test
    │   │   ├── trailing_commas.test
    │   │   ├── undefined_block.test
    │   │   └── undefined_block_deep.test
    │   ├── macros/
    │   │   ├── arrow_as_arg.test
    │   │   ├── default_values.test
    │   │   ├── macro_with_capture.test
    │   │   ├── nested_calls.test
    │   │   ├── reserved_variables.test
    │   │   ├── simple.test
    │   │   ├── trailing_commas.test
    │   │   ├── unknown_macro.test
    │   │   ├── unknown_macro_different_template.test
    │   │   ├── varargs.test
    │   │   ├── varargs_argument.test
    │   │   └── with_filters.test
    │   ├── operators/
    │   │   ├── concat_vs_add_sub.test
    │   │   ├── contat_vs_add_sub.legacy.test
    │   │   ├── minus_vs_pipe.legacy.test
    │   │   ├── not_precedence.legacy.test
    │   │   └── not_precedence.test
    │   ├── regression/
    │   │   ├── 4029-iterator_to_array.test
    │   │   ├── 4033-missing-unwrap.test
    │   │   ├── 4701-block-inheritance-issue.test
    │   │   ├── block_names_unicity.test
    │   │   ├── combined_debug_info.test
    │   │   ├── empty_token.test
    │   │   ├── markup_test.test
    │   │   ├── multi_word_tests.test
    │   │   ├── simple_xml_element.test
    │   │   └── strings_like_numbers.test
    │   ├── tags/
    │   │   ├── apply/
    │   │   │   ├── basic.test
    │   │   │   ├── json_encode.test
    │   │   │   ├── multiple.test
    │   │   │   ├── nested.test
    │   │   │   ├── scope.test
    │   │   │   ├── with_for_tag.test
    │   │   │   └── with_if_tag.test
    │   │   ├── autoescape/
    │   │   │   ├── basic.test
    │   │   │   ├── blocks.test
    │   │   │   ├── double_escaping.test
    │   │   │   ├── functions.test
    │   │   │   ├── literal.test
    │   │   │   ├── nested.test
    │   │   │   ├── objects.test
    │   │   │   ├── raw.test
    │   │   │   ├── strategy.test
    │   │   │   ├── type.test
    │   │   │   ├── with_filters.test
    │   │   │   ├── with_filters_arguments.test
    │   │   │   ├── with_pre_escape_filters.test
    │   │   │   └── with_preserves_safety_filters.test
    │   │   ├── block/
    │   │   │   ├── basic.test
    │   │   │   ├── block_unique_name.test
    │   │   │   ├── conditional_block.test
    │   │   │   └── special_chars.test
    │   │   ├── deprecated/
    │   │   │   ├── block.legacy.test
    │   │   │   ├── macro.legacy.test
    │   │   │   ├── template.legacy.test
    │   │   │   ├── with_package.legacy.test
    │   │   │   └── with_package_version.legacy.test
    │   │   ├── embed/
    │   │   │   ├── basic.test
    │   │   │   ├── complex_dynamic_parent.test
    │   │   │   ├── dynamic_parent.test
    │   │   │   ├── embed_ignore_missing.test
    │   │   │   ├── error_line.test
    │   │   │   ├── multiple.test
    │   │   │   ├── nested.test
    │   │   │   └── with_extends.test
    │   │   ├── for/
    │   │   │   ├── context.test
    │   │   │   ├── else.test
    │   │   │   ├── for_on_strings.test
    │   │   │   ├── inner_variables.test
    │   │   │   ├── keys.test
    │   │   │   ├── keys_and_values.test
    │   │   │   ├── loop_context.test
    │   │   │   ├── loop_context_local.test
    │   │   │   ├── nested_else.test
    │   │   │   ├── objects.test
    │   │   │   ├── objects_countable.test
    │   │   │   ├── recursive.test
    │   │   │   ├── reserved_names.test
    │   │   │   └── values.test
    │   │   ├── from.test
    │   │   ├── guard/
    │   │   │   ├── basic.test
    │   │   │   ├── exception.test
    │   │   │   ├── nested.test
    │   │   │   └── throwing_handler.test
    │   │   ├── if/
    │   │   │   ├── basic.test
    │   │   │   ├── empty_body.test
    │   │   │   └── expression.test
    │   │   ├── include/
    │   │   │   ├── basic.test
    │   │   │   ├── expression.test
    │   │   │   ├── ignore_missing.test
    │   │   │   ├── ignore_missing_exists.test
    │   │   │   ├── include_missing_extends.test
    │   │   │   ├── missing.test
    │   │   │   ├── missing_nested.test
    │   │   │   ├── only.test
    │   │   │   ├── template_instance.test
    │   │   │   ├── templates_as_array.test
    │   │   │   └── with_variables.test
    │   │   ├── inheritance/
    │   │   │   ├── basic.test
    │   │   │   ├── block_expr.test
    │   │   │   ├── block_expr2.test
    │   │   │   ├── capturing_block.test
    │   │   │   ├── conditional.test
    │   │   │   ├── conditional_block.test
    │   │   │   ├── conditional_block_nested.test
    │   │   │   ├── dynamic.test
    │   │   │   ├── dynamic_parent_from_include.test
    │   │   │   ├── empty.test
    │   │   │   ├── extends_as_array.test
    │   │   │   ├── extends_as_array_with_empty_name.test
    │   │   │   ├── extends_as_array_with_nested_blocks.test
    │   │   │   ├── extends_in_block.test
    │   │   │   ├── extends_in_macro.test
    │   │   │   ├── extends_with_nested_blocks.test
    │   │   │   ├── multiple.test
    │   │   │   ├── multiple_dynamic.test
    │   │   │   ├── nested_blocks.test
    │   │   │   ├── nested_blocks_parent_only.test
    │   │   │   ├── nested_inheritance.test
    │   │   │   ├── parent.test
    │   │   │   ├── parent_as_template_wrapper.test
    │   │   │   ├── parent_change.test
    │   │   │   ├── parent_isolation.test
    │   │   │   ├── parent_nested.test
    │   │   │   ├── parent_without_extends.test
    │   │   │   ├── parent_without_extends_but_traits.test
    │   │   │   ├── template_instance.test
    │   │   │   └── use.test
    │   │   ├── macro/
    │   │   │   ├── argument_reserved_names.test
    │   │   │   ├── auto_import.test
    │   │   │   ├── auto_import_blocks.test
    │   │   │   ├── auto_import_without_blocks.test
    │   │   │   ├── basic.test
    │   │   │   ├── colon_not_supported_as_default_separator.test
    │   │   │   ├── endmacro_name.test
    │   │   │   ├── external.test
    │   │   │   ├── from.test
    │   │   │   ├── from_embed_with_global_macro.test
    │   │   │   ├── from_in_block_is_local.test
    │   │   │   ├── from_local_override.test
    │   │   │   ├── from_macro_in_a_macro.test
    │   │   │   ├── from_macros_in_parent.test
    │   │   │   ├── from_nested_blocks.test
    │   │   │   ├── from_nested_blocks_with_global_macro.test
    │   │   │   ├── from_recursive.test
    │   │   │   ├── from_reserved_names.test
    │   │   │   ├── from_self_parent.test
    │   │   │   ├── from_syntax_error.test
    │   │   │   ├── global.test
    │   │   │   ├── import_and_blocks.test
    │   │   │   ├── import_embed_with_global_macro.test
    │   │   │   ├── import_from_string_template.test
    │   │   │   ├── import_in_block_is_local.test
    │   │   │   ├── import_local_override.test
    │   │   │   ├── import_macro_in_a_macro.test
    │   │   │   ├── import_macros_in_parent.test
    │   │   │   ├── import_nested_blocks.test
    │   │   │   ├── import_nested_blocks_with_global_macro.test
    │   │   │   ├── import_reserved_names.test
    │   │   │   ├── import_same_parent_and_child.test
    │   │   │   ├── import_self_parent.test
    │   │   │   ├── import_syntax_error.test
    │   │   │   ├── named_arguments.test
    │   │   │   ├── self_import.test
    │   │   │   ├── special_chars.test
    │   │   │   └── super_globals.test
    │   │   ├── sandbox/
    │   │   │   ├── array.legacy.test
    │   │   │   ├── not_valid1.legacy.test
    │   │   │   ├── not_valid2.legacy.test
    │   │   │   └── simple.legacy.test
    │   │   ├── set/
    │   │   │   ├── basic.test
    │   │   │   ├── capture-empty.test
    │   │   │   ├── capture.test
    │   │   │   ├── capture_scope.test
    │   │   │   ├── expression.test
    │   │   │   ├── inheritance.test
    │   │   │   ├── inheritance_overriding.test
    │   │   │   ├── mutating.test
    │   │   │   └── reserved_names.test
    │   │   ├── special_chars.test
    │   │   ├── use/
    │   │   │   ├── aliases.test
    │   │   │   ├── basic.test
    │   │   │   ├── deep.test
    │   │   │   ├── deep_empty.test
    │   │   │   ├── inheritance.test
    │   │   │   ├── inheritance2.test
    │   │   │   ├── multiple.test
    │   │   │   ├── multiple_aliases.test
    │   │   │   ├── parent_block.test
    │   │   │   ├── parent_block2.test
    │   │   │   ├── parent_block3.test
    │   │   │   ├── use_aliased_block_overridden.test
    │   │   │   └── use_with_parent.test
    │   │   ├── verbatim/
    │   │   │   ├── basic.test
    │   │   │   └── whitespace_control.test
    │   │   └── with/
    │   │       ├── basic.test
    │   │       ├── expression.test
    │   │       ├── globals.test
    │   │       ├── iterable.test
    │   │       ├── nested.test
    │   │       ├── with_no_mapping.test
    │   │       └── with_only.test
    │   ├── tests/
    │   │   ├── array.test
    │   │   ├── constant.test
    │   │   ├── defined.test
    │   │   ├── defined_for_attribute.legacy.test
    │   │   ├── defined_for_attribute.test
    │   │   ├── defined_for_blocks.test
    │   │   ├── defined_for_blocks_with_template.test
    │   │   ├── defined_for_constants.test
    │   │   ├── defined_for_macros.test
    │   │   ├── defined_on_complex_expr.test
    │   │   ├── dynamic_test.test
    │   │   ├── empty.test
    │   │   ├── even.test
    │   │   ├── in.test
    │   │   ├── in_with_iterator.test
    │   │   ├── in_with_objects.test
    │   │   ├── iterable.test
    │   │   ├── mapping.test
    │   │   ├── null_coalesce.legacy.test
    │   │   ├── null_coalesce.test
    │   │   ├── null_coalesce_block.test
    │   │   ├── odd.test
    │   │   └── sequence.test
    │   └── whitespace/
    │       ├── trim_block.test
    │       ├── trim_delimiter_as_strings.test
    │       ├── trim_left.test
    │       ├── trim_line_left.test
    │       ├── trim_line_right.test
    │       └── trim_right.test
    ├── IntegrationTest.php
    ├── LexerTest.php
    ├── Loader/
    │   ├── ArrayTest.php
    │   ├── ChainTest.php
    │   ├── FilesystemTest.php
    │   └── Fixtures/
    │       ├── inheritance/
    │       │   ├── array_inheritance_empty_parent.html.twig
    │       │   ├── array_inheritance_nonexistent_parent.html.twig
    │       │   ├── array_inheritance_valid_parent.html.twig
    │       │   ├── parent.html.twig
    │       │   └── spare_parent.html.twig
    │       ├── named/
    │       │   └── index.html
    │       ├── named_bis/
    │       │   └── index.html
    │       ├── named_final/
    │       │   └── index.html
    │       ├── named_quater/
    │       │   └── named_absolute.html
    │       ├── named_ter/
    │       │   └── index.html
    │       ├── normal/
    │       │   └── index.html
    │       ├── normal_bis/
    │       │   └── index.html
    │       ├── normal_final/
    │       │   └── index.html
    │       ├── normal_ter/
    │       │   └── index.html
    │       ├── phar/
    │       │   └── phar-sample.phar
    │       └── themes/
    │           ├── theme1/
    │           │   └── blocks.html.twig
    │           └── theme2/
    │               └── blocks.html.twig
    ├── Node/
    │   ├── AutoEscapeTest.php
    │   ├── BlockReferenceTest.php
    │   ├── BlockTest.php
    │   ├── DeprecatedTest.php
    │   ├── DoTest.php
    │   ├── EmbedTest.php
    │   ├── Expression/
    │   │   ├── ArrayTest.php
    │   │   ├── Binary/
    │   │   │   ├── AddTest.php
    │   │   │   ├── AndTest.php
    │   │   │   ├── ConcatTest.php
    │   │   │   ├── DivTest.php
    │   │   │   ├── FloorDivTest.php
    │   │   │   ├── ModTest.php
    │   │   │   ├── MulTest.php
    │   │   │   ├── NullCoalesceTest.php
    │   │   │   ├── OrTest.php
    │   │   │   └── SubTest.php
    │   │   ├── CallTest.php
    │   │   ├── ConditionalTest.php
    │   │   ├── ConstantTest.php
    │   │   ├── Filter/
    │   │   │   └── RawTest.php
    │   │   ├── FilterTest.php
    │   │   ├── FilterTestExtension.php
    │   │   ├── FunctionTest.php
    │   │   ├── GetAttrTest.php
    │   │   ├── NullCoalesceTest.php
    │   │   ├── ParentTest.php
    │   │   ├── Ternary/
    │   │   │   └── ConditionalTernaryTest.php
    │   │   ├── TestTest.php
    │   │   ├── Unary/
    │   │   │   ├── NegTest.php
    │   │   │   ├── NotTest.php
    │   │   │   └── PosTest.php
    │   │   └── Variable/
    │   │       ├── AssignContextVariableTest.php
    │   │       └── ContextVariableTest.php
    │   ├── ForTest.php
    │   ├── IfTest.php
    │   ├── ImportTest.php
    │   ├── IncludeTest.php
    │   ├── MacroTest.php
    │   ├── ModuleTest.php
    │   ├── NodeTest.php
    │   ├── PrintTest.php
    │   ├── SandboxTest.php
    │   ├── SetTest.php
    │   ├── TextTest.php
    │   └── TypesTest.php
    ├── NodeVisitor/
    │   ├── OptimizerTest.php
    │   └── SandboxTest.php
    ├── ParserTest.php
    ├── Profiler/
    │   ├── Dumper/
    │   │   ├── BlackfireTest.php
    │   │   ├── HtmlTest.php
    │   │   ├── ProfilerTestCase.php
    │   │   └── TextTest.php
    │   └── ProfileTest.php
    ├── Runtime/
    │   └── EscaperRuntimeTest.php
    ├── TemplateTest.php
    ├── TemplateWrapperTest.php
    ├── TokenParser/
    │   ├── GuardTokenParserTest.php
    │   └── TypesTokenParserTest.php
    ├── TokenStreamTest.php
    ├── Util/
    │   ├── CallableArgumentsExtractorTest.php
    │   └── DeprecationCollectorTest.php
    └── drupal_test.sh
Download .txt
Showing preview only (243K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2527 symbols across 405 files)

FILE: extra/cache-extra/CacheExtension.php
  class CacheExtension (line 17) | final class CacheExtension extends AbstractExtension
    method getTokenParsers (line 19) | public function getTokenParsers(): array

FILE: extra/cache-extra/CacheRuntime.php
  class CacheRuntime (line 16) | class CacheRuntime
    method __construct (line 20) | public function __construct(CacheInterface $cache)
    method getCache (line 25) | public function getCache(): CacheInterface

FILE: extra/cache-extra/Node/CacheNode.php
  class CacheNode (line 19) | class CacheNode extends AbstractExpression
    method __construct (line 21) | public function __construct(AbstractExpression $key, ?AbstractExpressi...
    method compile (line 37) | public function compile(Compiler $compiler): void

FILE: extra/cache-extra/Tests/FunctionalTest.php
  class FunctionalTest (line 24) | class FunctionalTest extends TestCase
    method testIsCached (line 26) | public function testIsCached()
    method testTtlNoArgs (line 36) | public function testTtlNoArgs()
    method testTtlTooManyArgs (line 44) | public function testTtlTooManyArgs()
    method testTagsNoArgs (line 52) | public function testTagsNoArgs()
    method testTagsTooManyArgs (line 60) | public function testTagsTooManyArgs()
    method createEnvironment (line 68) | private function createEnvironment(array $templates, ?ArrayAdapter $ca...

FILE: extra/cache-extra/Tests/IntegrationTest.php
  class IntegrationTest (line 20) | class IntegrationTest extends IntegrationTestCase
    method getExtensions (line 22) | public function getExtensions()
    method getRuntimeLoaders (line 29) | protected function getRuntimeLoaders()
    method getFixturesDirectory (line 41) | protected static function getFixturesDirectory(): string

FILE: extra/cache-extra/TokenParser/CacheTokenParser.php
  class CacheTokenParser (line 22) | class CacheTokenParser extends AbstractTokenParser
    method parse (line 24) | public function parse(Token $token): Node
    method decideCacheEnd (line 65) | public function decideCacheEnd(Token $token): bool
    method getTag (line 70) | public function getTag(): string

FILE: extra/cssinliner-extra/CssInlinerExtension.php
  class CssInlinerExtension (line 18) | class CssInlinerExtension extends AbstractExtension
    method getFilters (line 20) | public function getFilters(): array
    method inlineCss (line 30) | public static function inlineCss(string $body, string ...$css): string

FILE: extra/cssinliner-extra/Resources/functions.php
  function twig_inline_css (line 19) | function twig_inline_css(string $body, string ...$css): string

FILE: extra/cssinliner-extra/Tests/IntegrationTest.php
  class IntegrationTest (line 17) | class IntegrationTest extends IntegrationTestCase
    method getExtensions (line 19) | public function getExtensions()
    method getFixturesDirectory (line 26) | protected static function getFixturesDirectory(): string

FILE: extra/cssinliner-extra/Tests/LegacyFunctionsTest.php
  class LegacyFunctionsTest (line 22) | class LegacyFunctionsTest extends TestCase
    method testInlineCss (line 24) | public function testInlineCss()

FILE: extra/html-extra/Cva.php
  class Cva (line 19) | final class Cva
    method __construct (line 29) | public function __construct(
    method apply (line 82) | public function apply(array $recipes, ?string ...$additionalClasses): ...
    method resolveCompoundVariant (line 116) | private function resolveCompoundVariant(array $compound, array $recipe...

FILE: extra/html-extra/HtmlAttr/AttributeValueInterface.php
  type AttributeValueInterface (line 22) | interface AttributeValueInterface
    method getValue (line 30) | public function getValue(): ?string;

FILE: extra/html-extra/HtmlAttr/InlineStyle.php
  class InlineStyle (line 19) | final class InlineStyle implements MergeableInterface, AttributeValueInt...
    method __construct (line 23) | public function __construct(mixed $value)
    method mergeInto (line 32) | public function mergeInto(mixed $previous): mixed
    method appendFrom (line 45) | public function appendFrom(mixed $newValue): mixed
    method getValue (line 54) | public function getValue(): ?string

FILE: extra/html-extra/HtmlAttr/MergeableInterface.php
  type MergeableInterface (line 27) | interface MergeableInterface
    method mergeInto (line 41) | public function mergeInto(mixed $previous): mixed;
    method appendFrom (line 54) | public function appendFrom(mixed $newValue): mixed;

FILE: extra/html-extra/HtmlAttr/SeparatedTokenList.php
  class SeparatedTokenList (line 19) | final class SeparatedTokenList implements AttributeValueInterface, Merge...
    method __construct (line 23) | public function __construct(mixed $value, private readonly string $sep...
    method mergeInto (line 34) | public function mergeInto(mixed $previous): mixed
    method appendFrom (line 47) | public function appendFrom(mixed $newValue): mixed
    method getValue (line 56) | public function getValue(): ?string

FILE: extra/html-extra/HtmlExtension.php
  class HtmlExtension (line 27) | final class HtmlExtension extends AbstractExtension
    method __construct (line 31) | public function __construct(?MimeTypes $mimeTypes = null)
    method getFilters (line 36) | public function getFilters(): array
    method getFunctions (line 45) | public function getFunctions(): array
    method dataUri (line 64) | public function dataUri(string $data, ?string $mime = null, array $par...
    method htmlClasses (line 101) | public static function htmlClasses(...$args): string
    method htmlCva (line 133) | public static function htmlCva(array|string $base = [], array $variant...
    method htmlAttrType (line 139) | public static function htmlAttrType(mixed $value, string $type = 'sst'...
    method htmlAttrMerge (line 150) | public static function htmlAttrMerge(iterable|string|false|null ...$ar...
    method htmlAttr (line 195) | public static function htmlAttr(Environment $env, iterable|string|fals...

FILE: extra/html-extra/Resources/functions.php
  function twig_html_classes (line 19) | function twig_html_classes(...$args): string

FILE: extra/html-extra/Tests/CvaTest.php
  class CvaTest (line 17) | class CvaTest extends TestCase
    method testRecipes (line 22) | public function testRecipes(array $recipe, array $recipes, string $exp...
    method testApply (line 29) | public function testApply()
    method testApplyWithNullString (line 52) | public function testApplyWithNullString()
    method recipeProvider (line 75) | public static function recipeProvider(): iterable
    method testAdditionalClasses (line 626) | public function testAdditionalClasses(string|array $base, array|string...
    method provideAdditionalClassesCases (line 636) | public static function provideAdditionalClassesCases(): iterable

FILE: extra/html-extra/Tests/HtmlAttrMergeTest.php
  class HtmlAttrMergeTest (line 19) | class HtmlAttrMergeTest extends TestCase
    method testMerge (line 24) | public function testMerge(array $expected, array $inputs)
    method htmlAttrProvider (line 31) | public static function htmlAttrProvider(): \Generator
    method testIncompatibleValuesMergeThrowsException (line 183) | public function testIncompatibleValuesMergeThrowsException()
  class MergeableStub (line 195) | class MergeableStub implements MergeableInterface
    method __construct (line 197) | public function __construct(private readonly mixed $value)
    method mergeInto (line 201) | public function mergeInto(mixed $previous): mixed
    method appendFrom (line 208) | public function appendFrom(mixed $newValue): mixed
    method __toString (line 219) | public function __toString(): string

FILE: extra/html-extra/Tests/HtmlAttrTest.php
  class HtmlAttrTest (line 22) | class HtmlAttrTest extends TestCase
    method testPrintingAttributes (line 27) | public function testPrintingAttributes(string $expected, array $inputs)
    method htmlAttrProvider (line 34) | public static function htmlAttrProvider(): \Generator
    method testIterableObjectCastedToArray (line 252) | public function testIterableObjectCastedToArray()
    method testDataAttributeWithNonJsonEncodableValueThrowsRuntimeError (line 274) | public function testDataAttributeWithNonJsonEncodableValueThrowsRuntim...
    method testNonStringableObjectAsAttributeValueThrowsRuntimeError (line 285) | public function testNonStringableObjectAsAttributeValueThrowsRuntimeEr...
  class StringableStub (line 297) | class StringableStub implements \Stringable
    method __construct (line 299) | public function __construct(private readonly string $value)
    method __toString (line 303) | public function __toString(): string
  class AttributeValueStub (line 309) | class AttributeValueStub implements AttributeValueInterface
    method __construct (line 311) | public function __construct(private readonly ?string $value)
    method getValue (line 315) | public function getValue(): ?string

FILE: extra/html-extra/Tests/IntegrationTest.php
  class IntegrationTest (line 17) | class IntegrationTest extends IntegrationTestCase
    method getExtensions (line 19) | public function getExtensions()
    method getFixturesDirectory (line 26) | protected static function getFixturesDirectory(): string

FILE: extra/html-extra/Tests/LegacyFunctionsTest.php
  class LegacyFunctionsTest (line 20) | class LegacyFunctionsTest extends TestCase
    method testHtmlToMarkdown (line 22) | public function testHtmlToMarkdown()

FILE: extra/inky-extra/InkyExtension.php
  class InkyExtension (line 18) | class InkyExtension extends AbstractExtension
    method getFilters (line 20) | public function getFilters(): array
    method inky (line 30) | public static function inky(string $body): string

FILE: extra/inky-extra/Resources/functions.php
  function twig_inky (line 19) | function twig_inky(string $body): string

FILE: extra/inky-extra/Tests/IntegrationTest.php
  class IntegrationTest (line 17) | class IntegrationTest extends IntegrationTestCase
    method getExtensions (line 19) | public function getExtensions()
    method getFixturesDirectory (line 26) | protected static function getFixturesDirectory(): string

FILE: extra/inky-extra/Tests/LegacyFunctionsTest.php
  class LegacyFunctionsTest (line 22) | class LegacyFunctionsTest extends TestCase
    method testInlineCss (line 24) | public function testInlineCss()

FILE: extra/intl-extra/IntlExtension.php
  class IntlExtension (line 28) | final class IntlExtension extends AbstractExtension
    method availableDateFormats (line 30) | private static function availableDateFormats(): array
    method __construct (line 153) | public function __construct(?\IntlDateFormatter $dateFormatterPrototyp...
    method getFilters (line 159) | public function getFilters(): array
    method getFunctions (line 180) | public function getFunctions(): array
    method getCountryName (line 194) | public function getCountryName(?string $country, ?string $locale = nul...
    method getCurrencyName (line 207) | public function getCurrencyName(?string $currency, ?string $locale = n...
    method getCurrencySymbol (line 220) | public function getCurrencySymbol(?string $currency, ?string $locale =...
    method getLanguageName (line 233) | public function getLanguageName(?string $language, ?string $locale = n...
    method getLocaleName (line 246) | public function getLocaleName(?string $data, ?string $locale = null): ...
    method getTimezoneName (line 259) | public function getTimezoneName(?string $timezone, ?string $locale = n...
    method getCountryTimezones (line 272) | public function getCountryTimezones(string $country): array
    method getLanguageNames (line 281) | public function getLanguageNames(?string $locale = null): array
    method getScriptNames (line 290) | public function getScriptNames(?string $locale = null): array
    method getCountryNames (line 299) | public function getCountryNames(?string $locale = null): array
    method getLocaleNames (line 308) | public function getLocaleNames(?string $locale = null): array
    method getCurrencyNames (line 317) | public function getCurrencyNames(?string $locale = null): array
    method getTimezoneNames (line 326) | public function getTimezoneNames(?string $locale = null): array
    method formatCurrency (line 335) | public function formatCurrency($amount, string $currency, array $attrs...
    method formatNumber (line 346) | public function formatNumber($number, array $attrs = [], string $style...
    method formatNumberStyle (line 361) | public function formatNumberStyle(string $style, $number, array $attrs...
    method formatDateTime (line 370) | public function formatDateTime(Environment $env, $date, ?string $dateF...
    method formatDate (line 393) | public function formatDate(Environment $env, $date, ?string $dateForma...
    method formatTime (line 402) | public function formatTime(Environment $env, $date, ?string $timeForma...
    method createDateFormatter (line 407) | private function createDateFormatter(?string $locale, ?string $dateFor...
    method createNumberFormatter (line 450) | private function createNumberFormatter(?string $locale, string $style,...

FILE: extra/intl-extra/Tests/IntegrationTest.php
  class IntegrationTest (line 17) | class IntegrationTest extends IntegrationTestCase
    method getExtensions (line 19) | public function getExtensions()
    method getFixturesDirectory (line 26) | protected static function getFixturesDirectory(): string

FILE: extra/intl-extra/Tests/IntlExtensionTest.php
  class IntlExtensionTest (line 20) | class IntlExtensionTest extends TestCase
    method testFormatterWithoutProto (line 22) | public function testFormatterWithoutProto()
    method testFormatterWithoutProtoFallsBackToCoreExtensionTimezone (line 34) | public function testFormatterWithoutProtoFallsBackToCoreExtensionTimez...
    method testFormatterWithoutProtoSkipTimezoneConverter (line 48) | public function testFormatterWithoutProtoSkipTimezoneConverter()
    method testFormatterProto (line 62) | public function testFormatterProto()
    method testFormatterOverridenProto (line 81) | public function testFormatterOverridenProto()

FILE: extra/markdown-extra/DefaultMarkdown.php
  class DefaultMarkdown (line 17) | class DefaultMarkdown implements MarkdownInterface
    method __construct (line 21) | public function __construct()
    method convert (line 34) | public function convert(string $body): string

FILE: extra/markdown-extra/ErusevMarkdown.php
  class ErusevMarkdown (line 14) | class ErusevMarkdown implements MarkdownInterface
    method __construct (line 18) | public function __construct(?\Parsedown $converter = null)
    method convert (line 23) | public function convert(string $body): string

FILE: extra/markdown-extra/LeagueMarkdown.php
  class LeagueMarkdown (line 17) | class LeagueMarkdown implements MarkdownInterface
    method __construct (line 22) | public function __construct(?MarkdownConverter $converter = null)
    method convert (line 28) | public function convert(string $body): string

FILE: extra/markdown-extra/MarkdownExtension.php
  class MarkdownExtension (line 18) | final class MarkdownExtension extends AbstractExtension
    method getFilters (line 20) | public function getFilters(): array
    method htmlToMarkdown (line 31) | public static function htmlToMarkdown(string $body, array $options = [...

FILE: extra/markdown-extra/MarkdownInterface.php
  type MarkdownInterface (line 14) | interface MarkdownInterface
    method convert (line 16) | public function convert(string $body): string;

FILE: extra/markdown-extra/MarkdownRuntime.php
  class MarkdownRuntime (line 14) | class MarkdownRuntime
    method __construct (line 18) | public function __construct(MarkdownInterface $converter)
    method convert (line 23) | public function convert(string $body): string

FILE: extra/markdown-extra/MichelfMarkdown.php
  class MichelfMarkdown (line 16) | class MichelfMarkdown implements MarkdownInterface
    method __construct (line 20) | public function __construct(?MarkdownExtra $converter = null)
    method convert (line 30) | public function convert(string $body): string

FILE: extra/markdown-extra/Resources/functions.php
  function html_to_markdown (line 19) | function html_to_markdown(string $body, array $options = []): string

FILE: extra/markdown-extra/Tests/FunctionalTest.php
  class FunctionalTest (line 25) | class FunctionalTest extends TestCase
    method testMarkdown (line 30) | public function testMarkdown(string $template, string $expected)
    method getMarkdownTests (line 60) | public static function getMarkdownTests()

FILE: extra/markdown-extra/Tests/IntegrationTest.php
  class IntegrationTest (line 17) | class IntegrationTest extends IntegrationTestCase
    method getExtensions (line 19) | public function getExtensions()
    method getFixturesDirectory (line 26) | protected static function getFixturesDirectory(): string

FILE: extra/markdown-extra/Tests/LegacyFunctionsTest.php
  class LegacyFunctionsTest (line 23) | class LegacyFunctionsTest extends TestCase
    method testHtmlToMarkdown (line 25) | public function testHtmlToMarkdown()

FILE: extra/string-extra/StringExtension.php
  class StringExtension (line 26) | final class StringExtension extends AbstractExtension
    method __construct (line 33) | public function __construct(?SluggerInterface $slugger = null)
    method getFilters (line 38) | public function getFilters(): array
    method createUnicodeString (line 48) | public function createUnicodeString(?string $text): UnicodeString
    method createSlug (line 53) | public function createSlug(string $string, string $separator = '-', ?s...
    method plural (line 61) | public function plural(string $value, string $locale = 'en', bool $all...
    method singular (line 73) | public function singular(string $value, string $locale = 'en', bool $a...
    method getInflector (line 82) | private function getInflector(string $locale): InflectorInterface

FILE: extra/string-extra/Tests/IntegrationTest.php
  class IntegrationTest (line 17) | class IntegrationTest extends IntegrationTestCase
    method getExtensions (line 19) | public function getExtensions()
    method getFixturesDirectory (line 26) | protected static function getFixturesDirectory(): string

FILE: extra/twig-extra-bundle/DependencyInjection/Compiler/MissingExtensionSuggestorPass.php
  class MissingExtensionSuggestorPass (line 19) | class MissingExtensionSuggestorPass implements CompilerPassInterface
    method process (line 21) | public function process(ContainerBuilder $container): void
    method process (line 38) | public function process(ContainerBuilder $container)
  class MissingExtensionSuggestorPass (line 35) | class MissingExtensionSuggestorPass implements CompilerPassInterface
    method process (line 21) | public function process(ContainerBuilder $container): void
    method process (line 38) | public function process(ContainerBuilder $container)

FILE: extra/twig-extra-bundle/DependencyInjection/Configuration.php
  class Configuration (line 19) | class Configuration implements ConfigurationInterface
    method getConfigTreeBuilder (line 21) | public function getConfigTreeBuilder(): TreeBuilder
    method addCommonMarkConfiguration (line 44) | private function addCommonMarkConfiguration(ArrayNodeDefinition $rootN...

FILE: extra/twig-extra-bundle/DependencyInjection/TwigExtraExtension.php
  type TwigExtraExtensionTrait (line 23) | trait TwigExtraExtensionTrait
    method load (line 25) | public function load(array $configs, ContainerBuilder $container): void
    method load (line 35) | public function load(array $configs, ContainerBuilder $container)
  type TwigExtraExtensionTrait (line 32) | trait TwigExtraExtensionTrait
    method load (line 25) | public function load(array $configs, ContainerBuilder $container): void
    method load (line 35) | public function load(array $configs, ContainerBuilder $container)
  class TwigExtraExtension (line 45) | class TwigExtraExtension extends Extension
    method doLoad (line 49) | private function doLoad(array $configs, ContainerBuilder $container): ...

FILE: extra/twig-extra-bundle/Extensions.php
  class Extensions (line 22) | final class Extensions
    method getClasses (line 94) | public static function getClasses(): array
    method getFilter (line 99) | public static function getFilter(string $name): array
    method getFunction (line 110) | public static function getFunction(string $name): array
    method getTag (line 121) | public static function getTag(string $name): array

FILE: extra/twig-extra-bundle/LeagueCommonMarkConverterFactory.php
  class LeagueCommonMarkConverterFactory (line 20) | final class LeagueCommonMarkConverterFactory
    method __construct (line 28) | public function __construct(iterable $extensions, array $config = [])
    method __invoke (line 34) | public function __invoke(): CommonMarkConverter

FILE: extra/twig-extra-bundle/MissingExtensionSuggestor.php
  class MissingExtensionSuggestor (line 16) | final class MissingExtensionSuggestor
    method suggestFilter (line 18) | public function suggestFilter(string $name): bool
    method suggestFunction (line 27) | public function suggestFunction(string $name): bool
    method suggestTag (line 36) | public function suggestTag(string $name): bool

FILE: extra/twig-extra-bundle/Tests/DependencyInjection/TwigExtraExtensionTest.php
  class TwigExtraExtensionTest (line 21) | class TwigExtraExtensionTest extends TestCase
    method testDefaultConfiguration (line 23) | public function testDefaultConfiguration()

FILE: extra/twig-extra-bundle/Tests/Fixture/Kernel.php
  class Kernel (line 24) | class Kernel extends BaseKernel
    method registerBundles (line 28) | public function registerBundles(): iterable
    method configureContainer (line 35) | protected function configureContainer(ContainerBuilder $c, LoaderInter...
    method configureRoutes (line 60) | protected function configureRoutes($routes): void

FILE: extra/twig-extra-bundle/Tests/IntegrationTest.php
  class IntegrationTest (line 16) | class IntegrationTest extends KernelTestCase
    method testCommonMarkRendering (line 18) | public function testCommonMarkRendering()

FILE: extra/twig-extra-bundle/TwigExtraBundle.php
  class TwigExtraBundle (line 20) | class TwigExtraBundle extends Bundle
    method build (line 22) | public function build(ContainerBuilder $container): void
    method build (line 33) | public function build(ContainerBuilder $container)
  class TwigExtraBundle (line 30) | class TwigExtraBundle extends Bundle
    method build (line 22) | public function build(ContainerBuilder $container): void
    method build (line 33) | public function build(ContainerBuilder $container)

FILE: src/AbstractTwigCallable.php
  class AbstractTwigCallable (line 17) | abstract class AbstractTwigCallable implements TwigCallableInterface
    method __construct (line 26) | public function __construct(string $name, $callable = null, array $opt...
    method __toString (line 67) | public function __toString(): string
    method getName (line 72) | public function getName(): string
    method getDynamicName (line 77) | public function getDynamicName(): string
    method getCallable (line 85) | public function getCallable()
    method getNodeClass (line 90) | public function getNodeClass(): string
    method needsCharset (line 95) | public function needsCharset(): bool
    method needsEnvironment (line 100) | public function needsEnvironment(): bool
    method needsContext (line 105) | public function needsContext(): bool
    method withDynamicArguments (line 113) | public function withDynamicArguments(string $name, string $dynamicName...
    method setArguments (line 126) | public function setArguments(array $arguments): void
    method getArguments (line 133) | public function getArguments(): array
    method isVariadic (line 138) | public function isVariadic(): bool
    method isDeprecated (line 143) | public function isDeprecated(): bool
    method triggerDeprecation (line 148) | public function triggerDeprecation(?string $file = null, ?int $line = ...
    method getDeprecatingPackage (line 156) | public function getDeprecatingPackage(): string
    method getDeprecatedVersion (line 166) | public function getDeprecatedVersion(): string
    method getAlternative (line 176) | public function getAlternative(): ?string
    method getMinimalNumberOfRequiredArguments (line 183) | public function getMinimalNumberOfRequiredArguments(): int

FILE: src/Attribute/AsTwigFilter.php
  class AsTwigFilter (line 30) | #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
    method __construct (line 44) | public function __construct(

FILE: src/Attribute/AsTwigFunction.php
  class AsTwigFunction (line 30) | #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
    method __construct (line 42) | public function __construct(

FILE: src/Attribute/AsTwigTest.php
  class AsTwigTest (line 30) | #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
    method __construct (line 40) | public function __construct(

FILE: src/Attribute/FirstClassTwigCallableReady.php
  class FirstClassTwigCallableReady (line 17) | #[\Attribute(\Attribute::TARGET_METHOD)]

FILE: src/Attribute/YieldReady.php
  class YieldReady (line 17) | #[\Attribute(\Attribute::TARGET_CLASS)]

FILE: src/Cache/CacheInterface.php
  type CacheInterface (line 23) | interface CacheInterface
    method generateKey (line 28) | public function generateKey(string $name, string $className): string;
    method write (line 35) | public function write(string $key, string $content): void;
    method load (line 40) | public function load(string $key): void;
    method getTimestamp (line 45) | public function getTimestamp(string $key): int;

FILE: src/Cache/ChainCache.php
  class ChainCache (line 22) | final class ChainCache implements CacheInterface, RemovableCacheInterface
    method __construct (line 27) | public function __construct(
    method generateKey (line 32) | public function generateKey(string $name, string $className): string
    method write (line 37) | public function write(string $key, string $content): void
    method load (line 46) | public function load(string $key): void
    method getTimestamp (line 59) | public function getTimestamp(string $key): int
    method remove (line 72) | public function remove(string $name, string $cls): void
    method splitKey (line 84) | private function splitKey(string $key): array

FILE: src/Cache/FilesystemCache.php
  class FilesystemCache (line 19) | class FilesystemCache implements CacheInterface, RemovableCacheInterface
    method __construct (line 26) | public function __construct(string $directory, int $options = 0)
    method generateKey (line 32) | public function generateKey(string $name, string $className): string
    method load (line 39) | public function load(string $key): void
    method write (line 46) | public function write(string $key, string $content): void
    method remove (line 79) | public function remove(string $name, string $cls): void
    method getTimestamp (line 87) | public function getTimestamp(string $key): int

FILE: src/Cache/NullCache.php
  class NullCache (line 19) | final class NullCache implements CacheInterface, RemovableCacheInterface
    method generateKey (line 21) | public function generateKey(string $name, string $className): string
    method write (line 26) | public function write(string $key, string $content): void
    method load (line 30) | public function load(string $key): void
    method getTimestamp (line 34) | public function getTimestamp(string $key): int
    method remove (line 39) | public function remove(string $name, string $cls): void

FILE: src/Cache/ReadOnlyFilesystemCache.php
  class ReadOnlyFilesystemCache (line 19) | class ReadOnlyFilesystemCache extends FilesystemCache
    method write (line 21) | public function write(string $key, string $content): void

FILE: src/Cache/RemovableCacheInterface.php
  type RemovableCacheInterface (line 17) | interface RemovableCacheInterface
    method remove (line 19) | public function remove(string $name, string $cls): void;

FILE: src/Compiler.php
  class Compiler (line 20) | class Compiler
    method __construct (line 32) | public function __construct(
    method getEnvironment (line 37) | public function getEnvironment(): Environment
    method getSource (line 42) | public function getSource(): string
    method reset (line 50) | public function reset(int $indentation = 0)
    method compile (line 67) | public function compile(Node $node, int $indentation = 0)
    method subcompile (line 89) | public function subcompile(Node $node, bool $raw = true)
    method raw (line 116) | public function raw(string $string)
    method write (line 129) | public function write(...$strings)
    method string (line 144) | public function string(string $value)
    method repr (line 156) | public function repr($value)
    method addDebugInfo (line 195) | public function addDebugInfo(Node $node)
    method getDebugInfo (line 210) | public function getDebugInfo(): array
    method indent (line 220) | public function indent(int $step = 1)
    method outdent (line 232) | public function outdent(int $step = 1)
    method getVarName (line 244) | public function getVarName(): string
    method checkForEcho (line 249) | private function checkForEcho(string $string): void

FILE: src/DeprecatedCallableInfo.php
  class DeprecatedCallableInfo (line 17) | final class DeprecatedCallableInfo
    method __construct (line 22) | public function __construct(
    method setType (line 31) | public function setType(string $type): void
    method setName (line 36) | public function setName(string $name): void
    method triggerDeprecation (line 41) | public function triggerDeprecation(?string $file = null, ?int $line = ...

FILE: src/Environment.php
  class Environment (line 44) | class Environment
    method __construct (line 111) | public function __construct(LoaderInterface $loader, array $options = [])
    method useYield (line 150) | public function useYield(): bool
    method enableDebug (line 160) | public function enableDebug()
    method disableDebug (line 171) | public function disableDebug()
    method isDebug (line 182) | public function isDebug()
    method enableAutoReload (line 192) | public function enableAutoReload()
    method disableAutoReload (line 202) | public function disableAutoReload()
    method isAutoReload (line 212) | public function isAutoReload()
    method enableStrictVariables (line 222) | public function enableStrictVariables()
    method disableStrictVariables (line 233) | public function disableStrictVariables()
    method isStrictVariables (line 244) | public function isStrictVariables()
    method removeCache (line 249) | public function removeCache(string $name): void
    method getCache (line 270) | public function getCache($original = true)
    method setCache (line 284) | public function setCache($cache)
    method getTemplateClass (line 315) | public function getTemplateClass(string $name, ?int $index = null): st...
    method render (line 331) | public function render($name, array $context = []): string
    method display (line 345) | public function display($name, array $context = []): void
    method load (line 359) | public function load($name): TemplateWrapper
    method loadTemplate (line 388) | public function loadTemplate(string $cls, string $name, ?int $index = ...
    method createTemplate (line 445) | public function createTemplate(string $template, ?string $name = null)...
    method isTemplateFresh (line 476) | public function isTemplateFresh(string $name, int $time): bool
    method resolveTemplate (line 492) | public function resolveTemplate($names): TemplateWrapper
    method setLexer (line 522) | public function setLexer(Lexer $lexer)
    method tokenize (line 530) | public function tokenize(Source $source): TokenStream
    method setParser (line 542) | public function setParser(Parser $parser)
    method parse (line 552) | public function parse(TokenStream $stream): ModuleNode
    method setCompiler (line 564) | public function setCompiler(Compiler $compiler)
    method compile (line 572) | public function compile(Node $node): string
    method compileSource (line 586) | public function compileSource(Source $source): string
    method setLoader (line 601) | public function setLoader(LoaderInterface $loader)
    method getLoader (line 606) | public function getLoader(): LoaderInterface
    method setCharset (line 614) | public function setCharset(string $charset)
    method getCharset (line 624) | public function getCharset(): string
    method hasExtension (line 629) | public function hasExtension(string $class): bool
    method addRuntimeLoader (line 637) | public function addRuntimeLoader(RuntimeLoaderInterface $loader)
    method getExtension (line 649) | public function getExtension(string $class): ExtensionInterface
    method getRuntime (line 665) | public function getRuntime(string $class)
    method addExtension (line 687) | public function addExtension(ExtensionInterface $extension)
    method setExtensions (line 698) | public function setExtensions(array $extensions)
    method getExtensions (line 707) | public function getExtensions(): array
    method addTokenParser (line 715) | public function addTokenParser(TokenParserInterface $parser)
    method getTokenParsers (line 725) | public function getTokenParsers(): array
    method getTokenParser (line 733) | public function getTokenParser(string $name): ?TokenParserInterface
    method registerUndefinedTokenParserCallback (line 741) | public function registerUndefinedTokenParserCallback(callable $callabl...
    method addNodeVisitor (line 749) | public function addNodeVisitor(NodeVisitorInterface $visitor)
    method getNodeVisitors (line 759) | public function getNodeVisitors(): array
    method addFilter (line 767) | public function addFilter(TwigFilter $filter)
    method getFilter (line 775) | public function getFilter(string $name): ?TwigFilter
    method registerUndefinedFilterCallback (line 783) | public function registerUndefinedFilterCallback(callable $callable): void
    method getFilters (line 799) | public function getFilters(): array
    method addTest (line 807) | public function addTest(TwigTest $test)
    method getTests (line 817) | public function getTests(): array
    method getTest (line 825) | public function getTest(string $name): ?TwigTest
    method registerUndefinedTestCallback (line 833) | public function registerUndefinedTestCallback(callable $callable): void
    method addFunction (line 841) | public function addFunction(TwigFunction $function)
    method getFunction (line 849) | public function getFunction(string $name): ?TwigFunction
    method registerUndefinedFunctionCallback (line 857) | public function registerUndefinedFunctionCallback(callable $callable):...
    method getFunctions (line 873) | public function getFunctions(): array
    method addGlobal (line 888) | public function addGlobal(string $name, $value)
    method getGlobals (line 904) | public function getGlobals(): array
    method resetGlobals (line 917) | public function resetGlobals(): void
    method mergeGlobals (line 926) | public function mergeGlobals(array $context): array
    method getExpressionParsers (line 936) | public function getExpressionParsers(): ExpressionParsers
    method updateOptionsHash (line 941) | private function updateOptionsHash(): void

FILE: src/Error/Error.php
  class Error (line 36) | class Error extends \Exception
    method __construct (line 53) | public function __construct(string $message, int $lineno = -1, ?Source...
    method getRawMessage (line 65) | public function getRawMessage(): string
    method getTemplateLine (line 70) | public function getTemplateLine(): int
    method setTemplateLine (line 75) | public function setTemplateLine(int $lineno): void
    method getSourceContext (line 81) | public function getSourceContext(): ?Source
    method setSourceContext (line 86) | public function setSourceContext(?Source $source = null): void
    method guess (line 92) | public function guess(): void
    method appendMessage (line 102) | public function appendMessage($rawMessage): void
    method updateRepr (line 108) | private function updateRepr(): void
    method guessTemplateInfo (line 136) | private function guessTemplateInfo(): void

FILE: src/Error/LoaderError.php
  class LoaderError (line 19) | class LoaderError extends Error

FILE: src/Error/RuntimeError.php
  class RuntimeError (line 20) | class RuntimeError extends Error

FILE: src/Error/SyntaxError.php
  class SyntaxError (line 20) | class SyntaxError extends Error
    method addSuggestions (line 28) | public function addSuggestions(string $name, array $items): void

FILE: src/ExpressionParser.php
  class ExpressionParser (line 41) | class ExpressionParser
    method __construct (line 52) | public function __construct(
    method parseExpression (line 59) | public function parseExpression($precedence = 0)
    method parsePrimaryExpression (line 73) | public function parsePrimaryExpression()
    method parseStringExpression (line 83) | public function parseStringExpression()
    method parseArrayExpression (line 93) | public function parseArrayExpression()
    method parseSequenceExpression (line 103) | public function parseSequenceExpression()
    method parseHashExpression (line 113) | public function parseHashExpression()
    method parseMappingExpression (line 123) | public function parseMappingExpression()
    method parsePostfixExpression (line 133) | public function parsePostfixExpression($node)
    method parseSubscriptExpression (line 158) | public function parseSubscriptExpression($node)
    method parseFilterExpression (line 174) | public function parseFilterExpression($node)
    method parseFilterExpressionRaw (line 186) | public function parseFilterExpressionRaw($node)
    method parseArguments (line 213) | public function parseArguments()
    method parseAssignmentExpression (line 299) | public function parseAssignmentExpression()
    method parseMultitargetExpression (line 326) | public function parseMultitargetExpression()
    method checkConstantExpression (line 343) | private function checkConstantExpression(Node $node): bool
    method parseOnlyArguments (line 363) | public function parseOnlyArguments()

FILE: src/ExpressionParser/AbstractExpressionParser.php
  class AbstractExpressionParser (line 14) | abstract class AbstractExpressionParser implements ExpressionParserInter...
    method __toString (line 16) | public function __toString(): string
    method getPrecedenceChange (line 21) | public function getPrecedenceChange(): ?PrecedenceChange
    method getAliases (line 26) | public function getAliases(): array
    method getOperatorTokens (line 31) | public function getOperatorTokens(): array

FILE: src/ExpressionParser/ExpressionParserDescriptionInterface.php
  type ExpressionParserDescriptionInterface (line 14) | interface ExpressionParserDescriptionInterface
    method getDescription (line 16) | public function getDescription(): string;

FILE: src/ExpressionParser/ExpressionParserInterface.php
  type ExpressionParserInterface (line 22) | interface ExpressionParserInterface
    method __toString (line 24) | public function __toString(): string;
    method getName (line 26) | public function getName(): string;
    method getPrecedence (line 28) | public function getPrecedence(): int;
    method getPrecedenceChange (line 30) | public function getPrecedenceChange(): ?PrecedenceChange;
    method getAliases (line 35) | public function getAliases(): array;

FILE: src/ExpressionParser/ExpressionParserType.php
  method getType (line 22) | public static function getType(object $object): ExpressionParserType

FILE: src/ExpressionParser/ExpressionParsers.php
  class ExpressionParsers (line 19) | final class ExpressionParsers implements \IteratorAggregate
    method __construct (line 39) | public function __construct(array $parsers = [])
    method add (line 49) | public function add(array $parsers): static
    method getByClass (line 73) | public function getByClass(string $class): ?ExpressionParserInterface
    method getByName (line 85) | public function getByName(string $interface, string $name): ?Expressio...
    method getIterator (line 90) | public function getIterator(): \Traversable
    method getPrecedenceChanges (line 116) | public function getPrecedenceChanges(): \WeakMap
    method getOperatorTokensFor (line 145) | public static function getOperatorTokensFor(ExpressionParserInterface ...

FILE: src/ExpressionParser/Infix/ArgumentsTrait.php
  type ArgumentsTrait (line 24) | trait ArgumentsTrait
    method parseCallableArguments (line 26) | private function parseCallableArguments(Parser $parser, int $line, boo...
    method parseNamedArguments (line 36) | private function parseNamedArguments(Parser $parser, bool $parseOpenPa...

FILE: src/ExpressionParser/Infix/ArrowExpressionParser.php
  class ArrowExpressionParser (line 26) | final class ArrowExpressionParser extends AbstractExpressionParser imple...
    method parse (line 28) | public function parse(Parser $parser, AbstractExpression $expr, Token ...
    method getName (line 34) | public function getName(): string
    method getDescription (line 39) | public function getDescription(): string
    method getPrecedence (line 44) | public function getPrecedence(): int
    method getAssociativity (line 49) | public function getAssociativity(): InfixAssociativity

FILE: src/ExpressionParser/Infix/AssignmentExpressionParser.php
  class AssignmentExpressionParser (line 29) | class AssignmentExpressionParser extends BinaryOperatorExpressionParser
    method __construct (line 31) | public function __construct(
    method parse (line 40) | public function parse(Parser $parser, AbstractExpression $left, Token ...
    method getDescription (line 62) | public function getDescription(): string

FILE: src/ExpressionParser/Infix/BinaryOperatorExpressionParser.php
  class BinaryOperatorExpressionParser (line 27) | class BinaryOperatorExpressionParser extends AbstractExpressionParser im...
    method __construct (line 29) | public function __construct(
    method parse (line 44) | public function parse(Parser $parser, AbstractExpression $left, Token ...
    method getAssociativity (line 51) | public function getAssociativity(): InfixAssociativity
    method getName (line 56) | public function getName(): string
    method getDescription (line 61) | public function getDescription(): string
    method getPrecedence (line 66) | public function getPrecedence(): int
    method getPrecedenceChange (line 71) | public function getPrecedenceChange(): ?PrecedenceChange
    method getAliases (line 76) | public function getAliases(): array

FILE: src/ExpressionParser/Infix/ConditionalTernaryExpressionParser.php
  class ConditionalTernaryExpressionParser (line 27) | final class ConditionalTernaryExpressionParser extends AbstractExpressio...
    method parse (line 29) | public function parse(Parser $parser, AbstractExpression $left, Token ...
    method getName (line 43) | public function getName(): string
    method getDescription (line 48) | public function getDescription(): string
    method getPrecedence (line 53) | public function getPrecedence(): int
    method getAssociativity (line 58) | public function getAssociativity(): InfixAssociativity

FILE: src/ExpressionParser/Infix/DotExpressionParser.php
  class DotExpressionParser (line 34) | final class DotExpressionParser extends AbstractExpressionParser impleme...
    method parse (line 38) | public function parse(Parser $parser, AbstractExpression $expr, Token ...
    method getName (line 81) | public function getName(): string
    method getAliases (line 86) | public function getAliases(): array
    method getDescription (line 91) | public function getDescription(): string
    method getPrecedence (line 96) | public function getPrecedence(): int
    method getAssociativity (line 101) | public function getAssociativity(): InfixAssociativity

FILE: src/ExpressionParser/Infix/FilterExpressionParser.php
  class FilterExpressionParser (line 29) | final class FilterExpressionParser extends AbstractExpressionParser impl...
    method parse (line 35) | public function parse(Parser $parser, AbstractExpression $expr, Token ...
    method getName (line 61) | public function getName(): string
    method getDescription (line 66) | public function getDescription(): string
    method getPrecedence (line 71) | public function getPrecedence(): int
    method getPrecedenceChange (line 76) | public function getPrecedenceChange(): ?PrecedenceChange
    method getAssociativity (line 81) | public function getAssociativity(): InfixAssociativity

FILE: src/ExpressionParser/Infix/FunctionExpressionParser.php
  class FunctionExpressionParser (line 30) | final class FunctionExpressionParser extends AbstractExpressionParser im...
    method parse (line 36) | public function parse(Parser $parser, AbstractExpression $expr, Token ...
    method getName (line 71) | public function getName(): string
    method getDescription (line 76) | public function getDescription(): string
    method getPrecedence (line 81) | public function getPrecedence(): int
    method getAssociativity (line 86) | public function getAssociativity(): InfixAssociativity

FILE: src/ExpressionParser/Infix/IsExpressionParser.php
  class IsExpressionParser (line 31) | class IsExpressionParser extends AbstractExpressionParser implements Inf...
    method parse (line 37) | public function parse(Parser $parser, AbstractExpression $expr, Token ...
    method getPrecedence (line 65) | public function getPrecedence(): int
    method getName (line 70) | public function getName(): string
    method getDescription (line 75) | public function getDescription(): string
    method getAssociativity (line 80) | public function getAssociativity(): InfixAssociativity

FILE: src/ExpressionParser/Infix/IsNotExpressionParser.php
  class IsNotExpressionParser (line 22) | final class IsNotExpressionParser extends IsExpressionParser
    method parse (line 24) | public function parse(Parser $parser, AbstractExpression $expr, Token ...
    method getName (line 29) | public function getName(): string

FILE: src/ExpressionParser/Infix/SquareBracketExpressionParser.php
  class SquareBracketExpressionParser (line 30) | final class SquareBracketExpressionParser extends AbstractExpressionPars...
    method parse (line 32) | public function parse(Parser $parser, AbstractExpression $expr, Token ...
    method getName (line 72) | public function getName(): string
    method getDescription (line 77) | public function getDescription(): string
    method getPrecedence (line 82) | public function getPrecedence(): int
    method getAssociativity (line 87) | public function getAssociativity(): InfixAssociativity

FILE: src/ExpressionParser/InfixExpressionParserInterface.php
  type InfixExpressionParserInterface (line 19) | interface InfixExpressionParserInterface extends ExpressionParserInterface
    method parse (line 24) | public function parse(Parser $parser, AbstractExpression $left, Token ...
    method getAssociativity (line 26) | public function getAssociativity(): InfixAssociativity;

FILE: src/ExpressionParser/PrecedenceChange.php
  class PrecedenceChange (line 19) | class PrecedenceChange
    method __construct (line 21) | public function __construct(
    method getPackage (line 28) | public function getPackage(): string
    method getVersion (line 33) | public function getVersion(): string
    method getNewPrecedence (line 38) | public function getNewPrecedence(): int

FILE: src/ExpressionParser/Prefix/GroupingExpressionParser.php
  class GroupingExpressionParser (line 28) | final class GroupingExpressionParser extends AbstractExpressionParser im...
    method parse (line 30) | public function parse(Parser $parser, Token $token): AbstractExpression
    method toAssignContextVariable (line 65) | private static function toAssignContextVariable(AbstractExpression $ex...
    method getName (line 74) | public function getName(): string
    method getDescription (line 79) | public function getDescription(): string
    method getPrecedence (line 84) | public function getPrecedence(): int

FILE: src/ExpressionParser/Prefix/LiteralExpressionParser.php
  class LiteralExpressionParser (line 31) | final class LiteralExpressionParser extends AbstractExpressionParser imp...
    method parse (line 33) | public function parse(Parser $parser, Token $token): AbstractExpression
    method getName (line 96) | public function getName(): string
    method getOperatorTokens (line 101) | public function getOperatorTokens(): array
    method getDescription (line 106) | public function getDescription(): string
    method getPrecedence (line 111) | public function getPrecedence(): int
    method parseStringExpression (line 117) | private function parseStringExpression(Parser $parser)
    method parseSequenceExpression (line 145) | private function parseSequenceExpression(Parser $parser)
    method parseMappingExpression (line 175) | private function parseMappingExpression(Parser $parser)

FILE: src/ExpressionParser/Prefix/UnaryOperatorExpressionParser.php
  class UnaryOperatorExpressionParser (line 26) | final class UnaryOperatorExpressionParser extends AbstractExpressionPars...
    method __construct (line 28) | public function __construct(
    method parse (line 43) | public function parse(Parser $parser, Token $token): AbstractExpression
    method getName (line 48) | public function getName(): string
    method getDescription (line 53) | public function getDescription(): string
    method getPrecedence (line 58) | public function getPrecedence(): int
    method getPrecedenceChange (line 63) | public function getPrecedenceChange(): ?PrecedenceChange
    method getAliases (line 68) | public function getAliases(): array

FILE: src/ExpressionParser/PrefixExpressionParserInterface.php
  type PrefixExpressionParserInterface (line 19) | interface PrefixExpressionParserInterface extends ExpressionParserInterface
    method parse (line 24) | public function parse(Parser $parser, Token $token): AbstractExpression;

FILE: src/Extension/AbstractExtension.php
  class AbstractExtension (line 14) | abstract class AbstractExtension implements LastModifiedExtensionInterface
    method getTokenParsers (line 16) | public function getTokenParsers()
    method getNodeVisitors (line 21) | public function getNodeVisitors()
    method getFilters (line 26) | public function getFilters()
    method getTests (line 31) | public function getTests()
    method getFunctions (line 36) | public function getFunctions()
    method getOperators (line 41) | public function getOperators()
    method getExpressionParsers (line 46) | public function getExpressionParsers(): array
    method getLastModified (line 51) | public function getLastModified(): int

FILE: src/Extension/AttributeExtension.php
  class AttributeExtension (line 27) | final class AttributeExtension extends AbstractExtension
    method __construct (line 38) | public function __construct(private string $class)
    method getClass (line 45) | public function getClass(): string
    method getFilters (line 50) | public function getFilters(): array
    method getFunctions (line 59) | public function getFunctions(): array
    method getTests (line 68) | public function getTests(): array
    method getLastModified (line 77) | public function getLastModified(): int
    method initFromAttributes (line 85) | private function initFromAttributes(): void
    method needsEnvironment (line 163) | private function needsEnvironment(\ReflectionFunctionAbstract $functio...

FILE: src/Extension/CoreExtension.php
  class CoreExtension (line 117) | final class CoreExtension extends AbstractExtension
    method setDateFormat (line 145) | public function setDateFormat($format = null, $dateIntervalFormat = null)
    method getDateFormat (line 161) | public function getDateFormat()
    method setTimezone (line 171) | public function setTimezone($timezone)
    method getTimezone (line 181) | public function getTimezone()
    method setNumberFormat (line 197) | public function setNumberFormat($decimal, $decimalPoint, $thousandSep)
    method getNumberFormat (line 207) | public function getNumberFormat()
    method getTokenParsers (line 212) | public function getTokenParsers(): array
    method getFilters (line 236) | public function getFilters(): array
    method getFunctions (line 290) | public function getFunctions(): array
    method getTests (line 310) | public function getTests(): array
    method getNodeVisitors (line 329) | public function getNodeVisitors(): array
    method getExpressionParsers (line 334) | public function getExpressionParsers(): array
    method cycle (line 415) | public static function cycle($values, $position): mixed
    method random (line 454) | public static function random(string $charset, $values = null, $max = ...
    method formatDate (line 518) | public function formatDate($date, $format = null, $timezone = null): s...
    method modifyDate (line 544) | public function modifyDate($date, $modifier)
    method sprintf (line 556) | public static function sprintf($format, ...$values): string
    method dateConverter (line 564) | public static function dateConverter(Environment $env, $date, $format ...
    method convertDate (line 581) | public function convertDate($date = null, $timezone = null)
    method replace (line 636) | public static function replace($str, $from): string
    method round (line 656) | public static function round($value, $precision = 0, $method = 'common')
    method formatNumber (line 683) | public function formatNumber($number, $decimal = null, $decimalPoint =...
    method urlencode (line 708) | public static function urlencode($url): string
    method merge (line 730) | public static function merge(...$arrays): array
    method slice (line 757) | public static function slice(string $charset, $item, $start, $length =...
    method first (line 791) | public static function first(string $charset, $item)
    method last (line 807) | public static function last(string $charset, $item)
    method join (line 834) | public static function join($value, $glue = '', $and = null): string
    method split (line 878) | public static function split(string $charset, $value, $delimiter, $lim...
    method default (line 906) | public static function default($value, $default = '')
    method keys (line 926) | public static function keys($array): array
    method invoke (line 963) | public static function invoke(\Closure $arrow, ...$arguments): mixed
    method reverse (line 978) | public static function reverse(string $charset, $item, $preserveKeys =...
    method shuffle (line 1013) | public static function shuffle(string $charset, $item)
    method sort (line 1047) | public static function sort(Environment $env, $array, $arrow = null): ...
    method inFilter (line 1069) | public static function inFilter($value, $compare)
    method compare (line 1121) | public static function compare($a, $b)
    method matches (line 1180) | public static function matches(string $regexp, ?string $str): int
    method trim (line 1203) | public static function trim($string, $characterMask = null, $side = 'b...
    method nl2br (line 1227) | public static function nl2br($string): string
    method spaceless (line 1239) | public static function spaceless($content): string
    method convertEncoding (line 1251) | public static function convertEncoding($string, $to, $from): string
    method length (line 1267) | public static function length(string $charset, $thing): int
    method upper (line 1299) | public static function upper(string $charset, $string): string
    method lower (line 1311) | public static function lower(string $charset, $string): string
    method striptags (line 1324) | public static function striptags($string, $allowable_tags = null): string
    method titleCase (line 1336) | public static function titleCase(string $charset, $string): string
    method capitalize (line 1348) | public static function capitalize(string $charset, $string): string
    method callMacro (line 1358) | public static function callMacro(Template $template, string $method, a...
    method ensureTraversable (line 1383) | public static function ensureTraversable($seq)
    method toArray (line 1395) | public static function toArray($seq, $preserveKeys = true)
    method testEmpty (line 1420) | public static function testEmpty($value): bool
    method testSequence (line 1447) | public static function testSequence($value): bool
    method testMapping (line 1470) | public static function testMapping($value): bool
    method include (line 1495) | public static function include(Environment $env, $context, $template, ...
    method source (line 1542) | public static function source(Environment $env, $name, $ignoreMissing ...
    method enumCases (line 1567) | public static function enumCases(string $enum): array
    method enum (line 1587) | public static function enum(string $enum): \UnitEnum
    method constant (line 1613) | public static function constant($constant, $object = null, bool $check...
    method batch (line 1647) | public static function batch($items, $size, $fill = null, $preserveKey...
    method getAttribute (line 1686) | public static function getAttribute(Environment $env, Source $source, ...
    method column (line 1949) | public static function column($array, $name, $index = null): array
    method filter (line 1967) | public static function filter(Environment $env, $array, $arrow)
    method find (line 1988) | public static function find(Environment $env, $array, $arrow)
    method map (line 2010) | public static function map(Environment $env, $array, $arrow)
    method reduce (line 2031) | public static function reduce(Environment $env, $array, $arrow, $initi...
    method arraySome (line 2052) | public static function arraySome(Environment $env, $array, $arrow)
    method arrayEvery (line 2074) | public static function arrayEvery(Environment $env, $array, $arrow)
    method checkArrow (line 2094) | public static function checkArrow(Environment $env, $arrow, $thing, $t...
    method captureOutput (line 2110) | public static function captureOutput(iterable $body): string
    method parseParentFunction (line 2133) | public static function parseParentFunction(Parser $parser, Node $fakeN...
    method parseBlockFunction (line 2149) | public static function parseBlockFunction(Parser $parser, Node $fakeNo...
    method parseAttributeFunction (line 2160) | public static function parseAttributeFunction(Parser $parser, Node $fa...
    method getPropertyChecker (line 2177) | private static function getPropertyChecker(string $class, string $prop...

FILE: src/Extension/DebugExtension.php
  class DebugExtension (line 19) | final class DebugExtension extends AbstractExtension
    method getFunctions (line 21) | public function getFunctions(): array
    method dump (line 39) | public static function dump(Environment $env, $context, ...$vars)

FILE: src/Extension/EscaperExtension.php
  class EscaperExtension (line 24) | final class EscaperExtension extends AbstractExtension
    method __construct (line 36) | public function __construct($defaultStrategy = 'html')
    method getTokenParsers (line 41) | public function getTokenParsers(): array
    method getNodeVisitors (line 46) | public function getNodeVisitors(): array
    method getFilters (line 51) | public function getFilters(): array
    method getLastModified (line 60) | public function getLastModified(): int
    method setEnvironment (line 71) | public function setEnvironment(Environment $environment): void
    method setEscaperRuntime (line 87) | public function setEscaperRuntime(EscaperRuntime $escaper)
    method setDefaultStrategy (line 102) | public function setDefaultStrategy($defaultStrategy): void
    method getDefaultStrategy (line 118) | public function getDefaultStrategy(string $name)
    method setEscaper (line 139) | public function setEscaper($strategy, callable $callable)
    method getEscapers (line 162) | public function getEscapers()
    method setSafeClasses (line 174) | public function setSafeClasses(array $safeClasses = [])
    method addSafeClass (line 190) | public function addSafeClass(string $class, array $strategies)
    method escapeFilterIsSafe (line 206) | public static function escapeFilterIsSafe(Node $filterArgs)

FILE: src/Extension/ExtensionInterface.php
  type ExtensionInterface (line 32) | interface ExtensionInterface
    method getTokenParsers (line 39) | public function getTokenParsers();
    method getNodeVisitors (line 46) | public function getNodeVisitors();
    method getFilters (line 53) | public function getFilters();
    method getTests (line 60) | public function getTests();
    method getFunctions (line 67) | public function getFunctions();
    method getOperators (line 79) | public function getOperators();

FILE: src/Extension/GlobalsInterface.php
  type GlobalsInterface (line 19) | interface GlobalsInterface
    method getGlobals (line 24) | public function getGlobals(): array;

FILE: src/Extension/LastModifiedExtensionInterface.php
  type LastModifiedExtensionInterface (line 14) | interface LastModifiedExtensionInterface extends ExtensionInterface
    method getLastModified (line 22) | public function getLastModified(): int;

FILE: src/Extension/OptimizerExtension.php
  class OptimizerExtension (line 16) | final class OptimizerExtension extends AbstractExtension
    method __construct (line 18) | public function __construct(
    method getNodeVisitors (line 23) | public function getNodeVisitors(): array

FILE: src/Extension/ProfilerExtension.php
  class ProfilerExtension (line 17) | class ProfilerExtension extends AbstractExtension
    method __construct (line 21) | public function __construct(Profile $profile)
    method enter (line 29) | public function enter(Profile $profile)
    method leave (line 38) | public function leave(Profile $profile)
    method getNodeVisitors (line 48) | public function getNodeVisitors(): array

FILE: src/Extension/RuntimeExtensionInterface.php
  type RuntimeExtensionInterface (line 17) | interface RuntimeExtensionInterface

FILE: src/Extension/SandboxExtension.php
  class SandboxExtension (line 22) | final class SandboxExtension extends AbstractExtension
    method __construct (line 29) | public function __construct(SecurityPolicyInterface $policy, $sandboxe...
    method getTokenParsers (line 36) | public function getTokenParsers(): array
    method getNodeVisitors (line 41) | public function getNodeVisitors(): array
    method enableSandbox (line 46) | public function enableSandbox(): void
    method disableSandbox (line 51) | public function disableSandbox(): void
    method isSandboxed (line 56) | public function isSandboxed(?Source $source = null): bool
    method isSandboxedGlobally (line 61) | public function isSandboxedGlobally(): bool
    method isSourceSandboxed (line 66) | private function isSourceSandboxed(?Source $source): bool
    method setSecurityPolicy (line 75) | public function setSecurityPolicy(SecurityPolicyInterface $policy): void
    method getSecurityPolicy (line 80) | public function getSecurityPolicy(): SecurityPolicyInterface
    method checkSecurity (line 85) | public function checkSecurity($tags, $filters, $functions, ?Source $so...
    method checkMethodAllowed (line 92) | public function checkMethodAllowed($obj, $method, int $lineno = -1, ?S...
    method checkPropertyAllowed (line 106) | public function checkPropertyAllowed($obj, $property, int $lineno = -1...
    method ensureToStringAllowed (line 123) | public function ensureToStringAllowed($obj, int $lineno = -1, ?Source ...
    method ensureToStringAllowedForArray (line 145) | private function ensureToStringAllowedForArray(array $obj, int $lineno...

FILE: src/Extension/StagingExtension.php
  class StagingExtension (line 27) | final class StagingExtension extends AbstractExtension
    method addFunction (line 35) | public function addFunction(TwigFunction $function): void
    method getFunctions (line 44) | public function getFunctions(): array
    method addFilter (line 49) | public function addFilter(TwigFilter $filter): void
    method getFilters (line 58) | public function getFilters(): array
    method addNodeVisitor (line 63) | public function addNodeVisitor(NodeVisitorInterface $visitor): void
    method getNodeVisitors (line 68) | public function getNodeVisitors(): array
    method addTokenParser (line 73) | public function addTokenParser(TokenParserInterface $parser): void
    method getTokenParsers (line 82) | public function getTokenParsers(): array
    method addTest (line 87) | public function addTest(TwigTest $test): void
    method getTests (line 96) | public function getTests(): array

FILE: src/Extension/StringLoaderExtension.php
  class StringLoaderExtension (line 18) | final class StringLoaderExtension extends AbstractExtension
    method getFunctions (line 20) | public function getFunctions(): array
    method templateFromString (line 36) | public static function templateFromString(Environment $env, string|\St...

FILE: src/Extension/YieldNotReadyExtension.php
  class YieldNotReadyExtension (line 19) | final class YieldNotReadyExtension extends AbstractExtension
    method __construct (line 21) | public function __construct(
    method getNodeVisitors (line 26) | public function getNodeVisitors(): array

FILE: src/ExtensionSet.php
  class ExtensionSet (line 39) | final class ExtensionSet
    method __construct (line 72) | public function __construct()
    method initRuntime (line 80) | public function initRuntime()
    method hasExtension (line 85) | public function hasExtension(string $class): bool
    method getExtension (line 90) | public function getExtension(string $class): ExtensionInterface
    method setExtensions (line 104) | public function setExtensions(array $extensions): void
    method getExtensions (line 114) | public function getExtensions(): array
    method getSignature (line 119) | public function getSignature(): string
    method isInitialized (line 124) | public function isInitialized(): bool
    method getLastModified (line 129) | public function getLastModified(): int
    method addExtension (line 150) | public function addExtension(ExtensionInterface $extension): void
    method addFunction (line 169) | public function addFunction(TwigFunction $function): void
    method getFunctions (line 181) | public function getFunctions(): array
    method getFunction (line 190) | public function getFunction(string $name): ?TwigFunction
    method registerUndefinedFunctionCallback (line 220) | public function registerUndefinedFunctionCallback(callable $callable):...
    method addFilter (line 225) | public function addFilter(TwigFilter $filter): void
    method getFilters (line 237) | public function getFilters(): array
    method getFilter (line 246) | public function getFilter(string $name): ?TwigFilter
    method registerUndefinedFilterCallback (line 276) | public function registerUndefinedFilterCallback(callable $callable): void
    method addNodeVisitor (line 281) | public function addNodeVisitor(NodeVisitorInterface $visitor): void
    method getNodeVisitors (line 293) | public function getNodeVisitors(): array
    method addTokenParser (line 302) | public function addTokenParser(TokenParserInterface $parser): void
    method getTokenParsers (line 314) | public function getTokenParsers(): array
    method getTokenParser (line 323) | public function getTokenParser(string $name): ?TokenParserInterface
    method registerUndefinedTokenParserCallback (line 345) | public function registerUndefinedTokenParserCallback(callable $callabl...
    method getGlobals (line 353) | public function getGlobals(): array
    method resetGlobals (line 375) | public function resetGlobals(): void
    method addTest (line 380) | public function addTest(TwigTest $test): void
    method getTests (line 392) | public function getTests(): array
    method getTest (line 401) | public function getTest(string $name): ?TwigTest
    method registerUndefinedTestCallback (line 431) | public function registerUndefinedTestCallback(callable $callable): void
    method getExpressionParsers (line 436) | public function getExpressionParsers(): ExpressionParsers
    method initExtensions (line 445) | private function initExtensions(): void
    method initExtension (line 465) | private function initExtension(ExtensionInterface $extension): void
    method convertInfixExpressionParser (line 544) | private function convertInfixExpressionParser(string $nodeClass, strin...

FILE: src/FileExtensionEscapingStrategy.php
  class FileExtensionEscapingStrategy (line 25) | class FileExtensionEscapingStrategy
    method guess (line 34) | public static function guess(string $name)

FILE: src/Lexer.php
  class Lexer (line 21) | class Lexer
    method __construct (line 73) | public function __construct(Environment $env, array $options = [])
    method initialize (line 88) | private function initialize(): void
    method tokenize (line 185) | public function tokenize(Source $source): TokenStream
    method lexData (line 240) | private function lexData(): void
    method lexBlock (line 305) | private function lexBlock(): void
    method lexVar (line 316) | private function lexVar(): void
    method lexExpression (line 327) | private function lexExpression(): void
    method stripcslashes (line 384) | private function stripcslashes(string $str, string $quoteType): string
    method lexRawData (line 441) | private function lexRawData(): void
    method lexComment (line 465) | private function lexComment(): void
    method lexString (line 474) | private function lexString(): void
    method lexInterpolation (line 498) | private function lexInterpolation(): void
    method pushToken (line 511) | private function pushToken($type, $value = ''): void
    method moveCursor (line 521) | private function moveCursor($text): void
    method getOperatorRegex (line 527) | private function getOperatorRegex(): string
    method pushState (line 560) | private function pushState($state): void
    method popState (line 566) | private function popState(): void
    method checkBrackets (line 575) | private function checkBrackets(string $code): void

FILE: src/Loader/ArrayLoader.php
  class ArrayLoader (line 29) | final class ArrayLoader implements LoaderInterface
    method __construct (line 34) | public function __construct(
    method setTemplate (line 39) | public function setTemplate(string $name, string $template): void
    method getSourceContext (line 44) | public function getSourceContext(string $name): Source
    method exists (line 53) | public function exists(string $name): bool
    method getCacheKey (line 58) | public function getCacheKey(string $name): string
    method isFresh (line 67) | public function isFresh(string $name, int $time): bool

FILE: src/Loader/ChainLoader.php
  class ChainLoader (line 22) | final class ChainLoader implements LoaderInterface
    method __construct (line 32) | public function __construct(
    method addLoader (line 37) | public function addLoader(LoaderInterface $loader): void
    method getLoaders (line 52) | public function getLoaders(): array
    method getSourceContext (line 61) | public function getSourceContext(string $name): Source
    method exists (line 80) | public function exists(string $name): bool
    method getCacheKey (line 95) | public function getCacheKey(string $name): string
    method isFresh (line 114) | public function isFresh(string $name, int $time): bool

FILE: src/Loader/FilesystemLoader.php
  class FilesystemLoader (line 22) | class FilesystemLoader implements LoaderInterface
    method __construct (line 40) | public function __construct($paths = [], ?string $rootPath = null)
    method getPaths (line 57) | public function getPaths(string $namespace = self::MAIN_NAMESPACE): array
    method getNamespaces (line 69) | public function getNamespaces(): array
    method setPaths (line 77) | public function setPaths($paths, string $namespace = self::MAIN_NAMESP...
    method addPath (line 92) | public function addPath(string $path, string $namespace = self::MAIN_N...
    method prependPath (line 108) | public function prependPath(string $path, string $namespace = self::MA...
    method getSourceContext (line 127) | public function getSourceContext(string $name): Source
    method getCacheKey (line 136) | public function getCacheKey(string $name): string
    method exists (line 152) | public function exists(string $name)
    method isFresh (line 163) | public function isFresh(string $name, int $time): bool
    method findTemplate (line 176) | protected function findTemplate(string $name, bool $throw = true)
    method normalizeName (line 237) | private function normalizeName(string $name): string
    method parseName (line 242) | private function parseName(string $name, string $default = self::MAIN_...
    method validateName (line 258) | private function validateName(string $name): void
    method isAbsolutePath (line 280) | private function isAbsolutePath(string $file): bool

FILE: src/Loader/LoaderInterface.php
  type LoaderInterface (line 22) | interface LoaderInterface
    method getSourceContext (line 29) | public function getSourceContext(string $name): Source;
    method getCacheKey (line 36) | public function getCacheKey(string $name): string;
    method isFresh (line 43) | public function isFresh(string $name, int $time): bool;
    method exists (line 48) | public function exists(string $name);

FILE: src/Markup.php
  class Markup (line 19) | class Markup implements \Countable, \JsonSerializable, \Stringable
    method __construct (line 24) | public function __construct($content, $charset)
    method __toString (line 30) | public function __toString(): string
    method getCharset (line 35) | public function getCharset(): string
    method count (line 43) | #[\ReturnTypeWillChange]
    method jsonSerialize (line 52) | #[\ReturnTypeWillChange]

FILE: src/Node/AutoEscapeNode.php
  class AutoEscapeNode (line 28) | #[YieldReady]
    method __construct (line 31) | public function __construct($value, Node $body, int $lineno)
    method compile (line 36) | public function compile(Compiler $compiler): void

FILE: src/Node/BlockNode.php
  class BlockNode (line 23) | #[YieldReady]
    method __construct (line 26) | public function __construct(string $name, Node $body, int $lineno)
    method compile (line 31) | public function compile(Compiler $compiler): void

FILE: src/Node/BlockReferenceNode.php
  class BlockReferenceNode (line 23) | #[YieldReady]
    method __construct (line 26) | public function __construct(string $name, int $lineno)
    method compile (line 31) | public function compile(Compiler $compiler): void

FILE: src/Node/BodyNode.php
  class BodyNode (line 21) | #[YieldReady]

FILE: src/Node/CaptureNode.php
  class CaptureNode (line 22) | #[YieldReady]
    method __construct (line 25) | public function __construct(Node $body, int $lineno)
    method compile (line 30) | public function compile(Compiler $compiler): void

FILE: src/Node/CheckSecurityCallNode.php
  class CheckSecurityCallNode (line 20) | #[YieldReady]
    method compile (line 26) | public function compile(Compiler $compiler)

FILE: src/Node/CheckSecurityNode.php
  class CheckSecurityNode (line 20) | #[YieldReady]
    method __construct (line 32) | public function __construct(array $usedFilters, array $usedTags, array...
    method compile (line 41) | public function compile(Compiler $compiler): void

FILE: src/Node/CheckToStringNode.php
  class CheckToStringNode (line 28) | #[YieldReady]
    method __construct (line 31) | public function __construct(AbstractExpression $expr)
    method compile (line 36) | public function compile(Compiler $compiler): void

FILE: src/Node/DeprecatedNode.php
  class DeprecatedNode (line 24) | #[YieldReady]
    method __construct (line 27) | public function __construct(AbstractExpression $expr, int $lineno)
    method compile (line 32) | public function compile(Compiler $compiler): void

FILE: src/Node/DoNode.php
  class DoNode (line 23) | #[YieldReady]
    method __construct (line 26) | public function __construct(AbstractExpression $expr, int $lineno)
    method compile (line 31) | public function compile(Compiler $compiler): void

FILE: src/Node/EmbedNode.php
  class EmbedNode (line 24) | #[YieldReady]
    method __construct (line 28) | public function __construct(string $name, int $index, ?AbstractExpress...
    method addGetTemplate (line 36) | protected function addGetTemplate(Compiler $compiler, string $template...

FILE: src/Node/EmptyNode.php
  class EmptyNode (line 21) | #[YieldReady]
    method __construct (line 24) | public function __construct(int $lineno = 0)
    method setNode (line 29) | public function setNode(string $name, Node $node): void

FILE: src/Node/Expression/AbstractExpression.php
  class AbstractExpression (line 22) | abstract class AbstractExpression extends Node
    method isGenerator (line 24) | public function isGenerator(): bool
    method setExplicitParentheses (line 32) | public function setExplicitParentheses(): self
    method hasExplicitParentheses (line 39) | public function hasExplicitParentheses(): bool

FILE: src/Node/Expression/ArrayExpression.php
  class ArrayExpression (line 20) | class ArrayExpression extends AbstractExpression implements SupportDefin...
    method __construct (line 26) | public function __construct(array $elements, int $lineno)
    method getKeyValuePairs (line 38) | public function getKeyValuePairs(): array
    method hasElement (line 51) | public function hasElement(AbstractExpression $key): bool
    method isSequence (line 69) | public function isSequence(): bool
    method addElement (line 89) | public function addElement(AbstractExpression $value, ?AbstractExpress...
    method compile (line 98) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/ArrowFunctionExpression.php
  class ArrowFunctionExpression (line 25) | class ArrowFunctionExpression extends AbstractExpression
    method __construct (line 27) | public function __construct(AbstractExpression $expr, Node $names, $li...
    method compile (line 40) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/AssignNameExpression.php
  class AssignNameExpression (line 20) | class AssignNameExpression extends ContextVariable
    method __construct (line 22) | public function __construct(string $name, int $lineno)
    method compile (line 36) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Binary/AbstractBinary.php
  class AbstractBinary (line 19) | abstract class AbstractBinary extends AbstractExpression implements Bina...
    method __construct (line 25) | public function __construct(Node $left, Node $right, int $lineno)
    method compile (line 37) | public function compile(Compiler $compiler): void
    method operator (line 52) | abstract public function operator(Compiler $compiler): Compiler;

FILE: src/Node/Expression/Binary/AddBinary.php
  class AddBinary (line 18) | class AddBinary extends AbstractBinary implements ReturnNumberInterface
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/AndBinary.php
  class AndBinary (line 18) | class AndBinary extends AbstractBinary implements ReturnBoolInterface
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/BinaryInterface.php
  type BinaryInterface (line 19) | interface BinaryInterface
    method __construct (line 21) | public function __construct(AbstractExpression $left, AbstractExpressi...

FILE: src/Node/Expression/Binary/BitwiseAndBinary.php
  class BitwiseAndBinary (line 18) | class BitwiseAndBinary extends AbstractBinary implements ReturnNumberInt...
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/BitwiseOrBinary.php
  class BitwiseOrBinary (line 18) | class BitwiseOrBinary extends AbstractBinary implements ReturnNumberInte...
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/BitwiseXorBinary.php
  class BitwiseXorBinary (line 18) | class BitwiseXorBinary extends AbstractBinary implements ReturnNumberInt...
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/ConcatBinary.php
  class ConcatBinary (line 18) | class ConcatBinary extends AbstractBinary implements ReturnStringInterface
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/DivBinary.php
  class DivBinary (line 18) | class DivBinary extends AbstractBinary implements ReturnNumberInterface
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/ElvisBinary.php
  class ElvisBinary (line 19) | final class ElvisBinary extends AbstractBinary implements OperatorEscape...
    method __construct (line 25) | public function __construct(Node $left, Node $right, int $lineno)
    method compile (line 33) | public function compile(Compiler $compiler): void
    method operator (line 46) | public function operator(Compiler $compiler): Compiler
    method getOperandNamesToEscape (line 51) | public function getOperandNamesToEscape(): array

FILE: src/Node/Expression/Binary/EndsWithBinary.php
  class EndsWithBinary (line 17) | class EndsWithBinary extends AbstractBinary implements ReturnBoolInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 32) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/EqualBinary.php
  class EqualBinary (line 17) | class EqualBinary extends AbstractBinary implements ReturnBoolInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 36) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/FloorDivBinary.php
  class FloorDivBinary (line 17) | class FloorDivBinary extends AbstractBinary implements ReturnNumberInter...
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 26) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/GreaterBinary.php
  class GreaterBinary (line 17) | class GreaterBinary extends AbstractBinary implements ReturnBoolInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 36) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/GreaterEqualBinary.php
  class GreaterEqualBinary (line 17) | class GreaterEqualBinary extends AbstractBinary implements ReturnBoolInt...
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 36) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/HasEveryBinary.php
  class HasEveryBinary (line 17) | class HasEveryBinary extends AbstractBinary implements ReturnBoolInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 30) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/HasSomeBinary.php
  class HasSomeBinary (line 17) | class HasSomeBinary extends AbstractBinary implements ReturnBoolInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 30) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/InBinary.php
  class InBinary (line 17) | class InBinary extends AbstractBinary implements ReturnBoolInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 30) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/LessBinary.php
  class LessBinary (line 17) | class LessBinary extends AbstractBinary implements ReturnBoolInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 36) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/LessEqualBinary.php
  class LessEqualBinary (line 17) | class LessEqualBinary extends AbstractBinary implements ReturnBoolInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 36) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/MatchesBinary.php
  class MatchesBinary (line 21) | class MatchesBinary extends AbstractBinary implements ReturnBoolInterface
    method __construct (line 23) | public function __construct(Node $left, Node $right, int $lineno)
    method compile (line 45) | public function compile(Compiler $compiler): void
    method operator (line 56) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/ModBinary.php
  class ModBinary (line 18) | class ModBinary extends AbstractBinary implements ReturnNumberInterface
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/MulBinary.php
  class MulBinary (line 18) | class MulBinary extends AbstractBinary implements ReturnNumberInterface
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/NotEqualBinary.php
  class NotEqualBinary (line 17) | class NotEqualBinary extends AbstractBinary implements ReturnBoolInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 36) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/NotInBinary.php
  class NotInBinary (line 17) | class NotInBinary extends AbstractBinary implements ReturnBoolInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 30) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/NotSameAsBinary.php
  class NotSameAsBinary (line 17) | class NotSameAsBinary extends AbstractBinary implements ReturnBoolInterface
    method operator (line 19) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/NullCoalesceBinary.php
  class NullCoalesceBinary (line 25) | final class NullCoalesceBinary extends AbstractBinary implements Operato...
    method __construct (line 31) | public function __construct(Node $left, Node $right, int $lineno)
    method compile (line 49) | public function compile(Compiler $compiler): void
    method operator (line 62) | public function operator(Compiler $compiler): Compiler
    method getOperandNamesToEscape (line 67) | public function getOperandNamesToEscape(): array

FILE: src/Node/Expression/Binary/ObjectDestructuringSetBinary.php
  class ObjectDestructuringSetBinary (line 24) | class ObjectDestructuringSetBinary extends AbstractBinary
    method __construct (line 33) | public function __construct(Node $left, Node $right, int $lineno)
    method compile (line 52) | public function compile(Compiler $compiler): void
    method operator (line 72) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/OrBinary.php
  class OrBinary (line 18) | class OrBinary extends AbstractBinary implements ReturnBoolInterface
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/PowerBinary.php
  class PowerBinary (line 17) | class PowerBinary extends AbstractBinary implements ReturnNumberInterface
    method operator (line 19) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/RangeBinary.php
  class RangeBinary (line 17) | class RangeBinary extends AbstractBinary implements ReturnArrayInterface
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 30) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/SameAsBinary.php
  class SameAsBinary (line 17) | class SameAsBinary extends AbstractBinary implements ReturnBoolInterface
    method operator (line 19) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/SequenceDestructuringSetBinary.php
  class SequenceDestructuringSetBinary (line 25) | class SequenceDestructuringSetBinary extends AbstractBinary
    method __construct (line 33) | public function __construct(Node $left, Node $right, int $lineno)
    method compile (line 48) | public function compile(Compiler $compiler): void
    method operator (line 63) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/SetBinary.php
  class SetBinary (line 23) | class SetBinary extends AbstractBinary
    method __construct (line 29) | public function __construct(Node $left, Node $right, int $lineno)
    method operator (line 40) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/SpaceshipBinary.php
  class SpaceshipBinary (line 17) | class SpaceshipBinary extends AbstractBinary implements ReturnNumberInte...
    method operator (line 19) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/StartsWithBinary.php
  class StartsWithBinary (line 17) | class StartsWithBinary extends AbstractBinary implements ReturnBoolInter...
    method compile (line 19) | public function compile(Compiler $compiler): void
    method operator (line 32) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/SubBinary.php
  class SubBinary (line 18) | class SubBinary extends AbstractBinary implements ReturnNumberInterface
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Binary/XorBinary.php
  class XorBinary (line 18) | class XorBinary extends AbstractBinary implements ReturnBoolInterface
    method operator (line 20) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/BlockReferenceExpression.php
  class BlockReferenceExpression (line 23) | class BlockReferenceExpression extends AbstractExpression implements Sup...
    method __construct (line 31) | public function __construct(Node $name, ?Node $template, int $lineno)
    method compile (line 45) | public function compile(Compiler $compiler): void
    method compileTemplateCall (line 63) | private function compileTemplateCall(Compiler $compiler, string $metho...
    method compileBlockArguments (line 82) | private function compileBlockArguments(Compiler $compiler): Compiler

FILE: src/Node/Expression/CallExpression.php
  class CallExpression (line 25) | abstract class CallExpression extends AbstractExpression
    method compileCallable (line 32) | protected function compileCallable(Compiler $compiler)
    method compileArguments (line 70) | protected function compileArguments(Compiler $compiler, $isArray = fal...
    method getArguments (line 136) | protected function getArguments($callable, $arguments)
    method normalizeName (line 265) | protected function normalizeName(string $name): string
    method getCallableParameters (line 273) | private function getCallableParameters($callable, bool $isVariadic): a...
    method reflectCallable (line 314) | private function reflectCallable(TwigCallableInterface $callable): Ref...
    method getTwigCallable (line 328) | private function getTwigCallable(): TwigCallableInterface

FILE: src/Node/Expression/ConditionalExpression.php
  class ConditionalExpression (line 18) | class ConditionalExpression extends AbstractExpression implements Operat...
    method __construct (line 20) | public function __construct(AbstractExpression $expr1, AbstractExpress...
    method compile (line 27) | public function compile(Compiler $compiler): void
    method getOperandNamesToEscape (line 49) | public function getOperandNamesToEscape(): array

FILE: src/Node/Expression/ConstantExpression.php
  class ConstantExpression (line 20) | class ConstantExpression extends AbstractExpression implements SupportDe...
    method __construct (line 24) | public function __construct($value, int $lineno)
    method compile (line 29) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/EmptyExpression.php
  class EmptyExpression (line 23) | final class EmptyExpression extends AbstractExpression
    method __construct (line 25) | public function __construct(int $lineno)
    method compile (line 30) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Filter/DefaultFilter.php
  class DefaultFilter (line 36) | class DefaultFilter extends FilterExpression
    method __construct (line 41) | #[FirstClassTwigCallableReady]
    method compile (line 68) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Filter/RawFilter.php
  class RawFilter (line 26) | class RawFilter extends FilterExpression
    method __construct (line 31) | #[FirstClassTwigCallableReady]
    method compile (line 41) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/FilterExpression.php
  class FilterExpression (line 21) | class FilterExpression extends CallExpression
    method __construct (line 26) | #[FirstClassTwigCallableReady]
    method compile (line 59) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/FunctionExpression.php
  class FunctionExpression (line 20) | class FunctionExpression extends CallExpression implements SupportDefine...
    method __construct (line 25) | #[FirstClassTwigCallableReady]
    method enableDefinedTest (line 50) | public function enableDefinedTest(): void
    method compile (line 60) | public function compile(Compiler $compiler)

FILE: src/Node/Expression/FunctionNode/EnumCasesFunction.php
  class EnumCasesFunction (line 19) | class EnumCasesFunction extends FunctionExpression
    method compile (line 21) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/FunctionNode/EnumFunction.php
  class EnumFunction (line 19) | class EnumFunction extends FunctionExpression
    method compile (line 21) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/GetAttrExpression.php
  class GetAttrExpression (line 20) | class GetAttrExpression extends AbstractExpression implements SupportDef...
    method __construct (line 28) | public function __construct(AbstractExpression $node, AbstractExpressi...
    method enableDefinedTest (line 42) | public function enableDefinedTest(): void
    method compile (line 48) | public function compile(Compiler $compiler): void
    method changeIgnoreStrictCheck (line 160) | private function changeIgnoreStrictCheck(self $node): void
    method markAsShortCircuited (line 170) | private function markAsShortCircuited(): void
    method isShortCircuited (line 175) | private function isShortCircuited(): bool
    method getVarName (line 180) | private function getVarName(Compiler $compiler): string

FILE: src/Node/Expression/InlinePrint.php
  class InlinePrint (line 20) | final class InlinePrint extends AbstractExpression
    method __construct (line 25) | public function __construct(Node $node, int $lineno)
    method compile (line 32) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/ListExpression.php
  class ListExpression (line 17) | class ListExpression extends AbstractExpression
    method __construct (line 22) | public function __construct(array $items, int $lineno)
    method compile (line 27) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/MacroReferenceExpression.php
  class MacroReferenceExpression (line 22) | class MacroReferenceExpression extends AbstractExpression implements Sup...
    method __construct (line 27) | public function __construct(TemplateVariable $template, string $name, ...
    method __clone (line 32) | public function __clone()
    method compile (line 42) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/MethodCallExpression.php
  class MethodCallExpression (line 17) | class MethodCallExpression extends AbstractExpression implements Support...
    method __construct (line 22) | public function __construct(AbstractExpression $node, string $method, ...
    method compile (line 33) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/NameExpression.php
  class NameExpression (line 18) | class NameExpression extends AbstractExpression implements SupportDefine...
    method __construct (line 29) | public function __construct(string $name, int $lineno)
    method compile (line 38) | public function compile(Compiler $compiler): void
    method isSpecial (line 99) | public function isSpecial()
    method isSimple (line 109) | public function isSimple()

FILE: src/Node/Expression/NullCoalesceExpression.php
  class NullCoalesceExpression (line 25) | class NullCoalesceExpression extends ConditionalExpression
    method __construct (line 31) | public function __construct(Node $left, Node $right, int $lineno)
    method compile (line 55) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/OperatorEscapeInterface.php
  type OperatorEscapeInterface (line 19) | interface OperatorEscapeInterface
    method getOperandNamesToEscape (line 24) | public function getOperandNamesToEscape(): array;

FILE: src/Node/Expression/ParentExpression.php
  class ParentExpression (line 22) | class ParentExpression extends AbstractExpression
    method __construct (line 24) | public function __construct(string $name, int $lineno)
    method compile (line 29) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/ReturnArrayInterface.php
  type ReturnArrayInterface (line 14) | interface ReturnArrayInterface extends ReturnPrimitiveTypeInterface

FILE: src/Node/Expression/ReturnBoolInterface.php
  type ReturnBoolInterface (line 14) | interface ReturnBoolInterface extends ReturnPrimitiveTypeInterface

FILE: src/Node/Expression/ReturnNumberInterface.php
  type ReturnNumberInterface (line 14) | interface ReturnNumberInterface extends ReturnPrimitiveTypeInterface

FILE: src/Node/Expression/ReturnPrimitiveTypeInterface.php
  type ReturnPrimitiveTypeInterface (line 14) | interface ReturnPrimitiveTypeInterface

FILE: src/Node/Expression/ReturnStringInterface.php
  type ReturnStringInterface (line 14) | interface ReturnStringInterface extends ReturnPrimitiveTypeInterface

FILE: src/Node/Expression/SupportDefinedTestDeprecationTrait.php
  type SupportDefinedTestDeprecationTrait (line 21) | trait SupportDefinedTestDeprecationTrait
    method getAttribute (line 23) | public function getAttribute($name, $default = null)
    method setAttribute (line 34) | public function setAttribute(string $name, $value): void

FILE: src/Node/Expression/SupportDefinedTestInterface.php
  type SupportDefinedTestInterface (line 19) | interface SupportDefinedTestInterface
    method enableDefinedTest (line 21) | public function enableDefinedTest(): void;
    method isDefinedTestEnabled (line 23) | public function isDefinedTestEnabled(): bool;

FILE: src/Node/Expression/SupportDefinedTestTrait.php
  type SupportDefinedTestTrait (line 14) | trait SupportDefinedTestTrait
    method enableDefinedTest (line 18) | public function enableDefinedTest(): void
    method isDefinedTestEnabled (line 23) | public function isDefinedTestEnabled(): bool

FILE: src/Node/Expression/TempNameExpression.php
  class TempNameExpression (line 17) | class TempNameExpression extends AbstractExpression
    method __construct (line 21) | public function __construct(string|int|null $name, int $lineno)
    method compile (line 41) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Ternary/ConditionalTernary.php
  class ConditionalTernary (line 21) | final class ConditionalTernary extends AbstractExpression implements Ope...
    method __construct (line 23) | public function __construct(AbstractExpression $test, AbstractExpressi...
    method compile (line 32) | public function compile(Compiler $compiler): void
    method getOperandNamesToEscape (line 45) | public function getOperandNamesToEscape(): array

FILE: src/Node/Expression/Test/ConstantTest.php
  class ConstantTest (line 26) | class ConstantTest extends TestExpression
    method compile (line 28) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Test/DefinedTest.php
  class DefinedTest (line 33) | class DefinedTest extends TestExpression
    method __construct (line 38) | #[FirstClassTwigCallableReady]
    method compile (line 58) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Test/DivisiblebyTest.php
  class DivisiblebyTest (line 24) | class DivisiblebyTest extends TestExpression
    method compile (line 26) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Test/EvenTest.php
  class EvenTest (line 24) | class EvenTest extends TestExpression
    method compile (line 26) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Test/NullTest.php
  class NullTest (line 24) | class NullTest extends TestExpression
    method compile (line 26) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Test/OddTest.php
  class OddTest (line 24) | class OddTest extends TestExpression
    method compile (line 26) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Test/SameasTest.php
  class SameasTest (line 22) | class SameasTest extends TestExpression
    method compile (line 24) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Test/TrueTest.php
  class TrueTest (line 24) | class TrueTest extends TestExpression
    method compile (line 26) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/TestExpression.php
  class TestExpression (line 20) | class TestExpression extends CallExpression implements ReturnBoolInterface
    method __construct (line 22) | #[FirstClassTwigCallableReady]
    method compile (line 56) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Unary/AbstractUnary.php
  class AbstractUnary (line 19) | abstract class AbstractUnary extends AbstractExpression implements Unary...
    method __construct (line 24) | public function __construct(Node $node, int $lineno)
    method compile (line 33) | public function compile(Compiler $compiler): void
    method operator (line 47) | abstract public function operator(Compiler $compiler): Compiler;

FILE: src/Node/Expression/Unary/NegUnary.php
  class NegUnary (line 17) | class NegUnary extends AbstractUnary
    method operator (line 19) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Unary/NotUnary.php
  class NotUnary (line 17) | class NotUnary extends AbstractUnary
    method operator (line 19) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Unary/PosUnary.php
  class PosUnary (line 17) | class PosUnary extends AbstractUnary
    method operator (line 19) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Unary/SpreadUnary.php
  class SpreadUnary (line 16) | final class SpreadUnary extends AbstractUnary
    method operator (line 18) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Unary/StringCastUnary.php
  class StringCastUnary (line 16) | final class StringCastUnary extends AbstractUnary
    method operator (line 18) | public function operator(Compiler $compiler): Compiler

FILE: src/Node/Expression/Unary/UnaryInterface.php
  type UnaryInterface (line 19) | interface UnaryInterface
    method __construct (line 21) | public function __construct(AbstractExpression $node, int $lineno);

FILE: src/Node/Expression/Variable/AssignContextVariable.php
  class AssignContextVariable (line 16) | final class AssignContextVariable extends AssignNameExpression

FILE: src/Node/Expression/Variable/AssignTemplateVariable.php
  class AssignTemplateVariable (line 17) | final class AssignTemplateVariable extends AbstractExpression
    method __construct (line 19) | public function __construct(TemplateVariable $var, bool $global = true)
    method compile (line 24) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/Variable/ContextVariable.php
  class ContextVariable (line 16) | class ContextVariable extends NameExpression

FILE: src/Node/Expression/Variable/LocalVariable.php
  class LocalVariable (line 16) | final class LocalVariable extends TempNameExpression

FILE: src/Node/Expression/Variable/TemplateVariable.php
  class TemplateVariable (line 17) | class TemplateVariable extends TempNameExpression
    method getName (line 19) | public function getName(Compiler $compiler): string
    method compile (line 28) | public function compile(Compiler $compiler): void

FILE: src/Node/Expression/VariadicExpression.php
  class VariadicExpression (line 16) | class VariadicExpression extends ArrayExpression
    method compile (line 18) | public function compile(Compiler $compiler): void

FILE: src/Node/FlushNode.php
  class FlushNode (line 22) | #[YieldReady]
    method __construct (line 25) | public function __construct(int $lineno)
    method compile (line 30) | public function compile(Compiler $compiler): void

FILE: src/Node/ForElseNode.php
  class ForElseNode (line 22) | #[YieldReady]
    method __construct (line 25) | public function __construct(Node $body, int $lineno)
    method compile (line 30) | public function compile(Compiler $compiler): void

FILE: src/Node/ForLoopNode.php
  class ForLoopNode (line 22) | #[YieldReady]
    method __construct (line 25) | public function __construct(int $lineno)
    method compile (line 30) | public function compile(Compiler $compiler): void

FILE: src/Node/ForNode.php
  class ForNode (line 25) | #[YieldReady]
    method __construct (line 30) | public function __construct(AssignContextVariable $keyTarget, AssignCo...
    method compile (line 52) | public function compile(Compiler $compiler): void

FILE: src/Node/IfNode.php
  class IfNode (line 26) | #[YieldReady]
    method __construct (line 29) | public function __construct(Node $tests, ?Node $else, int $lineno)
    method compile (line 45) | public function compile(Compiler $compiler): void

FILE: src/Node/ImportNode.php
  class ImportNode (line 25) | #[YieldReady]
    method __construct (line 28) | public function __construct(AbstractExpression $expr, AbstractExpressi...
    method compile (line 43) | public function compile(Compiler $compiler): void

FILE: src/Node/IncludeNode.php
  class IncludeNode (line 24) | #[YieldReady]
    method __construct (line 27) | public function __construct(AbstractExpression $expr, ?AbstractExpress...
    method compile (line 37) | public function compile(Compiler $compiler): void
    method addGetTemplate (line 84) | protected function addGetTemplate(Compiler $compiler/* , string $templ...
    method addTemplateArguments (line 98) | protected function addTemplateArguments(Compiler $compiler)

FILE: src/Node/MacroNode.php
  class MacroNode (line 25) | #[YieldReady]
    method __construct (line 34) | public function __construct(string $name, Node $body, Node $arguments,...
    method compile (line 59) | public function compile(Compiler $compiler): void

FILE: src/Node/ModuleNode.php
  class ModuleNode (line 30) | #[YieldReady]
    method __construct (line 36) | public function __construct(Node $body, ?AbstractExpression $parent, N...
    method setIndex (line 79) | public function setIndex($index)
    method compile (line 84) | public function compile(Compiler $compiler): void
    method compileTemplate (line 96) | protected function compileTemplate(Compiler $compiler)
    method compileGetParent (line 128) | protected function compileGetParent(Compiler $compiler)
    method compileClassHeader (line 164) | protected function compileClassHeader(Compiler $compiler)
    method compileConstructor (line 205) | protected function compileConstructor(Compiler $compiler)
    method compileDisplay (line 345) | protected function compileDisplay(Compiler $compiler)
    method compileClassFooter (line 393) | protected function compileClassFooter(Compiler $compiler)
    method compileMacros (line 405) | protected function compileMacros(Compiler $compiler)
    method compileGetTemplateName (line 413) | protected function compileGetTemplateName(Compiler $compiler)
    method compileIsTraitable (line 432) | protected function compileIsTraitable(Compiler $compiler)
    method compileDebugInfo (line 482) | protected function compileDebugInfo(Compiler $compiler)
    method compileGetSourceContext (line 499) | protected function compileGetSourceContext(Compiler $compiler)

FILE: src/Node/NameDeprecation.php
  class NameDeprecation (line 19) | class NameDeprecation
    method __construct (line 25) | public function __construct(string $package = '', string $version = ''...
    method getPackage (line 32) | public function getPackage(): string
    method getVersion (line 37) | public function getVersion(): string
    method getNewName (line 42) | public function getNewName(): string

FILE: src/Node/Node.php
  class Node (line 26) | #[YieldReady]
    method __construct (line 48) | public function __construct(array $nodes = [], array $attributes = [],...
    method __toString (line 68) | public function __toString(): string
    method __clone (line 108) | public function __clone()
    method compile (line 118) | public function compile(Compiler $compiler)
    method getTemplateLine (line 125) | public function getTemplateLine(): int
    method getNodeTag (line 130) | public function getNodeTag(): ?string
    method setNodeTag (line 138) | public function setNodeTag(string $tag): void
    method hasAttribute (line 147) | public function hasAttribute(string $name): bool
    method getAttribute (line 152) | public function getAttribute(string $name)
    method setAttribute (line 171) | public function setAttribute(string $name, $value): void
    method deprecateAttribute (line 186) | public function deprecateAttribute(string $name, NameDeprecation $dep)...
    method removeAttribute (line 191) | public function removeAttribute(string $name): void
    method hasNode (line 199) | public function hasNode(string $name): bool
    method getNode (line 207) | public function getNode(string $name): self
    method setNode (line 229) | public function setNode(string $name, self $node): void
    method removeNode (line 250) | public function removeNode(string $name): void
    method deprecateNode (line 258) | public function deprecateNode(string $name, NameDeprecation $dep): void
    method count (line 266) | #[\ReturnTypeWillChange]
    method getIterator (line 272) | public function getIterator(): \Traversable
    method getTemplateName (line 277) | public function getTemplateName(): ?string
    method setSourceContext (line 282) | public function setSourceContext(Source $source): void
    method getSourceContext (line 290) | public function getSourceContext(): ?Source

FILE: src/Node/NodeCaptureInterface.php
  type NodeCaptureInterface (line 19) | interface NodeCaptureInterface

FILE: src/Node/NodeOutputInterface.php
  type NodeOutputInterface (line 19) | interface NodeOutputInterface

FILE: src/Node/Nodes.php
  class Nodes (line 21) | #[YieldReady]
    method __construct (line 24) | public function __construct(array $nodes = [], int $lineno = 0)

FILE: src/Node/PrintNode.php
  class PrintNode (line 24) | #[YieldReady]
    method __construct (line 27) | public function __construct(AbstractExpression $expr, int $lineno)
    method compile (line 32) | public function compile(Compiler $compiler): void

FILE: src/Node/SandboxNode.php
  class SandboxNode (line 22) | #[YieldReady]
    method __construct (line 25) | public function __construct(Node $body, int $lineno)
    method compile (line 30) | public function compile(Compiler $compiler): void

FILE: src/Node/SetNode.php
  class SetNode (line 23) | #[YieldReady]
    method __construct (line 26) | public function __construct(bool $capture, Node $names, Node $values, ...
    method compile (line 54) | public function compile(Compiler $compiler): void

FILE: src/Node/TextNode.php
  class TextNode (line 23) | #[YieldReady]
    method __construct (line 26) | public function __construct(string $data, int $lineno)
    method compile (line 31) | public function compile(Compiler $compiler): void

FILE: src/Node/TypesNode.php
  class TypesNode (line 22) | #[YieldReady]
    method __construct (line 28) | public function __construct(array $types, int $lineno)
    method compile (line 36) | public function compile(Compiler $compiler)

FILE: src/Node/WithNode.php
  class WithNode (line 22) | #[YieldReady]
    method __construct (line 25) | public function __construct(Node $body, ?Node $variables, bool $only, ...
    method compile (line 35) | public function compile(Compiler $compiler): void

FILE: src/NodeTraverser.php
  class NodeTraverser (line 24) | final class NodeTraverser
    method __construct (line 32) | public function __construct(Environment $env, array $visitors = [])
    method addVisitor (line 40) | public function addVisitor(NodeVisitorInterface $visitor): void
    method traverse (line 48) | public function traverse(Node $node): Node
    method traverseForVisitor (line 60) | private function traverseForVisitor(NodeVisitorInterface $visitor, Nod...

FILE: src/NodeVisitor/AbstractNodeVisitor.php
  class AbstractNodeVisitor (line 24) | abstract class AbstractNodeVisitor implements NodeVisitorInterface
    method enterNode (line 26) | final public function enterNode(Node $node, Environment $env): Node
    method leaveNode (line 31) | final public function leaveNode(Node $node, Environment $env): ?Node
    method doEnterNode (line 41) | abstract protected function doEnterNode(Node $node, Environment $env);
    method doLeaveNode (line 48) | abstract protected function doLeaveNode(Node $node, Environment $env);

FILE: src/NodeVisitor/EscaperNodeVisitor.php
  class EscaperNodeVisitor (line 35) | final class EscaperNodeVisitor implements NodeVisitorInterface
    method __construct (line 44) | public function __construct()
    method enterNode (line 49) | public function enterNode(Node $node, Environment $env): Node
    method leaveNode (line 68) | public function leaveNode(Node $node, Environment $env): ?Node
    method escapeConditional (line 99) | private function escapeConditional($expression, Environment $env, stri...
    method escapeExpression (line 112) | private function escapeExpression(AbstractExpression $expression, Envi...
    method preEscapeFilterNode (line 117) | private function preEscapeFilterNode(FilterExpression $filter, Environ...
    method isSafeFor (line 142) | private function isSafeFor(string $type, AbstractExpression $expressio...
    method needEscaping (line 163) | private function needEscaping(): string|bool
    method getEscaperFilter (line 172) | private function getEscaperFilter(Environment $env, string $type, Abst...
    method getPriority (line 181) | public function getPriority(): int

FILE: src/NodeVisitor/NodeVisitorInterface.php
  type NodeVisitorInterface (line 22) | interface NodeVisitorInterface
    method enterNode (line 29) | public function enterNode(Node $node, Environment $env): Node;
    method leaveNode (line 36) | public function leaveNode(Node $node, Environment $env): ?Node;
    method getPriority (line 45) | public function getPriority();

FILE: src/NodeVisitor/OptimizerNodeVisitor.php
  class OptimizerNodeVisitor (line 40) | final class OptimizerNodeVisitor implements NodeVisitorInterface
    method __construct (line 54) | public function __construct(
    method enterNode (line 70) | public function enterNode(Node $node, Environment $env): Node
    method leaveNode (line 79) | public function leaveNode(Node $node, Environment $env): ?Node
    method optimizePrintNode (line 97) | private function optimizePrintNode(Node $node): Node
    method enterOptimizeFor (line 124) | private function enterOptimizeFor(Node $node): void
    method leaveOptimizeFor (line 188) | private function leaveOptimizeFor(Node $node): void
    method addLoopToCurrent (line 197) | private function addLoopToCurrent(): void
    method addLoopToAll (line 202) | private function addLoopToAll(): void
    method getPriority (line 209) | public function getPriority(): int

FILE: src/NodeVisitor/SafeAnalysisNodeVisitor.php
  class SafeAnalysisNodeVisitor (line 30) | final class SafeAnalysisNodeVisitor implements NodeVisitorInterface
    method setSafeVars (line 35) | public function setSafeVars(array $safeVars): void
    method getSafe (line 43) | public function getSafe(Node $node)
    method setSafe (line 70) | private function setSafe(Node $node, array $safe): void
    method enterNode (line 88) | public function enterNode(Node $node, Environment $env): Node
    method leaveNode (line 93) | public function leaveNode(Node $node, Environment $env): ?Node
    method intersectSafe (line 164) | private function intersectSafe(array $a, array $b): array
    method getPriority (line 181) | public function getPriority(): int

FILE: src/NodeVisitor/SandboxNodeVisitor.php
  class SandboxNodeVisitor (line 37) | final class SandboxNodeVisitor implements NodeVisitorInterface
    method enterNode (line 48) | public function enterNode(Node $node, Environment $env): Node
    method leaveNode (line 106) | public function leaveNode(Node $node, Environment $env): ?Node
    method wrapNode (line 122) | private function wrapNode(Node $node, string $name): void
    method wrapArrayNode (line 136) | private function wrapArrayNode(Node $node, string $name): void
    method getPriority (line 144) | public function getPriority(): int

FILE: src/NodeVisitor/YieldNotReadyNodeVisitor.php
  class YieldNotReadyNodeVisitor (line 22) | final class YieldNotReadyNodeVisitor implements NodeVisitorInterface
    method __construct (line 26) | public function __construct(
    method enterNode (line 31) | public function enterNode(Node $node, Environment $env): Node
    method leaveNode (line 50) | public function leaveNode(Node $node, Environment $env): ?Node
    method getPriority (line 55) | public function getPriority(): int

FILE: src/OperatorPrecedenceChange.php
  class OperatorPrecedenceChange (line 23) | class OperatorPrecedenceChange extends PrecedenceChange
    method __construct (line 25) | public function __construct(

FILE: src/Parser.php
  class Parser (line 43) | class Parser
    method __construct (line 61) | public function __construct(
    method getEnvironment (line 67) | public function getEnvironment(): Environment
    method getVarName (line 72) | public function getVarName(): string
    method parse (line 82) | public function parse(TokenStream $stream, $test = null, bool $dropNee...
    method shouldIgnoreUnknownTwigCallables (line 148) | public function shouldIgnoreUnknownTwigCallables(): bool
    method subparseIgnoreUnknownTwigCallables (line 153) | public function subparseIgnoreUnknownTwigCallables($test, bool $dropNe...
    method subparse (line 167) | public function subparse($test, bool $dropNeedle = false): Node
    method getBlockStack (line 245) | public function getBlockStack(): array
    method peekBlockStack (line 255) | public function peekBlockStack()
    method popBlockStack (line 260) | public function popBlockStack(): void
    method pushBlockStack (line 265) | public function pushBlockStack($name): void
    method hasBlock (line 270) | public function hasBlock(string $name): bool
    method getBlock (line 277) | public function getBlock(string $name): Node
    method setBlock (line 284) | public function setBlock(string $name, BlockNode $value): void
    method hasMacro (line 293) | public function hasMacro(string $name): bool
    method setMacro (line 300) | public function setMacro(string $name, MacroNode $node): void
    method addTrait (line 305) | public function addTrait($trait): void
    method hasTraits (line 310) | public function hasTraits(): bool
    method embedTemplate (line 320) | public function embedTemplate(ModuleNode $template)
    method addImportedSymbol (line 327) | public function addImportedSymbol(string $type, string $alias, ?string...
    method getImportedSymbol (line 341) | public function getImportedSymbol(string $type, string $alias)
    method isMainScope (line 347) | public function isMainScope(): bool
    method pushLocalScope (line 352) | public function pushLocalScope(): void
    method popLocalScope (line 357) | public function popLocalScope(): void
    method getExpressionParser (line 365) | public function getExpressionParser(): ExpressionParser
    method parseExpression (line 376) | public function parseExpression(int $precedence = 0): AbstractExpression
    method getParent (line 398) | public function getParent(): ?Node
    method hasInheritance (line 408) | public function hasInheritance()
    method setParent (line 413) | public function setParent(?Node $parent): void
    method getStream (line 430) | public function getStream(): TokenStream
    method getCurrentToken (line 435) | public function getCurrentToken(): Token
    method getFunction (line 440) | public function getFunction(string $name, int $line): TwigFunction
    method getFilter (line 470) | public function getFilter(string $name, int $line): TwigFilter
    method getTest (line 499) | public function getTest(int $line): TwigTest
    method filterBodyNodes (line 547) | private function filterBodyNodes(Node $node, bool $nested = false): ?Node
    method checkPrecedenceDeprecations (line 595) | private function checkPrecedenceDeprecations(ExpressionParserInterface...

FILE: src/Profiler/Dumper/BaseDumper.php
  class BaseDumper (line 19) | abstract class BaseDumper
    method dump (line 23) | public function dump(Profile $profile): string
    method formatTemplate (line 28) | abstract protected function formatTemplate(Profile $profile, $prefix):...
    method formatNonTemplate (line 30) | abstract protected function formatNonTemplate(Profile $profile, $prefi...
    method formatTime (line 32) | abstract protected function formatTime(Profile $profile, $percent): st...
    method dumpProfile (line 34) | private function dumpProfile(Profile $profile, $prefix = '', $sibling ...

FILE: src/Profiler/Dumper/BlackfireDumper.php
  class BlackfireDumper (line 19) | final class BlackfireDumper
    method dump (line 21) | public function dump(Profile $profile): string
    method dumpChildren (line 43) | private function dumpChildren(string $parent, Profile $profile, &$data...
    method dumpProfile (line 56) | private function dumpProfile(string $edge, Profile $profile, &$data): ...

FILE: src/Profiler/Dumper/HtmlDumper.php
  class HtmlDumper (line 19) | final class HtmlDumper extends BaseDumper
    method dump (line 28) | public function dump(Profile $profile): string
    method formatTemplate (line 33) | protected function formatTemplate(Profile $profile, $prefix): string
    method formatNonTemplate (line 38) | protected function formatNonTemplate(Profile $profile, $prefix): string
    method formatTime (line 43) | protected function formatTime(Profile $profile, $percent): string

FILE: src/Profiler/Dumper/TextDumper.php
  class TextDumper (line 19) | final class TextDumper extends BaseDumper
    method formatTemplate (line 21) | protected function formatTemplate(Profile $profile, $prefix): string
    method formatNonTemplate (line 26) | protected function formatNonTemplate(Profile $profile, $prefix): string
    method formatTime (line 31) | protected function formatTime(Profile $profile, $percent): string

FILE: src/Profiler/Node/EnterProfileNode.php
  class EnterProfileNode (line 23) | #[YieldReady]
    method __construct (line 26) | public function __construct(string $extensionName, string $type, strin...
    method compile (line 31) | public function compile(Compiler $compiler): void

FILE: src/Profiler/Node/LeaveProfileNode.php
  class LeaveProfileNode (line 23) | #[YieldReady]
    method __construct (line 26) | public function __construct(string $varName)
    method compile (line 31) | public function compile(Compiler $compiler): void

FILE: src/Profiler/NodeVisitor/ProfilerNodeVisitor.php
  class ProfilerNodeVisitor (line 29) | final class ProfilerNodeVisitor implements NodeVisitorInterface
    method __construct (line 33) | public function __construct(
    method enterNode (line 39) | public function enterNode(Node $node, Environment $env): Node
    method leaveNode (line 44) | public function leaveNode(Node $node, Environment $env): ?Node
    method getPriority (line 66) | public function getPriority(): int

FILE: src/Profiler/Profile.php
  class Profile (line 17) | final class Profile implements \IteratorAggregate, \Serializable
    method __construct (line 27) | public function __construct(
    method getTemplate (line 36) | public function getTemplate(): string
    method getType (line 41) | public function getType(): string
    method getName (line 46) | public function getName(): string
    method isRoot (line 51) | public function isRoot(): bool
    method isTemplate (line 56) | public function isTemplate(): bool
    method isBlock (line 61) | public function isBlock(): bool
    method isMacro (line 66) | public function isMacro(): bool
    method getProfiles (line 74) | public function getProfiles(): array
    method addProfile (line 79) | public function addProfile(self $profile): void
    method getDuration (line 87) | public function getDuration(): float
    method getStartTime (line 105) | public function getStartTime(): float
    method getEndTime (line 113) | public function getEndTime(): float
    method getMemoryUsage (line 121) | public function getMemoryUsage(): int
    method getPeakMemoryUsage (line 129) | public function getPeakMemoryUsage(): int
    method enter (line 137) | public function enter(): void
    method leave (line 149) | public function leave(): void
    method reset (line 158) | public function reset(): void
    method getIterator (line 164) | public function getIterator(): \Traversable
    method serialize (line 169) | public function serialize(): string
    method unserialize (line 174) | public function unserialize($data): void
    method __serialize (line 182) | public function __serialize(): array
    method __unserialize (line 190) | public function __unserialize(array $data): void

FILE: src/Resources/core.php
  function twig_cycle (line 20) | function twig_cycle($values, $position)
  function twig_random (line 32) | function twig_random(Environment $env, $values = null, $max = null)
  function twig_date_format_filter (line 44) | function twig_date_format_filter(Environment $env, $date, $format = null...
  function twig_date_modify_filter (line 56) | function twig_date_modify_filter(Environment $env, $date, $modifier)
  function twig_sprintf (line 68) | function twig_sprintf($format, ...$values)
  function twig_date_converter (line 80) | function twig_date_converter(Environment $env, $date = null, $timezone =...
  function twig_replace_filter (line 92) | function twig_replace_filter($str, $from)
  function twig_round (line 104) | function twig_round($value, $precision = 0, $method = 'common')
  function twig_number_format_filter (line 116) | function twig_number_format_filter(Environment $env, $number, $decimal =...
  function twig_urlencode_filter (line 128) | function twig_urlencode_filter($url)
  function twig_array_merge (line 140) | function twig_array_merge(...$arrays)
  function twig_slice (line 152) | function twig_slice(Environment $env, $item, $start, $length = null, $pr...
  function twig_first (line 164) | function twig_first(Environment $env, $item)
  function twig_last (line 176) | function twig_last(Environment $env, $item)
  function twig_join_filter (line 188) | function twig_join_filter($value, $glue = '', $and = null)
  function twig_split_filter (line 200) | function twig_split_filter(Environment $env, $value, $delimiter, $limit ...
  function twig_get_array_keys_filter (line 212) | function twig_get_array_keys_filter($array)
  function twig_reverse_filter (line 224) | function twig_reverse_filter(Environment $env, $item, $preserveKeys = fa...
  function twig_sort_filter (line 236) | function twig_sort_filter(Environment $env, $array, $arrow = null)
  function twig_matches (line 248) | function twig_matches(string $regexp, ?string $str)
  function twig_trim_filter (line 260) | function twig_trim_filter($string, $characterMask = null, $side = 'both')
  function twig_nl2br (line 272) | function twig_nl2br($string)
  function twig_spaceless (line 284) | function twig_spaceless($content)
  function twig_convert_encoding (line 296) | function twig_convert_encoding($string, $to, $from)
  function twig_length_filter (line 308) | function twig_length_filter(Environment $env, $thing)
  function twig_upper_filter (line 320) | function twig_upper_filter(Environment $env, $string)
  function twig_lower_filter (line 332) | function twig_lower_filter(Environment $env, $string)
  function twig_striptags (line 344) | function twig_striptags($string, $allowable_tags = null)
  function twig_title_string_filter (line 356) | function twig_title_string_filter(Environment $env, $string)
  function twig_capitalize_string_filter (line 368) | function twig_capitalize_string_filter(Environment $env, $string)
  function twig_test_empty (line 380) | function twig_test_empty($value)
  function twig_test_iterable (line 392) | function twig_test_iterable($value)
  function twig_include (line 404) | function twig_include(Environment $env, $context, $template, $variables ...
  function twig_source (line 416) | function twig_source(Environment $env, $name, $ignoreMissing = false)
  function twig_constant (line 428) | function twig_constant($constant, $object = null)
  function twig_constant_is_defined (line 440) | function twig_constant_is_defined($constant, $object = null)
  function twig_array_batch (line 452) | function twig_array_batch($items, $size, $fill = null, $preserveKeys = t...
  function twig_array_column (line 464) | function twig_array_column($array, $name, $index = null): array
  function twig_array_filter (line 476) | function twig_array_filter(Environment $env, $array, $arrow)
  function twig_array_map (line 488) | function twig_array_map(Environment $env, $array, $arrow)
  function twig_array_reduce (line 500) | function twig_array_reduce(Environment $env, $array, $arrow, $initial = ...
  function twig_array_some (line 512) | function twig_array_some(Environment $env, $array, $arrow)
  function twig_array_every (line 524) | function twig_array_every(Environment $env, $array, $arrow)
  function twig_check_arrow_in_sandbox (line 536) | function twig_check_arrow_in_sandbox(Environment $env, $arrow, $thing, $...

FILE: src/Resources/debug.php
  function twig_var_dump (line 20) | function twig_var_dump(Environment $env, $context, ...$vars)

FILE: src/Resources/escaper.php
  function twig_raw_filter (line 22) | function twig_raw_filter($string)
  function twig_escape_filter (line 34) | function twig_escape_filter(Environment $env, $string, $strategy = 'html...
  function twig_escape_filter_is_safe (line 46) | function twig_escape_filter_is_safe(Node $filterArgs)

FILE: src/Resources/string_loader.php
  function twig_template_from_string (line 21) | function twig_template_from_string(Environment $env, $template, ?string ...

FILE: src/Runtime/EscaperRuntime.php
  class EscaperRuntime (line 18) | final class EscaperRuntime implements RuntimeExtensionInterface
    method __construct (line 29) | public function __construct(
    method setEscaper (line 42) | public function setEscaper($strategy, callable $callable)
    method getEscapers (line 52) | public function getEscapers()
    method setSafeClasses (line 62) | public function setSafeClasses(array $safeClasses = [])
    method addSafeClass (line 77) | public function addSafeClass(string $class, array $strategies)
    method escape (line 100) | public function escape($string, string $strategy = 'html', ?string $ch...
    method convertEncoding (line 338) | private function convertEncoding(string $string, string $to, string $f...

FILE: src/RuntimeLoader/ContainerRuntimeLoader.php
  class ContainerRuntimeLoader (line 24) | class ContainerRuntimeLoader implements RuntimeLoaderInterface
    method __construct (line 26) | public function __construct(
    method load (line 31) | public function load(string $class)

FILE: src/RuntimeLoader/FactoryRuntimeLoader.php
  class FactoryRuntimeLoader (line 19) | class FactoryRuntimeLoader implements RuntimeLoaderInterface
    method __construct (line 24) | public function __construct(
    method load (line 29) | public function load(string $class)

FILE: src/RuntimeLoader/RuntimeLoaderInterface.php
  type RuntimeLoaderInterface (line 19) | interface RuntimeLoaderInterface
    method load (line 26) | public function load(string $class);

FILE: src/Sandbox/SecurityError.php
  class SecurityError (line 21) | class SecurityError extends Error

FILE: src/Sandbox/SecurityNotAllowedFilterError.php
  class SecurityNotAllowedFilterError (line 19) | final class SecurityNotAllowedFilterError extends SecurityError
    method __construct (line 23) | public function __construct(string $message, string $functionName)
    method getFilterName (line 29) | public function getFilterName(): string

FILE: src/Sandbox/SecurityNotAllowedFunctionError.php
  class SecurityNotAllowedFunctionError (line 19) | final class SecurityNotAllowedFunctionError extends SecurityError
    method __construct (line 23) | public function __construct(string $message, string $functionName)
    method getFunctionName (line 29) | public function getFunctionName(): string

FILE: src/Sandbox/SecurityNotAllowedMethodError.php
  class SecurityNotAllowedMethodError (line 19) | final class SecurityNotAllowedMethodError extends SecurityError
    method __construct (line 24) | public function __construct(string $message, string $className, string...
    method getClassName (line 31) | public function getClassName(): string
    method getMethodName (line 36) | public function getMethodName(): string

FILE: src/Sandbox/SecurityNotAllowedPropertyError.php
  class SecurityNotAllowedPropertyError (line 19) | final class SecurityNotAllowedPropertyError extends SecurityError
    method __construct (line 24) | public function __construct(string $message, string $className, string...
    method getClassName (line 31) | public function getClassName(): string
    method getPropertyName (line 36) | public function getPropertyName(): string

FILE: src/Sandbox/SecurityNotAllowedTagError.php
  class SecurityNotAllowedTagError (line 19) | final class SecurityNotAllowedTagError extends SecurityError
    method __construct (line 23) | public function __construct(string $message, string $tagName)
    method getTagName (line 29) | public function getTagName(): string

FILE: src/Sandbox/SecurityPolicy.php
  class SecurityPolicy (line 22) | final class SecurityPolicy implements SecurityPolicyInterface
    method __construct (line 30) | public function __construct(array $allowedTags = [], array $allowedFil...
    method setAllowedTags (line 39) | public function setAllowedTags(array $tags): void
    method setAllowedFilters (line 44) | public function setAllowedFilters(array $filters): void
    method setAllowedMethods (line 49) | public function setAllowedMethods(array $methods): void
    method setAllowedProperties (line 57) | public function setAllowedProperties(array $properties): void
    method setAllowedFunctions (line 62) | public function setAllowedFunctions(array $functions): void
    method checkSecurity (line 67) | public function checkSecurity($tags, $filters, $functions): void
    method checkMethodAllowed (line 94) | public function checkMethodAllowed($obj, $method): void
    method checkPropertyAllowed (line 115) | public function checkPropertyAllowed($obj, $property): void

FILE: src/Sandbox/SecurityPolicyInterface.php
  type SecurityPolicyInterface (line 19) | interface SecurityPolicyInterface
    method checkSecurity (line 28) | public function checkSecurity($tags, $filters, $functions): void;
    method checkMethodAllowed (line 36) | public function checkMethodAllowed($obj, $method): void;
    method checkPropertyAllowed (line 44) | public function checkPropertyAllowed($obj, $property): void;

FILE: src/Sandbox/SourcePolicyInterface.php
  type SourcePolicyInterface (line 21) | interface SourcePolicyInterface
    method enableSandbox (line 23) | public function enableSandbox(Source $source): bool;

FILE: src/Source.php
  class Source (line 19) | final class Source
    method __construct (line 26) | public function __construct(
    method getCode (line 33) | public function getCode(): string
    method getName (line 38) | public function getName(): string
    method getPath (line 43) | public function getPath(): string

FILE: src/Template.php
  class Template (line 29) | abstract class Template
    method __construct (line 45) | public function __construct(
    method getTemplateName (line 55) | abstract public function getTemplateName(): string;
    method getDebugInfo (line 62) | abstract public function getDebugInfo(): array;
    method getSourceContext (line 67) | abstract public function getSourceContext(): Source;
    method getParent (line 77) | public function getParent(array $context): self|TemplateWrapper|false
    method doGetParent (line 98) | protected function doGetParent(array $context): bool|string|self|Templ...
    method isTraitable (line 103) | public function isTraitable(): bool
    method displayParentBlock (line 118) | public function displayParentBlock($name, array $context, array $block...
    method displayBlock (line 136) | public function displayBlock($name, array $context, array $blocks = []...
    method renderParentBlock (line 155) | public function renderParentBlock($name, array $context, array $blocks...
    method renderBlock (line 189) | public function renderBlock($name, array $context, array $blocks = [],...
    method hasBlock (line 231) | public function hasBlock($name, array $context, array $blocks = []): bool
    method getBlockNames (line 259) | public function getBlockNames(array $context, array $blocks = []): array
    method load (line 273) | protected function load(string|TemplateWrapper|array $template, int $l...
    method loadTemplate (line 318) | protected function loadTemplate($template, $templateName = null, ?int ...
    method unwrap (line 338) | public function unwrap(): self
    method getBlocks (line 351) | public function getBlocks(): array
    method display (line 356) | public function display(array $context, array $blocks = []): void
    method render (line 363) | public function render(array $context): string
    method yield (line 396) | public function yield(array $context, array $blocks = []): iterable
    method yieldBlock (line 426) | public function yieldBlock($name, array $context, array $blocks = [], ...
    method yieldParentBlock (line 486) | public function yieldParentBlock($name, array $context, array $blocks ...
    method hasMacro (line 497) | protected function hasMacro(string $name, array $context): bool
    method getTemplateForMacro (line 510) | protected function getTemplateForMacro(string $name, array $context, i...
    method doDisplay (line 534) | abstract protected function doDisplay(array $context, array $blocks = ...

FILE: src/TemplateWrapper.php
  class TemplateWrapper (line 19) | final class TemplateWrapper
    method __construct (line 27) | public function __construct(
    method stream (line 36) | public function stream(array $context = []): iterable
    method streamBlock (line 44) | public function streamBlock(string $name, array $context = []): iterable
    method render (line 49) | public function render(array $context = []): string
    method display (line 57) | public function display(array $context = [])
    method hasBlock (line 64) | public function hasBlock(string $name, array $context = []): bool
    method getBlockNames (line 72) | public function getBlockNames(array $context = []): array
    method renderBlock (line 77) | public function renderBlock(string $name, array $context = []): string
    method displayBlock (line 85) | public function displayBlock(string $name, array $context = [])
    method getSourceContext (line 93) | public function getSourceContext(): Source
    method getTemplateName (line 98) | public function getTemplateName(): string
    method unwrap (line 108) | public function unwrap()

FILE: src/Test/IntegrationTestCase.php
  class IntegrationTestCase (line 31) | abstract class IntegrationTestCase extends TestCase
    method getFixturesDir (line 38) | protected function getFixturesDir()
    method getFixturesDirectory (line 43) | protected static function getFixturesDirectory(): string
    method getRuntimeLoaders (line 51) | protected function getRuntimeLoaders()
    method getExtensions (line 59) | protected function getExtensions()
    method getTwigFilters (line 67) | protected function getTwigFilters()
    method getTwigFunctions (line 75) | protected function getTwigFunctions()
    method getTwigTests (line 83) | protected function getTwigTests()
    method getUndefinedFilterCallbacks (line 91) | protected function getUndefinedFilterCallbacks(): array
    method getUndefinedFunctionCallbacks (line 99) | protected function getUndefinedFunctionCallbacks(): array
    method getUndefinedTestCallbacks (line 107) | protected function getUndefinedTestCallbacks(): array
    method getUndefinedTokenParserCallbacks (line 115) | protected function getUndefinedTokenParserCallbacks(): array
    method testIntegration (line 125) | public function testIntegration($file, $message, $condition, $template...
    method testLegacyIntegration (line 137) | public function testLegacyIntegration($file, $message, $condition, $te...
    method getTests (line 147) | public function getTests($name, $legacyTests = false)
    method getLegacyTests (line 204) | public function getLegacyTests()
    method doIntegrationTest (line 212) | protected function doIntegrationTest($file, $message, $condition, $tem...
    method parseTemplates (line 341) | protected static function parseTemplates($test)

FILE: src/Test/NodeTestCase.php
  class NodeTestCase (line 22) | abstract class NodeTestCase extends TestCase
    method getTests (line 32) | public function getTests()
    method provideTests (line 40) | public static function provideTests(): iterable
    method testCompile (line 53) | #[DataProvider('getTests'), DataProvider('provideTests')]
    method assertNodeCompilation (line 62) | public function assertNodeCompilation($source, Node $node, ?Environmen...
    method getCompiler (line 77) | protected function getCompiler(?Environment $environment = null)
    method getEnvironment (line 87) | protected function getEnvironment()
    method createEnvironment (line 92) | protected static function createEnvironment(): Environment
    method getVariableGetter (line 102) | protected function getVariableGetter($name, $line = false)
    method createVariableGetter (line 109) | final protected static function createVariableGetter(string $name, boo...
    method getAttributeGetter (line 121) | protected function getAttributeGetter()
    method createAttributeGetter (line 128) | final protected static function createAttributeGetter(): string
    method checkDataProvider (line 134) | #[BeforeClass]

FILE: src/Token.php
  class Token (line 18) | final class Token
    method __construct (line 42) | public function __construct(
    method __toString (line 55) | public function __toString(): string
    method test (line 71) | public function test($type, $values = null): bool
    method getLine (line 122) | public function getLine(): int
    method getType (line 130) | public function getType(): int
    method getValue (line 137) | public function getValue()
    method toEnglish (line 142) | public function toEnglish(): string
    method typeToString (line 147) | public static function typeToString(int $type, bool $short = false): s...
    method typeToEnglish (line 202) | public static function typeToEnglish(int $type): string

FILE: src/TokenParser/AbstractTokenParser.php
  class AbstractTokenParser (line 25) | abstract class AbstractTokenParser implements TokenParserInterface
    method setParser (line 32) | public function setParser(Parser $parser): void
    method parseAssignmentExpression (line 40) | protected function parseAssignmentExpression(): Nodes

FILE: src/TokenParser/ApplyTokenParser.php
  class ApplyTokenParser (line 31) | final class ApplyTokenParser extends AbstractTokenParser
    method parse (line 33) | public function parse(Token $token): Node
    method decideApplyEnd (line 57) | public function decideApplyEnd(Token $token): bool
    method getTag (line 62) | public function getTag(): string

FILE: src/TokenParser/AutoEscapeTokenParser.php
  class AutoEscapeTokenParser (line 25) | final class AutoEscapeTokenParser extends AbstractTokenParser
    method parse (line 27) | public function parse(Token $token): Node
    method decideBlockEnd (line 49) | public function decideBlockEnd(Token $token): bool
    method getTag (line 54) | public function getTag(): string

FILE: src/TokenParser/BlockTokenParser.php
  class BlockTokenParser (line 34) | final class BlockTokenParser extends AbstractTokenParser
    method parse (line 36) | public function parse(Token $token): Node
    method decideBlockEnd (line 68) | public function decideBlockEnd(Token $token): bool
    method getTag (line 73) | public function getTag(): string

FILE: src/TokenParser/DeprecatedTokenParser.php
  class DeprecatedTokenParser (line 31) | final class DeprecatedTokenParser extends AbstractTokenParser
    method parse (line 33) | public function parse(Token $token): Node
    method getTag (line 61) | public function getTag(): string

FILE: src/TokenParser/DoTokenParser.php
  class DoTokenParser (line 23) | final class DoTokenParser extends AbstractTokenParser
    method parse (line 25) | public function parse(Token $token): Node
    method getTag (line 34) | public function getTag(): string

FILE: src/TokenParser/EmbedTokenParser.php
  class EmbedTokenParser (line 25) | final class EmbedTokenParser extends IncludeTokenParser
    method parse (line 27) | public function parse(Token $token): Node
    method decideBlockEnd (line 64) | public function decideBlockEnd(Token $token): bool
    method getTag (line 69) | public function getTag(): string

FILE: src/TokenParser/ExtendsTokenParser.php
  class ExtendsTokenParser (line 27) | final class ExtendsTokenParser extends AbstractTokenParser
    method parse (line 29) | public function parse(Token $token): Node
    method getTag (line 46) | public function getTag(): string

FILE: src/TokenParser/FlushTokenParser.php
  class FlushTokenParser (line 25) | final class FlushTokenParser extends AbstractTokenParser
    method parse (line 27) | public function parse(Token $token): Node
    method getTag (line 34) | public function getTag(): string

FILE: src/TokenParser/ForTokenParser.php
  class ForTokenParser (line 32) | final class ForTokenParser extends AbstractTokenParser
    method parse (line 34) | public function parse(Token $token): Node
    method decideForFork (line 66) | public function decideForFork(Token $token): bool
    method decideForEnd (line 71) | public function decideForEnd(Token $token): bool
    method getTag (line 76) | public function getTag(): string

FILE: src/TokenParser/FromTokenParser.php
  class FromTokenParser (line 28) | final class FromTokenParser extends AbstractTokenParser
    method parse (line 30) | public function parse(Token $token): Node
    method getTag (line 65) | public function getTag(): string

FILE: src/TokenParser/GuardTokenParser.php
  class GuardTokenParser (line 23) | final class GuardTokenParser extends AbstractTokenParser
    method parse (line 25) | public function parse(Token $token): Node
    method decideGuardFork (line 65) | public function decideGuardFork(Token $token): bool
    method decideGuardEnd (line 70) | public function decideGuardEnd(Token $token): bool
    method getTag (line 75) | public function getTag(): string

FILE: src/TokenParser/IfTokenParser.php
  class IfTokenParser (line 34) | final class IfTokenParser extends AbstractTokenParser
    method parse (line 36) | public function parse(Token $token): Node
    method decideIfFork (line 76) | public function decideIfFork(Token $token): bool
    method decideIfEnd (line 81) | public function decideIfEnd(Token $token): bool
    method getTag (line 86) | public function getTag(): string

FILE: src/TokenParser/ImportTokenParser.php
  class ImportTokenParser (line 27) | final class ImportTokenParser extends AbstractTokenParser
    method parse (line 29) | public function parse(Token $token): Node
    method getTag (line 41) | public function getTag(): string

FILE: src/TokenParser/IncludeTokenParser.php
  class IncludeTokenParser (line 29) | class IncludeTokenParser extends AbstractTokenParser
    method parse (line 31) | public function parse(Token $token): Node
    method parseArguments (line 43) | protected function parseArguments()
    method getTag (line 69) | public function getTag(): string

FILE: src/TokenParser/MacroTokenParser.php
  class MacroTokenParser (line 35) | final class MacroTokenParser extends AbstractTokenParser
    method parse (line 37) | public function parse(Token $token): Node
    method decideBlockEnd (line 62) | public function decideBlockEnd(Token $token): bool
    method getTag (line 67) | public function getTag(): string
    method parseDefinition (line 72) | private function parseDefinition(): ArrayExpression
    method checkConstantExpression (line 107) | private function checkConstantExpression(Node $node): bool

FILE: src/TokenParser/SandboxTokenParser.php
  class SandboxTokenParser (line 32) | final class SandboxTokenParser extends AbstractTokenParser
    method parse (line 34) | public function parse(Token $token): Node
    method decideBlockEnd (line 59) | public function decideBlockEnd(Token $token): bool
    method getTag (line 64) | public function getTag(): string

FILE: src/TokenParser/SetTokenParser.php
  class SetTokenParser (line 32) | final class SetTokenParser extends AbstractTokenParser
    method parse (line 34) | public function parse(Token $token): Node
    method decideBlockEnd (line 65) | public function decideBlockEnd(Token $token): bool
    method getTag (line 70) | public function getTag(): string
    method parseMultitargetExpression (line 75) | private function parseMultitargetExpression(): Nodes

FILE: src/TokenParser/TokenParserInterface.php
  type TokenParserInterface (line 24) | interface TokenParserInterface
    method setParser (line 29) | public function setParser(Parser $parser): void;
    method parse (line 38) | public function parse(Token $token);
    method getTag (line 45) | public function getTag();

FILE: src/TokenParser/TypesTokenParser.php
  class TypesTokenParser (line 29) | final class TypesTokenParser extends AbstractTokenParser
    method parse (line 31) | public function parse(Token $token): Node
    method parseSimpleMappingExpression (line 45) | private function parseSimpleMappingExpression(TokenStream $stream): array
    method getTag (line 85) | public function getTag(): string

FILE: src/TokenParser/UseTokenParser.php
  class UseTokenParser (line 35) | final class UseTokenParser extends AbstractTokenParser
    method parse (line 37) | public function parse(Token $token): Node
    method getTag (line 71) | public function getTag(): string

FILE: src/TokenParser/WithTokenParser.php
  class WithTokenParser (line 25) | final class WithTokenParser extends AbstractTokenParser
    method parse (line 27) | public function parse(Token $token): Node
    method decideWithEnd (line 47) | public function decideWithEnd(Token $token): bool
    method getTag (line 52) | public function getTag(): string

FILE: src/TokenStream.php
  class TokenStream (line 22) | final class TokenStream
    method __construct (line 26) | public function __construct(
    method __toString (line 37) | public function __toString(): string
    method injectTokens (line 45) | public function injectTokens(array $tokens)
    method next (line 53) | public function next(): Token
    method nextIf (line 67) | public function nextIf($primary, $secondary = null)
    method expect (line 75) | public function expect($type, $value = null, ?string $message = null):...
    method look (line 97) | public function look(int $number = 1): Token
    method test (line 109) | public function test($primary, $secondary = null): bool
    method isEOF (line 117) | public function isEOF(): bool
    method getCurrent (line 122) | public function getCurrent(): Token
    method getSourceContext (line 127) | public function getSourceContext(): Source

FILE: src/TwigCallableInterface.php
  type TwigCallableInterface (line 17) | interface TwigCallableInterface extends \Stringable
    method getName (line 19) | public function getName(): string;
    method getType (line 21) | public function getType(): string;
    method getDynamicName (line 23) | public function getDynamicName(): string;
    method getCallable (line 28) | public function getCallable();
    method getNodeClass (line 30) | public function getNodeClass(): string;
    method needsCharset (line 32) | public function needsCharset(): bool;
    method needsEnvironment (line 34) | public function needsEnvironment(): bool;
    method needsContext (line 36) | public function needsContext(): bool;
    method withDynamicArguments (line 38) | public function withDynamicArguments(string $name, string $dynamicName...
    method getArguments (line 40) | public function getArguments(): array;
    method isVariadic (line 42) | public function isVariadic(): bool;
    method isDeprecated (line 44) | public function isDeprecated(): bool;
    method getDeprecatingPackage (line 46) | public function getDeprecatingPackage(): string;
    method getDeprecatedVersion (line 48) | public function getDeprecatedVersion(): string;
    method getAlternative (line 50) | public function getAlternative(): ?string;
    method getMinimalNumberOfRequiredArguments (line 52) | public function getMinimalNumberOfRequiredArguments(): int;

FILE: src/TwigFilter.php
  class TwigFilter (line 24) | final class TwigFilter extends AbstractTwigCallable
    method __construct (line 29) | public function __construct(string $name, $callable = null, array $opt...
    method getType (line 42) | public function getType(): string
    method getSafe (line 47) | public function getSafe(Node $filterArgs): ?array
    method getPreservesSafety (line 60) | public function getPreservesSafety(): array
    method getPreEscape (line 65) | public function getPreEscape(): ?string
    method getMinimalNumberOfRequiredArguments (line 70) | public function getMinimalNumberOfRequiredArguments(): int

FILE: src/TwigFunction.php
  class TwigFunction (line 24) | final class TwigFunction extends AbstractTwigCallable
    method __construct (line 29) | public function __construct(string $name, $callable = null, array $opt...
    method getType (line 41) | public function getType(): string
    method getParserCallable (line 46) | public function getParserCallable(): ?callable
    method getSafe (line 51) | public function getSafe(Node $functionArgs): ?array

FILE: src/TwigTest.php
  class TwigTest (line 23) | final class TwigTest extends AbstractTwigCallable
    method __construct (line 28) | public function __construct(string $name, $callable = null, array $opt...
    method getType (line 38) | public function getType(): string
    method needsCharset (line 43) | public function needsCharset(): bool
    method needsEnvironment (line 48) | public function needsEnvironment(): bool
    method needsContext (line 53) | public function needsContext(): bool
    method hasOneMandatoryArgument (line 58) | public function hasOneMandatoryArgument(): bool
    method getMinimalNumberOfRequiredArguments (line 63) | public function getMinimalNumberOfRequiredArguments(): int

FILE: src/Util/CallableArgumentsExtractor.php
  class CallableArgumentsExtractor (line 26) | final class CallableArgumentsExtractor
    method __construct (line 30) | public function __construct(
    method extractArguments (line 40) | public function extractArguments(Node $arguments): array
    method normalizeName (line 174) | private function normalizeName(string $name): string
    method toSnakeCase (line 179) | private function toSnakeCase(string $name): string
    method getCallableParameters (line 184) | private function getCallableParameters(): array

FILE: src/Util/DeprecationCollector.php
  class DeprecationCollector (line 21) | final class DeprecationCollector
    method __construct (line 23) | public function __construct(
    method collectDir (line 36) | public function collectDir(string $dir, string $ext = '.twig'): array
    method collect (line 54) | public function collect(\Traversable $iterator): array

FILE: src/Util/ReflectionCallable.php
  class ReflectionCallable (line 21) | final class ReflectionCallable
    method __construct (line 27) | public function __construct(
    method getReflector (line 78) | public function getReflector(): \ReflectionFunctionAbstract
    method getCallable (line 86) | public function getCallable()
    method getName (line 91) | public function getName(): string

FILE: src/Util/TemplateDirIterator.php
  class TemplateDirIterator (line 17) | class TemplateDirIterator extends \IteratorIterator
    method current (line 22) | #[\ReturnTypeWillChange]
    method key (line 31) | #[\ReturnTypeWillChange]

FILE: tests/Cache/ChainTest.php
  class ChainTest (line 28) | class ChainTest extends TestCase
    method setUp (line 35) | protected function setUp(): void
    method tearDown (line 47) | protected function tearDown(): void
    method testLoadInA (line 54) | public function testLoadInA()
    method testLoadInB (line 72) | public function testLoadInB()
    method testLoadInBoth (line 90) | public function testLoadInBoth()
    method testLoadMissing (line 119) | public function testLoadMissing()
    method testWrite (line 128) | public function testWrite()
    method testGetTimestampInA (line 155) | public function testGetTimestampInA()
    method testGetTimestampInB (line 170) | public function testGetTimestampInB()
    method testGetTimestampInBoth (line 185) | public function testGetTimestampInBoth()
    method testGetTimestampMissingFile (line 210) | public function testGetTimestampMissingFile()
    method testGenerateKey (line 218) | public function testGenerateKey($expected, $input)
    method provideInput (line 224) | public static function provideInput()
    method generateSource (line 232) | private function generateSource()

FILE: tests/Cache/FilesystemTest.php
  class FilesystemTest (line 27) | class FilesystemTest extends TestCase
    method setUp (line 33) | protected function setUp(): void
    method tearDown (line 41) | protected function tearDown(): void
    method testLoad (line 48) | public function testLoad()
    method testLoadMissing (line 65) | public function testLoadMissing()
    method testWrite (line 76) | public function testWrite()
    method testWriteFailMkdir (line 91) | public function testWriteFailMkdir()
    method testWriteFailDirWritable (line 112) | public function testWriteFailDirWritable()
    method testWriteFailWriteFile (line 135) | public function testWriteFailWriteFile()
    method testGetTimestamp (line 152) | public function testGetTimestamp()
    method testGetTimestampMissingFile (line 166) | public function testGetTimestampMissingFile()
    method testGenerateKey (line 177) | public function testGenerateKey($expected, $input)
    method provideDirectories (line 183) | public static function provideDirectories()
    method generateSource (line 197) | private function generateSource()

FILE: tests/Cache/ReadOnlyFilesystemTest.php
  class ReadOnlyFilesystemTest (line 27) | class ReadOnlyFilesystemTest extends TestCase
    method setUp (line 33) | protected function setUp(): void
    method tearDown (line 41) | protected function tearDown(): void
    method testLoad (line 48) | public function testLoad()
    method testLoadMissing (line 65) | public function testLoadMissing()
    method testWrite (line 76) | public function testWrite()
    method testGetTimestamp (line 90) | public function testGetTimestamp()
    method testGetTimestampMissingFile (line 104) | public function testGetTimestampMissingFile()
    method testGenerateKey (line 115) | public function testGenerateKey($expected, $input)
    method provideDirectories (line 121) | public static function provideDirectories()
    method generateSource (line 135) | private function generateSource()

FILE: tests/CompilerTest.php
  class CompilerTest (line 28) | class CompilerTest extends TestCase
    method testReprNumericValueWithLocale (line 30) | public function testReprNumericValueWithLocale()

FILE: tests/ContainerRuntimeLoaderTest.php
  class ContainerRuntimeLoaderTest (line 27) | class ContainerRuntimeLoaderTest extends TestCase
    method testLoad (line 29) | public function testLoad()
    method testLoadUnknownRuntimeReturnsNull (line 40) | public function testLoadUnknownRuntimeReturnsNull()

FILE: tests/CustomExtensionTest.php
  class CustomExtensionTest (line 28) | class CustomExtensionTest extends TestCase
    method testGetInvalidOperators (line 35) | public function testGetInvalidOperators(ExtensionInterface $extension,...
    method provideInvalidExtensions (line 46) | public static function provideInvalidExtensions()
  class InvalidOperatorExtension (line 54) | class InvalidOperatorExtension implements ExtensionInterface
    method __construct (line 58) | public function __construct($operators)
    method getTokenParsers (line 63) | public function getTokenParsers(): array
    method getNodeVisitors (line 68) | public function getNodeVisitors(): array
    method getFilters (line 73) | public function getFilters(): array
    method getTests (line 78) | public function getTests(): array
    method getFunctions (line 83) | public function getFunctions(): array
    method getOperators (line 88) | public function getOperators(): array

FILE: tests/DeprecatedCallableInfoTest.php
  class DeprecatedCallableInfoTest (line 26) | class DeprecatedCallableInfoTest extends TestCase
    method testTriggerDeprecation (line 31) | public function testTriggerDeprecation($expected, DeprecatedCallableIn...
    method provideTestsForTriggerDeprecation (line 54) | public static function provideTestsForTriggerDeprecation(): iterable
    method testTriggerDeprecationWithoutFileOrLine (line 62) | public function testTriggerDeprecationWithoutFileOrLine()

FILE: tests/EnvironmentTest.php
  class EnvironmentTest (line 51) | class EnvironmentTest extends TestCase
    method testVersionConstants (line 55) | public function testVersionConstants()
    method testAutoescapeOption (line 70) | public function testAutoescapeOption()
    method escapingStrategyCallback (line 87) | public function escapingStrategyCallback($name)
    method testGlobals (line 92) | public function testGlobals()
    method testExtensionsAreNotInitializedWhenRenderingACompiledTemplate (line 188) | public function testExtensionsAreNotInitializedWhenRenderingACompiledT...
    method testAutoReloadCacheMiss (line 223) | public function testAutoReloadCacheMiss()
    method testAutoReloadCacheHit (line 250) | public function testAutoReloadCacheHit()
    method testAutoReloadOutdatedCacheHit (line 278) | public function testAutoReloadOutdatedCacheHit()
    method testHasGetExtensionByClassName (line 306) | public function testHasGetExtensionByClassName()
    method testAddExtension (line 314) | public function testAddExtension()
    method testAddMockExtension (line 336) | public function testAddMockExtension()
    method testOverrideExtension (line 348) | public function testOverrideExtension()
    method testAddRuntimeLoader (line 359) | public function testAddRuntimeLoader()
    method testFailLoadTemplate (line 385) | public function testFailLoadTemplate()
    method testUndefinedFunctionCallback (line 396) | public function testUndefinedFunctionCallback()
    method testUndefinedFilterCallback (line 412) | public function testUndefinedFilterCallback()
    method testUndefinedTestCallback (line 428) | public function testUndefinedTestCallback()
    method testUndefinedTokenParserCallback (line 444) | public function testUndefinedTokenParserCallback()
    method testLegacyEchoingNode (line 468) | public function testLegacyEchoingNode()
    method getMockLoader (line 489) | protected function getMockLoader($templateName, $templateContent)
    method testResettingGlobals (line 504) | public function testResettingGlobals()
    method testHotCache (line 531) | public function testHotCache()
  class EnvironmentTest_Extension_WithGlobals (line 579) | class EnvironmentTest_Extension_WithGlobals extends AbstractExtension
    method getGlobals (line 581) | public function getGlobals()
  class EnvironmentTest_Extension (line 589) | class EnvironmentTest_Extension extends AbstractExtension implements Glo...
    method getTokenParsers (line 591) | public function getTokenParsers(): array
    method getNodeVisitors (line 598) | public function getNodeVisitors(): array
    method getFilters (line 605) | public function getFilters(): array
    method getTests (line 612) | public function getTests(): array
    method getFunctions (line 619) | public function getFunctions(): array
    method getExpressionParsers (line 626) | public function getExpressionParsers(): array
    method getGlobals (line 634) | public function getGlobals(): array
  class EnvironmentTest_TokenParser (line 642) | class EnvironmentTest_TokenParser extends AbstractTokenParser
    method parse (line 644) | public function parse(Token $token): Node
    method getTag (line 651) | public function getTag(): string
  class EnvironmentTest_NodeVisitor (line 657) | class EnvironmentTest_NodeVisitor implements NodeVisitorInterface
    method enterNode (line 659) | public function enterNode(Node $node, Environment $env): Node
    method leaveNode (line 664) | public function leaveNode(Node $node, Environment $env): ?Node
    method getPriority (line 669) | public function getPriority(): int
  class EnvironmentTest_ExtensionWithoutRuntime (line 675) | class EnvironmentTest_ExtensionWithoutRuntime extends AbstractExtension
    method getFunctions (line 677) | public function getFunctions(): array
  class EnvironmentTest_Runtime (line 686) | class EnvironmentTest_Runtime
    method fromRuntime (line 688) | public function fromRuntime($name = 'bar')
  class EnvironmentTest_LegacyEchoingNode (line 694) | class EnvironmentTest_LegacyEchoingNode extends Node
    method compile (line 696) | public function compile($compiler)

FILE: tests/ErrorTest.php
  class ErrorTest (line 39) | class ErrorTest extends TestCase
    method testErrorWithObjectFilename (line 41) | public function testErrorWithObjectFilename()
    method testTwigExceptionGuessWithMissingVarAndArrayLoader (line 49) | public function testTwigExceptionGuessWithMissingVarAndArrayLoader()
    method testTwigExceptionGuessWithExceptionAndArrayLoader (line 78) | public function testTwigExceptionGuessWithExceptionAndArrayLoader()
    method testTwigExceptionGuessWithMissingVarAndFilesystemLoader (line 106) | public function testTwigExceptionGuessWithMissingVarAndFilesystemLoader()
    method testTwigExceptionGuessWithExceptionAndFilesystemLoader (line 125) | public function testTwigExceptionGuessWithExceptionAndFilesystemLoader()
    method testTwigExceptionAddsFileAndLine (line 147) | public function testTwigExceptionAddsFileAndLine($templates, $name, $l...
    method testTwigArrayFilterThrowsRuntimeExceptions (line 175) | public function testTwigArrayFilterThrowsRuntimeExceptions()
    method testTwigArrayMapThrowsRuntimeExceptions (line 202) | public function testTwigArrayMapThrowsRuntimeExceptions()
    method testTwigArrayReduceThrowsRuntimeExceptions (line 229) | public function testTwigArrayReduceThrowsRuntimeExceptions()
    method testTwigExceptionUpdateFileAndLineTogether (line 254) | public function testTwigExceptionUpdateFileAndLineTogether()
    method testErrorWithoutLineAndContext (line 275) | public function testErrorWithoutLineAndContext(LoaderInterface $loader...
    method getErrorWithoutLineAndContextData (line 351) | public static function getErrorWithoutLineAndContextData(): iterable
    method getErroredTemplates (line 381) | public static function getErroredTemplates()
    method testErrorFromArrayLoader (line 455) | public function testErrorFromArrayLoader()
    method testErrorFromFilesystemLoader (line 478) | public function testErrorFromFilesystemLoader()
  class ErrorTest_Foo (line 494) | class ErrorTest_Foo
    method bar (line 496) | public function bar()

FILE: tests/ExpressionParserTest.php
  class ExpressionParserTest (line 52) | class ExpressionParserTest extends TestCase
    method testCanOnlyAssignToNames (line 59) | public function testCanOnlyAssignToNames($template)
    method getFailingTestsForAssignment (line 68) | public static function getFailingTestsForAssignment()
    method testSequenceExpression (line 89) | public function testSequenceExpression($template, $expected)
    method testSequenceSyntaxError (line 102) | public function testSequenceSyntaxError($template)
    method getFailingTestsForSequence (line 111) | public static function getFailingTestsForSequence()
    method getTestsForSequence (line 120) | public static function getTestsForSequence()
    method testStringExpressionDoesNotConcatenateTwoConsecutiveStrings (line 228) | public function testStringExpressionDoesNotConcatenateTwoConsecutiveSt...
    method testSequenceCompilationError (line 238) | public function testSequenceCompilationError()
    method testStringExpression (line 250) | public function testStringExpression($template, $expected)
    method getTestsForString (line 260) | public static function getTestsForString()
    method testNullSafeOperator (line 307) | public function testNullSafeOperator($template, $data, $expected)
    method getTestsForNullSafeOperator (line 314) | public static function getTestsForNullSafeOperator()
    method testInvalidNullSafeOperatorShortCircuiting (line 379) | public function testInvalidNullSafeOperatorShortCircuiting(string $tem...
    method getTestForInvalidNullSafeOperatorShortCircuiting (line 389) | public static function getTestForInvalidNullSafeOperatorShortCircuiting()
    method testMacroDefinitionDoesNotSupportNonNameVariableName (line 403) | public function testMacroDefinitionDoesNotSupportNonNameVariableName()
    method testMacroDefinitionDoesNotSupportNonConstantDefaultValues (line 417) | public function testMacroDefinitionDoesNotSupportNonConstantDefaultVal...
    method getMacroDefinitionDoesNotSupportNonConstantDefaultValues (line 428) | public static function getMacroDefinitionDoesNotSupportNonConstantDefa...
    method testMacroDefinitionSupportsConstantDefaultValues (line 439) | public function testMacroDefinitionSupportsConstantDefaultValues($temp...
    method getMacroDefinitionSupportsConstantDefaultValues (line 451) | public static function getMacroDefinitionSupportsConstantDefaultValues()
    method testUnknownFunction (line 464) | public function testUnknownFunction()
    method testUnknownFunctionWithoutSuggestions (line 475) | public function testUnknownFunctionWithoutSuggestions()
    method testUnknownFilter (line 486) | public function testUnknownFilter()
    method testUnknownFilterWithoutSuggestions (line 497) | public function testUnknownFilterWithoutSuggestions()
    method testUnknownTest (line 508) | public function testUnknownTest()
    method testUnknownTestWithoutSuggestions (line 520) | public function testUnknownTestWithoutSuggestions()
    method testCompiledCodeForDynamicTest (line 531) | public function testCompiledCodeForDynamicTest()
    method testCompiledCodeForDynamicFunction (line 546) | public function testCompiledCodeForDynamicFunction()
    method testCompiledCodeForDynamicFilter (line 561) | public function testCompiledCodeForDynamicFilter()
    method testNotReadyFunctionWithNoConstructor (line 576) | public function testNotReadyFunctionWithNoConstructor()
    method testNotReadyFilterWithNoConstructor (line 586) | public function testNotReadyFilterWithNoConstructor()
    method testNotReadyTestWithNoConstructor (line 596) | public function testNotReadyTestWithNoConstructor()
    method testNotReadyFunction (line 609) | public function testNotReadyFunction()
    method testNotReadyFilter (line 624) | public function testNotReadyFilter()
    method testNotReadyTest (line 639) | public function testNotReadyTest()
    method testReadyFunction (line 651) | public function testReadyFunction()
    method testReadyFilter (line 661) | public function testReadyFilter()
    method testReadyTest (line 671) | public function testReadyTest()
    method testTwoWordTestPrecedence (line 681) | public function testTwoWordTestPrecedence()
    method testUnaryPrecedenceChange (line 692) | public function testUnaryPrecedenceChange()
    method testBindingPower (line 719) | public function testBindingPower(string $expression, string $expectedE...
    method getBindingPowerTests (line 730) | public static function getBindingPowerTests(): iterable
    method testLiteralExpressionParserGetOperatorTokensReturnsEmptyArray (line 803) | public function testLiteralExpressionParserGetOperatorTokensReturnsEmp...
    method testExpressionParserGetOperatorTokensDefaultBehavior (line 812) | public function testExpressionParserGetOperatorTokensDefaultBehavior()
    method testLiteralIsNotRegisteredAsOperator (line 825) | public function testLiteralIsNotRegisteredAsOperator()
  class NotReadyFunctionExpression (line 834) | class NotReadyFunctionExpression extends FunctionExpression
    method __construct (line 836) | public function __construct(string $function, Node $arguments, int $li...
  class NotReadyFilterExpression (line 842) | class NotReadyFilterExpression extends FilterExpression
    method __construct (line 844) | public function __construct(Node $node, ConstantExpression $filter, No...
  class NotReadyTestExpression (line 850) | class NotReadyTestExpression extends TestExpression
    method __construct (line 852) | public function __construct(Node $node, string $test, ?Node $arguments...
  class NotReadyFunctionExpressionWithNoConstructor (line 858) | class NotReadyFunctionExpressionWithNoConstructor extends FunctionExpres...
  class NotReadyFilterExpressionWithNoConstructor (line 862) | class NotReadyFilterExpressionWithNoConstructor extends FilterExpression
  class NotReadyTestExpressionWithNoConstructor (line 866) | class NotReadyTestExpressionWithNoConstructor extends TestExpression
  class ReadyFunctionExpression (line 870) | class ReadyFunctionExpression extends FunctionExpression
    method __construct (line 872) | #[FirstClassTwigCallableReady]
  class ReadyFilterExpression (line 879) | class ReadyFilterExpression extends FilterExpression
    method __construct (line 881) | #[FirstClassTwigCallableReady]
  class ReadyTestExpression (line 888) | class ReadyTestExpression extends TestExpression
    method __construct (line 890) | #[FirstClassTwigCallableReady]

FILE: tests/Extension/AttributeExtensionTest.php
  class AttributeExtensionTest (line 26) | class AttributeExtensionTest extends TestCase
    method testFilter (line 31) | public function testFilter(string $name, string $method, array $options)
    method provideFilters (line 45) | public static function provideFilters()
    method testFunction (line 59) | public function testFunction(string $name, string $method, array $opti...
    method provideFunctions (line 73) | public static function provideFunctions()
    method testTest (line 87) | public function testTest(string $name, string $method, array $options)
    method provideTests (line 101) | public static function provideTests()
    method testFilterRequireOneArgument (line 111) | public function testFilterRequireOneArgument()
    method testTestRequireOneArgument (line 121) | public function testTestRequireOneArgument()
    method testLastModifiedWithObject (line 131) | public function testLastModifiedWithObject()
    method testLastModifiedWithClass (line 138) | public function testLastModifiedWithClass()
    method testMultipleRegistrations (line 153) | public function testMultipleRegistrations()

FILE: tests/Extension/CoreTest.php
  class CoreTest (line 33) | class CoreTest extends TestCase
    method testCycleFunction (line 40) | public function testCycleFunction($values, $position, $expected)
    method provideCycleCases (line 45) | public static function provideCycleCases()
    method testCycleFunctionThrowRuntimeError (line 63) | public function testCycleFunctionThrowRuntimeError($values, mixed $pos...
    method provideCycleInvalidCases (line 69) | public static function provideCycleInvalidCases()
    method testRandomFunction (line 81) | public function testRandomFunction(array $expectedInArray, $value1, $v...
    method getRandomFunctionTestData (line 88) | public static function getRandomFunctionTestData()
    method testRandomFunctionWithoutParameter (line 137) | public function testRandomFunctionWithoutParameter()
    method testRandomFunctionReturnsAsIs (line 147) | public function testRandomFunctionReturnsAsIs()
    method testRandomFunctionOfEmptyArrayThrowsException (line 155) | public function testRandomFunctionOfEmptyArrayThrowsException()
    method testRandomFunctionOnNonUTF8String (line 161) | public function testRandomFunctionOnNonUTF8String()
    method testReverseFilterOnNonUTF8String (line 170) | public function testReverseFilterOnNonUTF8String()
    method testTwigFirst (line 181) | public function testTwigFirst($expected, $input)
    method provideTwigFirstCases (line 186) | public static function provideTwigFirstCases()
    method testTwigLast (line 202) | public function testTwigLast($expected, $input)
    method provideTwigLastCases (line 207) | public static function provideTwigLastCases()
    method testArrayKeysFilter (line 223) | public function testArrayKeysFilter(array $expected, $input)
    method provideArrayKeyCases (line 228) | public static function provideArrayKeyCases()
    method testInFilter (line 246) | public function testInFilter($expected, $value, $compare)
    method provideInFilterCases (line 251) | public static function provideInFilterCases()
    method testSliceFilter (line 274) | public function testSliceFilter($expected, $input, $start, $length = n...
    method provideSliceFilterCases (line 279) | public static function provideSliceFilterCases()
    method testCompare (line 303) | public function testCompare($expected, $a, $b)
    method testCompareNAN (line 309) | public function testCompareNAN()
    method provideCompareCases (line 317) | public static function provideCompareCases()
    method testSandboxedInclude (line 375) | public function testSandboxedInclude()
    method testSandboxedIncludeWithPreloadedTemplate (line 390) | public function testSandboxedIncludeWithPreloadedTemplate()
    method testLastModified (line 409) | public function testLastModified()
    method testCycleWithArrayAccessAndTraversableButNotCountable (line 417) | public function testCycleWithArrayAccessAndTraversableButNotCountable()
  class CoreTestIteratorAggregate (line 453) | final class CoreTestIteratorAggregate implements \IteratorAggregate
    method __construct (line 457) | public function __construct(array $array, array $keys, $allowAccess = ...
    method getIterator (line 462) | public function getIterator(): \Traversable
  class CoreTestIteratorAggregateAggregate (line 468) | final class CoreTestIteratorAggregateAggregate implements \IteratorAggre...
    method __construct (line 472) | public function __construct(array $array, array $keys, $allowValueAcce...
    method getIterator (line 477) | public function getIterator(): \Traversable
  class CoreTestIterator (line 483) | final class CoreTestIterator implements \Iterator
    method __construct (line 491) | public function __construct(array $values, array $keys, $allowValueAcc...
    method rewind (line 500) | public function rewind(): void
    method current (line 505) | #[\ReturnTypeWillChange]
    method key (line 515) | #[\ReturnTypeWillChange]
    method next (line 521) | public function next(): void
    method valid (line 529) | public function valid(): bool

FILE: tests/Extension/EscaperTest.php
  class EscaperTest (line 29) | class EscaperTest extends TestCase
    method testCustomEscaper (line 36) | public function testCustomEscaper($expected, $string, $strategy)
    method provideCustomEscaperCases (line 44) | public static function provideCustomEscaperCases()
    method testCustomEscaperWithoutCallingSetEscaperRuntime (line 58) | public function testCustomEscaperWithoutCallingSetEscaperRuntime($expe...
    method testCustomEscapersOnMultipleEnvs (line 69) | public function testCustomEscapersOnMultipleEnvs()
    method testLastModified (line 83) | public function testLastModified()
  function legacy_escaper (line 89) | function legacy_escaper(Environment $twig, $string, $charset)
  function legacy_escaper_again (line 94) | function legacy_escaper_again(Environment $twig, $string, $charset)

FILE: tests/Extension/Fixtures/ExtensionWithAttributes.php
  class ExtensionWithAttributes (line 20) | class ExtensionWithAttributes
    method fooFilter (line 22) | #[AsTwigFilter(name: 'foo', isSafe: ['html'])]
    method withContextFilter (line 27) | #[AsTwigFilter('with_context_filter', needsContext: true)]
    method withEnvFilter (line 32) | #[AsTwigFilter('with_env_filter')]
    method withEnvAndContextFilter (line 37) | #[AsTwigFilter('with_env_and_context_filter', needsContext: true)]
    method variadicFilter (line 42) | #[AsTwigFilter('variadic_filter')]
    method deprecatedFilter (line 47) | #[AsTwigFilter('deprecated_filter', deprecationInfo: new DeprecatedCal...
    method patternFilter (line 52) | #[AsTwigFilter('pattern_*_filter')]
    method fooFunction (line 57) | #[AsTwigFunction(name: 'foo', isSafe: ['html'])]
    method withContextFunction (line 62) | #[AsTwigFunction('with_context_function', needsContext: true)]
    method withEnvFunction (line 67) | #[AsTwigFunction('with_env_function')]
    method withEnvAndContextFunction (line 72) | #[AsTwigFunction('with_env_and_context_function', needsContext: true)]
    method noArgFunction (line 77) | #[AsTwigFunction('no_arg_function')]
    method variadicFunction (line 82) | #[AsTwigFunction('variadic_function')]
    method deprecatedFunction (line 87) | #[AsTwigFunction('deprecated_function', deprecationInfo: new Deprecate...
    method fooTest (line 92) | #[AsTwigTest(name: 'foo')]
    method variadicTest (line 97) | #[AsTwigTest('variadic_test')]
    method withContextTest (line 102) | #[AsTwigTest('with_context_test', needsContext: true)]
    method withEnvTest (line 107) | #[AsTwigTest('with_env_test')]
    method withEnvAndContextTest (line 112) | #[AsTwigTest('with_env_and_context_test', needsContext: true)]
    method deprecatedTest (line 117) | #[AsTwigTest('deprecated_test', deprecationInfo: new DeprecatedCallabl...

FILE: tests/Extension/Fixtures/FilterWithoutValue.php
  class FilterWithoutValue (line 16) | class FilterWithoutValue
    method myFilter (line 18) | #[AsTwigFilter('my_filter')]

FILE: tests/Extension/Fixtures/TestWithoutValue.php
  class TestWithoutValue (line 16) | class TestWithoutValue
    method myTest (line 18) | #[AsTwigTest('my_test')]

FILE: tests/Extension/LegacyDebugFunctionsTest.php
  class LegacyDebugFunctionsTest (line 22) | class LegacyDebugFunctionsTest extends TestCase
    method testDump (line 24) | public function testDump()

FILE: tests/Extension/LegacyStringLoaderFunctionsTest.php
  class LegacyStringLoaderFunctionsTest (line 22) | class LegacyStringLoaderFunctionsTest extends TestCase
    method testTemplateFromString (line 24) | public function testTemplateFromString()

FILE: tests/Extension/SandboxTest.php
  class SandboxTest (line 40) | class SandboxTest extends TestCase
    method setUp (line 47) | protected function setUp(): void
    method testSandboxForCoreTags (line 91) | public function testSandboxForCoreTags(string $tag, string $template)
    method getSandboxedForCoreTagsTests (line 101) | public static function getSandboxedForCoreTagsTests()
    method testSandboxForExtendsAndUseTags (line 129) | public function testSandboxForExtendsAndUseTags(string $tag, string $t...
    method getSandboxedForExtendsAndUseTagsTests (line 137) | public static function getSandboxedForExtendsAndUseTagsTests()
    method testSandboxWithInheritance (line 143) | public function testSandboxWithInheritance()
    method testSandboxGloballySet (line 153) | public function testSandboxGloballySet()
    method testSandboxUnallowedPropertyAccessor (line 159) | public function testSandboxUnallowedPropertyAccessor()
    method testSandboxUnallowedArrayIndexAccessor (line 171) | public function testSandboxUnallowedArrayIndexAccessor()
    method testIfSandBoxIsDisabledAfterSyntaxErrorLegacy (line 190) | public function testIfSandBoxIsDisabledAfterSyntaxErrorLegacy()
    method testIfSandBoxIsDisabledAfterSyntaxError (line 202) | public function testIfSandBoxIsDisabledAfterSyntaxError()
    method testSandboxGloballyFalseUnallowedFilterWithIncludeTemplateFromStringSandboxed (line 214) | public function testSandboxGloballyFalseUnallowedFilterWithIncludeTemp...
    method testSandboxGloballyTrueUnallowedFilterWithIncludeTemplateFromStringSandboxed (line 226) | public function testSandboxGloballyTrueUnallowedFilterWithIncludeTempl...
    method testSandboxGloballyFalseUnallowedFilterWithIncludeTemplateFromStringNotSandboxed (line 238) | public function testSandboxGloballyFalseUnallowedFilterWithIncludeTemp...
    method testSandboxGloballyTrueUnallowedFilterWithIncludeTemplateFromStringNotSandboxed (line 245) | public function testSandboxGloballyTrueUnallowedFilterWithIncludeTempl...
    method testSandboxUnallowedFilter (line 257) | public function testSandboxUnallowedFilter()
    method testSandboxUnallowedTag (line 268) | public function testSandboxUnallowedTag()
    method testSandboxUnallowedProperty (line 279) | public function testSandboxUnallowedProperty()
    method testSandboxUnallowedToString (line 294) | public function testSandboxUnallowedToString($template)
    method getSandboxUnallowedToStringTests (line 306) | public static function getSandboxUnallowedToStringTests()
    method testSandboxAllowedToString (line 339) | public function testSandboxAllowedToString($template, $output)
    method getSandboxAllowedToStringTests (line 345) | public static function getSandboxAllowedToStringTests()
    method testSandboxAllowMethodToString (line 362) | public function testSandboxAllowMethodToString()
    method testSandboxAllowMethodToStringDisabled (line 370) | public function testSandboxAllowMethodToStringDisabled()
    method testSandboxUnallowedFunction (line 378) | public function testSandboxUnallowedFunction()
    method testSandboxUnallowedRangeOperator (line 389) | public function testSandboxUnallowedRangeOperator()
    method testSandboxAllowMethodFoo (line 400) | public function testSandboxAllowMethodFoo()
    method testSandboxAllowFilter (line 408) | public function testSandboxAllowFilter()
    method testSandboxAllowTag (line 414) | public function testSandboxAllowTag()
    method testSandboxAllowProperty (line 420) | public function testSandboxAllowProperty()
    method testSandboxAllowFunction (line 426) | public function testSandboxAllowFunction()
    method testSandboxAllowRangeOperator (line 432) | public function testSandboxAllowRangeOperator()
    method testSandboxAllowMethodsCaseInsensitive (line 438) | public function testSandboxAllowMethodsCaseInsensitive()
    method testSandboxLocallySetForAnInclude (line 450) | public function testSandboxLocallySetForAnInclude()
    method testMacrosInASandbox (line 474) | public function testMacrosInASandbox()
    method testSandboxDisabledAfterIncludeFunctionError (line 488) | public function testSandboxDisabledAfterIncludeFunctionError()
    method testSandboxWithNoClosureFilter (line 504) | public function testSandboxWithNoClosureFilter()
    method testSandboxWithClosureFilter (line 517) | public function testSandboxWithClosureFilter()
    method testMultipleClassMatchesViaInheritanceInAllowedMethods (line 527) | public function testMultipleClassMatchesViaInheritanceInAllowedMethods()
    method getEnvironment (line 565) | protected function getEnvironment($sandboxed, $options, $templates, $t...
    method testSandboxSourcePolicyEnableReturningFalse (line 575) | public function testSandboxSourcePolicyEnableReturningFalse()
    method testSandboxSourcePolicyEnableReturningTrue (line 586) | public function testSandboxSourcePolicyEnableReturningTrue()
    method testSandboxSourcePolicyFalseDoesntOverrideOtherEnables (line 598) | public function testSandboxSourcePolicyFalseDoesntOverrideOtherEnables()
  class ParentClass (line 611) | class ParentClass
    method ParentMethod (line 613) | public function ParentMethod()
  class ChildClass (line 617) | class ChildClass extends ParentClass
    method ChildMethod (line 619) | public function ChildMethod()
  class FooObject (line 624) | class FooObject
    method reset (line 630) | public static function reset()
    method __toString (line 635) | public function __toString()
    method foo (line 642) | public function foo()
    method getFooBar (line 649) | public function getFooBar()
    method getAnotherFooObject (line 656) | public function getAnotherFooObject()
  class ArrayLikeObject (line 662) | class ArrayLikeObject extends \ArrayObject
    method offsetExists (line 664) | public function offsetExists($offset): bool
    method offsetGet (line 669) | public function offsetGet($offset): mixed
    method offsetSet (line 674) | public function offsetSet($offset, $value): void
    method offsetUnset (line 678) | public function offsetUnset($offset): void
  class MagicObject (line 683) | class MagicObject
    method __get (line 685) | public function __get($name): mixed
    method __isset (line 690) | public function __isset($name): bool

FILE: tests/Extension/StringLoaderExtensionTest.php
  class StringLoaderExtensionTest (line 20) | class StringLoaderExtensionTest extends TestCase
    method testIncludeWithTemplateStringAndNoSandbox (line 22) | public function testIncludeWithTemplateStringAndNoSandbox()

FILE: tests/FactoryRuntimeLoaderTest.php
  class FactoryRuntimeLoaderTest (line 26) | class FactoryRuntimeLoaderTest extends TestCase
    method testLoad (line 28) | public function testLoad()
    method testLoadReturnsNullForUnmappedRuntime (line 35) | public function testLoadReturnsNullForUnmappedRuntime()
  function getRuntime (line 43) | function getRuntime()

FILE: tests/FileExtensionEscapingStrategyTest.php
  class FileExtensionEscapingStrategyTest (line 26) | class FileExtensionEscapingStrategyTest extends TestCase
    method testGuess (line 31) | public function testGuess($strategy, $filename)
    method getGuessData (line 36) | public static function getGuessData()

FILE: tests/FilesystemHelper.php
  class FilesystemHelper (line 23) | class FilesystemHelper
    method removeDir (line 25) | public static function removeDir($dir)

FILE: tests/IntegrationTest.php
  function html (line 43) | function html()
  class IntegrationTest (line 48) | class IntegrationTest extends IntegrationTestCase
    method getExtensions (line 50) | public function getExtensions()
    method getUndefinedFunctionCallbacks (line 62) | protected function getUndefinedFunctionCallbacks(): array
    method getUndefinedTestCallbacks (line 75) | protected function getUndefinedTestCallbacks(): array
    method getUndefinedFilterCallbacks (line 96) | protected function getUndefinedFilterCallbacks(): array
    method getFixturesDirectory (line 109) | protected static function getFixturesDirectory(): string
  function test_foo (line 115) | function test_foo($value = 'foo')
  class TwigTestFoo (line 120) | class TwigTestFoo implements \Iterator
    method bar (line 129) | public function bar($param1 = null, $param2 = null)
    method getFoo (line 134) | public function getFoo()
    method getEmpty (line 139) | public function getEmpty()
    method getNull (line 144) | public function getNull()
    method getSelf (line 149) | public function getSelf()
    method is (line 154) | public function is()
    method in (line 159) | public function in()
    method not (line 164) | public function not()
    method strToLower (line 169) | public function strToLower($value)
    method rewind (line 174) | public function rewind(): void
    method current (line 179) | #[\ReturnTypeWillChange]
    method key (line 185) | #[\ReturnTypeWillChange]
    method next (line 191) | public function next(): void
    method valid (line 196) | public function valid(): bool
  class TwigTestTokenParser_§ (line 202) | class TwigTestTokenParser_§ extends AbstractTokenParser
    method parse (line 204) | public function parse(Token $token): Node
    method getTag (line 211) | public function getTag(): string
  class TwigTestExtension (line 217) | class TwigTestExtension extends AbstractExtension
    method getTokenParsers (line 219) | public function getTokenParsers(): array
    method getFilters (line 226) | public function getFilters(): array
    method getFunctions (line 247) | public function getFunctions(): array
    method getTests (line 262) | public function getTests(): array
    method notFilter (line 270) | public function notFilter($value)
    method §Filter (line 275) | public function §Filter($value)
    method §Function (line 280) | public function §Function($value)
    method escape_and_nl2br (line 288) | public function escape_and_nl2br($env, $value, $sep = '<br />')
    method nl2br (line 296) | public function nl2br($value, $sep = '<br />')
    method dynamic_path (line 303) | public function dynamic_path($element, $item)
    method dynamic_foo (line 308) | public function dynamic_foo($foo, $bar, $item)
    method dynamic_test (line 313) | public function dynamic_test($element, $item)
    method escape_something (line 318) | public function escape_something($value)
    method preserves_safety (line 323) | public function preserves_safety($value)
    method staticCall (line 328) | public static function staticCall($value)
    method br (line 333) | public function br()
    method is_multi_word (line 338) | public function is_multi_word($value)
    method __call (line 343) | public function __call($method, $arguments)
    method __callStatic (line 352) | public static function __callStatic($method, $arguments)
  class MagicCallStub (line 366) | class MagicCallStub
    method __call (line 368) | public function __call($name, $args)
  class ToStringStub (line 374) | class ToStringStub
    method __construct (line 381) | public function __construct($string)
    method __toString (line 386) | public function __toString()
  class CountableStub (line 397) | class CountableStub implements \Countable
    method __construct (line 401) | public function __construct($count)
    method count (line 406) | public function count(): int
    method __toString (line 411) | public function __toString()
  class IteratorAggregateStub (line 420) | class IteratorAggregateStub implements \IteratorAggregate
    method __construct (line 424) | public function __construct(array $data)
    method getIterator (line 429) | public function getIterator(): \Traversable
  class SimpleIteratorForTesting (line 435) | class SimpleIteratorForTesting implements \Iterator
    method current (line 440) | #[\ReturnTypeWillChange]
    method next (line 446) | public function next(): void
    method key (line 451) | #[\ReturnTypeWillChange]
    method valid (line 457) | public function valid(): bool
    method rewind (line 462) | public function rewind(): void
    method __toString (line 467) | public function __toString()

FILE: tests/LexerTest.php
  class LexerTest (line 32) | class LexerTest extends TestCase
    method testNameLabelForTag (line 36) | public function testNameLabelForTag()
    method testNameLabelForFunction (line 47) | public function testNameLabelForFunction()
    method testBracketsNesting (line 58) | public function testBracketsNesting()
    method countToken (line 66) | protected function countToken($template, $type, $value = null)
    method testLineDirective (line 84) | public function testLineDirective()
    method testLineDirectiveInline (line 106) | public function testLineDirectiveInline()
    method testLongComments (line 124) | public function testLongComments()
    method testLongVerbatim (line 136) | public function testLongVerbatim()
    method testLongVar (line 148) | public function testLongVar()
    method testLongBlock (line 160) | public function testLongBlock()
    method testBigNumbers (line 172) | public function testBigNumbers()
    method testStringWithEscapedDelimiter (line 186) | public function testStringWithEscapedDelimiter(string $template, strin...
    method getStringWithEscapedDelimiter (line 195) | public static function getStringWithEscapedDelimiter()
    method testStringWithEscapedDelimiterProducingDeprecation (line 262) | public function testStringWithEscapedDelimiterProducingDeprecation(str...
    method getStringWithEscapedDelimiterProducingDeprecation (line 276) | public static function getStringWithEscapedDelimiterProducingDeprecati...
    method testStringWithInterpolation (line 303) | public function testStringWithInterpolation()
    method testStringWithEscapedInterpolation (line 324) | public function testStringWithEscapedInterpolation()
    method testStringWithHash (line 339) | public function testStringWithHash()
    method testStringWithUnterminatedInterpolation (line 354) | public function testStringWithUnterminatedInterpolation()
    method testStringWithNestedInterpolations (line 365) | public function testStringWithNestedInterpolations()
    method testStringWithNestedInterpolationsInBlock (line 386) | public function testStringWithNestedInterpolationsInBlock()
    method testOperatorEndingWithALetterAtTheEndOfALine (line 408) | public function testOperatorEndingWithALetterAtTheEndOfALine()
    method testFilterAndAttributeNamedAfterOperator (line
Condensed preview — 1117 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,038K chars).
[
  {
    "path": ".editorconfig",
    "chars": 224,
    "preview": "; top-most EditorConfig file\nroot = true\n\n; Unix-style newlines\n[*]\nend_of_line = LF\n\n[*.php]\nindent_style = space\ninden"
  },
  {
    "path": ".gitattributes",
    "chars": 302,
    "preview": "/bin/ export-ignore\n/doc/ export-ignore\n/extra/ export-ignore\n/tests/ export-ignore\n/.editorconfig export-ignore\n/.git* "
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 118,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 5174,
    "preview": "name: \"CI\"\n\non:\n    pull_request:\n    push:\n\nenv:\n    SYMFONY_PHPUNIT_DISABLE_RESULT_CACHE: 1\n\npermissions:\n  contents: "
  },
  {
    "path": ".github/workflows/documentation.yml",
    "chars": 1665,
    "preview": "name: \"Documentation\"\n\non:\n    pull_request:\n    push:\n\npermissions:\n  contents: read\n\njobs:\n    build:\n        name: \"B"
  },
  {
    "path": ".github/workflows/fabbot.yml",
    "chars": 195,
    "preview": "name: CS\n\non:\n  pull_request:\n\npermissions:\n  contents: read\n\njobs:\n  call-fabbot:\n    name: Fabbot\n    uses: symfony-to"
  },
  {
    "path": ".gitignore",
    "chars": 96,
    "preview": "/doc/_build/vendor\n/doc/_build/output\n/composer.lock\n/phpunit.xml\n/vendor\n.phpunit.result.cache\n"
  },
  {
    "path": ".php-cs-fixer.dist.php",
    "chars": 936,
    "preview": "<?php\n\nuse PhpCsFixer\\Config;\nuse PhpCsFixer\\Finder;\nuse PhpCsFixer\\Runner\\Parallel\\ParallelConfigFactory;\n\nreturn (new "
  },
  {
    "path": "CHANGELOG",
    "chars": 21579,
    "preview": "# 3.24.1 (2026-XX-XX)\n\n * n/a\n\n# 3.24.0 (2026-03-17)\n\n * Deprecate not implementing the `getOperatorTokens()` method in "
  },
  {
    "path": "LICENSE",
    "chars": 1516,
    "preview": "Copyright (c) 2009-present by the Twig Team.\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, w"
  },
  {
    "path": "README.rst",
    "chars": 741,
    "preview": "Twig, the flexible, fast, and secure template language for PHP\n========================================================="
  },
  {
    "path": "bin/generate_operators_precedence.php",
    "chars": 6446,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "composer.json",
    "chars": 1502,
    "preview": "{\n    \"name\": \"twig/twig\",\n    \"type\": \"library\",\n    \"description\": \"Twig, the flexible, fast, and secure template lang"
  },
  {
    "path": "doc/.doctor-rst.yaml",
    "chars": 1672,
    "preview": "rules:\n    american_english: ~\n    avoid_repetetive_words: ~\n    blank_line_after_directive: ~\n    blank_line_before_dir"
  },
  {
    "path": "doc/_build/build.php",
    "chars": 2407,
    "preview": "#!/usr/bin/env php\n<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and l"
  },
  {
    "path": "doc/_build/composer.json",
    "chars": 405,
    "preview": "{\n    \"minimum-stability\": \"dev\",\n    \"prefer-stable\": true,\n    \"config\": {\n        \"platform\": {\n            \"php\": \"8"
  },
  {
    "path": "doc/advanced.rst",
    "chars": 34215,
    "preview": "Extending Twig\n==============\n\nTwig can be extended in many ways; you can add extra tags, filters, tests,\noperators, glo"
  },
  {
    "path": "doc/api.rst",
    "chars": 19422,
    "preview": "Twig for Developers\n===================\n\nThis chapter describes the API to Twig and not the template language. It will\nb"
  },
  {
    "path": "doc/coding_standards.rst",
    "chars": 3334,
    "preview": "Coding Standards\n================\n\n.. note::\n\n    The `Twig CS fixer tool <https://github.com/VincentLanglet/Twig-CS-Fix"
  },
  {
    "path": "doc/deprecated.rst",
    "chars": 18144,
    "preview": "Deprecated Features\n===================\n\nThis document lists deprecated features in Twig 3.x. Deprecated features are\nke"
  },
  {
    "path": "doc/filters/abs.rst",
    "chars": 251,
    "preview": "``abs``\n=======\n\nThe ``abs`` filter returns the absolute value.\n\n.. code-block:: twig\n\n    {# number = -5 #}\n\n    {{ num"
  },
  {
    "path": "doc/filters/batch.rst",
    "chars": 1834,
    "preview": "``batch``\n=========\n\nThe ``batch`` filter \"batches\" items by returning a list of lists with the\ngiven number of items. A"
  },
  {
    "path": "doc/filters/capitalize.rst",
    "chars": 232,
    "preview": "``capitalize``\n==============\n\nThe ``capitalize`` filter capitalizes a value. The first character will be\nuppercase, all"
  },
  {
    "path": "doc/filters/column.rst",
    "chars": 480,
    "preview": "``column``\n==========\n\nThe ``column`` filter returns the values from a single column in the input\narray.\n\n.. code-block:"
  },
  {
    "path": "doc/filters/convert_encoding.rst",
    "chars": 478,
    "preview": "``convert_encoding``\n====================\n\nThe ``convert_encoding`` filter converts a string from one encoding to\nanothe"
  },
  {
    "path": "doc/filters/country_name.rst",
    "chars": 1078,
    "preview": "``country_name``\n================\n\nThe ``country_name`` filter returns the country name given its ISO-3166 code:\n\n.. cod"
  },
  {
    "path": "doc/filters/currency_name.rst",
    "chars": 1088,
    "preview": "``currency_name``\n=================\n\nThe ``currency_name`` filter returns the currency name given its ISO 4217 code:\n\n.."
  },
  {
    "path": "doc/filters/currency_symbol.rst",
    "chars": 1076,
    "preview": "``currency_symbol``\n===================\n\nThe ``currency_symbol`` filter returns the currency symbol given its ISO 4217\nc"
  },
  {
    "path": "doc/filters/data_uri.rst",
    "chars": 1415,
    "preview": "``data_uri``\n============\n\nThe ``data_uri`` filter generates a URL using the data scheme as defined in\n`RFC 2397`_:\n\n.. "
  },
  {
    "path": "doc/filters/date.rst",
    "chars": 2741,
    "preview": "``date``\n========\n\nThe ``date`` filter formats a date to a given format:\n\n.. code-block:: twig\n\n    {{ post.published_at"
  },
  {
    "path": "doc/filters/date_modify.rst",
    "chars": 541,
    "preview": "``date_modify``\n===============\n\nThe ``date_modify`` filter modifies a date with a given modifier string:\n\n.. code-block"
  },
  {
    "path": "doc/filters/default.rst",
    "chars": 1171,
    "preview": "``default``\n===========\n\nThe ``default`` filter returns the passed default value if the value is\nundefined or empty, oth"
  },
  {
    "path": "doc/filters/escape.rst",
    "chars": 5616,
    "preview": "``escape``\n==========\n\nThe ``escape`` filter escapes a string using strategies that depend on the\ncontext.\n\nBy default, "
  },
  {
    "path": "doc/filters/filter.rst",
    "chars": 1192,
    "preview": "``filter``\n==========\n\nThe ``filter`` filter filters elements of a sequence or a mapping using an arrow\nfunction. The ar"
  },
  {
    "path": "doc/filters/find.rst",
    "chars": 1018,
    "preview": "``find``\n========\n\n.. versionadded:: 3.11\n\n    The ``find`` filter was added in Twig 3.11.\n\nThe ``find`` filter returns "
  },
  {
    "path": "doc/filters/first.rst",
    "chars": 445,
    "preview": "``first``\n=========\n\nThe ``first`` filter returns the first \"element\" of a sequence, a mapping, or\na string:\n\n.. code-bl"
  },
  {
    "path": "doc/filters/format.rst",
    "chars": 387,
    "preview": "``format``\n==========\n\nThe ``format`` filter formats a given string by replacing the placeholders\n(placeholders follows "
  },
  {
    "path": "doc/filters/format_currency.rst",
    "chars": 4431,
    "preview": "``format_currency``\n===================\n\nThe ``format_currency`` filter formats a number as a currency:\n\n.. code-block::"
  },
  {
    "path": "doc/filters/format_date.rst",
    "chars": 1028,
    "preview": "``format_date``\n===============\n\nThe ``format_date`` filter formats a date. It behaves in the exact same way as\nthe :doc"
  },
  {
    "path": "doc/filters/format_datetime.rst",
    "chars": 3735,
    "preview": "``format_datetime``\n===================\n\nThe ``format_datetime`` filter formats a date time:\n\n.. code-block:: twig\n\n    "
  },
  {
    "path": "doc/filters/format_number.rst",
    "chars": 5638,
    "preview": "``format_number``\n=================\n\nThe ``format_number`` filter formats a number:\n\n.. code-block:: twig\n\n    {{ '12.34"
  },
  {
    "path": "doc/filters/format_time.rst",
    "chars": 1028,
    "preview": "``format_time``\n===============\n\nThe ``format_time`` filter formats a time. It behaves in the exact same way as\nthe :doc"
  },
  {
    "path": "doc/filters/html_attr_merge.rst",
    "chars": 4553,
    "preview": "``html_attr_merge``\n===================\n\n.. _html_attr_merge:\n\n.. versionadded:: 3.24\n\n    The ``html_attr_merge`` filte"
  },
  {
    "path": "doc/filters/html_attr_type.rst",
    "chars": 3422,
    "preview": "``html_attr_type``\n==================\n\n.. _html_attr_type:\n\n.. versionadded:: 3.24\n\n    The ``html_attr_type`` filter wa"
  },
  {
    "path": "doc/filters/html_to_markdown.rst",
    "chars": 2280,
    "preview": "``html_to_markdown``\n====================\n\nThe ``html_to_markdown`` filter converts a block of HTML to Markdown:\n\n.. cod"
  },
  {
    "path": "doc/filters/index.rst",
    "chars": 851,
    "preview": "Filters\n=======\n\n.. toctree::\n    :maxdepth: 1\n\n    abs\n    batch\n    capitalize\n    column\n    convert_encoding\n    cou"
  },
  {
    "path": "doc/filters/inky_to_html.rst",
    "chars": 1010,
    "preview": "``inky_to_html``\n================\n\nThe ``inky_to_html`` filter processes an `inky email template\n<https://github.com/fou"
  },
  {
    "path": "doc/filters/inline_css.rst",
    "chars": 1680,
    "preview": "``inline_css``\n==============\n\nThe ``inline_css`` filter inlines CSS styles in HTML documents:\n\n.. code-block:: html+twi"
  },
  {
    "path": "doc/filters/invoke.rst",
    "chars": 363,
    "preview": "``invoke``\n==========\n\n.. versionadded:: 3.19\n\n    The ``invoke`` filter has been added in Twig 3.19.\n\nThe ``invoke`` fi"
  },
  {
    "path": "doc/filters/join.rst",
    "chars": 694,
    "preview": "``join``\n========\n\nThe ``join`` filter returns a string which is the concatenation of the items\nof a sequence:\n\n.. code-"
  },
  {
    "path": "doc/filters/json_encode.rst",
    "chars": 649,
    "preview": "``json_encode``\n===============\n\nThe ``json_encode`` filter returns the JSON representation of a value:\n\n.. code-block::"
  },
  {
    "path": "doc/filters/keys.rst",
    "chars": 530,
    "preview": "``keys``\n========\n\nThe ``keys`` filter returns the keys of a sequence or a mapping. It is useful\nwhen you want to iterat"
  },
  {
    "path": "doc/filters/language_name.rst",
    "chars": 1151,
    "preview": "``language_name``\n=================\n\nThe ``language_name`` filter returns the language name based on its ISO 639-1\ncode,"
  },
  {
    "path": "doc/filters/last.rst",
    "chars": 438,
    "preview": "``last``\n========\n\nThe ``last`` filter returns the last \"element\" of a sequence, a mapping, or\na string:\n\n.. code-block:"
  },
  {
    "path": "doc/filters/length.rst",
    "chars": 719,
    "preview": "``length``\n==========\n\nThe ``length`` filter returns the number of items of a sequence or mapping, or\nthe length of a st"
  },
  {
    "path": "doc/filters/locale_name.rst",
    "chars": 1072,
    "preview": "``locale_name``\n===============\n\nThe ``locale_name`` filter returns the locale name given its code:\n\n.. code-block:: twi"
  },
  {
    "path": "doc/filters/lower.rst",
    "chars": 303,
    "preview": "``lower``\n=========\n\nThe ``lower`` filter converts a value to lowercase:\n\n.. code-block:: twig\n\n    {{ 'WELCOME'|lower }"
  },
  {
    "path": "doc/filters/map.rst",
    "chars": 809,
    "preview": "``map``\n=======\n\nThe ``map`` filter applies an arrow function to the elements of a sequence or a\nmapping. The arrow func"
  },
  {
    "path": "doc/filters/markdown_to_html.rst",
    "chars": 2212,
    "preview": "``markdown_to_html``\n====================\n\nThe ``markdown_to_html`` filter converts a block of Markdown to HTML:\n\n.. cod"
  },
  {
    "path": "doc/filters/merge.rst",
    "chars": 1317,
    "preview": "``merge``\n=========\n\nThe ``merge`` filter merges sequences and mappings:\n\nFor sequences, new values are added at the end"
  },
  {
    "path": "doc/filters/nl2br.rst",
    "chars": 362,
    "preview": "``nl2br``\n=========\n\nThe ``nl2br`` filter inserts HTML line breaks before all newlines in a string:\n\n.. code-block:: htm"
  },
  {
    "path": "doc/filters/number_format.rst",
    "chars": 1797,
    "preview": "``number_format``\n=================\n\nThe ``number_format`` filter formats numbers.  It is a wrapper around PHP's\n`number"
  },
  {
    "path": "doc/filters/plural.rst",
    "chars": 1416,
    "preview": "``plural``\n==========\n\n.. versionadded:: 3.11\n\n    The ``plural`` filter was added in Twig 3.11.\n\nThe ``plural`` filter "
  },
  {
    "path": "doc/filters/raw.rst",
    "chars": 332,
    "preview": "``raw``\n=======\n\nThe ``raw`` filter marks the value as being \"safe\", which means that in an\nenvironment with automatic e"
  },
  {
    "path": "doc/filters/reduce.rst",
    "chars": 785,
    "preview": "``reduce``\n==========\n\nThe ``reduce`` filter iteratively reduces a sequence or a mapping to a single\nvalue using an arro"
  },
  {
    "path": "doc/filters/replace.rst",
    "chars": 678,
    "preview": "``replace``\n===========\n\nThe ``replace`` filter replaces placeholders in a string (the placeholder\nformat is free-form):"
  },
  {
    "path": "doc/filters/reverse.rst",
    "chars": 992,
    "preview": "``reverse``\n===========\n\nThe ``reverse`` filter reverses a sequence, a mapping, or a string:\n\n.. code-block:: twig\n\n    "
  },
  {
    "path": "doc/filters/round.rst",
    "chars": 783,
    "preview": "``round``\n=========\n\nThe ``round`` filter rounds a number to a given precision:\n\n.. code-block:: twig\n\n    {{ 42.55|roun"
  },
  {
    "path": "doc/filters/shuffle.rst",
    "chars": 1647,
    "preview": "``shuffle``\n===========\n\n.. versionadded:: 3.11\n\n    The ``shuffle`` filter was added in Twig 3.11.\n\nThe ``shuffle`` fil"
  },
  {
    "path": "doc/filters/singular.rst",
    "chars": 1448,
    "preview": "``singular``\n============\n\n.. versionadded:: 3.11\n\n    The ``singular`` filter was added in Twig 3.11.\n\nThe ``singular``"
  },
  {
    "path": "doc/filters/slice.rst",
    "chars": 2726,
    "preview": "``slice``\n===========\n\nThe ``slice`` filter extracts a slice of a sequence, a mapping, or a string:\n\n.. code-block:: twi"
  },
  {
    "path": "doc/filters/slug.rst",
    "chars": 1588,
    "preview": "``slug``\n========\n\nThe ``slug`` filter transforms a given string into another string that\nonly includes safe ASCII chara"
  },
  {
    "path": "doc/filters/sort.rst",
    "chars": 986,
    "preview": "``sort``\n========\n\nThe ``sort`` filter sorts sequences and mappings:\n\n.. code-block:: twig\n\n    {% for user in users|sor"
  },
  {
    "path": "doc/filters/spaceless.rst",
    "chars": 1869,
    "preview": "``spaceless``\n=============\n\n.. warning::\n\n    The ``spaceless`` filter is deprecated as of Twig 3.12. While not a full\n"
  },
  {
    "path": "doc/filters/split.rst",
    "chars": 1358,
    "preview": "``split``\n=========\n\nThe ``split`` filter splits a string by the given delimiter and returns a list\nof strings:\n\n.. code"
  },
  {
    "path": "doc/filters/striptags.rst",
    "chars": 614,
    "preview": "``striptags``\n=============\n\nThe ``striptags`` filter strips SGML/XML tags and replaces adjacent whitespace characters\nb"
  },
  {
    "path": "doc/filters/timezone_name.rst",
    "chars": 1215,
    "preview": "``timezone_name``\n=================\n\nThe ``timezone_name`` filter returns the timezone name given its ISO 8601 timezone "
  },
  {
    "path": "doc/filters/title.rst",
    "chars": 254,
    "preview": "``title``\n=========\n\nThe ``title`` filter returns a titlecased version of the value. Words will\nstart with uppercase let"
  },
  {
    "path": "doc/filters/trim.rst",
    "chars": 896,
    "preview": "``trim``\n========\n\nThe ``trim`` filter strips whitespace (or other characters) from the beginning\nand end of a string:\n\n"
  },
  {
    "path": "doc/filters/u.rst",
    "chars": 1864,
    "preview": "``u``\n=====\n\nThe ``u`` filter wraps a text in a Unicode object (a `Symfony UnicodeString\ninstance <https://symfony.com/d"
  },
  {
    "path": "doc/filters/upper.rst",
    "chars": 280,
    "preview": "``upper``\n=========\n\nThe ``upper`` filter converts a value to uppercase:\n\n.. code-block:: twig\n\n    {{ 'welcome'|upper }"
  },
  {
    "path": "doc/filters/url_encode.rst",
    "chars": 630,
    "preview": "``url_encode``\n==============\n\nThe ``url_encode`` filter percent encodes a given string as URL segment or a\nmapping as q"
  },
  {
    "path": "doc/functions/attribute.rst",
    "chars": 1491,
    "preview": "``attribute``\n=============\n\n.. warning::\n\n    The ``attribute`` function is deprecated as of Twig 3.15. Use the\n    :re"
  },
  {
    "path": "doc/functions/block.rst",
    "chars": 915,
    "preview": "``block``\n=========\n\nWhen a template uses inheritance and if you want to render a block multiple\ntimes, use the ``block`"
  },
  {
    "path": "doc/functions/constant.rst",
    "chars": 596,
    "preview": "``constant``\n============\n\n``constant`` returns the constant value for a given string:\n\n.. code-block:: twig\n\n    {{ som"
  },
  {
    "path": "doc/functions/country_names.rst",
    "chars": 1167,
    "preview": "``country_names``\n=================\n\n.. versionadded:: 3.5\n\n    The ``country_names`` function was added in Twig 3.5.\n\nT"
  },
  {
    "path": "doc/functions/country_timezones.rst",
    "chars": 937,
    "preview": "``country_timezones``\n=====================\n\nThe ``country_timezones`` function returns the names of the timezones assoc"
  },
  {
    "path": "doc/functions/currency_names.rst",
    "chars": 1199,
    "preview": "``currency_names``\n==================\n\n.. versionadded:: 3.5\n\n    The ``currency_names`` function was added in Twig 3.5."
  },
  {
    "path": "doc/functions/cycle.rst",
    "chars": 1043,
    "preview": "``cycle``\n=========\n\nThe ``cycle`` function cycles on a sequence:\n\n.. code-block:: twig\n\n    {% set start_year = date() "
  },
  {
    "path": "doc/functions/date.rst",
    "chars": 1067,
    "preview": "``date``\n========\n\nConverts an argument to a date to allow date comparison:\n\n.. code-block:: html+twig\n\n    {% if date(u"
  },
  {
    "path": "doc/functions/dump.rst",
    "chars": 1595,
    "preview": "``dump``\n========\n\nThe ``dump`` function dumps information about a template variable. This is\nmostly useful to debug a t"
  },
  {
    "path": "doc/functions/enum.rst",
    "chars": 1083,
    "preview": "``enum``\n========\n\n.. versionadded:: 3.15\n\n    The ``enum`` function was added in Twig 3.15.\n\n``enum`` gives access to e"
  },
  {
    "path": "doc/functions/enum_cases.rst",
    "chars": 514,
    "preview": "``enum_cases``\n==============\n\n.. versionadded:: 3.12\n\n    The ``enum_cases`` function was added in Twig 3.12.\n\n``enum_c"
  },
  {
    "path": "doc/functions/html_attr.rst",
    "chars": 6417,
    "preview": "``html_attr``\n=============\n\n.. _html_attr:\n\n.. versionadded:: 3.23\n\n    The ``html_attr`` function was added in Twig 3."
  },
  {
    "path": "doc/functions/html_classes.rst",
    "chars": 913,
    "preview": "``html_classes``\n================\n\nThe ``html_classes`` function returns a string by conditionally joining class\nnames t"
  },
  {
    "path": "doc/functions/html_cva.rst",
    "chars": 5292,
    "preview": "``html_cva``\n============\n\n.. versionadded:: 3.12\n\n    The ``html_cva`` function was added in Twig 3.12.\n\n`CVA (Class Va"
  },
  {
    "path": "doc/functions/include.rst",
    "chars": 2366,
    "preview": "``include``\n===========\n\nThe ``include`` function returns the rendered content of a template:\n\n.. code-block:: twig\n\n   "
  },
  {
    "path": "doc/functions/index.rst",
    "chars": 412,
    "preview": "Functions\n=========\n\n.. toctree::\n    :maxdepth: 1\n\n    attribute\n    block\n    constant\n    cycle\n    date\n    dump\n   "
  },
  {
    "path": "doc/functions/language_names.rst",
    "chars": 1153,
    "preview": "``language_names``\n==================\n\n.. versionadded:: 3.5\n\n    The ``language_names`` function was added in Twig 3.5."
  },
  {
    "path": "doc/functions/locale_names.rst",
    "chars": 1172,
    "preview": "``locale_names``\n================\n\n.. versionadded:: 3.5\n\n    The ``locale_names`` function was added in Twig 3.5.\n\nThe "
  },
  {
    "path": "doc/functions/max.rst",
    "chars": 330,
    "preview": "``max``\n=======\n\n``max`` returns the biggest value of a sequence or a set of values:\n\n.. code-block:: twig\n\n    {{ max(1"
  },
  {
    "path": "doc/functions/min.rst",
    "chars": 329,
    "preview": "``min``\n=======\n\n``min`` returns the lowest value of a sequence or a set of values:\n\n.. code-block:: twig\n\n    {{ min(1,"
  },
  {
    "path": "doc/functions/parent.rst",
    "chars": 582,
    "preview": "``parent``\n==========\n\nWhen a template uses inheritance, it's possible to render the contents of the\nparent block when o"
  },
  {
    "path": "doc/functions/random.rst",
    "chars": 1145,
    "preview": "``random``\n==========\n\nThe ``random`` function returns a random value depending on the supplied\nparameter type:\n\n* a ran"
  },
  {
    "path": "doc/functions/range.rst",
    "chars": 1222,
    "preview": "``range``\n=========\n\nReturns a list containing an arithmetic progression of integers:\n\n.. code-block:: twig\n\n    {% for "
  },
  {
    "path": "doc/functions/script_names.rst",
    "chars": 1129,
    "preview": "``script_names``\n================\n\n.. versionadded:: 3.5\n\n    The ``script_names`` function was added in Twig 3.5.\n\nThe "
  },
  {
    "path": "doc/functions/source.rst",
    "chars": 702,
    "preview": "``source``\n==========\n\nThe ``source`` function returns the content of a template without rendering it:\n\n.. code-block:: "
  },
  {
    "path": "doc/functions/template_from_string.rst",
    "chars": 1397,
    "preview": "``template_from_string``\n========================\n\nThe ``template_from_string`` function loads a template from a string:"
  },
  {
    "path": "doc/functions/timezone_names.rst",
    "chars": 1219,
    "preview": "``timezone_names``\n==================\n\n.. versionadded:: 3.5\n\n    The ``timezone_names`` function was added in Twig 3.5."
  },
  {
    "path": "doc/index.rst",
    "chars": 272,
    "preview": "Twig\n====\n\n.. toctree::\n    :maxdepth: 2\n\n    intro\n    installation\n    templates\n    api\n    advanced\n    sandbox\n    "
  },
  {
    "path": "doc/installation.rst",
    "chars": 216,
    "preview": "Installation\n============\n\nInstall `Composer`_ and run the following command to get the latest version:\n\n.. code-block::"
  },
  {
    "path": "doc/internals.rst",
    "chars": 4902,
    "preview": "Twig Internals\n==============\n\nTwig is very extensible and you can hack it. Keep in mind that you\nshould probably try to"
  },
  {
    "path": "doc/intro.rst",
    "chars": 2368,
    "preview": "Introduction\n============\n\nWelcome to the documentation for Twig, the flexible, fast, and secure template\nengine for PHP"
  },
  {
    "path": "doc/operators_precedence.rst",
    "chars": 25502,
    "preview": "\n+------------+------------------+---------+---------------+------------------------------------------------------------"
  },
  {
    "path": "doc/recipes.rst",
    "chars": 18576,
    "preview": "Recipes\n=======\n\n.. _deprecation-notices:\n\nDisplaying Deprecation Notices\n------------------------------\n\nDeprecated fea"
  },
  {
    "path": "doc/sandbox.rst",
    "chars": 3762,
    "preview": "Twig Sandbox\n============\n\nThe ``sandbox`` extension can be used to evaluate untrusted code.\n\nRegistering the Sandbox\n--"
  },
  {
    "path": "doc/tags/apply.rst",
    "chars": 436,
    "preview": "``apply``\n=========\n\nThe ``apply`` tag allows you to apply Twig filters on a block of template data:\n\n.. code-block:: tw"
  },
  {
    "path": "doc/tags/autoescape.rst",
    "chars": 1783,
    "preview": "``autoescape``\n==============\n\nWhether automatic escaping is enabled or not, you can mark a section of a\ntemplate to be "
  },
  {
    "path": "doc/tags/block.rst",
    "chars": 492,
    "preview": "``block``\n=========\n\nBlocks are used for inheritance and act as placeholders and replacements at\nthe same time. They are"
  },
  {
    "path": "doc/tags/cache.rst",
    "chars": 3474,
    "preview": "``cache``\n=========\n\n.. versionadded:: 3.2\n\n    The ``cache`` tag was added in Twig 3.2.\n\nThe ``cache`` tag tells Twig t"
  },
  {
    "path": "doc/tags/deprecated.rst",
    "chars": 1323,
    "preview": "``deprecated``\n==============\n\nTwig generates a deprecation notice (via a call to the ``trigger_error()``\nPHP function) "
  },
  {
    "path": "doc/tags/do.rst",
    "chars": 176,
    "preview": "``do``\n======\n\nThe ``do`` tag works exactly like the regular variable expression (``{{ ...\n}}``) just that it doesn't pr"
  },
  {
    "path": "doc/tags/embed.rst",
    "chars": 6130,
    "preview": "``embed``\n=========\n\nThe ``embed`` tag combines the behavior of :doc:`include<include>` and\n:doc:`extends<extends>`.\nIt "
  },
  {
    "path": "doc/tags/extends.rst",
    "chars": 7447,
    "preview": "``extends``\n===========\n\nThe ``extends`` tag can be used to extend a template from another one.\n\n.. note::\n\n    Like PHP"
  },
  {
    "path": "doc/tags/flush.rst",
    "chars": 222,
    "preview": "``flush``\n=========\n\nThe ``flush`` tag tells Twig to flush the output buffer:\n\n.. code-block:: twig\n\n    {% flush %}\n\n.."
  },
  {
    "path": "doc/tags/for.rst",
    "chars": 3919,
    "preview": "``for``\n=======\n\nLoop over each item in a sequence or a mapping. For example, to display a list\nof users provided in a v"
  },
  {
    "path": "doc/tags/from.rst",
    "chars": 200,
    "preview": "``from``\n========\n\nThe ``from`` tag imports :doc:`macro<../tags/macro>` names into the current\nnamespace. The tag is doc"
  },
  {
    "path": "doc/tags/guard.rst",
    "chars": 767,
    "preview": "``guard``\n=========\n\n.. versionadded:: 3.15\n\n    The ``guard`` tag was added in Twig 3.15.\n\nThe ``guard`` statement chec"
  },
  {
    "path": "doc/tags/if.rst",
    "chars": 2138,
    "preview": "``if``\n======\n\nThe ``if`` statement in Twig is comparable with the if statements of PHP.\n\nIn the simplest form you can u"
  },
  {
    "path": "doc/tags/import.rst",
    "chars": 199,
    "preview": "``import``\n==========\n\nThe ``import`` tag imports :doc:`macro<../tags/macro>` names in a local\nvariable. The tag is docu"
  },
  {
    "path": "doc/tags/include.rst",
    "chars": 3554,
    "preview": "``include``\n===========\n\nThe ``include`` statement includes a template and outputs the rendered content\nof that file:\n\n."
  },
  {
    "path": "doc/tags/index.rst",
    "chars": 268,
    "preview": "Tags\n====\n\n.. toctree::\n    :maxdepth: 1\n\n    apply\n    autoescape\n    block\n    cache\n    deprecated\n    do\n    embed\n "
  },
  {
    "path": "doc/tags/macro.rst",
    "chars": 4679,
    "preview": "``macro``\n=========\n\nMacros are comparable with functions in regular programming languages. They\nare useful to reuse tem"
  },
  {
    "path": "doc/tags/sandbox.rst",
    "chars": 907,
    "preview": "``sandbox``\n===========\n\n.. warning::\n\n    The ``sandbox`` tag is deprecated as of Twig 3.15.\n    Use the ``sandboxed`` "
  },
  {
    "path": "doc/tags/set.rst",
    "chars": 2017,
    "preview": "``set``\n=======\n\nInside code blocks you can also assign values to variables. Assignments use\nthe ``set`` tag and can hav"
  },
  {
    "path": "doc/tags/types.rst",
    "chars": 1562,
    "preview": "``types``\n=========\n\n.. versionadded:: 3.13\n\n    The ``types`` tag was added in Twig 3.13. This tag is **experimental** "
  },
  {
    "path": "doc/tags/use.rst",
    "chars": 3319,
    "preview": "``use``\n=======\n\n.. note::\n\n    Horizontal reuse is an advanced Twig feature that is hardly ever needed in\n    regular t"
  },
  {
    "path": "doc/tags/verbatim.rst",
    "chars": 371,
    "preview": "``verbatim``\n============\n\nThe ``verbatim`` tag marks sections as being raw text that should not be\nparsed. For example "
  },
  {
    "path": "doc/tags/with.rst",
    "chars": 1104,
    "preview": "``with``\n========\n\nUse the ``with`` tag to create a new inner scope. Variables set within this\nscope are not visible out"
  },
  {
    "path": "doc/templates.rst",
    "chars": 38584,
    "preview": "Twig for Template Designers\n===========================\n\nThis document describes the syntax and semantics of the templat"
  },
  {
    "path": "doc/tests/constant.rst",
    "chars": 538,
    "preview": "``constant``\n============\n\n``constant`` checks if a variable has the exact same value as a constant. You\ncan use either "
  },
  {
    "path": "doc/tests/defined.rst",
    "chars": 696,
    "preview": "``defined``\n===========\n\n``defined`` checks if a variable is defined in the current context. This is very\nuseful if you "
  },
  {
    "path": "doc/tests/divisibleby.rst",
    "chars": 193,
    "preview": "``divisible by``\n================\n\n``divisible by`` checks if a variable is divisible by a number:\n\n.. code-block:: twig"
  },
  {
    "path": "doc/tests/empty.rst",
    "chars": 483,
    "preview": "``empty``\n=========\n\n``empty`` checks if a variable is an empty string, an empty sequence, an empty\nmapping, exactly ``f"
  },
  {
    "path": "doc/tests/even.rst",
    "chars": 163,
    "preview": "``even``\n========\n\n``even`` returns ``true`` if the given number is even:\n\n.. code-block:: twig\n\n    {{ var is even }}\n\n"
  },
  {
    "path": "doc/tests/index.rst",
    "chars": 170,
    "preview": "Tests\n=====\n\n.. toctree::\n    :maxdepth: 1\n\n    constant\n    defined\n    divisibleby\n    empty\n    even\n    iterable\n   "
  },
  {
    "path": "doc/tests/iterable.rst",
    "chars": 396,
    "preview": "``iterable``\n============\n\n``iterable`` checks if a variable is an array or a traversable object:\n\n.. code-block:: twig\n"
  },
  {
    "path": "doc/tests/mapping.rst",
    "chars": 361,
    "preview": "``mapping``\n===========\n\n``mapping`` checks if a variable is a mapping:\n\n.. code-block:: twig\n\n    {% set users = {alice"
  },
  {
    "path": "doc/tests/null.rst",
    "chars": 170,
    "preview": "``null``\n========\n\n``null`` returns ``true`` if the variable is ``null``:\n\n.. code-block:: twig\n\n    {{ var is null }}\n\n"
  },
  {
    "path": "doc/tests/odd.rst",
    "chars": 160,
    "preview": "``odd``\n=======\n\n``odd`` returns ``true`` if the given number is odd:\n\n.. code-block:: twig\n\n    {{ var is odd }}\n\n.. se"
  },
  {
    "path": "doc/tests/sameas.rst",
    "chars": 261,
    "preview": "``same as``\n===========\n\n``same as`` checks if a variable is the same as another variable.\nThis is equivalent to ``===``"
  },
  {
    "path": "doc/tests/sequence.rst",
    "chars": 332,
    "preview": "``sequence``\n============\n\n``sequence`` checks if a variable is a sequence:\n\n.. code-block:: twig\n\n    {% set users = [\""
  },
  {
    "path": "extra/cache-extra/.gitattributes",
    "chars": 74,
    "preview": "/Tests export-ignore\n/.git* export-ignore\n/phpunit.xml.dist export-ignore\n"
  },
  {
    "path": "extra/cache-extra/.gitignore",
    "chars": 56,
    "preview": "vendor/\ncomposer.lock\nphpunit.xml\n.phpunit.result.cache\n"
  },
  {
    "path": "extra/cache-extra/CacheExtension.php",
    "chars": 499,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/cache-extra/CacheRuntime.php",
    "chars": 507,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/cache-extra/LICENSE",
    "chars": 1068,
    "preview": "Copyright (c) 2021-present Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
  },
  {
    "path": "extra/cache-extra/Node/CacheNode.php",
    "chars": 1909,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/cache-extra/README.md",
    "chars": 243,
    "preview": "Cache Extension\n===============\n\nThis package is a Twig extension that provides integration with the Symfony\nCache compo"
  },
  {
    "path": "extra/cache-extra/Tests/Fixtures/cache.test",
    "chars": 423,
    "preview": "--TEST--\n\"cache\" tag\n--TEMPLATE--\n{% set foo = \"bar\" %}\n{% set value1 %}\n    {% cache \"test;v1\" ttl(3) %}\n        {% set"
  },
  {
    "path": "extra/cache-extra/Tests/Fixtures/cache_complex.test",
    "chars": 243,
    "preview": "--TEST--\n\"cache\" tag\n--TEMPLATE--\n{% cache 'test_%s_%s'|format(10, 10000) ttl(36000) %}\n   {% set content %}\n      ok\n  "
  },
  {
    "path": "extra/cache-extra/Tests/Fixtures/cache_with_blocks.test",
    "chars": 274,
    "preview": "--TEST--\n\"cache\" tag\n--TEMPLATE--\n{% extends \"layout.twig\" %}\n{% block bar %}\n    {% cache \"foo\" %}\n        {%- block co"
  },
  {
    "path": "extra/cache-extra/Tests/Fixtures/macro.test",
    "chars": 348,
    "preview": "--TEST--\nmacro call inside \"cache\" tag\n--TEMPLATE--\n{% macro macro_out(bar) %}{{ bar }}{% endmacro %}\n1\n{% cache \"testma"
  },
  {
    "path": "extra/cache-extra/Tests/FunctionalTest.php",
    "chars": 3257,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/cache-extra/Tests/IntegrationTest.php",
    "chars": 1076,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/cache-extra/TokenParser/CacheTokenParser.php",
    "chars": 2387,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/cache-extra/composer.json",
    "chars": 824,
    "preview": "{\n    \"name\": \"twig/cache-extra\",\n    \"type\": \"library\",\n    \"description\": \"A Twig extension for Symfony Cache\",\n    \"k"
  },
  {
    "path": "extra/cache-extra/phpunit.xml.dist",
    "chars": 691,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSch"
  },
  {
    "path": "extra/cssinliner-extra/.gitattributes",
    "chars": 74,
    "preview": "/Tests export-ignore\n/.git* export-ignore\n/phpunit.xml.dist export-ignore\n"
  },
  {
    "path": "extra/cssinliner-extra/.gitignore",
    "chars": 56,
    "preview": "vendor/\ncomposer.lock\nphpunit.xml\n.phpunit.result.cache\n"
  },
  {
    "path": "extra/cssinliner-extra/CssInlinerExtension.php",
    "chars": 880,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/cssinliner-extra/LICENSE",
    "chars": 1068,
    "preview": "Copyright (c) 2019-present Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
  },
  {
    "path": "extra/cssinliner-extra/README.md",
    "chars": 225,
    "preview": "Twig CssInliner Extension\n=========================\n\nThis package is a Twig extension that provides the following:\n\n * ["
  },
  {
    "path": "extra/cssinliner-extra/Resources/functions.php",
    "chars": 543,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/cssinliner-extra/Tests/Fixtures/inline_css.test",
    "chars": 1557,
    "preview": "--TEST--\n\"inline_css\" filter\n--TEMPLATE--\n{% apply inline_css %}\n    <html><style>p { color: red }</style><p>Great!</p><"
  },
  {
    "path": "extra/cssinliner-extra/Tests/IntegrationTest.php",
    "chars": 605,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/cssinliner-extra/Tests/LegacyFunctionsTest.php",
    "chars": 641,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/cssinliner-extra/composer.json",
    "chars": 945,
    "preview": "{\n    \"name\": \"twig/cssinliner-extra\",\n    \"type\": \"library\",\n    \"description\": \"A Twig extension to allow inlining CSS"
  },
  {
    "path": "extra/cssinliner-extra/phpunit.xml.dist",
    "chars": 697,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSch"
  },
  {
    "path": "extra/html-extra/.gitattributes",
    "chars": 74,
    "preview": "/Tests export-ignore\n/.git* export-ignore\n/phpunit.xml.dist export-ignore\n"
  },
  {
    "path": "extra/html-extra/.gitignore",
    "chars": 56,
    "preview": "vendor/\ncomposer.lock\nphpunit.xml\n.phpunit.result.cache\n"
  },
  {
    "path": "extra/html-extra/Cva.php",
    "chars": 3974,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/html-extra/HtmlAttr/AttributeValueInterface.php",
    "chars": 834,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/html-extra/HtmlAttr/InlineStyle.php",
    "chars": 1813,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/html-extra/HtmlAttr/MergeableInterface.php",
    "chars": 2416,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/html-extra/HtmlAttr/SeparatedTokenList.php",
    "chars": 2138,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/html-extra/HtmlExtension.php",
    "chars": 9441,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/html-extra/LICENSE",
    "chars": 1068,
    "preview": "Copyright (c) 2019-present Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
  },
  {
    "path": "extra/html-extra/README.md",
    "chars": 498,
    "preview": "Twig HTML Extension\n===================\n\nThis package is a Twig extension that provides the following:\n\n * [`data_uri`]["
  },
  {
    "path": "extra/html-extra/Resources/functions.php",
    "chars": 511,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/html-extra/Tests/CvaTest.php",
    "chars": 21985,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  },
  {
    "path": "extra/html-extra/Tests/Fixtures/data_uri.test",
    "chars": 3954,
    "preview": "--TEST--\n\"data_uri\" filter\n--TEMPLATE--\n{{ 'foobar#'|data_uri(parameters={charset: \"utf-8\", foo: \"$bar\"}) }}\n{{ '<b>foob"
  },
  {
    "path": "extra/html-extra/Tests/Fixtures/html_attr.test",
    "chars": 3006,
    "preview": "--TEST--\n\"html_attr\" function\n--TEMPLATE--\nSimple attributes: <tag {{ html_attr({ foo: 'bar' }, { bar: 'baz' }) }}/>\nRel"
  },
  {
    "path": "extra/html-extra/Tests/Fixtures/html_attr_merge.test",
    "chars": 245,
    "preview": "--TEST--\n\"html_attr_merge\" filter\n--TEMPLATE--\n{% autoescape false %}\n{{ { foo: 'bar' } | html_attr_merge({ bar: 'baz', "
  },
  {
    "path": "extra/html-extra/Tests/Fixtures/html_classes.test",
    "chars": 375,
    "preview": "--TEST--\n\"html_classes\" function\n--TEMPLATE--\n{{ html_classes('a', {'b': true, 'c': false}, 'd', false ? 'e', true ? 'f'"
  },
  {
    "path": "extra/html-extra/Tests/Fixtures/html_classes_with_unsupported_arg.test",
    "chars": 245,
    "preview": "--TEST--\n\"html_classes\" function\n--TEMPLATE--\n{{ html_classes(true) }}\n--DATA--\nreturn []\n--EXCEPTION--\nTwig\\Error\\Runti"
  },
  {
    "path": "extra/html-extra/Tests/Fixtures/html_classes_with_unsupported_key.test",
    "chars": 236,
    "preview": "--TEST--\n\"html_classes\" function\n--TEMPLATE--\n{{ html_classes(['foo']) }}\n--DATA--\nreturn []\n--EXCEPTION--\nTwig\\Error\\Ru"
  },
  {
    "path": "extra/html-extra/Tests/Fixtures/html_cva.test",
    "chars": 710,
    "preview": "--TEST--\n\"html_cva\" function\n--TEMPLATE--\n{% set alert = html_cva(\n    ['alert'],\n    {\n       color: {\n           blue:"
  },
  {
    "path": "extra/html-extra/Tests/Fixtures/html_cva_pass_to_template.test",
    "chars": 474,
    "preview": "--TEST--\npass Cva object to template\n--TEMPLATE--\n{{ alert.apply({colors: 'primary', sizes: 'sm'}) }}\n--DATA--\nreturn [\n"
  },
  {
    "path": "extra/html-extra/Tests/HtmlAttrMergeTest.php",
    "chars": 6997,
    "preview": "<?php\n\n/*\n * This file is part of Twig.\n *\n * (c) Fabien Potencier\n *\n * For the full copyright and license information,"
  }
]

// ... and 917 more files (download for full content)

About this extraction

This page contains the full source code of the twigphp/Twig GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1117 files (1.8 MB), approximately 499.5k tokens, and a symbol index with 2527 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!