User:DemocraticLuntz/cenparse.js

// /** * Formats a Census page query. * top_list is an array of a line in the files, 0th element is place name, * 1st element is place type, 2nd element is county, * 3rd element is state * * curr_geo is place * *  * Now changed to 0th element is est_column, then decennial begins at 4th */ CenPop.est_column=0; CenPop.begin_decennial=4; CenPop.removed_refs={};

CenPop.format_page_query = function(top_list,curr_geo,show_type,show_county) {   var place_name=top_list[0], place_type=top_list[1], county_name=top_list[2]; var state_name=top_list[3], full_name=top_list[0]; if(show_type && place_type === 'township') full_name+=' township'; else if(show_type) full_name+=' ('+place_type+')'; if(show_county) full_name+=', '+county_name; /* Regardless of flag, we want county at beginning if we're doing counties */ if(curr_geo==='county') { full_name = county_name; } full_name+=', '+state_name; return full_name; }; /** * Returns a string containing the US Census Population template as it currently * exists in the given page prior to any modifications we may make. We use this * so that we can replace it later with our (possibly) different and updated * data. */ CenPop.get_pop_str = function(input) { var ret_str='',begin_re = new RegExp('\{\{USCensusPop|\{\{US[ \n\r]*Census[ \n\r]*population'); var brace_depth=2,begin_pos=input.search(begin_re), curr_pos=0,in_len=input.length,curr_char; if(begin_pos===-1 && ($('#noMatch').html(+$('#noMatch').html + 1)||true)) return ''; curr_pos=begin_pos+2; while(brace_depth>0 && curr_pos < in_len) brace_depth+=(curr_char=input.charAt(curr_pos++))&&curr_char==='{'?1:(curr_char==='}'?-1:0); if(curr_pos]*>/g; const array = [...str_to_check.matchAll(unclosed_name_re)]; if(array.length==0) return -1; return str_to_check.lastIndexOf(array[array.length-1][0]); };

