From 928a926ba578e890e1ecfd3beafba2e6e2f68ed0 Mon Sep 17 00:00:00 2001 From: Peter Edberg <42151464+pedberg-icu@users.noreply.github.com> Date: Mon, 20 May 2024 12:47:33 -0700 Subject: [PATCH] CLDR-15764 Add examples with RTL context to reports; fix other report issues (#3733) --- .../unicode/cldr/util/DateTimeFormats.java | 40 +++++++++++++++---- .../cldr/util/VerifyCompactNumbers.java | 24 ++++++++++- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/util/DateTimeFormats.java b/tools/cldr-code/src/main/java/org/unicode/cldr/util/DateTimeFormats.java index d1d34208920..e14b0044046 100644 --- a/tools/cldr-code/src/main/java/org/unicode/cldr/util/DateTimeFormats.java +++ b/tools/cldr-code/src/main/java/org/unicode/cldr/util/DateTimeFormats.java @@ -12,6 +12,7 @@ import com.ibm.icu.text.DecimalFormat; import com.ibm.icu.text.MessageFormat; import com.ibm.icu.text.SimpleDateFormat; +import com.ibm.icu.text.UnicodeSet; import com.ibm.icu.util.Calendar; import com.ibm.icu.util.DateInterval; import com.ibm.icu.util.ICUUncheckedIOException; @@ -71,6 +72,14 @@ enum MyOptions { private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + // The following is also in ExampleGenerator and VerifyCompactNumbers; it and other shared + // constant sets should + // probably be moved to a common file of such things. + private static final UnicodeSet BIDI_MARKS = new UnicodeSet("[:Bidi_Control:]").freeze(); + private static final String exampleSep = "
"; + private static final String rtlStart = "
"; + private static final String rtlEnd = "
"; + private static final String[] STOCK = {"short", "medium", "long", "full"}; private static final String[] CALENDAR_FIELD_TO_PATTERN_LETTER = { "G", "y", "M", @@ -97,7 +106,7 @@ enum MyOptions { .put("a", new Date(2012 - 1900, 0, 13, 2, 45, 59)) .put("h", new Date(2012 - 1900, 0, 13, 15, 45, 59)) .put("H", new Date(2012 - 1900, 0, 13, 15, 45, 59)) - .put("m", SAMPLE_DATE_DEFAULT_END) + .put("m", new Date(2012 - 1900, 0, 13, 14, 46, 59)) .build(); // // "G", "y", "M", // null, new Date(2013 - 1900, 0, 13, 14, 45, 59), new Date(2012 - 1900, 1, 13, 14, 45, @@ -121,6 +130,7 @@ enum MyOptions { private DateIntervalInfo dateIntervalInfo = new DateIntervalInfo(); private String calendarID; private CLDRFile file; + private boolean isRTL; private static String surveyUrl = CLDRConfig.getInstance() @@ -154,6 +164,8 @@ public DateTimeFormats set(CLDRFile file, String calendarID, boolean useStock) { generator = DateTimePatternGenerator.getEmptyInstance(); this.calendarID = calendarID; boolean haveDefaultHourChar = false; + String characterOrder = file.getStringValue("//ldml/layout/orientation/characterOrder"); + isRTL = (characterOrder != null && characterOrder.equals("right-to-left")); for (String stock : STOCK) { String path = @@ -490,7 +502,7 @@ public void addTable(DateTimeFormats comparison, Appendable output) { FIELDS_TITLE, "Skeleton", "English Example", - "Native Example", + "Native Example (neutral context,
then RTL if relevant)", false); for (String[] nameAndSkeleton : NAME_AND_PATTERN) { String name = nameAndSkeleton[0]; @@ -571,7 +583,7 @@ public void addTable(DateTimeFormats comparison, Appendable output) { private String getExample(String skeleton) { String example; if (skeleton.contains("®")) { - return getRelativeExampleFromSkeleton(skeleton); + example = getRelativeExampleFromSkeleton(skeleton); } else { int slashPos = skeleton.indexOf('/'); if (slashPos >= 0) { @@ -602,7 +614,11 @@ private String getExample(String skeleton) { example = format.format(SAMPLE_DATE); } } - return TransliteratorUtilities.toHTML.transform(example); + String transformedExample = TransliteratorUtilities.toHTML.transform(example); + if (isRTL || BIDI_MARKS.containsSome(transformedExample)) { + transformedExample += exampleSep + rtlStart + transformedExample + rtlEnd; + } + return transformedExample; } static final Pattern RELATIVE_DATE = @@ -675,19 +691,27 @@ private String getRelativeExampleFromSkeleton(String skeleton) { // String length = skeleton.contains("MMMM") ? skeleton.contains("E") ? // "full" : "long" // : skeleton.contains("MMM") ? "medium" : "short"; - String path2 = getDTSeparator("full"); - String datetimePattern = file.getStringValue(path2).replace("'", ""); + String path2 = getDTSeparator("full", "atType"); + String datetimePattern = + file.getStringValue( + getDTSeparator("full", "atType")); // prefer the atType variant here + if (datetimePattern == null) { + datetimePattern = file.getStringValue(getDTSeparator("full", "standard")); + } + datetimePattern = datetimePattern.replace("'", ""); return MessageFormat.format(datetimePattern, formattedTime, value); } } - private String getDTSeparator(String length) { + private String getDTSeparator(String length, String type) { String path = "//ldml/dates/calendars/calendar[@type=\"" + calendarID + "\"]/dateTimeFormats/dateTimeFormatLength[@type=\"" + length - + "\"]/dateTimeFormat[@type=\"standard\"]/pattern[@type=\"standard\"]"; + + "\"]/dateTimeFormat[@type=\"" + + type + + "\"]/pattern[@type=\"standard\"]"; return path; } diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/util/VerifyCompactNumbers.java b/tools/cldr-code/src/main/java/org/unicode/cldr/util/VerifyCompactNumbers.java index 5d5b27c9b9e..70fd3fb4b69 100644 --- a/tools/cldr-code/src/main/java/org/unicode/cldr/util/VerifyCompactNumbers.java +++ b/tools/cldr-code/src/main/java/org/unicode/cldr/util/VerifyCompactNumbers.java @@ -3,6 +3,7 @@ import com.ibm.icu.text.CompactDecimalFormat; import com.ibm.icu.text.CompactDecimalFormat.CompactStyle; import com.ibm.icu.text.NumberFormat; +import com.ibm.icu.text.UnicodeSet; import com.ibm.icu.util.Currency; import com.ibm.icu.util.ICUUncheckedIOException; import com.ibm.icu.util.ULocale; @@ -35,6 +36,13 @@ public class VerifyCompactNumbers { private static final CLDRConfig CLDR_CONFIG = CLDRConfig.getInstance(); private static final String DIR = CLDRPaths.VERIFY_DIR + "numbers/"; + // The following is also in ExampleGenerator and DateTimeFormats; it and other shared constant + // sets should + // probably be moved to a common file of such things. + private static final UnicodeSet BIDI_MARKS = new UnicodeSet("[:Bidi_Control:]").freeze(); + private static final String exampleSep = "
"; + private static final String rtlStart = "
"; + private static final String rtlEnd = "
"; static final Options myOptions = new Options(); @@ -146,12 +154,16 @@ public static void showNumbers( Set debugCreationErrors = new LinkedHashSet<>(); Set errors = new LinkedHashSet<>(); String locale = cldrFile.getLocaleID(); + String characterOrder = + cldrFile.getStringValue("//ldml/layout/orientation/characterOrder"); + boolean isRTL = (characterOrder != null && characterOrder.equals("right-to-left")); TablePrinter tablePrinter1 = new TablePrinter() // .setCaption("Timezone Formats") .setTableAttributes("class='dtf-table'") - .addColumn("Numeric Format") + .addColumn( + "Numeric Format
(neutral context,
then RTL if relevant)") .setHeaderCell(true) .setHeaderAttributes("class='dtf-th'") .setCellAttributes("class='dtf-s'") @@ -241,6 +253,9 @@ public static void showNumbers( } String formattedNumber = nf.format(source); + if (isRTL || BIDI_MARKS.containsSome(formattedNumber)) { + formattedNumber += exampleSep + rtlStart + formattedNumber + rtlEnd; + } String compactFormattedNumber = cdf == null ? "n/a" : cdf.format(source); String compactLongFormattedNumber = cdfs == null ? "n/a" : cdfs.format(source); String compactCurrFormattedNumber = @@ -360,6 +375,13 @@ public static Set collectSamplesAndSetFormats( // samples.addAll(samples2); Set allSamples = new TreeSet<>(); + // First add selected negative values and 0 + allSamples.add(-123456.7d); // decimal sep, and grouping sep if used + allSamples.add(-123456d); // no decimal sep, grouping sep if used + allSamples.add(-12.3d); // decimal sep, no grouping sep + allSamples.add(-12d); // no decimal or grouping sep + allSamples.add(0d); // no decimal or grouping sep + // Then the larger set of positive values for (long i = 1; i <= 100000000000000L; i *= factor) { for (Double sample : samples) { double source = i * sample;