Class: BibTeX::Entry

Inherits:
Element show all
Extended by:
Forwardable
Includes:
Enumerable
Defined in:
lib/bibtex/entry.rb

Overview

Represents a regular BibTeX entry.

Constant Summary collapse

REQUIRED_FIELDS =

Hash containing the required fields of the standard entry types

Hash.new([]).merge({
	:article       => [:author,:title,:journal,:year],
	:book          => [[:author,:editor],:title,:publisher,:year],
	:booklet       => [:title],
	:conference    => [:author,:title,:booktitle,:year],
	:inbook        => [[:author,:editor],:title,[:chapter,:pages],:publisher,:year],
	:incollection  => [:author,:title,:booktitle,:publisher,:year],
	:inproceedings => [:author,:title,:booktitle,:year],
	:manual        => [:title],
	:mastersthesis => [:author,:title,:school,:year],
	:misc          => [],
	:phdthesis     => [:author,:title,:school,:year],
	:proceedings   => [:title,:year],
	:techreport    => [:author,:title,:institution,:year],
	:unpublished   => [:author,:title,:note]
}).freeze
NAME_FIELDS =
[:author,:editor,:translator].freeze
DATE_FIELDS =
[:year,:month].freeze
MONTHS =
[:jan,:feb,:mar,:apr,:may,:jun,:jul,:aug,:sep,:oct,:nov,:dec].freeze
MONTHS_FILTER =
Hash.new do |h,k|
  case k.to_s.strip
  when /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i
    h[k] = Value.new(k.to_s[0,3].downcase.to_sym)
  when /^\d\d?$/
    h[k] = Value.new(MONTHS[k.to_i - 1] || k)
  else
    h[k] = Value.new(k)
  end
end
CSL_FILTER =
Hash.new {|h,k|k}.merge(Hash[*%w{
  date      issued
  isbn      ISBN
  booktitle container-title
  journal   container-title
  series    collection-title
  address   publisher-place
  pages     page
  number    issue
  url       URL
  doi       DOI
  year      issued
}.map(&:intern)]).freeze
CSL_FIELDS =
%w{ abstract annote archive archive_location archive-place
  authority call-number chapter-number citation-label citation-number
  collection-title container-title DOI edition event event-place
  first-reference-note-number genre ISBN issue jurisdiction keyword locator 
  medium note number number-of-pages number-of-volumes original-publisher
  original-publisher-place original-title page page-first publisher
  publisher-place references section status title URL version volume
  year-suffix accessed container event-date issued original-date
  author editor translator recipient interviewer publisher composer
  original-publisher original-author container-author collection-editor
}.map(&:intern).freeze
CSL_TYPES =
Hash.new {|h,k|k}.merge(Hash[*%w{
  booklet        pamphlet
  conference     paper-conference
  inbook         chapter
  incollection   chapter
  inproceedings  paper-conference
  manual         book
  mastersthesis  thesis
  misc           article
  phdthesis      thesis
  proceedings    paper-conference
  techreport     report
  unpublished    manuscript
}.map(&:intern)]).freeze

Instance Attribute Summary collapse

Attributes inherited from Element

#bibliography

Instance Method Summary collapse

Methods inherited from Element

#matches?, #meets?, parse, #to_json, #to_yaml

Constructor Details

#initialize(attributes = {}) {|_self| ... } ⇒ Entry

Creates a new instance. If a hash is given, the entry is populated accordingly.

Yields:

  • (_self)

Yield Parameters:

  • _self (BibTeX::Entry)

    the object that the method was called on



109
110
111
112
113
114
115
116
117
118
# File 'lib/bibtex/entry.rb', line 109

def initialize(attributes = {})
	@fields = {}
  
  self.type = attributes.delete(:type) if attributes.has_key?(:type)
  self.key = attributes.delete(:key) if attributes.has_key?(:key)
	
	add(attributes)
	
	yield self if block_given?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



153
154
155
156
157
# File 'lib/bibtex/entry.rb', line 153

def method_missing(name, *args)
  return self[name] if @fields.has_key?(name)
  return self.send(:add, name.to_s.chop.to_sym, args[0]) if name.to_s.match(/=$/)		  
  super
