• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.unicode.cldr.tool;
2 
3 import java.io.IOException;
4 import java.util.List;
5 
6 import org.unicode.cldr.util.CLDRFile;
7 
8 import com.ibm.icu.impl.Row.R4;
9 
10 public class ChartLanguageMatching extends Chart {
11 
main(String[] args)12     public static void main(String[] args) {
13         new ChartLanguageMatching().writeChart(null);
14     }
15 
16     @Override
getDirectory()17     public String getDirectory() {
18         return FormattedFileWriter.CHART_TARGET_DIR;
19     }
20 
21     @Override
getTitle()22     public String getTitle() {
23         return "Language Matching";
24     }
25 
26     @Override
getExplanation()27     public String getExplanation() {
28         return "<p>Language Matching data is used to match the user’s desired language/locales against an application’s supported languages/locales. "
29             + "For more information, see "
30             + "<a href='http://unicode.org/reports/tr35/#LanguageMatching'>Language Matching</a>. "
31             + "The latest release data for this chart is in "
32             + "<a href='http://unicode.org/cldr/latest/common/supplemental/languageInfo.xml'>languageInfo.xml</a>. "
33             + "The matching process is approximately:<p>"
34             + "<ul>"
35             + "<li>The rules are tested—in order—for matches, with the first one winning.</li>"
36             + "<li>Any exact match between fields has zero distance.</li>"
37             + "<li>The placeholder (*) matches any code (of that type). "
38             + "For the last field in Supported, it must be different than Desired.</li>"
39             + "<li>The <i>Distance</i> indicates how close the match is, where identical fields have distance = 0. </li>"
40             + "<li>A ⬌︎ in the <i>Sym?</i> column indicates that the distance is symmetric, "
41             + "and is thus used for both directions: Supported→Desired and Desired→Supported. "
42             + "A → indicates that the distance is <i>not</i> symmetric: this is usually a <i>fallback</i> match.</li>"
43             + "</ul>";
44     }
45 
46     @Override
writeContents(FormattedFileWriter pw)47     public void writeContents(FormattedFileWriter pw) throws IOException {
48         TablePrinter tablePrinter = new TablePrinter()
49             .addColumn("Desired", "class='source'", null, "class='source'", true)
50             .addColumn("Supported", "class='source'", null, "class='source'", true)
51             .addColumn("D. Code", "class='source'", null, "class='source'", true)
52             .setBreakSpans(true)
53             .addColumn("S. Code", "class='source'", null, "class='source'", true)
54             .setBreakSpans(true)
55             .addColumn("Distance", "class='target'", null, "class='target'", true)
56             .addColumn("Sym?", "class='target'", null, "class='target'", true);
57 
58         for (String type : SDI.getLanguageMatcherKeys()) {
59             pw.write("<h2>Type=" + type + "</h2>");
60             List<R4<String, String, Integer, Boolean>> data = SDI.getLanguageMatcherData(type);
61             for (R4<String, String, Integer, Boolean> row : data) {
62                 // <languageMatch desired="gsw" supported="de" percent="96" oneway="true" /> <!-- All Swiss speakers can read High German -->
63 
64                 tablePrinter.addRow()
65                     //.addCell(ENGLISH.getName(locale))
66                     .addCell(getName(row.get0(), true))
67                     .addCell(getName(row.get1(), false))
68                     .addCell(row.get0())
69                     .addCell(row.get1())
70                     .addCell((100 - row.get2()))
71                     .addCell(row.get3() ? "→" : "⬌")
72                     .finishRow();
73             }
74             pw.write(tablePrinter.toTable());
75             tablePrinter.clearRows();
76         }
77     }
78 
getName(String codeWithStars, boolean user)79     private String getName(String codeWithStars, boolean user) {
80         if (!codeWithStars.contains("*") && !codeWithStars.contains("$")) {
81             return ENGLISH.getName(codeWithStars, true, CLDRFile.SHORT_ALTS);
82         }
83         String[] parts = codeWithStars.split("_");
84         if (parts[0].equals("*")) {
85             parts[0] = "xxx";
86         }
87         if (parts.length > 1 && parts[1].equals("*")) {
88             parts[1] = "Xxxx";
89         }
90         String parts2orig = "XY";
91         if (parts.length > 2) {
92             parts2orig = parts[2];
93             if (parts[2].equals("*")) {
94                 parts[2] = "XX";
95             } else if (parts[2].startsWith("$")) {
96                 parts[2] = "XY";
97             }
98         }
99         String result = ENGLISH.getName(String.join("_", parts), true, CLDRFile.SHORT_ALTS);
100         if (user) {
101             result = result
102                 .replace("Xxxx", "any-script")
103                 .replace("xxx", "any-language")
104                 .replace("XX", "any-region")
105                 .replace("XY", parts2orig);
106         } else {
107             result = replaceStar(result);
108         }
109         return result;
110     }
111 
replaceStar(String result)112     private String replaceStar(String result) {
113         String temp = result.replace("XX", "any-other-region");
114         temp = temp.equals(result) ? temp.replace("Xxxx", "any-other-script") : temp.replace("Xxxx", "any-script");
115         temp = temp.equals(result) ? temp.replace("xxx", "any-other-language") : temp.replace("xxx", "any-language");
116         return temp;
117     }
118 }
119