code: def parseString(lines, start=0, **scope):
      data = OrderedDict()
      if isinstance(lines, str):
          lines = lines.replace("\\\n", "")
          lines = lines.split("\n")
          lines = [
              l
              for l in lines
              if re.search(r"\S", l) and not re.match(r"\s*#", l)
          ]  ## remove empty lines
  
      indent = measureIndent(lines[start])
      ln = start - 1
  
      try:
          while True:
              ln += 1
              # print ln
              if ln >= len(lines):
                  break
  
              l = lines[ln]
  
              ## Skip blank lines or lines starting with #
              if re.match(r"\s*#", l) or not re.search(r"\S", l):
                  continue
  
              ## Measure line indentation, make sure it is correct for this level
              lineInd = measureIndent(l)
              if lineInd < indent:
                  ln -= 1
                  break
              if lineInd > indent:
                  # print lineInd, indent
                  raise ParseError(
                      "Indentation is incorrect. Expected %d, got %d"
                      % (indent, lineInd),
                      ln + 1,
                      l,
                  )
  
              if ":" not in l:
                  raise ParseError("Missing colon", ln + 1, l)
  
              (k, p, v) = l.partition(":")
              k = k.strip()
              v = v.strip()
  
              ## set up local variables to use for eval
              if len(k) < 1:
                  raise ParseError(
                      "Missing name preceding colon", ln + 1, l
                  )
              if (
                  k[0] == "(" and k[-1] == ")"
              ):  ## If the key looks like a tuple, try evaluating it.
                  try:
                      k1 = eval(k, scope)
                      if type(k1) is tuple:
                          k = k1
                  except:
                      # If tuple conversion fails, keep the string
                      pass
              if re.search(r"\S", v) and v[0] != "#":  ## eval the value
                  try:
                      val = eval(v, scope)
                  except:
                      ex = sys.exc_info()[1]
                      raise ParseError(
                          "Error evaluating expression '%s': [%s: %s]"
                          % (v, ex.__class__.__name__, str(ex)),
                          (ln + 1),
                          l,
                      )
              else:
                  if (
                      ln + 1 >= len(lines)
                      or measureIndent(lines[ln + 1]) <= indent
                  ):
                      # print "blank dict"
                      val = {}
                  else:
                      # print "Going deeper..", ln+1
                      (ln, val) = parseString(
                          lines, start=ln + 1, **scope
                      )
              data[k] = val
          # print k, repr(val)
      except ParseError:
          raise
      except:
          ex = sys.exc_info()[1]
          raise ParseError(
              "%s: %s" % (ex.__class__.__name__, str(ex)), ln + 1, l
          )
      # print "Returning shallower..", ln+1
      return (ln, data)
  
file_path: pyqtgraph/pyqtgraph/configfile.py
imports: import datetime
  import os
  import re
  import sys
  from collections import OrderedDict
  import numpy
  from .None import units
  from .colormap import ColorMap
  from .Point import Point
  from .Qt import QtCore
label_desc: Use image node_id 5 for calling a global function with example usage: parseString(lines, start) and returns: ln,  data