浏览代码

LibUnicode: Add a method to combine locale subtags into a display string

This is just a convenience wrapper around the underlying generated APIs.
Timothy Flynn 3 年之前
父节点
当前提交
b0671ceb74
共有 2 个文件被更改,包括 35 次插入0 次删除
  1. 34 0
      Userland/Libraries/LibUnicode/Locale.cpp
  2. 1 0
      Userland/Libraries/LibUnicode/Locale.h

+ 34 - 0
Userland/Libraries/LibUnicode/Locale.cpp

@@ -765,6 +765,40 @@ Optional<StringView> __attribute__((weak)) get_locale_short_date_field_mapping(S
 Optional<StringView> __attribute__((weak)) get_locale_narrow_date_field_mapping(StringView, StringView) { return {}; }
 Optional<StringView> __attribute__((weak)) get_locale_narrow_date_field_mapping(StringView, StringView) { return {}; }
 Optional<StringView> __attribute__((weak)) get_locale_key_mapping(StringView, StringView) { return {}; }
 Optional<StringView> __attribute__((weak)) get_locale_key_mapping(StringView, StringView) { return {}; }
 
 
+// https://www.unicode.org/reports/tr35/tr35-39/tr35-general.html#Display_Name_Elements
+Optional<String> format_locale_for_display(StringView locale, LocaleID locale_id)
+{
+    auto language_id = move(locale_id.language_id);
+    VERIFY(language_id.language.has_value());
+
+    auto patterns = Unicode::get_locale_display_patterns(locale);
+    if (!patterns.has_value())
+        return {};
+
+    auto primary_tag = get_locale_language_mapping(locale, *language_id.language).value_or(*language_id.language);
+    Optional<StringView> script;
+    Optional<StringView> region;
+
+    if (language_id.script.has_value())
+        script = get_locale_script_mapping(locale, *language_id.script).value_or(*language_id.script);
+    if (language_id.region.has_value())
+        region = get_locale_territory_mapping(locale, *language_id.region).value_or(*language_id.region);
+
+    Optional<String> secondary_tag;
+
+    if (script.has_value() && region.has_value())
+        secondary_tag = patterns->locale_separator.replace("{0}"sv, *script).replace("{1}"sv, *region);
+    else if (script.has_value())
+        secondary_tag = *script;
+    else if (region.has_value())
+        secondary_tag = *region;
+
+    if (!secondary_tag.has_value())
+        return primary_tag;
+
+    return patterns->locale_pattern.replace("{0}"sv, primary_tag).replace("{1}"sv, *secondary_tag);
+}
+
 Vector<StringView> get_locale_key_mapping_list(StringView locale, StringView keyword)
 Vector<StringView> get_locale_key_mapping_list(StringView locale, StringView keyword)
 {
 {
     if (keyword == "hc"sv) {
     if (keyword == "hc"sv) {

+ 1 - 0
Userland/Libraries/LibUnicode/Locale.h

@@ -158,6 +158,7 @@ Optional<ListPatternType> list_pattern_type_from_string(StringView list_pattern_
 Optional<ListPatternStyle> list_pattern_style_from_string(StringView list_pattern_style);
 Optional<ListPatternStyle> list_pattern_style_from_string(StringView list_pattern_style);
 
 
 Optional<DisplayPattern> get_locale_display_patterns(StringView locale);
 Optional<DisplayPattern> get_locale_display_patterns(StringView locale);
+Optional<String> format_locale_for_display(StringView locale, LocaleID locale_id);
 
 
 Optional<StringView> get_locale_language_mapping(StringView locale, StringView language);
 Optional<StringView> get_locale_language_mapping(StringView locale, StringView language);
 Optional<StringView> get_locale_territory_mapping(StringView locale, StringView territory);
 Optional<StringView> get_locale_territory_mapping(StringView locale, StringView territory);