This records the design of version 0.1.0, what the full version would add and who would use it.
Intl.Locale canonicalizes by CLDR rather than by
RFC 5646. On the JVM, wrapping the JDK would bring in its copy of the
registry, e.g. he in a priority list with iw. So the library has one
implementation, which the JVM tests compare with the JDK. The docstring
of test/dk/simongray/langtag/jdk_test.clj lists where the JDK differs.{:grandfathered "zh-min-nan"},
since its subtags don't mean what their shape says (section 2.2.8).{"u" ["co" "phonebk"]}, since a digit
singleton would make the awkward keyword :1.(or (lookup ...) "en") is short enough.clojure.core/filter would. The JDK returns each tag
once instead, which would merge documents that share a tag.sort-by does, so that
DanNet can pick a label by its language and get the label back. An item
whose tag is nil, e.g. a label without a language, matches nothing.These need the IANA Language Subtag Registry:
The code marks each place where an algorithm stops short of these with a TODO, e.g. lookup, which doesn't treat iw and he as the same language. Matching with canonical ranges has a rule of its own: RFC 4647, section 3.2, says to match both the canonical and the original range, or to canonicalize the tags too.
How the full version would ship the registry. As whatwg-url does with its Unicode tables:
clojure -X:registry) writes
resources/dk/simongray/langtag/registry.txt, with a line per record and
only the fields that the algorithms use: type, subtag, Preferred-Value,
Suppress-Script, Macrolanguage and Prefix. That comes to about a tenth
of the registry's 732 KB, close to the size of whatwg-url's idna.txt.table-text macro like whatwg-url's reads the table as a resource on
the JVM and inlines it as a string literal in ClojureScript. A delay
parses it on first use, so the functions that don't need it never load
it.DanNet. Its ->language-negotiation-ic in
src/main/dk/cst/dannet/web/resources.clj uses Pedestal's media-type
negotiation, which compares whole tags. So an Accept-Language of only
da-DK, only en-GB or DA matches neither da nor en. Lookup finds da, en
and da. The negotiation branch would become:
(if-let [language (some-> (get-in ctx [:request :headers "accept-language"])
(langtag/lookup supported-languages))]
(assoc-in ctx [:request :accept-language] {:field language :type language})
ctx)
This keeps the map that the cookie branch sets, so request->languages
in response.clj reads :type as before. The TODO on select-label in
web/i18n.cljc (to compare with BCP 47) could become
(first (langtag/basic-filter languages lang labels)), which also accepts
a label in en-GB for en. A nil in its languages stands for a label without
one, which no range matches, so select-label would keep its own fallback
for those.
podcast-clj. Its validator checks a language by its shape
(language-tag? in src/dk/simongray/podcast/feed/validate.cljc), so it
accepts en-US-US and en-a. With langtag/well-formed? it would refuse
both, and langtag/error could give the reason in the diagnostic. Apple's
two or three letters would stay a check of their own, on the :language of
the parsed tag. The entry "Language, email and media-type values aren't
validated" in doc/needs-2026.md looks out of date, since validate.cljc
now checks all three.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |