1 /*
2  * RmdFormatOptionsHelper.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.ui;
16 
17 import java.util.List;
18 
19 import org.rstudio.core.client.files.FileSystemItem;
20 import org.rstudio.studio.client.common.FilePathUtils;
21 import org.rstudio.studio.client.rmarkdown.model.RmdFrontMatterOutputOptions;
22 import org.rstudio.studio.client.rmarkdown.model.RmdTemplateFormatOption;
23 
24 import com.google.gwt.core.client.JavaScriptObject;
25 
26 public class RmdFormatOptionsHelper
27 {
optionsListToJson( List<RmdFormatOption> options, FileSystemItem document, RmdFrontMatterOutputOptions optionList)28    public final static JavaScriptObject optionsListToJson(
29          List<RmdFormatOption> options,
30          FileSystemItem document,
31          RmdFrontMatterOutputOptions optionList)
32    {
33       if (optionList == null)
34          optionList = RmdFrontMatterOutputOptions.create();
35       for (RmdFormatOption option: options)
36       {
37          if (option.valueIsDefault())
38          {
39             optionList.removeOption(option.getOption().getName());
40          }
41          else
42          {
43             String type = option.getOption().getType();
44             if (option.getValue() == null)
45             {
46                // all nulls are written identically
47                addOption(optionList, option.getOption(), null);
48             }
49             else if (type == RmdTemplateFormatOption.TYPE_BOOLEAN)
50             {
51                addOption(optionList, option.getOption(),
52                          Boolean.parseBoolean(option.getValue()));
53             }
54             else if (type == RmdTemplateFormatOption.TYPE_FLOAT)
55             {
56                addOption(optionList, option.getOption(),
57                          Float.parseFloat(option.getValue()));
58             }
59             else if (type == RmdTemplateFormatOption.TYPE_INTEGER)
60             {
61                addOption(optionList, option.getOption(),
62                          Integer.parseInt(option.getValue()));
63             }
64             else if (type == RmdTemplateFormatOption.TYPE_CHOICE ||
65                      type == RmdTemplateFormatOption.TYPE_STRING)
66             {
67                addOption(optionList, option.getOption(), option.getValue());
68             }
69             else if (type == RmdTemplateFormatOption.TYPE_FILE)
70             {
71                // For file options, compute the path relative to the document
72                // if we're starting with an absolute path
73                if (document != null &&
74                    option.getValue() != null &&
75                    FilePathUtils.pathIsAbsolute(option.getValue()))
76                {
77                   FileSystemItem selFile =
78                         FileSystemItem.createFile(option.getValue());
79                   // this will be null if no relative path can be found; if
80                   // this is the case, we'll use the absolute path as-is
81                   String relativePath =
82                         selFile.getPathRelativeTo(document.getParentPath());
83                   addOption(optionList, option.getOption(),
84                             relativePath == null ? option.getValue() :
85                                                    relativePath);
86                }
87                else
88                {
89                   addOption(optionList, option.getOption(), option.getValue());
90                }
91             }
92          }
93       }
94       return optionList;
95    }
96 
97    // We need one of these per type since JSNI doesn't unbox templated types
98    // for us
addOption(JavaScriptObject optionList, RmdTemplateFormatOption option, boolean value)99    private final native static void addOption (JavaScriptObject optionList,
100          RmdTemplateFormatOption option, boolean value) /*-{
101       optionList[option.option_name] = value;
102    }-*/;
103 
addOption(JavaScriptObject optionList, RmdTemplateFormatOption option, String value)104    private final native static void addOption (JavaScriptObject optionList,
105          RmdTemplateFormatOption option, String value) /*-{
106       optionList[option.option_name] = value;
107    }-*/;
108 
addOption(JavaScriptObject optionList, RmdTemplateFormatOption option, float value)109    private final native static void addOption (JavaScriptObject optionList,
110          RmdTemplateFormatOption option, float value) /*-{
111       optionList[option.option_name] = value;
112    }-*/;
113 
addOption(JavaScriptObject optionList, RmdTemplateFormatOption option, int value)114    private final native static void addOption (JavaScriptObject optionList,
115          RmdTemplateFormatOption option, int value) /*-{
116       optionList[option.option_name] = value;
117    }-*/;
118 }
119