모듈:생리컵 비교표

최근 편집: 2021년 8월 1일 (일) 17:45

이 모듈에 대한 설명문서는 모듈:생리컵 비교표/설명문서에서 만들 수 있습니다

local mArguments = require('Module:@en/Arguments')
local p = {}

local TYPE_LENGTH = 0;
local TYPE_VOLUME = 1;
local TYPE_WEIGHT = 2;

local PROPERTIES = {
  { ['pid'] = 'P26', ['type'] = TYPE_LENGTH, ['label'] = '몸체 길이<br/>(mm)' },
  { ['pid'] = 'P27', ['type'] = TYPE_LENGTH, ['label'] = '꼬리 길이<br/>(mm)' },
  { ['pid'] = 'P35', ['type'] = TYPE_LENGTH, ['label'] = '전체 길이<br/>(mm)' },
  { ['pid'] = 'P29', ['type'] = TYPE_VOLUME, ['label'] = '용량(mL)' },
  { ['pid'] = 'P24', ['type'] = TYPE_LENGTH, ['label'] = '직경(mm)' },
  { ['pid'] = 'P49', ['type'] = TYPE_WEIGHT, ['label'] = '무게(g)' }
}

---
-- @param item
-- @param preporty
-- @param preferedUnit unit과 convert를 원소로 갖는 '단위와 환산법'들의 배열.
--  각 선호 단위의 unit 원소는 단위 항목을 나타내는 문자열이고, convert는 해당
--  단위가 제공되었을 때 어떻게 변환할지이다. convert가 nil이면 그대로 사용한다.
local function _getQuantity(item, property, preferedUnit)
  local sts = item:getBestStatements(property)
  
  for i, v in ipairs(preferedUnit) do
    for i2, v2 in ipairs(sts) do
      if string.find(v2.mainsnak.datavalue.value.unit, v.unit) then
        rt = tonumber(v2.mainsnak.datavalue.value.amount)
        if v.convert ~= nil then
          rt = v.convert(rt)
        end
        return rt
      end
    end
  end
  return false
end

local function _getLengthQuantity(item, property)
  return _getQuantity(item, property, {
    {
      unit = 'Q31', -- 밀리미터
      convert = nil
    },
    {
      unit = 'Q32', -- 인치
      convert = function(v) return tonumber(v)*25.4 end
    }
  }, 'mm')
end

local function _getVolumeQuantity(item, property)
  return _getQuantity(item, property, {
    {
      unit = 'Q41', -- 밀리리터
      convert = nil
    }
  }, 'mL')
end

local function _getWeightQuantity(item, property)
  return _getQuantity(item, property, {
    {
      unit = 'Q103', -- 그램
      convert = nil
    }
  }, 'g')
end

function p.main(frame)
  local args = mArguments.getArgs(frame)
  local cellData = {}
  local validProperties = {}
  local validPropertyMap = {}
  
  for _, cupQid in ipairs(args) do
    cupData = { ['qid'] = cupQid }
    local item = mw.wikibase.getEntity( cupQid )
    cupData.label = item:getLabel()
    cupData.data = {}
    for _, data in ipairs(PROPERTIES) do
      local quantity = false
      local pid = data.pid
      if data.type == TYPE_VOLUME then
        quantity = _getVolumeQuantity( item, pid )
      elseif data.type == TYPE_LENGTH then
        quantity = _getLengthQuantity( item, pid )
      else
        quantity = _getWeightQuantity( item, pid )
      end
      if quantity ~= false then
        if validPropertyMap[pid] == nil then
          validPropertyMap[pid] = true
          validProperties[#validProperties+1] = pid
        end
        cupData[pid] = quantity
      end
    end
    cellData[#cellData+1] = cupData
  end
  
  local s = ''
  s = s .. string.format(
    '<table class="sortable wikitable %s">\n',
    args.class or ''
  )
  
  -- Render table header
  s = s .. '<tr>\n<th>제품</th>'
  for _, data in ipairs(PROPERTIES) do
    if ( validPropertyMap[data.pid] ) then
      s = s .. '<th>' .. data.label .. '</th>\n'
    end
  end
  s = s .. '</tr>\n'
  
  -- Render table rows
  for _, data in ipairs(cellData) do
    s = s .. '<tr>\n'
    s = s .. string.format(
      '<td>%s</td>',
      data.label
    )
    for _, pid in ipairs(validProperties) do
      s = s .. '<td>'
      if data[pid] then
        s = s .. data[pid] ..
          ' ' .. frame:expandTemplate{
            title = '위키베이스 편집 버튼',
            args = {
              qid = data.qid,
              pid = pid
            }
          }
        end
      s = s ..'</td>\n'
    end
    s = s .. '</tr>\n'
  end
  
  return s .. '</table>'
end

return p