github-desktop/script/generate-octicons.ts

109 lines
2.6 KiB
TypeScript
Raw Normal View History

2016-06-14 18:22:47 +00:00
/* generate-octicons
*
* Utility script for generating a strongly typed representation of all
* octicons distributed by the octicons NPM package. Enumerates the icons
* and generates the TypeScript class containing just what Desktop needs.
2016-06-14 18:22:47 +00:00
*/
2017-11-04 01:05:05 +00:00
import * as fs from 'fs'
import * as Path from 'path'
import * as cp from 'child_process'
import xml2js = require('xml2js')
import toCamelCase = require('to-camel-case')
interface IXML2JSNode {
path: {
$: {
d: string
}
}
}
interface IOcticonData {
readonly jsFriendlyName: string
readonly pathData: string
readonly width: string
readonly height: string
}
const viewBoxRe = /0 0 (\d+) (\d+)/
function readXml(xml: string): Promise<IXML2JSNode> {
return new Promise((resolve, reject) => {
xml2js.parseString(xml, function(err, result: IXML2JSNode) {
if (err) {
reject(err)
} else {
resolve(result)
}
})
})
}
async function generateIconData(): Promise<ReadonlyArray<IOcticonData>> {
const octicons = require('octicons')
const results = new Array<IOcticonData>()
for (const name of Object.keys(octicons)) {
const octicon = octicons[name]
const viewBox = octicon.options.viewBox
const viewBoxMatch = viewBoxRe.exec(viewBox)
if (!viewBoxMatch) {
2017-11-04 01:05:05 +00:00
throw new Error(
`*** ERROR! Unexpected viewBox format for ${octicon.symbol}`
)
}
const [, width, height] = viewBoxMatch
2017-11-04 01:05:05 +00:00
const result = await readXml(octicon.path)
const pathData = result.path.$.d
2017-11-04 01:05:05 +00:00
const jsFriendlyName = toCamelCase(octicon.symbol)
results.push({ jsFriendlyName, width, height, pathData })
}
return results
}
generateIconData().then(result => {
const out = fs.createWriteStream(
2017-11-04 01:05:05 +00:00
Path.resolve(__dirname, '../app/src/ui/octicons/octicons.generated.ts'),
{
2017-09-25 16:49:22 +00:00
encoding: 'utf-8',
}
)
2016-06-15 17:47:16 +00:00
out.write('/*\n')
out.write(
' * This file is automatically generated by the generate-octicons tool.\n'
)
out.write(' * Manually changing this file will only lead to sadness.\n')
out.write(' */\n\n')
out.write('export class OcticonSymbol {\n')
2016-06-13 18:40:13 +00:00
out.write(
'\n public constructor(public w: number, public h: number, public d: string) { }\n\n'
)
result.forEach(function(symbol) {
const { jsFriendlyName, pathData, width, height } = symbol
out.write(
` public static get ${jsFriendlyName}() { return new OcticonSymbol(${width}, ${height}, '${pathData}') }\n`
)
})
out.write('}\n')
out.end()
console.log(`Wrote ${result.length} octicons`)
2017-11-04 01:05:05 +00:00
// this is a shortcut to prettify the generated code
cp.execSync('yarn eslint:fix')
})