UNPKG

@anireact/d

Version:

Dedent templates, autoindent interpolations, and more.

213 lines 6.15 kB
/** * Just an identity function. Can be reused to save few bytes of your bundle, huh. */ export declare const id: <t extends unknown>(x: t) => t; /** * Template tag args type check. Does its best to detect actual template-tag * calls and to filter out other similar signatures: * * - The {@linkcode args} array must be non-empty. * - The head `args[0]`: * - Must be `Array.isArray`. * - Must be frozen. * - Must have own `raw` prop with non-enumerable `value` descriptor. * - The raws `args[0].raw`: * - Must be `Array.isArray`. * - Must be frozen. * - Must have the same length as head. * - The tail `args.slice(1)`: * - Must be one item shorter than head. * * ```typescript * function f(...args: BDD.Args<any> | [x: string[]]) { * if (isTemplate(args)) { * // Called as a tag * } else { * let [x] = args; * // Called as a regular function * } * } * ``` */ export declare const isTemplate: <t extends d.Args<any>>(args: any[]) => args is t; /** * The dedent tag you want: * * - Raw mode. * - If the first line is blank, it’s trimmed. * - If the last line is blank, it’s trimmed. * - Other lines are dedented by the least common indent. * - Blank lines don’t affect the dedent width. * - Non-blank first line doesn’t affect the dedent width and isn’t dedented. * - Tab interpreted as a _single_ space. * - Interpolation values are converted to strings. * - If the interpolation value is multiline, the lines are autoindented to * match the indent of the line the interpolation is placed at. Blank lines of * interpolation are not autoindented. * - Completebly blank templates with no interpolations are kept untouched. * * _See README or tests for additional examples._ */ export declare function d(...args: d.Args<any>): string; /** * Custom dedent tag constructor. * * _See the types {@linkcode d.Tag|Tag} and {@linkcode d.Params|Params}._ * * ```typescript * // Similar to `d`, but uses cooked literals: * d({ * raw: false, * impl: d, * }); * * // Similar to `d`, but doesn’t autoindent interpolations: * d({ * impl: v => v.map(d.stringify).join(''), * }); * * // Similar to `d`, but doesn’t concatenate substrings: * d({ * impl: v => v.map(d), * }); * * // Similar to `d.tokenize`, but stringifies tokens: * d({ * impl: v => v.map(d.stringify), * }); * ``` * * @param params Tag constructor params. * @returns Constructed dedent tag. */ export declare function d<q, z>(params: d.Params<q, z>): d.Tag<q, z>; /** * The default {@linkcode d} tag {@linkcode d.Params.impl|impl} function: * * 1. Stringifies tokens and autoindents interpolations. * 2. Then concatentates everything into a single string. */ export declare function d(v: d.Token<any>[]): string; /** * Converts {@linkcode d.Token|Token} to string, autoindents interpolations: * * ```typescript * let arr = [ * { lit: true, value: 'lit-1' }, * { lit: false, value: 'line-1\nline-2', pad: ' ' }, * { lit: true, value: 'lit-2' }, * ]; * * deepEqual(arr.map(d), [ * 'lit-1', * 'line-1\n line-2', * 'lit-2', * ]); * ``` * * @param t A token to autoindent. * @returns Stringified and autoindented token value. */ export declare function d(t: d.Token<any>): string; export declare namespace d { /** * Template tag args array type. * * @template q Quasi type. */ type Args<q> = [head: TemplateStringsArray, ...tail: q[]]; /** * Template tag type. * * @template q Quasi type. * @template z Result type. */ type Tag<q, z> = (...args: Args<q>) => z; /** * Better Dedent token type, either literal {@linkcode Lit} or interpolation * {@linkcode Quasi}. */ type Token<q> = Lit | Quasi<q>; /** * Literal token. */ interface Lit { /** Type tag. */ readonly lit: true; /** Literal value. */ value: string; } /** * Quasi token. * * @template q Quasi type. */ interface Quasi<q> { /** Type tag. */ readonly lit: false; /** Quasi value. */ value: q; /** Autoindent prefix. */ pad: string; } /** * Custom Better Dedent tag {@link d|constructor} params. * * @template q Quasi type. * @template z Result type. */ interface Params<q, z> { /** Raw mode flag; defaults to `true`. */ raw?: boolean | undefined; /** Tag implementation function. */ impl(v: Token<q>[]): z; } /** * Converts {@linkcode Token} value using `String()`. * * ```typescript * d.stringify({ * lit: true, * value: 'Literal', * }) === 'Literal'; * * d.stringify({ * lit: false, * value: 2434, * pad: '', * }) === '2434'; * * d.stringify({ * lit: false, * value: { * toString: () => 'x.toString', * }, * pad: '', * }) === 'x.toString'; * * d.stringify({ * lit: false, * value: { * [Symbol.toPrimitive]: () => 'x[Symbol.toPrimitive]', * }, * pad: '', * }) === 'x[Symbol.toPrimitive]'; * ``` */ const stringify: (t: d.Token<any>) => string; /** * Similar to the {@linkcode d} tag, but returns an array of * {@linkcode Token} objects, with no autoindent applied to interpolation * tokens: * * ```typescript * deepEqual( * d.tokenize`¶ * ␣␣␣␣␣␣␣␣Literal¶ * ␣␣␣␣␣␣␣␣␣␣␣␣${'Interpolation'}¶ * ␣␣␣␣␣␣␣␣Another literal¶ * ␣␣␣␣`, * [ * { lit: true, value: 'Literal\n ' }, * { lit: false, value: 'Interpolation', pad: ' ' }, * { lit: true, value: '\nAnother literal' }, * ], * ); * ``` */ const tokenize: <q extends unknown>(head: TemplateStringsArray, ...tail: q[]) => Token<q>[]; } //# sourceMappingURL=dedent.d.mts.map