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 +3 -3
- data/History.txt +6 -0
- data/README.md +16 -2
- data/bibtex-ruby.gemspec +1 -1
- data/features/issues/latex_filter.feature +164 -11
- data/lib/bibtex/bibliography.rb +12 -7
- data/lib/bibtex/entry.rb +14 -5
- data/lib/bibtex/names.rb +23 -2
- data/lib/bibtex/value.rb +9 -12
- data/lib/bibtex/version.rb +1 -1
- data/test/bibtex/test_bibliography.rb +15 -4
- data/test/bibtex/test_entry.rb +39 -7
- data/test/bibtex/test_names.rb +23 -0
- data/test/bibtex/test_parser.rb +41 -10
- data/test/bibtex/test_value.rb +10 -10
- data/test/profile.rb +1 -1
- metadata +13 -13
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.
|
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.
|
31
|
-
unicode (
|
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
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
|
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
|
-
|
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.
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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 "
|
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"
|
data/lib/bibtex/bibliography.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
138
|
+
entries.each_value { |e| e.parse_names }
|
135
139
|
self
|
136
140
|
end
|
137
141
|
|
138
142
|
def parse_months
|
139
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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!
|
539
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
215
|
+
tokens.select { |v| v.is_a?(Symbol) }
|
216
216
|
end
|
217
217
|
|
218
|
-
def each_token;
|
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
|
-
|
230
|
-
|
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
|
|
data/lib/bibtex/version.rb
CHANGED
@@ -16,7 +16,7 @@ module BibTeX
|
|
16
16
|
end
|
17
17
|
|
18
18
|
describe '.open' do
|
19
|
-
it '
|
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 '
|
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 '
|
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 '
|
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 }
|
data/test/bibtex/test_entry.rb
CHANGED
@@ -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 '
|
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 '
|
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 '
|
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 '
|
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 '
|
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 '
|
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 '
|
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
|
data/test/bibtex/test_names.rb
CHANGED
@@ -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
|
data/test/bibtex/test_parser.rb
CHANGED
@@ -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 '
|
11
|
+
it 'returns a Bibliography instance' do
|
12
12
|
assert @bib
|
13
13
|
refute @bib.empty?
|
14
14
|
end
|
15
15
|
|
16
|
-
it '
|
16
|
+
it 'parses all entries' do
|
17
17
|
assert_equal 3, @bib.length
|
18
18
|
end
|
19
19
|
|
20
|
-
it '
|
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)))
|
data/test/bibtex/test_value.rb
CHANGED
@@ -78,45 +78,45 @@ module BibTeX
|
|
78
78
|
end
|
79
79
|
|
80
80
|
describe "#convert" do
|
81
|
-
it "
|
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 "
|
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 "
|
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 "
|
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 "
|
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 "
|
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 "
|
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 "
|
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 "
|
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 '
|
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
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.
|
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-
|
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: &
|
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.
|
21
|
+
version: 0.0.6
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2158238240
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: multi_json
|
27
|
-
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: *
|
35
|
+
version_requirements: *2158237720
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rake
|
38
|
-
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: *
|
46
|
+
version_requirements: *2158237240
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: racc
|
49
|
-
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: *
|
57
|
+
version_requirements: *2158236760
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rdoc
|
60
|
-
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: *
|
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
|