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