code: def choose_include_text(s, params, source_path):
    
    lines = s.splitlines()
    start_after = None
    start_at = None
    end_before = None
    end_at = None
  
    for term in params.split("&"):
      if '=' in term:
        param, value = [p.strip() for p in term.split('=', 1)]
      else:
        param, value = term.strip(), ''
      if not param: continue
      if param == "start-after":
        start_after = value
      elif param == "start-at":
        start_at = value
      elif param == "end-before":
        end_before = value
      elif param == "end-at":
        end_at = value
      else:
        raise TaskError('Invalid include directive "{0}"'
                        ' in {1}'.format(params, source_path))
  
    chosen_lines = []
    # two loops, one waits to "start recording", one "records"
    for line_ix in range(0, len(lines)):
      line = lines[line_ix]
      if (not start_at) and (not start_after):
        # if we didn't set a start-* param, don't wait to start
        break
      if start_at is not None and start_at in line:
        break
      if start_after is not None and start_after in line:
        line_ix += 1
        break
    else:
      # never started recording:
      return ''
    for line_ix in range(line_ix, len(lines)):
      line = lines[line_ix]
      if end_before is not None and end_before in line:
        break
      chosen_lines.append(line)
      if end_at is not None and end_at in line:
        break
    else:
      if (end_before or end_at):
        # we had an end- filter, but never encountered it.
        return ''
    return '\n'.join(chosen_lines)
docs: Given the contents of a file and !inc[these params], return matching lines
  
    If there was a problem matching parameters, return empty list.
  
    :param s: file's text
    :param params: string like "start-at=foo&end-at=bar"
    :param source_path: path to source .md. Useful in error messages