141 lines
3.1 KiB
Ruby
141 lines
3.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Repubmark
|
|
module Elems
|
|
class ListItem < Base
|
|
extend Forwardable
|
|
|
|
parents :List
|
|
|
|
attr_reader :index, :titled_ref
|
|
|
|
def initialize(parent, index, titled_ref = nil)
|
|
super parent
|
|
|
|
self.index = index
|
|
self.titled_ref = titled_ref
|
|
|
|
@caption = Caption.new self
|
|
@sublist = nil
|
|
end
|
|
|
|
#################
|
|
# Basic methods #
|
|
#################
|
|
|
|
def word_count = @caption.word_count + (@sublist&.word_count || 0)
|
|
|
|
def to_html
|
|
[
|
|
"<li>\n",
|
|
build_ref(:html),
|
|
@caption.to_html,
|
|
@sublist&.to_html,
|
|
"</li>\n",
|
|
].join.freeze
|
|
end
|
|
|
|
def to_gemtext
|
|
[
|
|
if titled_ref
|
|
"#{build_ref(:gemtext)}#{@caption.to_gemtext}".strip
|
|
else
|
|
"* #{unicode_decor_own}#{@caption.to_gemtext}".strip
|
|
end,
|
|
@sublist&.to_gemtext,
|
|
].join("\n").freeze
|
|
end
|
|
|
|
##################
|
|
# Helper methods #
|
|
##################
|
|
|
|
def level = parent.level
|
|
|
|
def last? = index >= parent.items_count - 1
|
|
|
|
def unicode_decor_own
|
|
"#{parent.unicode_decor}#{last? ? '└' : '├'} " unless level.zero?
|
|
end
|
|
|
|
def unicode_decor_parent = parent.unicode_decor
|
|
|
|
###################
|
|
# Builder methods #
|
|
###################
|
|
|
|
def subolist
|
|
raise 'No nested link lists' if titled_ref
|
|
raise 'Sublist already exists' if @sublist
|
|
|
|
@sublist = List.new self, links: false, ordered: true
|
|
yield @sublist
|
|
nil
|
|
end
|
|
|
|
def subulist
|
|
raise 'No nested link lists' if titled_ref
|
|
raise 'Sublist already exists' if @sublist
|
|
|
|
@sublist = List.new self, links: false, ordered: false
|
|
yield @sublist
|
|
nil
|
|
end
|
|
|
|
def respond_to_missing?(method_name, _include_private)
|
|
@caption.respond_to?(method_name) || super
|
|
end
|
|
|
|
def method_missing(method_name, ...)
|
|
if @caption.respond_to? method_name
|
|
raise 'Caption after sublist' if @sublist
|
|
|
|
@caption.public_send(method_name, ...)
|
|
else
|
|
super
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def parent=(parent)
|
|
unless parent.instance_of? List
|
|
raise TypeError, "Expected #{List}, got #{parent.class}"
|
|
end
|
|
|
|
@parent = parent
|
|
end
|
|
|
|
def index=(index)
|
|
index = Integer index
|
|
raise 'Invalid index' if index.negative?
|
|
|
|
@index = index
|
|
end
|
|
|
|
def titled_ref=(titled_ref)
|
|
return @titled_ref = nil if titled_ref.nil?
|
|
|
|
unless titled_ref.instance_of? TitledRef
|
|
raise TypeError, "Expected #{TitledRef}, got #{titled_ref.class}"
|
|
end
|
|
|
|
@titled_ref = titled_ref
|
|
end
|
|
|
|
def build_ref(format)
|
|
return if titled_ref.nil?
|
|
|
|
case format
|
|
when :html
|
|
"<a href=\"#{titled_ref.url}\">#{titled_ref.title}</a>\n".freeze
|
|
when :gemtext
|
|
"=> #{titled_ref.url} #{unicode_decor_own}#{titled_ref.title} ".freeze
|
|
else
|
|
raise 'Invalid format'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|