class CiteProc::Ruby::Format

Attributes

available[R]
stopwords[R]
input[R]
locale[R]
node[R]
output[R]

Public Class Methods

inherited(base) click to toggle source
# File lib/citeproc/ruby/format.rb, line 24
def inherited(base)
  Format.available << base
end
load(name = nil) click to toggle source
# File lib/citeproc/ruby/format.rb, line 28
def load(name = nil)
  return new unless name
  return name if name.is_a?(Format)

  name = name.to_s.downcase

  klass = available.detect do |format|
    format.name.split('::')[-1].downcase == name
  end

  raise(Error, "unknown format: #{name}") unless klass

  klass.new
end
squeezable() click to toggle source
# File lib/citeproc/ruby/format.rb, line 52
def squeezable
  @squeezable ||= Format.squeezable
end
squeezable?(string) click to toggle source
# File lib/citeproc/ruby/format.rb, line 48
def squeezable?(string)
  squeezable === string
end
stopword?(word, locale = :en) click to toggle source
# File lib/citeproc/ruby/format.rb, line 43
def stopword?(word, locale = :en)
  return unless stopwords.key?(locale)
  stopwords[locale].include?(word.downcase)
end

Public Instance Methods

apply(input, node, locale = nil) click to toggle source
# File lib/citeproc/ruby/format.rb, line 142
def apply(input, node, locale = nil)
  return '' if input.nil?
  return input if input.empty? || node.nil?

  return ArgumentError unless node.respond_to?(:formatting_options)


  @input, @output, @node, @locale = input, input.dup, node, locale

  setup!

  # NB: Layout nodes apply formatting to
  # affixes; all other nodes do not!
  if node.is_a? CSL::Style::Layout
    apply_prefix if options.key?(:prefix)
    apply_suffix if options.key?(:suffix)
  end

  keys.each do |format|
    if options.key?(format)
      method = "apply_#{format}".tr('-', '_')
      send method if respond_to?(method)
    end
  end unless options.empty?

  output.gsub!(/\.+/, '') if node.strip_periods?

  apply_quotes if node.quotes? && !locale.nil?

  finalize_content!

  unless node.is_a? CSL::Style::Layout
    apply_prefix if options.key?(:prefix)
    apply_suffix if options.key?(:suffix)
  end

  apply_display if options.key?(:display)

  finalize!

  output
ensure
  cleanup!
end
apply_display() click to toggle source
# File lib/citeproc/ruby/format.rb, line 263
def apply_display
end
apply_prefix() click to toggle source
# File lib/citeproc/ruby/format.rb, line 266
def apply_prefix
  output.replace(squeeze_prefix(output, prefix))
end
apply_quotes() click to toggle source
# File lib/citeproc/ruby/format.rb, line 203
def apply_quotes
  output.replace locale.quote(output, escape_quotes?)
end
apply_suffix() click to toggle source
# File lib/citeproc/ruby/format.rb, line 270
def apply_suffix
  output.replace(squeeze_suffix(output, suffix))
end
apply_text_case() click to toggle source
# File lib/citeproc/ruby/format.rb, line 207
def apply_text_case
  case options[:'text-case']
  when 'lowercase'
    output.replace CiteProc.downcase output

  when 'uppercase'
    output.replace CiteProc.upcase output

  when 'capitalize-first'
    output.sub!(/^([^\p{L}]*)(\p{Ll})/) { "#{$1}#{CiteProc.upcase($2)}" }

  when 'capitalize-all'
    output.gsub!(/\b(\p{Ll})/) { CiteProc.upcase($1) }

  when 'sentence'
    output.sub!(/^([^\p{L}]*)(\p{Ll})/) { "#{$1}#{CiteProc.upcase($2)}" }
    output.gsub!(/\b(\p{Lu})(\p{Lu}+)\b/) { "#{$1}#{CiteProc.downcase($2)}" }

  when 'title'
    return if locale && locale.language != :en

    # TODO add support for stop words consisting of multiple words
    #output.gsub!(/\b(\p{Lu})(\p{Lu}+)\b/) { "#{$1}#{CiteProc.downcase($2)}" }

    # TODO exceptions: word followed by colon
    first = true
    output.gsub!(/\b(\p{L})([\p{L}\.]+)\b/) do |word|
      first_letter = $1
      rest_of_word = $2
      result = word

      if first_letter.match(/^\p{Ll}/) && (!Format.stopword?(word) || first)
        result = "#{CiteProc.upcase(first_letter)}#{rest_of_word}"
      end
      first = false
      result
    end

    output.gsub!(/(\.|\b)(\p{Ll})([\p{L}\.]+)\b$/) do |word|
      word_boundary = $1
      first_letter = $2
      rest_of_word = $3

      if word_boundary == '.'
        word
      else
        "#{CiteProc.upcase(first_letter)}#{rest_of_word}"
      end
    end
  end
end
bibliography(bibliography, locale = nil) click to toggle source
# File lib/citeproc/ruby/format.rb, line 137
def bibliography(bibliography, locale = nil)
  bibliography.connector = "\n" * bibliography.entry_spacing
  bibliography
