Module:Ibox

-- --fills sub(lang) infobox by main infobox data local p = {}

function p.updated (frame) if not frame then frame = { args = { 'LinkPreview/ru/com', 'd M Y', 'ru' }       }        frame.preprocess = function (s) return '20170923063416|newpages.js\n20180212073404|code.css\n20180308050631|code.js' end end local args = frame.args local pagename = args['pagename'] or args[1] or args['1'] or mw.title.getCurrentTitle.rootText local fmt = args['format'] or args[2] or args['2'] or 'Y.m.d'   local lang = args['uselang'] or args[3] or args['3'] or 'en' pagename = mw.ustring.match(pagename, '[^/]*')--rootpagename local timeq = '' local dplq = '' local dplo = frame:preprocess(dplq) local ret, page, upd, pos = , , '', 0 for m in mw.ustring.gmatch(mw.text.trim(dplo), '[^\n]+') do       pos = mw.ustring.find(m, '|') or 0 if pos < 1 then--wrong dpl output return ret end upd = mw.ustring.sub(m, 0, pos - 1) page = mw.ustring.sub(m, pos + 1) ret = ret .. mw.ustring.gsub(timeq, '%%date%%', upd) .. ' (' .. page .. ') ' end ret = mw.ustring.gsub(ret, '(.*) $', '%1')--strip last \n\n return frame:preprocess(ret) end--updated

function p.t (frame) local s, s1 = '', '\n\nPreview button for article comments.' local content = '' --ct: current title; bt: base title; local ct, bt, debug = {}, {}, false if not frame then debug = true frame = {['args'] = {}} frame.args['Author'] = ''--'user:fngplg' frame.args['Examples'] = ''--'ru.borderlands' frame.args['Description'] = 'Adds preview button to article comments.' frame.args['Updated'] = ''--'2017.09.08' frame.args['Code'] = ''--'code.js' frame.args['Languages'] = ''--'ru' frame.args['Status'] = ''--'beta' frame.args['Image caption'] = '' frame.args['Image file'] = '' frame.args['Image size'] = '' frame.args['Scope'] = '' frame.args['Title'] = '' frame.args['Using code by'] = '' frame.args['Other attribution'] = '' frame.args['Type'] = '' bt.getContent = function return s1 end ct.isSubpage = true ct.basePageTitle = bt       frame.getCurrentTitle = function  return ct end frame.getParent = function return frame end frame.preprocess = function (obj, s) return s end end --arguments local args = frame:getParent.args local a_author = args['Author'] local a_examples = args['Examples'] local a_description = args['Description'] local a_updated = args['Updated'] local a_code = args['Code'] local a_languages = args['Languages'] local a_sstatus = args['Status'] local a_image_caption = args['Image caption'] local a_image_file = args['Image file'] local a_image_size = args['Image size'] local a_scope = args['Scope'] local a_title = args['Title'] local a_using_code_by = args['Using code by'] local a_other_attribution = args['Other attribution'] local a_ttype = args['Type'] local a_uselang = args['uselang'] --options --force static local a_force = args['force'] --force per param --force to update: a_f == '0' local a_fauthor = p.iif(args['fAuthor'] == '0', false, args['fAuthor']) local a_fexamples = p.iif(args['fExamples'] == '0', false, args['fExamples']) local a_fdescription = p.iif(args['fDescription'] == '0', false, true) local a_fupdated = p.iif(args['fUpdated'] == '0', false, args['fUpdated']) local a_fcode = p.iif(args['fCode'] == '0', false, args['fCode']) local a_flanguages = p.iif(args['fLanguages'] == '0', false, args['fLanguages']) local a_fsstatus = p.iif(args['fStatus'] == '0', false, args['fStatus']) local a_fimage_caption = p.iif(args['fImage caption'] == '0', false, true) local a_fimage_file = p.iif(args['fImage file'] == '0', false, args['fImage file']) local a_fimage_size = p.iif(args['fImage size'] == '0', false, args['fImage size']) local a_fscope = p.iif(args['fScope'] =='0', false, args['fScope']) local a_ftitle = p.iif(args['fTitle'] =='0', false, true) local a_fusing_code_by = p.iif(args['fUsing code by'] == '0', false, args['fUsing code by']) local a_fother_attribution = p.iif(args['fOther attribution'] == '0', false, args['fOther attribution']) local a_fttype = p.iif(args['fType'] == '0', false, args['fType']) --arguments local ret = {} ret.uselang = a_uselang --or mytitle.subpageText ret.author = a_author ret.code = a_code ret.examples = a_examples ret.description = a_description ret.updated = a_updated ret.languages = a_languages ret.sstatus = a_sstatus ret.image_caption = a_image_caption ret.image_file = a_image_file ret.image_size = a_image_size ret.scope = a_scope ret.title = a_title ret.using_code_by = a_using_code_by ret.other_attribution = a_other_attribution ret.ttype = a_ttype --get data from basepage local mytitle = p.iif(debug, ct, mw.title.getCurrentTitle) --p.getParent(frame) local ret1 if mytitle.isSubpage and (not a_force) then content = mytitle.basePageTitle:getContent ret1 = p.process(content) if ret1 then ret = ret1 end ret.uselang = a_uselang or mytitle.subpageText ret.author = p.iif(a_fauthor, a_author, ret.author) ret.code = p.iif(a_fcode, a_code, ret.code) ret.examples = p.iif(a_fexamples, a_examples, ret.examples) ret.description = p.iif(a_fdescription, a_description, ret.description) --ret1 is free for use now ret.updated = p.iif(a_fupdated, a_updated, ret.updated) ret.languages = p.iif(a_flanguages, a_languages, ret.languages) ret.sstatus = p.iif(a_fsstatus, a_sstatus, ret.sstatus) ret.image_caption = p.iif(a_fimage_caption, a_image_caption, ret.image_caption) ret.image_file = p.iif(a_fimage_file, a_image_file, ret.image_file) ret.image_size = p.iif(a_fimage_size, a_image_size, ret.image_size) ret.scope = p.iif(a_fscope, a_scope, ret.scope) ret.title = p.iif(a_ftitle, a_title, ret.title) ret.using_code_by = p.iif(a_fusing_code_by, a_using_code_by, ret.using_code_by) ret.other_attribution = p.iif(a_fother_attribution, a_other_attribution, ret.other_attribution) ret.ttype = p.iif(a_fttype, a_ttype, ret.ttype) end s = p.construct(ret) if frame.preprocess then s = frame:preprocess(s) end return s end--t

