rbibtex 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ 0.0.2
2
+ * Simplified Grammar a bit
3
+ * Now parsing @comment correctly
4
+ * Made rbib2bib actually usefull.
5
+ * Sorting of entries
6
+ * Sorting of fields
7
+ * A help
8
+ * Nicer output respecting formatting.
9
+
1
10
  0.0.1
2
11
  * Removed unneccessary dependency on pp
3
12
  * Added rbib2bib pretty printer
data/InstalledFiles ADDED
@@ -0,0 +1,2 @@
1
+ /home/bschroed//bin/rbib2bib
2
+ /home/bschroed//lib/ruby/site_ruby/1.8/rbibtex/rbibtex.tab.rb
data/README CHANGED
@@ -52,9 +52,13 @@ Brian
52
52
  ## ToDo
53
53
  * The binaries are only quick hacks for my specific applications right now,
54
54
  they should be rewritten and extended.
55
+ * I should transfer functionality from rbib2bib into a library usable by all
56
+ programs.
55
57
  * The full bibtex format is not parsed, I only allow for a specific subset
56
58
  right now.
57
59
  * Escaping is not implemented.
60
+ * Create the documentation after having racc'ed the .y files, then cleanup
61
+ again before packaging.
58
62
 
59
63
  ## Authors
60
64
  This was implemented by Brian Schroeder.
data/bin/rbib2bib CHANGED
@@ -1,76 +1,147 @@
1
- #! /usr/bin/ruby
2
-
3
- $:.unshift("~/lib/ruby")
4
-
5
- require "rbibtex"
6
-
7
- file = BibTeX::Parser.new.parse( ARGF.read )
8
-
9
- first = [:author, :title, :year]
10
- last = [:note, :pdf, :ps, :www]
11
-
12
- puts "@comment { Pretty Printed using rbib2bib }"
13
-
14
- max_key_length = file.inject(0) { | r, entry |
15
- entry.properties.inject(r) { | r, (k, _) |
16
- [r, k.to_s.length].max
17
- }
18
- }
19
-
20
- p max_key_length
1
+ #! /home/bschroed//bin/ruby
21
2
 
3
+ # Some string handling routines for wordwrapping and tabifying.
22
4
  class String
23
5
  def wrap(width = 78, tabwidth = 8)
24
6
  raise "Invalid width" if width < 0
25
7
  self.untabify(tabwidth).
26
- gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n") }.
27
- gsub(/\s*\Z/m, "")
8
+ gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n") }.
9
+ gsub(/\s*\Z/m, "")
28
10
  end
29
11
 
30
12
  def indent_hanging(indent = 2)
31
- self.gsub(/\n/, "\n#{" " * indent}")
13
+ self.gsub(/\n/, "\n#{" " * indent}")
32
14
  end
33
-
15
+
34
16
  def indent(indent = 2)
35
- self.gsub(/^/, " " * indent)
17
+ self.gsub(/^/, " " * indent)
36
18
  end
37
19
 
38
20
 
39
21
  def untabify(tab_width = 8)
40
22
  self.gsub(/\t/, " "*tab_width)
41
23
  end
42
-
24
+
43
25
  def deindent_hanging(indent = [self[/^\s*/].untabify.length, self[/\n(\s*)/, 1].to_s.untabify.length].max)
