@@ -24,6 +24,10 @@ TypeScript support.
2424- Includes pluralization support (plugins can be optionally added for more
2525 features)
2626- Easy to integrate with existing projects
27+ - Inline ` /* ... */ ` comments let you differentiate identical source strings
28+ without affecting the fallback text
29+ - Bundled Korean tagged template adds automatic particle selection when ` locale `
30+ is set to ` ko `
2731
2832## Installation
2933
@@ -49,6 +53,36 @@ const text = formatter.format("Hello World");
4953console .log (text ); // Output: Hello World
5054```
5155
56+ You can pass values in the second argument and interpolate them inside the
57+ template. When no translation is registered, the original text is used as the
58+ fallback.
59+
60+ ``` typescript
61+ const formatter = new Formatter ({ locale: " en" });
62+
63+ formatter .format (" Hello, {name}!" , { name: " Kelly" });
64+ // → "Hello, Kelly!"
65+ ```
66+
67+ ### Supplying Localized Messages
68+
69+ Provide a message catalog to translate strings. The ` Formatter ` generics keep
70+ the message keys type-safe.
71+
72+ ``` typescript
73+ const messages = {
74+ " Hello, {name}!" : " 안녕하세요, {name}!" ,
75+ };
76+
77+ const formatter = new Formatter <typeof messages >({
78+ locale: " ko" ,
79+ messages ,
80+ });
81+
82+ formatter .format (" Hello, {name}!" , { name: " Kelly" });
83+ // → "안녕하세요, Kelly!"
84+ ```
85+
5286### Handling Plurals
5387
5488Intlit provides support for handling plural forms in different languages, making
@@ -127,3 +161,122 @@ console.log(
127161 formatter .format (" You have {count} file{count.other:}s{/}." , { count: 100 }),
128162); // Output: لديك 100 ملفات.
129163```
164+
165+ ### Gender and Conditional Segments
166+
167+ Hooks in Intlit behave like chained methods. The default hooks include helpers
168+ for gendered output and ` else ` fallbacks.
169+
170+ ``` typescript
171+ const formatter = new Formatter ({ locale: " en" });
172+
173+ formatter .format (
174+ " {user} added {photoCount.one:}a new photo{.other:}{_} new photos{/} to {gender.male:}his{.female:}her{.other:}their{/} stream." ,
175+ { user: " Alex" , photoCount: 2 , gender: " female" },
176+ );
177+ // → "Alex added 2 new photos to her stream."
178+ ```
179+
180+ Inside nested segments the current value is available through the special ` _ `
181+ parameter, so you can reuse the original number (as seen above when printing the
182+ plural count).
183+
184+ ### Adding Context with Inline Comments
185+
186+ Inline block comments are stripped from the rendered output but kept in the key.
187+ They are perfect for differentiating identical phrases that need distinct
188+ translations.
189+
190+ ``` typescript
191+ const messages = {
192+ " /* 환영 */안녕하세요." : " Welcome!" ,
193+ " /* 일반 */안녕하세요." : " Hello!" ,
194+ };
195+
196+ const formatter = new Formatter ({
197+ locale: " en" ,
198+ messages ,
199+ });
200+
201+ formatter .format (" /* 환영 */안녕하세요." );
202+ // → "Welcome!"
203+
204+ formatter .format (" /* 일반 */안녕하세요." );
205+ // → "Hello!"
206+
207+ // Because the comments are ignored at runtime the fallback remains clean.
208+ new Formatter ({ locale: " ko" }).format (" /* 환영 */안녕하세요." );
209+ // → "안녕하세요."
210+ ```
211+
212+ ### Integrating a Tagged Template Handler
213+
214+ Need smarter whitespace management or language-specific post-processing? Intlit
215+ ships with a particle-aware template handler that is applied automatically when
216+ ` locale ` is set to ` ko ` .
217+
218+ ``` typescript
219+ const formatter = new Formatter ({ locale: " ko" });
220+
221+ formatter .format (
222+ ` 새 소식이 있습니다:\n {count.one:}새 메시지가 하나 생겼어요{.other:}{_}개의 새 메시지가 있어요{/}
223+ ` ,
224+ { count: 3 },
225+ );
226+ // → "새 소식이 있습니다:\n3개의 새 메시지가 있어요"
227+ ```
228+
229+ For other locales you can still provide your own ` taggedTemplate ` function to
230+ massage the final string (e.g. trim indentation, collapse whitespace, or run
231+ additional transforms).
232+
233+ ### Custom Hooks
234+
235+ Extend Intlit by adding application-specific hooks. A hook receives a
236+ ` HookContext ` object describing the current placeholder and returns the next
237+ value that should flow through the chain.
238+
239+ ``` typescript
240+ import { Formatter , type Hook } from " intlit" ;
241+
242+ const upper: Hook = (ctx ) => String (ctx .current ?? " " ).toUpperCase ();
243+
244+ const fallback: Hook = (ctx ) =>
245+ ctx .current == null || ctx .current === " " ? " (none)" : ctx .current ;
246+
247+ const formatter = new Formatter ({
248+ locale: " en" ,
249+ hooks: { upper , fallback },
250+ });
251+
252+ formatter .format (" Hello, {name.upper.fallback}!" , { name: " alex" });
253+ // → "Hello, ALEX!"
254+ ```
255+
256+ Hooks receive:
257+
258+ - ` ctx.original ` : The value that came directly from ` Formatter#format ` .
259+ - ` ctx.current ` : The value produced so far in the chain. Whatever the hook
260+ returns becomes the new ` ctx.current ` .
261+ - ` ctx.locale ` : Locale that was supplied when constructing the formatter.
262+ - ` args ` : Arguments passed from the template method such as the ` currency ` part
263+ in ` {price.number:currency} ` . Arguments can include nested templates.
264+
265+ To share state across hook invocations, keep data in a
266+ ` WeakMap<HookContext, …> ` . The built-in gender and plural hooks follow this
267+ pattern to remember which branch has already matched.
268+
269+ Combine custom hooks with the built-in plural helpers to cover complex cases
270+ without branching in your code.
271+
272+ ## Formatter Options
273+
274+ ` new Formatter(options) ` accepts the following configuration:
275+
276+ - ` locale ` : Locale passed to plural rules. Defaults to ` en ` .
277+ - ` messages ` : A record of source text → translated text pairs.
278+ - ` hooks ` : Extra hook implementations that augment or replace the defaults.
279+ - ` taggedTemplate ` : Custom renderer for the template literal output.
280+
281+ Instantiate different ` Formatter ` objects per locale, or swap the ` messages `
282+ object dynamically when building multi-locale applications.
0 commit comments