https://en.wikipedia.org/w/index.php?action=history&feed=atom&title=Module%3AWeather%2FstableSandbox Module:Weather/stableSandbox - Revision history 2025-06-07T02:43:34Z Revision history for this page on the wiki MediaWiki 1.45.0-wmf.4 https://en.wikipedia.org/w/index.php?title=Module:Weather/stableSandbox&diff=742821650&oldid=prev Erutuon: creating a copy of Module:Weather/sandbox that can be used in articles until my work on the actual sandbox is complete and I have merged it with the main module 2016-10-06T00:51:52Z <p>creating a copy of <a href="/wiki/Module:Weather/sandbox" title="Module:Weather/sandbox">Module:Weather/sandbox</a> that can be used in articles until my work on the actual sandbox is complete and I have merged it with the main module</p> <p><b>New page</b></p><div>export = {}<br /> degree = &quot;°&quot; -- used by add_unit_names()<br /> minus = &quot;−&quot; -- used by makeRow() and makeTable()<br /> thinSpace = mw.ustring.char(0x2009) -- used by makeCell()<br /> <br /> -- Error message handling<br /> message = &quot;&quot;<br /> <br /> local function add_message(new_message)<br /> if show then<br /> if check_for_string(message) then<br /> message = message .. &quot; &quot; .. new_message<br /> else<br /> message = &quot;Notices: &quot; .. new_message<br /> end<br /> end<br /> end<br /> <br /> -- Input and output parameters<br /> local function get_format (frame)<br /> local input_parameter = frame.args.input<br /> local output_parameter = frame.args.output<br /> <br /> if input_parameter == nil then<br /> error(&quot;Please provide the number of values and a unit in the input parameter&quot;)<br /> else<br /> length = tonumber(string.match(input_parameter, &quot;(%d+)&quot;)) -- Find digits in the input parameter.<br /> input_unit = string.match(input_parameter, &quot;([CF])&quot;) -- C or F<br /> if string.find(input_parameter, &quot;[^CF%d%s]&quot;) then<br /> add_message(&quot;There are extraneous characters in the &lt;span style=\&quot;background-color: #EEE; font-family: monospace;\&quot;&gt;output&lt;/span&gt; parameter.&quot;)<br /> end<br /> end<br /> <br /> if input_unit == &quot;C&quot; then<br /> output_unit = &quot;F&quot;<br /> elseif input_unit == &quot;F&quot; then<br /> output_unit = &quot;C&quot;<br /> else<br /> error (&quot;Please provide an input unit in the input parameter: F for Fahrenheit or C for Celsius&quot;, 0)<br /> end<br /> <br /> if length == nil then<br /> error (&quot;get_format has not found a length value in the input parameter&quot;)<br /> end<br /> <br /> if output_parameter == nil then<br /> add_message(&quot;No output format has been provided in the &lt;span style=\&quot;background-color: #EEE; font-family: monospace;\&quot;&gt;output&lt;/span&gt; parameter.&quot;)<br /> else<br /> cell_format = {}<br /> local n = 1<br /> for unit in output_parameter:gmatch(&quot;[CF]&quot;) do<br /> cell_format[n] = unit<br /> n = n + 1<br /> if n &gt; 2 then<br /> break<br /> end<br /> end<br /> local function set_format(key, formatVariable, formatValue1, formatValue2)<br /> if string.find(output_parameter, key) then<br /> cell_format[formatVariable] = formatValue1<br /> else<br /> cell_format[formatVariable] = formatValue2<br /> end<br /> end<br /> if cell_format[1] then<br /> cell_format.first = cell_format[1]<br /> else<br /> error(&quot;C or F not found in output parameter&quot;)<br /> end<br /> if cell_format[2] == nil then<br /> cell_format[&quot;convert_units&quot;] = &quot;no&quot;<br /> else<br /> if cell_format[2] == cell_format[1] then<br /> error(&quot;There should not be two of the same unit name in the output parameter.&quot;)<br /> else<br /> cell_format[&quot;convert_units&quot;] = &quot;yes&quot;<br /> end<br /> end<br /> set_format(&quot;unit&quot;, &quot;unit_names&quot;, &quot;yes&quot;, &quot;no&quot;)<br /> set_format(&quot;no ?color&quot;, &quot;color&quot;, &quot;no&quot;, &quot;yes&quot;)<br /> set_format(&quot;sort&quot;, &quot;sortable&quot;, &quot;yes&quot;, &quot;no&quot;)<br /> set_format(&quot;full ?size&quot;, &quot;small_font&quot;, &quot;no&quot;, &quot;yes&quot;)<br /> set_format(&quot;no ?brackets&quot;, &quot;brackets&quot;, &quot;no&quot;, &quot;yes&quot;)<br /> set_format(&quot;round&quot;, &quot;decimals&quot;, &quot;0&quot;, &quot;&quot;)<br /> if string.find(output_parameter, &quot;line break&quot;) then<br /> cell_format[&quot;line_break&quot;] = &quot;yes&quot;<br /> elseif string.find(output_parameter, &quot;one line&quot;) then<br /> cell_format[&quot;line_break&quot;] = &quot;no&quot;<br /> else<br /> cell_format[&quot;line_break&quot;] = &quot;auto&quot;<br /> end<br /> if string.find(output_parameter, &quot;one line&quot;) and string.find(output_parameter, &quot;line break&quot;) then<br /> error(&quot;Place either \&quot;one line\&quot; or \&quot;line break\&quot; in the output parameter, not both&quot;)<br /> end<br /> end<br /> if frame.args.palette == nil then<br /> palette = &quot;cool2avg&quot;<br /> else<br /> palette = frame.args.palette<br /> end<br /> <br /> if frame.args.messages == &quot;show&quot; then<br /> show = true<br /> else<br /> show = false<br /> end<br /> <br /> return length, input_unit, output_unit<br /> end<br /> <br /> -- Number and string-handling functions<br /> local function check_for_number(value)<br /> return type(tonumber(value)) == &quot;number&quot;<br /> end<br /> <br /> function check_for_string(string)<br /> string = tostring(string)<br /> return string ~= &quot;&quot; and string ~= nil<br /> end<br /> <br /> local function round(value, decimals)<br /> value = tonumber(value)<br /> if type(value) == &quot;number&quot; then<br /> local string = string.format(&quot;%.&quot; .. decimals .. &quot;f&quot;, value)<br /> return string<br /> elseif value == nil then<br /> value = &quot;nil&quot;<br /> add_message(&quot;Format was asked to operate on &quot; .. value .. &quot;, which cannot be converted to a number.&quot;, 2)<br /> return &quot;&quot;<br /> end<br /> end<br /> <br /> local function convert(value, decimals, unit) -- Unit is the unit being converted from. It defaults to input_unit.<br /> if not unit then<br /> unit = input_unit<br /> end<br /> if check_for_number(value) then<br /> local value = tonumber(value)<br /> if unit == &quot;C&quot; then<br /> add_message(value .. &quot; &quot; .. degree .. unit .. &quot; was converted.&quot;)<br /> return round(value * 9/5 + 32, decimals)<br /> elseif unit == &quot;F&quot; then<br /> add_message(value .. &quot; &quot; .. degree .. unit .. &quot; was converted.&quot;)<br /> return round((value - 32) * 5/9, decimals)<br /> else<br /> error(&quot;Input unit not recognized&quot;, 2)<br /> end<br /> else<br /> return &quot;&quot; -- Setting result to empty string if value is not a number avoids concatenation errors.<br /> end<br /> end<br /> <br /> -- Input parsing<br /> function make_array(parameter, array, frame)<br /> local array = {}<br /> local n = 1<br /> for number in parameter:gmatch(&quot;%-?%d+%.?%d?&quot;) do<br /> local number = number<br /> if n == 1 then<br /> local decimals = number:match(&quot;%.(%d+)&quot;)<br /> if decimals == nil then<br /> precision = &quot;0&quot;<br /> else<br /> precision = #decimals<br /> end<br /> end<br /> table.insert(array, n, number)<br /> n = n + 1<br /> if n &gt; length then<br /> break<br /> end<br /> end<br /> if not array[length] then<br /> add_message(&quot;There are not &quot; .. length .. &quot; values in the &quot; .. parameter .. &quot; parameter.&quot;)<br /> end<br /> return array, precision<br /> end<br /> <br /> function make_arrays(frame)<br /> get_format(frame)<br /> local parameter_a = frame.args.a<br /> local parameter_b = frame.args.b<br /> local parameter_c = frame.args.c<br /> if parameter_a then<br /> a = make_array(parameter_a, a, frame)<br /> else<br /> error(&quot;Please provide a set of numbers in parameter a&quot;)<br /> end<br /> if parameter_b then<br /> b = make_array(parameter_b, b, frame)<br /> else<br /> add_message(&quot;There is no content in parameter &lt;span style=\&quot;background-color: #EEE; font-family: monospace;\&quot;&gt;b&lt;/span&gt;.&quot;)<br /> end<br /> if parameter_c then<br /> c = make_array(parameter_c, c, frame)<br /> else<br /> add_message(&quot;There is no content in parameter &lt;span style=\&quot;background-color: #EEE; font-family: monospace;\&quot;&gt;c&lt;/span&gt;.&quot;)<br /> end<br /> return a, b, c<br /> end<br /> <br /> -- Color generation<br /> <br /> palettes = {<br /> -- The first three arrays in each palette defines background color using a table of four numbers,<br /> -- say { 11, 22, 33, 44 } (values in °C).<br /> -- That means the color is 0 below 11 and above 44, and is 255 from 22 to 33.<br /> -- The color rises from 0 to 255 between 11 and 22, and falls between 33 and 44.<br /> cool = {<br /> { -42.75, 4.47, 41.5, 60 },<br /> { -42.75, 4.47, 4.5, 41.5 },<br /> { -90 , -42.78, 4.5, 23 },<br /> white = { -23.3, 37.8 },<br /> },<br /> cool2 = {<br /> { -42.75, 4.5 , 41.5, 56 },<br /> { -42.75, 4.5 , 4.5, 41.5 },<br /> { -90 , -42.78, 4.5, 23 },<br /> white = { -23.3, 35 },<br /> },<br /> cool2avg = {<br /> { -38, 4.5, 25 , 45 },<br /> { -38, 4.5, 4.5, 30 },<br /> { -70, -38 , 4.5, 23 },<br /> white = { -23.3, 25 },<br /> },<br /> }<br /> <br /> local function temperature_color(palette, value, out_rgb)<br /> --[[ Return style for a table cell based on the given value which<br /> should be a temperature in °C. ]]<br /> local background_color, text_color<br /> value = tonumber(value)<br /> if value == nil then<br /> background_color, text_color = &#039;FFF&#039;, &#039;000&#039;<br /> add_message(&quot;Value supplied to &lt;span style=\&quot;background-color: #EEE; font-family: monospace;\&quot;&gt;temperature_color&lt;/span&gt; is not recognized.&quot;)<br /> else<br /> local min, max = unpack(palette.white or { -23, 35 })<br /> if value &lt; min or value &gt;= max then<br /> text_color = &#039;FFF&#039;<br /> else<br /> text_color = &#039;&#039; -- This assumes that black text color is the default for most readers.<br /> end<br /> <br /> local background_rgb = out_rgb or {}<br /> for i, v in ipairs(palette) do<br /> local a, b, c, d = unpack(v)<br /> if value &lt;= a then<br /> background_rgb[i] = 0<br /> elseif value &lt; b then<br /> background_rgb[i] = (value - a) * 255 / (b - a)<br /> elseif value &lt;= c then<br /> background_rgb[i] = 255<br /> elseif value &lt; d then<br /> background_rgb[i] = 255 - ( (value - c) * 255 / (d - c) )<br /> else<br /> background_rgb[i] = 0<br /> end<br /> end<br /> background_color = string.format(&#039;%02X%02X%02X&#039;, background_rgb[1], background_rgb[2], background_rgb[3])<br /> end<br /> if text_color == &quot;&quot; then<br /> return background_color<br /> else<br /> return background_color, text_color<br /> end<br /> end<br /> <br /> local function color_CSS(background_color, text_color)<br /> if background_color and text_color then<br /> return &#039;background: #&#039; .. background_color .. &#039;; color: #&#039; .. text_color .. &#039;;&#039;<br /> elseif background_color then<br /> return &#039;background: #&#039; .. background_color .. &#039;;&#039;<br /> else<br /> return &#039;&#039;<br /> end<br /> end<br /> <br /> local function temperature_color_CSS(palette, value, out_rgb)<br /> return color_CSS(temperature_color(palette, value, out_rgb))<br /> end<br /> <br /> function temperature_CSS(value, unit, palette)<br /> local palette = palettes[palette] or palettes.cool<br /> local value = tonumber(value)<br /> if value == nil then<br /> error(&quot;The function &lt;span style=\&quot;background-color: #EEE; font-family: monospace;\&quot;&gt;temperature_CSS&lt;/span&gt; is receiving a nil value&quot;)<br /> else<br /> if unit == &#039;C&#039; then<br /> return color_CSS(temperature_color(palette, value))<br /> elseif unit == &#039;F&#039; then<br /> return color_CSS(temperature_color(palette, convert(value, decimals, &#039;F&#039;)))<br /> else<br /> unit_error(unit or &quot;nil&quot;)<br /> end<br /> end<br /> end<br /> <br /> local function style_attribute(palette, value, out_rgb)<br /> local font_size = &quot;font-size: 85%;&quot;<br /> local color = temperature_color_CSS(palette, value, out_rgb)<br /> return &#039;style=\&quot;&#039; .. color .. &#039; &#039; .. font_size .. &#039;\&quot;&#039;<br /> end<br /> <br /> function export.temperature_style(frame) -- used by Template:Average temperature table/color<br /> local palette = palettes[frame.args.palette] or palettes.cool<br /> local unit = frame.args.unit or &#039;C&#039;<br /> local value = tonumber(frame.args[1])<br /> if unit == &#039;C&#039; then<br /> return style_attribute(palette, value)<br /> elseif unit == &#039;F&#039; then<br /> return style_attribute(palette, convert(value, 1, &#039;F&#039;))<br /> else<br /> unit_error(unit)<br /> end<br /> end<br /> <br /> --[[ ==== Cell, row, table generation ==== ]]<br /> local output_formats = {<br /> high_low_average_F =<br /> { first = &quot;F&quot;,<br /> convert_units = &quot;yes&quot;,<br /> unit_names = &quot;no&quot;,<br /> color = &quot;yes&quot;,<br /> small_font = &quot;yes&quot;,<br /> sortable = &quot;yes&quot;,<br /> decimals = &quot;0&quot;,<br /> brackets = &quot;yes&quot;,<br /> line_break = &quot;auto&quot;, },<br /> high_low_average_C =<br /> { first = &quot;C&quot;,<br /> convert_units = &quot;yes&quot;,<br /> unit_names = &quot;no&quot;,<br /> color = &quot;yes&quot;,<br /> small_font = &quot;yes&quot;,<br /> sortable = &quot;yes&quot;,<br /> decimals = &quot;0&quot;,<br /> brackets = &quot;yes&quot;,<br /> line_break = &quot;auto&quot;, },<br /> high_low_F =<br /> { first = &quot;F&quot;,<br /> convert_units = &quot;yes&quot;,<br /> unit_names = &quot;no&quot;,<br /> color = &quot;no&quot;,<br /> small_font = &quot;yes&quot;,<br /> sortable = &quot;no&quot;,<br /> decimals = &quot;&quot;,<br /> brackets = &quot;yes&quot;,<br /> line_break = &quot;auto&quot;, },<br /> high_low_C =<br /> { first = &quot;C&quot;,<br /> convert_units = &quot;yes&quot;,<br /> unit_names = &quot;no&quot;,<br /> color = &quot;no&quot;,<br /> small_font = &quot;yes&quot;,<br /> sortable = &quot;no&quot;,<br /> decimals = &quot;0&quot;,<br /> brackets = &quot;yes&quot;,<br /> line_break = &quot;auto&quot;, },<br /> average_F =<br /> { first = &quot;F&quot;,<br /> convert_units = &quot;yes&quot;,<br /> unit_names = &quot;no&quot;,<br /> color = &quot;yes&quot;,<br /> small_font = &quot;yes&quot;,<br /> sortable = &quot;no&quot;,<br /> decimals = &quot;0&quot;,<br /> brackets = &quot;yes&quot;,<br /> line_break = &quot;auto&quot;, },<br /> average_C =<br /> { first = &quot;C&quot;,<br /> convert_units = &quot;yes&quot;,<br /> unit_names = &quot;no&quot;,<br /> color = &quot;yes&quot;,<br /> small_font = &quot;yes&quot;,<br /> sortable = &quot;no&quot;,<br /> decimals = &quot;0&quot;,<br /> brackets = &quot;yes&quot;,<br /> line_break = &quot;auto&quot;, },<br /> }<br /> <br /> local function add_unit_names(value, unit)<br /> if not unit then unit = input_unit end<br /> if output_format.unit_names == &quot;yes&quot; then<br /> if check_for_string(value) then<br /> return value .. &quot;&amp;nbsp;&quot; .. degree .. unit<br /> else<br /> return value -- Don&#039;t add a unit name to an empty string<br /> end<br /> else<br /> return value<br /> end<br /> end<br /> <br /> local function if_yes(parameter, realization1, realization2)<br /> if realization1 then<br /> if realization2 then<br /> if parameter == &quot;yes&quot; then<br /> parameter = { realization1, realization2 }<br /> else<br /> parameter = { &quot;&quot;, &quot;&quot; }<br /> end<br /> else<br /> if parameter == &quot;yes&quot; then<br /> parameter = realization1<br /> else<br /> parameter = &quot;&quot;<br /> end<br /> end<br /> else<br /> parameter = &quot;&quot;<br /> add_message(&quot;&lt;span style=\&quot;background-color: #EEE; font-family: monospace;\&quot;&gt;if_yes&lt;/span&gt; needs at least one realization&quot;)<br /> end<br /> return parameter<br /> end<br /> <br /> function makeCell(output_format, a, b, c)<br /> local cell, cell_content = &quot;&quot;, &quot;&quot;<br /> local color_CSS, other_CSS, title_attribute, sortkey, attribute_separator, converted_units_separator = &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;<br /> local style_attribute, high_low_separator, brackets, values, converted_units = {&quot;&quot;, &quot;&quot;}, {&quot;&quot;, &quot;&quot;}, {&quot;&quot;, &quot;&quot;}, {&quot;&quot;, &quot;&quot;}, {&quot;&quot;, &quot;&quot;}<br /> <br /> if check_for_number(output_format.decimals) then<br /> decimals = output_format.decimals<br /> --[[ Precision is the number of decimals in the first number of the last array.<br /> This may be a problem for data from Weatherbase,<br /> which seems to inappropriately remove .0 from numbers that have it. ]]<br /> else<br /> decimals = precision<br /> end<br /> <br /> if check_for_number(b) and check_for_number(a) then<br /> values, high_low_separator = { round(a, decimals), round(b, decimals) }, { thinSpace .. &quot;/&quot; .. thinSpace, if_yes(output_format.convert_units, thinSpace .. &quot;/&quot; .. thinSpace) }<br /> elseif check_for_number(a) then<br /> values = { round(a, decimals), &quot;&quot; }<br /> elseif check_for_number(c) then<br /> values = { round(c, decimals), &quot;&quot; }<br /> end<br /> if output_format.first == input_unit then<br /> if output_format.convert_units == &quot;yes&quot; then<br /> converted_units = { add_unit_names(convert(values[1], decimals), output_unit), add_unit_names(convert(values[2], decimals), output_unit) }<br /> end<br /> values = { add_unit_names(values[1]), add_unit_names(values[2]) }<br /> elseif output_format.first == &quot;C&quot; or output_format.first == &quot;F&quot; then<br /> if output_format.convert_units == &quot;yes&quot; then<br /> converted_units = { add_unit_names(values[1]), add_unit_names(values[2]) }<br /> end<br /> values = { add_unit_names(convert(values[1], decimals), output_unit), add_unit_names(convert(values[2], decimals), output_unit) }<br /> else<br /> if output_format.first == nil then<br /> output_format.first = &quot;nil&quot;<br /> end<br /> add_message(&quot;&lt;span style=\&quot;background-color: #EEE; font-family: monospace;\&quot;&gt;&quot; .. output_format.first .. &quot;&lt;/span&gt;, the value for &lt;span style=\&quot;background-color: #EEE; font-family: monospace;\&quot;&gt;first&lt;/span&gt; in &lt;span style=\&quot;background-color: #EEE; font-family: monospace;\&quot;&gt;output_format&lt;/span&gt; is not recognized.&quot;)<br /> end<br /> --[[<br /> Regarding line breaks:<br /> If there are two values, there will be at least three characters: 9/1.<br /> If there is one decimal, numbers will be three to five characters long<br /> and there will be 3 to 10 characters total even without unit conversion:<br /> 1.1, 116.5/88.0.<br /> If there are units, that adds three characters per number: 25 °C/20 °C.<br /> In each of these cases, a line break is needed so that table cells are not too wide;<br /> even more so when more than one of these things are true.<br /> ]]<br /> if output_format.convert_units == &quot;yes&quot; then<br /> brackets = if_yes(output_format.brackets, &quot;(&quot;, &quot;)&quot; )<br /> if output_format.line_break == &quot;auto&quot; then<br /> if check_for_string(values[2]) or decimals ~= &quot;0&quot; or output_format.show_units == &quot;yes&quot; then<br /> converted_units_separator = &quot;&lt;br&gt;&quot;<br /> else<br /> converted_units_separator = &quot;&amp;nbsp;&quot;<br /> end<br /> elseif output_format.line_break == &quot;yes&quot; then<br /> converted_units_separator = &quot;&lt;br&gt;&quot;<br /> elseif output_format.line_break == &quot;no&quot; then<br /> converted_units_separator = &quot;&amp;nbsp;&quot;<br /> else<br /> error(&quot;Value for line_break not recognized&quot;)<br /> end<br /> end<br /> <br /> cell_content = values[1] .. high_low_separator[1] .. values[2] .. converted_units_separator .. brackets[1] .. converted_units[1] .. high_low_separator[2] .. converted_units[2] .. brackets[2]<br /> <br /> if check_for_number(c) then<br /> color_CSS = if_yes(output_format.color, temperature_CSS(c, input_unit, palette))<br /> if check_for_number(b) and check_for_number(a) then<br /> local attribute_value<br /> if output_format.first == input_unit then<br /> attribute_value = c<br /> else<br /> attribute_value = convert(c, decimals)<br /> end<br /> sortkey = if_yes(output_format.sortable, &quot; data-sort-value=\&quot;&quot; .. attribute_value .. &quot;\&quot;&quot;)<br /> title_attribute = &quot; title=\&quot;Average temperature: &quot; .. attribute_value .. &quot; &quot; .. degree .. output_format.first .. &quot;\&quot;&quot;<br /> end<br /> elseif check_for_number(b) then<br /> color_css = &quot;&quot;<br /> elseif check_for_number(a) then<br /> color_CSS = if_yes(output_format.color, temperature_CSS(a, input_unit, palette))<br /> else<br /> add_message(&quot;Neither a nor b nor c are strings.&quot;)<br /> end<br /> other_CSS = if_yes(output_format.small_font, &quot;font-size: 85%;&quot;)<br /> if check_for_string(color_CSS) or check_for_string(other_CSS) then<br /> style_attribute = { &quot;style=\&quot;&quot;, &quot;\&quot;&quot; }<br /> end<br /> <br /> if check_for_string(other_CSS) or check_for_string(color_CSS) or check_for_string(title_attribute) or check_for_string(sortkey) then<br /> attribute_separator = &quot; | &quot;<br /> end<br /> cell = &quot;\n| &quot; .. style_attribute[1] .. color_CSS .. other_CSS .. style_attribute[2] .. title_attribute .. sortkey .. attribute_separator .. cell_content<br /> return cell<br /> end<br /> <br /> function export.makeRow(frame)<br /> make_arrays(frame)<br /> local output = &quot;&quot;<br /> if frame.args[1] then<br /> output = &quot;\n|-&quot;<br /> output = output .. &quot;\n! &quot; .. frame.args[1]<br /> if frame.args[2] then<br /> output = output .. &quot; !! &quot; .. frame.args[2]<br /> end<br /> end<br /> if cell_format then<br /> output_format = cell_format<br /> end<br /> if a and b and c then<br /> for i = 1, length do<br /> if not output_format then<br /> output_format = output_formats.high_low_average_F<br /> end<br /> output = output .. makeCell(output_format, a[i], b[i], c[i])<br /> end<br /> elseif a and b then<br /> for i = 1, length do<br /> if not output_format then<br /> output_format = output_formats.high_low_F<br /> end<br /> output = output .. makeCell(output_format, a[i], b[i])<br /> end<br /> elseif a then<br /> for i = 1, length do<br /> if not output_format then<br /> output_format = output_formats.average_F<br /> end<br /> output = output .. makeCell(output_format, a[i])<br /> end<br /> end<br /> output = mw.ustring.gsub(output, &quot;([%p%s])-(%d)&quot;, &quot;%1&quot; .. minus .. &quot;%2&quot;)<br /> return output<br /> end<br /> <br /> function export.makeTable(frame)<br /> make_arrays(frame)<br /> local output = &quot;{| class=\&quot;wikitable center nowrap\&quot;&quot;<br /> if cell_format then<br /> output_format = cell_format<br /> end<br /> if a and b and c then<br /> for i = 1, length do<br /> if not output_format then<br /> output_format = output_formats.high_low_average_F<br /> end<br /> output = output .. makeCell(output_format, a[i], b[i], c[i])<br /> end<br /> elseif a and b then<br /> for i = 1, length do<br /> if not output_format then<br /> output_format = output_formats.high_low_F<br /> end<br /> output = output .. makeCell(output_format, a[i], b[i])<br /> end<br /> elseif a then<br /> for i = 1, length do<br /> if not output_format then<br /> output_format = output_formats.average_F<br /> end<br /> output = output .. makeCell(output_format, a[i])<br /> end<br /> end<br /> output = mw.ustring.gsub(output, &quot;([%p%s])-(%d)&quot;, &quot;%1&quot; .. minus .. &quot;%2&quot;)<br /> --[[ Replaces hyphens that have a punctuation or space character before them and a number after them,<br /> making sure that hyphens in &quot;data-sort-type&quot; are not replaced with minuses.<br /> If Lua had (?&lt;=), a capture would not be necessary. ]]<br /> output = output .. &quot;\n|}&quot;<br /> if show then<br /> output = output .. &quot;\n\n&lt;span style=\&quot;color: red; font-size: 80%; line-height: 100%;\&quot;&gt;&quot; .. message .. &quot;&lt;/span&gt;&quot;<br /> end<br /> return output<br /> end<br /> <br /> <br /> <br /> local chart = [[<br /> {{Graph:Chart<br /> |width=600<br /> |height=180<br /> |xAxisTitle=Celsius<br /> |yAxisTitle=__COLOR<br /> |type=line<br /> |x=__XVALUES<br /> |y=__YVALUES<br /> |colors=__COLOR<br /> }}<br /> ]]<br /> <br /> function export.show(frame)<br /> -- For testing, return wikitext to show graphs of how the red/green/blue colors<br /> -- vary with temperature, and a table of the resulting colors.<br /> local function collection()<br /> -- Return a table to hold items.<br /> return {<br /> n = 0,<br /> add = function (self, item)<br /> self.n = self.n + 1<br /> self[self.n] = item<br /> end,<br /> join = function (self, sep)<br /> return table.concat(self, sep)<br /> end,<br /> }<br /> end<br /> local function make_chart(result, color, xvalues, yvalues)<br /> result:add(&#039;\n&#039;)<br /> result:add(frame:preprocess((chart:gsub(&#039;__[A-Z]+&#039;, {<br /> __COLOR = color,<br /> __XVALUES = xvalues:join(&#039;,&#039;),<br /> __YVALUES = yvalues:join(&#039;,&#039;),<br /> }))))<br /> end<br /> local function with_minus(value)<br /> if value &lt; 0 then<br /> return minus .. tostring(-value)<br /> end<br /> return tostring(value)<br /> end<br /> local args = frame.args<br /> local first = args[1] or -90<br /> local last = args[2] or 59<br /> local palette = palettes[args.palette] or palettes.cool<br /> local xvals, reds, greens, blues = collection(), collection(), collection(), collection()<br /> local wikitext = collection()<br /> wikitext:add(&#039;{| class=&quot;wikitable&quot;\n|-\n&#039;)<br /> local columns = 0<br /> for celsius = first, last do<br /> local background_rgb = {}<br /> local style = style_attribute(palette, celsius, background_rgb)<br /> local R = math.floor(background_rgb[1])<br /> local G = math.floor(background_rgb[2])<br /> local B = math.floor(background_rgb[3])<br /> xvals:add(celsius)<br /> reds:add(R)<br /> greens:add(G)<br /> blues:add(B)<br /> wikitext:add(&#039;| &#039; .. style .. &#039; | &#039; .. with_minus(celsius) .. &#039;\n&#039;)<br /> columns = columns + 1<br /> if columns &gt;= 10 then<br /> columns = 0<br /> wikitext:add(&#039;|-\n&#039;)<br /> end<br /> end<br /> wikitext:add(&#039;|}\n&#039;)<br /> make_chart(wikitext, &#039;Red&#039;, xvals, reds)<br /> make_chart(wikitext, &#039;Green&#039;, xvals, greens)<br /> make_chart(wikitext, &#039;Blue&#039;, xvals, blues)<br /> return wikitext:join()<br /> end<br /> <br /> return export</div> Erutuon