タグ付きテンプレートでコーディングしてみるテスト

簡単なページを作る時にwikiのように書けたらと思い

```javascript:test.js

$(e=>{

	var vote = `
		Across the Universe
		Baby It's You
		Carol
		Dear Prudence
		Every Little Thing
	`.trim().split(/\s*\n+\s*/)
	
	var episode = Object.entries({
		EVENT_A:'All You Need Is Love',
		EVENT_B:'Bad Boy',
		EVENT_C:'Come Together',
		EVENT_D:'Dig a Pony',
	})
	
	$('body').append(_html`
		ul.Tab(
			li,data-index=0,tab
			li,data-index=1,tab
			li,data-index=2,tab
		),${e=>console.log(e.target.dataset)}
		.Contents(
			.pane,data-tab=Content1(
				.cover,image=hero.png,text
				.header,Content1 | header-1
				.row(span,Ain't She Sweet)
				.row(b,Baby It's You)
				//.row(img,src=Telop.png)
			)
			.pane,data-tab=Content2(
				.header,Content2 | header-1
				ul.rows,${vote.map(s=>_html('li',s))}
				.header,Content2 | header-2
				ul.rows,${vote.map((s,i)=>
					_html('li',s,{index:i,value:s})
				)},${e=>{
					console.log(e.target.dataset)
				}}
			)
			.pane,data-tab=Content3(
				.header,Content3 | header-1
				ul.rows,${episode.map(a=>
					_html('li,name:',a[1],{type:a[0],value:a[1]})
				)},${e=>{
					console.log(e.target.dataset)
				}}
			)
		)
	`)
})

function _html(...a){
	if(typeof a[0]==='string')		return _html.static.create(a)
	if(a[0] instanceof jQuery)		return _html.static.append(a.shift(),a)
	if(_html.template.isTagged(a))	return _html.template.parse(a)
	return $('<div>')
}

_html.static = new class{

	video(){return $('<video loop autoplay muted>')}
	image(q,s){q.css('background-image',`url(${s})`)}
	data(q,data){$.each(data,(k,v)=>{q[0].dataset[k]=v})}
	
	create(a){
		var q,m
		var text = a.shift().trim().replace(/\s*(,|=)\s*/g,'$1')
		switch(m = text.match(/^\w+/)){
			case 'video':	q = this.video();	break;
			case null:		q = $('<div>');		break;
			default:		q = $('<'+m+'>')
		}
		text.replace(/,([\w-]+)=([^,]+)/g,(m,k,v)=>{
			switch(k.toLowerCase()){
				case 'image':		this.image(q,v);	break;
				case 'background':	this.image(q,v);	break;
				default: 			q.attr(k,v)
			}
			return ''
		}).replace(/,([^,]+)/g,(m,s)=>{
			q.append(s)
			return ''
		}).replace(/([#\.])([\w-]+)/g,(m,s,t)=>{
			switch(s){
				case '#':	q.attr('id',t);	break;
				case '.':	q.addClass(t);	break;
			}
			return ''
		})
		return this.append(q,a)
	}
	append(q,a){
		a.forEach(v=>{
			if(v instanceof jQuery){
				q.append(v)
			}else{
				switch(Object.prototype.toString.call(v)){
					case '[object Function]':	q.click(v);		break;
					case '[object Object]':		this.data(q,v);	break;
					default:q.append(v);
				}
			}
		})
		return q
	}
}

_html.template = new class{
	isTagged(a){
		if(Array.isArray(a[0])==false)			return false
		if(a[0].length!=a.length)				return false
		if(a[0].hasOwnProperty('raw')==false)	return false
		return true
	}
	parse(a){
		var text = a[0].map((s,i)=>{
			if(i==0) return s
			if(typeof a[i]==='string') return a[i]+s 
			return '<!--'+i+'-->'+s
		}).join('').trim()
		var _check = text
		while (/\(([^()]+)\)/.test(text)){
			text = text.replace(/\(([^()]*)\)/g,(m,s)=>{
				a.push(this.rows(s.trim(),a))
				return '<!--'+(a.length-1)+'-->'
			})
		}
		var v = this.rows(text,a)
		if(v.length==1) return v[0]
		return _html('',v)
	}
	rows(text,vars){
		var rows = text.trim().split(/\s*\n\s*/).map(row=>{
			if(/<!--\d+-->/.test(row)) return this.row(row,vars)
			return [row]
		}).filter(a=>/^\/\//.test(a[0])==false)
		return rows.map(args=>_html(...args))
	}
	row(row,vars){
		var args = []
		row.replace(/(<!--|-->)/g,m=>{
			if(m=='<!--')	return "\n"+m
			if(m=='-->')	return m+"\n"
			return r
		}).split("\n").forEach((s,i)=>{
			var m = s.match(/^<!--(\d+)-->$/)
			switch(true){
				case(m!=null):	args.push(vars[m[1]]);			break
				case(i==0):		args.push(s.replace(/,+$/,''));	break
				default: 		args = args.concat(s.split(','));
			}
		})
		args = args.filter(s=>s!='')
		if(typeof args[0] ==='string') return args
		if(args[0] instanceof jQuery) return args
		args.unshift('div')
		return args
	}
}

```