# frozen_string_literal: true module Repubmark module Elems class Chapter < Base parents :Article, :Chapter def initialize(parent, level = 1, title = nil) super parent self.level = level self.title = title verify! @canvas = Canvas.new self @chapters = [] end ################# # Basic methods # ################# def word_count (@title ? count_words(@title) : 0) + @canvas.word_count + @chapters.sum(&:word_count) end def to_html [ build_title_html, @canvas.to_html, *@chapters.map(&:to_html), ].join.freeze end def to_gemtext [ build_title_gemtext, @canvas.to_gemtext, *@chapters.map(&:to_gemtext), ].join.freeze end ################### # Builder methods # ################### def chapter(title) chapter = Chapter.new self, @level + 1, title @chapters << chapter yield chapter nil end def respond_to_missing?(method_name, _include_private) @canvas.respond_to?(method_name) || super end def method_missing(method_name, ...) if @canvas.respond_to? method_name raise 'Intro after chapters' unless @chapters.empty? @canvas.public_send(method_name, ...) else super end end private def level=(level) level = Integer level raise unless level.positive? @level = level end def title=(title) return @title = nil if title.nil? title = String(title).strip.freeze raise 'Empty title' if title.empty? @title = title end def verify! raise 'Non-empty title for level 1' if @level == 1 && @title raise 'Empty title for level >= 2' if @level != 1 && @title.nil? end def build_title_html "#@title\n" if @level != 1 end def build_title_gemtext "\n#{'#' * @level} #@title\n\n" if @level != 1 end end end end