def __init__(self, text: str, *contexts: dict[str, Any]) -> None:
        """Construct a Templite with the given `text`.

        `contexts` are dictionaries of values to use for future renderings.
        These are good for filters and global values.

        """
        self.context = {}
        for context in contexts:
            self.context.update(context)

        self.all_vars: set[str] = set()
        self.loop_vars: set[str] = set()

        # We construct a function in source form, then compile it and hold onto
        # it, and execute it to render the template.
        code = CodeBuilder()

        code.add_line("def render_function(context, do_dots):")
        code.indent()
        vars_code = code.add_section()
        code.add_line("result = []")
        code.add_line("append_result = result.append")
        code.add_line("extend_result = result.extend")
        code.add_line("to_str = str")

        buffered: list[str] = []

        def flush_output() -> None:
            """Force `buffered` to the code builder."""
            if len(buffered) == 1:
                code.add_line("append_result(%s)" % buffered[0])
            elif len(buffered) > 1:
                code.add_line("extend_result([%s])" % ", ".join(buffered))
            del buffered[:]

        ops_stack = []

        # Split the text to form a list of tokens.
        tokens = re.split(r"(?s)({{.*?}}|{%.*?%}|{#.*?#})", text)

        squash = in_joined = False

        for token in tokens:
            if token.startswith("{"):
                start, end = 2, -2
                squash = (token[-3] == "-")
                if squash:
                    end = -3

                if token.startswith("{#"):
                    # Comment: ignore it and move on.
                    continue
                elif token.startswith("{{"):
                    # An expression to evaluate.
                    expr = self._expr_code(token[start:end].strip())
                    buffered.append("to_str(%s)" % expr)
                else:
                    # token.startswith("{%")
                    # Action tag: split into words and parse further.
                    flush_output()

                    words = token[start:end].strip().split()
                    if words[0] == "if":
                        # An if statement: evaluate the expression to determine if.
                        if len(words) != 2:
                            self._syntax_error("Don't understand if", token)
                        ops_stack.append("if")
                        code.add_line("if %s:" % self._expr_code(words[1]))
                        code.indent()
                    elif words[0] == "for":
                        # A loop: iterate over expression result.
                        if len(words) != 4 or words[2] != "in":
                            self._syntax_error("Don't understand for", token)
                        ops_stack.append("for")
                        self._variable(words[1], self.loop_vars)
                        code.add_line(
                            f"for c_{words[1]} in {self._expr_code(words[3])}:",
                        )
                        code.indent()
                    elif words[0] == "joined":
                        ops_stack.append("joined")
                        in_joined = True
                    elif words[0].startswith("end"):
                        # Endsomething.  Pop the ops stack.
                        if len(words) != 1:
                            self._syntax_error("Don't understand end", token)
                        end_what = words[0][3:]
                        if not ops_stack:
                            self._syntax_error("Too many ends", token)
                        start_what = ops_stack.pop()
                        if start_what != end_what:
                            self._syntax_error("Mismatched end tag", end_what)
                        if end_what == "joined":
                            in_joined = False
                        else:
                            code.dedent()
                    else:
                        self._syntax_error("Don't understand tag", words[0])
            else:
                # Literal content.  If it isn't empty, output it.
                if in_joined:
                    token = re.sub(r"\s*\n\s*", "", token.strip())
                elif squash:
                    token = token.lstrip()
                if token:
                    buffered.append(repr(token))

        if ops_stack:
            self._syntax_error("Unmatched action tag", ops_stack[-1])

        flush_output()

        for var_name in self.all_vars - self.loop_vars:
            vars_code.add_line(f"c_{var_name} = context[{var_name!r}]")

        code.add_line("return ''.join(result)")
        code.dedent()
        self._render_function = cast(
            Callable[
                [dict[str, Any], Callable[..., Any]],
                str,
            ],
            code.get_globals()["render_function"],
        )
Construct a Templite with the given `text`.

        `contexts` are dictionaries of values to use for future renderings.
        These are good for filters and global values.

        
coverage/templite.py