Difference between revisions of "Gadget-Bibliography.js"
From ACES
(4 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
(function($, mw) { | (function ($, mw) { | ||
"use strict"; | "use strict"; | ||
var allowedPages = ["Publications", "Home"]; | var allowedPages = ["Publications", "Home"]; | ||
Line 28: | Line 28: | ||
document.body.removeChild(el); | document.body.removeChild(el); | ||
} | |||
function getPDF(rawBib) { | |||
var pdfMap = {} | |||
Array.from(rawBib.matchAll(/^@.+?\{(.+?),\s*(?:\n(?!@).*?)*?\npdf\s*=\s*\{(.*)\}/mg)) | |||
.forEach(function (m) { | |||
pdfMap[m[1]] = m[2] | |||
}) | |||
return pdfMap | |||
} | } | ||
Line 35: | Line 44: | ||
var dataTable = undefined; | var dataTable = undefined; | ||
var rawBib = $(e).find(".bibliography-data")[0].textContent; | var rawBib = $(e).find(".bibliography-data")[0].textContent; | ||
var pdfMap = getPDF(rawBib) | |||
var bib = Cite(rawBib); | var bib = Cite(rawBib); | ||
var data = []; | var data = []; | ||
var pageTitleIter = rawBib.matchAll(/^_pageName = \{(.+)\}\s*,?\s*$/gm); | var pageTitleIter = rawBib.matchAll(/^_pageName = \{(.+)\}\s*,?\s*$/gm); | ||
bib.data.forEach(function (entry) { | |||
bib.data.forEach(function(entry) { | |||
var linkTarget = new URL( | var linkTarget = new URL( | ||
articlePath.replace("$1", pageTitleIter.next().value[1]) | articlePath.replace("$1", pageTitleIter.next().value[1]) | ||
Line 53: | Line 62: | ||
editLink.attr("target", "_blank"); | editLink.attr("target", "_blank"); | ||
var urlData = entry.URL | |||
entry.URL = undefined | |||
entry.render = Cite(entry).format("bibliography", { | entry.render = Cite(entry).format("bibliography", { | ||
format: "html", | format: "html", | ||
Line 58: | Line 69: | ||
lang: "en-US", | lang: "en-US", | ||
}); | }); | ||
entry.URL = urlData | |||
entry.pdf = pdfMap[entry.id] | |||
if (entry.pdf) { | |||
entry.render += " " + $("<a />") | |||
.text("[PDF]") | |||
.attr( | |||
"href", | |||
new URL(articlePath.replace("$1", "Special:filepath/" + pdfMap[entry.id])).toString() | |||
) | |||
.prop('outerHTML'); | |||
} | |||
if (urlData && urlData.startsWith("http")) { | |||
entry.render += " " + $("<a />") | |||
.text("[URL]") | |||
.attr( | |||
"href", | |||
urlData | |||
) | |||
.prop('outerHTML'); | |||
} | |||
entry.pageTitle = editLink[0].outerHTML + linkEle[0].outerHTML; | entry.pageTitle = editLink[0].outerHTML + linkEle[0].outerHTML; | ||
entry.year = entry.issued["date-parts"][0][0] || 1970; | entry.year = entry.issued && entry.issued["date-parts"] && entry.issued["date-parts"][0] && entry.issued["date-parts"][0][0] || 1970; | ||
yearGroup[parseInt(entry.year)] = false; | yearGroup[parseInt(entry.year)] = false; | ||
Line 73: | Line 106: | ||
// Generate buttons | // Generate buttons | ||
var orderedYears = Object.keys(yearGroup).sort(function(x, y) { | var orderedYears = Object.keys(yearGroup).sort(function (x, y) { | ||
if (x < y) return 1; | if (x < y) return 1; | ||
if (x > y) return -1; | if (x > y) return -1; | ||
Line 82: | Line 115: | ||
dt.column("year:name").search( | dt.column("year:name").search( | ||
orderedYears | orderedYears | ||
.filter(function (e) { | |||
return yearGroup[e]; | |||
}) | |||
.join("|"), | |||
true, | true, | ||
false | false | ||
Line 91: | Line 124: | ||
dt.draw(); | dt.draw(); | ||
} | } | ||
var buttons = orderedYears.slice(0, nYearButtons).map(function(year) { | var buttons = orderedYears.slice(0, nYearButtons).map(function (year) { | ||
return { | return { | ||
text: year, | text: year, | ||
action: function(e, dt, node, config) { | action: function (e, dt, node, config) { | ||
yearGroup[year] = !yearGroup[year]; | yearGroup[year] = !yearGroup[year]; | ||
node.toggleClass("active", yearGroup[year]); | node.toggleClass("active", yearGroup[year]); | ||
Line 107: | Line 140: | ||
buttons.push({ | buttons.push({ | ||
text: "Rest", | text: "Rest", | ||
action: function(e, dt, node, config) { | action: function (e, dt, node, config) { | ||
statusRest = !statusRest; | statusRest = !statusRest; | ||
restYears.forEach(function(el) { | restYears.forEach(function (el) { | ||
yearGroup[el] = !yearGroup[el]; | yearGroup[el] = !yearGroup[el]; | ||
}); | }); | ||
Line 120: | Line 153: | ||
buttons.push({ | buttons.push({ | ||
text: "Export BibTeX", | text: "Export BibTeX", | ||
action: function(e, dt, node, config) { | action: function (e, dt, node, config) { | ||
var text = Cite(dt.rows({ page: "current" }).data().toArray()).format( | var text = Cite(dt.rows({ page: "current" }).data().toArray()).format( | ||
"bibtex" | "bibtex" | ||
Line 132: | Line 165: | ||
data: data, | data: data, | ||
columns: [{ | columns: [{ | ||
className: "cell-apa", | |||
data: "render", | |||
title: "APA", | |||
render: function (data, type, row) { | |||
// If display or filter data is requested, format the date | |||
if (type === "sort") return row.year; | |||
return data; | |||
}, | }, | ||
}, | |||
{ | |||
name: "year", | |||
data: "year", | |||
visible: false, | |||
}, | |||
], | ], | ||
paging: false, | paging: false, | ||
Line 158: | Line 192: | ||
if (!isAnon) { | if (!isAnon) { | ||
options.columns.unshift({ | options.columns.unshift({ | ||
className: "cell-pageTitle", | |||
data: "pageTitle", | data: "pageTitle", | ||
title: "In-site Page", | title: "In-site Page", | ||
Line 171: | Line 206: | ||
var Cite = window.require("citation-js"); | var Cite = window.require("citation-js"); | ||
var rawBib = $(e).find(".bibliography-data")[0].textContent; | var rawBib = $(e).find(".bibliography-data")[0].textContent; | ||
var pdfMap = getPDF(rawBib) | |||
var bib = Cite(rawBib); | var bib = Cite(rawBib); | ||
var ul = $("<ul />", { class: "csl-bib-body" }); | var ul = $("<ul />", { class: "csl-bib-body" }); | ||
bib.data.forEach(function(entry) { | bib.data.forEach(function (entry) { | ||
var li = $("<li/>", { class: "bib-entry" }); | var li = $("<li/>", { class: "bib-entry" }); | ||
var link = $("<a />").text("[PDF]"); | if (pdfMap[entry.id]) { | ||
li.append(link); | var link = $("<a />").text("[PDF]"); | ||
link.attr( | |||
"href", | |||
new URL(articlePath.replace("$1", "Special:filepath/" + pdfMap[entry.id])).toString() | |||
); | |||
li.append(link); | |||
li.append(" "); | |||
} | |||
if (entry.URL) { | |||
var link = $("<a />").text("[URL]"); | |||
link.attr( | |||
"href", | |||
entry.URL | |||
); | |||
li.append(link); | |||
li.append(" "); | |||
} | |||
var urlData = entry.URL | |||
entry.URL = undefined | |||
li.append( | li.append( | ||
$( | $( | ||
Line 190: | Line 243: | ||
).css("display", "inline") | ).css("display", "inline") | ||
); | ); | ||
entry.URL = urlData | |||
ul.append(li); | ul.append(li); | ||
}); | }); | ||
Line 205: | Line 259: | ||
function run() { | function run() { | ||
$(".bibliography:not(.test)").each(function(i, e) { | $(".bibliography:not(.test)").each(function (i, e) { | ||
var style = e.getAttribute("data-style"); | var style = e.getAttribute("data-style"); | ||
if (style === "list") { | if (style === "list") { | ||
Line 220: | Line 274: | ||
mw.hook("wikipage.content").add(callback); | mw.hook("wikipage.content").add(callback); | ||
} | } | ||
scripts.forEach(function(s) { | scripts.forEach(function (s) { | ||
mw.loader.getScript(s).then(onLoaded); | mw.loader.getScript(s).then(onLoaded); | ||
}); | }); |
Latest revision as of 19:21, 9 November 2021
(function ($, mw) {
"use strict";
var allowedPages = ["Publications", "Home"];
var nYearButtons = 5;
if (!allowedPages.includes(mw.config.get("wgPageName"))) return;
if (window.BibLoaded) return;
window.BibLoaded = true;
console.log("[Bibliography] 0.0.1");
var scriptLoaded = 0;
var mwConfig = mw.config.get(["wgUserName", "wgServer", "wgArticlePath"]);
var isAnon = mwConfig.wgUserName === null;
var articlePath = mwConfig.wgServer + mwConfig.wgArticlePath;
function download(filename, text) {
var el = document.createElement("a");
el.setAttribute(
"href",
"data:text/plain;charset=utf-8," + encodeURIComponent(text)
);
el.setAttribute("download", filename);
el.style.display = "none";
document.body.appendChild(el);
el.click();
document.body.removeChild(el);
}
function getPDF(rawBib) {
var pdfMap = {}
Array.from(rawBib.matchAll(/^@.+?\{(.+?),\s*(?:\n(?!@).*?)*?\npdf\s*=\s*\{(.*)\}/mg))
.forEach(function (m) {
pdfMap[m[1]] = m[2]
})
return pdfMap
}
function genDataTable(e) {
var Cite = window.require("citation-js");
var yearGroup = {};
var dataTable = undefined;
var rawBib = $(e).find(".bibliography-data")[0].textContent;
var pdfMap = getPDF(rawBib)
var bib = Cite(rawBib);
var data = [];
var pageTitleIter = rawBib.matchAll(/^_pageName = \{(.+)\}\s*,?\s*$/gm);
bib.data.forEach(function (entry) {
var linkTarget = new URL(
articlePath.replace("$1", pageTitleIter.next().value[1])
);
var linkEle = $("<a>").text(entry.id);
linkEle.attr("href", linkTarget.toString());
var editLink = $("<a>").html(
'<span class="material-icons-outlined">edit</span>'
);
linkTarget.searchParams.append("action", "formedit");
editLink.attr("href", linkTarget.toString());
editLink.attr("target", "_blank");
var urlData = entry.URL
entry.URL = undefined
entry.render = Cite(entry).format("bibliography", {
format: "html",
template: "apa",
lang: "en-US",
});
entry.URL = urlData
entry.pdf = pdfMap[entry.id]
if (entry.pdf) {
entry.render += " " + $("<a />")
.text("[PDF]")
.attr(
"href",
new URL(articlePath.replace("$1", "Special:filepath/" + pdfMap[entry.id])).toString()
)
.prop('outerHTML');
}
if (urlData && urlData.startsWith("http")) {
entry.render += " " + $("<a />")
.text("[URL]")
.attr(
"href",
urlData
)
.prop('outerHTML');
}
entry.pageTitle = editLink[0].outerHTML + linkEle[0].outerHTML;
entry.year = entry.issued && entry.issued["date-parts"] && entry.issued["date-parts"][0] && entry.issued["date-parts"][0][0] || 1970;
yearGroup[parseInt(entry.year)] = false;
data.push(entry);
});
var tb = $("<table></table>")[0];
e.replaceWith(tb);
tb = $(tb);
tb.append($("<thead>"));
tb.append($("<tbody>"));
tb.addClass("display");
// Generate buttons
var orderedYears = Object.keys(yearGroup).sort(function (x, y) {
if (x < y) return 1;
if (x > y) return -1;
return 0;
});
function draw(dt) {
dt.column("year:name").search(
orderedYears
.filter(function (e) {
return yearGroup[e];
})
.join("|"),
true,
false
);
dt.draw();
}
var buttons = orderedYears.slice(0, nYearButtons).map(function (year) {
return {
text: year,
action: function (e, dt, node, config) {
yearGroup[year] = !yearGroup[year];
node.toggleClass("active", yearGroup[year]);
draw(dt);
},
};
});
if (orderedYears.length > nYearButtons) {
var statusRest = false;
var restYears = orderedYears.slice(nYearButtons);
buttons.push({
text: "Rest",
action: function (e, dt, node, config) {
statusRest = !statusRest;
restYears.forEach(function (el) {
yearGroup[el] = !yearGroup[el];
});
node.toggleClass("active", statusRest);
draw(dt);
},
});
}
// export BibTeX button
buttons.push({
text: "Export BibTeX",
action: function (e, dt, node, config) {
var text = Cite(dt.rows({ page: "current" }).data().toArray()).format(
"bibtex"
);
download("bibtex.bib", text);
},
titleAttr: "export",
});
var options = {
data: data,
columns: [{
className: "cell-apa",
data: "render",
title: "APA",
render: function (data, type, row) {
// If display or filter data is requested, format the date
if (type === "sort") return row.year;
return data;
},
},
{
name: "year",
data: "year",
visible: false,
},
],
paging: false,
order: [
[0, "desc"]
],
rowGroup: {
dataSrc: "year",
},
dom: "fBrtip",
buttons: buttons,
};
if (!isAnon) {
options.columns.unshift({
className: "cell-pageTitle",
data: "pageTitle",
title: "In-site Page",
});
options.order[0][0] += 1;
options.order.push([0, "asc"]);
}
dataTable = tb.dataTable(options);
dataTable = dataTable.DataTable();
}
function genList(e) {
var Cite = window.require("citation-js");
var rawBib = $(e).find(".bibliography-data")[0].textContent;
var pdfMap = getPDF(rawBib)
var bib = Cite(rawBib);
var ul = $("<ul />", { class: "csl-bib-body" });
bib.data.forEach(function (entry) {
var li = $("<li/>", { class: "bib-entry" });
if (pdfMap[entry.id]) {
var link = $("<a />").text("[PDF]");
link.attr(
"href",
new URL(articlePath.replace("$1", "Special:filepath/" + pdfMap[entry.id])).toString()
);
li.append(link);
li.append(" ");
}
if (entry.URL) {
var link = $("<a />").text("[URL]");
link.attr(
"href",
entry.URL
);
li.append(link);
li.append(" ");
}
var urlData = entry.URL
entry.URL = undefined
li.append(
$(
$(
Cite(entry).format("bibliography", {
format: "html",
template: "apa",
lang: "en-US",
})
).html()
).css("display", "inline")
);
entry.URL = urlData
ul.append(li);
});
if (e.getAttribute("data-more")) {
var linkMore = $("<a />").text("More...");
linkMore.attr(
"href",
new URL(articlePath.replace("$1", "Publications")).toString()
);
ul.append(linkMore);
}
e.replaceWith(ul[0]);
return ul;
}
function run() {
$(".bibliography:not(.test)").each(function (i, e) {
var style = e.getAttribute("data-style");
if (style === "list") {
return genList(e);
}
return genDataTable(e);
});
}
function loadScripts(scripts, callback) {
function onLoaded() {
scriptLoaded++;
if (scriptLoaded === scripts.length)
mw.hook("wikipage.content").add(callback);
}
scripts.forEach(function (s) {
mw.loader.getScript(s).then(onLoaded);
});
}
loadScripts(
[
"https://cdn.jsdelivr.net/npm/citation-js@0.5.1",
"https://cdn.datatables.net/v/dt/dt-1.11.1/b-2.0.0/rg-1.1.3/datatables.min.js",
],
run
);
mw.loader.load(
"https://cdn.datatables.net/v/dt/dt-1.11.1/b-2.0.0/rg-1.1.3/datatables.min.css",
"text/css"
);
})(jQuery, mediaWiki);