asciidoctor-bibliography 0.0.1.dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +50 -0
  3. data/Gemfile +21 -0
  4. data/Gemfile.lock +41 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.adoc +101 -0
  7. data/SYNTAX.adoc +117 -0
  8. data/asciidoctor-bibliography.gemspec +37 -0
  9. data/deprecated/asciidoctor-bibliography/asciidoctor/bibliographer_postprocessor.rb +23 -0
  10. data/deprecated/asciidoctor-bibliography/asciidoctor/bibliography_block_macro.rb +77 -0
  11. data/deprecated/asciidoctor-bibliography/asciidoctor/citation_processor.rb +144 -0
  12. data/deprecated/asciidoctor-bibliography/asciidoctor/cite_inline_macro.rb +30 -0
  13. data/deprecated/asciidoctor-bibliography/citationdata.rb +23 -0
  14. data/deprecated/asciidoctor-bibliography/citations.rb +45 -0
  15. data/deprecated/asciidoctor-bibliography/citationutils.rb +67 -0
  16. data/deprecated/asciidoctor-bibliography/extensions.rb +64 -0
  17. data/deprecated/asciidoctor-bibliography/filehandlers.rb +32 -0
  18. data/deprecated/asciidoctor-bibliography/index.rb +31 -0
  19. data/deprecated/asciidoctor-bibliography/processor.rb +208 -0
  20. data/deprecated/asciidoctor-bibliography/processorutils.rb +34 -0
  21. data/deprecated/asciidoctor-bibliography/styles.rb +27 -0
  22. data/lib/asciidoctor-bibliography.rb +3 -0
  23. data/lib/asciidoctor-bibliography/asciidoctor.rb +17 -0
  24. data/lib/asciidoctor-bibliography/asciidoctor/bibliographer_preprocessor.rb +68 -0
  25. data/lib/asciidoctor-bibliography/bibliographer.rb +31 -0
  26. data/lib/asciidoctor-bibliography/citation.rb +73 -0
  27. data/lib/asciidoctor-bibliography/database.rb +20 -0
  28. data/lib/asciidoctor-bibliography/databases/bibtex.rb +43 -0
  29. data/lib/asciidoctor-bibliography/formatters/csl.rb +12 -0
  30. data/lib/asciidoctor-bibliography/formatters/tex.rb +164 -0
  31. data/lib/asciidoctor-bibliography/helpers.rb +40 -0
  32. data/lib/asciidoctor-bibliography/index.rb +43 -0
  33. data/lib/asciidoctor-bibliography/version.rb +3 -0
  34. data/samples/.byebug_history +245 -0
  35. data/samples/biblio.bib +31 -0
  36. data/samples/latex_macros_in_bibtex/reference.bib +16 -0
  37. data/samples/latex_macros_in_bibtex/sample.adoc +13 -0
  38. data/samples/sample-authoryear.adoc +72 -0
  39. data/samples/sample-authoryear.html +550 -0
  40. data/samples/sample-numbers.adoc +72 -0
  41. data/samples/sample-numbers.html +550 -0
  42. metadata +187 -0
