User:Bluedeck/serve/22a3c85609d4d626bc01cd87df71d01f6bb9a62efce214d37b0d4faf4f3ebb74.js

注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。

// author: bluedeck <bluedeck@outlook.com>
// available under CC-BY-SA 3.0

function parseDb(sds)
{
	var clean = function(arr,criteria)	// delete any and all cells that is criteria.
	{
		var brr=[];
		var kk=0;
		for(var jj=0;jj<arr.length;jj++)
		{
			if(arr[jj]===criteria)
			{
				kk++;
			}
			else
			{brr[jj-kk]=arr[jj]}
		}
		return brr;
	};
	
	// preparation: toss away any and all returns. we never need them.
	sds = sds.split("\r").join("");		// still string.
	
	// first, we have to split the whole document by newlines.
	sds = sds.split("\n");
	
	// now look for any and all lines that start with @ sign. they are meta data lines.
	// store them in a special meta array.
	var meta = [];
	for(var i in sds)
	{
		if(sds[i][0]==="@")
		{
			meta[meta.length] = sds[i];	// store such a line into a new meta line.
			sds[i] = "";				// clear this line so we remove it in the next step.
		}
	}
	
	// now we toss away any empty lines.
	sds = clean(sds,"");
	
	// before proceeding, tidy up the meta lines by tossing away things that are not meta.
	for(var i in meta)
	{
		if(meta[i].slice(0,6)!=="@meta\t")
		{
			meta[i]="";
		}
	}
	meta = clean(meta,"");
	
	// now we have a very beautiful meta array and a neat sds array.
	// we first parse metadata. create the standard object. note that all meta objects are strings, never boolean or num.
	var std = {"meta":{"name":"undefined","expandable":"true","cols":"auto","rows":"auto"},"h":[],"q":[]};
	
	// delete the "@meta\t" head from each line, then split all the cells.
	for(var i in meta)
	{
		meta[i] = meta[i].split("@meta\t").join("");
	}
	meta = meta.join("\t").split("\t");
	meta = clean(meta,"");
	
	// configure meta into std. we'll say goodbye to meta from now on.
	for(var i in meta)
	{
		if(meta[i].split(":")[0]==="name")				{std.meta.name=meta[i].split(":")[1];}
		else if(meta[i].split(":")[0]==="expandable")	{std.meta.expandable=meta[i].split(":")[1];}
		else if(meta[i].split(":")[0]==="cols")			{std.meta.cols=meta[i].split(":")[1];}
		else if(meta[i].split(":")[0]==="rows")			{std.meta.rows=meta[i].split(":")[1];}
	}
	
	// take a look at sds[0]. split it by ["\t"] and fit into std.h. of course we should do cleanup.
	std.h = clean(sds[0].split("\t"),"");
	
	// since sds[0] has been used, we discard it.
	sds = sds.slice(1);
	
	for(var i in sds)
	{
		sds[i] = clean(sds[i].split("\t"),"");
	}
	
	std.q = sds;
	
	// now parse cells. the head is still parsed although it can only contain strings.
	for(var i in std.h)
	{
		std.h[i] = parseCell(std.h[i]);
	}
	
	for(var i in std.q)
	{
		for(var j in std.q[i])
		{
			std.q[i][j] = parseCell(std.q[i][j]);
		}
	}
	
	// we're all set.
	return std;
}

function dbfy(std)
{
	// fool proof
	if(!std.meta){return false;}
	if(!std.meta.name){std.meta.name = "";}
	if(!std.meta.expandable){std.meta.expandable = "true";}
	if(!std.meta.cols){std.meta.cols = "auto";}
	if(!std.meta.rows){std.meta.rows = "auto";}
	
	// preprocess
	for(var i in std.h)
	{
		std.h = cellify(std.h);
	}
	for(var i in std.q)
	{
		for(var j in std.q[i])
		{
			std.q[i][j] = cellify(std.q[i][j]);
		}
	}
	
	var sds = "@meta\tname:"+std.meta.name+"\texpandable:"+std.meta.expandable+"\tcols:"+std.meta.cols+"\trows:"+std.meta.rows;
	var sds = sds+"\n"+std.h.join("\t");
	for(var i in std.q)
	{
		sds = sds+"\n"+std.q[i].join("\t");
	}
	return sds;
}

function cellify(json)
{
	if(typeof json ==="string")
	{
		if(json === ""){return "$string:"}
		return json.split("\\").join("\\\\").split("\t").join("\\t").split("\n").join("\\n").split("\r").join("\\r").split("@").join("\\a").split("$").join("\\s");
	}
	if(typeof json === "number")
	{
		return "$double:"+json;
	}
	if(typeof json === "boolean")
	{
		return "$boolean:"+json.toString();
	}
	if(json === null)
	{
		return "$null";
	}
	if(json === undefined)
	{
		return "$undefined";
	}
	else
	{
		return false;
	}	
}

function parseCell(cell)
{
	var ps = function (a)
	{
		return a.split("\\a").join("@").split("\\s").join("$").split("\\r").join("\r").split("\\n").join("\n").split("\\t").join("\t").split("\\\\").join("\\");
	};
	
	if(cell[0]==="@")
	{
		return undefined;
	}
	if(cell[0]==="$")
	{
		var head=cell.split(":")[0];
		var body=cell.slice(head.length+1);
		if(head==="$int"||head==="$"||head==="$long"||head==="$unsigned"||head==="$unsigned long"||head==="$float"||head==="$double"||head==="$byte")
		{
			return parseInt(body);
		}
		if(head==="$boolean"&&body==="true")
		{
			return true;
		}
		if(head==="$boolean"&&body!=="true")
		{
			return false;
		}
		if(head==="$char")
		{
			return ps(body)[0];
		}
		if(head==="$string")
		{
			return ps(body);
		}
		if(head==="$null")
		{
			return null;
		}
		if(head==="$undefined")
		{
			return undefined;
		}
		return ps(body);
	}
	return ps(cell);
}