citeproc-ruby 0.0.1
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/README.md +78 -0
- data/lib/citeproc.rb +100 -0
- data/lib/citeproc/bibliography.rb +57 -0
- data/lib/citeproc/data.rb +149 -0
- data/lib/citeproc/date.rb +133 -0
- data/lib/citeproc/formatter.rb +38 -0
- data/lib/citeproc/item.rb +53 -0
- data/lib/citeproc/name.rb +284 -0
- data/lib/citeproc/processor.rb +166 -0
- data/lib/citeproc/selector.rb +61 -0
- data/lib/citeproc/variable.rb +82 -0
- data/lib/citeproc/version.rb +3 -0
- data/lib/csl/locale.rb +223 -0
- data/lib/csl/node.rb +72 -0
- data/lib/csl/nodes.rb +1364 -0
- data/lib/csl/renderer.rb +88 -0
- data/lib/csl/sort.rb +53 -0
- data/lib/csl/style.rb +110 -0
- data/lib/csl/term.rb +124 -0
- data/lib/extensions/core.rb +43 -0
- data/lib/plugins/filters/bibtex.rb +12 -0
- data/lib/plugins/formats/default.rb +134 -0
- data/lib/plugins/formats/html.rb +67 -0
- data/lib/support/attributes.rb +99 -0
- data/lib/support/tree.rb +80 -0
- data/resource/locale/locales-af-ZA.xml +304 -0
- data/resource/locale/locales-ar-AR.xml +304 -0
- data/resource/locale/locales-bg-BG.xml +304 -0
- data/resource/locale/locales-ca-AD.xml +304 -0
- data/resource/locale/locales-cs-CZ.xml +304 -0
- data/resource/locale/locales-da-DK.xml +304 -0
- data/resource/locale/locales-de-AT.xml +304 -0
- data/resource/locale/locales-de-CH.xml +304 -0
- data/resource/locale/locales-de-DE.xml +332 -0
- data/resource/locale/locales-el-GR.xml +303 -0
- data/resource/locale/locales-en-US.xml +313 -0
- data/resource/locale/locales-es-ES.xml +304 -0
- data/resource/locale/locales-et-EE.xml +304 -0
- data/resource/locale/locales-fr-FR.xml +304 -0
- data/resource/locale/locales-he-IL.xml +304 -0
- data/resource/locale/locales-hu-HU.xml +304 -0
- data/resource/locale/locales-is-IS.xml +304 -0
- data/resource/locale/locales-it-IT.xml +304 -0
- data/resource/locale/locales-ja-JP.xml +304 -0
- data/resource/locale/locales-kh-KH.xml +303 -0
- data/resource/locale/locales-ko-KR.xml +304 -0
- data/resource/locale/locales-mn-MN.xml +304 -0
- data/resource/locale/locales-nb-NO.xml +304 -0
- data/resource/locale/locales-nl-NL.xml +304 -0
- data/resource/locale/locales-nn-NO.xml +304 -0
- data/resource/locale/locales-pl-PL.xml +304 -0
- data/resource/locale/locales-pt-BR.xml +304 -0
- data/resource/locale/locales-pt-PT.xml +304 -0
- data/resource/locale/locales-ro-RO.xml +304 -0
- data/resource/locale/locales-ru-RU.xml +304 -0
- data/resource/locale/locales-sk-SK.xml +304 -0
- data/resource/locale/locales-sl-SI.xml +304 -0
- data/resource/locale/locales-sr-RS.xml +304 -0
- data/resource/locale/locales-sv-SE.xml +304 -0
- data/resource/locale/locales-th-TH.xml +304 -0
- data/resource/locale/locales-tr-TR.xml +304 -0
- data/resource/locale/locales-uk-UA.xml +304 -0
- data/resource/locale/locales-vi-VN.xml +304 -0
- data/resource/locale/locales-zh-CN.xml +304 -0
- data/resource/locale/locales-zh-TW.xml +304 -0
- data/resource/schema/csl-categories.rnc +39 -0
- data/resource/schema/csl-data.rnc +98 -0
- data/resource/schema/csl-terms.rnc +106 -0
- data/resource/schema/csl-types.rnc +39 -0
- data/resource/schema/csl-variables.rnc +182 -0
- data/resource/schema/csl.rnc +941 -0
- data/resource/style/acta-materialia-x.csl +128 -0
- data/resource/style/advanced-engineering-materials-x.csl +121 -0
- data/resource/style/ama.csl +185 -0
- data/resource/style/ama2-x.csl +179 -0
- data/resource/style/apa-x.csl +324 -0
- data/resource/style/apa.csl +254 -0
- data/resource/style/apsa-x.csl +163 -0
- data/resource/style/apsa.csl +176 -0
- data/resource/style/asa-x.csl +203 -0
- data/resource/style/asa.csl +216 -0
- data/resource/style/asm-journals-x.csl +131 -0
- data/resource/style/bibtex-x2.csl +175 -0
- data/resource/style/bluebook-demo-x.csl +392 -0
- data/resource/style/bluebook-demo.csl +942 -0
- data/resource/style/chicago-author-date-listing.csl +434 -0
- data/resource/style/chicago-author-date.csl +369 -0
- data/resource/style/chicago-fullnote-bibliography-bb.csl +928 -0
- data/resource/style/chicago-fullnote-bibliography.csl +695 -0
- data/resource/style/chicago-note-bibliography.csl +446 -0
- data/resource/style/chicago-note.csl +388 -0
- data/resource/style/greek-chicago-x.csl +1182 -0
- data/resource/style/harvard1-institution-italic.csl +190 -0
- data/resource/style/harvard1.csl +181 -0
- data/resource/style/ieee.csl +129 -0
- data/resource/style/mhra-x.csl +312 -0
- data/resource/style/mhra.csl +390 -0
- data/resource/style/mhra_note_without_bibliography-x.csl +330 -0
- data/resource/style/mhra_note_without_bibliography.csl +338 -0
- data/resource/style/mla-x.csl +178 -0
- data/resource/style/mla.csl +189 -0
- data/resource/style/nature-x.csl +81 -0
- data/resource/style/nature.csl +88 -0
- data/resource/style/nlm.csl +117 -0
- data/spec/citeproc/bibliography_spec.rb +45 -0
- data/spec/citeproc/citeproc_spec.rb +76 -0
- data/spec/citeproc/date_spec.rb +85 -0
- data/spec/citeproc/formatter_spec.rb +101 -0
- data/spec/citeproc/item_spec.rb +71 -0
- data/spec/citeproc/name_spec.rb +30 -0
- data/spec/citeproc/processor_spec.rb +61 -0
- data/spec/citeproc/selector_spec.rb +82 -0
- data/spec/citeproc/variable_spec.rb +69 -0
- data/spec/csl/locale_spec.rb +208 -0
- data/spec/csl/node_spec.rb +25 -0
- data/spec/csl/nodes_spec.rb +140 -0
- data/spec/csl/style_spec.rb +62 -0
- data/spec/csl/term_spec.rb +56 -0
- data/spec/fixtures/dates.yaml +80 -0
- data/spec/fixtures/names.yaml +115 -0
- data/spec/fixtures/nodes.yaml +245 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/attributes_spec.rb +39 -0
- data/spec/support/tree_spec.rb +163 -0
- metadata +264 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<style
|
|
2
|
+
xmlns="http://purl.org/net/xbiblio/csl"
|
|
3
|
+
class="in-text"
|
|
4
|
+
xml:lang="en">
|
|
5
|
+
<info>
|
|
6
|
+
<title>National Library of Medicine</title>
|
|
7
|
+
<id>http://www.zotero.org/styles/nlm</id>
|
|
8
|
+
<link href="http://www.zotero.org/styles/nlm" />
|
|
9
|
+
<author>
|
|
10
|
+
<name>Michael Berkowitz</name>
|
|
11
|
+
<email>mberkowi@gmu.edu</email>
|
|
12
|
+
</author>
|
|
13
|
+
<category term="generic-base" />
|
|
14
|
+
<category term="numeric" />
|
|
15
|
+
<updated />
|
|
16
|
+
</info>
|
|
17
|
+
<macro name="author">
|
|
18
|
+
<names suffix=". " variable="author">
|
|
19
|
+
<name delimiter=", " delimiter-precedes-last="always" initialize-with="" name-as-sort-order="all" sort-separator=" " />
|
|
20
|
+
</names>
|
|
21
|
+
</macro>
|
|
22
|
+
<macro name="editor">
|
|
23
|
+
<names suffix=", editor(s). " variable="editor">
|
|
24
|
+
<name delimiter=", " delimiter-precedes-last="always" initialize-with="" name-as-sort-order="all" sort-separator=" " />
|
|
25
|
+
</names>
|
|
26
|
+
</macro>
|
|
27
|
+
<macro name="publisher">
|
|
28
|
+
<text suffix=": " variable="publisher-place" />
|
|
29
|
+
<text suffix="; " variable="publisher" />
|
|
30
|
+
<date variable="issued">
|
|
31
|
+
<date-part name="year" suffix=". " />
|
|
32
|
+
</date>
|
|
33
|
+
</macro>
|
|
34
|
+
<macro name="access">
|
|
35
|
+
<group delimiter=" ">
|
|
36
|
+
<group delimiter=" " prefix="[" suffix="]">
|
|
37
|
+
<text term="cited" text-case="lowercase" />
|
|
38
|
+
<date suffix=" " variable="accessed">
|
|
39
|
+
<date-part name="year" />
|
|
40
|
+
<date-part form="short" name="month" prefix=" " />
|
|
41
|
+
<date-part name="day" prefix=" " />
|
|
42
|
+
</date>
|
|
43
|
+
</group>
|
|
44
|
+
<group>
|
|
45
|
+
<text value="Available from: " />
|
|
46
|
+
<text variable="URL" />
|
|
47
|
+
</group>
|
|
48
|
+
</group>
|
|
49
|
+
</macro>
|
|
50
|
+
<macro name="title">
|
|
51
|
+
<group delimiter=" ">
|
|
52
|
+
<text variable="title" />
|
|
53
|
+
<choose>
|
|
54
|
+
<if variable="URL">
|
|
55
|
+
<text prefix="[" suffix="]" term="internet" text-case="capitalize-first" />
|
|
56
|
+
</if>
|
|
57
|
+
</choose>
|
|
58
|
+
</group>
|
|
59
|
+
</macro>
|
|
60
|
+
<macro name="edition">
|
|
61
|
+
<choose>
|
|
62
|
+
<if is-numeric="edition">
|
|
63
|
+
<group delimiter=" ">
|
|
64
|
+
<number form="ordinal" variable="edition" />
|
|
65
|
+
<text form="short" suffix="." term="edition" />
|
|
66
|
+
</group>
|
|
67
|
+
</if>
|
|
68
|
+
<else>
|
|
69
|
+
<text suffix="." variable="edition" />
|
|
70
|
+
</else>
|
|
71
|
+
</choose>
|
|
72
|
+
</macro>
|
|
73
|
+
<citation
|
|
74
|
+
collapse="citation-number">
|
|
75
|
+
<sort>
|
|
76
|
+
<key variable="citation-number" />
|
|
77
|
+
</sort>
|
|
78
|
+
<layout delimiter="; " prefix="(" suffix=")">
|
|
79
|
+
<text variable="citation-number" />
|
|
80
|
+
</layout>
|
|
81
|
+
</citation>
|
|
82
|
+
<bibliography
|
|
83
|
+
second-field-align="true">
|
|
84
|
+
<layout>
|
|
85
|
+
<text suffix=". " variable="citation-number" />
|
|
86
|
+
<text macro="author" />
|
|
87
|
+
<text macro="title" suffix=". " />
|
|
88
|
+
<choose>
|
|
89
|
+
<if type="book">
|
|
90
|
+
<text macro="edition" prefix=" " suffix=" " />
|
|
91
|
+
<text macro="publisher" prefix=" " />
|
|
92
|
+
</if>
|
|
93
|
+
<else-if type="chapter">
|
|
94
|
+
<group prefix=" " suffix=". ">
|
|
95
|
+
<text suffix=": " term="in" text-case="capitalize-first" />
|
|
96
|
+
<text macro="editor" />
|
|
97
|
+
<text variable="container-title" />
|
|
98
|
+
</group>
|
|
99
|
+
<text macro="publisher" prefix=" " />
|
|
100
|
+
<text prefix=" p. " suffix="." variable="page" />
|
|
101
|
+
</else-if>
|
|
102
|
+
<else>
|
|
103
|
+
<text form="short" suffix=". " variable="container-title" />
|
|
104
|
+
<date suffix=";" variable="issued">
|
|
105
|
+
<date-part name="year" suffix=" " />
|
|
106
|
+
<date-part form="short" name="month" suffix=" " />
|
|
107
|
+
<date-part name="day" />
|
|
108
|
+
</date>
|
|
109
|
+
<text variable="volume" />
|
|
110
|
+
<text prefix="(" suffix="):" variable="issue" />
|
|
111
|
+
<text suffix="." variable="page" />
|
|
112
|
+
</else>
|
|
113
|
+
</choose>
|
|
114
|
+
<text macro="access" />
|
|
115
|
+
</layout>
|
|
116
|
+
</bibliography>
|
|
117
|
+
</style>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module CiteProc
|
|
2
|
+
describe Bibliography do
|
|
3
|
+
|
|
4
|
+
let(:json) {'[{"test":"test","bibliography-errors":[]},["1","2"]]'}
|
|
5
|
+
|
|
6
|
+
describe '#new' do
|
|
7
|
+
it { should_not be_nil }
|
|
8
|
+
|
|
9
|
+
it 'accepts a JSON string' do
|
|
10
|
+
Bibliography.new(json).should_not be_empty
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'accepts a data array' do
|
|
14
|
+
Bibliography.new([1,2,3]).data.should == [1,2,3]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'accepts an options hash' do
|
|
18
|
+
Bibliography.new('test'=>'test').options['test'].should == 'test'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'accepts an options hash with errors' do
|
|
22
|
+
Bibliography.new('bibliography-errors'=>[1,2,3]).errors.should == [1,2,3]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe '#to_json' do
|
|
27
|
+
it 'returns valid JSON when empty' do
|
|
28
|
+
JSON.parse(Bibliography.new.to_json).should_not be_nil
|
|
29
|
+
end
|
|
30
|
+
it 'returns valid JSON with data' do
|
|
31
|
+
JSON.parse(Bibliography.new([1,2,3]).to_json).should_not be_nil
|
|
32
|
+
end
|
|
33
|
+
it 'returns valid JSON with options' do
|
|
34
|
+
JSON.parse(Bibliography.new({'test'=>'test'}).to_json).should_not be_nil
|
|
35
|
+
end
|
|
36
|
+
it 'returns valid JSON with options and data' do
|
|
37
|
+
JSON.parse(Bibliography.new([{'test'=>'test'}, [1,2]]).to_json).should_not be_nil
|
|
38
|
+
end
|
|
39
|
+
it 'supports round-trips' do
|
|
40
|
+
Bibliography.new(json).to_json.should == json
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#
|
|
2
|
+
# This generates RSpec tests from the JSON test cases of the citeproc-tests
|
|
3
|
+
# suite.
|
|
4
|
+
#
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Filter applied to each test to decide whether we should run it. Use this
|
|
9
|
+
# to stay sane while the Processor is not feature-complete!
|
|
10
|
+
#
|
|
11
|
+
def filter(file, fixture)
|
|
12
|
+
# return ['affix_InterveningEmpty.json'].include?(File.basename(file))
|
|
13
|
+
# File.basename(file) =~ /bugreports_greek/i
|
|
14
|
+
# File.basename(file) =~ /sort_stripmark/i
|
|
15
|
+
# return File.basename(file) =~ /^date_rawparsesimpledate/i
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module CiteProc
|
|
20
|
+
|
|
21
|
+
describe 'citeproc' do
|
|
22
|
+
|
|
23
|
+
let(:proc) { Processor.new }
|
|
24
|
+
|
|
25
|
+
Test::Fixtures::Processor.each_pair do |file, fixture|
|
|
26
|
+
|
|
27
|
+
tokens = File.basename(file).split(/_|\.json/)
|
|
28
|
+
|
|
29
|
+
describe tokens[0].downcase do
|
|
30
|
+
|
|
31
|
+
name = tokens[1].gsub(/([[:lower:]])([[:upper:]])/, '\1 \2').downcase
|
|
32
|
+
|
|
33
|
+
it name do
|
|
34
|
+
pending if tokens[0] =~ /^(position|disambiguate|integration|flipflop|collapse|parallel)/
|
|
35
|
+
|
|
36
|
+
proc.style = fixture['csl']
|
|
37
|
+
proc.import(fixture['input'])
|
|
38
|
+
proc.format = :html
|
|
39
|
+
|
|
40
|
+
proc.add_abbreviations(fixture['abbreviations']) if fixture['abbreviations']
|
|
41
|
+
|
|
42
|
+
case fixture['mode']
|
|
43
|
+
|
|
44
|
+
when 'citation'
|
|
45
|
+
# citations => process_citation_cluster
|
|
46
|
+
# citation_items || :all => make_citation_cluster
|
|
47
|
+
data = fixture['citation_items']
|
|
48
|
+
|
|
49
|
+
unless data
|
|
50
|
+
result = proc.cite((fixture['bibentries'] && fixture['bibentries'].last) || :all).map { |d| d[1] }.join
|
|
51
|
+
else
|
|
52
|
+
result = data.map { |d| proc.cite(d).map { |c| c[1] }.join }.join("\n")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
when 'bibliography'
|
|
56
|
+
result = proc.bibliography(fixture['bibsection'] || :all).to_s
|
|
57
|
+
|
|
58
|
+
when 'bibliography-header'
|
|
59
|
+
pending('not yet implemented')
|
|
60
|
+
|
|
61
|
+
when 'bibliography-nosort'
|
|
62
|
+
pending('not yet implemented')
|
|
63
|
+
|
|
64
|
+
else
|
|
65
|
+
CiteProc.log.warn "unkown processor mode: #{fixture['mode']}"
|
|
66
|
+
pending('not yet implemented')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
result.should == fixture['result']
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
end if filter(file, fixture)
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module CiteProc
|
|
4
|
+
|
|
5
|
+
describe Date do
|
|
6
|
+
|
|
7
|
+
describe '#new' do
|
|
8
|
+
it { should_not be_nil }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe '.create' do
|
|
12
|
+
it 'should accept parameters and return a new instance' do
|
|
13
|
+
Date.create('date-parts' => [[2001, 1]]).year.should == 2001
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe '#sort' do
|
|
18
|
+
|
|
19
|
+
let(:ad2k) { Date.create('date-parts' => [[2000]])}
|
|
20
|
+
let(:may) { Date.create('date-parts' => [[2000, 5]])}
|
|
21
|
+
let(:first_of_may) { Date.create('date-parts' => [[2000, 5, 1]])}
|
|
22
|
+
|
|
23
|
+
let(:bc100) { Date.create('date-parts' => [[-100]]) }
|
|
24
|
+
let(:bc50) { Date.create('date-parts' => [[-50]]) }
|
|
25
|
+
let(:ad50) { Date.create('date-parts' => [[50]]) }
|
|
26
|
+
let(:ad100) { Date.create('date-parts' => [[100]]) }
|
|
27
|
+
|
|
28
|
+
it 'dates with more date-parts will come after those with fewer parts' do
|
|
29
|
+
(ad2k < may && may < first_of_may).should be true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'negative years are sorted inversely' do
|
|
33
|
+
[ad50, bc100, bc50, ad100].sort.map(&:year).should == [-100, -50, 50, 100]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Test::Fixtures::Dates.keys.each do |feature|
|
|
38
|
+
describe feature do
|
|
39
|
+
Test::Fixtures::Dates[feature].each do |example|
|
|
40
|
+
|
|
41
|
+
it example['it'] do
|
|
42
|
+
dates = example['dates'].map { |date| Date.new(date) }
|
|
43
|
+
expected = example['expected']
|
|
44
|
+
options = example['options']
|
|
45
|
+
|
|
46
|
+
result = case feature
|
|
47
|
+
when 'display'
|
|
48
|
+
dates.map { |date| date.display(options) }
|
|
49
|
+
when 'json-api'
|
|
50
|
+
dates.map(&:to_json)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
result.should == expected
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe 'literal dates' do
|
|
61
|
+
|
|
62
|
+
it 'is not literal by default' do
|
|
63
|
+
Date.new.should_not be_literal
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'is literal if it contains only a literal field' do
|
|
67
|
+
Date.create(:literal => 'foo').should be_literal
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'is literal if it contains a literal field' do
|
|
71
|
+
Date.create('date-parts' => [[2000]], :literal => 'foo').should be_literal
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe 'uncertain dates' do
|
|
76
|
+
it 'are uncertain' do
|
|
77
|
+
Date.new({ 'date-parts' => [[-225]], 'circa' => '1' }).should be_uncertain
|
|
78
|
+
Date.new { |d| d.parts = [[-225]]; d.circa = true }.should be_uncertain
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
module CiteProc
|
|
2
|
+
describe Formatter do
|
|
3
|
+
|
|
4
|
+
it { should_not be_nil }
|
|
5
|
+
|
|
6
|
+
describe '#format' do
|
|
7
|
+
it 'returns the current format by default' do
|
|
8
|
+
Formatter.new.format.should be_a_kind_of(Format::Default)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'applies the current format if arguments are given' do
|
|
12
|
+
Formatter.new.format('foo').should == 'foo'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '#apply' do
|
|
17
|
+
|
|
18
|
+
it 'returns an empty string by default' do
|
|
19
|
+
Formatter.new.apply.should == ''
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context 'using the default style' do
|
|
23
|
+
|
|
24
|
+
let(:format) { Formatter.new }
|
|
25
|
+
|
|
26
|
+
it 'returns the given string if there are no attributes' do
|
|
27
|
+
format.apply('foo') == 'foo'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'returns the formatted string (prefix)' do
|
|
31
|
+
format.apply('foo', 'prefix' => '@').should == '@foo'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'returns the formatted string (suffix)' do
|
|
35
|
+
format.apply('foo', 'suffix' => '@').should == 'foo@'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'returns the formatted string (affixes)' do
|
|
39
|
+
format.apply('foo', 'prefix' => '@', 'suffix' => '@').should == '@foo@'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'returns the formatted string (display)' do
|
|
43
|
+
format.apply('foo', 'display' => 'block').should == 'foo'
|
|
44
|
+
format.apply('foo', 'display' => 'inline').should == 'foo'
|
|
45
|
+
format.apply('foo', 'display' => 'right-inline').should == 'foo'
|
|
46
|
+
format.apply('foo', 'display' => 'left-margin').should == 'foo'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'returns the formatted string (strip periods)' do
|
|
50
|
+
format.apply('foo', 'strip-periods' => 'true').should == 'foo'
|
|
51
|
+
format.apply('foo.', 'strip-periods' => 'true').should == 'foo'
|
|
52
|
+
format.apply('f.oo.', 'strip-periods' => 'true').should == 'f oo'
|
|
53
|
+
format.apply('.foo.', 'strip-periods' => 'true').should == 'foo'
|
|
54
|
+
format.apply('foo...', 'strip-periods' => 'true').should == 'foo'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'returns the formatted string (font-style)' do
|
|
58
|
+
format.apply('foo', 'font-style' => 'normal').should == 'foo'
|
|
59
|
+
format.apply('foo', 'font-style' => 'italic').should == 'foo'
|
|
60
|
+
format.apply('foo', 'font-style' => 'italics').should == 'foo'
|
|
61
|
+
format.apply('foo', 'font-style' => 'oblique').should == 'foo'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'returns the formatted string (font-variant)' do
|
|
65
|
+
format.apply('foo', 'font-variant' => 'normal').should == 'foo'
|
|
66
|
+
format.apply('foo', 'font-variant' => 'small-caps').should == 'foo'
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'returns the formatted string (font-weight)' do
|
|
70
|
+
format.apply('foo', 'font-weight' => 'normal').should == 'foo'
|
|
71
|
+
format.apply('foo', 'font-weight' => 'bold').should == 'foo'
|
|
72
|
+
format.apply('foo', 'font-weight' => 'light').should == 'foo'
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'returns the formatted string (text-decoration)' do
|
|
76
|
+
format.apply('foo', 'text-decoration' => 'none').should == 'foo'
|
|
77
|
+
format.apply('foo', 'text-decoration' => 'underline').should == 'foo'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'returns the formatted string (vertical-align)' do
|
|
81
|
+
format.apply('foo', 'vertical-align' => 'baseline').should == 'foo'
|
|
82
|
+
format.apply('foo', 'vertical-align' => 'sub').should == 'foo'
|
|
83
|
+
format.apply('foo', 'vertical-align' => 'sup').should == 'foo'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'returns the formatted string (text-case)' do
|
|
87
|
+
format.apply('foo', 'text-case' => 'none').should == 'foo'
|
|
88
|
+
format.apply('foo Foo FOO', 'text-case' => 'lowercase').should == 'foo foo foo'
|
|
89
|
+
format.apply('foo Foo FoO', 'text-case' => 'uppercase').should == 'FOO FOO FOO'
|
|
90
|
+
format.apply('foo foo foo', 'text-case' => 'capitalize-first').should == 'Foo foo foo'
|
|
91
|
+
format.apply('foo FOO fOo', 'text-case' => 'capitalize-all').should == 'Foo Foo Foo'
|
|
92
|
+
format.apply('the short story of foo and bar', 'text-case' => 'title').should == 'The Short Story of Foo and Bar'
|
|
93
|
+
format.apply('the short story of FOO and BAR', 'text-case' => 'title').should == 'The Short Story of FOO and BAR'
|
|
94
|
+
format.apply('the short story of foo and bar', 'text-case' => 'sentence').should == 'The short story of foo and bar'
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module CiteProc
|
|
4
|
+
describe Item do
|
|
5
|
+
|
|
6
|
+
let(:item) { Item.new }
|
|
7
|
+
|
|
8
|
+
describe '#new' do
|
|
9
|
+
it { should_not be_nil }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe '.create' do
|
|
13
|
+
it 'accepts parameters and returns a new item containing the parameters' do
|
|
14
|
+
pending #Item.new(:author => 'Poe, Edgar A.').author.family == 'Poe'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe '#add_observers' do
|
|
19
|
+
it 'adds a new observer to the empty list of observers' do
|
|
20
|
+
expect {
|
|
21
|
+
item.add_observer(stub('observer', :update => nil))
|
|
22
|
+
}.to change { item.count_observers }.from(0).to(1)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'adds a new observers to the internal list of observers' do
|
|
26
|
+
expect {
|
|
27
|
+
item.add_observer(stub('observer1', :update => nil))
|
|
28
|
+
item.add_observer(stub('observer2', :update => nil))
|
|
29
|
+
item.add_observer(stub('observer3', :update => nil))
|
|
30
|
+
}.to change { item.count_observers }.from(0).to(3)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe '#delete_observers' do
|
|
35
|
+
let(:observer) { stub('observer', :update => nil) }
|
|
36
|
+
|
|
37
|
+
it 'raises no error if the list of observers is empty' do
|
|
38
|
+
item.delete_observer(observer)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'does not alter the list of observers if the given observer is not currently observing the item' do
|
|
42
|
+
item.add_observer(observer)
|
|
43
|
+
item.count_observers.should == 1
|
|
44
|
+
item.delete_observer(stub('observer2'))
|
|
45
|
+
item.count_observers.should == 1
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'removes the given observer from the list of observers' do
|
|
49
|
+
item.add_observer(observer)
|
|
50
|
+
expect {
|
|
51
|
+
item.delete_observer(observer)
|
|
52
|
+
}.to change { item.count_observers }.from(1).to(0)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe '#[]' do
|
|
57
|
+
it 'returns the value for the given key' do
|
|
58
|
+
item['foo'] = 'foo'
|
|
59
|
+
item['foo'].should == 'foo'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'notifies observers on every variable access' do
|
|
63
|
+
observer = stub('observer')
|
|
64
|
+
observer.should_receive(:update).once
|
|
65
|
+
item.add_observer(observer)
|
|
66
|
+
item['foo']
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|