citeproc-ruby 0.0.6 → 1.0.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.
Files changed (186) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.document +4 -0
  4. data/.gitignore +10 -0
  5. data/.rspec +3 -0
  6. data/.simplecov +4 -0
  7. data/.travis.yml +17 -0
  8. data/.yardopts +2 -0
  9. data/AGPL +662 -0
  10. data/BSDL +29 -0
  11. data/Gemfile +42 -0
  12. data/Guardfile +14 -0
  13. data/README.md +32 -76
  14. data/Rakefile +60 -0
  15. data/citeproc-ruby.gemspec +46 -0
  16. data/cucumber.yml +1 -0
  17. data/features/bibliography.feature +25 -0
  18. data/features/name_options.feature +37 -0
  19. data/features/names.feature +192 -0
  20. data/features/renderer.feature +74 -0
  21. data/features/sort.feature +50 -0
  22. data/features/step_definitions/renderer.rb +80 -0
  23. data/features/support/env.rb +33 -0
  24. data/features/support/hooks.rb +10 -0
  25. data/lib/citeproc/ruby.rb +32 -0
  26. data/lib/citeproc/ruby/engine.rb +122 -0
  27. data/lib/citeproc/ruby/format.rb +303 -0
  28. data/lib/citeproc/ruby/formats/default.rb +25 -0
  29. data/lib/citeproc/ruby/formats/html.rb +221 -0
  30. data/lib/citeproc/ruby/renderer.rb +140 -0
  31. data/lib/citeproc/ruby/renderer/choose.rb +106 -0
  32. data/lib/citeproc/ruby/renderer/date.rb +90 -0
  33. data/lib/citeproc/ruby/renderer/format.rb +129 -0
  34. data/lib/citeproc/ruby/renderer/group.rb +34 -0
  35. data/lib/citeproc/ruby/renderer/history.rb +40 -0
  36. data/lib/citeproc/ruby/renderer/label.rb +66 -0
  37. data/lib/citeproc/ruby/renderer/layout.rb +20 -0
  38. data/lib/citeproc/ruby/renderer/locale.rb +26 -0
  39. data/lib/citeproc/ruby/renderer/macro.rb +20 -0
  40. data/lib/citeproc/ruby/renderer/names.rb +401 -0
  41. data/lib/citeproc/ruby/renderer/number.rb +41 -0
  42. data/lib/citeproc/ruby/renderer/observer.rb +44 -0
  43. data/lib/citeproc/ruby/renderer/state.rb +96 -0
  44. data/lib/citeproc/ruby/renderer/text.rb +62 -0
  45. data/lib/citeproc/ruby/sort.rb +82 -0
  46. data/lib/citeproc/ruby/version.rb +5 -0
  47. data/spec/citeproc/ruby/engine_spec.rb +94 -0
  48. data/spec/citeproc/ruby/formats/default_spec.rb +159 -0
  49. data/spec/citeproc/ruby/formats/html_spec.rb +162 -0
  50. data/spec/citeproc/ruby/renderer/choose_spec.rb +293 -0
  51. data/spec/citeproc/ruby/renderer/date_spec.rb +173 -0
  52. data/spec/citeproc/ruby/renderer/group_spec.rb +88 -0
  53. data/spec/citeproc/ruby/renderer/history_spec.rb +38 -0
  54. data/spec/citeproc/ruby/renderer/label_spec.rb +225 -0
  55. data/spec/citeproc/ruby/renderer/layout_spec.rb +41 -0
  56. data/spec/citeproc/ruby/renderer/macro_spec.rb +31 -0
  57. data/spec/citeproc/ruby/renderer/names_spec.rb +396 -0
  58. data/spec/citeproc/ruby/renderer/number_spec.rb +120 -0
  59. data/spec/citeproc/ruby/renderer/text_spec.rb +120 -0
  60. data/spec/citeproc/ruby/renderer_spec.rb +65 -0
  61. data/spec/fixtures/items.rb +80 -0
  62. data/{resource/locale → spec/fixtures/locales}/locales-en-US.xml +2 -11
  63. data/{resource/locale → spec/fixtures/locales}/locales-fr-FR.xml +77 -66
  64. data/{resource/style → spec/fixtures/styles}/apa.csl +5 -5
  65. data/spec/spec_helper.rb +67 -14
  66. metadata +121 -211
  67. data/lib/citeproc.rb +0 -100
  68. data/lib/citeproc/bibliography.rb +0 -57
  69. data/lib/citeproc/data.rb +0 -149
  70. data/lib/citeproc/date.rb +0 -133
  71. data/lib/citeproc/formatter.rb +0 -38
  72. data/lib/citeproc/item.rb +0 -53
  73. data/lib/citeproc/name.rb +0 -284
  74. data/lib/citeproc/processor.rb +0 -166
  75. data/lib/citeproc/selector.rb +0 -61
  76. data/lib/citeproc/variable.rb +0 -82
  77. data/lib/citeproc/version.rb +0 -3
  78. data/lib/csl/locale.rb +0 -223
  79. data/lib/csl/node.rb +0 -72
  80. data/lib/csl/nodes.rb +0 -1418
  81. data/lib/csl/renderer.rb +0 -88
  82. data/lib/csl/sort.rb +0 -61
  83. data/lib/csl/style.rb +0 -110
  84. data/lib/csl/term.rb +0 -124
  85. data/lib/extensions/core.rb +0 -43
  86. data/lib/plugins/filters/bibtex.rb +0 -12
  87. data/lib/plugins/formats/default.rb +0 -134
  88. data/lib/plugins/formats/html.rb +0 -67
  89. data/lib/support/attributes.rb +0 -99
  90. data/lib/support/compatibility.rb +0 -83
  91. data/lib/support/tree.rb +0 -80
  92. data/resource/locale/locales-af-ZA.xml +0 -305
  93. data/resource/locale/locales-ar-AR.xml +0 -306
  94. data/resource/locale/locales-bg-BG.xml +0 -305
  95. data/resource/locale/locales-ca-AD.xml +0 -305
  96. data/resource/locale/locales-cs-CZ.xml +0 -305
  97. data/resource/locale/locales-da-DK.xml +0 -305
  98. data/resource/locale/locales-de-AT.xml +0 -304
  99. data/resource/locale/locales-de-CH.xml +0 -304
  100. data/resource/locale/locales-de-DE.xml +0 -332
  101. data/resource/locale/locales-el-GR.xml +0 -305
  102. data/resource/locale/locales-en-GB.xml +0 -304
  103. data/resource/locale/locales-es-ES.xml +0 -305
  104. data/resource/locale/locales-et-EE.xml +0 -304
  105. data/resource/locale/locales-eu.xml +0 -305
  106. data/resource/locale/locales-fa-IR.xml +0 -304
  107. data/resource/locale/locales-fi-FI.xml +0 -304
  108. data/resource/locale/locales-fr-CA.xml +0 -306
  109. data/resource/locale/locales-he-IL.xml +0 -304
  110. data/resource/locale/locales-hu-HU.xml +0 -305
  111. data/resource/locale/locales-is-IS.xml +0 -304
  112. data/resource/locale/locales-it-IT.xml +0 -305
  113. data/resource/locale/locales-ja-JP.xml +0 -305
  114. data/resource/locale/locales-kh-KH.xml +0 -303
  115. data/resource/locale/locales-km-KH.xml +0 -304
  116. data/resource/locale/locales-ko-KR.xml +0 -305
  117. data/resource/locale/locales-mn-MN.xml +0 -306
  118. data/resource/locale/locales-nb-NO.xml +0 -304
  119. data/resource/locale/locales-nl-NL.xml +0 -304
  120. data/resource/locale/locales-nn-NO.xml +0 -304
  121. data/resource/locale/locales-pl-PL.xml +0 -305
  122. data/resource/locale/locales-pt-BR.xml +0 -304
  123. data/resource/locale/locales-pt-PT.xml +0 -305
  124. data/resource/locale/locales-ro-RO.xml +0 -305
  125. data/resource/locale/locales-ru-RU.xml +0 -306
  126. data/resource/locale/locales-sk-SK.xml +0 -304
  127. data/resource/locale/locales-sl-SI.xml +0 -305
  128. data/resource/locale/locales-sr-RS.xml +0 -305
  129. data/resource/locale/locales-sv-SE.xml +0 -305
  130. data/resource/locale/locales-th-TH.xml +0 -304
  131. data/resource/locale/locales-tr-TR.xml +0 -305
  132. data/resource/locale/locales-uk-UA.xml +0 -306
  133. data/resource/locale/locales-vi-VN.xml +0 -305
  134. data/resource/locale/locales-zh-CN.xml +0 -304
  135. data/resource/locale/locales-zh-TW.xml +0 -305
  136. data/resource/schema/csl-categories.rnc +0 -39
  137. data/resource/schema/csl-data.rnc +0 -98
  138. data/resource/schema/csl-terms.rnc +0 -106
  139. data/resource/schema/csl-types.rnc +0 -39
  140. data/resource/schema/csl-variables.rnc +0 -182
  141. data/resource/schema/csl.rnc +0 -941
  142. data/resource/style/bibtex.csl +0 -177
  143. data/resource/style/chicago-annotated-bibliography.csl +0 -513
  144. data/resource/style/chicago-author-date-basque.csl +0 -707
  145. data/resource/style/chicago-author-date-de.csl +0 -394
  146. data/resource/style/chicago-author-date-listing.csl +0 -434
  147. data/resource/style/chicago-author-date.csl +0 -425
  148. data/resource/style/chicago-dated-note-biblio-no-ibid.csl +0 -472
  149. data/resource/style/chicago-fullnote-bibliography-bb.csl +0 -928
  150. data/resource/style/chicago-fullnote-bibliography-delimiter-fixes.csl +0 -972
  151. data/resource/style/chicago-fullnote-bibliography-no-ibid-delimiter-fixes.csl +0 -963
  152. data/resource/style/chicago-fullnote-bibliography-no-ibid.csl +0 -785
  153. data/resource/style/chicago-fullnote-bibliography.csl +0 -803
  154. data/resource/style/chicago-library-list.csl +0 -511
  155. data/resource/style/chicago-note-biblio-no-ibid.csl +0 -514
  156. data/resource/style/chicago-note-bibliography.csl +0 -530
  157. data/resource/style/chicago-note.csl +0 -388
  158. data/resource/style/chicago-quick-copy.csl +0 -685
  159. data/resource/style/ieee.csl +0 -299
  160. data/resource/style/mla-notes.csl +0 -796
  161. data/resource/style/mla-underline.csl +0 -175
  162. data/resource/style/mla-url.csl +0 -214
  163. data/resource/style/mla.csl +0 -394
  164. data/resource/style/vancouver-brackets.csl +0 -256
  165. data/resource/style/vancouver-superscript-bracket-only-year.csl +0 -165
  166. data/resource/style/vancouver-superscript.csl +0 -256
  167. data/resource/style/vancouver.csl +0 -256
  168. data/spec/citeproc/bibliography_spec.rb +0 -45
  169. data/spec/citeproc/citeproc_spec.rb +0 -80
  170. data/spec/citeproc/date_spec.rb +0 -89
  171. data/spec/citeproc/formatter_spec.rb +0 -101
  172. data/spec/citeproc/item_spec.rb +0 -71
  173. data/spec/citeproc/name_spec.rb +0 -30
  174. data/spec/citeproc/processor_spec.rb +0 -61
  175. data/spec/citeproc/selector_spec.rb +0 -82
  176. data/spec/citeproc/variable_spec.rb +0 -69
  177. data/spec/csl/locale_spec.rb +0 -208
  178. data/spec/csl/node_spec.rb +0 -25
  179. data/spec/csl/nodes_spec.rb +0 -145
  180. data/spec/csl/style_spec.rb +0 -62
  181. data/spec/csl/term_spec.rb +0 -56
  182. data/spec/fixtures/dates.yaml +0 -80
  183. data/spec/fixtures/names.yaml +0 -115
  184. data/spec/fixtures/nodes.yaml +0 -245
  185. data/spec/support/attributes_spec.rb +0 -39
  186. data/spec/support/tree_spec.rb +0 -163
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ module CiteProc
4
+ module Ruby
5
+
6
+ describe 'Renderer#render_layout' do
7
+ let(:renderer) { Renderer.new }
8
+
9
+ let(:node) { CSL::Style::Layout.new }
10
+
11
+ let(:item) {
12
+ i = CiteProc::CitationItem.new(:id => 'ID-1')
13
+ i.data = CiteProc::Item.new(:id => 'ID-1')
14
+ i
15
+ }
16
+
17
+ it 'returns an empty string when empty' do
18
+ renderer.render(item, node).should == ''
19
+ end
20
+
21
+ describe 'with child nodes' do
22
+ before(:each) do
23
+ node << CSL::Style::Text.new(:value => 'foo')
24
+ node << CSL::Style::Text.new(:value => 'bar')
25
+ end
26
+
27
+ it 'renders each child' do
28
+ renderer.render(item, node).should == 'foobar'
29
+ end
30
+
31
+ it 'uses the delimiters if specified' do
32
+ node[:delimiter] = '-'
33
+ renderer.render(item, node).should == 'foo-bar'
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
41
+
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ module CiteProc
4
+ module Ruby
5
+
6
+ describe 'Renderer#render_macro' do
7
+ let(:renderer) { Renderer.new }
8
+
9
+ let(:node) { CSL::Style::Macro.new }
10
+
11
+ let(:item) {
12
+ i = CiteProc::CitationItem.new(:id => 'ID-1')
13
+ i.data = CiteProc::Item.new(:id => 'ID-1')
14
+ i
15
+ }
16
+
17
+ it 'returns an empty string when empty' do
18
+ renderer.render(item, node).should == ''
19
+ end
20
+
21
+ it 'renders each child' do
22
+ node << CSL::Style::Text.new(:value => 'foo')
23
+ node << CSL::Style::Text.new(:value => 'bar')
24
+
25
+ renderer.render(item, node).should == 'foobar'
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,396 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+
5
+ module CiteProc
6
+ module Ruby
7
+
8
+ describe "Renderer#render_names" do
9
+ let(:renderer) { Renderer.new }
10
+
11
+ let(:node) { CSL::Style::Names.new }
12
+
13
+ let(:item) {
14
+ i = CiteProc::CitationItem.new(:id => 'ID-1')
15
+ i.data = CiteProc::Item.new(:id => 'ID-1')
16
+ i
17
+ }
18
+
19
+ let(:poe) { people(:poe) }
20
+ let(:philosophers) { CiteProc::Names.new('Plato and Socrates and Aristotle') }
21
+
22
+ describe 'given an empty node' do
23
+ it 'returns an empty string for an empty item' do
24
+ renderer.render(item, node).should == ''
25
+ end
26
+
27
+ it 'returns an empty string for an item with variables' do
28
+ item.data.edition = 'foo'
29
+ renderer.render_names(item, node).should == ''
30
+ end
31
+ end
32
+
33
+ describe 'given a single name for the variable' do
34
+ before do
35
+ item.data.author = poe
36
+ node[:variable] = 'author'
37
+ end
38
+
39
+ it 'formats it in long form' do
40
+ renderer.render_names(item, node).should == 'Edgar Allen Poe'
41
+ end
42
+
43
+ it 'supports nested name node options' do
44
+ node << CSL::Style::Name.new(:form => 'short')
45
+ renderer.render_names(item, node).should == 'Poe'
46
+ end
47
+
48
+ it 'supports nested label node' do
49
+ node << CSL::Style::Label.new(:prefix => ' [', :suffix => ']')
50
+ renderer.render_names(item, node).should == 'Edgar Allen Poe [author]'
51
+ end
52
+ end
53
+
54
+ describe 'given multiple names for a single variable' do
55
+ before do
56
+ item.data.editor = philosophers
57
+ node[:variable] = 'editor'
58
+ end
59
+
60
+ it 'formats them as a list' do
61
+ renderer.render_names(item, node).should == 'Plato, Socrates, Aristotle'
62
+ end
63
+
64
+ it 'supports nested name node options' do
65
+ node << CSL::Style::Name.new(:and => 'symbol')
66
+ renderer.render_names(item, node).should == 'Plato, Socrates, & Aristotle'
67
+ end
68
+
69
+ it 'supports nested label node' do
70
+ node << CSL::Style::Label.new(:prefix => ' (', :suffix => ')')
71
+ renderer.render_names(item, node).should == 'Plato, Socrates, Aristotle (editors)'
72
+ end
73
+ end
74
+
75
+ describe 'given multiple variables' do
76
+ before do
77
+ node[:variable] = 'author editor'
78
+ node[:delimiter] = '; '
79
+ end
80
+
81
+ it 'renders all matching lists combinded using default delimiter' do
82
+ renderer.render_names(item, node).should == ''
83
+
84
+ item.data.author = poe
85
+ renderer.render_names(item, node).should == 'Edgar Allen Poe'
86
+
87
+ item.data.editor = philosophers
88
+ renderer.render_names(item, node).should == 'Edgar Allen Poe; Plato, Socrates, Aristotle'
89
+ end
90
+
91
+ it 'keeps the variable order' do
92
+ item.data.author = poe
93
+ item.data.editor = philosophers
94
+
95
+ node[:variable] = 'editor author'
96
+ renderer.render_names(item, node).should == 'Plato, Socrates, Aristotle; Edgar Allen Poe'
97
+ end
98
+
99
+ it 'supports labels' do
100
+ item.data.author = poe
101
+ item.data.editor = philosophers
102
+
103
+ node << CSL::Style::Label.new(:prefix => ' (', :suffix => ')')
104
+
105
+ renderer.render_names(item, node).should == 'Edgar Allen Poe (author); Plato, Socrates, Aristotle (editors)'
106
+ end
107
+
108
+ it 'resolves the editor translator special case' do
109
+ renderer.format = :text
110
+
111
+ node[:variable] = 'translator author editor'
112
+
113
+ item.data.editor = 'Patrick F. Quinn and G. R. Thompson'
114
+ item.data.author = poe
115
+
116
+ node.name = { :and => 'symbol', :form => 'short' }
117
+ node.label = { :prefix => ' (', :suffix => ')' }
118
+
119
+ renderer.render_names(item, node).should == 'Poe (author); Quinn & Thompson (editors)'
120
+
121
+ item.data.translator = poe
122
+ renderer.render_names(item, node).should == 'Poe (translator); Poe (author); Quinn & Thompson (editors)'
123
+
124
+ item.data.translator = 'Patrick F. Quinn and G. R. Thompson'
125
+
126
+ renderer.render(item, node).should == 'Quinn & Thompson (editors & translators); Poe (author)'
127
+ end
128
+ end
129
+ end
130
+
131
+ describe "Renderer#render_name" do
132
+ let(:renderer) { Renderer.new }
133
+
134
+ let(:node) { CSL::Style::Name.new }
135
+
136
+ let(:poe) { people(:poe) }
137
+ let(:philosophers) { CiteProc::Names.new('Plato and Socrates and Aristotle') }
138
+
139
+ describe 'given an empty node' do
140
+ it 'returns an empty string given no names' do
141
+ renderer.render_name(CiteProc::Names.new, node).should == ''
142
+ end
143
+
144
+ it 'formats the given name in long form' do
145
+ renderer.render_name(poe, node).should == 'Edgar Allen Poe'
146
+ end
147
+
148
+ it 'formats multiple names delimitted by commas' do
149
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, Aristotle'
150
+ end
151
+ end
152
+
153
+ describe 'given a node with and "and" attribute' do
154
+ it 'inserts a delimited connector' do
155
+ node[:and] = 'symbol'
156
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, & Aristotle'
157
+
158
+ node[:and] = 'text'
159
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, and Aristotle'
160
+ end
161
+ end
162
+
163
+ describe 'given a node with delimier-precedes-last' do
164
+ it 'inserts final delimiter only for three or more names when set to "contextual"' do
165
+ node.delimiter_contextually_precedes_last!
166
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, Aristotle'
167
+
168
+ node[:and] = 'text'
169
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, and Aristotle'
170
+
171
+ renderer.render_name(philosophers.take(2), node).should == 'Plato and Socrates'
172
+
173
+ node[:and] = nil
174
+ renderer.render_name(philosophers.take(2), node).should == 'Plato, Socrates'
175
+ end
176
+
177
+ it 'inserts final delimiter when set to "always"' do
178
+ node.delimiter_always_precedes_last!
179
+
180
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, Aristotle'
181
+
182
+ node[:and] = 'text'
183
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, and Aristotle'
184
+
185
+ renderer.render_name(philosophers.take(2), node).should == 'Plato, and Socrates'
186
+
187
+ node[:and] = nil
188
+ renderer.render_name(philosophers.take(2), node).should == 'Plato, Socrates'
189
+ end
190
+
191
+ it 'never inserts final delimiter when set to "never" (unless there is no "and")' do
192
+ node.delimiter_never_precedes_last!
193
+
194
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, Aristotle'
195
+ renderer.render_name(philosophers.take(2), node).should == 'Plato, Socrates'
196
+
197
+ node[:and] = 'text'
198
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates and Aristotle'
199
+ renderer.render_name(philosophers.take(2), node).should == 'Plato and Socrates'
200
+ end
201
+
202
+ it 'supports only-after-inverted-name rule' do
203
+ names = CiteProc::Names.new('Doe, J. and Smith, S. and Williams, T.')
204
+ node.delimiter_precedes_last_after_inverted_name!
205
+
206
+ # always delimit when there is no and!
207
+ renderer.render_name(names, node).should == 'J. Doe, S. Smith, T. Williams'
208
+ renderer.render_name(names.take(2), node).should == 'J. Doe, S. Smith'
209
+
210
+ node[:and] = 'text'
211
+ renderer.render_name(names, node).should == 'J. Doe, S. Smith and T. Williams'
212
+ renderer.render_name(names.take(2), node).should == 'J. Doe and S. Smith'
213
+
214
+ node[:'name-as-sort-order'] = 'first'
215
+ renderer.render_name(names, node).should == 'Doe, J., S. Smith and T. Williams'
216
+ renderer.render_name(names.take(2), node).should == 'Doe, J., and S. Smith'
217
+
218
+ node[:'name-as-sort-order'] = 'all'
219
+ renderer.render_name(names, node).should == 'Doe, J., Smith, S., and Williams, T.'
220
+ renderer.render_name(names.take(2), node).should == 'Doe, J., and Smith, S.'
221
+ end
222
+ end
223
+
224
+ describe 'truncation of name lists' do
225
+ let(:names) { CiteProc::Names.new('Doe, J. and Smith, S. and Williams, T.') }
226
+
227
+ it 'supports et-al formatting via an et-al node' do
228
+ node[:'et-al-min'] = 3
229
+ node[:'et-al-use-first'] = 2
230
+
231
+ others = CSL::Style::EtAl.new(:prefix => '!!')
232
+ node.stub(:et_al).and_return(others)
233
+
234
+ renderer.render_name(names, node).should == 'J. Doe, S. Smith, !!et al.'
235
+
236
+ others[:term] = 'and others'
237
+ renderer.render_name(names, node).should == 'J. Doe, S. Smith, !!and others'
238
+ end
239
+
240
+ it 'supports et-al-use-last' do
241
+ node[:'et-al-min'] = 3
242
+ node[:'et-al-use-first'] = 2
243
+ node[:'et-al-use-last'] = true
244
+
245
+ # truncated list must be at least two names short!
246
+ renderer.render_name(names, node).should == 'J. Doe, S. Smith, et al.'
247
+
248
+ node[:'et-al-use-first'] = 1
249
+ renderer.render_name(names, node).should == 'J. Doe, … T. Williams'
250
+ end
251
+
252
+ describe 'with default delimiter settings' do
253
+ it 'truncates the list if it matches or exceeds et-al-min' do
254
+ node[:'et-al-min'] = 3
255
+ node[:'et-al-use-first'] = 2
256
+
257
+ renderer.render_name(names, node).should == 'J. Doe, S. Smith, et al.'
258
+
259
+ node[:'et-al-use-first'] = 1
260
+ renderer.render_name(names, node).should == 'J. Doe et al.'
261
+ end
262
+
263
+ it 'does not truncate the list if it is less than et-al-min' do
264
+ node[:'et-al-min'] = 4
265
+ node[:'et-al-use-first'] = 2
266
+
267
+ renderer.render_name(names, node).should == 'J. Doe, S. Smith, T. Williams'
268
+ end
269
+ end
270
+
271
+ describe 'with delimiter-precedes-et-al set' do
272
+ it 'inserts delimiter only for two or more names when set to "contextual" or nil' do
273
+ node.truncate_when! 3
274
+ node.truncate_at! 2
275
+
276
+ # default behaviour should match contextual!
277
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, et al.'
278
+
279
+ node.truncate_at! 1
280
+ renderer.render_name(philosophers, node).should == 'Plato et al.'
281
+
282
+ # set contextual explicitly
283
+ node.delimiter_contextually_precedes_et_al!
284
+ renderer.render_name(philosophers, node).should == 'Plato et al.'
285
+
286
+ node.truncate_at! 2
287
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, et al.'
288
+ end
289
+
290
+ it 'inserts delimiter when set to "always"' do
291
+ node.truncate_when! 3
292
+ node.truncate_at! 2
293
+
294
+ node.delimiter_always_precedes_et_al!
295
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates, et al.'
296
+
297
+ node.truncate_at! 1
298
+ renderer.render_name(philosophers, node).should == 'Plato, et al.'
299
+ end
300
+
301
+ it 'never inserts delimiter when set to "never"' do
302
+ node.truncate_when! 3
303
+ node.truncate_at! 2
304
+
305
+ node.delimiter_never_precedes_et_al!
306
+ renderer.render_name(philosophers, node).should == 'Plato, Socrates et al.'
307
+
308
+ node.truncate_at! 1
309
+ renderer.render_name(philosophers, node).should == 'Plato et al.'
310
+ end
311
+
312
+ it 'supports only-after-inverted-name rule' do
313
+ node.truncate_when! 3
314
+ node.truncate_at! 2
315
+
316
+ node.delimiter_precedes_et_al_after_inverted_name!
317
+
318
+ renderer.render_name(names, node).should == 'J. Doe, S. Smith et al.'
319
+
320
+ node[:'name-as-sort-order'] = 'first'
321
+ renderer.render_name(names, node).should == 'Doe, J., S. Smith et al.'
322
+
323
+ node.truncate_at! 1
324
+ renderer.render_name(names, node).should == 'Doe, J., et al.'
325
+
326
+ node[:'name-as-sort-order'] = 'all'
327
+ renderer.render_name(names, node).should == 'Doe, J., et al.'
328
+
329
+ node.truncate_at! 2
330
+ renderer.render_name(names, node).should == 'Doe, J., Smith, S., et al.'
331
+ end
332
+ end
333
+ end
334
+
335
+ describe 'name-part formatting' do
336
+ let(:part) { CSL::Style::NamePart.new(:'text-case' => 'uppercase') }
337
+ before { node.parts << part }
338
+
339
+ it 'supports family name formatting' do
340
+ part[:name] = 'family'
341
+ renderer.render_name(poe, node).should == 'Edgar Allen POE'
342
+ end
343
+
344
+ it 'family part includes non-demoted particles' do
345
+ part[:name] = 'family'
346
+
347
+ renderer.render_name(people(:la_fontaine), node).should == 'Jean de LA FONTAINE'
348
+ renderer.render_name(people(:humboldt), node).should == 'Alexander von HUMBOLDT'
349
+ renderer.render_name(people(:van_gogh), node).should == 'Vincent VAN GOGH'
350
+ end
351
+
352
+ it 'family part affixes includes name suffix for non-inverted names' do
353
+ part.merge! :name => 'family', :prefix => '(', :suffix => ')'
354
+
355
+ la_fontaine = people(:la_fontaine)
356
+ la_fontaine[0].suffix = 'Jr.'
357
+
358
+ renderer.render_name(la_fontaine, node).should == 'Jean de (LA FONTAINE Jr.)'
359
+ end
360
+
361
+ it 'supports given name formatting' do
362
+ part[:name] = 'given'
363
+ renderer.render_name(poe, node).should == 'EDGAR ALLEN Poe'
364
+ end
365
+
366
+ it 'given part includes particles' do
367
+ part[:name] = 'given'
368
+
369
+ renderer.render_name(people(:la_fontaine), node).should == 'JEAN DE La Fontaine'
370
+ renderer.render_name(people(:humboldt), node).should == 'ALEXANDER VON Humboldt'
371
+ renderer.render_name(people(:van_gogh), node).should == 'VINCENT van Gogh'
372
+ end
373
+
374
+ it 'given part affixes enclose demoted particles' do
375
+ part.merge! :name => 'given', :prefix => '(', :suffix => ')'
376
+
377
+ la_fontaine = people(:la_fontaine)
378
+
379
+ renderer.render_name(la_fontaine, node).should == '(JEAN DE) La Fontaine'
380
+
381
+ node.all_names_as_sort_order!
382
+ renderer.render_name(la_fontaine, node).should == 'La Fontaine, (JEAN DE)'
383
+
384
+ la_fontaine[0].always_demote_particle!
385
+ renderer.render_name(la_fontaine, node).should == 'Fontaine, (JEAN DE La)'
386
+ end
387
+
388
+ it 'does not alter the passed-in name object' do
389
+ part[:name] = 'family'
390
+ renderer.render_name(poe, node).should == 'Edgar Allen POE'
391
+ poe.to_s.should == 'Edgar Allen Poe'
392
+ end
393
+ end
394
+ end
395
+ end
396
+ end