format
Formatting and printing string utilities.
Features
- No parsing
- No runtime error
- Type safety
- Single responsibility
- Minimum
Why
The purpose of this project is to provide minimum replacement formatting function.
Existing formatting solutions offer multiple features.
The Deno community already has std/fmt::sprintf. There are also various other 3rd party libraries.
These could accomplish a lot of work. On the other hand, they are somewhat over-specified. You have to pay more cost than you need to. (cost here refers to code size and execution speed).
We decompose formatting into replacement and serialization. Then, focus on replacement.
Usage
Type inference works well for template literal.
import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
assertEquals(format("{0} {name}!", { 0: "Hello", name: "Tom" }), "Hello Tom!");
//@ts-expect-error it should provide args.0 and args.name
format("{0} {name}!", {});
If the specifier is numeric only, you can specify an array as an argument.
import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
assertEquals(format("{0} world!", ["Hello"]), "Hello world!");
//@ts-expect-error it should provide args.0
format("{0} world!", []);
Placeholder
Placeholder is a pair of prefix and suffix.
Name | Default |
---|---|
prefix | { |
suffix | } |
This can be changed.
Template literal style:
import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
const result = format("should be <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>e</mi><mi>x</mi><mi>p</mi><mi>e</mi><mi>c</mi><mi>t</mi><mi>e</mi><mi>d</mi></mrow><mo separator="true">,</mo><mi>a</mi><mi>c</mi><mi>t</mi><mi>u</mi><mi>a</mi><mi>l</mi></mrow><annotation encoding="application/x-tex">{expected}, actual </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">p</span><span class="mord mathnormal">ec</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal">u</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>{actual}", {
expected: "string",
actual: "number",
}, { placeholders: [{ prefix: "${", suffix: "}" }] });
assertEquals(result, "should be string, actual number");
//@ts-expect-error it should be error
format("should be <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>e</mi><mi>x</mi><mi>p</mi><mi>e</mi><mi>c</mi><mi>t</mi><mi>e</mi><mi>d</mi></mrow><mo separator="true">,</mo><mi>a</mi><mi>c</mi><mi>t</mi><mi>u</mi><mi>a</mi><mi>l</mi></mrow><annotation encoding="application/x-tex">{expected}, actual </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">p</span><span class="mord mathnormal">ec</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal">u</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>{actual}", {}, {
placeholders: [{ prefix: "${", suffix: "}" }],
});
Percent style:
import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
const result = format("Hello %s!!!", { "": "world" }, {
placeholders: [{ prefix: "%", suffix: "s" }],
});
assertEquals(result, "Hello world!!!");
Multiple placeholders:
import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
const result = format("[0] {name}: {title}", {
0: new Date("2038/1/1"),
name: "",
title: "",
}, {
placeholders: [
{ prefix: "{", suffix: "}" },
{ prefix: "[", suffix: "]" },
],
});
assertEquals(result, "abcde{fg}ijk]a}");
The computational complexity of placeholder is O(n) compared to argument. It is recommended to reduce the number of placeholders as much as possible.
Custom serialization
Argument serialization uses the String
constructor by default.
To change this, specify the stringify
option.
import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
const result = format("{0}{1}{2}", ["1", 1, true], {
stringify: (arg) => {
if (typeof arg === "string") return `"${arg}"`;
return String(arg);
},
});
assertEquals(result, `"1"1true`);
Override type inference
In certain circumstances, template literal types cannot be provided. In such cases, generics can be specified.
import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
declare const string: string;
//@ts-expect-error it should provide args.name and args.title
format<"name" | "title">(string, {});
API
See deno doc for all APIs.
License
Copyright © 2023-present Tomoki Miyauci.
Released under the MIT license