citeproc 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
data/{LICENSE → BSDL} RENAMED
@@ -1,4 +1,5 @@
1
- Copyright 2009-2011 Sylvester Keil. All rights reserved.
1
+ Copyright 2012 President and Fellows of Harvard College.
2
+ Copyright 2009-2012 Sylvester Keil. All rights reserved.
2
3
 
3
4
  Redistribution and use in source and binary forms, with or without
4
5
  modification, are permitted provided that the following conditions are met:
data/Gemfile CHANGED
@@ -2,10 +2,21 @@ source :rubygems
2
2
  gemspec
3
3
 
4
4
  group :debug do
5
- gem 'ruby-debug', :platforms => [:ruby_18, :jruby]
6
- gem 'ruby-debug19', :require => 'ruby-debug', :platforms => [:ruby_19]
5
+ gem 'debugger', '~>1.1.3', :platform => :mri_19
7
6
  end
8
7
 
9
8
  group :optional do
10
9
  gem 'chronic', '~>0.6'
10
+ gem 'edtf', '~>1.0.0'
11
+
12
+ gem 'bibtex-ruby', '~>2.0.10', :require => 'bibtex'
13
+
14
+ gem 'simplecov', '~>0.6.4'
15
+
16
+ gem 'unicode_utils', '~>1.3.0', :platform => :mri_19
17
+ gem 'unicode', '~>0.4.2', :platform => :mri_18
18
+ end
19
+
20
+ group :extra do
21
+ gem 'oniguruma', '~>1.1.0', :platform => :mri_18
11
22
  end
data/README.md CHANGED
@@ -1,4 +1,35 @@
1
1
  CiteProc
2
2
  ========
3
+ CiteProc is a cite processor interface and citation data API based on the
4
+ Citation Style Language (CSL) specifications. To actually process citations
5
+ a dedicated processor engine is required; these can be installed as separate
6
+ gems.
3
7
 
