bibtex-ruby 2.1.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bibtex-ruby might be problematic. Click here for more details.
- data/Gemfile.lock +1 -1
- data/History.txt +6 -0
- data/lib/bibtex/bibliography.rb +76 -71
- data/lib/bibtex/elements.rb +12 -1
- data/lib/bibtex/entry.rb +166 -121
- data/lib/bibtex/value.rb +26 -3
- data/lib/bibtex/version.rb +2 -2
- data/test/bibtex/test_bibliography.rb +53 -38
- data/test/bibtex/test_entry.rb +90 -57
- data/test/bibtex/test_names.rb +14 -0
- data/test/bibtex/test_value.rb +22 -12
- metadata +4 -4
data/lib/bibtex/entry.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
#--
|
2
2
|
# BibTeX-Ruby
|
3
3
|
# Copyright (C) 2010-2012 Sylvester Keil <sylvester.keil.or.at>
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# This program is free software: you can redistribute it and/or modify
|
6
6
|
# it under the terms of the GNU General Public License as published by
|
7
7
|
# the Free Software Foundation, either version 3 of the License, or
|
8
8
|
# (at your option) any later version.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# This program is distributed in the hope that it will be useful,
|
11
11
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
12
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
13
|
# GNU General Public License for more details.
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# You should have received a copy of the GNU General Public License
|
16
16
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
17
|
#++
|
@@ -21,7 +21,7 @@ module BibTeX
|
|
21
21
|
# Represents a regular BibTeX entry.
|
22
22
|
#
|
23
23
|
class Entry < Element
|
24
|
-
extend Forwardable
|
24
|
+
extend Forwardable
|
25
25
|
include Enumerable
|
26
26
|
|
27
27
|
# Defines the required fields of the standard entry types
|
@@ -47,11 +47,11 @@ module BibTeX
|
|
47
47
|
:booktitle => :title,
|
48
48
|
# :editor => :author
|
49
49
|
}.freeze
|
50
|
-
|
51
|
-
|
50
|
+
|
51
|
+
|
52
52
|
NAME_FIELDS = [:author,:editor,:translator].freeze
|
53
53
|
DATE_FIELDS = [:year,:month].freeze
|
54
|
-
|
54
|
+
|
55
55
|
MONTHS = [:jan,:feb,:mar,:apr,:may,:jun,:jul,:aug,:sep,:oct,:nov,:dec].freeze
|
56
56
|
|
57
57
|
MONTHS_FILTER = Hash.new do |h,k|
|
@@ -64,7 +64,7 @@ module BibTeX
|
|
64
64
|
h[k] = Value.new(k)
|
65
65
|
end
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
CSL_FILTER = Hash.new {|h,k|k}.merge(Hash[*%w{
|
69
69
|
date issued
|
70
70
|
isbn ISBN
|
@@ -82,7 +82,7 @@ module BibTeX
|
|
82
82
|
CSL_FIELDS = %w{ abstract annote archive archive_location archive-place
|
83
83
|
authority call-number chapter-number citation-label citation-number
|
84
84
|
collection-title container-title DOI edition event event-place
|
85
|
-
first-reference-note-number genre ISBN issue jurisdiction keyword locator
|
85
|
+
first-reference-note-number genre ISBN issue jurisdiction keyword locator
|
86
86
|
medium note number number-of-pages number-of-volumes original-publisher
|
87
87
|
original-publisher-place original-title page page-first publisher
|
88
88
|
publisher-place references section status title URL version volume
|
@@ -90,7 +90,7 @@ module BibTeX
|
|
90
90
|
author editor translator recipient interviewer publisher composer
|
91
91
|
original-publisher original-author container-author collection-editor
|
92
92
|
}.map(&:intern).freeze
|
93
|
-
|
93
|
+
|
94
94
|
CSL_TYPES = Hash.new {|h,k|k}.merge(Hash[*%w{
|
95
95
|
booklet pamphlet
|
96
96
|
conference paper-conference
|
@@ -136,33 +136,51 @@ module BibTeX
|
|
136
136
|
article Article
|
137
137
|
}.map(&:intern)]).freeze
|
138
138
|
|
139
|
-
|
139
|
+
|
140
140
|
attr_reader :fields, :type
|
141
|
-
|
141
|
+
|
142
142
|
def_delegators :@fields, :empty?
|
143
143
|
|
144
144
|
# Creates a new instance. If a hash is given, the entry is populated accordingly.
|
145
145
|
def initialize(attributes = {})
|
146
146
|
@fields = {}
|
147
|
-
|
147
|
+
|
148
148
|
self.type = attributes.delete(:type) if attributes.has_key?(:type)
|
149
149
|
self.key = attributes.delete(:key) if attributes.has_key?(:key)
|
150
|
-
|
150
|
+
|
151
151
|
add(attributes)
|
152
|
-
|
152
|
+
|
153
153
|
yield self if block_given?
|
154
154
|
end
|
155
155
|
|
156
|
-
def initialize_copy
|
156
|
+
def initialize_copy(other)
|
157
157
|
@fields = {}
|
158
|
-
|
158
|
+
|
159
159
|
self.type = other.type
|
160
160
|
self.key = other.key
|
161
|
-
|
161
|
+
|
162
162
|
add(other.fields)
|
163
163
|
end
|
164
164
|
|
165
|
+
def merge(other, filter = field_names)
|
166
|
+
dup.merge!(other, filter)
|
167
|
+
end
|
168
|
+
|
169
|
+
def merge!(other, filter = field_names)
|
170
|
+
raise InvalidArgument, "failed to merge entries: type mismatch: #{type} #{other.type}" unless
|
171
|
+
type == other.type
|
165
172
|
|
173
|
+
other.each do |name, value|
|
174
|
+
if has_field?(name)
|
175
|
+
get(name).merge!(value) if filter.include?(name)
|
176
|
+
else
|
177
|
+
add name, value.dup
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
self
|
182
|
+
end
|
183
|
+
|
166
184
|
# Generate Accessors for required fields (#52)
|
167
185
|
|
168
186
|
REQUIRED_FIELDS.values.flatten.uniq.each do |name|
|
@@ -177,12 +195,12 @@ module BibTeX
|
|
177
195
|
nil
|
178
196
|
end
|
179
197
|
end
|
180
|
-
|
198
|
+
|
181
199
|
define_method("#{name}=") do |value|
|
182
200
|
add name, value
|
183
201
|
end
|
184
202
|
end
|
185
|
-
|
203
|
+
|
186
204
|
# call-seq:
|
187
205
|
# entry.each { |key, value| block } -> entry
|
188
206
|
# entry.each_pair { |key, value| block } -> entry
|
@@ -201,15 +219,15 @@ module BibTeX
|
|
201
219
|
to_enum
|
202
220
|
end
|
203
221
|
end
|
204
|
-
|
222
|
+
|
205
223
|
alias each_pair each
|
206
|
-
|
207
|
-
|
224
|
+
|
225
|
+
|
208
226
|
# Returns the Entry's field name aliases.
|
209
227
|
def aliases
|
210
228
|
@aliases ||= FIELD_ALIASES.dup
|
211
229
|
end
|
212
|
-
|
230
|
+
|
213
231
|
# Sets the Entry's key. If the Entry is currently registered with a
|
214
232
|
# Bibliography, re-registers the Entry with the new key; note that this
|
215
233
|
# may change the key value if another Entry is already regsitered with
|
@@ -218,7 +236,7 @@ module BibTeX
|
|
218
236
|
# Returns the new key.
|
219
237
|
def key=(key)
|
220
238
|
key = key.to_s
|
221
|
-
|
239
|
+
|
222
240
|
if registered?
|
223
241
|
bibliography.entries.delete(@key)
|
224
242
|
key = register(key)
|
@@ -228,7 +246,7 @@ module BibTeX
|
|
228
246
|
rescue => e
|
229
247
|
raise BibTeXError, "failed to set key to #{key.inspect}: #{e.message}"
|
230
248
|
end
|
231
|
-
|
249
|
+
|
232
250
|
def key
|
233
251
|
@key ||= default_key
|
234
252
|
end
|
@@ -240,14 +258,14 @@ module BibTeX
|
|
240
258
|
def type=(type)
|
241
259
|
@type = type.to_sym
|
242
260
|
end
|
243
|
-
|
261
|
+
|
244
262
|
def has_type?(type)
|
245
263
|
type.to_s.match(/^(?:entry|\*)$/i) || @type == type.to_sym || super
|
246
264
|
end
|
247
|
-
|
265
|
+
|
248
266
|
alias type? has_type?
|
249
|
-
|
250
|
-
|
267
|
+
|
268
|
+
|
251
269
|
def has_field?(*names)
|
252
270
|
names.flatten.any? do |name|
|
253
271
|
name.respond_to?(:to_sym) ? fields.has_key?(name.to_sym) : false
|
@@ -261,7 +279,7 @@ module BibTeX
|
|
261
279
|
!has_field(name) && has_parent? && parent.provides?(name)
|
262
280
|
end
|
263
281
|
end
|
264
|
-
|
282
|
+
|
265
283
|
# Returns true if the Entry has a field (or alias) for any of the passed-in names.
|
266
284
|
def provides?(*names)
|
267
285
|
names.flatten.any? do |name|
|
@@ -272,20 +290,20 @@ module BibTeX
|
|
272
290
|
end
|
273
291
|
end
|
274
292
|
end
|
275
|
-
|
293
|
+
|
276
294
|
def provides_or_inherits?(*names)
|
277
295
|
provides?(names) || inherits?(names)
|
278
296
|
end
|
279
|
-
|
297
|
+
|
280
298
|
# Returns the field value referenced by the passed-in name.
|
281
299
|
# For example, this will return the 'title' value for 'booktitle' if a
|
282
300
|
# corresponding alias is defined.
|
283
301
|
def provide(name)
|
284
302
|
return nil unless name.respond_to?(:to_sym)
|
285
|
-
name = name.to_sym
|
303
|
+
name = name.to_sym
|
286
304
|
fields[name] || fields[aliases[name]]
|
287
305
|
end
|
288
|
-
|
306
|
+
|
289
307
|
# If the Entry has a cross-reference, copies all referenced all inherited
|
290
308
|
# values from the parent.
|
291
309
|
#
|
@@ -294,10 +312,10 @@ module BibTeX
|
|
294
312
|
inherited_fields.each do |name|
|
295
313
|
fields[name] = parent.provide(name)
|
296
314
|
end
|
297
|
-
|
315
|
+
|
298
316
|
self
|
299
317
|
end
|
300
|
-
|
318
|
+
|
301
319
|
# Returns a sorted list of the Entry's field names. If a +filter+ is passed
|
302
320
|
# as argument, returns all field names that are also defined by the filter.
|
303
321
|
# If the +filter+ is empty, returns all field names.
|
@@ -306,15 +324,15 @@ module BibTeX
|
|
306
324
|
# a cross-reference, the list will include all inherited fields.
|
307
325
|
def field_names(filter = [], include_inherited = true)
|
308
326
|
names = fields.keys
|
309
|
-
|
327
|
+
|
310
328
|
if include_inherited && has_parent?
|
311
329
|
names.concat(inherited_fields)
|
312
330
|
end
|
313
|
-
|
331
|
+
|
314
332
|
unless filter.empty?
|
315
333
|
names = names & filter.map(&:to_sym)
|
316
334
|
end
|
317
|
-
|
335
|
+
|
318
336
|
names.sort!
|
319
337
|
names
|
320
338
|
end
|
@@ -322,21 +340,21 @@ module BibTeX
|
|
322
340
|
# Returns a sorted list of all field names referenced by this Entry's cross-reference.
|
323
341
|
def inherited_fields
|
324
342
|
return [] unless has_parent?
|
325
|
-
|
343
|
+
|
326
344
|
names = parent.fields.keys - fields.keys
|
327
345
|
names.concat(parent.aliases.reject { |k,v| !parent.has_field?(v) }.keys)
|
328
346
|
names.sort!
|
329
|
-
|
347
|
+
|
330
348
|
names
|
331
349
|
end
|
332
|
-
|
333
|
-
|
350
|
+
|
351
|
+
|
334
352
|
def method_missing(name, *args, &block)
|
335
353
|
case
|
336
354
|
when fields.has_key?(name)
|
337
355
|
fields[name]
|
338
356
|
when name.to_s =~ /^(.+)=$/
|
339
|
-
send(:add, $1.to_sym, args[0])
|
357
|
+
send(:add, $1.to_sym, args[0])
|
340
358
|
when name =~ /^(?:convert|from)_([a-z]+)(!)?$/
|
341
359
|
$2 ? convert!($1, &block) : convert($1, &block)
|
342
360
|
when has_parent? && parent.provides?(name)
|
@@ -350,12 +368,12 @@ module BibTeX
|
|
350
368
|
provides?(method.to_sym) || method.to_s.match(/=$/) ||
|
351
369
|
method =~ /^(?:convert|from)_([a-z]+)(!)?$/ || (has_parent? && parent.respond_to?(method)) || super
|
352
370
|
end
|
353
|
-
|
371
|
+
|
354
372
|
# Returns a copy of the Entry with all the field names renamed.
|
355
373
|
def rename(*arguments)
|
356
374
|
dup.rename!(*arguments)
|
357
375
|
end
|
358
|
-
|
376
|
+
|
359
377
|
# Renames the given field names unless a field with the new name already
|
360
378
|
# exists.
|
361
379
|
def rename!(*arguments)
|
@@ -370,16 +388,16 @@ module BibTeX
|
|
370
388
|
|
371
389
|
alias rename_fields rename
|
372
390
|
alias rename_fields! rename!
|
373
|
-
|
391
|
+
|
374
392
|
# Returns the value of the field with the given name. If the value is not
|
375
393
|
# defined and the entry has cross-reference, returns the cross-referenced
|
376
394
|
# value instead.
|
377
395
|
def [](name)
|
378
396
|
fields[name.to_sym] || parent && parent.provide(name)
|
379
397
|
end
|
380
|
-
|
398
|
+
|
381
399
|
alias get []
|
382
|
-
|
400
|
+
|
383
401
|
def fetch(name, default = nil)
|
384
402
|
get(name) || block_given? ? yield(name) : default
|
385
403
|
end
|
@@ -395,11 +413,11 @@ module BibTeX
|
|
395
413
|
define_method(contributor) do
|
396
414
|
get(contributor)
|
397
415
|
end
|
398
|
-
|
416
|
+
|
399
417
|
alias_method "#{contributor}s", contributor
|
400
418
|
end
|
401
|
-
|
402
|
-
|
419
|
+
|
420
|
+
|
403
421
|
# call-seq:
|
404
422
|
# add(:author, "Edgar A. Poe")
|
405
423
|
# add(:author, "Edgar A. Poe", :title, "The Raven")
|
@@ -413,10 +431,10 @@ module BibTeX
|
|
413
431
|
Hash[*arguments.flatten].each_pair do |name, value|
|
414
432
|
fields[name.to_sym] = Value.create(value)
|
415
433
|
end
|
416
|
-
|
434
|
+
|
417
435
|
self
|
418
436
|
end
|
419
|
-
|
437
|
+
|
420
438
|
alias << add
|
421
439
|
|
422
440
|
# Removes the field with a given name from the entry.
|
@@ -433,10 +451,31 @@ module BibTeX
|
|
433
451
|
end
|
434
452
|
end
|
435
453
|
|
436
|
-
|
437
|
-
|
454
|
+
# Creates the entry's digest based on the passed-in filters.
|
455
|
+
#
|
456
|
+
# The digest contains the type and all key-value pairs based
|
457
|
+
# on the passed in filter.
|
458
|
+
#
|
459
|
+
# If a block is given, the computed digest will be passed to
|
460
|
+
# the block for post-processing (the entry itself will be passed
|
461
|
+
# as the second parameter).
|
462
|
+
#
|
463
|
+
# @see #field_names
|
464
|
+
#
|
465
|
+
# @param [<Symbol>] the field names to use
|
466
|
+
# @return [String] the digest string
|
467
|
+
def digest(filter = [])
|
468
|
+
names = field_names(filter)
|
469
|
+
digest = type.to_s
|
470
|
+
|
471
|
+
names.zip(values_at(*names)).each do |key, value|
|
472
|
+
digest << "|#{key}:#{value}"
|
473
|
+
end
|
474
|
+
|
475
|
+
digest = yield(digest, self) if block_given?
|
476
|
+
digest
|
438
477
|
end
|
439
|
-
|
478
|
+
|
440
479
|
def identifier
|
441
480
|
case
|
442
481
|
when provides?(:doi)
|
@@ -449,23 +488,23 @@ module BibTeX
|
|
449
488
|
"urn:bibtex:#{key}"
|
450
489
|
end
|
451
490
|
end
|
452
|
-
|
491
|
+
|
453
492
|
# Called when the element was added to a bibliography.
|
454
493
|
def added_to_bibliography(bibliography)
|
455
494
|
super
|
456
495
|
|
457
496
|
@key = register(key)
|
458
|
-
|
497
|
+
|
459
498
|
[:parse_names, :parse_months].each do |parser|
|
460
499
|
send(parser) if bibliography.options[parser]
|
461
500
|
end
|
462
|
-
|
501
|
+
|
463
502
|
if bibliography.options.has_key?(:filter)
|
464
503
|
[*bibliography.options[:filter]].each do |filter|
|
465
504
|
convert!(filter)
|
466
505
|
end
|
467
506
|
end
|
468
|
-
|
507
|
+
|
469
508
|
self
|
470
509
|
end
|
471
510
|
|
@@ -480,7 +519,7 @@ module BibTeX
|
|
480
519
|
def registered?
|
481
520
|
!!(bibliography && bibliography.entries[key].equal?(self))
|
482
521
|
end
|
483
|
-
|
522
|
+
|
484
523
|
# Registers this Entry in the associated Bibliographies entries hash.
|
485
524
|
# This method may change the Entry's key, if another entry is already
|
486
525
|
# registered with the current key.
|
@@ -488,13 +527,13 @@ module BibTeX
|
|
488
527
|
# Returns the key or nil if the Entry is not associated with a Bibliography.
|
489
528
|
def register(key)
|
490
529
|
return nil if bibliography.nil?
|
491
|
-
|
530
|
+
|
492
531
|
k = key.dup
|
493
532
|
k.succ! while bibliography.has_key?(k)
|
494
533
|
bibliography.entries[k] = self
|
495
534
|
k
|
496
535
|
end
|
497
|
-
|
536
|
+
|
498
537
|
def replace(*arguments)
|
499
538
|
arguments = bibliography.q('@string') if arguments.empty?
|
500
539
|
fields.values.each { |v| v.replace(*arguments) }
|
@@ -509,18 +548,18 @@ module BibTeX
|
|
509
548
|
def month=(month)
|
510
549
|
fields[:month] = MONTHS_FILTER[month]
|
511
550
|
end
|
512
|
-
|
551
|
+
|
513
552
|
def parse_month
|
514
553
|
fields[:month] = MONTHS_FILTER[fields[:month]] if has_field?(:month)
|
515
554
|
self
|
516
555
|
end
|
517
|
-
|
556
|
+
|
518
557
|
alias parse_months parse_month
|
519
|
-
|
558
|
+
|
520
559
|
def date
|
521
560
|
get(:date) || get(:year)
|
522
561
|
end
|
523
|
-
|
562
|
+
|
524
563
|
# Parses all name values of the entry. Tries to replace and join the
|
525
564
|
# value prior to parsing.
|
526
565
|
def parse_names
|
@@ -535,34 +574,34 @@ module BibTeX
|
|
535
574
|
|
536
575
|
self
|
537
576
|
end
|
538
|
-
|
577
|
+
|
539
578
|
# Returns a list of all names (authors, editors, translators).
|
540
579
|
def names
|
541
580
|
NAME_FIELDS.map { |k| has_field?(k) ? @fields[k].tokens : nil }.flatten.compact
|
542
581
|
end
|
543
|
-
|
544
|
-
|
582
|
+
|
583
|
+
|
545
584
|
# Returns true if the Entry has a valid cross-reference in the Bibliography.
|
546
585
|
def has_parent?
|
547
586
|
!parent.nil?
|
548
587
|
end
|
549
588
|
|
550
|
-
alias has_cross_reference? has_parent?
|
589
|
+
alias has_cross_reference? has_parent?
|
551
590
|
|
552
591
|
# Returns true if the Entry cross-references an Entry which is not
|
553
592
|
# registered in the current Bibliography.
|
554
593
|
def parent_missing?
|
555
594
|
has_field?(:crossref) && !has_parent?
|
556
595
|
end
|
557
|
-
|
596
|
+
|
558
597
|
alias cross_reference_missing? parent_missing?
|
559
|
-
|
598
|
+
|
560
599
|
# Returns the cross-referenced Entry from the Bibliography or nil if this
|
561
600
|
# Entry does define a cross-reference.
|
562
601
|
def parent
|
563
602
|
bibliography && bibliography[fields[:crossref]]
|
564
603
|
end
|
565
|
-
|
604
|
+
|
566
605
|
alias cross_reference parent
|
567
606
|
|
568
607
|
|
@@ -571,9 +610,9 @@ module BibTeX
|
|
571
610
|
def has_children?
|
572
611
|
!children.empty?
|
573
612
|
end
|
574
|
-
|
613
|
+
|
575
614
|
alias cross_referenced? has_children?
|
576
|
-
|
615
|
+
|
577
616
|
# Returns a list of all entries in the Bibliography containing a
|
578
617
|
# cross-reference to this entry or [] if there are no references to this
|
579
618
|
# entry.
|
@@ -582,11 +621,11 @@ module BibTeX
|
|
582
621
|
end
|
583
622
|
|
584
623
|
alias cross_referenced_by children
|
585
|
-
|
624
|
+
|
586
625
|
def container_title
|
587
626
|
get(:booktitle) || get(:journal) || get(:container)
|
588
627
|
end
|
589
|
-
|
628
|
+
|
590
629
|
def pages_from
|
591
630
|
fetch(:pages, '').split(/\D+/)[0]
|
592
631
|
end
|
@@ -594,13 +633,19 @@ module BibTeX
|
|
594
633
|
def pages_to
|
595
634
|
fetch(:pages, '').split(/\D+/)[-1]
|
596
635
|
end
|
597
|
-
|
636
|
+
|
598
637
|
# Returns true if this entry is published inside a book, collection or journal
|
599
638
|
def contained?
|
600
639
|
has_field?(:booktitle, :container, :journal)
|
601
640
|
end
|
602
|
-
|
603
|
-
|
641
|
+
|
642
|
+
# Returns an array containing the values associated with the given keys.
|
643
|
+
def values_at(*arguments)
|
644
|
+
arguments.map do |key|
|
645
|
+
get key
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
604
649
|
# Returns a duplicate entry with all values converted using the filter.
|
605
650
|
# If an optional block is given, only those values will be converted where
|
606
651
|
# the block returns true (the block will be called with each key-value pair).
|
@@ -609,18 +654,18 @@ module BibTeX
|
|
609
654
|
def convert(filter)
|
610
655
|
block_given? ? dup.convert!(filter, &Proc.new) : dup.convert!(filter)
|
611
656
|
end
|
612
|
-
|
657
|
+
|
613
658
|
# In-place variant of @see #convert
|
614
659
|
def convert!(filter)
|
615
660
|
fields.each_pair { |k,v| !block_given? || yield(k,v) ? v.convert!(filter) : v }
|
616
661
|
self
|
617
662
|
end
|
618
|
-
|
663
|
+
|
619
664
|
def <=>(other)
|
620
665
|
type != other.type ? type <=> other.type : key != other.key ? key <=> other.key : to_s <=> other.to_s
|
621
666
|
end
|
622
|
-
|
623
|
-
|
667
|
+
|
668
|
+
|
624
669
|
# Returns a string of all the entry's fields.
|
625
670
|
def content(options = {})
|
626
671
|
fields.map { |k,v| "#{k} = #{ fields[k].to_s(options) }" }.join(",\n")
|
@@ -631,7 +676,7 @@ module BibTeX
|
|
631
676
|
options[:quotes] ||= %w({ })
|
632
677
|
["@#{type}{#{key},", content(options).gsub(/^/,' '), "}\n"].join("\n")
|
633
678
|
end
|
634
|
-
|
679
|
+
|
635
680
|
def to_hash(options = {})
|
636
681
|
options[:quotes] ||= %w({ })
|
637
682
|
hash = { :key => key, :type => type }
|
@@ -641,32 +686,32 @@ module BibTeX
|
|
641
686
|
|
642
687
|
def to_citeproc(options = {})
|
643
688
|
options[:quotes] ||= []
|
644
|
-
|
689
|
+
|
645
690
|
parse_names
|
646
691
|
parse_month
|
647
|
-
|
692
|
+
|
648
693
|
hash = { 'id' => key.to_s, 'type' => CSL_TYPES[type].to_s }
|
649
|
-
|
694
|
+
|
650
695
|
each_pair do |k,v|
|
651
696
|
hash[CSL_FILTER[k].to_s] = v.to_citeproc(options) unless DATE_FIELDS.include?(k)
|
652
697
|
end
|
653
|
-
|
698
|
+
|
654
699
|
hash['issued'] = citeproc_date
|
655
700
|
hash
|
656
701
|
end
|
657
|
-
|
702
|
+
|
658
703
|
def issued
|
659
704
|
m = MONTHS.find_index(fields[:month].to_s.intern) unless !has_field?(:month)
|
660
705
|
m = m + 1 unless m.nil?
|
661
|
-
|
706
|
+
|
662
707
|
Hash['date-parts', [[fields[:year],m].compact.map(&:to_i)]]
|
663
708
|
end
|
664
|
-
|
709
|
+
|
665
710
|
alias citeproc_date issued
|
666
|
-
|
711
|
+
|
667
712
|
def to_xml(options = {})
|
668
713
|
require 'rexml/document'
|
669
|
-
|
714
|
+
|
670
715
|
xml = REXML::Element.new('bibtex:entry')
|
671
716
|
xml.attributes['id'] = key
|
672
717
|
|
@@ -674,54 +719,54 @@ module BibTeX
|
|
674
719
|
|
675
720
|
fields.each do |key, value|
|
676
721
|
field = REXML::Element.new("bibtex:#{key}")
|
677
|
-
|
722
|
+
|
678
723
|
if options[:extended] && value.name?
|
679
724
|
value.each { |n| entry.add_element(n.to_xml) }
|
680
725
|
else
|
681
726
|
field.text = value.to_s(options)
|
682
727
|
end
|
683
|
-
|
728
|
+
|
684
729
|
entry.add_element(field)
|
685
730
|
end
|
686
731
|
|
687
732
|
xml.add_element(entry)
|
688
733
|
xml
|
689
734
|
end
|
690
|
-
|
735
|
+
|
691
736
|
# Returns a RDF::Graph representation of the entry using the BIBO ontology.
|
692
737
|
# TODO: improve level of detail captured by export
|
693
738
|
def to_rdf(options = {})
|
694
739
|
require 'rdf'
|
695
|
-
|
740
|
+
|
696
741
|
bibo = RDF::Vocabulary.new('http://purl.org/ontology/bibo/')
|
697
|
-
|
742
|
+
|
698
743
|
graph = RDF::Graph.new
|
699
744
|
entry = RDF::URI.new(identifier)
|
700
745
|
|
701
746
|
graph << [entry, RDF.type, bibo[BIBO_TYPES[type]]]
|
702
|
-
|
703
|
-
[:title, :language].each do |key|
|
747
|
+
|
748
|
+
[:title, :language].each do |key|
|
704
749
|
graph << [entry, RDF::DC[key], get(key).to_s] if field?(key)
|
705
750
|
end
|
706
751
|
|
707
752
|
graph << [entry, RDF::DC.date, get(:year).to_s] if field?(:year)
|
708
|
-
|
753
|
+
|
709
754
|
if field?(:publisher)
|
710
755
|
address = RDF::Vocabulary.new('http://schemas.talis.com/2005/address/schema#')
|
711
756
|
pub = RDF::Node.new
|
712
757
|
|
713
758
|
graph << [pub, RDF.type, RDF::FOAF[:Organization]]
|
714
759
|
graph << [pub, RDF::FOAF.name, get(:publisher)]
|
715
|
-
|
760
|
+
|
716
761
|
graph << [pub, address[:localityName], get(:address)] if field?(:address)
|
717
|
-
|
762
|
+
|
718
763
|
graph << [entry, RDF::DC.published, pub]
|
719
764
|
end
|
720
765
|
|
721
|
-
[:doi, :edition, :volume].each do |key|
|
766
|
+
[:doi, :edition, :volume].each do |key|
|
722
767
|
graph << [entry, bibo[key], get(key).to_s] if field?(key)
|
723
768
|
end
|
724
|
-
|
769
|
+
|
725
770
|
if has_field?(:pages)
|
726
771
|
if get(:pages).to_s =~ /^\s*(\d+)\s*-+\s*(\d+)\s*$/
|
727
772
|
graph << [entry, bibo[:pageStart], $1]
|
@@ -736,13 +781,13 @@ module BibTeX
|
|
736
781
|
|
737
782
|
graph << [seq, RDF.type, RDF[:Seq]]
|
738
783
|
graph << [entry, bibo[:authorList], seq]
|
739
|
-
|
784
|
+
|
740
785
|
authors.each do |author|
|
741
786
|
a = RDF::Node.new
|
742
|
-
|
787
|
+
|
743
788
|
graph << [a, RDF.type, RDF::FOAF[:Person]]
|
744
|
-
|
745
|
-
if author.is_a?(Name)
|
789
|
+
|
790
|
+
if author.is_a?(Name)
|
746
791
|
[:given, :family, :prefix, :suffix].each do |part|
|
747
792
|
graph << [a, bibo["#{part}Name"], author.send(part).to_s]
|
748
793
|
end
|
@@ -778,30 +823,30 @@ module BibTeX
|
|
778
823
|
graph << [seq, RDF.li, e]
|
779
824
|
end
|
780
825
|
end
|
781
|
-
|
826
|
+
|
782
827
|
graph
|
783
828
|
rescue LoadError
|
784
829
|
BibTeX.log.error "Please gem install rdf for RDF support."
|
785
830
|
end
|
786
|
-
|
831
|
+
|
787
832
|
alias to_bibo to_rdf
|
788
|
-
|
789
|
-
|
833
|
+
|
834
|
+
|
790
835
|
|
791
836
|
|
792
837
|
private
|
793
|
-
|
838
|
+
|
794
839
|
# Returns a default key for this entry.
|
795
840
|
def default_key
|
796
841
|
k = names[0]
|
797
842
|
k = k.respond_to?(:family) ? k.family : k.to_s
|
798
843
|
k = k[/[A-Za-z]+/] || 'unknown'
|
799
844
|
k << (has_field?(:year) ? year : '-')
|
800
|
-
k << 'a'
|
845
|
+
k << 'a'
|
801
846
|
k.downcase!
|
802
847
|
k
|
803
848
|
end
|
804
|
-
|
805
|
-
|
849
|
+
|
850
|
+
|
806
851
|
end
|
807
852
|
end
|