bibtex-ruby 2.1.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
|