end

Instance Attribute Details

#fieldsObject (readonly)

Returns the value of attribute fields.



105
106
107
# File 'lib/bibtex/entry.rb', line 105

def fields
  @fields
end

#typeObject

Returns the value of attribute type.



105
106
107
# File 'lib/bibtex/entry.rb', line 105

def type
  @type
end

Instance Method Details

#<=>(other) ⇒ Object



325
326
327
# File 'lib/bibtex/entry.rb', line 325

def <=>(other)
  type != other.type ? type <=> other.type : key != other.key ? key <=> other.key : to_s <=> other.to_s
end

#[](name) ⇒ Object

Returns the value of the field with the given name.



184
185
186
# File 'lib/bibtex/entry.rb', line 184

def [](name)
	@fields[name.to_sym]
end

#[]=(name, value) ⇒ Object

Adds a new field (name-value pair) to the entry. Returns the new value.



190
191
192
# File 'lib/bibtex/entry.rb', line 190

def []=(name, value)
	add(name.to_sym, value)
end

#add(*arguments) ⇒ Object Also known as: <<

Adds a new field (name-value pair) or multiple fields to the entry. Returns the entry for chainability.

call-seq: add(:author, “Edgar A. Poe”) add(:author, “Edgar A. Poe”, :title, “The Raven”) add([:author, “Edgar A. Poe”, :title, “The Raven”]) add(:author => “Edgar A. Poe”, :title => “The Raven”)



203
204
205
206
207
208
# File 'lib/bibtex/entry.rb', line 203

def add(*arguments)
  Hash[*arguments.flatten].each_pair do |name, value|
	  @fields[name.to_sym] = Value.new(value)
	end
	self
end

#added_to_bibliography(bibliography) ⇒ Object

Called when the element was added to a bibliography.



227
228
229
230
231
# File 'lib/bibtex/entry.rb', line 227

def added_to_bibliography(bibliography)
	super
	bibliography.entries[key] = self
	self
end

#content(options = {}) ⇒ Object

Returns a string of all the entry’s fields.



277
278
279
# File 'lib/bibtex/entry.rb', line 277

def content(options = {})
	@fields.map { |k,v| "#{k} = #{ @fields[k].to_s(options) }" }.join(",\n")
end

#delete(name) ⇒ Object

Removes the field with a given name from the entry. Returns the value of the deleted field; nil if the field was not set.



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

def delete(name)
	@fields.delete(name.to_sym)
end

#has_field?(field) ⇒ Boolean

Returns:

  • (Boolean)


149
150
151
# File 'lib/bibtex/entry.rb', line 149

def has_field?(field)
  @fields.has_key?(field)
end

#has_type?(type) ⇒ Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/bibtex/entry.rb', line 145

def has_type?(type)
  type.to_s.match(/^entry$/i) || @type == type.to_sym || super
end

#issuedObject Also known as: citeproc_date



304
305
306
307
308
# File 'lib/bibtex/entry.rb', line 304

def issued
  m = MONTHS.find_index(@fields[:month] && @fields[:month].v)
  m = m + 1 unless m.nil?
  { 'date-parts' => [[@fields[:year],m].compact.map(&:to_i)] }
end

#joinObject



246
247
248
249
# File 'lib/bibtex/entry.rb', line 246

def join
			@fields.values.each(&:join)
  self
end

#keyObject Also known as: id



132
133
134
# File 'lib/bibtex/entry.rb', line 132

def key
  @key ||= default_key
end

#key=(key) ⇒ Object Also known as: id=

Sets the key of the entry

Raises:

  • (ArgumentError)


121
122
123
124
125
126
127
128
129
130
# File 'lib/bibtex/entry.rb', line 121

def key=(key)
	raise(ArgumentError, "keys must be convertible to Symbol; was: #{type.class.name}.") unless type.respond_to?(:to_sym)

    unless @bibliography.nil?
			@bibliography.entries.delete(@key)
			@bibliography.entries[key] = self
    end

	@key = key.to_sym
end

#month=(month) ⇒ Object



251
252
253
# File 'lib/bibtex/entry.rb', line 251

def month=(month)
  @fields[:month] = MONTHS_FILTER[month]
