Module: Jekyll::Scholar::Utilities

Included in:
BibTeXConverter, BibTeXTag, BibliographyTag, CiteDetailsTag, CiteTag, Details, DetailsGenerator, QuoteTag, ReferenceTag
Defined in:
lib/jekyll/scholar/utilities.rb

Overview

Utility methods used by several Scholar plugins. The methods in this module may depend on the presence of #config, #bibtex_files, and #site readers

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



17
18
19
# File 'lib/jekyll/scholar/utilities.rb', line 17

def config
  @config
end

#contextObject (readonly)

Returns the value of attribute context.



17
18
19
# File 'lib/jekyll/scholar/utilities.rb', line 17

def context
  @context
end

#maxObject (readonly)

Returns the value of attribute max.



17
18
19
# File 'lib/jekyll/scholar/utilities.rb', line 17

def max
  @max
end

#prefixObject (readonly)

Returns the value of attribute prefix.



17
18
19
# File 'lib/jekyll/scholar/utilities.rb', line 17

def prefix
  @prefix
end

#siteObject (readonly)

Returns the value of attribute site.



17
18
19
# File 'lib/jekyll/scholar/utilities.rb', line 17

def site
  @site
end

#textObject (readonly)

Returns the value of attribute text.



17
18
19
# File 'lib/jekyll/scholar/utilities.rb', line 17

def text
  @text
end

Instance Method Details

#base_urlObject



316
317
318
# File 'lib/jekyll/scholar/utilities.rb', line 316

def base_url
  @base_url ||= site.config['baseurl'] || site.config['base_url'] || ''
end

#bibliographyObject



116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/jekyll/scholar/utilities.rb', line 116

def bibliography
  unless @bibliography
    @bibliography = BibTeX.parse(
      bibtex_paths.reduce('') { |s, p| s << IO.read(p) },
      bibtex_options
    )
    @bibliography.replace_strings if replace_strings?
    @bibliography.join if join_strings? && replace_strings?
  end

  @bibliography
end

#bibliography_tag(entry, index) ⇒ Object



248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/jekyll/scholar/utilities.rb', line 248

def bibliography_tag(entry, index)
  return missing_reference unless entry

  liquid_template.render({
    'entry' => liquidify(entry),
    'reference' => reference_tag(entry, index),
    'key' => entry.key,
    'type' => entry.type.to_s,
    'link' => repository_link_for(entry),
    'links' => repository_links_for(entry),
    'index' => index,
    'details' => details_link_for(entry)
  })
end

#bibliography_templateObject



229
230
231
# File 'lib/jekyll/scholar/utilities.rb', line 229

def bibliography_template
  @bibliography_template || config['bibliography_template']
end

#bibtex_fileObject

:nodoc: backwards compatibility



93
94
95
# File 'lib/jekyll/scholar/utilities.rb', line 93

def bibtex_file
  bibtex_files[0]
end

#bibtex_filesObject



88
89
90
# File 'lib/jekyll/scholar/utilities.rb', line 88

def bibtex_files
  @bibtex_files ||= [config['bibliography']]
end

#bibtex_filtersObject



101
102
103
# File 'lib/jekyll/scholar/utilities.rb', line 101

def bibtex_filters
  config['bibtex_filters'] ||= []
end

#bibtex_optionsObject



97
98
99
# File 'lib/jekyll/scholar/utilities.rb', line 97

def bibtex_options
  config['bibtex_options'] ||= {}
end

#bibtex_pathObject

:nodoc: backwards compatibility



112
113
114
# File 'lib/jekyll/scholar/utilities.rb', line 112

def bibtex_path
  bibtex_paths[0]
end

#bibtex_pathsObject



105
106
107
108
109
# File 'lib/jekyll/scholar/utilities.rb', line 105

def bibtex_paths
  @bibtex_paths ||= bibtex_files.map { |file|
    extend_path file
  }
end

#citation_item_for(entry, citation_number = nil) ⇒ Object



