bibtex-ruby 2.0.0 → 2.0.1

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 CHANGED
@@ -2,7 +2,7 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  bibtex-ruby (2.0.0)
5
- latex-decode (>= 0.0.3)
5
+ latex-decode (>= 0.0.6)
6
6
  multi_json (~> 1.0)
7
7
 
8
8
  GEM
@@ -27,8 +27,8 @@ 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.3)
31
- unicode (>= 0.4)
30
+ latex-decode (0.0.6)
31
+ unicode (~> 0.4)
32
32
  linecache (0.46)
33
33
  rbx-require-relative (> 0.0.4)
34
34
  linecache19 (0.5.12)
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ 2.0.1 / 2011-10-20
2
+ ==================
3
+
4
+ * Fixed name parser incompatibility with Rails (kudos to @amattsmith)
5
+ * Improved latex-decoder (kudos to @etc)
6
+
1
7
  2.0.0 / 2011-09-25
2
8
  ==================
3
9
 
data/README.md CHANGED
@@ -144,7 +144,10 @@ Instead of parsing strings you can also create BibTeX elements directly in Ruby:
144
144
 
145
145
  ### Cross References
146
146
 
147
- From version 2.0, BibTeX-Ruby correctly resolves entry cross-references, which are commonly used for entries with type `inbook`, `incollection`, and `inproceedings`. When an entry has a valid citation key in field `crossref`, BibTeX-Ruby will return any fields inherited from the parent entry:
147
+ From version 2.0, BibTeX-Ruby correctly resolves entry cross-references, which
148
+ are commonly used for entries with type `inbook`, `incollection`, and
149
+ `inproceedings`. When an entry has a valid citation key in field `crossref`,
150
+ BibTeX-Ruby will return any fields inherited from the parent entry:
148
151
 
149
152
  > b = BibTeX.parse <<-END
150
153
  @inbook{fraassen_1989b,
@@ -162,7 +165,8 @@ From version 2.0, BibTeX-Ruby correctly resolves entry cross-references, which a
162
165
  }
163
166
  END
164
167
  > b['fraassen_1989b'].booktitle
165
- => <"Laws and Symmetry">
168
+ => <"Laws and Symmetry">
169
+
166
170
 
167
171
  ### Queries
168
172
 
@@ -280,6 +284,16 @@ are parsed and can easily be mapped to their last names:
280
284
  END
281
285
  => ["Hawthorne", "Melville"]
282
286
 
287
+ Another useful method is `Bibliography#names` which returns all names in
288
+ your bibliography (authors, editors, translators). For example, to quickly
289
+ expand the initials of a name across your entire bibliography, you could
290
+ use the following snippet:
291
+
292
+ b.names.each do |name|
293
+ name.first = 'Edgar Allen' if name.first =~ /E\.\s*A\./ and name.last == 'Poe'
294
+ end
295
+
296
+
283
297
  ### Filters
284
298
 
285
299
  Since version 1.3.8 BibTeX-Ruby comes with a plugin framework for input
data/bibtex-ruby.gemspec CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
25
25
  export/conversion to formats such as YAML, JSON, CSL, and XML (BibTeXML).
26
26
  END_DESCRIPTION
27
27
 
28
- s.add_runtime_dependency('latex-decode', ['>=0.0.3'])
28
+ s.add_runtime_dependency('latex-decode', ['>=0.0.6'])
29
29
  s.add_runtime_dependency('multi_json', ['~>1.0'])
30
30
 
31
31
  s.add_development_dependency('rake', ['~>0.9'])
@@ -4,15 +4,168 @@ Feature: Parse BibTeX files and convert LaTeX to Unicode
4
4
  convert them to Unicode
5
5
 
6
6
  @latex
