Module:Collapsible list

From Viki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Collapsible list/doc

  1 -- This module implements {{collapsible list}}.
  2 
  3 local p = {}
  4 
  5 local function gettitlestyletracking( ts )
  6 	if not ts then return '' end
  7 	ts = mw.ustring.gsub(mw.ustring.lower(ts), '%s', '')
  8 	local tsvals = mw.text.split(ts, ';')
  9 	table.sort(tsvals)
 10 	local skey = table.concat(tsvals,';')
 11 	skey = mw.ustring.gsub(skey, '^;', '')
 12 	skey = mw.text.encode(mw.text.encode(skey),'%c%[%]=')
 13 	if (mw.ustring.match(';' .. ts, ';background:') or mw.ustring.match(';' .. ts, ';background%-color:')) 
 14 		and mw.ustring.match(';' .. ts, ';text%-align:') then 
 15 		return '[[Category:Pages using collapsible list with both background and text-align in titlestyle|' .. skey .. ' ]]'
 16 	end
 17 	return '[[Category:Pages using collapsible list without both background and text-align in titlestyle|' .. skey .. ' ]]'
 18 end
 19 
 20 local function getListItem( data )
 21     if not type( data ) == 'string' then
 22         return ''
 23     end
 24     return mw.ustring.format( '<li style="line-height: inherit; margin: 0">%s</li>', data )
 25 end
 26 
 27 -- Returns an array containing the keys of all positional arguments
 28 -- that contain data (i.e. non-whitespace values).
 29 local function getArgNums( args )
 30     local nums = {}
 31     for k, v in pairs( args ) do
 32         if type( k ) == 'number' and
 33             k >= 1 and
 34             math.floor( k ) == k and
 35             type( v ) == 'string' and
 36             mw.ustring.match( v, '%S' ) then
 37                 table.insert( nums, k )
 38         end
 39     end
 40     table.sort( nums )
 41     return nums
 42 end
 43 
 44 -- Formats a list of classes, styles or other attributes.
 45 local function formatAttributes( attrType, ... )
 46     local attributes = { ... }
 47     local nums = getArgNums( attributes )
 48     local t = {}
 49     for i, num in ipairs( nums ) do
 50         table.insert( t, attributes[ num ] )
 51     end
 52     if #t == 0 then
 53         return '' -- Return the blank string so concatenation will work.
 54     end
 55     return mw.ustring.format( ' %s="%s"', attrType, table.concat( t, ' ' ) )
 56 end
 57 
 58 local function buildList( args )
 59     -- Get the list items.
 60     local listItems = {}
 61     local argNums = getArgNums( args )
 62     for i, num in ipairs( argNums ) do
 63         table.insert( listItems, getListItem( args[ num ] ) )
 64     end
 65     if #listItems == 0 then
 66         return ''
 67     end
 68     listItems = table.concat( listItems )
 69 
 70 	-- hack around mw-collapsible show/hide jumpiness by looking for text-alignment
 71 	-- by setting a margin if centered
 72 	local textAlignmentCentered = 'text%-align%s*:%s*center'
 73 	local centeredTitle = (args.title_style and args.title_style:lower():match(textAlignmentCentered)
 74 		or args.titlestyle and args.titlestyle:lower():match(textAlignmentCentered))
 75 	local centeredTitleSpacing
 76 	if centeredTitle then
 77 		centeredTitleSpacing = 'margin: 0 4em'
 78 	else
 79 		centeredTitleSpacing = ''
 80 	end
 81 
 82     -- Get class, style and title data.
 83     local collapsibleContainerClass = formatAttributes(
 84     	'class',
 85     	'mw-collapsible', not args.expand and 'mw-collapsed'
 86     )
 87     local collapsibleContainerStyle = formatAttributes(
 88         'style',
 89         'text-align: center; font-size: 95%;',
 90         args.frame_style,
 91         args.framestyle
 92     )
 93     local collapsibleTitleStyle = formatAttributes(
 94         'style',
 95         'line-height: 1.6em; font-weight: bold; font-size: 100%; text-align: left;',
 96         args.title_style,
 97         args.titlestyle
 98     )
 99     local jumpyTitleStyle = formatAttributes(
100         'style',
101         centeredTitleSpacing
102     )
103     local title = args.title or 'List'
104     local ulclass = formatAttributes( 'class', 'mw-collapsible-content', args.hlist and 'hlist' )
105     local ulstyle = formatAttributes( 
106         'style',
107         'font-size: 105%; margin-top: 0; margin-bottom: 0; line-height: inherit; text-align: left;',
108         not args.bullets and 'list-style: none none; margin-left: 0;',
109         args.list_style,
110         args.liststyle
111     )
112     
113     -- Build the list.
114     return mw.ustring.format( 
115         '<div%s%s>\n<div%s><div%s>%s</div></div>\n<ul%s%s>%s</ul>\n</div>',
116         collapsibleContainerClass, collapsibleContainerStyle,
117         collapsibleTitleStyle, jumpyTitleStyle, title, ulclass, ulstyle, listItems
118     ) .. gettitlestyletracking(args.title_style or args.titlestyle)
119 end
120 
121 function p.main( frame )
122     local origArgs
123     if frame == mw.getCurrentFrame() then
124         origArgs = frame:getParent().args
125         for k, v in pairs( frame.args ) do
126             origArgs = frame.args
127             break
128         end
129     else
130         origArgs = frame
131     end
132     
133     local args = {}
134     for k, v in pairs( origArgs ) do
135         if type( k ) == 'number' or v ~= '' then
136             args[ k ] = v
137         end
138     end
139     return buildList( args )
140 end
141 
142 return p