docs: def convert_lines_to_block(lines, block_map, link_stack, source_path, block_name=ALL_BLOCK_NAME):
      """Converts the specified block content lines (list of strings) into a Block object.
  
      Nested blocks are recursively converted into strings and cached in the block_map. Include tags
      are processed as well. The resulting block string is also added to the block_map, along with any
      nested blocks.
  
      PARAMETERS:
      lines       -- str; content lines to be converted into a Block.
      block_map   -- BlockMap
      link_stack  -- LinkStack
      source_path -- str; the path of the file from which this content came, relative to the current
                     working directory.
      block_name  -- str; the name of the block that contains this content. By default, the name is
                    'all'
  
      RETURNS:
      Block; the result of converting the block content.
      """
      found_closing_block = False
      segments = []
      while lines:
          line = lines.pop(0)
  
          # Check if the line is a closing tag. This should only occur if we encounter the closing
          # block tag that matches the block_name parameter.
          close_tag_match = BLOCK_CLOSE_REGEX.match(line)
          if close_tag_match:
              if close_tag_match.group(1) != block_name:
                  raise InvalidBlockName('Expected closing block ' + block_name + \
                      'but found block named "' + block_tag_match.group(1) + '" in ' + source_path)
              # If the block name is valid, we are done processing this block.
              found_closing_block = True
              break
  
          # Otherwise, check if the line is a nested block.
          open_tag_match = BLOCK_OPEN_REGEX.match(line)
          if open_tag_match:
              # Make sure the block name is not the reserved ALL_BLOCK_NAME.
              inner_block_name = open_tag_match.group(1)
              if inner_block_name == ALL_BLOCK_NAME:
                  raise InvalidBlockName(
                      '"{0}" is a reserved block name, but found block named "{0}" in {1}'.format(
                          ALL_BLOCK_NAME, source_path))
  
              # Recursively convert nested block contents to a Block.
              inner_block = convert_lines_to_block(
                  lines,
                  block_map,
                  link_stack,
                  source_path,
                  inner_block_name)
              segments.append(inner_block)
              continue
  
          # Otherwise, check if the line is a variable. The line should be omitted.
          variable_match = VARIABLE_REGEX.match(line)
          if variable_match:
              process_variable(variable_match, block_map)
              continue
  
          # Otherwise, check if the line is an include tag.
          include_match = INCLUDE_REGEX.match(line)
          if include_match:
              included_content = process_links(include_match, block_map, link_stack, source_path)
              # Omit empty content.
              if included_content != '':
                  append_text_to_segments(segments, included_content)
          else:
              append_text_to_segments(segments, line)
  
      if block_name != ALL_BLOCK_NAME and not found_closing_block:
          raise InvalidBlockName(
                  'Expected closing block called "{0}" in {1}'.format(block_name, source_path))
  
      block = Block(source_path, block_name, segments)
      block_map.add_block(block)
      return block