CenPop.parse_USCensusPop=function(match,p1,p2,p3) { var temp_removed_refs=[]; var term_map = new Map,results={},re1=new RegExp('\|'); var begin_year=parseInt($('.beginYearText').val); var bar_list = match.slice(0,match.lastIndexOf('}}')).split('\|'); // slice off ending }} var temp_str='Split data\n',eq_list,depth={'bracket':0,'brace':0},curr; var footnote_str='',in_footnote=false,in_ref=false,i,j,last_beginref,last_endref; var last_closed_name_ref; var match_all_name_ref; var new_in_ref=false; var y, x;   var closed_name_re=/ref name\=[^\/\>]*\/\>/; var in_other=false,other_name=""; var char_str={'\\[\\[':['bracket',1],'\\]\\]':['bracket',-1],'\{\{':['brace',1],'\}\}':['brace',-1]},x; for (var elem in bar_list) { new_in_ref=false; if(in_footnote && !in_ref && depth['brace']<=0 && depth['bracket']<=0) in_footnote=false; if(in_other && !in_ref && depth['brace']<=0 && depth['bracket']<=0) in_other=false; eq_list=bar_list[elem].split('\='); if(in_footnote) { footnote_str+='|'; //last_beginref=bar_list[elem].lastIndexOf('<ref'); last_beginref = CenPop.get_last_unclosed_begin_ref(bar_list[elem]); last_endref=bar_list[elem].lastIndexOf(' '); if(last_beginref !== -1 && (last_endref === -1 || last_endref < last_beginref)) in_ref=true; else if(last_endref !== -1) in_ref=false; for(x in char_str) if((curr=bar_list[elem].match(x))) depth[char_str[x][0]]+=char_str[x][1]*curr.length; footnote_str+=bar_list[elem].trim; }		else if(in_other) { results[other_name]+='|'; //		   last_beginref=bar_list[elem].lastIndexOf('=2) { var first_str=eq_list[0].trim,second_str=eq_list[1].trim; if(first_str.match('footnote')!== null && (in_footnote=true)) { for(var j=1; j < eq_list.length; j++) { if(j>1) footnote_str+='='; //last_beginref=eq_list[j].lastIndexOf('<ref'); last_beginref = CenPop.get_last_unclosed_begin_ref(eq_list[j]);

last_endref=eq_list[j].lastIndexOf(' '); if(last_beginref !== -1 && (last_endref === -1 || last_endref < last_beginref)) in_ref=true; else if(last_endref !== -1) in_ref=false; for(x in char_str) { if((curr=eq_list[j].match(x))) depth[char_str[x][0]]+=char_str[x][1]*curr.length; } if(depth['bracket']<0) depth['bracket']=0; footnote_str+=eq_list[j]; }		   }		    else if(first_str.match('[0-9]+') !== null) {				second_int=parseInt(second_str); if(!isNaN(second_int) && second_int!==0) term_map.set(parseInt(first_str),second_int); else term_map.set(first_str,second_str); }		   else if(first_str.match('align')) term_map.set(first_str.trim,second_str.trim); else if(first_str.match('[0-9]+n')) term_map.set(first_str.trim,second_str.trim); else { in_other=true; other_name=first_str; results[first_str]='' for(var j=1; j < eq_list.length; j++) { if(j>1) results[first_str]+='='; //last_beginref=eq_list[j].lastIndexOf('<ref'); last_beginref = CenPop.get_last_unclosed_begin_ref(eq_list[j]);

last_endref=eq_list[j].lastIndexOf(' '); if(last_beginref !== -1 && (last_endref === -1 || last_endref < last_beginref)) in_ref=true; else if(last_endref !== -1) in_ref=false; for(x in char_str) { if((curr=eq_list[j].match(x))) depth[char_str[x][0]]+=char_str[x][1]*curr.length; } if(depth['bracket']<0) depth['bracket']=0; results[first_str]+=eq_list[j]; //if(in_ref) results[first_str]+="="; }		   }		}    }    results.term_map=term_map; results.footnote_str=footnote_str.trim; if(depth['brace']>=0) return results; return null; };

/* Add to a US Census Population template */ CenPop.add_to_template= function(input, estorcensus) { CenPop.most_recent_census=CenPop.most_recent_census_pop=0; //TODO should maybe be nulll? var result=CenPop.get_pop_str(input); if(!result) return ''; CenPop.debug("result="+result,"global"); // If the template already exists, add our data var ret = input.replace(result,function(match,p1,p2,p3) {	var parse_results=CenPop.parse_USCensusPop(match,p1,p2,p3);	if(!parse_results) return ;	console.log("USCensusPop parse_results="+JSON.stringify(parse_results));	var term_map=parse_results.term_map,footnote_str=parse_results.footnote_str.trim;	if(parse_results['estref']!==undefined) {		var refname_regexp=new RegExp(/\/]*)"?\s*>.*<\/ref>/),estref_match;		if((estref_match=parse_results['estref'].match(refname_regexp)))		{			CenPop.removed_refs[estref_match[1]]=estref_match[0];		}	}	else {		parse_results.estref=;	}	var temp_estyear=parseInt($('.estYearText').val),temp_lastcen=temp_estyear-(temp_estyear % 10);	var pop_stuff='\n';	return pop_stuff;   });    CenPop.debug('Finished add_to_template','global');    return ret; };

CenPop.get_histpop_str = function(input, estorcensus) { var ret_str=''; var begin_re = new RegExp('\{\{HistPop|\{\{Historical[ \n\r]*[pP]opulations'); var brace_depth=2; var begin_pos=input.search(begin_re); var curr_pos=begin_pos+2,in_len=input.length; if(begin_pos===-1 &&($('#noMatch').html(+$('#noMatch').html + 1)||true)) return; while(brace_depth>0 && curr_pos < in_len) brace_depth+=(curr_char=input.charAt(curr_pos++))&&curr_char==='{'?1:(curr_char==='}'?-1:0); if(curr_pos<in_len && brace_depth===0 && input.charAt(curr_pos)==='\n') return input.slice(begin_pos,curr_pos+1); else if(curr_pos<in_len && brace_depth===0) return input.slice(begin_pos,curr_pos); else return ''; };

CenPop.parse_histpop=function(match,p1,p2,p3) { var estorcensus=$('input[name="estorcensus"]:checked').val; var copy_list = ['title','type','align','width','state','shading','pop_name','percentages']; var term_map = new Map,results={}; var begin_year=parseInt($('.beginYearText').val); var re1=new RegExp('\|'); var last_right_braces=match.lastIndexOf('}}'); var bar_list = match.slice(0,last_right_braces).split('\|'),eq_list; var temp_str='Split data\n'; var footnote_str=,source_str=; var depth={'bracket':0,'brace':0} var char_str={'\\[\\[':['bracket',1],'\\]\\]':['bracket',-1],'\{\{':['brace',1],'\}\}':['brace',-1]},x; var in_footnote=false, in_source=false; var in_footnote_ref=false, in_source_ref=false; var in_other_ref=false; var bar_iter=0; for (bar_iter=0; bar_iter< bar_list.length; bar_iter++) { elem = bar_iter; if(!in_footnote_ref && depth['brace']<=0 && depth['bracket'] <=0) in_footnote=false; if(!in_source_ref && depth['brace']<=0 && depth['bracket'] <= 0) in_source=false; eq_list=bar_list[elem].split('\='); if(in_footnote) { footnote_str+='|'; if(bar_list[elem].match('<ref') !== null 	      && bar_list[elem].match('<ref[^]* ') === null) in_footnote_ref=true; else if(bar_list[elem].match(' ') !== null) in_footnote_ref=false; for(x in char_str) if((curr=bar_list[elem].match(x))) depth[char_str[x][0]]+=char_str[x][1]*curr.length; footnote_str+=bar_list[elem].trim; }	else if(in_source) { source_str+='|'; if(bar_list[elem].match('=2) { var first_str=eq_list[0].trim,second_str=eq_list[1].trim; if(first_str.match('footnote')!== null && (in_footnote=true)) { for(var j=1; j < eq_list.length; j++) { if(j>1) footnote_str+='='; // Add the removed = if we're not right after footnote if(eq_list[j].match('1) source_str+='='; if(eq_list[j].match('<ref') && !eq_list[j].match('<ref[^]* ')) in_source_ref=true; else if(eq_list[j].match(' ') !== null) in_source_ref=false; for(x in char_str) { if((curr=eq_list[j].match(x))) depth[char_str[x][0]]+=char_str[x][1]*curr.length; } for(x in depth) if(depth[x]<0) depth[x]=0; source_str+=eq_list[j]; }	   }	    else term_map.set(first_str.trim,second_str.trim); }	else if(eq_list.length==1) { var first_str1=eq_list[0].trim,second_num; if(first_str1.match('[0-9]+') !== null && bar_iter+1 < bar_list.length && (bar_iter+=1) &&	      (second_num=parseInt(bar_list[bar_iter])) &&	       !isNaN(second_num) && second_num!==0) term_map.set(parseInt(first_str1),second_num); }   }    results.term_map=term_map; results.footnote_str=footnote_str.trim; results.source_str=source_str.trim; if(depth['brace']>=0) return CenPop.remake_histpop_template(results, estorcensus); return null; };

CenPop.remake_histpop_template=function(results, estorcensus) { var term_map=results.term_map,source_str=results.source_str,footnote_str=results.footnote_str; var pop_stuff='\n'; return pop_stuff; };

CenPop.add_to_histpop_template = function(input, estorcensus) { var result=CenPop.get_histpop_str(input, estorcensus),ret; if(result && (ret = input.replace(result,CenPop.parse_histpop))) return ret; else return ''; };

/** Add a new population template */ CenPop.add_pop = function(input, estorcensus) { //	console.log("input="+input); console.warn("Adding new population template!") var demo_re = new RegExp('(\=\=Demographics\=\=|\=\= Demographics \=\=)\n'); var geo_re = new RegExp('(\=\=Geography\=\=|\=\= Geography \=\=)\n'),sec_re = /==[\s\w]+==\n/; var pop_stuff='\n'; if(input.search(demo_re)!=-1) return input.replace(demo_re,function(match) { return match+pop_stuff; }); else if((geo_pos=input.search(geo_re)) !== -1 && ((sec_match=input.substr(geo_pos+2).match(sec_re))||1)) { console.log('sec_match='+JSON.stringify(sec_match)); if(sec_match) return input.replace(sec_match[0],function(match) { return '==Demographics==\n'+pop_stuff+match; }); else return ''; }   else if((sec_match=input.match(sec_re))) return input.replace(sec_match[0],'==Demographics==\n'+pop_stuff+sec_match[0]); else return ''; }; /** * Add FIPS code to place it's missing from, and return new content, empty if fail */ CenPop.add_FIPS = function(content,fips_code) {   regexp1='/{{Infobox settlement.*\|blank_name\s*=\s*(FIPS code|\s*)\s*\|blank_info\s*=\s*\|'; regexp2='/{{Infobox settlement.*\|blank_name\s*=.*\|blank_info\s*=\s*\|'; };

/** * Update top-level templates in a wiki document, returning the new document (TODO) * * @param content the raw text of the document (unparsed) * @param templates_to_update an object containing each template to update * @return the updated content, null if a failure happens */

/** * Return the entire template specified by the template regexp to return * @param input the input to search * @param temp_regexp the regular expression object for the beginning of the template */

CenPop.get_template = function(input, temp_regexp) { var ret_str=''; var brace_depth=1; var begin_pos=input.search(temp_regexp), curr_pos=input.search(temp_regexp)+2; var in_len=input.length, in_nowiki=false; CenPop.in_comment=false; if(begin_pos===-1) { CenPop.debug('Failed to match template with "'+temp_regexp+' in '+input,'global');	return ;   }    curr_pos=begin_pos+2;    while(brace_depth>0 && curr_pos < in_len) {	if(!in_nowiki && !CenPop.in_comment && curr_pos + 2 <= in_len && 	   input.slice(curr_pos,curr_pos+2)==='{{' && ((++brace_depth)||1)) curr_pos+=2;	else if(!in_nowiki && !CenPop.in_comment && curr_pos+2 <= in_len && 		input.slice(curr_pos,curr_pos+2)==='}}' && ((brace_depth--)||1)) curr_pos+=2;	else if(curr_pos+8<=in_len && input.slice(curr_pos,curr_pos+8)===' '&&(in_nowiki=true)) curr_pos+=8;	else if(in_nowiki&&curr_pos+9<=in_len && input.slice(curr_pos,curr_pos+9)===' ' && !(in_nowiki=false)) curr_pos+=9;	else if(curr_pos+4<=in_len && input.slice(curr_pos,curr_pos+4) ===  &&		!(CenPop.in_comment=false)) curr_pos+=3;	else curr_pos+=1;    }    if(curr_pos<in_len && brace_depth===0 && input.charAt(curr_pos)==='\n') return input.slice(begin_pos,curr_pos+1); else if(curr_pos<in_len && brace_depth===0) return input.slice(begin_pos,curr_pos); else return null; };

/** * Update a template, used primarily for infobox settlement but potentially/probably works elsewhere * @param content content of the template * @param fields_to_update a javascript object with the fields to update and the * @param fields_no_overwrite fields to add only if they were previously blank * @return     new values */ CenPop.update_template=function(input,fields_to_update, fields_no_overwrite, fields_to_remove) { console.warn("fields_to_remove=",fields_to_remove) var in_field=false, in_ref=false, in_nowiki=false, in_brackets=false; var in_len=input.length,x,next_equals; var new_field_obj={}; var refname_regexp=new RegExp(/^\/]*)"?\s*(\/)?>/);   var ref_ret;    var updates={'ret_str':,brace_depth:0,curr_pos:0,in_comment:false,curr_field_name:,old_field_val:,		 curr_ref:,curr_ref_name:,curr_comments:,curr_pos:2,brace_depth:1,ret_str:'{{',curr_ref:''};    for(x in updates) CenPop[x]=updates[x];    /* We already know it begins with '{{' */    while(CenPop.brace_depth>0 && CenPop.curr_pos < in_len) {		if(!in_nowiki && !CenPop.in_comment && 		   input.slice(CenPop.curr_pos,CenPop.curr_pos+4)==='<ref')		{		    ref_ret=refname_regexp.exec(input.substr(CenPop.curr_pos));		    if(ref_ret!== null) {				CenPop.curr_ref_name=ref_ret[1];				if(ref_ret.length<=2 || ref_ret[2] !== '/') {				    CenPop.debug("***in_ref with name",'update');				    in_ref=true;				}				else {				    CenPop.debug("***parsed ref with name, no inner part,length="+ref_ret.length,'update'); in_ref=false; CenPop.curr_ref=ref_ret[0]; }				/* TODO: this is taking way too much!!! (fixed 07/29/2020?) */ CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+ref_ret[0].length),in_field,in_ref); }		   else { /* Not a named and defined ref, can ignore */ if((temp_val=input.substr(CenPop.curr_pos).search('>'))==-1) { in_ref=false; CenPop.debug("Badly formed ref tag!",'global'); CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+4),in_field,in_ref); }				else { CenPop.debug("***in_ref without name,"+input.slice(CenPop.curr_pos,CenPop.curr_pos+temp_val+1),'update'); in_ref=true; CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+temp_val+1),in_field,in_ref); }		   }		}		else if(!in_nowiki && !CenPop.in_comment && CenPop.curr_pos+6 <= in_len &&			input.slice(CenPop.curr_pos,CenPop.curr_pos+6)===' ') { CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+6),in_field,in_ref); CenPop.add_removed_reference(fields_to_update,fields_no_overwrite); /* Update before leaving ref */ in_ref=false; }		else if(!in_nowiki && !CenPop.in_comment && CenPop.curr_pos + 2 <= in_len && 			input.slice(CenPop.curr_pos,CenPop.curr_pos+2)==='{{') { CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+2), in_field, in_ref); CenPop.brace_depth++; }		else if(!in_nowiki && !CenPop.in_comment && CenPop.curr_pos+2 <= in_len && 			input.slice(CenPop.curr_pos,CenPop.curr_pos+2)==='}}') { CenPop.brace_depth--; if(CenPop.brace_depth <= 0 && CenPop.curr_field_name !== '') { var added_new_field=CenPop.add_last_field(fields_to_update,in_field, fields_no_overwrite,new_field_obj, fields_to_remove); // We updated this field, delete it				if(added_new_field) delete fields_to_update[CenPop.curr_field_name.trim]; in_field=false; // Add any new fields not yet updated CenPop.add_remaining_fields(fields_to_update); }		   /* Brace depth decrement needs to be before, so in_field set to false */ CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+2), in_field, in_ref); }		else if(CenPop.curr_pos+8<=in_len && 			input.slice(CenPop.curr_pos,CenPop.curr_pos+8)===' ') { in_nowiki=true; CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+8), in_field, in_ref); }		else if(in_nowiki&&CenPop.curr_pos+9<=in_len && 			input.slice(CenPop.curr_pos,CenPop.curr_pos+9)===' ') { in_nowiki=false; CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+9), in_field, in_ref); }		else if(CenPop.curr_pos+4<=in_len && 			input.slice(CenPop.curr_pos,CenPop.curr_pos+4) === '') { CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+3), in_field, in_ref); my_iter=CenPop.curr_pos; while(my_iter<input.length && 		   input.charAt(my_iter).toString.search('\n')!==-1) my_iter++; CenPop.debug('end space"'+input.slice(CenPop.curr_pos,my_iter)+'"','update'); CenPop.curr_comment+=input.slice(CenPop.curr_pos,my_iter); CenPop.in_comment=false; }		else if(!CenPop.in_comment && !in_nowiki && CenPop.curr_pos+2<=in_len &&			input.slice(CenPop.curr_pos,CenPop.curr_pos+2) === ) {		   in_brackets=true;		    CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+2), in_field, in_ref);		}		else if(!CenPop.in_comment && !in_nowiki &&  CenPop.curr_pos+2<=in_len &&			input.slice(CenPop.curr_pos,CenPop.curr_pos+2) === ) { in_brackets=false; CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+2), in_field, in_ref); }		else if(!in_nowiki && !CenPop.in_comment && !in_ref && !in_brackets &&			CenPop.brace_depth === 1 && input.charAt(CenPop.curr_pos) === '|') { /* Deal with last field */ var added_new_field=CenPop.add_last_field(fields_to_update,in_field, fields_no_overwrite,new_field_obj, fields_to_remove); if(added_new_field) { /* We updated this field */ if(CenPop.curr_field_name.trim in fields_to_update) { CenPop.debug('Add and found "'+CenPop.curr_field_name.trim+'"','update'); delete fields_to_update[CenPop.curr_field_name.trim]; }				else CenPop.debug("Failed to find the trimmed field name",'update'); }		   else { /* Delete it anyway if it wasn't updated, becaue of no overwrite policy */ if(CenPop.curr_field_name.trim in fields_to_update) { delete fields_to_update[CenPop.curr_field_name.trim]; CenPop.debug("No write, but deleting "+CenPop.curr_field_name.trim,'update'); }		   }		    CenPop.old_field_val=''; next_equals=input.substr(CenPop.curr_pos).search('='); next_bar=input.substr(CenPop.curr_pos+1).search(/\|/); if(next_equals == -1 || (next_bar >= 0 && next_equals > next_bar)) { CenPop.debug("Either next bar found before next equals or no next equals",'update'); in_field=false; if(next_equals > next_bar) { CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+1), in_field, in_ref); }				else { /* Just move onto the next character */ CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+1), in_field, in_ref); }		   }		    else { /* Get the field name, update to go past the equals */ in_field=false; CenPop.curr_field_name = input.slice(CenPop.curr_pos+1,CenPop.curr_pos+next_equals); in_field=true; CenPop.curr_pos+=next_equals+1; }		}		else {		   /* Normal character, just move up one */ CenPop.update_fields(input.slice(CenPop.curr_pos,CenPop.curr_pos+1),in_field,in_ref); }   }    if(CenPop.curr_pos< in_len && CenPop.brace_depth===0) { if(input.charAt(CenPop.curr_pos)==='\n') return {'text':CenPop.ret_str+'\n','fields':new_field_obj}; else return {'text':CenPop.ret_str,'fields':new_field_obj}; }   else if(CenPop.brace_depth==0) { /* No newline, weird */ return {'text':CenPop.ret_str+'\n','fields':new_field_obj}; }   else { CenPop.debug('CenPop.curr_pos='+CenPop.curr_pos+', in_len='+in_len+', brace_depth='+CenPop.brace_depth+'\nUnknown brace parsing error in update_template','update'); return {'text':'','fields':{}}; } }; /** * Deals with each possible terminal in update */ CenPop.update_fields = function(terminal, in_field, in_ref) { if(!in_field) CenPop.ret_str+=terminal; else CenPop.old_field_val+=terminal; if(in_ref) CenPop.curr_ref+=terminal; if(CenPop.in_comment) CenPop.curr_comment+=terminal; CenPop.curr_pos+=terminal.length; }; /** * Add the previously added field, return true if it was updated */

CenPop.add_last_field = function(fields_to_update, in_field, fields_no_overwrite,return_field_objs, fields_to_remove) { /* Fixed to have set of fields not to overwrite, so we only write to them if they are empty or missing entirely POTENTIAL BUG: those pages that have something in blank_name nothing in blank_info */   /* Work around in thing bug */ var is_no_overwrite=false; for(i=0; i < fields_no_overwrite.length; i++) { if(fields_no_overwrite[i]===CenPop.curr_field_name.trim) { is_no_overwrite=true; break; }   }    if(CenPop.curr_field_name.trim in fields_to_remove) { CenPop.debug("Removing field "+CenPop.curr_field_name.trim,'update'); return false; }   if(in_field && CenPop.curr_field_name.trim in fields_to_update       && (!is_no_overwrite || CenPop.old_field_val.toString.trim.length===0)) { CenPop.debug('curr_field_name.trim='+CenPop.curr_field_name.trim+',CenPop.old_field_val.toString.trim='+CenPop.old_field_val.toString.trim+' is_no_overwrite='+is_no_overwrite,'update'); CenPop.ret_str+=CenPop.new_field_vals(CenPop.curr_field_name,						     fields_to_update[CenPop.curr_field_name.trim]); return_field_objs[CenPop.curr_field_name.trim]=fields_to_update[CenPop.curr_field_name.trim]; if(CenPop.curr_comment.toString.length > 0) { /* Has comments, add at the end */ CenPop.ret_str+=CenPop.curr_comment.toString; }		if(CenPop.curr_ref_name !== '') { CenPop.curr_ref_name=''; CenPop.curr_ref=''; }		else CenPop.debug("blank, CenPop.curr_ref_name="+CenPop.curr_ref_name,'update'); //CenPop.curr_field_name=''; CenPop.old_field_val=''; //	CenPop.debug('removed_refs='+JSON.stringify(CenPop.removed_refs),'update'); CenPop.curr_comment=''; return true; }   else if(in_field) { CenPop.debug("old val but in field, "+CenPop.curr_field_name+", old_field_val="+CenPop.old_field_val,'update'); /* add the old_val */ if(CenPop.curr_ref_name !== '') { CenPop.curr_ref_name=''; CenPop.curr_ref=''; }		CenPop.ret_str+=CenPop.new_field_vals(CenPop.curr_field_name, CenPop.old_field_val); return_field_objs[CenPop.curr_field_name.trim]=CenPop.old_field_val;

//CenPop.curr_field_name=''; CenPop.old_field_val=''; CenPop.curr_comment=''; if(is_no_overwrite)	return true; else return false; }	}; /* Add the fields that were not yet put into the file, i.e. the new fields The rest of the fields should have already been deleted from fields_to_update */ CenPop.add_remaining_fields = function(fields_to_update) {   var field_name; for(field_name in fields_to_update) { CenPop.debug('adding remaining field '+field_name,'update'); CenPop.ret_str+=CenPop.new_field_vals(field_name,fields_to_update[field_name]); } }; /* Add a removed reference */ CenPop.add_removed_reference = function(fields_to_update,fields_no_overwrite) { /* Only add it if it's gonna be ditched. Oops we probably have a problem now where we add one back if it's equivalent to what we're adding in our replacement Hopefully checking for it in the replacement of the current field prevents putting it in removed_refs */   if(fields_to_update[CenPop.curr_field_name.trim]!==undefined && !fields_no_overwrite.includes(CenPop.curr_field_name.trim)       && fields_to_update[CenPop.curr_field_name.trim].toString.search('')===-1) {   	console.log("fields_to_update="+JSON.stringify(fields_to_update)+", fields_no_overwrite="+JSON.stringify(fields_no_overwrite)); console.log("CenPop.curr_ref_name="+CenPop.curr_ref_name+", CenPop.curr_ref="+CenPop.curr_ref) console.log("CenPop.curr_field_name="+CenPop.curr_field_name.trim); CenPop.removed_refs[CenPop.curr_ref_name]=CenPop.curr_ref; }   else { console.log("Nothing found in add_removed_reference with CenPop.curr_ref_name="+CenPop.curr_ref_name+", CenPop.curr_ref"+CenPop.curr_ref); }   CenPop.curr_ref_name=''; CenPop.curr_ref=''; };

/* Deals with new fields val */ CenPop.new_field_vals = function(curr_field_name,curr_val) {   if(!curr_val) { 	CenPop.debug('curr_field_name='+curr_field_name+' has no curr_val'); return; }   var ret_val='|'+curr_field_name; if(curr_field_name.charAt(curr_field_name.length-1)!== ' ') { 	ret_val+=' '; }   ret_val+='='; if(curr_val.toString.charAt(0) !== ' ') { 	ret_val+=' '; }   ret_val+= curr_val.toString; if(ret_val.charAt(ret_val.length-1)!=='\n') { 	ret_val+='\n'; }   return ret_val; };

/** * Returns an object with the fields and values */ CenPop.convert.parse_template=function(input) {   CenPop.convert.ret_obj={}; // the object to return CenPop.convert.ret_str=''; //	var begin_re = new RegExp(temp_regexp); CenPop.convert.brace_depth=0; CenPop.convert.curr_pos=0; in_len=input.length; var in_field=false, in_ref=false, in_nowiki=false, in_brackets=false; CenPop.convert.in_comment=false, CenPop.convert.curr_field_name=''; CenPop.convert.old_field_val=''; var next_equals; CenPop.convert.curr_ref=, CenPop.convert.curr_ref_name=; CenPop.convert.curr_comments=''; // Holds any comments from this field, to insert at end of line var refname_regexp=new RegExp(/^\/]*)"?\s*(\/)?>/);   var ref_ret;    // We already know it begins with '{{'     CenPop.convert.curr_pos=2;    CenPop.convert.brace_depth=1;    CenPop.convert.ret_str='{{';    CenPop.convert.curr_ref='';    while(CenPop.convert.brace_depth>0 && CenPop.convert.curr_pos < in_len)    {	if(!in_nowiki && !CenPop.convert.in_comment && 	   input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+4)==='<ref')	{	    ref_ret=refname_regexp.exec(input.substr(CenPop.convert.curr_pos));	    if(ref_ret!== null)	    {		CenPop.convert.curr_ref_name=ref_ret[1];		if(ref_ret.length<=2 || ref_ret[2] !== '/')		{		    //	CenPop.debug("***in_ref with name",'update');		    in_ref=true;		}		else		{		    //	CenPop.debug("***parsed ref with name, no inner part,length="+ref_ret.length,'update');		    in_ref=false;		    CenPop.convert.curr_ref=ref_ret[0]; }		// TODO: this is taking way too much!!! CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+ref_ret[0].length),in_field,in_ref); }	   else {		// Not a named and defined ref, can ignore temp_val=input.substr(CenPop.convert.curr_pos).search('>'); if(temp_val==-1) {		   in_ref=false; CenPop.debug("Badly formed ref tag!",'global'); CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+4),in_field,in_ref); }		else {		   CenPop.debug("***in_ref without name,"+input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+temp_val+1),'update');

in_ref=true; CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+temp_val+1),in_field,in_ref); }	   }	}	else if(!in_nowiki && !CenPop.convert.in_comment && CenPop.convert.curr_pos+6 <= in_len &&		input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+6)===' ') {	   CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+6),in_field,in_ref); // Update before leaving ref in_ref=false; }	else if(!in_nowiki && !CenPop.convert.in_comment && CenPop.convert.curr_pos + 2 <= in_len && 		input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+2)==='{{') {	   CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+2), in_field, in_ref); CenPop.convert.brace_depth++;

}	else if(!in_nowiki && !CenPop.convert.in_comment && CenPop.convert.curr_pos+2 <= in_len && 		input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+2)==='}}') {	   CenPop.convert.brace_depth--; //	console.log("*Brace depth down to"+CenPop.convert.brace_depth); if(CenPop.convert.brace_depth <= 0 && CenPop.convert.curr_field_name !== '') {		CenPop.convert.add_last_field(in_field); }	   // Brace depth decrement needs to be before, so in_field set to false CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+2), in_field, in_ref); }	else if(CenPop.convert.curr_pos+8<=in_len && 		input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+8)===' ') {	   in_nowiki=true; CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+8), in_field, in_ref); }	else if(in_nowiki&&CenPop.convert.curr_pos+9<=in_len && 		input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+9)===' ') {	   in_nowiki=false; CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+9), in_field, in_ref);

}	else if(CenPop.convert.curr_pos+4<=in_len && 		input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+4) === '') {

//CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+3), in_field, in_ref); CenPop.convert.curr_pos+=3; my_iter=CenPop.convert.curr_pos; while(my_iter<input.length && input.charAt(my_iter).toString.search('\n')!==-1) {		my_iter++; }	   //	CenPop.debug('end space"'+input.slice(CenPop.convert.curr_pos,my_iter)+'"','update'); CenPop.convert.curr_comment+=input.slice(CenPop.convert.curr_pos,my_iter); CenPop.convert.in_comment=false;

}	else if(!CenPop.convert.in_comment && !in_nowiki && CenPop.convert.curr_pos+2<=in_len &&		input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+2) === )	{	   in_brackets=true;	    CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+2), in_field, in_ref);	}	else if(!CenPop.convert.in_comment && !in_nowiki &&  CenPop.convert.curr_pos+2<=in_len &&		input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+2) === ) {	   in_brackets=false; CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+2), in_field, in_ref); }	else if(!in_nowiki && !CenPop.convert.in_comment && !in_ref && !in_brackets &&		CenPop.convert.brace_depth === 1 && input.charAt(CenPop.convert.curr_pos) === '|') {	   // Deal with last field CenPop.convert.add_last_field(in_field);

CenPop.convert.old_field_val=''; next_equals=input.substr(CenPop.convert.curr_pos).search('='); next_bar=input.substr(CenPop.convert.curr_pos+1).search(/\|/); //	CenPop.debug('next_equals='+next_equals+'\tnext_bar='+next_bar,'update'); if(next_equals == -1 || (next_bar >= 0 && next_equals > next_bar)) {		//CenPop.debug("Can't find next equals ",'global'); in_field=false; // Just move onto the next field if(next_equals > next_bar) {		   // Don't save anything, just go to next_bar CenPop.convert.curr_pos+=next_bar; //CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,next_bar), in_field, in_ref);

}		else CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+1), in_field, in_ref); }	   else {		// Get the field name, update to go past the equals in_field=false; CenPop.convert.curr_field_name = input.slice(CenPop.convert.curr_pos+1,CenPop.convert.curr_pos+next_equals); in_field=true; CenPop.convert.curr_pos+=next_equals+1;

}	}	else {	   // Normal character, just move up one if(!CenPop.convert.in_comment) CenPop.convert.update_fields(input.slice(CenPop.convert.curr_pos,CenPop.convert.curr_pos+1),in_field,in_ref); else CenPop.convert.curr_pos+=1 }   }    if(CenPop.convert.brace_depth==0) {	return CenPop.convert.ret_obj; }   else {	CenPop.debug('CenPop.curr_pos='+CenPop.convert.curr_pos+', in_len='+in_len+', brace_depth='+CenPop.convert.brace_depth+'\nUnknown brace parsing error in update_template','update'); return CenPop.convert.ret_obj; } };

// Deals with each possible terminal in update CenPop.convert.update_fields = function(terminal, in_field, in_ref) { if(!in_field) CenPop.convert.ret_str+=terminal; else CenPop.convert.old_field_val+=terminal; if(in_ref) CenPop.convert.curr_ref+=terminal; if(CenPop.convert.in_comment) CenPop.convert.curr_comment+=terminal; CenPop.convert.curr_pos+=terminal.length; }; // Add the previously added field, return true if it was updated CenPop.convert.add_last_field = function(in_field) { CenPop.convert.ret_obj[CenPop.convert.curr_field_name.toString.trim]=CenPop.convert.old_field_val.toString.trim; }; //