class AsciidoctorBibtex::Asciidoctor::CitationProcessor
A tree processor to replace all citations and bibliography.
This processor scans the document, generates a list of citations, replaces each citation with citation text and the reference block macro placeholder with the final bibliography list. It relys on the block macro processor to generate the place holder.
NOTE: According to the asiidoctor extension policy, the tree processor can only produce texts with inline macros.
Public Instance Methods
parse_asciidoc(parent, content, attributes = {})
click to toggle source
This is an adapted version of Asciidoctor::Extension::parse_content, where resultant blocks are returned as a list instead of attached to the parent.
# File lib/asciidoctor-bibtex/extensions.rb, line 181 def parse_asciidoc(parent, content, attributes = {}) result = [] reader = ::Asciidoctor::Reader.new content while reader.has_more_lines? block = ::Asciidoctor::Parser.next_block reader, parent, attributes result << block if block end result end
process(document)
click to toggle source
# File lib/asciidoctor-bibtex/extensions.rb, line 63 def process(document) bibtex_file = (document.attr 'bibtex-file').to_s bibtex_style = ((document.attr 'bibtex-style') || 'ieee').to_s bibtex_locale = ((document.attr 'bibtex-locale') || 'en-US').to_s bibtex_order = ((document.attr 'bibtex-order') || 'appearance').to_sym bibtex_format = ((document.attr 'bibtex-format') || 'asciidoc').to_sym bibtex_throw = ((document.attr 'bibtex-throw') || 'false').to_s.downcase bibtex_citation_template = ((document.attr 'bibtex-citation-template') || '[$id]').to_s # Fild bibtex file automatically if not supplied. if bibtex_file.empty? bibtex_file = AsciidoctorBibtex::PathUtils.find_bibfile document.base_dir end if bibtex_file.empty? bibtex_file = AsciidoctorBibtex::PathUtils.find_bibfile '.' end if bibtex_file.empty? bibtex_file = AsciidoctorBibtex::PathUtils.find_bibfile "#{ENV['HOME']}/Documents" end if bibtex_file.empty? puts 'Error: bibtex-file is not set and automatic search failed' exit end # Extract all AST nodes that can contain citations. prose_blocks = document.find_by do |b| (b.content_model == :simple) || (b.context == :list_item) || (b.context == :table_cell) || (b.title?) end return nil if prose_blocks.nil? processor = Processor.new bibtex_file, true, bibtex_style, bibtex_locale, bibtex_order == :appearance, bibtex_format, bibtex_throw == 'true', custom_citation_template: bibtex_citation_template # First pass: extract all citations. prose_blocks.each do |block| if block.context == :list_item || block.context == :table_cell # NOTE: we access the instance variable @text for raw text. # Otherwise the footnotes in the text will be pre-processed and # ghost footnotes will be inserted (as of asciidoctor 2.0.10). line = block.instance_variable_get(:@text) unless line.nil? || line.empty? processor.process_citation_macros line end elsif block.content_model == :simple block.lines.each do |line| processor.process_citation_macros line end else line = block.instance_variable_get(:@title) processor.process_citation_macros line end end # Make processor finalize macro processing as required. processor.finalize_macro_processing # Second pass: replace citations with citation texts. prose_blocks.each do |block| if block.context == :list_item || block.context == :table_cell # NOTE: we access the instance variable @text for raw text. line = block.instance_variable_get(:@text) unless line.nil? or line.empty? line = processor.replace_citation_macros(line) line = processor.replace_bibitem_macros(line) block.text = line end elsif block.content_model == :simple block.lines.each_with_index do |line, index| line = processor.replace_citation_macros(line) line = processor.replace_bibitem_macros(line) block.lines[index] = line end else # NOTE: we access the instance variable @text for raw text. line = block.instance_variable_get(:@title) line = processor.replace_citation_macros(line) line = processor.replace_bibitem_macros(line) block.title = line end end references_asciidoc = [] if (bibtex_format == :latex) || (bibtex_format == :bibtex) references_asciidoc << %(+++\\bibliography{#{bibtex_file}}{}+++) references_asciidoc << %(+++\\bibliographystyle{#{bibtex_style}}+++) elsif bibtex_format == :biblatex references_asciidoc << %(+++\\printbibliography+++) else references_asciidoc = processor.build_bibliography_list end # Third pass: replace the bibliography paragraph with the bibliography # list. biblio_blocks = document.find_by do |b| # for fast search (since most searches shall fail) (b.content_model == :simple) && (b.lines.size == 1) \ && (b.lines[0] == BibliographyBlockMacroPlaceholder) end biblio_blocks.each do |block| block_index = block.parent.blocks.index do |b| b == block end reference_blocks = parse_asciidoc block.parent, references_asciidoc reference_blocks.reverse.each do |b| block.parent.blocks.insert block_index, b end block.parent.blocks.delete_at block_index + reference_blocks.size end nil end