Class: BibTeX::Bibliography

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

Overview

The Bibliography class models a BibTeX bibliography; typically, it corresponds to a ‘.bib’ file.

Constant Summary collapse

DEFAULTS =
{ :parse_names => true, :parse_months => true }.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) {|_self| ... } ⇒ Bibliography

Creates a new bibliography.

Yields:

  • (_self)

Yield Parameters:



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

def initialize(options = {})
  @options = DEFAULTS.merge(options)
  @data, @strings, @entries = [], {}, {}

  yield self if block_given?
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



80
81
82
# File 'lib/bibtex/bibliography.rb', line 80

def data
  @data
end

#entriesObject (readonly)

Returns the value of attribute entries.



80
81
82
# File 'lib/bibtex/bibliography.rb', line 80

def entries
  @entries
end

#errorsObject (readonly)

Returns all objects which could not be parsed successfully.



196
197
198
# File 'lib/bibtex/bibliography.rb', line 196

def errors
  @errors
end

#optionsObject (readonly)

Returns the value of attribute options.



80
81
82
# File 'lib/bibtex/bibliography.rb', line 80

def options
  @options
end

#pathObject

Returns the value of attribute path.



79
80
81
# File 'lib/bibtex/bibliography.rb', line 79

def path
  @path
end

#stringsObject (readonly)

Returns the value of attribute strings.



80
81
82
# File 'lib/bibtex/bibliography.rb', line 80

def strings
  @strings
end

Class Method Details

.attr_by_type(*arguments) ⇒ Object

Defines a new accessor that selects elements by type.



71
72
73
74
75
76
# File 'lib/bibtex/bibliography.rb', line 71

def attr_by_type(*arguments)
  arguments.each do |type|
    method_id = "#{type}s"
    define_method(method_id) { find_by_type(type) } unless respond_to?(method_id)
  end
end

.open(path, options = {}) ⇒ Object

Opens and parses the ‘.bib’ file at the given path. Returns a new Bibliography instance corresponding to the file, or, if a block is given, yields the instance to the block, ensuring that the file is saved after the block’s execution (use the :out option if you want to specify a save path other than the path from where the file is loaded).

The options argument is passed on to BibTeX::Parser.new. Additional option parameters are:

-:parse_names: set to false to disable automatic name parsing -:parse_months: set to false to disable automatic month conversion -:filter: convert all entries using the sepcified filter (not set by default)



52
53
54
55
56
57
58
59
60
61
# File 'lib/bibtex/bibliography.rb', line 52

def open(path, options = {})
  b = parse(Kernel.open(path).read, options)
  return b unless block_given?

  begin
    yield b
  ensure
    b.save_to(options[:out] || path)
  end
end

.parse(bibtex, options = {}) ⇒ Object

Parses the given string and returns a corresponding Bibliography instance.



64
65
66
# File 'lib/bibtex/bibliography.rb', line 64

def parse(bibtex, options = {})
  Parser.new(options).parse(bibtex) || Bibliography.new(options)
end

Instance Method Details

#<=>(other) ⇒ Object



323
324
325
# File 'lib/bibtex/bibliography.rb', line 323

def <=>(other)
  other.respond_to?(:to_a) ? to_a <=> other.to_a : nil
end

#[](*arguments) ⇒ Object

Returns an element or a list of elements according to the given index, range, or query. Contrary to the Bibliography#query this method does not yield to a block for additional refinement of the query.

call-seq: >> bib

> Returns the last element of the Bibliography or nil

>> bib

> Returns the second and third elements or nil

>> bib >> Same as above >> bib

> Returns the first entry with key ‘key’ or nil

>> bib

> Returns all entries with key ‘key’ or []

>> bib

> Returns all entries of type ‘article’ or []

>> bib