7
- Scenario: A BibTeX file containing a LaTeX umlaut
8
- When I parse the following file:
9
- """
10
- @misc{issue16,
11
- author = {rbq},
12
- title = {An umlaut: \"u!},
13
- year = 2011,
14
- }
15
- """
16
- Then my bibliography should contain an entry with key "issue16"
7
+ Scenario: A BibTeX file containing a LaTeX umlaut
8
+ When I parse the following file:
9
+ """
10
+ @misc{issue16,
11
+ author = {rbq},
12
+ title = {An umlaut: \"u!},
13
+ year = 2011,
14
+ }
15
+ """
16
+ Then my bibliography should contain an entry with key "issue16"
17
+ When I convert all entries using the filter "latex"
18
+ Then the entry with key "issue16" should have a field "title" with the value "An umlaut: ü!"
19
+
20
+ @latex
21
+ Scenario: A BibTeX file containing a variety of LaTeX strings
22
+ When I parse the following file:
23
+ """
24
+ @book{proust_1996,
25
+ address = {Paris},
26
+ author = {Proust, Jo\"{e}lle},
27
+ booktitle = {Perception et Intermodalit\'{e}: Approches Actuelles De La Question De Molyneux},
28
+ editor = {Proust, Jo\"{e}lle},
29
+ keywords = {Perception; Molyneux's Problem},
30
+ publisher = {Presses Universitaires de France},
31
+ title = {Perception et Intermodalit\'{e}: Approches Actuelles De La Question De Molyneux},
32
+ year = {1996}
33
+ }
34
+ @incollection{bach-y-rita_1996,
35
+ author = {{Bach-y-Rita}, Paul},
36
+ crossref = {proust_1996},
37
+ keywords = {Perception; Molyneux's Problem; Vision},
38
+ note = {Reprinted in translation in \textcite[pp. 497--514]{noe_2002}.},
39
+ pages = {81--100},
40
+ title = {Substitution Sensorielle et Qualia}
41
+ }
42
+ @article{noe_2008,
43
+ author = {No\"{e}, Alva},
44
+ journal = {Philosophy and Phenomenological Research},
45
+ keywords = {Perception; Enactivism; Vision},
46
+ month = {may},
47
+ number = {3},
48
+ pages = {660--665},
49
+ title = {Pr\'{e}cis of \emph{Action in Perception}},
50
+ url = {http://dx.doi.org/10.1111/j.1933-1592.2008.00161.x},
51
+ volume = {76},
52
+ year = {2008}
53
+ }
54
+ @article{bermudez_2007,
55
+ author = {Berm\'{u}dez, Jos\'{e} Luis},
56
+ date-added = {2011-10-02 12:43:54 -0400},
57
+ date-modified = {2011-10-02 12:43:54 -0400},
58
+ journal = {Philosophical Perspectives},
59
+ keywords = {Nonconceptual Content; Mind; Perception},
60
+ month = {dec},
61
+ number = {1},
62
+ pages = {55--72},
63
+ title = {What is at Stake in the Debate on Nonconceptual Content?},
64
+ url = {http://dx.doi.org/10.1111/j.1520-8583.2007.00120.x},
65
+ volume = {21},
66
+ year = {2007}
67
+ }
68
+ @book{ellegard_1958,
69
+ address = {G\"{o}teborg},
70
+ author = {Elleg{\aa}rd, Alvar},
71
+ booktitle = {Darwin and the General Reader: The Reception of Darwin's Theory of Evolution in the British Periodical Press, 1859---1972},
72
+ keywords = {Darwin; History of Biology; History of Science; Sociology of Science},
73
+ note = {Reprinted by University of Chicago Press.},
74
+ publisher = {G\"{o}teborg Universitets {\AA}rsskrift},
75
+ title = {Darwin and the General Reader: The Reception of Darwin's Theory of Evolution in the British Periodical Press, 1859--1972},
76
+ volume = {64},
77
+ year = {1958}
78
+ }
79
+ @article{haggqvist_2007,
80
+ author = {H\"{a}ggqvist, S\"{o}ren and {\AA}sa Maria Wikforss},
81
+ journal = {Erkenntnis},
82
+ keywords = {Externalism; Content; Mind},
83
+ month = {nov},
84
+ number = {3},
85
+ pages = {373--386},
86
+ title = {Externalism and A Posteriori Semantics},
87
+ url = {http://dx.doi.org/10.1007/s10670-007-9051-4},
88
+ volume = {67},
89
+ year = {2007}
90
+ }
91
+ @article{hajek_1996,
92
+ abstract = {According to finite frequentism, the probability of an attribute A in a finite reference class B is the relative frequency of actual occurrences of A within B. I present fifteen arguments against this position.},
93
+ author = {H\'{a}jek, Alan},
94
+ journal = {Erkenntnis},
95
+ keywords = {Probability},
96
+ month = {nov},
97
+ number = {2-3},
98
+ pages = {209-227},
99
+ title = {``Mises redux''---Redux: Fifteen Arguments against Finite Frequentism},
100
+ volume = {45},
101
+ year = {1996}
102
+ }
103
+ @article{bergstrom_1970a,
104
+ author = {Bergstr\"{o}m, Ingvar},
105
+ journal = {Oud Holland},
106
+ keywords = {Holland; 17C; History of Art},
107
+ number = {1-4},
108
+ pages = {143-157},
109
+ title = {De Gheyn as a \emph{Vanitas} Painter},
110
+ url = {http://dx.doi.org/10.1163/187501770X00112},
111
+ volume = {85},
112
+ year = {1970}
113
+ }
114
+ @incollection{bricmont_2001,
115
+ address = {Heidelberg},
116
+ author = {Bricmont, Jean and D\"{u}rr, Detlef and Galavotti, Maria C. and Ghirardi, Giancarlo and Petruccione, Francesco and Zangh\`{i}, Nino},
117
+ booktitle = {Chance in Physics: Foundations and Perspectives},
118
+ editor = {Bricmont, Jean and D\"{u}rr, Detlef and Galavotti, Maria C. and Ghirardi, Giancarlo and Petruccione, Francesco and Zangh\`{i}, Nino},
119
+ keywords = {Philosophy of Science; Physics; Probability; Quantum Mechanics; Thermodynamics},
120
+ publisher = {Springer},
121
+ series = {Lecture Notes in Physics},
122
+ title = {Chance in Physics: Foundations and Perspectives},
123
+ year = {2001}
124
+ }
125
+ @article{bowler_1975,
126
+ author = {Bowler, Peter J.},
127
+ journal = {Journal of the History of Ideas},
128
+ keywords = {History of Biology; History of Science},
129
+ month = {mar},
130
+ number = {1},
131
+ pages = {95--114},
132
+ title = {The Changing Meaning of ``Evolution''\,},
133
+ url = {http://dx.doi.org/10.2307/2709013},
134
+ volume = {36},
135
+ year = {1975}
136
+ }
137
+ @article{wood_1995,
138
+ author = {Wood, Christopher S.},
139
+ issue = {October-December},
140
+ journal = {Word and Image},
141
+ keywords = {History of Art; Holland; 17C; Curiosity},
142
+ number = {4},
143
+ pages = {332-352},
144
+ title = {\,`Curious Pictures' and the Art of Description},
145
+ volume = {11},
146
+ year = {1995}
147
+ }
148
+ @article{worrall_2000a,
149
+ author = {Worrall, John},
150
+ journal = {British Journal for the Philosophy of Science},
151
+ keywords = {Newton; Underdetermination; Confirmation; Induction; Scientific Method; Philosophy of Science},
152
+ month = {mar},
153
+ number = {1},
154
+ pages = {45--80},
155
+ title = {The Scope, Limits, and Distinctiveness of the Method of `Deduction from the Phenomena': Some Lessons from Newton's `Demonstrations' in Optics},
156
+ url = {http://dx.doi.org/10.1093/bjps/51.1.45},
157
+ volume = {51},
158
+ year = {2000}
159
+ }
160
+ """
17
161
  When I convert all entries using the filter "latex"
