repubmark/lib/repubmark/elems/chapter.rb

102 lines
2.1 KiB
Ruby

# 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
"<h#@level>#@title</h#@level>\n" if @level != 1
end
def build_title_gemtext
"\n#{'#' * @level} #@title\n\n" if @level != 1
end
end
end
end