repubmark/lib/repubmark/elems/joint.rb

177 lines
4.3 KiB
Ruby

# frozen_string_literal: true
module Repubmark
module Elems
class Joint < Base
parents :Caption, :Quote
def initialize(parent)
super parent
@raw1 = nil
@base = nil
@raw2 = nil
@notes = []
@raw3 = nil
@context = nil
@context_note = false
end
#################
# Basic methods #
#################
def word_count = components.sum(&:word_count)
def to_summary_plain = components.map(&:to_summary_plain).join.freeze
def to_html = components.map(&:to_html).join.freeze
def to_gemtext = components.map(&:to_gemtext).join.freeze
########################
# Builder methods: Raw #
########################
def raw(str)
text = Text.new self, str
if @notes.any?
raise 'Joint raw text already exists' if @raw3
@raw3 = text
elsif @base
raise 'Joint raw text already exists' if @raw2
@raw2 = text
else
raise 'Joint raw text already exists' if @raw1
@raw1 = text
end
end
#########################
# Builder methods: Base #
#########################
def abbrev(abbrev, transcript) = base Abbrev.new self, abbrev, transcript
def bold(str) = base Text.new self, str, bold: true
def code_inline(str) = base CodeInline.new self, str
def ellipsis = base Special.new self, :ellipsis
def fraction(top, bottom) = base Fraction.new self, top, bottom
def italic(str) = base Text.new self, str, italic: true
def link(text, uri) = base Link.new self, text, uri
def link_italic(text, uri) = base Link.new self, text, uri, italic: true
def mdash = base Special.new self, :mdash
def power(base, exponent) = base Power.new self, base, exponent
def quote(str = nil)
quote = Quote.new self
case [!!str, block_given?]
when [true, false] then quote.text str
when [false, true] then yield quote
else
raise 'Invalid args'
end
base quote
end
def quote_italic(str)
quote = Quote.new self
quote.italic str
base quote
end
def section(*args) = base Section.new self, *args
def text(str) = base Text.new self, str
##########################
# Builder methods: Notes #
##########################
def context(index, anchor)
raise 'Context already given' if @context
@context = [index, anchor]
nil
end
def context_note
raise 'No context given' if @context.nil?
raise 'Context already noted' if @context_note
@context_note = true
ref_note(*@context)
end
def ref_note(index, anchor)
note Note.new self, index, anchor
end
private
def components
raise 'No context note' if @context && !@context_note
[@raw1, @base, @raw2, *@notes, @raw3].compact
end
def base(elem)
raise 'Joint base already exists' if @base
raise 'Joint notes already exist' if @notes.any?
@base = elem
nil
end
def note(elem)
raise 'Joint base does not exists' if @base.nil?
@notes << elem
nil
end
module ForwardingBuilders
def joint = raise NotImplementedError, "#{self.class}#joint"
def abbrev(*args) = joint { |joint| joint.abbrev(*args) }
def bold(*args) = joint { |joint| joint.bold(*args) }
def code_inline(*args) = joint { |joint| joint.code_inline(*args) }
def ellipsis(*args) = joint { |joint| joint.ellipsis(*args) }
def fraction(*args) = joint { |joint| joint.fraction(*args) }
def italic(*args) = joint { |joint| joint.italic(*args) }
def link(*args) = joint { |joint| joint.link(*args) }
def link_italic(*args) = joint { |joint| joint.link_italic(*args) }
def mdash(*args) = joint { |joint| joint.mdash(*args) }
def power(*args) = joint { |joint| joint.power(*args) }
def quote_italic(*args) = joint { |joint| joint.quote_italic(*args) }
def section(*args) = joint { |joint| joint.section(*args) }
def text(*args) = joint { |joint| joint.text(*args) }
end
end
end
end