44
26
  self.untabify.gsub(/^\s{0,#{indent}}/, "")
45
27
  end
46
-
28
+
47
29
  def deindent(indent = self[/^\s*/].untabify.length)
48
30
  self.untabify.gsub(/^\s{0,#{indent}}/, "")
49
31
  end
50
32
 
51
33
  def unwrap
52
34
  self.split(/\n\n+/).map { | paragraph |
53
- paragraph.gsub(/\n(?=\S)/, " ")
35
+ paragraph.gsub(/((?:\n|^)\S[^\n]*)\n(?=\S)/, "\\1 ")
54
36
  }.join("\n\n")
55
37
  end
56
38
  end
57
39
 
58
- file.each do | entry |
59
-
60
- p = entry.properties.dup
61
- f = first.map { | k | [k, p.delete(k)] }
62
- l = last.map { | k | [k, p.delete(k)] }
63
- p = p.to_a.map{ | (k, v) | [k.to_s, v] }.sort
64
-
65
- puts "@#{entry.type}{#{entry.key},"
66
- (f + p + l).each do | (k, v) |
67
- next unless v
68
-
69
- print %( #{k}).ljust(max_key_length+2) + " = {"
70
- print v.deindent_hanging.unwrap.wrap(78-(max_key_length+6)).indent_hanging(max_key_length+6)
71
- puts "},"
40
+ module Bib2Bib
41
+ VERSION = "0.0.2"
42
+
43
+ require 'optparse'
44
+
45
+ class Options < OptionParser
46
+ attr_reader :wrap, :sort_by, :top_fields, :bottom_fields, :output, :help, :show_version, :comment
47
+
48
+ def initialize
49
+ super()
50
+
51
+ # Defaults
52
+ @top_fields = [:author, :title, :year]
53
+ @bottom_fields = [:note, :pdf, :ps, :www]
54
+ @comment = true
55
+ @output = STDOUT
56
+
57
+ # Parser Actions
58
+ self.banner = "Usage: #{ __FILE__ } [-o OUTPUT] [OPTIONS] INPUT [INPUT_1 ...]"
59
+ self.on("-o FILENAME", "--output FILENAME", String,
60
+ "Set the output filename. Writes to stdout if nothing is given") { | v | @output = File.open(v, 'w') }
61
+ self.on("-s", "--sort-by", "--sort_by Field_1,Field2,...", Array,
62
+ "Specify fields that shall be used for sorting of the file") { | v | @sort_by = v.map { | e | e.downcase.to_sym } }
63
+ self.on("-t", "--top_fields Field_1,Field2,...", Array,
64
+ "Specify a list of fields that are written first in the output") { | v | @top_fields = v.map { | e | e.downcase.to_sym }
65
+ @bottom_fields -= @top_fields }
66
+ self.on("-b", "--bottom_fields Field_1,Field2,...", Array,
67
+ "Specify a list of fields that are written last in the output") { | v | @bottom_fields = v.map { | e | e.downcase.to_sym }
68
+ @top_fields -= @bottom_fields }
69
+ self.on("-C", "--no-comment",
70
+ "Suppress generation of 'Created by' comment") { @comment = false }
71
+ self.on("-?", "--help",
72
+ "Show this help") { @help = true }
73
+ self.on("-v", "--version",
74
+ "Output version number and exit") { @show_version = true }
75
+ end
76
+
77
+ def parse!(*args)
78
+ super
79
+ raise "You can't specify an empty list of fields for sorting" if @sort_by and @sort_by.empty?
80
+ end
72
81
  end
73
- puts "}"
74
- puts
75
- end
76
82
 
83
+ options = Options.new
84
+ begin
85
+ options.parse!(ARGV)
86
+ rescue => e
87
+ puts "Invalid Commandline Arguments"
88
+ puts e
89
+ puts options
90
+ exit
91
+ end
92
+
93
+ if options.show_version
94
+ puts VERSION
95
+ exit
96
+ end
97
+
98
+ if options.help
99
+ puts options
100
+ exit
101
+ end
102
+
103
+ require "rbibtex"
104
+
105
+
106
+ entries = BibTeX::Parser.new.parse( ARGF.read )
107
+ O = options.output
108
+
109
+ if @comment
110
+ O.puts "@comment { Pretty Printed using rbib2bib }"
111
+ end
112
+
113
+ # Calculate maximum key length
114
+ max_key_length = entries.entries.inject(0) { | r, entry |
115
+ entry.properties.inject(r) { | r, (k, _) |
116
+ [r, k.to_s.length].max
117
+ }
118
+ }
119
+
120
+ def self.extract_properties(properties, fields)
121
+ fields.map { | k | [k, properties.delete(k)] }.select { | (_, v) | v }
122
+ end
123
+
124
+ elements = entries.elements.select { | e | e.is_a?(BibTeX::Entry) or e.is_a?(BibTeX::Comment) }
125
+ if options.sort_by
126
+ elements = elements.sort_by { | e | e.is_a?(BibTeX::Comment) ? [] : options.sort_by.map { | k | e.properties[k] || "" } }
127
+ end
128
+ puts elements.map { | entry |
129
+
130
+ if entry.is_a?BibTeX::Comment
131
+ "@comment { #{entry.to_s.deindent_hanging.unwrap.wrap(78 - 11).indent_hanging(11)} }"
132
+ else
133
+ properties = entry.properties.dup
134
+ top = extract_properties(properties, options.top_fields)
135
+ bottom = extract_properties(properties, options.bottom_fields)
136
+ middle = properties.to_a.map { | (k, v) | [k.to_s, v] }.sort
137
+
138
+ "@#{entry.type}{#{entry.key},\n" +
139
+ (
140
+ (top + middle + bottom).map { | (k, v) |
141
+ %( #{k}).ljust(max_key_length+2) + " = {#{v.deindent_hanging.unwrap.wrap(78-(max_key_length+6)).indent_hanging(max_key_length+6)}}"
142
+ }.join(",\n")
143
+ ) + "\n}"
144
+ end
145
+ }.join("\n\n\n")
146
+
147
+ end
data/bin/rbib2html CHANGED
@@ -1,4 +1,4 @@
1
- #! /usr/bin/ruby
1
+ #! /home/bschroed//bin/ruby
2
2
 
3
3
  $:.unshift("~/lib/ruby")
4
4
 
data/bin/rbib2txt CHANGED
@@ -1,4 +1,4 @@
1
- #! /usr/bin/ruby
1
+ #! /home/bschroed//bin/ruby
2
2
 
3
3
  $:.unshift("~/lib/ruby")
4
4
 
@@ -2,8 +2,10 @@ class BibTeX::Parser
2
2
 
3
3
  rule
4
4
 
5
- file : opt_space { result = val[0] }
6
- | opt_space object_list opt_space { result = val[1] }
5
+ file : opt_space_element { result = File.new(Space.new(val[0])) }
6
+ | opt_space_element
7
+ object_list
8
+ opt_space_element { result = File.new(*([val[0]] + val[1] + [val[2]]) ) }
7
9
  ;
8
10
 
9
11
  object_list : object { result = [val[0]] }
@@ -17,7 +19,7 @@ rule
17
19
  | entry { result = val[0] }
18
20
  ;
19
21
 
20
- comment : COMMENT opt_space value { result = [:comment, val[2]] }
22
+ comment : COMMENT opt_space value { result = Comment.new(val[2]) }
21
23
  ;
22
24
 
23
25
  entry : entry_head assignment_list
@@ -60,44 +62,52 @@ rule
60
62
  | SINGLE_ANFZ value_content_single_del SINGLE_ANFZ { result = val[1] }
61
63
  | DOUBLE_ANFZ value_content_double_del DOUBLE_ANFZ { result = val[1] }
62
64
  | WORD
65
+ ;
66
+
67
+ brace : LBRACE
68
+ | RBRACE
69
+ ;
70
+
71
+ anfz : SINGLE_ANFZ
72
+ | DOUBLE_ANFZ
63
73
  ;
64
74
 
65
75
  value_content_single_del : { result = "" }
66
- | value_content SPACE { result << val[1] }
67
- | value_content WORD { result << val[1] }
68
- | value_content COMMA { result << val[1] }
69
- /* | value_content "\\" SINGLE_ANFZ { result << val[1] << val[2]} */
76
+ | value_content general_vc_token { result << val[1] }
77
+ | value_content brace { result << val[1] }
70
78
  | value_content DOUBLE_ANFZ { result << val[1] }
71
- | value_content CHARACTER { result << val[1] }
72
- | value_content AT { result << val[1] }
73
- | value_content LBRACE { result << val[1] }
74
- | value_content RBRACE { result << val[1] }
75
79
  ;
76
80
 
77
81
  value_content_double_del : { result = "" }
78
- | value_content SPACE { result << val[1] }
79
- | value_content WORD { result << val[1] }
80
- | value_content COMMA { result << val[1] }
82
+ | value_content general_vc_token { result << val[1] }
83
+ | value_content brace { result << val[1] }
81
84
  | value_content SINGLE_ANFZ { result << val[1] }
82
- /* | value_content "\\" DOUBLE_ANFZ { result << val[1] << val[2] } */
83
- | value_content CHARACTER { result << val[1] }
84
- | value_content AT { result << val[1] }
85
- | value_content LBRACE { result << val[1] }
86
- | value_content RBRACE { result << val[1] }
87
85
  ;
88
86
 
89
- value_content : { result = "" }
90
- | value_content SPACE { result << val[1] }
91
- | value_content WORD { result << val[1] }
92
- | value_content COMMA { result << val[1] }
93
- | value_content SINGLE_ANFZ { result << val[1] }
94
- | value_content DOUBLE_ANFZ { result << val[1] }
95
- | value_content CHARACTER { result << val[1] }
96
- | value_content AT { result << val[1] }
87
+ value_content : { result = "" }
88
+ | value_content general_vc_token { result << val[1] }
89
+ | value_content anfz { result << val[1] }
97
90
  | value_content
98
91
  LBRACE value_content RBRACE { result << val[1] << val[2] << val[3] }
99
92
  ;
100
93
 
94
+ general_vc_token : SPACE
95
+ | WORD
96
+ | COMMA
97
+ | EQUALS
98
+ | CHARACTER
99
+ | AT
100
+ ;
101
+
102
+ opt_space_element :
103
+ | space_element
104
+ ;
105
+
106
+ space_element : SPACE { result = Space.new(val[0]) }
107
+
108
+ space : SPACE
109
+ ;
110
+
101
111
  opt_space :
102
112
  | SPACE
103
113
  ;
@@ -109,6 +119,34 @@ end
109
119
 
110
120
  module BibTeX
111
121
  Entry = Struct.new(:type, :key, :properties)
122
+
123
+ class Space < String; end
124
+
125
+ class Comment
126
+ def initialize(comment)
127
+ @comment = comment
128
+ end
129
+
130
+ def to_s
131
+ @comment
132
+ end
133
+
134
+ alias :to_str :to_s
135
+ end
136
+
137
+ class File
138
+ def initialize(*elements)
139
+ @elements = elements.compact
140
+ end
141
+
142
+ def elements
143
+ @elements
144
+ end
145
+
146
+ def entries
147
+ @elements.select { | e | e.is_a?Entry }
148
+ end
149
+ end
112
150
  end
113
151
 
114
152
  ---- inner ----
@@ -120,13 +158,13 @@ end
120
158
  def parse( str )
121
159
  @q = []
122
160
 
123
- @yydebug = true
161
+ # @yydebug = true
124
162
 
125
163
  while str.size > 0 do
126
164
  case str
127
165
  when /\A[\t\n\s]+/o
128
166
  @q.push [:SPACE, $&]
129
- when /\ACOMMENT/o
167
+ when /\Acomment/io
130
168
  @q.push [:COMMENT, $&]
131
169
  when /\A\,/o
132
170
  @q.push [:COMMA, $&]
data/papers.bib CHANGED
@@ -184,7 +184,8 @@
184
184
  pages = {70--73},
185
185
  year = 2005,
186
186
  Organization = {IEEE},
187
- note = {A short overview of applications and methods for lip tracking, automated speech recogniton, person recogniton, etc. Pointers to databases with joint AV material and relevant Publications.}
187
+ note = {A short overview of applications and methods for lip tracking, automated speech recogniton, person recogniton, etc. Pointers to databases with joint AV material and relevant Publications.},
188
+ pdf = {}
188
189
  }
189
190
 
190
191
  @Article{seyadarabi:facial,
@@ -195,5 +196,11 @@ NUMBER = 4 ,
195
196
  year = 2004 ,
196
197
  ISSN = {1305-239X},
197
198
  Author = {Hadi Seyedarabi and Ali Aghagolzadeh and Sohrab Khanmohammadi},
198
- note = {Written in very bad english and does not contain too much information. They track feature points in 2D video data using optical flow and use these points to interpolate a triangle mesh. They claim to have a muscle-based model, but that shows nowhere.}
199
+ note = {Written in very bad english and does not contain too much information. They track feature points in 2D video data using optical flow and use these points to interpolate a triangle mesh. They claim to have a muscle-based model, but that shows nowhere.},
200
+ pdf = {}
201
+ }
202
+
203
+ @comment {
204
+ todo:
205
+ pdf = {local/blake_sparse_realtime_tracking.pdf}
199
206
  }
data/test.bib ADDED
@@ -0,0 +1,5 @@
1
+ @comment {
2
+ todo:
3
+ pdf = {local/blake_sparse_realtime_tracking.pdf}
4
+ x
5
+ }
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: rbibtex
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.1
6
+ version: 0.0.2
7
7
  date: 2005-11-09 00:00:00 +01:00
8
8
  summary: A bibtex parsing library written in pure ruby
9
9
  require_paths:
@@ -39,7 +39,9 @@ authors:
39
39
  files:
40
40
  - papers.bib
41
41
  - README
42
+ - test.bib
42
43
  - CHANGELOG
44
+ - InstalledFiles
43
45
  - papers.html
44
46
  - setup.rb
45
47
  - bin