18
- Then the entry with key "issue16" should have a field "title" with the value "An umlaut: ü!"
162
+ Then the entry with key "proust_1996" should have a field "author" with the value "Proust, Joëlle"
163
+ And the entry with key "proust_1996" should have a field "booktitle" with the value "Perception et Intermodalité: Approches Actuelles De La Question De Molyneux"
164
+ And the entry with key "bermudez_2007" should have a field "author" with the value "Bermúdez, José Luis"
165
+ And the entry with key "ellegard_1958" should have a field "address" with the value "Göteborg"
166
+ And the entry with key "ellegard_1958" should have a field "publisher" with the value "Göteborg Universitets Årsskrift"
167
+ And the entry with key "haggqvist_2007" should have a field "author" with the value "Häggqvist, Sören and Åsa Maria Wikforss"
168
+ And the entry with key "hajek_1996" should have a field "author" with the value "Hájek, Alan"
169
+ And the entry with key "hajek_1996" should have a field "title" with the value "“Mises redux”—Redux: Fifteen Arguments against Finite Frequentism"
170
+ And the entry with key "bergstrom_1970a" should have a field "author" with the value "Bergström, Ingvar"
171
+ And the entry with key "worrall_2000a" should have a field "title" with the value "The Scope, Limits, and Distinctiveness of the Method of ‘Deduction from the Phenomena’: Some Lessons from Newton’s ‘Demonstrations’ in Optics"
@@ -125,18 +125,22 @@ module BibTeX
125
125
  # Saves the bibliography to a file at the given path. Returns the bibliography.
126
126
  def save_to(path, options = {})
127
127
  options[:quotes] ||= %w({ })
128
- File.open(path, 'w:UTF-8') { |f| f.write(to_s(options)) }
128
+
129
+ File.open(path, 'w:UTF-8') do |f|
130
+ f.write(to_s(options))
131
+ end
132
+
129
133
  self
130
134
  end
131
135
 
132
136
 
133
137
  def parse_names
134
- @entries.each_value { |e| e.parse_names }
138
+ entries.each_value { |e| e.parse_names }
135
139
  self
136
140
  end
137
141
 
138
142
  def parse_months
139
- @entries.each_value { |e| e.parse_month }
143
+ entries.each_value { |e| e.parse_month }
140
144
  self
141
145
  end
142
146
 
@@ -145,7 +149,10 @@ module BibTeX
145
149
  # the block is used as a condition (the block will be called with each
146
150
  # entry). @see Entry#convert!
147
151
  def convert (filter)
148
- @entries.each_value { |e| e.convert!(filter) if !block_given? || yield(e) }
152
+ entries.each_value do |entry|
153
+ entry.convert!(filter) if !block_given? || yield(entry)
154
+ end
155
+
149
156
  self
