UNPKG

astro-d2

Version:

Astro integration and remark plugin to transform D2 Markdown code blocks into diagrams.

110 lines (98 loc) 3.39 kB
import { z } from 'astro/zod' export const AttributesSchema = z .object({ /** * When specified, the diagram will package multiple boards as 1 SVG which transitions through each board at the * specified interval (in milliseconds). */ animateInterval: z.string().optional(), /** * Overrides the global `appendix` configuration for the diagram. */ appendix: z .union([z.literal('true'), z.literal('false')]) .optional() .transform((value) => value === 'true'), /** * The dark theme to use for the diagram when the user's system preference is set to dark mode. * * To disable the dark theme, set this attribute to `'false'`. * * @see https://d2lang.com/tour/themes */ darkTheme: z .string() .optional() .transform((value) => (value === 'false' ? false : value)), /** * Overrides the global `inline` configuration for the diagram. */ inline: z .union([z.literal('true'), z.literal('false')]) .optional() .transform((value) => (value === undefined ? undefined : value === 'true')), /** * Overrides the global `layout` configuration for the diagram. */ layout: z.union([z.literal('dagre'), z.literal('elk'), z.literal('tala')]).optional(), /** * Overrides the global `pad` configuration for the diagram. */ pad: z.coerce.number().optional(), /** * Overrides the global `sketch` configuration for the diagram. */ sketch: z .union([z.literal('true'), z.literal('false')]) .optional() .transform((value) => (value === 'false' ? false : value)), /** * Defines the target board to render when using composition. * Use `root` to target the root board. * * @see https://d2lang.com/tour/composition */ target: z .string() .optional() .transform((value) => (value === 'root' ? '' : value)), /** * The title of the diagram that will be used as the `alt` attribute of the generated image. * * @default 'Diagram' */ title: z.string().default('Diagram'), /** * The default theme to use for the diagram. * * @see https://d2lang.com/tour/themes */ theme: z.string().optional(), /** * The width (in pixels) of the diagram. */ width: z.coerce.number().optional(), }) .default({}) const attributeRegex = /(?<key>[^\s"'=]+)=(?:(?<noQuoteValue>\w+)|'(?<singleQuoteValue>[^']+)'|"(?<doubleQuoteValue>[^"]+))|(?<truthyKey>\w+)/g export function getAttributes(attributesStr: string | null | undefined) { return AttributesSchema.parse(parseAttributes(attributesStr)) } function parseAttributes(attributesStr: string | null | undefined) { if (!attributesStr) { return {} } const matches = attributesStr.matchAll(attributeRegex) const attributes: Record<string, string> = {} for (const match of matches) { const { key, noQuoteValue, singleQuoteValue, doubleQuoteValue, truthyKey } = match.groups ?? {} const attributeKey = truthyKey ?? key const attributeValue = truthyKey ? 'true' : (noQuoteValue ?? singleQuoteValue ?? doubleQuoteValue) if (attributeKey && attributeValue) { attributes[attributeKey] = attributeValue } } return attributes } export type DiagramAttributes = z.infer<typeof AttributesSchema>