MediaWiki

Difference between revisions of "Gadget-Bibliography.js"

From ACES

(add button filter)
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
(function ($, mw) {
(function ($, mw) {
  "use strict";
    "use strict";
  var allowedPages = ["Publications"];
    var allowedPages = ["Publications", "Home"];
  var nYearButtons = 5;
    var nYearButtons = 5;
  if (!allowedPages.includes(mw.config.get("wgPageName"))) return;
    if (!allowedPages.includes(mw.config.get("wgPageName"))) return;
  if (window.BibLoaded) return;
    if (window.BibLoaded) return;
  // window.BibLoaded = true;
    window.BibLoaded = true;


  console.log("[Bibliography] 0.0.1");
    console.log("[Bibliography] 0.0.1");
  var scriptLoaded = 0;
    var scriptLoaded = 0;
  var mwConfig = mw.config.get(["wgUserName", "wgServer", "wgArticlePath"]);
    var mwConfig = mw.config.get(["wgUserName", "wgServer", "wgArticlePath"]);


  var isAnon = mwConfig.wgUserName === null;
    var isAnon = mwConfig.wgUserName === null;
  var articlePath = mwConfig.wgServer + mwConfig.wgArticlePath;
    var articlePath = mwConfig.wgServer + mwConfig.wgArticlePath;


  function run() {
    function download(filename, text) {
    var Cite = window.require("citation-js");
        var el = document.createElement("a");
     $(".bibliography:not(.test)").each(function (i, e) {
        el.setAttribute(
      var yearGroup = {};
            "href",
      var dataTable = undefined;
            "data:text/plain;charset=utf-8," + encodeURIComponent(text)
      var rawBib = $(e).find(".bibliography-data")[0].textContent;
        );
      console.log(rawBib);
        el.setAttribute("download", filename);
      var bib = Cite(rawBib);
 
      var data = [];
        el.style.display = "none";
      console.log(bib);
        document.body.appendChild(el);
      var pageTitleIter = rawBib.matchAll(/^_pageName = \{(.+)\}\s*,?\s*$/gm);
 
        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");


      bib.data.forEach(function (entry) {
            var urlData = entry.URL
        var linkTarget = new URL(
            entry.URL = undefined
          articlePath.replace("$1", pageTitleIter.next().value[1])
            entry.render = Cite(entry).format("bibliography", {
        );
                format: "html",
        var linkEle = $("<a>").text(entry.id);
                template: "apa",
        linkEle.attr("href", linkTarget.toString());
                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');
            }


        var editLink = $("<a>").html(
            entry.pageTitle = editLink[0].outerHTML + linkEle[0].outerHTML;
          '<span class="material-icons-outlined">edit</span>'
            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;
        linkTarget.searchParams.append("action", "formedit");
        editLink.attr("href", linkTarget.toString());
        editLink.attr("target", "_blank");


        entry.render = Cite(entry).format("bibliography", {
            data.push(entry);
          format: "html",
          template: "apa",
          lang: "en-US",
         });
         });
        entry.pageTitle = editLink[0].outerHTML + linkEle[0].outerHTML;
        entry.year = 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");


      var tb = $("<table></table>")[0];
        // Generate buttons
      e.replaceWith(tb);
        var orderedYears = Object.keys(yearGroup).sort(function (x, y) {
      tb = $(tb);
            if (x < y) return 1;
      tb.append($("<thead>"));
            if (x > y) return -1;
      tb.append($("<tbody>"));
            return 0;
      tb.addClass("display");
        });
      console.log(data);


      // Generate buttons
         function draw(dt) {
      var orderedYears = Object.keys(yearGroup).sort(function (x, y) {
            dt.column("year:name").search(
         if (x < y) return 1;
                orderedYears
        if (x > y) return -1;
                    .filter(function (e) {
        return 0;
                        return yearGroup[e];
      });
                    })
      function draw(dt) {
                    .join("|"),
        dt.column("year:name").search(
                true,
          orderedYears
                false
            .filter(function (e) {
            );
              return yearGroup[e];
            dt.draw();
            })
        }
            .join("|"),
        var buttons = orderedYears.slice(0, nYearButtons).map(function (year) {
          true,
            return {
          false
                text: year,
        );
                action: function (e, dt, node, config) {
        dt.draw();
                    yearGroup[year] = !yearGroup[year];
      }
                    node.toggleClass("active", yearGroup[year]);
      var buttons = orderedYears.slice(0, nYearButtons).map(function (year) {
                    draw(dt);
        return {
                },
          text: year,
            };
          action: function (e, dt, node, config) {
        });
            yearGroup[year] = !yearGroup[year];
        if (orderedYears.length > nYearButtons) {
            node.toggleClass("active", yearGroup[year]);
            var statusRest = false;
            draw(dt);
            var restYears = orderedYears.slice(nYearButtons);
            console.log(e, dt, node, config);
          },
        };
      });
      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({
         buttons.push({
          text: "Rest",
            text: "Export BibTeX",
          action: function (e, dt, node, config) {
            action: function (e, dt, node, config) {
             statusRest = !statusRest;
                var text = Cite(dt.rows({ page: "current" }).data().toArray()).format(
             restYears.forEach(function (el) {
                    "bibtex"
              yearGroup[el] = !yearGroup[el];
                );
                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",
             });
             });
             node.toggleClass("active", statusRest);
             options.order[0][0] += 1;
             draw(dt);
            options.order.push([0, "asc"]);
             console.log(e, dt, node, config);
        }
          },
        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;
    }


      var options = {
    function run() {
         data: data,
         $(".bibliography:not(.test)").each(function (i, e) {
        columns: [
            var style = e.getAttribute("data-style");
          {
            if (style === "list") {
            data: "render",
                return genList(e);
            title: "APA",
             }
            render: function (data, type, row) {
             return genDataTable(e);
              // 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({
          data: "pageTitle",
          title: "In-site Page",
         });
         });
        options.order[0][0] += 1;
     }
        options.order.push([0, "asc"]);
      }
      dataTable = tb.dataTable(options);
      dataTable = dataTable.DataTable();
      console.log(dataTable);
     });
  }


  function loadScripts(scripts, callback) {
    function loadScripts(scripts, callback) {
    function onLoaded() {
        function onLoaded() {
      scriptLoaded++;
            scriptLoaded++;
      if (scriptLoaded === scripts.length)
            if (scriptLoaded === scripts.length)
        mw.hook("wikipage.content").add(callback);
                mw.hook("wikipage.content").add(callback);
        }
        scripts.forEach(function (s) {
            mw.loader.getScript(s).then(onLoaded);
        });
     }
     }
    scripts.forEach(function (s) {
      mw.loader.getScript(s).then(onLoaded);
    });
  }


  loadScripts(
    loadScripts(
    [
        [
      "https://cdn.jsdelivr.net/npm/citation-js@0.5.1",
            "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",
            "https://cdn.datatables.net/v/dt/dt-1.11.1/b-2.0.0/rg-1.1.3/datatables.min.js",
    ],
        ],
    run
        run
  );
    );
  mw.loader.load(
    mw.loader.load(
    "https://cdn.datatables.net/v/dt/dt-1.11.1/b-2.0.0/rg-1.1.3/datatables.min.css",
        "https://cdn.datatables.net/v/dt/dt-1.11.1/b-2.0.0/rg-1.1.3/datatables.min.css",
    "text/css"
        "text/css"
  );
    );
})(jQuery, mediaWiki);
})(jQuery, mediaWiki);

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);