150
157
  end
151
158
 
@@ -156,7 +163,6 @@ module BibTeX
156
163
  #
157
164
  # Returns the object (or the list of objects) that were deleted; nil
158
165
  # if the object was not part of the bibliography.
159
- #
160
166
  def delete(*arguments, &block)
161
167
  objects = q(*arguments, &block).map { |o| o.removed_from_bibliography(self) }
162
168
  @data = @data - objects
@@ -166,7 +172,7 @@ module BibTeX
166
172
  alias remove delete
167
173
  alias rm delete
168
174
 
169
- #
175
+
170
176
  # Returns an element or a list of elements according to the given index,
171
177
  # range, or query. Contrary to the Bibliography#query this method does
172
178
  # not yield to a block for additional refinement of the query.
@@ -190,7 +196,6 @@ module BibTeX
190
196
  # => Returns all objects that match 'ruby' anywhere or []
191
197
  # >> bib['@book[keywords=ruby]']
192
198
  # => Returns all books whose keywords attribute equals 'ruby' or []
193
- #
194
199
  def [](*arguments)
195
200
  raise(ArgumentError, "wrong number of arguments (#{arguments.length} for 1..2)") unless arguments.length.between?(1,2)
196
201
 
data/lib/bibtex/entry.rb CHANGED
@@ -106,6 +106,7 @@ module BibTeX
106
106
  proceedings paper-conference
107
107
  techreport report
108
108
  unpublished manuscript
109
+ article article-journal
109
110
  }.map(&:intern)]).freeze
110
111
 
111
112
 
@@ -408,13 +409,15 @@ module BibTeX
408
409
  # value prior to parsing.
409
410
  def parse_names
410
411
  strings = bibliography ? bibliography.strings.values : []
412
+
411
413
  NAME_FIELDS.each do |key|
412
414
  if name = fields[key]
413
415
  name = name.dup.replace(strings).join.to_name
414
416
  fields[key] = name unless name.nil?
415
417
  end
416
418
  end
417
- self
419
+
420
+ self
418
421
  end
419
422
 
420
423
  # Returns a list of all names (authors, editors, translators).
@@ -485,10 +488,16 @@ module BibTeX
485
488
 
486
489
  def to_citeproc(options = {})
487
490
  options[:quotes] ||= []
491
+
492
+ parse_names
493
+ parse_month
494
+
488
495
  hash = { 'id' => key.to_s, 'type' => CSL_TYPES[type].to_s }
496
+
489
497
  each_pair do |k,v|
490
498
  hash[CSL_FILTER[k].to_s] = v.to_citeproc(options) unless DATE_FIELDS.include?(k)
491
499
  end
500
+
492
501
  hash['issued'] = citeproc_date
493
502
  hash
494
503
  end
@@ -496,7 +505,7 @@ module BibTeX
496
505
  def issued
497
506
  m = MONTHS.find_index(@fields[:month] && @fields[:month].v)
498
507
  m = m + 1 unless m.nil?
499
- { 'date-parts' => [[@fields[:year],m].compact.map(&:to_i)] }
508
+ Hash['date-parts', [[@fields[:year],m].compact.map(&:to_i)]]
500
509
  end
501
510
 
502
511
  alias citeproc_date issued
@@ -530,13 +539,13 @@ module BibTeX
530
539
  # the block returns true (the block will be called with each key-value pair).
531
540
  #
532
541
  # @see #convert!
533
- def convert (filter)
542
+ def convert(filter)
534
543
  block_given? ? dup.convert!(filter, &Proc.new) : dup.convert!(filter)
535
544
  end
536
545
 
537
546
  # In-place variant of @see #convert
538
- def convert! (filter)
539
- @fields.each_pair { |k,v| !block_given? || yield(k,v) ? v.convert!(filter) : v }
547
+ def convert!(filter)
548
+ fields.each_pair { |k,v| !block_given? || yield(k,v) ? v.convert!(filter) : v }
540
549
  self
541
550
  end
542
551
 
data/lib/bibtex/names.rb CHANGED
@@ -85,6 +85,12 @@ module BibTeX
85
85
  alias :<< :add
86
86
  alias :push :add
87
87
 
88
+ # Converts all string values according to the given filter.
89
+ def convert! (filter)
90
+ tokens.each { |t| t.convert!(filter) }
91
+ self
92
+ end
93
+
88
94
  def <=>(other)
89
95
  other.respond_to?(:to_a) ? to_a <=> other.to_a : super
90
96
  end
@@ -93,8 +99,9 @@ module BibTeX
93
99
 
94
100
  class Name < Struct.new(:first, :last, :prefix, :suffix)
95
101
  extend Forwardable
96
- include Comparable
97
102
 
103
+ include Comparable
104
+
98
105
  BibTeXML = {
99
106
  :first => :first,
100
107
  :last => :last,
@@ -102,7 +109,7 @@ module BibTeX
102
109
  :suffix => :lineage
103
110
  }.freeze
