bibtex-ruby 2.0.1 → 2.0.2
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 +2 -2
- data/History.txt +5 -0
- data/lib/bibtex.rb +12 -12
- data/lib/bibtex/bibliography.rb +98 -81
- data/lib/bibtex/elements.rb +191 -191
- data/lib/bibtex/entry.rb +470 -445
- data/lib/bibtex/lexer.rb +5 -5
- data/lib/bibtex/names.rb +2 -1
- data/lib/bibtex/value.rb +40 -43
- data/lib/bibtex/version.rb +1 -1
- data/test/bibtex/test_bibliography.rb +49 -49
- data/test/bibtex/test_entry.rb +214 -208
- data/test/bibtex/test_name_parser.rb +2 -2
- metadata +12 -12
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bibtex-ruby (2.0.
|
4
|
+
bibtex-ruby (2.0.1)
|
5
5
|
latex-decode (>= 0.0.6)
|
6
6
|
multi_json (~> 1.0)
|
7
7
|
|
@@ -27,7 +27,7 @@ GEM
|
|
27
27
|
gnuplot (2.3.6)
|
28
28
|
json (1.5.4)
|
29
29
|
json (1.5.4-java)
|
30
|
-
latex-decode (0.0.
|
30
|
+
latex-decode (0.0.9)
|
31
31
|
unicode (~> 0.4)
|
32
32
|
linecache (0.46)
|
33
33
|
rbx-require-relative (> 0.0.4)
|
data/History.txt
CHANGED
data/lib/bibtex.rb
CHANGED
@@ -16,22 +16,20 @@
|
|
16
16
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
17
|
#++
|
18
18
|
|
19
|
-
$:.unshift(File.dirname(__FILE__)) unless
|
20
|
-
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
21
|
-
|
22
19
|
require 'digest/md5'
|
23
|
-
|
24
|
-
require 'bibtex/version'
|
20
|
+
require 'forwardable'
|
25
21
|
require 'logger'
|
22
|
+
require 'open-uri'
|
26
23
|
|
27
24
|
require 'multi_json'
|
28
25
|
|
26
|
+
require 'bibtex/version'
|
27
|
+
|
29
28
|
# = BibTeX
|
30
29
|
#
|
31
30
|
# This module encompasses a parser for BibTeX files and
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# +Entry+.
|
31
|
+
# an API to the individual BibTeX objects: +String+,
|
32
|
+
# +Preamble+, +Comment+, and +Entry+.
|
35
33
|
#
|
36
34
|
# Author:: {Sylvester Keil}[http://sylvester.keil.or.at]
|
37
35
|
# Copyright:: Copyright (c) 2010-2011 Sylvester Keil
|
@@ -43,11 +41,13 @@ module BibTeX
|
|
43
41
|
# An instance of the Ruby core class +Logger+.
|
44
42
|
# Used for logging by BibTeX-Ruby.
|
45
43
|
#
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
@log = Logger.new(STDERR)
|
45
|
+
@log.level = ENV.has_key?('DEBUG') ? Logger::DEBUG : Logger::WARN
|
46
|
+
@log.datetime_format = '%Y-%m-%d %H:%M:%S'
|
49
47
|
|
50
|
-
|
48
|
+
class << self
|
49
|
+
attr_reader :log
|
50
|
+
end
|
51
51
|
|
52
52
|
end
|
53
53
|
|
data/lib/bibtex/bibliography.rb
CHANGED
@@ -16,9 +16,6 @@
|
|
16
16
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
17
|
#++
|
18
18
|
|
19
|
-
require 'forwardable'
|
20
|
-
require 'open-uri'
|
21
|
-
|
22
19
|
module BibTeX
|
23
20
|
|
24
21
|
#
|
@@ -35,8 +32,8 @@ module BibTeX
|
|
35
32
|
|
36
33
|
class << self
|
37
34
|
|
38
|
-
|
39
|
-
|
35
|
+
attr_reader :defaults
|
36
|
+
|
40
37
|
# Opens and parses the `.bib' file at the given +path+. Returns
|
41
38
|
# a new Bibliography instance corresponding to the file, or, if a block
|
42
39
|
# is given, yields the instance to the block, ensuring that the file
|
@@ -53,7 +50,7 @@ module BibTeX
|
|
53
50
|
#
|
54
51
|
def open(path, options = {})
|
55
52
|
b = parse(Kernel.open(path, 'r:UTF-8').read, options)
|
56
|
-
|
53
|
+
b.path = path
|
57
54
|
return b unless block_given?
|
58
55
|
|
59
56
|
begin
|
@@ -65,14 +62,14 @@ module BibTeX
|
|
65
62
|
|
66
63
|
# Parses the given string and returns a corresponding Bibliography instance.
|
67
64
|
def parse(input, options = {})
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
65
|
+
case input
|
66
|
+
when Array, Hash, Element
|
67
|
+
Bibliography.new(options).add(input)
|
68
|
+
when ::String
|
69
|
+
Parser.new(options).parse(input) || Bibliography.new(options)
|
70
|
+
else
|
71
|
+
raise ArgumentError, "failed to parse #{input.inspect}"
|
72
|
+
end
|
76
73
|
end
|
77
74
|
|
78
75
|
# Defines a new accessor that selects elements by type.
|
@@ -88,22 +85,30 @@ module BibTeX
|
|
88
85
|
|
89
86
|
attr_reader :data, :strings, :entries, :errors, :options
|
90
87
|
|
91
|
-
attr_by_type :article, :book, :journal, :collection, :preamble,
|
92
|
-
|
88
|
+
attr_by_type :article, :book, :journal, :collection, :preamble,
|
89
|
+
:comment, :meta_content
|
93
90
|
|
94
|
-
def_delegators :@data, :length, :size, :
|
95
|
-
|
91
|
+
def_delegators :@data, :length, :size, :empty?
|
92
|
+
def_delegators :@entries, :key?, :has_key?
|
96
93
|
|
97
94
|
|
98
95
|
# Creates a new bibliography.
|
99
96
|
def initialize(options = {})
|
100
97
|
@options = Bibliography.defaults.merge(options)
|
101
|
-
@data, @strings = [], {}
|
102
|
-
|
98
|
+
@data, @strings, @errors = [], {}, []
|
99
|
+
@entries = Hash.new { |h,k| h.fetch(k.to_s, nil) }
|
103
100
|
|
104
101
|
yield self if block_given?
|
105
102
|
end
|
106
103
|
|
104
|
+
def initialize_copy(other)
|
105
|
+
@options = other.options.dup
|
106
|
+
@errors = other.errors.dup
|
107
|
+
@data, @strings = [], {}
|
108
|
+
@entries = Hash.new { |h,k| h.fetch(k.to_s, nil) }
|
109
|
+
add(other.data)
|
110
|
+
end
|
111
|
+
|
107
112
|
# Adds a new element, or a list of new elements to the bibliography.
|
108
113
|
# Returns the Bibliography for chainability.
|
109
114
|
def add(*arguments)
|
@@ -127,11 +132,21 @@ module BibTeX
|
|
127
132
|
options[:quotes] ||= %w({ })
|
128
133
|
|
129
134
|
File.open(path, 'w:UTF-8') do |f|
|
130
|
-
|
131
|
-
|
132
|
-
|
135
|
+
f.write(to_s(options))
|
136
|
+
end
|
137
|
+
|
133
138
|
self
|
134
139
|
end
|
140
|
+
|
141
|
+
|
142
|
+
def each
|
143
|
+
if block_given?
|
144
|
+
data.each(&Proc.new)
|
145
|
+
self
|
146
|
+
else
|
147
|
+
to_enum
|
148
|
+
end
|
149
|
+
end
|
135
150
|
|
136
151
|
|
137
152
|
def parse_names
|
@@ -150,12 +165,12 @@ module BibTeX
|
|
150
165
|
# entry). @see Entry#convert!
|
151
166
|
def convert (filter)
|
152
167
|
entries.each_value do |entry|
|
153
|
-
|
154
|
-
|
155
|
-
|
168
|
+
entry.convert!(filter) if !block_given? || yield(entry)
|
169
|
+
end
|
170
|
+
|
156
171
|
self
|
157
172
|
end
|
158
|
-
|
173
|
+
|
159
174
|
|
160
175
|
# Deletes an object, or a list of objects from the bibliography.
|
161
176
|
# If a list of objects is to be deleted, you can either supply the list
|
@@ -173,10 +188,6 @@ module BibTeX
|
|
173
188
|
alias rm delete
|
174
189
|
|
175
190
|
|
176
|
-
# Returns an element or a list of elements according to the given index,
|
177
|
-
# range, or query. Contrary to the Bibliography#query this method does
|
178
|
-
# not yield to a block for additional refinement of the query.
|
179
|
-
#
|
180
191
|
# call-seq:
|
181
192
|
# >> bib[-1]
|
182
193
|
# => Returns the last element of the Bibliography or nil
|
@@ -196,34 +207,35 @@ module BibTeX
|
|
196
207
|
# => Returns all objects that match 'ruby' anywhere or []
|
197
208
|
# >> bib['@book[keywords=ruby]']
|
198
209
|
# => Returns all books whose keywords attribute equals 'ruby' or []
|
210
|
+
#
|
211
|
+
# Returns an element or a list of elements according to the given index,
|
212
|
+
# range, or query. Contrary to the Bibliography#query this method does
|
213
|
+
# not yield to a block for additional refinement of the query.
|
214
|
+
#
|
199
215
|
def [](*arguments)
|
200
216
|
raise(ArgumentError, "wrong number of arguments (#{arguments.length} for 1..2)") unless arguments.length.between?(1,2)
|
201
217
|
|
202
218
|
case
|
203
219
|
when arguments[0].is_a?(Numeric) || arguments[0].is_a?(Range)
|
204
220
|
data[*arguments]
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
221
|
+
when arguments.length == 1
|
222
|
+
case
|
223
|
+
when arguments[0].nil?
|
224
|
+
nil
|
225
|
+
when arguments[0].respond_to?(:empty?) && arguments[0].empty?
|
226
|
+
nil
|
227
|
+
when arguments[0].is_a?(Symbol)
|
228
|
+
entries[arguments[0]]
|
229
|
+
when arguments[0].respond_to?(:start_with?) && !arguments[0].start_with?('@')
|
230
|
+
entries[arguments[0]]
|
231
|
+
else
|
232
|
+
query(*arguments)
|
233
|
+
end
|
218
234
|
else
|
219
235
|
query(*arguments)
|
220
236
|
end
|
221
237
|
end
|
222
238
|
|
223
|
-
# Returns all objects which could not be parsed successfully.
|
224
|
-
def errors
|
225
|
-
@errors ||= []
|
226
|
-
end
|
227
239
|
|
228
240
|
# Returns true if there are object which could not be parsed.
|
229
241
|
def errors?
|
@@ -233,14 +245,14 @@ module BibTeX
|
|
233
245
|
# Returns true if the +Bibliography+ contains no errors and only
|
234
246
|
# valid BibTeX objects (meta content is ignored).
|
235
247
|
def valid?
|
236
|
-
!errors? &&
|
248
|
+
!errors? && entries.values.all?(&:valid?)
|
249
|
+
end
|
250
|
+
|
251
|
+
# Returns a list of the names of all authors, editors and translators in the Bibliography.
|
252
|
+
def names
|
253
|
+
map(&:names).flatten
|
237
254
|
end
|
238
255
|
|
239
|
-
# Returns a list of the names of all authors, editors and translators in the Bibliography.
|
240
|
-
def names
|
241
|
-
map(&:names).flatten
|
242
|
-
end
|
243
|
-
|
244
256
|
# Replaces all string symbols which are defined in the bibliography.
|
245
257
|
#
|
246
258
|
# By default symbols in @string, @preamble and entries are replaced; this
|
@@ -273,8 +285,9 @@ module BibTeX
|
|
273
285
|
self
|
274
286
|
end
|
275
287
|
|
288
|
+
|
276
289
|
def sort(*arguments, &block)
|
277
|
-
|
290
|
+
data.sort(*arguments, &block)
|
278
291
|
self
|
279
292
|
end
|
280
293
|
|
@@ -283,6 +296,10 @@ module BibTeX
|
|
283
296
|
map { |o| o.to_s(options) }.join
|
284
297
|
end
|
285
298
|
|
299
|
+
def inspect
|
300
|
+
"#<#{self.class} data=[#{length}]>"
|
301
|
+
end
|
302
|
+
|
286
303
|
def to_a(options = {})
|
287
304
|
map { |o| o.to_hash(options) }
|
288
305
|
end
|
@@ -308,16 +325,16 @@ module BibTeX
|
|
308
325
|
end
|
309
326
|
|
310
327
|
# Returns a REXML::Document representation of the bibliography using the
|
311
|
-
|
328
|
+
# BibTeXML format.
|
312
329
|
def to_xml(options = {})
|
313
330
|
require 'rexml/document'
|
314
|
-
|
331
|
+
|
315
332
|
xml = REXML::Document.new
|
316
333
|
xml << REXML::XMLDecl.new('1.0','UTF-8')
|
317
334
|
|
318
335
|
root = REXML::Element.new('bibtex:file')
|
319
|
-
|
320
|
-
|
336
|
+
root.add_namespace('bibtex', 'http://bibtexml.sf.net/')
|
337
|
+
|
321
338
|
each { |e| root.add_element(e.to_xml(options)) }
|
322
339
|
|
323
340
|
xml.add_element(root)
|
@@ -342,11 +359,11 @@ module BibTeX
|
|
342
359
|
# #=> same as above without using a block
|
343
360
|
#
|
344
361
|
def query(*arguments, &block)
|
345
|
-
raise
|
362
|
+
raise ArgumentError, "wrong number of arguments (#{arguments.length} for 0..2)" unless arguments.length.between?(0,2)
|
346
363
|
|
347
364
|
q, selector = arguments.reverse
|
348
365
|
filter = block ? Proc.new { |e| e.match?(q) && block.call(e) } :
|
349
|
-
|
366
|
+
Proc.new { |e| e.match?(q) }
|
350
367
|
|
351
368
|
send(query_handler(selector), &filter)
|
352
369
|
end
|
@@ -363,26 +380,26 @@ module BibTeX
|
|
363
380
|
other.respond_to?(:to_a) ? to_a <=> other.to_a : nil
|
364
381
|
end
|
365
382
|
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
383
|
+
# TODO this should be faster than select_duplicates_by
|
384
|
+
# def detect_duplicates_by(*arguments)
|
385
|
+
# end
|
386
|
+
|
387
|
+
def select_duplicates_by(*arguments)
|
388
|
+
d, fs = Hash.new([]), arguments.flatten.map(&:to_sym)
|
389
|
+
q('@entry') do |e|
|
390
|
+
d[e.generate_hash(fs)] << e
|
391
|
+
end
|
392
|
+
|
393
|
+
d.values.dup
|
394
|
+
end
|
395
|
+
|
396
|
+
alias duplicates select_duplicates_by
|
397
|
+
|
398
|
+
def duplicates?
|
399
|
+
!select_duplicates_by?.empty?
|
400
|
+
end
|
401
|
+
|
402
|
+
|
386
403
|
private
|
387
404
|
|
388
405
|
def query_handler(selector)
|
data/lib/bibtex/elements.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#--
|
2
2
|
# BibTeX-Ruby
|
3
|
-
# Copyright (C) 2010-2011
|
3
|
+
# Copyright (C) 2010-2011 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
|
@@ -9,45 +9,45 @@
|
|
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
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
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
|
-
# along with this program.
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
17
|
#++
|
18
18
|
|
19
19
|
module BibTeX
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
#
|
22
|
+
# The base class for BibTeX objects.
|
23
|
+
#
|
24
|
+
class Element
|
25
25
|
include Comparable
|
26
26
|
|
27
27
|
attr_writer :id
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
attr_reader :bibliography
|
29
|
+
|
30
|
+
# Returns an array of BibTeX elements.
|
31
31
|
def self.parse(input, options = {})
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
32
|
+
case input
|
33
|
+
when Element
|
34
|
+
[input]
|
35
|
+
when Hash
|
36
|
+
[Entry.new(input)]
|
37
|
+
when Array
|
38
|
+
input.inject([]) { |s,a| s.concat(parse(a, options)) }
|
39
|
+
when ::String
|
40
|
+
Parser.new(options).parse(input).data.each do |e|
|
41
|
+
e.parse_names unless !e.respond_to?(:parse_names) || options[:parse_names] == false
|
42
|
+
e.parse_month unless !e.respond_to?(:parse_month) || options[:parse_months] == false
|
43
|
+
end
|
44
|
+
else
|
45
|
+
raise ArgumentError, "failed to parse Element from #{input.inspect}"
|
46
|
+
end
|
47
47
|
end
|
48
48
|
|
49
|
-
|
50
|
-
|
49
|
+
# Returns a string containing the object's content.
|
50
|
+
def content(options = {}); ''; end
|
51
51
|
|
52
52
|
# Invokes BibTeX string replacement on this element.
|
53
53
|
def replace(*arguments); self; end
|
@@ -63,19 +63,19 @@ module BibTeX
|
|
63
63
|
self.class.name.split(/::/).last.gsub(/([[:lower:]])([[:upper:]])/) { "#{$1}_#{$2}" }.downcase.intern
|
64
64
|
end
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
# Returns a list of names for that Element. All Elements except Entries return an empty list.
|
67
|
+
def names
|
68
|
+
[]
|
69
|
+
end
|
70
|
+
|
71
71
|
def has_type?(type)
|
72
72
|
self.type == type.intern || defined?(type) == 'constant' && is_a?(type)
|
73
73
|
end
|
74
74
|
|
75
75
|
[:entry, :book, :article, :collection, :string, :preamble, :comment]. each do |type|
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
method_id = "#{type}?"
|
77
|
+
define_method(method_id) { has_type?(type) } unless method_defined?(method_id)
|
78
|
+
end
|
79
79
|
|
80
80
|
# Returns true if the element matches the given query.
|
81
81
|
def matches?(query)
|
@@ -112,85 +112,85 @@ module BibTeX
|
|
112
112
|
|
113
113
|
alias meet? meets?
|
114
114
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
115
|
+
alias to_s content
|
116
|
+
|
117
|
+
def to_hash(options = {})
|
118
|
+
{ type => content }
|
119
|
+
end
|
120
|
+
|
121
|
+
def to_yaml(options = {})
|
122
|
+
require 'yaml'
|
123
123
|
to_hash.to_yaml
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
124
|
+
end
|
125
|
+
|
126
|
+
def to_json(options = {})
|
127
|
+
MultiJson.encode(to_hash(options))
|
128
|
+
end
|
129
|
+
|
130
|
+
def to_xml(options = {})
|
131
|
+
require 'rexml/document'
|
132
|
+
xml = REXML::Element.new(type)
|
133
|
+
xml.text = content
|
134
|
+
xml
|
135
|
+
end
|
136
136
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
137
|
+
# Called when the element was added to a bibliography.
|
138
|
+
def added_to_bibliography(bibliography)
|
139
|
+
# raise BibTeXError, "failed to add element to Bibliography: already registered with another Bibliography" unless @bibliography.nil?
|
140
|
+
@bibliography = bibliography
|
141
|
+
self
|
142
|
+
end
|
143
|
+
|
144
|
+
# Called when the element was removed from a bibliography.
|
145
|
+
def removed_from_bibliography(bibliography)
|
146
|
+
@bibliography = nil
|
147
|
+
self
|
148
|
+
end
|
149
|
+
|
150
|
+
def <=>(other)
|
151
|
+
return nil unless other.respond_to? :type and other.respond_to? :to_s
|
152
|
+
[type, to_s] <=> [other.type, other.to_s]
|
153
|
+
end
|
154
|
+
|
155
|
+
# Returns the Element as a nicely formatted string.
|
156
|
+
def inspect
|
157
|
+
"#<#{self.class} #{content.gsub(/\n/, ' ')}>"
|
158
|
+
end
|
159
|
+
end
|
160
160
|
|
161
161
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
162
|
+
#
|
163
|
+
# Represents a @string object.
|
164
|
+
#
|
165
|
+
# In BibTeX @string objects contain a single string constant
|
166
|
+
# assignment. For example, @string{ foo = "bar" } defines the
|
167
|
+
# constant `foo'; this constant can be used (using BibTeX's
|
168
|
+
# string concatenation syntax) in susbsequent
|
169
|
+
# @string and @preamble objects, as well as in field values
|
170
|
+
# of regular entries.
|
171
|
+
#
|
172
|
+
class String < Element
|
173
173
|
include Replaceable
|
174
174
|
|
175
|
-
|
175
|
+
attr_reader :key
|
176
176
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
177
|
+
# Creates a new instance.
|
178
|
+
def initialize(key = nil, value = nil)
|
179
|
+
@key, @value = key.to_sym, Value.new(value)
|
180
|
+
yield self if block_given?
|
181
|
+
end
|
182
182
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
183
|
+
# Sets the string's key (i.e., the symbol identifying the constant).
|
184
|
+
def key=(key)
|
185
|
+
raise(ArgumentError, "keys must be convertible to Symbol; was: #{type.class.name}.") unless type.respond_to?(:to_sym)
|
186
|
+
|
187
|
+
unless bibliography.nil?
|
188
|
+
bibliography.strings.delete(@key)
|
189
|
+
bibliography.strings[key.to_sym] = self
|
190
|
+
end
|
191
191
|
|
192
|
-
|
193
|
-
|
192
|
+
@key = key.to_sym
|
193
|
+
end
|
194
194
|
|
195
195
|
# Retuns the string's value if parameter matches the key; nil otherwise.
|
196
196
|
def [](key)
|
@@ -198,104 +198,104 @@ module BibTeX
|
|
198
198
|
end
|
199
199
|
|
200
200
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
201
|
+
# Called when the element was added to a bibliography.
|
202
|
+
def added_to_bibliography(bibliography)
|
203
|
+
super
|
204
|
+
bibliography.strings[@key] = self
|
205
|
+
self
|
206
|
+
end
|
207
|
+
|
208
|
+
# Called when the element was removed from a bibliography.
|
209
|
+
def removed_from_bibliography(bibliography)
|
210
|
+
super
|
211
|
+
bibliography.strings[@key] = nil
|
212
|
+
self
|
213
|
+
end
|
214
214
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
215
|
+
# Returns a string representation of the @string's content.
|
216
|
+
def content
|
217
|
+
"#@key = #{@value.to_s(:quotes => '"')}"
|
218
|
+
end
|
219
219
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
220
|
+
# Returns a string representation of the @string object.
|
221
|
+
def to_s(options = {})
|
222
|
+
"@string{ #{content} }"
|
223
|
+
end
|
224
|
+
|
225
|
+
def to_hash(options = {})
|
226
|
+
{ :string => { @key => @value.to_s(:quotes => '"') } }
|
227
|
+
end
|
228
|
+
|
229
|
+
def to_xml(options = {})
|
230
|
+
require 'rexml/document'
|
231
|
+
|
232
|
+
xml = REXML::Element.new(:string)
|
233
|
+
|
234
|
+
k, v = REXML::Element.new(:key), REXML::Element.new(:value)
|
235
|
+
k.text = key.to_s
|
236
|
+
v.text = value.to_s(:quotes => '"')
|
237
|
+
|
238
|
+
xml.add_elements(k)
|
239
|
+
xml.add_elements(v)
|
240
|
+
|
241
|
+
xml
|
242
|
+
end
|
243
|
+
end
|
244
244
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
245
|
+
#
|
246
|
+
# Represents a @preamble object.
|
247
|
+
#
|
248
|
+
# In BibTeX an @preamble object contains a single string literal,
|
249
|
+
# a single constant, or a concatenation of string literals and
|
250
|
+
# constants.
|
251
|
+
class Preamble < Element
|
252
|
+
include Replaceable
|
253
253
|
|
254
|
-
|
255
|
-
|
254
|
+
# Creates a new instance.
|
255
|
+
def initialize(value = '')
|
256
256
|
@value = Value.new(value)
|
257
|
-
|
257
|
+
end
|
258
258
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
259
|
+
# Returns a string representation of the @preamble's content.
|
260
|
+
def content
|
261
|
+
@value.to_s(:quotes => '"')
|
262
|
+
end
|
263
263
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
264
|
+
# Returns a string representation of the @preamble object
|
265
|
+
def to_s(options = {})
|
266
|
+
"@preamble{ #{content} }"
|
267
|
+
end
|
268
|
+
end
|
269
269
|
|
270
|
-
|
271
|
-
|
270
|
+
# Represents a @comment object.
|
271
|
+
class Comment < Element
|
272
272
|
attr_accessor :content
|
273
273
|
|
274
|
-
|
275
|
-
|
276
|
-
|
274
|
+
def initialize(content = '')
|
275
|
+
@content = content
|
276
|
+
end
|
277
277
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
278
|
+
def to_s(options = {})
|
279
|
+
"@comment{ #@content }"
|
280
|
+
end
|
281
|
+
end
|
282
282
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
283
|
+
# Represents text in a `.bib' file, but outside of an
|
284
|
+
# actual BibTeX object; typically, such text is treated
|
285
|
+
# as a comment and is ignored by the parser.
|
286
|
+
# BibTeX-Ruby offers this class to allows for
|
287
|
+
# post-processing of this type of `meta' content. If you
|
288
|
+
# want the parser to include +MetaComment+ objects, you
|
289
|
+
# need to add +:meta_content+ to the parser's +:include+
|
290
|
+
# option.
|
291
|
+
class MetaContent < Element
|
292
|
+
attr_accessor :content
|
293
|
+
|
294
|
+
def initialize(content = '')
|
295
|
+
@content = content
|
296
|
+
end
|
297
297
|
|
298
|
-
|
299
|
-
|
298
|
+
def to_s(options = {}); @content; end
|
299
|
+
end
|
300
300
|
|
301
301
|
end
|