Модуль:Arkitexure
Перейти к навигации
Перейти к поиску
Документация
Пример
Ошибка скрипта: Модуля «Arkitexure/test» не существует.
local Utility = require( 'Модуль:Utility' )
local ItemList = require( 'Модуль:ItemList' ).create
-- #region Class abstraction
local function Class( constructor, parent )
local methods
if parent ~= nil then
methods = Utility.deepcopy( parent.methods )
else
methods = {}
end
if constructor == nil and parent ~= nil then
constructor = parent.constructor
end
local class = {
constructor = constructor,
parent = parent,
methods = methods,
new = function ( self, ... )
local inst = { mt = {
class = self,
__index = self.methods,
__tostring = self.methods.toString
} }
setmetatable( inst, inst.mt )
if self.constructor ~= nil then
self.constructor( inst, unpack( {...} ) )
end
return inst
end
}
setmetatable( class, { __call = class.new } )
return class
end
-- #endregion
-- Helper function to prepend or append an element
local function pushItem(t, i, first)
if first == false then
table.insert(t, 1, i)
else
table.insert(t, i)
end
return i
end
-- Helper function to convert objects in array to strings and concatenate them
local function concatStringLikeTable(t)
local tmp = {}
for _, v in ipairs(t) do
tmp[#tmp+1] = tostring(v)
end
return table.concat(tmp)
end
-- #region Component
local Component = Class( function ( self, parent )
self.parent = parent
end )
function Component.methods.addCategory( self, name, sortName )
self.parent:addCategory( name, sortName )
return self
end
function Component.methods.fillCargoField( self, name, value )
self.parent:fillCargoField( name, value )
return self
end
Component.methods.cargo = Component.methods.fillCargoField
function Component.methods.done( self )
return self.parent
end
-- #endregion
-- #region CargoFieldInfo
local CargoFieldInfo = Class( function ( self, name )
self[1] = name
end )
function CargoFieldInfo.methods.adapt( self, value )
return tostring( value )
end
CargoFieldInfo.String = CargoFieldInfo
CargoFieldInfo.Bool = CargoFieldInfo
CargoFieldInfo.Number = CargoFieldInfo
CargoFieldInfo.List = CargoFieldInfo
-- #endregion
-- #region ServiceWiring
local ServiceWiring = Class( function ( self )
self.categories = {}
self.enableCargo = false
self.enableCategories = mw.ext.VariablesLua.var('NoAutoCategories') ~= '1'
self.cargoData = {}
self.defaultCargoTable = nil
end )
function ServiceWiring.methods.addCategory( self, name, sortName )
table.insert(self.categories, string.format('[[Категория:%s|%s]]', name, sortName or name))
return self
end
function ServiceWiring.methods.setCargoEnabled( self, value )
self.enableCargo = value
return self
end
function ServiceWiring.methods.attachCargoTable( self, tableName )
self.cargoData[tableName] = {}
return self
end
function ServiceWiring.methods.attachCargoTableDefault( self, tableName )
self:attachCargoTable( tableName )
self.defaultCargoTable = tableName
return self
end
function ServiceWiring.methods.fillCargoField( self, tableNameOrName, nameOrValue, valueOrNil )
local tableName = tableNameOrName
local field = nameOrValue
local value = valueOrNil
if valueOrNil == nil then
value = key
field = tableName
tableName = self.defaultCargoTable
end
value = field:adapt( value )
if value == nil then
value = ''
end
self.cargoData[tableName][field[1]] = value
return self
end
function ServiceWiring.methods.commitCargo( self )
local sum = {}
-- TODO: rewrite to active execution
for tableName, values in pairs( self.cargoData ) do
if #values > 0 then
table.insert( sum, '{{#cargo_store:\n_table = ' .. tableName )
for key, value in pairs( values ) do
if value == nil then
value = ''
elseif type( value ) == 'table' then
value = table.concat( value, ';;' )
end
table.insert( sum, '|' .. key .. '=' .. tostring( value ) )
end
table.insert( sum, '}}' )
end
end
return table.concat( sum )
end
function ServiceWiring.methods.toString( self )
return self.enableCategories and table.concat( self.categories ) or ''
end
-- #endregion
-- Forward declarations
local Infobox
local Module
local Unit
local UnitRow
local KVUnitRow
local ItemTypeUnitRow
local Cell
-- #region Infobox
Infobox = Class( function ( self, config )
ServiceWiring.constructor( self )
self.config = config or {}
self.modules = {}
assert( self.config.title ~= nil, 'infobox header property "title" must not be null' )
self.getHeader()
end, ServiceWiring )
function Infobox.methods.module( self, last )
return self:insertModule( Module( self ), last )
end
function Infobox.methods.insertModule( self, instance, last )
return pushItem( self.modules, instance, last )
end
function Infobox.methods.getHeader( self, last )
if self._modHeader then
return self._modHeader
end
self._modHeader = self:module( false )
-- Display a title box with a creature head
if self.config.withDinoHead then
self._modHeader
:unit()
:row()
:cell { Cell.X2W25, Cell.Left }
:text( string.format('[[Файл:%s.png|43px|alt=]]', self.config.title) )
:done()
:cell { Cell.X2W75, Cell.Right }
:text( self.config.title )
:done()
:done()
:done()
else
self._modHeader
:unit()
:row()
:cell { Cell.Single, Cell.Masthead }
:text( self.config.title )
:done()
:done()
:done()
end
return self._modHeader
end
function Infobox.methods.toString( self )
return string.format( '<div class="info-arkitex info-framework">%s</div>%s%s',
concatStringLikeTable( self.modules ), ServiceWiring.methods.toString( self ) )
end
function Infobox.methods.done( self )
return self:toString()
end
-- #endregion
-- #region Module
Module = Class( function ( self, parent )
self.parent = parent
self.units = {}
end, Component )
function Module.methods.appendUnit( self, unit )
table.insert( self.units, unit )
return unit
end
function Module.methods.unit( self, caption )
return self:appendUnit( Unit( self, caption ) )
end
function Module.methods.newUnit(self, cls, ...)
return self:appendUnit(cls(self, unpack( {...} )))
end
-- Module to HTML converter
function Module.methods.toString( self )
return string.format( '<div class="info-arkitex info-module">%s</div>', concatStringLikeTable( self.units ) )
end
-- #endregion
-- #region Unit
Unit = Class( function ( self, parent, caption )
self.parent = parent
self.caption = caption
self.rows = {}
end, Component )
function Unit.methods.row( self )
return self:appendRow( UnitRow( self ) )
end
-- Name + Value unit row constructor
function Unit.methods.rowKV( self, name, value )
return self:appendRow( KVUnitRow( self, name, value ) )
end
-- Item type row constructor
function Unit.methods.rowItemType( self, itemType, itemCategory )
return self:appendRow( ItemTypeUnitRow( self, itemType, itemCategory ) )
end
function Unit.methods.appendRow(self, instance)
table.insert( self.rows, instance )
return instance
end
-- Module to HTML converter
function Unit.methods.toString(self)
local captionHtml = ''
if self.caption then
captionHtml = string.format( '<div class="info-unit-caption">\'\'\'%s\'\'\'</div>', self.caption )
end
return string.format( '<div class="info-arkitex info-unit">%s%s</div>', captionHtml, concatStringLikeTable( self.rows ) )
end
-- #endregion
-- #region Unit row
UnitRow = Class( function ( self, parent )
self.parent = parent
self.cells = {}
end, Component )
function UnitRow.methods.cell(self, args)
return self:insertCell( Cell( self, args ) )
end
function UnitRow.methods.insertCell(self, instance)
table.insert( self.cells, instance )
return instance
end
function UnitRow.methods.newCell(self, cls, ...)
return self:insertCell(cls(self, unpack( {...} )))
end
function UnitRow.methods.toString(self)
return string.format( '<div class="info-arkitex info-unit-row">%s</div>', concatStringLikeTable( self.cells ) )
end
-- #endregion
-- #region Key-value unit row
KVUnitRow = Class( function ( self, parent, name, value )
self.parent = parent
self.mName = nil
self.mValue = nil
self:name(name):value(value)
end, UnitRow )
-- Name setter
function KVUnitRow.methods.name(self, name)
assert(name ~= nil, 'infobox named row name must not be null')
self.mName = name
return self
end
-- Value setter
function KVUnitRow.methods.value(self, value)
if value == '' then
value = nil
end
self.mValue = value
return self
end
function KVUnitRow.methods.fillCargoField( self, name, value )
return Component.methods.fillCargoField( self, name, value or self.mValue )
end
KVUnitRow.methods.cargo = KVUnitRow.methods.fillCargoField
-- Unit row to HTML converter
function KVUnitRow.methods.toString(self)
if self.mValue == nil then
return ''
end
return string.format( '<div class="info-arkitex info-unit-row">%s%s</div>',
tostring( Cell( self, { Cell.Left, Cell.X2W40 } ):text( self.mName ) ),
tostring( Cell( self, { Cell.Right, Cell.X2W60 } ):text( self.mValue ) ) )
end
-- #endregion
-- #region Boolean key-value unit row
BoolKVUnitRow = Class( nil, KVUnitRow )
function BoolKVUnitRow.methods.fillCargoField( self, name, value )
return Component.methods.fillCargoField( self, name, value or self.mValue )
end
BoolKVUnitRow.methods.cargo = BoolKVUnitRow.methods.fillCargoField
-- Unit row to HTML converter
function BoolKVUnitRow.methods.toString(self)
if self.mValue == nil then
return ''
end
local checkmarkValue = 'Unknown'
if self.mValue == true then
checkmarkValue = 'Yes'
elseif self.mValue == false then
checkmarkValue = 'No'
end
return string.format(
'<div class="info-arkitex info-unit-row">%s%s</div>',
tostring( Cell( self, { Cell.Left, Cell.X2W40 } ):text( self.mName ) ),
tostring( Cell( self, { Cell.Right, Cell.X2W60 } ):text(
mw.getCurrentFrame():expandTemplate { title = 'Checkmark', args = { checkmarkValue } }
) )
)
end
-- #endregion
-- #region Common item type unit row
ItemTypeUnitRow = Class( function ( self, parent, itemType, itemCategory )
self.parent = parent
self.mName = 'Type'
self.mValue = string.format( '[[:Категория:%s|%s]]', itemCategory, itemType )
self:addCategory( itemCategory )
end, KVUnitRow )
-- #endregion
-- #region Cell
Cell = Class( function ( self, parent, args )
self.parent = parent
self.mText = args.text
self.classes = args
end, Component )
-- Area division
Cell.X1W100 = 'info-X1-100'
Cell.X2W25 = 'info-X2-25'
Cell.X2W40 = 'info-X2-40'
Cell.X2W50 = 'info-X2-50'
Cell.X2W60 = 'info-X2-60'
Cell.X2W75 = 'info-X2-75'
Cell.X3W33 = 'info-X3-33'
-- Directional
Cell.Left = 'info-arkitex-left'
Cell.Right = 'info-arkitex-right'
-- Special
Cell.Masthead = 'info-masthead'
Cell.Column = 'info-column'
Cell.ForceBackground = 'info-with-background'
-- Text constructor
function Cell.methods.text(self, text)
self.mText = text
return self
end
-- Cell to HTML converter
function Cell.methods.toString(self)
local text = self.mText
if type( text ) == 'function' then
text = text()
end
if text == nil or text == '' then
return ''
end
if type( text ) == 'table' then
text = ItemList( text )
elseif type( text ) == 'number' then
text = mw.getContentLanguage():formatNum( text )
end
return string.format( '<div class="info-arkitex %s">%s</div>', table.concat( self.classes, ' ' ), text )
end
-- #endregion
-- Export constructors
return {
Class = Class,
Component = Component,
CargoFieldInfo = CargoFieldInfo,
ServiceWiring = ServiceWiring,
Infobox = Infobox,
Module = Module,
Unit = Unit,
UnitRow = UnitRow,
KVUnitRow = KVUnitRow,
BoolKVUnitRow = BoolKVUnitRow,
ItemTypeUnitRow = ItemTypeUnitRow,
Cell = Cell,
}