본문으로 이동

모듈:Infobox

KANOTYPE WIKI

이 모듈에 대한 설명문서는 모듈:Infobox/설명문서에서 만들 수 있습니다

  1 local p = {}
  2 local args = {}
  3 local origArgs = {}
  4 local root
  5 local empty_row_categories = {}
  6 local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]'
  7 local has_rows = false
  8 local lists = {
  9 	plainlist_t = {
 10 		patterns = {
 11 			'^plainlist$',
 12 			'%splainlist$',
 13 			'^plainlist%s',
 14 			'%splainlist%s'
 15 		},
 16 		found = false,
 17 		styles = 'Plainlist/styles.css'
 18 	},
 19 	hlist_t = {
 20 		patterns = {
 21 			'^hlist$',
 22 			'%shlist$',
 23 			'^hlist%s',
 24 			'%shlist%s'
 25 		},
 26 		found = false,
 27 		styles = 'Hlist/styles.css'
 28 	}
 29 }
 30 
 31 local function has_list_class(args_to_check)
 32 	for _, list in pairs(lists) do
 33 		if not list.found then
 34 			for _, arg in pairs(args_to_check) do
 35 				for _, pattern in ipairs(list.patterns) do
 36 					if mw.ustring.find(arg or '', pattern) then
 37 						list.found = true
 38 						break
 39 					end
 40 				end
 41 				if list.found then break end
 42 			end
 43 		end
 44 	end
 45 end
 46 
 47 local function fixChildBoxes(sval, tt)
 48 	local function notempty( s ) return s and s:match( '%S' ) end
 49 	
 50 	if notempty(sval) then
 51 		local marker = '<span class=special_infobox_marker>'
 52 		local s = sval
 53 		-- start moving templatestyles and categories inside of table rows
 54 		local slast = ''
 55 		while slast ~= s do
 56 			slast = s
 57 			s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])', '%2%1')
 58 			s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)', '%2%1')
 59 		end
 60 		-- end moving templatestyles and categories inside of table rows
 61 		s = mw.ustring.gsub(s, '(<%s*[Tt][Rr])', marker .. '%1')
 62 		s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>)', '%1' .. marker)
 63 		if s:match(marker) then
 64 			s = mw.ustring.gsub(s, marker .. '%s*' .. marker, '')
 65 			s = mw.ustring.gsub(s, '([\r\n]|-[^\r\n]*[\r\n])%s*' .. marker, '%1')
 66 			s = mw.ustring.gsub(s, marker .. '%s*([\r\n]|-)', '%1')
 67 			s = mw.ustring.gsub(s, '(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)' .. marker, '%1')
 68 			s = mw.ustring.gsub(s, '(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)' .. marker, '%1')
 69 			s = mw.ustring.gsub(s, '^(%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
 70 			s = mw.ustring.gsub(s, '([\r\n]%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
 71 			s = mw.ustring.gsub(s, marker .. '(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)', '%1')
 72 			s = mw.ustring.gsub(s, marker .. '(%s*\n|%})', '%1')
 73 		end
 74 		if s:match(marker) then
 75 			local subcells = mw.text.split(s, marker)
 76 			s = ''
 77 			for k = 1, #subcells do
 78 				if k == 1 then
 79 					s = s .. subcells[k] .. '</' .. tt .. '></tr>'
 80 				elseif k == #subcells then
 81 					local rowstyle = ' style="display:none"'
 82 					if notempty(subcells[k]) then rowstyle = ''	end
 83 					s = s .. '<tr' .. rowstyle ..'><' .. tt .. ' colspan=2>\n' ..
 84 						subcells[k]
 85 				elseif notempty(subcells[k]) then
 86 					if (k % 2) == 0 then
 87 						s = s .. subcells[k]
 88 					else
 89 						s = s .. '<tr><' .. tt .. ' colspan=2>\n' ..
 90 							subcells[k] .. '</' .. tt .. '></tr>'
 91 					end
 92 				end
 93 			end
 94 		end
 95 		-- the next two lines add a newline at the end of lists for the PHP parser
 96 		-- [[Special:Diff/849054481]]
 97 		-- remove when [[:phab:T191516]] is fixed or OBE
 98 		s = mw.ustring.gsub(s, '([\r\n][%*#;:][^\r\n]*)$', '%1\n')
 99 		s = mw.ustring.gsub(s, '^([%*#;:][^\r\n]*)$', '%1\n')
100 		s = mw.ustring.gsub(s, '^([%*#;:])', '\n%1')
101 		s = mw.ustring.gsub(s, '^(%{%|)', '\n%1')
102 		return s
103 	else
104 		return sval
105 	end
106 end
107 
108 -- Cleans empty tables
109 local function cleanInfobox()
110 	root = tostring(root)
111 	if has_rows == false then
112 		root = mw.ustring.gsub(root, '<table[^<>]*>%s*</table>', '')
113 	end
114 end
115 
116 -- Returns the union of the values of two tables, as a sequence.
117 local function union(t1, t2)
118 
119 	local vals = {}
120 	for k, v in pairs(t1) do
121 		vals[v] = true
122 	end
123 	for k, v in pairs(t2) do
124 		vals[v] = true
125 	end
126 	local ret = {}
127 	for k, v in pairs(vals) do
128 		table.insert(ret, k)
129 	end
130 	return ret
131 end
132 
133 -- Returns a table containing the numbers of the arguments that exist
134 -- for the specified prefix. For example, if the prefix was 'data', and
135 -- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
136 local function getArgNums(prefix)
137 	local nums = {}
138 	for k, v in pairs(args) do
139 		local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
140 		if num then table.insert(nums, tonumber(num)) end
141 	end
142 	table.sort(nums)
143 	return nums
144 end
145 
146 -- Adds a row to the infobox, with either a header cell
147 -- or a label/data cell combination.
148 local function addRow(rowArgs)
149 	
150 	if rowArgs.header and rowArgs.header ~= '_BLANK_' then
151 		has_rows = true
152 		has_list_class({ rowArgs.rowclass, rowArgs.class, args.headerclass })
153 		
154 		root
155 			:tag('tr')
156 				:addClass(rowArgs.rowclass)
157 				:cssText(rowArgs.rowstyle)
158 				:tag('th')
159 					:attr('colspan', '2')
160 					:addClass('infobox-header')
161 					:addClass(rowArgs.class)
162 					:addClass(args.headerclass)
163 					-- @deprecated next; target .infobox-<name> .infobox-header
164 					:cssText(args.headerstyle)
165 					:cssText(rowArgs.rowcellstyle)
166 					:wikitext(fixChildBoxes(rowArgs.header, 'th'))
167 		if rowArgs.data then
168 			root:wikitext(
169 				'[[Category:Pages using infobox templates with ignored data cells]]'
170 			)
171 		end
172 	elseif rowArgs.data and rowArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then
173 		has_rows = true
174 		has_list_class({ rowArgs.rowclass, rowArgs.class })
175 		
176 		local row = root:tag('tr')
177 		row:addClass(rowArgs.rowclass)
178 		row:cssText(rowArgs.rowstyle)
179 		if rowArgs.label then
180 			row
181 				:tag('th')
182 					:attr('scope', 'row')
183 					:addClass('infobox-label')
184 					-- @deprecated next; target .infobox-<name> .infobox-label
185 					:cssText(args.labelstyle)
186 					:cssText(rowArgs.rowcellstyle)
187 					:wikitext(rowArgs.label)
188 					:done()
189 		end
190 
191 		local dataCell = row:tag('td')
192 		dataCell
193 			:attr('colspan', not rowArgs.label and '2' or nil)
194 			:addClass(not rowArgs.label and 'infobox-full-data' or 'infobox-data')
195 			:addClass(rowArgs.class)
196 			-- @deprecated next; target .infobox-<name> .infobox(-full)-data
197 			:cssText(rowArgs.datastyle)
198 			:cssText(rowArgs.rowcellstyle)
199 			:wikitext(fixChildBoxes(rowArgs.data, 'td'))
200 	else
201 		table.insert(empty_row_categories, rowArgs.data or '')
202 	end
203 end
204 
205 local function renderTitle()
206 	if not args.title then return end
207 
208 	has_rows = true
209 	has_list_class({args.titleclass})
210 	
211 	root
212 		:tag('caption')
213 			:addClass('infobox-title')
214 			:addClass(args.titleclass)
215 			-- @deprecated next; target .infobox-<name> .infobox-title
216 			:cssText(args.titlestyle)
217 			:wikitext(args.title)
218 	
219 end
220 
221 local function renderAboveRow()
222 	if not args.above then return end
223 
224 	has_rows = true
225 	has_list_class({ args.aboveclass })
226 	
227 	root
228 		:tag('tr')
229 			:tag('th')
230 				:attr('colspan', '2')
231 				:addClass('infobox-above')
232 				:addClass(args.aboveclass)
233 				-- @deprecated next; target .infobox-<name> .infobox-above
234 				:cssText(args.abovestyle)
235 				:wikitext(fixChildBoxes(args.above,'th'))
236 end
237 
238 local function renderBelowRow()
239 	if not args.below then return end
240 
241 	has_rows = true
242 	has_list_class({ args.belowclass })
243 	
244 	root
245 		:tag('tr')
246 			:tag('td')
247 				:attr('colspan', '2')
248 				:addClass('infobox-below')
249 				:addClass(args.belowclass)
250 				-- @deprecated next; target .infobox-<name> .infobox-below
251 				:cssText(args.belowstyle)
252 				:wikitext(fixChildBoxes(args.below,'td'))
253 end
254 
255 local function addSubheaderRow(subheaderArgs)
256 	if subheaderArgs.data and
257 		subheaderArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then
258 		has_rows = true
259 		has_list_class({ subheaderArgs.rowclass, subheaderArgs.class })
260 		
261 		local row = root:tag('tr')
262 		row:addClass(subheaderArgs.rowclass)
263 
264 		local dataCell = row:tag('td')
265 		dataCell
266 			:attr('colspan', '2')
267 			:addClass('infobox-subheader')
268 			:addClass(subheaderArgs.class)
269 			:cssText(subheaderArgs.datastyle)
270 			:cssText(subheaderArgs.rowcellstyle)
271 			:wikitext(fixChildBoxes(subheaderArgs.data, 'td'))
272 	else
273 		table.insert(empty_row_categories, subheaderArgs.data or '')
274 	end
275 end
276 
277 local function renderSubheaders()
278 	if args.subheader then
279 		args.subheader1 = args.subheader
280 	end
281 	if args.subheaderrowclass then
282 		args.subheaderrowclass1 = args.subheaderrowclass
283 	end
284 	local subheadernums = getArgNums('subheader')
285 	for k, num in ipairs(subheadernums) do
286 		addSubheaderRow({
287 			data = args['subheader' .. tostring(num)],
288 			-- @deprecated next; target .infobox-<name> .infobox-subheader
289 			datastyle = args.subheaderstyle,
290 			rowcellstyle = args['subheaderstyle' .. tostring(num)],
291 			class = args.subheaderclass,
292 			rowclass = args['subheaderrowclass' .. tostring(num)]
293 		})
294 	end
295 end
296 
297 local function addImageRow(imageArgs)
298 
299 	if imageArgs.data and
300 		imageArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then
301 
302 		has_rows = true
303 		has_list_class({ imageArgs.rowclass, imageArgs.class })
304 		
305 		local row = root:tag('tr')
306 		row:addClass(imageArgs.rowclass)
307 
308 		local dataCell = row:tag('td')
309 		dataCell
310 			:attr('colspan', '2')
311 			:addClass('infobox-image')
312 			:addClass(imageArgs.class)
313 			:cssText(imageArgs.datastyle)
314 			:wikitext(fixChildBoxes(imageArgs.data, 'td'))
315 	else
316 		table.insert(empty_row_categories, imageArgs.data or '')
317 	end
318 end
319 
320 local function renderImages()
321 	if args.image then
322 		args.image1 = args.image
323 	end
324 	if args.caption then
325 		args.caption1 = args.caption
326 	end
327 	local imagenums = getArgNums('image')
328 	for k, num in ipairs(imagenums) do
329 		local caption = args['caption' .. tostring(num)]
330 		local data = mw.html.create():wikitext(args['image' .. tostring(num)])
331 		if caption then
332 			data
333 				:tag('div')
334 					:addClass('infobox-caption')
335 					-- @deprecated next; target .infobox-<name> .infobox-caption
336 					:cssText(args.captionstyle)
337 					:wikitext(caption)
338 		end
339 		addImageRow({
340 			data = tostring(data),
341 			-- @deprecated next; target .infobox-<name> .infobox-image
342 			datastyle = args.imagestyle,
343 			class = args.imageclass,
344 			rowclass = args['imagerowclass' .. tostring(num)]
345 		})
346 	end
347 end
348 
349 -- When autoheaders are turned on, preprocesses the rows
350 local function preprocessRows()
351 	if not args.autoheaders then return end
352 	
353 	local rownums = union(getArgNums('header'), getArgNums('data'))
354 	table.sort(rownums)
355 	local lastheader
356 	for k, num in ipairs(rownums) do
357 		if args['header' .. tostring(num)] then
358 			if lastheader then
359 				args['header' .. tostring(lastheader)] = nil
360 			end
361 			lastheader = num
362 		elseif args['data' .. tostring(num)] and
363 			args['data' .. tostring(num)]:gsub(
364 				category_in_empty_row_pattern, ''
365 			):match('^%S') then
366 			local data = args['data' .. tostring(num)]
367 			if data:gsub(category_in_empty_row_pattern, ''):match('%S') then
368 				lastheader = nil
369 			end
370 		end
371 	end
372 	if lastheader then
373 		args['header' .. tostring(lastheader)] = nil
374 	end
375 end
376 
377 -- Gets the union of the header and data argument numbers,
378 -- and renders them all in order
379 local function renderRows()
380 
381 	local rownums = union(getArgNums('header'), getArgNums('data'))
382 	table.sort(rownums)
383 	for k, num in ipairs(rownums) do
384 		addRow({
385 			header = args['header' .. tostring(num)],
386 			label = args['label' .. tostring(num)],
387 			data = args['data' .. tostring(num)],
388 			datastyle = args.datastyle,
389 			class = args['class' .. tostring(num)],
390 			rowclass = args['rowclass' .. tostring(num)],
391 			-- @deprecated next; target .infobox-<name> rowclass
392 			rowstyle = args['rowstyle' .. tostring(num)],
393 			rowcellstyle = args['rowcellstyle' .. tostring(num)]
394 		})
395 	end
396 end
397 
398 local function renderNavBar()
399 	if not args.name then return end
400 
401 	has_rows = true
402 	root
403 		:tag('tr')
404 			:tag('td')
405 				:attr('colspan', '2')
406 				:addClass('infobox-navbar')
407 				:wikitext(require('Module:Navbar')._navbar{
408 					args.name,
409 					mini = 1,
410 				})
411 end
412 
413 local function renderItalicTitle()
414 	local italicTitle = args['italic title'] and mw.ustring.lower(args['italic title'])
415 	if italicTitle == '' or italicTitle == 'force' or italicTitle == 'yes' then
416 		root:wikitext(require('Module:Italic title')._main({}))
417 	end
418 end
419 
420 -- Categories in otherwise empty rows are collected in empty_row_categories.
421 -- This function adds them to the module output. It is not affected by
422 -- args.decat because this module should not prevent module-external categories
423 -- from rendering.
424 local function renderEmptyRowCategories()
425 	for _, s in ipairs(empty_row_categories) do
426 		root:wikitext(s)
427 	end
428 end
429 
430 -- Render tracking categories. args.decat == turns off tracking categories.
431 local function renderTrackingCategories()
432 	if args.decat == 'yes' then return end
433 	if args.child == 'yes' then
434 		if args.title then
435 			root:wikitext(
436 				'[[Category:Pages using embedded infobox templates with the title parameter]]'
437 			)
438 		end
439 	elseif #(getArgNums('data')) == 0 and mw.title.getCurrentTitle().namespace == 0 then
440 		root:wikitext('[[Category:Articles using infobox templates with no data rows]]')
441 	end
442 end
443 
444 --[=[
445 Loads the templatestyles for the infobox.
446 
447 TODO: FINISH loading base templatestyles here rather than in
448 MediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables.
449 See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :).
450 When we do this we should clean up the inline CSS below too.
451 Will have to do some bizarre conversion category like with sidebar.
452 
453 ]=]
454 local function loadTemplateStyles()
455 	local frame = mw.getCurrentFrame()
456 	
457 	local hlist_templatestyles = ''
458 	if lists.hlist_t.found then
459 		hlist_templatestyles = frame:extensionTag{
460 			name = 'templatestyles', args = { src = lists.hlist_t.styles }
461 		}
462 	end
463 	
464 	local plainlist_templatestyles = ''
465 	if lists.plainlist_t.found then
466 		plainlist_templatestyles = frame:extensionTag{
467 			name = 'templatestyles', args = { src = lists.plainlist_t.styles }
468 		}
469 	end
470 	
471 	-- See function description
472 	local base_templatestyles = frame:extensionTag{
473 		name = 'templatestyles', args = { src = 'Module:Infobox/styles.css' }
474 	}
475 
476 	local templatestyles = ''
477 	if args['templatestyles'] then
478 		templatestyles = frame:extensionTag{
479 			name = 'templatestyles', args = { src = args['templatestyles'] }
480 		}
481 	end
482 	
483 	local child_templatestyles = ''
484 	if args['child templatestyles'] then
485 		child_templatestyles = frame:extensionTag{
486 			name = 'templatestyles', args = { src = args['child templatestyles'] }
487 		}
488 	end
489 	
490 	local grandchild_templatestyles = ''
491 	if args['grandchild templatestyles'] then
492 		grandchild_templatestyles = frame:extensionTag{
493 			name = 'templatestyles', args = { src = args['grandchild templatestyles'] }
494 		}
495 	end
496 	
497 	return table.concat({
498 		-- hlist -> plainlist -> base is best-effort to preserve old Common.css ordering.
499 		-- this ordering is not a guarantee because the rows of interest invoking
500 		-- each class may not be on a specific page
501 		hlist_templatestyles,
502 		plainlist_templatestyles,
503 		base_templatestyles,
504 		templatestyles,
505 		child_templatestyles,
506 		grandchild_templatestyles
507 	})
508 end
509 
510 -- common functions between the child and non child cases
511 local function structure_infobox_common()
512 	renderSubheaders()
513 	renderImages()
514 	preprocessRows()
515 	renderRows()
516 	renderBelowRow()
517 	renderNavBar()
518 	renderItalicTitle()
519 	renderEmptyRowCategories()
520 	renderTrackingCategories()
521 	cleanInfobox()
522 end
523 
524 -- Specify the overall layout of the infobox, with special settings if the
525 -- infobox is used as a 'child' inside another infobox.
526 local function _infobox()
527 	if args.child ~= 'yes' then
528 		root = mw.html.create('table')
529 
530 		root
531 			:addClass(args.subbox == 'yes' and 'infobox-subbox' or 'infobox')
532 			:addClass(args.bodyclass)
533 			-- @deprecated next; target .infobox-<name>
534 			:cssText(args.bodystyle)
535 		
536 		has_list_class({ args.bodyclass })
537 
538 		renderTitle()
539 		renderAboveRow()
540 	else
541 		root = mw.html.create()
542 
543 		root
544 			:wikitext(args.title)
545 	end
546 	structure_infobox_common()
547 	
548 	return loadTemplateStyles() .. root
549 end
550 
551 -- If the argument exists and isn't blank, add it to the argument table.
552 -- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
553 local function preprocessSingleArg(argName)
554 	if origArgs[argName] and origArgs[argName] ~= '' then
555 		args[argName] = origArgs[argName]
556 	end
557 end
558 
559 -- Assign the parameters with the given prefixes to the args table, in order, in
560 -- batches of the step size specified. This is to prevent references etc. from
561 -- appearing in the wrong order. The prefixTable should be an array containing
562 -- tables, each of which has two possible fields, a "prefix" string and a
563 -- "depend" table. The function always parses parameters containing the "prefix"
564 -- string, but only parses parameters in the "depend" table if the prefix
565 -- parameter is present and non-blank.
566 local function preprocessArgs(prefixTable, step)
567 	if type(prefixTable) ~= 'table' then
568 		error("Non-table value detected for the prefix table", 2)
569 	end
570 	if type(step) ~= 'number' then
571 		error("Invalid step value detected", 2)
572 	end
573 
574 	-- Get arguments without a number suffix, and check for bad input.
575 	for i,v in ipairs(prefixTable) do
576 		if type(v) ~= 'table' or type(v.prefix) ~= "string" or
577 			(v.depend and type(v.depend) ~= 'table') then
578 			error('Invalid input detected to preprocessArgs prefix table', 2)
579 		end
580 		preprocessSingleArg(v.prefix)
581 		-- Only parse the depend parameter if the prefix parameter is present
582 		-- and not blank.
583 		if args[v.prefix] and v.depend then
584 			for j, dependValue in ipairs(v.depend) do
585 				if type(dependValue) ~= 'string' then
586 					error('Invalid "depend" parameter value detected in preprocessArgs')
587 				end
588 				preprocessSingleArg(dependValue)
589 			end
590 		end
591 	end
592 
593 	-- Get arguments with number suffixes.
594 	local a = 1 -- Counter variable.
595 	local moreArgumentsExist = true
596 	while moreArgumentsExist == true do
597 		moreArgumentsExist = false
598 		for i = a, a + step - 1 do
599 			for j,v in ipairs(prefixTable) do
600 				local prefixArgName = v.prefix .. tostring(i)
601 				if origArgs[prefixArgName] then
602 					-- Do another loop if any arguments are found, even blank ones.
603 					moreArgumentsExist = true
604 					preprocessSingleArg(prefixArgName)
605 				end
606 				-- Process the depend table if the prefix argument is present
607 				-- and not blank, or we are processing "prefix1" and "prefix" is
608 				-- present and not blank, and if the depend table is present.
609 				if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then
610 					for j,dependValue in ipairs(v.depend) do
611 						local dependArgName = dependValue .. tostring(i)
612 						preprocessSingleArg(dependArgName)
613 					end
614 				end
615 			end
616 		end
617 		a = a + step
618 	end
619 end
620 
621 -- Parse the data parameters in the same order that the old {{infobox}} did, so
622 -- that references etc. will display in the expected places. Parameters that
623 -- depend on another parameter are only processed if that parameter is present,
624 -- to avoid phantom references appearing in article reference lists.
625 local function parseDataParameters()
626 
627 	preprocessSingleArg('autoheaders')
628 	preprocessSingleArg('child')
629 	preprocessSingleArg('bodyclass')
630 	preprocessSingleArg('subbox')
631 	preprocessSingleArg('bodystyle')
632 	preprocessSingleArg('title')
633 	preprocessSingleArg('titleclass')
634 	preprocessSingleArg('titlestyle')
635 	preprocessSingleArg('above')
636 	preprocessSingleArg('aboveclass')
637 	preprocessSingleArg('abovestyle')
638 	preprocessArgs({
639 		{prefix = 'subheader', depend = {'subheaderstyle', 'subheaderrowclass'}}
640 	}, 10)
641 	preprocessSingleArg('subheaderstyle')
642 	preprocessSingleArg('subheaderclass')
643 	preprocessArgs({
644 		{prefix = 'image', depend = {'caption', 'imagerowclass'}}
645 	}, 10)
646 	preprocessSingleArg('captionstyle')
647 	preprocessSingleArg('imagestyle')
648 	preprocessSingleArg('imageclass')
649 	preprocessArgs({
650 		{prefix = 'header'},
651 		{prefix = 'data', depend = {'label'}},
652 		{prefix = 'rowclass'},
653 		{prefix = 'rowstyle'},
654 		{prefix = 'rowcellstyle'},
655 		{prefix = 'class'}
656 	}, 50)
657 	preprocessSingleArg('headerclass')
658 	preprocessSingleArg('headerstyle')
659 	preprocessSingleArg('labelstyle')
660 	preprocessSingleArg('datastyle')
661 	preprocessSingleArg('below')
662 	preprocessSingleArg('belowclass')
663 	preprocessSingleArg('belowstyle')
664 	preprocessSingleArg('name')
665 	-- different behaviour for italics if blank or absent
666 	args['italic title'] = origArgs['italic title']
667 	preprocessSingleArg('decat')
668 	preprocessSingleArg('templatestyles')
669 	preprocessSingleArg('child templatestyles')
670 	preprocessSingleArg('grandchild templatestyles')
671 end
672 
673 -- If called via #invoke, use the args passed into the invoking template.
674 -- Otherwise, for testing purposes, assume args are being passed directly in.
675 function p.infobox(frame)
676 	if frame == mw.getCurrentFrame() then
677 		origArgs = frame:getParent().args
678 	else
679 		origArgs = frame
680 	end
681 	
682 	parseDataParameters()
683 	
684 	return _infobox()
685 end
686 
687 -- For calling via #invoke within a template
688 function p.infoboxTemplate(frame)
689 	origArgs = {}
690 	for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end
691 	
692 	parseDataParameters()
693 	
694 	return _infobox()
695 end
696 return p