docs: def collect_spans(ast: AST) -> List[Tuple[str, Tuple[int, int]]]:
      """Collect flattened list of spans of BEL syntax types
  
      Provide simple list of BEL syntax type spans for highlighting.
      Function names, NSargs, NS prefix, NS value and StrArgs will be
      tagged.
  
      Args:
          ast: AST of BEL assertion
  
      Returns:
          List[Tuple[str, Tuple[int, int]]]: list of span objects (<type>, (<start>, <end>))
      """
  
      spans = []
  
      if ast.get("subject", False):
          spans.extend(collect_spans(ast["subject"]))
  
      if ast.get("object", False):
          spans.extend(collect_spans(ast["object"]))
  
      if ast.get("nested", False):
          spans.extend(collect_spans(ast["nested"]))
  
      if ast.get("function", False):
          log.debug(f"Processing function")
          spans.append(("Function", ast["function"]["name_span"]))
          log.debug(f"Spans: {spans}")
  
      if ast.get("args", False):
          for idx, arg in enumerate(ast["args"]):
              log.debug(f"Arg  {arg}")
  
              if arg.get("function", False):
                  log.debug(f"Recursing on arg function")
                  results = collect_spans(arg)
                  log.debug(f"Results {results}")
                  spans.extend(results)  # Recurse arg function
              elif arg.get("nsarg", False):
                  log.debug(f"Processing NSArg   Arg {arg}")
                  spans.append(("NSArg", arg["span"]))
                  spans.append(("NSPrefix", arg["nsarg"]["ns_span"]))
                  spans.append(("NSVal", arg["nsarg"]["ns_val_span"]))
              elif arg["type"] == "StrArg":
                  spans.append(("StrArg", arg["span"]))
  
      log.debug(f"Spans: {spans}")
      return spans