astro-lilypond 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/execLilyPond.d.ts +2 -1
- package/dist/execLilyPond.js +3 -3
- package/dist/index.d.ts +7 -2
- package/dist/index.js +13 -5
- package/dist/plugins/renderMarkdownBlock.js +2 -1
- package/dist/render.d.ts +8 -0
- package/dist/render.js +10 -1
- package/dist/utils/emitLilypondAsset.d.ts +2 -1
- package/dist/utils/emitLilypondAsset.js +2 -2
- package/dist/utils/emitLilypondPdfAsset.d.ts +2 -0
- package/dist/utils/emitLilypondPdfAsset.js +2 -2
- package/dist/utils/resolveDefaults.js +2 -1
- package/package.json +7 -7
package/dist/execLilyPond.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { AstroIntegrationLogger } from "astro";
|
|
2
|
-
import type { Format } from "./render.js";
|
|
2
|
+
import type { Backend, Format } from "./render.js";
|
|
3
3
|
export interface ExecLilypondOptions {
|
|
4
4
|
binaryPath: string;
|
|
5
5
|
format: Format;
|
|
6
|
+
backend: Backend;
|
|
6
7
|
crop: boolean;
|
|
7
8
|
resolution: number;
|
|
8
9
|
includePaths: string[];
|
package/dist/execLilyPond.js
CHANGED
|
@@ -8,7 +8,7 @@ const MAX_BUFFER = 16 * 1024 * 1024; // 16 MiB
|
|
|
8
8
|
* build output); throws a normalized Error on a non-zero exit or timeout.
|
|
9
9
|
*/
|
|
10
10
|
export async function execLilyPond(options) {
|
|
11
|
-
const { binaryPath, format, crop, resolution, includePaths, timeout, inputPath, outputBase, logger, } = options;
|
|
11
|
+
const { binaryPath, format, backend, crop, resolution, includePaths, timeout, inputPath, outputBase, logger, } = options;
|
|
12
12
|
const args = [
|
|
13
13
|
// Render the correct format
|
|
14
14
|
`--format=${format}`,
|
|
@@ -20,9 +20,9 @@ export async function execLilyPond(options) {
|
|
|
20
20
|
// inside of individual .ly files
|
|
21
21
|
// Disable point-and-click behavior on SVGs when clicking noteheads
|
|
22
22
|
"--define-default=no-point-and-click",
|
|
23
|
-
//
|
|
23
|
+
// `cairo` is faster, but only `ps` supports \postscript markup
|
|
24
24
|
// https://lilypond.org/doc/v2.26/Documentation/usage/advanced-command_002dline-options-for-lilypond
|
|
25
|
-
|
|
25
|
+
`--define-default=backend=${backend}`,
|
|
26
26
|
// Resolution for generating PNGs (set in DPI)
|
|
27
27
|
`--define-default=resolution=${resolution}`,
|
|
28
28
|
// Set cropping
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { AstroIntegration } from "astro";
|
|
|
2
2
|
import { type AstroComponentFactory } from "astro/runtime/server/index.js";
|
|
3
3
|
import { type AutoInstallOptions } from "./binary/index.js";
|
|
4
4
|
import { type PluginOptions } from "./plugins/index.js";
|
|
5
|
-
import { type LilypondDefaults } from "./render.js";
|
|
5
|
+
import { type Backend, type LilypondDefaults } from "./render.js";
|
|
6
6
|
import { type LilypondMetadata, type RenderedHtmlOptions } from "./utils/index.js";
|
|
7
7
|
export declare const LY_EXTENSIONS: readonly [".ly", ".lilypond", ".ily"];
|
|
8
8
|
export type { AstroComponentFactory, AutoInstallOptions, LilypondDefaults, LilypondMetadata, PluginOptions as LilypondPluginOptions, };
|
|
@@ -29,6 +29,11 @@ export interface GetScoreOptions {
|
|
|
29
29
|
* @default the `defaults.format` configured on the integration ("svg" unless overridden)
|
|
30
30
|
*/
|
|
31
31
|
format?: "svg" | "png";
|
|
32
|
+
/**
|
|
33
|
+
* Graphics backend for `Score` and `pdf`.
|
|
34
|
+
* @default the `defaults.backend` configured on the integration ("cairo" unless overridden)
|
|
35
|
+
*/
|
|
36
|
+
backend?: Backend;
|
|
32
37
|
/**
|
|
33
38
|
* Crop `Score` to a single tightly-fit image instead of full pages.
|
|
34
39
|
* @default false
|
|
@@ -60,7 +65,7 @@ type ScoreImageProps = RenderedHtmlOptions;
|
|
|
60
65
|
* or a `lilypondLoader()` entry) to a renderable `<Score />` component.
|
|
61
66
|
*/
|
|
62
67
|
export declare function getScore(score: LilypondScore, options?: GetScoreOptions): Promise<GetScoreResult>;
|
|
63
|
-
export interface ScoreProps extends ScoreImageProps, Pick<GetScoreOptions, "format" | "crop"> {
|
|
68
|
+
export interface ScoreProps extends ScoreImageProps, Pick<GetScoreOptions, "format" | "backend" | "crop"> {
|
|
64
69
|
/**
|
|
65
70
|
* A `LilypondScore` from a `.ly`/`.ily`/`.lilypond` import
|
|
66
71
|
* or a `lilypondLoader()` entry.
|
package/dist/index.js
CHANGED
|
@@ -30,8 +30,10 @@ function createErrorScoreComponent(error, title) {
|
|
|
30
30
|
export async function getScore(score, options = {}) {
|
|
31
31
|
const state = getLilypondState();
|
|
32
32
|
const { logger } = state;
|
|
33
|
-
const { resolution, cropScale, format: defaultFormat, } = resolveDefaults(state.defaults);
|
|
33
|
+
const { resolution, cropScale, backend: defaultBackend, format: defaultFormat, } = resolveDefaults(state.defaults);
|
|
34
34
|
const format = options.format ?? defaultFormat;
|
|
35
|
+
const backend = options.backend ?? defaultBackend;
|
|
36
|
+
const defaults = { ...state.defaults, backend };
|
|
35
37
|
const crop = options.crop ?? false;
|
|
36
38
|
try {
|
|
37
39
|
const [{ Score, pages }, pdf] = await Promise.all([
|
|
@@ -39,6 +41,7 @@ export async function getScore(score, options = {}) {
|
|
|
39
41
|
const pages = await emitLilypondAsset({
|
|
40
42
|
title: score.assetTitle,
|
|
41
43
|
format,
|
|
44
|
+
backend,
|
|
42
45
|
source: score.source,
|
|
43
46
|
resolution,
|
|
44
47
|
crop,
|
|
@@ -47,7 +50,7 @@ export async function getScore(score, options = {}) {
|
|
|
47
50
|
render: () => render(score.source, {
|
|
48
51
|
format,
|
|
49
52
|
crop,
|
|
50
|
-
defaults
|
|
53
|
+
defaults,
|
|
51
54
|
timeout: state.timeout,
|
|
52
55
|
binaryPath: state.binaryPath,
|
|
53
56
|
includePaths: score.includePaths,
|
|
@@ -64,11 +67,12 @@ export async function getScore(score, options = {}) {
|
|
|
64
67
|
? emitLilypondPdfAsset({
|
|
65
68
|
title: score.assetTitle,
|
|
66
69
|
source: score.source,
|
|
70
|
+
backend,
|
|
67
71
|
binaryPath: state.binaryPath,
|
|
68
72
|
render: () => render(score.source, {
|
|
69
73
|
format: "pdf",
|
|
70
74
|
crop: false,
|
|
71
|
-
defaults
|
|
75
|
+
defaults,
|
|
72
76
|
timeout: state.timeout,
|
|
73
77
|
binaryPath: state.binaryPath,
|
|
74
78
|
includePaths: score.includePaths,
|
|
@@ -98,8 +102,12 @@ export async function getScore(score, options = {}) {
|
|
|
98
102
|
* `getScore()` instead when you need those.
|
|
99
103
|
*/
|
|
100
104
|
export const Score = createComponent(async (result, props) => {
|
|
101
|
-
const { content, format, crop, ...imageProps } = props;
|
|
102
|
-
const { Score: ContentScore } = await getScore(content, {
|
|
105
|
+
const { content, format, backend, crop, ...imageProps } = props;
|
|
106
|
+
const { Score: ContentScore } = await getScore(content, {
|
|
107
|
+
format,
|
|
108
|
+
backend,
|
|
109
|
+
crop,
|
|
110
|
+
});
|
|
103
111
|
return renderTemplate `${renderComponent(result, "Score", ContentScore, imageProps)}`;
|
|
104
112
|
});
|
|
105
113
|
function injectMarkdownPlugin(processor, key, plugin) {
|
|
@@ -9,13 +9,14 @@ import { altTextForBlock, emitLilypondAsset, prependVersion, renderedErrorHtml,
|
|
|
9
9
|
export async function renderMarkdownBlock(options, block) {
|
|
10
10
|
const { logger } = options;
|
|
11
11
|
const { title } = block;
|
|
12
|
-
const { version, format, resolution, cropScale } = resolveDefaults(options.defaults);
|
|
12
|
+
const { version, format, backend, resolution, cropScale } = resolveDefaults(options.defaults);
|
|
13
13
|
const source = version ? prependVersion(block.value, version) : block.value;
|
|
14
14
|
const alt = altTextForBlock(block.meta, block.value);
|
|
15
15
|
try {
|
|
16
16
|
const pages = await emitLilypondAsset({
|
|
17
17
|
title,
|
|
18
18
|
format,
|
|
19
|
+
backend,
|
|
19
20
|
source,
|
|
20
21
|
resolution,
|
|
21
22
|
crop: true,
|
package/dist/render.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import type { AstroIntegrationLogger } from "astro";
|
|
|
2
2
|
import type { LilypondVersion } from "./types/lilypondVersion.js";
|
|
3
3
|
export declare const FORMATS: readonly ["png", "svg", "pdf"];
|
|
4
4
|
export type Format = (typeof FORMATS)[number];
|
|
5
|
+
export declare const BACKENDS: readonly ["cairo", "ps"];
|
|
6
|
+
export type Backend = (typeof BACKENDS)[number];
|
|
5
7
|
/**
|
|
6
8
|
* Defaults passed to each score for rendering.
|
|
7
9
|
*/
|
|
@@ -17,6 +19,12 @@ export interface LilypondDefaults {
|
|
|
17
19
|
* @default "svg"
|
|
18
20
|
*/
|
|
19
21
|
format?: "svg" | "png";
|
|
22
|
+
/**
|
|
23
|
+
* Graphics backend. `"cairo"` is recommended for faster output.
|
|
24
|
+
* `"ps"` is required for `\postscript` markup, and can't produce SVG.
|
|
25
|
+
* @default "cairo"
|
|
26
|
+
*/
|
|
27
|
+
backend?: Backend;
|
|
20
28
|
/**
|
|
21
29
|
* Resolution in DPI (only applies to PNG).
|
|
22
30
|
* @default 144
|
package/dist/render.js
CHANGED
|
@@ -5,9 +5,11 @@ import { execLilyPond } from "./execLilyPond.js";
|
|
|
5
5
|
import { readOutputFile, safeInputFileName } from "./readOutputFile.js";
|
|
6
6
|
import { resolveDefaults } from "./utils/resolveDefaults.js";
|
|
7
7
|
export const FORMATS = ["png", "svg", "pdf"];
|
|
8
|
+
export const BACKENDS = ["cairo", "ps"];
|
|
8
9
|
const defaultLilypondDefaults = {
|
|
9
10
|
version: "2.26.0",
|
|
10
11
|
format: "svg",
|
|
12
|
+
backend: "cairo",
|
|
11
13
|
resolution: 144,
|
|
12
14
|
cropScale: 1.5,
|
|
13
15
|
};
|
|
@@ -20,10 +22,16 @@ export const defaultOptions = {
|
|
|
20
22
|
};
|
|
21
23
|
export async function render(source, options) {
|
|
22
24
|
const { format = defaultOptions.format, crop = defaultOptions.crop, binaryPath = defaultOptions.binaryPath, timeout = defaultOptions.timeout, includePaths = [], sourceName, logger, } = options;
|
|
23
|
-
const { resolution } = resolveDefaults(options.defaults);
|
|
25
|
+
const { backend, resolution } = resolveDefaults(options.defaults);
|
|
24
26
|
if (!FORMATS.includes(format)) {
|
|
25
27
|
throw new Error(`${format} is not a supported format`);
|
|
26
28
|
}
|
|
29
|
+
if (!BACKENDS.includes(backend)) {
|
|
30
|
+
throw new Error(`${backend} is not a supported backend`);
|
|
31
|
+
}
|
|
32
|
+
if (backend === "ps" && format === "svg") {
|
|
33
|
+
throw new Error('The "ps" backend can\'t render SVG; use format "png" or backend "cairo"');
|
|
34
|
+
}
|
|
27
35
|
const dir = await mkdtemp(join(tmpdir(), "astro-lilypond-"));
|
|
28
36
|
const inputPath = join(dir, safeInputFileName(sourceName));
|
|
29
37
|
const outputBase = join(dir, "output");
|
|
@@ -32,6 +40,7 @@ export async function render(source, options) {
|
|
|
32
40
|
await execLilyPond({
|
|
33
41
|
binaryPath,
|
|
34
42
|
format,
|
|
43
|
+
backend,
|
|
35
44
|
crop,
|
|
36
45
|
resolution,
|
|
37
46
|
includePaths,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { LilypondPage } from "../index.js";
|
|
2
|
-
import type { Format } from "../render.js";
|
|
2
|
+
import type { Backend, Format } from "../render.js";
|
|
3
3
|
export interface EmitLilypondAssetOptions {
|
|
4
4
|
title: string;
|
|
5
5
|
format: Format;
|
|
6
|
+
backend: Backend;
|
|
6
7
|
source: string;
|
|
7
8
|
resolution: number;
|
|
8
9
|
crop: boolean;
|
|
@@ -4,8 +4,8 @@ export async function emitLilypondAsset(options) {
|
|
|
4
4
|
if (!options.binaryPath) {
|
|
5
5
|
throw new Error("astro-lilypond: please add the `lilypond()` integration to your Astro config.");
|
|
6
6
|
}
|
|
7
|
-
const { title, format, source, resolution, crop, sizeScale, render } = options;
|
|
8
|
-
const assets = await emitAsset(`${title}.[hash].${format}`, [source, format, resolution, crop, sizeScale], async () => {
|
|
7
|
+
const { title, format, backend, source, resolution, crop, sizeScale, render, } = options;
|
|
8
|
+
const assets = await emitAsset(`${title}.[hash].${format}`, [source, format, backend, resolution, crop, sizeScale], async () => {
|
|
9
9
|
const buffers = await render();
|
|
10
10
|
return buffers.map((data) => {
|
|
11
11
|
const dimensions = imageDimensionsFor(format, data);
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { LilypondPdfResult } from "../index.js";
|
|
2
|
+
import type { Backend } from "../render.js";
|
|
2
3
|
export interface EmitLilypondPdfAssetOptions {
|
|
3
4
|
title: string;
|
|
4
5
|
source: string;
|
|
6
|
+
backend: Backend;
|
|
5
7
|
binaryPath: string | undefined;
|
|
6
8
|
render: () => Promise<Buffer[]>;
|
|
7
9
|
}
|
|
@@ -3,8 +3,8 @@ export async function emitLilypondPdfAsset(options) {
|
|
|
3
3
|
if (!options.binaryPath) {
|
|
4
4
|
throw new Error("astro-lilypond: please add the `lilypond()` integration to your Astro config.");
|
|
5
5
|
}
|
|
6
|
-
const { title, source, render } = options;
|
|
7
|
-
const asset = await emitAsset(`${title}.[hash].pdf`, [source, "pdf"], async () => {
|
|
6
|
+
const { title, source, backend, render } = options;
|
|
7
|
+
const asset = await emitAsset(`${title}.[hash].pdf`, [source, "pdf", backend], async () => {
|
|
8
8
|
const [data] = await render();
|
|
9
9
|
return { data };
|
|
10
10
|
});
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { defaultOptions } from "../render.js";
|
|
2
2
|
/** Fills in any `defaults` fields left unset with `render.ts`'s own defaults. */
|
|
3
3
|
export function resolveDefaults(defaults) {
|
|
4
|
-
const { version, format, resolution, cropScale } = defaultOptions.defaults;
|
|
4
|
+
const { version, format, backend, resolution, cropScale } = defaultOptions.defaults;
|
|
5
5
|
return {
|
|
6
6
|
version: defaults?.version ?? version,
|
|
7
7
|
format: defaults?.format ?? format,
|
|
8
|
+
backend: defaults?.backend ?? backend,
|
|
8
9
|
resolution: defaults?.resolution ?? resolution,
|
|
9
10
|
cropScale: defaults?.cropScale ?? cropScale,
|
|
10
11
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro-lilypond",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "An Astro integration for rendering Lilypond markup to music notation.",
|
|
5
5
|
"homepage": "https://lilypond.ky.fyi",
|
|
6
6
|
"author": "Ky Decker",
|
|
@@ -60,16 +60,16 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@astrojs/markdown-remark": "^7.3.1",
|
|
63
|
-
"@astrojs/markdown-satteri": "^0.4.
|
|
63
|
+
"@astrojs/markdown-satteri": "^0.4.2",
|
|
64
64
|
"@types/mdast": "^4.0.4",
|
|
65
|
-
"@types/node": "^26.
|
|
66
|
-
"@vitest/coverage-v8": "^
|
|
67
|
-
"astro": "^7.3.
|
|
65
|
+
"@types/node": "^26.6.3",
|
|
66
|
+
"@vitest/coverage-v8": "^5.0.2",
|
|
67
|
+
"astro": "^7.3.5",
|
|
68
68
|
"satteri": "^0.10.5",
|
|
69
69
|
"typescript": "^7.0.2",
|
|
70
70
|
"unified": "^11.0.5",
|
|
71
|
-
"vite": "^8.
|
|
72
|
-
"vitest": "^
|
|
71
|
+
"vite": "^8.3.1",
|
|
72
|
+
"vitest": "^5.0.2"
|
|
73
73
|
},
|
|
74
74
|
"scripts": {
|
|
75
75
|
"build": "tsc --project tsconfig.build.json",
|