wtf_wikipedia
Version:
parse wikiscript into json
1,043 lines (988 loc) • 27.7 kB
JavaScript
import parse from '../../parse/toJSON/index.js'
import strip from '../../parse/toJSON/_strip.js'
import { titlecase, percentage, toOrdinal } from '../_lib.js'
export default {
//https://en.wikipedia.org/wiki/Template:Ra
ra: (tmpl) => {
let obj = parse(tmpl, ['hours', 'minutes', 'seconds'])
return [obj.hours || 0, obj.minutes || 0, obj.seconds || 0].join(':')
},
//https://en.wikipedia.org/wiki/Template:Deg2HMS
deg2hms: (tmpl) => {
//this template should do the conversion
let obj = parse(tmpl, ['degrees'])
return (obj.degrees || '') + '°'
},
hms2deg: (tmpl) => {
//this template should do the conversion too
let obj = parse(tmpl, ['hours', 'minutes', 'seconds'])
return [obj.hours || 0, obj.minutes || 0, obj.seconds || 0].join(':')
},
decdeg: (tmpl) => {
//this template should do the conversion too
let obj = parse(tmpl, ['deg', 'min', 'sec', 'hem', 'rnd'])
return (obj.deg || obj.degrees) + '°'
},
//https://en.wikipedia.org/wiki/Template:Sortname
sortname: (tmpl) => {
let obj = parse(tmpl, ['first', 'last', 'target', 'sort'])
let name = `${obj.first || ''} ${obj.last || ''}`
name = name.trim()
if (obj.nolink) {
return obj.target || name
}
if (obj.dab) {
name += ` (${obj.dab})`
if (obj.target) {
obj.target += ` (${obj.dab})`
}
}
if (obj.target) {
return `[[${obj.target}|${name}]]`
}
return `[[${name}]]`
},
// https://en.wikipedia.org/wiki/Template:First_word
'first word': (tmpl) => {
let obj = parse(tmpl, ['text'])
let str = obj.text || ''
if (obj.sep) {
return str.split(obj.sep)[0]
}
return str.split(' ')[0]
},
trunc: (tmpl) => {
let obj = parse(tmpl, ['str', 'len'])
return (obj.str || '').substr(0, obj.len)
},
'str mid': (tmpl) => {
let obj = parse(tmpl, ['str', 'start', 'end']) || {}
let start = parseInt(obj.start, 10) - 1
let end = parseInt(obj.end, 10)
return (obj.str || '').substr(start, end)
},
reign: (tmpl) => {
let obj = parse(tmpl, ['start', 'end'])
return `(r. ${obj.start} – ${obj.end})`
},
// https://en.wikipedia.org/wiki/Template:Decade_link
'decade link': (tmpl) => {
let { year } = parse(tmpl, ['year'])
return `${year}|${year}s`
},
// https://en.wikipedia.org/wiki/Template:Decade
decade: (tmpl) => {
let obj = parse(tmpl, ['year'])
let year = Number(obj.year)
year = Math.floor(year / 10) * 10 // round to decade
return `${year}s`
},
// https://en.wikipedia.org/wiki/Template:Century
century: (tmpl) => {
let obj = parse(tmpl, ['year'])
let year = parseInt(obj.year, 10)
year = Math.floor(year / 100) + 1
return `${year}`
},
//https://en.wikipedia.org/wiki/Template:Radic
radic: (tmpl) => {
let obj = parse(tmpl, ['after', 'before'])
return `${obj.before || ''}√${obj.after || ''}`
},
'medical cases chart/row': (tmpl) => {
// Deprecated template; we keep it.
return tmpl
},
//https://en.wikipedia.org/wiki/Template:OldStyleDate
oldstyledate: (tmpl) => {
let obj = parse(tmpl, ['date', 'year'])
return obj.year ? obj.date + ' ' + obj.year : obj.date
},
//formatting things - https://en.wikipedia.org/wiki/Template:Nobold
braces: (tmpl) => {
let obj = parse(tmpl, ['text'])
let attrs = ''
if (obj.list) {
attrs = '|' + obj.list.join('|')
}
return '{{' + (obj.text || '') + attrs + '}}'
},
hlist: (tmpl) => {
let obj = parse(tmpl)
obj.list = obj.list || []
return obj.list.join(' · ')
},
pagelist: (tmpl) => {
let arr = parse(tmpl).list || []
return arr.join(', ')
},
// not perfect - https://en.m.wikipedia.org/wiki/Template:Interlinear
interlinear: (tmpl) => {
let arr = parse(tmpl).list || []
return arr.join('\n\n')
},
//actually rendering these links removes the text.
//https://en.wikipedia.org/wiki/Template:Catlist
catlist: (tmpl) => {
let arr = parse(tmpl).list || []
return arr.join(', ')
},
//https://en.wikipedia.org/wiki/Template:Br_separated_entries
'br separated entries': (tmpl) => {
let arr = parse(tmpl).list || []
return arr.join('\n\n')
},
'comma separated entries': (tmpl) => {
let arr = parse(tmpl).list || []
return arr.join(', ')
},
//https://en.wikipedia.org/wiki/Template:Bare_anchored_list
'anchored list': (tmpl) => {
let arr = parse(tmpl).list || []
arr = arr.map((str, i) => `${i + 1}. ${str}`)
return arr.join('\n\n')
},
'bulleted list': (tmpl) => {
let arr = parse(tmpl).list || []
arr = arr.filter((f) => f)
arr = arr.map((str) => '• ' + str)
return arr.join('\n\n')
},
//a strange, newline-based list - https://en.wikipedia.org/wiki/Template:Plainlist
plainlist: (tmpl) => {
tmpl = strip(tmpl)
let arr = tmpl.split('|').slice(1) //remove the title
arr = arr.join('|').split(/\n ?\* ?/) //split on newline
arr = arr.filter((s) => s)
return arr.join('\n\n')
},
//https://en.wikipedia.org/wiki/Template:Term
term: (tmpl) => {
let obj = parse(tmpl, ['term'])
return `${obj.term}:`
},
linum: (tmpl) => {
let { num, text } = parse(tmpl, ['num', 'text'])
return `${num}. ${text}`
},
'block indent': (tmpl) => {
let obj = parse(tmpl)
if (obj['1']) {
return '\n' + obj['1'] + '\n'
}
return ''
},
//https://en.wikipedia.org/wiki/Template:Lbs
lbs: (tmpl) => {
let obj = parse(tmpl, ['text'])
return `[[${obj.text} Lifeboat Station|${obj.text}]]`
},
//Foo-class
lbc: (tmpl) => {
let obj = parse(tmpl, ['text'])
return `[[${obj.text}-class lifeboat|${obj.text}-class]]`
},
lbb: (tmpl) => {
let obj = parse(tmpl, ['text'])
return `[[${obj.text}-class lifeboat|${obj.text}]]`
},
//https://www.mediawiki.org/wiki/Help:Magic_words#Formatting
'#dateformat': (tmpl) => {
tmpl = tmpl.replace(/:/, '|')
let obj = parse(tmpl, ['date', 'format'])
return obj.date
},
//https://www.mediawiki.org/wiki/Help:Magic_words#Formatting
lc: (tmpl) => {
tmpl = tmpl.replace(/:/, '|')
let obj = parse(tmpl, ['text'])
return (obj.text || '').toLowerCase()
},
//https://www.mediawiki.org/wiki/Help:Magic_words#Formatting
uc: (tmpl) => {
tmpl = tmpl.replace(/:/, '|')
let obj = parse(tmpl, ['text'])
return (obj.text || '').toUpperCase()
},
lcfirst: (tmpl) => {
tmpl = tmpl.replace(/:/, '|')
let text = parse(tmpl, ['text']).text
if (!text) {
return ''
}
return text[0].toLowerCase() + text.substr(1)
},
ucfirst: (tmpl) => {
tmpl = tmpl.replace(/:/, '|')
let text = parse(tmpl, ['text']).text
if (!text) {
return ''
}
return text[0].toUpperCase() + text.substr(1)
},
padleft: (tmpl) => {
tmpl = tmpl.replace(/:/, '|')
let obj = parse(tmpl, ['text', 'num'])
let text = obj.text || ''
return text.padStart(obj.num, obj.str || '0')
},
padright: (tmpl) => {
tmpl = tmpl.replace(/:/, '|')
let obj = parse(tmpl, ['text', 'num'])
let text = obj.text || ''
return text.padEnd(obj.num, obj.str || '0')
},
//https://en.wikipedia.org/wiki/Template:Abbrlink
abbrlink: (tmpl) => {
let obj = parse(tmpl, ['abbr', 'page'])
if (obj.page) {
return `[[${obj.page}|${obj.abbr}]]`
}
return `[[${obj.abbr}]]`
},
// https://en.wikipedia.org/wiki/Template:Own
own: (tmpl) => {
let obj = parse(tmpl, ['author'])
let str = 'Own work'
if (obj.author) {
str += ' by ' + obj.author
}
return str
},
//https://www.mediawiki.org/wiki/Help:Magic_words#Formatting
formatnum: (tmpl) => {
tmpl = tmpl.replace(/:/, '|')
let obj = parse(tmpl, ['number'])
let str = obj.number || ''
str = str.replace(/,/g, '')
let num = Number(str)
return num.toLocaleString() || ''
},
//https://en.wikipedia.org/wiki/Template:Frac
fraction: (tmpl) => {
let obj = parse(tmpl, ['a', 'b', 'c'])
if (obj.c) {
return `${obj.a} ${obj.b}/${obj.c}`
}
if (obj.b) {
return `${obj.a}/${obj.b}`
}
return `1/${obj.b}`
},
//https://en.wikipedia.org/wiki/Template:Convert#Ranges_of_values
convert: (tmpl) => {
let obj = parse(tmpl, ['num', 'two', 'three', 'four'])
//todo: support plural units
if (obj.two === '-' || obj.two === 'to' || obj.two === 'and') {
if (obj.four) {
return `${obj.num} ${obj.two} ${obj.three} ${obj.four}`
}
return `${obj.num} ${obj.two} ${obj.three}`
}
return `${obj.num} ${obj.two}`
},
// Large number of aliases - https://en.wikipedia.org/wiki/Template:Tl
tl: (tmpl) => {
let obj = parse(tmpl, ['first', 'second'])
return obj.second || obj.first
},
//this one's a little different
won: (tmpl) => {
let data = parse(tmpl, ['text'])
return data.place || data.text || titlecase(data.template)
},
//a convulated way to make a xml tag - https://en.wikipedia.org/wiki/Template:Tag
tag: (tmpl) => {
let obj = parse(tmpl, ['tag', 'open'])
const ignore = {
span: true,
div: true,
p: true,
}
//pair, empty, close, single
if (!obj.open || obj.open === 'pair') {
//just skip generating spans and things..
if (ignore[obj.tag]) {
return obj.content || ''
}
return `<${obj.tag} ${obj.attribs || ''}>${obj.content || ''}</${obj.tag}>`
}
return ''
},
//dumb inflector - https://en.wikipedia.org/wiki/Template:Plural
plural: (tmpl) => {
tmpl = tmpl.replace(/plural:/, 'plural|')
let obj = parse(tmpl, ['num', 'word'])
let num = Number(obj.num)
let word = obj.word
if (num !== 1) {
if (/.y$/.test(word)) {
word = word.replace(/y$/, 'ies')
} else {
word += 's'
}
}
return num + ' ' + word
},
//https://en.wikipedia.org/wiki/Template:DEC
dec: (tmpl) => {
let obj = parse(tmpl, ['degrees', 'minutes', 'seconds'])
let str = (obj.degrees || 0) + '°'
if (obj.minutes) {
str += obj.minutes + `′`
}
if (obj.seconds) {
str += obj.seconds + '″'
}
return str
},
//https://en.wikipedia.org/wiki/Template:Val
val: (tmpl) => {
let obj = parse(tmpl, ['number', 'uncertainty'])
let num = obj.number
if (num && Number(num)) {
num = Number(num).toLocaleString()
}
let str = num || ''
//prefix/suffix
if (obj.p) {
str = obj.p + str
}
if (obj.s) {
str = obj.s + str
}
//add units, too
if (obj.u || obj.ul || obj.upl) {
str = str + ' ' + (obj.u || obj.ul || obj.upl)
}
return str
},
//{{percentage | numerator | denominator | decimals to round to (zero or greater) }}
percentage: (tmpl) => {
let obj = parse(tmpl, ['numerator', 'denominator', 'decimals'])
let num = Number(obj.numerator) / Number(obj.denominator)
num *= 100
if (num === null) {
return ''
}
let dec = Number(obj.decimals) || 0
return `${num.toFixed(dec)}%`
},
// this one is re-used by i18n
small: (tmpl) => {
let obj = parse(tmpl)
if (obj.list && obj.list[0]) {
return obj.list[0]
}
return ''
},
// {{Percent-done|done=N|total=N|digits=N}}
'percent-done': (tmpl) => {
let obj = parse(tmpl, ['done', 'total', 'digits'])
let num = percentage({
numerator: obj.done,
denominator: obj.total,
decimals: obj.digits,
})
if (num === null) {
return ''
}
return `${obj.done} (${num}%) done`
},
loop: (tmpl) => {
let data = parse(tmpl, ['times', 'text'])
let n = Number(data.times) || 0
let out = ''
for (let i = 0; i < n; i += 1) {
out += data.text || ''
}
return out
},
'str len': (tmpl) => {
let data = parse(tmpl, ['text'])
return String((data.text || '').trim().length)
},
digits: (tmpl) => {
let data = parse(tmpl, ['text'])
return (data.text || '').replace(/[^0-9]/g, '')
},
resize: (tmpl) => {
let { n, text } = parse(tmpl, ['n', 'text'])
if (!text) {
return n || ''
}
return text || ''
},
'last word': (tmpl) => {
let data = parse(tmpl, ['text'])
let arr = (data.text || '').split(/ /g)
return arr[arr.length - 1] || ''
},
replace: (tmpl) => {
let data = parse(tmpl, ['text', 'from', 'to'])
if (!data.from || !data.to) {
return data.text || ''
}
return (data.text || '').replace(data.from, data.to)
},
'title case': (tmpl) => {
let data = parse(tmpl, ['text'])
let txt = data.text || ''
return txt
.split(/ /)
.map((w, i) => {
if ((i > 0 && w === 'the') || w === 'of') {
return w
}
return titlecase(w)
})
.join(' ')
},
'no spam': (tmpl) => {
let data = parse(tmpl, ['account', 'domain'])
return `${data.account || ''}@${data.domain}`
},
'baseball year': (tmpl) => {
let year = parse(tmpl, ['year']).year || ''
return `[[${year} in baseball|${year}]]`
},
'mlb year': (tmpl) => {
let year = parse(tmpl, ['year']).year || ''
return `[[${year} Major League Baseball season|${year}]]`
},
'nlds year': (tmpl) => {
let { year } = parse(tmpl, ['year'])
return `[[${year || ''} National League Division Series|${year}]]`
},
'alds year': (tmpl) => {
let { year } = parse(tmpl, ['year'])
return `[[${year || ''} American League Division Series|${year}]]`
},
'nfl year': (tmpl) => {
let { year, other } = parse(tmpl, ['year', 'other'])
if (other && year) {
return `[[${year} NFL season|${year}]]–[[${other} NFL season|${other}]]`
}
return `[[${year || ''} NFL season|${year}]]`
},
'nfl playoff year': (tmpl) => {
let { year } = parse(tmpl, ['year'])
year = Number(year)
let after = year + 1
return `[[${year}–${after} NFL playoffs|${year}]]`
},
'nba year': (tmpl) => {
let { year } = parse(tmpl, ['year'])
year = Number(year)
let after = year + 1
return `[[${year}–${after} NBA season|${year}–${after}]]`
},
'mhl year': (tmpl) => {
let data = parse(tmpl, ['year'])
let year = Number(data.year)
let after = year + 1
return `[[${year}–${after} NHL season|${year}–${after}]]`
},
// some math
min: (tmpl) => {
let arr = parse(tmpl).list || []
let min = Number(arr[0]) || 0
arr.forEach((str) => {
let n = Number(str)
if (!isNaN(n) && n < min) {
min = n
}
})
return String(min)
},
max: (tmpl) => {
let arr = parse(tmpl).list || []
let max = Number(arr[0]) || 0
arr.forEach((str) => {
let n = Number(str)
if (!isNaN(n) && n > max) {
max = n
}
})
return String(max)
},
// US-politics
uspolabbr: (tmpl) => {
let { party, state, house } = parse(tmpl, ['party', 'state', 'house', 'link'])
if (!party || !state) {
return ''
}
let out = `${party}‑${state}`
if (house) {
out += ` ${toOrdinal(house)}`
}
return out
},
// https://en.wikipedia.org/wiki/Template:Ushr
ushr: (tmpl) => {
let { state, num, type } = parse(tmpl, ['state', 'num', 'type'])
let link = ''
if (num === 'AL') {
link = `${state}'s at-large congressional district`
} else {
num = toOrdinal(Number(num))
return `${state}'s ${num} congressional district`
}
if (type) {
type = type.toLowerCase()
num = num === 'AL' ? 'At-large' : num
// there are many of these
if (type === 'e') {
return `[[${link}|${num}]]`
}
if (type === 'u') {
return `[[${link}|${state}]]`
}
if (type === 'b' || type === 'x') {
return `[[${link}|${state} ${num}]]`
}
}
return `[[${link}]]`
},
// transit station links
metro: (tmpl) => {
let { name, dab } = parse(tmpl, ['name', 'dab'])
if (dab) {
return `[[${name} station (${dab})|${name}]]`
}
return `[[${name} station|${name}]]`
},
station: (tmpl) => {
let { name, dab } = parse(tmpl, ['name', 'x', 'dab'])
if (dab) {
return `[[${name} station (${dab})|${name}]]`
}
return `[[${name} station|${name}]]`
},
bssrws: (tmpl) => {
let { one, two } = parse(tmpl, ['one', 'two'])
let name = one
if (two) {
name += ' ' + two
}
return `[[${name} railway station|${name}]]`
},
stnlnk: (tmpl) => {
let { name, dab } = parse(tmpl, ['name', 'dab'])
if (dab) {
return `[[${name} railway station (${dab})|${name}]]`
}
return `[[${name} railway station|${name}]]`
},
// https://en.wikipedia.org/wiki/Template:Station_link
'station link': (tmpl) => {
let { station, system } = parse(tmpl, ['system', 'station']) //incomplete
return station || system
},
'line link': (tmpl) => {
let { station, system } = parse(tmpl, ['system', 'station']) //incomplete
return station || system
},
subway: (tmpl) => {
let { name } = parse(tmpl, ['name'])
return `[[${name} subway station|${name}]]`
},
'lrt station': (tmpl) => {
let { name } = parse(tmpl, ['name'])
return `[[${name} LRT station|${name}]]`
},
'mrt station': (tmpl) => {
let { name } = parse(tmpl, ['name'])
return `[[${name} MRT station|${name}]]`
},
rht: (tmpl) => {
let { name } = parse(tmpl, ['name'])
return `[[${name} railway halt|${name}]]`
},
ferry: (tmpl) => {
let { name } = parse(tmpl, ['name'])
return `[[${name} ferry wharf|${name}]]`
},
tram: (tmpl) => {
let { name, dab } = parse(tmpl, ['name', 'dab'])
if (dab) {
return `[[${name} tram stop (${dab})|${name}]]`
}
return `[[${name} tram stop|${name}]]`
},
tstop: (tmpl) => {
let { name, dab } = parse(tmpl, ['name', 'dab'])
if (dab) {
return `[[${name} ${dab} stop|${name}]]`
}
return `[[${name} stop|${name}]]`
},
// boats
ship: (tmpl) => {
let { prefix, name, id } = parse(tmpl, ['prefix', 'name', 'id'])
prefix = prefix || ''
return id ? `[[${prefix.toUpperCase()} ${name}]]` : `[[${prefix.toUpperCase()} ${name}]]`
},
sclass: (tmpl) => {
let { cl, type } = parse(tmpl, ['cl', 'type', 'fmt'])
return `[[${cl}-class ${type} |''${cl}''-class]] [[${type}]]`
},
'center block': (tmpl) => {
let { text } = parse(tmpl, ['text'])
return text || ''
},
align: (tmpl) => {
let { text } = parse(tmpl, ['dir', 'text'])
return text || ''
},
font: (tmpl) => {
let { text } = parse(tmpl, ['text'])
return text || ''
},
float: (tmpl) => {
let { text, dir } = parse(tmpl, ['dir', 'text'])
if (!text) {
return dir
}
return text || ''
},
lower: (tmpl) => {
let { text, n } = parse(tmpl, ['n', 'text'])
if (!text) {
return n
}
return text || ''
},
splitspan: (tmpl) => {
let list = parse(tmpl).list || []
return (list[0] || '') + '\n' + (list[1] || '')
},
bracket: (tmpl) => {
let { text } = parse(tmpl, ['text'])
if (text) {
return `[${text}]`
}
return '['
},
// https://en.wikipedia.org/wiki/Template:In_title
'in title': (tmpl) => {
let { title, text } = parse(tmpl, ['title', 'text'])
if (text) {
return text
}
if (title) {
return `All pages with titles containing ${title}` //[[Special: ..]]
}
return ''
},
'look from': (tmpl) => {
let { title, text } = parse(tmpl, ['title', 'text'])
if (text) {
return text
}
if (title) {
return `All pages with titles beginning with ${title}` //[[Special: ..]]
}
return ''
},
'literal translation': (tmpl) => {
let arr = parse(tmpl).list || []
arr = arr.map((str) => `'${str}'`)
return 'lit. ' + arr.join(' or ')
},
overset: (tmpl) => {
let data = parse(tmpl, ['over', 'base'])
return [data.over || '', data.base || ''].join(' ')
},
underset: (tmpl) => {
let data = parse(tmpl, ['under', 'base'])
return [data.base || '', data.under || ''].join(' ')
},
ceil: (tmpl) => {
let data = parse(tmpl, ['txt'])
return `⌈${data.txt}⌉`
},
floor: (tmpl) => {
let data = parse(tmpl, ['txt'])
return `⌊${data.txt}⌋`
},
'vol.': (tmpl) => {
let data = parse(tmpl, ['n'])
return `vol. ${data.n}`
},
rp: (tmpl) => {
let data = parse(tmpl, ['page'])
if (data.pages) {
return `pp${data.pages}`
}
return `p. ${data.page || ''}`
},
gaps: (tmpl) => {
let data = parse(tmpl)
return data.list.join(' ')
},
bra: (tmpl) => {
let data = parse(tmpl, ['a'])
return `⟨${data.a || ''}|`
},
ket: (tmpl) => {
let data = parse(tmpl, ['a'])
return `${data.a || ''}⟩`
},
'angle bracket': (tmpl) => {
let data = parse(tmpl, ['txt'])
return `⟨${data.txt || ''}⟩`
},
'bra-ket': (tmpl) => {
let data = parse(tmpl, ['a', 'b'])
return `⟨${data.a || ''}|${data.b || ''}⟩`
},
braket: (tmpl) => {
let data = parse(tmpl, ['sym', 'a', 'b'])
if (data.sym === 'bra') {
return `⟨${data.a}|`
} else if (data.sym === 'ket') {
return `⟨|${data.a || ''}⟩`
} else {
return `⟨${data.a || ''}|${data.b || ''}⟩`
}
},
pars: (tmpl) => {
let data = parse(tmpl, ['text', 's'])
return `(${data.text || ''})`
},
circumfix: (tmpl) => {
let data = parse(tmpl, ['text'])
return `⟩${data.text || ''}⟨`
},
fluc: (tmpl) => {
let data = parse(tmpl, ['val', 'type'])
let n = Number(data.val)
if (data['custom label']) {
return data['custom label']
}
if (n > 0) {
return ` +${n}` //▲
} else if (n < 0) {
return ` ${n}` //▼
} else if (n === 0) {
return ` no change `
}
return data.val || ''
},
'p.': (tmpl) => {
let data = parse(tmpl, ['a', 'b'])
if (data.b) {
if (parseInt(data.b, 10)) {
return `pp. ${data.a}–${data.b}` //page-range
} else {
return `pp. ${data.a}${data.b}`
}
}
return `p. ${data.a || ''}`
},
subsup: (tmpl) => {
let data = parse(tmpl, ['symbol', 'subscript', 'superscript'])
return `${data.symbol || ''} ${data.subscript || ''} ${data.superscript || ''}`
},
su: (tmpl) => {
let data = parse(tmpl, ['p', 'b'])
return `${data.p || ''} ${data.b || ''}`
},
precision: (tmpl) => {
let data = parse(tmpl, ['num'])
let num = data.num || ''
if (!num.match(/\./) && num.match(/0*$/) && num !== '0') {
return num.match(/0*$/)[0].length * -1
}
let dec = num.split(/\./)[1] || ''
return dec.length
},
intmath: (tmpl) => {
let data = parse(tmpl, ['sign', 'subscript', 'superscript'])
const signs = {
int: '∫',
iint: '∬',
iiint: '∭',
oint: '∮',
varointclockwise: '∲',
ointctrclockwise: '∳',
oiint: '∯',
oiiint: '∰',
}
return `${signs[data.sign] || ''} ${data.superscript || ''} ${data.subscript || ''} `
},
ldelim: (tmpl) => {
let data = parse(tmpl, ['a', 'b', 'sub', 'sup'])
let after = `${data.sub || ''}${data.sup || ''}`
if (data.a === 'square') {
return `[${data.b || ''}]${after}`
} else if (data.a === 'round') {
return `(${data.b || ''})${after}`
} else if (data.a === 'vert') {
return `|${data.b || ''}|${after}`
} else if (data.a === 'doublevert') {
return `||${data.b || ''}||${after}`
}
return `${data.b || ''} ${after}`
},
multiply: (tmpl) => {
let data = parse(tmpl, ['a', 'b'])
return Number(data.a) * Number(data.b)
},
sum: (tmpl) => {
let data = parse(tmpl, ['a', 'b'])
return Number(data.a) + Number(data.b)
},
round: (tmpl) => {
let data = parse(tmpl, ['val', 'decimals'])
let n = Number(data.val)
//todo: handle decimal place
return Math.round(n) || ''
},
rounddown: (tmpl) => {
let data = parse(tmpl, ['val', 'decimals'])
let n = Number(data.val)
//todo: handle decimal place
return Math.floor(n) || ''
},
roundup: (tmpl) => {
let data = parse(tmpl, ['val', 'decimals'])
let n = Number(data.val)
//todo: handle decimal place
return Math.ceil(n) || ''
},
parity: (tmpl) => {
let data = parse(tmpl, ['val', 'even', 'odd'])
if (Number(data.val) % 2 === 0) {
return data.even || 'even'
}
return data.odd || 'odd'
},
hexadecimal: (tmpl) => {
let data = parse(tmpl, ['val'])
let n = Number(data.val)
if (!n) {
return data.val
}
return n.toString(16).toUpperCase()
},
octal: (tmpl) => {
let data = parse(tmpl, ['val'])
let n = Number(data.val)
if (!n) {
return data.val
}
return n.toString(8).toUpperCase() + '₈'
},
decimal2base: (tmpl) => {
let data = parse(tmpl, ['n', 'radix'])
let n = Number(data.n)
let radix = Number(data.radix)
if (!n || !radix) {
return data.n
}
return n.toString(radix).toUpperCase()
},
hex2dec: (tmpl) => {
let data = parse(tmpl, ['val'])
return parseInt(data.val, 16) || data.val
},
ifnotempty: (tmpl) => {
let data = parse(tmpl, ['cond', 'a', 'b'])
if (data.cond) {
return data.a
}
return data.b
},
both: (tmpl) => {
let data = parse(tmpl, ['a', 'b'])
if (data.a && data.b) {
return '1'
}
return ''
},
ifnumber: (tmpl) => {
let data = parse(tmpl, ['n', 'yes', 'no'])
if (!isNaN(Number(data.n))) {
return data.yes || '1'
}
return data.no || ''
},
'order of magnitude': (tmpl) => {
let data = parse(tmpl, ['val'])
let num = parseInt(data.val, 10)
//todo: support decimal forms
if (num || num === 0) {
return String(num).length - 1
}
return '0'
},
'percent and number': (tmpl) => {
let data = parse(tmpl, ['number', 'total', 'decimals'])
let n = Number(data.number) / Number(data.total)
n *= 100
let dec = Number(data.decimals) || 0
return `${n.toFixed(dec)}% (${Number(data.number).toLocaleString()})`
},
music: (tmpl) => {
let data = parse(tmpl, ['glyph'])
// these have unicode working character subs
let glyphs = {
flat: '♭',
b: '♭',
sharp: '♯',
'#': '♯',
natural: '♮',
n: '♮',
doubleflat: '𝄫',
bb: '𝄫',
'##': '𝄪',
doublesharp: '𝄪',
quarternote: '♩',
quarter: '♩',
treble: '𝄞',
trebleclef: '𝄞',
bass: '𝄢',
bassclef: '𝄢',
altoclef: '𝄡',
alto: '𝄡',
tenor: '𝄡',
tenorclef: '𝄡',
}
if (glyphs.hasOwnProperty(data.glyph)) {
return glyphs[data.glyph]
}
return ''
},
simplenuclide: (tmpl) => {
let data = parse(tmpl, ['name', 'mass'])
return `[[${data.name}|${data.mass || ''}${data.name}]]`
},
'font color': (tmpl) => {
let data = parse(tmpl, ['fg', 'bg', 'text'])
if (data.bg && data.text) {
return data.text
}
return data.bg
},
'colored link': (tmpl) => {
let data = parse(tmpl, ['color', 'title', 'text'])
return `[[${data.title}|${data.text || data.title}]]`
},
nftu: (tmpl) => {
let data = parse(tmpl, ['age', 'team'])
return `${data.team} U${data.age}`
},
tls: (tmpl) => {
let data = parse(tmpl, ['name', 'one', 'two'])
let out = `subst:${data.name}`
if (data.one) {
out += '|' + data.one
}
if (data.two) {
out += '|' + data.two
}
return `{{${out}}}`
},
}