1 /* 2 * RmdFrontMatter.java 3 * 4 * Copyright (C) 2021 by RStudio, PBC 5 * 6 * Unless you have received this program directly from RStudio pursuant 7 * to the terms of a commercial license agreement with RStudio, then 8 * this program is licensed to you under the terms of version 3 of the 9 * GNU Affero General Public License. This program is distributed WITHOUT 10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. 13 * 14 */ 15 package org.rstudio.studio.client.rmarkdown.model; 16 17 import com.google.gwt.core.client.JavaScriptObject; 18 import com.google.gwt.core.client.JsArrayString; 19 20 public class RmdFrontMatter extends JavaScriptObject 21 { RmdFrontMatter()22 protected RmdFrontMatter() 23 { 24 } 25 create()26 public static final native RmdFrontMatter create() /*-{ 27 return { 28 output: {} 29 }; 30 }-*/; 31 setAuthor(String author)32 public final native void setAuthor(String author) /*-{ 33 this.author = author; 34 }-*/; 35 setTitle(String title)36 public final native void setTitle(String title) /*-{ 37 this.title = title; 38 }-*/; 39 setRuntime(String runtime)40 public final native void setRuntime(String runtime) /*-{ 41 this.runtime = runtime; 42 }-*/; 43 addDate()44 public final native void addDate() /*-{ 45 // We use JavaScript to create a date string so the document picks up the 46 // system locale's mechanism for formatting dates. 47 // 48 // IE 11 adds unprintable Unicode characters to the date string that we 49 // need to remove for R Markdown. See case 4300 for details, including a 50 // link to the issue reported against IE in early 2014 (unresolved as of 51 // 3/2015) 52 var date = (new Date()).toLocaleDateString().replace(/\u200e/g, ""); 53 54 // Remove periods as they interfere with rendering to PDF. 55 // see: https://github.com/rstudio/rmarkdown/issues/145#issuecomment-47415718 56 date = date.replace(/\./g, " "); 57 date = date.replace(/\s+/g, " "); 58 59 this.date = date; 60 }-*/; 61 addResourceFile(String file)62 public final native void addResourceFile(String file) /*-{ 63 if (typeof this.resource_files === "undefined") 64 this.resource_files = []; 65 else if (typeof this.resource_files === "string") 66 this.resource_files = [ this.resource_files ]; 67 this.resource_files.push(file); 68 }-*/; 69 getResourceFiles()70 public final native JsArrayString getResourceFiles() /*-{ 71 if (typeof this.resource_files === "undefined") 72 return []; 73 else if (typeof this.resource_files === "string") 74 return [ this.resource_files ]; 75 return this.resource_files; 76 }-*/; 77 getFormatList()78 public final native JsArrayString getFormatList() /*-{ 79 if (typeof this.output === "undefined") 80 return [ "html_document" ]; 81 if (typeof this.output === "string") 82 return [ this.output ]; 83 else 84 return Object.getOwnPropertyNames(this.output); 85 }-*/; 86 getQuartoFormatList()87 public final native JsArrayString getQuartoFormatList() /*-{ 88 if (typeof this.format === "undefined") 89 return [ "html" ]; 90 if (typeof this.format === "string") 91 return [ this.format ]; 92 else 93 return Object.getOwnPropertyNames(this.format); 94 }-*/; 95 getOutputOption( String format)96 public final native RmdFrontMatterOutputOptions getOutputOption( 97 String format) /*-{ 98 if (typeof this.output === "undefined" || 99 this.output === format) 100 return {} 101 102 var options = this.output[format]; 103 if (typeof options === "undefined") 104 return null; 105 else if (options === "default") 106 return {} 107 else 108 return options; 109 }-*/; 110 setOutputOption(String format, JavaScriptObject options)111 public final native void setOutputOption(String format, 112 JavaScriptObject options) /*-{ 113 114 // handle missing output type 115 if (typeof this.output === "undefined") 116 this.output = {}; 117 118 // default format options 119 if (Object.getOwnPropertyNames(options).length === 0) 120 { 121 if (typeof this.output === "string") 122 { 123 // already have a default output format -- convert to list 124 var prevFormat = this.output; 125 this.output = {}; 126 this.output[prevFormat] = "default"; 127 } 128 if (typeof this.output === "object") 129 { 130 if (Object.getOwnPropertyNames(this.output).length === 0) 131 { 132 // no existing output format, use this one with defaults 133 this.output = format; 134 } 135 else 136 { 137 this.output[format] = "default"; 138 } 139 } 140 } 141 else 142 { 143 if (typeof this.output === "string") 144 this.output = {}; 145 this.output[format] = options; 146 } 147 }-*/; 148 applyCreateOptions(String author, String title, String format, boolean isShiny)149 public final void applyCreateOptions(String author, String title, 150 String format, boolean isShiny) 151 { 152 setTitle(title); 153 if (author.length() > 0) 154 { 155 setAuthor(author); 156 addDate(); 157 } 158 if (isShiny) 159 { 160 setRuntime(SHINY_RUNTIME); 161 } 162 if (format != null) 163 { 164 setOutputOption(format, RmdFrontMatterOutputOptions.create()); 165 } 166 } 167 168 public final static String OUTPUT_KEY = "output"; 169 public final static String FORMAT_KEY = "format"; 170 public final static String RUNTIME_KEY = "runtime"; 171 public final static String SERVER_KEY = "server"; 172 public final static String KNIT_KEY = "knit"; 173 174 public final static String DEFAULT_FORMAT = "default"; 175 public final static String SHINY_RUNTIME = "shiny"; 176 public final static String SHINY_PRERENDERED_RUNTIME = "shiny_prerendered"; 177 public final static String SHINY_RMD_RUNTIME = "shinyrmd"; 178 public final static String FRONTMATTER_SEPARATOR = "---\n"; 179 } 180