asciidoctor-bibtex 0.4.1 → 0.5.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 +4 -4
- data/README.md +5 -5
- data/lib/asciidoctor-bibtex.rb +4 -14
- data/lib/asciidoctor-bibtex/CitationMacro.rb +96 -0
- data/lib/asciidoctor-bibtex/CitationUtils.rb +34 -0
- data/lib/asciidoctor-bibtex/PathUtils.rb +21 -0
- data/lib/asciidoctor-bibtex/Processor.rb +281 -0
- data/lib/asciidoctor-bibtex/StringUtils.rb +57 -0
- data/lib/asciidoctor-bibtex/{styles.rb → StyleUtils.rb} +8 -8
- data/lib/asciidoctor-bibtex/extensions.rb +160 -50
- data/lib/asciidoctor-bibtex/version.rb +1 -1
- metadata +52 -15
- data/lib/asciidoctor-bibtex/asciidoctor.rb +0 -7
- data/lib/asciidoctor-bibtex/bibextension.rb +0 -177
- data/lib/asciidoctor-bibtex/citation.rb +0 -25
- data/lib/asciidoctor-bibtex/citationdata.rb +0 -23
- data/lib/asciidoctor-bibtex/citations.rb +0 -45
- data/lib/asciidoctor-bibtex/citationutils.rb +0 -67
- data/lib/asciidoctor-bibtex/filehandlers.rb +0 -32
- data/lib/asciidoctor-bibtex/processor.rb +0 -206
- data/lib/asciidoctor-bibtex/processorutils.rb +0 -34
- data/lib/utils.rb +0 -111
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# StringUtils.rb
|
5
|
+
#
|
6
|
+
# Some utilities for strings.
|
7
|
+
#
|
8
|
+
# Copyright (c) Peter Lane, 2012-13.
|
9
|
+
# Copyright (c) Zhang Yang, 2019.
|
10
|
+
#
|
11
|
+
# Released under Open Works License, 0.9.2
|
12
|
+
#
|
13
|
+
|
14
|
+
module AsciidoctorBibtex
|
15
|
+
module StringUtils
|
16
|
+
# Converts html output produced by citeproc to asciidoc markup
|
17
|
+
def self.html_to_asciidoc(s)
|
18
|
+
s = s.gsub(%r{</?i>}, '_')
|
19
|
+
s = s.gsub(%r{</?b>}, '*')
|
20
|
+
s = s.gsub(%r{</?span.*?>}, '')
|
21
|
+
s = s.gsub(/\{|\}/, '')
|
22
|
+
s
|
23
|
+
end
|
24
|
+
|
25
|
+
# Provides a check that a string is in integer
|
26
|
+
def self.is_i?(s)
|
27
|
+
!!(s =~ /^[-+]?[0-9]+$/)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Merge consecutive number so that "1,2,3,5" becomes "1-3,5"
|
31
|
+
def self.combine_consecutive_numbers(str)
|
32
|
+
nums = str.split(',').collect(&:strip)
|
33
|
+
res = ''
|
34
|
+
# Loop through ranges
|
35
|
+
start_range = 0
|
36
|
+
while start_range < nums.length
|
37
|
+
end_range = start_range
|
38
|
+
while (end_range < nums.length - 1) &&
|
39
|
+
is_i?(nums[end_range]) &&
|
40
|
+
is_i?(nums[end_range + 1]) &&
|
41
|
+
(nums[end_range + 1].to_i == nums[end_range].to_i + 1)
|
42
|
+
end_range += 1
|
43
|
+
end
|
44
|
+
if end_range - start_range >= 2
|
45
|
+
res += "#{nums[start_range]}-#{nums[end_range]}, "
|
46
|
+
else
|
47
|
+
start_range.upto(end_range) do |i|
|
48
|
+
res += "#{nums[i]}, "
|
49
|
+
end
|
50
|
+
end
|
51
|
+
start_range = end_range + 1
|
52
|
+
end
|
53
|
+
# finish by removing last comma
|
54
|
+
res.gsub(/, $/, '')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -3,25 +3,25 @@
|
|
3
3
|
# Simple checks on available styles through CSL
|
4
4
|
#
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
module Styles
|
6
|
+
require 'citeproc'
|
7
|
+
require 'csl/styles'
|
9
8
|
|
10
|
-
|
9
|
+
module AsciidoctorBibtex
|
10
|
+
module StyleUtils
|
11
|
+
def self.available
|
11
12
|
CSL::Style.ls
|
12
13
|
end
|
13
14
|
|
14
|
-
def
|
15
|
+
def self.default_style
|
15
16
|
'apa'
|
16
17
|
end
|
17
18
|
|
18
|
-
def
|
19
|
+
def self.valid?(style)
|
19
20
|
Styles.available.include? style
|
20
21
|
end
|
21
22
|
|
22
|
-
def
|
23
|
+
def self.is_numeric?(style)
|
23
24
|
CSL::Style.load(style).citation_format == :numeric
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
27
|
-
|
@@ -1,64 +1,174 @@
|
|
1
|
-
# Some extension and helper methods.
|
2
1
|
#
|
3
|
-
#
|
4
|
-
#
|
2
|
+
# Treeprocessor extension for asciidoctor
|
3
|
+
#
|
5
4
|
|
6
|
-
|
5
|
+
require 'asciidoctor'
|
6
|
+
require 'asciidoctor/extensions'
|
7
|
+
require 'asciidoctor/reader'
|
8
|
+
require 'asciidoctor/parser'
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
def third
|
11
|
-
self[2]
|
12
|
-
end
|
10
|
+
require_relative 'PathUtils'
|
11
|
+
require_relative 'Processor'
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
13
|
+
module AsciidoctorBibtex
|
14
|
+
module Asciidoctor
|
15
|
+
# Placeholder paragraph for the bibliography paragraph. Choose a uuid so
|
16
|
+
# that it is a special word unlikeky to conflict with normal texts.
|
17
|
+
BibliographyBlockMacroPlaceholder = %(a5d42deb-3cfc-4293-b96a-fcb47316ce56)
|
18
|
+
|
19
|
+
# BibliographyBlockMacro
|
20
|
+
#
|
21
|
+
# The `bibliography::[] block macro` processor.
|
22
|
+
#
|
23
|
+
# This macro processor does only half the work. It just parse the macro
|
24
|
+
# and set bibtex file and style if found in the macro. The macro is then
|
25
|
+
# expanded to a special paragraph, which is then replaced with generated
|
26
|
+
# references by the treeprocessor.
|
27
|
+
#
|
28
|
+
class BibliographyBlockMacro < ::Asciidoctor::Extensions::BlockMacroProcessor
|
29
|
+
use_dsl
|
30
|
+
named :bibliography
|
31
|
+
name_positional_attributes :style, :locale
|
32
|
+
|
33
|
+
def process(parent, target, attrs)
|
34
|
+
# NOTE: bibtex-file and bibtex-style set by this macro shall be
|
35
|
+
# overridable by document attributes and commandline arguments. So we
|
36
|
+
# respect the convention here.
|
37
|
+
if target && (!parent.document.attr? 'bibtex-file')
|
38
|
+
parent.document.set_attribute 'bibtex-file', target
|
39
|
+
end
|
40
|
+
if attrs.key?(:style) && (!parent.document.attr? 'bibtex-style')
|
41
|
+
parent.document.set_attribute 'bibtex-style', attrs[:style]
|
42
|
+
end
|
43
|
+
if attrs.key?(:locale) && (!parent.document.attr? 'bibtex-locale')
|
44
|
+
parent.document.set_attribute 'bibtex-locale', attrs[:locale]
|
45
|
+
end
|
46
|
+
create_paragraph parent, BibliographyBlockMacroPlaceholder, {}
|
27
47
|
end
|
28
48
|
end
|
29
49
|
|
30
|
-
|
31
|
-
|
32
|
-
|
50
|
+
# CitationProcessor
|
51
|
+
#
|
52
|
+
# A tree processor to replace all citations and bibliography.
|
53
|
+
#
|
54
|
+
# This processor scans the document, generates a list of citations, replaces
|
55
|
+
# each citation with citation text and the reference block macro placeholder
|
56
|
+
# with the final bibliography list. It relys on the block macro processor to
|
57
|
+
# generate the place holder.
|
58
|
+
#
|
59
|
+
# NOTE: According to the asiidoctor extension policy, the tree processor can
|
60
|
+
# only produce texts with inline macros.
|
61
|
+
#
|
62
|
+
class CitationProcessor < ::Asciidoctor::Extensions::Treeprocessor
|
63
|
+
def process(document)
|
64
|
+
bibtex_file = (document.attr 'bibtex-file').to_s
|
65
|
+
bibtex_style = ((document.attr 'bibtex-style') || 'ieee').to_s
|
66
|
+
bibtex_locale = ((document.attr 'bibtex-locale') || 'en-US').to_s
|
67
|
+
bibtex_order = ((document.attr 'bibtex-order') || 'appearance').to_sym
|
68
|
+
bibtex_format = ((document.attr 'bibtex-format') || 'asciidoc').to_sym
|
69
|
+
bibtex_throw = ((document.attr 'bibtex-throw') || 'false').to_s.downcase
|
33
70
|
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
end
|
71
|
+
# Fild bibtex file automatically if not supplied.
|
72
|
+
if bibtex_file.empty?
|
73
|
+
bibtex_file = AsciidoctorBibtex::PathUtils.fild_bibfile '.'
|
74
|
+
end
|
75
|
+
if bibtex_file.empty?
|
76
|
+
bibtex_file = AsciidoctorBibtex::PathUtils.find_bibfile "#{ENV['HOME']}/Documents"
|
77
|
+
end
|
78
|
+
if bibtex_file.empty?
|
79
|
+
puts 'Error: bibtex-file is not set and automatic search failed'
|
80
|
+
exit
|
81
|
+
end
|
38
82
|
|
39
|
-
#
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
r
|
47
|
-
end
|
48
|
-
end
|
83
|
+
# Extract all AST nodes that can contain citations.
|
84
|
+
prose_blocks = document.find_by do |b|
|
85
|
+
(b.content_model == :simple) ||
|
86
|
+
(b.context == :list_item) ||
|
87
|
+
(b.context == :table_cell)
|
88
|
+
end
|
89
|
+
return nil if prose_blocks.nil?
|
49
90
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
91
|
+
processor = Processor.new bibtex_file, true, bibtex_style, bibtex_locale,
|
92
|
+
bibtex_order == :appearance, bibtex_format,
|
93
|
+
bibtex_throw == 'true'
|
94
|
+
|
95
|
+
# First pass: extract all citations.
|
96
|
+
prose_blocks.each do |block|
|
97
|
+
if block.context == :list_item || block.context == :table_cell
|
98
|
+
line = block.text
|
99
|
+
processor.process_citation_macros line
|
100
|
+
else
|
101
|
+
block.lines.each do |line|
|
102
|
+
processor.process_citation_macros line
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
# Make processor finalize macro processing as required.
|
107
|
+
processor.finalize_macro_processing
|
108
|
+
|
109
|
+
# Second pass: replace citations with citation texts.
|
110
|
+
prose_blocks.each do |block|
|
111
|
+
if block.context == :list_item || block.context == :table_cell
|
112
|
+
line = block.text
|
113
|
+
line = processor.replace_citation_macros(line)
|
114
|
+
block.text = line
|
115
|
+
else
|
116
|
+
block.lines.each_with_index do |line, index|
|
117
|
+
line = processor.replace_citation_macros(line)
|
118
|
+
block.lines[index] = line
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
references_asciidoc = []
|
124
|
+
if (bibtex_format == :latex) || (bibtex_format == :bibtex)
|
125
|
+
references_asciidoc << %(+++\\bibliography{#{bibtex_file}}{}+++)
|
126
|
+
references_asciidoc << %(+++\\bibliographystyle{#{bibtex_style}}+++)
|
127
|
+
elsif bibtex_format == :biblatex
|
128
|
+
references_asciidoc << %(+++\\printbibliography+++)
|
129
|
+
else
|
130
|
+
references_asciidoc = processor.build_bibliography_list
|
131
|
+
end
|
132
|
+
|
133
|
+
# Third pass: replace the bibliography paragraph with the bibliography
|
134
|
+
# list.
|
135
|
+
biblio_blocks = document.find_by do |b|
|
136
|
+
# for fast search (since most searches shall fail)
|
137
|
+
(b.content_model == :simple) && (b.lines.size == 1) \
|
138
|
+
&& (b.lines[0] == BibliographyBlockMacroPlaceholder)
|
139
|
+
end
|
140
|
+
biblio_blocks.each do |block|
|
141
|
+
block_index = block.parent.blocks.index do |b|
|
142
|
+
b == block
|
143
|
+
end
|
144
|
+
reference_blocks = parse_asciidoc block.parent, references_asciidoc
|
145
|
+
reference_blocks.reverse.each do |b|
|
146
|
+
block.parent.blocks.insert block_index, b
|
147
|
+
end
|
148
|
+
block.parent.blocks.delete_at block_index + reference_blocks.size
|
149
|
+
end
|
150
|
+
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
|
154
|
+
# This is an adapted version of Asciidoctor::Extension::parse_content,
|
155
|
+
# where resultant blocks are returned as a list instead of attached to
|
156
|
+
# the parent.
|
157
|
+
def parse_asciidoc(parent, content, attributes = {})
|
158
|
+
result = []
|
159
|
+
reader = ::Asciidoctor::Reader.new content
|
160
|
+
while reader.has_more_lines?
|
161
|
+
block = ::Asciidoctor::Parser.next_block reader, parent, attributes
|
162
|
+
result << block if block
|
163
|
+
end
|
164
|
+
result
|
165
|
+
end
|
166
|
+
end
|
56
167
|
end
|
57
168
|
end
|
58
169
|
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
-
|
170
|
+
# Register the extensions to asciidoctor
|
171
|
+
Asciidoctor::Extensions.register do
|
172
|
+
block_macro AsciidoctorBibtex::Asciidoctor::BibliographyBlockMacro
|
173
|
+
treeprocessor AsciidoctorBibtex::Asciidoctor::CitationProcessor
|
63
174
|
end
|
64
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-bibtex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zhang YANG
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.0.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 3.0.0
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 2.0.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 3.0.0
|
@@ -86,6 +86,48 @@ dependencies:
|
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '0.2'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: minitest
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '5'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '5'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: bundler
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '2'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '2'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rake
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '12'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '12'
|
89
131
|
description: |
|
90
132
|
asciidoctor-bibtex adds bibtex support for asciidoc documents by introducing
|
91
133
|
two new macros: `cite:[KEY]` and `bibliography::[]`. Citations are parsed and
|
@@ -100,19 +142,14 @@ files:
|
|
100
142
|
- LICENSE.txt
|
101
143
|
- README.md
|
102
144
|
- lib/asciidoctor-bibtex.rb
|
103
|
-
- lib/asciidoctor-bibtex/
|
104
|
-
- lib/asciidoctor-bibtex/
|
105
|
-
- lib/asciidoctor-bibtex/
|
106
|
-
- lib/asciidoctor-bibtex/
|
107
|
-
- lib/asciidoctor-bibtex/
|
108
|
-
- lib/asciidoctor-bibtex/
|
145
|
+
- lib/asciidoctor-bibtex/CitationMacro.rb
|
146
|
+
- lib/asciidoctor-bibtex/CitationUtils.rb
|
147
|
+
- lib/asciidoctor-bibtex/PathUtils.rb
|
148
|
+
- lib/asciidoctor-bibtex/Processor.rb
|
149
|
+
- lib/asciidoctor-bibtex/StringUtils.rb
|
150
|
+
- lib/asciidoctor-bibtex/StyleUtils.rb
|
109
151
|
- lib/asciidoctor-bibtex/extensions.rb
|
110
|
-
- lib/asciidoctor-bibtex/filehandlers.rb
|
111
|
-
- lib/asciidoctor-bibtex/processor.rb
|
112
|
-
- lib/asciidoctor-bibtex/processorutils.rb
|
113
|
-
- lib/asciidoctor-bibtex/styles.rb
|
114
152
|
- lib/asciidoctor-bibtex/version.rb
|
115
|
-
- lib/utils.rb
|
116
153
|
homepage: https://github.com/asciidoctor/asciidoctor-bibtex
|
117
154
|
licenses:
|
118
155
|
- OWL
|
@@ -1,177 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Treeprocessor extension for asciidoctor
|
3
|
-
#
|
4
|
-
|
5
|
-
require 'asciidoctor'
|
6
|
-
require 'asciidoctor/extensions'
|
7
|
-
require 'asciidoctor/reader'
|
8
|
-
require 'asciidoctor/parser'
|
9
|
-
require 'bibtex/filters'
|
10
|
-
require 'latex/decode/base'
|
11
|
-
require 'latex/decode/maths'
|
12
|
-
require 'latex/decode/accents'
|
13
|
-
require 'latex/decode/diacritics'
|
14
|
-
require 'latex/decode/punctuation'
|
15
|
-
require 'latex/decode/symbols'
|
16
|
-
require 'latex/decode/greek'
|
17
|
-
require_relative 'styles'
|
18
|
-
require_relative 'filehandlers'
|
19
|
-
|
20
|
-
module AsciidoctorBibtex
|
21
|
-
module Asciidoctor
|
22
|
-
|
23
|
-
# This filter extends the original latex filter in bibtex-ruby to handle
|
24
|
-
# unknown latex macros more gracefully. We could have used latex-decode
|
25
|
-
# gem together with our custom replacement rules, but latex-decode eats up
|
26
|
-
# all braces after it finishes all decoding. So we hack over the
|
27
|
-
# LaTeX.decode function and insert our rules before `strip_braces`.
|
28
|
-
class LatexFilter < ::BibTeX::Filter
|
29
|
-
def apply(value)
|
30
|
-
text = value.to_s
|
31
|
-
LaTeX::Decode::Base.normalize(text)
|
32
|
-
LaTeX::Decode::Maths.decode!(text)
|
33
|
-
LaTeX::Decode::Accents.decode!(text)
|
34
|
-
LaTeX::Decode::Diacritics.decode!(text)
|
35
|
-
LaTeX::Decode::Punctuation.decode!(text)
|
36
|
-
LaTeX::Decode::Symbols.decode!(text)
|
37
|
-
LaTeX::Decode::Greek.decode!(text)
|
38
|
-
text = text.gsub(/\\url\{(.+?)\}/, " \\1 ").gsub(/\\\w+(?=\s+\w)/, "").gsub(/\\\w+(?:\[.+?\])?\s*\{(.+?)\}/, "\\1")
|
39
|
-
LaTeX::Decode::Base.strip_braces(text)
|
40
|
-
LaTeX.normalize_C(text)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
BibliographyBlockMacroPlaceholder = %(BIBLIOGRAPHY BLOCK MACRO PLACEHOLDER)
|
45
|
-
|
46
|
-
# This macro processor does only half the work. It just parse the macro
|
47
|
-
# and set bibtex file and style if found in the macro. The macro is then
|
48
|
-
# expanded to a special paragraph, which is then replaced with generated
|
49
|
-
# references by the treeprocessor.
|
50
|
-
class BibliographyBlockMacro < ::Asciidoctor::Extensions::BlockMacroProcessor
|
51
|
-
use_dsl
|
52
|
-
named :bibliography
|
53
|
-
name_positional_attributes :style
|
54
|
-
|
55
|
-
def process parent, target, attrs
|
56
|
-
# NOTE: bibtex-file and bibtex-style set by this macro shall be
|
57
|
-
# overridable by document attributes and commandline arguments. So we
|
58
|
-
# respect the convention here.
|
59
|
-
if target and not parent.document.attr? 'bibtex-file'
|
60
|
-
parent.document.set_attribute 'bibtex-file', target
|
61
|
-
end
|
62
|
-
if attrs.key? :style and not parent.document.attr? 'bibtex-style'
|
63
|
-
parent.document.set_attribute 'bibtex-style', attrs[:style]
|
64
|
-
end
|
65
|
-
if attrs.key? :locale and not parent.document.attr? 'bibtex-locale'
|
66
|
-
parent.document.set_attribute 'bibtex-locale', attrs[:locale]
|
67
|
-
end
|
68
|
-
create_paragraph parent, BibliographyBlockMacroPlaceholder, {}
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# This processor scans the document, generates a list of citations,
|
73
|
-
# replace each citation with correct text and the reference block macro
|
74
|
-
# placeholder with the final reference list. It relys on the block macro
|
75
|
-
# processor to generate the place holder.
|
76
|
-
class CitationProcessor < ::Asciidoctor::Extensions::Treeprocessor
|
77
|
-
|
78
|
-
def process document
|
79
|
-
bibtex_file = (document.attr 'bibtex-file').to_s
|
80
|
-
bibtex_style = ((document.attr 'bibtex-style') || 'ieee').to_s
|
81
|
-
bibtex_locale = ((document.attr 'bibtex-locale') || 'en-US').to_s
|
82
|
-
bibtex_order = ((document.attr 'bibtex-order') || 'appearance').to_sym
|
83
|
-
bibtex_format = ((document.attr 'bibtex-format') || 'asciidoc').to_sym
|
84
|
-
|
85
|
-
if bibtex_file.empty?
|
86
|
-
bibtex_file = AsciidoctorBibtex::FileHandlers.find_bibliography "."
|
87
|
-
end
|
88
|
-
if bibtex_file.empty?
|
89
|
-
bibtex_file = AsciidoctorBibtex::FileHandlers.find_bibliography "#{ENV['HOME']}/Documents"
|
90
|
-
end
|
91
|
-
if bibtex_file.empty?
|
92
|
-
puts "Error: bibtex-file is not set and automatic search failed"
|
93
|
-
exit
|
94
|
-
end
|
95
|
-
|
96
|
-
bibtex = BibTeX.open bibtex_file, :filter => [LatexFilter]
|
97
|
-
processor = Processor.new bibtex, true, bibtex_style, bibtex_locale, bibtex_order == :appearance, bibtex_format
|
98
|
-
|
99
|
-
prose_blocks = document.find_by {|b| b.content_model == :simple or b.context == :list_item}
|
100
|
-
prose_blocks.each do |block|
|
101
|
-
if block.context == :list_item
|
102
|
-
line = block.instance_variable_get :@text
|
103
|
-
processor.citations.add_from_line line
|
104
|
-
else
|
105
|
-
block.lines.each do |line|
|
106
|
-
processor.citations.add_from_line line
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
prose_blocks.each do |block|
|
112
|
-
if block.context == :list_item
|
113
|
-
line = block.instance_variable_get :@text
|
114
|
-
processor.citations.retrieve_citations(line).each do |citation|
|
115
|
-
line = line.gsub(citation.original, processor.complete_citation(citation))
|
116
|
-
end
|
117
|
-
block.instance_variable_set :@text, line
|
118
|
-
else
|
119
|
-
block.lines.each do |line|
|
120
|
-
tmp = line.clone
|
121
|
-
processor.citations.retrieve_citations(line).each do |citation|
|
122
|
-
tmp = tmp.gsub(citation.original, processor.complete_citation(citation))
|
123
|
-
end
|
124
|
-
line.replace tmp
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
references_asciidoc = []
|
130
|
-
if bibtex_format == :latex or bibtex_format == :bibtex
|
131
|
-
references_asciidoc << %(+++\\bibliography{#{bibtex_file}}{}+++)
|
132
|
-
references_asciidoc << %(+++\\bibliographystyle{#{bibtex_style}}+++)
|
133
|
-
elsif bibtex_format == :biblatex
|
134
|
-
references_asciidoc << %(+++\\printbibliography+++)
|
135
|
-
else
|
136
|
-
processor.cites.each do |ref|
|
137
|
-
references_asciidoc << processor.get_reference(ref)
|
138
|
-
references_asciidoc << ''
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
biblio_blocks = document.find_by do |b|
|
143
|
-
# for fast search (since most searches shall fail)
|
144
|
-
b.content_model == :simple and b.lines.size == 1 \
|
145
|
-
and b.lines[0] == BibliographyBlockMacroPlaceholder
|
146
|
-
end
|
147
|
-
biblio_blocks.each do |block|
|
148
|
-
block_index = block.parent.blocks.index do |b|
|
149
|
-
b == block
|
150
|
-
end
|
151
|
-
reference_blocks = parse_asciidoc block.parent, references_asciidoc
|
152
|
-
reference_blocks.reverse.each do |b|
|
153
|
-
block.parent.blocks.insert block_index, b
|
154
|
-
end
|
155
|
-
block.parent.blocks.delete_at block_index + reference_blocks.size
|
156
|
-
end
|
157
|
-
|
158
|
-
nil
|
159
|
-
end
|
160
|
-
|
161
|
-
# This is an adapted version of Asciidoctor::Extension::parse_content,
|
162
|
-
# where resultant blocks are returned as a list instead of attached to
|
163
|
-
# the parent.
|
164
|
-
def parse_asciidoc parent, content, attributes = {}
|
165
|
-
result = []
|
166
|
-
reader = ::Asciidoctor::Reader.new content
|
167
|
-
while reader.has_more_lines?
|
168
|
-
block = ::Asciidoctor::Parser.next_block reader, parent, attributes
|
169
|
-
result << block if block
|
170
|
-
end
|
171
|
-
result
|
172
|
-
end
|
173
|
-
|
174
|
-
end
|
175
|
-
|
176
|
-
end
|
177
|
-
end
|