4
- The CiteProc gem is a Ruby abstraction layer for the JSON API used by citeproc-js. To process citations you also require a dedicate processor engine available as a separate gem: these will include citeproc-js, citeproc-ruby and eventually citeproc-hs. As work on these packages is still in progress, please be aware of the following caveats: the 0.0.2 release of citeproc-ruby is still a standalone package and will conflict with this release of citeproc; support will be added in future versions. The citeproc-js gem currently works only in JRuby (using an embedded version of the Rhino JavaScript interpreter) but is going to support other versions of Ruby using different JavaScript runtimes.
8
+ ### A word of caution
9
+ As work on this and on the related packages is still in progress, please
10
+ be aware of the following caveats: the 0.0.x branch of citeproc-ruby is still
11
+ a standalone package and will conflict with this release of citeproc; support
12
+ will be added in future versions of the 1.x.x branch.
13
+
14
+ [![Build Status](https://secure.travis-ci.org/berkmancenter/citeproc.png)](http://travis-ci.org/berkmancenter/citeproc)
15
+
16
+
17
+ Citation Data
18
+ -------------
19
+
20
+ Processor Interface
21
+ -------------------
22
+
23
+ Credits
24
+ -------
25
+
26
+
27
+ Copyright
28
+ ---------
29
+ Copyright 2012 President and Fellows of Harvard College.
30
+
31
+ Copyright 2009-2012 Sylvester Keil. All rights reserved.
32
+
33
+ License
34
+ -------
35
+ CiteProc is dual licensed under the AGPL and the FreeBSD license.
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler'
4
+ begin
5
+ Bundler.setup
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+
12
+ $:.unshift(File.join(File.dirname(__FILE__), './lib'))
13
+ require 'citeproc/version'
14
+
15
+
16
+ desc 'Run an IRB session with CiteProc loaded'
17
+ task :console, [:script] do |t,args|
18
+ ARGV.clear
19
+
20
+ require 'irb'
21
+ require 'citeproc'
22
+
23
+ IRB.conf[:SCRIPT] = args.script
24
+ IRB.start
25
+ end
26
+
27
+ require 'rspec/core'
28
+ require 'rspec/core/rake_task'
29
+ RSpec::Core::RakeTask.new(:spec) do |spec|
30
+ spec.pattern = FileList['spec/**/*_spec.rb']
31
+ end
32
+
33
+ require 'cucumber/rake/task'
34
+ Cucumber::Rake::Task.new(:cucumber)
35
+
36
+ task :default => :spec
37
+
38
+ require 'yard'
39
+ YARD::Rake::YardocTask.new
data/citeproc.gemspec CHANGED
@@ -8,28 +8,35 @@ Gem::Specification.new do |s|
8
8
  s.name = 'citeproc'
9
9
  s.version = CiteProc::VERSION.dup
10
10
  s.platform = Gem::Platform::RUBY
11
+
11
12
  s.authors = ['Sylvester Keil']
12
- s.email = 'http://sylvester.keil.or.at'
13
- s.homepage = 'http://inukshuk.github.com/citeproc'
13
+ s.email = ['sylvester@keil.or.at']
14
+
15
+ s.homepage = 'https://github.com/inukshuk/citeproc'
14
16
  s.summary = 'A cite processor interface.'
15
- s.description = 'A a cite processor for Citation Style Language (CSL) styles.'
16
- s.license = 'FreeBSD'
17
+ s.description =
18
+ """
19
+ A cite processor interface for Citation Style Language (CSL) styles.
20
+ """
21
+
22
+ s.license = 'AGPL'
17
23
  s.date = Time.now.strftime('%Y-%m-%d')
18
24
 
19
- s.add_runtime_dependency('multi_json', '~>1.0')
25
+ s.add_runtime_dependency('multi_json', '~>1.3.5')
26
+ s.add_runtime_dependency('namae', '~>0.1')
20
27
 
21
- s.add_development_dependency('cucumber', ['>=1.0.2'])
22
- s.add_development_dependency('rspec', ['>=2.6.0'])
23
- s.add_development_dependency('watchr', ['>=0.7'])
28
+ s.add_development_dependency('cucumber', ['~>1.2.0'])
29
+ s.add_development_dependency('rspec', ['~>2.10.0'])
30
+ s.add_development_dependency('watchr', ['~>0.7'])
31
+ s.add_development_dependency('rake', ['~>0.9.2'])
32
+ s.add_development_dependency('yard', ['~>0.8.1'])
24
33
 
25
34
  s.files = `git ls-files`.split("\n")
26
35
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
36
  s.executables = []
28
37
  s.require_path = 'lib'
29
38
 
30
- s.rdoc_options = %w{--line-numbers --inline-source --title "CiteProc" --main README.md --webcvs=http://github.com/inukshuk/citeproc/tree/master/}
31
- s.extra_rdoc_files = %w{README.md}
32
-
39
+ s.has_rdoc = 'yard'
33
40
  end
34
41
 
35
42
  # vim: syntax=ruby
data/lib/citeproc.rb CHANGED
@@ -1,13 +1,11 @@
1
1
 
2
- require 'multi_json'
2
+ require 'date'
3
3
  require 'forwardable'
4
4
  require 'observer'
5
5
  require 'uri'
6
6
 
7
- if ENV['DEBUG']
8
- require 'ruby-debug'
9
- Debugger.start
10
- end
7
+ require 'multi_json'
8
+ require 'namae'
11
9
 
12
10
  require 'citeproc/version'
13
11
 
@@ -17,7 +15,11 @@ require 'citeproc/version'
17
15
  #
18
16
  module CiteProc
19
17
 
20
- module Converters; end
18
+ module Converters
19
+ end
20
+
21
+ module Utilities
22
+ end
21
23
 
22
24
  end
23
25
 
@@ -34,11 +36,11 @@ require 'citeproc/date'
34
36
  require 'citeproc/names'
35
37
 
36
38
  CiteProc::Variable.class_eval do
37
- @factories = Hash.new { |h,k| h.fetch(k.to_sym, CiteProc::Variable) }.merge(
38
- Hash[*@types.map { |n,k|
39
- [n, CiteProc.const_get(k.to_s.capitalize)]
40
- }.flatten]
41
- ).freeze
39
+ @factories = Hash.new { |h,k| h.fetch(k.to_s.intern, CiteProc::Variable) }.merge(
40
+ Hash[*@types.map { |n,k|
41
+ [n, CiteProc.const_get(k.to_s.capitalize)]
42
+ }.flatten]
43
+ ).freeze
42
44
  end
43
45
 
44
46
  require 'citeproc/item'
@@ -1,5 +1,3 @@
1
- require 'multi_json'
2
-
3
1
  module CiteProc
4
2
  module Abbreviate
5
3
 
@@ -20,8 +18,7 @@ module CiteProc
20
18
  end
21
19
  end
22
20
 
23
- # call-seq:
24
- # abbreviate(namespace = :default, context, word)
21
+ # @overload abbreviate(namespace = :default, context, word)
25
22
  def abbreviate(*arguments)
26
23
  raise ArgumentError, "wrong number of arguments (#{arguments.length} for 2..3)" unless (2..3).include?(arguments.length)
27
24
  arguments.unshift(namespace || :default) if arguments.length < 3
@@ -39,8 +39,7 @@ module CiteProc
39
39
 
40
40
  self
41
41
  rescue => e
42
- puts e.backtrace.join("\n")
43
- raise ArgumentError, "failed to open asset #{input.inspect}: #{e.message}"
42
+ raise ArgumentError, "failed to open asset #@location (#{input.inspect}): #{e.message}"
44
43
  end
45
44
 
46
45
  def name
@@ -66,8 +65,16 @@ module CiteProc
66
65
  end
67
66
 
68
67
  def extend_name(input)
69
- name = File.extname(input).empty? ? [input, extension].compact.join : input.to_s.dup
70
- name = name.start_with?(prefix.to_s) ? name : [prefix, name].join
68
+ if File.extname(input) != extension
69
+ name = [input, extension].compact.join
70
+ else
71
+ name = input.to_s.dup
72
+ end
73
+
74
+ unless name.start_with?(prefix.to_s)
75
+ name = [prefix, name].join
76
+ end
77
+
71
78
  name
72
79
  end
73
80
 
@@ -1,16 +1,8 @@
1
-
2
1
  module CiteProc
3
-
4
- # TODO refactor using a Struct instead of a hash. This will have to convert
5
- # the CiteProc/CSL names which are no proper method names.
6
-
7
-
2
+
8
3
  module Attributes
9
4
  extend Forwardable
10
-
11
5
 
12
- FALSE_PATTERN = (/^(false|no|never)$/i).freeze
13
-
14
6
  def self.included(base)
15
7
  base.extend(ClassMethods)
16
8
  end
@@ -19,104 +11,119 @@ module CiteProc
19
11
  @attributes ||= {}
20
12
  end
21
13
 
22
- def_delegators :attributes, :length, :empty?
23
-
24
- def [](key)
25
- attributes[filter_key(key)]
26
- end
27
-
28
- def []=(key, value)
29
- attributes[filter_key(key)] = filter_value(value)
30
- end
31
-
32
- def filter_key(key)
33
- key.to_sym
34
- end
35
-
36
- def filter_value(value, key = nil)
37
- value.respond_to?(:deep_copy) ? value.deep_copy : value.dup
38
- rescue
39
- value
40
- end
41
-
14
+ def_delegators :attributes, :length, :empty?, :values_at, :key?, :value?
15
+
16
+ alias size length
17
+
18
+ def [](key)
19
+ attributes[filter_key(key)]
20
+ end
21
+
22
+ def []=(key, value)
23
+ attributes[filter_key(key)] = filter_value(value)
24
+ end
25
+
26
+ def filter_key(key)
27
+ key.to_sym
28
+ end
29
+
30
+ def filter_value(value, key = nil)
31
+ value.respond_to?(:deep_copy) ? value.deep_copy : value.dup
32
+ rescue
33
+ value
34
+ end
35
+
42
36
  def merge(other)
43
37
  return self if other.nil?
44
38
 
45
- case other
46
- when String, /^\s*\{/
47
- other = MulitJson.decode(other, :symbolize_keys => true)
48
- when Hash
49
- # do nothing
50
- when Attributes
39
+ case
40
+ when other.is_a?(String) && /^\s*\{/ =~ other
41
+ other = MultiJson.decode(other, :symbolize_keys => true)
42
+ when other.respond_to?(:each_pair)
43
+ # do nothing
44
+ when other.respond_to?(:to_hash)
51
45
  other = other.to_hash
52
- else
53
- raise ParseError, "failed to merge attributes and #{other.inspect}"
46
+ else
47
+ raise ParseError, "failed to merge attributes and #{other.inspect}"
54
48
  end
55
49
 
56
50
  other.each_pair do |key, value|
57
- attributes[filter_key(key)] = filter_value(value, key)
58
- end
59
-
51
+ attributes[filter_key(key)] = filter_value(value, key)
52
+ end
53
+
60
54
  self
61
55
  end
62
56
 
63
57
  alias update merge
64
58
 
65
- def reverse_merge(other)
66
- fail "not implemented yet"
67
- end
68
-
69
- def to_hash
70
- attributes.deep_copy
71
- end
72
-
73
- def to_citeproc
74
- Hash[*attributes.map { |k,v|
75
- [k.to_s, v.respond_to?(:to_citeproc) ? v.to_citeproc : v.to_s]
76
- }.flatten(1)]
77
- end
78
-
79
- def to_json
80
- MultiJson.encode(to_citeproc)
81
- end
82
-
83
- # Don't expose internals to public API
84
- private :filter_key, :filter_value
85
-
86
- # initialize_copy should be able to access attributes
87
- protected :attributes
88
-
89
-
90
-
91
- # def eql?(other)
92
- # case
93
- # when equal?(other)
94
- # true
95
- # when self.class != other.class, length != other.length
96
- # false
97
- # else
98
- # other.attributes.each_pair do |key, value|
99
- # return false unless attributes[key].eql?(value)
100
- # end
101
- #
102
- # true
103
- # end
104
- # end
105
- #
106
- # def hash
107
- # end
108
-
59
+ def reverse_merge(other)
60
+ fail "not implemented yet"
61
+ end
62
+
63
+ def to_hash
64
+ attributes.deep_copy
65
+ end
66
+
67
+ # @return [Hash] a hash-based representation of the attributes
68
+ def to_citeproc
69
+ Hash[attributes.map { |k,v|
70
+ [k.to_s, v.respond_to?(:to_citeproc) ? v.to_citeproc : v.to_s]
71
+ }]
72
+ end
73
+
74
+ # @return [String] a JSON string representation of the attributes
75
+ def to_json
76
+ MultiJson.encode(to_citeproc)
77
+ end
78
+
79
+ # Don't expose internals to public API
80
+ private :filter_key, :filter_value
81
+
82
+ # initialize_copy should be able to access attributes
83
+ protected :attributes
84
+
85
+
86
+ # Two Attribute-based objects are equal if they are the same object,
87
+ # or if all their attributes are equal using _#eql?_.
88
+ #
89
+ # @param other [Object] the other object
90
+ # @return [Boolean] whether or not self and passed-in object are equal
91
+ def eql?(other)
92
+ case
93
+ when equal?(other)
94
+ true
95
+ when self.class != other.class, length != other.length
96
+ false
97
+ else
98
+ other.attributes.each_pair do |key, value|
99
+ return false unless attributes[key].eql?(value)
100
+ end
101
+
102
+ true
103
+ end
104
+ end
105
+
106
+ # @return [Fixnum] a hash value based on the object's attributes
107
+ def hash
108
+ digest = size
109
+ attributes.each do |attribute|
110
+ digest ^= attribute.hash
111
+ end
112
+
113
+ digest
114
+ end
115
+
109
116
  module ClassMethods
110
117
 
111
- def create(parameters)
112
- create!(parameters)
113
- rescue
114
- nil
115
- end
118
+ def create(parameters)
119
+ create!(parameters)
120
+ rescue
121
+ nil
122
+ end
116
123
 
117
- def create!(parameters)
118
- new.merge(parameters)
119
- end
124
+ def create!(parameters)
125
+ new.merge(parameters)
126
+ end
120
127
 
121
128
  def attr_predicates(*arguments)
122
129
  arguments.flatten.each do |field|
@@ -152,12 +159,12 @@ module CiteProc
152
159
  attributes[field.to_sym] = value
153
160
  end
154
161
  end
155
-
162
+
156
163
  predicate_id = [method_id, '?'].join
157
164
  if predicate && !instance_methods.include?(predicate_id)
158
165
  define_method(predicate_id) do
159
- v = attributes[field.to_sym]
160
- !(v.nil? || (v.respond_to?(:empty?) && v.empty?) || v =~ FALSE_PATTERN)
166
+ v = attributes[field.to_sym]
167
+ !(!v || (v.respond_to?(:empty?) && v.empty?) || v.to_s =~ /^(false|no|never)$/i)
161
168
  end
162
169
 
163
170
  has_predicate = ['has_', predicate_id].join