From bf4f63a0e649627748dace6b2c9f63dd2c0782ce Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 1 Oct 2016 14:37:15 -0700 Subject: [PATCH] Progress --- package.json | 3 +- src/index.ts | 93 +++++++----------------------- src/themeGenerator.ts | 43 ++++++++++++++ src/vscodeThemeGenerator.ts | 111 ++++++++++++++++++++++++++++++++++++ 4 files changed, 177 insertions(+), 73 deletions(-) create mode 100644 src/themeGenerator.ts create mode 100644 src/vscodeThemeGenerator.ts diff --git a/package.json b/package.json index 8ba1f3c..98a29fb 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "Generates editor/terminal themes using a set of colors", "main": "dist/index.js", "scripts": { - "build": "typings install && tsc" + "build": "typings install && tsc", + "start": "node dist/index.js" }, "author": "Tyriar", "license": "MIT", diff --git a/src/index.ts b/src/index.ts index 83b3f38..a3623f2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,77 +2,26 @@ import * as fs from 'fs'; import * as path from 'path'; - -console.log('test'); - -interface IColorSet { - ansiGroups?: { - ansiNormal?: IAnsiColorSet; - ansiBright?: IAnsiColorSet; - } - syntaxGroups?: { - constant?: string; - identifier?: string; - statement?: string; - type?: string; - global?: string; - emphasis?: string; - special?: string; - trivial?: string; - } - uiGroups?: { - userActionNeeded?: string; - userCurrentState?: string; - backgroundState?: string; - background?: string; - foreground?: string; - } -} - -interface IAnsiColorSet { - black?: string; - red?: string; - green?: string; - yellow?: string; - blue?: string; - magenta?: string; - cyan?: string; - white?: string; -} - -interface IThemeGenerator { - generateTheme(colorSet: IColorSet): string; -} - -interface IVscodeJsonTheme { - name?: string; - include?: string; - settings?: any[]; -} - -class VscodeThemeGenerator implements IThemeGenerator { - public generateTheme(colorSet: IColorSet): string { - let theme: IVscodeJsonTheme = {}; - theme.name = 'Generated theme'; - theme.settings = []; - if (colorSet.syntaxGroups.identifier) { - theme.settings.push({ - 'name': 'Function declarations', - 'scope': 'entity.name.function', - 'settings': { - 'foreground': colorSet.syntaxGroups.identifier - } - }); - } - return JSON.stringify(theme); - } -} +import { IColorSet } from './themeGenerator' +import { VscodeThemeGenerator } from './vscodeThemeGenerator' const colorSet: IColorSet = { - syntaxGroups: { - identifier: '#F00' - } -}; -const themeJson = new VscodeThemeGenerator().generateTheme(colorSet); -const outputFile = path.join(__dirname, '..', 'out', 'theme.json') -fs.writeFileSync(outputFile, themeJson); \ No newline at end of file + syntax: { + identifier: '#ffffff', + string: '#87d75f', + number: '#ffcc66', + keyword: '#ff8f7e', + functionCall: '#cae682', + storage: '#88b8f6', + comment: '#989898', + class: '#cae682', + type: '#88b8f6' + }, + ui: { + background: '#151515' + } +}; +const themeJson = new VscodeThemeGenerator().generateTheme('Generated theme 2', colorSet); +const outputFile = path.join(__dirname, '..', 'out', 'theme.json') + +fs.writeFileSync(outputFile, themeJson); diff --git a/src/themeGenerator.ts b/src/themeGenerator.ts new file mode 100644 index 0000000..ab953ce --- /dev/null +++ b/src/themeGenerator.ts @@ -0,0 +1,43 @@ +export interface IThemeGenerator { + generateTheme(name: string, colorSet: IColorSet): string; +} + +export interface IColorSet { + ansi?: { + normal?: IAnsiColorSet; + bright?: IAnsiColorSet; + } + syntax?: { + functionCall?: string; + identifier?: string; + keyword?: string; + number?: string; + storage?: string; + string?: string; + comment?: string; + class?: string; + type?: string; + } + ui?: { + background?: string; + foreground?: string; + } + /*uiGroups?: { + userActionNeeded?: string; + userCurrentState?: string; + backgroundState?: string; + background?: string; + foreground?: string; + }*/ +} + +export interface IAnsiColorSet { + black?: string; + red?: string; + green?: string; + yellow?: string; + blue?: string; + magenta?: string; + cyan?: string; + white?: string; +} diff --git a/src/vscodeThemeGenerator.ts b/src/vscodeThemeGenerator.ts new file mode 100644 index 0000000..2a8f668 --- /dev/null +++ b/src/vscodeThemeGenerator.ts @@ -0,0 +1,111 @@ +import { IColorSet, IThemeGenerator } from './themeGenerator' + +export interface IVscodeJsonTheme { + name?: string; + include?: string; + globalSettings?: { + background?: string; + foreground?: string; + }; + settings?: any[]; +} + +type SourceFetcher = (colorSet: IColorSet) => string; +type ColorGenerator = (color: string) => any; + +interface IRuleGenerator { + source: SourceFetcher; + generate: ColorGenerator; +} + +enum FontStyle { + NONE = 0, + ITALIC = 1 << 0, + BOLD = 1 << 1, + UNDERLINE = 1 << 2 +} + +function getSimpleColorGenerator(name: string, scope: string, fontStyle: number = FontStyle.NONE): (color: string) => any { + return (color: string) => { + let colorRule: any = { + 'name': name, + 'scope': scope, + 'settings': { + 'foreground': color + } + }; + let fontStyleValue = ''; + if (fontStyle & FontStyle.ITALIC) { + fontStyleValue += ' italic'; + } + if (fontStyle & FontStyle.BOLD) { + fontStyleValue += ' bold'; + } + if (fontStyle & FontStyle.UNDERLINE) { + fontStyleValue += ' underline'; + } + if (fontStyleValue.length > 0) { + colorRule.settings.fontStyle = fontStyleValue.trim(); + } + return colorRule; + } +} + +// An ordered list of rules to be applied if the source conditions are met +const vscodeJsonThemeRules: IRuleGenerator[] = [ + { source: set => set.syntax.identifier, + generate: getSimpleColorGenerator('Identifier', 'variable') }, + { source: set => set.syntax.string, + generate: getSimpleColorGenerator('String', 'string') }, + { source: set => set.syntax.number, + generate: getSimpleColorGenerator('Number', 'constant.numeric') }, + { source: set => set.syntax.keyword, + generate: getSimpleColorGenerator('Keyword', 'keyword, modifier, language.this') }, + // support/module function calls (eg. join in path.join) are colored as function calls + { source: set => set.syntax.functionCall, + generate: getSimpleColorGenerator('Function call', 'entity.name.function, support.function') }, + { source: set => set.syntax.storage, + generate: getSimpleColorGenerator('Storage', 'storage.type') }, + // TypeScript modules are colored as variables + { source: set => set.syntax.identifier, + generate: getSimpleColorGenerator('Modules', 'module.support', FontStyle.ITALIC) }, + { source: set => set.syntax.type, + generate: getSimpleColorGenerator('Type', 'type') }, + { source: set => set.syntax.comment, + generate: getSimpleColorGenerator('Comment', 'comment', FontStyle.ITALIC) }, + { source: set => set.syntax.class, + generate: getSimpleColorGenerator('Class', 'entity.name.class', FontStyle.UNDERLINE) } +]; + +export class VscodeThemeGenerator implements IThemeGenerator { + public generateTheme(name: string, colorSet: IColorSet): string { + let theme: IVscodeJsonTheme = {}; + theme.name = name; + theme.settings = []; + if (colorSet.ui.background) { + theme.settings.push({ + 'name': 'background', + 'settings': { + 'background': colorSet.ui.background + } + }); + } + if (colorSet.ui.foreground) { + theme.settings.push({ + 'name': 'foreground', + 'settings': { + 'foreground': colorSet.ui.foreground + } + }); + } + vscodeJsonThemeRules.forEach(ruleGenerator => { + try { + let color = ruleGenerator.source(colorSet); + theme.settings.push(ruleGenerator.generate(color)); + } catch (ex) { + // Ignore when source color does not exist + } + }); + return JSON.stringify(theme); + } +}