104
111
 
105
- def_delegators :to_s, :=~, :===, *(String.instance_methods(false).reject { |m| m =~ /^\W|each|!$/ })
112
+ def_delegators :to_s, :=~, :===, *(String.instance_methods(false).reject { |m| m =~ /^\W|each|first|last|!$/ })
106
113
 
107
114
  class << self
108
115
  def parse(string)
@@ -174,6 +181,20 @@ module BibTeX
174
181
  end
175
182
  end
176
183
 
184
+ def convert(filter)
185
+ dup.convert!(filter)
186
+ end
187
+
188
+ def convert!(filter)
189
+ if f = Filters.resolve(filter)
190
+ each_pair { |k,v| self[k] = f.apply(v) unless v.nil? }
191
+ else
192
+ raise ArgumentError, "Failed to load filter #{filter.inspect}"
193
+ end
194
+
195
+ self
196
+ end
197
+
177
198
  def to_citeproc(options = {})
178
199
  hash = {}
179
200
  hash['family'] = family unless family.nil?
data/lib/bibtex/value.rb CHANGED
@@ -89,7 +89,7 @@ module BibTeX
89
89
 
90
90
  [:strip!, :upcase!, :downcase!, :sub!, :gsub!, :chop!, :chomp!, :rstrip!].each do |method_id|
91
91
  define_method(method_id) do |*arguments, &block|
92
- @tokens.each do |part|
92
+ tokens.each do |part|
93
93
  part.send(method_id, *arguments, &block) unless part.nil?
94
94
  end
95
95
  self
@@ -103,7 +103,7 @@ module BibTeX
103
103
  when ::String # simulates Ruby's String#replace
104
104
  @tokens = [argument]
105
105
  when String
106
- @tokens = @tokens.map { |v| argument.key == v ? argument.value.tokens : v }.flatten
106
+ @tokens = @tokens.map { |v| argument.key == v ? argument.value.tokens : v }.flatten
107
107
  when Hash
108
108
  @tokens = @tokens.map { |v| argument[v] || v }
109
109
  end
@@ -205,17 +205,17 @@ module BibTeX
205
205
 
206
206
  # Returns true if the Value contains at least one symbol.
207
207
  def symbol?
208
- @tokens.detect { |v| v.is_a?(Symbol) }
208
+ tokens.detect { |v| v.is_a?(Symbol) }
209
209
  end
210
210
 
211
211
  alias has_symbol? symbol?
212
212
 
213
213
  # Returns all symbols contained in the Value.
214
214
  def symbols
215
- @tokens.select { |v| v.is_a?(Symbol) }
215
+ tokens.select { |v| v.is_a?(Symbol) }
216
216
  end
217
217
 
218
- def each_token; @tokens.each; end
218
+ def each_token; tokens.each; end
219
219
 
220
220
  # Returns a new Value with all string values converted according to the given filter.
221
221
  def convert (filter)
@@ -224,15 +224,12 @@ module BibTeX
224
224
 
225
225
  # Converts all string values according to the given filter.
226
226
  def convert! (filter)
227
- f = Filters.resolve(filter)
228
-
229
- unless f
230
- message = "Failed to load filter #{f.inspect}"
231
- Log.error message
232
- raise ArgumentError.new(message)
227
+ if f = Filters.resolve(filter)
228
+ tokens.map! { |t| f.apply(t) }
229
+ else
230
+ raise ArgumentError, "Failed to load filter #{filter.inspect}"
233
231
  end
234
232
 
235
- @tokens.map! { |t| f.apply(t) }
236
233
  self
237
234
  end
238
235
 
@@ -18,6 +18,6 @@
18
18
 
19
19
  module BibTeX
20
20
  module Version
21
- STRING = '2.0.0'.freeze
21
+ STRING = '2.0.1'.freeze
22
22
  end
23
23
  end
@@ -16,7 +16,7 @@ module BibTeX
16
16
  end
17
17
 
18
18
  describe '.open' do
19
- it 'should accept a block and save the file after execution' do
19
+ it 'accepts a block and save the file after execution' do
20
20
  tmp = Tempfile.new('bibtex')
21
21
  tmp.close
22
22
  b = BibTeX.open(Test.fixtures(:bibdesk)).save_to(tmp.path)
@@ -31,7 +31,7 @@ module BibTeX
31
31
  end
32
32
 
33
33
  describe '.parse' do
34
- it 'should accept filters' do
34
+ it 'accepts filters' do
35
35
  Bibliography.parse("@misc{k, title = {\\''u}}", :filter => 'latex')[0].title.must_be :==, 'ü'
36
36
  end
37
37
  end
@@ -150,12 +150,12 @@ module BibTeX
150
150
  def @filter.apply (value); value.is_a?(::String) ? value.upcase : value; end
