1 package org.unicode.cldr.tool; 2 3 import java.io.IOException; 4 import java.util.Arrays; 5 import java.util.stream.Collectors; 6 7 import org.unicode.cldr.tool.FormattedFileWriter.Anchors; 8 import org.unicode.cldr.util.CLDRConfig; 9 import org.unicode.cldr.util.CLDRFile; 10 import org.unicode.cldr.util.SupplementalDataInfo; 11 12 import com.ibm.icu.text.ListFormatter; 13 import com.ibm.icu.util.ICUUncheckedIOException; 14 import com.ibm.icu.util.ULocale; 15 16 /** 17 * To add a new chart, subclass this, and add the subclass to {@link ShowLanguages.printLanguageData()}. There isn't much 18 * documentation, so best to look at a simple subclass to see how it works. 19 * @author markdavis 20 */ 21 public abstract class Chart { 22 public static final CLDRConfig CONFIG = CLDRConfig.getInstance(); 23 public static final SupplementalDataInfo SDI = CONFIG.getSupplementalDataInfo(); 24 public static final CLDRFile ENGLISH = CONFIG.getEnglish(); 25 public static final String LS = System.lineSeparator(); 26 27 public static final String PREV_CHART_VERSION_DIRECTORY = ToolConstants.getBaseDirectory(ToolConstants.PREV_CHART_VERSION); 28 public static final String CHART_VERSION_DIRECTORY = ToolConstants.getBaseDirectory(ToolConstants.CHART_VERSION); 29 30 private static final String GITHUB_ROOT = "https://github.com/unicode-org/cldr/blob/master/"; 31 private static final String LDML_SPEC = "https://unicode.org/reports/tr35/"; 32 dataScrapeMessage(String specPart, String testFile, String... dataFiles)33 public static String dataScrapeMessage(String specPart, String testFile, String... dataFiles) { 34 final String dataFileList = dataFiles.length == 0 ? null : 35 ListFormatter.getInstance(ULocale.ENGLISH).format( 36 Arrays.asList(dataFiles).stream() 37 .map(dataFile -> Chart.dataFileLink(dataFile)) 38 .collect(Collectors.toSet())); 39 40 return "<p>" 41 + "<b>Warning:</b> Do not scrape this chart for production data.\n" 42 + "Instead, for the meaning of the fields and data consult the " + Chart.ldmlSpecLink(specPart) 43 + (dataFileList == null ? "" : ", and for machine-readable source data, access " + dataFileList) 44 + (testFile == null ? "" : ", and for test data, access " + dataFileLink(testFile)) 45 + ".</p>\n"; 46 } 47 dataFileLink(String dataFile)48 private static String dataFileLink(String dataFile) { 49 return "<a href='" + GITHUB_ROOT + dataFile + "' target='" + dataFile + "'>" + dataFile + "</a>"; 50 } 51 ldmlSpecLink(String specPart)52 public static String ldmlSpecLink(String specPart) { 53 return "<a href='" + LDML_SPEC + (specPart == null ? "" : specPart) + "' target='units.xml'>LDML specification</a>"; 54 } 55 56 /** 57 * null means a string will be constructed from the title. Otherwise a real file name (no html extension). 58 * @return 59 */ getFileName()60 public String getFileName() { 61 return null; 62 } 63 64 /** 65 * Show Date? 66 * @return 67 */ getExplanation()68 public String getExplanation() { 69 return null; 70 } 71 72 /** 73 * Short explanation that will go just after the title/dates. 74 * @return 75 */ getShowDate()76 public boolean getShowDate() { 77 return true; 78 } 79 80 /** 81 * Directory for the file to go into. 82 * @return 83 */ getDirectory()84 public abstract String getDirectory(); 85 86 /** 87 * Short title for page. Will appear at the top, and in the window title, and in the index. 88 * @return 89 */ getTitle()90 public abstract String getTitle(); 91 92 /** 93 * Work 94 * @param pw 95 * @throws IOException 96 */ writeContents(FormattedFileWriter pw)97 public abstract void writeContents(FormattedFileWriter pw) throws IOException; 98 writeFooter(FormattedFileWriter pw)99 public void writeFooter(FormattedFileWriter pw) throws IOException { 100 standardFooter(pw, AnalyticsID.CLDR); 101 } 102 103 private enum AnalyticsID { 104 CLDR("UA-7672775-1"), ICU("UA-7670213-1"), ICU_GUIDE("UA-7670256-1"), UNICODE("UA-7670213-1"), UNICODE_UTILITY("UA-8314904-1"); 105 public final String id; 106 AnalyticsID(String id)107 private AnalyticsID(String id) { 108 this.id = id; 109 } 110 } 111 standardFooter(FormattedFileWriter pw, AnalyticsID analytics)112 private static void standardFooter(FormattedFileWriter pw, AnalyticsID analytics) throws IOException { 113 pw.write("<div style='text-align: center; margin-top:2em; margin-bottom: 60em;'><br>\n" 114 + "<a href='http://www.unicode.org/unicode/copyright.html'>\n" 115 + "<img src='http://www.unicode.org/img/hb_notice.gif' style='border-style: none; width: 216px; height=50px;' alt='Access to Copyright and terms of use'>" 116 + "</a><br>\n<script src='http://www.unicode.org/webscripts/lastModified.js'></script>" 117 + "</div><script>\n\n" 118 + "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){" 119 + "(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o)," 120 + "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)" 121 + "})(window,document,'script','//www.google-analytics.com/analytics.js','ga');" 122 + " ga('create', '" 123 + analytics 124 + "', 'auto');" 125 + " ga('send', 'pageview');" 126 + "</script>\n"); 127 } 128 writeChart(Anchors anchors)129 public final void writeChart(Anchors anchors) { 130 try ( 131 FormattedFileWriter x = new FormattedFileWriter(getFileName(), getTitle(), getExplanation(), anchors);) { 132 x.setDirectory(getDirectory()); 133 x.setShowDate(getShowDate()); 134 writeContents(x); 135 writeFooter(x); 136 } catch (IOException e) { 137 throw new ICUUncheckedIOException(e); 138 } 139 } 140 getTsvDir(String targetDir, String topicName)141 public static String getTsvDir(String targetDir, String topicName) { 142 String target = targetDir.replaceAll(topicName, "tsv"); 143 if (target.equals(targetDir)) { 144 throw new IllegalArgumentException("Can't make TSV directory from " + targetDir); 145 } 146 return target; 147 } 148 } 149