# frozen_string_literal: true module Doing class Items < Array # List sections, title only # # @return [Array] section titles # def section_titles @sections.map(&:title) end # Test if section already exists # # @param section [String] section title # # @return [Boolean] true if section exists # def section?(section) section = section.is_a?(Section) ? section.title.downcase : section.downcase @sections.map { |i| i.title.downcase }.include?(section) end ## ## Return the best section match for a search query ## ## @param frag The search query ## @param distance The distance apart characters can be (fuzziness) ## ## @return [Section] (first) matching section object ## def guess_section(frag, distance: 2) section = nil re = frag.to_rx(distance: distance, case_type: :ignore) @sections.each do |sect| next unless sect.title =~ /#{re}/i Doing.logger.debug('Match:', %(Assuming "#{sect.title}" from "#{frag}")) section = sect break end section end # Add a new section to the sections array. Accepts # either a Section object, or a title string that will # be converted into a Section. # # @param section [Section] The section to add. A # String value will be converted to # Section automatically. # @param log [Boolean] Add a log message # notifying the user about the # creation of the section. # # @return nothing # def add_section(section, log: false) section = section.is_a?(Section) ? section : Section.new(section.cap_first) return if section?(section) @sections.push(section) Doing.logger.info('New section:', %("#{section}" added)) if log end def delete_section(section, log: false) return unless section?(section) raise DoingRuntimeError, 'Section not empty' if in_section(section).count.positive? @sections.each do |sect| next unless sect.title == section && in_section(sect).count.zero? @sections.delete(sect) Doing.logger.info('Removed section:', %("#{section}" removed)) if log end Doing.logger.error('Not found:', %("#{section}" not found)) end end end