File size: 2,032 Bytes
d605f27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

import {Writable} from "stream";
import {MIDI} from "@k-l-lambda/music-widgets";

import {EngraverOptions, EngraverResult, postProcessSvg} from "./lilyCommands";



let lilypondEx = null;

const loadAddon = (path: string): boolean => {
	lilypondEx = require(path);

	return !!lilypondEx;
};


const engraveSvg = async (source: string,
	{onProcStart, onMidiRead, onSvgRead, includeFolders = []}: EngraverOptions = {}): Promise<Partial<EngraverResult>> => {
	if (!lilypondEx)
		throw new Error("Lilypond addon not loaded.");

	let logs;
	const svgs = [];
	let midi;

	const engravePromise = lilypondEx.engrave(source, {
		includeFolders,
		log (message) {
			logs = message;
		},
		onSVG (filename, content) {
			const captures = filename.match(/-(\d+)\.svg$/);
			const index = captures ? Number(captures[1]) - 1 : 0;

			const svg = postProcessSvg(content);
			svgs[index] = svg;

			onSvgRead && onSvgRead(index, svg);
		},
		onMIDI (_, buffer) {
			midi = MIDI.parseMidiData(buffer);

			onMidiRead && onMidiRead(midi);
		},
	});

	await onProcStart && onProcStart();

	const errorLevel = await engravePromise;

	return {
		logs,
		svgs,
		midi,
		errorLevel,
	};
};


const engraveSvgWithStream = async (source: string,
	output: Writable, {includeFolders = []}: {includeFolders?: string[]} = {},
): Promise<Partial<EngraverResult>> => {
	let logs;
	//let midi;

	//const tasks = [];

	const errorLevel = await lilypondEx.engrave(source, {
		includeFolders,
		log (message) {
			logs = message;
		},
		onSVG (_, content) {
			// Write stream in non-main thread may result in blocking, so post a task to event looping.
			//tasks.push(new Promise(resolve => ));
			setImmediate(() => {
				output.write(content);
				output.write("\n\n\n\n");
			});
		},
		//onMIDI (_, buffer) {
		//	midi = MIDI.parseMidiData(buffer);
		//},
	});

	//await Promise.all(tasks);
	await new Promise(resolve => setImmediate(resolve));

	return {
		logs,
		//midi,
		errorLevel,
	};
};




export {
	loadAddon,
	engraveSvg,
	engraveSvgWithStream,
};