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