モジュール:Remix
表示
モジュール:Remixは、いくつかのWikitext支援機能を提供します。
- 関数conjureは、<page>タグと似たトランスクルージョン機能を提供します。詳細は「テンプレート:Conjure」をご確認ください。
- 関数foreachは、繰り返し実行の機能を提供します。詳細は「テンプレート:Foreach」をご確認ください。
- 関数demoshowは、Wikitextとその実行結果を表示する機能を提供します。詳細は「テンプレート:Demoshow」をご確認ください。
- 関数inheritcatは、引数pagenameで渡されたページのカテゴリを取得し展開します。詳細は「テンプレート:Inheritcat」をご確認ください。
- 関数replace_multipleは、引数contentで渡された文字列に対してrplptnNとrplfmtNの文字列置換を正数Nの小さい順に行った文字列を返します。使用例は「テンプレート:Interval」をご確認ください。
- 関数hexdumpは、引数contentで渡された文字列をhexdump出力します。
local bi = {}
function bi.create_rplset(in_args)
local rplset = {}
for k, v in pairs(in_args) do
local m = mw.ustring.match(k, '^rplptn(%d+)$')
if m ~= nil then
local ptn = mw.text.decode(bi.get_alt_if_empty(v, ''))
local fmt = mw.text.decode(bi.get_alt_if_empty(in_args['rplfmt' .. m], ''))
local err = bi.get_alt_if_empty(in_args['rplerr' .. m], '')
local han = bi.get_alt_if_empty(in_args['rplhan' .. m], '0')
if han ~= '0' then
ptn = bi.zen2han(ptn)
fmt = bi.zen2han(fmt)
end
if #ptn > 0 then
rplset[#rplset + 1] = {['idx'] = m, ['ptn'] = ptn, ['fmt'] = fmt, ['err'] = err, ['idx'] = m}
end
end
end
table.sort(rplset, function(a,b)
return tonumber(a['idx']) < tonumber(b['idx'])
end)
return rplset
end
function bi.use_rplset(content, rplset)
for i, v in ipairs(rplset) do
local k = v['ptn']
if v['err'] == '' or v['err'] == 'skip' then
-- skip error
elseif mw.ustring.match(content, k) == nil then
if v['err'] == 'error' then
return bi.createErrorMessage('NOT MATCH PATTERN#' .. v['idx'] .. ' "<nowiki>' .. k .. '</nowiki>"')
elseif v['err'] == 'blank' then
return ''
else
return v['err']
end
end
content = mw.ustring.gsub(content, k, v['fmt'])
end
return content
end
function bi.get_contents(in_args)
local rplset = bi.create_rplset(in_args)
local nilqa = {}
local argindex = bi.get_alt_if_empty(in_args['index'], nil)
local argpages = bi.get_alt_if_empty(in_args['pages'], nil)
local argdelim = bi.get_alt_if_empty(in_args['delim'], '')
local argfromsection = bi.get_alt_if_empty(in_args['fromsection'], nil)
local argtosection = bi.get_alt_if_empty(in_args['tosection'], nil)
local argonlysection = bi.get_alt_if_empty(in_args['onlysection'], nil)
local argshowlink = bi.get_alt_if_empty(in_args['showlink'], '1')
if argshowlink == '1' then
argshowlink = '元ページ'
end
local arghexdump = bi.get_alt_if_empty(in_args['hexdump'], '0')
local arggaplink = bi.get_alt_if_empty(in_args['gaplink'], '')
local argbindCJK = bi.get_alt_if_empty(in_args['bindCJK'], '0')
local argbindwest = bi.get_alt_if_empty(in_args['bindwest'], '0')
local argtitlepath = bi.get_alt_if_empty(in_args['titlepath'], nil)
local argkanji_old2new = bi.get_alt_if_empty(in_args['kanji_old2new'], '0')
local rgx_ss_begin_Q = '<section%s+begin%s*=%s*"'; local rgx_ss_begin_E = '"%s*/>'
local rgx_ss_end_Q = '<section%s+end%s*=%s*"'; local rgx_ss_end_E = '"%s*/>'
local single_pagelink = ''
local err_nosection = "\n[[Category:Pages transcluding nonexistent sections]]\n"
local match_count = 0
if argonlysection ~= nil then
if argfromsection ~= nil or argtosection ~= nil then
return bi.createErrorMessage('onlysection and (from,to)section is exclusive.')
else
argfromsection = argonlysection
argtosection = argonlysection
end
end
if argfromsection ~= nil then
argfromsection = bi.escape_lua_regex(argfromsection)
end
if argtosection ~= nil then
argtosection = bi.escape_lua_regex(argtosection)
end
if argpages == nil then
local fname = argindex
local title = bi.get_title(fname)
local text = title:getContent()
if text == nil then
return bi.createErrorMessage('NOT EXIST TITLE "' .. fname .. '"')
end
if argfromsection ~= nil then
local ptnstr = '^.*(' .. rgx_ss_begin_Q .. argfromsection .. rgx_ss_begin_E .. ')'
text, match_count = mw.ustring.gsub(text, ptnstr, '%1')
if match_count ~= 1 then
return bi.createErrorMessage('INVALID FROMSECTION "' .. argfromsection .. '" IN "' .. fname .. '"') .. err_nosection
end
end
if argtosection ~= nil then
local ptnstr = '(' .. rgx_ss_end_Q .. argtosection .. rgx_ss_end_E .. ').*$'
text, match_count = mw.ustring.gsub(text, ptnstr, '%1')
if match_count ~= 1 then
return bi.createErrorMessage('INVALID TOSECTION "' .. argtosection .. '" IN "' .. fname .. '"') .. err_nosection
end
end
if argshowlink ~= '0' then
single_pagelink = bi.create_pagelink(fname, argshowlink, arggaplink)
end
table.insert(nilqa, text)
table.insert(nilqa, argdelim)
else
if mw.ustring.match(mw.ustring.lower(argindex), '^page:.+$') == nil then
argindex = 'Page:' .. argindex
end
local num_arr = bi.parse_num_arr_str(argpages, ',', ';')
for idx, num in ipairs(num_arr) do
repeat
local fname = argindex .. '/' .. num
local page = mw.ext.proofreadPage.newPage(mw.ustring.sub(fname, 6))
local title = page.title
local text = title:getContent()
if text == nil then
table.insert(nilqa, bi.createErrorMessage('NOT EXIST PAGE "' .. fname .. '"'))
break
end
if idx == 1 and argfromsection ~= nil then
local ptnstr = '^.*(' .. rgx_ss_begin_Q .. argfromsection .. rgx_ss_begin_E .. ')'
text, match_count = mw.ustring.gsub(text, ptnstr, '%1')
if match_count ~= 1 then
table.insert(nilqa, bi.createErrorMessage('INVALID FROMSECTION "' .. argfromsection .. '" IN "' .. fname .. '"') .. err_nosection)
break
end
end
if idx == table.getn(num_arr) and argtosection ~= nil then
local ptnstr = '(' .. rgx_ss_end_Q .. argtosection .. rgx_ss_end_E .. ').*$'
text, match_count = mw.ustring.gsub(text, ptnstr, '%1')
if match_count ~= 1 then
table.insert(nilqa, bi.createErrorMessage('INVALID TOSECTION "' .. argtosection .. '" IN "' .. fname .. '"') .. err_nosection)
break
end
end
if argshowlink ~= '0' then
table.insert(nilqa, bi.create_pagelink(fname, page.displayedNumber, arggaplink))
end
table.insert(nilqa, text)
table.insert(nilqa, argdelim)
until true
end
end
local content = table.concat(nilqa, "")
content = bi.use_rplset(content, rplset)
if argkanji_old2new ~= '0' then
local chjpn = require('Module:CharacterJPN')
content = chjpn.kanji_old2new_direct2(content, in_args['oldnew'], in_args['exclude'], in_args['exold'], in_args['exnew'])
end
if argbindCJK ~= '0' then
content = bi.bindCJK(content, argbindCJK)
end
if argbindwest ~= '0' then
content = bi.bindwest(content)
end
if argpages == nil then
content = bi.resolve_relative_path(argtitlepath or argindex, content)
elseif argtitlepath then
content = bi.resolve_relative_path(argtitlepath, content)
end
content = single_pagelink .. content
if arghexdump ~= '0' then
return bi.get_hexdump_html(content, false)
end
return content
end
function bi.replace_multiple(frame)
local content = bi.get_alt_if_empty(frame.args['content'], '')
local arghexdump = bi.get_alt_if_empty(frame.args['hexdump'], '0')
local rplset = bi.create_rplset(frame.args)
content = bi.use_rplset(content, rplset)
if arghexdump ~= '0' then
return bi.get_hexdump_html(content, true)
end
return content
end
function bi.conjure(frame)
local content = mw.getCurrentFrame():preprocess(bi.get_contents(frame.args))
local str_excludecat = bi.get_alt_if_empty(frame.args['excludecat'], '')
if #str_excludecat > 0 then
local ret_content, include_cats, exclude_cats = bi.exclude_category(content, str_excludecat)
content = ret_content
end
return content
end
function bi.foreach(frame)
local argkey1 = bi.zen2han(bi.get_alt_if_empty(frame.args['key'], ''))
local argkey2 = bi.zen2han(bi.get_alt_if_empty(frame.args['key2'], ''))
local argkey3 = bi.zen2han(bi.get_alt_if_empty(frame.args['key3'], ''))
local argvalues1= bi.zen2han(bi.get_alt_if_empty(frame.args['values'], ''))
local argvalues2 = bi.zen2han(bi.get_alt_if_empty(frame.args['values2'], ''))
local argvalues3 = bi.zen2han(bi.get_alt_if_empty(frame.args['values3'], ''))
local argcontent = bi.get_alt_if_empty(frame.args['content'], '')
local argheader1 = bi.get_alt_if_empty(frame.args['header'], '')
local argheader2 = bi.get_alt_if_empty(frame.args['header2'], '')
local argheader3 = bi.get_alt_if_empty(frame.args['header3'], '')
local argfooter1 = bi.get_alt_if_empty(frame.args['footer'], '')
local argfooter2 = bi.get_alt_if_empty(frame.args['footer2'], '')
local argfooter3 = bi.get_alt_if_empty(frame.args['footer3'], '')
local argpreprocess = bi.get_alt_if_empty(frame.args['preprocess'], '0')
local argtrim = bi.get_alt_if_empty(frame.args['trim'], '0')
local argcomma = bi.get_alt_if_empty(frame.args['comma'], ',')
local argsemicolon = bi.get_alt_if_empty(frame.args['semicolon'], ';')
local arghexdump = bi.get_alt_if_empty(frame.args['hexdump'], '0')
local num_arr1 = bi.parse_num_arr_str(argvalues1, argcomma, argsemicolon)
local num_arr2 = bi.parse_num_arr_str(argvalues2, argcomma, argsemicolon)
local num_arr3 = bi.parse_num_arr_str(argvalues3, argcomma, argsemicolon)
local nilqa = {}
local content = ''
repeat
if argcontent == '' then
content = bi.createErrorMessage("argument '''content''' not found")
elseif #argkey1 == 0 then
content = bi.createErrorMessage("argument '''key''' not found")
elseif #num_arr1 == 0 then
content = bi.createErrorMessage("argument '''values''' not found")
elseif #num_arr2 > 0 and #argkey2 == 0 then
content = bi.createErrorMessage("argument '''key2''' not found")
elseif #num_arr2 == 0 and #argkey2 > 0 then
content = bi.createErrorMessage("argument '''values2''' not found")
elseif #num_arr3 > 0 and #argkey3 == 0 then
content = bi.createErrorMessage("argument '''key3''' not found")
elseif #num_arr3 == 0 and #argkey3 > 0 then
content = bi.createErrorMessage("argument '''values3''' not found")
elseif #num_arr3 > 0 and #num_arr2 == 0 then
content = bi.createErrorMessage("argument '''values2''' not found")
end
if #content > 0 then -- treat as error
content = mw.getCurrentFrame():preprocess(content)
break
end
if #argheader1 > 0 then
table.insert(nilqa, argheader1)
end
for k1, v1 in pairs(num_arr1) do
if argtrim ~= '0' then
v1 = mw.ustring.gsub(v1, "^%s*(.-)%s*$", "%1")
end
local str1 = mw.ustring.gsub(argcontent, argkey1, v1)
if #num_arr2 == 0 then
table.insert(nilqa, str1)
else
if #argheader2 > 0 then
local header = mw.ustring.gsub(argheader2, argkey1, v1)
table.insert(nilqa, header)
end
for k2, v2 in pairs(num_arr2) do
if argtrim ~= '0' then
v2 = mw.ustring.gsub(v2, "^%s*(.-)%s*$", "%1")
end
local str2 = mw.ustring.gsub(str1, argkey2, v2)
if #num_arr3 == 0 then
table.insert(nilqa, str2)
else
if #argheader3 > 0 then
local header = mw.ustring.gsub(mw.ustring.gsub(argheader3, argkey1, v1), argkey2, v2)
table.insert(nilqa, header)
end
for k3, v3 in pairs(num_arr3) do
if argtrim ~= '0' then
v3 = mw.ustring.gsub(v3, "^%s*(.-)%s*$", "%1")
end
local str3 = mw.ustring.gsub(str2, argkey3, v3)
table.insert(nilqa, str3)
end
if #argfooter3 > 0 then
local footer = mw.ustring.gsub(mw.ustring.gsub(argfooter3, argkey1, v1), argkey2, v2)
table.insert(nilqa, footer)
end
end
end
if #argfooter2 > 0 then
local footer = mw.ustring.gsub(argfooter2, argkey1, v1)
table.insert(nilqa, footer)
end
end
end
if #argfooter1 > 0 then
table.insert(nilqa, argfooter1)
end
content = table.concat(nilqa, "")
content = bi.zen2han(mw.text.decode(content))
if argpreprocess ~= '0' then
content = mw.getCurrentFrame():preprocess(content)
end
until true
if arghexdump ~= '0' then
return bi.get_hexdump_html(content, true)
end
return content
end
function bi.foreach_replace(frame)
return bi.foreach(frame)
end
function bi.demoshow(frame)
local argwikitext = bi.get_alt_if_empty(frame.args['wikitext'], nil)
local argbefore = bi.get_alt_if_empty(frame.args['before'], nil)
local argafter = bi.get_alt_if_empty(frame.args['after'], nil)
local argcontent = bi.get_alt_if_empty(frame.args['content'], nil)
local argusepre = bi.get_alt_if_empty(frame.args['usepre'], '0')
local argbr = bi.get_alt_if_empty(frame.args['br'], nil)
local content = ''
repeat
if argwikitext == nil then
content = bi.createErrorMessage("argument '''wikitext''' not found")
break
elseif argbefore == nil then
content = bi.createErrorMessage("argument '''before''' not found")
break
elseif argafter == nil then
content = bi.createErrorMessage("argument '''after''' not found")
break
elseif argcontent == nil then
content = bi.createErrorMessage("argument '''content''' not found")
break
end
local bra_nowiki, ket_nowiki = '<nowiki>', '</nowiki>'
if argusepre ~= '0' then
bra_nowiki, ket_nowiki = '<pre>', '</pre>'
end
content = argcontent
local wikitext = bi.zen2han(argwikitext)
local before_wikitext = bra_nowiki .. wikitext .. ket_nowiki
if argbr ~= nil then
if argusepre == '0' then
before_wikitext = mw.ustring.gsub(before_wikitext, argbr, ket_nowiki .. '<br/>' .. bra_nowiki)
else
before_wikitext = mw.ustring.gsub(before_wikitext, argbr, "\n")
end
wikitext = mw.ustring.gsub(wikitext, argbr, "\n")
end
content = mw.ustring.gsub(mw.ustring.gsub(content, argbefore, before_wikitext), argafter, wikitext)
until true
content = bi.zen2han(mw.text.decode(content))
return mw.getCurrentFrame():preprocess(content)
end
function bi.inheritcat(frame)
local pagename = frame.args['pagename']
local str_excludecat = bi.get_alt_if_empty(frame.args['excludecat'], nil)
local useroot = bi.get_alt_if_empty(frame.args['useroot'], '0')
if useroot ~= '0' then
if mw.ustring.match(pagename, '/') == nil then
return mw.getCurrentFrame():preprocess(bi.createErrorMessage('NOT SUBPAGE "' .. pagename .. '"'))
end
pagename = mw.ustring.gsub(pagename, "^([^/]+)/.+$", "%1")
end
local title = bi.get_title(pagename)
local text = title:getContent()
local content = mw.getCurrentFrame():preprocess(text)
local ret_content, include_cats, exclude_cats = bi.exclude_category(content, str_excludecat)
local retstr = table.concat(include_cats, "\n")
return retstr
end
function bi.inherit_categories(frame)
return bi.inheritcat(frame)
end
function bi.exclude_category(str_content, str_exclude)
local u_200E = '' -- 目視しにくいU+200Eが入っているので注意
local excarr = {}
if str_exclude ~= nil then
str_exclude = mw.ustring.gsub(str_exclude, u_200E, '')
for e1 in mw.ustring.gmatch(str_exclude, '[^,]+') do
local e2 = bi.escape_lua_regex(e1)
table.insert(excarr, e2)
end
end
if #excarr > 0 then
str_content = mw.ustring.gsub(str_content, u_200E, '')
end
local ret_content = str_content
local include_cats = {}
local exclude_cats = {}
for e1 in mw.ustring.gmatch(str_content, '%[%[%s*[Cc]ategory%s*:[^%]]+%]%]') do
local rgx_matched = nil
for idx, val in ipairs(excarr) do
local rgx_cat = '%[%[%s*[Cc]ategory%s*:%s*' .. val .. '%s*%]%]'
if mw.ustring.match(e1, rgx_cat) ~= nil then
rgx_matched = rgx_cat
break
end
rgx_cat = '%[%[%s*[Cc]ategory%s*:%s*' .. val .. '%s*%|[^%]]*%s*%]%]'
if mw.ustring.match(e1, rgx_cat) ~= nil then
rgx_matched = rgx_cat
break
end
end
if rgx_matched == nil then
table.insert(include_cats, e1)
else
table.insert(exclude_cats, e1)
ret_content = mw.ustring.gsub(ret_content, rgx_matched, '')
end
end
for e1 in mw.ustring.gmatch(str_content, '%[%[%s*カテゴリ%s*:[^%]]+%]%]') do
local rgx_matched = nil
for idx, val in ipairs(excarr) do
local rgx_cat = '%[%[%s*カテゴリ%s*:%s*' .. val .. '%s*%]%]'
if mw.ustring.match(e1, rgx_cat) ~= nil then
rgx_matched = rgx_cat
break
end
rgx_cat = '%[%[%s*カテゴリ%s*:%s*' .. val .. '%s*%|[^%]]*%s*%]%]'
if mw.ustring.match(e1, rgx_cat) ~= nil then
rgx_matched = rgx_cat
break
end
end
if rgx_matched == nil then
table.insert(include_cats, e1)
else
table.insert(exclude_cats, e1)
ret_content = mw.ustring.gsub(ret_content, rgx_matched, '')
end
end
return ret_content, include_cats, exclude_cats
end
-- @param num_arr_str number array string separated by ','. number range format is 'FROM;TO;STEP'. STEP can be omitted, and treated as 1 or -1.
-- @return sample '2,7;11,5,40' => {2,7,8,9,10,11,5,40}. '7;12;2,3,10,40' => {7,9,11,3,10,40}. '9,6;4,20;15;-2,20' => {9,6,5,4,20,18,16,20}
function bi.parse_num_arr_str(num_arr_str, sep_comma, sep_semicolon)
local ret_arr = {}
for e1 in mw.ustring.gmatch(num_arr_str, '[^' .. sep_comma .. ']+') do
if mw.ustring.match(e1, '^[^' .. sep_semicolon .. ']+$') then
table.insert(ret_arr, e1)
elseif mw.ustring.match(e1, '^%d+' .. sep_semicolon .. '%d+.*$') then
local p = {}
for e2 in mw.ustring.gmatch(e1, '[^' .. sep_semicolon .. ']+') do
table.insert(p, math.floor(e2))
end
local psize = #p
if psize == 2 then
if p[1] <= p[2] then
p[3] = 1
else
p[3] = -1
end
elseif psize == 3 then
assert(mw.ustring.match(p[3], '^-?%d+$'), 'invalid step ' .. p[3])
else
assert(false, 'invalid range ' .. e2)
end
for n = p[1], p[2], p[3] do
table.insert(ret_arr, math.floor(n))
end
else
assert(false, 'invalid array ' .. e1)
end
end
return ret_arr
end
function bi.escape_lua_regex(instr)
return mw.ustring.gsub(instr, '([%(%)%.%%%+%-%*%?%[%]%^%$])', '%%%1')
end
function bi.bindCJK(content, bind_option)
local range_cjk = ' -ヿ⺀々〇〻㐀-䶿一-鿿가-힣-︀-️!-ᄒ𠀀-𱍊󠄀-󠇯' -- 目視しにくい異体字セレクター(U+FE00〜U+FE0F、U+E0100〜U+E01EF)を含んでいるので、編集は要注意
local rgxcap_cjk = '([' .. range_cjk .. '])'
local rgx_lf, fmt_after = '\n', '%1%2'
local ret_str = mw.ustring.gsub(content, rgxcap_cjk .. rgx_lf .. rgxcap_cjk, fmt_after)
if bind_option == '1' then
return ret_str
elseif bind_option == '2' then
bind_option = 'r,ruby,rs'
elseif bind_option == '3' then
bind_option = 'r,ruby,rs,rbcmnt,rbcmnt2'
end
for e1 in mw.ustring.gmatch(bind_option, '[^,]+') do
local tmplptn = e1
local ch = mw.ustring.codepoint(e1, 1, 1)
if 0x41 <= ch and ch <= 0x5A then
tmplptn = '[' .. mw.ustring.char(ch) .. mw.ustring.char(ch + 0x20) .. ']' .. mw.ustring.sub(e1, 2)
elseif 0x61 <= ch and ch <= 0x7A then
tmplptn = '[' .. mw.ustring.char(ch - 0x20) .. mw.ustring.char(ch) .. ']' .. mw.ustring.sub(e1, 2)
end
-- 以下rgxcap_tmpl_arrの一つ目は引数なし。二つ目は引数ありで出現頻度の高いルビ末尾{{く}}や{{ぐ}}に対応するため末尾を「}}}?}?」としている。
local rgxcap_tmpl_arr = {'({{' .. tmplptn .. '}})', '({{' .. tmplptn .. '|[^}]-}}}?}?)'}
for idx, rgxcap_tmpl in ipairs(rgxcap_tmpl_arr) do
ret_str = mw.ustring.gsub(ret_str, rgxcap_tmpl .. rgx_lf .. rgxcap_cjk, fmt_after)
ret_str = mw.ustring.gsub(ret_str, rgxcap_cjk .. rgx_lf .. rgxcap_tmpl, fmt_after)
ret_str = mw.ustring.gsub(ret_str, rgxcap_tmpl .. rgx_lf .. rgxcap_tmpl, fmt_after)
end
end
return ret_str
end
function bi.split_log(text)
return mw.ustring.gsub(text, '(.)', '_%1')
end
function bi.bindwest(content)
local range_west = 'A-Za-zÀ-֏'
local rgx_str1 = '([' .. range_west .. '])%-\n([' .. range_west .. '])'
local rgx_str2 = '([' .. range_west .. '])\\%-\n([' .. range_west .. '])'
return mw.ustring.gsub(mw.ustring.gsub(content, rgx_str1, '%1%2'), rgx_str2, '%1-%2')
end
function bi.create_pagelink(str_page, str_alias, str_gap)
local gap = ''
if #str_gap > 0 then
gap = '{{Gap|' .. str_gap .. '}}'
end
return '{{MarginNote|margin=left|margin-width=300|text=[[' .. str_page .. '|[' .. str_alias .. ']]]' .. gap .. '}}'
end
function bi.get_alt_if_empty(instr, altstr)
if instr == nil or #instr == 0 then
return altstr
end
return instr
end
function bi.get_title(fname)
local title = mw.title.new(fname)
local redir_title = title.redirectTarget
if redir_title then
title = redir_title
end
return title
end
function bi.createErrorMessage(message)
return '{{color|red|🚧🚨👷♀️ ' .. message .. ' 👷♂️🚨🚧}}'
end
local mypagename = ''
function bi.resolve_relative_path(str_pagename, text)
mypagename = str_pagename
local content = mw.ustring.gsub(text, '(%[%[%s*)([%./]+)([^%./%]]*)(%]%])', bi.rplfnc_resolve_relative_path)
return content
end
function bi.rplfnc_resolve_relative_path(c1, c2, c3, c4)
if c2 == nil and c3 == nil and c4 == nil then
return c1
elseif c2 == '/' then
if mw.ustring.find(c3, '^[^%|%[%]]+') ~= nil then
return c1 .. mypagename .. '/' .. c3 .. c4
end
else
local match_count = 0
_, match_count = mw.ustring.gsub(c2, '%.%./', '../')
if match_count > 0 then
local rgxstr_tail = mw.ustring.rep('/[^/]+', match_count) .. '$'
local neostr = mw.ustring.gsub(mypagename, rgxstr_tail, '')
if mw.ustring.find(c3, '^[^%|%[%]]+') ~= nil then
neostr = neostr .. '/'
end
return c1 .. neostr .. c3 .. c4
end
end
return c1 .. c2 .. c3 .. c4
end
function bi.zen2han(text)
local content = mw.ustring.gsub(text, '([!-}])', bi.rplfnc_zen2han)
return content
end
function bi.rplfnc_zen2han(c1)
local ch = mw.ustring.codepoint(c1, 1, 1)
if 0xFF01 <= ch and ch <= 0xFF5D then
return mw.ustring.char(ch - 0xFEE0)
end
return c1
end
function bi.insert_for_hexdump(datas, hexs, raws, colmax, altch, br)
if #hexs > 0 then
local hstr = table.concat(hexs, "")
local gaplen = colmax * 7 - mw.ustring.len(hstr)
table.insert(datas, hstr)
table.insert(datas, mw.ustring.rep(" ", gaplen))
table.insert(datas, " 🧐")
table.insert(datas, table.concat(raws, ""))
table.insert(datas, "🧐")
table.insert(datas, br)
hexs = {}
raws = {}
end
return datas, hexs, raws
end
function bi.get_hexdump_html(instr, b_preprocess)
local datas = {}
local hexs = {}
local raws = {}
local colmax = 16
local altch = "."
local br = "\n"
local idx = 0
table.insert(datas, "<pre>\n")
for chnum in mw.ustring.gcodepoint(instr) do
idx = idx + 1
if ((idx - 1) % colmax == 0) then
datas, hexs, raws = bi.insert_for_hexdump(datas, hexs, raws, colmax, altch, br)
table.insert(datas, mw.ustring.format("%08X🧐", idx - 1))
end
if chnum <= 0xFFFF then
table.insert(hexs, mw.ustring.format(" %04X", chnum))
elseif chnum <= 0xFFFFF then
table.insert(hexs, mw.ustring.format(" %05X", chnum))
else
table.insert(hexs, mw.ustring.format(" %06X", chnum))
end
local ch = mw.ustring.char(chnum)
if mw.ustring.find(ch, "^%s$") and ch ~= ' ' then
table.insert(raws, altch)
else
table.insert(raws, ch)
end
end
datas, hexs, raws = bi.insert_for_hexdump(datas, hexs, raws, colmax, altch, br)
table.insert(datas, "</pre>")
local content = table.concat(datas, "")
if b_preprocess then
return mw.getCurrentFrame():preprocess(content)
end
return content
end
function bi.hexdump(frame)
local content = bi.get_alt_if_empty(frame.args['content'], '')
return bi.get_hexdump_html(content, true)
end
return bi