citeproc 0.0.8 → 0.0.9

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