code: def convert_bsf_in_folder(
      src_dir_path: str,
      dst_dir_path: str,
      converter: str = "beios",
      doc_delim: str = "\n",
      train_test_split_file: str = None,
  ) -> None:
      """
  
      :param doc_delim: delimiter to be used between documents
      :param src_dir_path: path to directory with BSF marked files
      :param dst_dir_path: where to save output data
      :param converter: `beios` or `iob` output formats
      :param train_test_split_file: path to file containing train/test lists of file names
      :return:
      """
      ann_path = os.path.join(src_dir_path, "*.tok.ann")
      ann_files = glob.glob(ann_path)
      ann_files.sort()
  
      tok_path = os.path.join(src_dir_path, "*.tok.txt")
      tok_files = glob.glob(tok_path)
      tok_files.sort()
  
      corpus_folder = os.path.join(dst_dir_path, CORPUS_NAME)
      if not os.path.exists(corpus_folder):
          os.makedirs(corpus_folder)
  
      if len(ann_files) == 0 or len(tok_files) == 0:
          raise FileNotFoundError(
              f"Token and annotation files are not found at specified path {ann_path}"
          )
      if len(ann_files) != len(tok_files):
          raise RuntimeError(
              f"Mismatch between Annotation and Token files. Ann files: {len(ann_files)}, token files: {len(tok_files)}"
          )
  
      train_set = []
      dev_set = []
      test_set = []
  
      data_sets = [train_set, dev_set, test_set]
      split_weights = (8, 1, 1)
  
      if train_test_split_file is not None:
          (
              train_names,
              dev_names,
              test_names,
          ) = read_languk_train_test_split(train_test_split_file)
  
      log.info(
          f'Found {len(tok_files)} files in data folder "{src_dir_path}"'
      )
      for tok_fname, ann_fname in tqdm(
          zip(tok_files, ann_files), total=len(tok_files), unit="file"
      ):
          if tok_fname[:-3] != ann_fname[:-3]:
              tqdm.write(
                  f"Token and Annotation file names do not match ann={ann_fname}, tok={tok_fname}"
              )
              continue
  
          with open(tok_fname) as tok_file, open(ann_fname) as ann_file:
              token_data = tok_file.read()
              ann_data = ann_file.read()
              out_data = convert_bsf(token_data, ann_data, converter)
  
              if train_test_split_file is None:
                  target_dataset = choices(data_sets, split_weights)[0]
              else:
                  target_dataset = train_set
                  fkey = os.path.basename(tok_fname)[:-4]
                  if fkey in dev_names:
                      target_dataset = dev_set
                  elif fkey in test_names:
                      target_dataset = test_set
  
              target_dataset.append(out_data)
      log.info(
          f"Data is split as following: train={len(train_set)}, dev={len(dev_set)}, test={len(test_set)}"
      )
  
      # writing data to {train/dev/test}.bio files
      names = ["train", "dev", "test"]
      if doc_delim != "\n":
          doc_delim = "\n" + doc_delim + "\n"
      for idx, name in enumerate(names):
          fname = os.path.join(corpus_folder, name + ".bio")
          with open(fname, "w") as f:
              f.write(doc_delim.join(data_sets[idx]))
          log.info("Writing to " + fname)
  
      log.info("All done")
  
file_path: stanza/stanza/utils/datasets/ner/convert_bsf_to_beios.py
imports: import argparse
  import logging
  import os
  import glob
  from collections import namedtuple
  import re
  from typing import Tuple
  from tqdm import tqdm
  from random import choices, shuffle
label_desc: Use image node_id 5 for calling a global function with example usage: convert_bsf_in_folder(src_dir_path, dst_dir_path, converter, doc_delim, train_test_split_file) without return types