346
347
348
349
350
351
352
# File 'lib/jekyll/scholar/utilities.rb', line 346

def citation_item_for(entry, citation_number = nil)
  CiteProc::CitationItem.new id: entry.id do |c|
    c.data = CiteProc::Item.new entry.to_citeproc
    c.data[:'citation-number'] = citation_number
    c.data.suppress! 'author' if suppress_author?
  end
end

#citation_number(key) ⇒ Object



358
359
360
# File 'lib/jekyll/scholar/utilities.rb', line 358

def citation_number(key)
  (context['citation_numbers'] ||= {})[key] ||= cited_keys.length
end

#cite(keys) ⇒ Object



362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/jekyll/scholar/utilities.rb', line 362

def cite(keys)
  items = keys.map do |key|
    if bibliography.key?(key)
      entry = bibliography[key]
      entry = entry.convert(*bibtex_filters) unless bibtex_filters.empty?
    else
      return missing_reference
    end
  end

  link_to "##{[prefix, keys[0]].compact.join('-')}", render_citation(items)
end

#cite_details(key, text) ⇒ Object



375
376
377
378
379
380
381
# File 'lib/jekyll/scholar/utilities.rb', line 375

def cite_details(key, text)
  if bibliography.key?(key)
    link_to details_link_for(bibliography[key]), text || config['details_link']
  else
    missing_reference
  end
end

#cited_keysObject



354
355
356
# File 'lib/jekyll/scholar/utilities.rb', line 354

def cited_keys
  context['cited'] ||= []
end

#cited_only?Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/jekyll/scholar/utilities.rb', line 186

def cited_only?
  !!@cited
end

#cited_referencesObject



403
404
405
# File 'lib/jekyll/scholar/utilities.rb', line 403

def cited_references
  context && context['cited'] || []
end

#content_tag(name, content_or_attributes, attributes = {}) ⇒ Object



383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/jekyll/scholar/utilities.rb', line 383

