def locate_block(mm, header, trailer, force_head=False, force_tail=False,
                 skip_header=True, skip_trailer=None):
  """ find the memory locations bounding a block of text
  in between header and trailer; header and trailer are
  not included by default
  e.g. see block_text

  Args:
    mm (mmap.mmap): memory map to text file
    header  (str): string indicating the beginning of block
    trailer (str): string indicating the end of block
    skip_head (bool, optional): skip header, default is True
    skip_trailer (bool, optional): skip trailer, default is True,
      unless force_tail, then default to False
  Return:
    tuple: (begin_idx, end_idx), memory span of text block
  """
  if skip_trailer is None:
    skip_trailer = not force_tail
  begin_idx = mm.find(header.encode())
  if begin_idx == -1:
    if force_head:
      begin_idx = 0
    else:
      raise RuntimeError('failed to find "%s"' % header)
  if skip_header:
    mm.seek(begin_idx)
    mm.readline()
    begin_idx = mm.tell()
  end_idx = mm.find(trailer.encode())
  whence = 1  # seek from current location by default
  if end_idx == -1:
    if force_tail:
      whence = 2  # seek from end of file
    else:
      raise RuntimeError('failed to find "%s"' % trailer)
  if not skip_trailer:
    mm.seek(end_idx, whence)
    mm.readline()
    end_idx = mm.tell()
  return begin_idx, end_idx