<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lars Willighagen</title>
    <description>The latest articles on DEV Community by Lars Willighagen (@larsgw).</description>
    <link>https://dev.to/larsgw</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53523%2F6b173dda-580a-4c73-90bb-239f91d5f4c5.jpg</url>
      <title>DEV Community: Lars Willighagen</title>
      <link>https://dev.to/larsgw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/larsgw"/>
    <language>en</language>
    <item>
      <title>Debugging the Karmabug</title>
      <dc:creator>Lars Willighagen</dc:creator>
      <pubDate>Fri, 16 Aug 2019 00:12:47 +0000</pubDate>
      <link>https://dev.to/larsgw/debugging-the-karmabug-p3a</link>
      <guid>https://dev.to/larsgw/debugging-the-karmabug-p3a</guid>
      <description>&lt;p&gt;&lt;em&gt;Debugging like you just tumbled down Fate's Wheel of Fortune (Image by &lt;a href="https://commons.wikimedia.org/w/index.php?curid=8860206"&gt;Cayambe - Own work, CC BY-SA 3.0&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For reasons I will not go through right now, I needed a new library for making synchronous HTTP requests in Node.js. I know what you are saying, "But that's one of the seven deadly sins of JavaScript!" ^1 Well, just know I had my reasons, and I wanted to replace &lt;code&gt;sync-request&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since I was already using the Fetch API with &lt;code&gt;node-fetch&lt;/code&gt; in the async part of my library, I thought: why not build a &lt;code&gt;sync-fetch&lt;/code&gt;, using &lt;code&gt;node-fetch&lt;/code&gt; under the hood like &lt;code&gt;sync-request&lt;/code&gt; uses &lt;code&gt;(then-)request&lt;/code&gt;. Two days later, it was actually working, as far as I could tell. However, if I wanted to publish this horror I need some actual testing.&lt;/p&gt;

&lt;p&gt;Luckily &lt;code&gt;node-fetch&lt;/code&gt; has a nice test suite, I only needed to convert &lt;strong&gt;194&lt;/strong&gt; test cases to use the synchronous API. Not fun work, but worth its while, maybe. Anyway, the first test cases worked, but then it got stuck on the first actual request.&lt;/p&gt;

&lt;p&gt;This is were I have to introduce you to the Karmabug. You see, after some testing I figured out that &lt;em&gt;only&lt;/em&gt; the combination of &lt;em&gt;my&lt;/em&gt; &lt;code&gt;sync-fetch&lt;/code&gt; and the test server just... stopped. The arguments were correct, my &lt;code&gt;fetch&lt;/code&gt; works with &lt;code&gt;https://example.org&lt;/code&gt; and the test server works with &lt;code&gt;node-fetch&lt;/code&gt;, but this combination simply did not. Investigating either pointed to the other, and I had no idea what to do next.&lt;/p&gt;

&lt;p&gt;That would make a good tweet, I thought. &lt;a href="https://twitter.com/larswillighagen/status/1162143220039671809"&gt;"Karma for making sync HTTP requests I guess."&lt;/a&gt; Literally two minutes later it hit me: that was &lt;em&gt;exactly&lt;/em&gt; what was going on. The test server could not respond to the requests because the request &lt;em&gt;itself&lt;/em&gt; was blocking the event loop.&lt;/p&gt;

&lt;p&gt;^1 Incidentally, the seven deadly sins of JavaScript all happen to be Sloth.&lt;/p&gt;

</description>
      <category>debugging</category>
    </item>
    <item>
      <title>Finishing and checking both mappings</title>
      <dc:creator>Lars Willighagen</dc:creator>
      <pubDate>Mon, 05 Aug 2019 15:29:00 +0000</pubDate>
      <link>https://dev.to/citation-js/finishing-and-checking-both-mappings-4k8i</link>
      <guid>https://dev.to/citation-js/finishing-and-checking-both-mappings-4k8i</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/citation-js/creating-a-ris-mapping-from-the-original-specification-1kfo"&gt;last post&lt;/a&gt; I explained how I started implementing the RIS specification that I found in the Internet Archive, only to discover that there is an older specification, which seems to be more common at times.&lt;/p&gt;

&lt;p&gt;Now, I have implemented the old spec, which luckily was not nearly as complex. One thing that came to my attention was that there were a lot of redundant tags: for title, there are &lt;code&gt;TI&lt;/code&gt;, &lt;code&gt;T1&lt;/code&gt;, &lt;code&gt;CT&lt;/code&gt; and usually &lt;code&gt;BT&lt;/code&gt;; for journal names there’s &lt;code&gt;JO&lt;/code&gt; &amp;amp; &lt;code&gt;JF&lt;/code&gt;, and &lt;code&gt;JA&lt;/code&gt;, &lt;code&gt;J1&lt;/code&gt;, &amp;amp; &lt;code&gt;J2&lt;/code&gt; for abbreviated journal names. While I can imagine some nuanced difference in meaning between those tags, those meanings are not documented, and not trivial to figure out either. Anyway, that is not a problem for the implementation.&lt;/p&gt;

&lt;p&gt;I also updated the implementation of the new spec, to fix some mistakes and add some more mappings. In addition, because in real life there seem to be some implementations that export a mix of the two specifications, I created an implementation based on the new spec, that if needed can defer to the old one — and some random properties that Wikipedia and Zotero have picked up somewhere, and are not in either spec.&lt;/p&gt;

&lt;p&gt;How do the results look? First of all, the example that was giving me issues in the last post looks a lot nicer now:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;issue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;230-265&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;article-journal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;47&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;On computable numbers, with an application to the Entscheidungsproblem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Turing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;given&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alan Mathison&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="nx"&gt;issued&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date-parts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt; &lt;span class="mi"&gt;1937&lt;/span&gt; &lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;container-title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Proc. of London Mathematical Society&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The only thing that was missing when I first tried this out was the end of the page range, because &lt;code&gt;SP&lt;/code&gt; in the new spec is the entire page range, while in the old spec you need both &lt;code&gt;SP&lt;/code&gt; and &lt;code&gt;EP&lt;/code&gt;. I had to fix that manually — not a problem, just something to keep in mind when re-running the scripts.&lt;/p&gt;

&lt;p&gt;One other thing to check was how to the mappings look from above, without all the type-specific shenanigans. I keep &lt;a href="https://docs.google.com/spreadsheets/d/13BQg5lg29VkRb4appz-eh1jcQsfI-0rdCTdmvpg577M/edit?usp=sharing"&gt;a (public) spreadsheet&lt;/a&gt; with mappings from CSL-JSON to all kinds of different formats, so I added the RIS mappings. So, a sanity check. Does it make sense?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dWry6MYR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/v3uwmjcx11fp62v5slz0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dWry6MYR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/v3uwmjcx11fp62v5slz0.png" alt="RIS mappings" title="RIS mappings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;No&lt;/em&gt;, not at all! The RIS tag &lt;code&gt;SE&lt;/code&gt; is mapped to 10 different CSL variables, and the CSL &lt;code&gt;number&lt;/code&gt; variables is mapped to 9 different RIS tags. To me, it does not make any sense, even accounting for the fact that I know there is some variation between entry types.&lt;/p&gt;

&lt;p&gt;The question that remains is, does it work? Even if it does not look like it makes sense, the output could still make sense, if other implementations follow the specification to a similar degree. I know Zotero does not entirely follow it — all the spec anomalies that &lt;em&gt;are&lt;/em&gt; implemented are attributed to weird EndNote quirks, not the weird &lt;em&gt;spec&lt;/em&gt; quirks.&lt;/p&gt;

