wikidata-label-picker
v0.1.0
Published
Pick the best label from a Wikidata language map with language, script, and wildcard fallback
Maintainers
Readme
wikidata-label-picker
Pick the best label from a Wikidata language map, given an ordered list of fallback steps: exact language codes, Unicode script matches, or a wildcard.
Install
npm install wikidata-label-pickerUsage
import { pickWikidataLabel, Script } from 'wikidata-label-picker';Basic: pick by language code
const labels = { en: 'cat', fr: 'chat', ka: 'კატა' };
pickWikidataLabel(labels, ['en']);
// { lang: 'en', label: 'cat' }
pickWikidataLabel(labels, ['de']);
// undefinedScript fallback
If no exact language match exists, fall back to any label written in a particular Unicode script:
const labels = { en: 'cat', fr: 'chat', ka: 'კატა' };
pickWikidataLabel(labels, ['de', { script: 'Georgian' }]);
// { lang: 'ka', label: 'კატა' }Full fallback chain
Combine language codes, script matches, and the '*' wildcard. Steps are
tried in order; the first match wins.
const labels = { en: 'cat', fr: 'chat', ka: 'კატა' };
pickWikidataLabel(labels, ['de', { script: 'Georgian' }, '*']);
// { lang: 'ka', label: 'კატა' }
// ('de' misses, Georgian matches 'ka', so '*' is never reached)API
pickWikidataLabel(labels, fallbacks)
function pickWikidataLabel(
labels: Readonly<Record<string, string>>,
fallbacks: readonly FallbackStep[],
): LabelMatch | undefined;labels -- A Wikidata-style language map: keys are language codes, values
are label strings.
fallbacks -- An ordered array of steps. Each step is one of:
| Step | Type | Behavior |
|------|------|----------|
| 'en' | string | Exact language-code lookup. |
| { script: 'Latin' } | { script: string } | First label whose text contains at least one character in the given Unicode script. When multiple labels match, tie is broken by language code sorted lexicographically. |
| '*' | string | Any label. Tie broken by language code sorted lexicographically. |
Returns LabelMatch | undefined. If no step matches, returns undefined.
LabelMatch
interface LabelMatch {
lang: string;
label: string;
}FallbackStep
type FallbackStep = string | { script: string };Script matching
Script steps use the Unicode \p{Script=X} property via RegExp with the u
flag. A label matches if it contains at least one character belonging to that
script. For example, { script: 'Georgian' } matches any label containing a
Georgian character.
Script constants
The Script object provides common Unicode script names as typed constants:
import { Script } from 'wikidata-label-picker';
Script.Latin // 'Latin'
Script.Georgian // 'Georgian'
Script.Han // 'Han'
Script.Arabic // 'Arabic'
// ... and othersFull list: Arabic, Armenian, Bengali, Cyrillic, Devanagari, Ethiopic, Georgian, Greek, Gujarati, Han, Hangul, Hebrew, Hiragana, Kannada, Katakana, Khmer, Lao, Latin, Malayalam, Myanmar, Oriya, Sinhala, Tamil, Telugu, Thai, Tibetan.
These are convenience constants, not a closed set. Any valid Unicode script name works as a plain string:
pickWikidataLabel(labels, [{ script: 'Tifinagh' }]);Invalid script names throw a TypeError with a message that includes the bad
script value:
pickWikidataLabel(labels, [{ script: 'NotARealScript' }]);
// throws TypeError: Invalid Unicode script name: "NotARealScript"ScriptName type
type ScriptName = (typeof Script)[keyof typeof Script];Union of the string literal types from the Script object. The script field
in FallbackStep accepts any string, not just ScriptName, so you are not
limited to the predefined constants. Invalid script names throw at runtime.
Tie-breaking
When a script step or '*' matches multiple labels, the one with the
lexicographically smallest language code wins. This makes results deterministic
across calls with the same input.
License
MIT
