class Rticles::Paragraph
Attributes
after_id[RW]
before_id[RW]
choices[W]
Public Class Methods
generate_html(paragraphs, options={})
click to toggle source
# File lib/rticles/paragraph.rb, line 238 def self.generate_html(paragraphs, options={}) paragraph_groups = [] paragraphs.each do |paragraph| if paragraph.continuation? paragraph_groups.last.push(paragraph) else paragraph_groups.push([paragraph]) end end generate_html_for_paragraph_groups(paragraph_groups, options) end
Protected Class Methods
generate_html_for_paragraph_groups(paragraph_groups, options={})
click to toggle source
# File lib/rticles/paragraph.rb, line 252 def self.generate_html_for_paragraph_groups(paragraph_groups, options={}) previous_type = nil # Remove paragraph groups that should not be displayed, given the choices that have been passed in paragraph_groups = paragraph_groups.map do |pg| first_paragraph = pg[0] first_paragraph.choices = options[:choices] if first_paragraph.resolve_choices(first_paragraph.body) pg else nil end end paragraph_groups = paragraph_groups.compact return "" if paragraph_groups.empty? # Handle last paragraph group separately so we can do list punctuation if necessary. paragraph_groups_except_last = paragraph_groups[0..-2] last_paragraph_group = paragraph_groups[-1] html = paragraph_groups_except_last.inject("") do |memo, paragraph_group| # FIXME: Don't generate HTML by interpolating into a string; # use some standard library function that provides some safe # escaping defaults, etc.. if options[:list] options[:list_punctuation] = ';' end first_paragraph = paragraph_group[0] if first_paragraph.heading? if previous_type == :paragraph memo += "</ol>" end if paragraph_group.length == 1 memo += generate_html_for_paragraphs(paragraph_group, options) else memo += "<hgroup>#{generate_html_for_paragraphs(paragraph_group, options)}</hgroup>" end previous_type = :heading else unless previous_type == :paragraph memo += "<ol>" end index = first_paragraph.index(options[:choices]) li_opening_tag = "<li value=\"#{index}\">" memo += "#{li_opening_tag}#{generate_html_for_paragraphs(paragraph_group, options)}</li>" previous_type = :paragraph end memo end # Process final paragraph group if options[:list] options[:list_punctuation] = '.' end first_paragraph = last_paragraph_group[0] if first_paragraph.heading? if previous_type == :paragraph html += "</ol>" end if last_paragraph_group.length == 1 html += generate_html_for_paragraphs(last_paragraph_group, options) else html += "<hgroup>#{generate_html_for_paragraphs(last_paragraph_group, options)}</hgroup>" end previous_type = :heading else unless previous_type == :paragraph html += "<ol>" end index = first_paragraph.index(options[:choices]) li_opening_tag = "<li value=\"#{index}\">" html += "#{li_opening_tag}#{generate_html_for_paragraphs(last_paragraph_group, options)}</li>" previous_type = :paragraph end if previous_type == :paragraph html += "</ol>" end end
generate_html_for_paragraphs(paragraphs, options={})
click to toggle source
# File lib/rticles/paragraph.rb, line 340 def self.generate_html_for_paragraphs(paragraphs, options={}) paragraphs.inject("") do |memo, paragraph| body = paragraph.body_for_display({:with_index => true}.merge(options)) return memo if body.nil? if paragraph.heading? memo += "<h#{paragraph.heading_level}>#{body}#{options[:list_punctuation]}</h#{paragraph.heading_level}>" else memo += "#{body}#{options[:list_punctuation]}" end if !paragraph.children.empty? memo += generate_html(paragraph.children, options.merge(list: paragraph.list?, list_punctuation: nil)) end memo end end
Public Instance Methods
ancestors()
click to toggle source
# File lib/rticles/paragraph.rb, line 91 def ancestors node = self nodes = [] nodes.push(node = node.parent) while node.parent nodes end
body_for_display(options={})
click to toggle source
# File lib/rticles/paragraph.rb, line 164 def body_for_display(options={}) options = options.with_indifferent_access if options[:insertions] @insertions = options[:insertions] end if options[:choices] @choices = options[:choices] end with_meta_characters = options[:with_meta_characters] || false result = resolve_choices(body) return result if result.nil? result = resolve_references(result, with_meta_characters) result = resolve_insertions(result) if options[:with_index] && full_index(true, choices, options[:numbering_config]) result = "#{full_index} #{result}" end result end
body_with_resolved_references(with_meta_characters=false)
click to toggle source
# File lib/rticles/paragraph.rb, line 190 def body_with_resolved_references(with_meta_characters=false) resolve_references(body, with_meta_characters) end
can_indent?()
click to toggle source
# File lib/rticles/paragraph.rb, line 106 def can_indent? !!higher_item end
can_move_higher?()
click to toggle source
# File lib/rticles/paragraph.rb, line 102 def can_move_higher? !!higher_item end
can_move_lower?()
click to toggle source
# File lib/rticles/paragraph.rb, line 98 def can_move_lower? !!lower_item end
can_outdent?()
click to toggle source
# File lib/rticles/paragraph.rb, line 118 def can_outdent? !!parent_id end
full_index(recalculate=false, choices=nil, numbering_config=nil)
click to toggle source
# File lib/rticles/paragraph.rb, line 72 def full_index(recalculate=false, choices=nil, numbering_config=nil) return nil if heading? || continuation? return @full_index if @full_index && !recalculate if numbering_config.nil? numbering_config = Rticles::Numbering::Config.new end if numbering_config.innermost_only @full_index = numbering_config[level].format.sub('#', Rticles::Numbering.number_to_string(index(choices), numbering_config[level].style)) else @full_index = ancestors.unshift(self).reverse.map do |p| numbering_config[p.level].format.sub('#', Rticles::Numbering.number_to_string(p.index(choices), numbering_config[p.level].style)) end @full_index = @full_index.join(numbering_config.separator) end end
heading?()
click to toggle source
# File lib/rticles/paragraph.rb, line 48 def heading? heading && heading > 0 end
heading_level()
click to toggle source
# File lib/rticles/paragraph.rb, line 52 def heading_level ancestors.length + (heading ? heading : 0) end
higher_items()
click to toggle source
# File lib/rticles/paragraph.rb, line 132 def higher_items return nil unless in_list? acts_as_list_class.where( "#{scope_condition} AND #{position_column} < #{(send(position_column).to_i).to_s}" ) end
indent!()
click to toggle source
# File lib/rticles/paragraph.rb, line 110 def indent! return unless can_indent? new_parent_id = higher_item.id remove_from_list update_attribute(:parent_id, new_parent_id) send(:assume_bottom_position) end
index(choices=nil)
click to toggle source
# File lib/rticles/paragraph.rb, line 60 def index(choices=nil) return nil if heading? || continuation? predecessors = higher_items.where(['(heading = 0 OR heading IS NULL) AND (continuation = ? OR continuation IS NULL)', false]) if choices.present? predecessors = predecessors.for_choices(choices) end predecessors.count + 1 end
level()
click to toggle source
# File lib/rticles/paragraph.rb, line 56 def level ancestors.length + 1 end
lower_items()
click to toggle source
# File lib/rticles/paragraph.rb, line 139 def lower_items return nil unless in_list? acts_as_list_class.where( "#{scope_condition} AND #{position_column} > #{(send(position_column).to_i).to_s}" ) end
normalise_references()
click to toggle source
# File lib/rticles/paragraph.rb, line 154 def normalise_references return if body.blank? raw_reference_re = /!(\d\.)*\d/ Rails.logger.debug("Body: #{body}") self.body = body.gsub(raw_reference_re) do |match| raw_reference = match.sub('!', '') '#rticles#' + document.paragraph_for_reference(raw_reference).id.to_s end end
outdent!()
click to toggle source
# File lib/rticles/paragraph.rb, line 122 def outdent! return unless can_outdent? new_parent_id = parent.parent_id new_position = parent.position + 1 reparent_lower_items_under_self remove_from_list update_attribute(:parent_id, new_parent_id) insert_at(new_position) end
prepare_for_editing()
click to toggle source
# File lib/rticles/paragraph.rb, line 233 def prepare_for_editing self.body = body_with_resolved_references(true) self end
reparent_lower_items_under_self()
click to toggle source
# File lib/rticles/paragraph.rb, line 146 def reparent_lower_items_under_self return unless in_list? acts_as_list_class.update_all( "#{position_column} = (#{position_column} - #{position}), parent_id = #{id}", "#{scope_condition} AND #{position_column} > #{send(position_column).to_i}" ) end
resolve_choices(string)
click to toggle source
# File lib/rticles/paragraph.rb, line 218 def resolve_choices(string) choice_re = /\A#rticles#(true|false)#([A-Za-z_]+) / match = string.match(choice_re) return string if !match choice_name = match[2] choice_parameter = match[1] if (choices[choice_name] && choice_parameter == 'true') || (!choices[choice_name] && choice_parameter == 'false') string.sub(choice_re, '') else nil end end
resolve_insertions(string)
click to toggle source
# File lib/rticles/paragraph.rb, line 205 def resolve_insertions(string) return string if string.blank? insertion_re = /#rticles#([A-Za-z_]+)/ string.gsub(insertion_re) do |match| insertion_name = match.sub('#rticles#', '') if insertions[insertion_name].present? insertions[insertion_name].to_s.gsub("\n", "<br>") else "[#{insertion_name.humanize.upcase}]" end end end
resolve_references(string, with_meta_characters=false)
click to toggle source
# File lib/rticles/paragraph.rb, line 194 def resolve_references(string, with_meta_characters=false) return string if string.blank? normalised_reference_re = /#rticles#(\d+)/ string.gsub(normalised_reference_re) do |match| normalised_reference = match.sub('#rticles#', '') result = with_meta_characters ? '!' : '' result += document.paragraphs.find(normalised_reference).full_index result end end
set_document_id()
click to toggle source
# File lib/rticles/paragraph.rb, line 27 def set_document_id if parent self.document_id ||= parent.document_id end end
set_parent_and_position()
click to toggle source
# File lib/rticles/paragraph.rb, line 36 def set_parent_and_position if before_id.present? sibling = self.class.find(before_id) self.update_attribute(:parent_id, sibling.parent_id) insert_at(sibling.position) elsif after_id.present? sibling = self.class.find(after_id) self.update_attribute(:parent_id, sibling.parent_id) insert_at(self.class.find(after_id).position + 1) end end
Protected Instance Methods
choices()
click to toggle source
# File lib/rticles/paragraph.rb, line 367 def choices if @choices @choices.with_indifferent_access else {}.with_indifferent_access end end
insertions()
click to toggle source
# File lib/rticles/paragraph.rb, line 358 def insertions return @insertions.with_indifferent_access if @insertions begin (parent || document).insertions.with_indifferent_access rescue NoMethodError raise RuntimeError, "parent was nil when finding insertions; I am: #{self.inspect}" end end