151
151
  end
152
152
 
153
- it 'should support arbitrary conversions' do
153
+ it 'supports arbitrary conversions' do
154
154
  @bib.convert(@filter)
155
155
  assert_equal 'RUBY, RAILS', @bib[:rails].keywords
156
156
  end
157
157
 
158
- it 'should support conditional arbitrary conversions' do
158
+ it 'supports conditional arbitrary conversions' do
159
159
  @bib.convert(@filter) { |e| e.key != 'rails' }
160
160
  assert_equal 'ruby, rails', @bib[:rails].keywords
161
161
  assert_equal 'RUBY', @bib[:flanagan2008].keywords
@@ -163,6 +163,17 @@ module BibTeX
163
163
 
164
164
  end
165
165
 
166
+ describe 'LaTeX filter' do
167
+ before do
168
+ @bib['rails'].keywords = 'r\\"uby'
169
+ end
170
+
171
+ it 'converts LaTeX umlauts' do
172
+ @bib.convert(:latex)['rails'].keywords.must_be :==, 'rüby'
173
+ end
174
+
175
+ end
176
+
166
177
  describe 'BibTeXML export' do
167
178
  before { @bibtexml = Tempfile.new('bibtexml') }
168
179
  after { @bibtexml.unlink }
@@ -1,3 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+
1
3
  require 'helper.rb'
2
4
 
3
5
  module BibTeX
@@ -190,13 +192,13 @@ module BibTeX
190
192
  end
191
193
  end
192
194
 
193
- it 'should support renaming! of field attributes' do
195
+ it 'supports renaming! of field attributes' do
194
196
  @entry.rename!(:title => :foo)
195
197
  refute @entry.has_field?(:title)
196
198
  assert_equal 'Moby Dick', @entry[:foo]
197
199
  end
198
200
 
199
- it 'should support renaming of field attributes' do
201
+ it 'supports renaming of field attributes' do
200
202
  e = @entry.rename(:title => :foo)
201
203
 
202
204
  assert @entry.has_field?(:title)
@@ -210,7 +212,7 @@ module BibTeX
210
212
  end
211
213
 
212
214
 
213
- it 'should support citeproc export' do
215
+ it 'supports citeproc export' do
214
216
  e = @entry.to_citeproc
215
217
  assert_equal 'book', e['type']
216
218
  assert_equal 'New York', e['publisher-place']
@@ -226,24 +228,24 @@ module BibTeX
226
228
  def @filter.apply (value); value.is_a?(::String) ? value.upcase : value; end
227
229
  end
228
230
 
229
- it 'should support arbitrary conversion' do
231
+ it 'supports arbitrary conversion' do
230
232
  e = @entry.convert(@filter)
231
233
  assert_equal 'MOBY DICK', e.title
232
234
  assert_equal 'Moby Dick', @entry.title
233
235
  end
234
236
 
235
- it 'should support arbitrary in-place conversion' do
237
+ it 'supports arbitrary in-place conversion' do
236
238
  @entry.convert!(@filter)
237
239
  assert_equal 'MOBY DICK', @entry.title
238
240
  end
239
241
 
240
- it 'should support conditional arbitrary in-place conversion' do
242
+ it 'supports conditional arbitrary in-place conversion' do
241
243
  @entry.convert!(@filter) { |k,v| k.to_s =~ /publisher/i }
242
244
  assert_equal 'Moby Dick', @entry.title
243
245
  assert_equal 'PENGUIN', @entry.publisher
244
246
  end
245
247
 
246
- it 'should support conditional arbitrary conversion' do
248
+ it 'supports conditional arbitrary conversion' do
247
249
  e = @entry.convert(@filter) { |k,v| k.to_s =~ /publisher/i }
248
250
  assert_equal 'Moby Dick', e.title
249
251
  assert_equal 'PENGUIN', e.publisher
@@ -252,6 +254,36 @@ module BibTeX
252
254
 
253
255
  end
254
256
 
257
+ describe 'LaTeX filter' do
258
+ before do
259
+ @entry.title = 'M\\"{o}by Dick'
260
+ end
261
+
262
+ describe '#convert' do
263
+ it 'converts LaTeX umlauts' do
264
+ @entry.convert(:latex).title.must_be :==, 'Möby Dick'
265
+ end
266
+
267
+ it 'does not change the original entry' do
268
+ e = @entry.convert(:latex)
269
+ e.wont_be :==, @entry
270
+ e.title.to_s.length.must_be :<, @entry.title.to_s.length
271
+ end
272
+ end
273
+
274
+ describe '#convert!' do
275
+ it 'converts LaTeX umlauts' do
276
+ @entry.convert!(:latex).title.must_be :==, 'Möby Dick'
277
+ end
278
+
279
+ it 'changes the original entry in-place' do
280
+ e = @entry.convert!(:latex)
281
+ e.must_be :equal?, @entry
282
+ e.title.to_s.length.must_be :==, @entry.title.to_s.length
283
+ end
284
+ end
285
+
286
+ end
255
287
  end
