asciidoctor-bibliography 0.3.0 → 0.4.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +23 -4
  3. data/asciidoctor-bibliography.gemspec +8 -8
  4. data/lib/asciidoctor-bibliography.rb +6 -0
  5. data/lib/asciidoctor-bibliography/asciidoctor/bibliographer_preprocessor.rb +35 -23
  6. data/lib/asciidoctor-bibliography/bibliographer.rb +0 -15
  7. data/lib/asciidoctor-bibliography/citation.rb +29 -22
  8. data/lib/asciidoctor-bibliography/databases/bibtex.rb +4 -1
  9. data/lib/asciidoctor-bibliography/formatter.rb +28 -0
  10. data/lib/asciidoctor-bibliography/index.rb +24 -16
  11. data/lib/asciidoctor-bibliography/options.rb +65 -32
  12. data/lib/asciidoctor-bibliography/version.rb +1 -1
  13. data/lib/citeproc/ruby/formats/adoc.rb +36 -0
  14. data/lib/csl/styles/tex-citealp-authoryear.csl +117 -0
  15. data/lib/csl/styles/tex-citealp-numeric.csl +116 -0
  16. data/lib/csl/styles/tex-citealps-authoryear.csl +117 -0
  17. data/lib/csl/styles/tex-citealps-numeric.csl +116 -0
  18. data/lib/csl/styles/tex-citealt-authoryear.csl +119 -0
  19. data/lib/csl/styles/tex-citealt-numeric.csl +119 -0
  20. data/lib/csl/styles/tex-citealts-authoryear.csl +119 -0
  21. data/lib/csl/styles/tex-citealts-numeric.csl +119 -0
  22. data/lib/csl/styles/tex-citeauthor-authoryear.csl +116 -0
  23. data/lib/csl/styles/tex-citeauthor-numeric.csl +116 -0
  24. data/lib/csl/styles/tex-citeauthors-authoryear.csl +116 -0
  25. data/lib/csl/styles/tex-citeauthors-numeric.csl +116 -0
  26. data/lib/csl/styles/tex-citep-authoryear.csl +117 -0
  27. data/lib/csl/styles/tex-citep-numeric.csl +116 -0
  28. data/lib/csl/styles/tex-citeps-authoryear.csl +117 -0
  29. data/lib/csl/styles/tex-citeps-numeric.csl +116 -0
  30. data/lib/csl/styles/tex-citet-authoryear.csl +119 -0
  31. data/lib/csl/styles/tex-citet-numeric.csl +119 -0
  32. data/lib/csl/styles/tex-citets-authoryear.csl +119 -0
  33. data/lib/csl/styles/tex-citets-numeric.csl +119 -0
  34. data/lib/csl/styles/tex-citeyear-authoryear.csl +116 -0
  35. data/lib/csl/styles/tex-citeyear-numeric.csl +116 -0
  36. data/lib/csl/styles/tex-citeyearpar-authoryear.csl +116 -0
  37. data/lib/csl/styles/tex-citeyearpar-numeric.csl +116 -0
  38. data/samples/tex/sample-numbers.adoc +1 -1
  39. data/samples/tex/sample-sort.adoc +1 -1
  40. data/spec/citation_helper.rb +46 -0
  41. data/spec/citation_item_spec.rb +0 -2
  42. data/spec/csl/styles/tex_citealp_authoryear_spec.rb +42 -0
  43. data/spec/csl/styles/tex_citealp_numeric_spec.rb +42 -0
  44. data/spec/csl/styles/tex_citealps_authoryear_spec.rb +42 -0
  45. data/spec/csl/styles/tex_citealps_numeric_spec.rb +42 -0
  46. data/spec/csl/styles/tex_citealt_authoryear_spec.rb +42 -0
  47. data/spec/csl/styles/tex_citealt_numeric_spec.rb +42 -0
  48. data/spec/csl/styles/tex_citealts_authoryear_spec.rb +42 -0
  49. data/spec/csl/styles/tex_citealts_numeric_spec.rb +42 -0
  50. data/spec/csl/styles/tex_citeauthor_authoryear_spec.rb +42 -0
  51. data/spec/csl/styles/tex_citeauthor_numeric_spec.rb +42 -0
  52. data/spec/csl/styles/tex_citeauthors_authoryear_spec.rb +42 -0
  53. data/spec/csl/styles/tex_citeauthors_numeric_spec.rb +42 -0
  54. data/spec/csl/styles/tex_citep_authoryear_spec.rb +42 -0
  55. data/spec/csl/styles/tex_citep_numeric_spec.rb +42 -0
  56. data/spec/csl/styles/tex_citeps_authoryear_spec.rb +42 -0
  57. data/spec/csl/styles/tex_citeps_numeric_spec.rb +42 -0
  58. data/spec/csl/styles/tex_citet_authoryear_spec.rb +42 -0
  59. data/spec/csl/styles/tex_citet_numeric_spec.rb +42 -0
  60. data/spec/csl/styles/tex_citets_authoryear_spec.rb +42 -0
  61. data/spec/csl/styles/tex_citets_numeric_spec.rb +42 -0
  62. data/spec/csl/styles/tex_citeyear_authoryear_spec.rb +42 -0
  63. data/spec/csl/styles/tex_citeyear_numeric_spec.rb +42 -0
  64. data/spec/csl/styles/tex_citeyearpar_authoryear_spec.rb +42 -0
  65. data/spec/csl/styles/tex_citeyearpar_numeric_spec.rb +42 -0
  66. data/spec/database_spec.rb +20 -1
  67. data/spec/macros_spec.rb +21 -0
  68. data/spec/options_spec.rb +105 -1
  69. metadata +72 -24
  70. data/lib/asciidoctor-bibliography/formatters/csl.rb +0 -28
  71. data/lib/asciidoctor-bibliography/formatters/tex.rb +0 -187
  72. data/lib/asciidoctor-bibliography/helpers.rb +0 -41
  73. data/spec/helpers_spec.rb +0 -73
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 60349740c0d584e5373c9f81c67d97a938eb1f87
4
- data.tar.gz: 50fd0f1d8577a54664f9a8e9efdecdb268809edc
3
+ metadata.gz: ec220969b63ad6811daffac07fbf41eaec5a382d
4
+ data.tar.gz: '089f60f0d33c8737b6308b7ab7a494dae7b93803'
5
5
  SHA512:
