Class: BibTeX::Value

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Comparable
Defined in:
lib/bibtex/value.rb

Overview

A BibTeX Value is something very much like a string. In BibTeX files it can appear on the right hand side of @string or @entry field assignments or as @preamble contents. In the example below [VALUE] indicates possible occurences of values in BibTeX:

@preamble{ "foo" [VALUE] }
@string{ foo = "foo" [VALUE] }
@book{id,
  author = {John Doe} [VALUE],
  title = foo # "bar" [VALUE]
}

All Values have in common that they can be simple strings in curly braces or double quotes or complex BibTeX string-concatenations (using the ‘#’ symbol).

Generally, Values try to behave as much as normal Ruby strings as possible; If you do not require any of the advanced BibTeX functionality (string replacement or concatentaion) you can simply convert them to strings using to_s. Note that BibTeX Names are special instances of Values which currently do not support string concatenation or replacement.

Direct Known Subclasses

Names

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*arguments) ⇒ Value

Returns a new instance of Value.



69
70
71
72
73
74
# File 'lib/bibtex/value.rb', line 69

def initialize(*arguments)
  @tokens = []
  arguments.flatten.compact.each do |argument|
    add(argument)
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



284
285
286
287
288
289
290
# File 'lib/bibtex/value.rb', line 284

def method_missing(name, *args)
  if name.to_s =~ /^(?:convert|from)_([a-z]+)(!)?$/
    Regexp.last_match(2) ? convert!(Regexp.last_match(1)) : convert(Regexp.last_match(1))
  else
    super
  end
end

Instance Attribute Details

#tokensObject (readonly) Also known as: to_a

Returns the value of attribute tokens.



48
49
50
# File 'lib/bibtex/value.rb', line 48

def tokens
  @tokens
end

Class Method Details

.create(*args) ⇒ Object

call-seq:

create(other) => other.dup
create(*args) => Value.new(args)

Duplicates a Value object (or an object of any subclass of Value), or initializes a new one.



65
66
67
# File 'lib/bibtex/value.rb', line 65

def self.create(*args)
  args[0].class < Value && args.size == 1 ? args[0].dup : Value.new(args)
end

Instance Method Details

#<=>(other) ⇒ Object



296
297
298
299
300
301
302
# File 'lib/bibtex/value.rb', line 296

def <=>(other)
  if numeric? && other.respond_to?(:numeric?) && other.numeric?
    to_i <=> other.to_i
  else
    to_s <=> other.to_s
  end
end

#add(argument) ⇒ Object Also known as: <<, push



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/bibtex/value.rb', line 101

def add(argument)
  case argument
  when Value
    @tokens += argument.tokens.dup
  when ::String
    @tokens << argument
  when Symbol
    @tokens << argument
  else
    if argument.respond_to?(:to_s)
      @tokens << argument.to_s
    else
      raise(ArgumentError, "Failed to create Value from argument #{argument.inspect}; expected String, Symbol or Value instance.")
    end
  end
  self
end

#atomic?Boolean

Returns true if the Value is empty or consists of a single token.

Returns:

  • (Boolean)


214
215
216
# File 'lib/bibtex/value.rb', line 214

def atomic?
  @tokens.length < 2
end

#convert(*filters) ⇒ Object

Returns a new Value with all string values converted according to the given filter(s).



270
271
272
# File 'lib/bibtex/value.rb', line 270

def convert(*filters)
  dup.convert!(*filters)
end

#convert!(*filters) ⇒ Object

Converts all string values according to the given filter(s).



275
276
277
278
279
280
281
282
# File 'lib/bibtex/value.rb', line 275

def convert!(*filters)
  filters.flatten.each do |filter|
    f = Filters.resolve!(filter)
    @tokens.map! { |t| f.apply(t) }
  end

  self
end

#date?Boolean

Returns true if the Value’s content is a date.

Returns:

  • (Boolean)


232
233
234
# File 'lib/bibtex/value.rb', line 232

def date?
  !to_date.nil?
end

#include_token?(token) ⇒ Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/bibtex/value.rb', line 97

def include_token?(token)
  @tokens.include?(token)
end

#initialize_copy(other) ⇒ Object



76
77
78
79
80
81
82
83
# File 'lib/bibtex/value.rb', line 76

def initialize_copy(other)
  @tokens = other.tokens.map do |token|
    if token.nil? then nil
    elsif token.is_a?(Symbol) then token
    else token.dup
    end
  end
end

#inspectObject



209
210
211
# File 'lib/bibtex/value.rb', line 209

def inspect
  "#<#{self.class} #{@tokens.map(&:inspect).join(', ')}>"
end

#join(separator = '') ⇒ Value

call-seq:

Value.new('foo', 'bar').join #=> <'foobar'>
Value.new(:foo, 'bar').join  #=> <:foo, 'bar'>

Parameters:

  • separator (String) (defaults to: '')

Returns:

  • (Value)

    the instance with all consecutive String tokens joined



