asciidoctor-bibliography 0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +17 -0
  4. data/Gemfile +1 -1
  5. data/Rakefile +3 -3
  6. data/asciidoctor-bibliography.gemspec +28 -26
  7. data/lib/asciidoctor-bibliography.rb +4 -1
  8. data/lib/asciidoctor-bibliography/asciidoctor.rb +3 -9
  9. data/lib/asciidoctor-bibliography/asciidoctor/bibliographer_preprocessor.rb +43 -15
  10. data/lib/asciidoctor-bibliography/asciidoctor/document_ext.rb +11 -0
  11. data/lib/asciidoctor-bibliography/bibliographer.rb +20 -9
  12. data/lib/asciidoctor-bibliography/citation.rb +74 -51
  13. data/lib/asciidoctor-bibliography/citation_item.rb +27 -0
  14. data/lib/asciidoctor-bibliography/database.rb +14 -7
  15. data/lib/asciidoctor-bibliography/databases/bibtex.rb +5 -4
  16. data/lib/asciidoctor-bibliography/exceptions.rb +5 -0
  17. data/lib/asciidoctor-bibliography/formatters/csl.rb +5 -0
  18. data/lib/asciidoctor-bibliography/formatters/tex.rb +20 -22
  19. data/lib/asciidoctor-bibliography/helpers.rb +3 -3
  20. data/lib/asciidoctor-bibliography/index.rb +21 -25
  21. data/lib/asciidoctor-bibliography/version.rb +1 -1
  22. data/samples/{biblio.bib → standard/biblio.bib} +0 -0
  23. data/samples/standard/sample-default.adoc +22 -0
  24. data/samples/standard/sample-default.html +476 -0
  25. data/samples/standard/sample-din.adoc +22 -0
  26. data/samples/standard/sample-din.html +476 -0
  27. data/samples/standard/sample-ieee.adoc +22 -0
  28. data/samples/standard/sample-ieee.html +476 -0
  29. data/samples/tex/biblio.bib +31 -0
  30. data/samples/{sample-authoryear.adoc → tex/sample-authoryear.adoc} +2 -3
  31. data/samples/{sample-authoryear.html → tex/sample-authoryear.html} +9 -6
  32. data/samples/tex/sample-din.adoc +74 -0
  33. data/samples/tex/sample-din.html +556 -0
  34. data/samples/{sample-numbers.adoc → tex/sample-numbers.adoc} +4 -0
  35. data/samples/{sample-numbers.html → tex/sample-numbers.html} +14 -8
  36. data/samples/tex/sample-ordering.adoc +20 -0
  37. data/samples/tex/sample-ordering.html +467 -0
  38. data/spec/citation_item_spec.rb +52 -0
  39. data/spec/database_spec.rb +39 -0
  40. data/spec/fixtures/database.bib +31 -0
  41. data/spec/fixtures/database.bibtex +6 -0
  42. data/spec/fixtures/database.unk +0 -0
  43. data/spec/throwaway_spec.rb +6 -0
  44. metadata +61 -25
  45. data/deprecated/asciidoctor-bibliography/asciidoctor/bibliographer_postprocessor.rb +0 -23
  46. data/deprecated/asciidoctor-bibliography/asciidoctor/bibliography_block_macro.rb +0 -77
  47. data/deprecated/asciidoctor-bibliography/asciidoctor/citation_processor.rb +0 -144
  48. data/deprecated/asciidoctor-bibliography/asciidoctor/cite_inline_macro.rb +0 -30
  49. data/deprecated/asciidoctor-bibliography/citationdata.rb +0 -23
  50. data/deprecated/asciidoctor-bibliography/citations.rb +0 -45
  51. data/deprecated/asciidoctor-bibliography/citationutils.rb +0 -67
  52. data/deprecated/asciidoctor-bibliography/extensions.rb +0 -64
  53. data/deprecated/asciidoctor-bibliography/filehandlers.rb +0 -32
  54. data/deprecated/asciidoctor-bibliography/index.rb +0 -31
  55. data/deprecated/asciidoctor-bibliography/processor.rb +0 -208
  56. data/deprecated/asciidoctor-bibliography/processorutils.rb +0 -34
  57. data/deprecated/asciidoctor-bibliography/styles.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24be1ddb4ec69d1ffabf68e2fc7cf1c628be6130
