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