177 lines
4.3 KiB
Ruby
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
|