6
- metadata.gz: cfab5b8627b11ccd161641fc0ff126a30bfc080fbf75e8740aa4341732a205c31992b237f53e67f1d544dbc32f5612a79dfdf717f438c2c966b940f94e3683c2
7
- data.tar.gz: 2f19a9de392c561bf9ad961271b174db27639bdb98ce1c02dcaf1df22f6e2687ae2bd0c4b4311f23018203a6effc4aac96ea4e7ab5b9fd2bafc808d7399d672a
6
+ metadata.gz: 8697d604dd13e6aa72fb652b6e8c61a1bbeef82ab4240d2de96fc0e15d02343646e9494e119baad65269a3802c5b32078e8c233aad864cb707d9943173704d0d
7
+ data.tar.gz: 69704a0dc0dbd0a99142adc00752b904ad5a082baadd755f03b8e49a3b4871e49fdd7fc14bf88011f6eb6e723909791f9b1c986fff1b00e4a5800bb39fcf5964
@@ -16,7 +16,7 @@ Citation styling leverages the popular http://citationstyles.org/[CSL] language
16
16
  so you have direct access to thousands of crowdsourced styles including IEEE,
17
17
  APA, Chicago, DIN and ISO 690.
18
18
 
19
- The `bibliography:[]` command generates a full reference list that adheres to
19
+ The `bibliography::[]` command generates a full reference list that adheres to
20
20
  your configured citation style.
21
21
 
22
22
  On top of that you also have a formatter derived from the `Bib(La)TeX` world,
@@ -28,7 +28,7 @@ Its syntax is designed to be "`native-asciidoctor`":
28
28
  * contextual cite `cite[key, page=3]`;
29
29
  * multiple cites `cite:[key1]+[key2]`;
30
30
  * full cite `fullcite:[key]`; and
31
- * TeX-compatible macros including `citep:[key]`, `citet:[]key` and friends.
31
+ * TeX-compatible macros including `citep:[key]`, `citet:[key]` and friends.
32
32
 
33
33
 
34
34
  == Installation
@@ -180,6 +180,18 @@ or searching through the friendly http://editor.citationstyles.org/[style editor
180
180
  You can also simply use the filename of a CSL file on your machine if you need more customization.
