Jump to content

User:Salix alba/Citoid.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*************

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=http%3A%2F%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%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%2Fdeveloper%2Emozilla%2Eorg%2Fen-US%2Fdocs%2FWeb%2FAPI%2FXMLHttpRequest HTTP/1.1

https://citoid.wikimedia.org/api?action=query&format=mediawiki&search=http%3A%2F%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=http%3A%2F%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=http%3A%2F%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%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=http%3A%2F%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=http%3A%2F%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=http%3A%2F%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>&nbsp;&nbsp;"+
		    "<input type='radio' name='datestyle' value='MDY'>September 1, 2014</input>&nbsp;&nbsp;"+
		    "<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: '/media/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);
        });