コンテンツにスキップ

モジュール:List

提供:KANOTYPE WIKI

このモジュールについての説明文ページを モジュール:List/doc に作成できます

  1 local libUtil = require('libraryUtil')
  2 local checkType = libUtil.checkType
  3 local mTableTools = require('Module:TableTools')
  4 
  5 local p = {}
  6 
  7 local listTypes = {
  8 	['bulleted'] = true,
  9 	['unbulleted'] = true,
 10 	['horizontal'] = true,
 11 	['ordered'] = true,
 12 	['horizontal_ordered'] = true
 13 }
 14 
 15 function p.makeListData(listType, args)
 16 	-- Constructs a data table to be passed to p.renderList.
 17 	local data = {}
 18 
 19 	-- Classes and TemplateStyles
 20 	data.classes = {}
 21 	data.templatestyles = ''
 22 	if listType == 'horizontal' or listType == 'horizontal_ordered' then
 23 		table.insert(data.classes, 'hlist')
 24 		data.templatestyles = mw.getCurrentFrame():extensionTag{
 25 			name = 'templatestyles', args = { src = 'Hlist/styles.css' }
 26 		}
 27 	elseif listType == 'unbulleted' then
 28 		table.insert(data.classes, 'plainlist')
 29 		data.templatestyles = mw.getCurrentFrame():extensionTag{
 30 			name = 'templatestyles', args = { src = 'Plainlist/styles.css' }
 31 		}
 32 	end
 33 	table.insert(data.classes, args.class)
 34 
 35 	-- Main div style
 36 	data.style = args.style
 37 
 38 	-- Indent for horizontal lists
 39 	if listType == 'horizontal' or listType == 'horizontal_ordered' then
 40 		local indent = tonumber(args.indent)
 41 		indent = indent and indent * 1.6 or 0
 42 		if indent > 0 then
 43 			data.marginLeft = indent .. 'em'
 44 		end
 45 	end
 46 	
 47 	-- List style types for ordered lists
 48 	-- This could be "1, 2, 3", "a, b, c", or a number of others. The list style
 49 	-- type is either set by the "type" attribute or the "list-style-type" CSS
 50 	-- property.
 51 	if listType == 'ordered' or listType == 'horizontal_ordered' then 
 52 		data.listStyleType = args.list_style_type or args['list-style-type']
 53 		data.type = args['type']
 54 
 55 		-- Detect invalid type attributes and attempt to convert them to
 56 		-- list-style-type CSS properties.
 57 		if data.type 
 58 			and not data.listStyleType
 59 			and not tostring(data.type):find('^%s*[1AaIi]%s*$')
 60 		then
 61 			data.listStyleType = data.type
 62 			data.type = nil
 63 		end
 64 	end
 65 	
 66 	-- List tag type
 67 	if listType == 'ordered' or listType == 'horizontal_ordered' then
 68 		data.listTag = 'ol'
 69 	else
 70 		data.listTag = 'ul'
 71 	end
 72 
 73 	-- Start number for ordered lists
 74 	data.start = args.start
 75 	if listType == 'horizontal_ordered' then
 76 		-- Apply fix to get start numbers working with horizontal ordered lists.
 77 		local startNum = tonumber(data.start)
 78 		if startNum then
 79 			data.counterReset = 'listitem ' .. tostring(startNum - 1)
 80 		end
 81 	end
 82 
 83 	-- List style
 84 	 -- ul_style and ol_style are included for backwards compatibility. No
 85 	 -- distinction is made for ordered or unordered lists.
 86 	data.listStyle = args.list_style
 87 
 88 	-- List items
 89 	-- li_style is included for backwards compatibility. item_style was included
 90 	-- to be easier to understand for non-coders.
 91 	data.itemStyle = args.item_style or args.li_style
 92 	data.items = {}
 93 	for _, num in ipairs(mTableTools.numKeys(args)) do
 94 		local item = {}
 95 		item.content = args[num]
 96 		item.style = args['item' .. tostring(num) .. '_style']
 97 			or args['item_style' .. tostring(num)]
 98 		item.value = args['item' .. tostring(num) .. '_value']
 99 			or args['item_value' .. tostring(num)]
100 		table.insert(data.items, item)
101 	end
102 	
103 	return data
104 end
105 
106 function p.renderList(data)
107 	-- Renders the list HTML.
108 	
109 	-- Return the blank string if there are no list items.
110 	if type(data.items) ~= 'table' or #data.items < 1 then
111 		return ''
112 	end
113 	
114 	-- Render the main div tag.
115 	local root = mw.html.create('div')
116 	for _, class in ipairs(data.classes or {}) do
117 		root:addClass(class)
118 	end
119 	root:css{['margin-left'] = data.marginLeft}
120 	if data.style then
121 		root:cssText(data.style)
122 	end
123 
124 	-- Render the list tag.
125 	local list = root:tag(data.listTag or 'ul')
126 	list
127 		:attr{start = data.start, type = data.type}
128 		:css{
129 			['counter-reset'] = data.counterReset,
130 			['list-style-type'] = data.listStyleType
131 		}
132 	if data.listStyle then
133 		list:cssText(data.listStyle)
134 	end
135 
136 	-- Render the list items
137 	for _, t in ipairs(data.items or {}) do
138 		local item = list:tag('li')
139 		if data.itemStyle then
140 			item:cssText(data.itemStyle)
141 		end
142 		if t.style then
143 			item:cssText(t.style)
144 		end
145 		item
146 			:attr{value = t.value}
147 			:wikitext(t.content)
148 	end
149 
150 	return data.templatestyles .. tostring(root)
151 end
152 
153 function p.renderTrackingCategories(args)
154 	local isDeprecated = false -- Tracks deprecated parameters.
155 	for k, v in pairs(args) do
156 		k = tostring(k)
157 		if k:find('^item_style%d+$') or k:find('^item_value%d+$') then
158 			isDeprecated = true
159 			break
160 		end
161 	end
162 	local ret = ''
163 	if isDeprecated then
164 		ret = ret .. '[[Category:List templates with deprecated parameters]]'
165 	end
166 	return ret
167 end
168 
169 function p.makeList(listType, args)
170 	if not listType or not listTypes[listType] then
171 		error(string.format(
172 			"bad argument #1 to 'makeList' ('%s' is not a valid list type)",
173 			tostring(listType)
174 		), 2)
175 	end
176 	checkType('makeList', 2, args, 'table')
177 	local data = p.makeListData(listType, args)
178 	local list = p.renderList(data)
179 	local trackingCategories = p.renderTrackingCategories(args)
180 	return list .. trackingCategories
181 end
182 
183 for listType in pairs(listTypes) do
184 	p[listType] = function (frame)
185 		local mArguments = require('Module:Arguments')
186 		local origArgs = mArguments.getArgs(frame, {
187 			frameOnly = ((frame and frame.args and frame.args.frameonly or '') ~= ''),
188 			valueFunc = function (key, value)
189 			if not value or not mw.ustring.find(value, '%S') then return nil end
190 			if mw.ustring.find(value, '^%s*[%*#;:]') then
191 				return value
192 			else
193 				return value:match('^%s*(.-)%s*$')
194 			end
195 			return nil
196 		end
197 		})
198 		-- Copy all the arguments to a new table, for faster indexing.
199 		local args = {}
200 		for k, v in pairs(origArgs) do
201 			args[k] = v
202 		end
203 		return p.makeList(listType, args)
204 	end
205 end
206 
207 return p