end

#parse_monthObject Also known as: parse_months



255
256
257
258
# File 'lib/bibtex/entry.rb', line 255

def parse_month
  @fields[:month] = MONTHS_FILTER[@fields[:month]] if @fields.has_key?(:month)
  self
end

#parse_namesObject

Parses all name values of the entry. Tries to replace and join the value prior to parsing.



264
265
266
267
268
269
270
271
272
273
274
# File 'lib/bibtex/entry.rb', line 264

def parse_names
  NAME_FIELDS.each do |key|
    if name = @fields[key]
      name.replace(bibliography.q('@string')) unless bibliography.nil?
      name.join
      name = name.to_name
      @fields[key] = name
    end
  end
  self
end

#removed_from_bibliography(bibliography) ⇒ Object

Called when the element was removed from a bibliography.



234
235
236
237
238
# File 'lib/bibtex/entry.rb', line 234

def removed_from_bibliography(bibliography)
	super
	bibliography.entries[key] = nil
	self
end

#rename(*arguments) ⇒ Object Also known as: rename_fields

Returns a copy of the Entry with all the field names renamed.



164
165
166
# File 'lib/bibtex/entry.rb', line 164

def rename(*arguments)
  dup.rename!(*arguments)
end

#rename!(*arguments) ⇒ Object Also known as: rename_fields!

Renames the given field names unless a field with the new name already exists.



170
171
172
173
174
175
176
177
178
# File 'lib/bibtex/entry.rb', line 170

def rename!(*arguments)
  Hash[*arguments.flatten].each_pair do |from,to|
    if @fields.has_key?(from) && !@fields.has_key?(to)
      @fields[to] = @fields[from]
      @fields.delete(from)
     end
  end
  self
end

#replace(*arguments) ⇒ Object



240
241
242
243
244
# File 'lib/bibtex/entry.rb', line 240

def replace(*arguments)
  arguments = bibliography.q('@string') if arguments.empty?
	@fields.values.each { |v| v.replace(*arguments) }
	self
end

#respond_to?(method) ⇒ Boolean

Returns:

  • (Boolean)


159
160
161
# File 'lib/bibtex/entry.rb', line 159

def respond_to?(method)
  @fields.has_key?(method.to_sym) || method.to_s.match(/=$/) || super
end

#to_citeproc(options = {}) ⇒ Object



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

def to_citeproc(options = {})
  options[:quotes] ||= []
  hash = { 'id' => key.to_s, 'type' => CSL_TYPES[type].to_s }
    each_pair do |k,v|
    hash[CSL_FILTER[k].to_s] = v.to_citeproc(options) unless DATE_FIELDS.include?(k)
  end
  hash['issued'] = citeproc_date
  hash
end

#to_hash(options = {}) ⇒ Object



287
288
289
290
291
292
# File 'lib/bibtex/entry.rb', line 287

def to_hash(options = {})
  options[:quotes] ||= %w({ })
  hash = { :key => key, :type => type }
  each_pair { |k,v| hash[k] = v.to_s(options) }
  hash
end

#to_s(options = {}) ⇒ Object

Returns a string representation of the entry.



282
283
284
285
# File 'lib/bibtex/entry.rb', line 282

def to_s(options = {})
  options[:quotes] ||= %w({ })
	["@#{type}{#{key},", content(options).gsub(/^/,'  '), "}\n"].join("\n")
end

#to_xml(options = {}) ⇒ Object



312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/bibtex/entry.rb', line 312

def to_xml(options = {})
  require 'rexml/document'
   
		xml = REXML::Element.new(type)
		xml.attributes['key'] = key
    @fields.each do |k,v|
      e = REXML::Element.new(k.to_s)
      e.text = v.to_s(options)
      xml.add_element(e)
    end
    xml
end

#valid?Boolean

Returns false if the entry is one of the standard entry types and does not have definitions of all the required fields for that type.

Returns:

  • (Boolean)


220
221
222
223
224
# File 'lib/bibtex/entry.rb', line 220

def valid?
	REQUIRED_FIELDS[@type].all? do |f|
		f.is_a?(Array) ? !(f & @fields.keys).empty? : !@fields[f].nil?
	end
end