scholar 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ doc/
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/cassettes
14
+ spec/reports
15
+ spec/tmp
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format Fuubar
2
+ --color
3
+ --drb
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p385
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ branches:
2
+ only:
3
+ - master
4
+ rvm:
5
+ - 1.9.2
6
+ - 1.9.3
7
+ - 2.0.0
8
+ script: bundle exec rspec spec
9
+ notifications:
10
+ email:
11
+ - ethan.turkeltaub@gmail.com
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development, :test do
6
+ gem 'rake'
7
+ gem 'pry'
8
+ gem 'log_buddy'
9
+ end
10
+
11
+ group :test do
12
+ gem 'rspec'
13
+
14
+ gem 'factory_girl'
15
+
16
+ gem 'spork'
17
+ gem 'fuubar'
18
+
19
+ gem 'cane'
20
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,58 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ scholar (0.1.0)
5
+ activesupport (~> 3.2.11)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (3.2.11)
11
+ i18n (~> 0.6)
12
+ multi_json (~> 1.0)
13
+ cane (2.5.0)
14
+ parallel
15
+ coderay (1.0.8)
16
+ diff-lcs (1.1.3)
17
+ factory_girl (4.2.0)
18
+ activesupport (>= 3.0.0)
19
+ fuubar (1.1.0)
20
+ rspec (~> 2.0)
21
+ rspec-instafail (~> 0.2.0)
22
+ ruby-progressbar (~> 1.0.0)
23
+ i18n (0.6.1)
24
+ log_buddy (0.7.0)
25
+ method_source (0.8.1)
26
+ multi_json (1.5.0)
27
+ parallel (0.6.1)
28
+ pry (0.9.11.4)
29
+ coderay (~> 1.0.5)
30
+ method_source (~> 0.8)
31
+ slop (~> 3.4)
32
+ rake (10.0.3)
33
+ rspec (2.12.0)
34
+ rspec-core (~> 2.12.0)
35
+ rspec-expectations (~> 2.12.0)
36
+ rspec-mocks (~> 2.12.0)
37
+ rspec-core (2.12.2)
38
+ rspec-expectations (2.12.1)
39
+ diff-lcs (~> 1.1.3)
40
+ rspec-instafail (0.2.4)
41
+ rspec-mocks (2.12.1)
42
+ ruby-progressbar (1.0.2)
43
+ slop (3.4.3)
44
+ spork (0.9.2)
45
+
46
+ PLATFORMS
47
+ ruby
48
+
49
+ DEPENDENCIES
50
+ cane
51
+ factory_girl
52
+ fuubar
53
+ log_buddy
54
+ pry
55
+ rake
56
+ rspec
57
+ scholar!
58
+ spork
data/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ethan Turkeltaub
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # Scholar [![Build Status](https://secure.travis-ci.org/noted/scholar.png)](https://travis-ci.org/noted/scholar)
2
+
3
+ Scholar is a Ruby library for building [MLA citations](http://www.mla.org/) for scholarly works.
4
+
5
+ ```ruby
6
+ salinger = Scholar::Citation.new({
7
+ :type => :book,
8
+ :media => :print,
9
+ :title => "The Catcher in the Rye",
10
+ :contributors => [
11
+ {
12
+ :role => :author,
13
+ :first => "J",
14
+ :middle => "D",
15
+ :last => "Salinger"
16
+ }
17
+ ],
18
+ :publisher => "Little, Brown",
19
+ :city => "Boston",
20
+ :year => "1995"
21
+ })
22
+ salinger.html # => Salinger, J. D. <em>Catcher in the Rye</em>. Boston: Little, Brown, 1995.
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ To create a citation, you pass `Scholar::Citation` a hash with the attributes associated with the source. See the specific type on [the wiki](https://github.com/noted/scholar/wiki/Supported-Types) for the attributes available.
28
+
29
+ ### Global Attributes
30
+
31
+ All source types can take these fields.
32
+
33
+ * `:type` &mdash; The type of publication you're citing ([see the wiki for a list of supported types](https://github.com/noted/scholar/wiki/Supported-Types)).
34
+ * `:contributors` &mdash; An array of contributors (see below for details).
35
+
36
+ #### Contributors
37
+
38
+ The `:contributors` key is an array of hashes that define contributors. Here's an example.
39
+
40
+ ```ruby
41
+ :contributors => [
42
+ {
43
+ :role => :author,
44
+ :first => "Douglas",
45
+ :middle => "Noel",
46
+ :last => "Adams"
47
+ },
48
+ {
49
+ :role => :author,
50
+ :first => "Eion",
51
+ :last => "Colfer"
52
+ },
53
+ {
54
+ :role => :editor,
55
+ :first => "John",
56
+ :last => "Sample",
57
+ :suffix => "PhD"
58
+ }
59
+ {
60
+ :role => :compiler,
61
+ :first => "Steve",
62
+ :last => "Jobs"
63
+ },
64
+ {
65
+ :role => :translator,
66
+ :first => "Bill",
67
+ :last => "Gates"
68
+ }
69
+ ]
70
+ ```
71
+
72
+ Each hash can take the following fields:
73
+
74
+ * `:role` &mdash; Can be `:author`, `:editor`, `:translator`, `:compiler`.
75
+ * `:first` &mdash; The person's name.
76
+ * `:middle` &mdash; The person's middle name (will convert to middle initial).
77
+ * `:last` &mdash; The person's surname.
78
+ * `:suffix` &mdash; Any suffixes the person has ("PhD", "Esq", "Jr", etc). Omit periods.
79
+
80
+ ## Contributing
81
+
82
+ 1. [Fork the repository.][fork]
83
+ 2. [Create a topic branch.][branch]
84
+ 3. Add tests for your unimplemented feature or bug fix.
85
+ 4. Run `bundle exec rspec`. If your tests pass, return to step 3.
86
+ 5. Implement your feature or bug fix.
87
+ 6. Run `bundle exec rspec`. If your tests fail, return to step 5.
88
+ 7. Add documentation for your feature or bug fix.
89
+ 8. Add, commit, and push your changes.
90
+ 9. [Submit a pull request.][pr]
91
+
92
+ [fork]: http://help.github.com/fork-a-repo/
93
+ [branch]: http://learn.github.com/p/branching.html
94
+ [pr]: http://help.github.com/send-pull-requests/
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/lib/scholar.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'json'
2
+ require 'active_support/all'
3
+
4
+ require_relative 'scholar/utilities'
5
+ require_relative 'scholar/citation'
6
+ require_relative 'scholar/source'
7
+
8
+ # Allows for the creation of scholarly MLA citations.
9
+ module Scholar
10
+ end
@@ -0,0 +1,55 @@
1
+ module Scholar
2
+
3
+ # A Citation object containing the attributes of the
4
+ # citation and the HTML citation itself.
5
+ class Citation
6
+
7
+ # The pieces of data in the Citation.
8
+ attr_reader :attributes
9
+
10
+ # The actual HTML citation.
11
+ attr_reader :html
12
+
13
+ # Creates a new Citation from the given attributes.
14
+ #
15
+ # ==== Attributes
16
+ #
17
+ # * +options+ - The attributes of the Citation.
18
+ #
19
+ # ==== Options
20
+ #
21
+ # * +:type+ - Not optional. The type of source you are citing.
22
+ # * +:contributors+ - An array of hashes of contributors.
23
+ #
24
+ # ==== Examples
25
+ #
26
+ # citation = Scholar::Citation.new({
27
+ # :type => :book,
28
+ # :title => "Foobar",
29
+ # :contributors => [
30
+ # {
31
+ # :role => :author,
32
+ # :first => "John",
33
+ # :last => "Sample"
34
+ # }
35
+ # ]
36
+ # })
37
+ #
38
+ # Obviously, you'd include more than that, but you need to see the
39
+ # specific sources for more documentation.
40
+ def initialize(options = {})
41
+ source = "Scholar::Sources::#{options[:type].to_s.camelize}".constantize
42
+
43
+ @attributes = options
44
+ @attributes.delete(:type)
45
+
46
+ @attributes = Scholar::Utilities.contributors!(@attributes)
47
+ @attributes = Scholar::Utilities.order!(@attributes, source.sequence)
48
+
49
+ attributes = @attributes.clone
50
+ attributes = Scholar::Utilities.format!(attributes, source.rules)
51
+
52
+ @html = Scholar::Utilities.concatenate!(attributes)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,59 @@
1
+ module Scholar
2
+
3
+ # The basis for sources. Inherit from this class to create
4
+ # other types of sources.
5
+ class Source < Utilities
6
+ class << self
7
+
8
+ # Defines the order of attributes for Sources.
9
+ #
10
+ # ==== Attributes
11
+ #
12
+ # * +arr+ - Array of Symbols (keys). This is the order the hash's key will be in.
13
+ def sequence(arr = nil)
14
+ unless arr.nil?
15
+ @@sequence = arr
16
+ end
17
+
18
+ self.descendants.empty? ? @@sequence : nil
19
+ end
20
+
21
+ # Defines what actions need to be taken on the attributes.
22
+ #
23
+ # ==== Attributes
24
+ #
25
+ # * +block+ - A block of +rule+ definitions. The rule definition should call a method in Scholar::Utilities::Formatters.
26
+ #
27
+ # ==== Example
28
+ #
29
+ # rules do
30
+ # rule(:foo) {|v| italicize(v) }
31
+ # end
32
+ def rules(&block)
33
+ if block
34
+ @@rules ||= []
35
+
36
+ self.class_eval(&block)
37
+ else
38
+ self.descendants.empty? ? @@rules : nil
39
+ end
40
+ end
41
+
42
+ # Defines a specific action to be taken on an attribute.
43
+ #
44
+ # ==== Attributes
45
+ #
46
+ # * +key+ - The key of the hash to take the action on. Symbol.
47
+ # * +action+ - The action to take on the key. Should be a method within Scholar::Utilities::Formatters.
48
+ def rule(key, &action)
49
+ @@rules << [key, action]
50
+ end
51
+ end
52
+ end
53
+
54
+ # A collection of different source types.
55
+ module Sources
56
+ end
57
+
58
+ Dir[File.dirname(__FILE__) + '/sources/*.rb'].each {|file| require file }
59
+ end
@@ -0,0 +1,55 @@
1
+ module Scholar
2
+ module Sources
3
+
4
+ # A normal book.
5
+ class Book < Scholar::Source
6
+ sequence [
7
+ :authors,
8
+ :title,
9
+ :editors,
10
+ :compilers,
11
+ :translators,
12
+ :edition,
13
+ :volume,
14
+ :city,
15
+ :publisher,
16
+ :year,
17
+ :media,
18
+ :series
19
+ ]
20
+
21
+ rules do
22
+ rule(:authors) {|v| period(v) }
23
+
24
+ rule(:title) {|v| italicize(v) }
25
+ rule(:title) {|v| period(v) }
26
+
27
+ rule(:editors) {|v| replace("Ed. #{v}") }
28
+ rule(:editors) {|v| period(v) }
29
+
30
+ rule(:compilers) {|v| replace("Comp. #{v}") }
31
+ rule(:compilers) {|v| period(v) }
32
+
33
+ rule(:translators) {|v| replace("Trans. #{v}") }
34
+ rule(:translators) {|v| period(v) }
35
+
36
+ rule(:edition) {|v| replace("#{ordinal(v)} ed") }
37
+ rule(:edition) {|v| period(v) }
38
+
39
+ rule(:volume) {|v| replace("Vol. #{v}") }
40
+ rule(:volume) {|v| period(v) }
41
+
42
+ rule(:city) {|v| colon(v) }
43
+
44
+ rule(:publisher) {|v| comma(v) }
45
+
46
+ rule(:year) {|v| period(v) }
47
+
48
+ rule(:media) {|v| capitalize(v) }
49
+ rule(:media) {|v| period(v) }
50
+
51
+ rule(:series) {|v| period(v) }
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,10 @@
1
+ module Scholar
2
+
3
+ # Manifest various utilities to change attributes correctly.
4
+ class Utilities
5
+ Dir[File.dirname(__FILE__) + '/utilities/*.rb'].each {|file| require file }
6
+
7
+ extend Scholar::Utilities::Formatters
8
+ extend Scholar::Utilities::Data
9
+ end
10
+ end
@@ -0,0 +1,96 @@
1
+ module Scholar
2
+ class Utilities
3
+
4
+ # A person associated with a work.
5
+ class Contributor
6
+
7
+ # The data associated with the person.
8
+ attr_reader :attributes
9
+
10
+ # The name in the correct format.
11
+ attr_reader :name
12
+
13
+ # Create a Contributor.
14
+ #
15
+ # ==== Attributes
16
+ #
17
+ # * +hash+ - The data associated with the Contributor.
18
+ # * +order+ - Last-name first (+:last+) or first-name first (+:first+).
19
+ #
20
+ # ==== Options
21
+ #
22
+ # * +:first+ - The name of the Contributor.
23
+ # * +:middle+ - The middle name of the Contributor. Will be shortened to an initial.
24
+ # * +:last+ - The surname of the Contributor.
25
+ # * +:suffix+ - The suffix of the Contributor (PhD, Esq, etc).
26
+ #
27
+ # ==== Examples
28
+ #
29
+ # Scholar::Utilities::Contributor.new({:first => "Douglas", :last => "Adams"})
30
+ def initialize(hash, order = :first)
31
+ @order = order
32
+
33
+ @attributes = order!(hash)
34
+ @name = name!(@attributes)
35
+ end
36
+
37
+ # Reorders the name of the Contributor with the given order.
38
+ #
39
+ # ==== Attributes
40
+ #
41
+ # * +order+ - Either +:first+ or +:last+ name first.
42
+ def reorder!(order)
43
+ @order = order
44
+
45
+ @attributes = order!(@attributes, order)
46
+ @name = name!(@attributes)
47
+
48
+ if @name[-2, 2] == ".," # Fix this.
49
+ @name = @name[0..-3]
50
+ end
51
+
52
+ self
53
+ end
54
+
55
+ private
56
+
57
+ # Order according to the sequence.
58
+ def order!(hash, method = @order)
59
+ if method == :last
60
+ sequence = [:role, :last, :first, :middle, :suffix]
61
+ else
62
+ sequence = [:role, :first, :middle, :last, :suffix]
63
+ end
64
+
65
+ ordered = Scholar::Utilities.order!(hash, sequence)
66
+ end
67
+
68
+ # Generate the name with the given hash.
69
+ def name!(attributes)
70
+ hash = attributes.clone
71
+
72
+ [:role, :order].each do |k|
73
+ hash.delete(k)
74
+ end
75
+
76
+ if hash[:first].length == 1
77
+ hash[:first] = "#{hash[:first]}."
78
+ end
79
+
80
+ if hash[:middle]
81
+ hash[:middle] = "#{hash[:middle][0,1].upcase}."
82
+ end
83
+
84
+ if @order == :last || hash[:suffix]
85
+ hash[:last] = "#{hash[:last]},"
86
+ end
87
+
88
+ if @order == :last && hash[:middle]
89
+ hash[:middle] = "#{hash[:middle]},"
90
+ end
91
+
92
+ hash.values.compact.reject(&:empty?).join(' ').squish
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,62 @@
1
+ module Scholar
2
+ class Utilities
3
+
4
+ # A list of Contributors.
5
+ class ContributorList
6
+
7
+ # An Array of Contributors.
8
+ attr_reader :contributors
9
+
10
+ # The names in MLA format.
11
+ attr_reader :names
12
+
13
+ # Create a list of Contributors.
14
+ #
15
+ # ==== Attributes
16
+ #
17
+ # * +contributors+ - An Array of Contributors or an Array of Hashes.
18
+ # * +role+ - Either +:author:+ or +:nonauthor+.
19
+ #
20
+ # ==== Examples
21
+ #
22
+ # Scholar::Utilities::ContributorList.new([
23
+ # {
24
+ # :first => "Douglas",
25
+ # :last => "Adams"
26
+ # },
27
+ # {
28
+ # :first => "Eion",
29
+ # :last => "Colfer"
30
+ # }
31
+ # ])
32
+ def initialize(contributors, role = :nonauthor)
33
+ @names = ""
34
+
35
+ contributors.each do |c|
36
+ if c.is_a?(Hash)
37
+ contributors[contributors.index(c)] = Contributor.new(c)
38
+ end
39
+ end
40
+
41
+ contributors.each do |c|
42
+ if contributors.index(c) == 0 && role == :author
43
+ c.reorder!(:last)
44
+ else
45
+ c.reorder!(:first)
46
+ end
47
+
48
+ @names << c.name
49
+
50
+ unless contributors.last == c
51
+ @names << ", "
52
+ end
53
+ end
54
+
55
+ @contributors = contributors
56
+ @role = role
57
+
58
+ return self
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,68 @@
1
+ module Scholar
2
+ class Utilities
3
+
4
+ # Utilities for dealing with hashes and actually creating the
5
+ # citations.
6
+ module Data
7
+
8
+ # Concatenates hashes values into space-separated String.
9
+ def concatenate!(attributes)
10
+ attributes.values.compact.reject(&:empty?).join(' ').squish
11
+ end
12
+
13
+ # Take contributors in hash and makes a ContributorList for each role.
14
+ def contributors!(attributes)
15
+ data = attributes[:contributors]
16
+
17
+ attributes.delete(:contributors)
18
+
19
+ contributors = {}
20
+ data.each do |c|
21
+ role = c[:role].to_s.pluralize.to_sym
22
+
23
+ if contributors.has_key?(role)
24
+ contributors[role] << c
25
+ else
26
+ contributors[role] = [c]
27
+ end
28
+ end
29
+
30
+ contributors.each do |role, list|
31
+ if role == :authors
32
+ contributors[role] = ContributorList.new(list, :author).names
33
+ else
34
+ contributors[role] = ContributorList.new(list).names
35
+ end
36
+ end
37
+
38
+ attributes.merge(contributors)
39
+ end
40
+
41
+ # Formats the keys of a hash with given rules.
42
+ def format!(attributes, rules = [])
43
+ rules.each do |key, action|
44
+ unless attributes[key].nil?
45
+ attributes[key] = Scholar::Utilities.instance_eval do
46
+ action.call(attributes[key])
47
+ end
48
+ end
49
+ end
50
+
51
+ attributes
52
+ end
53
+
54
+ # Re-orders a hash based on a template.
55
+ def order!(hash, template)
56
+ ordered = ActiveSupport::OrderedHash.new
57
+
58
+ template.each do |key|
59
+ if hash[key]
60
+ ordered[key] = hash[key]
61
+ end
62
+ end
63
+
64
+ ordered
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,58 @@
1
+ module Scholar
2
+ class Utilities
3
+
4
+ # String formatters.
5
+ module Formatters
6
+
7
+ # Capitalize the first character of a String.
8
+ def capitalize(str)
9
+ str.to_s.capitalize
10
+ end
11
+
12
+ # Add carets (<>) around String.
13
+ def carets(str)
14
+ "&#60;#{str.to_s}&#62;"
15
+ end
16
+
17
+ # Add a colon to the end of a String.
18
+ def colon(str)
19
+ "#{str.to_s}:"
20
+ end
21
+
22
+ # Add a comma to the end of a String.
23
+ def comma(str)
24
+ "#{str.to_s},"
25
+ end
26
+
27
+ # Add <em> tags around a String to italicize it.
28
+ def italicize(str)
29
+ "<em>#{str.to_s}</em>"
30
+ end
31
+
32
+ # Return the ordinal form of an integer (1 turns into 1st, etc).
33
+ def ordinal(int)
34
+ ActiveSupport::Inflector.ordinalize(int.to_i)
35
+ end
36
+
37
+ # Add a period to the end of a String.
38
+ def period(str)
39
+ "#{str.to_s}."
40
+ end
41
+
42
+ # Wrap a String in quotes.
43
+ def quotes(str)
44
+ "&#8220;#{str.to_s}&#8221;"
45
+ end
46
+
47
+ # Replace with a String.
48
+ def replace(str)
49
+ str.to_s
50
+ end
51
+
52
+ # Add +<u>+ tags around a String to italicize it.
53
+ def underline(str)
54
+ "<u>#{str.to_s}</u>"
55
+ end
56
+ end
57
+ end
58
+ end
data/scholar.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "scholar"
8
+ gem.version = "0.1.0"
9
+ gem.authors = ["Ethan Turkeltaub"]
10
+ gem.email = ["ethan.turkeltaub@gmail.com"]
11
+ gem.description = %q{Generate valid MLA citations.}
12
+ gem.summary = %q{Generate valid MLA citations.}
13
+ gem.homepage = "http://github.com/noted/scholar"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_dependency 'activesupport', '~> 3.2.11'
22
+ end
@@ -0,0 +1,27 @@
1
+ FactoryGirl.define do
2
+ factory :contributor, class: Scholar::Utilities::Contributor do
3
+ trait :first do
4
+ hash = {
5
+ :role => :editor,
6
+ :first => "John",
7
+ :middle => "Quentin",
8
+ :last => "Sample",
9
+ :suffix => "PhD"
10
+ }
11
+
12
+ initialize_with { Scholar::Utilities::Contributor.new(hash) }
13
+ end
14
+
15
+ trait :last do
16
+ hash = {
17
+ :role => :author,
18
+ :first => "Les",
19
+ :middle => "Randy",
20
+ :last => "Grossman",
21
+ :suffix => "Esq"
22
+ }
23
+
24
+ initialize_with { Scholar::Utilities::Contributor.new(hash, :last) }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ FactoryGirl.define do
2
+ factory :contributors, class: Scholar::Utilities::ContributorList do
3
+ trait :author do
4
+ arr = [
5
+ {
6
+ :role => :author,
7
+ :first => "John",
8
+ :last => "Green"
9
+ },
10
+ {
11
+ :role => :author,
12
+ :first => "Douglas",
13
+ :middle => "Noel",
14
+ :last => "Adams"
15
+ },
16
+ {
17
+ :role => :author,
18
+ :first => "Neil",
19
+ :middle => "deGrasse",
20
+ :last => "Tyson",
21
+ :suffix => "PhD"
22
+ }
23
+ ]
24
+
25
+ initialize_with { Scholar::Utilities::ContributorList.new(arr, :author) }
26
+ end
27
+
28
+ trait :nonauthor do
29
+ arr = [
30
+ {
31
+ :role => :editor,
32
+ :first => "Carl",
33
+ :last => "Sagan"
34
+ },
35
+ {
36
+ :role => :editor,
37
+ :first => "Neil",
38
+ :middle => "deGrasse",
39
+ :last => "Tyson",
40
+ :suffix => "PhD"
41
+ }
42
+ ]
43
+
44
+ initialize_with { Scholar::Utilities::ContributorList.new(arr) }
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scholar::Source do
4
+ let(:s) { Scholar::Source }
5
+
6
+ describe ".sequence" do
7
+ context "passed Array" do
8
+ let(:sequence) { s.sequence([:foo, :bar]) }
9
+
10
+ it { s.sequence.should be_nil }
11
+ end
12
+
13
+ context "no arguments" do
14
+ let(:sequence) { s.sequence }
15
+
16
+ it { s.sequence.should be_nil }
17
+ end
18
+ end
19
+
20
+ describe ".rules" do
21
+ context "passed rule definitions" do
22
+ let(:rules) { s.rules { rules(:foo) {|v| "#{v}"} } }
23
+
24
+ it { s.sequence.should be_nil }
25
+ end
26
+
27
+ context "no arguments" do
28
+ it { s.sequence.should be_nil }
29
+ end
30
+ end
31
+
32
+ describe ".rule" do
33
+ let(:rule) { s.rule(:foo) {|v| "#{v}"} }
34
+
35
+ it { rule.pop[0].should eql(:foo) }
36
+ it { rule.pop[1].should be_an_instance_of Proc }
37
+ end
38
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scholar::Sources::Book do
4
+ let(:data) do
5
+ {
6
+ :type => :book,
7
+ :media => :print,
8
+ :title => "The Hitchhiker's Guide to the Galaxy",
9
+ :contributors => [
10
+ {
11
+ :role => :author,
12
+ :first => "Douglas",
13
+ :middle => "Noel",
14
+ :last => "Adams"
15
+ },
16
+ {
17
+ :role => :editor,
18
+ :first => "Peter",
19
+ :last => "Guzzardi"
20
+ },
21
+ {
22
+ :role => :translator,
23
+ :first => "Les",
24
+ :last => "Grossman"
25
+ },
26
+ {
27
+ :role => :compiler,
28
+ :first => "Eion",
29
+ :last => "Colfer"
30
+ }
31
+ ],
32
+ :edition => 1,
33
+ :volume => 1,
34
+ :publisher => "Random House",
35
+ :city => "London",
36
+ :year => "1972",
37
+ :series => "The Hitchhiker's Guide to the Galaxy"
38
+ }
39
+ end
40
+
41
+ let(:citation) do
42
+ "Adams, Douglas N. <em>The Hitchhiker's Guide to the Galaxy</em>. Ed. Peter Guzzardi. Comp. Eion Colfer. Trans. Les Grossman. 1st ed. Vol. 1. London: Random House, 1972. Print. The Hitchhiker's Guide to the Galaxy."
43
+ end
44
+
45
+ let(:c) { Scholar::Citation.new(data) }
46
+
47
+ it { c.html.should eql citation }
48
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scholar::Utilities::ContributorList do
4
+ context "authors" do
5
+ let(:c) { build(:contributors, :author) }
6
+
7
+ it { c.should be_an_instance_of Scholar::Utilities::ContributorList }
8
+ it { c.names.should eql "Green, John, Douglas N. Adams, Neil D. Tyson, PhD"}
9
+ end
10
+
11
+ context "non-authors" do
12
+ let(:c) { build(:contributors, :nonauthor) }
13
+
14
+ it { c.should be_an_instance_of Scholar::Utilities::ContributorList }
15
+ it { c.names.should eql "Carl Sagan, Neil D. Tyson, PhD"}
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scholar::Utilities::Contributor do
4
+ context "author" do
5
+ let(:c) { build(:contributor, :last) }
6
+
7
+ it { c.should be_an_instance_of Scholar::Utilities::Contributor }
8
+ it { c.name.should eql "Grossman, Les R., Esq" }
9
+ end
10
+
11
+ context "non-author" do
12
+ let(:c) { build(:contributor, :first) }
13
+
14
+ it { c.should be_an_instance_of Scholar::Utilities::Contributor }
15
+ it { c.name.should eql "John Q. Sample, PhD"}
16
+ end
17
+
18
+ describe "#reorder!" do
19
+ let(:first) { build(:contributor, :first) }
20
+ let(:last) { build(:contributor, :last) }
21
+
22
+ before do
23
+ first.reorder!(:last)
24
+ last.reorder!(:first)
25
+ end
26
+
27
+ it { first.name.should eql "Sample, John Q., PhD" }
28
+ it { last.name.should eql "Les R. Grossman, Esq" }
29
+ end
30
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scholar::Utilities::Data do
4
+ let(:s) { Scholar::Utilities }
5
+
6
+ describe "#concatenate!" do
7
+ let(:hash) do
8
+ { :foo => "bar ", :bar => "foo", :foobar => "barfoo" }
9
+ end
10
+
11
+ let(:c) { s.concatenate!(hash) }
12
+
13
+ it { c.should eql "bar foo barfoo" }
14
+ end
15
+
16
+ describe "#contributors!" do # Clean this up.
17
+ let(:pre) do
18
+ {
19
+ :foo => "bar",
20
+ :contributors => [
21
+ {
22
+ :role => :author,
23
+ :first => "John",
24
+ :last => "Green"
25
+ },
26
+ {
27
+ :role => :author,
28
+ :first => "Carl",
29
+ :last => "Sagan"
30
+ },
31
+ {
32
+ :role => :editor,
33
+ :first => "Neil",
34
+ :middle => "deGrasse",
35
+ :last => "Tyson",
36
+ :suffix => "PhD"
37
+ },
38
+ {
39
+ :role => :translator,
40
+ :first => "Dalai",
41
+ :last => "Lama"
42
+ }
43
+ ]
44
+ }
45
+ end
46
+
47
+ let(:post) do
48
+ {
49
+ :foo => "bar",
50
+ :authors => "Green, John, Carl Sagan",
51
+ :editors => "Neil D. Tyson, PhD",
52
+ :translators => "Dalai Lama"
53
+ }
54
+ end
55
+
56
+ let(:c) { s.contributors!(pre) }
57
+
58
+ it { c.should eql post }
59
+ end
60
+
61
+ describe "#format!" do
62
+ let(:hash) do
63
+ { :foo => "Barfoo", :bar => "Foobar" }
64
+ end
65
+
66
+ let(:rules) do
67
+ Scholar::Source.rules do
68
+ rule(:foo) {|v| italicize(v) }
69
+ rule(:bar) {|v| underline(v) }
70
+ end
71
+ end
72
+
73
+ let(:result) do
74
+ { :foo => "<em>Barfoo</em>", :bar => "<u>Foobar</u>" }
75
+ end
76
+
77
+ let(:c) { s.format!(hash, rules) }
78
+
79
+ it { c.should eql result }
80
+ end
81
+
82
+ describe "#order!" do
83
+ let(:hash) do
84
+ { :foobar => "Foo to the bar to the foo.", :bar => "Hello there.", :abc => "123" }
85
+ end
86
+
87
+ let(:sequence) do
88
+ [ :abc, :foobar, :bar ]
89
+ end
90
+
91
+ let(:h) { s.order!(hash, sequence) }
92
+
93
+ it { h.keys.should eql sequence }
94
+ end
95
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe Scholar::Utilities::Formatters do
4
+ let(:s) { Scholar::Utilities }
5
+
6
+ describe ".capitalize" do
7
+ let(:str) { s.capitalize("foo") }
8
+
9
+ it { str.should eql "Foo" }
10
+ end
11
+
12
+ describe ".carets" do
13
+ let(:str) { s.carets("foo") }
14
+
15
+ it { str.should eql "&#60;foo&#62;" }
16
+ end
17
+
18
+ describe ".colon" do
19
+ let(:str) { s.colon("foo") }
20
+
21
+ it { str.should eql "foo:" }
22
+ end
23
+
24
+ describe ".comma" do
25
+ let(:str) { s.comma("foo") }
26
+
27
+ it { str.should eql "foo," }
28
+ end
29
+
30
+ describe ".italicize" do
31
+ let(:str) { s.italicize("foo") }
32
+
33
+ it { str.should eql "<em>foo</em>" }
34
+ end
35
+
36
+ describe ".ordinal" do
37
+ let(:int) { s.ordinal(1) }
38
+
39
+ it { int.should eql "1st" }
40
+ end
41
+
42
+ describe ".period" do
43
+ let(:str) { s.period("foo") }
44
+
45
+ it { str.should eql "foo." }
46
+ end
47
+
48
+ describe ".quotes" do
49
+ let(:str) { s.quotes("foo") }
50
+
51
+ it { str.should eql "&#8220;foo&#8221;" }
52
+ end
53
+
54
+ describe ".replace" do
55
+ let(:str) { s.replace("foo") }
56
+
57
+ it { str.should eql "foo" }
58
+ end
59
+
60
+ describe ".underline" do
61
+ let(:str) { s.underline("foo") }
62
+
63
+ it { str.should eql "<u>foo</u>" }
64
+ end
65
+ end
@@ -0,0 +1,16 @@
1
+ require 'spork'
2
+
3
+ Spork.prefork do
4
+ require 'rspec'
5
+ require 'factory_girl'
6
+
7
+ require 'log_buddy'
8
+
9
+ require_relative '../lib/scholar'
10
+
11
+ FactoryGirl.find_definitions
12
+
13
+ RSpec.configure do |c|
14
+ c.include FactoryGirl::Syntax::Methods
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scholar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ethan Turkeltaub
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.11
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.11
30
+ description: Generate valid MLA citations.
31
+ email:
32
+ - ethan.turkeltaub@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - .rspec
39
+ - .ruby-version
40
+ - .travis.yml
41
+ - Gemfile
42
+ - Gemfile.lock
43
+ - LICENSE.md
44
+ - README.md
45
+ - Rakefile
46
+ - lib/scholar.rb
47
+ - lib/scholar/citation.rb
48
+ - lib/scholar/source.rb
49
+ - lib/scholar/sources/book.rb
50
+ - lib/scholar/utilities.rb
51
+ - lib/scholar/utilities/contributor.rb
52
+ - lib/scholar/utilities/contributor_list.rb
53
+ - lib/scholar/utilities/data.rb
54
+ - lib/scholar/utilities/formatters.rb
55
+ - scholar.gemspec
56
+ - spec/factories/contributor.rb
57
+ - spec/factories/contributor_list.rb
58
+ - spec/scholar/source_spec.rb
59
+ - spec/scholar/sources/book_spec.rb
60
+ - spec/scholar/utilities/contributor_list_spec.rb
61
+ - spec/scholar/utilities/contributor_spec.rb
62
+ - spec/scholar/utilities/data_spec.rb
63
+ - spec/scholar/utilities/formatters_spec.rb
64
+ - spec/spec_helper.rb
65
+ homepage: http://github.com/noted/scholar
66
+ licenses:
67
+ - MIT
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ segments:
79
+ - 0
80
+ hash: -551428721
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ segments:
88
+ - 0
89
+ hash: -551428721
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 1.8.25
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: Generate valid MLA citations.
96
+ test_files:
97
+ - spec/factories/contributor.rb
98
+ - spec/factories/contributor_list.rb
99
+ - spec/scholar/source_spec.rb
100
+ - spec/scholar/sources/book_spec.rb
101
+ - spec/scholar/utilities/contributor_list_spec.rb
102
+ - spec/scholar/utilities/contributor_spec.rb
103
+ - spec/scholar/utilities/data_spec.rb
104
+ - spec/scholar/utilities/formatters_spec.rb
105
+ - spec/spec_helper.rb