bibtex-ruby 1.3.5 → 1.3.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bibtex-ruby might be problematic. Click here for more details.

data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bibtex-ruby (1.3.5)
4
+ bibtex-ruby (1.3.6)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -11,7 +11,7 @@ GEM
11
11
  watchr
12
12
  builder (3.0.0)
13
13
  columnize (0.3.2)
14
- cucumber (0.10.5)
14
+ cucumber (0.10.6)
15
15
  builder (>= 2.1.2)
16
16
  diff-lcs (>= 1.1.2)
17
17
  gherkin (~> 2.4.0)
@@ -32,6 +32,7 @@ GEM
32
32
  term-ansicolor (>= 1.0.4)
33
33
  racc (1.4.6)
34
34
  rake (0.9.2)
35
+ rdoc (3.6.1)
35
36
  ruby-debug (0.10.4)
36
37
  columnize (>= 0.1)
37
38
  ruby-debug-base (~> 0.10.4.0)
@@ -64,6 +65,7 @@ DEPENDENCIES
64
65
  mynyml-redgreen (>= 0.7)
65
66
  racc (>= 1.4)
66
67
  rake (>= 0.8)
68
+ rdoc (>= 3.6)
67
69
  ruby-debug
68
70
  ruby-debug19
69
71
  ruby-prof (>= 0.10)
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ === 1.3.6 / 2011-06-11
2
+
3
+ * Refactored lexer and parser for speed
4
+ * Added support for @strings with braced values (fixes #10)
5
+
1
6
  === 1.3.5 / 2011-06-07
2
7
 
3
8
  * Removed debugger initialisation
data/Manifest CHANGED
@@ -7,6 +7,7 @@ README.md
7
7
  Rakefile
8
8
  auto.watchr
9
9
  bibtex-ruby.gemspec
10
+ doc
10
11
  examples
11
12
  examples/bib2html.rb
12
13
  examples/bib2yaml.rb
@@ -15,9 +16,11 @@ features
15
16
  features/bibtex.feature
16
17
  features/entries.feature
17
18
  features/issues
19
+ features/issues/braced_strings.feature
18
20
  features/issues/number_keys.feature
19
21
  features/issues/parse_months.feature
20
22
  features/issues/slash_keys.feature
23
+ features/issues/trailing_comma.feature
21
24
  features/names.feature
22
25
  features/preambles.feature
23
26
  features/query.feature
@@ -54,6 +57,7 @@ test/bibtex
54
57
  test/bibtex/test_bibliography.rb
55
58
  test/bibtex/test_elements.rb
56
59
  test/bibtex/test_entry.rb
60
+ test/bibtex/test_lexer.rb
57
61
  test/bibtex/test_names.rb
58
62
  test/bibtex/test_parser.rb
59
63
  test/bibtex/test_string.rb
data/README.md CHANGED
@@ -43,18 +43,15 @@ many styles:
43
43
 
44
44
  >> require 'citeproc' # requires the citeproc-ruby gem
45
45
  => true
46
- >> CiteProc.process b[:pickaxe].to_citeproc, :style => :apa
47
- => "Thomas, D., Fowler, C., & Hunt, A. (2009). Programming Ruby 1.9:
48
- The Pragmatic Programmer's Guide. The Facets of Ruby.
49
- Raleigh, North Carolina: The Pragmatic Bookshelf."
50
- >> CiteProc.process b[:pickaxe].to_citeproc, :style => 'chicago-author-date'
51
- => "Thomas, Dave, Chad Fowler, and Andy Hunt. 2009. Programming Ruby 1.9:
52
- The Pragmatic Programmer's Guide. The Facets of Ruby.
53
- Raleigh, North Carolina: The Pragmatic Bookshelf."
54
- >> CiteProc.process b[:pickaxe].to_citeproc, :style => :mla
55
- => "Thomas, Dave, Chad Fowler, and Andy Hunt. Programming Ruby 1.9:
56
- The Pragmatic Programmer's Guide. Raleigh, North Carolina:
57
- The Pragmatic Bookshelf, 2009."
46
+ >> CiteProc.process b[:pickaxe].to_citeproc, :style => :apa
47
+ => "Thomas, D., Fowler, C., & Hunt, A. (2009). Programming Ruby 1.9: The Pragmatic Programmer's
48
+ Guide. The Facets of Ruby. Raleigh, North Carolina: The Pragmatic Bookshelf."
49
+ >> CiteProc.process b[:pickaxe].to_citeproc, :style => 'chicago-author-date'
50
+ => "Thomas, Dave, Chad Fowler, and Andy Hunt. 2009. Programming Ruby 1.9: The Pragmatic
51
+ Programmer's Guide. The Facets of Ruby.Raleigh, North Carolina: The Pragmatic Bookshelf."
52
+ >> CiteProc.process b[:pickaxe].to_citeproc, :style => :mla
53
+ => "Thomas, Dave, Chad Fowler, and Andy Hunt. Programming Ruby 1.9: The Pragmatic Programmer's
54
+ Guide. Raleigh, North Carolina: The Pragmatic Bookshelf, 2009."
58
55
 
59
56
 
60
57
  Installation
data/bibtex-ruby.gemspec CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.add_development_dependency('json', ['>= 1.5'])
28
28
  s.add_development_dependency('ruby-prof', ['>= 0.10'])
29
29
  s.add_development_dependency('gnuplot', ['>= 2.3'])
30
+ s.add_development_dependency('rdoc', ['>= 3.6'])
30
31
 
31
32
  s.files = File.open('Manifest').readlines.map(&:chomp)
32
33
  s.test_files = Dir.glob('test/**/test*.rb')
@@ -0,0 +1,48 @@
1
+ Feature: BibTeX Braced Strings
2
+ As a hacker who works with bibliographies
3
+ I want to be able to parse BibTeX files containing string definitions using braced expressions
4
+ Because applications such as BibDesk produce that format
5
+
6
+ @string
7
+ Scenario: A simple string assignment
8
+ When I parse the following file:
9
+ """
10
+ @string{ foo = {foo} }
11
+ """
12
+ Then my bibliography should contain 1 string
13
+
14
+ @string @replacement
15
+ Scenario: A BibTeX file with string assignments
16
+ When I parse the following file:
17
+ """
18
+ Simple strings:
19
+ @string{ foo1 = {foo} }
20
+ @string{ foo2 = {foo}}
21
+ @string{ foo3 ={foo}}
22
+ @string{foo4={foo}}
23
+ @string{ foo5 = {"foo" bar} }
24
+ @string{ foo6 = {"foo" bar{"}} }
25
+
26
+ Compound strings:
27
+ @string{ foo7 = foo1 }
28
+ @string{ foo8 = foo1 # {bar} }
29
+ @string{ foo9 = {foo } # {bar} }
30
+
31
+ """
32
+ Then my bibliography should contain 9 strings
33
+ And my bibliography should contain these strings:
34
+ | value |
35
+ | foo |
36
+ | foo |
37
+ | foo |
38
+ | foo |
39
+ | "foo" bar |
40
+ | "foo" bar{"} |
41
+ | foo1 |
42
+ | foo1 # "bar" |
43
+ | "foo " # "bar" |
44
+ When I replace and join all strings in my bibliography
45
+ Then the string "foo7" should be "foo"
46
+ And the string "foo8" should be "foobar"
47
+ And the string "foo9" should be "foo bar"
48
+
@@ -0,0 +1,21 @@
1
+ Feature: Parse BibTeX files with trailing commas
2
+ As a hacker who works with bibliographies
3
+ I want to be able to parse BibTeX files with a trailing comma
4
+
5
+ Scenario: A BibTeX file with lots of objects and comments
6
+ When I parse the following file:
7
+ """
8
+ @article{rb2011,
9
+ author = {Keil, Sylvester},
10
+ title = "BibTeX-Ruby",
11
+ year = 2011,
12
+ },
13
+
14
+ @article{key03,
15
+ year = 2000,
16
+ title = "A {bunch {of} braces {in}} title",
17
+ },
18
+ """
19
+ Then my bibliography should contain an entry with key "rb2011"
20
+ And my bibliography should contain 1 articles published in 2011
21
+ And my bibliography should contain an entry with key "key03"
@@ -71,10 +71,18 @@ Then /^there should be exactly (\d+) match(?:es)?$/ do |matches|
71
71
  end
72
72
 
73
73
 
74
+ Then /^my bibliography should contain (\d+) (\w+)$/ do |count, type|
75
+ assert_equal count.to_i, @bibliography.q("@#{type.chomp('s')}").length
76
+ end
77
+
74
78
  Then /^my bibliography should contain (\d+) (\w+) published in (\d+)$/ do |count, type, year|
75
- assert_equal @bibliography.q("@#{type.chomp!('s')}[year=#{year}]").length, count.to_i
79
+ assert_equal count.to_i, @bibliography.q("@#{type.chomp('s')}[year=#{year}]").length
76
80
  end
77
81
 
78
82
  Then /^my bibliography should contain an? (\w+) with id "([^"]*)"$/ do |type, id|