> Returns all preamble objects (this is the same as Bibliography#preambles) or []

>> bib

> Returns all objects that match ‘ruby’ anywhere or []

>> bib[‘@book’]

> Returns all books whose keywords attribute equals ‘ruby’ or []

Raises:

  • (ArgumentError)


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

def [](*arguments)
  raise(ArgumentError, "wrong number of arguments (#{arguments.length} for 1..2)") unless arguments.length.between?(1,2)

  case
  when !([Range, Numeric] & arguments[0].class.ancestors).empty?
    @data[*arguments] 
  when arguments.length == 1 && arguments[0].is_a?(Symbol)
    @entries[arguments[0]]
  else
    query(*arguments)
  end
end

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

Adds a new element, or a list of new elements to the bibliography. Returns the Bibliography for chainability.



99
100
101
102
103
104
105
# File 'lib/bibtex/bibliography.rb', line 99

def add(*arguments)
  arguments.flatten.each do |element|
    raise(ArgumentError, "Failed to add #{ element.inspect } to Bibliography; instance of BibTeX::Element expected.") unless element.is_a?(Element)
    @data << element.added_to_bibliography(self)
  end
  self
end

#convert(filter) ⇒ Object

Converts all enties using the given filter. If an optional block is given the block is used as a condition (the block will be called with each entry). @see Entry#convert!



135
136
137
138
# File 'lib/bibtex/bibliography.rb', line 135

def convert (filter)
  @entries.each_value { |e| e.convert!(filter) if !block_given? || yield(e) }
  self
end

#delete(*arguments, &block) ⇒ Object Also known as: remove, rm

Deletes an object, or a list of objects from the bibliography. If a list of objects is to be deleted, you can either supply the list of objects or use a query or block to define the list.

Returns the object (or the list of objects) that were deleted; nil if the object was not part of the bibliography.



148
149
150
151
152
# File 'lib/bibtex/bibliography.rb', line 148

def delete(*arguments, &block)
  objects = q(*arguments, &block).map { |o| o.removed_from_bibliography(self) }
  @data = @data - objects
  objects.length == 1 ? objects[0] : objects
end

#errors?Boolean

Returns true if there are object which could not be parsed.

Returns:

  • (Boolean)


201
202
203
# File 'lib/bibtex/bibliography.rb', line 201

def errors?
  !errors.empty?
end

#find_by_type(*types, &block) ⇒ Object Also known as: find_by_types



317
318
319
# File 'lib/bibtex/bibliography.rb', line 317

def find_by_type(*types, &block)
  q(types.flatten.compact.map { |t| "@#{t}" }.join(', '), &block)
end

#join(filter = '') ⇒ Object Also known as: join_strings



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

def join(filter = '')
  q(filter, &:join)
  self
end

#parse_monthsObject



127
128
129
130
# File 'lib/bibtex/bibliography.rb', line 127

def parse_months
  @entries.each_value { |e| e.parse_month }
  self
end

#parse_namesObject



122
123
124
125
# File 'lib/bibtex/bibliography.rb', line 122

def parse_names
  @entries.each_value { |e| e.parse_names }
  self
end

#query(*arguments, &block) ⇒ Object Also known as: q

Returns objects in the Bibliography which match the given selector and, optionally, the conditions specified in the given block.

call-seq: bib.query() #=> returns all objects bib.query(:all) #=> returns all objects bib.query(:first) #=> returns the first object bib.query(‘@book’) #=> returns all books bib.query(:first, ‘@book, @article’) #=> returns the first book or article bib.query(‘@book, @article) #=> returns all books published in 2011 and all articles bib.query(’@book, @article) { |o| o.year == ‘2011’ } #=> returns all books and articles published in 2011 bib.query(‘@book, @article) #=> same as above without using a block

Raises:

  • (ArgumentError)


306
307
308
309
310
311
312
313
# File 'lib/bibtex/bibliography.rb', line 306

def query(*arguments, &block)
  raise(ArgumentError, "wrong number of arguments (#{arguments.length} for 0..2)") unless arguments.length.between?(0,2)

  q, selector = arguments.reverse
  filter = block ? Proc.new { |e| e.match?(q) && block.call(e) } : Proc.new { |e| e.match?(q) }

  send(query_handler(selector), &filter)
end

#rename(*arguments, &block) ⇒ Object



238
239
240
241
# File 'lib/bibtex/bibliography.rb', line 238

def rename(*arguments, &block)
  q('@entry') { |e| e.rename(*arguments, &block) }
  self
end

#replace(filter = '') ⇒ Object Also known as: replace_strings

Replaces all string symbols which are defined in the bibliography.

By default symbols in @string, @preamble and entries are replaced; this behaviour can be changed using the optional query parameter.

Note that strings are replaced in the order in which they occur in the bibliography.

call-seq: bib.replace #=> replaces all symbols bib.replace(‘@string, @preamble’) #=> replaces only symbols in @string and @preamble objects



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

def replace(filter = '')
  q(filter) { |e| e.replace(@strings.values) }
  self
end

#save(options = {}) ⇒ Object

Saves the bibliography to the current path.



111
112
113
# File 'lib/bibtex/bibliography.rb', line 111

def save(options = {})
  save_to(@path, options)
end

#save_to(path, options = {}) ⇒ Object

Saves the bibliography to a file at the given path. Returns the bibliography.



116
117
118
119
120
# File 'lib/bibtex/bibliography.rb', line 116

def save_to(path, options = {})
  options[:quotes] ||= %w({ })
  File.open(path, "w") { |f| f.write(to_s(options)) }
  self
end

#sort(*arguments, &block) ⇒ Object



243
244
245
246
# File 'lib/bibtex/bibliography.rb', line 243

def sort(*arguments, &block)
  @data.sort(*arguments, &block)
  self
end

#to_a(options = {}) ⇒ Object



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

def to_a(options = {})
  map { |o| o.to_hash(options) }
end

#to_citeproc(options = {}) ⇒ Object

Returns a CiteProc JSON representation of the bibliography. Only BibTeX enrties are exported.



273
274
275
# File 'lib/bibtex/bibliography.rb', line 273

def to_citeproc(options = {})
  q('@entry').map { |o| o.to_citeproc(options) }
end

#to_hash(options = {}) ⇒ Object

Returns a Ruby hash representation of the bibliography.



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

def to_hash(options = {})
  { :bibliography => map { |o| o.to_hash(options) } }
end

#to_json(options = {}) ⇒ Object

Returns a JSON representation of the bibliography.



268
269
270
# File 'lib/bibtex/bibliography.rb', line 268

def to_json(options = {})
  to_a(options).to_json
end

#to_s(options = {}) ⇒ Object

Returns a string representation of the bibliography.



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

def to_s(options = {})
  map { |o| o.to_s(options) }.join
end

#to_xmlObject

Returns an XML representation of the bibliography. Only BibTeX entries are exported.



278
279
280
281
282
283
284
285
286
287
# File 'lib/bibtex/bibliography.rb', line 278

def to_xml
  require 'rexml/document'
 
  xml = REXML::Document.new
  xml << REXML::XMLDecl.new('1.0','UTF-8')
  root = REXML::Element.new('bibliography')
  each { |e| root.add_element(e.to_xml) }
  xml << root
  xml
end

#to_yaml(options = {}) ⇒ Object

Returns a YAML representation of the bibliography.



263
264
265
# File 'lib/bibtex/bibliography.rb', line 263

def to_yaml(options = {})
  to_a(options).to_yaml
end

#valid?Boolean

Returns true if the Bibliography contains no errors and only valid BibTeX objects (meta content is ignored).

Returns:

  • (Boolean)


207
208
209
# File 'lib/bibtex/bibliography.rb', line 207

def valid?
  !errors? && @entries.values.all?(&:valid?)
end