@@ -0,0 +1,144 @@
1
+ require 'asciidoctor'
2
+ require 'asciidoctor/extensions'
3
+ require 'asciidoctor/reader'
4
+ require 'asciidoctor/parser'
5
+ # require 'bibtex/filters'
6
+ # require 'latex/decode/base'
7
+ # require 'latex/decode/maths'
8
+ # require 'latex/decode/accents'
9
+ # require 'latex/decode/diacritics'
10
+ # require 'latex/decode/punctuation'
11
+ # require 'latex/decode/symbols'
12
+ # require 'latex/decode/greek'
13
+ # require_relative 'styles'
14
+ # require_relative 'filehandlers'
15
+
16
+ module AsciidoctorBibliography
17
+ module Asciidoctor
18
+
19
+ # This filter extends the original latex filter in bibtex-ruby to handle
20
+ # unknown latex macros more gracefully. We could have used latex-decode
21
+ # gem together with our custom replacement rules, but latex-decode eats up
22
+ # all braces after it finishes all decoding. So we hack over the
23
+ # LaTeX.decode function and insert our rules before `strip_braces`.
24
+ # class LatexFilter < ::BibTeX::Filter
25
+ # def apply(value)
26
+ # text = value.to_s
27
+ # LaTeX::Decode::Base.normalize(text)
28
+ # LaTeX::Decode::Maths.decode!(text)
29
+ # LaTeX::Decode::Accents.decode!(text)
30
+ # LaTeX::Decode::Diacritics.decode!(text)
31
+ # LaTeX::Decode::Punctuation.decode!(text)
32
+ # LaTeX::Decode::Symbols.decode!(text)
33
+ # LaTeX::Decode::Greek.decode!(text)
34
+ # text.gsub!(/\\url\{(.+?)\}/, " \\1 ")
35
+ # text.gsub!(/\\\w+(?=\s+\w)/, "")
36
+ # text.gsub!(/\\\w+(?:\[.+?\])?\s*\{(.+?)\}/, "\\1")
37
+ # LaTeX::Decode::Base.strip_braces(text)
38
+ # LaTeX.normalize_C(text)
39
+ # end
40
+ # end
41
+
42
+ # This processor scans the document, generates a list of citations,
43
+ # replace each citation with correct text and the reference block macro
44
+ # placeholder with the final reference list. It relys on the block macro
45
+ # processor to generate the place holder.
46
+ class CitationProcessor < ::Asciidoctor::Extensions::Treeprocessor
47
+
48
+ def process document
49
+ puts self
50
+ # byebug
51
+ # bibtex_file = (document.attr 'bibtex-file').to_s
52
+ # bibtex_style = ((document.attr 'bibtex-style') || 'ieee').to_s
53
+ # bibtex_order = ((document.attr 'bibtex-order') || 'appearance').to_sym
54
+ # bibtex_format = ((document.attr 'bibtex-format') || 'asciidoc').to_sym
55
+
56
+ # if bibtex_file.empty?
57
+ # bibtex_file = AsciidoctorBibliography::FileHandlers.find_bibliography "."
58
+ # end
59
+ # if bibtex_file.empty?
60
+ # bibtex_file = AsciidoctorBibliography::FileHandlers.find_bibliography "#{ENV['HOME']}/Documents"
61
+ # end
62
+ # if bibtex_file.empty?
63
+ # puts "Error: bibtex-file is not set and automatic search failed"
64
+ # exit
65
+ # end
66
+
67
+ # bibtex = BibTeX.open bibtex_file, :filter => [LatexFilter]
68
+ # processor = Processor.new bibtex, true, bibtex_style, bibtex_order == :appearance, bibtex_format
69
+
70
+ # prose_blocks = document.find_by {|b| b.content_model == :simple or b.context == :list_item}
71
+ # prose_blocks.each do |block|
72
+ # if block.context == :list_item
73
+ # line = block.instance_variable_get :@text
74
+ # processor.citations.add_from_line line
75
+ # else
76
+ # block.lines.each do |line|
77
+ # processor.citations.add_from_line line
78
+ # end
79
+ # end
80
+ # end
81
+
82
+ # prose_blocks.each do |block|
83
+ # if block.context == :list_item
84
+ # line = block.instance_variable_get :@text
85
+ # processor.citations.retrieve_citations(line).each do |citation|
86
+ # line.gsub!(citation.original, processor.complete_citation(citation))
87
+ # end
88
+ # block.instance_variable_set :@text, line
89
+ # else
90
+ # block.lines.each do |line|
91
+ # processor.citations.retrieve_citations(line).each do |citation|
92
+ # line.gsub!(citation.original, processor.complete_citation(citation))
93
+ # end
94
+ # end
95
+ # end
96
+ # end
97
+
98
+ # references_asciidoc = []
99
+ # if bibtex_format == :latex
100
+ # references_asciidoc << %(+++\\bibliography{#{bibtex_file}}{}+++)
101
+ # references_asciidoc << %(+++\\bibliographystyle{#{bibtex_style}}+++)
102
+ # else
103
+ # processor.cites.each do |ref|
104
+ # references_asciidoc << processor.get_reference(ref)
105
+ # references_asciidoc << ''
106
+ # end
107
+ # end
108
+
109
+ # biblio_blocks = document.find_by do |b|
110
+ # # for fast search (since most searches shall fail)
111
+ # b.content_model == :simple and b.lines.size == 1 \
112
+ # and b.lines[0] == BibliographyBlockMacroPlaceholder
113
+ # end
114
+ # biblio_blocks.each do |block|
115
+ # block_index = block.parent.blocks.index do |b|
116
+ # b == block
117
+ # end
118
+ # reference_blocks = parse_asciidoc block.parent, references_asciidoc
119
+ # reference_blocks.reverse.each do |b|
120
+ # block.parent.blocks.insert block_index, b
121
+ # end
122
+ # block.parent.blocks.delete_at block_index + reference_blocks.size
123
+ # end
124
+
125
+ # nil
126
+ end
127
+
128
+ # This is an adapted version of Asciidoctor::Extension::parse_content,
129
+ # where resultant blocks are returned as a list instead of attached to
130
+ # the parent.
131
+ def parse_asciidoc parent, content, attributes = {}
132
+ result = []
133
+ reader = ::Asciidoctor::Reader.new content
134
+ while reader.has_more_lines?
135
+ block = ::Asciidoctor::Parser.next_block reader, parent, attributes
136
+ result << block if block
137
+ end
138
+ result
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+ end
@@ -0,0 +1,30 @@
1
+ require 'asciidoctor'
2
+ require 'asciidoctor/extensions'
3
+
4
+ require 'securerandom'
5
+
6
+ module AsciidoctorBibliography
7
+ module Asciidoctor
8
+
9
+ class CiteInlineMacro < ::Asciidoctor::Extensions::InlineMacroProcessor
10
+ use_dsl
11
+
12
+ named :cite
13
+ # name_positional_attributes 'volnum'
14
+
15
+ def process parent, target, attrs
16
+ puts self
17
+
18
+ citation = AsciidoctorBibliography::Citation.new parent, target, attrs, SecureRandom.uuid
19
+ parent.document.bibliographer.citations << citation
20
+
21
+ # text = target # TODO: typeset
22
+ # target = "#bibliography-#{target}"
23
+ # parent.document.register :links, target
24
+ # (create_anchor parent, text, type: :link, target: target).render
25
+
26
+ citation.placeholder
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ # citationdata class
2
+ #
3
+ # Copyright (c) Peter Lane, 2013.
4
+ # Released under Open Works License, 0.9.2
5
+
6
+ module AsciidoctorBibliography
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
@@ -0,0 +1,45 @@
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 AsciidoctorBibliography
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
@@ -0,0 +1,67 @@
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 AsciidoctorBibliography
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|fullcite/
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
@@ -0,0 +1,64 @@
1
+ # Some extension and helper methods.
2
+ #
3
+ # Copyright (c) Peter Lane, 2012-13.
4
+ # Released under Open Works License, 0.9.2
5
+
6
+ module AsciidoctorBibliographyArrayExtensions
7
+
8
+ # Retrieve the third item of an array
9
+ # Note: no checks for validity
10
+ def third
11
+ self[2]
12
+ end
13
+
14
+ # Join items in array using commas and 'and' on last item
15
+ def comma_and_join
16
+ if size < 2
17
+ return self.join("")
18
+ end
19
+ result = ""
20
+ self.each_with_index do |item, index|
21
+ if index.zero?
22
+ result << item
23
+ elsif index == size-1
24
+ result << " and #{item}"
25
+ else
26
+ result << ", #{item}"
27
+ end
28
+ end
29
+
30
+ return result
31
+ end
32
+ end
33
+
34
+ # monkey patch the extension methods to Array
35
+ class Array
36
+ include AsciidoctorBibliographyArrayExtensions
37
+ end
38
+
39
+ # Converts html output produced by citeproc to asciidoc markup
40
+ module StringHtmlToAsciiDoc
41
+ def html_to_asciidoc
42
+ r = self.gsub(/<\/?i>/, '_')
43
+ r = r.gsub(/<\/?b>/, '*')
44
+ r = r.gsub(/<\/?span.*?>/, '')
45
+ r = r.gsub(/\{|\}/, '')
46
+ r
47
+ end
48
+ end
49
+
50
+ # Provides a check that a string is in integer
51
+ # Taken from:
52
+ # http://stackoverflow.com/questions/1235863/test-if-a-string-is-basically-an-integer-in-quotes-using-ruby
53
+ module IntegerCheck
54
+ def is_i?
55
+ !!(self =~ /^[-+]?[0-9]+$/)
56
+ end
57
+ end
58
+
59
+ # monkey patch the extension methods into String
60
+ class String
61
+ include StringHtmlToAsciiDoc
62
+ include IntegerCheck
63
+ end
64
+
@@ -0,0 +1,32 @@
1
+ #
2
+ # filehandlers.rb
3
+ # Contains top-level file utility methods
4
+ #
5
+
6
+ module AsciidoctorBibliography
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
+
@@ -0,0 +1,31 @@
1
+ module AsciidoctorBibliography
2
+ class Index
3
+ attr_reader :parent, :target, :attrs, :uuid
4
+
5
+ def initialize(parent, target, attrs, uuid)
6
+ @parent = parent
7
+ @target = target
8
+ @attrs = attrs
9
+ @uuid = uuid
10
+ end
11
+
12
+ def placeholder
13
+ "{#{uuid}}"
14
+ end
15
+
16
+ # attr_reader :ref, :pages
17
+
18
+ # def initialize ref, pages
19
+ # @ref = ref
20
+ # @pages = pages
21
+ # # clean up pages
22
+ # @pages = '' unless @pages
23
+ # @pages.gsub!("--","-")
24
+ # end
25
+
26
+ # def to_s
27
+ # "#{@ref}:#{@pages}"
28
+ # end
29
+ end
30
+ end
31
+