79
83
  assert_equal @bibliography[id.to_sym].type, type.to_sym
80
84
  end
85
+
86
+ Then /^the string "([^"]*)" should be "([^"]*)"$/ do |key, value|
87
+ assert_equal value, @bibliography.strings[key.to_sym].v.to_s
88
+ end
@@ -2,6 +2,7 @@ Feature: BibTeX Strings
2
2
  As a hacker who works with bibliographies
3
3
  I want to be able to parse BibTeX files containing string assignments
4
4
 
5
+ @string
5
6
  Scenario: A BibTeX file with string assignments
6
7
  When I parse the following file:
7
8
  """
@@ -30,7 +30,9 @@ module BibTeX
30
30
 
31
31
  include Enumerable
32
32
  include Comparable
33
-
33
+
34
+ DEFAULTS = { :parse_names => true, :parse_months => true }.freeze
35
+
34
36
  class << self
35
37
 
36
38
  # Opens and parses the `.bib' file at the given +path+. Returns
@@ -40,7 +42,11 @@ module BibTeX
40
42
  # to specify a save path other than the path from where the file is
41
43
  # loaded).
42
44
  #
43
- # The options argument is passed on to BibTeX::Parser.new.
45
+ # The options argument is passed on to BibTeX::Parser.new. Additional
46
+ # option parameters are:
47
+ #
48
+ # -:parse_names: set to false to disable automatic name parsing
49
+ # -:parse_months: set to false to disable automatic month conversion
44
50
  #
45
51
  def open(path, options = {})
46
52
  b = parse(Kernel.open(path).read, options)
@@ -55,10 +61,7 @@ module BibTeX
55
61
 
56
62
  # Parses the given string and returns a corresponding Bibliography instance.
57
63
  def parse(bibtex, options = {})
58
- b = Parser.new(options).parse(bibtex)
59
- b.parse_names unless b.nil? || options[:parse_names] == false
60
- b.parse_months unless b.nil? || options[:parse_months] == false
61
- b
64
+ Parser.new(options).parse(bibtex)
62
65
  end
63
66
 
64
67
  #
@@ -73,7 +76,7 @@ module BibTeX
73
76
  end
74
77
 
75
78
  attr_accessor :path
76
- attr_reader :data, :strings, :entries, :errors
79
+ attr_reader :data, :strings, :entries, :errors, :options
77
80
 
78
81
  attr_by_type :article, :book, :journal, :collection, :preamble, :comment, :meta_content
79
82
 
@@ -81,13 +84,13 @@ module BibTeX
81
84
 
82
85
 
83
86
  #
84
- # Creates a new bibliography; empty if no data attribute is specified.
87
+ # Creates a new bibliography.
85
88
  #
86
- def initialize(data = [])
87
- @data = []
88
- @strings = {}
89
- @entries = {}
90
- add(data)
89
+ def initialize(options = {})
90
+ @options = DEFAULTS.merge(options)
91
+ @data, @strings, @entries = [], {}, {}
92
+
93
+ yield self if block_given?
91
94
  end
92
95
 
93
96
  # Adds a new element, or a list of new elements to the bibliography.
@@ -100,8 +103,8 @@ module BibTeX
100
103
  self
101
104
  end
102
105
 
103
- alias :<< :add
104
- alias :push :add
106
+ alias << add
107
+ alias push add
105
108
 
106
109
  # Saves the bibliography to the current path.
107
110
  def save(options = {})
@@ -116,12 +119,12 @@ module BibTeX
116
119
  end
117
120
 
118
121
  def parse_names
119
- q('@entry') { |e| e.parse_names }
122
+ @entries.values.each { |e| e.parse_names }
120
123
  self
121
124
  end
122
125
 
123
126
  def parse_months
124
- q('@entry') { |e| e.parse_month }
127
+ @entries.values.each { |e| e.parse_month }
125
128
  self
126
129
  end
127
130
 
@@ -139,8 +142,8 @@ module BibTeX
139
142
  objects.length == 1 ? objects[0] : objects
140
143
  end
141
144
 
142
- alias :remove :delete
143
- alias :rm :delete
145
+ alias remove delete
146
+ alias rm delete
144
147
 
145
148
  #
146
149
  # Returns an element or a list of elements according to the given index,
@@ -221,7 +224,7 @@ module BibTeX
221
224
  self
222
225
  end
223
226
 
224
- alias :join_strings :join
227
+ alias join_strings join
225
228
 
226
229
  def rename(*arguments, &block)
227
230
  q('@entry') { |e| e.rename(*arguments, &block) }
@@ -300,13 +303,13 @@ module BibTeX
300
303
  send(query_handler(selector), &filter)
301
304
  end
302
305
 
303
- alias :q :query
306
+ alias q query
304
307
 
305
308
  def find_by_type(*types, &block)
306
309
  q(types.flatten.compact.map { |t| "@#{t}" }.join(', '), &block)
307
310
  end
308
311
 
309
- alias :find_by_types :find_by_type
312
+ alias find_by_types find_by_type
310
313
 
311
314
  def <=>(other)
312
315
  other.respond_to?(:to_a) ? to_a <=> other.to_a : nil
data/lib/bibtex/bibtex.y CHANGED
@@ -30,7 +30,7 @@ expect 0
30
30
 
31
31
  rule
32
32
 
33
- bibliography : /* empty */ { result = BibTeX::Bibliography.new }
33
+ bibliography : /* empty */ { result = BibTeX::Bibliography.new(@options) }
34
34
  | objects { result = val[0] }
35
35
 
36
36
  objects : object { result = BibTeX::Bibliography.new << val[0] }
@@ -60,6 +60,7 @@ rule
60
60
  | string_value SHARP string_literal { result << val[2] }
61
61
 
62
62
  string_literal : NAME { result = val[0].downcase.to_sym }
63
+ | LBRACE content RBRACE { result = val[1] }
63
64
  | STRING_LITERAL { result = val[0] }
64
65
 
65
66
  entry : entry_head assignments RBRACE { result = val[0] << val[1] }
@@ -79,7 +80,6 @@ rule
79
80
 
80
81
  value : string_value { result = val[0] }
81
82
  | NUMBER { result = val[0] }
82
- | LBRACE content RBRACE { result = val[1] }
83
83
 
84
84
  end
85
85
 
@@ -88,43 +88,31 @@ require 'bibtex/lexer'
88
88
 
89
89
  ---- inner
90
90
 
91
- attr_reader :lexer
91
+ attr_reader :lexer, :options
92
92
 
93
+ DEFAULTS = { :include => [:errors], :debug => ENV['DEBUG'] == true }.freeze
94
+
93
95
  def initialize(options = {})
94
- self.options.merge!(options)
96
+ @options = DEFAULTS.merge(options)
95
97
  @lexer = Lexer.new(@options)
96
98
  end
97
99
 
98
- def options
99
- @options ||= { :include => [:errors], :debug => ENV['DEBUG'] == true }
100
- end
101
-
102
100
  def parse(input)
103
- @yydebug = debug?
104
-
105
- @lexer.data = input
106
- @lexer.analyse
101
+ @yydebug = debug?
102
+ @lexer.analyse(input)
107
103
 
108
104
  do_parse
105
+ #yyparse(@lexer,:each)
109
106
  end
110
107
 
111
108
  def next_token
112
- token = @lexer.next_token
113
- if token[0] == :ERROR
114
- include_errors? ? token : next_token
115
- else
116
- [token[0],token[1][0]]
117
- end
109
+ @lexer.next_token
118
110
  end
119
111
 
120
112
  def debug?
121
113
  @options[:debug] == true
122
114
  end
123
-
124
- def include_errors?
125
- @options[:include].include?(:errors)
126
- end
127
-
115
+
128
116
  def on_error(tid, val, vstack)
129
117
  Log.error("Failed to parse BibTeX on value %s (%s) %s" % [val.inspect, token_to_str(tid) || '?', vstack.inspect])
130
118
  #raise(ParseError, "Failed to parse BibTeX on value %s (%s) %s" % [val.inspect, token_to_str(tid) || '?', vstack.inspect])
@@ -38,9 +38,7 @@ module BibTeX
38
38
  end
39
39
 
40
40
  # Returns a string containing the object's content.
41
- def content(options = {})
42
- ''
43
- end
41
+ def content(options = {}); ''; end
44
42
 
45
43
  # Invokes BibTeX string replacement on this element.
46
44
  def replace(*arguments); self; end
@@ -70,28 +68,28 @@ module BibTeX
70
68
 
71
69
  # Returns true if the element matches the given query.
72
70
  def matches?(query)
73
- return true if query.nil? || query.respond_to?(:empty?) && query.empty?
71
+ return true if !query || query.respond_to?(:empty?) && query.empty?
74
72
 
75
73
  case query
76
- when Element
77
- self == query
78
74
  when Symbol
79
- id == query
75
+ query == id
76
+ when Element
77
+ query == self
80
78
  when Regexp
81
79
  to_s.match(query)
82
- when /^\/(.+)\/$/
83
- to_s.match(Regexp.new($1))
84
80
  when /@(\w+)(?:\[([^\]]*)\])?/
85
81
  query.scan(/@(\w+)(?:\[([^\]]*)\])?/).any? do |type, condition|
86
82
  has_type?(type) && ( condition.nil? || meets?(condition.split(/,\s*/)) )
87
83
  end
84
+ when /^\/(.+)\/$/
85
+ to_s.match(Regexp.new($1))
88
86
  else
89
87
  id == query.to_sym
90
88
  end
91
89
  end
92
90
 
93
- alias :=== :matches?
94
- alias :match? :matches?
91
+ alias === matches?
92
+ alias match? matches?
95
93
 
96
94
  # Returns true if the element meets all of the given conditions.
97
95
  def meets?(*conditions)
@@ -101,9 +99,9 @@ module BibTeX
101
99
  end
102
100
  end
103
101
 
104
- alias :meet? :meets?
102
+ alias meet? meets?
105
103
 
106
- alias :to_s :content
104
+ alias to_s content
107
105
 
108
106
  def to_hash(options = {})
109
107
  { type => content }