181
181
 
182
182
 
183
+ === Localization
184
+
185
+ Citation styles can be localized using the following option:
186
+
187
+ [source,asciidoc]
188
+ ----
189
+ :bibliography-locale: en-US
190
+ ----
191
+
192
+ The default is `en-US`. Here is an exhaustive list of recognized locales: `af-ZA`, `ar`, `bg-BG`, `ca-AD`, `cs-CZ`, `cy-GB`, `da-DK`, `de-AT`, `de-CH`, `de-DE`, `el-GR`, `en-GB`, `en-US`, `es-CL`, `es-ES`, `es-MX`, `et-EE`, `eu`, `fa-IR`, `fi-FI`, `fr-CA`, `fr-FR`, `he-IL`, `hr-HR`, `hu-HU`, `id-ID`, `is-IS`, `it-IT`, `ja-JP`, `km-KH`, `ko-KR`, `lt-LT`, `lv-LV`, `mn-MN`, `nb-NO`, `nl-NL`, `nn-NO`, `pl-PL`, `pt-BR`, `pt-PT`, `ro-RO`, `ru-RU`, `sk-SK`, `sl-SI`, `sr-RS`, `sv-SE`, `th-TH`, `tr-TR`, `uk-UA`, `vi-VN`, `zh-CN` and `zh-TW`.
193
+
194
+
183
195
  === Hyperlinks
184
196
 
185
197
  By default, citations include hyperlinks to their entry in the bibliography.
@@ -250,7 +262,7 @@ To use them effectively you'll need to know its implementation.
250
262
 
251
263
  This task is not daunting at all, as the http://editor.citationstyles.org/[style editor] allows you to quickly list them and understand their role.
252
264
 
253
- As for the `sort` option, the valid values are `ascending` (default) and `descending` as you'd exect.
265
+ As for the `sort` option, the valid values are `ascending` (default) and `descending` as you'd expect.
254
266
 
255
267
 
256
268
  === TeX-mode
@@ -267,12 +279,17 @@ While the `cite` macro is reserved for CSL styling, all traditional Bib(La)TeX m
267
279
  * `citealp*`
268
280
  * `citeauthor`
269
281
  * `citeauthor*`
270
- * `citeyear` and `citeyearpar`.
282
+ * `citeyear`
283
+ * `citeyearpar`
271
284
 
272
285
  NOTE: no macros are missing since `\cite` is equivalent to `\citet`!
273
286
 
274
287
  To cite multiple items you can concatenate them just like with `cite`.
275
288
 
289
+ All macros accept standard locators, `locator`, `suffix` and `prefix`.
290
+ The behaviour of these parameters is designed to reproduce the one expected
291
+ from the traditional `TeX` citation macros `\cite...[prefix][suffix]{key}`.
292
+
276
293
  You can set their style in the header:
277
294
 
278
295
  [source,asciidoc]
@@ -282,6 +299,8 @@ You can set their style in the header:
282
299
 
283
300
  Accepted values are `authoryear` (default) and `numeric`.
284
301
 
302
+ Furthermore, `fullcite` is also available and accepts no parameters except a single reference key.
303
+
285
304
  == Development
286
305
 
287
306
  We follow Sandi Metz's Rules for this gem, you can read the
