Skip to content

Commit

Permalink
Implement export citation popup (#1375)
Browse files Browse the repository at this point in the history
Main changes:

* Add modal popup for citation formats

* Add graphical feedback when successfully copying to clipboard

* Replace "Bib Export" row with copy-to-clipboard buttons

* Fix subtle bug in as_dict
  • Loading branch information
Marcel Bollmann authored Jun 25, 2021
1 parent 63f9c22 commit dd57942
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 18 deletions.
6 changes: 5 additions & 1 deletion bin/anthology/anthology.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ def import_file(self, filename):
collection_id = collection.get("id")
for volume_xml in collection:
volume = Volume.from_xml(
volume_xml, collection_id, self.venues, self.sigs, self.formatter
volume_xml,
collection_id,
self.venues,
self.sigs,
self.formatter,
)

# MJP 2021-05: no longer doing this since it kills branch previews.
Expand Down
5 changes: 3 additions & 2 deletions bin/anthology/papers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import iso639
import logging as log

from .utils import (
build_anthology_id,
parse_element,
Expand All @@ -27,7 +28,7 @@
)
from . import data

# For BibTeX export
# For bibliography export
from .formatter import bibtex_encode, bibtex_make_entry


Expand Down Expand Up @@ -316,7 +317,7 @@ def as_bibtex(self, concise=False):
return bibtex_make_entry(bibkey, bibtype, entries)

def as_dict(self):
value = self.attrib
value = self.attrib.copy()
value["paper_id"] = self.paper_id
value["parent_volume_id"] = self.parent_volume_id
value["bibkey"] = self.bibkey
Expand Down
11 changes: 10 additions & 1 deletion bin/anthology/venues.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
class VenueIndex:
def __init__(self, srcdir=None):
self.venues, self.letters, self.joint_map = {}, {}, defaultdict(list)
self.acronyms_by_key = {}
self.acronyms = {} # acronym -> venue
self.acronyms_by_key = {} # slug -> acronym
self.venue_dict = None
if srcdir is not None:
self.load_from_dir(srcdir)
Expand Down Expand Up @@ -96,6 +97,7 @@ def load_from_dir(self, directory):
# encapsulation --MB)
self.venues[val["acronym"]] = val
self.acronyms_by_key[key] = val["acronym"]
self.acronyms[val["acronym"]] = val

if "oldstyle_letter" in val:
if not val["is_toplevel"]:
Expand Down Expand Up @@ -123,6 +125,13 @@ def get_by_letter(self, letter):
"""Get a venue acronym by first letter (e.g., Q -> TACL)."""
return self.letters.get(letter, None)

def get_by_acronym(self, acronym):
"""Get a venue object by its acronym (assumes acronyms are unique)."""
try:
return self.acronyms[acronym]
except KeyError:
log.critical(f"Unknown venue acronym: {acronym}")

def get_main_venue(self, anthology_id):
"""Get a venue acronym by anthology ID (e.g., acl -> ACL)."""
collection_id, volume_id, _ = deconstruct_anthology_id(anthology_id)
Expand Down
1 change: 1 addition & 0 deletions bin/anthology/volumes.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def __init__(
self._id = volume_id
self.ingest_date = ingest_date
self.formatter = formatter
self.venue_index = venue_index
self._set_meta_info(meta_data)
self.attrib["venues"] = venue_index.get_associated_venues(self.full_id)
self.attrib["sigs"] = sig_index.get_associated_sigs(self.full_id)
Expand Down
2 changes: 1 addition & 1 deletion hugo/assets/css/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ $theme-colors: map-merge(
@import 'vendor/bootstrap/scss/list-group';
@import 'vendor/bootstrap/scss/close';
// @import 'vendor/bootstrap/scss/toasts';
// @import 'vendor/bootstrap/scss/modal';
@import 'vendor/bootstrap/scss/modal';
@import 'vendor/bootstrap/scss/tooltip';
// @import 'vendor/bootstrap/scss/popover';
// @import 'vendor/bootstrap/scss/carousel';
Expand Down
117 changes: 104 additions & 13 deletions hugo/layouts/papers/single.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,34 @@
<script>
$( document ).ready(function() {
if (ClipboardJS.isSupported()) {
new ClipboardJS(".btn-clipboard");
success_fn = function(e) {
// turns button into "copy successful"-style for 2 seconds
var src = $(e.trigger);
src.toggleClass("btn-success");
src.children("i").toggleClass("far fa-clipboard fas fa-clipboard-check");
e.clearSelection();

setTimeout(function() {
src.toggleClass("btn-success");
src.children("i").toggleClass("far fa-clipboard fas fa-clipboard-check");
}, 2000);
};

var clipboard = new ClipboardJS(".btn-clipboard");
clipboard.on('success', success_fn);
$(".btn-clipboard").removeClass("d-none");

// buttons outside the "cite" popup can't copy the content the usual way
// because the content element is hidden at the time; therefore we fetch
// and return the text to be copied manually
var clipboard_outside = new ClipboardJS(".btn-clipboard-outside", {
text: function(trigger) {
var target = trigger.getAttribute("data-clipboard-target");
return $(target).text();
}
});
clipboard_outside.on('success', success_fn);
$(".btn-clipboard-outside").removeClass("d-none");
}
});
</script>
Expand All @@ -51,6 +77,9 @@
{{ $anthology_id := .Params.anthology_id }}
{{ $volume_id := index (split .Params.anthology_id "-") 0 }}
{{ $paper := index (index .Site.Data.papers $volume_id) .Params.anthology_id }}
{{ $has_bib := fileExists (printf "/data-export/%s.bib" $anthology_id) }}
{{ $has_xml := fileExists (printf "/data-export/%s.xml" $anthology_id) }}
{{ $has_endf := fileExists (printf "/data-export/%s.endf" $anthology_id) }}
<section id="main">
<h2 id="title">
{{ with $paper.pdf }}
Expand Down Expand Up @@ -159,19 +188,19 @@ <h5 class="card-title">Abstract</h5>
<dt>Bibkey:</dt>
<dd>{{ with $paper.bibkey }}{{ . }}{{ end }}</dd>
-->
<dt class="acl-button-row">Bib Export formats:</dt>
<dt class="acl-button-row">Copy Citation:</dt>
<dd class="acl-button-row">
{{ if (fileExists (printf "/data-export/%s.bib" $anthology_id)) }}
<a class="btn btn-secondary btn-sm" href="{{ (printf "/%s.bib" $anthology_id) | relURL }}">BibTeX</a>
{{ if $has_bib }}
<button type="button" class="btn btn-clipboard-outside btn-secondary btn-sm d-none" data-clipboard-target="#citeBibtexContent"><i class="far fa-clipboard pr-2"></i>BibTeX</button>
{{ end }}
{{ if (fileExists (printf "/data-export/%s.xml" $anthology_id)) }}
<a class="btn btn-secondary btn-sm" href="{{ (printf "/%s.xml" $anthology_id) | relURL }}">MODS XML</a>
{{ if $has_xml }}
<button type="button" class="btn btn-clipboard-outside btn-secondary btn-sm d-none" data-clipboard-target="#citeModsContent"><i class="far fa-clipboard pr-2"></i>MODS XML</button>
{{ end }}
{{ if (fileExists (printf "/data-export/%s.endf" $anthology_id)) }}
<a class="btn btn-secondary btn-sm" href="{{ (printf "/%s.endf" $anthology_id) | relURL }}">EndNote</a>
{{ if $has_endf }}
<button type="button" class="btn btn-clipboard-outside btn-secondary btn-sm d-none" data-clipboard-target="#citeEndnoteContent"><i class="far fa-clipboard pr-2"></i>Endnote</button>
{{ end }}
{{ if (fileExists (printf "/data-export/%s.bib" $anthology_id)) }}
<button type="button" class="btn btn-clipboard btn-secondary btn-sm d-none" data-clipboard-text="{{ readFile (printf "/data-export/%s.bib" $anthology_id) }}"><i class="far fa-clipboard pr-2"></i>Copy BibTeX to Clipboard</button>
{{ if (or $has_bib $has_xml $has_endf) }}
<button type="button" class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#citeModal">More options…</button>
{{ end }}
</dd>

Expand Down Expand Up @@ -206,9 +235,9 @@ <h5 class="card-title">Abstract</h5>
</a>
{{ end }}
{{ end }}
{{ if (fileExists (printf "/data-export/%s.bib" $anthology_id)) }}
<a class="btn btn-secondary" href="{{ (printf "/%s.bib" $anthology_id) | relURL }}" title="Export '{{ $paper.title | htmlEscape }}' to bib format">
<i class="fas fa-file-export"></i><span class="pl-2 transform-lower-sm">Bib</span><span class="d-none d-sm-inline">TeX</span>
{{ if (or $has_bib $has_xml $has_endf) }}
<a class="btn btn-secondary" title="Open dialog for exporting citations" data-toggle="modal" data-target="#citeModal" href="#">
<i class="fas fa-quote-left"></i><span class="pl-2">Cite</span>
</a>
{{ end }}
<a class="btn btn-secondary" href="https://scholar.google.com/scholar?{{ (querify "q" $paper.title) | safeURL }}" title="Search for '{{ $paper.title | htmlEscape }}' on Google Scholar">
Expand All @@ -223,5 +252,67 @@ <h5 class="card-title">Abstract</h5>
</div>
</div>
<hr />

<div class="modal fade" id="citeModal" tabindex="-1" role="dialog" aria-labelledby="citeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="citeModalLabel">Export citation</h5>
<button class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs mb-2" id="citeFormats" role="tablist">
<li class="nav-item">
<a class="nav-link {{ if not $has_bib }}disabled{{ else }}active{{ end }}" data-toggle="list" href="#citeBibtex" role="tab" aria-controls="citeBibtex" aria-selected="{{ if $has_bib }}true{{ else }}false{{ end }}">BibTeX</a>
</li>
<li class="nav-item">
<a class="nav-link {{ if not $has_xml }}disabled{{ end }}" data-toggle="list" href="#citeMods" role="tab" aria-controls="citeMods" aria-selected="false">MODS XML</a>
</li>
<li class="nav-item">
<a class="nav-link {{ if not $has_endf }}disabled{{ end }}" data-toggle="list" href="#citeEndnote" role="tab" aria-controls="citeEndnote" aria-selected="false">Endnote</a>
</li>
</ul>

<div class="tab-content" id="citeFormatsContent">
<div class="tab-pane active" id="citeBibtex" role="tabpanel">
{{- if $has_bib -}}
<pre id="citeBibtexContent" class="bg-light border p-2" style="max-height: 50vh;">
{{- readFile (printf "/data-export/%s.bib" $anthology_id) -}}
</pre>
<div class="modal-footer pb-1">
<a class="btn btn-secondary" href="{{ (printf "/%s.bib" $anthology_id) | relURL }}"><i class="fas fa-download pr-2"></i>Download as File</a>
<button class="btn btn-clipboard btn-primary d-none" data-clipboard-target="#citeBibtexContent"><i class="far fa-clipboard pr-2"></i>Copy to Clipboard</button>
</div>
{{- end -}}
</div>
<div class="tab-pane" id="citeMods" role="tabpanel">
{{- if $has_xml -}}
<pre id="citeModsContent" class="bg-light border p-2" style="max-height: 50vh;">
{{- readFile (printf "/data-export/%s.xml" $anthology_id) -}}
</pre>
<div class="modal-footer pb-1">
<a class="btn btn-secondary" href="{{ (printf "/%s.xml" $anthology_id) | relURL }}"><i class="fas fa-download pr-2"></i>Download as File</a>
<button class="btn btn-clipboard btn-primary d-none" data-clipboard-target="#citeModsContent"><i class="far fa-clipboard pr-2"></i>Copy to Clipboard</button>
</div>
{{- end -}}
</div>
<div class="tab-pane" id="citeEndnote" role="tabpanel">
{{- if $has_endf -}}
<pre id="citeEndnoteContent" class="bg-light border p-2" style="max-height: 50vh;">
{{- readFile (printf "/data-export/%s.endf" $anthology_id) -}}
</pre>
<div class="modal-footer pb-1">
<a class="btn btn-secondary" href="{{ (printf "/%s.endf" $anthology_id) | relURL }}"><i class="fas fa-download pr-2"></i>Download as File</a>
<button class="btn btn-clipboard btn-primary d-none" data-clipboard-target="#citeEndnoteContent"><i class="far fa-clipboard pr-2"></i>Copy to Clipboard</button>
</div>
{{- end -}}
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{{ end }}

0 comments on commit dd57942

Please sign in to comment.