utilities.rb 4.27 KB
Newer Older
Sylvester Keil's avatar
Sylvester Keil committed
1
module Jekyll
2
  class Scholar
3

4 5 6 7
    # Utility methods used by several Scholar plugins. The methods in this
    # module may depend on the presence of #config, #bibtex_file, and
    # #site readers
    module Utilities
8

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
      attr_reader :bibtex_file, :config, :site, :query,
        :context, :prefix, :key, :text

      def optparse(arguments)
        return if arguments.nil? || arguments.empty?

        parser = OptionParser.new do |opts|
          opts.on('-c', '--cited') do |cited|
            @cited = true
          end

          opts.on('-f', '--file FILE') do |file|
            @bibtex_file = file
          end

          opts.on('-q', '--query QUERY') do |query|
            @query = query
          end

          opts.on('-p', '--prefix PREFIX') do |prefix|
            @prefix = prefix
          end

          opts.on('-t', '--text TEXT') do |text|
            @text = text
          end
        end

        argv = arguments.split(/(\B-[cfqpt]|\B--(?:cited|file|query|prefix|text))/)

        parser.parse argv.map(&:strip).reject(&:empty?)
      end
41

42 43 44
      def bibtex_options
        @bibtex_options ||= { :filter => :latex }
      end
45

46 47 48
      def bibtex_path
        @bibtex_path ||= extend_path(bibtex_file)
      end
49

50 51
      def bibliography
        @bibliography ||= BibTeX.open(bibtex_path, bibtex_options)
52 53
      end

54
      def entries
55
        b = bibliography[query || config['query']]
56 57

        unless config['sort_by'] == 'none'
58
          b = b.sort_by { |e| e[config['sort_by']].to_s }
59 60
          b.reverse! if config['order'] =~ /^(desc|reverse)/i
        end
61

62 63
        b
      end
64

65 66 67 68
      def cited_only?
        !!@cited
      end

69 70 71 72
      def extend_path(name)
        if name.nil? || name.empty?
          name = config['bibliography']
        end
73

74 75 76 77
        p = File.join(config['source'], name)
        p << '.bib' unless File.exists?(p)
        p
      end
78

79 80 81 82 83 84 85 86 87
      def reference_tag(entry)
        return '(missing reference)' unless entry

        reference = CiteProc.process entry.to_citeproc,
          :style => config['style'], :locale => config['locale'], :format => 'html'

        content_tag :span, reference, :id => [prefix, entry.key].compact.join('-')
      end

88 89 90
      def generate_details?
        site.layouts.key?(File.basename(config['details_layout'], '.html'))
      end
91

92 93
      def details_file_for(entry)
        name = entry.key.to_s.dup
94

95
        name.gsub!(/[:\s]+/, '_')
96

97 98
        [name, 'html'].join('.')
      end
99

Sylvester Keil's avatar
Sylvester Keil committed
100
      def details_link_for(entry, base = base_url)
101
        File.join(base, details_path, details_file_for(entry))
Sylvester Keil's avatar
Sylvester Keil committed
102
      end
103

Sylvester Keil's avatar
Sylvester Keil committed
104
      def base_url
105
        @base_url ||= site.config['baseurl'] || site.config['base_url'] || ''
106
      end
107

108 109 110
      def details_path
        config['details_dir']
      end
111

Sylvester Keil's avatar
Sylvester Keil committed
112 113 114
      def cite(key)
        entry = bibliography[key]

115 116 117
        context['cited'] ||= []
        context['cited'] << key

Sylvester Keil's avatar
Sylvester Keil committed
118 119 120
        if bibliography.key?(key)
          citation = CiteProc.process entry.to_citeproc, :style => config['style'],
            :locale => config['locale'], :format => 'html', :mode => :citation
121

122
          link_to "##{[prefix, entry.key].compact.join('-')}", citation.join
Sylvester Keil's avatar
Sylvester Keil committed
123
        else
124
          '(missing reference)'
Sylvester Keil's avatar
Sylvester Keil committed
125
        end
126 127
      rescue
        "(#{key})"
Sylvester Keil's avatar
Sylvester Keil committed
128
      end
Sylvester Keil's avatar
Sylvester Keil committed
129

130
      def cite_details(key, text)
Hiren Patel's avatar
Hiren Patel committed
131
        if bibliography.key?(key)
Sylvester Keil's avatar
Sylvester Keil committed
132
          link_to details_link_for(bibliography[key]), text || config['details_link']
Hiren Patel's avatar
Hiren Patel committed
133
        else
134
          '(missing reference)'
Hiren Patel's avatar
Hiren Patel committed
135 136
        end
      end
137

Sylvester Keil's avatar
Sylvester Keil committed
138 139 140 141 142 143
      def content_tag(name, content_or_attributes, attributes = {})
        if content_or_attributes.is_a?(Hash)
          content, attributes = nil, content_or_attributes
        else
          content = content_or_attributes
        end
144

Sylvester Keil's avatar
Sylvester Keil committed
145
        attributes = attributes.map { |k,v| %Q(#{k}="#{v}") }
146

Sylvester Keil's avatar
Sylvester Keil committed
147 148 149 150 151 152
        if content.nil?
          "<#{[name, attributes].flatten.compact.join(' ')}/>"
        else
          "<#{[name, attributes].flatten.compact.join(' ')}>#{content}</#{name}>"
        end
      end
153

Sylvester Keil's avatar
Sylvester Keil committed
154 155 156
      def link_to(href, content, attributes = {})
        content_tag :a, content || href, attributes.merge(:href => href)
      end
157

158 159 160 161
      def cited_references
        context && context['cited'] || []
      end

Sylvester Keil's avatar
Sylvester Keil committed
162
      def set_context_to(context)
163
        @context, @site, = context, context.registers[:site]
Sylvester Keil's avatar
Sylvester Keil committed
164 165
        config.merge!(site.config['scholar'] || {})
      end
166
    end
167

168
  end
Hiren Patel's avatar
Hiren Patel committed
169
end