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