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