def (name, content_or_attributes, attributes = {})
  if content_or_attributes.is_a?(Hash)
    content, attributes = nil, content_or_attributes
  else
    content = content_or_attributes
  end

  attributes = attributes.map { |k,v| %Q(#{k}="#{v}") }

  if content.nil?
    "<#{[name, attributes].flatten.compact.join(' ')}/>"
  else
    "<#{[name, attributes].flatten.compact.join(' ')}>#{content}</#{name}>"
  end
end

#details_file_for(entry) ⇒ Object



289
290
291
292
293
294
295
# File 'lib/jekyll/scholar/utilities.rb', line 289

def details_file_for(entry)
  name = entry.key.to_s.dup

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

  [name, 'html'].join('.')
end


312
313
314
# File 'lib/jekyll/scholar/utilities.rb', line 312

def details_link_for(entry, base = base_url)
  File.join(base, details_path, details_file_for(entry))
end

#details_pathObject



320
321
322
# File 'lib/jekyll/scholar/utilities.rb', line 320

def details_path
  config['details_dir']
end

#entriesObject



133
134
135
# File 'lib/jekyll/scholar/utilities.rb', line 133

def entries
  sort bibliography[query || config['query']]
end

#extend_path(name) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/jekyll/scholar/utilities.rb', line 194

def extend_path(name)
  if name.nil? || name.empty?
    name = config['bibliography']
  end

  # return as is if it is an absolute path
  return name if name.start_with?('/') && File.exists?(name)

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

#generate_details?Boolean

Returns:

  • (Boolean)


285
286
287
# File 'lib/jekyll/scholar/utilities.rb', line 285

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

#interpolate(string) ⇒ Object



416
417
418
419
420
421
422
# File 'lib/jekyll/scholar/utilities.rb', line 416

def interpolate(string)
  return unless string

  string.gsub(/{{\s*([\w\.]+)\s*}}/) do |match|
    context.send(:resolve, $1) || match
  end
end

#join_strings?Boolean

Returns:

  • (Boolean)


182
183
184
# File 'lib/jekyll/scholar/utilities.rb', line 182

def join_strings?
  config['join_strings']
end

#keysObject



407
408
409
410
411
412
413
414
# File 'lib/jekyll/scholar/utilities.rb', line 407

def keys
  # De-reference keys (in case they are variables)
  # We need to do this every time, to support for loops,
  # where the context can change for each invocation.
  Array(@keys).map do |key|
    context.send(:resolve, key) || key
  end
end

#limit_entries?Boolean

Returns:

  • (Boolean)


137
138
139
# File 'lib/jekyll/scholar/utilities.rb', line 137

def limit_entries?
  !max.nil?
end


399
400
401
# File 'lib/jekyll/scholar/utilities.rb', line 399

def link_to(href, content, attributes = {})
   :a, content || href, attributes.merge(:href => href)
end

#liquid_templateObject



233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/jekyll/scholar/utilities.rb', line 233

def liquid_template
  return @liquid_template if @liquid_template

  tmp = bibliography_template

  case
  when tmp.nil?, tmp.empty?
    tmp = '{{reference}}'
  when site.layouts.key?(tmp)
    tmp = site.layouts[tmp].content
  end

  @liquid_template = Liquid::Template.parse(tmp)
end

#liquidify(entry) ⇒ Object



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/jekyll/scholar/utilities.rb', line 263

def liquidify(entry)
  e = {}

  e['key'] = entry.key
  e['type'] = entry.type.to_s

  if entry.field?(:abstract)
    tmp = entry.dup
    tmp.delete :abstract
    e['bibtex'] = tmp.to_s
  else
    e['bibtex'] = entry.to_s
  end

  entry.fields.each do |key, value|
    value = value.convert(*bibtex_filters) unless bibtex_filters.empty?
    e[key.to_s] = value.to_s
  end

  e
end

#load_repositoryObject



161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/jekyll/scholar/utilities.rb', line 161

def load_repository
  repo = Hash.new { |h,k| h[k] = {} }

  return repo unless repository?

  Dir[File.join(repository_path, '**/*')].each do |path|
    extname = File.extname(path)
    repo[File.basename(path, extname)][extname[1..-1]] = path
  end

  repo
end

#locatorsObject



84
85
86
# File 'lib/jekyll/scholar/utilities.rb', line 84

def locators
  @locators ||= []
end

#missing_referenceObject



221
222
223
# File 'lib/jekyll/scholar/utilities.rb', line 221

def missing_reference
  config['missing_reference']
end

#optparse(arguments) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/jekyll/scholar/utilities.rb', line 29

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('-C', '--cited_in_order') do |cited|
      @cited, @skip_sort = true, true
    end

    opts.on('-A', '--suppress_author') do |cited|
      @suppress_author = true
    end

    opts.on('-f', '--file FILE') do |file|
      @bibtex_files ||= []
      @bibtex_files << 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

    opts.on('-l', '--locator LOCATOR') do |locator|
      locators << locator
    end

    opts.on('-m', '--max MAX') do |max|
      @max = max
    end

    opts.on('-s', '--style STYLE') do |style|
      @style = style
    end

    opts.on('-T', '--template TEMPLATE') do |template|
      @bibliography_template = template
    end
  end

  argv = arguments.split(/(\B-[cCfqptTslmA]|\B--(?:cited(_in_order)?|file|query|prefix|text|style|template|locator|max|suppress_author|))/)

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

#queryObject



129
130
131
# File 'lib/jekyll/scholar/utilities.rb', line 129

def query
  interpolate @query
end

#reference_tag(entry, index = nil) ⇒ Object



207
208
209
210
211
212
213
214
215
# File 'lib/jekyll/scholar/utilities.rb', line 207

def reference_tag(entry, index = nil)
  return missing_reference unless entry

  entry = entry.convert(*bibtex_filters) unless bibtex_filters.empty?
  reference = render_bibliography entry, index

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

#reference_tagnameObject



225
226
227
# File 'lib/jekyll/scholar/utilities.rb', line 225

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

#render_bibliography(entry, index = nil) ⇒ Object



341
342
343
344
# File 'lib/jekyll/scholar/utilities.rb', line 341

def render_bibliography(entry, index = nil)
  renderer.render citation_item_for(entry, index),
    STYLES[style].bibliography
end

#render_citation(items) ⇒ Object



329
330
331
332
333
334
335
336
337
338
339
# File 'lib/jekyll/scholar/utilities.rb', line 329

def render_citation(items)
  renderer.render items.zip(locators).map { |entry, locator|
    cited_keys << entry.key
    cited_keys.uniq!

    item = citation_item_for entry, citation_number(entry.key)
    item.locator = locator

    item
  }, STYLES[style].citation
end

#rendererObject



324
325
326
327
# File 'lib/jekyll/scholar/utilities.rb', line 324

def renderer
  @renderer ||= CiteProc::Ruby::Renderer.new :format => 'html',
    :style => style, :locale => config['locale']
end

#replace_strings?Boolean

Returns:

  • (Boolean)


178
179
180
# File 'lib/jekyll/scholar/utilities.rb', line 178

def replace_strings?
  config['replace_strings']
end

#repositoryObject



157
158
159
# File 'lib/jekyll/scholar/utilities.rb', line 157

def repository
  @repository ||= load_repository
end

#repository?Boolean

Returns:

  • (Boolean)


153
154
155
# File 'lib/jekyll/scholar/utilities.rb', line 153

def repository?
  !config['repository'].nil? && !config['repository'].empty?
end


297
298
299
300
301
302
303
304
# File 'lib/jekyll/scholar/utilities.rb', line 297

def repository_link_for(entry, base = base_url)
  links = repository[entry.key]
  url   = links['pdf'] || links['ps']

  return unless url

  File.join(base, url)
end


306
307
308
309
310
# File 'lib/jekyll/scholar/utilities.rb', line 306

def repository_links_for(entry, base = base_url)
  Hash[repository[entry.key].map { |ext, url|
    [ext, File.join(base, url)]
  }]
end

#repository_pathObject



174
175
176
# File 'lib/jekyll/scholar/utilities.rb', line 174

def repository_path
  config['repository']
end

#set_context_to(context) ⇒ Object



424
425
426
427
428
# File 'lib/jekyll/scholar/utilities.rb', line 424

def set_context_to(context)
  @context, @site, = context, context.registers[:site]
  config.merge!(site.config['scholar'] || {})
  self
end

#skip_sort?Boolean

Returns:

  • (Boolean)


190
191
192
# File 'lib/jekyll/scholar/utilities.rb', line 190

def skip_sort?
  @skip_sort || config['sort_by'] == 'none'
end

#sort(unsorted) ⇒ Object



141
142
143
144
145
146
147
# File 'lib/jekyll/scholar/utilities.rb', line 141

def sort(unsorted)
  return unsorted if skip_sort?

  sorted = unsorted.sort_by { |e| e[config['sort_by']].to_s }
  sorted.reverse! if config['order'] =~ /^(desc|reverse)/i
  sorted
end

#split_arguments(arguments) ⇒ Object



19
20
21
22
23
24
25
26
27
# File 'lib/jekyll/scholar/utilities.rb', line 19

def split_arguments(arguments)

  tokens = arguments.strip.split(/\s+/)

  args = tokens.take_while { |a| !a.start_with?('-') }
  opts = (tokens - args).join(' ')

  [args, opts]
end

#styleObject



217
218
219
# File 'lib/jekyll/scholar/utilities.rb', line 217

def style
  @style || config['style']
end

#suppress_author?Boolean

Returns:

  • (Boolean)


149
150
151
# File 'lib/jekyll/scholar/utilities.rb', line 149

def suppress_author?
  !!@suppress_author
end