154
155
156
157
158
159
160
161
162
163
# File 'lib/bibtex/value.rb', line 154

def join(separator = '')
  @tokens = @tokens.each_with_object([]) do |b, a|
    if a[-1].is_a?(::String) && b.is_a?(::String)
      a[-1] = [a[-1], b].join(separator)
    else
      a << b
    end
  end
  self
end

#merge(other) ⇒ Object



85
86
87
# File 'lib/bibtex/value.rb', line 85

def merge(other)
  dup.merge!(other)
end

#merge!(other) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/bibtex/value.rb', line 89

def merge!(other)
  other.tokens.each do |token|
    add token unless include_token?(token)
  end

  self
end

#name?Boolean Also known as: names?

Returns true if the value is a BibTeX name value.

Returns:

  • (Boolean)


219
220
221
# File 'lib/bibtex/value.rb', line 219

def name?
  false
end

#numeric?Boolean

Returns true if the Value’s content is numeric.

Returns:

  • (Boolean)


245
246
247
# File 'lib/bibtex/value.rb', line 245

def numeric?
  atomic? && @tokens[0] =~ /^\s*[+-]?\d+\s*$/
end

#replace(*arguments) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/bibtex/value.rb', line 131

def replace(*arguments)
  return self unless has_symbol?

  arguments.flatten.each do |argument|
    case argument
    when ::String # simulates Ruby's String#replace
      @tokens = [argument]
    when String
      @tokens = @tokens.map { |v| argument.key == v ? argument.value.tokens : v }.flatten
    when Hash
      @tokens = @tokens.map { |v| argument[v] || v }
    end
  end
  self
end

#respond_to?(method, include_all = false) ⇒ Boolean

Returns:

  • (Boolean)


292
293
294
# File 'lib/bibtex/value.rb', line 292

def respond_to?(method, include_all = false)
  method =~ /^(?:convert|from)_([a-z]+)(!)?$/ || super
end

#symbol?Boolean Also known as: has_symbol?

Returns true if the Value contains at least one symbol.

Returns:

  • (Boolean)


258
259
260
# File 'lib/bibtex/value.rb', line 258

def symbol?
  @tokens.detect { |v| v.is_a?(Symbol) }
end

#symbolsObject

Returns all symbols contained in the Value.



265
266
267
# File 'lib/bibtex/value.rb', line 265

def symbols
  @tokens.select { |v| v.is_a?(Symbol) }
end

#to_citeproc(options = {}) ⇒ Object



253
254
255
# File 'lib/bibtex/value.rb', line 253

def to_citeproc(options = {})
  to_s(options)
end

#to_dateObject

Returns the string as a date.



237
238
239
240
241
242
# File 'lib/bibtex/value.rb', line 237

def to_date
  require 'date'
  Date.parse(to_s)
rescue StandardError
  nil
end

#to_iObject



249
250
251
# File 'lib/bibtex/value.rb', line 249

def to_i
  @tokens[0].to_i
end

#to_nameObject Also known as: to_names



225
226
227
# File 'lib/bibtex/value.rb', line 225

def to_name
  Names.parse(to_s)
end

#to_s(options = {}) ⇒ Object

call-seq:

Value.new('foo').to_s                       #=> "foo"
Value.new(:foo).to_s                        #=> "foo"
Value.new('foo').to_s(:quotes => '"')       #=> "\"foo\""
Value.new(:foo).to_s(:quotes => '"')       #=> "foo"
Value.new('foo').to_s(:quotes => ['"','"']) #=> "\"foo\""
Value.new('foo').to_s(:quotes => ['{','}']) #=> "{foo}"
Value.new(:foo, 'bar').to_s                 #=> "foo # \"bar\""
Value.new('foo', 'bar').to_s                #=> "\"foo\" # \"bar\""
Value.new('\"u').to_s(:filter => :latex)    #=> "ü"

Returns a the Value as a string. @see #value; If the Value is atomic and the option :quotes is given, the string will be quoted using the quote symbols specified.

If the option :filter is given, the Value will be converted using the filter(s) specified.



182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/bibtex/value.rb', line 182

def to_s(options = {})
  if options.key?(:filter)
    return convert(options[:filter]).to_s(
      options.reject { |k,| k == :filter || (k == :quotes && (!atomic? || symbol?)) }
    )
  end

  return value.to_s unless options.key?(:quotes) && atomic? && !symbol?

  q = Array(options[:quotes])
  [q[0], value, q[-1]].compact.join
end

#valueObject Also known as: v

Returns the Value as a string or, if it consists of a single symbol, as a Symbol instance. If the Value contains multiple tokens, they will be joined by a ‘#’, additionally, all string tokens will be turned into string literals (i.e., delimitted by quotes).



199
200
201
202
203
204
205
# File 'lib/bibtex/value.rb', line 199

def value
  if atomic?
    @tokens[0]
  else
    @tokens.map { |v| v.is_a?(::String) ? v.inspect : v }.join(' # ')
  end
end