bibtex-ruby 2.0.0 → 2.0.1

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 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