@@ -4,7 +4,7 @@ lib = File.expand_path("../lib", __FILE__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require "asciidoctor-bibliography/version"
6
6
 
7
- Gem::Specification.new do |spec|
7
+ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
8
8
  spec.name = "asciidoctor-bibliography"
9
9
  spec.version = AsciidoctorBibliography::VERSION
10
10
  spec.authors = ["Ribose Inc."]
@@ -19,11 +19,11 @@ Gem::Specification.new do |spec|
19
19
  * contextual cite `cite[key, page=3]`;
20
20
  * multiple cites `cite:[key1]+[key2]`;
21
21
  * full cite `fullcite:[key]`; and
22
- * TeX-compatible macros including `citep:[key]`, `citet:[]key` and friends.
22
+ * TeX-compatible macros including `citep:[key]`, `citet:[key]` and friends.
23
23
 
24
24
  Citation output styles are fully bridged to the CSL library, supporting formats such as IEEE, APA, Chicago, DIN and ISO 690.
25
25
 
26
- The `bibliography:[]` command generates a full reference list that adheres to your configured citation style.
26
+ The `bibliography::[]` command generates a full reference list that adheres to your configured citation style.
27
27
  END
28
28
  spec.homepage = "https://github.com/riboseinc/asciidoctor-bibliography"
29
29
  spec.license = "MIT"
@@ -33,11 +33,11 @@ END
33
33
  spec.test_files = `git ls-files -- {spec}/*`.split("\n")
34
34
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
35
35
 
36
- spec.add_dependency "asciidoctor"
37
- spec.add_dependency "citeproc-ruby"
38
- spec.add_dependency "csl-styles", "~> 1"
39
- spec.add_dependency "latex-decode", "~> 0.2"
40
- spec.add_dependency "bibtex-ruby"
36
+ spec.add_dependency "asciidoctor", "~> 1.5.6"
37
+ spec.add_dependency "citeproc-ruby", "~> 1.1.7"
38
+ spec.add_dependency "csl-styles", "~> 1.0.1"
39
+ spec.add_dependency "latex-decode", "~> 0.2.2"
40
+ spec.add_dependency "bibtex-ruby", "~> 4.4.4"
41
41
 
42
42
  spec.add_development_dependency "bundler"
43
43
  spec.add_development_dependency "byebug"
@@ -4,3 +4,9 @@ rescue LoadError
4
4
  end
5
5
 
6
6
  require_relative "asciidoctor-bibliography/asciidoctor"
7
+
8
+ module AsciidoctorBibliography
9
+ def self.root
10
+ File.dirname __dir__
11
+ end
12
+ end
@@ -1,6 +1,5 @@
1
1
  require "asciidoctor"
2
2
 
3
- require_relative "../helpers"
4
3
  require_relative "../database"
5
4
  require_relative "../citation"
6
5
  require_relative "../index"
@@ -13,40 +12,53 @@ module AsciidoctorBibliography
13
12
  document.bibliographer.options =
14
13
  ::AsciidoctorBibliography::Options.new_from_reader reader
15
14
 
16
- # Load database(s).
17
- document.bibliographer.database = Database.new(document.bibliographer.options.database)
15
+ document.bibliographer.database =
16
+ ::AsciidoctorBibliography::Database.new document.bibliographer.options.database
18
17
 
19
- # Find, store and replace citations with uuids.
20
- processed_lines = reader.read_lines.map do |line|
21
- line.gsub(Citation::REGEXP) do
22
- citation = Citation.new(*Regexp.last_match.captures)
23
- document.bibliographer.add_citation(citation)
24
- citation.uuid
25
- end
26
- end
18
+ process_reader reader, document.bibliographer
19
+ end
20
+
21
+ private
22
+
23
+ def process_reader(reader, bibliographer)
24
+ # First we fetch citations and replace them with uuids,
25
+ processed_lines = fetch_citations reader.lines, bibliographer
26
+ reader = ::Asciidoctor::Reader.new processed_lines
27
+ # then we render them
28
+ processed_lines = render_citations reader.lines, bibliographer
27
29
  reader = ::Asciidoctor::Reader.new processed_lines
30
+ # and finally we render indices.
31
+ processed_lines = render_indices reader.lines, bibliographer
32
+ ::Asciidoctor::Reader.new processed_lines
33
+ end
34
+
35
+ def fetch_citations(lines, bibliographer)
36
+ lines.join("\n").gsub!(Citation::REGEXP) do
37
+ citation = Citation.new(*Regexp.last_match.captures)
38
+ bibliographer.add_citation(citation)
39
+ citation.uuid
40
+ end.lines.map(&:chomp)
41
+ end
28
42
 
29
- # Find and replace uuids with formatted citations.
30
- processed_lines = reader.lines.join("\n") # for quicker matching
31
- document.bibliographer.citations.each do |citation|
43
+ def render_citations(lines, bibliographer)
44
+ processed_lines = lines.join("\n")
45
+ bibliographer.citations.each do |citation|
32
46
  processed_lines.sub!(citation.uuid) do
33
- citation.render document.bibliographer
47
+ citation.render bibliographer
34
48
  end
35
49
  end
36
- processed_lines = processed_lines.lines.map(&:chomp)
37
- reader = ::Asciidoctor::Reader.new processed_lines
50
+ processed_lines.lines.map(&:chomp)
51
+ end
38
52
 
39
- # Find and format indices.
40
- processed_lines = reader.read_lines.map do |line|
53
+ def render_indices(lines, bibliographer)
54
+ lines.map do |line|
41
55
  if line =~ Index::REGEXP
42
56
  index = Index.new(*Regexp.last_match.captures)
43
- index.render document.bibliographer
57
+ index.render bibliographer
44
58
  else
45
59
  line
46
60
  end
47
- end
48
- processed_lines.flatten!
49
- ::Asciidoctor::Reader.new processed_lines
61
+ end.flatten
50
62
  end
51
63
  end
52
64
  end
@@ -22,20 +22,5 @@ module AsciidoctorBibliography
22
22
  def appearance_index_of(id)
23
23
  @occurring_keys.index(id) + 1
24
24
  end
25
-
26
- def sort
27
- return unless options["order"] == "alphabetical"
28
- @occurring_keys = @occurring_keys.sort_by do |target|
29
- first_author_family_name(target)
30
- end
31
- end
32
-
33
- private
34
-
35
- def first_author_family_name(key)
36
- authors = database.find_entry_by_id(key)["author"]
37
- return "" if authors.nil?
38
- authors.map { |h| h["family"] }.compact.first # TODO: is the first also alphabetically the first?
39
- end
40
25
  end
41
26
  end
@@ -1,11 +1,15 @@
1
1
  require "securerandom"
2
- require_relative "formatters/csl"
3
- require_relative "formatters/tex"
2
+ require_relative "formatter"
4
3
  require_relative "citation_item"
5
4
 
5
+ require "csl/styles"
6
+
6
7
  module AsciidoctorBibliography
7
8
  class Citation
8
- MACRO_NAME_REGEXP = Formatters::TeX::MACROS.keys.concat(%w[cite fullcite]).
9
+ TEX_MACROS = %w[citet citet* citealt citealt* citep citep* citealp citealp*
10
+ citeauthor citeauthor* citeyear citeyearpar].freeze
11
+
12
+ MACRO_NAME_REGEXP = TEX_MACROS.dup.concat(%w[cite fullcite]).
9
13
  map { |s| Regexp.escape s }.join("|").freeze
10
14
  REGEXP = /\\?(#{MACRO_NAME_REGEXP}):(?:(\S*?)?\[(|.*?[^\\])\])(?:\+(\S*?)?\[(|.*?[^\\])\])*/
11
15
  REF_ATTRIBUTES = %i[chapter page section clause].freeze
@@ -31,18 +35,17 @@ module AsciidoctorBibliography
31
35
  render_citation_with_csl(bibliographer)
32
36
  when "fullcite"
33
37
  render_fullcite_with_csl(bibliographer)
34
- when *Formatters::TeX::MACROS.keys
35
- formatter = Formatters::TeX.new(bibliographer.options.tex_style)
36
- formatter.import bibliographer.database
37
- formatter.render bibliographer, self
38
+ when *TEX_MACROS
39
+ filename = ["tex", macro.tr("*", "s"), bibliographer.options.tex_style].join("-")
40
+ filepath = File.join AsciidoctorBibliography.root, "lib/csl/styles", filename
41
+ render_citation_with_csl(bibliographer, style: filepath, tex: true)
38
42
  end
39
43
  end
40
44
 
41
45
  def render_fullcite_with_csl(bibliographer)
42
- formatter = Formatters::CSL.new(bibliographer.options.style)
46
+ formatter = Formatter.new(bibliographer.options.style, locale: bibliographer.options.locale)
43
47
  prepare_fullcite_item bibliographer, formatter
44
48
  formatted_citation = formatter.render(:bibliography, id: citation_items.first.key).join
45
- formatted_citation = Helpers.html_to_asciidoc formatted_citation
46
49
  # We prepend an empty interpolation to avoid interferences w/ standard syntax (e.g. block role is "\n[foo]")
47
50
  "{empty}" + formatted_citation
48
51
  end
@@ -51,9 +54,9 @@ module AsciidoctorBibliography
51
54
  formatter.import([bibliographer.database.find_entry_by_id(citation_items.first.key)])
52
55
  end
53
56
 
54
- def render_citation_with_csl(bibliographer)
55
- formatter = Formatters::CSL.new(bibliographer.options.style)
56
- items = prepare_items bibliographer, formatter
57
+ def render_citation_with_csl(bibliographer, style: bibliographer.options.style, tex: false)
58
+ formatter = Formatter.new(style, locale: bibliographer.options.locale)
59
+ items = prepare_items bibliographer, formatter, tex: tex
57
60
  formatted_citation = formatter.engine.renderer.render(items, formatter.engine.style.citation)
58
61
  escape_brackets_inside_xref! formatted_citation
59
62
  # We prepend an empty interpolation to avoid interferences w/ standard syntax (e.g. block role is "\n[foo]")
@@ -66,25 +69,29 @@ module AsciidoctorBibliography
66
69
  end
67
70
  end
68
71
 
69
- def prepare_items(bibliographer, formatter)
70
- cites_with_local_attributes = citation_items.map { |cite| prepare_metadata bibliographer, cite }
72
+ def prepare_items(bibliographer, formatter, tex: false)
73
+ # NOTE: when we're using our custom TeX CSL styles prefix/suffix are used as
74
+ # varieables for metadata instead of as parameters for citations.
75
+ cites_with_local_attributes = citation_items.map { |cite| prepare_metadata bibliographer, cite, affix: tex }
71
76
  formatter.import cites_with_local_attributes
72
- formatter.sort(mode: :citation)
73
- formatter.data.map(&:cite).each { |item| prepare_item bibliographer.options, item }
77
+ formatter.force_sort!(mode: :citation)
78
+ formatter.data.map(&:cite).each { |item| prepare_item bibliographer.options, item, affix: !tex }
74
79
  end
75
80
 
76
- def prepare_metadata(bibliographer, cite)
81
+ def prepare_metadata(bibliographer, cite, affix: false)
77
82
  bibliographer.database.find_entry_by_id(cite.key).
78
- merge('citation-number': bibliographer.appearance_index_of(cite.key)).
79
- merge('citation-label': cite.key). # TODO: smart label generators
80
- merge('locator': cite.locator.nil? ? nil : " ")
83
+ merge 'citation-number': bibliographer.appearance_index_of(cite.key),
84
+ 'citation-label': cite.key, # TODO: smart label generators
85
+ 'locator': cite.locator.nil? ? nil : " ",
86
+ 'prefix': affix ? cite.prefix : nil,
87
+ 'suffix': affix ? cite.suffix : nil
81
88
  # TODO: why is a non blank 'locator' necessary to display locators set at a later stage?
82
89
  end
83
90
 
84
- def prepare_item(options, item)
91
+ def prepare_item(options, item, affix: true)
85
92
  # TODO: hyperlink, suppress_author and only_author options
86
93
  ci = citation_items.detect { |c| c.key == item.id }
87
- wrap_item item, ci.prefix, ci.suffix
94
+ wrap_item item, ci.prefix, ci.suffix if affix
88
95
  wrap_item item, "xref:#{xref_id(item.id)}{{{", "}}}" if options.hyperlinks?
89
96
  item.label, item.locator = ci.locator
90
97
  end
@@ -17,13 +17,15 @@ module AsciidoctorBibliography
17
17
  ::BibTeX.open(filename, filter: [LatexFilter]).to_citeproc
18
18
  end
19
19
 
20
+ # NOTE: the class below comes from asciidoctor-bibtex
21
+
20
22
  # This filter extends the original latex filter in bibtex-ruby to handle
21
23
  # unknown latex macros more gracefully. We could have used latex-decode
22
24
  # gem together with our custom replacement rules, but latex-decode eats up
23
25
  # all braces after it finishes all decoding. So we hack over the
24
26
  # LaTeX.decode function and insert our rules before `strip_braces`.
25
27
  class LatexFilter < ::BibTeX::Filter
26
- def apply(value)
28
+ def apply(value) # rubocop:disable Metrics/MethodLength; keep this a list, though!
27
29
  text = value.to_s
28
30
  LaTeX::Decode::Base.normalize(text)
29
31
  LaTeX::Decode::Maths.decode!(text)
@@ -32,6 +34,7 @@ module AsciidoctorBibliography
32
34
  LaTeX::Decode::Punctuation.decode!(text)
33
35
  LaTeX::Decode::Symbols.decode!(text)
34
36
  LaTeX::Decode::Greek.decode!(text)
37
+ # TODO: could we be doing something smarter with some macros, e.g. \url?
35
38
  text.gsub!(/\\url\{(.+?)\}/, ' \\1 ')
36
39
  text.gsub!(/\\\w+(?=\s+\w)/, "")
37
40
  text.gsub!(/\\\w+(?:\[.+?\])?\s*\{(.+?)\}/, '\\1')
@@ -0,0 +1,28 @@
1
+ require "citeproc"
2
+ require "csl/styles"
3
+ require "yaml"
4
+
5
+ require_relative "../citeproc/ruby/formats/adoc"
6
+
7
+ module AsciidoctorBibliography
8
+ class Formatter < ::CiteProc::Processor
9
+ def initialize(style, locale: "en-US")
10
+ super style: style, format: :adoc, locale: locale
11
+ end
12
+
13
+ def replace_bibliography_sort(array)
14
+ new_keys = array.map(&::CSL::Style::Sort::Key.method(:new))
15
+ new_sort = ::CSL::Style::Sort.new.add_children(*new_keys)
16
+
17
+ bibliography = engine.style.find_child("bibliography")
18
+ bibliography.find_child("sort")&.unlink
19
+
20
+ bibliography.add_child new_sort
21
+ end
22
+
23
+ def force_sort!(mode:)
24
+ # Valid modes are :citation and :bibliography
25
+ engine.sort! data, engine.style.send(mode).sort_keys if engine.style.send(mode).sort?
26
+ end
27
+ end
28
+ end
@@ -1,7 +1,5 @@
1
1
  require "asciidoctor/attribute_list"
2
- require_relative "formatters/csl"
3
-
4
- require_relative "helpers"
2
+ require_relative "formatter"
5
3
 
6
4
  module AsciidoctorBibliography
7
5
  class Index
@@ -16,23 +14,13 @@ module AsciidoctorBibliography
16
14
  end
17
15
 
18
16
  def render(bibliographer)
19
- formatter = Formatters::CSL.new(bibliographer.options.style)
20
-
21
- unless bibliographer.options.sort.nil?
22
- formatter.replace_bibliography_sort bibliographer.options.sort
23
- end
24
-
25
- filtered_db = bibliographer.occurring_keys.
26
- map { |id| bibliographer.database.find_entry_by_id(id) }.
27
- map { |entry| prepare_entry_metadata bibliographer, entry }
28
- formatter.import filtered_db
29
- formatter.sort(mode: :bibliography)
17
+ formatter = setup_formatter bibliographer
30
18
 
31
19
  lines = []
32
20
  formatter.bibliography.each_with_index do |reference, index|
33
21
  line = "{empty}"
34
22
  line << "anchor:#{anchor_id(formatter.data[index].id)}[]"
35
- line << Helpers.html_to_asciidoc(reference)
23
+ line << reference
36
24
  lines << line
37
25
  end
38
26
 
@@ -40,6 +28,26 @@ module AsciidoctorBibliography
40
28
  lines.join("\n\n").lines.map(&:strip)
41
29
  end
42
30
 
31
+ private
32
+
33
+ def setup_formatter(bibliographer)
34
+ formatter = Formatter.new(bibliographer.options.style, locale: bibliographer.options.locale)
35
+
36
+ formatter.replace_bibliography_sort bibliographer.options.sort unless bibliographer.options.sort.nil?
37
+
38
+ filtered_db = prepare_filtered_db bibliographer
39
+ formatter.import filtered_db
40
+ formatter.force_sort!(mode: :bibliography)
41
+
42
+ formatter
43
+ end
44
+
45
+ def prepare_filtered_db(bibliographer)
46
+ bibliographer.occurring_keys.
47
+ map { |id| bibliographer.database.find_entry_by_id(id) }.
48
+ map { |entry| prepare_entry_metadata bibliographer, entry }
49
+ end
50
+
43
51
  def prepare_entry_metadata(bibliographer, entry)
44
52
  entry.
45
53
  merge('citation-number': bibliographer.appearance_index_of(entry["id"])).
@@ -51,7 +59,7 @@ module AsciidoctorBibliography
51
59
  end
52
60
 
53
61
  def render_entry_label(target, formatter)
54
- Helpers.html_to_asciidoc formatter.render(:bibliography, id: target).join
62
+ formatter.render(:bibliography, id: target).join
55
63
  end
56
64
 
57
65
  def render_entry(target, formatter)