Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting access to the data of a BibTeX entry #270

Open
stevecheckoway opened this issue Jul 30, 2019 · 6 comments
Open

Getting access to the data of a BibTeX entry #270

stevecheckoway opened this issue Jul 30, 2019 · 6 comments

Comments

@stevecheckoway
Copy link
Contributor

I generate my own details pages based on the url field for both historical reasons (namely, my site structure predates my use of Jekyll) and customization reasons and I think it would be helpful to be able to access a BibTeX entry's fields given just the key.

It seems like this might be possible using {% bibliography … %} with a query and a template, but I haven't yet succeeded in making that work and it seems fairly cumbersome.

I came up with an approach that seems to work (although I haven't actually done extensive testing nor tried any options like --file):

require 'jekyll-scholar'

# Usage {% bibtex_entry var = key options %}

module Jekyll
  class Scholar
    class BibTeXEntryTag < Liquid::Tag
      include Scholar::Utilities

      Syntax = /(#{Liquid::VariableSignature}+)\s*=\s*(.*)\s*/om

      attr_reader :to, :key

      def initialize(tag_name, markup, options)
        super
        if markup =~ Syntax
          @to = $1
          keys, arguments = split_arguments($2)
        else
          raise SyntaxError.new("Invalid bibtex_entry tag")
        end
        @key = keys.first
        @config = Scholar.defaults.dup
        optparse(arguments)
      end

      def render(context, output='')
        set_context_to(context)
        entry = bibliography[key]
        entry = entry.convert(*bibtex_filters) unless bibtex_filters.empty?
        context.scopes.last[@to] = liquidify(entry)
        output
      end

      def blank?
        true
      end
    end
  end
end

Liquid::Template.register_tag('bibtex_entry', Jekyll::Scholar::BibTeXEntryTag)

(Note that I just threw this together based on Liquid's assign tag and the tags in Jekyll Scholar. Using entry.to_citeproc might be a better choice.)

Does an alternative approach for this already exist? If not, is this, or something like it worth adding to Jekyll Scholar?

One thing that might be nice is to normalize the various fields by compressing spaces/newlines, removing braces, and possibly other modifications.

@inukshuk
Copy link
Owner

I might be missing something, but IIRC we do expose the full entry to the template. That is, if you define a custom template you can access any field of your entry (as well as the rendered reference string).

Looking briefly, here's a test case that uses a custom template (for complicated templates you can put them into a separate file also).

@inukshuk
Copy link
Owner

One thing that might be nice is to normalize the various fields by compressing spaces/newlines, removing braces, and possibly other modifications.

One way to do this would be by using bibtex-ruby filters (you would have to require those filters and configure jekyll-scholar to use them).

@stevecheckoway
Copy link
Contributor Author

Sorry if I wasn't clear. What I'd like is to get access to a given entry's fields. For example, I have about 30 pages that are analogous to the auto-generated details pages. Each one is a bit different in form but has some commonalities. I'd like to be able to write something like

---
---
{% bibtex_entry entry checkoway-et-al:juniper-dual-ec:ccs16 %}

# {{ entry.title }}
By {{ entry.author }}.

## Abstract
The paper abstract goes here.

## Something else
Something specific to this particular paper.

## Reference
{{ entry.bibtex }}

In fact, a lot of it is the same except for the paper-specific bits. So it'd be nice to have a _layout/paper.html that contains something like (typed without testing):

---
layout: default
---
{% bibtex_entry page.key %}
<article>
<h1 class="paper-title">{{ entry.title }}</h1>
<p>By {{ entry.author }}</p>
{{ content }}
<h2>Reference</h2>
<pre><code>{{ entry.bibtex }}</code></pre>
</article>

And then I can write the detail pages as

---
key: 'checkoway-et-al:juniper-dual-ec:ccs16'
layout: paper
---
## Abstract
The paper abstract goes here.

## Something else
Something specific to this particular paper.

Currently, I do this by duplicating all of this BibTeX information by hand. (Actually, my author situation is a bit more complex because it looks up authors by name in some site data, but the principle is the same.)

I'm not aware of a good way to do this using the currently existing Jekyll scholar tags. Maybe I could get {% bibliography %} to work with a single entry via a query (although I haven't managed that yet) and supply custom elements as well as a template, but each template would need to be unique to the file.

The template functionality seems far more suited to producing entries in a bibliography. Indeed, I make use of that functionality here with the following (somewhat complicated) template

---
---
{% assign LaTeX = '<span class="tex">L<span class="raise">a</span>T<span class="drop">e</span>X</span>' %}
<meta property="position" content="{{ index }}">
{{ reference | replace_regex: ', \(\\textbf[^)]*\)', '' | replace: '\LaTeX', LaTeX }}{% if entry.url %}
{% assign short = entry.url | replace_regex: '^.*/papers/([^/]*)/?$', '\1' %}
{% assign link = site.baseurl | append: '/papers/' | append: short %}
{% assign pdf = link | append: '/' | append: short | append: '.pdf' %}
[<a href="{{ link }}" property="url">Details</a>{% unless entry.nopdf %}, <a href="{{ pdf }}">PDF</a>{% endunless %}]{% endif %}

(As an aside, _layout seems like the wrong place to look for templates. Surely _includes is more appropriate, although it's probably too late to change that now.)

I'll take a look at the bibtex-ruby filters.

@inukshuk
Copy link
Owner

The first example above should be easy to do using a custom template and the bibliography tag, but if I understand this correctly now, you would need only one entry per page and the template would have some variations: i.e., you really just want a quick way to insert a given bibtex entry into a page and then access it in different ways, right?

In that case, a new tag along the lines of bibtex_entry is probably the best option. In any case, if you looked at detail pages and bibliography in combination with a custom liquid template already I think those were the best options currently available.

If we add something like the bibtex_entry tag, perhaps we could use a 'tag body' and always default to a variable name ('entry' or something shorter?). For example,

{% bibtex checkoway-et-al:juniper-dual-ec:ccs16 %}

# {{entry.title}}
By {{entry.author}}
...

{% endbibtex %}

I'm not sure if this actually works, but it would seem a little bit easier to understand to me that the entry is only injected into the tag's body and not into the whole page.

If you typically need a single entry per page, you could also add the id to the front-matter and routinely inject the corresponding entry into pages which set such an id.

@conghienquoc
Copy link

Hi @stevecheckoway , I'm also in the same situation as you were. How did you end up handling it? Thanks,

@stevecheckoway
Copy link
Contributor Author

@conghienquoc Looks like I never did.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants