docs: def indent_code(original_code, options=None):
      """ indented_code(string : str, fname : str) -> [...]
  
      Arguments:
      fpath: Simply used in formatting the warning messages
  
      >>> indent_code("(print\n'Hello)")
      {'bracket_locations': [],
       'comment_locations': [],
       'in_comment': 0,
       'in_newlisp_tag_string': False,
       'in_string': False,
       'in_symbol_with_space': False,
       'indented_code': ['(print\n', " 'Hello)"],
       'last_quote_location': (),
       'last_symbol_location': (),
       'message_stack': [],
       'newlisp_brace_locations': [],
       'original_code': ['(print\n', "'Hello)"],
       'first_tag_string': ()}
  
  
      The last entry in the list is the indented string.
      """
  
      opts = parse_options(options)
      keywords = add_keywords(opts)
  
      # Safeguards against processing brackets inside strings
      in_string = False
  
      # newLISP use curly brackets as a syntax for multiline strings
      # this variable here tries to keep track of that
      in_newlisp_string = 0
      in_newlisp_tag_string = False
      newlisp_brace_locations = []
      first_tag_string = ()
  
      # zero_level helps us get the same results as Sitaram's indenter when in
      # --no-compact mode.
      zero_level = 0
  
      # The two variables prevent formatting comment regions or symbols with whitespace
      in_comment = 0
      in_symbol_with_space = False
      comment_locations = []
      last_symbol_location = ()
  
      # A in_symbol_region is the region between pipes(|   |) or in strings. This
      # includes the comment region. This region is not to be messed with.
      in_symbol_region = in_string or in_comment or in_symbol_with_space or \
          in_newlisp_string or in_newlisp_tag_string
  
      # we need to know the line number in order to issue almost accurate messages about
      # unclosed brackets and string
      line_number = 1
  
      # Stores the last position a quote was encountered so that in case there are
      # any unclosed strings, we can pinpoint them
      last_quote_location = ()
  
      line_ending = find_line_ending(original_code)
      code_lines = split_preserve(original_code, line_ending)
  
      indented_code = []
  
      bracket_locations = []
  
      # List of warnings from errors in the code
      message_stack = []
  
      for line in code_lines:
          escaped   = False
          curr_line = line
  
          # Get the indent level and the indented line
          zero_level, curr_line, indent_level = indent_line(zero_level,
                                                            bracket_locations,
                                                            line, in_comment,
                                                            in_symbol_region, opts)
          # Build up the indented string.
          indented_code.append(curr_line)
          regex = '^[ \t]*'
          lead_spaces = re.findall(regex, curr_line)
          if lead_spaces:
              curr_line = re.sub(regex, detabify(lead_spaces[0], opts), curr_line)
          offset = 0
          for curr_char in curr_line:
              next_char = curr_line[offset + 1:offset + 2]
              prev_char = curr_line[offset - 1:offset]
  
              substr = curr_line[offset + 1:]  # slice to the end
  
              if escaped:
                  # Move to the next character if the current one has been escaped
                  escaped = False
                  offset += 1
                  continue
  
              if curr_char == '\\' and not in_newlisp_string and not in_newlisp_tag_string:
                  # the next character has been escaped
                  escaped = True
  
              if (curr_char == ';' or (curr_char == '#' and opts.dialect == 'newlisp'))\
                      and not in_symbol_region and not \
                      (prev_char == '#' and opts.dialect == 'scheme'):
                  # a comment has been found, go to the next line
                  # A sharp sign(#) before a semi-colon in Scheme is used to
                  # comment out sections of code. We don't treat it as a comment
                  break
  
              # ----------------------------------------------------------
              # Comments are dealt with here. Clojure and newLISP don't have Lisp
              # style multiline comments so don't include them.
              if opts.dialect not in ['clojure', 'newlisp'] and curr_char == '|' \
                      and not in_string:
                  if prev_char == '#' and not in_symbol_with_space:
                      comment_locations.append((line_number, offset))
                      in_comment += 1
                  elif in_comment and next_char == '#':
                      in_comment -= 1
                      comment_locations.pop()
                  elif not in_comment:
                      if in_symbol_with_space:
                          last_symbol_location = ()
                          in_symbol_with_space = False
                      else:
                          last_symbol_location = (line_number, offset)
                          in_symbol_with_space = True
  
              # ----------------------------------------------------------
  
              # Strings are dealt with here only if we are not comment
              if not (in_symbol_with_space or in_comment or in_newlisp_tag_string):
                  if curr_char == '"':
                      last_quote_location = (line_number, offset)
                      in_string = True if not in_string else False
                  if opts.dialect == 'newlisp' and not in_string:
                      # We handle newLISP's multiline(brace) string here. Brace
                      # strings can nest
                      if curr_char == '{':
                          newlisp_brace_locations.append((line_number, offset))
                          in_newlisp_string += 1
                      elif curr_char == '}':
                          if newlisp_brace_locations:
                              newlisp_brace_locations.pop()
                          else:
                              message = "Attempt to close a non-existent newLISP string"
                              warning_info = {
                                  'msg': message,
                                  'line': line_number,
                                  'column': offset
                              }
                              message_stack.append(warning_info)
                          in_newlisp_string -= 1
  
              if curr_char == '[' and opts.dialect == 'newlisp' and not \
                      (in_newlisp_string or in_string):
                  # We have to handle tag strings in newLISP here.
                  if re.match('\[text\]', curr_line[offset:offset + 7]):
                      in_newlisp_tag_string = True
                      if first_tag_string == ():
                          first_tag_string = (line_number, offset)
                  elif re.match('\[/text\]', curr_line[offset:offset + 7]):
                      in_newlisp_tag_string = False
                      first_tag_string = ()
  
              in_symbol_region = in_string or in_comment or in_symbol_with_space \
                  or in_newlisp_string or in_newlisp_tag_string
  
              if in_symbol_region:
                  # move on if we are in a string, a symbol with a space or a comment
                  # altogether known as the symbol region
                  offset += 1
                  continue
  
              # Finds the real position of a bracket to be used in pinpointing where
              # the unclosed bracket is. The real position is different from the offset
              # because current offset is the position of the bracket in the
              # trimmed string not the original.
              real_position = (offset - zero_level) + \
                  len(re.findall('^[ \t]*', line)[0]) - indent_level
              if curr_char in ['(', '[', '{']:
                  if curr_char in ['[', '{'] and opts.dialect in ['lisp', 'newlisp']:
                      # Square/Curly brackets are used should not contribute to
                      # the indentation in CL and newLISP
                      offset += 1
                      continue
  
                  first_arg_pos, spaces_before_func = \
                      find_first_arg_pos(offset, curr_line, opts)
                  func_name = substr[0:first_arg_pos - 1].strip(')]\t\n\r ').lower()
                  in_list_literal = False
                  if re.search("[^#]('|`|#)([ \t]*\(|\[)($|\r)", curr_line[0:offset + 1]):
                      in_list_literal = True
  
                  if re.search('^[^ \t]+[ \t]*($|\r)', substr):
                      # The function is the last symbol/form in the line
                      func_name = substr.strip(')]\t\n\r ').lower()
  
                  if in_list_literal:
                      # an empty string is always in a non-empty string, we don't want
                      # this. We set False as the func_name because it's not a string
                      # in_list_literal prevents an keyword in a list literal from
                      # affecting the indentation
                      func_name = ''
  
                  if func_name in ['define-macro', 'defmacro']:
                      # Macro names are part of two space indenters.
                      # This part tries to find the name so that it is not indented
                      # like a function the next time it's used.
                      end_of_space = re.search('^[ \t]*', substr).end()
                      substr = substr[end_of_space:]
                      substr = substr[re.search('[ \t]*', substr).start():].strip()
                      macro_name = substr[:substr.find(' ')]  # macro name is delimeted by whitespace
                      if macro_name != '':
                          keywords[macro_name] = KEYWORD1
  
                  # first_item stores the position of the first item in the literal list
                  # it's necessary so that we don't assume that the first item is always
                  # after the opening bracket.
                  first_item = re.search('[ \t]*', curr_line[offset + 1:]).end() + offset + 1
                  bracket_locations = _push_to_list(bracket_locations[:], func_name,
                                                    curr_char, line_number, offset,
                                                    first_arg_pos, first_item,
                                                    in_list_literal,
                                                    spaces_before_func, opts)
  
              elif curr_char in [']', ')', '}']:
                  if curr_char in [']', '}'] and opts.dialect in ['lisp', 'newlisp']:
                      # Square/Curly brackets are used should not contribute to
                      # the indentation in CL and newLISP
                      offset += 1
                      continue
  
                  bracket_locations = _pop_from_list(curr_char, bracket_locations[:],
                                                     line_number, real_position,
                                                     offset, message_stack)
  
              if bracket_locations and curr_char in [' ', '\t'] and \
                      keywords[bracket_locations[-1]['func_name']] == KEYWORD2:
                  # This part changes the indentation level of a then clause so that
                  # we can achieve something like:
                  #         (if (= this that)
                  #             'then-form
                  #           'else-form)
                  # This is done by keeping track of the number of spaces found. If
                  # you find two spaces it means that, for example that we have just
                  # passed the then-form and hence should decrease the indentation
                  # level by 2.(I shamelessly copied this algorithm from Dorai's
                  # indenter)
                  if prev_char not in [' ', '\t', ''] or not \
                          re.search('^[ \t]*(;|#\||$|\r)', curr_line):
                      # The level shouldn't be decreased if the line is a comment
                      # line. The regex above takes care of that.
                      bracket_locations[-1]['spaces'] += 1
                  if bracket_locations[-1]['spaces'] == 2:
                      bracket_locations[-1]['indent_level'] -= \
                          0 if opts.uniform else opts.indent_size
                      # some dummy value to prevent control from reaching here again
                      bracket_locations[-1]['spaces'] = 999
  
              offset += 1
          line_number += 1
      res = {
          'message_stack': message_stack,
          'first_tag_string': first_tag_string,
          'in_newlisp_tag_string': in_newlisp_tag_string,
          'last_symbol_location': last_symbol_location,
          'comment_locations': comment_locations,
          'newlisp_brace_locations': newlisp_brace_locations,
          'in_string': in_string,
          'in_comment': in_comment,
          'in_symbol_with_space': in_symbol_with_space,
          'bracket_locations': bracket_locations,
          'last_quote_location': last_quote_location,
          'original_code': code_lines,
          'indented_code': indented_code
      }
      return res