function p.construct (ret) --infobox constructor local s = '' return s end --construct

function p.process (content) --process content. return {} --link/template defender local strips = {} --patterns local pibox = '{{[iI]nfobox[ _]JavaScript/fng%s-|' --'{{([iI]nfobox[ _]JavaScript%s-|.*)}}' local pauthor = '.-|%s-Author%s-=%s-(.-)%s-[|%z]' local pcode = '.-|%s-Code%s-=%s-(.-)%s-[|%z]' local pexamples = '.-|%s-Examples%s-=%s-(.-)%s-[|%z]' local pdescription = '.-|%s-Description%s-=%s-(.-)%s-[|%z]' local pupdated = '.-|%s-Updated%s-=%s-(.-)%s-[|%z]' local planguages = '.-|%s-Languages%s-=%s-(.-)%s-[|%z]' local pstatus = '.-|%s-Status%s-=%s-(.-)%s-[|%z]' local pimage_caption = '.-|%s-Image caption%s-=%s-(.-)%s-[|%z]' local pimage_file = '.-|%s-Image file%s-=%s-(.-)%s-[|%z]' local pimage_size = '.-|%s-Image size%s-=%s-(.-)%s-[|%z]' local pscope = '.-|%s-Scope%s-=%s-(.-)%s-[|%z]' local ptitle = '.-|%s-Title%s-=%s-(.-)%s-[|%z]' local pusing_code_by = '.-|%s-Using code by%s-=%s-(.-)%s-[|%z]' local pother_attribution = '.-|%s-Other attribution%s-=%s-(.-)%s-[|%z]' local pttype = '.-|%s-Type%s-=%s-(.-)%s-[|%z]' --patterns local pos = mw.ustring.find(content, pibox, 1, false) if pos == nil then --no infobox found return end local ibox = mw.ustring.match(content, '.-(%b{})', pos) --add \0 to indicate end of string ibox = mw.ustring.sub(ibox, 3, #ibox - 2) .. '\0'   --mw.log('ibox:', ibox) local libox = ibox for m in mw.ustring.gmatch(libox, '%b{}') do       ibox = p.strip(ibox, m, strips) end libox = ibox for m in mw.ustring.gmatch(libox, '%b[]') do       ibox = p.strip(ibox, m, strips) end local author = mw.ustring.match(ibox, pauthor)-- or '' local code = mw.ustring.match(ibox, pcode)-- or '' local examples = mw.ustring.match(ibox, pexamples)-- or '' local description = mw.ustring.match(ibox, pdescription)-- or '' local updated = mw.ustring.match(ibox, pupdated)-- or '' local languages = mw.ustring.match(ibox, planguages)-- or '' local sstatus = mw.ustring.match(ibox, pstatus)-- or '' local image_caption = mw.ustring.match(ibox, pimage_caption)-- or '' local image_file = mw.ustring.match(ibox, pimage_file)-- or '' local image_size = mw.ustring.match(ibox, pimage_size)-- or '' local scope = mw.ustring.match(ibox, pscope)-- or '' local title = mw.ustring.match(ibox, ptitle)-- or '' local using_code_by = mw.ustring.match(ibox, pusing_code_by)-- or '' local other_attribution = mw.ustring.match(ibox, pother_attribution)-- or '' local ttype = mw.ustring.match(ibox, pttype)-- or '' local ret = {} ret.author = p.iif(author, p.unstrip(author, strips), nil) ret.code = p.iif(code, p.unstrip(code, strips), nil) ret.examples = p.iif(examples, p.unstrip(examples, strips), nil) ret.description = p.iif(description, p.unstrip(description, strips), nil) ret.updated = p.iif(updated, p.unstrip(updated, strips), nil) ret.languages = p.iif(languages, p.unstrip(languages, strips), nil) ret.sstatus = p.iif(sstatus, p.unstrip(sstatus, strips), nil) ret.image_caption = p.iif(image_caption, p.unstrip(image_caption, strips), nil) ret.image_file = p.iif(image_file, p.unstrip(image_file, strips), nil) ret.image_size = p.iif(image_size, p.unstrip(image_size, strips), nil) ret.scope = p.iif(scope, p.unstrip(scope, strips), nil) ret.title = p.iif(title, p.unstrip(title, strips), nil) ret.using_code_by = p.iif(using_code_by, p.unstrip(using_code_by, strips), nil) ret.other_attribution = p.iif(other_attribution, p.unstrip(other_attribution, strips), nil) ret.ttype = p.iif(ttype, p.unstrip(ttype, strips), nil) return ret end --process

function p.unstrip (src, strips) if (src == nil ) or (src == '') then return nil end for i = #strips, 1, -1 do       src = mw.ustring.gsub(src, strips[i].k, strips[i].v, 1) end return src end--unstrip

function p.strip (src, str, strips) local lrnd lrnd = tostring(math.floor(math.random * 1000000000)) table.insert(strips, {k = lrnd, v = str}) src = mw.ustring.gsub(src, p.escapeLua(str), lrnd, 1) return src end--strip

function p.getParent (frame) local cf, pf = frame, frame:getParent if pf then return p.getParent(pf) else return cf end end

function p.iif (condition, istrue, isfalse) if condition then return istrue else return isfalse end end

function p.escapeLua (s) --https://stackoverflow.com/questions/9790688/escaping-strings-for-gsub return mw.ustring.gsub(s, '([^%w])', '%%%1') end

function p.parseDate (d) if not d then return end --is d parsed already if type(d) == 'table' then if d.normalized then return d       end end local mon = {jan=1, feb=2, mar=3, apr=4, may=5, jun=6, jul=7, aug=8, sep=9, oct=10, nov=11, dec=12} local delim = {'-', ' ', '.', '/'} local dt, dy, dm, dd = {}, , , '' local d1 = mw.ustring.lower(d)--do not break unformatted d   for i = 1, #delim do        dy, dm, dd = mw.ustring.match(d1, '(.-)%' .. delim[i] .. '(.-)%' .. delim[i] .. '(.*)') if dy and dm and dd then --try to parse month if tonumber(dm) then dm = tonumber(dm) else dm = mw.ustring.sub(dm, 1, 3) dm = mon[dm] end dy = tonumber(dy) dd = tonumber(dd) if dm and dy and dd then --yyyy required. will stop work properly at 2032 if (dd < 32) and (dy < 32) then return d end --works only for yyyy format if dd > 31 then dd, dy = dy, dd end --os.time-ready table. usage: os.date('%Y.%m.%d', os.time(dt)) dt.year = dy               dt.month = dm                dt.day = dd                dt.normalized = dy .. '-' .. p.iif(dm < 10, '0' .. dm, dm) .. '-' .. p.iif(dd < 10, '0'.. dd, dd) return dt           end--if actual date end--if something end--delimiters loop return d end--parseDate

function p.getDay (d) --in: {[yyyy], [mm], [dd]} --out: dd, i or nil --year and month was removed already. table.remove(d, i) for y/m if #d == 1 and tonumber(d[1]) then return p.iif(#d[1] == 1, '0' .. d[1], d[1]) end return end--getday

function p.getYear (d) --in: {[yyyy], [mm], [dd]} --out: yyyy, i or nil local yyyy for i = 1, #d do       --yyyy = tonumber(d[i]) --if yyyy and yyyy > 31 then return i, yyyy end if #d[i] == 4 and tonumber(d[i]) then return d[i], i        end end return end--getyear

function p.getMonth (d) --in: {[yyyy], [mm], [dd]} --out: mm, i or nil local mon = {jan='01', feb='02', mar='03', apr='04', may='05', jun='06', jul='07', aug='08', sep='09', oct='10', nov='11', dec='12'} local mm   for i = 1, #d do        mm = mw.ustring.sub(d[i], 1, 3) mm = mon[mm] if mm then return mm, i end end return end--getmonth

return p