diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/test/ExampleGenerator.java b/tools/cldr-code/src/main/java/org/unicode/cldr/test/ExampleGenerator.java
index 913e4884462..16702b605e6 100644
--- a/tools/cldr-code/src/main/java/org/unicode/cldr/test/ExampleGenerator.java
+++ b/tools/cldr-code/src/main/java/org/unicode/cldr/test/ExampleGenerator.java
@@ -445,6 +445,9 @@ private String getExampleHtmlExtended(String xpath, String value, boolean nonTri
/**
* Do the main work of getExampleHtml given that the result was not found in the cache.
*
+ *
Creates a list that the handlers in constructExampleHtmlExtended can add examples to, and
+ * then formats the example list appropriately.
+ *
* @param xpath the path; e.g., "//ldml/dates/timeZoneNames/fallbackFormat"
* @param value the value; e.g., "{1} [{0}]"; not necessarily the winning value
* @param nonTrivial true if we should avoid returning a trivial example (just value wrapped in
@@ -452,7 +455,20 @@ private String getExampleHtmlExtended(String xpath, String value, boolean nonTri
* @return the example HTML, or null
*/
private String constructExampleHtml(String xpath, String value, boolean nonTrivial) {
- String result = null;
+ List examples = new ArrayList<>();
+ constructExampleHtmlExtended(xpath, value, examples);
+ String result = formatExampleList(examples);
+ if (result != null) { // Handle the outcome
+ if (nonTrivial && value.equals(result)) {
+ result = null;
+ } else {
+ result = finalizeBackground(result);
+ }
+ }
+ return result;
+ }
+
+ private void constructExampleHtmlExtended(String xpath, String value, List examples) {
boolean showContexts =
isRTL || BIDI_MARKS.containsSome(value); // only used for certain example types
/*
@@ -461,87 +477,77 @@ private String constructExampleHtml(String xpath, String value, boolean nonTrivi
*/
XPathParts parts = XPathParts.getFrozenInstance(xpath).cloneAsThawed();
if (parts.contains("dateRangePattern")) { // {0} - {1}
- result = handleDateRangePattern(value);
+ handleDateRangePattern(value, examples);
} else if (parts.contains("timeZoneNames")) {
- result = handleTimeZoneName(parts, value);
+ handleTimeZoneName(parts, value, examples);
} else if (parts.contains("localeDisplayNames")) {
- result = handleDisplayNames(xpath, parts, value);
+ handleDisplayNames(xpath, parts, value, examples);
} else if (parts.contains("currency")) {
- result = handleCurrency(xpath, parts, value);
+ handleCurrency(xpath, parts, value, examples);
} else if (parts.contains("dayPeriods")) {
- result = handleDayPeriod(parts, value);
+ handleDayPeriod(parts, value, examples);
} else if (parts.contains("monthContext")) {
- result = handleDateSymbol(parts, value);
+ handleDateSymbol(parts, value, examples);
} else if (parts.contains("pattern") || parts.contains("dateFormatItem")) {
if (parts.contains("calendar")) {
- result = handleDateFormatItem(xpath, value, showContexts);
+ handleDateFormatItem(xpath, value, showContexts, examples);
} else if (parts.contains("miscPatterns")) {
- result = handleMiscPatterns(parts, value);
+ handleMiscPatterns(parts, value, examples);
} else if (parts.contains("numbers")) {
if (parts.contains("currencyFormat")) {
- result = handleCurrencyFormat(parts, value, showContexts);
+ handleCurrencyFormat(parts, value, showContexts, examples);
} else {
- result = handleDecimalFormat(parts, value, showContexts);
+ handleDecimalFormat(parts, value, showContexts, examples);
}
}
} else if (parts.contains("minimumGroupingDigits")) {
- result = handleMinimumGrouping(parts, value);
+ handleMinimumGrouping(parts, value, examples);
} else if (parts.getElement(2).contains("symbols")) {
- result = handleNumberSymbol(parts, value);
+ handleNumberSymbol(parts, value, examples);
} else if (parts.contains("defaultNumberingSystem")
|| parts.contains("otherNumberingSystems")) {
- result = handleNumberingSystem(value);
+ handleNumberingSystem(value, examples);
} else if (parts.contains("currencyFormats") && parts.contains("unitPattern")) {
- result = formatCountValue(xpath, parts, value);
+ formatCountValue(xpath, parts, value, examples);
} else if (parts.getElement(-1).equals("compoundUnitPattern")) {
- result = handleCompoundUnit(parts);
+ handleCompoundUnit(parts, examples);
} else if (parts.getElement(-1).equals("compoundUnitPattern1")
|| parts.getElement(-1).equals("unitPrefixPattern")) {
- result = handleCompoundUnit1(parts, value);
+ handleCompoundUnit1(parts, value, examples);
} else if (parts.getElement(-2).equals("unit")
&& (parts.getElement(-1).equals("unitPattern")
|| parts.getElement(-1).equals("displayName"))) {
- result = handleFormatUnit(parts, value);
+ handleFormatUnit(parts, value, examples);
} else if (parts.getElement(-1).equals("perUnitPattern")) {
- result = handleFormatPerUnit(value);
+ handleFormatPerUnit(value, examples);
} else if (parts.getElement(-2).equals("minimalPairs")) {
- result = handleMinimalPairs(parts, value);
+ handleMinimalPairs(parts, value, examples);
} else if (parts.getElement(-1).equals("durationUnitPattern")) {
- result = handleDurationUnit(value);
+ handleDurationUnit(value, examples);
} else if (parts.contains("intervalFormats")) {
- result = handleIntervalFormats(parts, value);
+ handleIntervalFormats(parts, value, examples);
} else if (parts.getElement(1).equals("delimiters")) {
- result = handleDelimiters(parts, xpath, value);
+ handleDelimiters(parts, xpath, value, examples);
} else if (parts.getElement(1).equals("listPatterns")) {
- result = handleListPatterns(parts, value);
+ handleListPatterns(parts, value, examples);
} else if (parts.getElement(2).equals("ellipsis")) {
- result = handleEllipsis(parts.getAttributeValue(-1, "type"), value);
+ handleEllipsis(parts.getAttributeValue(-1, "type"), value, examples);
} else if (parts.getElement(-1).equals("monthPattern")) {
- result = handleMonthPatterns(parts, value);
+ handleMonthPatterns(parts, value, examples);
} else if (parts.getElement(-1).equals("appendItem")) {
- result = handleAppendItems(parts, value);
+ handleAppendItems(parts, value, examples);
} else if (parts.getElement(-1).equals("annotation")) {
- result = handleAnnotationName(parts, value);
+ handleAnnotationName(parts, value, examples);
} else if (parts.getElement(-1).equals("characterLabel")) {
- result = handleLabel(parts, value);
+ handleLabel(parts, value, examples);
} else if (parts.getElement(-1).equals("characterLabelPattern")) {
- result = handleLabelPattern(parts, value);
+ handleLabelPattern(parts, value, examples);
} else if (parts.getElement(1).equals("personNames")) {
- result = handlePersonName(parts, value);
+ handlePersonName(parts, value, examples);
} else if (parts.getElement(-1).equals("exemplarCharacters")
|| parts.getElement(-1).equals("parseLenient")) {
- result = handleUnicodeSet(parts, xpath, value);
+ handleUnicodeSet(parts, xpath, value, examples);
}
-
- // Handle the outcome
- if (result != null) {
- if (nonTrivial && value.equals(result)) {
- result = null;
- } else {
- result = finalizeBackground(result);
- }
- }
- return result;
}
// Note: may want to change to locale's order; if so, these would be instance fields
@@ -559,13 +565,13 @@ private String constructExampleHtml(String xpath, String value, boolean nonTrivi
* Add examples for UnicodeSets. First, show a hex format of non-spacing marks if there are any,
* then show delta to the winning value if there are any.
*/
- private String handleUnicodeSet(XPathParts parts, String xpath, String value) {
- ArrayList examples = new ArrayList<>();
+ private void handleUnicodeSet(
+ XPathParts parts, String xpath, String value, List examples) {
UnicodeSet valueSet;
try {
valueSet = new UnicodeSet(value);
} catch (Exception e) {
- return null;
+ return;
}
String winningValue = cldrFile.getWinningValue(xpath);
if (!winningValue.equals(value)) {
@@ -601,7 +607,6 @@ private String handleUnicodeSet(XPathParts parts, String xpath, String value) {
}
}
examples.add(setBackground(INTERNAL) + valueSet.toPattern(false)); // internal format
- return formatExampleList(examples);
}
/**
@@ -659,7 +664,7 @@ public String toString() {
private static final Function BACKGROUND_TRANSFORM =
x -> backgroundStartSymbol + x + backgroundEndSymbol;
- private String handlePersonName(XPathParts parts, String value) {
+ private void handlePersonName(XPathParts parts, String value, List examples) {
// ldml/personNames/personName[@order="givenFirst"][@length="long"][@usage="addressing"][@style="formal"]/namePattern => {prefix} {surname}
String debugState = "start";
try {
@@ -670,12 +675,9 @@ private String handlePersonName(XPathParts parts, String value) {
PersonNameFormatter.Usage.from(parts.getAttributeValue(2, "usage")),
PersonNameFormatter.Formality.from(
parts.getAttributeValue(2, "formality")));
-
- List examples = null;
final CLDRFile cldrFile2 = getCldrFile();
switch (parts.getElement(2)) {
case "nameOrderLocales":
- examples = new ArrayList<>();
for (String localeId : PersonNameFormatter.SPLIT_SPACE.split(value)) {
final String name =
localeId.equals("und")
@@ -684,12 +686,7 @@ private String handlePersonName(XPathParts parts, String value) {
examples.add(localeId + " = " + name);
}
break;
- case "initialPattern":
- return null;
- case "sampleName":
- return null;
case "personName":
- examples = new ArrayList<>();
Map sampleNames =
personNamesCache.getSampleNames(cldrFile2);
PersonNameFormatter personNameFormatter =
@@ -741,7 +738,6 @@ private String handlePersonName(XPathParts parts, String value) {
}
break;
}
- return formatExampleList(examples);
} catch (Exception e) {
StringBuffer stackTrace;
try (StringWriter sw = new StringWriter();
@@ -751,7 +747,8 @@ private String handlePersonName(XPathParts parts, String value) {
} catch (Exception e2) {
stackTrace = new StringBuffer("internal error");
}
- return "Internal error: " + e.getMessage() + "\n" + debugState + "\n" + stackTrace;
+ examples.add(
+ "Internal error: " + e.getMessage() + "\n" + debugState + "\n" + stackTrace);
}
}
@@ -826,9 +823,8 @@ private SimpleNameObject getBestAvailable(
return null;
}
- private String handleLabelPattern(XPathParts parts, String value) {
+ private void handleLabelPattern(XPathParts parts, String value, List examples) {
if ("category-list".equals(parts.getAttributeValue(-1, "type"))) {
- List examples = new ArrayList<>();
CLDRFile cfile = getCldrFile();
SimpleFormatter initialPattern = SimpleFormatter.compile(setBackground(value));
String path = CLDRFile.getKey(CLDRFile.TERRITORY_NAME, "FR");
@@ -840,19 +836,16 @@ private String handleLabelPattern(XPathParts parts, String value) {
EmojiConstants.getEmojiFromRegionCodes("FR")
+ " ⇒ "
+ initialPattern.format(flagName, regionName)));
- return formatExampleList(examples);
}
- return null;
}
- private String handleLabel(XPathParts parts, String value) {
+ private void handleLabel(XPathParts parts, String value, List examples) {
// "//ldml/characterLabels/characterLabel[@type=\"" + typeAttributeValue + "\"]"
switch (parts.getAttributeValue(-1, "type")) {
case "flag":
{
String value2 = backgroundStartSymbol + value + backgroundEndSymbol;
CLDRFile cfile = getCldrFile();
- List examples = new ArrayList<>();
SimpleFormatter initialPattern =
SimpleFormatter.compile(
cfile.getStringValue(
@@ -862,12 +855,11 @@ private String handleLabel(XPathParts parts, String value) {
addSubdivisionFlag(value2, "gbeng", initialPattern, examples);
addSubdivisionFlag(value2, "gbsct", initialPattern, examples);
addSubdivisionFlag(value2, "gbwls", initialPattern, examples);
- return formatExampleList(examples);
+ return;
}
case "keycap":
{
String value2 = backgroundStartSymbol + value + backgroundEndSymbol;
- List examples = new ArrayList<>();
CLDRFile cfile = getCldrFile();
SimpleFormatter initialPattern =
SimpleFormatter.compile(
@@ -876,10 +868,10 @@ private String handleLabel(XPathParts parts, String value) {
examples.add(invertBackground(initialPattern.format(value2, "1")));
examples.add(invertBackground(initialPattern.format(value2, "10")));
examples.add(invertBackground(initialPattern.format(value2, "#")));
- return formatExampleList(examples);
+ return;
}
default:
- return null;
+ return;
}
}
@@ -914,17 +906,16 @@ private void addSubdivisionFlag(
+ initialPattern.format(value2, subdivisionName)));
}
- private String handleAnnotationName(XPathParts parts, String value) {
+ private void handleAnnotationName(XPathParts parts, String value, List examples) {
// ldml/annotations/annotation[@cp="🦰"][@type="tts"]
// skip anything but the name
if (!"tts".equals(parts.getAttributeValue(-1, "type"))) {
- return null;
+ return;
}
String cp = parts.getAttributeValue(-1, "cp");
if (cp == null || cp.isEmpty()) {
- return null;
+ return;
}
- Set examples = new LinkedHashSet<>();
int first = cp.codePointAt(0);
switch (first) {
case 0x1F46A: // 👪 U+1F46A FAMILY
@@ -990,7 +981,6 @@ private String handleAnnotationName(XPathParts parts, String value) {
}
break;
}
- return formatExampleList(examples);
}
private String getEmojiName(CLDRFile cfile, String skin) {
@@ -1059,13 +1049,12 @@ private void formatPeople(
initialPattern.format(personName, skinName), hairName)));
}
- private String handleDayPeriod(XPathParts parts, String value) {
+ private void handleDayPeriod(XPathParts parts, String value, List examples) {
// ldml/dates/calendars/calendar[@type="gregorian"]/dayPeriods/dayPeriodContext[@type="format"]/dayPeriodWidth[@type="wide"]/dayPeriod[@type="morning1"]
// ldml/dates/calendars/calendar[@type="gregorian"]/dayPeriods/dayPeriodContext[@type="stand-alone"]/dayPeriodWidth[@type="wide"]/dayPeriod[@type="morning1"]
- List examples = new ArrayList<>();
final String dayPeriodType = parts.getAttributeValue(5, "type");
if (dayPeriodType == null) {
- return null; // formerly happened for some "/alias" paths
+ return; // formerly happened for some "/alias" paths
}
org.unicode.cldr.util.DayPeriodInfo.Type aType =
dayPeriodType.equals("format")
@@ -1075,7 +1064,7 @@ private String handleDayPeriod(XPathParts parts, String value) {
supplementalDataInfo.getDayPeriods(aType, cldrFile.getLocaleID());
String periodString = parts.getAttributeValue(-1, "type");
if (periodString == null) {
- return null; // formerly happened for some "/alias" paths
+ return; // formerly happened for some "/alias" paths
}
DayPeriod dayPeriod = DayPeriod.valueOf(periodString);
String periods = dayPeriodInfo.toString(dayPeriod);
@@ -1093,16 +1082,15 @@ private String handleDayPeriod(XPathParts parts, String value) {
examples.add(invertBackground(timeFormatString));
}
}
- return formatExampleList(examples.toArray(new String[0]));
}
- private String handleDateSymbol(XPathParts parts, String value) {
+ private void handleDateSymbol(XPathParts parts, String value, List examples) {
// Currently only called for month names, can expand in the future to handle other symbols.
// The idea is to show format months in a yMMMM?d date format, and stand-alone months in a
// yMMMM? format.
String length = parts.findAttributeValue("monthWidth", "type"); // wide, abbreviated, narrow
if (length.equals("narrow")) {
- return null; // no examples for narrow
+ return; // no examples for narrow
}
String context = parts.findAttributeValue("monthContext", "type"); // format, stand-alone
String calendarId =
@@ -1137,7 +1125,7 @@ private String handleDateSymbol(XPathParts parts, String value) {
dateFormat = cldrFile.getWinningValue(checkPath);
}
if (dateFormat == null) {
- return null;
+ return;
}
SimpleDateFormat sdf = icuServiceBuilder.getDateFormat(calendarId, dateFormat);
sdf.setTimeZone(ZONE_SAMPLE);
@@ -1158,12 +1146,11 @@ private String handleDateSymbol(XPathParts parts, String value) {
monthNames[8] = value;
dfs.setMonths(monthNames, DateFormatSymbols.STANDALONE, DateFormatSymbols.ABBREVIATED);
sdf.setDateFormatSymbols(dfs);
- return sdf.format(DATE_SAMPLE);
+ examples.add(sdf.format(DATE_SAMPLE));
}
- private String handleMinimalPairs(XPathParts parts, String minimalPattern) {
- List examples = new ArrayList<>();
-
+ private void handleMinimalPairs(
+ XPathParts parts, String minimalPattern, List examples) {
Output output = new Output<>();
String count;
String otherCount;
@@ -1213,7 +1200,7 @@ private String handleMinimalPairs(XPathParts parts, String minimalPattern) {
sampleBad = bestMinimalPairSamples.getBestUnitWithGender(otherGender, output);
break;
default:
- return null;
+ return;
}
String formattedUnit =
format(minimalPattern, backgroundStartSymbol + sample + backgroundEndSymbol);
@@ -1224,11 +1211,10 @@ private String handleMinimalPairs(XPathParts parts, String minimalPattern) {
formattedUnit =
format(minimalPattern, backgroundStartSymbol + sampleBad + backgroundEndSymbol);
examples.add(EXAMPLE_OF_INCORRECT + formattedUnit);
- return formatExampleList(examples);
}
private String getOtherGender(String gender) {
- if (gender == null) {
+ if (gender == null || grammarInfo == null) {
return null;
}
Collection unitGenders =
@@ -1286,17 +1272,16 @@ private UnitLength getUnitLength(XPathParts parts) {
return UnitLength.valueOf(parts.getAttributeValue(-3, "type").toUpperCase(Locale.ENGLISH));
}
- private String handleFormatUnit(XPathParts parts, String unitPattern) {
+ private void handleFormatUnit(XPathParts parts, String unitPattern, List examples) {
// Sample:
// //ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="accusative"]
String longUnitId = parts.getAttributeValue(-2, "type");
final String shortUnitId = UNIT_CONVERTER.getShortId(longUnitId);
if (UnitConverter.HACK_SKIP_UNIT_NAMES.contains(shortUnitId)) {
- return null;
+ return;
}
- List examples = new ArrayList<>();
if (parts.getElement(-1).equals("unitPattern")) {
String count = parts.getAttributeValue(-1, "count");
DecimalQuantity amount = getBest(Count.valueOf(count));
@@ -1340,7 +1325,6 @@ private String handleFormatUnit(XPathParts parts, String unitPattern) {
relatedUnit,
UnitSystem.getSystemsDisplay(systems)));
}
- return formatExampleList(examples);
}
/**
@@ -1443,21 +1427,25 @@ private String getConstrastingCase(
return null;
}
- private String handleFormatPerUnit(String value) {
+ private void handleFormatPerUnit(String value, List examples) {
DecimalFormat numberFormat = icuServiceBuilder.getNumberFormat(1);
- return format(value, backgroundStartSymbol + numberFormat.format(1) + backgroundEndSymbol);
+ examples.add(
+ format(
+ value,
+ backgroundStartSymbol + numberFormat.format(1) + backgroundEndSymbol));
}
- public String handleCompoundUnit(XPathParts parts) {
+ public void handleCompoundUnit(XPathParts parts, List examples) {
UnitLength unitLength = getUnitLength(parts);
String compoundType = parts.getAttributeValue(-2, "type");
Count count =
Count.valueOf(CldrUtility.ifNull(parts.getAttributeValue(-1, "count"), "other"));
- return handleCompoundUnit(unitLength, compoundType, count);
+ handleCompoundUnit(unitLength, compoundType, count, examples);
}
@SuppressWarnings("deprecation")
- public String handleCompoundUnit(UnitLength unitLength, String compoundType, Count count) {
+ public void handleCompoundUnit(
+ UnitLength unitLength, String compoundType, Count count, List examples) {
/*
*
@@ -1482,7 +1470,8 @@ public String handleCompoundUnit(UnitLength unitLength, String compoundType, Cou
// we want to get a number that works for the count passed in.
DecimalQuantity amount = getBest(count);
if (amount == null) {
- return "n/a";
+ examples.add("n/a");
+ return;
}
DecimalQuantity oneValue = DecimalQuantity_DualStorageBCD.fromExponentString("1");
@@ -1490,7 +1479,8 @@ public String handleCompoundUnit(UnitLength unitLength, String compoundType, Cou
String unit2mid;
switch (compoundType) {
default:
- return "n/a";
+ examples.add("n/a");
+ return;
case "per":
unit1mid = getFormattedUnit("length-meter", unitLength, amount);
unit2mid = getFormattedUnit("duration-second", unitLength, oneValue, "");
@@ -1511,20 +1501,22 @@ public String handleCompoundUnit(UnitLength unitLength, String compoundType, Cou
String form = this.pluralInfo.getPluralRules().select(amount);
// we rebuild a path, because we may have changed it.
String perPath = makeCompoundUnitPath(unitLength, compoundType, "compoundUnitPattern");
- return format(getValueFromFormat(perPath, form), unit1, unit2);
+ examples.add(format(getValueFromFormat(perPath, form), unit1, unit2));
}
- public String handleCompoundUnit1(XPathParts parts, String compoundPattern) {
+ public void handleCompoundUnit1(
+ XPathParts parts, String compoundPattern, List examples) {
UnitLength unitLength = getUnitLength(parts);
String pathCount = parts.getAttributeValue(-1, "count");
if (pathCount == null) {
- return handleCompoundUnit1Name(unitLength, compoundPattern);
+ handleCompoundUnit1Name(unitLength, compoundPattern, examples);
} else {
- return handleCompoundUnit1(unitLength, Count.valueOf(pathCount), compoundPattern);
+ handleCompoundUnit1(unitLength, Count.valueOf(pathCount), compoundPattern, examples);
}
}
- private String handleCompoundUnit1Name(UnitLength unitLength, String compoundPattern) {
+ private void handleCompoundUnit1Name(
+ UnitLength unitLength, String compoundPattern, List examples) {
String pathFormat =
"//ldml/units/unitLength"
+ unitLength.typeString
@@ -1535,15 +1527,17 @@ private String handleCompoundUnit1Name(UnitLength unitLength, String compoundPat
String modFormat =
combinePrefix(meterFormat, compoundPattern, unitLength == UnitLength.LONG);
- return removeEmptyRuns(modFormat);
+ examples.add(removeEmptyRuns(modFormat));
}
- public String handleCompoundUnit1(UnitLength unitLength, Count count, String compoundPattern) {
+ public void handleCompoundUnit1(
+ UnitLength unitLength, Count count, String compoundPattern, List examples) {
// we want to get a number that works for the count passed in.
DecimalQuantity amount = getBest(count);
if (amount == null) {
- return "n/a";
+ examples.add("n/a");
+ return;
}
DecimalFormat numberFormat = icuServiceBuilder.getNumberFormat(1);
@@ -1564,7 +1558,8 @@ public String handleCompoundUnit1(UnitLength unitLength, Count count, String com
String modFormat =
combinePrefix(meterFormat, compoundPattern, unitLength == UnitLength.LONG);
- return removeEmptyRuns(format(modFormat, numberFormat.format(amount.toBigDecimal())));
+ examples.add(
+ removeEmptyRuns(format(modFormat, numberFormat.format(amount.toBigDecimal()))));
}
// TODO, pass in unitLength instead of last parameter, and do work in Units.combinePattern.
@@ -1612,28 +1607,30 @@ private DecimalQuantity getBest(Count count) {
return range.end;
}
- private String handleMiscPatterns(XPathParts parts, String value) {
+ private void handleMiscPatterns(XPathParts parts, String value, List examples) {
DecimalFormat numberFormat = icuServiceBuilder.getNumberFormat(0);
String start = backgroundStartSymbol + numberFormat.format(99) + backgroundEndSymbol;
if ("range".equals(parts.getAttributeValue(-1, "type"))) {
String end = backgroundStartSymbol + numberFormat.format(144) + backgroundEndSymbol;
- return format(value, start, end);
+ examples.add(format(value, start, end));
} else {
- return format(value, start);
+ examples.add(format(value, start));
}
}
- private String handleIntervalFormats(XPathParts parts, String value) {
+ private void handleIntervalFormats(XPathParts parts, String value, List examples) {
if (!parts.getAttributeValue(3, "type").equals("gregorian")) {
- return null;
+ return;
}
if (parts.getElement(6).equals("intervalFormatFallback")) {
SimpleDateFormat dateFormat = new SimpleDateFormat();
String fallbackFormat = invertBackground(setBackground(value));
- return format(
- fallbackFormat,
- dateFormat.format(FIRST_INTERVAL),
- dateFormat.format(SECOND_INTERVAL.get("y")));
+ examples.add(
+ format(
+ fallbackFormat,
+ dateFormat.format(FIRST_INTERVAL),
+ dateFormat.format(SECOND_INTERVAL.get("y"))));
+ return;
}
String greatestDifference = parts.getAttributeValue(-1, "id");
/*
@@ -1659,12 +1656,13 @@ private String handleIntervalFormats(XPathParts parts, String value) {
* Reference: https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
* For now, such paths do not get examples.
*/
- return null;
+ return;
}
- return intervalFormat.format(FIRST_INTERVAL, later);
+ examples.add(intervalFormat.format(FIRST_INTERVAL, later));
}
- private String handleDelimiters(XPathParts parts, String xpath, String value) {
+ private void handleDelimiters(
+ XPathParts parts, String xpath, String value, List examples) {
String lastElement = parts.getElement(-1);
final String[] elements = {
"quotationStart", "alternateQuotationStart",
@@ -1685,65 +1683,70 @@ private String handleDelimiters(XPathParts parts, String xpath, String value) {
"//ldml/localeDisplayNames/types/type[@key=\"calendar\"][@type=\"gregorian\"]");
// NOTE: the example provided here is partially in English because we don't
// have a translated conversational example in CLDR.
- return invertBackground(
- format("{0}They said {1}" + example + "{2}.{3}", (Object[]) quotes));
+ examples.add(
+ invertBackground(
+ format("{0}They said {1}" + example + "{2}.{3}", (Object[]) quotes)));
}
- private String handleListPatterns(XPathParts parts, String value) {
+ private void handleListPatterns(XPathParts parts, String value, List examples) {
// listPatternType is either "duration" or null/other list
String listPatternType = parts.getAttributeValue(-2, "type");
if (listPatternType == null || !listPatternType.contains("unit")) {
- return handleRegularListPatterns(parts, value, ListTypeLength.from(listPatternType));
+ handleRegularListPatterns(parts, value, ListTypeLength.from(listPatternType), examples);
} else {
- return handleDurationListPatterns(parts, value, UnitLength.from(listPatternType));
+ handleDurationListPatterns(parts, value, UnitLength.from(listPatternType), examples);
}
}
- private String handleRegularListPatterns(
- XPathParts parts, String value, ListTypeLength listTypeLength) {
+ private void handleRegularListPatterns(
+ XPathParts parts, String value, ListTypeLength listTypeLength, List examples) {
String patternType = parts.getAttributeValue(-1, "type");
if (patternType == null) {
- return null; // formerly happened for some "/alias" paths
+ return; // formerly happened for some "/alias" paths
}
String pathFormat = "//ldml/localeDisplayNames/territories/territory[@type=\"{0}\"]";
String territory1 = getValueFromFormat(pathFormat, "CH");
String territory2 = getValueFromFormat(pathFormat, "JP");
if (patternType.equals("2")) {
- return invertBackground(format(setBackground(value), territory1, territory2));
+ examples.add(invertBackground(format(setBackground(value), territory1, territory2)));
+ return;
}
String territory3 = getValueFromFormat(pathFormat, "EG");
String territory4 = getValueFromFormat(pathFormat, "CA");
- return longListPatternExample(
- listTypeLength.getPath(),
- patternType,
- value,
- territory1,
- territory2,
- territory3,
- territory4);
- }
-
- private String handleDurationListPatterns(
- XPathParts parts, String value, UnitLength unitWidth) {
+ examples.add(
+ longListPatternExample(
+ listTypeLength.getPath(),
+ patternType,
+ value,
+ territory1,
+ territory2,
+ territory3,
+ territory4));
+ }
+
+ private void handleDurationListPatterns(
+ XPathParts parts, String value, UnitLength unitWidth, List examples) {
String patternType = parts.getAttributeValue(-1, "type");
if (patternType == null) {
- return null; // formerly happened for some "/alias" paths
+ return; // formerly happened for some "/alias" paths
}
String duration1 = getFormattedUnit("duration-day", unitWidth, 4);
String duration2 = getFormattedUnit("duration-hour", unitWidth, 2);
if (patternType.equals("2")) {
- return invertBackground(format(setBackground(value), duration1, duration2));
+ examples.add(invertBackground(format(setBackground(value), duration1, duration2)));
+ return;
}
String duration3 = getFormattedUnit("duration-minute", unitWidth, 37);
String duration4 = getFormattedUnit("duration-second", unitWidth, 23);
- return longListPatternExample(
- unitWidth.listTypeLength.getPath(),
- patternType,
- value,
- duration1,
- duration2,
- duration3,
- duration4);
+ examples.add(
+ longListPatternExample(
+ unitWidth.listTypeLength.getPath(),
+ patternType,
+ value,
+ duration1,
+ duration2,
+ duration3,
+ duration4));
}
public enum UnitLength {
@@ -1843,7 +1846,7 @@ private String getValueFromFormat(String format, Object... arguments) {
return cldrFile.getWinningValue(format(format, arguments));
}
- public String handleEllipsis(String type, String value) {
+ public void handleEllipsis(String type, String value, List examples) {
String pathFormat = "//ldml/localeDisplayNames/territories/territory[@type=\"{0}\"]";
// {0} …
// … {0}
@@ -1858,7 +1861,7 @@ public String handleEllipsis(String type, String value) {
if (type.contains("initial")) {
territory1 = territory2;
}
- return invertBackground(format(setBackground(value), territory1, territory2));
+ examples.add(invertBackground(format(setBackground(value), territory1, territory2)));
}
public static String clip(String text, int clipStart, int clipEnd) {
@@ -1883,7 +1886,7 @@ public static String clip(String text, int clipStart, int clipEnd) {
* @param value
* @return
*/
- private String handleMonthPatterns(XPathParts parts, String value) {
+ private void handleMonthPatterns(XPathParts parts, String value, List examples) {
String calendar = parts.getAttributeValue(3, "type");
String context = parts.getAttributeValue(5, "type");
String month = "8";
@@ -1893,20 +1896,20 @@ private String handleMonthPatterns(XPathParts parts, String value) {
"//ldml/dates/calendars/calendar[@type=\"{0}\"]/months/monthContext[@type=\"{1}\"]/monthWidth[@type=\"{2}\"]/month[@type=\"8\"]";
month = getValueFromFormat(xpath, calendar, context, width);
}
- return invertBackground(format(setBackground(value), month));
+ examples.add(invertBackground(format(setBackground(value), month)));
}
- private String handleAppendItems(XPathParts parts, String value) {
+ private void handleAppendItems(XPathParts parts, String value, List examples) {
String request = parts.getAttributeValue(-1, "request");
if (!"Timezone".equals(request)) {
- return null;
+ return;
}
String calendar = parts.getAttributeValue(3, "type");
SimpleDateFormat sdf =
icuServiceBuilder.getDateFormat(calendar, 0, DateFormat.MEDIUM, null);
String zone = cldrFile.getStringValue("//ldml/dates/timeZoneNames/gmtZeroFormat");
- return format(value, setBackground(sdf.format(DATE_SAMPLE)), setBackground(zone));
+ examples.add(format(value, setBackground(sdf.format(DATE_SAMPLE)), setBackground(zone)));
}
private class IntervalFormat {
@@ -1989,22 +1992,23 @@ public IntervalFormat setPattern(XPathParts parts, String pattern) {
}
}
- private String handleDurationUnit(String value) {
+ private void handleDurationUnit(String value, List examples) {
DateFormat df = this.icuServiceBuilder.getDateFormat("gregorian", value.replace('h', 'H'));
df.setTimeZone(TimeZone.GMT_ZONE);
long time = ((5 * 60 + 37) * 60 + 23) * 1000;
try {
- return df.format(new Date(time));
+ examples.add(df.format(new Date(time)));
} catch (IllegalArgumentException e) {
// e.g., Illegal pattern character 'o' in "aɖabaƒoƒo m:ss"
- return null;
+ return;
}
}
@SuppressWarnings("deprecation")
- private String formatCountValue(String xpath, XPathParts parts, String value) {
+ private void formatCountValue(
+ String xpath, XPathParts parts, String value, List examples) {
if (!parts.containsAttribute("count")) { // no examples for items that don't format
- return null;
+ return;
}
final PluralInfo plurals =
supplementalDataInfo.getPlurals(PluralType.cardinal, cldrFile.getLocaleID());
@@ -2021,12 +2025,12 @@ private String formatCountValue(String xpath, XPathParts parts, String value) {
final LinkedHashSet exampleCount = new LinkedHashSet<>(CURRENCY_SAMPLES);
String countString = parts.getAttributeValue(-1, "count");
if (countString == null) {
- return null;
+ return;
} else {
try {
count = Count.valueOf(countString);
} catch (Exception e) {
- return null; // counts like 0
+ return; // counts like 0
}
}
@@ -2102,7 +2106,7 @@ private String formatCountValue(String xpath, XPathParts parts, String value) {
}
}
}
- return result.isEmpty() ? null : result;
+ examples.add(result.isEmpty() ? null : result);
}
@SuppressWarnings("deprecation")
@@ -2214,7 +2218,7 @@ public String countAttribute(Count count) {
return "[@count=\"" + count + "\"]";
}
- private String handleMinimumGrouping(XPathParts parts, String value) {
+ private void handleMinimumGrouping(XPathParts parts, String value, List examples) {
String numberSystem = cldrFile.getWinningValue("//ldml/numbers/defaultNumberingSystem");
String checkPath =
"//ldml/numbers/decimalFormats[@numberSystem=\""
@@ -2227,14 +2231,12 @@ private String handleMinimumGrouping(XPathParts parts, String value) {
double sampleNum1 = 543.21;
double sampleNum2 = 6543.21;
double sampleNum3 = 76543.21;
- String example = "";
- example = addExampleResult(formatNumber(numberFormat, sampleNum1), example);
- example = addExampleResult(formatNumber(numberFormat, sampleNum2), example);
- example = addExampleResult(formatNumber(numberFormat, sampleNum3), example);
- return example;
+ examples.add(formatNumber(numberFormat, sampleNum1));
+ examples.add(formatNumber(numberFormat, sampleNum2));
+ examples.add(formatNumber(numberFormat, sampleNum3));
}
- private String handleNumberSymbol(XPathParts parts, String value) {
+ private void handleNumberSymbol(XPathParts parts, String value, List examples) {
String symbolType = parts.getElement(-1);
String numberSystem = parts.getAttributeValue(2, "numberSystem"); // null if not present
int index; // dec/percent/sci
@@ -2269,7 +2271,7 @@ private String handleNumberSymbol(XPathParts parts, String value) {
} else {
// We don't need examples for standalone symbols, i.e. infinity and nan.
// We don't have an example for the list symbol either.
- return null;
+ return;
}
DecimalFormat x = icuServiceBuilder.getNumberFormat(index, numberSystem);
String example;
@@ -2298,16 +2300,16 @@ private String handleNumberSymbol(XPathParts parts, String value) {
}
example = x.format(numberSample);
example = example.replace(originalValue, formattedValue);
- return backgroundStartSymbol + example + backgroundEndSymbol;
+ examples.add(backgroundStartSymbol + example + backgroundEndSymbol);
}
- private String handleNumberingSystem(String value) {
+ private void handleNumberingSystem(String value, List examples) {
NumberFormat x = icuServiceBuilder.getGenericNumberFormat(value);
x.setGroupingUsed(false);
- return x.format(NUMBER_SAMPLE_WHOLE);
+ examples.add(x.format(NUMBER_SAMPLE_WHOLE));
}
- private String handleTimeZoneName(XPathParts parts, String value) {
+ private void handleTimeZoneName(XPathParts parts, String value, List examples) {
String result = null;
if (parts.contains("exemplarCity")) {
// ldml/dates/timeZoneNames/zone[@type="America/Los_Angeles"]/exemplarCity
@@ -2319,7 +2321,8 @@ private String handleTimeZoneName(XPathParts parts, String value) {
} else {
result = value; // trivial -- is this beneficial?
}
- return result;
+ examples.add(result);
+ return;
}
if (countryCode.equals("001")) {
// GMT code, so format.
@@ -2328,7 +2331,7 @@ private String handleTimeZoneName(XPathParts parts, String value) {
int hours = Integer.parseInt(hourOffset);
result = getGMTFormat(null, null, hours);
} catch (RuntimeException e) {
- return null; // fail, skip
+ return; // fail, skip
}
} else {
result = setBackground(cldrFile.getName(CLDRFile.TERRITORY_NAME, countryCode));
@@ -2408,11 +2411,12 @@ private String handleTimeZoneName(XPathParts parts, String value) {
}
}
}
- return result;
+ examples.add(result);
}
@SuppressWarnings("deprecation")
- private String handleDateFormatItem(String xpath, String value, boolean showContexts) {
+ private void handleDateFormatItem(
+ String xpath, String value, boolean showContexts, List examples) {
// Get here if parts contains "calendar" and either of "pattern", "dateFormatItem"
String fullpath = cldrFile.getFullXPath(xpath);
@@ -2459,7 +2463,7 @@ private String handleDateFormatItem(String xpath, String value, boolean showCont
cldrFile.getWinningPath(xpath.replaceAll("dateTimeFormat", "timeFormat"));
int tfLengthOffset = timeFormatXPathForPrefix.indexOf("timeFormatLength");
if (tfLengthOffset < 0) {
- return "";
+ return;
}
String timeFormatXPathPrefix = timeFormatXPathForPrefix.substring(0, tfLengthOffset);
String timeLongerFormatXPath =
@@ -2492,8 +2496,6 @@ private String handleDateFormatItem(String xpath, String value, boolean showCont
"//ldml/dates/fields/field[@type=\"day\"]/relative[@type=\"0\"]");
String relativeDayValue = cldrFile.getWinningValue(relativeDayXPath);
- List examples = new ArrayList<>();
-
String dfResult = df.format(DATE_SAMPLE);
String tlfResult = tlf.format(DATE_SAMPLE);
String tsfResult = tsf.format(DATE_SAMPLE); // DATE_SAMPLE is in the afternoon
@@ -2588,11 +2590,12 @@ private String handleDateFormatItem(String xpath, String value, boolean showCont
examples.add(dtf.format(DATE_SAMPLE));
}
- return formatExampleList(examples.toArray(new String[0]));
+ return;
} else {
String id = parts.findAttributeValue("dateFormatItem", "id");
if ("NEW".equals(id) || value == null) {
- return startItalicSymbol + "n/a" + endItalicSymbol;
+ examples.add(startItalicSymbol + "n/a" + endItalicSymbol);
+ return;
} else {
String numbersOverride = parts.findAttributeValue("pattern", "numbers");
SimpleDateFormat sdf =
@@ -2612,7 +2615,8 @@ private String handleDateFormatItem(String xpath, String value, boolean showCont
// Standard date/time format, or availableFormat without dayPeriod
if (value.contains("MMM") || value.contains("LLL")) {
// alpha month, do not need context examples
- return sdf.format(DATE_SAMPLE);
+ examples.add(sdf.format(DATE_SAMPLE));
+ return;
} else {
// Use contextExamples if showContexts T
String example =
@@ -2622,14 +2626,13 @@ private String handleDateFormatItem(String xpath, String value, boolean showCont
+ exampleEndSymbol
: "";
example = addExampleResult(sdf.format(DATE_SAMPLE), example, showContexts);
- return example;
+ examples.add(example);
+ return;
}
} else {
- List examples = new ArrayList<>();
examples.add(sdf.format(DATE_SAMPLE3));
examples.add(sdf.format(DATE_SAMPLE));
examples.add(sdf.format(DATE_SAMPLE4));
- return formatExampleList(examples.toArray(new String[0]));
}
}
}
@@ -2662,7 +2665,8 @@ private boolean symbolIsLetters(String currencySymbol, boolean onBothSides) {
* @param value
* @return
*/
- private String handleCurrencyFormat(XPathParts parts, String value, boolean showContexts) {
+ private void handleCurrencyFormat(
+ XPathParts parts, String value, boolean showContexts, List examples) {
String example =
showContexts ? exampleStartHeaderSymbol + contextheader + exampleEndSymbol : "";
@@ -2687,7 +2691,8 @@ private String handleCurrencyFormat(XPathParts parts, String value, boolean show
String countValue = parts.getAttributeValue(-1, "count");
if (countValue != null) {
- return formatCountDecimal(df, countValue);
+ examples.add(formatCountDecimal(df, countValue));
+ return;
}
double sampleAmount = 1295.00;
@@ -2711,7 +2716,7 @@ private String handleCurrencyFormat(XPathParts parts, String value, boolean show
example = addExampleResult(formatNumber(df, -sampleAmount), example, showContexts);
}
- return example;
+ examples.add(example);
}
private String getDefaultTerritory() {
@@ -2744,14 +2749,16 @@ private String getDefaultTerritory() {
* @param value
* @return
*/
- private String handleDecimalFormat(XPathParts parts, String value, boolean showContexts) {
+ private void handleDecimalFormat(
+ XPathParts parts, String value, boolean showContexts, List examples) {
String example =
showContexts ? exampleStartHeaderSymbol + contextheader + exampleEndSymbol : "";
String numberSystem = parts.getAttributeValue(2, "numberSystem"); // null if not present
DecimalFormat numberFormat = icuServiceBuilder.getNumberFormat(value, numberSystem);
String countValue = parts.getAttributeValue(-1, "count");
if (countValue != null) {
- return formatCountDecimal(numberFormat, countValue);
+ examples.add(formatCountDecimal(numberFormat, countValue));
+ return;
}
double sampleNum1 = 5.43;
@@ -2763,7 +2770,7 @@ private String handleDecimalFormat(XPathParts parts, String value, boolean showC
example = addExampleResult(formatNumber(numberFormat, sampleNum2), example, showContexts);
// have positive and negative
example = addExampleResult(formatNumber(numberFormat, -sampleNum2), example, showContexts);
- return example;
+ examples.add(example);
}
private String formatCountDecimal(DecimalFormat numberFormat, String countValue) {
@@ -2820,7 +2827,8 @@ private Double getExampleForPattern(DecimalFormat format, Count count) {
return samples.get(count);
}
- private String handleCurrency(String xpath, XPathParts parts, String value) {
+ private void handleCurrency(
+ String xpath, XPathParts parts, String value, List examples) {
String currency = parts.getAttributeValue(-2, "type");
String fullPath = cldrFile.getFullXPath(xpath, false);
if (parts.contains("symbol")) {
@@ -2843,22 +2851,20 @@ private String handleCurrency(String xpath, XPathParts parts, String value) {
result =
setBackground(result)
.replace(value, backgroundEndSymbol + value + backgroundStartSymbol);
- return result;
+ examples.add(result);
} else if (parts.contains("displayName")) {
- return formatCountValue(xpath, parts, value);
+ formatCountValue(xpath, parts, value, examples);
}
- return null;
+ return;
}
- private String handleDateRangePattern(String value) {
- String result;
+ private void handleDateRangePattern(String value, List examples) {
SimpleDateFormat dateFormat = icuServiceBuilder.getDateFormat("gregorian", 2, 0);
- result =
+ examples.add(
format(
value,
setBackground(dateFormat.format(DATE_SAMPLE)),
- setBackground(dateFormat.format(DATE_SAMPLE2)));
- return result;
+ setBackground(dateFormat.format(DATE_SAMPLE2))));
}
/**
@@ -2876,7 +2882,8 @@ private String getLocaleDisplayPattern(String elementToOverride, String element,
}
}
- private String handleDisplayNames(String xpath, XPathParts parts, String value) {
+ private void handleDisplayNames(
+ String xpath, XPathParts parts, String value, List examples) {
String result = null;
if (parts.contains("codePatterns")) {
// ldml/localeDisplayNames/codePatterns/codePattern[@type="language"]
@@ -2892,6 +2899,8 @@ private String handleDisplayNames(String xpath, XPathParts parts, String value)
: type.equals("script")
? "Avst"
: type.equals("territory") ? "057" : "CODE"));
+ examples.add(result);
+ return;
} else if (parts.contains("localeDisplayPattern")) {
// ldml/localeDisplayNames/localeDisplayPattern/localePattern
// ldml/localeDisplayNames/localeDisplayPattern/localeSeparator
@@ -2910,18 +2919,18 @@ private String handleDisplayNames(String xpath, XPathParts parts, String value)
locales.add(
element.equals("localeKeyTypePattern") ? "uz-Arab-u-tz-etadd" : "uz-Arab-AF");
locales.add("uz-Arab-AF-u-tz-etadd-nu-arab");
- String[] examples = new String[locales.size()];
+ // String[] examples = new String[locales.size()];
for (int i = 0; i < locales.size(); i++) {
- examples[i] =
+ examples.add(
invertBackground(
cldrFile.getName(
locales.get(i),
false,
localeKeyTypePattern,
localePattern,
- localeSeparator));
+ localeSeparator)));
}
- result = formatExampleList(examples);
+ return;
} else if (parts.contains("languages")
|| parts.contains("scripts")
|| parts.contains("territories")) {
@@ -2935,9 +2944,10 @@ private String handleDisplayNames(String xpath, XPathParts parts, String value)
} else {
result = cldrFile.getBaileyValue(xpath, null, null);
}
+ examples.add(result);
+ return;
} else {
value = setBackground(value);
- List examples = new ArrayList<>();
String nameType = parts.getElement(3);
Map likely = supplementalDataInfo.getLikelySubtags();
@@ -2948,7 +2958,7 @@ private String handleDisplayNames(String xpath, XPathParts parts, String value)
String tag = "language".equals(nameType) ? type : "und_" + type;
String max = LikelySubtags.maximize(tag, likely);
if (max == null) {
- return null;
+ return;
}
LanguageTagParser ltp = new LanguageTagParser().set(max);
String languageName = null;
@@ -3057,10 +3067,9 @@ private String handleDisplayNames(String xpath, XPathParts parts, String value)
+ "\"]");
examples.add(invertBackground(format(codePattern, value)));
}
- result = formatExampleList(examples.toArray(new String[0]));
+ return;
}
}
- return result;
}
private String formatExampleList(String[] examples) {
@@ -3077,7 +3086,7 @@ private String formatExampleList(String[] examples) {
* @param examples
* @return
*/
- private String formatExampleList(Collection examples) {
+ public String formatExampleList(Collection examples) {
if (examples == null || examples.isEmpty()) {
return null;
}
diff --git a/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestExampleGenerator.java b/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestExampleGenerator.java
index a239a63f518..8b2652c160e 100644
--- a/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestExampleGenerator.java
+++ b/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestExampleGenerator.java
@@ -502,9 +502,10 @@ public void TestCompoundUnit() {
private void checkCompoundUnits(String locale, String[][] tests) {
ExampleGenerator exampleGenerator = getExampleGenerator(locale);
for (String[] test : tests) {
- String actual =
- exampleGenerator.handleCompoundUnit(
- UnitLength.valueOf(test[1]), test[0], Count.valueOf(test[2]));
+ List examples = new ArrayList<>();
+ exampleGenerator.handleCompoundUnit(
+ UnitLength.valueOf(test[1]), test[0], Count.valueOf(test[2]), examples);
+ String actual = exampleGenerator.formatExampleList(examples);
assertEquals("CompoundUnit", test[3], ExampleGenerator.simplify(actual, true));
}
}
@@ -564,10 +565,10 @@ public void TestCompoundUnit2() {
for (String[] test : tests) {
ExampleGenerator exampleGenerator = getExampleGenerator(test[0]);
-
- String actual =
- exampleGenerator.handleCompoundUnit1(
- UnitLength.valueOf(test[1]), Count.valueOf(test[2]), test[3]);
+ List examples = new ArrayList<>();
+ exampleGenerator.handleCompoundUnit1(
+ UnitLength.valueOf(test[1]), Count.valueOf(test[2]), test[3], examples);
+ String actual = exampleGenerator.formatExampleList(examples);
assertEquals("CompoundUnit", test[4], ExampleGenerator.simplify(actual, true));
}
}