Work with IANA language tags based on BCP 47 standards for validation, parsing, and manipulation of language tags and subtags
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Advanced search functionality for finding tags and subtags by description, plus utilities for working with macrolanguages and specific subtag types.
Search for tags and subtags by description with support for regular expressions and case-insensitive matching.
/**
* Search for tags and subtags by description
* @param {string|RegExp} query - Search query string or regular expression
* @param {boolean} [all=false] - Include grandfathered/redundant tags in results
* @returns {(Tag|Subtag)[]} Array of matching Tag and Subtag objects
*/
function search(query: string | RegExp, all?: boolean): (Tag | Subtag)[];Usage Examples:
import { search } from "language-tags";
// Simple string search (case-insensitive)
const frenchResults = search("french");
frenchResults.forEach(result => {
if (result instanceof Tag) {
console.log(`Tag: ${result.format()} - ${result.descriptions()[0]}`);
} else {
console.log(`Subtag: ${result.format()} (${result.type()}) - ${result.descriptions()[0]}`);
}
});
// Regular expression search
const englishVariants = search(/^English/);
console.log(`Found ${englishVariants.length} results starting with "English"`);
// Case-sensitive search (when query contains uppercase)
const specificResults = search("United States");
console.log(specificResults[0].subtag); // "us"
// Search with all results including grandfathered tags
const allResults = search("chinese", true);
console.log(`Total results: ${allResults.length}`);Work with macrolanguages and their constituent individual languages.
/**
* Get all individual languages for a given macrolanguage subtag
* @param {string} macrolanguage - The macrolanguage subtag code
* @returns {Subtag[]} Array of individual language Subtag objects
* @throws {Error} If the provided code is not a macrolanguage
*/
function languages(macrolanguage: string): Subtag[];Usage Examples:
import { languages } from "language-tags";
// Get all Chinese language variants
try {
const chineseLanguages = languages("zh");
console.log(`Chinese has ${chineseLanguages.length} individual languages:`);
chineseLanguages.forEach(lang => {
console.log(`- ${lang.format()}: ${lang.descriptions()[0]}`);
});
// Output includes: cmn (Mandarin Chinese), yue (Yue Chinese), etc.
} catch (error) {
console.log("Not a macrolanguage");
}
// Check Arabic variants
const arabicLanguages = languages("ar");
arabicLanguages.forEach(lang => {
console.log(`${lang.format()}: ${lang.descriptions().join(", ")}`);
});Convenience functions for looking up specific types of subtags.
/**
* Get a language-type subtag by code
* @param {string} subtag - The subtag code to look up
* @returns {Subtag|null} Language Subtag object or null if not found
*/
function language(subtag: string): Subtag | null;
/**
* Get a region-type subtag by code
* @param {string} subtag - The subtag code to look up
* @returns {Subtag|null} Region Subtag object or null if not found
*/
function region(subtag: string): Subtag | null;
/**
* Get a subtag by specific type
* @param {string} subtag - The subtag code to look up
* @param {string} type - The specific type to retrieve
* @returns {Subtag|null} Subtag object of specified type or null if not found
*/
function type(subtag: string, type: string): Subtag | null;
/**
* Get the registry file date
* @returns {string} Date string when the IANA registry was last updated (YYYY-MM-DD format)
*/
function date(): string;Usage Examples:
import { language, region, type } from "language-tags";
// Look up specific language
const english = language("en");
if (english) {
console.log(english.descriptions()); // ["English"]
console.log(english.scope()); // null (not a macrolanguage)
}
// Look up specific region
const unitedStates = region("US");
if (unitedStates) {
console.log(`${unitedStates.format()}: ${unitedStates.descriptions().join(", ")}`); // "US: United States"
}
// Look up by specific type
const hanScript = type("Hans", "script");
if (hanScript) {
console.log(`${hanScript.format()}: ${hanScript.descriptions().join(", ")}`); // "Hans: Han (Simplified variant)"
}
// Handle not found cases
const nonexistent = language("xyz");
if (!nonexistent) {
console.log("Language code 'xyz' not found");
}
// Get registry information
const registryDate = date();
console.log(`Registry last updated: ${registryDate}`); // "Registry last updated: 2023-12-11"
// Look up different types for the same code
const zhLanguage = type("zh", "language");
const zhMacro = type("zh", "macrolanguage");
console.log(`zh as language: ${zhLanguage?.descriptions()[0]}`);
console.log(`zh as macrolanguage: ${zhMacro?.descriptions()[0]}`);import { search, languages } from "language-tags";
function findSimilarLanguages(query) {
// Search by description
const results = search(query);
// Filter for language subtags only
const languageResults = results.filter(result =>
result.type && result.type() === "language"
);
// Also check if query is a macrolanguage
try {
const variants = languages(query.toLowerCase());
return {
similar: languageResults,
variants: variants
};
} catch {
return {
similar: languageResults,
variants: []
};
}
}
const chineseInfo = findSimilarLanguages("Chinese");
console.log(`Similar languages: ${chineseInfo.similar.length}`);
console.log(`Chinese variants: ${chineseInfo.variants.length}`);import { search } from "language-tags";
function findRegionsForLanguage(languageName) {
// Search for the language name
const results = search(languageName);
// Find regions mentioned in descriptions
const regions = [];
results.forEach(result => {
if (result.type && result.type() === "region") {
const descriptions = result.descriptions();
if (descriptions.some(desc =>
desc.toLowerCase().includes(languageName.toLowerCase())
)) {
regions.push(result);
}
}
});
return regions;
}
const spanishRegions = findRegionsForLanguage("spanish");
spanishRegions.forEach(region => {
console.log(`${region.subtag}: ${region.descriptions()[0]}`);
});import { search, language, region, type } from "language-tags";
function validateAndDescribe(lang, script, reg) {
const results = {};
// Validate language
const langSubtag = language(lang);
if (langSubtag) {
results.language = {
code: lang,
name: langSubtag.descriptions()[0],
valid: true
};
} else {
// Try searching for similar
const similar = search(lang).filter(r => r.type && r.type() === "language");
results.language = {
code: lang,
valid: false,
suggestions: similar.slice(0, 3).map(s => ({
code: s.subtag,
name: s.descriptions()[0]
}))
};
}
// Validate script if provided
if (script) {
const scriptSubtag = type(script, "script");
if (scriptSubtag) {
results.script = {
code: script,
name: scriptSubtag.descriptions()[0],
valid: true
};
} else {
const similar = search(script).filter(r => r.type && r.type() === "script");
results.script = {
code: script,
valid: false,
suggestions: similar.slice(0, 3).map(s => ({
code: s.subtag,
name: s.descriptions()[0]
}))
};
}
}
// Validate region if provided
if (reg) {
const regionSubtag = region(reg);
if (regionSubtag) {
results.region = {
code: reg,
name: regionSubtag.descriptions()[0],
valid: true
};
} else {
const similar = search(reg).filter(r => r.type && r.type() === "region");
results.region = {
code: reg,
valid: false,
suggestions: similar.slice(0, 3).map(s => ({
code: s.subtag,
name: s.descriptions()[0]
}))
};
}
}
return results;
}
// Example usage
const validation = validateAndDescribe("en", "Latn", "US");
console.log(JSON.stringify(validation, null, 2));Search results can be either Tag or Subtag objects. You can distinguish between them:
import { search } from "language-tags";
import Tag from "language-tags/lib/Tag.js";
import Subtag from "language-tags/lib/Subtag.js";
const results = search("english");
results.forEach(result => {
if (result instanceof Tag) {
console.log(`Complete tag: ${result.format()}`);
console.log(`Type: ${result.type()}`);
console.log(`Valid: ${result.valid()}`);
} else if (result instanceof Subtag) {
console.log(`Subtag: ${result.subtag}`);
console.log(`Type: ${result.type()}`);
console.log(`Descriptions: ${result.descriptions().join(", ")}`);
}
// Alternative approach using duck typing
if (result.type && typeof result.type === 'function') {
// It's a Subtag (has type() method)
console.log(`Subtag result: ${result.format()}`);
} else {
// It's a Tag (has format() but no type() method in same way)
console.log(`Tag result: ${result.format()}`);
}
});language, region, type) when you know the expected subtag type for better performance