asciidoctor-bibtex 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,25 +0,0 @@
1
- # citation class
2
- #
3
- # Copyright (c) Peter Lane, 2012.
4
- # Released under Open Works License, 0.9.2
5
-
6
- module AsciidoctorBibtex
7
- # Class to hold information about a single citation:
8
- # its reference and any page numbers
9
- class Citation
10
- attr_reader :ref, :pages
11
-
12
- def initialize ref, pages
13
- @ref = ref
14
- @pages = pages
15
- # clean up pages
16
- @pages = '' unless @pages
17
- @pages = @pages.gsub("--","-")
18
- end
19
-
20
- def to_s
21
- "#{@ref}:#{@pages}"
22
- end
23
- end
24
- end
25
-
@@ -1,23 +0,0 @@
1
- # citationdata class
2
- #
3
- # Copyright (c) Peter Lane, 2013.
4
- # Released under Open Works License, 0.9.2
5
-
6
- module AsciidoctorBibtex
7
- # Class to hold information about a citation in text:
8
- # the text forming the citation, its type, pretext, and enclosed cites
9
- class CitationData
10
- attr_reader :original, :type, :pretext, :cites
11
-
12
- def initialize original, type, pretext, cites
13
- @original = original
14
- @type = type
15
- @pretext = if pretext.nil?
16
- ''
17
- else
18
- pretext
19
- end
20
- @cites = cites
21
- end
22
- end
23
- end
@@ -1,45 +0,0 @@
1
- #
2
- # Class to hold and manage citations
3
- #
4
- # Copyright (c) Peter Lane, 2013.
5
- # Released under Open Works License, 0.9.2
6
-
7
- module AsciidoctorBibtex
8
- # Class to store list of citations used in document
9
- class Citations
10
- include CitationUtils
11
-
12
- attr_reader :cites_used
13
-
14
- def initialize
15
- @cites_used = []
16
- end
17
-
18
- # Given a line of text, extract any citations and include new citation references in current list
19
- def add_from_line line
20
- retrieve_citations(line).each do |citation|
21
- @cites_used += citation.cites.collect {|cite| cite.ref}
22
- end
23
- @cites_used.uniq! {|item| item.to_s} # only keep each reference once
24
- end
25
-
26
- # Return a list of citation references in document, sorted into order
27
- def sorted_cites biblio
28
- @cites_used.sort_by do |ref|
29
- bibitem = biblio[ref]
30
-
31
- unless bibitem.nil?
32
- # extract the reference, and uppercase.
33
- # Remove { } from grouped names for sorting.
34
- author = bibitem.author
35
- if author.nil?
36
- author = bibitem.editor
37
- end
38
- author_chicago(author).collect {|s| s.upcase.gsub("{","").gsub("}","")} + [bibitem.year]
39
- else
40
- [ref]
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,67 +0,0 @@
1
- # Utility functions for citations class
2
- #
3
- # Copyright (c) Peter Lane, 2013.
4
- # Released under Open Works License, 0.9.2
5
-
6
- module AsciidoctorBibtex
7
- # Some utility functions used in Citations class
8
- module CitationUtils
9
-
10
- # Given a line, return a list of CitationData instances
11
- # containing information on each set of citation information
12
- def retrieve_citations line
13
- result = []
14
- md = CITATION_FULL.match line
15
- while md
16
- data = CitationData.new md[0], md[1], nil, []
17
- cm = CITATION_KEY.match md[2]
18
- while cm
19
- pages = nil
20
- if cm[2]
21
- pages = cm[2][1...-1]
22
- end
23
- data.cites << Citation.new(cm[1], pages)
24
- # look for next ref within citation
25
- cm = CITATION_KEY.match cm.post_match
26
- end
27
- result << data
28
- # look for next citation on line
29
- md = CITATION_FULL.match md.post_match
30
- end
31
-
32
- return result
33
- end
34
-
35
- # arrange author string, flag for order of surname/initials
36
- def arrange_authors authors, surname_first
37
- return [] if authors.nil?
38
- authors.split(/\band\b/).collect do |name|
39
- if name.include?(", ")
40
- parts = name.strip.rpartition(", ")
41
- if surname_first
42
- "#{parts.first}, #{parts.third}"
43
- else
44
- "#{parts.third} #{parts.first}"
45
- end
46
- else
47
- name
48
- end
49
- end
50
- end
51
-
52
- # Arrange given author string into Chicago format
53
- def author_chicago authors
54
- arrange_authors authors, true
55
- end
56
-
57
- # matches a citation key, such as 'Dan2012(99-100)'
58
- CITATION_KEY = /([^\s,()\[\]]+)(\(\d+(-\d+)*\))?/
59
- # matches a citation type
60
- CITATION_TYPE = /cite|citenp/
61
- # matches a citation list
62
- CITATION_LIST_TAIL = /(\s*,\s*#{CITATION_KEY})*/
63
- CITATION_LIST = /(?:#{CITATION_KEY}#{CITATION_LIST_TAIL})/
64
- # matches the whole citation
65
- CITATION_FULL = /(#{CITATION_TYPE}):\[(#{CITATION_LIST})\]/
66
- end
67
- end
@@ -1,32 +0,0 @@
1
- #
2
- # filehandlers.rb
3
- # Contains top-level file utility methods
4
- #
5
-
6
- module AsciidoctorBibtex
7
-
8
- module FileHandlers
9
- # Locate a bibliography file to read in given dir
10
- def FileHandlers.find_bibliography dir
11
- begin
12
- candidates = Dir.glob("#{dir}/*.bib")
13
- if candidates.empty?
14
- return ""
15
- else
16
- return candidates.first
17
- end
18
- rescue # catch all errors, and return empty string
19
- return ""
20
- end
21
- end
22
-
23
- # Add '-ref' before the extension of a filename
24
- def FileHandlers.add_ref filename
25
- file_dir = File.dirname(File.expand_path(filename))
26
- file_base = File.basename(filename, ".*")
27
- file_ext = File.extname(filename)
28
- return "#{file_dir}#{File::SEPARATOR}#{file_base}-ref#{file_ext}"
29
- end
30
- end
31
- end
32
-
@@ -1,206 +0,0 @@
1
- #
2
- # Manage the current set of citations, the document settings,
3
- # and main operations.
4
- #
5
-
6
- module AsciidoctorBibtex
7
-
8
- # Class used through utility method to hold data about citations for
9
- # current document, and run the different steps to add the citations
10
- # and bibliography
11
- class Processor
12
- include ProcessorUtils
13
-
14
- attr_reader :biblio, :links, :style, :citations
15
-
16
- def initialize biblio, links, style, locale, numeric_in_appearance_order = false, output = :asciidoc, bibfile = ""
17
- @biblio = biblio
18
- @links = links
19
- @numeric_in_appearance_order = numeric_in_appearance_order
20
- @style = style
21
- @locale = locale
22
- @citations = Citations.new
23
- @filenames = Set.new
24
- @output = output
25
- @bibfile = bibfile
26
-
27
- if output != :latex and output != :bibtex and output != :biblatex
28
- @citeproc = CiteProc::Processor.new style: @style, format: :html, locale: @locale
29
- @citeproc.import @biblio.to_citeproc
30
- end
31
- end
32
-
33
- # Return the complete citation text for given cite_data
34
- def complete_citation cite_data
35
-
36
- if @output == :latex or @output == :bibtex or @output == :biblatex
37
- result = '+++'
38
- cite_data.cites.each do |cite|
39
- # NOTE: xelatex does not support "\citenp", so we output all
40
- # references as "cite" here unless we're using biblatex.
41
- if @output == :biblatex
42
- if cite_data.type == "citenp"
43
- result << "\\" << 'textcite'
44
- else
45
- result << "\\" << 'parencite'
46
- end
47
- else
48
- result << "\\" << 'cite'
49
- end
50
- if cite.pages != ''
51
- result << "[p. " << cite.pages << "]"
52
- end
53
- result << "{" << "#{cite.ref}" << "},"
54
- end
55
- if result[-1] == ','
56
- result = result[0..-2]
57
- end
58
- result << "+++"
59
- return result
60
- else
61
- result = ''
62
- ob, cb = '(', ')'
63
-
64
- cite_data.cites.each_with_index do |cite, index|
65
- # before all items apart from the first, insert appropriate separator
66
- result << "#{separator} " unless index.zero?
67
-
68
- # @links requires adding hyperlink to reference
69
- result << "<<#{cite.ref}," if @links
70
-
71
- # if found, insert reference information
72
- unless biblio[cite.ref].nil?
73
- item = biblio[cite.ref].clone
74
- cite_text, ob, cb = make_citation item, cite.ref, cite_data, cite
75
- else
76
- puts "Unknown reference: #{cite.ref}"
77
- cite_text = "#{cite.ref}"
78
- end
79
-
80
- result << cite_text.html_to_asciidoc
81
- # @links requires finish hyperlink
82
- result << ">>" if @links
83
- end
84
-
85
- unless @links
86
- # combine numeric ranges
87
- if Styles.is_numeric? @style
88
- result = combine_consecutive_numbers result
89
- end
90
- end
91
-
92
- return include_pretext result, cite_data, ob, cb
93
- end
94
- end
95
-
96
- # Retrieve text for reference in given style
97
- # - ref is reference for item to give reference for
98
- def get_reference ref
99
- result = ""
100
- result << ". " if Styles.is_numeric? @style
101
-
102
- begin
103
- cptext = @citeproc.render :bibliography, id: ref
104
- rescue Exception => e
105
- puts "Failed to render #{ref}: #{e}"
106
- end
107
- result << "[[#{ref}]]" if @links
108
- if cptext.nil?
109
- return result+ref
110
- else
111
- result << cptext.first
112
- end
113
-
114
- return result.html_to_asciidoc
115
- end
116
-
117
- def separator
118
- if Styles.is_numeric? @style
119
- ','
120
- else
121
- ';'
122
- end
123
- end
124
-
125
- # Format pages with pp/p as appropriate
126
- def with_pp pages
127
- return '' if pages.empty?
128
-
129
- if @style.include? "chicago"
130
- pages
131
- elsif pages.include? '-'
132
- "pp.&#160;#{pages}"
133
- else
134
- "p.&#160;#{pages}"
135
- end
136
- end
137
-
138
- # Return page string for given cite
139
- def page_str cite
140
- result = ''
141
- unless cite.pages.empty?
142
- result << "," unless Styles.is_numeric? @style
143
- result << " #{with_pp(cite.pages)}"
144
- end
145
-
146
- return result
147
- end
148
-
149
- def include_pretext result, cite_data, ob, cb
150
- pretext = cite_data.pretext
151
- pretext += ' ' unless pretext.empty? # add space after any content
152
-
153
- if Styles.is_numeric? @style
154
- "#{pretext}#{ob}#{result}#{cb}"
155
- elsif cite_data.type == "cite"
156
- "#{ob}#{pretext}#{result}#{cb}"
157
- else
158
- "#{pretext}#{result}"
159
- end
160
- end
161
-
162
- # Numeric citations are handled by computing the position of the reference
163
- # in the list of used citations.
164
- # Other citations are formatted by citeproc.
165
- def make_citation item, ref, cite_data, cite
166
- if Styles.is_numeric? @style
167
- cite_text = if @numeric_in_appearance_order
168
- "#{@citations.cites_used.index(cite.ref) + 1}"
169
- else
170
- "#{sorted_cites.index(cite.ref) + 1}"
171
- end
172
- fc = '['
173
- lc = ']'
174
- else
175
- cite_text = @citeproc.process id: ref, mode: :citation
176
- fc = ''
177
- lc = ''
178
- end
179
-
180
- if Styles.is_numeric? @style
181
- cite_text << "#{page_str(cite)}"
182
- elsif cite_data.type == "citenp"
183
- cite_text = cite_text.gsub(item.year, "#{fc}#{item.year}#{page_str(cite)}#{lc}").gsub(", #{fc}", " #{fc}")
184
- else
185
- cite_text << page_str(cite)
186
- end
187
-
188
- cite_text = cite_text.gsub(",", "&#44;") if @links # replace comma
189
-
190
- return cite_text, fc, lc
191
- end
192
-
193
- def sorted_cites
194
- @citations.sorted_cites @biblio
195
- end
196
-
197
- def cites
198
- if Styles.is_numeric?(@style) and @numeric_in_appearance_order
199
- @citations.cites_used
200
- else
201
- sorted_cites
202
- end
203
- end
204
-
205
- end
206
- end
@@ -1,34 +0,0 @@
1
-
2
- module AsciidoctorBibtex
3
- module ProcessorUtils
4
- # Used with numeric styles to combine consecutive numbers into ranges
5
- # e.g. 1,2,3 -> 1-3, or 1,2,3,6,7,8,9,12 -> 1-3,6-9,12
6
- # leave references with page numbers alone
7
- def combine_consecutive_numbers str
8
- nums = str.split(",").collect(&:strip)
9
- res = ""
10
- # Loop through ranges
11
- start_range = 0
12
- while start_range < nums.length do
13
- end_range = start_range
14
- while (end_range < nums.length-1 and
15
- nums[end_range].is_i? and
16
- nums[end_range+1].is_i? and
17
- nums[end_range+1].to_i == nums[end_range].to_i + 1) do
18
- end_range += 1
19
- end
20
- if end_range - start_range >= 2
21
- res += "#{nums[start_range]}-#{nums[end_range]}, "
22
- else
23
- start_range.upto(end_range) do |i|
24
- res += "#{nums[i]}, "
25
- end
26
- end
27
- start_range = end_range + 1
28
- end
29
- # finish by removing last comma
30
- res.gsub(/, $/, '')
31
- end
32
- end
33
- end
34
-
@@ -1,111 +0,0 @@
1
- # Some extension and helper methods.
2
- #
3
- # Copyright (c) Peter Lane, 2012-13.
4
- # Copyright (c) Zhang YANG, 2016-09.
5
- # Released under Open Works License, 0.9.2
6
-
7
- module AsciidoctorBibtex
8
- module Utils
9
-
10
- def find_bibtex_database dir
11
- begin
12
- candidates = Dir.glob("#{dir}/*.bib")
13
- if candidates.empty?
14
- return ""
15
- else
16
- return candidates.first
17
- end
18
- rescue # catch all errors, and return empty string
19
- return ""
20
- end
21
- end
22
-
23
- # Used with numeric styles to combine consecutive numbers into ranges
24
- # e.g. 1,2,3 -> 1-3, or 1,2,3,6,7,8,9,12 -> 1-3,6-9,12
25
- # leave references with page numbers alone
26
- def combine_consecutive_numbers str
27
- nums = str.split(",").collect(&:strip)
28
- res = ""
29
- # Loop through ranges
30
- start_range = 0
31
- while start_range < nums.length do
32
- end_range = start_range
33
- while (end_range < nums.length-1 and
34
- nums[end_range].is_i? and
35
- nums[end_range+1].is_i? and
36
- nums[end_range+1].to_i == nums[end_range].to_i + 1) do
37
- end_range += 1
38
- end
39
- if end_range - start_range >= 2
40
- res += "#{nums[start_range]}-#{nums[end_range]}, "
41
- else
42
- start_range.upto(end_range) do |i|
43
- res += "#{nums[i]}, "
44
- end
45
- end
46
- start_range = end_range + 1
47
- end
48
- # finish by removing last comma
49
- res.gsub(/, $/, '')
50
- end
51
- end
52
- end
53
-
54
- module AsciidoctorBibtexArrayExtensions
55
-
56
- # Retrieve the third item of an array
57
- # Note: no checks for validity
58
- def third
59
- self[2]
60
- end
61
-
62
- # Join items in array using commas and 'and' on last item
63
- def semantic_join
64
- if size < 2
65
- return self.join("")
66
- end
67
- result = ""
68
- self.each_with_index do |item, index|
69
- if index.zero?
70
- result << item
71
- elsif index == size-1
72
- result << " and #{item}"
73
- else
74
- result << ", #{item}"
75
- end
76
- end
77
-
78
- return result
79
- end
80
- end
81
-
82
- # monkey patch the extension methods to Array
83
- class Array
84
- include AsciidoctorBibtexArrayExtensions
85
- end
86
-
87
- # Converts html output produced by citeproc to asciidoc markup
88
- module StringHtmlToAsciiDoc
89
- def html_to_asciidoc
90
- r = self.gsub(/<\/?i>/, '_')
91
- r = r.gsub(/<\/?b>/, '*')
92
- r = r.gsub(/<\/?span.*?>/, '')
93
- r = r.gsub(/\{|\}/, '')
94
- r
95
- end
96
- end
97
-
98
- # Provides a check that a string is in integer
99
- # Taken from:
100
- # http://stackoverflow.com/questions/1235863/test-if-a-string-is-basically-an-integer-in-quotes-using-ruby
101
- module IntegerCheck
102
- def is_i?
103
- !!(self =~ /^[-+]?[0-9]+$/)
104
- end
105
- end
106
-
107
- # monkey patch the extension methods into String
108
- class String
109
- include StringHtmlToAsciiDoc
110
- include IntegerCheck
111
- end