256
288
 
257
289
  describe 'citeproc export' do
@@ -1,3 +1,5 @@
1
+ # coding: utf-8
2
+
1
3
  require 'helper'
2
4
 
3
5
  module BibTeX
@@ -19,5 +21,26 @@ module BibTeX
19
21
 
20
22
  end
21
23
 
24
+ describe "conversions" do
25
+ before do
26
+ class Upcase < BibTeX::Filter
27
+ def apply (value)
28
+ value.upcase
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "#convert" do
34
+ it "converts the value when given a filter instance" do
35
+ Names.parse('Poe and Hawthorne').convert(Upcase.instance).to_s.must_be :==, 'POE and HAWTHORNE'
36
+ end
37
+
38
+ it "converts LaTeX umlauts" do
39
+ Names.parse("S{\\o}ren Kirkegaard and Emmanuel L\\'evinas").convert(:latex).to_s.must_be :==, 'Kirkegaard, Søren and Lévinas, Emmanuel'
40
+ end
41
+ end
42
+
43
+ end
44
+
22
45
  end
23
46
  end
@@ -8,26 +8,19 @@ module BibTeX
8
8
  @bib = Parser.new(:debug => false).parse(File.read(Test.fixtures(:entry)))
9
9
  end
10
10
 
11
- it 'should return a Bibliography' do
11
+ it 'returns a Bibliography instance' do
12
12
  assert @bib
13
13
  refute @bib.empty?
14
14
  end
15
15
 
16
- it 'should parse all entries' do
16
+ it 'parses all entries' do
17
17
  assert_equal 3, @bib.length
18
18
  end
19
19
 
20
- it 'should parse the key values' do
20
+ it 'parses the key values' do
21
21
  assert_equal %w{ key:0 key:1 foo }, @bib.map(&:key)
22
22
  end
23
23
 
24
- it 'should handle strange keys' do
25
- input = "@Misc{George Martin06,title = {FEAST FOR CROWS}}"
26
- bib = Parser.new(:debug => false, :strict => false).parse(input)
27
- assert_equal "George Martin06", bib.first.key
28
- assert bib[:"George Martin06"]
29
- end
30
-
31
24
  it 'should parse the entry types' do
32
25
  assert_equal [:book, :article, :article], @bib.map(&:type)
33
26
  end
@@ -47,6 +40,44 @@ module BibTeX
47
40
  end
48
41
  end
49
42
 
