citeproc-ruby 0.0.6 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.document +4 -0
- data/.gitignore +10 -0
- data/.rspec +3 -0
- data/.simplecov +4 -0
- data/.travis.yml +17 -0
- data/.yardopts +2 -0
- data/AGPL +662 -0
- data/BSDL +29 -0
- data/Gemfile +42 -0
- data/Guardfile +14 -0
- data/README.md +32 -76
- data/Rakefile +60 -0
- data/citeproc-ruby.gemspec +46 -0
- data/cucumber.yml +1 -0
- data/features/bibliography.feature +25 -0
- data/features/name_options.feature +37 -0
- data/features/names.feature +192 -0
- data/features/renderer.feature +74 -0
- data/features/sort.feature +50 -0
- data/features/step_definitions/renderer.rb +80 -0
- data/features/support/env.rb +33 -0
- data/features/support/hooks.rb +10 -0
- data/lib/citeproc/ruby.rb +32 -0
- data/lib/citeproc/ruby/engine.rb +122 -0
- data/lib/citeproc/ruby/format.rb +303 -0
- data/lib/citeproc/ruby/formats/default.rb +25 -0
- data/lib/citeproc/ruby/formats/html.rb +221 -0
- data/lib/citeproc/ruby/renderer.rb +140 -0
- data/lib/citeproc/ruby/renderer/choose.rb +106 -0
- data/lib/citeproc/ruby/renderer/date.rb +90 -0
- data/lib/citeproc/ruby/renderer/format.rb +129 -0
- data/lib/citeproc/ruby/renderer/group.rb +34 -0
- data/lib/citeproc/ruby/renderer/history.rb +40 -0
- data/lib/citeproc/ruby/renderer/label.rb +66 -0
- data/lib/citeproc/ruby/renderer/layout.rb +20 -0
- data/lib/citeproc/ruby/renderer/locale.rb +26 -0
- data/lib/citeproc/ruby/renderer/macro.rb +20 -0
- data/lib/citeproc/ruby/renderer/names.rb +401 -0
- data/lib/citeproc/ruby/renderer/number.rb +41 -0
- data/lib/citeproc/ruby/renderer/observer.rb +44 -0
- data/lib/citeproc/ruby/renderer/state.rb +96 -0
- data/lib/citeproc/ruby/renderer/text.rb +62 -0
- data/lib/citeproc/ruby/sort.rb +82 -0
- data/lib/citeproc/ruby/version.rb +5 -0
- data/spec/citeproc/ruby/engine_spec.rb +94 -0
- data/spec/citeproc/ruby/formats/default_spec.rb +159 -0
- data/spec/citeproc/ruby/formats/html_spec.rb +162 -0
- data/spec/citeproc/ruby/renderer/choose_spec.rb +293 -0
- data/spec/citeproc/ruby/renderer/date_spec.rb +173 -0
- data/spec/citeproc/ruby/renderer/group_spec.rb +88 -0
- data/spec/citeproc/ruby/renderer/history_spec.rb +38 -0
- data/spec/citeproc/ruby/renderer/label_spec.rb +225 -0
- data/spec/citeproc/ruby/renderer/layout_spec.rb +41 -0
- data/spec/citeproc/ruby/renderer/macro_spec.rb +31 -0
- data/spec/citeproc/ruby/renderer/names_spec.rb +396 -0
- data/spec/citeproc/ruby/renderer/number_spec.rb +120 -0
- data/spec/citeproc/ruby/renderer/text_spec.rb +120 -0
- data/spec/citeproc/ruby/renderer_spec.rb +65 -0
- data/spec/fixtures/items.rb +80 -0
- data/{resource/locale → spec/fixtures/locales}/locales-en-US.xml +2 -11
- data/{resource/locale → spec/fixtures/locales}/locales-fr-FR.xml +77 -66
- data/{resource/style → spec/fixtures/styles}/apa.csl +5 -5
- data/spec/spec_helper.rb +67 -14
- metadata +121 -211
- data/lib/citeproc.rb +0 -100
- data/lib/citeproc/bibliography.rb +0 -57
- data/lib/citeproc/data.rb +0 -149
- data/lib/citeproc/date.rb +0 -133
- data/lib/citeproc/formatter.rb +0 -38
- data/lib/citeproc/item.rb +0 -53
- data/lib/citeproc/name.rb +0 -284
- data/lib/citeproc/processor.rb +0 -166
- data/lib/citeproc/selector.rb +0 -61
- data/lib/citeproc/variable.rb +0 -82
- data/lib/citeproc/version.rb +0 -3
- data/lib/csl/locale.rb +0 -223
- data/lib/csl/node.rb +0 -72
- data/lib/csl/nodes.rb +0 -1418
- data/lib/csl/renderer.rb +0 -88
- data/lib/csl/sort.rb +0 -61
- data/lib/csl/style.rb +0 -110
- data/lib/csl/term.rb +0 -124
- data/lib/extensions/core.rb +0 -43
- data/lib/plugins/filters/bibtex.rb +0 -12
- data/lib/plugins/formats/default.rb +0 -134
- data/lib/plugins/formats/html.rb +0 -67
- data/lib/support/attributes.rb +0 -99
- data/lib/support/compatibility.rb +0 -83
- data/lib/support/tree.rb +0 -80
- data/resource/locale/locales-af-ZA.xml +0 -305
- data/resource/locale/locales-ar-AR.xml +0 -306
- data/resource/locale/locales-bg-BG.xml +0 -305
- data/resource/locale/locales-ca-AD.xml +0 -305
- data/resource/locale/locales-cs-CZ.xml +0 -305
- data/resource/locale/locales-da-DK.xml +0 -305
- data/resource/locale/locales-de-AT.xml +0 -304
- data/resource/locale/locales-de-CH.xml +0 -304
- data/resource/locale/locales-de-DE.xml +0 -332
- data/resource/locale/locales-el-GR.xml +0 -305
- data/resource/locale/locales-en-GB.xml +0 -304
- data/resource/locale/locales-es-ES.xml +0 -305
- data/resource/locale/locales-et-EE.xml +0 -304
- data/resource/locale/locales-eu.xml +0 -305
- data/resource/locale/locales-fa-IR.xml +0 -304
- data/resource/locale/locales-fi-FI.xml +0 -304
- data/resource/locale/locales-fr-CA.xml +0 -306
- data/resource/locale/locales-he-IL.xml +0 -304
- data/resource/locale/locales-hu-HU.xml +0 -305
- data/resource/locale/locales-is-IS.xml +0 -304
- data/resource/locale/locales-it-IT.xml +0 -305
- data/resource/locale/locales-ja-JP.xml +0 -305
- data/resource/locale/locales-kh-KH.xml +0 -303
- data/resource/locale/locales-km-KH.xml +0 -304
- data/resource/locale/locales-ko-KR.xml +0 -305
- data/resource/locale/locales-mn-MN.xml +0 -306
- data/resource/locale/locales-nb-NO.xml +0 -304
- data/resource/locale/locales-nl-NL.xml +0 -304
- data/resource/locale/locales-nn-NO.xml +0 -304
- data/resource/locale/locales-pl-PL.xml +0 -305
- data/resource/locale/locales-pt-BR.xml +0 -304
- data/resource/locale/locales-pt-PT.xml +0 -305
- data/resource/locale/locales-ro-RO.xml +0 -305
- data/resource/locale/locales-ru-RU.xml +0 -306
- data/resource/locale/locales-sk-SK.xml +0 -304
- data/resource/locale/locales-sl-SI.xml +0 -305
- data/resource/locale/locales-sr-RS.xml +0 -305
- data/resource/locale/locales-sv-SE.xml +0 -305
- data/resource/locale/locales-th-TH.xml +0 -304
- data/resource/locale/locales-tr-TR.xml +0 -305
- data/resource/locale/locales-uk-UA.xml +0 -306
- data/resource/locale/locales-vi-VN.xml +0 -305
- data/resource/locale/locales-zh-CN.xml +0 -304
- data/resource/locale/locales-zh-TW.xml +0 -305
- data/resource/schema/csl-categories.rnc +0 -39
- data/resource/schema/csl-data.rnc +0 -98
- data/resource/schema/csl-terms.rnc +0 -106
- data/resource/schema/csl-types.rnc +0 -39
- data/resource/schema/csl-variables.rnc +0 -182
- data/resource/schema/csl.rnc +0 -941
- data/resource/style/bibtex.csl +0 -177
- data/resource/style/chicago-annotated-bibliography.csl +0 -513
- data/resource/style/chicago-author-date-basque.csl +0 -707
- data/resource/style/chicago-author-date-de.csl +0 -394
- data/resource/style/chicago-author-date-listing.csl +0 -434
- data/resource/style/chicago-author-date.csl +0 -425
- data/resource/style/chicago-dated-note-biblio-no-ibid.csl +0 -472
- data/resource/style/chicago-fullnote-bibliography-bb.csl +0 -928
- data/resource/style/chicago-fullnote-bibliography-delimiter-fixes.csl +0 -972
- data/resource/style/chicago-fullnote-bibliography-no-ibid-delimiter-fixes.csl +0 -963
- data/resource/style/chicago-fullnote-bibliography-no-ibid.csl +0 -785
- data/resource/style/chicago-fullnote-bibliography.csl +0 -803
- data/resource/style/chicago-library-list.csl +0 -511
- data/resource/style/chicago-note-biblio-no-ibid.csl +0 -514
- data/resource/style/chicago-note-bibliography.csl +0 -530
- data/resource/style/chicago-note.csl +0 -388
- data/resource/style/chicago-quick-copy.csl +0 -685
- data/resource/style/ieee.csl +0 -299
- data/resource/style/mla-notes.csl +0 -796
- data/resource/style/mla-underline.csl +0 -175
- data/resource/style/mla-url.csl +0 -214
- data/resource/style/mla.csl +0 -394
- data/resource/style/vancouver-brackets.csl +0 -256
- data/resource/style/vancouver-superscript-bracket-only-year.csl +0 -165
- data/resource/style/vancouver-superscript.csl +0 -256
- data/resource/style/vancouver.csl +0 -256
- data/spec/citeproc/bibliography_spec.rb +0 -45
- data/spec/citeproc/citeproc_spec.rb +0 -80
- data/spec/citeproc/date_spec.rb +0 -89
- data/spec/citeproc/formatter_spec.rb +0 -101
- data/spec/citeproc/item_spec.rb +0 -71
- data/spec/citeproc/name_spec.rb +0 -30
- data/spec/citeproc/processor_spec.rb +0 -61
- data/spec/citeproc/selector_spec.rb +0 -82
- data/spec/citeproc/variable_spec.rb +0 -69
- data/spec/csl/locale_spec.rb +0 -208
- data/spec/csl/node_spec.rb +0 -25
- data/spec/csl/nodes_spec.rb +0 -145
- data/spec/csl/style_spec.rb +0 -62
- data/spec/csl/term_spec.rb +0 -56
- data/spec/fixtures/dates.yaml +0 -80
- data/spec/fixtures/names.yaml +0 -115
- data/spec/fixtures/nodes.yaml +0 -245
- data/spec/support/attributes_spec.rb +0 -39
- data/spec/support/tree_spec.rb +0 -163
@@ -0,0 +1,41 @@
|
|
1
|
+
module CiteProc
|
2
|
+
module Ruby
|
3
|
+
|
4
|
+
class Renderer
|
5
|
+
|
6
|
+
# @param item [CiteProc::CitationItem]
|
7
|
+
# @param node [CSL::Style::Number]
|
8
|
+
# @return [String]
|
9
|
+
def render_number(item, node)
|
10
|
+
return '' unless node.has_variable?
|
11
|
+
|
12
|
+
variable = item.data[node.variable]
|
13
|
+
return variable.to_s unless variable && variable.numeric?
|
14
|
+
|
15
|
+
numbers = variable.tokenize
|
16
|
+
|
17
|
+
case
|
18
|
+
when node.ordinal? || node.long_ordinal?
|
19
|
+
options = node.attributes_for :form
|
20
|
+
# TODO lookup term of variable to check gender
|
21
|
+
|
22
|
+
numbers.map! do |num|
|
23
|
+
num =~ /^\d+$/ ? ordinalize(num, options) : num
|
24
|
+
end
|
25
|
+
|
26
|
+
when node.roman?
|
27
|
+
numbers.map! do |num|
|
28
|
+
num =~ /^\d+$/ ? romanize(num) : num
|
29
|
+
end
|
30
|
+
|
31
|
+
else
|
32
|
+
# nothing
|
33
|
+
end
|
34
|
+
|
35
|
+
numbers.join('')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CiteProc
|
2
|
+
module Ruby
|
3
|
+
|
4
|
+
class Renderer
|
5
|
+
|
6
|
+
class ItemObserver
|
7
|
+
attr_accessor :history, :item
|
8
|
+
|
9
|
+
def initialize(item, history = {})
|
10
|
+
@item, @history = item, history
|
11
|
+
end
|
12
|
+
|
13
|
+
def start
|
14
|
+
item.add_observer(self)
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def stop
|
19
|
+
item.delete_observer(self)
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def update(method, key, value)
|
24
|
+
history[key] = value if method == :read
|
25
|
+
end
|
26
|
+
|
27
|
+
def skip?
|
28
|
+
!history.empty? && history.values.all?(&:nil?)
|
29
|
+
end
|
30
|
+
|
31
|
+
def accessed
|
32
|
+
history.select { |key, value| !value.nil? }.keys
|
33
|
+
end
|
34
|
+
|
35
|
+
def clear!
|
36
|
+
history.clear
|
37
|
+
self
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module CiteProc
|
2
|
+
module Ruby
|
3
|
+
class Renderer
|
4
|
+
|
5
|
+
def citation_mode?
|
6
|
+
state.mode == 'citation'
|
7
|
+
end
|
8
|
+
|
9
|
+
def bibliography_mode?
|
10
|
+
state.mode == 'bibliography'
|
11
|
+
end
|
12
|
+
|
13
|
+
def sort_mode?
|
14
|
+
state.mode == 'key'
|
15
|
+
end
|
16
|
+
|
17
|
+
def substitution_mode?
|
18
|
+
!state.substitute.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def style
|
22
|
+
return unless state.node && !state.node.root? &&
|
23
|
+
state.node.root.is_a?(CSL::Style)
|
24
|
+
|
25
|
+
state.node.root
|
26
|
+
end
|
27
|
+
|
28
|
+
class State
|
29
|
+
include Observable
|
30
|
+
|
31
|
+
attr_reader :history, :node, :item, :authors, :substitute
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@history, @authors = History.new(self, 3), []
|
35
|
+
end
|
36
|
+
|
37
|
+
def store!(item, node)
|
38
|
+
@item, @node = item, node
|
39
|
+
ensure
|
40
|
+
changed
|
41
|
+
end
|
42
|
+
|
43
|
+
def store_authors!(authors)
|
44
|
+
@authors << authors
|
45
|
+
ensure
|
46
|
+
changed
|
47
|
+
end
|
48
|
+
|
49
|
+
def clear!(result = nil)
|
50
|
+
memories = conserve(result)
|
51
|
+
@item, @node, @substitute, @authors, @names = nil, nil, nil, [], nil
|
52
|
+
ensure
|
53
|
+
changed
|
54
|
+
notify_observers :clear!, memories.delete(:mode), memories
|
55
|
+
end
|
56
|
+
|
57
|
+
def mode
|
58
|
+
node && node.nodename
|
59
|
+
end
|
60
|
+
|
61
|
+
def substitute!(names)
|
62
|
+
@substitute = names
|
63
|
+
end
|
64
|
+
|
65
|
+
def clear_substitute!(backup = nil)
|
66
|
+
@substitute = backup
|
67
|
+
end
|
68
|
+
|
69
|
+
def previous_authors
|
70
|
+
past = history.recall(mode)
|
71
|
+
return unless past && !past.empty?
|
72
|
+
|
73
|
+
past[:authors]
|
74
|
+
end
|
75
|
+
|
76
|
+
def rendered_names?
|
77
|
+
@names
|
78
|
+
end
|
79
|
+
|
80
|
+
def rendered_names!
|
81
|
+
@names = true
|
82
|
+
end
|
83
|
+
|
84
|
+
def conserve(result = nil)
|
85
|
+
{
|
86
|
+
:mode => mode,
|
87
|
+
:item => item,
|
88
|
+
:authors => authors,
|
89
|
+
:result => result
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module CiteProc
|
2
|
+
module Ruby
|
3
|
+
|
4
|
+
class Renderer
|
5
|
+
|
6
|
+
# @param item [CiteProc::CitationItem]
|
7
|
+
# @param node [CSL::Style::Text]
|
8
|
+
# @return [String]
|
9
|
+
def render_text(item, node)
|
10
|
+
case
|
11
|
+
when node.has_variable?
|
12
|
+
|
13
|
+
if node.variable == 'locator'
|
14
|
+
|
15
|
+
# Subtle: when there is no locator we also look
|
16
|
+
# in item.data; there should be no locator there
|
17
|
+
# either but the read access will be noticed by
|
18
|
+
# observers (if any).
|
19
|
+
text = item.locator || item.data[:locator].to_s
|
20
|
+
|
21
|
+
else
|
22
|
+
text = item.data.variable(node.variable, node.variable_options).to_s
|
23
|
+
|
24
|
+
# Check for abbreviations or short-form fallbacks!
|
25
|
+
context, was_short_form = node.variable.split(/-short/, 2)
|
26
|
+
|
27
|
+
if was_short_form || node[:form] == 'short'
|
28
|
+
if text.empty?
|
29
|
+
text = item.data.variable(context, node.variable_options).to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
text = abbreviate(context, text) || text
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
case
|
38
|
+
when node.variable == 'page'
|
39
|
+
format_page_range!(text, node.page_range_format)
|
40
|
+
|
41
|
+
when node.variable == 'page-first' && text.empty?
|
42
|
+
text = item.data[:'page'].to_s[/\d+/].to_s
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
text
|
47
|
+
|
48
|
+
when node.has_macro?
|
49
|
+
render item, node.macro
|
50
|
+
|
51
|
+
when node.has_term?
|
52
|
+
translate node[:term], node.attributes_for(:plural, :form)
|
53
|
+
|
54
|
+
else
|
55
|
+
node.value.to_s
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module CiteProc
|
2
|
+
module Ruby
|
3
|
+
|
4
|
+
module SortItems
|
5
|
+
|
6
|
+
def sort!(items, keys)
|
7
|
+
return itmes unless !keys.nil? && !keys.empty?
|
8
|
+
|
9
|
+
# TODO refactor
|
10
|
+
if items.is_a?(CitationData)
|
11
|
+
items.sort! do |a, b|
|
12
|
+
compare_items_by_keys(a.data, b.data, keys)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
items.sort! do |a, b|
|
16
|
+
compare_items_by_keys(a, b, keys)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @returns [-1, 0, 1, nil]
|
22
|
+
def compare_items_by_keys(a, b, keys)
|
23
|
+
result = 0
|
24
|
+
|
25
|
+
keys.each do |key|
|
26
|
+
result = compare_items_by_key(a, b, key)
|
27
|
+
return result unless result.zero?
|
28
|
+
end
|
29
|
+
|
30
|
+
result
|
31
|
+
end
|
32
|
+
|
33
|
+
# @returns [-1, 0, 1, nil]
|
34
|
+
def compare_items_by_key(a, b, key)
|
35
|
+
if key.macro?
|
36
|
+
result = compare_items(*renderer.render_sort(a, b, key.macro, key))
|
37
|
+
|
38
|
+
else
|
39
|
+
va, vb = a[key.variable], b[key.variable]
|
40
|
+
|
41
|
+
# Return early if one side is nil. In this
|
42
|
+
# case ascending/descending is irrelevant!
|
43
|
+
return 1 if va.nil? || va.empty?
|
44
|
+
return -1 if vb.nil? || va.empty?
|
45
|
+
|
46
|
+
result = case CiteProc::Variable.types[key.variable]
|
47
|
+
when :names
|
48
|
+
node = CSL::Style::Name.new(key.name_options)
|
49
|
+
node.all_names_as_sort_order!
|
50
|
+
|
51
|
+
compare_items(*renderer.render_sort(va, vb, node, key))
|
52
|
+
|
53
|
+
when :date
|
54
|
+
va <=> vb
|
55
|
+
when :number
|
56
|
+
va <=> vb
|
57
|
+
else
|
58
|
+
compare_items(va, vb)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
result = -result unless key.ascending?
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
def compare_items(a, b)
|
67
|
+
if sort_case_sensitively?
|
68
|
+
a <=> b
|
69
|
+
else
|
70
|
+
a.to_s.downcase <=> b.to_s.downcase
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def sort_case_sensitively?
|
75
|
+
return false unless processor && processor.options
|
76
|
+
processor.options[:sort_case_sensitively]
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module CiteProc
|
6
|
+
module Ruby
|
7
|
+
|
8
|
+
describe 'The CiteProc-Ruby Engine' do
|
9
|
+
let(:cp) { CiteProc::Processor.new :style => 'apa', :format => 'text' }
|
10
|
+
let(:engine) { cp.engine }
|
11
|
+
|
12
|
+
it 'registers itself as "citeproc-ruby"' do
|
13
|
+
CiteProc::Engine.available.should include('citeproc-ruby')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'is the default engine' do
|
17
|
+
CiteProc::Engine.default.should equal(CiteProc::Ruby::Engine)
|
18
|
+
engine.should be_a(CiteProc::Ruby::Engine)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#bibliography' do
|
22
|
+
|
23
|
+
describe 'when there are no items in the processor' do
|
24
|
+
it 'returns an empty bibliography for any selector' do
|
25
|
+
cp.bibliography().should be_empty
|
26
|
+
cp.bibliography(:all => {}).should be_empty
|
27
|
+
cp.bibliography(:none => {}).should be_empty
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#render' do
|
34
|
+
|
35
|
+
describe 'when there are no items in the processor' do
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'when there are items in the processor' do
|
39
|
+
before(:each) do
|
40
|
+
cp << items(:grammatology).data
|
41
|
+
cp << items(:knuth1968).data
|
42
|
+
cp << items(:difference).data
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'renders the reference for the given id' do
|
46
|
+
cp.render(:bibliography, :id => 'grammatology').should == ['Derrida, J. (1976). Of Grammatology (corrected ed.). Baltimore: Johns Hopkins University Press.']
|
47
|
+
cp.render(:citation, :id => 'grammatology', :locator => '3-4').should == '(Derrida, 1976, pp. 3-4)'
|
48
|
+
cp.render(:bibliography, :id => 'knuth1968').should == ['Knuth, D. (1968). The art of computer programming (Vol. 1). Boston: Addison-Wesley.']
|
49
|
+
|
50
|
+
node = cp.engine.style.macros['author']
|
51
|
+
(node > 'names' > 'name')[:initialize] = 'false'
|
52
|
+
|
53
|
+
cp.engine.format = 'html'
|
54
|
+
cp.render(:bibliography, :id => 'knuth1968').should == ['Knuth, Donald. (1968). <i>The art of computer programming</i> (Vol. 1). Boston: Addison-Wesley.']
|
55
|
+
|
56
|
+
cp.render(:citation, :id => 'knuth1968', :locator => '23').should == '(Knuth, 1968, p. 23)'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'overrides locales if the processor option is set' do
|
60
|
+
cp.render(:bibliography, :id => 'difference').should == ['Derrida, J. (1967). L’écriture et la différence (1st ed.). Paris: Éditions du Seuil.']
|
61
|
+
|
62
|
+
cp.options[:allow_locale_overrides] = true
|
63
|
+
cp.render(:bibliography, :id => 'difference').should == ['Derrida, J. (1967). L’écriture et la différence (1ʳᵉ éd.). Paris: Éditions du Seuil.']
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#process' do
|
69
|
+
describe 'when there are no items in the processor' do
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'when there are items in the processor' do
|
73
|
+
before(:each) do
|
74
|
+
cp << items(:grammatology).data
|
75
|
+
cp << items(:knuth1968).data
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'renders the citation for the given id' do
|
79
|
+
cp.process(:id => 'knuth1968', :locator => '23').should == '(Knuth, 1968, p. 23)'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'combines and sorts multiple cite items' do
|
83
|
+
cp.process([
|
84
|
+
{:id => 'knuth1968', :locator => '23'},
|
85
|
+
{:id => 'grammatology', :locator => '11-14'}
|
86
|
+
]).should == '(Derrida, 1976, pp. 11-14; Knuth, 1968, p. 23)'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module CiteProc
|
6
|
+
module Ruby
|
7
|
+
|
8
|
+
describe 'Formats::Text#apply' do
|
9
|
+
let(:format) { Format.load 'text' }
|
10
|
+
let(:node) { CSL::Style::Text.new }
|
11
|
+
|
12
|
+
it 'returns an empty string if input is nil' do
|
13
|
+
format.apply(nil, node).should == ''
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'returns the string unchanged if empty' do
|
17
|
+
input = ''
|
18
|
+
format.apply(input, node).should be_equal(input)
|
19
|
+
input.should == ''
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns the string unchanged if node is nil' do
|
23
|
+
input = 'foo'
|
24
|
+
format.apply(input, nil).should be_equal(input)
|
25
|
+
input.should == 'foo'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'supports localized quotes' do
|
29
|
+
locale = double(:locale)
|
30
|
+
locale.stub(:punctuation_in_quotes?).and_return(true)
|
31
|
+
locale.stub(:quote).and_return('bar')
|
32
|
+
|
33
|
+
node[:quotes] = true
|
34
|
+
|
35
|
+
format.apply('foo', node, locale).should == 'bar'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'disregards localized closing quotes when squeezing affixes' do
|
39
|
+
locale = double(:locale)
|
40
|
+
locale.stub(:punctuation_in_quotes?).and_return(true)
|
41
|
+
locale.stub(:quote) { |t| '"' << t << '"' }
|
42
|
+
locale.stub(:t) { |t| t == 'close-quote' ? '"' : "'" }
|
43
|
+
|
44
|
+
node[:quotes] = true
|
45
|
+
node[:suffix] = '.'
|
46
|
+
|
47
|
+
format.apply('foo', node, locale).should == '"foo."'
|
48
|
+
format.apply("'foo'", node, locale).should == "\"'foo.'\""
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'text-case formats' do
|
52
|
+
it 'supports lowercase' do
|
53
|
+
node[:'text-case'] = 'lowercase'
|
54
|
+
format.apply('Foo BAR', node).should == 'foo bar'
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'supports lowercase for non-ascii letters' do
|
58
|
+
node[:'text-case'] = 'lowercase'
|
59
|
+
format.apply('SCHÖN!', node).should == 'schön!'
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'supports uppercase' do
|
63
|
+
node[:'text-case'] = 'uppercase'
|
64
|
+
format.apply('Foo BAR', node).should == 'FOO BAR'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'supports uppercase for non-ascii letters' do
|
68
|
+
node[:'text-case'] = 'uppercase'
|
69
|
+
format.apply('schön!', node).should == 'SCHÖN!'
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'does not alter the original string' do
|
73
|
+
node[:'text-case'] = 'lowercase'
|
74
|
+
input = 'fooBar'
|
75
|
+
|
76
|
+
format.apply(input, node).should == 'foobar'
|
77
|
+
input.should == 'fooBar'
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'supports capitalize-first' do
|
81
|
+
node[:'text-case'] = 'capitalize-first'
|
82
|
+
|
83
|
+
format.apply('foo bar', node).should == 'Foo bar'
|
84
|
+
format.apply('Foo bar', node).should == 'Foo bar'
|
85
|
+
format.apply('!foo bar', node).should == '!Foo bar'
|
86
|
+
format.apply('én foo bar', node).should == 'Én foo bar'
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'supports capitalize-all' do
|
90
|
+
node[:'text-case'] = 'capitalize-all'
|
91
|
+
|
92
|
+
format.apply('foo bar', node).should == 'Foo Bar'
|
93
|
+
format.apply('!foo bar', node).should == '!Foo Bar'
|
94
|
+
format.apply('én foo bar', node).should == 'Én Foo Bar'
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'supports sentence case' do
|
98
|
+
node[:'text-case'] = 'sentence'
|
99
|
+
|
100
|
+
format.apply('FOO bar', node).should == 'Foo bar'
|
101
|
+
format.apply('foo Bar BAR', node).should == 'Foo Bar Bar'
|
102
|
+
format.apply('én Foo bar', node).should == 'Én Foo bar'
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'supports title case' do
|
106
|
+
node[:'text-case'] = 'title'
|
107
|
+
|
108
|
+
format.apply('The adventures of Huckleberry Finn', node).should == 'The Adventures of Huckleberry Finn'
|
109
|
+
format.apply("This IS a pen that is a smith pencil", node).should == 'This IS a Pen That Is a Smith Pencil'
|
110
|
+
#format.apply('of mice and men', node).should == 'Of Mice And Men'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe 'strip-periods' do
|
115
|
+
before { node[:'strip-periods'] = true }
|
116
|
+
|
117
|
+
it 'strips all periods from the output' do
|
118
|
+
format.apply('hello there...! how.are.you?', node).should == 'hello there! howareyou?'
|
119
|
+
format.apply('foo bar!', node).should == 'foo bar!'
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'does not strip periods from affixes' do
|
123
|
+
node[:prefix] = '...('
|
124
|
+
node[:suffix] = ').'
|
125
|
+
|
126
|
+
format.apply('foo.bar.', node).should == '...(foobar).'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'affixes' do
|
131
|
+
it 'are added after text formats have been applied' do
|
132
|
+
node[:prefix] = 'foo'
|
133
|
+
node[:suffix] = 'ooo'
|
134
|
+
node[:'text-case'] = 'uppercase'
|
135
|
+
|
136
|
+
format.apply('ooo', node).should == 'fooOOOooo'
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'drop squeezable characters at start/end' do
|
140
|
+
node[:suffix] = ' '
|
141
|
+
|
142
|
+
format.apply('foo', node).should == 'foo '
|
143
|
+
format.apply('foo ', node).should == 'foo '
|
144
|
+
|
145
|
+
node[:suffix] = '. '
|
146
|
+
format.apply('foo', node).should == 'foo. '
|
147
|
+
format.apply('foo.', node).should == 'foo. '
|
148
|
+
format.apply('foo?', node).should == 'foo? '
|
149
|
+
|
150
|
+
node[:prefix] = '.'
|
151
|
+
format.apply('foo', node).should == '.foo. '
|
152
|
+
format.apply('.foo', node).should == '.foo. '
|
153
|
+
format.apply(',foo', node).should == '.,foo. '
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|