User:Salix alba/Citoid.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | This user script seems to have a documentation page at User:Salix alba/Citoid and an accompanying .css page at User:Salix alba/Citoid.css. |
/*************
Generates a citation template from a url using the citoid server
Author User:Salix alba
Date: 15 July 2021
Version: 0.05
Heavily borrowed from
User:Mvolz/veCiteFromURL.js
Interface element taken from
TemplateDataEditor
http://fr.wikipedia.org/w/index.php?title=Utilisateur:Ltrlg/scripts/TemplateDataEditor.js
https://citoid.wikimedia.org/api?action=query&format=mediawiki&search=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Fwww%2Etheguardian%2Ecom%2Feducation%2F2016%2Fapr%2F12%2Fgrammar-schools-nicky-morgan-kent-parent-11-plus&basefields=true
Slightly customized.
***************/
function Citoid($) {
////// Customization for local wikis
var lang = mw.config.get('wgUserLanguage');
var messages = {
"en": {
"toolbox-label": 'Citoid',
"toolbox-tooltip": 'Generate reference from a URL',
"title": 'Citoid reference ',
"close": 'Close',
"monthnames": ['January','February','March','April','May','June','July','August','September','October','November','December']
},
};
if(messages[lang]==null) lang='en';
var url;
function formatCS1Date(isodate) {
console.log(isodate);
var style = $( "input:radio[name=datestyle]:checked" ).val();
var day="",month="",year="",daynum="",monthnum="";
// Input format 2014-08-31T09:28EDT
var re1 = /(\d\d\d\d)-(\d\d)-(\d\d).*/;
var test1 = isodate.match(re1);
// Or sometimes September 29, 2014
var re2 = /([A-Z][a-z]+) (\d+), (\d\d\d\d).*/;
var test2 = isodate.match(re2);
var re3 = /(\d\d\d\d)-(\d\d)/;
var test3 = isodate.match(re3);
if(test1 !== null) {
// Input format 2014-08-31T09:28EDT
day = parseInt(test1[3],10);
daynum= test1[3];
month = parseInt(test1[2],10)-1;
monthnum = test1[2];
year = test1[1];
}
else if(test2 !== null) {
// September 29, 2014
day = parseInt(test2[2],10);
var monthtxt = test2[1];
year = test2[3];
if(day<10) daynum = "0" + day; else daynum = day;
var index = messages['en'].monthnames.indexOf(monthtxt)+1;
if(index<10) monthnum = "0" + index; else monthnum = index;
month = index-1;
}
else if(test3 !== null) {
month = parseInt(test3[2],10)-1;
monthnum = test3[2];
year = test3[1];
if(style == "MDY")
return ""+messages[lang].monthnames[month]+", "+year;
else if(style == "YMD")
return ""+year+"-"+monthnum;
else
return ""+messages[lang].monthnames[month]+" "+year;
}
//console.log(day,month,year,daynum,monthnum);
//console.log(messages[lang].monthnames);
//console.log(messages[lang].monthnames[month]);
if(style == "MDY")
return ""+messages[lang].monthnames[month]+" "+day+", "+year;
else if(style == "YMD")
return ""+year+"-"+monthnum+"-"+daynum;
else
return ""+day+" "+messages[lang].monthnames[month]+" "+year;
}
/* Returns a javascript object given search results */
function getPlainObject( url, searchResults ) {
console.log(searchResults);
var content, plainObject, d, templateHref, templateName,
citation = JSON.parse( JSON.stringify( searchResults ) )[0], //uses the first citation result for the time being
templateTypeMap = {
book: 'Cite book',
bookSection: 'Cite book',
journalArticle: 'Cite journal',
magazineArticle: 'Cite news',
newspaperArticle: 'Cite news',
thesis: 'Cite journal',
letter: 'Citation',
manuscript: 'Cite book',
interview: 'Citation',
film: 'Citation',
artwork: 'Citation',
webpage: 'Cite web',
report: 'Cite journal',
bill: 'Citation',
hearing: 'Citation',
patent: 'Citation',
statute: 'Citation',
email: 'Cite web',
map: 'Citation',
blogPost: 'Cite web',
instantMessage: 'Citation',
forumPost: 'Cite web',
audioRecording: 'Citation',
presentation: 'Cite journal',
videoRecording: 'Citation',
tvBroadcast: 'Citation',
radioBroadcast: 'Citation',
podcast: 'Citation',
computerProgram: 'Citation',
conferencePaper: 'Cite journal',
'document': 'Citation',
encyclopediaArticle: 'Cite journal',
dictionaryEntry: 'Cite journal'
},
//Parameter map for Template:Citation on en-wiki
//In the format citation-template-field:citoid-field
citationParams = {
'first1': 'author1-first',
'last1': 'author1-last',
'first2': 'author2-first',
'last2': 'author2-last',
'first3': 'author3-first',
'last3': 'author3-last',
'first4': 'author4-first',
'last4': 'author4-last',
// 'accessdate': 'accessDate',
'title': 'title',
'url': 'url',
'publisher': 'publisher',
//a large number of Zotero types have the field publicationTitle
//however, in setting journal to publicationTitle, the citation
//will be formatted as a journal article, which may not always be
//desirable.
'journal': 'publicationTitle',
// 'newspaper': 'publicationTitle',
'date': 'date',
'location': 'place',
'issn': 'ISSN',
'isbn': 'ISBN',
'pages': 'pages',
'volume': 'volume',
'series': 'series',
'issue': 'issue',
'via': 'libraryCatalog',
'pmid': 'PMID',
'pmc': 'PMCID',
'doi': 'DOI'
},
webParams = {
'first1': 'author1-first',
'last1': 'author1-last',
'first2': 'author2-first',
'last2': 'author2-last',
'first3': 'author3-first',
'last3': 'author3-last',
'first4': 'author4-first',
'last4': 'author4-last',
'access-date': 'accessDate',
'title': 'title',
'url': 'url',
'date': 'date',
'publisher': 'publisher',
'via': 'libraryCatalog',
'website': 'publicationTitle'
},
newsParams = {
'first1': 'author1-first',
'last1': 'author1-last',
'first2': 'author2-first',
'last2': 'author2-last',
'first3': 'author3-first',
'last3': 'author3-last',
'first4': 'author4-first',
'last4': 'author4-last',
'access-date': 'accessDate',
'title': 'title',
'url': 'url',
'publisher': 'publisher',
'newspaper': 'publicationTitle',
'date': 'date',
'location': 'place',
'issn': 'ISSN',
'isbn': 'ISBN',
'pages': 'pages',
'volume': 'volume',
'series': 'series',
'issue': 'issue',
'via': 'libraryCatalog',
'doi': 'DOI'
},
bookParams = {
'first1': 'author1-first',
'last1': 'author1-last',
'first2': 'author2-first',
'last2': 'author2-last',
'first3': 'author3-first',
'last3': 'author3-last',
'first4': 'author4-first',
'last4': 'author4-last',
// 'accessdate': 'accessDate',
'title': 'title',
'url': 'url',
'publisher': 'publisher',
'journal': 'publicationTitle',
'date': 'date',
'location': 'place',
'issn': 'ISSN',
'isbn': 'ISBN',
'pages': 'pages',
'volume': 'volume',
'series': 'series',
'issue': 'issue',
'via': 'libraryCatalog',
'doi': 'DOI'
},
journalParams = {
'first1': 'author1-first',
'last1': 'author1-last',
'first2': 'author2-first',
'last2': 'author2-last',
'first3': 'author3-first',
'last3': 'author3-last',
'first4': 'author4-first',
'last4': 'author4-last',
// 'accessdate': 'accessDate',
'title': 'title',
'url': 'url',
'publisher': 'publisher',
'journal': 'publicationTitle',
'date': 'date',
'location': 'place',
'issn': 'ISSN',
'isbn': 'ISBN',
'pages': 'pages',
'volume': 'volume',
'series': 'series',
'issue': 'issue',
'pmid': 'PMID',
'pmc': 'PMCID',
'doi': 'DOI'
},
//format 'template name':parameter obj name
templateParamMap = {
'Citation': citationParams,
'Cite web': webParams,
'Cite news': newsParams,
'Cite journal': journalParams,
'Cite book': bookParams
},
//This will contain the correct template with the fields filled out
paramObj = {};
templateName = templateTypeMap[citation.itemType];
templateHref = 'Template:' + templateName;
//hack for now- set citation url to supplied url if not given
if (!citation.url) {citation.url = url;}
//hack for PMC
if (citation.PMCID) {citation.url = null;}
//hack for websiteTitle
if (citation.websiteTitle) {citation.publicationTitle = citation.websiteTitle;}
$.each( templateParamMap[templateName], function ( key, value ) {
//console.log("loop",key,value);
var objString = citation[value] !== undefined ? citation[value] : '';
//console.log(objString);
if(typeof objString == 'string') {
var replaced = objString.replaceAll('|', '-');
paramObj[key] = { 'wt': replaced };
} else {
paramObj[key] = { 'wt': objString };
}
} );
// Fix for author array
var authors = citation['author'];
if(authors) {
for(i=0;i<authors.length;++i) {
var j = i+1;
paramObj['first' + j] = { 'wt': authors[i][0].replaceAll('|', '-') };
paramObj['last' + j] = { 'wt': authors[i][1].replaceAll('|', '-') };
}
}
d = new Date();
//var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
//ds = d.getDate() + " " + months[d.getMonth()] + " " + d.getGetFullYear();
var d2 = paramObj.date.wt;
if(d2) {
paramObj.date.wt = formatCS1Date(d2);
}
// Greatly simplified return result
plainObject = { //before paren put get plain object
'templateName': templateName.toLowerCase(),
'href': templateHref,
'params': paramObj
};
return plainObject;
}
//// build the code for the template
function buildTemplateCode(obj) {
var res = "<ref>{{" + obj.templateName;
$.each( obj.params, function ( key, value ) {
var wt = value.wt;
if(wt) {
//console.log(key,wt);
res = res + "|" + key + "=" + wt;
}
} );
res = res + "}}</ref>";
return res;
}
////// Called when toolbox button clicked
function callCitoid() {
url = $('#citoid-url').val();
//alert("Call citoid url [" + url +"]");
//curl 'http://citoid.wikimedia.org/api?action=query&format=mediawiki&search=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttps%2Fdeveloper%2Emozilla%2Eorg%2Fen-US%2Fdocs%2FWeb%2FAPI%2FXMLHttpRequest' -H 'Pragma: no-cache' -H 'Origin: http://en.wikipedia.org' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'accept-language: en' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Cache-Control: no-cache' -H 'Referer: http://en.wikipedia.org/wiki/Cross-origin_resource_sharing?veaction=edit' -H 'Connection: keep-alive' --compressed
/*
GET /api?action=query&format=mediawiki&search=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttps%2Fdeveloper%2Emozilla%2Eorg%2Fen-US%2Fdocs%2FWeb%2FAPI%2FXMLHttpRequest HTTP/1.1
https://citoid.wikimedia.org/api?action=query&format=mediawiki&search=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Fwww%2Etheguardian%2Ecom%2Feducation%2F2016%2Fapr%2F12%2Fgrammar-schools-nicky-morgan-kent-parent-11-plus&basefields=true
Host: citoid.wikimedia.org
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
*/
//Accept: application/json, text/javascript, */*; q=0.01
/*Origin: http://en.wikipedia.org
accept-language: en
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36
Referer: http://en.wikipedia.org/wiki/Cross-origin_resource_sharing?veaction=edit
Accept-Encoding: gzip, deflate, sdch
curl 'https://citoid.wikimedia.org/api?action=query&format=mediawiki&search=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Fwww%2Etheguardian%2Ecom%2Feducation%2F2016%2Fapr%2F12%2Fgrammar-schools-nicky-morgan-kent-parent-11-plus&basefields=true'
-H 'pragma: no-cache' -H 'origin: https://en.wikipedia.org' -H 'accept-encoding: gzip, deflate, sdch'
-H 'accept-language: en'
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36'
-H 'accept: application/json, text/javascript, /*; q=0.01'
-H 'cache-control: no-cache' -H 'referer: https://en.wikipedia.org/' --compressed
[{"itemType":"newspaperArticle","notes":[],"tags":[{"tag":"Grammar schools","type":1},{"tag":"Secondary schools","type":1},{"tag":"Schools","type":1},{"tag":"Education","type":1},{"tag":"Nicky Morgan","type":1},{"tag":"Education policy","type":1},{"tag":"Politics","type":1}],"url":"http://www.theguardian.com/education/2016/apr/12/grammar-schools-nicky-morgan-kent-parent-11-plus","abstractNote":"With selective schools now able to apply to open ‘annexes’, a Kent parent has written an open letter to the education secretary","date":"2016-04-12","ISSN":["0261-3077"],"language":"en-GB","publicationTitle":"The Guardian","section":"Education","title":"Grammar schools and the opportunity gap: 10 questions for Nicky Morgan","libraryCatalog":"The Guardian","accessDate":"2016-04-12","shortTitle":"Grammar schools and the opportunity gap","author":[["Joanne","Bartley"]]}]
https://citoid.wikimedia.org/api?action=query&format=mediawiki&search=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Fwww%2Etheguardian%2Ecom%2Feducation%2F2016%2Fapr%2F12%2Fgrammar-schools-nicky-morgan-kent-parent-11-plus&basefields=true
Post June 2017
https://en.wikipedia.org/api/rest_v1/data/citation/mediawiki/
https%3A%2F%2Frp.liu233w.com%3A443%2Fhttps%2Fwww.theguardian.com%2Fmusic%2F2016%2Foct%2F20%2Fewan-mclennan-and-george-monbiot-breaking-the-spell-of-loneliness-review-fellside
?action=query&format=json
*/
var citoidService = "https://en.wikipedia.org/api";
var prefix = 'https://en.wikipedia.org/api/rest_v1/data/citation/mediawiki/';
var mid = encodeURIComponent(url);
//var suffix = '&basefields=true';
var suffix = '?action=query&format=json';
var send = prefix+mid+suffix;
console.log(prefix+mid+suffix);
//gen 'https://citoid.wikimedia.org/api?action=query&format=mediawiki&search=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Fwww. theguardian. com%2Feducation%2F2016%2Fapr%2F12%2Fgrammar-schools-nicky-morgan-kent-parent-11-plusbasefields=true
//url: 'https://citoid.wikimedia.org/api?action=query&format=mediawiki&search=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Fwww%2Etheguardian%2Ecom%2Feducation%2F2016%2Fapr%2F12%2Fgrammar-schools-nicky-morgan-kent-parent-11-plus&basefields=true',
$.ajax( {
beforeSend: function (request) {
request.setRequestHeader('Content-Type', 'application/json');
},
url: send,
//url: 'https://citoid.wikimedia.org/api?action=query&format=mediawiki&search=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Fwww%2Etheguardian%2Ecom%2Feducation%2F2016%2Fapr%2F12%2Fgrammar-schools-nicky-morgan-kent-parent-11-plus&basefields=true',
type: 'GET',
//data: { action:"query", format:"mediawiki", search: url, basefields: "true" } ,
success: doneAjax,
error: function ( XMLHttpRequest, textStatus, errorThrown) {
console.log( 'Status: ' + textStatus + ' Error: ' + errorThrown );
console.log("Req");
console.log(XMLHttpRequest);
console.log("getAllResponseHeaders");
console.log(XMLHttpRequest.getAllResponseHeaders());
mw.notify( 'Status:' + textStatus + 'Error: ' + errorThrown );
},
} );
}
function doneAjax(result) {
//console.log(JSON.stringify(result, null, 4));
var plain = getPlainObject( url, result );
//console.log(result[0]);
//console.log(plain);
var res = buildTemplateCode(plain);
//console.log(res);
$('#citoid-code').text(res);
$('#citoid-full').text(JSON.stringify(result, null, 4));
//alert("doneAjax");
}
function openCitoidWindow() {
$cont.fadeIn('slow');
}
///// Close the dialog
function close() {
$cont.fadeOut('slow', function(){
});
}
////////// Building called after page loads
function buildHTML() {
$button = $('<button>')
.attr({ id: 'citoid-button', type:'button' })
.text("Generate Citation")
.click(callCitoid);
$body = $('<div>')
.attr('id', 'citoid-body')
.append("<p>URL: "+
"<input type='text' id='citoid-url' size='200' /></p>")
.append("<p>Date format: "+
"<input type='radio' name='datestyle' value='DMY' checked >1 September 2014</input> "+
"<input type='radio' name='datestyle' value='MDY'>September 1, 2014</input> "+
"<input type='radio' name='datestyle' value='YMD'>2014-09-01</input></p>")
.append($button)
.append("<p>Template code</p>")
.append("<textarea id='citoid-code'>")
.append("<p>Full citoid data</p>")
.append("<textarea id='citoid-full'>");
$title = $('<h2>').text( messages[lang]['title'] );
$cont = $('<div>')
.attr('id', 'citoid-cont')
.append($('<div>')
.attr('id', 'citoid-dialog')
.append( $title )
.append($('<a>')
.attr({
id: 'citoid-close',
href: '#',
title: messages[lang]['close']
})
.click(function(){
close();
return false;
})
.append($('<img>')
.attr({
alt: messages[lang]['close'],
src: '//upload.wikimedia.org/wikipedia/commons/thumb/8/8d/VisualEditor_-_Icon_-_Close.svg/24px-VisualEditor_-_Icon_-_Close.svg.png'
})
)
)
.append($body)
)
.hide();
$(document.body).append($cont);
}
////// Adds a link in the toolbox
function addPortletLink() {
$(
mw.util.addPortletLink('p-tb', '#', messages['en']['toolbox-label'], 'citoid', messages['en']['toolbox-tooltip'] )
).click(function(){
openCitoidWindow();
return false;
});
}
/////// Actions to do once page loads,
function start() {
//alert("Citoid 0.02");
addPortletLink();
buildHTML();
//console.log(formatCS1Date("2014-09-29T07:08:59.468Z"));
//console.log(formatCS1Date("2014-10-01T07:08:59.468Z"));
//console.log(formatCS1Date("September 29, 2014"));
//console.log(formatCS1Date("October 1, 2014"));
}
////////// START //////////
start();
}
/////// Wrapper code
//if( true
// $.inArray( mw.config.get('wgNamespaceNumber'), [ 2, 10 ] ) !== -1
// && $.inArray( mw.config.get('wgAction'), [ 'edit', 'submit' ] ) !== -1 */ ) {
mw.loader.load(
'//en.wikipedia.org/w/index.php?title=User:Salix alba/Citoid.css&action=raw&ctype=text/css&smaxage=21600&maxage=86400',
'text/css' );
mw.loader.using('mediawiki.util', function(){
$(document).ready(Citoid);
});