end
close_inner_quote() click to toggle source
# File lib/citeproc/ruby/format.rb, line 195
def close_inner_quote
  locale && locale.t('close-inner-quote') || "'"
end
close_quote() click to toggle source
# File lib/citeproc/ruby/format.rb, line 191
def close_quote
  locale && locale.t('close-quote') ||  '"'
end
concat(string, suffix)
Alias for: squeeze_suffix
escape_quotes?() click to toggle source
# File lib/citeproc/ruby/format.rb, line 187
def escape_quotes?
  false
end
join(list, delimiter = nil) click to toggle source
# File lib/citeproc/ruby/format.rb, line 121
def join(list, delimiter = nil)
  raise ArgumentError unless list.is_a?(Enumerable)
  return '' if list.length.zero?
  return list[0] if list.length == 1

  if delimiter.nil? || delimiter.empty?
    list.inject do |m, n|
      concat(m, n)
    end
  else
    list.inject do |m, n|
      concat(concat(m, delimiter), n)
    end
  end
end
keys() click to toggle source
# File lib/citeproc/ruby/format.rb, line 59
def keys
  @keys ||= (CSL::Schema.attr(:formatting) - [:prefix, :suffix, :display])
end
prefix() click to toggle source
# File lib/citeproc/ruby/format.rb, line 274
def prefix
  options[:prefix].to_s
end
punctuation_in_quotes?() click to toggle source
# File lib/citeproc/ruby/format.rb, line 259
def punctuation_in_quotes?
  !locale.nil? && locale.punctuation_in_quotes?
end
split_closing_quotes(string) click to toggle source
# File lib/citeproc/ruby/format.rb, line 199
def split_closing_quotes(string)
  string.split(/([#{close_inner_quote}#{close_quote}]+)$/, 2)
end
squeezable?(string) click to toggle source
# File lib/citeproc/ruby/format.rb, line 63
def squeezable?(string)
  self.class.squeezable?(string)
end
squeeze_prefix(string, prefix) click to toggle source
# File lib/citeproc/ruby/format.rb, line 108
def squeeze_prefix(string, prefix)
  raise ArgumentError unless string.is_a?(::String)
  raise ArgumentError unless prefix.is_a?(::String)

  prefix = prefix.reverse.each_char.drop_while.with_index { |c, i|
    squeezable?(c) && string.start_with?(prefix[-(i + 1) .. -1])
  }.join('').reverse

  "#{prefix}#{string}"
end
squeeze_suffix(string, suffix) click to toggle source
# File lib/citeproc/ruby/format.rb, line 67
def squeeze_suffix(string, suffix)
  raise ArgumentError unless string.is_a?(::String)
  raise ArgumentError unless suffix.is_a?(::String)

  return string.dup if suffix.empty?
  return suffix.dup if string.empty?

  string, stripped = strip(string)
  string, quotes = split_closing_quotes(string)

  suffix = decode_entities(suffix)

  suffix = suffix.each_char.drop_while.with_index { |c, i|
    squeezable?(c) && string.end_with?(suffix[0, i + 1])
  }.join('')

  # Handle special cases like ?. or ;.
  if suffix.start_with?('.') && string.end_with?(';', ',', '!', '?', ':')
    suffix = suffix[1..-1]
  end

  # Handle special cases ;, and :,
  if suffix.start_with?(',') && string.end_with?(';', ':')
    suffix = suffix[1..-1]
  end

  # Handle special cases ,; and :;
  if suffix.start_with?(';') && string.end_with?(',', ':')
    suffix = suffix[1..-1]
  end

  # Handle punctiation-in-quote
  if !quotes.nil? && punctuation_in_quotes?
    if suffix.sub!(/^([\.,])/, '')
      punctuation = ($1).to_s
    end
  end

  "#{string}#{punctuation}#{quotes}#{stripped}#{suffix}"
end
Also aliased as: concat
strip(string) click to toggle source
# File lib/citeproc/ruby/format.rb, line 282
def strip(string)
  string
end
suffix() click to toggle source
# File lib/citeproc/ruby/format.rb, line 278
def suffix
  options[:suffix].to_s
end

Protected Instance Methods

cleanup!() click to toggle source
# File lib/citeproc/ruby/format.rb, line 309
def cleanup!
  @input, @output, @node, @options = nil
end
decode_entities(string) click to toggle source
# File lib/citeproc/ruby/format.rb, line 303
def decode_entities(string)
  string.gsub(/&#x([0-9a-f]);/) do
    [Integer("0x#{$1}")].pack('U')
  end
end
finalize!() click to toggle source
# File lib/citeproc/ruby/format.rb, line 294
def finalize!
end
finalize_content!() click to toggle source
# File lib/citeproc/ruby/format.rb, line 297
def finalize_content!
end
options() click to toggle source
# File lib/citeproc/ruby/format.rb, line 290
def options
  @options ||= @node.formatting_options
end
setup!() click to toggle source
# File lib/citeproc/ruby/format.rb, line 300
def setup!
end