4
- data.tar.gz: b0abf289da6967d4da9e1aeb75acfadc3a4a5f24
3
+ metadata.gz: 6260e8b2da719aeb370dfe1946181cab10dadd35
4
+ data.tar.gz: f8e5f843bd9348f0333c1257b042578ce2f435b6
5
5
  SHA512:
6
- metadata.gz: a46db6e6d83b1faa86df2d69d521a7f1810e0f7bd53ee6abe339328c425aff40b7fe9f804c94fe6fb6d93a5afc19f241311e79caf333fce6fcc12cd5f4a610dc
7
- data.tar.gz: dc999d205e2c1d919489ba773eb37ea42253eb4b922e40a9abca0109e76ded8e8446cfe9276959ab92c1dffd8831fb81e610fa425a5910a8f2ae1919769ec52f
6
+ metadata.gz: 0cec621922c04cbefa6047adf59a648413c72253366172d2beda895708c6559ce52d79c07a13a71f20b573e04b3c6de69e0dc30c69ef07def99afc2689c3284b
7
+ data.tar.gz: a927d96b5e3c2725643ae0b20aea75147281d288de88d5dd578306c83559c2a27227217c4afb8e3639d7afa2fa4d8498365b6b142b3d8b976a5b9a44cd36e40e
data/.gitignore CHANGED
@@ -48,3 +48,6 @@ Gemfile.lock
48
48
 
49
49
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
50
  .rvmrc
51
+
52
+ **/.byebug
53
+ .byebug_history
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3
3
+ Excludes:
4
+ - deprecated/**/*.rb
5
+ - spec/**/*.rb
6
+
7
+ Metrics/LineLength:
8
+ Max: 120
9
+
10
+ FrozenStringLiteralComment:
11
+ Enabled: false
12
+
13
+ Style/FileName:
14
+ Enabled: false
15
+
16
+ Documentation:
17
+ Enabled: false
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
@@ -1,40 +1,42 @@
1
1
  # coding: utf-8
2
2
 
