🤷‍♂️ RStudio Addin to Search and Copy Emoji
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

182 lines
5.8KB

  1. #' The ermoji emoji gadget
  2. #'
  3. #' Opens a miniUI based Shiny gadget in the RStudio Viewer pane with a
  4. #' searchable table of emoji. Select a row and click the copy desired button.
  5. #'
  6. #' @param clipout Should the gadget attempt to write to the clipboard?
  7. #' @param ... Ignored at this time
  8. #' @name ermoji
  9. #' @return nothing
  10. #' @import shiny
  11. #' @import miniUI
  12. #' @export
  13. ermoji_gadget <- function(clipout = clipr::clipr_available(), ...) {
  14. runGadget(ermoji_ui, ermoji_server(clipout, ...), viewer = paneViewer(500), stopOnCancel = FALSE)
  15. }
  16. #' @rdname ermoji
  17. #' @export
  18. ermoji_shiny <- function(clipout = clipr::clipr_available(), ...) {
  19. shinyApp(ui = ermoji_ui, server = ermoji_server(clipout, ...))
  20. }
  21. ermoji_ui <- miniPage(
  22. title = "ermoji",
  23. tags$head(
  24. tags$style(
  25. HTML("
  26. .dropdown-item {
  27. display: block;
  28. width: 100%;
  29. padding: .25rem 1.5rem;
  30. clear: both;
  31. font-weight: 400;
  32. color: #212529;
  33. text-align: inherit;
  34. white-space: nowrap;
  35. background-color: transparent;
  36. border: 0;
  37. }
  38. .dropdown-menu {
  39. color: #212529;
  40. text-align: left;
  41. list-style: none;
  42. }
  43. ")
  44. )
  45. ),
  46. gadgetTitleBar("ermoji"),
  47. miniContentPanel(
  48. padding = 10,
  49. DT::dataTableOutput('emojis', height = "100%", width = "98%")
  50. ),
  51. miniButtonBlock(
  52. actionButton("copy_name", "Copy :emoji_name:", class = "btn-success"),
  53. tags$div(class = "btn-group dropup", style = "width: 33%",
  54. tags$button(class = "btn btn-warning dropdown-toggle", href = "#",
  55. role = "button", id = "dropdownMenuLink", style = "width: 100%",
  56. "data-toggle" = "dropdown", "aria-haspopup" = "true",
  57. "aria-expanded" = "false",
  58. "Copy Unicode"),
  59. tags$div(class = "dropdown-menu", style = "width: 100%",
  60. "aria-labelledby"="dropdownMenuLink",
  61. actionLink("copy_utf", "Copy unicode", class = "dropdown-item"),
  62. actionLink("copy_html", "Copy HTML", class = "dropdown-item")
  63. )
  64. ),
  65. actionButton("copy_gliph", "Copy Emoji", class = "btn-primary")
  66. )
  67. )
  68. ermoji_server <- function(clipout = clipr::clipr_available()) {
  69. function(input, output, session) {
  70. output$emojis <- DT::renderDataTable({
  71. emojis <- emo::jis
  72. emojis <- emojis[, c('emoji', 'name', "group", "keywords", "aliases")]
  73. emojis$keywords <- vapply(emojis$keywords, function(x) paste(x, collapse = ", "), character(1))
  74. emojis$aliases <- vapply(emojis$aliases, function(x) paste(x, collapse = ", "), character(1))
  75. DT::datatable(
  76. emojis,
  77. rownames = FALSE,
  78. colnames = c("Emoji", "Name", "Group", "Keywords", "Aliases"),
  79. filter = "top",
  80. selection = "single",
  81. fillContainer = TRUE,
  82. # style = 'bootstrap',
  83. class = 'compact stripe nowrap hover',
  84. options = list(
  85. searchHighlight = TRUE,
  86. search = list(regex = TRUE, caseInsensitive = FALSE),
  87. columnDefs = list(list(
  88. className = "dt-center", targets = 0
  89. )),
  90. pageLength = 10,
  91. lengthMenu = c(4, 5, 10)
  92. )
  93. )
  94. })
  95. this_emoji <- reactive({
  96. req(input$emojis_rows_selected)
  97. as.list(emo::jis[input$emojis_rows_selected, ])
  98. })
  99. this_emoji_name <- reactive({
  100. # name <- this_emoji()$name
  101. name <- this_emoji()$aliases[[1]][1]
  102. paste0(":", gsub(" ", "_", name), ":")
  103. })
  104. this_emoji_uni <- reactive({
  105. uni <- paste0("\\U", this_emoji()$runes)
  106. gsub(" ", "\\\\U", uni)
  107. })
  108. this_emoji_html <- reactive({
  109. rune2html(this_emoji()$runes)
  110. })
  111. truncate <- function(x, n = 10) {
  112. if (nchar(x) > n) {
  113. paste0(strtrim(x, n), "...")
  114. } else x
  115. }
  116. observeEvent(input$emojis_rows_selected, {
  117. if (!isTruthy(input$emojis_rows_selected)) {
  118. updateActionButton(session, "copy_name", "Copy :emoji_name:")
  119. updateActionButton(session, "copy_utf", "Copy Unicode")
  120. updateActionButton(session, "copy_html", "Copy HTML")
  121. updateActionButton(session, "copy_gliph", "Copy Emoji")
  122. } else {
  123. updateActionButton(session, "copy_name", paste0("Copy <code>", this_emoji_name(), "</code>"))
  124. updateActionButton(session, "copy_utf", paste("Copy Unicode: <code>", truncate(this_emoji_uni()), "</code>"))
  125. updateActionButton(session, "copy_html", paste("Copy HTML: <code>", escape_html(truncate(this_emoji_html())), "</code>"))
  126. updateActionButton(session, "copy_gliph", paste("Copy", this_emoji()$emoji))
  127. }
  128. })
  129. copy_modal <- function(text) {
  130. showModal(
  131. modalDialog(
  132. title = "Select and Copy",
  133. tags$p("I don't have access to your clipboard. Select the text and", tags$kbd("Ctrl/Cmd"), "+", tags$kbd("c"), "to copy."),
  134. tags$pre(text),
  135. easyClose = TRUE
  136. )
  137. )
  138. }
  139. observeEvent(input$copy_name, {
  140. if (clipout) clipr::write_clip(this_emoji_name()) else copy_modal(this_emoji_name())
  141. })
  142. observeEvent(input$copy_utf, {
  143. if (clipout) clipr::write_clip(this_emoji_uni()) else copy_modal(this_emoji_uni())
  144. })
  145. observeEvent(input$copy_html, {
  146. if (clipout) clipr::write_clip(this_emoji_html()) else copy_modal(this_emoji_html())
  147. })
  148. observeEvent(input$copy_gliph, {
  149. if (clipout) clipr::write_clip(this_emoji()$emoji) else copy_modal(this_emoji()$emoji)
  150. })
  151. observeEvent(input$done, {
  152. stopApp(invisible())
  153. })
  154. observeEvent(input$cancel, {
  155. stopApp(invisible())
  156. })
  157. }
  158. }
  159. escape_html <- function(x) {
  160. x = gsub('&', '&amp;', x)
  161. x = gsub('<', '&lt;', x)
  162. x = gsub('>', '&gt;', x)
  163. x = gsub('"', '&quot;', x)
  164. x
  165. }
  166. rune2html <- function(runes) {
  167. gsub("([0-9A-F]{4,8}) ?", "&#x\\1;", runes)
  168. }