Skip to Content
GuidesLiterals & Adjacency

Literals & Adjacency

Text you meant as literal stays literal, and two adjacent tokens never silently merge into a different token when the output is read back. rosetta-date calls this guarantee round-trip safety at the token boundary.

Literals

Literal (verbatim) text is preserved across dialects, though each syntax family marks it differently:

  • Delimited dialects (e.g. moment [...], ldml '...') wrap literal text in delimiters. Only the letter-bearing span is escaped, so separators stay clean (DD/MMdd/MM, not dd'/'MM); a literal apostrophe is '' in ldml ('o''clock'o'clock), and a literal ] — which has no in-band escape inside a moment [...] run — is emitted between bracketed spans (a]b[a]][b]).
  • Directive dialects (e.g. strftime) treat all non-directive text as literal verbatim — no wrapping needed — and escape only the marker by doubling it (%%%).

Adjacent tokens

When a conversion would place two tokens that collide — i.e. reading the output back would lex them as one different token — rosetta-date separates them with the target dialect’s empty literal.

For example, date-fns PPPp (a long date next to a short time) becomes moment LL + LT. But gluing them as LLLT would re-read as LLL (the long localized date preset) + T, a different parse. So the converter inserts []:

import { convert } from 'rosetta-date' import { dateFns, momentjs } from 'rosetta-date/libraries' convert('PPPp', { from: dateFns, to: momentjs }) // 'LL[]LT' — '[]' keeps LL and LT apart

When a dialect has no empty literal

A quote-style dialect like ldml has no empty literal — '' is a literal apostrophe, not nothing — so it cannot express such an adjacency. There the second token is routed through onUnsupportedToken with reason unrepresentable-adjacency:

  • the default literalizes it, escaping it so it can never re-merge into a different token, while
  • 'throw' lets a mass migration catch it.

This is why adjacency is one of the four unsupported-token reasons rather than a silent fix-up: in a quote-style target the merge is genuinely unrepresentable, and you may want to know.

Last updated on