&lt;p&gt;That made me wonder to what degree the EndNote implementation follows the specification. However, I do not have EndNote, so this is a call to action! Can you help me with clearing up the RIS cloud for me by submitting your RIS exports to &lt;a href="https://github.com/citation-js/ris-examples/tree/master/EndNote"&gt;a CC0-licensed repo&lt;/a&gt;? Preferably with all kinds of reference types — articles, books, chapters, conference papers, webpages, software, patents, bills, maps, artworks, whatever you can find. For legal reasons, please replace abstracts and other copyrightable content by &lt;code&gt;[... omitted]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the meantime, I will be collecting RIS exports from other sources, like Zotero and Mendeley and websites like Google Scholar, BMC and PubMed Central. If you know of any other sources, please let me know!&lt;/p&gt;

</description>
      <category>citationjs</category>
      <category>ris</category>
    </item>
    <item>
      <title>Creating a RIS mapping from the "original" specification</title>
      <dc:creator>Lars Willighagen</dc:creator>
      <pubDate>Tue, 30 Jul 2019 00:29:00 +0000</pubDate>
      <link>https://dev.to/citation-js/creating-a-ris-mapping-from-the-original-specification-1kfo</link>
      <guid>https://dev.to/citation-js/creating-a-ris-mapping-from-the-original-specification-1kfo</guid>
      <description>&lt;p&gt;So a while ago I was looking around for the RIS specification again. I had not found it earlier, only a reference implementation from Zotero, a surprisingly complete list of tags and types on Wikipedia and some examples from various websites and programs exporting RIS files. They did not seem to mesh, however. There were some slight differences in tags here and there, and a bunch of useful tags listed by Wikipedia were labelled “degenerate” in the Zotero codebase, and only used for imports — implying some sort of problem.&lt;/p&gt;

&lt;p&gt;What could be going on? Well, I checked out the references on the Wikipedia page again, to see if there really was no official specification or some other more reliable source where it got its information from. And, suddenly, there &lt;em&gt;was&lt;/em&gt; an actual source this time. I do not know how I missed it earlier, but there was a page (&lt;a href="https://web.archive.org/web/20120526103719/http://refman.com/support/risformat_intro.asp"&gt;archived&lt;/a&gt;) that linked to a zip file containing a PDF file with general specifications and an Excel file with sheets with property lists for all different types.&lt;/p&gt;

&lt;p&gt;That sounded useful, so I spent &lt;em&gt;waaayy&lt;/em&gt; to much time automating &lt;a href="https://github.com/citation-js/ris-mappings"&gt;a script&lt;/a&gt; to turn those sheets — with a bunch of user input — into usable mappings for Citation.js. I just finished that today, apart from some… questionable mappings, but I wanted to at least test the final script with an example. As for the results, well, see for yourself. &lt;a href="https://en.wikipedia.org/wiki/RIS_(file_format)#Example_multi-record_format"&gt;The example&lt;/a&gt;, from the Wikipedia page (CC-BY-SA 3.0 Unported) was&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TY - JOUR
T1 - On computable numbers, with an application to the Entscheidungsproblem
A1 - Turing, Alan Mathison
JO - Proc. of London Mathematical Society
VL - 47
IS - 1
SP - 230
EP - 265
Y1 - 1937
ER -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;and my results were&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"page"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;230&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"article-journal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"volume"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That looked really weird and disappointing. Again, what could possibly be going on here? Well, the example on Wikipedia is using &lt;code&gt;T1&lt;/code&gt;, &lt;code&gt;A1&lt;/code&gt;, &lt;code&gt;JO&lt;/code&gt; and &lt;code&gt;Y1&lt;/code&gt; while the specs say to use &lt;code&gt;TI&lt;/code&gt;, &lt;code&gt;AU&lt;/code&gt;, &lt;code&gt;T2&lt;/code&gt; and &lt;code&gt;PY&lt;/code&gt; here. Were are these differences coming from?&lt;/p&gt;

&lt;p&gt;After some digging around on Wikipedia I found &lt;a href="https://en.wikipedia.org/wiki/Talk:RIS_(file_format)#Versions_of_the_specification"&gt;a comment&lt;/a&gt; saying that there are in fact to specifications: one from 2011 and one from before. The archived spec I checked out was from 2012 (as linked by Wikipedia!), while they use the version from before 2011; which luckily is &lt;a href="https://web.archive.org/web/20110930172154/http://www.refman.com/support/risformat_intro.asp"&gt;still available&lt;/a&gt;. To be continued.&lt;/p&gt;

