citeproc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright 2009-2011 Sylvester Keil. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice,
7
+ this list of conditions and the following disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
14
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
16
+ EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
17
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
20
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
22
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
+
24
+ The views and conclusions contained in the software and documentation are
25
+ those of the authors and should not be interpreted as representing official
26
+ policies, either expressed or implied, of the copyright holder.
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ CiteProc
2
+ ========
data/auto.watchr ADDED
@@ -0,0 +1,20 @@
1
+
2
+ # Rules
3
+ # --------------------------------------------------
4
+ watch( '^spec/.+_spec.rb' ) { |m| rspec m[0] }
5
+ watch( '^lib/(.*)\.rb' ) { |m| rspec "spec/#{m[1]}_spec.rb" }
6
+
7
+ # Signal Handling
8
+ # --------------------------------------------------
9
+ Signal.trap('QUIT') { rspec 'spec' } # Ctrl-\
10
+ Signal.trap('INT' ) { abort("\n") } # Ctrl-C
11
+
12
+ def rspec (*paths)
13
+ paths = paths.reject { |p| !File.exists?(p) }
14
+ run "bundle exec rspec #{ paths.empty? ? 'spec' : paths.join(' ') }"
15
+ end
16
+
17
+ def run (cmd)
18
+ puts cmd
19
+ system cmd
20
+ end
data/citeproc.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $:.unshift lib unless $:.include?(lib)
4
+
5
+ require 'citeproc/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'citeproc'
9
+ s.version = CiteProc::VERSION.dup
10
+ s.platform = Gem::Platform::RUBY
11
+ s.authors = ['Sylvester Keil']
12
+ s.email = 'http://sylvester.keil.or.at'
13
+ s.homepage = 'http://inukshuk.github.com/citeproc'
14
+ 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.date = Time.now.strftime('%Y-%m-%d')
18
+
19
+ s.add_runtime_dependency('multi_json', '~>1.0')
20
+
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'])
24
+
25
+ s.files = `git ls-files`.split("\n")
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.executables = []
28
+ s.require_path = 'lib'
29
+
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
+
33
+ end
34
+
35
+ # vim: syntax=ruby
data/lib/citeproc.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+
3
+ require 'citeproc/version'
4
+ require 'citeproc/extensions'
5
+ require 'citeproc/errors'
6
+ require 'citeproc/abbreviate'
7
+ require 'citeproc/engine'
8
+ require 'citeproc/processor'
9
+ require 'citeproc/utilities'
10
+
11
+ CiteProc.extend CiteProc::Utilities
@@ -0,0 +1,30 @@
1
+ require 'multi_json'
2
+
3
+ module CiteProc
4
+ module Abbreviate
5
+
6
+ attr_reader :abbreviations
7
+ attr_accessor :default_namespace
8
+
9
+ def abbreviations=(abbreviations)
10
+ @abbreviations = case abbreviations
11
+ when ::String
12
+ MultiJson.decode(abbreviations, :symbolize_keys => true)
13
+ when ::Hash
14
+ abbreviations.deep_copy
15
+ else raise ArgumentError, "failed to set abbreviations from #{abbreviations.inspect}"
16
+ end
17
+ end
18
+
19
+ # call-seq:
20
+ # abbreviate(namespace = :default, context, word)
21
+ def abbreviate(*arguments)
22
+ raise ArgumentError, "wrong number of arguments (#{arguments.length} for 2..3)" unless (2..3).include?(arguments.length)
23
+ arguments.unshift(default_namespace || :default) if arguments.length < 3
24
+ @abbreviations.deep_fetch(*arguments)
25
+ end
26
+
27
+ alias abbrev abbreviate
28
+
29
+ end
30
+ end
@@ -0,0 +1,126 @@
1
+ require 'forwardable'
2
+
3
+ module CiteProc
4
+
5
+ class Engine
6
+
7
+ extend Forwardable
8
+ include Abbreviate
9
+
10
+ @subclasses ||= []
11
+
12
+ class << self
13
+
14
+ attr_reader :subclasses, :type, :version
15
+
16
+ private :new
17
+
18
+ def inherited(subclass)
19
+ subclass.public_class_method :new
20
+ @subclasses << subclass
21
+ @subclasses = subclasses.sort_by { |engine| -1 * engine.priority }
22
+ end
23
+
24
+ # Returns the engine class for the given name or nil. If no suitable
25
+ # class is found and a block is given, executes the block and returns
26
+ # the result. The list of available engines will be passed to the block.
27
+ def detect(name)
28
+ subclasses.detect { |e| e.name == name } ||
29
+ block_given? ? yield(subclasses) : nil
30
+ end
31
+
32
+ # Loads the engine with the given name and returns the engine class.
33
+ def detect!(name)
34
+ load(name)
35
+ block_given? ? detect(name, &Proc.new) : detect(name)
36
+ end
37
+
38
+ # Returns the best available engine class or nil.
39
+ def autodetect(options = {})
40
+ klass = subclasses.detect { |e|
41
+ !options.has_key?(:engine) || e.name == options[:engine] and
42
+ !options.has_key?(:name) || e.name == options[:name]
43
+ } || subclasses.first
44
+ end
45
+
46
+ # Loads the engine by requiring the engine name.
47
+ def load(name)
48
+ require name.gsub(/-/,'/')
49
+ rescue LoadError => e
50
+ warn "failed to load #{name} engine: try to gem install #{name}"
51
+ end
52
+
53
+ # Returns a list of all available engine names.
54
+ def available
55
+ subclasses.map(&:engine_name)
56
+ end
57
+
58
+ def engine_name
59
+ @name ||= name.gsub(/::/, '-').downcase # returns class name as fallback
60
+ end
61
+
62
+ def priority
63
+ @priority ||= 0
64
+ end
65
+ end
66
+
67
+ attr_accessor :processor, :locales, :style
68
+
69
+ def_delegators :@processor, :items, :options
70
+
71
+
72
+ def initialize(attributes = {})
73
+ @processor = attributes[:processor]
74
+ @abbreviations = attributes[:abbreviations] || { :default => {} }
75
+ yield self if block_given?
76
+ end
77
+
78
+ def start
79
+ @started = true
80
+ self
81
+ end
82
+
83
+ def stop
84
+ @started = false
85
+ self
86
+ end
87
+
88
+ def started?; !!@started; end
89
+
90
+ alias running? started?
91
+
92
+ [[:name, :engine_name], :type, :version].each do |method_id, target|
93
+ define_method(method_id) do
94
+ self.class.send(target || method_id)
95
+ end
96
+ end
97
+
98
+ def process
99
+ raise NotImplementedByEngine
100
+ end
101
+
102
+ def append
103
+ raise NotImplementedByEngine
104
+ end
105
+
106
+ alias append_citation_cluster append
107
+
108
+ def process_citation_cluster
109
+ raise NotImplementedByEngine
110
+ end
111
+
112
+ def make_bibliography
113
+ raise NotImplementedByEngine
114
+ end
115
+
116
+ def update_items
117
+ raise NotImplementedByEngine
118
+ end
119
+
120
+ def update_uncited_items
121
+ raise NotImplementedByEngine
122
+ end
123
+
124
+ end
125
+
126
+ end
@@ -0,0 +1,17 @@
1
+ module CiteProc
2
+
3
+ class Error < StandardError
4
+ attr_reader :original
5
+
6
+ def initialize(message, original = nil)
7
+ @original = original ? super([message, original.message].join(': ')) : super(message)
8
+ end
9
+ end
10
+
11
+ class EngineError < Error
12
+ end
13
+
14
+ class NotImplementedByEngine < EngineError
15
+ end
16
+
17
+ end
@@ -0,0 +1,44 @@
1
+
2
+ module CiteProc
3
+ module Extensions
4
+
5
+ module DeepCopy
6
+ def deep_copy
7
+ Hash[*map { |k,v| [
8
+ k.is_a?(Symbol) ? k : k.respond_to?(:deep_copy) ? k.deep_copy : k.clone,
9
+ v.is_a?(Symbol) ? v : v.respond_to?(:deep_copy) ? v.deep_copy : v.clone
10
+ ]}.flatten]
11
+ end
12
+ end
13
+
14
+ module DeepFetch
15
+ def deep_fetch(*arguments)
16
+ arguments.reduce(self) { |s,a| s[a] } rescue nil
17
+ end
18
+
19
+ def [](*arguments)
20
+ return super if arguments.length == 1
21
+ deep_fetch(*arguments)
22
+ end
23
+
24
+ end
25
+
26
+ module AliasMethods
27
+ private
28
+ def alias_methods(*arguments)
29
+ raise ArgumentError, "wrong number of arguments (#{arguments.length} for 2 or more)" if arguments.length < 2
30
+ method_id = arguments.shift
31
+ arguments.each { |a| alias_method method_id, a }
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ class Hash
38
+ include CiteProc::Extensions::DeepCopy
39
+ include CiteProc::Extensions::DeepFetch
40
+ end
41
+
42
+ # module Kernel
43
+ # include CiteProc::Extensions::AliasMethods
44
+ # end
@@ -0,0 +1,24 @@
1
+
2
+ module CiteProc
3
+ class Processor
4
+
5
+ @defaults ||= {
6
+ :locale => 'en-US',
7
+ :style => 'chicago-author-date',
8
+ :engine => 'citeproc-js',
9
+ :format => 'html'
10
+ }
11
+
12
+ class << self
13
+ attr_reader :defaults
14
+ end
15
+
16
+ attr_reader :options, :engine, :items
17
+
18
+ def initialize(options = {})
19
+ @options = Processor.defaults.merge(options)
20
+ @engine = Engine.autodetect(@options).new :processor => self
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+
2
+ module CiteProc
3
+ module Utilities
4
+
5
+ # call-seq:
6
+ # process(mode = :bibliography, items, options = {})
7
+ def process(*arguments)
8
+ end
9
+
10
+ def cite(items, options = {})
11
+ process(:citation, items, options)
12
+ end
13
+
14
+ def bibliography(items, options = {})
15
+ process(:bibliography, items, options)
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module CiteProc
2
+ VERSION = '0.0.1'.freeze
3
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ module CiteProc
4
+ describe 'Abbreviate' do
5
+ before { Object.class_eval { include Abbreviate } }
6
+
7
+ let(:subject) { Object.new }
8
+
9
+ describe '#abbreviations=' do
10
+ context 'given a hash' do
11
+ let(:abbrev) { Hash[:foo, :bar] }
12
+ it 'uses the hash as the new set of abbreviations' do
13
+ subject.abbreviations = abbrev
14
+ subject.abbreviations.should == abbrev
15
+ subject.abbreviations.should_not equal(abbrev)
16
+ end
17
+ end
18
+
19
+ context 'given a string' do
20
+ let(:abbrev) { '{"foo":"bar"}' }
21
+ it 'uses the hash as the new set of abbreviations' do
22
+ subject.abbreviations = abbrev
23
+ subject.abbreviations.should == Hash[:foo,'bar']
24
+ end
25
+ end
26
+ end
27
+
28
+ describe '#abbreviate' do
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ module CiteProc
4
+ describe 'Engine' do
5
+
6
+ it 'cannot be instantiated' do
7
+ lambda { Engine.new }.should raise_error(NoMethodError)
8
+ end
9
+
10
+ describe 'subclasses' do
11
+ let(:subject) { Class.new(Engine).new { |e| e.processor = double(:processor) } }
12
+
13
+ it 'can be instantiated' do
14
+ subject.should_not be nil
15
+ end
16
+
17
+ it 'can be started' do
18
+ expect { subject.start }.to change { subject.running? }.from(false).to(true)
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hash do
4
+ let(:hash) { { :a => { :b => { :c => :d } } } }
5
+
6
+
7
+ describe '#deep_copy' do
8
+ it { hash.should respond_to(:deep_copy) }
9
+
10
+ it 'returns a copy equal to the hash' do
11
+ hash.deep_copy.should == hash
12
+ end
13
+
14
+ it 'returns a copy that is not identical to the hash' do
15
+ hash.deep_copy.should_not equal(hash)
16
+ end
17
+
18
+ it 'returns a deep copy' do
19
+ hash.deep_copy[:a].should == hash[:a]
20
+ hash.deep_copy[:a].should_not equal(hash[:a])
21
+ hash.deep_copy[:a][:b].should == hash[:a][:b]
22
+ hash.deep_copy[:a][:b].should_not equal(hash[:a][:b])
23
+ hash.deep_copy[:a][:b][:c].should == hash[:a][:b][:c]
24
+ end
25
+ end
26
+
27
+ describe '#deep_fetch' do
28
+ # it 'behaves like normal for two arguments' do
29
+ # hash.fetch(:b, 42).should == 42
30
+ # end
31
+ #
32
+ # it 'behaves like normal for one argument and a block' do
33
+ # hash.fetch(:b) {42}.should == 42
34
+ # end
35
+
36
+ it 'returns the value of all the arguments applied as keys' do
37
+ hash.deep_fetch(:a, :b, :c).should == :d
38
+ end
39
+
40
+ it 'returns nil if any of the values did not exist' do
41
+ hash.deep_fetch(:x, :b, :c).should be nil
42
+ hash.deep_fetch(:a, :x, :c).should be nil
43
+ hash.deep_fetch(:a, :b, :x).should be nil
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ module CiteProc
4
+ describe 'Processor' do
5
+ before { Class.new(Engine) }
6
+
7
+ let(:subject) { Processor.new }
8
+
9
+ it { should_not be nil }
10
+
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'CiteProc' do
4
+
5
+ describe '.process' do
6
+ it 'is defined' do
7
+ CiteProc.should respond_to(:process)
8
+ end
9
+ end
10
+
11
+ end
12
+
@@ -0,0 +1 @@
1
+ require 'citeproc'
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: citeproc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sylvester Keil
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-03 00:00:00.000000000 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: multi_json
17
+ requirement: &2157053340 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '1.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2157053340
26
+ - !ruby/object:Gem::Dependency
27
+ name: cucumber
28
+ requirement: &2157052700 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *2157052700
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ requirement: &2157052100 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: 2.6.0
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *2157052100
48
+ - !ruby/object:Gem::Dependency
49
+ name: watchr
50
+ requirement: &2157051560 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0.7'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *2157051560
59
+ description: A a cite processor for Citation Style Language (CSL) styles.
60
+ email: http://sylvester.keil.or.at
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files:
64
+ - README.md
65
+ files:
66
+ - .gitignore
67
+ - .rspec
68
+ - Gemfile
69
+ - LICENSE
70
+ - README.md
71
+ - auto.watchr
72
+ - citeproc.gemspec
73
+ - lib/citeproc.rb
74
+ - lib/citeproc/abbreviate.rb
75
+ - lib/citeproc/engine.rb
76
+ - lib/citeproc/errors.rb
77
+ - lib/citeproc/extensions.rb
78
+ - lib/citeproc/processor.rb
79
+ - lib/citeproc/utilities.rb
80
+ - lib/citeproc/version.rb
81
+ - spec/citeproc/abbreviate_spec.rb
82
+ - spec/citeproc/engine_spec.rb
83
+ - spec/citeproc/extensions_spec.rb
84
+ - spec/citeproc/processor_spec.rb
85
+ - spec/citeproc/utilities_spec.rb
86
+ - spec/spec_helper.rb
87
+ has_rdoc: true
88
+ homepage: http://inukshuk.github.com/citeproc
89
+ licenses:
90
+ - FreeBSD
91
+ post_install_message:
92
+ rdoc_options:
93
+ - --line-numbers
94
+ - --inline-source
95
+ - --title
96
+ - ! '"CiteProc"'
97
+ - --main
98
+ - README.md
99
+ - --webcvs=http://github.com/inukshuk/citeproc/tree/master/
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 1.6.2
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: A cite processor interface.
120
+ test_files:
121
+ - spec/citeproc/abbreviate_spec.rb
122
+ - spec/citeproc/engine_spec.rb
123
+ - spec/citeproc/extensions_spec.rb
124
+ - spec/citeproc/processor_spec.rb
125
+ - spec/citeproc/utilities_spec.rb
126
+ - spec/spec_helper.rb