utilities.rb 4.95 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
      def bibtex_options
Artem Shinkarov's avatar
Artem Shinkarov committed
43
        @bibtex_options ||= { :strip => false }
44
      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
        # return as is if it is an absolute path
        return name if name.start_with?('/') && File.exists?(name)
76

77 78 79 80
        p = File.join(config['source'], name)
        p << '.bib' unless File.exists?(p)
        p
      end
81

82
      def reference_tag(entry)
Sylvester Keil's avatar
Sylvester Keil committed
83
        return missing_reference unless entry
84

Artem Shinkarov's avatar
Artem Shinkarov committed
85
        entry = entry.convert(:latex)
86 87 88
        reference = CiteProc.process entry.to_citeproc,
          :style => config['style'], :locale => config['locale'], :format => 'html'

Sylvester Keil's avatar
Sylvester Keil committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
        content_tag reference_tagname, reference,
          :id => [prefix, entry.key].compact.join('-')
      end

      def missing_reference
        config['missing_reference']
      end

      def reference_tagname
        config['reference_tagname'] || :span
      end

      def bibliography_template
        config['bibliography_template'] || '%{reference}'
      end

105
      def bibliography_tag(entry, index)
Sylvester Keil's avatar
Sylvester Keil committed
106 107 108 109
        return missing_reference unless entry

        bibliography_template % {
          :reference => reference_tag(entry),
110 111
          :key => entry.key,
          :index => index
Sylvester Keil's avatar
Sylvester Keil committed
112
        }
113 114
      end

115 116 117
      def generate_details?
        site.layouts.key?(File.basename(config['details_layout'], '.html'))
      end
118

119 120
      def details_file_for(entry)
        name = entry.key.to_s.dup
121

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

124 125
        [name, 'html'].join('.')
      end
126

Sylvester Keil's avatar
Sylvester Keil committed
127
      def details_link_for(entry, base = base_url)
128
        File.join(base, details_path, details_file_for(entry))
Sylvester Keil's avatar
Sylvester Keil committed
129
      end
130

Sylvester Keil's avatar
Sylvester Keil committed
131
      def base_url
132
        @base_url ||= site.config['baseurl'] || site.config['base_url'] || ''
133
      end
134

135 136 137
      def details_path
        config['details_dir']
      end
138

Sylvester Keil's avatar
Sylvester Keil committed
139
      def cite(key)
140 141 142
        context['cited'] ||= []
        context['cited'] << key

Sylvester Keil's avatar
Sylvester Keil committed
143
        if bibliography.key?(key)
144
          entry = bibliography[key].convert(:latex)
Sylvester Keil's avatar
Sylvester Keil committed
145 146
          citation = CiteProc.process entry.to_citeproc, :style => config['style'],
            :locale => config['locale'], :format => 'html', :mode => :citation
147

148
          link_to "##{[prefix, entry.key].compact.join('-')}", citation.join
Sylvester Keil's avatar
Sylvester Keil committed
149
        else
150
          '(missing reference)'
Sylvester Keil's avatar
Sylvester Keil committed
151
        end
152 153
      rescue
        "(#{key})"
Sylvester Keil's avatar
Sylvester Keil committed
154
      end
Sylvester Keil's avatar
Sylvester Keil committed
155

156
      def cite_details(key, text)
Hiren Patel's avatar
Hiren Patel committed
157
        if bibliography.key?(key)
Sylvester Keil's avatar
Sylvester Keil committed
158
          link_to details_link_for(bibliography[key]), text || config['details_link']
Hiren Patel's avatar
Hiren Patel committed
159
        else
160
          '(missing reference)'
Hiren Patel's avatar
Hiren Patel committed
161 162
        end
      end
163

Sylvester Keil's avatar
Sylvester Keil committed
164 165 166 167 168 169
      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
170

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

Sylvester Keil's avatar
Sylvester Keil committed
173 174 175 176 177 178
        if content.nil?
          "<#{[name, attributes].flatten.compact.join(' ')}/>"
        else
          "<#{[name, attributes].flatten.compact.join(' ')}>#{content}</#{name}>"
        end
      end
179

Sylvester Keil's avatar
Sylvester Keil committed
180 181 182
      def link_to(href, content, attributes = {})
        content_tag :a, content || href, attributes.merge(:href => href)
      end
183

184 185 186 187
      def cited_references
        context && context['cited'] || []
      end

Sylvester Keil's avatar
Sylvester Keil committed
188
      def set_context_to(context)
189
        @context, @site, = context, context.registers[:site]
Sylvester Keil's avatar
Sylvester Keil committed
190 191
        config.merge!(site.config['scholar'] || {})
      end
192
    end
193

194
  end
Hiren Patel's avatar
Hiren Patel committed
195
end