mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-28 00:37:53 +00:00
Merge pull request #14233 from keymanapp/feat/developer/kmc-convert-useArtifacts
feat(developer): kmc-convert: return data in-memory artifacts instead of writing to a file 😎
This commit is contained in:
commit
cec9437a71
5 changed files with 68 additions and 100 deletions
|
|
@ -25,41 +25,40 @@ export class ConverterMessages {
|
|||
static ERROR_NoConverterFound = SevError | 0x0002;
|
||||
static Error_NoConverterFound = (o: { inputFilename: string, outputFilename: string; }) => m(
|
||||
this.ERROR_NoConverterFound,
|
||||
`No converter is available that can convert from '${def(o.inputFilename)}' to '${def(o.outputFilename)}'.`
|
||||
`No converter is available that can convert from '${def(o.inputFilename)}' to '${def(o.outputFilename)}'.`,
|
||||
);
|
||||
|
||||
static ERROR_FileNotFound = SevError | 0x0003;
|
||||
static Error_FileNotFound = (o: { inputFilename: string; }) => m(
|
||||
this.ERROR_FileNotFound, `Input filename '${def(o.inputFilename)}
|
||||
' does not exist or could not be loaded.`
|
||||
this.ERROR_FileNotFound,
|
||||
`Input filename '${def(o.inputFilename)} ' does not exist or could not be loaded.`,
|
||||
);
|
||||
|
||||
static ERROR_UnableToRead = SevError | 0x0004;
|
||||
static Error_UnableToRead = (o: { inputFilename: string; }) => m(
|
||||
this.ERROR_UnableToRead, `Input file '${def(o.inputFilename)}
|
||||
' could not be read.`
|
||||
this.ERROR_UnableToRead,
|
||||
`Input file '${def(o.inputFilename)} ' could not be read.`,
|
||||
);
|
||||
|
||||
static ERROR_UnableToConvert = SevError | 0x0005;
|
||||
static Error_UnableToConvert = (o: { inputFilename: string; }) => m(
|
||||
this.ERROR_UnableToConvert, `Input file '${def(o.inputFilename)}
|
||||
' could not be converted.`
|
||||
this.ERROR_UnableToConvert,
|
||||
`Input file '${def(o.inputFilename)} ' could not be converted.`,
|
||||
);
|
||||
|
||||
static ERROR_UnableToWrite = SevError | 0x0006;
|
||||
static Error_UnableToWrite = (o: { outputFilename: string; }) => m(
|
||||
this.ERROR_UnableToWrite, `Output file for '${def(o.outputFilename)}
|
||||
' could not be written.`
|
||||
this.ERROR_UnableToWrite,
|
||||
`Output file for '${def(o.outputFilename)} ' could not be written.`,
|
||||
);
|
||||
|
||||
static ERROR_UnsupportedCharactersDetected = SevError | 0x0007;
|
||||
static Error_UnsupportedCharactersDetected = (o: { inputFilename: string, keymap_index: string, key: string, output: string; }) => m(
|
||||
this.ERROR_UnsupportedCharactersDetected, `Input file ${def(o.inputFilename)} contains unsupported character ('${def(o.output)}') on key (${def(o.key)}) at keyMap index ${def(o.keymap_index)}`
|
||||
this.ERROR_UnsupportedCharactersDetected,
|
||||
`Input file ${def(o.inputFilename)} contains unsupported character ('${def(o.output)}') on key ( ${def(o.key)}) at keyMap index ${def(o.keymap_index)}`,
|
||||
);
|
||||
|
||||
static ERROR_InvalidFile = SevError | 0x0008;
|
||||
static Error_InvalidFile = (o: { errorText: string; }) => m(
|
||||
this.ERROR_InvalidFile, `The source file has an invalid structure: ${def(o.errorText)}`
|
||||
);
|
||||
|
||||
this.ERROR_InvalidFile, `The source file has an invalid structure: ${def(o.errorText)}`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,8 @@ export class Converter implements KeymanCompiler {
|
|||
const converter = new ConverterClass(this.callbacks, converterOptions);
|
||||
const artifacts = await converter.run(inputFilename, outputFilename);
|
||||
// Note: any subsequent errors in conversion will have been reported by the converter
|
||||
return artifacts ? { artifacts } : null;
|
||||
//return artifacts ? { artifacts } : null;
|
||||
return artifacts ? artifacts : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7,19 +7,32 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import { CompilerCallbacks, CompilerOptions } from "@keymanapp/developer-utils";
|
||||
import { ConverterToKmnArtifacts } from "../converter-artifacts.js";
|
||||
import { CompilerCallbacks, CompilerOptions, KeymanCompilerResult, } from "@keymanapp/developer-utils";
|
||||
import { KmnFileWriter } from './kmn-file-writer.js';
|
||||
import { KeylayoutFileReader } from './keylayout-file-reader.js';
|
||||
import { ConverterMessages } from '../converter-messages.js';
|
||||
import { ConverterArtifacts } from "../converter-artifacts.js";
|
||||
import { ConverterToKmnArtifacts } from "../converter-artifacts.js"
|
||||
import { KeylayoutXMLSourceFile } from '../../../common/web/utils/src/types/keylayout/keylayout-xml.js';
|
||||
|
||||
/**
|
||||
* Object holding all important data for the conversion between
|
||||
* input (*.keylayout) format and output (*.kmn) format.
|
||||
* It contains input and output filenames, an array of all used modifiers
|
||||
* and all preprocessed key rules for up to 3 key/modifier combinations.
|
||||
*/
|
||||
|
||||
export interface ConverterResult extends KeymanCompilerResult {
|
||||
/**
|
||||
* Internal in-memory build artifacts from a successful compilation. Caller
|
||||
* can write these to disk with {@link Converter.write}
|
||||
*/
|
||||
artifacts: ConverterArtifacts;
|
||||
};
|
||||
|
||||
export interface ConverterToKmnResult extends ConverterResult {
|
||||
/**
|
||||
* Internal in-memory build artifacts from a successful compilation. Caller
|
||||
* can write these to disk with {@link Converter.write}
|
||||
*/
|
||||
artifacts: ConverterToKmnArtifacts;
|
||||
};
|
||||
|
||||
|
||||
export interface convert_object {
|
||||
keylayout_filename: string,
|
||||
kmn_filename: string,
|
||||
|
|
@ -51,14 +64,15 @@ export class KeylayoutToKmnConverter {
|
|||
* @param outputFilename the resulting keyman .kmn-file
|
||||
* @return null on success
|
||||
*/
|
||||
async run(inputFilename: string, outputFilename?: string): Promise<ConverterToKmnArtifacts> {
|
||||
|
||||
async run(inputFilename: string, outputFilename?: string): Promise<ConverterToKmnResult> {
|
||||
|
||||
if (!inputFilename) {
|
||||
this.callbacks.reportMessage(ConverterMessages.Error_FileNotFound({ inputFilename }));
|
||||
return null;
|
||||
}
|
||||
|
||||
outputFilename = outputFilename ?? inputFilename.replace(/\.keylayout$/, '.kmn');
|
||||
|
||||
const KeylayoutReader = new KeylayoutFileReader(this.callbacks/*, this.options*/);
|
||||
const jsonO: KeylayoutXMLSourceFile = KeylayoutReader.read(inputFilename);
|
||||
|
||||
|
|
@ -76,8 +90,6 @@ export class KeylayoutToKmnConverter {
|
|||
return null;
|
||||
}
|
||||
|
||||
outputFilename = outputFilename ?? inputFilename.replace(/\.keylayout$/, '.kmn');
|
||||
|
||||
const outArray: convert_object = await this.convert(jsonO, outputFilename);
|
||||
if (!outArray) {
|
||||
this.callbacks.reportMessage(ConverterMessages.Error_UnableToConvert({ inputFilename }));
|
||||
|
|
@ -86,15 +98,27 @@ export class KeylayoutToKmnConverter {
|
|||
|
||||
const kmnFileWriter = new KmnFileWriter(this.callbacks, this.options);
|
||||
|
||||
const out_text_ok: boolean = kmnFileWriter.write(outArray);
|
||||
// _S2 still write to file - will be removed later
|
||||
const out_text_ok: boolean = kmnFileWriter.writeToFile(outArray);
|
||||
if (!out_text_ok) {
|
||||
this.callbacks.reportMessage(ConverterMessages.Error_UnableToWrite({ outputFilename }));
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
// write to object/ConverterToKmnResult
|
||||
const out_Uint8: Uint8Array = kmnFileWriter.write(outArray);
|
||||
const Result_toBeReturned: ConverterToKmnResult = {
|
||||
artifacts: {
|
||||
kmn: { data: out_Uint8, filename: outputFilename }
|
||||
}
|
||||
};
|
||||
|
||||
if (!out_Uint8) {
|
||||
this.callbacks.reportMessage(ConverterMessages.Error_UnableToWrite({ outputFilename }));
|
||||
return null;
|
||||
}
|
||||
return Result_toBeReturned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief member function to read filename and behaviour of a json object into a convert_object
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export class KmnFileWriter {
|
|||
* @param outputfilename the file that will be written; if no outputfilename is given an outputfilename will be created from data_ukelele.keylayout_filename
|
||||
* @return true if data has been written; false if not
|
||||
*/
|
||||
public write(data_ukelele: convert_object): boolean {
|
||||
public writeToFile(data_ukelele: convert_object): boolean {
|
||||
|
||||
let data: string = "\n";
|
||||
|
||||
|
|
@ -37,29 +37,12 @@ export class KmnFileWriter {
|
|||
this.callbacks.fs.writeFileSync(data_ukelele.kmn_filename, new TextEncoder().encode(data));
|
||||
return true;
|
||||
} catch (err) {
|
||||
this.callbacks.reportMessage(ConverterMessages.Error_OutputFilenameIsRequired());
|
||||
this.callbacks.reportMessage(ConverterMessages.Error_UnableToWrite({outputFilename: data_ukelele.kmn_filename}));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public writeToString(data_ukelele: convert_object): string {
|
||||
let data: string = "\n";
|
||||
|
||||
// add top part of kmn file: STORES
|
||||
data += this.write_KmnFileHeader(data_ukelele);
|
||||
|
||||
// add bottom part of kmn file: RULES
|
||||
data += this.writeData_Rules(data_ukelele);
|
||||
|
||||
try {
|
||||
return data;
|
||||
} catch (err) {
|
||||
this.callbacks.reportMessage(ConverterMessages.Error_OutputFilenameIsRequired());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public writeToUint8Array(data_ukelele: convert_object): Uint8Array {
|
||||
public write(data_ukelele: convert_object): Uint8Array {
|
||||
let data: string = "\n";
|
||||
|
||||
// add top part of kmn file: STORES
|
||||
|
|
@ -71,7 +54,7 @@ export class KmnFileWriter {
|
|||
try {
|
||||
return new TextEncoder().encode(data);
|
||||
} catch (err) {
|
||||
this.callbacks.reportMessage(ConverterMessages.Error_OutputFilenameIsRequired());
|
||||
this.callbacks.reportMessage(ConverterMessages.Error_UnableToWrite({outputFilename: data_ukelele.kmn_filename}));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ describe('KmnFileWriter', function () {
|
|||
compilerTestCallbacks.clear();
|
||||
});
|
||||
|
||||
describe("write() ", function () {
|
||||
describe("writeToFile() ", function () {
|
||||
const inputFilename = makePathToFixture('../data/Test.keylayout');
|
||||
const sut = new KeylayoutToKmnConverter(compilerTestCallbacks, compilerTestOptions);
|
||||
const sut_r = new KeylayoutFileReader(compilerTestCallbacks);
|
||||
|
|
@ -35,59 +35,19 @@ describe('KmnFileWriter', function () {
|
|||
const read_unavailable = sut_r.read(inputFilename_unavailable);
|
||||
const converted_unavailable = sut.convert_bound.convert(read_unavailable, inputFilename_unavailable.replace(/\.keylayout$/, '.kmn'));
|
||||
|
||||
it('write() should return true (no error) if written', async function () {
|
||||
|
||||
const result = sut_w.write(converted);
|
||||
it('writeToFile()() should return true (no error) if written', async function () {
|
||||
const result = sut_w.writeToFile(converted);
|
||||
assert.isTrue(result);
|
||||
});
|
||||
|
||||
it('write() should return false if no inputfile', async function () {
|
||||
const result = sut_w.write(converted_unavailable);
|
||||
it('writeToFile()() should return false if no inputfile', async function () {
|
||||
const result = sut_w.writeToFile(converted_unavailable);
|
||||
assert.isFalse(result);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("writeToString() ", function () {
|
||||
const inputFilename = makePathToFixture('../data/Test.keylayout');
|
||||
const sut = new KeylayoutToKmnConverter(compilerTestCallbacks, compilerTestOptions);
|
||||
const sut_r = new KeylayoutFileReader(compilerTestCallbacks);
|
||||
const sut_w = new KmnFileWriter(compilerTestCallbacks, compilerTestOptions);
|
||||
const read = sut_r.read(inputFilename);
|
||||
const converted = sut.convert_bound.convert(read, inputFilename.replace(/\.keylayout$/, '.kmn'));
|
||||
|
||||
const out_expected_first: string = "c ..................................................................................................................\n"
|
||||
+ "c ..................................................................................................................\n"
|
||||
+ "c Keyman keyboard generated by kmn-convert version: " + KEYMAN_VERSION.VERSION + "\n"
|
||||
+ "c from Ukelele file: ";
|
||||
|
||||
const out_expected_last: string = "\n"
|
||||
+ "c ..................................................................................................................\n"
|
||||
+ "c ..................................................................................................................\n"
|
||||
+ "\n"
|
||||
+ "store(&TARGETS) 'desktop'\n"
|
||||
+ "\n"
|
||||
+ "begin Unicode > use(main)\n\n"
|
||||
+ "group(main) using keys\n\n"
|
||||
+ "\n";
|
||||
|
||||
// empty convert_object from unavailable file name
|
||||
const inputFilename_unavailable = makePathToFixture('../data/X.keylayout');
|
||||
const read_unavailable = sut_r.read(inputFilename_unavailable);
|
||||
const converted_unavailable = sut.convert_bound.convert(read_unavailable, inputFilename_unavailable.replace(/\.keylayout$/, '.kmn'));
|
||||
|
||||
it('writeToString() should return result', async function () {
|
||||
const result = sut_w.writeToString(converted);
|
||||
assert.isNotNull(result);
|
||||
});
|
||||
|
||||
it('writeToString() should return header in case of missing inputfile', async function () {
|
||||
const result = sut_w.writeToString(converted_unavailable);
|
||||
assert.equal(result, ("\n" + out_expected_first + out_expected_last));
|
||||
});
|
||||
});
|
||||
|
||||
describe("writeToUint8Array() ", function () {
|
||||
describe("write()() ", function () {
|
||||
const inputFilename = makePathToFixture('../data/Test.keylayout');
|
||||
const sut = new KeylayoutToKmnConverter(compilerTestCallbacks, compilerTestOptions);
|
||||
const sut_r = new KeylayoutFileReader(compilerTestCallbacks);
|
||||
|
|
@ -116,13 +76,14 @@ describe('KmnFileWriter', function () {
|
|||
const inputFilename_unavailable = makePathToFixture('../data/X.keylayout');
|
||||
const read_unavailable = sut_r.read(inputFilename_unavailable);
|
||||
const converted_unavailable = sut.convert_bound.convert(read_unavailable, inputFilename_unavailable.replace(/\.keylayout$/, '.kmn'));
|
||||
it('writeToUint8Array() should return header in case of missing inputfile', async function () {
|
||||
const result = sut_w.writeToUint8Array(converted_unavailable);
|
||||
|
||||
it('write()() should return header in case of missing inputfile', async function () {
|
||||
const result = sut_w.write(converted_unavailable);
|
||||
assert.equal(new TextDecoder().decode(result), ("\n" + out_expected_first + out_expected_last));
|
||||
});
|
||||
|
||||
it('writeToUint8Array() should return result', async function () {
|
||||
const result = sut_w.writeToUint8Array(converted);
|
||||
it('write()() should return result', async function () {
|
||||
const result = sut_w.write(converted);
|
||||
assert.isNotNull(result);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue