From 2409a01fe1c2b3a62a5ad71ac041015ff01199cf Mon Sep 17 00:00:00 2001 From: Jo Liss Date: Fri, 22 May 2020 19:35:02 +0000 Subject: [PATCH] update Template:Medical_cases_chart parsing for new `data` format Because of changes to the `data` format, some items would end up in the wrong attributes. The new row parsing implementation accommodates these changes and now mimics the template's Lua code. This commit also renames the `rows` attribute to `data` to match the template syntax, adds an `options` attribute for named arguments like `alttot1`, and changes all attribute names to camelCase. --- src/template/templates/science.js | 103 +++++++++++++++--------------- tests/templates-data.test.js | 4 +- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/template/templates/science.js b/src/template/templates/science.js index 6179dd2e..52c92c8b 100644 --- a/src/template/templates/science.js +++ b/src/template/templates/science.js @@ -47,71 +47,70 @@ let templates = { return '' }, - /* -{{Medical cases chart/Row -|1 = valid date -|2 = expression for deaths -|3 = expression for recoveries -|4 = expression for total cases (3rd classification) -|alttot1 = alternate expression for active cases (3rd classification) -|5 = expression for number in 4th classification -|6 = expression for total in 5th classification -|alttot2 = alternate expression for number in 5th classification -|7 = number in the first column -|8 = change in the first column -|firstright1= whether a change in the first column is not applicable (n.a.) (yes|y|1) -|9 = number in the second column -|10 = change in the second column -|firstright2= whether a change in the second column is not applicable (n.a.) (yes|y|1) -|divisor = scaling divisor of the bars (bigger value = narrower bars) [defaults to: 1] -|numwidth = max width of the numbers in the right columns (xx or xxxx)<-(n|t|m|w|d) [defaults to: mm] -|collapsible= whether the row is collapsible (yes|y|1) {WIP} -|collapsed = manual override of the initial row state (yes|y|1) {WIP} -|id = manual override of the row id {WIP} -}} -*/ - - // this is a weird one - //https://en.wikipedia.org/wiki/Template:Medical_cases_chart + // Parse https://en.wikipedia.org/wiki/Template:Medical_cases_chart -- see + // https://en.wikipedia.org/wiki/Module:Medical_cases_chart for the original + // parsing code. 'medical cases chart': (tmpl, list) => { let order = [ 'date', - 'deaths_expr', - 'recovery_expr', - 'cases_expr', - 'alt_expr_1', - '4th_expr', - '5th_expr', - 'alt_expr_2', - 'col_1', - 'col_1_change', - 'show_col_1', - 'col_2', - 'col_2_change', - 'show_col_2', - 'divisor', - 'numwidth', - 'collabsible', - 'collapsed', - 'id', + 'deathsExpr', + 'recoveriesExpr', + 'casesExpr', + '4thExpr', + '5thExpr', + 'col1', + 'col1Change', + 'col2', + 'col2Change', ] let obj = parse(tmpl) obj.data = obj.data || '' let rows = obj.data.split('\n') - obj.rows = rows.map((row) => { - let arr = row.split(/;/) - return order.reduce((h, k, i) => { - h[k] = arr[i] || null - return h - }, {}) + + // Mimic row parsing in _buildBars in the Lua source, from the following + // line on: + // + // for parameter in mw.text.gsplit(line, ';') do + let dataArray = rows.map((row) => { + let parameters = row.split(';') + let rowObject = { + options: new Map + } + let positionalIndex = 0 + for (let i = 0; i < parameters.length; i++) { + let parameter = parameters[i].trim() + if (parameter.match(/^[a-zA-Z_]/)) { + // Named argument + let [key, value] = parameter.split('=') + // At this point, the Lua code evaluates alttot1 and alttot2 values as + // #expr expressions, but we just pass them through. See also: + // https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##expr + if (value === undefined) { + value = null + } + rowObject.options.set(key, value) + } else { + // Positional argument + // Here again, the Lua code evaluates arguments at index 1 through 5 + // as #expr expressions, but we just pass them through. + if (positionalIndex < order.length) { + rowObject[order[positionalIndex]] = parameter + } + positionalIndex++ + } + } + for (; positionalIndex < order.length; positionalIndex++) { + rowObject[order[positionalIndex]] = null + } + return rowObject }) - delete obj.data + obj.data = dataArray list.push(obj) return '' }, 'medical cases chart/row': (tmpl) => { - // actually keep this template + // Deprecated template; we keep it. return tmpl }, } diff --git a/tests/templates-data.test.js b/tests/templates-data.test.js index 08e26ce6..956594fa 100644 --- a/tests/templates-data.test.js +++ b/tests/templates-data.test.js @@ -230,8 +230,8 @@ test('covid-1', function (t) { let doc = wtf(str) let obj = doc.templates(0) t.equal(obj.location, 'Savannah', 'location') - t.equal(obj.rows.length, 5, '5 rows') - t.equal(obj.rows[0].date, '2009-04-13', 'row[0]') + t.equal(obj.data.length, 5, '5 rows') + t.equal(obj.data[0].date, '2009-04-13', 'row[0]') t.end() })