3
- lib = File.expand_path("../lib", __FILE__)
3
+ lib = File.expand_path('../lib', __FILE__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require "asciidoctor-bibliography/version"
5
+ require 'asciidoctor-bibliography/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = "asciidoctor-bibliography"
8
+ spec.name = 'asciidoctor-bibliography'
9
9
  spec.version = AsciidoctorBibliography::VERSION
10
- spec.authors = ["Ribose Inc."]
11
- spec.email = ["open.source@ribose.com"]
10
+ spec.authors = ['Ribose Inc.']
11
+ spec.email = ['open.source@ribose.com']
12
12
 
13
- spec.summary = "Bibliographic references for asciidoc"
14
- spec.description = <<-END
15
- asciidoctor-bibliography adds bibliography support for asciidoc documents by introducing
16
- two new macros: `cite:[KEY]` and `bibliography::[]`. Citations are parsed and
17
- replaced with formatted inline texts, and reference lists are automatically
18
- generated and inserted into where `bibliography::[]` is placed. The
19
- references are formatted using styles provided by CSL.
13
+ spec.summary = 'Bibliographic references for asciidoc'
14
+ spec.description = <<~END
15
+ asciidoctor-bibliography adds bibliography support for asciidoc documents by introducing
16
+ two new macros: `cite:[KEY]` and `bibliography::[]`. Citations are parsed and
17
+ replaced with formatted inline texts, and reference lists are automatically
18
+ generated and inserted into where `bibliography::[]` is placed. The
19
+ references are formatted using styles provided by CSL.
20
20
  END
21
- spec.homepage = "https://github.com/riboseinc/asciidoctor-bibliography"
22
- spec.license = "MIT"
21
+ spec.homepage = 'https://github.com/riboseinc/asciidoctor-bibliography'
22
+ spec.license = 'MIT'
23
23
 
24
- spec.require_paths = ["lib"]
24
+ spec.require_paths = ['lib']
25
25
  spec.files = `git ls-files`.split("\n")
26
26
  spec.test_files = `git ls-files -- {spec}/*`.split("\n")
27
- spec.required_ruby_version = Gem::Requirement.new(">= 2.0.0")
27
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
28
28
 
29
- spec.add_dependency "asciidoctor"
30
- spec.add_dependency "citeproc-ruby"
31
- spec.add_dependency "csl-styles", "~> 1"
32
- spec.add_dependency "latex-decode", "~> 0.2"
33
- spec.add_dependency "bibtex-ruby"
29
+ spec.add_dependency 'asciidoctor'
30
+ spec.add_dependency 'citeproc-ruby'
31
+ spec.add_dependency 'csl-styles', '~> 1'
32
+ spec.add_dependency 'latex-decode', '~> 0.2'
33
+ spec.add_dependency 'bibtex-ruby'
34
34
 
35
- spec.add_development_dependency "bundler", "~> 1.14"
36
- spec.add_development_dependency "byebug"
37
- spec.add_development_dependency "rspec"
38
- spec.add_development_dependency "rake"
39
- spec.add_development_dependency "simplecov"
35
+ spec.add_development_dependency 'bundler'
36
+ spec.add_development_dependency 'byebug'
37
+ spec.add_development_dependency 'rspec'
38
+ spec.add_development_dependency 'rake'
39
+ spec.add_development_dependency 'simplecov'
40
+ spec.add_development_dependency 'yard'
41
+ spec.add_development_dependency 'rubocop'
40
42
  end
@@ -1,3 +1,6 @@
1
- # require 'byebug' if Gem.gem("byebug")
1
+ begin
2
+ require 'byebug'
3
+ rescue LoadError
4
+ end
2
5
 
3
6
  require_relative 'asciidoctor-bibliography/asciidoctor'
@@ -1,17 +1,11 @@
1
1
  require 'asciidoctor/extensions'
2
2
 
3
3
  require_relative 'asciidoctor/bibliographer_preprocessor'
4
+ require_relative 'asciidoctor/document_ext'
4
5
  require_relative 'bibliographer'
5
6
 
7
+ Asciidoctor::Document.include AsciidoctorBibliography::Asciidoctor::DocumentExt
8
+
6
9
  Asciidoctor::Extensions.register do
7
10
  preprocessor AsciidoctorBibliography::Asciidoctor::BibliographerPreprocessor
8
11
  end
9
-
10
- module Asciidoctor
11
- class Document
12
- # All our document-level permanence passes through this attribute accessor.
13
- def bibliographer
14
- @bibliographer ||= AsciidoctorBibliography::Bibliographer.new
15
- end
16
- end
17
- end
@@ -1,8 +1,7 @@
1
1
  require 'asciidoctor'
2
+ require 'pp'
2
3
 
3
4
  require_relative '../helpers'
4
- require_relative '../formatters/csl'
5
- require_relative '../formatters/tex'
6
5
  require_relative '../database'
7
6
  require_relative '../citation'
8
7
  require_relative '../index'
@@ -10,15 +9,16 @@ require_relative '../index'
10
9
  module AsciidoctorBibliography
11
10
  module Asciidoctor
12
11
  class BibliographerPreprocessor < ::Asciidoctor::Extensions::Preprocessor
13
- def process document, reader
12
+ def process(document, reader)
14
13
  set_bibliographer_options(document, reader)
15
14
 
16
- # We're handling single database/formatters; generalization will be straightforward when needed.
15
+ if document.bibliographer.options['database'].nil?
16
+ warn "No bibliographic database was provided: all bibliographic macros will be ignored. You can set it using the 'bibliography-database' option in the document's preamble."
17
+ return reader
18
+ end
19
+
20
+ # Load database(s).
17
21
  document.bibliographer.database = Database.new(document.bibliographer.options['database'])
18
- document.bibliographer.index_formatter = Formatters::CSL.new(document.bibliographer.options['reference-style'])
19
- document.bibliographer.index_formatter.import document.bibliographer.database
20
- document.bibliographer.citation_formatter = Formatters::TeX.new(document.bibliographer.options['citation-style'])
21
- document.bibliographer.citation_formatter.import document.bibliographer.database
22
22
 
23
23
  # Find, store and replace citations with uuids.
24
24
  processed_lines = reader.read_lines.map do |line|
@@ -31,6 +31,7 @@ module AsciidoctorBibliography
31
31
  reader = ::Asciidoctor::Reader.new processed_lines
32
32
 
33
33
  # NOTE: retrieval and formatting are separated to allow sorting and numeric styles.
34
+ # document.bibliographer.sort
34
35
 
35
36
  # Find and replace uuids with formatted citations.
36
37
  processed_lines = reader.lines.join("\n") # for quicker matching
@@ -40,7 +41,6 @@ module AsciidoctorBibliography
40
41
  end
41
42
  end
42
43
  processed_lines = processed_lines.lines.map(&:chomp)
43
-
44
44
  reader = ::Asciidoctor::Reader.new processed_lines
45
45
 
46
46
  # Find and format indices.
@@ -53,19 +53,47 @@ module AsciidoctorBibliography
53
53
  end
54
54
  end
55
55
  processed_lines.flatten!
56
- reader = ::Asciidoctor::Reader.new processed_lines
56
+ ::Asciidoctor::Reader.new processed_lines
57
57
  end
58
58
 
59
59
  private
60
60
 
61
+ OPTIONS_PREFIX = 'bibliography-'.freeze
62
+
63
+ OPTIONS_DEFAULTS = {
64
+ 'order' => 'alphabetical',
65
+ 'reference-style' => 'apa',
66
+ 'citation-style' => 'authoryear',
67
+ 'hyperlinks' => 'true',
68
+ 'database' => nil
69
+ }.freeze
70
+
61
71
  def set_bibliographer_options(document, reader)
62
72
  # We peek at the document attributes we need, without perturbing the parsing flow.
63
73
  # NOTE: we're in a preprocessor and they haven't been parsed yet; doing it manually.
64
- document_attributes =
65
- ::Asciidoctor::Parser
66
- .parse(reader, ::Asciidoctor::Document.new, header_only: true)
67
- .attributes
68
- document.bibliographer.options = Hash[Helpers.slice(document_attributes, 'bibliography-citation-style', 'bibliography-order', 'bibliography-reference-style', 'bibliography-database').map {|k, v| [k.sub(/^bibliography-/, ''), v] }]
74
+ # pp reader
75
+ header_attributes = extract_header_attributes reader
76
+ user_options = filter_bibliography_attributes header_attributes
77
+ document.bibliographer.options = OPTIONS_DEFAULTS.merge user_options
78
+ end
79
+
80
+ def extract_header_attributes(reader)
81
+ tdoc = ::Asciidoctor::Document.new
82
+ treader = ::Asciidoctor::PreprocessorReader.new(
83
+ tdoc,
84
+ reader.source_lines
85
+ )
86
+
87
+ ::Asciidoctor::Parser
88
+ .parse(treader, tdoc, header_only: true)
89
+ .attributes
90
+ end
91
+
92
+ def filter_bibliography_attributes(hash)
93
+ Helpers
94
+ .slice(hash, *OPTIONS_DEFAULTS.keys.map { |k| "#{OPTIONS_PREFIX}#{k}" })
95
+ .map { |k, v| [k[OPTIONS_PREFIX.length..-1], v] }.to_h
96
+ .reject { |_, value| value.nil? || value.empty? }.to_h
69
97
  end
70
98
  end
71
99
  end
@@ -0,0 +1,11 @@
1
+ # Extends Document to support additional method
2
+ module AsciidoctorBibliography
3
+ module Asciidoctor
4
+ module DocumentExt
5
+ # All our document-level permanence passes through this accessor.
6
+ def bibliographer
7
+ @bibliographer ||= AsciidoctorBibliography::Bibliographer.new
8
+ end
9
+ end
10
+ end
11
+ end
@@ -3,29 +3,40 @@ module AsciidoctorBibliography
3
3
  attr_accessor :citations
4
4
  attr_accessor :indices
5
5
  attr_accessor :database
6
- attr_accessor :index_formatter
7
- attr_accessor :citation_formatter
8
6
  attr_reader :occurring_keys
9
7
  attr_accessor :options
10
8
 
11
- # NOTE: while database and formatter are singular, they're meant for future generalization.
12
-
13
9
  def initialize
14
10
  @options = {}
15
11
  @citations = []
16
12
  @indices = []
17
13
  @database = nil
18
- @index_formatter = nil
19
- @citation_formatter = nil
20
14
  @occurring_keys = []
21
15
  end
22
16
 
23
17
  def add_citation(citation)
24
18
  citations << citation
25
- @occurring_keys.concat(citation.keys).uniq!
26
- citations.last.cites.each do |cite|
27
- cite.occurrence_index = @occurring_keys.index(cite.key)
19
+ @occurring_keys.concat(citation.citation_items.map(&:key)).uniq!
20
+ end
21
+
22
+ def appearance_index_of(id)
23
+ @occurring_keys.index(id) + 1
24
+ end
25
+
26
+ def sort
27
+ if options['order'] == 'alphabetical'
28
+ @occurring_keys = @occurring_keys.sort_by do |target|
29
+ first_author_family_name(target)
30
+ end
28
31
  end
29
32
  end
33
+
34
+ private
35
+
36
+ def first_author_family_name(key)
37
+ authors = database.find { |h| h['id'] == key }['author']
38
+ return '' if authors.nil?
39
+ authors.map { |h| h['family'] }.compact.first # TODO: is the first also alphabetically the first?
40
+ end
30
41
  end
31
42
  end
@@ -1,83 +1,106 @@
1
1
  require 'securerandom'
2
- require 'asciidoctor/attribute_list'
2
+ require_relative 'formatters/csl'
3
+ require_relative 'formatters/tex'
4
+ require_relative 'citation_item'
3
5
 
4
6
  module AsciidoctorBibliography
5
7
  class Citation
6
8
  TEX_MACROS_NAMES = Formatters::TeX::MACROS.keys.map { |s| Regexp.escape s }.concat(['fullcite']).join('|')
7
9
  REGEXP = /\\?(#{TEX_MACROS_NAMES}):(?:(\S*?)?\[(|.*?[^\\])\])(?:\+(\S*?)?\[(|.*?[^\\])\])*/
8
- REF_ATTRIBUTES = %i[chapter page section clause]
10
+ REF_ATTRIBUTES = %i[chapter page section clause].freeze
9
11
 
10
- # No need for a fully fledged class right now.
11
- Cite = Struct.new(:key, :occurrence_index, :target, :positional_attributes, :named_attributes)
12
+ attr_reader :macro, :citation_items
12
13
 
13
- attr_reader :macro, :cites
14
-
15
- def initialize(macro, *targets_and_attributes_list)
14
+ def initialize(macro, *target_and_attributes_list_pairs)
16
15
  @uuid = SecureRandom.uuid
17
16
  @macro = macro
18
- @cites = []
19
- targets_and_attributes_list.compact.each_slice(2).each do |target, attributes|
20
- positional_attributes, named_attributes = # true, false
21
- ::Asciidoctor::AttributeList.new(attributes).parse
22
- .group_by { |hash_key, _| hash_key.is_a? Integer }
23
- .values.map { |a| Hash[a] }
24
- positional_attributes = positional_attributes.values
25
- @cites << Cite.new(
26
- positional_attributes.first,
27
- nil,
28
- target,
29
- positional_attributes,
30
- named_attributes
31
- )
17
+ @citation_items = []
18
+ target_and_attributes_list_pairs.compact.each_slice(2).each do |_target, attribute_list|
19
+ @citation_items << CitationItem.new do |cite|
20
+ # NOTE: we're not doing anything with targets right now.
21
+ # cite.target = _target
22
+ cite.parse_attribute_list attribute_list
23
+ end
32
24
  end
33
25
  end
34
26
 
35
27
  def render(bibliographer)
36
- if macro == 'fullcite'
37
- formatter = Formatters::CSL.new(bibliographer.options['reference-style'])
38
-
39
- # NOTE: being able to overwrite a more general family of attributes would be neat.
40
- mergeable_attributes = Helpers.slice(cites.first.named_attributes || {}, *(REF_ATTRIBUTES.map(&:to_s)))
41
-
42
- # reject empty values
43
- mergeable_attributes.reject! do |key, value|
44
- value.nil? || value.empty?
45
- end
46
- # TODO: as is, cites other than the first are simply ignored.
47
- database_entry = bibliographer.database.find { |e| e['id'] == cites.first.key }
48
- database_entry.merge!(mergeable_attributes)
49
- formatter.import([database_entry])
50
- '{empty}' + Helpers.html_to_asciidoc(formatter.render(:bibliography, id: cites.first.key).join)
28
+ if macro == 'cite'
29
+ render_citation_with_csl(bibliographer)
30
+ elsif macro == 'fullcite'
31
+ render_fullcite_with_csl(bibliographer)
51
32
  elsif Formatters::TeX::MACROS.keys.include? macro
52
- bibliographer.citation_formatter.render(self)
33
+ formatter = Formatters::TeX.new(bibliographer.options['citation-style'])
34
+ formatter.import bibliographer.database
35
+ formatter.render(bibliographer, self)
53
36
  end
54
37
  end
55
38
 
56
- def uuid
57
- ":#{@uuid}:"
39
+ def render_citation_with_csl(bibliographer)
40
+ formatter = Formatters::CSL.new(bibliographer.options['reference-style'])
41
+
42
+ cites_with_local_attributes = citation_items.map { |cite| prepare_cite_metadata bibliographer, cite }
43
+ formatter.import cites_with_local_attributes
44
+ formatter.sort(mode: :citation)
45
+ items = formatter.data.map(&:cite)
46
+ items.each { |item| prepare_citation_item item, hyperlink: bibliographer.options['hyperlinks'] == 'true' }
47
+
48
+ formatted_citation = formatter.engine.renderer.render(items, formatter.engine.style.citation)
49
+ # We prepend an empty interpolation to avoid interferences w/ standard syntax (e.g. block role is "\n[foo]")
50
+ '{empty}' + formatted_citation.gsub(/{{{(?<xref_label>.*?)}}}/) do
51
+ # We escape closing square brackets inside the xref label.
52
+ ['[', Regexp.last_match[:xref_label].gsub(']', '\]'), ']'].join
53
+ end
58
54
  end
59
55
 
60
- def keys
61
- @cites.map { |h| h[:key] }
56
+ def prepare_cite_metadata(bibliographer, cite)
57
+ bibliographer.database.find { |e| e['id'] == cite.key }
58
+ .merge('citation-number': bibliographer.appearance_index_of(cite.key))
59
+ .merge('citation-label': cite.key) # TODO: smart label generators
60
+ .merge('locator': cite.locators.any? ? ' ' : nil)
61
+ # TODO: why is 'locator' necessary to display locators? (and not just in the item, later)
62
62
  end
63
63
 
64
- def xref(key, label)
65
- "xref:#{self.render_id(key)}[#{label.gsub(']','\]')}]"
64
+ def prepare_citation_item(item, hyperlink:)
65
+ # Wrap into hyperlink
66
+ if hyperlink
67
+ item.prefix = "xref:#{xref_id(item.id)}{{{" + item.prefix.to_s
68
+ item.suffix = item.suffix.to_s + '}}}'
69
+ end
70
+ # Assign locator
71
+ locator = citation_items.find { |cite| cite.key == item.id }.locators.first
72
+ item.label, item.locator = locator unless locator.nil?
73
+ # TODO: suppress_author and only_author options?
66
74
  end
67
75
 
68
- def render_id(key)
69
- ['bibliography', key].compact.join('-')
76
+ def render_fullcite_with_csl(bibliographer)
77
+ formatter = Formatters::CSL.new(bibliographer.options['reference-style'])
78
+
79
+ # NOTE: being able to overwrite a more general family of attributes would be neat.
80
+ mergeable_attributes = Helpers.slice(citation_items.first.named_attributes || {}, *REF_ATTRIBUTES.map(&:to_s))
81
+
82
+ # reject empty values
83
+ mergeable_attributes.reject! do |_key, value|
84
+ value.nil? || value.empty?
85
+ end
86
+ # TODO: as is, citation items other than the first are simply ignored.
87
+ database_entry = bibliographer.database.find { |e| e['id'] == citation_items.first.key }
88
+ database_entry.merge!(mergeable_attributes)
89
+ formatter.import([database_entry])
90
+ '{empty}' + Helpers.html_to_asciidoc(formatter.render(:bibliography, id: citation_items.first.key).join)
91
+ # '{empty}' + Helpers.html_to_asciidoc(formatter.render(:citation, id: citation_items.first.key))
70
92
  end
71
93
 
72
- private
94
+ def uuid
95
+ ":#{@uuid}:"
96
+ end
73
97
 
74
- def render_label(formatter, key)
75
- formatter.render(:citation, id: key)
98
+ def xref_id(key)
99
+ ['bibliography', key].compact.join('-')
76
100
  end
77
101
 
78
- def render_xref(formatter, key)
79
- "xref:#{render_id(key)}[#{render_label(formatter, key)}]"
102
+ def xref(key, label)
103
+ "xref:#{xref_id(key)}[#{label.gsub(']', '\]')}]"
80
104
  end
81
105
  end
82
106
  end
83
-