utilities.rb 4.32 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
        return name if File.exists?(name)

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

81 82 83 84 85 86 87 88 89
      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

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

94 95
      def details_file_for(entry)
        name = entry.key.to_s.dup
96

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

99 100
        [name, 'html'].join('.')
      end
101

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

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

110 111 112
      def details_path
        config['details_dir']
      end
113

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

117 118 119
        context['cited'] ||= []
        context['cited'] << key

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

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

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

Sylvester Keil's avatar
Sylvester Keil committed
140 141 142 143 144 145
      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
146

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

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

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

160 161 162 163
      def cited_references
        context && context['cited'] || []
      end

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

170
  end
Hiren Patel's avatar
Hiren Patel committed
171
end