//do NOT add this to your vector/monobook.js, this is designed to run on load
function templateLogic(){
if (!window.templateLogicCSS) templateLogic = appendCSS('\
.argument_name {color:#f67}\
.argument_default {color:#7a7a3d}\
div.indent {padding-left:1.5em; border-left:1px dashed #aaa;\
padding-bottom:0.3em; border-bottom:1px dashed #ddd}\
div.operator {padding-left:0.5em}\
span.keyword {font-weight:bold} .expr {background:#eee}\
.choice {font-style:italic}\
.magicvar {font-family:monospace}\
.link {text-decoration:underline}\
div.simple {display:inline; padding:0 0.5em; border:none}\
.tag {background:#eefac7}\
.cell {background:#f5f5f5}\
div.btn {float:right; cursor:pointer; border:2px ridge white; padding:2px; margin:2px}\
}')
var txt, hidden = []
//FUNCTIONS
function r(r1, r2){ txt = txt.replace(r1, r2) }
function hide(re){
r(re, function(s){ return '\x01'+hidden.push(s)+'\x02' })
}
String.prototype.wrap = function(def){ //'123'.wrap('div.my') -> <div class=my>123</div>
var el = 'span', cls = def
def = def.split('.')
if (def.length == 2) { el = def[0]; cls = def[1] }
return '<'+el+' class='+cls+'>'+this+'</'+el+'>'
}
String.prototype.splitOnce = function(ch){
var pos = this.indexOf(ch)
if (pos == -1) return [this.toString(), ""]
else return [this.substring(0,pos), this.substring(pos+1)]
}
String.prototype.substrBefore = function(ch){
return this.substring(0,this.indexOf(ch))
}
function showNext(s){
if (/^{{{/.test(s)) return showArgument(s.substring(3,s.length-3))
if (/^\[\[/.test(s)) return s.wrap('link')
s = s.substring(2,s.length-2).replace(/[\r\n]/g,'').replace(/^\s+/,'');
var ma = /^(#?\w+):(.*)/.exec(s)
if (ma) return showFunc(ma[1], ma[2])
ma = /^([^|]+)\|(.*)/.exec(s)
if (ma) return showTemplate(ma[1], ma[2])
return ('{{'+s+'}}').wrap('magicvar')
}
function showArgument(ar){ // like {{{name|}}}
var pos = ar.indexOf('|'), defa = ''
if (pos != -1){
defa = ar.substring(pos+1).wrap('argument_default')
ar = ar.substring(0, pos+1)
}
return ('$' + ar).wrap('argument_name') + defa
}
function showSwitch(arg){// like |a = 5
var res2 = '', choice, pos, block
for (var i=0; i<arg.length; i++){
block = '<b>|</b> '
if ((pos=arg[i].indexOf('=')) != -1){
block += arg[i].substring(0,pos).wrap('choice') + ' = '
arg[i] = arg[i].substring(pos+1)
}
block += arg[i].wrap('div.indent')
res2 += block.wrap('div.block')
}
return res2
}
function showTemplate(name, args){
var arg = args.split('|'), res = '<br>'+('{{'+name).wrap('template')
res += showSwitch(arg).wrap('div.indent')
return res + '}}'.wrap('template')
}
function showFunc(ff, args){
var arg = args.split('|')
switch(ff){
case '#ifeq':
arg[0] = arg.shift() + ' = ' + arg[0]//and continue to the next
case '#if': case '#iferror': case '#ifexpr': case '#ifexist':
res = ff.wrap('keyword') +' ( '+arg[0] +' )'+arg[1].wrap('div.indent')
if (!arg[2]) break
res += 'else'.wrap('keyword')+arg[2].wrap('div.indent')
break
case '#switch':
res = ff.wrap('keyword') + ' ( ' + arg[0] + ' )'
arg.shift()
res += showSwitch(arg).wrap('div.indent')
break
case '#expr':
//res = ma[2].wrap('div.expr')
res = ff.wrap('keyword') + args.wrap('div.indent')
break
default: res = '{{'+ff+':'+args+'}}'
}
return res.wrap('div.operator')
}
function removeOutput(){ $('#template-logic').remove() }
function processTxt(){
txt = '\n' + txt
r(/&/g,'&'); r(/</g,'<'); r(/>/g,'>')
/*
r(/(style|class|width|height|v?align|(row|col)span|border-\w+|background-\w+|cellspacing) *= *[\w"#% ]+/g,'<span class=style>$&</span>') //mark tags
*/
//first hide all arguments, templates and functions
do {
do {
txtOld = txt
hide(/{{{([^{}]+)}}}/g)
} while (txtOld != txt)
hide(/\[\[[^{}\]]+\]\]/g)
hide(/{{([^{}]+)}}/g)
} while (txtOld != txt)
//unhide them
for (var i=hidden.length; i>0; i--)
r( '\x01'+i+'\x02', showNext(hidden.pop()) )
r(/<\/?[a-z]+[^&<]{0,100}>/g,'<span class=tag>$&</span>') //mark tags
r(/\n{\|[\w %=#:"-]+/g, '<span class=cell>$&</span>') //table: {|
r(/\n\|-.*/g,'<span class=cell>$&</span>') // row: |-
r(/\n[\|!][\w %=#:;"-]+\|(?!\|)/g, '<span class=cell>$&</span>') //cell: |some style|
r(/\n/g,'<br>')
$('#wikiDiff, #wikiPreview').hide()
removeOutput()
var outputDiv = $('<div id=template-logic>\
<div class="btn closeme" title="Close">X</div>\
<div class="btn aboutme" title="About">?</div>'
+txt+'</div>')
.insertAfter($('#contentSub, #siteSub').eq(0))
outputDiv.find('div.closeme').click(function(){removeOutput()})
outputDiv.find('div.aboutme').click(function(){
window.open(mw.config.get('wgServer')+mw.config.get('wgArticlePath').replace(/\$1/,'')+'user_talk:js/templateLogic.js')
})
//add 'simple' class
outputDiv.find('div.indent').each(function(i, el){
el = $(el)
if (el.find('div').length == 0 && el.text().length < 60)
el.addClass('simple')
})
outputDiv.get(0).scrollIntoView()
}//processTxt
// MAIN
if (/edit|submit/.test(mw.config.get('wgAction'))){
var txt = $('#wpTextbox1').val()
processTxt()
}else{
$.get( mw.config.get('wgScript') + '?title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&action=raw',
function(data){ txt = data; processTxt() } )
}
} //templateLogic
$(templateLogic)