From WikiChip
Difference between revisions of "Module:core"
(Handle partial pdata lookup failure.) |
|||
(4 intermediate revisions by 2 users not shown) | |||
Line 47: | Line 47: | ||
function p.set_val(prop, val) | function p.set_val(prop, val) | ||
p.frame:preprocess('{{#set: ' .. prop .. '=' .. val .. '}}') | p.frame:preprocess('{{#set: ' .. prop .. '=' .. val .. '}}') | ||
+ | end | ||
+ | |||
+ | local function append_packaging_data(infobox, arg_name, pdata, add_space) | ||
+ | local package_name = origArgs[arg_name] | ||
+ | if not package_name or package_name == '' then return add_space end | ||
+ | |||
+ | local need_space = add_space | ||
+ | local function may_add_space() | ||
+ | need_space = true | ||
+ | if add_space then | ||
+ | infobox:tag('tr'):tag('td'):attr('colspan', '2'):tag('hr') | ||
+ | add_space = false | ||
+ | end | ||
+ | end | ||
+ | |||
+ | local function show_error(text) | ||
+ | infobox:wikitext('[[Category:Articles with invalid parameter in template]]') | ||
+ | may_add_space() | ||
+ | local e = mw.html.create('tr') | ||
+ | e:tag('td') | ||
+ | :attr('colspan', '2') | ||
+ | :attr('style', 'color: #c00;') | ||
+ | :wikitext(text) | ||
+ | infobox:node(e) | ||
+ | end | ||
+ | |||
+ | -- Reject unexpected input, esp. smw.ask operators []:|?*~ | ||
+ | if mw.ustring.find(package_name, '[^%w %-+._,/]') then | ||
+ | show_error('Invalid package name') | ||
+ | return need_space | ||
+ | end | ||
+ | |||
+ | local package_location, info, result = {} | ||
+ | local page_name = package_name | ||
+ | for field in string.gmatch(package_name, "([^,]+),?") do | ||
+ | table.insert(package_location, field) | ||
+ | end | ||
+ | if #package_location > 1 then | ||
+ | page_name = package_location[1] .. '/packages/' .. package_location[2] | ||
+ | if pdata['packages'][package_location[1]] then | ||
+ | info = pdata['packages'][package_location[1]][package_location[2]] | ||
+ | end | ||
+ | end | ||
+ | if mw.smw then | ||
+ | result = mw.smw.ask('[[Category:all ic packages]][[' .. page_name .. ']]' .. | ||
+ | '|?package|?package type|?package contacts|?package pitch' .. | ||
+ | '|?package length|?package width|?package height|?socket') | ||
+ | end | ||
+ | local dim_props = {'package length', 'package width', 'package height'} | ||
+ | if type(result) == 'table' and #result >= 1 and result[1]['package'] then | ||
+ | info = result[1] | ||
+ | else | ||
+ | if not info then | ||
+ | show_error('Unknown package "' .. package_name .. '"') | ||
+ | return need_space | ||
+ | end | ||
+ | page_name = nil | ||
+ | for i, name in ipairs(dim_props) | ||
+ | do info[name] = info.p_size and info.p_size[i] or nil end | ||
+ | end | ||
+ | |||
+ | local function tabled(x) return type(x) == 'table' and x or { x } end | ||
+ | local function show(label, text) | ||
+ | if not text or text == '' then return end | ||
+ | may_add_space() | ||
+ | infobox:node(p.add_entry(label, mw.html.create('td'):wikitext(text))) | ||
+ | end | ||
+ | local function param(a) | ||
+ | local prop_names = unpack(a) | ||
+ | local text, sep = '', '' | ||
+ | for i, prop_name in ipairs(tabled(prop_names)) do | ||
+ | local values = info[prop_name] -- single value or table | ||
+ | if values then | ||
+ | local n_values = 0 | ||
+ | for j, value in ipairs(tabled(values)) do | ||
+ | if value and value ~= '' then | ||
+ | if a.set_prop then p.set_val(a.set_prop, value) end | ||
+ | text = text .. sep .. value | ||
+ | sep = a.sep or ', ' | ||
+ | n_values = n_values + 1 | ||
+ | if n_values >= (a.max_values or 1) then break end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | return text | ||
+ | end | ||
+ | local p_type_text, p_type_abbr = param{{'package type', 'p_type'}}, '' | ||
+ | if p_type_text ~= '' and mw.ustring.len(p_type_text) <= 10 then | ||
+ | p_type_abbr = ' (' .. p_type_text .. ')' | ||
+ | p_type_text = '' | ||
+ | end | ||
+ | local p_name = param{{'package', 'p_name'}, set_prop='package', max_values=10} | ||
+ | if p_name ~= '' then | ||
+ | if page_name then p_name = '[[' .. page_name .. '|' .. p_name .. ']]' end | ||
+ | show('Package', p_name .. p_type_abbr) | ||
+ | end | ||
+ | show('Package Type', p_type_text) | ||
+ | show('Dimension', param{dim_props, sep=' × '}) | ||
+ | show('Pitch', param{{'package pitch', 'p_pitch'}, max_values=2, sep=' × '}) | ||
+ | show('Contacts', param{{'package contacts', 'p_contacts'}}) | ||
+ | show('Socket', param{{'socket', 'p_socket'}, set_prop='socket', max_values=10}) | ||
+ | return need_space | ||
end | end | ||
Line 238: | Line 341: | ||
-- #################################################################### | -- #################################################################### | ||
-- Packaging | -- Packaging | ||
− | + | local has_arg_pkg_name = has_arg('package name') or has_arg('package name 1') | |
+ | if has_arg('package module 1') or has_arg_pkg_name or has_arg('back image') then | ||
p.add_separator(infobox, 'Packaging') | p.add_separator(infobox, 'Packaging') | ||
end | end | ||
− | + | ||
-- Packaging | -- Packaging | ||
− | if | + | if has_arg_pkg_name then |
− | + | local pdata = require('Module:packaging data') | |
− | + | -- Also accept name, name 2, name 3 for consistency. | |
− | + | local add_space = append_packaging_data(infobox, 'package name', pdata, false) | |
− | + | for i = 1, 10 do | |
− | + | add_space = append_packaging_data(infobox, 'package name ' .. i, pdata, add_space) | |
− | + | end | |
− | + | end | |
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
if has_arg('package module 1') then | if has_arg('package module 1') then | ||
− | |||
for i = 1, 10 do | for i = 1, 10 do | ||
if has_arg('package module ' .. i) then | if has_arg('package module ' .. i) then |
Latest revision as of 23:45, 1 April 2023
To add this template, simple add
{{core}}to the page and save. The chip infobox will have a small
[Edit Values]
button at the top-right corner which can be used to add values using a form.
local p = {}
local origArgs
function p.add_file_prefix(str)
if string.match(string.lower(str), '^file:') then
return str
else
return 'File:' .. str
end
end
function p.add_separator(box, title)
box:tag('tr')
:tag('td')
:attr('class', 'header')
:attr('colspan', '2')
:wikitext(title)
end
function add_header(box, str)
box
:tag('tr')
:tag('td')
:attr('class', 'header')
:attr('colspan', '2')
:wikitext(str)
end
function p.add_entry(value, right)
local e = mw.html.create('tr')
e:tag('td')
:attr('class', 'label')
:wikitext(value)
e:node(right)
return e
end
function has_arg(name)
-- The argument can exist and be empty or not exist at all
return string.len(origArgs[name] or '') > 0
end
function arg(name)
return origArgs[name]
end
function p.set_val(prop, val)
p.frame:preprocess('{{#set: ' .. prop .. '=' .. val .. '}}')
end
local function append_packaging_data(infobox, arg_name, pdata, add_space)
local package_name = origArgs[arg_name]
if not package_name or package_name == '' then return add_space end
local need_space = add_space
local function may_add_space()
need_space = true
if add_space then
infobox:tag('tr'):tag('td'):attr('colspan', '2'):tag('hr')
add_space = false
end
end
local function show_error(text)
infobox:wikitext('[[Category:Articles with invalid parameter in template]]')
may_add_space()
local e = mw.html.create('tr')
e:tag('td')
:attr('colspan', '2')
:attr('style', 'color: #c00;')
:wikitext(text)
infobox:node(e)
end
-- Reject unexpected input, esp. smw.ask operators []:|?*~
if mw.ustring.find(package_name, '[^%w %-+._,/]') then
show_error('Invalid package name')
return need_space
end
local package_location, info, result = {}
local page_name = package_name
for field in string.gmatch(package_name, "([^,]+),?") do
table.insert(package_location, field)
end
if #package_location > 1 then
page_name = package_location[1] .. '/packages/' .. package_location[2]
if pdata['packages'][package_location[1]] then
info = pdata['packages'][package_location[1]][package_location[2]]
end
end
if mw.smw then
result = mw.smw.ask('[[Category:all ic packages]][[' .. page_name .. ']]' ..
'|?package|?package type|?package contacts|?package pitch' ..
'|?package length|?package width|?package height|?socket')
end
local dim_props = {'package length', 'package width', 'package height'}
if type(result) == 'table' and #result >= 1 and result[1]['package'] then
info = result[1]
else
if not info then
show_error('Unknown package "' .. package_name .. '"')
return need_space
end
page_name = nil
for i, name in ipairs(dim_props)
do info[name] = info.p_size and info.p_size[i] or nil end
end
local function tabled(x) return type(x) == 'table' and x or { x } end
local function show(label, text)
if not text or text == '' then return end
may_add_space()
infobox:node(p.add_entry(label, mw.html.create('td'):wikitext(text)))
end
local function param(a)
local prop_names = unpack(a)
local text, sep = '', ''
for i, prop_name in ipairs(tabled(prop_names)) do
local values = info[prop_name] -- single value or table
if values then
local n_values = 0
for j, value in ipairs(tabled(values)) do
if value and value ~= '' then
if a.set_prop then p.set_val(a.set_prop, value) end
text = text .. sep .. value
sep = a.sep or ', '
n_values = n_values + 1
if n_values >= (a.max_values or 1) then break end
end
end
end
end
return text
end
local p_type_text, p_type_abbr = param{{'package type', 'p_type'}}, ''
if p_type_text ~= '' and mw.ustring.len(p_type_text) <= 10 then
p_type_abbr = ' (' .. p_type_text .. ')'
p_type_text = ''
end
local p_name = param{{'package', 'p_name'}, set_prop='package', max_values=10}
if p_name ~= '' then
if page_name then p_name = '[[' .. page_name .. '|' .. p_name .. ']]' end
show('Package', p_name .. p_type_abbr)
end
show('Package Type', p_type_text)
show('Dimension', param{dim_props, sep=' × '})
show('Pitch', param{{'package pitch', 'p_pitch'}, max_values=2, sep=' × '})
show('Contacts', param{{'package contacts', 'p_contacts'}})
show('Socket', param{{'socket', 'p_socket'}, set_prop='socket', max_values=10})
return need_space
end
function p.core(frame)
p.frame = frame
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame.args
end
local infobox = mw.html.create('table')
infobox
:attr('class', 'infobox')
infobox
:tag('tr')
:tag('td'):attr('colspan', '2')
:tag('small'):attr('style', 'float: left; font-weight: bold;')
:wikitext('[[Special:FormEdit/core/' .. frame:preprocess('{{FULLPAGENAME}}') .. '|<i class="fa fa-edit"></i>Edit Values]]')
-- header
if has_arg('name') then
infobox
:tag('tr')
:tag('td')
:attr('class', 'header-main')
:attr('colspan', '2')
:wikitext('[[name::' .. arg('name') .. ']]')
end
-- image
for i = 1, 10 do
local name = (i == 1) and "" or " " .. i
if has_arg('image' .. name) then
local image = p.add_file_prefix(arg('image' .. name))
local image_size = has_arg('image' .. name .. ' size') and arg('image' .. name .. ' size') or "200px"
infobox
:tag('tr')
:tag('td')
:attr('style', 'text-align: center;')
:attr('colspan', '2')
-- make sure it's the ogimage
:wikitext('[[main image::' .. image .. '| ]][[' .. image .. '|class=wikichip_ogimage|' .. image_size .. ']]')
-- add a caption, if provided
if has_arg('caption' .. name) then
infobox
:tag('tr')
:tag('td')
:attr('style', 'text-align: center;')
:attr('colspan', '2')
:wikitext('[[main image caption::' .. arg('caption' .. name) .. ']]')
end
elseif not has_arg('no image' .. name) then
if i == 1 then
infobox
:tag('tr')
:tag('td')
:attr('style', 'text-align: center;')
:attr('colspan', '2')
:wikitext('[[File:no photo (ic).svg|link=|200px]]')
end
end
end
-- ####################################################################
-- some general info first
p.add_separator(infobox, 'General Info')
-- designer
if has_arg('developer') then
local designers = mw.html.create('td'):attr('style', 'width: 99%;')
designers:wikitext('[[designer::' .. arg('developer') .. '| ]][[' .. arg('developer') .. ']]')
for i = 2, 10 do
if not has_arg('developer ' .. i) then break end
designers:wikitext(', [[designer::' .. arg('developer ' .. i) .. '| ]][[' .. arg('developer ' .. i) .. ']]')
end
infobox:node(p.add_entry('Designer', designers))
end
-- manufacturer
if has_arg('manufacturer') then
local manufacturers = '[[manufacturer::' .. arg('manufacturer') .. '| ]][[' .. arg('manufacturer') .. ']]'
for i = 2, 10 do
if not has_arg('manufacturer ' .. i) then break end
manufacturers = manufacturers .. ', [[manufacturer::' .. arg('manufacturer ' .. i) .. '| ]][[' .. arg('manufacturer ' .. i) .. ']]'
end
infobox:node(p.add_entry('Manufacturer', mw.html.create('td'):wikitext(manufacturers)))
end
-- release date
if has_arg('first launched') or has_arg('first announced') then
local release = mw.html.create('td')
if has_arg('first announced') then
release:wikitext('[[first announced::' .. arg('first announced') .. ']] (announced)')
end
if has_arg('first launched') then
if has_arg('first announced') then
release:wikitext('<br>')
end
release:wikitext('[[first launched::' .. arg('first launched') .. ']] (launched)')
end
infobox:node(p.add_entry('Introduction', release))
end
if has_arg('fate') then
infobox:node(p.add_entry('Fate', mw.html.create('td'):wikitext('[[fate::' .. arg('fate') .. ']]')))
end
-- ####################################################################
-- some general info first
p.add_separator(infobox, 'Microarchitecture')
-- ISA
if has_arg('isa') or has_arg('isa family') then
local isa = mw.html.create('td'):wikitext('[[isa::' .. arg('isa') .. ']]')
for i = 2, 10 do
if not has_arg('isa ' .. i) then break end
isa:wikitext(', [[isa::' .. arg('isa ' .. i) .. ']]')
end
if has_arg('isa family') then
isa:wikitext(' ([[isa family::' .. arg('isa family') .. ']])')
end
infobox:node(p.add_entry('ISA', isa))
end
-- microarch
if has_arg('microarch') then
local microarchs = mw.html.create('td')
microarchs:wikitext('[[microarchitecture::' .. arg('microarch') .. '| ]]')
microarchs:wikitext('[[' .. mw.ustring.lower(arg('developer')) .. '/microarchitectures/' ..
mw.ustring.lower(arg('microarch')) .. '|' .. arg('microarch') .. ']]')
for i = 2, 10 do
if not has_arg('microarch ' .. i) then break end
microarchs:wikitext(', [[microarchitecture::' .. arg('microarch ' .. i) .. '| ]]')
microarchs:wikitext('[[' .. mw.ustring.lower(arg('developer')) .. '/microarchitectures/' ..
mw.ustring.lower(arg('microarch ' .. i)) .. '|' .. arg('microarch ' .. i) .. ']]')
end
infobox:node(p.add_entry('Microarchitecture', microarchs))
end
-- platform
if has_arg('platform') then
infobox:node(p.add_entry('Platform', mw.html.create('td'):wikitext('[[platform::' .. arg('platform') .. ']]')))
end
-- chipset
if has_arg('chipset') then
local chipset = mw.html.create('td'):wikitext('[[chipset::' .. arg('chipset') .. ']]')
for i = 2, 10 do
if not has_arg('chipset ' .. i) then break end
chipset:wikitext(', [[chipset::' .. arg('chipset ' .. i) .. ']]')
end
infobox:node(p.add_entry('Chipset', chipset))
end
-- word size
if has_arg('word') then
infobox:node(p.add_entry('Word Size', mw.html.create('td'):wikitext('[[word size::' .. arg('word') .. '| ]]' .. arg('word'))))
end
-- process
if has_arg('proc') then
local process = mw.html.create('td'):wikitext('[[process::' .. arg('proc') .. ']]')
for i = 2, 10 do
if not has_arg('proc ' .. i) then break end
process:wikitext(', [[process::' .. arg('proc ' .. i) .. ']]')
end
infobox:node(p.add_entry('Process', process))
end
-- Technology
if has_arg('tech') then
infobox:node(p.add_entry('Technology', mw.html.create('td'):wikitext('[[technology::' .. arg('tech') .. ']]')))
end
-- Clock
if has_arg('clock') then
infobox:node(p.add_entry('Clock', mw.html.create('td'):wikitext(arg('clock'))))
elseif has_arg('clock min') then
infobox:node(p.add_entry('Clock', mw.html.create('td'):wikitext(arg('clock min') .. ' - ' .. arg('clock max'))))
end
-- ####################################################################
-- ####################################################################
-- Packaging
local has_arg_pkg_name = has_arg('package name') or has_arg('package name 1')
if has_arg('package module 1') or has_arg_pkg_name or has_arg('back image') then
p.add_separator(infobox, 'Packaging')
end
-- Packaging
if has_arg_pkg_name then
local pdata = require('Module:packaging data')
-- Also accept name, name 2, name 3 for consistency.
local add_space = append_packaging_data(infobox, 'package name', pdata, false)
for i = 1, 10 do
add_space = append_packaging_data(infobox, 'package name ' .. i, pdata, add_space)
end
end
if has_arg('package module 1') then
for i = 1, 10 do
if has_arg('package module ' .. i) then
infobox
:tag('tr'):tag('td'):attr('colspan', '2'):attr('style', 'padding: 5px;')
:wikitext(frame:preprocess(arg('package module ' .. i)))
end
end
end
-- back_image
if has_arg('back image') then
local back_image = p.add_file_prefix(arg('back image'))
local back_image_size = has_arg('back image size') and arg('back image size') or "200px"
infobox
:tag('tr')
:tag('td')
:attr('style', 'text-align: center;')
:attr('colspan', '2')
-- make sure it's the ogimage
:wikitext('[[' .. back_image .. '|link=|' .. back_image_size .. ']]')
p.set_val('back image', back_image)
end
-- ####################################################################
-- ####################################################################
-- Successon
if has_arg('successor') or has_arg('predecessor') then
add_header(infobox, 'Succession')
local s = infobox:tag('tr')
local td = s:tag('td'):attr('colspan', '2')
local d1 = td:tag('div'):attr('style', 'display: inline-flex;')
local d2 = td:tag('div'):attr('style', 'display: inline-flex; float: right;')
if has_arg('predecessor') then
local list
if has_arg('predecessor link') then
list = '[[' .. arg('predecessor link') .. '|' .. arg('predecessor') .. ']]'
else
list = '[[' .. arg('predecessor') .. ']]'
end
for i = 2, 10 do
if not has_arg('predecessor ' .. i) then break end
if has_arg('predecessor ' .. i .. ' link') then
list = list .. '<br>[[' .. arg('predecessor ' .. i .. ' link') .. '|' .. arg('predecessor ' .. i) .. ']]'
else
list = list .. '<br>[[' .. arg('predecessor ' .. i) .. ']]'
end
end
d1:tag('div')
:attr('style', 'float: left; padding-right: 10px; margin: auto 5px;')
:wikitext('<i class="fa fa-chevron-left"></i>')
d1:tag('div')
:attr('style', 'float: left;')
:wikitext(list)
end
if has_arg('successor') then
local list
if has_arg('successor link') then
list = '[[' .. arg('successor link') .. '|' .. arg('successor') .. ']]'
else
list = '[[' .. arg('successor') .. ']]'
end
for i = 2, 10 do
if not has_arg('successor ' .. i) then break end
if has_arg('successor ' .. i .. ' link') then
list = list .. '<br>[[' .. arg('successor ' .. i .. ' link') .. '|' ..
arg('successor ' .. i) .. ']]'
else
list = list .. '<br>[[' .. arg('successor ' .. i) .. ']]'
end
end
d2:tag('div')
:attr('style', 'float: left;')
:wikitext(list)
d2:tag('div')
:attr('style', 'float: right; padding-left: 10px; margin: auto 5px;')
:wikitext('<i class="fa fa-chevron-right"></i>')
end
end
-- Contemporary
if has_arg('contemporary') then
add_header(infobox, 'Contemporary')
local s = infobox:tag('tr')
local td = s:tag('td'):attr('colspan', '2')
td:attr('style', 'text-align: center;')
local list
if has_arg('contemporary link') then
list = '[[' .. arg('contemporary link') .. '|' .. arg('contemporary') .. ']]'
else
list = '[[' .. arg('contemporary') .. ']]'
end
for i = 2, 10 do
if not has_arg('contemporary ' .. i) then break end
if has_arg('contemporary ' .. i .. ' link') then
list = list .. '<br>[[' .. arg('contemporary ' .. i .. ' link') .. '|' .. arg('contemporary ' .. i) .. ']]'
else
list = list .. '<br>[[' .. arg('contemporary ' .. i) .. ']]'
end
end
td:wikitext(list)
end
infobox:wikitext('[[instance of::core| ]]')
infobox:wikitext('[[Category:all microprocessor cores]]')
return infobox
end
return p