Skip to content

Commit 1c761b0

Browse files
authored
Merge pull request #53 from dreamRs/editor
New Editor Widget
2 parents 4e2a206 + 75728ed commit 1c761b0

28 files changed

+1248
-6
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: toastui
22
Title: Interactive Tables, Calendars and Charts for the Web
3-
Version: 0.3.4
3+
Version: 0.3.4.9000
44
Authors@R: c(
55
person("Victor", "Perrier", email = "victor.perrier@dreamrs.fr", role = c("aut", "cre", "cph")),
66
person("Fanny", "Meyer", role = "aut"),

NAMESPACE

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ export(datagrid)
3636
export(datagridOutput)
3737
export(datagridOutput2)
3838
export(datagrid_proxy)
39+
export(editor)
40+
export(editorOutput)
41+
export(editor_proxy)
42+
export(editor_proxy_change_preview)
43+
export(editor_proxy_hide)
44+
export(editor_proxy_insert)
45+
export(editor_proxy_show)
3946
export(grid_click)
4047
export(grid_col_button)
4148
export(grid_col_checkbox)
@@ -66,6 +73,7 @@ export(renderCalendar)
6673
export(renderChart)
6774
export(renderDatagrid)
6875
export(renderDatagrid2)
76+
export(renderEditor)
6977
export(reset_grid_theme)
7078
export(set_grid_lang)
7179
export(set_grid_theme)

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# toastui 0.4.0
2+
3+
* New htmlwidget `editor()`, a Markdown WYSIWYG Editor (https://ui.toast.com/tui-editor).
4+
5+
16
# toastui 0.3.4
27

38
* Updated `cal_props()` example.

R/editor-proxy.R

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
2+
#' Proxy for editor htmlwidget
3+
#'
4+
#' @param shinyId single-element character vector indicating the output ID of the
5+
#' chart to modify (if invoked from a Shiny module, the namespace will be added
6+
#' automatically).
7+
#' @param session the Shiny session object to which the chart belongs; usually the
8+
#' default value will suffice.
9+
#'
10+
#' @return A `editor_proxy` object.
11+
#'
12+
#' @family editor proxy methods
13+
#'
14+
#' @export
15+
#'
16+
#' @importFrom shiny getDefaultReactiveDomain
17+
#'
18+
#' @examples
19+
#' \dontrun{
20+
#'
21+
#' # Consider having created a editor widget with
22+
#' editorOutput("my_editor") # UI
23+
#' output$my_editor <- renderEditor({}) # Server
24+
#'
25+
#' # Then you can call proxy methods in observer:
26+
#'
27+
#' # set editor proxy then call a cal_proxy_* function
28+
#' editor_proxy("my_editor") %>%
29+
#' cal_proxy_today()
30+
#'
31+
#' # or directly
32+
#' cal_proxy_today("my_editor")
33+
#'
34+
#' }
35+
editor_proxy <- function(shinyId, session = shiny::getDefaultReactiveDomain()) {
36+
if (is.null(session)) {
37+
stop("editor_proxy must be called from the server function of a Shiny app")
38+
}
39+
if (!is.null(session$ns) && nzchar(session$ns(NULL)) && substring(shinyId, 1, nchar(session$ns(""))) != session$ns("")) {
40+
shinyId <- session$ns(shinyId)
41+
}
42+
structure(
43+
list(
44+
session = session,
45+
id = shinyId,
46+
x = list()
47+
),
48+
class = c("editor_proxy", "htmlwidgetProxy")
49+
)
50+
}
51+
52+
53+
#' Change editor's preview style
54+
#'
55+
#' @param proxy A [editor_proxy()] or `outputId` of the editor
56+
#' @param style Style for the editor : 'tab' or 'vertical'.
57+
#'
58+
#' @return A `editor_proxy` object.
59+
#' @export
60+
#'
61+
#' @family editor proxy methods
62+
#'
63+
#' @example examples/editor-proxy.R
64+
editor_proxy_change_preview <- function(proxy, style = c("tab", "vertical")) {
65+
if (is.character(proxy)) {
66+
proxy <- editor_proxy(proxy)
67+
}
68+
.call_proxy(
69+
proxy = proxy,
70+
name = "editor-change-preview",
71+
style = match.arg(style)
72+
)
73+
}
74+
75+
#' Insert text in an editor
76+
#'
77+
#' @param proxy A [editor_proxy()] or `outputId` of the editor
78+
#' @param text Text to insert.
79+
#'
80+
#' @return A `editor_proxy` object.
81+
#' @export
82+
#'
83+
#' @family editor proxy methods
84+
#'
85+
#' @example examples/editor-proxy.R
86+
editor_proxy_insert <- function(proxy, text) {
87+
if (is.character(proxy)) {
88+
proxy <- editor_proxy(proxy)
89+
}
90+
.call_proxy(
91+
proxy = proxy,
92+
name = "editor-insert-text",
93+
text = text
94+
)
95+
}
96+
97+
98+
#' @title Show/hide an editor
99+
#'
100+
#' @param proxy A [editor_proxy()] `htmlwidget` object.
101+
#'
102+
#' @export
103+
#'
104+
#' @return A `editor_proxy` object.
105+
#'
106+
#' @name editor-proxy-show-hide
107+
#' @family editor proxy methods
108+
#'
109+
#' @example examples/editor-proxy.R
110+
editor_proxy_show <- function(proxy) {
111+
if (is.character(proxy)) {
112+
proxy <- editor_proxy(proxy)
113+
}
114+
.call_proxy(
115+
proxy = proxy,
116+
name = "editor-show"
117+
)
118+
}
119+
120+
#' @export
121+
#' @rdname editor-proxy-show-hide
122+
editor_proxy_hide <- function(proxy) {
123+
if (is.character(proxy)) {
124+
proxy <- editor_proxy(proxy)
125+
}
126+
.call_proxy(
127+
proxy = proxy,
128+
name = "editor-hide"
129+
)
130+
}

R/editor.R

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
#' Create an interactive editor
3+
#'
4+
#' @param ... Options for the editor, see examples or [online reference](https://nhn.github.io/tui.editor/latest/ToastUIEditorCore).
5+
#' @param getMarkdownOnChange,getHTMLOnChange Get editor's content in Shiny application through an input value : `input$<outputId>_(markdown|html)`.
6+
#' @param height,width Height and width for the chart.
7+
#' @param elementId An optional id.
8+
#'
9+
#' @returns An `editor` htmlwidget.
10+
#' @export
11+
#'
12+
#' @example examples/ex-editor.R
13+
editor <- function(...,
14+
getMarkdownOnChange = TRUE,
15+
getHTMLOnChange = TRUE,
16+
width = NULL,
17+
height = NULL,
18+
elementId = NULL) {
19+
20+
x <- list_(
21+
options = list(
22+
usageStatistics = getOption("toastuiUsageStatistics", default = FALSE),
23+
height = "100%",
24+
...
25+
),
26+
getMarkdownOnChange = isTRUE(getMarkdownOnChange),
27+
getHTMLOnChange = isTRUE(getHTMLOnChange)
28+
)
29+
30+
createWidget(
31+
name = "editor",
32+
x = x,
33+
width = width,
34+
height = height,
35+
package = "toastui",
36+
elementId = elementId,
37+
sizingPolicy = sizingPolicy(
38+
padding = 0,
39+
defaultWidth = "100%",
40+
defaultHeight = "100%",
41+
viewer.defaultHeight = "100%",
42+
viewer.defaultWidth = "100%",
43+
knitr.figure = FALSE,
44+
knitr.defaultWidth = "100%",
45+
knitr.defaultHeight = "600px",
46+
browser.fill = TRUE,
47+
viewer.suppress = FALSE,
48+
browser.external = TRUE
49+
)
50+
)
51+
}
52+
53+
54+
#' @importFrom htmltools tagList tags
55+
editor_html <- function(id, style, class, ...) {
56+
tags$div(
57+
id = id,
58+
class = "toastui-editor-container",
59+
style = style,
60+
class = class,
61+
...,
62+
tags$div(id = paste0(id, "-editor"), style = "width:100%;height:100%;")
63+
)
64+
}
65+
66+

R/shiny.R

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,36 @@ chartOutput <- function(outputId, width = "100%", height = "400px"){
123123
#' @export
124124
renderChart <- function(expr, env = parent.frame(), quoted = FALSE) {
125125
if (!quoted) { expr <- substitute(expr) } # force quoted
126-
shinyRenderWidget(expr, datagridOutput, env, quoted = TRUE)
126+
shinyRenderWidget(expr, chartOutput, env, quoted = TRUE)
127127
}
128+
129+
130+
131+
132+
#' @title Shiny bindings for [editor()]
133+
#'
134+
#' @description Output and render functions for using [editor()] within Shiny
135+
#' applications and interactive Rmd documents.
136+
#'
137+
#' @inheritParams renderCalendar
138+
#'
139+
#' @return Output element that can be included in UI. Render function to create output in server.
140+
#'
141+
#' @name editor-shiny
142+
#'
143+
#' @importFrom htmlwidgets shinyWidgetOutput shinyRenderWidget
144+
#'
145+
#' @export
146+
#'
147+
#' @example examples/shiny-editor.R
148+
editorOutput <- function(outputId, width = "100%", height = "600px"){
149+
shinyWidgetOutput(outputId, "editor", width, height, package = "toastui", inline = FALSE)
150+
}
151+
152+
#' @rdname editor-shiny
153+
#' @export
154+
renderEditor <- function(expr, env = parent.frame(), quoted = FALSE) {
155+
if (!quoted) { expr <- substitute(expr) } # force quoted
156+
shinyRenderWidget(expr, editorOutput, env, quoted = TRUE)
157+
}
158+

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ Interactive charts:
5656
![](man/figures/chart-treemap.png)
5757

5858

59+
## Editor
60+
61+
Interactive Markdown WYSIWYG Editor:
62+
63+
![](man/figures/editor.png)
64+
5965

6066
## Development
6167

data-raw/editor-i18n.R

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
# Read i18n editor's options --------------------------------------------------------
3+
4+
lang <- data.table::fread("data-raw/editor-i18n.txt", header = TRUE)
5+
6+
cat(sprintf("import '@toast-ui/editor/dist/i18n/%s';", tools::file_path_sans_ext(lang[[3]][-1])), sep = "\n")

data-raw/editor-i18n.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
| Language Name | i18n File | Registered Code |
2+
| -------------------------- | --------- | --------------- |
3+
| Arabic | ar.js | `ar` |
4+
| Chinese (S) | zh-cn.js | `zh-CN` |
5+
| Chinese (T) | zh-tw.js | `zh-TW` |
6+
| Croatian (Croatia) | hr-hr.js | `hr` or `hr-HR` |
7+
| Czech (Czech Republic) | cs-cz.js | `cs` or `cs-CZ` |
8+
| Dutch (Netherlands) | nl-nl.js | `nl` or `nl-NL` |
9+
| English (United States) | en-us.js | `en` or `en-US` |
10+
| Finnish (Finland) | fi-fi.js | `fi` or `fi-FI` |
11+
| French (France) | fr-fr.js | `fr` or `fr-FR` |
12+
| Galician (Spain) | gl-es.js | `gl` or `gl-ES` |
13+
| German (Germany) | de-de.js | `de` or `de-DE` |
14+
| Italian (Italy) | it-it.js | `it` or `it-IT` |
15+
| Japanese (Japan) | ja-jp.js | `ja` or `ja-JP` |
16+
| Korean (Korea) | ko-kr.js | `ko` or `ko-KR` |
17+
| Norwegian Bokmål (Norway) | nb-no.js | `nb` or `nb-NO` |
18+
| Polish (Poland) | pl-pl.js | `pl` or `pl-PL` |
19+
| Portuguese (Brazil) | pt-br.js | `pt` or `pt-BR` |
20+
| Russian (Russia) | ru-ru.js | `ru` or `ru-RU` |
21+
| Spanish (Castilian, Spain) | es-es.js | `es` or `es-ES` |
22+
| Swedish (Sweden) | sv-se.js | `sv` or `sv-SE` |
23+
| Turkish (Turkey) | tr-tr.js | `tr` or `tr-TR` |
24+
| Ukrainian (Ukraine) | uk-ua.js | `uk` or `uk-UA` |

examples/editor-get-content.R

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
library(shiny)
3+
library(toastui)
4+
5+
ui <- fluidPage(
6+
tags$h2("Get editor's content"),
7+
editorOutput("my_editor"),
8+
tags$b("In markdown :"),
9+
verbatimTextOutput("res_md"),
10+
tags$b("In HTML :"),
11+
verbatimTextOutput("res_html")
12+
)
13+
14+
server <- function(input, output, session) {
15+
16+
output$my_editor <- renderEditor({
17+
editor(
18+
initialEditType = "wysiwyg",
19+
hideModeSwitch = TRUE,
20+
getMarkdownOnChange = TRUE,
21+
getHTMLOnChange = TRUE
22+
)
23+
})
24+
25+
output$res_md <- renderPrint({
26+
input$my_editor_markdown
27+
})
28+
29+
output$res_html <- renderPrint({
30+
input$my_editor_html
31+
})
32+
}
33+
34+
if (interactive())
35+
shinyApp(ui, server)

0 commit comments

Comments
 (0)