</description>
      <category>citationjs</category>
      <category>ris</category>
    </item>
    <item>
      <title>Citation.js: Wikidata Update</title>
      <dc:creator>Lars Willighagen</dc:creator>
      <pubDate>Sat, 25 May 2019 13:19:00 +0000</pubDate>
      <link>https://dev.to/citation-js/citation-js-wikidata-update-1oc4</link>
      <guid>https://dev.to/citation-js/citation-js-wikidata-update-1oc4</guid>
      <description>&lt;p&gt;The new update, &lt;code&gt;v0.4.4&lt;/code&gt;, contains a few &lt;a href="https://wikidata.org"&gt;Wikidata&lt;/a&gt; improvements (&lt;a href="%5Bhttps://github.com/citation-js/citation-js/commit/01be9362a9106b886fc6d8f37d8a4d53ecc49d22%5D(https://github.com/citation-js/citation-js/commit/01be9362a9106b886fc6d8f37d8a4d53ecc49d22)"&gt;commit&lt;/a&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;22 new mappings&lt;/li&gt;
&lt;li&gt;2 fixed mappings (&lt;code&gt;ISSN&lt;/code&gt; did not work and &lt;code&gt;publisher-place&lt;/code&gt; was mapped to the wrong thing)&lt;/li&gt;
&lt;li&gt;2 improved mappings (&lt;code&gt;container-title&lt;/code&gt; for chapters and more &lt;code&gt;URL&lt;/code&gt; mappings)&lt;/li&gt;
&lt;li&gt;1 removed mapping (&lt;code&gt;genre&lt;/code&gt; was inconsistent with the &lt;a href="%5Bhttps://discourse.citationstyles.org/t/inconsistencies-with-genre-and-medium/1475%5D(https://discourse.citationstyles.org/t/inconsistencies-with-genre-and-medium/1475)"&gt;intended use&lt;/a&gt;, although it followed the specification)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because most of these mappings require additional resources (&lt;code&gt;recipient&lt;/code&gt; has to fetch people, &lt;code&gt;review-*&lt;/code&gt; has to fetch the review subject and &lt;code&gt;original-publisher-place&lt;/code&gt; has to fetch the country and location of the publisher of the original version of a work) this would have caused a lot more requests to the API. It is a good thing, then, that there is a new resolver in place, which pre-fetches such information for all requested works at once.&lt;/p&gt;

&lt;p&gt;This has to be done in levels; you cannot fetch the country if you do not have the location, the location requires the publisher and to find out the publisher you have to have the work already. However, temporarily ignoring the cap of 50 items per request, the number of requests is now only based on those levels (which is at most five), instead of the number of claims requiring additional requests.&lt;/p&gt;

&lt;p&gt;For example, item &lt;a href="https://www.wikidata.org/wiki/Q21972834"&gt;&lt;code&gt;Q21972834&lt;/code&gt;&lt;/a&gt; (&lt;em&gt;Assembling the 20 Gb white spruce (Picea glauca) genome from whole-genome shotgun sequencing data&lt;/em&gt;) takes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;6 requests&lt;/strong&gt; in &lt;code&gt;v0.4.0-rc.2&lt;/code&gt;, before requests for properties were grouped (so it would make a request for every author)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 requests&lt;/strong&gt; in &lt;code&gt;v0.4.3&lt;/code&gt;: one for the work, one for the authors, and one for journal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2 requests&lt;/strong&gt; in &lt;code&gt;v0.4.4&lt;/code&gt;, which includes a bunch of new mappings that would have cost a total of 5 requests in the previous version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Grouping the requests from all works has the added benefit of not having to fetch the same author and journal info repeatedly — which can be quite common for bibliographies. For example, the bibliography of &lt;a href="https://egonw.github.io/cdkbook"&gt;&lt;em&gt;Groovy Cheminformatics with the Chemistry Development Kit&lt;/em&gt;&lt;/a&gt;, currently containing 74 items, takes 11 requests in the new version. For the same bibliography, the previous version would make at least 150 requests — for each item one for all the authors and one for the journal — and probably more than that.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q24599948%7CQ24650571%7CQ25713029%7CQ27061829%7CQ27062363%7CQ27062596%7CQ27065423%7CQ27093381%7CQ27134682%7CQ27134746%7CQ27134827%7CQ27162658%7CQ27211680%7CQ27499209%7CQ27656255%7CQ27783585%7CQ27783587%7CQ27902272%7CQ28090714%7CQ28133283%7CQ28186592%7CQ28837846%7CQ28837922%7CQ28837925%7CQ28837939%7CQ28837943%7CQ28837947%7CQ28842810%7CQ28842968%7CQ28843132%7CQ29039683%7CQ29042322%7CQ29616639%7CQ30149558%7CQ30853915%7CQ31127242%7CQ33874102%7CQ34160151%7CQ34206190%7CQ36662828%7CQ37988904%7CQ39811432%7CQ42704791%7CQ47543807%7CQ47632144%7CQ54062338%7CQ55880270%7CQ55934414%7CQ55954394%7CQ56112883&amp;amp;format=json&amp;amp;languages=en {} [core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q56170978%7CQ56454405%7CQ57836257%7CQ59771351%7CQ60167226%7CQ60167327%7CQ60167615%7CQ60167690%7CQ61463648%7CQ61649587%7CQ61779181%7CQ61779373%7CQ61779901%7CQ61779905%7CQ61779940%7CQ61780124%7CQ62926016%7CQ62926155%7CQ62927888%7CQ62968825%7CQ62969352%7CQ62969354%7CQ63367539%7CQ63367548&amp;amp;format=json&amp;amp;languages=en {} [core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q135122%7CQ1223539%7CQ59196164%7CQ1860%7CQ8513%7CQ766195%7CQ7441%7CQ28946414%7CQ50332566%7CQ46330054%7CQ57218960%7CQ57218835%7CQ55965812%7CQ43370919%7CQ37391332%7CQ57677801%7CQ60446154%7CQ60447576%7CQ60449513%7CQ29946263%7CQ60465926%7CQ60890297%7CQ20895241%7CQ910067%7CQ3007982%7CQ52113739%7CQ5111731%7CQ29405902%7CQ47473872%7CQ121182%7CQ128570%7CQ910164%7CQ2383032%7CQ1130645%7CQ908710%7CQ5727848%7CQ27065426%7CQ28946652%7CQ42783959%7CQ4420286%7CQ749647%7CQ309823%7CQ28540892%7CQ29052381%7CQ29052386%7CQ4914910%7CQ12149006%7CQ853614%7CQ1418791%7CQ50731867&amp;amp;format=json&amp;amp;languages=en {} [core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q56007851%7CQ5195068%7CQ11351%7CQ75%7CQ151332%7CQ3002926%7CQ27061944%7CQ27134800%7CQ6294930%7CQ27061853%7CQ28540435%7CQ28854723%7CQ766383%7CQ1425625%7CQ28540616%7CQ55406442%7CQ483666%7CQ11173%7CQ39972290%7CQ1069211%7CQ36534%7CQ27211732%7CQ251%7CQ1768406%7CQ1689854%7CQ30046697%7CQ55406542%7CQ5227350%7CQ38372872%7CQ38373802%7CQ3841253%7CQ55213915%7CQ7440973%7CQ30045595%7CQ451553%7CQ466769%7CQ203250%7CQ54837%7CQ3355939%7CQ40023319%7CQ26842658%7CQ109081%7CQ82264%7CQ898902%7CQ27711423%7CQ1767639%7CQ7209103%7CQ27768873%7CQ900316%7CQ48803&amp;amp;format=json&amp;amp;languages=en {} [core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q1884753%7CQ15064016%7CQ895901%7CQ2166958%7CQ907701%7CQ309%7CQ28796322%7CQ19845641%7CQ27061849%7CQ28923506%7CQ30046701%7CQ28865170%7CQ43370334%7CQ29387575%7CQ50983316%7CQ7395247%7CQ192864%7CQ336658%7CQ58409692%7CQ56421913%7CQ55182163%7CQ55182165%7CQ56670283%7CQ925779%7CQ50731930%7CQ909510%7CQ381009%7CQ38173%7CQ30046335%7CQ43370883%7CQ3705921%7CQ1154615%7CQ2334061%7CQ1988917%7CQ898967%7CQ2425378%7CQ10354104%7CQ47 480%7CQ1709878%7CQ900502&amp;amp;format=json&amp;amp;languages=en {} [core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q1120519%7CQ1860%7CQ113337%7CQ1767639%7CQ27134800%7CQ6294930%7CQ251%7CQ5776092%7CQ56421877%7CQ463360%7CQ109081%7CQ50731930%7CQ176916%7CQ26707540%7CQ30046697%7CQ28925563%7CQ1122491%7CQ3186908%7CQ969707%7CQ1948400%7CQ192864%7CQ898902%7CQ2835897%7CQ3007982%7CQ46155617%7CQ905549%7CQ485223%7CQ900502%7CQ15766522&amp;amp;format=json&amp;amp;languages=en {} [core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q7050%7CQ32%7CQ64%7CQ225471&amp;amp;format=json&amp;amp;languages=en {} [core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q47501431&amp;amp;format=json&amp;amp;languages=en {} [core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q33467704&amp;amp;format=json&amp;amp;languages=en {} [core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q55&amp;amp;format=json&amp;amp;languages=en {} [core] GET https://www.wikidata.org/w/api.php?action=wbgetentities&amp;amp;ids=Q183%7CQ145&amp;amp;format=json&amp;amp;languages=en {}  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, I &lt;em&gt;do&lt;/em&gt; notice slightly more requests with a low number of items than I would expect. I will look into that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conference papers in Wikidata
&lt;/h3&gt;

&lt;p&gt;Part of the mappings that were added in the recent update are the &lt;code&gt;event-*&lt;/code&gt; properties, i.e. “name of the related event (e.g. the conference name when citing a conference paper)” (&lt;a href="https://docs.citationstyles.org/en/master/specification.html#appendix-iv-variables"&gt;spec&lt;/a&gt;). Finding out how those are modelled in Wikidata proved a bit of a challenge, as most instances of &lt;a href="https://www.wikidata.org/wiki/Q23927052"&gt;&lt;code&gt;Q23927052&lt;/code&gt; (conference paper)&lt;/a&gt; are published in proceedings with the &lt;code&gt;book&lt;/code&gt; type. To get some numbers (&lt;a href="https://w.wiki/4JL"&gt;query&lt;/a&gt;):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;typeLabel&lt;/th&gt;
&lt;th&gt;items&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q571"&gt;Q571&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;book&lt;/td&gt;
&lt;td&gt;715&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q5633421"&gt;Q5633421&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;scientific journal&lt;/td&gt;
&lt;td&gt;676&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q1143604"&gt;Q1143604&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;proceedings&lt;/td&gt;
&lt;td&gt;315&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q16024164"&gt;Q16024164&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;medical journal&lt;/td&gt;
&lt;td&gt;53&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q23927052"&gt;Q23927052&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;conference paper&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q1002697"&gt;Q1002697&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;periodical literature&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q41298"&gt;Q41298&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;magazine&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;other&lt;/td&gt;
&lt;td&gt;other&lt;/td&gt;
&lt;td&gt;61&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;48 conference papers are published in conference papers? That does not seem right. But maybe they just have the wrong type, but still link to the event? Well no, not really (&lt;a href="https://w.wiki/4JN"&gt;query&lt;/a&gt;).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;hasEvent&lt;/th&gt;
&lt;th&gt;items&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;1952&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Luckily, the information is not lost: usually, the label contains location and date information about the event, although extracting that would be probably be a tedious task. However, perhaps there are a lot of proper proceedings out there, but the articles linked to it just have the wrong type (&lt;a href="https://w.wiki/4JH"&gt;query&lt;/a&gt;)?&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;typeLabel&lt;/th&gt;
&lt;th&gt;items&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q13442814"&gt;Q13442814&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;scholarly article&lt;/td&gt;
&lt;td&gt;3513&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q23927052"&gt;Q23927052&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;conference paper&lt;/td&gt;
&lt;td&gt;315&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q3331189"&gt;Q3331189&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;version, edition, or translation&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q1143604"&gt;Q1143604&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;proceedings&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q10885494"&gt;Q10885494&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;scientific conference paper&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q1980247"&gt;Q1980247&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;chapter&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q191067"&gt;Q191067&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;article&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q18918145"&gt;Q18918145&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;academic journal article&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.wikidata.org/entity/Q333291"&gt;Q333291&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;abstract&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;other&lt;/td&gt;
&lt;td&gt;other&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That seems to be the case: most works that are published in instances of proceedings are tagged as instances of scholarly articles, and only nine are tagged as both. And: relatively many have events linked to them (&lt;a href="https://w.wiki/4JP"&gt;query&lt;/a&gt;).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;hasEvent&lt;/th&gt;
&lt;th&gt;items&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;2692&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;1184&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That’s better. I’ll look into working together with WikiCite to work on the rest.&lt;/p&gt;

</description>
      <category>citationjs</category>
      <category>wikidata</category>
    </item>
    <item>
      <title>Citation.js Version 0.4: The Catch-up</title>
      <dc:creator>Lars Willighagen</dc:creator>
      <pubDate>Thu, 11 Apr 2019 20:24:00 +0000</pubDate>
      <link>https://dev.to/citation-js/citation-js-version-0-4-the-catch-up-5el</link>
      <guid>https://dev.to/citation-js/citation-js-version-0-4-the-catch-up-5el</guid>
      <description>&lt;p&gt;After about two years, finally &lt;code&gt;v0.4.0&lt;/code&gt; is ready for a release. Whether it is a real milestone given that there have been prereleases for about two years, while &lt;code&gt;0.3.x&lt;/code&gt; only lasted three weeks, is for you to decide but I am glad that everything I planned for this version is implemented now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VIM9hLYx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://citation.js.org/static/img/square_logo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VIM9hLYx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://citation.js.org/static/img/square_logo.png" alt="Citation.js logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Changes
&lt;/h3&gt;

&lt;p&gt;So, let’s go through the major changes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Modules
&lt;/h4&gt;

&lt;p&gt;Most importantly, the code is fully modulated now. The different components, the core, the CLI and all the individual format plugins, are &lt;a href="https://www.npmjs.com/org/citation-js"&gt;available on their own now&lt;/a&gt;. The &lt;code&gt;citation-js&lt;/code&gt; is now designed as a shell around those components, maintaining full backwards compatibility (apart from mapping changes) until that is no longer required.&lt;/p&gt;

&lt;h4&gt;
  
  
  Mappings
&lt;/h4&gt;

&lt;p&gt;A lot of different formats where either improved or introduced. The main newcomer is RIS, still only as output format. Support for NDJSON output was also added. The handling of styling and case-preserving brackets in BibTeX fields was improved, although the method of parsing those files is still lagging behind.&lt;/p&gt;

&lt;p&gt;Thanks to (independent) practical testing by Egon Willighagen and Jakob Voss and the &lt;a href="https://github.com/maxlath/wikidata-sdk/commits?author=maxlath"&gt;&lt;code&gt;wikidata-sdk&lt;/code&gt;&lt;/a&gt; library by Maxime Lathuilière we were also able to improve the Wikidata mapping quite a lot, although there is still work ahead.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuration
&lt;/h4&gt;

&lt;p&gt;Apart from the potential for customization that comes with the separate modules, there is quite some new configuration available. First of all, input parsing has some options: &lt;code&gt;strict&lt;/code&gt; which basically switches between errors and failing silently (not-so-long ago the default behavior); and &lt;code&gt;target&lt;/code&gt; which allows the user to specify a certain point at which the parsing should be stopped, mainly useful for debugging.&lt;/p&gt;

&lt;p&gt;Furthermore, individual input formats can be configured now too. For example, the default languages used in the Wikidata plugin can be configured now. The methods to add CSL templates and locales which was already available is using the same mechanism now.&lt;/p&gt;

&lt;p&gt;Finally, CSL output with &lt;code&gt;citeproc-js&lt;/code&gt; has been amended. First and foremost, support for &lt;code&gt;citation&lt;/code&gt; has been added (or rather, the original &lt;code&gt;citation-*&lt;/code&gt; has been renamed to &lt;code&gt;bibliography&lt;/code&gt;), so it is possible to get actual citations now. Also, the &lt;code&gt;nosort&lt;/code&gt; option has been added and the &lt;code&gt;prepend&lt;/code&gt;/&lt;code&gt;append&lt;/code&gt; options been improved.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stability &amp;amp; best practices
&lt;/h4&gt;

&lt;p&gt;Also important, there’s a lot more testing now and the commit messages and code style follow standard guidelines. Making a new repository for the different modules actually helped with that, allowing me to re-evaluate the decisions I made in that aspect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/larsgw/citation.js/blob/master/CHANGELOG.md"&gt;The full changelog is available here.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Paper &amp;amp; Preprint
&lt;/h3&gt;

&lt;p&gt;In the middle of all that (literally, the development halted for a few months) I wrote a paper about Citation.js, which I am currently revising after review. &lt;a href="https://peerj.com/preprints/27466/"&gt;The preprint is available here.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Further development
&lt;/h3&gt;

&lt;p&gt;There’s still a lot to be done, most of which has been discussed in the “Discussion” section of the preprint. I’ll go into some things that are planned for the (relatively) near future, other than additional mappings of course.&lt;/p&gt;

&lt;h4&gt;
  
  
  (Another) Wikidata refactor
&lt;/h4&gt;

&lt;p&gt;Part of the recent development to finish the release was a refactoring of the Wikidata parsing code to facilitate some changes and mainly to reduce unnecessary code duplication, originally the result of sync/async variants of almost every function. However, while working on that I came up with an even better refactor which should minimize the problems of under-fetching that I described in the preprint.&lt;/p&gt;

&lt;p&gt;To recap, under-fetching is the problem of not being able to fetch enough information in the desired amount of HTTP requests. For example, in Wikidata it’s not possible to get item labels of property values such as &lt;a href="https://www.wikidata.org/wiki/Property:P50"&gt;&lt;code&gt;P50&lt;/code&gt; (author)&lt;/a&gt;, and they require another HTTP call. It is not possible to fetch them together with the publication item you are fetching since you do not know who the authors are yet.&lt;/p&gt;

&lt;p&gt;So the minimal number of requests (not taking the limit of 50 items per request) is one for each “level” you need to go down: author labels would be the second level, and fetching the labels of name items if you decide to use &lt;a href="https://www.wikidata.org/wiki/Property:P735"&gt;&lt;code&gt;P735&lt;/code&gt; (given name)&lt;/a&gt; and &lt;a href="https://www.wikidata.org/wiki/Property:P734"&gt;&lt;code&gt;P734&lt;/code&gt; (family name)&lt;/a&gt; would be the third. That’s what this refactor will try to accomplish, and it shouldn’t be too complex but still non-trivial.&lt;/p&gt;

&lt;h4&gt;
  
  
  Turning the chain parser into a tree parser
&lt;/h4&gt;

&lt;p&gt;Currently the input is parsed iteratively, in a “chain” of types. For example, a Wikidata ID becomes a Wikidata API URL, which returns JSON, which gets parsed, and the resulting API response gets transformed into CSL-JSON. This also ensures that people could input a Wikidata API URL if they want, and that fetching and parsing JSON from a web resource doesn’t have to be implemented over and over again.&lt;/p&gt;

&lt;p&gt;When encountering arrays, if they are not recognized as some special array, each element is parsed until the target (CSL-JSON) is reached, at which point it returns. However, this proved problematic with some new features, like the &lt;code&gt;target&lt;/code&gt; option (parse until this format is reached, instead of the default CSL-JSON). Firstly, such options cannot be passed down to the other parsing functions, and secondly if a certain target format is reached in the array elements then the total format is always going to be an array of that, and will never match the target.&lt;/p&gt;

&lt;p&gt;A refactor of the parser, branching it instead of whatever is going on currently, should counter this.&lt;/p&gt;

&lt;h4&gt;
  
  
  More &lt;code&gt;citeproc&lt;/code&gt; interactions
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;citeproc&lt;/code&gt; is currently used in an almost state-less manner, which works fine for bibliographies but is quite limiting for working with citations. While users could redirect CSL output to &lt;code&gt;citeproc&lt;/code&gt; themselves, why not do it for them with more bibliography management, which Citation.js mostly lacks at the moment.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ditching CSL-JSON as the central format?
&lt;/h4&gt;

&lt;p&gt;CSL-JSON is great, but also quite limiting considering the available properties, the general problems of which are also discussed in the preprint. While additions could be made to CSL in terms of variables, which Frank Bennet has already done with CSL-M, and which the CSL team is doing now with a new release finally specifying a computer program type, CSL remains intended for generating citations, not for storing bibliographical data. At least, according to a quote that I cannot find anymore.&lt;/p&gt;

&lt;p&gt;However, this becomes quite clear practically. I count 10 of the 78 fields being specific to citing the item. An additional 4 are (usually) redundant and 3 poorly defined, one with just a question mark as description. On top of that, 12 could be replaced by allowing references to other publications, which would require just 4 fields instead, and 4 that could be replaced by other entities such as venues requiring no additional properties.&lt;/p&gt;

&lt;p&gt;Still, moving to a different format is quite something and this will have to be discussed. Of course, support for CSL-JSON wouldn’t be removed either way, just not exclusively used for storage. Also, these changes would take place way after any pending changes.&lt;/p&gt;




&lt;p&gt;And that is it for this post. Any feedback on the release and ideas for the things discussed above is very welcome here, in &lt;a href="https://github.com/citation-js/citation-js"&gt;the GitHub repo&lt;/a&gt; or on Twitter (&lt;a href="https://twitter.com/larswillighagen"&gt;@larswillighagen&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>citationjs</category>
    </item>
    <item>
      <title>Citation.js: Showing Blogger Posts on a Different Site</title>
      <dc:creator>Lars Willighagen</dc:creator>
      <pubDate>Wed, 22 Aug 2018 15:58:00 +0000</pubDate>
      <link>https://dev.to/larsgw/citationjs-showing-blogger-posts-on-a-different-site-ia7</link>
      <guid>https://dev.to/larsgw/citationjs-showing-blogger-posts-on-a-different-site-ia7</guid>
      <description>&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1026536137958072320-501" src="https://platform.twitter.com/embed/Tweet.html?id=1026536137958072320"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1026536137958072320-501');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1026536137958072320&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;I made a &lt;a href="https://getmdl.io" rel="noopener noreferrer"&gt;Material-themed&lt;/a&gt; page showing Citation.js blog posts from Blogger. It supports pagination, tags, search and linking individual posts. Since it's a single, static page I can't support &lt;code&gt;meta&lt;/code&gt; and &lt;code&gt;link&lt;/code&gt; tags for metadata, that would require JavaScript which indexers don't run.&lt;/p&gt;

&lt;p&gt;The great thing about the Blogger API is that you can generate feeds for single tags, like Citation.js for example, and search for tags and general queries within that tag. That's what makes all this possible. The URL scheme is very simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Tag feed&lt;/span&gt;
https://&lt;span class="nv"&gt;$BLOG&lt;/span&gt;.blogspot.com/feeds/posts/default/-/&lt;span class="nv"&gt;$TAG&lt;/span&gt;

&lt;span class="c"&gt;# Tag-in-tag feed&lt;/span&gt;
https://&lt;span class="nv"&gt;$BLOG&lt;/span&gt;.blogspot.com/feeds/posts/default/-/&lt;span class="nv"&gt;$TAG&lt;/span&gt;/&lt;span class="nv"&gt;$OTHER_TAG&lt;/span&gt;

&lt;span class="c"&gt;# Search-in-tag feed&lt;/span&gt;
&lt;span class="c"&gt;# Note: don't copy this, there's a ZWS before ?q= for syntax highlighting&lt;/span&gt;
https://&lt;span class="nv"&gt;$BLOG&lt;/span&gt;.blogspot.com/feeds/posts/default/-/&lt;span class="nv"&gt;$TAG&lt;/span&gt;​?q&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$QUERY&lt;/span&gt;

&lt;span class="c"&gt;# Post&lt;/span&gt;
https://&lt;span class="nv"&gt;$BLOG&lt;/span&gt;.blogspot.com/feeds/posts/default/&lt;span class="nv"&gt;$POST&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pagination and response formats complicate things a little, and are dealt with in the code below.&lt;/p&gt;

&lt;p&gt;Apart from the Material theme, it only uses vanilla JavaScript to generate the pages. The search bar doesn't even use JavaScript at all, just good ol' &lt;code&gt;form&lt;/code&gt; semantics. The JavaScript it does use is fairly simple. First, the query is parsed and an API URL is generated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://larsgw.blogspot.com/feeds/posts/default/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;?alt=json-in-script&amp;amp;callback=cb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://larsgw.blogspot.com/feeds/posts/default/-/Citation.js/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;?alt=json-in-script&amp;amp;callback=cb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://larsgw.blogspot.com/feeds/posts/default/-/Citation.js/?q=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;alt=json-in-script&amp;amp;callback=cb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://larsgw.blogspot.com/feeds/posts/default/-/Citation.js?alt=json-in-script&amp;amp;callback=cb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;startIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/start-index=&lt;/span&gt;&lt;span class="se"&gt;(\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;startIndex&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the only JSON API for Blogger is JSON-in-script, we append a script element loading the resource. This then calls the callback, &lt;code&gt;cb&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cb&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;feed&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;feedItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// pagination&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;hasIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start-index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;hasParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;indexPattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/start-index=&lt;/span&gt;&lt;span class="se"&gt;(\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rel&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;previous&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start-index=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;indexPattern&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hasIndex&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;indexPattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasParams&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt;
      &lt;span class="nx"&gt;paginatePrev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;href&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rel&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start-index=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;indexPattern&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hasIndex&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;indexPattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasParams&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;
      &lt;span class="nx"&gt;paginateNext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;href&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;load&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The callback then uses simple templates, which are just JS functions taking in the API response and outputting HTML to show the results on the page. Then, it figures out the pagination. Below is an example template.  It extracts the post id to make links and does some preprocessing, removing stackedit metadata and styling and lowering each heading two levels. Then, it puts together the HTML with some additional util functions and subtemplates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;feedItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^.*&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;post-&lt;/span&gt;&lt;span class="se"&gt;(\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$t&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[\s\S]&lt;/span&gt;&lt;span class="sr"&gt;*&amp;lt;div class="stackedit__html"&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;([\s\S]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;div&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;[\s\S]&lt;/span&gt;&lt;span class="sr"&gt;*$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="se"&gt;(\/?)&lt;/span&gt;&lt;span class="sr"&gt;h&lt;/span&gt;&lt;span class="se"&gt;([&lt;/span&gt;&lt;span class="sr"&gt;1-6&lt;/span&gt;&lt;span class="se"&gt;])&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;slash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;level&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;level&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;slash&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;slash&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;level&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;div class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col"&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;div class="mdl-card__title"&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;h2 class="mdl-card__title-text"&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;a href="?post=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;"&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$t&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;div class="mdl-card__supporting-text mdl-card--border"&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;span&amp;gt;&amp;lt;i class="material-icons"&amp;gt;edit&amp;lt;/i&amp;gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="nx"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;author&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;span&amp;gt;&amp;lt;i class="material-icons"&amp;gt;access_time&amp;lt;/i&amp;gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="nf"&gt;formatDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;span&amp;gt;&amp;lt;i class="material-icons"&amp;gt;link&amp;lt;/i&amp;gt; &amp;lt;a href="&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="nf"&gt;canonical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;"&amp;gt;Original post&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;span&amp;gt;&amp;lt;i class="material-icons"&amp;gt;bookmark&amp;lt;/i&amp;gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;div class="mdl-card__supporting-text"&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full source is available at &lt;a href="https://github.com/citation-js/site/blob/master/static/js/blog.js" rel="noopener noreferrer"&gt;here&lt;/a&gt;, and the page can be viewed &lt;a href="https://citation.js.org/blog/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FQd8EXpblQui1CSErr_BU1Os9Ykk-ximWT_hcTxGhtJBwY6JoM7jSxt7FlAwOSkAs57G4nZ64ccAtMg%3Ds2000" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FQd8EXpblQui1CSErr_BU1Os9Ykk-ximWT_hcTxGhtJBwY6JoM7jSxt7FlAwOSkAs57G4nZ64ccAtMg%3Ds2000" title="Blog screenshot" alt="Blog screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>blogging</category>
      <category>materialdesign</category>
    </item>
    <item>
      <title>Modern Altmetric badges</title>
      <dc:creator>Lars Willighagen</dc:creator>
      <pubDate>Sat, 11 Aug 2018 11:07:00 +0000</pubDate>
      <link>https://dev.to/larsgw/modern-altmetric-badges-43jk</link>
      <guid>https://dev.to/larsgw/modern-altmetric-badges-43jk</guid>
      <description>

&lt;p&gt;I recently found myself working with &lt;a href="http://api.altmetric.com/embeds.html"&gt;Altmetric badges&lt;/a&gt; again, and I realized how cumbersome it can be to work with scripts. The Altmetric badges can only be added by using their JavaScript library, while it would be a lot more user friendly to have a simple URL that embeds the badge, preferably even an image. I may be a bit spoiled by the badge ecosystem of the open source community, including &lt;a href="https://shields.io"&gt;Shields.io&lt;/a&gt;. There, badges are dynamically generated on the server side.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V8N-tH-x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/UQg3vzcJxQfpfN-BxyrPL1mPXJA8DJuPbMaBT3f2j8OlO0rllgifKTGPIkTzKJFvEAWXNxXrNaGaHw" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V8N-tH-x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/UQg3vzcJxQfpfN-BxyrPL1mPXJA8DJuPbMaBT3f2j8OlO0rllgifKTGPIkTzKJFvEAWXNxXrNaGaHw" alt="Badges in open source JavaScript projects" title="Badges in open source JavaScript projects"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Badges in open source JavaScript projects&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, Shields doesn’t support Altmetric. It does, however, support dynamic badges, and Altmetric does have an API. The endpoint is &lt;code&gt;api.altmetric.com/v1/doi/&lt;/code&gt; for DOI-based access (which is what we want in this case). So the parameters needed for the badge are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data type: JSON (the output format of the API)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;label&lt;/code&gt;: Altmetric&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;url&lt;/code&gt;: &lt;code&gt;https://api.altmetric.com/v1/doi/&amp;lt;DOI&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;query&lt;/code&gt;: &lt;code&gt;$.score&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;style&lt;/code&gt;: &lt;code&gt;social&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;logo&lt;/code&gt; would be &lt;code&gt;https://www.altmetric.com/wp-content/themes/altmetric/favicon.ico&lt;/code&gt;, but I can’t get that to work. The resulting URL is&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://img.shields.io/badge/dynamic/json.svg?url=https://api.altmetric.com/v1/doi/DOI&amp;amp;label=Altmetric&amp;amp;query=$.score&amp;amp;style=social
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which looks like this: &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8QXoVVKt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jqhwmhokrwm7ij0kg6qm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8QXoVVKt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jqhwmhokrwm7ij0kg6qm.png" alt="Altmetric badge"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note, however, that the use of the &lt;a href="http://api.altmetric.com/"&gt;Altmetric API is limited&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Free, rate-limited API&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No key required.&lt;/li&gt;
&lt;li&gt;Includes research object metadata and metrics only.&lt;/li&gt;
&lt;li&gt;Available only for one-time, limited term research projects.&lt;/li&gt;
&lt;li&gt;Best for small projects.&lt;/li&gt;
&lt;li&gt;Rate limited to 1 call per second.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;


</description>
      <category>altmetric</category>
      <category>badges</category>
      <category>shieldsio</category>
    </item>
    <item>
      <title>Debugging: Deja Vu</title>
      <dc:creator>Lars Willighagen</dc:creator>
      <pubDate>Mon, 30 Apr 2018 10:46:00 +0000</pubDate>
      <link>https://dev.to/larsgw/debugging-deja-vu-3mc5</link>
      <guid>https://dev.to/larsgw/debugging-deja-vu-3mc5</guid>
      <description>&lt;p&gt;I’m going to share some stories on debugging with you, &lt;del&gt;because I’m proud of them&lt;/del&gt;. (After writing up the first story, I’m no longer particularly proud, but I still want to share the story.) Here’s the first: a bug that seemed quite familiar.&lt;/p&gt;

&lt;p&gt;After &lt;a href="https://twitter.com/larswillighagen/status/986718567633735682"&gt;some trouble with mocking API requests&lt;/a&gt; I decided that supporting mocking in the browser isn’t as important as supporting mocking at all, so I installed &lt;a href="https://www.npmjs.com/package/mock-require"&gt;mock-require&lt;/a&gt; (I didn’t get &lt;a href="https://www.npmjs.com/package/proxyquire"&gt;proxyquire&lt;/a&gt; to work). Now, to confirm that the test bundle script actually omitted the API mocking code from the bundle when it should, I loaded the test suite in the browser. Guess what? Errors everywhere! Or rather, error everywhere. Every test case gave the same error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeError: Cannot assign to read only property 'length' of function 'function () {
      old.apply(self, arguments);
    }'
  at new Assertion (/build/test.citation.js:1810:30)
  at new Assertion (/build/test.citation.js:1799:25)
  at new Assertion (/build/test.citation.js:1799:25)
  at new Assertion (/build/test.citation.js:1799:25)
  at expect (/build/test.citation.js:1775:12)
  at Context._callee2$ (/build/test.citation.js:3582:35)
  at tryCatch (/build/citation.js:7891:17)
  at Generator.invoke [as _invoke] (/build/citation.js:8064:22)
  at Generator.prototype.(anonymous function) [as next] (/build/citation.js:7934:21)
  at step (/build/test.citation.js:3542:221)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Naturally, like a good programmer, I immediately googled the error message in conjunction with the various tools and frameworks I used for this bundle, instead of looking at the stack trace showing that something’s wrong with &lt;a href="https://github.com/Automattic/expect.js"&gt;expect.js&lt;/a&gt;. Anyway, after some time, I found a &lt;a href="https://github.com/Automattic/expect.js/issues/149"&gt;GitHub issue&lt;/a&gt; describing exactly the problem I was having. Scrolling through the responses, I was stunned:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/larsgw"&gt;larsgw&lt;/a&gt;&lt;/strong&gt; commented &lt;a href="https://github.com/Automattic/expect.js/issues/149#issuecomment-318820971"&gt;on Jul 29, 2017&lt;/a&gt;&lt;br&gt;&lt;br&gt;
+1: Same issue, but for all assertions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Somehow, I reported the same issue 10 months ago, but the site, running a bundle from 2 months old didn’t have the problem. Apparently, I had fixed the issue earlier, but forgotten about the solution, and I couldn’t figure out what that solution was. So I started debugging. First of all, the offending code wasn’t different from any other working bundle. It registered a bunch of functions as properties to a function, and it choked on the &lt;code&gt;length&lt;/code&gt; property. Makes sense, the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length"&gt;&lt;code&gt;length&lt;/code&gt; property isn’t writable on functions&lt;/a&gt;. But running some simple test code showed this shouldn’t be the problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;          &lt;span class="c1"&gt;// (no error)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sure, it didn’t actually do anything, but it didn’t throw an exception either. Besides, this was the exact same lines of code as in the GitHub repo, so how could that be the issue? The only thing I could do was comparing with the working examples. Diffing my bundle against the published one, which was difficult, because it’s generated code. Checking out commits until I found out which one worked, which was a pain because I repeatedly forgot to reinstall dependencies, something that could be critical.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sidebar (minor spoilers): the previous time I ‘solved’ the issue, it was much easier, because it was the first time setting the system up, so instead of referring to older commits as working examples, I looked at the docs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After a long while I realised what the workaround was earlier: instead of bundling expect.js with Browserify, I included it as a script (as &lt;a href="https://github.com/Automattic/expect.js#browser"&gt;recommended&lt;/a&gt;) and created a wrapper that exposed the &lt;code&gt;expect.js&lt;/code&gt; module and simply grabbed and exported the global &lt;code&gt;expect&lt;/code&gt; variable exposed by the script. I thought this was because the order of requiring the scripts mattered, but some testing proved this wasn’t the case. No, actually including expect.js into a Browserify bundle with Babelify transform on, or even simply running it through the Babel compiler caused the error.&lt;/p&gt;

&lt;p&gt;Back to diffing bundles I guess: what &lt;em&gt;are&lt;/em&gt; the differences between a babel-ed file and its source code if there isn’t really any syntax that needs to be transformed, or APIs that need to be polyfilled?&lt;/p&gt;

&lt;p&gt;Turns out, not much. Between those files, the only real difference was the location (or with &lt;code&gt;comments: false&lt;/code&gt; the existence) of comments, and some style differences caused by Babel’s code generator.&lt;/p&gt;

&lt;p&gt;And &lt;code&gt;'use strict'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Apparently, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode"&gt;&lt;code&gt;'use strict'&lt;/code&gt; makes assignments that otherwise fail silently throw an error&lt;/a&gt;. If I had read that documentation earlier, or if I had payed proper attention to the &lt;code&gt;Function.prototype.length&lt;/code&gt; docs (linked above), I would have known. Now it’s just a boring ending to a long journey. But hey, at least I learned some stuff.&lt;/p&gt;




&lt;p&gt;Solving this issue requires either a big change in the internals of a toolkit that hasn’t had an update in 4(!) years, or a workaround. I don’t want to use the workaround of including two extra files anymore, now that I know what is causing the issue, but the other workaround proves to be a problem itself, involving outdated documentation and &lt;a href="https://github.com/babel/babelify/issues/265"&gt;a bug in Babelify&lt;/a&gt;. More on that later.&lt;/p&gt;

&lt;p&gt;On a related note: I’m working on a new release for Citation.js, improving the parsing plugin system. The API should be pretty stable now, apart from the namespaces being prone to change, so I might change the schedule to one update with all current API changes instead.&lt;/p&gt;

</description>
      <category>debugging</category>
    </item>
    <item>
      <title>Citation.js Version 0.4 Beta: New Docs and Input Plugins</title>
      <dc:creator>Lars Willighagen</dc:creator>
      <pubDate>Fri, 22 Dec 2017 16:19:00 +0000</pubDate>
      <link>https://dev.to/citation-js/citationjs-version-04-beta-new-docs-and-input-plugins-3a0j</link>
      <guid>https://dev.to/citation-js/citationjs-version-04-beta-new-docs-and-input-plugins-3a0j</guid>
      <description>&lt;br&gt;
   Citation.js Version 0.4 Beta: New Docs and Input Plugins &lt;br&gt;
 

&lt;p&gt;It’s been a while. &lt;a href="https://github.com/larsgw/citation.js/graphs/contributors?from=2017-09-08&amp;amp;to=2017-12-19&amp;amp;type=c"&gt;Really&lt;/a&gt;. But now it’s back, with a new release: &lt;code&gt;v0.4.0-0&lt;/code&gt;, the &lt;code&gt;v0.4&lt;/code&gt; beta. Below I explain some of the changes in this release, and then the road-map of &lt;a href="https://citation.js.org"&gt;Citation.js&lt;/a&gt; for &lt;code&gt;v0.4&lt;/code&gt; and &lt;code&gt;v0.5&lt;/code&gt;. Also, Citation.js has a DOI now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://doi.org/10.5281/zenodo.1005176"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--04M9y8vG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://zenodo.org/badge/doi/10.5281/zenodo.1005176.svg" alt="DOI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Citation.js is now on &lt;a href="https://twitter.com/ZENODO_ORG?ref_src=twsrc%5Etfw"&gt;@ZENODO_ORG&lt;/a&gt;, and has a DOI! &lt;a href="https://t.co/X2ThPA2S1I"&gt;https://t.co/X2ThPA2S1I&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— Lars Willighagen (@larswillighagen) &lt;a href="https://twitter.com/larswillighagen/status/918033807156137985?ref_src=twsrc%5Etfw"&gt;October 11, 2017&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, &lt;a href="https://twitter.com/jsterlibs"&gt;@jsterlibs&lt;/a&gt; &lt;a href="https://twitter.com/jsterlibs/status/935436869764046849"&gt;tweeted&lt;/a&gt; about Citation.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Release
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Input plugins
&lt;/h3&gt;

&lt;p&gt;The main change in this release, is the addition of input plugins. This is the first step towards releasing &lt;code&gt;v0.4&lt;/code&gt;, as explained below. Although there’s specific documentation available &lt;a href="https://citation.js.org/api/tutorial-input_plugins.html"&gt;here&lt;/a&gt; and &lt;a href="https://citation.js.org/api/Cite.parse.html#.add"&gt;here&lt;/a&gt;, I’ll put an example here as well, as the API can be confusing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The API for registering input plugins will be changed once or twice before the release of &lt;code&gt;v0.4&lt;/code&gt;, once to make it less complex and weird, and possibly a second time to incorporate output plugins.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Adding a format
&lt;/h4&gt;

&lt;p&gt;Say you wanted to add the &lt;a href="https://en.wikipedia.org/wiki/RIS_(file_format)"&gt;RIS&lt;/a&gt; format (I should probably do that sometime). First, let’s define a type, to set things off.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'@ris/text'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I can’t really define the actual parser here, but I’ll add a variable in the example code.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* return CSL-JSON or some format supported by any other parser */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Testing if a given string is in the RIS format, we’ll use regex. This regex matches if any line starts with two alphanumerical characters, two spaces and a hyphen. That’s a pretty fuzzy match; &lt;em&gt;all&lt;/em&gt; lines should start with that sequence. However, this is just an example, and proper regex would be less elegant.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;risRegex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;\w{2}\ {2}&lt;/span&gt;&lt;span class="sr"&gt;-/gm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, let’s define the &lt;code&gt;dataType&lt;/code&gt; of RIS input. When using regex to test input, the &lt;code&gt;dataType&lt;/code&gt; is automatically determined to be &lt;code&gt;'String'&lt;/code&gt; anyway, but for the sake of being clear:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'String'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, to combine it all:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Cite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;parseType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;risRegex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;dataType&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Changing parsers
&lt;/h4&gt;

&lt;p&gt;Now, say someone else wrote that code above, and you &lt;em&gt;need&lt;/em&gt; to use it without modifying it, but you want a better regex? That can be arranged:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Cite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;dataType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'String'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;parseType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;(?:\w{2}\ {2}&lt;/span&gt;&lt;span class="sr"&gt;-.*&lt;/span&gt;&lt;span class="se"&gt;\n)&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(\w{2}\ {2}&lt;/span&gt;&lt;span class="sr"&gt;-.*&lt;/span&gt;&lt;span class="se"&gt;)?&lt;/span&gt;&lt;span class="sr"&gt;$/g&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Because the options &lt;code&gt;dataType&lt;/code&gt;, &lt;code&gt;parseType&lt;/code&gt;, &lt;code&gt;elementConstraint&lt;/code&gt; and &lt;code&gt;propertyConstraint&lt;/code&gt; are all treated as one thing, you need to pass everyone of those when replacing the type checker. &lt;code&gt;dataType&lt;/code&gt; is still not actually mandatory in this example, but is passed to demonstrate this.&lt;/p&gt;

&lt;h4&gt;
  
  
  Disabling a format
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;There is currently &lt;a href="https://github.com/larsgw/citation.js/issues/108"&gt;no way to remove a format&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this scenario, some plugin registered a new format to get citation data from &lt;code&gt;github.com&lt;/code&gt; URLs. Unfortunately, it doesn’t work. Instead of recognising the URL as a GitHub-specific URL, the type is &lt;code&gt;@else/url&lt;/code&gt;, the generic URL type. This is because the generic version was registered earlier, and there is not yet a category for generic types (see &lt;a href="https://github.com/larsgw/citation.js/issues/104"&gt;#104&lt;/a&gt;). If you don’t use the &lt;code&gt;@else/url&lt;/code&gt; type checker anyway, you can disable it like this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Cite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'@else/url'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;dataType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'String'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;parseType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;I’m not sure why the &lt;code&gt;dataType&lt;/code&gt; is needed here, as you’re disabling the parser anyway, but it doesn’t seem to work without it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Docs
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3TUFf4or--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://4.bp.blogspot.com/-BCbRZekDsN0/Wj0jlBOna0I/AAAAAAAAQpU/VwXpzWhWyx0Ol_oFkXluveRPJNmva_YdACLcBGAs/s1600/citation.js.org_api_tutorial-cli.html%252B%2525281%252529.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3TUFf4or--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://4.bp.blogspot.com/-BCbRZekDsN0/Wj0jlBOna0I/AAAAAAAAQpU/VwXpzWhWyx0Ol_oFkXluveRPJNmva_YdACLcBGAs/s1600/citation.js.org_api_tutorial-cli.html%252B%2525281%252529.png" alt="Proper CLI docs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recently, I’ve been updating the &lt;a href="https://citation.js.org/api"&gt;documentation&lt;/a&gt; on &lt;a href="https://citation.js.org"&gt;Citation.js&lt;/a&gt;, and it has been a pleasant experience, despite some hiccups in the documentation engine. There are tutorials now, and a lot of the JSDoc comments have been improved. I still want to improve some things in the theme, like clickable header links (similar to GitHub and NPM behaviour), and showing sub-tutorials in the navigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backwards compatibility
&lt;/h3&gt;

&lt;p&gt;This release should be largely backwards compatible. If there are any regressions, please report them &lt;a href="https://github.com/larsgw/citation.js/issues"&gt;in the bug tracker&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Road-map
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;v0.4&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/larsgw/citation.js/projects/3"&gt;&lt;code&gt;v0.4&lt;/code&gt;&lt;/a&gt; “is about making it easier to expand on input and output formats, possibly by creating schemes and methods parsing those schemes that can, say, convert BibJSON to CSL JSON based on a JSON file, something that can be stored independently of implementation.”&lt;/p&gt;

&lt;p&gt;The idea is to allow for all kinds of plugins, both in input parsing and output formatting, to be registered on the &lt;code&gt;Cite&lt;/code&gt; object, and to treat all internal parsers and formatters the same. Currently, input parser plugins are possible (see above), although they will be improved before &lt;code&gt;v0.4&lt;/code&gt;. Output parsers will be made soon too, and will be backwards-incompatible, because of the change in the output option format.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;v0.5&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Currently, the plan is to use JSON-LD as the internal format in &lt;a href="https://github.com/larsgw/citation.js/projects/5"&gt;&lt;code&gt;v0.5&lt;/code&gt;&lt;/a&gt;, while still keeping CSL-JSON as the internal scheme. Any input should then be converted to a list (or object) of fields, which will be added to the internal data store. Each field should be transformed to the CSL-JSON scheme individually, and added as a copy. As a result, there won’t be data loss when certain fields aren’t available in CSL-JSON, but are in the input and output schemes. It should also make it easier to write parsers for e.g. BibJSON.&lt;/p&gt;

&lt;p&gt;Of course, edge cases should be taken care of. For example, there is no &lt;a href="https://wikidata.org"&gt;Wikidata&lt;/a&gt; property for the CSL-JSON field &lt;code&gt;original-title&lt;/code&gt;, but that information can still be derived from the labels combined with the &lt;code&gt;P364&lt;/code&gt; (original language) property.&lt;/p&gt;

</description>
      <category>citationjs</category>
    </item>
  </channel>
</rss>
