scholar 0.1.0

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