class_docstr: Read notebook cells from plain Python or Julia files. Cells
  are identified by line breaks, unless they start with an
  explicit marker '# +'
class_docstr_tok: ["Read","notebook","cells","from","plain","Python","or","Julia","files",".","Cells","are","identified","by","line","breaks",",","unless","they","start","with","an","explicit","marker","'","#","+","'"]
docstr: Find the end of the region started with start and end markers
docstr_tok: ["Find","the","end","of","the","region","started","with","start","and","end","markers"]
code: def find_region_end(self, lines):
      """Find the end of the region started with start and end markers"""
      if self.metadata and "cell_type" in self.metadata:
          self.cell_type = self.metadata.pop("cell_type")
      else:
          self.cell_type = "code"
  
      parser = StringParser(self.language or self.default_language)
      for i, line in enumerate(lines):
          # skip cell header
          if self.metadata is not None and i == 0:
              continue
  
          if parser.is_quoted():
              parser.read_line(line)
              continue
  
          parser.read_line(line)
          # New code region
          # Simple code pattern in LightScripts must be preceded with a blank line
          if self.start_code_re.match(line) or (
              self.simple_start_code_re
              and self.simple_start_code_re.match(line)
              and (
                  self.cell_marker_start
                  or i == 0
                  or _BLANK_LINE.match(lines[i - 1])
              )
          ):
              if self.explicit_end_marker_required:
                  # Metadata here was conditioned on finding an explicit end marker
                  # before the next start marker. So we dismiss it.
                  self.metadata = None
                  self.language = None
  
              if i > 0 and _BLANK_LINE.match(lines[i - 1]):
                  if i > 1 and _BLANK_LINE.match(lines[i - 2]):
                      return i - 2, i, False
                  return i - 1, i, False
              return i, i, False
  
          if not self.ignore_end_marker and self.end_code_re:
              if self.end_code_re.match(line):
                  return i, i + 1, True
          elif _BLANK_LINE.match(line):
              if not next_code_is_indented(lines[i:]):
                  if i > 0:
                      return i, i + 1, False
                  if len(lines) > 1 and not _BLANK_LINE.match(lines[1]):
                      return 1, 1, False
                  return 1, 2, False
  
      return len(lines), len(lines), False
  
imports: import re
  import warnings
  from copy import copy
  from nbformat.v4.nbbase import new_code_cell, new_markdown_cell, new_raw_cell
  from packaging.version import parse
  from .doxygen import doxygen_to_markdown
  from .languages import _SCRIPT_EXTENSIONS
  from .cell_metadata import is_active, is_json_metadata, rmd_options_to_metadata, text_to_metadata
  from .languages import _JUPYTER_LANGUAGES_LOWER_AND_UPPER
  from .magics import is_magic, need_explicit_marker, uncomment_magic, unescape_code_start
  from .pep8 import pep8_lines_between_cells
  from .stringparser import StringParser
label_desc: Use image node_id 5 for calling the LightScriptCellReader obj's underlying member method code with example usage: obj.find_region_end(lines) and returns: len,  len,  False, i,  i,  False, unknown,  i,  False, i,  unknown,  True, unknown,  i,  False, int,  int,  False, i,  unknown,  False, int,  int,  False