@@ -693,7 +693,7 @@ enum SpaceHandling { Keep, Strip, StripSpaces, StripNewline };
693693
694694class TemplateToken {
695695public:
696- enum class Type { Text, Expression, If, Else, Elif, EndIf, For, EndFor, Set, EndSet, Comment, Macro, EndMacro, Filter, EndFilter };
696+ enum class Type { Text, Expression, If, Else, Elif, EndIf, For, EndFor, Generation, EndGeneration, Set, EndSet, Comment, Macro, EndMacro, Filter, EndFilter };
697697
698698 static std::string typeToString (Type t) {
699699 switch (t) {
@@ -712,6 +712,8 @@ class TemplateToken {
712712 case Type::EndMacro: return " endmacro" ;
713713 case Type::Filter: return " filter" ;
714714 case Type::EndFilter: return " endfilter" ;
715+ case Type::Generation: return " generation" ;
716+ case Type::EndGeneration: return " endgeneration" ;
715717 }
716718 return " Unknown" ;
717719 }
@@ -788,6 +790,14 @@ struct EndForTemplateToken : public TemplateToken {
788790 EndForTemplateToken (const Location & location, SpaceHandling pre , SpaceHandling post ) : TemplateToken(Type::EndFor, location, pre , post ) {}
789791};
790792
793+ struct GenerationTemplateToken : public TemplateToken {
794+ GenerationTemplateToken (const Location & location, SpaceHandling pre , SpaceHandling post ) : TemplateToken(Type::Generation, location, pre , post ) {}
795+ };
796+
797+ struct EndGenerationTemplateToken : public TemplateToken {
798+ EndGenerationTemplateToken (const Location & location, SpaceHandling pre , SpaceHandling post ) : TemplateToken(Type::EndGeneration, location, pre , post ) {}
799+ };
800+
791801struct SetTemplateToken : public TemplateToken {
792802 std::string ns;
793803 std::vector<std::string> var_names;
@@ -2149,7 +2159,7 @@ class Parser {
21492159 static std::regex comment_tok (R"( \{#([-~]?)(.*?)([-~]?)#\})" );
21502160 static std::regex expr_open_regex (R"( \{\{([-~])?)" );
21512161 static std::regex block_open_regex (R"( ^\{%([-~])?[\s\n\r]*)" );
2152- static std::regex block_keyword_tok (R"( (if|else|elif|endif|for|endfor|set|endset|block|endblock|macro|endmacro|filter|endfilter)\b)" );
2162+ static std::regex block_keyword_tok (R"( (if|else|elif|endif|for|endfor|generation|endgeneration| set|endset|block|endblock|macro|endmacro|filter|endfilter)\b)" );
21532163 static std::regex non_text_open_regex (R"( \{\{|\{%|\{#)" );
21542164 static std::regex expr_close_regex (R"( [\s\n\r]*([-~])?\}\})" );
21552165 static std::regex block_close_regex (R"( [\s\n\r]*([-~])?%\})" );
@@ -2229,6 +2239,12 @@ class Parser {
22292239 } else if (keyword == " endfor" ) {
22302240 auto post_space = parseBlockClose ();
22312241 tokens.push_back (std::make_unique<EndForTemplateToken>(location, pre_space, post_space));
2242+ } else if (keyword == " generation" ) {
2243+ auto post_space = parseBlockClose ();
2244+ tokens.push_back (std::make_unique<GenerationTemplateToken>(location, pre_space, post_space));
2245+ } else if (keyword == " endgeneration" ) {
2246+ auto post_space = parseBlockClose ();
2247+ tokens.push_back (std::make_unique<EndGenerationTemplateToken>(location, pre_space, post_space));
22322248 } else if (keyword == " set" ) {
22332249 static std::regex namespaced_var_regex (R"( (\w+)[\s\n\r]*\.[\s\n\r]*(\w+))" );
22342250
@@ -2330,6 +2346,13 @@ class Parser {
23302346 throw unterminated (**start);
23312347 }
23322348 children.emplace_back (std::make_shared<ForNode>(token->location , std::move (for_token->var_names ), std::move (for_token->iterable ), std::move (for_token->condition ), std::move (body), for_token->recursive , std::move (else_body)));
2349+ } else if (dynamic_cast <GenerationTemplateToken*>(token.get ())) {
2350+ auto body = parseTemplate (begin, it, end);
2351+ if (it == end || (*(it++))->type != TemplateToken::Type::EndGeneration) {
2352+ throw unterminated (**start);
2353+ }
2354+ // Treat as a no-op, as our scope is templates for inference, not training (`{% generation %}` wraps generated tokens for masking).
2355+ children.emplace_back (std::move (body));
23332356 } else if (auto text_token = dynamic_cast <TextTemplateToken*>(token.get ())) {
23342357 SpaceHandling pre_space = (it - 1 ) != begin ? (*(it - 2 ))->post_space : SpaceHandling::Keep;
23352358 SpaceHandling post_space = it != end ? (*it)->pre_space : SpaceHandling::Keep;
@@ -2397,6 +2420,7 @@ class Parser {
23972420 || dynamic_cast <EndFilterTemplateToken*>(token.get ())
23982421 || dynamic_cast <EndIfTemplateToken*>(token.get ())
23992422 || dynamic_cast <ElseTemplateToken*>(token.get ())
2423+ || dynamic_cast <EndGenerationTemplateToken*>(token.get ())
24002424 || dynamic_cast <ElifTemplateToken*>(token.get ())) {
24012425 it--; // unconsume the token
24022426 break ; // exit the loop
0 commit comments