• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  ******************************************************************************
3  * Copyright (C) 2005-2010, International Business Machines Corporation and        *
4  * others. All Rights Reserved.                                               *
5  ******************************************************************************
6  */
7 package org.unicode.cldr.tool;
8 
9 import java.io.BufferedReader;
10 import java.io.IOException;
11 import java.io.PrintWriter;
12 import java.util.Arrays;
13 import java.util.Collections;
14 import java.util.Date;
15 import java.util.HashSet;
16 import java.util.Iterator;
17 import java.util.Map;
18 import java.util.Map.Entry;
19 import java.util.Set;
20 import java.util.TreeMap;
21 import java.util.TreeSet;
22 
23 import org.unicode.cldr.draft.FileUtilities;
24 import org.unicode.cldr.test.CoverageLevel2;
25 import org.unicode.cldr.util.CLDRConfig;
26 import org.unicode.cldr.util.CLDRFile;
27 import org.unicode.cldr.util.CLDRPaths;
28 import org.unicode.cldr.util.CldrUtility;
29 import org.unicode.cldr.util.CldrUtility.VariableReplacer;
30 import org.unicode.cldr.util.ExtractCollationRules;
31 import org.unicode.cldr.util.Factory;
32 import org.unicode.cldr.util.FileCopier;
33 import org.unicode.cldr.util.LanguageTagParser;
34 import org.unicode.cldr.util.Level;
35 import org.unicode.cldr.util.LocaleIDParser;
36 import org.unicode.cldr.util.PathHeader;
37 import org.unicode.cldr.util.PathHeader.SectionId;
38 import org.unicode.cldr.util.StringId;
39 import org.unicode.cldr.util.TransliteratorUtilities;
40 
41 import com.google.common.base.Joiner;
42 import com.ibm.icu.dev.tool.UOption;
43 import com.ibm.icu.impl.Relation;
44 import com.ibm.icu.lang.UScript;
45 import com.ibm.icu.text.Collator;
46 import com.ibm.icu.text.RuleBasedCollator;
47 import com.ibm.icu.text.Transliterator;
48 import com.ibm.icu.text.UnicodeSet;
49 import com.ibm.icu.text.UnicodeSetIterator;
50 import com.ibm.icu.util.ULocale;
51 
52 public class ShowData {
53     private static final int HELP1 = 0, HELP2 = 1, SOURCEDIR = 2, DESTDIR = 3,
54         MATCH = 4, GET_SCRIPTS = 5,
55         LAST_DIR = 6,
56         COVERAGE = 7;
57 
58     private static final UOption[] options = {
59         UOption.HELP_H(),
60         UOption.HELP_QUESTION_MARK(),
61         UOption.SOURCEDIR().setDefault(CLDRPaths.MAIN_DIRECTORY),
62         UOption.DESTDIR().setDefault(CLDRPaths.CHART_DIRECTORY + "summary/"),
63         UOption.create("match", 'm', UOption.REQUIRES_ARG).setDefault(".*"),
64         UOption.create("getscript", 'g', UOption.NO_ARG),
65         UOption.create("last", 'l', UOption.REQUIRES_ARG).setDefault(CLDRPaths.LAST_RELEASE_DIRECTORY + "common/main/"),
66         UOption.create("coverage", 'c', UOption.REQUIRES_ARG).setDefault(Level.MODERN.toString()),
67     };
68 
dateFooter()69     public static String dateFooter() {
70         return "<p>Generation: " + CldrUtility.isoFormatDateOnly(new java.util.Date()) + "</p>" +
71             System.lineSeparator();
72     }
73 
74     static RuleBasedCollator uca = (RuleBasedCollator) Collator
75         .getInstance(ULocale.ROOT);
76 
77     {
78         uca.setNumericCollation(true);
79     }
80 
81     static PathHeader.Factory prettyPathMaker = PathHeader.getFactory(CLDRConfig.getInstance().getEnglish());
82 
83     static CLDRFile english;
84 
85     static Set<String> locales;
86 
87     static Relation<String, String> parentToChildren = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
88 
89     static Factory cldrFactory;
90 
main(String[] args)91     public static void main(String[] args) throws Exception {
92         // String p =
93         // prettyPathMaker.getPrettyPath("//ldml/characters/exemplarCharacters[@alt=\"proposed-u151-4\"]");
94         // String q = prettyPathMaker.getOriginal(p);
95 
96         double deltaTime = System.currentTimeMillis();
97         try {
98             CLDRConfig testInfo = ToolConfig.getToolInstance();
99             UOption.parseArgs(args, options);
100             String sourceDir = options[SOURCEDIR].value; // Utility.COMMON_DIRECTORY
101             // + "main/";
102             String targetDir = options[DESTDIR].value; // Utility.GEN_DIRECTORY +
103             // "main/";
104             cldrFactory = CLDRConfig.getInstance().getMainAndAnnotationsFactory(); // ignore source directory for now
105             english = cldrFactory.make("en", true);
106             String lastSourceDir = options[LAST_DIR].value; // Utility.COMMON_DIRECTORY
107 
108             Level requiredCoverage = Level.fromString(options[COVERAGE].toString()); // Utility.COMMON_DIRECTORY
109 
110             if (options[GET_SCRIPTS].doesOccur) {
111                 getScripts();
112                 return;
113             }
114 
115             FileCopier.ensureDirectoryExists(options[DESTDIR].value);
116             FileCopier.copy(ShowData.class, "summary-index.css", options[DESTDIR].value, "index.css");
117             FileCopier.copy(ShowData.class, "summary-index.html", options[DESTDIR].value, "index.html");
118             FormattedFileWriter.copyIncludeHtmls(options[DESTDIR].value);
119 
120             ToolUtilities.registerExtraTransliterators();
121 
122             // Factory collationFactory = Factory
123             // .make(sourceDir.replace("incoming/vetted/","common/") + "../collation/", ".*");
124             // ExtractCollationRules collationRules = new ExtractCollationRules();
125 
126             locales = new TreeSet<>(cldrFactory.getAvailable());
127             new CldrUtility.MatcherFilter(options[MATCH].value).retainAll(locales);
128             // Set paths = new TreeSet();
129             Set<PathHeader> prettySet = new TreeSet<>();
130 
131             CLDRFile.Status status = new CLDRFile.Status();
132             LocaleIDParser localeIDParser = new LocaleIDParser();
133 
134             //Map nonDistinguishingAttributes = new LinkedHashMap();
135             //CLDRFile parent = null;
136 
137             Map<PathHeader, Relation<String, String>> pathHeaderToValuesToLocale = new TreeMap<>();
138 
139             Set<String> defaultContents = testInfo.getSupplementalDataInfo().getDefaultContentLocales();
140 
141             // get all the locales in a group (with same written language)
142             LanguageTagParser ltp = new LanguageTagParser();
143 
144             LikelySubtags ls = new LikelySubtags();
145 
146             for (String locale : locales) {
147                 if (defaultContents.contains(locale)) {
148                     continue;
149                 }
150                 if (locale.startsWith("supplem") || locale.startsWith("character") || locale.equals("root")) {
151                     continue;
152                 }
153                 String max = ls.maximize(locale);
154                 if (max == null) {
155                     max = locale;
156                 }
157                 String baseLanguage = ls.minimize(ltp.set(max).getLanguageScript());
158                 if (baseLanguage.equals(locale)) {
159                     parentToChildren.put("root", locale);
160                     parentToChildren.put(locale, locale);
161                 } else {
162                     parentToChildren.put(baseLanguage, locale);
163                 }
164             }
165 
166             for (Entry<String, Set<String>> group : parentToChildren.keyValuesSet()) {
167                 String locale = group.getKey();
168                 Set<String> children = group.getValue();
169                 Map<String, CLDRFile> sublocales = new TreeMap<>();
170 
171                 boolean doResolved = localeIDParser.set(locale).getRegion().length() == 0;
172                 String languageSubtag = localeIDParser.getLanguage();
173                 //boolean isLanguageLocale = locale.equals(languageSubtag);
174 
175                 CLDRFile file = cldrFactory.make(locale, true);
176                 if (file.isNonInheriting())
177                     continue; // skip supplementals
178 
179                 // get all of the paths
180                 Set<String> allPaths = new HashSet<>();
181                 file.forEach(allPaths::add);
182 
183                 if (!locale.equals("root")) {
184                     for (String childLocale : children) {
185                         CLDRFile childCldrFile = cldrFactory.make(childLocale, false);
186                         if (childCldrFile != null) {
187                             childCldrFile.forEach(allPaths::add);
188                         }
189                         sublocales.put(childLocale, childCldrFile);
190                     }
191                 }
192 
193                 boolean showEnglish = !languageSubtag.equals("en");
194                 CoverageLevel2 coverageLevel = CoverageLevel2.getInstance(testInfo.getSupplementalDataInfo(), locale);
195 
196                 // put into set of simpler paths
197                 // and filter if necessary
198                 int skippedCount = 0;
199                 int aliasedCount = 0;
200                 int inheritedCount = 0;
201                 prettySet.clear();
202                 for (Iterator<String> it2 = allPaths.iterator(); it2.hasNext();) {
203                     String path = it2.next();
204                     if (path.indexOf("/alias") >= 0) {
205                         skippedCount++;
206                         continue; // skip code fllback
207                     }
208                     if (path.indexOf("/usesMetazone") >= 0) {
209                         skippedCount++;
210                         continue; // skip code fllback
211                     }
212                     if (path.indexOf("/references") >= 0) {
213                         skippedCount++;
214                         continue; // skip references
215                     }
216                     if (path.indexOf("[@alt=\"proposed") >= 0) {
217                         skippedCount++;
218                         continue; // skip code fllback
219                     }
220                     if (path.indexOf("/identity") >= 0) {
221                         skippedCount++;
222                         continue; // skip code fllback
223                     }
224                     PathHeader prettyString = prettyPathMaker.fromPath(path);
225                     if (prettyString.getSectionId() != SectionId.Special) {
226                         prettySet.add(prettyString);
227                     }
228                 }
229 
230                 PrintWriter pw = FileUtilities.openUTF8Writer(targetDir, locale + ".html");
231 
232                 String[] headerAndFooter = new String[2];
233 
234                 getChartTemplate(
235                     "Locale Data Summary for " + getLocaleNameAndCode(locale),
236                     ToolConstants.CHART_DISPLAY_VERSION,
237                     "<script>" + System.lineSeparator()
238                         + "if (location.href.split('?')[1].split(',')[0]=='hide') {" + System.lineSeparator()
239                         + "document.write('<style>');" + System.lineSeparator()
240                         + "document.write('.xx {display:none}');" + System.lineSeparator()
241                         + "document.write('</style>');" + System.lineSeparator() + "}" + System.lineSeparator()
242                         + "</script>",
243                     headerAndFooter, locale.equals("root") ? "Main Charts Index" : null, false);
244                 pw.println(headerAndFooter[0]);
245                 showLinks(pw, locale);
246                 showChildren(pw, locale);
247                 if (true) {
248                     pw.println("<p><b>Aliased/Inherited: </b><a href='" + locale
249                         + ".html?hide'>Hide</a> <a href='" + locale
250                         + ".html'>Show </a></p>");
251                 }
252                 pw.println("<table border=\"1\" cellpadding=\"2\" cellspacing=\"0\">");
253 
254                 pw.println("<tr><th>No</th>"
255                     + "<th width='10%'>Section</th>"
256                     + "<th width='10%'>Page</th>"
257                     + "<th width='10%'>Header</th>"
258                     + "<th width='10%'>Code</th>"
259                     + (showEnglish ? "<th>English</th>" : "")
260                     + "<th>Native</th>"
261                     + "<th>Sublocales…</th>"
262                     + "</tr>");
263 
264                 int count = 0;
265                 PathHeader oldParts = null;
266 
267                 Relation<String, String> childValueToLocales = Relation.of(
268                     new TreeMap<String, Set<String>>(), TreeSet.class);
269 
270                 for (PathHeader prettyPath : prettySet) {
271                     String path = prettyPath.getOriginalPath();
272                     boolean zeroOutEnglish = path.indexOf("/references") < 0;
273 
274                     String source = file.getSourceLocaleID(path, status);
275                     boolean isAliased = !status.pathWhereFound.equals(path);
276                     if (isAliased) {
277                         aliasedCount++;
278                         continue;
279                     }
280                     String value = file.getStringValue(path);
281 
282                     //String baileyValue = file.getBaileyValue(path, null, null);
283                     boolean isInherited = !source.equals(locale); // !CldrUtility.equals(baileyValue, value);
284                     if (isInherited) {
285                         inheritedCount++;
286                     }
287 
288                     //StringBuffer tempDraftRef = new StringBuffer();
289 
290                     String lastValue = null;
291                     boolean lastEquals = false;
292 
293                     childValueToLocales.clear();
294 
295                     for (Entry<String, CLDRFile> s : sublocales.entrySet()) {
296                         String newChildValue = s.getValue().getStringValue(path);
297                         if (newChildValue == null
298                             || CldrUtility.equals(newChildValue, value)
299                             || CldrUtility.INHERITANCE_MARKER.equals(newChildValue)) {
300                             continue;
301                         }
302                         childValueToLocales.put(newChildValue, s.getKey());
303                     }
304 
305                     String englishValue = null;
306                     if (zeroOutEnglish) {
307                         englishValue = "";
308                     }
309                     if (showEnglish
310                         && null != (englishValue = english.getStringValue(path))) {
311                     }
312 
313                     String statusClass = isAliased ? (isInherited ? " class='ah'"
314                         : " class='a'") : (isInherited ? " class='h'" : "");
315 
316 //                    Level currentCoverage = coverageLevel.getLevel(path);
317 //                    boolean hideCoverage = false;
318 //                    if (requiredCoverage.compareTo(currentCoverage) < 0) {
319 //                        hideCoverage = true;
320 //                    }
321 
322                     boolean hide = isAliased || isInherited;
323                     if (!hide) {
324                         Relation<String, String> valuesToLocales = pathHeaderToValuesToLocale.get(prettyPath);
325                         if (valuesToLocales == null) {
326                             pathHeaderToValuesToLocale.put(prettyPath, valuesToLocales = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class));
327                         }
328                         valuesToLocales.put(lastValue + "→→" + value, locale);
329                     }
330                     pw.println(
331                         (hide ? "<tr class='xx'><td" : "<tr><td")
332                             + statusClass
333                             + ">"
334                             + CldrUtility.getDoubleLinkedText(Long.toHexString(StringId.getId(path)), String.valueOf(++count))
335                             + addPart(oldParts == null ? null : oldParts.getSection(), prettyPath.getSection())
336                             + addPart(oldParts == null ? null : oldParts.getPage(), prettyPath.getPage())
337                             + addPart(oldParts == null ? null : oldParts.getHeader(), prettyPath.getHeader())
338                             + addPart(oldParts == null ? null : oldParts.getCode(), prettyPath.getCode())
339                             // + "</td><td>" +
340                             // TransliteratorUtilities.toHTML.transliterate(lastElement)
341                             + showValue(showEnglish, englishValue, value, false)
342                             + "</td>");
343                     boolean isExemplar = path.contains("/exemplar");
344                     showValue(pw, value, null, isExemplar);
345                     if (!childValueToLocales.keyValuesSet().isEmpty()) {
346                         for (Entry<String, Set<String>> x : childValueToLocales.keyValuesSet()) {
347                             showValue(pw, x.getKey(), x.getValue(), isExemplar);
348                         }
349                         pw.println("<td class='info'><a class='rightLink' target='CLDR-ST-DOCS' href='http://cldr.org/index/charts#TOC-Summary'>ⓘ</a></td>");
350                     }
351                     pw.println("</tr>");
352                     oldParts = prettyPath;
353                 }
354                 pw.println("</table><br><table>");
355                 pw.println("<tr><td class='a'>Aliased items: </td><td>" + aliasedCount
356                     + "</td></tr>");
357                 pw.println("<tr><td class='h'>Inherited items:</td><td>"
358                     + inheritedCount + "</td></tr>");
359                 if (skippedCount != 0)
360                     pw.println("<tr><td>Omitted items:</td><td>" + skippedCount
361                         + "</td></tr>");
362                 pw.println("</table>");
363 
364                 // pw.println("</body></html>");
365                 pw.println(headerAndFooter[1]);
366                 pw.close();
367             }
368             PrintWriter pw = FileUtilities.openUTF8Writer(targetDir, "all-changed.html");
369             String[] headerAndFooter = new String[2];
370 
371             getChartTemplate(
372                 "Locale Data Summary for ALL-CHANGED",
373                 ToolConstants.CHART_DISPLAY_VERSION,
374                 "",
375                 headerAndFooter, null, false);
376             pw.println(headerAndFooter[0]);
377             pw.println("<table border=\"1\" cellpadding=\"2\" cellspacing=\"0\">");
378             pw.println("<tr>" +
379                 "<th>Section</th>" +
380                 "<th>Page</th>" +
381                 "<th>Header</th>" +
382                 "<th>Code</th>" +
383                 "<th>Old</th>" +
384                 "<th>Changed</th>" +
385                 "<th>Locales</th>" +
386                 "</tr>");
387             for (Entry<PathHeader, Relation<String, String>> entry : pathHeaderToValuesToLocale.entrySet()) {
388                 PathHeader ph = entry.getKey();
389                 Set<Entry<String, Set<String>>> keyValuesSet = entry.getValue().keyValuesSet();
390                 String rowspan = keyValuesSet.size() == 1 ? ">" : " rowSpan='" + keyValuesSet.size() + "'>";
391                 pw
392                     .append("<tr><td class='g'").append(rowspan)
393                     .append(ph.getSectionId().toString())
394                     .append("</td><td class='g'").append(rowspan)
395                     .append(ph.getPageId().toString())
396                     .append("</td><td class='g'").append(rowspan)
397                     .append(ph.getHeader() == null ? "<i>n/a</i>" : ph.getHeader())
398                     .append("</td><td class='g'").append(rowspan)
399                     .append(ph.getCode())
400                     .append("</td>");
401                 boolean addRow = false;
402                 for (Entry<String, Set<String>> s : keyValuesSet) {
403                     String value = s.getKey();
404                     int breakPoint = value.indexOf("→→");
405                     if (addRow) {
406                         pw.append("<tr>");
407                     }
408                     pw.append("<td>")
409                         .append(DataShower.getPrettyValue(value.substring(0, breakPoint)))
410                         .append("</td><td class='v'>")
411                         .append(DataShower.getPrettyValue(value.substring(breakPoint + 2)))
412                         .append("</td><td>")
413                         .append(Joiner.on(", ").join(s.getValue()))
414                         .append("</td></tr>")
415                         .append(System.lineSeparator());
416                     addRow = true;
417                 }
418             }
419             pw.println(headerAndFooter[1]);
420             pw.close();
421         } finally {
422             deltaTime = System.currentTimeMillis() - deltaTime;
423             System.out.println("Elapsed: " + deltaTime / 1000.0 + " seconds");
424             System.out.println("Done");
425         }
426     }
427 
428     public static void showValue(PrintWriter pw, String value, Set<String> locales, boolean isExemplar) {
429         final boolean noLocales = locales == null || locales.isEmpty();
430         pw.println("<td"
431             + (isExemplar ? " style='max-width:20%'" : "")
432             + (noLocales ? "" : " title='" + Joiner.on(", ").join(locales) + "'")
433             + (value == null ? "></i>n/a</i>" : " class='v'" + DataShower.getBidiStyle(value) + ">" + DataShower.getPrettyValue(value))
434             + "</td>");
435     }
436 
437     private static String addPart(String oldPart, String newPart) {
438         String prefix;
439         if (newPart.equals(oldPart)) {
440             prefix = "</td><td class='n'>";
441         } else if (newPart.length() == 0) {
442             prefix = "</td><td>";
443         } else {
444             prefix = "</td><td class='g'>";
445         }
446         return prefix + TransliteratorUtilities.toHTML.transform(newPart);
447     }
448 
449     private static void getScripts() throws IOException {
450         Set<String> locales = cldrFactory.getAvailableLanguages();
451         Set<String> scripts = new TreeSet<>();
452         Map<String, Map<String, Set<String>>> script_name_locales = new TreeMap<>();
453         PrintWriter out = FileUtilities.openUTF8Writer(CLDRPaths.GEN_DIRECTORY, "scriptNames.txt");
454         for (Iterator<String> it = locales.iterator(); it.hasNext();) {
455             String locale = it.next();
456             System.out.println(locale);
457             CLDRFile file = cldrFactory.make(locale, false);
458             if (file.isNonInheriting())
459                 continue;
460             String localeName = file.getName(locale);
461             getScripts(localeName, scripts);
462             if (!scripts.contains("Latn")) {
463                 out
464                     .println(locale + "\t" + english.getName(locale) + "\t"
465                         + localeName);
466             }
467             for (Iterator<String> it2 = UnicodeScripts.iterator(); it2.hasNext();) {
468                 String script = it2.next();
469                 if (script.equals("Latn"))
470                     continue;
471                 String name = file.getName(CLDRFile.SCRIPT_NAME, script);
472                 if (getScripts(name, scripts).contains(script)) {
473                     Map<String, Set<String>> names_locales = script_name_locales.get(script);
474                     if (names_locales == null)
475                         script_name_locales.put(script, names_locales = new TreeMap<>());
476                     Set<String> localeSet = names_locales.get(name);
477                     if (localeSet == null)
478                         names_locales.put(name, localeSet = new TreeSet<>());
479                     localeSet.add(getLocaleNameAndCode(locale));
480                 }
481             }
482         }
483         for (Iterator<String> it2 = UnicodeScripts.iterator(); it2.hasNext();) {
484             String script = it2.next();
485             Object names = script_name_locales.get(script);
486             out.println(script + "\t("
487                 + english.getName(CLDRFile.SCRIPT_NAME, script) + ")\t" + names);
488         }
489         out.close();
490     }
491 
492     static Set<String> UnicodeScripts = Collections.unmodifiableSet(new TreeSet<>(Arrays
493         .asList(new String[] { "Arab", "Armn", "Bali", "Beng", "Bopo", "Brai",
494             "Bugi", "Buhd", "Cans", "Cher", "Copt", "Cprt", "Cyrl", "Deva",
495             "Dsrt", "Ethi", "Geor", "Glag", "Goth", "Grek", "Gujr", "Guru",
496             "Hang", "Hani", "Hano", "Hebr", "Hira", "Hrkt", "Ital", "Kana",
497             "Khar", "Khmr", "Knda", "Laoo", "Latn", "Limb", "Linb", "Mlym",
498             "Mong", "Mymr", "Nkoo", "Ogam", "Orya", "Osma", "Phag", "Phnx",
499             "Qaai", "Runr", "Shaw", "Sinh", "Sylo", "Syrc", "Tagb", "Tale",
500             "Talu", "Taml", "Telu", "Tfng", "Tglg", "Thaa", "Thai", "Tibt",
501             "Ugar", "Xpeo", "Xsux", "Yiii" })));
502 
503     private static Set<String> getScripts(String exemplars, Set<String> results) {
504         results.clear();
505         if (exemplars == null)
506             return results;
507         for (UnicodeSetIterator it = new UnicodeSetIterator(new UnicodeSet()
508             .addAll(exemplars)); it.next();) {
509             int cp = it.codepoint;
510             int script = UScript.getScript(cp);
511             results.add(UScript.getShortName(script));
512         }
513         return results;
514     }
515 
516     private static void showCollation(Factory collationFactory, String locale,
517         ExtractCollationRules collationRules) {
518         CLDRFile collationFile;
519         try {
520             collationFile = collationFactory.make(locale, false);
521         } catch (RuntimeException e) {
522             return; // skip
523         }
524         collationRules.set(collationFile);
525         for (Iterator<String> it = collationRules.iterator(); it.hasNext();) {
526             String key = it.next();
527             System.out.println(key + ": ");
528             String rules = collationRules.getRules(key);
529             System.out.println(rules);
530         }
531     }
532 
533     private static String showValue(boolean showEnglish, String comparisonValue,
534         String mainValue, boolean lastEquals) {
535         return !showEnglish ? ""
536             : comparisonValue == null ? (lastEquals ? "</td><td>=" : "</td><td><i>n/a</i>")
537                 : comparisonValue.length() == 0 ? "</td><td>&nbsp;"
538                     : comparisonValue.equals(mainValue) ? "</td><td>="
539                         : "</td><td class='e'" + DataShower.getBidiStyle(comparisonValue) + ">" + DataShower.getPrettyValue(comparisonValue);
540     }
541 
542     static DataShower dataShower = new DataShower();
543 
544     public static class DataShower {
545         static Transliterator toLatin = Transliterator.getInstance("any-latin");
546 
547         static UnicodeSet BIDI_R = new UnicodeSet(
548             "[[:Bidi_Class=R:][:Bidi_Class=AL:]]");
549 
550         static String getBidiStyle(String cellValue) {
551             return BIDI_R.containsSome(cellValue) ? " style='direction:rtl'" : "";
552         }
553 
554         public static String getPrettyValue(String textToInsert) {
555             String outValue = TransliteratorUtilities.toHTML
556                 .transliterate(textToInsert);
557             String transValue = textToInsert;
558             //String span = "";
559             try {
560                 transValue = toLatin.transliterate(textToInsert);
561             } catch (RuntimeException e) {
562             }
563             if (!transValue.equals(textToInsert)) {
564                 // WARNING: we use toXML in attributes
565                 outValue = "<span title='"
566                     + TransliteratorUtilities.toXML.transliterate(transValue) + "'>"
567                     + outValue + "</span>";
568             }
569             return outValue;
570         }
571     }
572 
573     private static String getNda(Set<String> skipList, Map<String, String> nonDistinguishingAttributes,
574         CLDRFile file, String path, String parentFullPath, StringBuffer draftRef) {
575         draftRef.setLength(0);
576         if (parentFullPath != null && !parentFullPath.equals(path)) {
577             file.getNonDistinguishingAttributes(parentFullPath,
578                 nonDistinguishingAttributes, skipList);
579             if (nonDistinguishingAttributes.size() != 0) {
580                 String parentNda = "";
581                 for (Iterator<String> it = nonDistinguishingAttributes.keySet().iterator(); it
582                     .hasNext();) {
583                     String key = it.next();
584                     String value = nonDistinguishingAttributes.get(key);
585                     if (key.equals("draft") && !value.equals("contributed")) {
586                         if (draftRef.length() != 0)
587                             draftRef.append(",");
588                         draftRef.append("d");
589                     } else if (key.equals("alt")) {
590                         if (draftRef.length() != 0)
591                             draftRef.append(",");
592                         draftRef.append("a");
593                     } else if (key.equals("references")) {
594                         if (draftRef.length() != 0)
595                             draftRef.append(",");
596                         draftRef.append(nonDistinguishingAttributes.get(key));
597                     } else {
598                         if (parentNda.length() != 0)
599                             parentNda += ", ";
600                         parentNda += key + "=" + nonDistinguishingAttributes.get(key);
601                     }
602                 }
603                 if (parentNda.length() != 0) {
604                     parentNda = parentNda.replaceAll("[/]", "/\u200B");
605                     parentNda = "[" + parentNda + "]";
606                 }
607                 return parentNda;
608             }
609         }
610         return "";
611     }
612 
613     private static void showLinks(PrintWriter pw, String locale) {
614         pw.print("<p>");
615         showLinks2(pw, locale);
616         pw.println("</p>");
617     }
618 
619     private static void showLinks2(PrintWriter pw, String locale) {
620         String parent = LocaleIDParser.getParent(locale);
621         if (parent != null) {
622             showLinks2(pw, parent);
623             pw.print(" &gt; ");
624         }
625         pw.println(getLinkedLocaleName(locale));
626     }
627 
628     private static void showChildren(PrintWriter pw, String locale) {
629         LanguageTagParser ltp = new LanguageTagParser();
630         TreeMap<String, String> nameToLocale = new TreeMap<>();
631         for (String sublocale : parentToChildren.get(locale)) {
632             String minimized = LIKELY.minimize(sublocale);
633             nameToLocale.put(getEnglishLocaleName(sublocale), minimized == null ? sublocale : minimized);
634         }
635 
636         boolean isRoot = locale.equals("root");
637         char lastFirstChar = 0;
638         boolean first = true;
639         for (Entry<String, String> nameAndCode : nameToLocale.entrySet()) {
640             String name = nameAndCode.getKey();
641             String localeCode = nameAndCode.getValue();
642             if (localeCode.equals(locale)) {
643                 continue;
644             }
645             char firstChar = name.charAt(0);
646             if (first) {
647                 pw.print(System.lineSeparator() + "<p style='margin-left:5em'>&gt; ");
648                 lastFirstChar = firstChar;
649                 first = false;
650             } else if (firstChar != lastFirstChar) {
651                 pw.print("</p>" + System.lineSeparator() + "<p style='margin-left:5em'> ");
652                 lastFirstChar = firstChar;
653             } else {
654                 pw.print(", ");
655             }
656             if (isRoot) {
657                 pw.print(getLinkedLocaleName(localeCode));
658             } else {
659                 pw.print(getLocaleMinusBaseAndCode(localeCode));
660             }
661         }
662         if (first) {
663             pw.println("</p>");
664         }
665     }
666 
667     public static String getLinkedLocaleName(String locale) {
668         return "<a href='" + locale + ".html'>" + getEnglishLocaleName(locale) + "</a> [" + locale + "]";
669     }
670 
671     public static String getEnglishLocaleName(String locale) {
672         return english.getName(locale, true, CLDRFile.SHORT_ALTS);
673     }
674 
675     private static String getLocaleNameAndCode(String locale) {
676         return getEnglishLocaleName(locale) + " [" + locale + "]";
677     }
678 
679     private static String getLocaleMinusBaseAndCode(String locale) {
680         String full = getEnglishLocaleName(locale);
681         int leftParen = full.indexOf('(');
682         if (leftParen >= 0) {
683             full = full.substring(leftParen + 1, full.lastIndexOf(')'));
684         }
685         return full + " [" + locale + "]";
686     }
687 
688     static final LikelySubtags LIKELY = new LikelySubtags();
689 
690     // public static SimpleDateFormat isoDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm",
691     // ULocale.ENGLISH);
692 
getChartTemplate(String title, String version, String header, String[] headerAndFooter, String indexTitle, boolean showDate)693     static public void getChartTemplate(String title, String version,
694         String header, String[] headerAndFooter, String indexTitle, boolean showDate) throws IOException {
695         if (version == null) {
696             version = ToolConstants.CHART_DISPLAY_VERSION;
697         }
698         VariableReplacer langTag = new VariableReplacer()
699             .add("%title%", title)
700             .add("%header%", header)
701             .add("%index-title%", "Index")
702             .add("%index%", "index.html")
703             .add("%header%", header)
704             .add("%version%", version)
705             .add("%date%", showDate ? CldrUtility.isoFormatDateOnly(new Date()) : "");
706         if (indexTitle != null) {
707             langTag
708                 .add("%index-title%", indexTitle)
709                 .add("%index%", "../index.html");
710         }
711         // "$" //
712         // + "Date" //
713         // + "$") // odd style to keep CVS from substituting
714          // isoDateFormat.format(new Date())
715         BufferedReader input = ToolUtilities.getUTF8Data("chart-template.html");
716         StringBuffer result = new StringBuffer();
717         while (true) {
718             String line = input.readLine();
719             if (line == null)
720                 break;
721             String langTagPattern = langTag.replace(line);
722             if (line.indexOf("%body%") >= 0) {
723                 headerAndFooter[0] = result.toString();
724                 result.setLength(0);
725                 continue;
726             }
727             result.append(langTagPattern).append(System.lineSeparator());
728         }
729         headerAndFooter[1] = result.toString();
730     }
731 }
732