Core API method for appending to the source code stream.

        It can take the following as input.

        *Strings*
            The processor is called if specified. String values from the 
            processed stream are added after newlines are alided and indented. 
            Other values are recursed on.
            
            Multiple adjacent newlines which straddle appends are alided to 
            produce a single newline. To insert multiple newlines, they must
            be adjacent in the same string passed to append.
            
        *Callables*
            Callables taking no arguments are called and their return value
            recursed on if not ``None`` or ``self``.
            
            Callables taking one argument are called with ``self`` and their
            return value is recursed on if not ``None`` or ``self``.

        *Iterables*
            The items recursed on.

        *Expressions*
            If ``code._CG_expression`` is defined, that value is recursed on.
            
            If ``code._CG_context`` is defined, its value will be appended to
            the processor using ``append``, if possible, while recursing.

        *Convertables*
            See :data:`convert`.

def append(self, code):
        """Core API method for appending to the source code stream.

        It can take the following as input.

        *Strings*
            The processor is called if specified. String values from the 
            processed stream are added after newlines are alided and indented. 
            Other values are recursed on.
            
            Multiple adjacent newlines which straddle appends are alided to 
            produce a single newline. To insert multiple newlines, they must
            be adjacent in the same string passed to append.
            
        *Callables*
            Callables taking no arguments are called and their return value
            recursed on if not ``None`` or ``self``.
            
            Callables taking one argument are called with ``self`` and their
            return value is recursed on if not ``None`` or ``self``.

        *Iterables*
            The items recursed on.

        *Expressions*
            If ``code._CG_expression`` is defined, that value is recursed on.
            
            If ``code._CG_context`` is defined, its value will be appended to
            the processor using ``append``, if possible, while recursing.

        *Convertables*
            See :data:`convert`.
            
        """
        # support one-shot push and pop of dictionaries using operators
        pop_next = self._pop_next
        if pop_next:
            self._pop_next = False

        if isinstance(code, str):
            # Strings are processed, then indented appropriately
            for token in self._process(code):
                prev = self.last_string
                prev_ends_with_nl = prev is None or prev.endswith('\n')
                token_starts_with_nl = token.startswith("\n")
                indent_depth = self.indent_depth
                if prev_ends_with_nl:
                    if indent_depth > 0:
                        self.code_builder.append(self.indent_str)
                    if token_starts_with_nl:
                        token = token[1:]

                if indent_depth > 0:
                    token = cypy.re_nonend_newline.sub(
                        "\n" + self.indent_str, token)

                if token != "":
                    self.code_builder.append(token)
        else: self._process_nonstrings(code)

        if pop_next:
            self.pop_context()
        return self