Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Nov 4, 2021
1 parent 67515ae commit e64bfc2
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 121 deletions.
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DS_Store
*.d.ts
*.log
coverage/
node_modules/
*.d.ts
*.log
.DS_Store
yarn.lock
236 changes: 121 additions & 115 deletions build.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'node:fs'
import https from 'node:https'
import concat from 'concat-stream'
import concatStream from 'concat-stream'
import {unified} from 'unified'
import parse from 'rehype-parse'
import {select, selectAll} from 'hast-util-select'
Expand All @@ -27,120 +27,126 @@ const headerToField = {

// From big to small:
const types = ['global', 'region', 'subregion', 'intermediate', 'area']
const overview = 'https://unstats.un.org/unsd/methodology/m49/overview/'

https
.request('https://unstats.un.org/unsd/methodology/m49/overview/', onrequest)
.end()

function onrequest(response) {
response.pipe(concat(onconcat)).on('error', console.error)
}

function onconcat(buf) {
const tree = unified().use(parse).parse(buf)

const table = select('#downloadTableEN', tree)
const headers = selectAll('thead td', table).map((d) => toString(d).trim())
const rows = selectAll('tbody tr', table)

const fields = headers.map((d) => {
if (!(d in headerToField)) {
throw new Error('Cannot handle unknown column header: `' + d + '`')
}

return headerToField[d]
.request(overview, (response) => {
response
.pipe(
concatStream((buf) => {
const tree = unified().use(parse).parse(buf)

const table = select('#downloadTableEN', tree)
const headers = selectAll('thead td', table).map((d) =>
toString(d).trim()
)
const rows = selectAll('tbody tr', table)

const fields = headers.map((d) => {
if (!(d in headerToField)) {
throw new Error(
'Cannot handle unknown column header: `' + d + '`'
)
}

return headerToField[d]
})

const records = rows.map((row) => {
const record = {}
const cells = selectAll('td', row)
let index = -1

while (++index < cells.length) {
const field = fields[index]
/** @type {string|boolean} */
let value = toString(cells[index]).trim()

if (!field) {
throw new Error(
'Cannot handle superfluous cell: `' +
value +
'` (' +
index +
')'
)
}

if (field === 'ldc' || field === 'lldc' || field === 'sids') {
value = /^x$/i.test(value)
}

record[field] = value
}

return record
})

const byCode = {}
let index = -1

while (++index < records.length) {
const record = records[index]
const stack = []
let kind = -1

while (++kind < types.length) {
const prefix = types[kind]
const code = record[prefix]
const name = record[prefix + 'Name']

// Sometimes, intermediate sizes aren’t available (e.g., for Antarctica).
if (!code || !name) {
continue
}

if (code in byCode) {
byCode[code].stack = Object.assign(
[],
byCode[code].stack,
stack
)
} else {
byCode[code] = {
type: kind,
name,
code,
iso3166: prefix === 'area' ? record.iso3166 : undefined,
stack: stack.concat()
}
}

stack[kind] = code
}
}

const toIso = {}

const codes = Object.keys(byCode)
.sort()
.map((code) => {
const entry = byCode[code]

entry.parent = entry.stack.pop()
entry.stack = undefined

if (entry.iso3166) {
toIso[entry.code] = entry.iso3166
}

return entry
})

fs.writeFileSync(
'index.js',
'export const unM49 = ' +
JSON.stringify(codes, null, 2) +
'\n\nexport const toIso3166 = ' +
JSON.stringify(toIso, null, 2) +
'\n'
)
})
)
.on('error', console.error)
})

const records = rows.map((row) => {
const record = {}
const cells = selectAll('td', row)
let index = -1
let field
let value

while (++index < cells.length) {
field = fields[index]
value = toString(cells[index]).trim()

if (!field) {
throw new Error(
'Cannot handle superfluous cell: `' + value + '` (' + index + ')'
)
}

if (field === 'ldc' || field === 'lldc' || field === 'sids') {
value = /^x$/i.test(value)
}

record[field] = value
}

return record
})

const byCode = {}
let index = -1
let stack
let record
let kind
let prefix
let code
let name

while (++index < records.length) {
record = records[index]
stack = []
kind = -1

while (++kind < types.length) {
prefix = types[kind]
code = record[prefix]
name = record[prefix + 'Name']

// Sometimes, intermediate sizes aren’t available (e.g., for Antarctica).
if (!code || !name) {
continue
}

if (code in byCode) {
byCode[code].stack = Object.assign([], byCode[code].stack, stack)
} else {
byCode[code] = {
type: kind,
name,
code,
iso3166: prefix === 'area' ? record.iso3166 : undefined,
stack: stack.concat()
}
}

stack[kind] = code
}
}

const toIso = {}

const codes = Object.keys(byCode)
.sort()
.map((code) => {
const entry = byCode[code]

entry.parent = entry.stack.pop()
entry.stack = undefined

if (entry.iso3166) {
toIso[entry.code] = entry.iso3166
}

return entry
})

fs.writeFileSync(
'index.js',
'export const unM49 = ' +
JSON.stringify(codes, null, 2) +
'\n\nexport const toIso3166 = ' +
JSON.stringify(toIso, null, 2) +
'\n'
)
}
.end()
10 changes: 7 additions & 3 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ import test from 'tape'
import {unM49} from './index.js'

test('m49', function (t) {
let index = -1

t.plan(2)
t.plan(3)

t.ok(Array.isArray(unM49), 'should be an `array`')

let index = -1
let found = false

while (++index < unM49.length) {
if (unM49[index].code !== '826') {
continue
}

found = true
t.deepEqual(
unM49[index],
{
Expand All @@ -25,4 +27,6 @@ test('m49', function (t) {
'should work'
)
}

t.equal(found, true, 'expected `826` in array')
})

0 comments on commit e64bfc2

Please sign in to comment.