csl 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +8 -0
- data/.gitmodules +6 -0
- data/.rspec +3 -0
- data/.simplecov +2 -0
- data/.travis.yml +13 -0
- data/.yardopts +2 -0
- data/AGPL +662 -0
- data/BSDL +29 -0
- data/Gemfile +24 -0
- data/Guardfile +14 -0
- data/README.md +39 -0
- data/Rakefile +45 -0
- data/csl.gemspec +36 -0
- data/cucumber.yml +1 -0
- data/features/locales/loading.feature +57 -0
- data/features/locales/ordinalize.feature +861 -0
- data/features/parser/info.feature +27 -0
- data/features/parser/localized_dates.feature +35 -0
- data/features/parser/terms.feature +28 -0
- data/features/step_definitions/locale_steps.rb +34 -0
- data/features/step_definitions/parser_steps.rb +28 -0
- data/features/step_definitions/style_steps.rb +16 -0
- data/features/style/loading.feature +53 -0
- data/features/support/env.rb +8 -0
- data/lib/csl.rb +54 -0
- data/lib/csl/compatibility.rb +19 -0
- data/lib/csl/errors.rb +15 -0
- data/lib/csl/extensions.rb +63 -0
- data/lib/csl/info.rb +40 -0
- data/lib/csl/loader.rb +78 -0
- data/lib/csl/locale.rb +393 -0
- data/lib/csl/locale/date.rb +48 -0
- data/lib/csl/locale/style_options.rb +10 -0
- data/lib/csl/locale/term.rb +185 -0
- data/lib/csl/node.rb +285 -0
- data/lib/csl/parser.rb +92 -0
- data/lib/csl/pretty_printer.rb +33 -0
- data/lib/csl/schema.rb +109 -0
- data/lib/csl/style.rb +53 -0
- data/lib/csl/style/bibliography.rb +15 -0
- data/lib/csl/style/citation.rb +17 -0
- data/lib/csl/style/conditional.rb +11 -0
- data/lib/csl/style/date.rb +16 -0
- data/lib/csl/style/group.rb +9 -0
- data/lib/csl/style/label.rb +14 -0
- data/lib/csl/style/layout.rb +10 -0
- data/lib/csl/style/macro.rb +9 -0
- data/lib/csl/style/names.rb +54 -0
- data/lib/csl/style/number.rb +33 -0
- data/lib/csl/style/sort.rb +21 -0
- data/lib/csl/style/text.rb +10 -0
- data/lib/csl/treelike.rb +442 -0
- data/lib/csl/version.rb +3 -0
- data/spec/csl/info_spec.rb +116 -0
- data/spec/csl/locale/date_spec.rb +63 -0
- data/spec/csl/locale/style_options_spec.rb +19 -0
- data/spec/csl/locale/term_spec.rb +96 -0
- data/spec/csl/locale_spec.rb +128 -0
- data/spec/csl/node_spec.rb +100 -0
- data/spec/csl/parser_spec.rb +92 -0
- data/spec/csl/schema_spec.rb +70 -0
- data/spec/csl/style/bibliography_spec.rb +7 -0
- data/spec/csl/style/citation_spec.rb +7 -0
- data/spec/csl/style/conditional_spec.rb +7 -0
- data/spec/csl/style/date_spec.rb +11 -0
- data/spec/csl/style/group_spec.rb +7 -0
- data/spec/csl/style/label_spec.rb +7 -0
- data/spec/csl/style/layout_spec.rb +7 -0
- data/spec/csl/style/macro_spec.rb +7 -0
- data/spec/csl/style/names_spec.rb +23 -0
- data/spec/csl/style/number_spec.rb +84 -0
- data/spec/csl/style/text_spec.rb +7 -0
- data/spec/csl/style_spec.rb +19 -0
- data/spec/csl/treelike_spec.rb +151 -0
- data/spec/spec_helper.rb +30 -0
- metadata +192 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
Feature: Parse CSL info elements
|
2
|
+
As a hacker of CSL styles
|
3
|
+
I want to be able to parse CSL info strings
|
4
|
+
|
5
|
+
Scenario: A typical style info element
|
6
|
+
When I parse the CSL string
|
7
|
+
"""
|
8
|
+
<info>
|
9
|
+
<title>American Medical Association</title>
|
10
|
+
<id>http://www.zotero.org/styles/ama</id>
|
11
|
+
<link href="http://www.zotero.org/styles/ama" rel="self"/>
|
12
|
+
<author>
|
13
|
+
<name>Julian Onions</name>
|
14
|
+
<email>julian.onions@gmail.com</email>
|
15
|
+
</author>
|
16
|
+
<category citation-format="numeric"/>
|
17
|
+
<category field="medicine"/>
|
18
|
+
<updated/>
|
19
|
+
<summary>The American Medical Association style as used in JAMA.</summary>
|
20
|
+
<link href="http://www.samford.edu/schools/pharmacy/dic/amaquickref07.pdf" rel="documentation"/>
|
21
|
+
<rights>This work is licensed under a Creative Commons Attribution-Share Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/</rights>
|
22
|
+
</info>
|
23
|
+
"""
|
24
|
+
Then the nodename should be "info"
|
25
|
+
And the title should be "American Medical Association"
|
26
|
+
And the author name should be "Julian Onions"
|
27
|
+
And the author email should be "julian.onions@gmail.com"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Feature: Parse CSL localized date elements
|
2
|
+
As a hacker of CSL styles
|
3
|
+
I want to be able to parse CSL localized date strings
|
4
|
+
|
5
|
+
Scenario: A text date
|
6
|
+
When I parse the CSL string in the Locale scope
|
7
|
+
"""
|
8
|
+
<date form="text">
|
9
|
+
<date-part name="month" suffix=" "/>
|
10
|
+
<date-part name="day" form="numeric-leading-zeros" suffix=", "/>
|
11
|
+
<date-part name="year"/>
|
12
|
+
</date>
|
13
|
+
"""
|
14
|
+
Then the nodename should be "date"
|
15
|
+
And the attribute "form" should be "text"
|
16
|
+
And the node should have 3 parts
|
17
|
+
And text? should be "true"
|
18
|
+
And the part number 1 should have the attribute "name" set to "month"
|
19
|
+
|
20
|
+
Scenario: A numeric date
|
21
|
+
When I parse the CSL string in the Locale scope
|
22
|
+
"""
|
23
|
+
<date form="numeric">
|
24
|
+
<date-part name="month" form="numeric-leading-zeros" suffix="/"/>
|
25
|
+
<date-part name="day" form="numeric-leading-zeros" suffix="/"/>
|
26
|
+
<date-part name="year"/>
|
27
|
+
</date>
|
28
|
+
"""
|
29
|
+
Then the nodename should be "date"
|
30
|
+
And the attribute "form" should be "numeric"
|
31
|
+
And the node should have 3 parts
|
32
|
+
And text? should be "false"
|
33
|
+
And numeric? should be "true"
|
34
|
+
And the part number 3 should have the attribute "name" set to "year"
|
35
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: Parse CSL localized terms
|
2
|
+
As a hacker of CSL styles
|
3
|
+
I want to be able to parse CSL localized terms
|
4
|
+
|
5
|
+
Scenario: A few standard terms
|
6
|
+
When I parse the CSL string
|
7
|
+
"""
|
8
|
+
<terms>
|
9
|
+
<term name="accessed">accessed</term>
|
10
|
+
<term name="and">and</term>
|
11
|
+
<term name="and others">and others</term>
|
12
|
+
<term name="anonymous">anonymous</term>
|
13
|
+
<term name="anonymous" form="short">anon.</term>
|
14
|
+
<term name="circa">circa</term>
|
15
|
+
<term name="circa" form="short">c.</term>
|
16
|
+
<term name="cited">cited</term>
|
17
|
+
<term name="edition">
|
18
|
+
<single>edition</single>
|
19
|
+
<multiple>editions</multiple>
|
20
|
+
</term>
|
21
|
+
</terms>
|
22
|
+
"""
|
23
|
+
Then the nodename should be "terms"
|
24
|
+
And the node should have 9 terms
|
25
|
+
And the term number 1 should have the attribute "name" set to "accessed"
|
26
|
+
And the term number 2 should be a textnode
|
27
|
+
And the term number 9 should have the attribute "name" set to "edition"
|
28
|
+
And the term number 9 should not be a textnode
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Given /^the(?: following)? locale:?$/ do |string|
|
2
|
+
@csl = CSL::Locale.load(string)
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I load the locale from the string$/ do |string|
|
6
|
+
@csl = CSL::Locale.load(string)
|
7
|
+
end
|
8
|
+
|
9
|
+
When /^I ordinalize the number (\d+)(?: using the (long) form(?: and (feminine|masculine) gender))?$/ do |num, form, gender|
|
10
|
+
@ordinal = @locale.ordinalize(num, :form => form, :gender => gender)
|
11
|
+
end
|
12
|
+
|
13
|
+
Then /^the ordinal should (?:be|equal) "([^"]*)"$/ do |ord|
|
14
|
+
@ordinal.should == ord
|
15
|
+
end
|
16
|
+
|
17
|
+
When /^I ordinalize these numbers:?$/ do |table|
|
18
|
+
@ordinals = table.rows.map do |row|
|
19
|
+
num, form, gender, number = *row
|
20
|
+
@csl.ordinalize(num, :form => form, :gender => gender, :number => number)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Then /^the ordinals should (?:be|equal):?$/ do |table|
|
25
|
+
@ordinals.join(' ').should == table.rows.flatten.join(' ')
|
26
|
+
end
|
27
|
+
|
28
|
+
Then /^the locale should should have (\d+) terms$/ do |num|
|
29
|
+
@csl.terms.length.should == num.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
Then /^the (\w+[\?!]?) of the term "([^"]*)" should be "([^"]*)"$/ do |method, name, expected|
|
33
|
+
@csl.terms.detect { |t| t.name == name }.send(method).should == expected
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
When /^I parse the CSL string(?: in the (\w+) scope)?$/ do |scope, string|
|
3
|
+
@csl = CSL.parse string, CSL.const_get(scope || 'Node')
|
4
|
+
end
|
5
|
+
|
6
|
+
Then /^(?:the )?(\w+[\?!]?) should be "([^"]*)"$/ do |name, expected|
|
7
|
+
@csl.send(name).to_s.should == expected
|
8
|
+
end
|
9
|
+
|
10
|
+
Then /^the (\w+) (\w+) should be "([^"]*)"$/ do |outer, inner, expected|
|
11
|
+
@csl.send(outer).send(inner).to_s.should == expected
|
12
|
+
end
|
13
|
+
|
14
|
+
Then /^the attribute "([^"]*)" should be "([^"]*)"$/ do |name, expected|
|
15
|
+
@csl[name.to_sym].should == expected
|
16
|
+
end
|
17
|
+
|
18
|
+
Then /^the node should have (\d+) (\w+)$/ do |length, name|
|
19
|
+
@csl.send(name).length.should == length.to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
Then /^the (\w+) number (\d+) should have the attribute "([^"]*)" set to "([^"]*)"$/ do |name, offset, attribute, expected|
|
23
|
+
@csl.send("#{name}s")[offset.to_i - 1][attribute.to_sym].should == expected
|
24
|
+
end
|
25
|
+
|
26
|
+
Then /^the (\w+) number (\d+) should( not)? be a (\w+)$/ do |name, offset, negate, predicate|
|
27
|
+
@csl.send("#{name}s")[offset.to_i - 1].send("#{predicate}?").should == negate.nil?
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
When /^I load the style from the string$/ do |string|
|
3
|
+
@csl = CSL::Style.load string
|
4
|
+
end
|
5
|
+
|
6
|
+
Then /^the locale (\d+) should should have (\d+) terms?$/ do |locale, term|
|
7
|
+
@csl.locales[locale.to_i - 1].terms.length.should == term.to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
Then /^the locale (\d+) (\w+\??) should be "([^"]*)"$/ do |locale, method, expected|
|
11
|
+
@csl.locales[locale.to_i - 1].send(method).to_s.should == expected
|
12
|
+
end
|
13
|
+
|
14
|
+
Then /^the style should have (\d+) contributors$/ do |num|
|
15
|
+
@csl.info.contributors.length.should == num.to_i
|
16
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Feature: Loading CSL Style
|
2
|
+
As a hacker of CSL styles
|
3
|
+
I want to be able to parse CSL styles
|
4
|
+
|
5
|
+
Scenario: Loading a style from a string
|
6
|
+
When I load the style from the string
|
7
|
+
"""
|
8
|
+
<?xml version="1.0" encoding="utf-8"?>
|
9
|
+
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="never">
|
10
|
+
<info>
|
11
|
+
<title>American Psychological Association 6th Edition</title>
|
12
|
+
<id>http://www.zotero.org/styles/apa</id>
|
13
|
+
<link href="http://www.zotero.org/styles/apa" rel="self"/>
|
14
|
+
<link href="http://owl.english.purdue.edu/owl/resource/560/01/" rel="documentation"/>
|
15
|
+
<author>
|
16
|
+
<name>Simon Kornblith</name>
|
17
|
+
<email>simon@simonster.com</email>
|
18
|
+
</author>
|
19
|
+
<contributor>
|
20
|
+
<name>Bruce D'Arcus</name>
|
21
|
+
</contributor>
|
22
|
+
<contributor>
|
23
|
+
<name>Curtis M. Humphrey</name>
|
24
|
+
</contributor>
|
25
|
+
<contributor>
|
26
|
+
<name>Richard Karnesky</name>
|
27
|
+
<email>karnesky+zotero@gmail.com</email>
|
28
|
+
<uri>http://arc.nucapt.northwestern.edu/Richard_Karnesky</uri>
|
29
|
+
</contributor>
|
30
|
+
<contributor>
|
31
|
+
<name>Sebastian Karcher</name>
|
32
|
+
</contributor>
|
33
|
+
<category field="psychology"/>
|
34
|
+
<category field="generic-base"/>
|
35
|
+
<category citation-format="author-date"/>
|
36
|
+
<updated>2010-01-27T20:08:03+00:00</updated>
|
37
|
+
<rights>This work is licensed under a Creative Commons Attribution-Share Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/</rights>
|
38
|
+
</info>
|
39
|
+
<locale xml:lang="en">
|
40
|
+
<terms>
|
41
|
+
<term name="translator" form="short">
|
42
|
+
<single>trans.</single>
|
43
|
+
<multiple>trans.</multiple>
|
44
|
+
</term>
|
45
|
+
</terms>
|
46
|
+
</locale>
|
47
|
+
</style>
|
48
|
+
"""
|
49
|
+
Then the info title should be "American Psychological Association 6th Edition"
|
50
|
+
And the locale 1 should should have 1 term
|
51
|
+
And the locale 1 language should be "en"
|
52
|
+
And the locale 1 region should be "US"
|
53
|
+
And the style should have 4 contributors
|
data/lib/csl.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
require 'enumerator'
|
3
|
+
require 'forwardable'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'singleton'
|
6
|
+
require 'set'
|
7
|
+
|
8
|
+
require 'csl/version'
|
9
|
+
|
10
|
+
require 'csl/compatibility'
|
11
|
+
require 'csl/extensions'
|
12
|
+
require 'csl/errors'
|
13
|
+
|
14
|
+
require 'csl/schema'
|
15
|
+
|
16
|
+
require 'csl/pretty_printer'
|
17
|
+
require 'csl/loader'
|
18
|
+
require 'csl/parser'
|
19
|
+
require 'csl/treelike'
|
20
|
+
require 'csl/node'
|
21
|
+
|
22
|
+
require 'csl/info'
|
23
|
+
|
24
|
+
require 'csl/locale'
|
25
|
+
require 'csl/locale/date'
|
26
|
+
require 'csl/locale/term'
|
27
|
+
require 'csl/locale/style_options'
|
28
|
+
|
29
|
+
require 'csl/style'
|
30
|
+
require 'csl/style/bibliography'
|
31
|
+
require 'csl/style/citation'
|
32
|
+
require 'csl/style/conditional'
|
33
|
+
require 'csl/style/date'
|
34
|
+
require 'csl/style/group'
|
35
|
+
require 'csl/style/label'
|
36
|
+
require 'csl/style/layout'
|
37
|
+
require 'csl/style/macro'
|
38
|
+
require 'csl/style/names'
|
39
|
+
require 'csl/style/number'
|
40
|
+
require 'csl/style/text'
|
41
|
+
|
42
|
+
module CSL
|
43
|
+
|
44
|
+
module_function
|
45
|
+
|
46
|
+
def parse(*arguments)
|
47
|
+
Parser.instance.parse(*arguments)
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse!(*arguments)
|
51
|
+
Parser.instance.parse!(*arguments)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
class Symbol
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
def <=>(other)
|
6
|
+
return unless other.kind_of? Symbol
|
7
|
+
to_s <=> other.to_s
|
8
|
+
end
|
9
|
+
end unless Symbol.is_a?(Comparable)
|
10
|
+
|
11
|
+
class Module
|
12
|
+
if RUBY_VERSION < '1.9'
|
13
|
+
alias const? const_defined?
|
14
|
+
else
|
15
|
+
def const?(name)
|
16
|
+
const_defined?(name, false)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/csl/errors.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
# Some methods in this file are taken from ActiveSupport
|
3
|
+
# and are copyright (c) 2005-2010 David Heinemeier Hansson.
|
4
|
+
# They are loaded only if ActiveSupport is not present.
|
5
|
+
|
6
|
+
module CSL
|
7
|
+
module Extensions
|
8
|
+
|
9
|
+
# ActiveSupport Fallback
|
10
|
+
module SymbolizeKeys
|
11
|
+
def symbolize_keys
|
12
|
+
inject({}) do |options, (key, value)|
|
13
|
+
options[(key.to_sym rescue key) || key] = value
|
14
|
+
options
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def symbolize_keys!
|
19
|
+
replace(symbolize_keys)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
# ActiveSupport Fallback
|
25
|
+
module StringifyKeys
|
26
|
+
def stringify_keys
|
27
|
+
inject({}) do |options, (key, value)|
|
28
|
+
options[(key.to_s rescue key) || key] = value
|
29
|
+
options
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def stringify_keys!
|
34
|
+
replace(symbolize_keys)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
module Nesting
|
39
|
+
def nesting
|
40
|
+
name.split(/::/).inject([]) { |ns, n| ns << (ns[-1] || Object).const_get(n) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module Blank
|
45
|
+
def blank?
|
46
|
+
nil? || respond_to?(:empty?) && empty?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Hash
|
53
|
+
include CSL::Extensions::SymbolizeKeys unless method_defined?(:symbolize_keys)
|
54
|
+
include CSL::Extensions::StringifyKeys unless method_defined?(:stringify_keys)
|
55
|
+
end
|
56
|
+
|
57
|
+
class Module
|
58
|
+
include CSL::Extensions::Nesting
|
59
|
+
end
|
60
|
+
|
61
|
+
class Object
|
62
|
+
include CSL::Extensions::Blank unless method_defined?(:blank?)
|
63
|
+
end
|
data/lib/csl/info.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module CSL
|
2
|
+
|
3
|
+
class Info < Node
|
4
|
+
|
5
|
+
attr_children :author, :category, :contributor, :id, :issn, :eissn,
|
6
|
+
:issnl, :link, :published, :rights, :summary, :title, :'title-short',
|
7
|
+
:updated, :'link-dependent-style'
|
8
|
+
|
9
|
+
alias contributors contributor
|
10
|
+
|
11
|
+
|
12
|
+
class Contributor < Node
|
13
|
+
attr_children :name, :email, :uri
|
14
|
+
end
|
15
|
+
|
16
|
+
class Author < Node
|
17
|
+
attr_children :name, :email, :uri
|
18
|
+
end
|
19
|
+
|
20
|
+
class Translator < Node
|
21
|
+
attr_children :name, :email, :uri
|
22
|
+
end
|
23
|
+
|
24
|
+
class Link < TextNode
|
25
|
+
attr_struct :href, :rel
|
26
|
+
end
|
27
|
+
|
28
|
+
class DependentStyle < TextNode
|
29
|
+
attr_struct :href, :rel
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
class Category < TextNode
|
34
|
+
attr_struct :field, :'citation-format'
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
data/lib/csl/loader.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
module CSL
|
2
|
+
#
|
3
|
+
# Mixin used by Locale and Style to load assets either from disk or from
|
4
|
+
# the network. Classes including the Loader module are expected to provide
|
5
|
+
# appropriate root, prefix and extension values and a parse method that
|
6
|
+
# will be passed the contents of the asset data.
|
7
|
+
#
|
8
|
+
module Loader
|
9
|
+
|
10
|
+
attr_accessor :root, :prefix, :extension
|
11
|
+
|
12
|
+
# call-seq:
|
13
|
+
# Style.load(:apa) -> style
|
14
|
+
# Style.load('chicago-author.csl') -> style
|
15
|
+
# Locale.load('en') -> locale
|
16
|
+
# Locale.load('http://example.com/de.xml') -> locale
|
17
|
+
#
|
18
|
+
# Resolves the passed-in path/name or string and loads the asset data.
|
19
|
+
# The data will be passed on to the #parse method of the base class.
|
20
|
+
# Typically, this will return a new instance of the class.
|
21
|
+
def load(input)
|
22
|
+
case
|
23
|
+
when input.respond_to?(:read)
|
24
|
+
data = input.read
|
25
|
+
when input.to_s =~ /^\s*</
|
26
|
+
data = input
|
27
|
+
else
|
28
|
+
|
29
|
+
case
|
30
|
+
when File.exists?(input)
|
31
|
+
location = input
|
32
|
+
when File.exists?(extend_name(input))
|
33
|
+
location = extend_name(input)
|
34
|
+
when File.exists?(extend_path(input))
|
35
|
+
location = extend_path(input)
|
36
|
+
else
|
37
|
+
location = input
|
38
|
+
end
|
39
|
+
|
40
|
+
Kernel.open(location, 'r:UTF-8') do |io|
|
41
|
+
data = io.read
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
parse(data)
|
46
|
+
|
47
|
+
rescue => e
|
48
|
+
raise ParseError, "failed to load #{input.inspect}: #{e.message}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Extends the passed-in string to a full path.
|
52
|
+
def extend_path(string)
|
53
|
+
File.join(root.to_s, extend_name(string))
|
54
|
+
end
|
55
|
+
|
56
|
+
# Extends the passed-in string to a style/locale name, by prefixing and
|
57
|
+
# appending the default name prefix and extension.
|
58
|
+
def extend_name(string)
|
59
|
+
if File.extname(string).empty?
|
60
|
+
name = [string, extension].compact.join
|
61
|
+
else
|
62
|
+
name = string.to_s.dup
|
63
|
+
end
|
64
|
+
|
65
|
+
unless name.start_with?(prefix.to_s)
|
66
|
+
name = [prefix, name].join
|
67
|
+
end
|
68
|
+
|
69
|
+
name
|
70
|
+
end
|
71
|
+
|
72
|
+
# The base class is exepcted to redefine the #parse method.
|
73
|
+
def parse(data)
|
74
|
+
raise 'Not Implemented'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|