Repository: incubator-freemarker-docgen Updated Branches: refs/heads/master 3f34f5638 -> b69ded483
Added features so that the non-binary output files will contain a configured copyright header comment Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/commit/b69ded48 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/tree/b69ded48 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/diff/b69ded48 Branch: refs/heads/master Commit: b69ded483275ad4d1c0be1f7dee043eff9b6ea93 Parents: 3f34f56 Author: ddekany <ddek...@apache.org> Authored: Fri Jan 1 20:25:30 2016 +0100 Committer: ddekany <ddek...@apache.org> Committed: Fri Jan 1 20:25:30 2016 +0100 ---------------------------------------------------------------------- .../org/freemarker/docgen/CJSONInterpreter.java | 4 +- src/main/org/freemarker/docgen/TextUtil.java | 39 ++++++ src/main/org/freemarker/docgen/Transform.java | 129 ++++++++++++++++--- .../org/freemarker/docgen/statics/fonts/NOTICE | 19 +++ .../docgen/statics/fonts/README-BUILD.txt | 19 --- .../freemarker/docgen/statics/fonts/icomoon.svg | 1 + .../docgen/templates/eclipse-toc.ftlx | 5 + .../org/freemarker/docgen/templates/page.ftlh | 5 + .../freemarker/docgen/templates/sitemap.ftlx | 5 + .../freemarker/docgen/templates/toc-json.ftl | 3 + 10 files changed, 193 insertions(+), 36 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/blob/b69ded48/src/main/org/freemarker/docgen/CJSONInterpreter.java ---------------------------------------------------------------------- diff --git a/src/main/org/freemarker/docgen/CJSONInterpreter.java b/src/main/org/freemarker/docgen/CJSONInterpreter.java index 615b555..8b23cfe 100644 --- a/src/main/org/freemarker/docgen/CJSONInterpreter.java +++ b/src/main/org/freemarker/docgen/CJSONInterpreter.java @@ -774,7 +774,7 @@ final class CJSONInterpreter { c = tx.charAt(p); - // Map: + // JSON Object: if (c == '{') { Object nr; p++; @@ -815,7 +815,7 @@ final class CJSONInterpreter { return res; //! } - // List: + // JSON array: if (c == '[') { p++; List<Object> res = new ArrayList<Object>(); http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/blob/b69ded48/src/main/org/freemarker/docgen/TextUtil.java ---------------------------------------------------------------------- diff --git a/src/main/org/freemarker/docgen/TextUtil.java b/src/main/org/freemarker/docgen/TextUtil.java index ed3b47e..5e6f8ae 100644 --- a/src/main/org/freemarker/docgen/TextUtil.java +++ b/src/main/org/freemarker/docgen/TextUtil.java @@ -18,6 +18,11 @@ */ package org.freemarker.docgen; +import java.io.FileNotFoundException; +import java.io.IOException; + +import freemarker.template.utility.StringUtil; + final class TextUtil { // Can't be instantiated @@ -262,5 +267,39 @@ final class TextUtil { return sb.toString(); } + + public static String detectEOL(String s, String defaultEOL) { + int unixEOLs = 0; + int windowsEOLs = 0; + int macEOLs = 0; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '\n') { + unixEOLs++; + } + if (c == '\r') { + if (i + 1 < s.length() && s.charAt(i + 1) == '\n') { + i++; + windowsEOLs++; + } else { + macEOLs++; + } + } + } + + if (unixEOLs > windowsEOLs && unixEOLs > macEOLs) { + return "\n"; + } else if (windowsEOLs > unixEOLs && windowsEOLs > macEOLs) { + return "\r\n"; + } else if (macEOLs > unixEOLs && macEOLs > windowsEOLs) { + return "\r"; + } else { + return defaultEOL; + } + } + + public static String normalizeEOL(final String s, String eol) throws FileNotFoundException, IOException { + return StringUtil.replace(s, "\r\n", eol).replace("\n", eol).replace("\r", eol); + } } http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/blob/b69ded48/src/main/org/freemarker/docgen/Transform.java ---------------------------------------------------------------------- diff --git a/src/main/org/freemarker/docgen/Transform.java b/src/main/org/freemarker/docgen/Transform.java index c1c6e21..5bc998d 100644 --- a/src/main/org/freemarker/docgen/Transform.java +++ b/src/main/org/freemarker/docgen/Transform.java @@ -49,13 +49,19 @@ import static org.freemarker.docgen.DocBook5Constants.VISIBLE_TOPLEVEL_ELEMENTS; import static org.freemarker.docgen.DocBook5Constants.XMLNS_DOCBOOK5; import static org.freemarker.docgen.DocBook5Constants.XMLNS_XLINK; +import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStreamWriter; +import java.io.StringReader; import java.io.Writer; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; @@ -369,7 +375,12 @@ import freemarker.template.utility.StringUtil; * <li><p><tt>showXXELogo</tt> (boolean): Specifies if an * "Edited with XXE" logo should be shown on the generated pages. * Defaults to <tt>false</tt>. - * + * + * <li><p><tt>copyrightStartYear</tt> (String): Used in the page footer copyright notice. + * <li><p><tt>copyrightHolder</tt> (String): Used in the page footer copyright notice. + * <li><p><tt>copyrightCommentFile</tt> (String): The path of a HTML file to the text used inside + * the output files as copyright header comment. If this path is relative, it's relative to the source + * directory. * </ul> * * <li><p><tt>docgen-templates</tt> directory: @@ -402,7 +413,7 @@ import freemarker.template.utility.StringUtil; * <li>You can omit the commas that otherwise would be at the end of the line. * <li>JavaScript comments are supported (<tt>/* ... *<!-- -->/</tt> and * <tt>// ...</tt>) - * <li>If a file is expected to contain a map, like most configuration + * <li>If a file is expected to contain a JSON object, like most configuration * files are, putting the whole thing between <tt>{</tt> and <tt>}</tt> is * optional. * <li>Maps remember the order in which the entries were specified in the @@ -474,6 +485,7 @@ public final class Transform { static final String SETTING_EXTERNAL_BOOKMARKS = "externalBookmarks"; static final String SETTING_COPYRIGHT_HOLDER = "copyrightHolder"; static final String SETTING_COPYRIGHT_START_YEAR = "copyrightStartYear"; + static final String SETTING_COPYRIGHT_COMMENT_FILE = "copyrightCommentFile"; static final String SETTING_SEO_META = "seoMeta"; static final String SETTING_LOGO = "logo"; static final String SETTING_LOGO_KEY_SRC = "src"; @@ -540,6 +552,8 @@ public final class Transform { = SETTING_DEPLOY_URL; private static final String VAR_ONLINE_TRACKER_HTML = SETTING_ONLINE_TRACKER_HTML; + private static final String VAR_COPYRIGHT_COMMENT = "copyrightComment"; + private static final String VAR_COPYRIGHT_JAVA_COMMENT = "copyrightJavaComment"; private static final String VAR_SHOW_EDITORAL_NOTES = "showEditoralNotes"; private static final String VAR_TRANSFORM_START_TIME @@ -766,6 +780,8 @@ public final class Transform { private String copyrightHolder; private Integer copyrightStartYear; + private String copyrightComment; + private String copyrightJavaComment; private Map<String, Map<String, String>> seoMeta; @@ -928,6 +944,14 @@ public final class Transform { copyrightHolder = castSettingToString(cfgFile, settingName, settingValue); } else if (settingName.equals(SETTING_COPYRIGHT_START_YEAR)) { copyrightStartYear = castSettingToInt(cfgFile, settingName, settingValue); + } else if (settingName.equals(SETTING_COPYRIGHT_COMMENT_FILE)) { + copyrightComment = StringUtil.chomp(getFileContentForSetting(cfgFile, settingName, settingValue)); + String eol = TextUtil.detectEOL(copyrightComment, "\n"); + StringBuilder sb = new StringBuilder("/*").append(eol); + new BufferedReader(new StringReader(copyrightComment)).lines() + .forEach(s -> sb.append(" * ").append(s).append(eol)); + sb.append(" */"); + copyrightJavaComment = sb.toString(); } else if (settingName.equals(SETTING_SEO_META)) { Map<String, Object> m = castSettingToMap( cfgFile, settingName, settingValue); @@ -1023,14 +1047,7 @@ public final class Transform { } else if (settingName.equals(SETTING_DEPLOY_URL)) { deployUrl = castSettingToString(cfgFile, settingName, settingValue); } else if (settingName.equals(SETTING_ONLINE_TRACKER_HTML)) { - String onlineTrackerHtmlPath = castSettingToString(cfgFile, settingName, settingValue); - File f = new File(getSourceDirectory(), onlineTrackerHtmlPath); - if (!f.exists()) { - throw newCfgFileException( - cfgFile, SETTING_ONLINE_TRACKER_HTML, - "File not found: " + f.toPath()); - } - onlineTrackerHTML = FileUtil.loadString(f, UTF_8); + onlineTrackerHTML = getFileContentForSetting(cfgFile, settingName, settingValue); } else if (settingName.equals(SETTING_REMOVE_NODES_WHEN_ONLINE)) { removeNodesWhenOnline = Collections.unmodifiableSet(new HashSet<String>( castSettingToStringList(cfgFile, settingName, settingValue))); @@ -1329,6 +1346,10 @@ public final class Transform { fmConfig.setSharedVariable( VAR_COPYRIGHT_START_YEAR, copyrightStartYear); fmConfig.setSharedVariable( + VAR_COPYRIGHT_COMMENT, copyrightComment); + fmConfig.setSharedVariable( + VAR_COPYRIGHT_JAVA_COMMENT, copyrightJavaComment); + fmConfig.setSharedVariable( VAR_TABS, tabs); fmConfig.setSharedVariable( VAR_SECONDARY_TABS, secondaryTabs); @@ -1471,6 +1492,7 @@ public final class Transform { copyCommonStatic("fonts/icomoon.svg"); copyCommonStatic("fonts/icomoon.ttf"); copyCommonStatic("fonts/icomoon.woff"); + copyCommonStatic("fonts/NOTICE"); for (int i = 1; i < 15; i++) { copyCommonStatic("img/callouts/" + i + ".gif"); @@ -1624,7 +1646,7 @@ public final class Transform { } return (String) settingValue; } - + private boolean caseSettingToBoolean(File cfgFile, String settingName, Object settingValue) throws DocgenException { if (!(settingValue instanceof Boolean)) { @@ -1754,10 +1776,87 @@ public final class Transform { return (Map<String, String>) mapEntryValue; } - private void copyCommonStatic(String path) throws IOException { - FileUtil.copyResourceIntoFile( - Transform.class, "statics", path, - new File(destDir, "docgen-resources")); + private String getFileContentForSetting(File cfgFile, + String settingName, Object settingValue) throws DocgenException { + String settingValueStr = castSettingToString(cfgFile, settingName, settingValue); + File f = new File(getSourceDirectory(), settingValueStr); + if (!f.exists()) { + throw newCfgFileException( + cfgFile, settingName, + "File not found: " + f.toPath()); + } + try { + return FileUtil.loadString(f, UTF_8); + } catch (IOException e) { + throw newCfgFileException( + cfgFile, "Error while reading file for setting \"" + settingName + "\": " + f.toPath(), + e); + } + } + + private void copyCommonStatic(String staticFileName) throws IOException, DocgenException { + String resourcePath = "statics/" + staticFileName; + try (InputStream in = Transform.class.getResourceAsStream(resourcePath)) { + if (in == null) { + throw new IOException("Failed to open class-loader resource: " + resourcePath + " relatively to " + + Transform.class.getPackage().getName()); + } + + if (copyrightComment != null && (staticFileName.endsWith(".css") || staticFileName.endsWith(".js"))) { + // ISO-8859-1 will be good enough as far as the resource isn't UTF-16 or EBCDIC: + final Charset fileCharset = StandardCharsets.ISO_8859_1; + String content = FileUtil.loadString(in, fileCharset); + final String eol = TextUtil.detectEOL(content, "\n"); + + // If we have an initial comment, then that must be a copyright header, which we will remove. + if (content.startsWith("/*")) { + int commentEnd = content.indexOf("*/"); + if (commentEnd == -1) { + throw new BugException("Unclosed initial \"/*\" in resource " + resourcePath); + } + commentEnd += 2; + String comment = content.substring(0, commentEnd); + if (!comment.contains("Copyright") && !comment.contains("copyright") + && !comment.contains("License") && !comment.contains("license")) { + throw new BugException("The initial /*...*/ comments doesn't look like a copyright header " + + "in resource " + resourcePath); + } + + // Include an EOL after the comment, if there's any. + if (commentEnd < content.length()) { + char c = content.charAt(commentEnd); + if (c == '\n') { + commentEnd++; + } else if (c == '\r') { + commentEnd++; + if (commentEnd < content.length() && content.charAt(commentEnd) == '\n') { + commentEnd++; + } + } + } + + // Remove existing copyright header: + content = content.substring(commentEnd); + } + + // Add copyright comment: + StringBuilder sb = new StringBuilder(TextUtil.normalizeEOL(copyrightJavaComment, eol)); + sb.append(eol); + if (content.length() > 0 && content.charAt(0) != '\n' && content.charAt(0) != '\r') { + sb.append(eol); + } + sb.append(content); + content = sb.toString(); + + Path destSubdir = destDir.toPath().resolve("docgen-resources"); + Files.createDirectories(destSubdir); + Files.write(destSubdir.resolve(staticFileName), content.getBytes(fileCharset)); + } else { + FileUtil.copyResourceIntoFile( + Transform.class, "statics", staticFileName, + new File(destDir, "docgen-resources")); + } + } } /** http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/blob/b69ded48/src/main/org/freemarker/docgen/statics/fonts/NOTICE ---------------------------------------------------------------------- diff --git a/src/main/org/freemarker/docgen/statics/fonts/NOTICE b/src/main/org/freemarker/docgen/statics/fonts/NOTICE new file mode 100644 index 0000000..4d68649 --- /dev/null +++ b/src/main/org/freemarker/docgen/statics/fonts/NOTICE @@ -0,0 +1,19 @@ +These "icomoon" fonts were generated with https://icomoon.io/app/, from a +selection from these fronts: + +* Entypo pictograms, version 2.0, by Daniel Bruce (www.entypo.com). + Each included pictogram is either licensed under Creative + Commons Attribution-ShareAlike 3.0 (CC BY-SA 3.0) + (http://creativecommons.org/licenses/by-sa/3.0/legalcode), or + under SIL Open Font License 1.1 (http://scripts.sil.org/OFL). + +* Font Awesome by Dave Gandy (http://fontawesome.io), licensed under + SIL Open Font License 1.1 (http://scripts.sil.org/OFL). + +* Material Design icons by Google + (http://google.github.io/material-design-icons/), licensed under + Creative Common Attribution 4.0 International License (CC-BY 4.0) + (https://creativecommons.org/licenses/by/4.0/). + +"selection.json" stores the IcoMoon App selection, and is only stored here +for reproducibility. It's not used for anything. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/blob/b69ded48/src/main/org/freemarker/docgen/statics/fonts/README-BUILD.txt ---------------------------------------------------------------------- diff --git a/src/main/org/freemarker/docgen/statics/fonts/README-BUILD.txt b/src/main/org/freemarker/docgen/statics/fonts/README-BUILD.txt deleted file mode 100644 index 4d68649..0000000 --- a/src/main/org/freemarker/docgen/statics/fonts/README-BUILD.txt +++ /dev/null @@ -1,19 +0,0 @@ -These "icomoon" fonts were generated with https://icomoon.io/app/, from a -selection from these fronts: - -* Entypo pictograms, version 2.0, by Daniel Bruce (www.entypo.com). - Each included pictogram is either licensed under Creative - Commons Attribution-ShareAlike 3.0 (CC BY-SA 3.0) - (http://creativecommons.org/licenses/by-sa/3.0/legalcode), or - under SIL Open Font License 1.1 (http://scripts.sil.org/OFL). - -* Font Awesome by Dave Gandy (http://fontawesome.io), licensed under - SIL Open Font License 1.1 (http://scripts.sil.org/OFL). - -* Material Design icons by Google - (http://google.github.io/material-design-icons/), licensed under - Creative Common Attribution 4.0 International License (CC-BY 4.0) - (https://creativecommons.org/licenses/by/4.0/). - -"selection.json" stores the IcoMoon App selection, and is only stored here -for reproducibility. It's not used for anything. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/blob/b69ded48/src/main/org/freemarker/docgen/statics/fonts/icomoon.svg ---------------------------------------------------------------------- diff --git a/src/main/org/freemarker/docgen/statics/fonts/icomoon.svg b/src/main/org/freemarker/docgen/statics/fonts/icomoon.svg index 0539897..0c1e073 100644 --- a/src/main/org/freemarker/docgen/statics/fonts/icomoon.svg +++ b/src/main/org/freemarker/docgen/statics/fonts/icomoon.svg @@ -1,4 +1,5 @@ <?xml version="1.0" standalone="no"?> +<!-- See NOTICE file for copyright information! --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > <svg xmlns="http://www.w3.org/2000/svg"> <metadata>Generated by IcoMoon</metadata> http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/blob/b69ded48/src/main/org/freemarker/docgen/templates/eclipse-toc.ftlx ---------------------------------------------------------------------- diff --git a/src/main/org/freemarker/docgen/templates/eclipse-toc.ftlx b/src/main/org/freemarker/docgen/templates/eclipse-toc.ftlx index dbe01ae..6ffb2d9 100644 --- a/src/main/org/freemarker/docgen/templates/eclipse-toc.ftlx +++ b/src/main/org/freemarker/docgen/templates/eclipse-toc.ftlx @@ -1,6 +1,11 @@ <#ftl nsPrefixes={"D":"http://docbook.org/ns/docbook"}> <#import "util.ftl" as u> <?xml version="1.0" encoding="utf-8"?> +<#if copyrightComment?hasContent> + <!--<#lt> + ${copyrightComment}<#lt> + --><#lt> +</#if> <?NLS TYPE="org.eclipse.help.toc"?> <#assign http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/blob/b69ded48/src/main/org/freemarker/docgen/templates/page.ftlh ---------------------------------------------------------------------- diff --git a/src/main/org/freemarker/docgen/templates/page.ftlh b/src/main/org/freemarker/docgen/templates/page.ftlh index fc70ec8..fbdfa33 100644 --- a/src/main/org/freemarker/docgen/templates/page.ftlh +++ b/src/main/org/freemarker/docgen/templates/page.ftlh @@ -91,6 +91,11 @@ <#macro page> <!doctype html><#lt> + <#if copyrightComment?hasContent> + <!--<#lt> + ${copyrightComment}<#lt> + --><#lt> + </#if> <html lang="en" class="page-type-${getPageType()?replace(':', '-')?replace('_', '-')}"><#lt> <#nested> </html><#lt> http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/blob/b69ded48/src/main/org/freemarker/docgen/templates/sitemap.ftlx ---------------------------------------------------------------------- diff --git a/src/main/org/freemarker/docgen/templates/sitemap.ftlx b/src/main/org/freemarker/docgen/templates/sitemap.ftlx index 1c87c97..324b016 100644 --- a/src/main/org/freemarker/docgen/templates/sitemap.ftlx +++ b/src/main/org/freemarker/docgen/templates/sitemap.ftlx @@ -18,6 +18,11 @@ </#list> </#macro> <?xml version="1.0" encoding="UTF-8"?> +<#if copyrightComment?hasContent> + <!--<#lt> + ${copyrightComment}<#lt> + --><#lt> +</#if> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <@sitemapUrls tocRoot /> </urlset> http://git-wip-us.apache.org/repos/asf/incubator-freemarker-docgen/blob/b69ded48/src/main/org/freemarker/docgen/templates/toc-json.ftl ---------------------------------------------------------------------- diff --git a/src/main/org/freemarker/docgen/templates/toc-json.ftl b/src/main/org/freemarker/docgen/templates/toc-json.ftl index 28cfc31..fdd35cc 100644 --- a/src/main/org/freemarker/docgen/templates/toc-json.ftl +++ b/src/main/org/freemarker/docgen/templates/toc-json.ftl @@ -1,4 +1,7 @@ <#import "util.ftl" as u> +<#if copyrightComment?hasContent> + ${copyrightJavaComment}<#lt> +</#if> <#macro tocNodeToJSON node> { "title": "${u.getRequiredTitleAsString(node.element)?jsonString}",