class_docstr: Lexer for psql sessions.
  
  .. versionadded:: 1.5
class_docstr_tok: ["Lexer","for","psql","sessions",".","..","versionadded",":",":","1.5"]
code: def get_tokens_unprocessed(self, data):
      sql = PsqlRegexLexer(**self.options)
  
      lines = lookahead(line_re.findall(data))
  
      # prompt-output cycle
      while 1:
          # consume the lines of the command: start with an optional prompt
          # and continue until the end of command is detected
          curcode = ""
          insertions = []
          while 1:
              try:
                  line = next(lines)
              except StopIteration:
                  # allow the emission of partially collected items
                  # the repl loop will be broken below
                  break
  
              # Identify a shell prompt in case of psql commandline example
              if line.startswith("$") and not curcode:
                  lexer = get_lexer_by_name("console", **self.options)
                  for x in lexer.get_tokens_unprocessed(line):
                      yield x
                  break
  
              # Identify a psql prompt
              mprompt = re_prompt.match(line)
              if mprompt is not None:
                  insertions.append(
                      (
                          len(curcode),
                          [(0, Generic.Prompt, mprompt.group())],
                      )
                  )
                  curcode += line[len(mprompt.group()) :]
              else:
                  curcode += line
  
              # Check if this is the end of the command
              # TODO: better handle multiline comments at the end with
              # a lexer with an external state?
              if re_psql_command.match(
                  curcode
              ) or re_end_command.search(curcode):
                  break
  
          # Emit the combined stream of command and prompt(s)
          for item in do_insertions(
              insertions, sql.get_tokens_unprocessed(curcode)
          ):
              yield item
  
          # Emit the output lines
          out_token = Generic.Output
          while 1:
              line = next(lines)
              mprompt = re_prompt.match(line)
              if mprompt is not None:
                  # push the line back to have it processed by the prompt
                  lines.send(line)
                  break
  
              mmsg = re_message.match(line)
              if mmsg is not None:
                  if mmsg.group(1).startswith("ERROR") or mmsg.group(
                      1
                  ).startswith("FATAL"):
                      out_token = Generic.Error
                  yield (mmsg.start(1), Generic.Strong, mmsg.group(1))
                  yield (mmsg.start(2), out_token, mmsg.group(2))
              else:
                  yield (0, out_token, line)
  
imports: import re
  from pygments.lexer import Lexer, RegexLexer, do_insertions, bygroups, words
  from pygments.token import Punctuation, Whitespace, Error, Text, Comment, Operator, Keyword, Name, String, Number, Generic
  from pygments.lexers import get_lexer_by_name, ClassNotFound
  from pygments.util import iteritems
  from pygments.lexers._postgres_builtins import KEYWORDS, DATATYPES, PSEUDO_TYPES, PLPGSQL_KEYWORDS
  from pygments.lexers import _tsql_builtins
label_desc: Use image node_id 1 for calling the PostgresConsoleLexer obj's underlying member method code with example usage: obj.get_tokens_unprocessed(data) without return types