43
+ describe 'key parsing' do
44
+ it 'handles whitespace in keys' do
45
+ input = "@Misc{George Martin06,title = {FEAST FOR CROWS}}"
46
+ bib = Parser.new(:debug => false, :strict => false).parse(input)
47
+ assert_equal "George Martin06", bib.first.key
48
+ assert bib[:"George Martin06"]
49
+ end
50
+ end
51
+
52
+ describe 'backslashes and escape sequences' do
53
+
54
+ it 'leaves backslashes intact' do
55
+ Parser.new.parse(%q(@misc{key, title = "a backslash: \"}))[0].title.must_be :==, 'a backslash: \\'
56
+ end
57
+
58
+ it 'parses LaTeX escaped quotes {"}' do
59
+ Parser.new.parse(%q(@misc{key, title = "{"}"}))[0].title.must_be :==, '{"}'
60
+ end
61
+
62
+ it 'parses complex LaTeX markup' do
63
+ b = Parser.new.parse(<<-END)[0]
64
+ @book{proust_1996,
65
+ address = {Paris},
66
+ author = {Proust, Jo\\"{e}lle},
67
+ booktitle = {Perception et Intermodalit\\'{e}: Approches Actuelles De La Question De Molyneux},
68
+ editor = {Proust, Jo\\"{e}lle},
69
+ keywords = {Perception; Molyneux's Problem},
70
+ publisher = {Presses Universitaires de France},
71
+ title = {Perception et Intermodalit\\'{e}: Approches Actuelles De La Question De Molyneux},
72
+ year = {1996}
73
+ }
74
+ END
75
+ b.booktitle.must_be :==, "Perception et Intermodalit\\'{e}: Approches Actuelles De La Question De Molyneux"
76
+ b.editor.must_be :==, 'Proust, Jo\"{e}lle'
77
+ end
78
+
79
+ end
80
+
50
81
  describe 'given a set of explicit and implicit comments' do
51
82
  before do
52
83
  @bib = Parser.new(:debug => false, :include => [:meta_content]).parse(File.read(Test.fixtures(:comment)))
@@ -78,45 +78,45 @@ module BibTeX
78
78
  end
79
79
 
80
80
  describe "#convert" do
81
- it "should convert the value when given a filter instance" do
81
+ it "converts the value when given a filter instance" do
82
82
  assert_equal ['FOO', '"FOO" # bar'], @values.map { |v| v.convert(Upcase.instance).to_s }
83
83
  end
84
84
 
85
- it "should convert the value when given a filter class" do
85
+ it "converts the value when given a filter class" do
86
86
  assert_equal ['FOO', '"FOO" # bar'], @values.map { |v| v.convert(Upcase).to_s }
87
87
  end
88
88
 
89
- it "should convert the value when given the name of a filter" do
89
+ it "converts the value when given the name of a filter" do
90
90
  assert_equal ['FOO', '"FOO" # bar'], @values.map { |v| v.convert(:upcase).to_s }
91
91
  assert_equal ['FOO', '"FOO" # bar'], @values.map { |v| v.convert('upcase').to_s }
92
92
  end
93
93
 
94
- it "should convert the value when using a ghost method" do
94
+ it "converts the value when using a ghost method" do
95
95
  assert_equal ['FOO', '"FOO" # bar'], @values.map { |v| v.convert_upcase.to_s }
96
96
  end
97
97
 
98
- it "should not alter the value when using a filter name" do
98
+ it "does not alter the value when using a filter name" do
99
99
  @values.each { |v| v.convert(:upcase) }
100
100
  assert_equal ['foo', '"foo" # bar'], @values.map(&:to_s)
101
101
  end
102
102
 
103
- it "should not alter the value when using a ghost method" do
103
+ it "does not alter the value when using a ghost method" do
104
104
  @values.each { |v| v.convert_upcase }
105
105
  assert_equal ['foo', '"foo" # bar'], @values.map(&:to_s)
106
106
  end
107
107
  end
108
108
 
109
109
  describe "#convert!" do
110
- it "should convert the value when given the name of a filter" do
110
+ it "converts the value when given the name of a filter" do
111
111
  assert_equal ['FOO', '"FOO" # bar'], @values.map { |v| v.convert!(:upcase).to_s }
112
112
  end
113
113
 
114
- it "should alter the value when given the name of a filter" do
114
+ it "alters the value when given the name of a filter" do
115
115
  @values.each { |v| v.convert!(:upcase) }
116
116
  assert_equal ['FOO', '"FOO" # bar'], @values.map(&:to_s)
117
117
  end
118
118
 
119
- it "should alter the value when using a ghost method" do
119
+ it "alters the value when using a ghost method" do
120
120
  @values.each { |v| v.convert_upcase! }
121
121
  assert_equal ['FOO', '"FOO" # bar'], @values.map(&:to_s)
122
122
  end
@@ -124,7 +124,7 @@ module BibTeX
124
124
  end
125
125
 
126
126
  describe "#to_s" do
127
- it 'should accept a :filter option and convert the values accordingly without changing the value' do
127
+ it 'accepts a :filter option and convert the values accordingly without changing the value' do
128
128
  assert_equal '"FOO" # bar', @values[1].to_s(:filter => :upcase)
129
129
  assert_equal '"foo" # bar', @values[1].to_s
130
130
  end
data/test/profile.rb CHANGED
@@ -20,7 +20,7 @@ data = data * 50
20
20
  # data = File.open(File.expand_path('../fixtures/benchmark.bib', __FILE__)).read
21
21
 
22
22
  result = RubyProf.profile do
23
- BibTeX.parse(data)
23
+ BibTeX.parse(data)
24
24
  # BibTeX::Lexer.new.analyse(data)
25
25
  end
26
26
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bibtex-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-25 00:00:00.000000000Z
12
+ date: 2011-10-20 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: latex-decode
16
- requirement: &2157691200 !ruby/object:Gem::Requirement
16
+ requirement: &2158238240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.0.3
21
+ version: 0.0.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2157691200
24
+ version_requirements: *2158238240
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: multi_json
27
- requirement: &2157690680 !ruby/object:Gem::Requirement
27
+ requirement: &2158237720 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '1.0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2157690680
35
+ version_requirements: *2158237720
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &2157690200 !ruby/object:Gem::Requirement
38
+ requirement: &2158237240 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0.9'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2157690200
46
+ version_requirements: *2158237240
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: racc
49
- requirement: &2157689720 !ruby/object:Gem::Requirement
49
+ requirement: &2158236760 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '1.4'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2157689720
57
+ version_requirements: *2158236760
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rdoc
60
- requirement: &2157689240 !ruby/object:Gem::Requirement
60
+ requirement: &2158236280 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '3.9'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2157689240
68
+ version_requirements: *2158236280
69
69
  description: ! "\t\tBibTeX-Ruby is the Rubyist's swiss-army-knife for all things BibTeX.
70
70
  It\n includes a parser for all common BibTeX objects (@string, @preamble,\n @comment
71
71
  and regular entries) and a sophisticated name parser that\n tokenizes correctly