diff --git a/R/process.R b/R/process.R
index 697cee3..506166c 100644
--- a/R/process.R
+++ b/R/process.R
@@ -1,25 +1,29 @@
-#' Split document into metadata and slides
-#'
-#' @param doc path to source file
-#' @return list with metadata and slides
-#' @keywords internal
-#' @noRd
-to_deck <- function(doc){
- txt = str_split_fixed(read_file(doc), '\n---', 2)
- meta = yaml.load(gsub("^---\n+", '', txt[1]))
- cfile = ifelse(is.null(meta$config), 'config.yml', meta$config)
- deck = modifyList(get_config(cfile), c(meta, slides = txt[2]))
- deck$standalone = ifelse(deck$mode == "standalone", TRUE, FALSE)
- return(deck)
-}
-
-#' Split slides into individual slides
-#'
-#' Slides are separated by a newline followed by three horizontal dashes.
-#' An empty new line SHOULD precede the three horizontal dashes, otherwise
-#' it will not be treated as a slide separator
-#' @keywords internal
-#' @noRd
-split_slides <- function(slides, pat = '\n\n---'){
- str_split(slides, pattern = pat)[[1]]
-}
+#' Split document into metadata and slides
+#'
+#' @param doc path to source file
+#' @return list with metadata and slides
+#' @keywords internal
+#' @noRd
+to_deck <- function(doc){
+ txt = str_split_fixed(read_file(doc), '\n---', 2)
+ meta = yaml.load(gsub("^---\n+", '', txt[1]))
+ meta = lapply(meta,function(x){
+ if(class(x)=="list" | length(x)!=1) return(x)
+ return(iconv(x,"UTF-8","UTF-8"))
+ })
+ cfile = ifelse(is.null(meta$config), 'config.yml', meta$config)
+ deck = modifyList(get_config(cfile), c(meta, slides = txt[2]))
+ deck$standalone = ifelse(deck$mode == "standalone", TRUE, FALSE)
+ return(deck)
+}
+
+#' Split slides into individual slides
+#'
+#' Slides are separated by a newline followed by three horizontal dashes.
+#' An empty new line SHOULD precede the three horizontal dashes, otherwise
+#' it will not be treated as a slide separator
+#' @keywords internal
+#' @noRd
+split_slides <- function(slides, pat = '\n\n---'){
+ str_split(slides, pattern = pat)[[1]]
+}
diff --git a/R/render.R b/R/render.R
index b134be8..9325a01 100644
--- a/R/render.R
+++ b/R/render.R
@@ -1,143 +1,145 @@
-#' Render a slide
-#'
-#' @param slide list containing elements of the parsed slide
-#' @param layouts list of layouts
-#' @param payload list containing site and page, useful for blogs
-#' @noRd
-# TOTHINK: Should partials also be passed along?
-render_slide <- function(slide, layouts, payload){
- default = "{{{slide.header}}}\n{{{slide.content}}}"
- layout = layouts[[slide$tpl %||% 'slide']] %||% slide$tpl2 %||% default
- payload = modifyList(payload, list(slide = slide))
- slide$rendered = whisker.render(layout, payload, partials = layouts) %|% update_classes
- raw_slide = !is.null(slide$class) && grepl('RAW', slide$class)
- if (!(raw_slide)){
- slide$rendered = whisker.render(slide$rendered, payload, partials = layouts)
- }
-
- return(slide)
-}
-
-#' Render slides
-#' @noRd
-render_slides <- function(slides, layouts, payload){
- lapply(slides, render_slide, layouts = layouts, payload = payload)
-}
-
-
-#' Render page
-#'
-#' @param page list containing the parsed page
-#' @param payload list containing site and pages
-# TODO: Refactor by splitting code into smaller manageable chunks
-render_page <- function(page, payload, return_page = FALSE, save_payload = FALSE){
- in_dir(dirname(page$file), {
- if (page$mode == 'selfcontained'){
- page$url[['lib']] <- page$url[['lib']] %||% 'libraries'
- with(page, copy_libraries(framework, highlighter, widgets, url$lib))
- if (!is.null(page$ext_widgets)){
- copy_external_widgets(page$ext_widgets, page$url$lib)
- }
- }
-
- # add layouts, urls and stylesheets from frameworks, widgets and assets
- page = page %|% add_urls %|% add_stylesheets %|% add_config_fr
- if (!is.null(page$ext_widgets)){
- page$widgets = c(page$widgets, basename(unlist(page$ext_widgets)))
- }
-
-
- widget_configs = read_configs(page$widgets, page$url$widgets)
- widget_configs = modifyList(widget_configs, read_config('assets', "."))
- widget_configs = modifyList(widget_configs, list(custom = page$assets))
-
- if (page$onefile %?=% TRUE){
- framework_config = read_config(page$framework, file.path(page$url$lib, 'frameworks'))
- highlighter_config = read_config(page$highlighter,
- file.path(page$url$lib, 'highlighters')
- )
- highlighter_config[[1]]$css = file.path(page$url$highlighters,
- page$highlighter, "css", paste0(page$hitheme, '.css')
- )
- widget_configs = c(widget_configs, framework_config, highlighter_config)
- }
-
- page$assets = as.list(sapply(c('css', 'js', 'jshead', 'ready'), function(x){
- return(get_assets(x, widget_configs, standalone = page$onefile))
- }))
-
- layouts = get_layouts(page$url$layouts)
-
- # Quick Fix for Backward Compatibility with Older slidifyLibraries
- path_to_partials = file.path(page$url$framework, 'partials')
- if (file.exists(path_to_partials)){
- partials = get_layouts(path_to_partials)
- } else {
- partials = get_layouts(file.path(page$url$framework, 'layouts'))
- }
- partials = modifyList(partials, list(javascripts = get_javascripts(page)))
-
- payload = modifyList(payload, list(page = page))
-
-
- page$slides = render_slides(page$slides, layouts, payload)
- page$content = paste(lapply(page$slides, pluck('rendered')), collapse = '\n')
- payload$page = page
-
-
- # outputFile = gsub("*.[R]?md$", '.html', page$file)
- outputFile = sprintf("%s.html", page$filename)
- layout = layouts[[page$layout %||% 'deck']]
- if (save_payload){
- save(layout, payload, partials, file = "payload.RData")
- }
- cat(whisker.render(layout, payload, partials = partials), file = outputFile)
-
- # create standalone deck if page mode is standalone
- if (page$mode == 'standalone'){
- outputFile = make_standalone(page, outputFile)
- }
-
- # Extract R Code from Page if purl = TRUE
- if (page$purl %?=% TRUE) purl(page$file)
- })
- if (return_page){ return(page) }
-}
-
-
-#' Render pages
-#'
-#' @noRd
-render_pages <- function(pages, site, tags, ...){
- payload = list(site = site, pages = pages, tags = tags)
- invisible(lapply(pages, render_page, payload = payload, ...))
-}
-
-#' Render deck using layouts
-#'
-#' @keywords internal
-#' @noRd
-# This function has been replaced by render_page and needs to be DEPRECATED
-render_deck <- function(deck, layouts, partials){
- #' Render a slide based on specified layout
- render_slide <- function(slide){
- tpl <- slide$tpl %||% 'slide'
- slide2 <- modifyList(slide, list(deck = deck[names(deck) != 'slides']))
- slide$rendered = whisker.render(layouts[tpl], slide) %|% update_classes
- slide$rendered = whisker.render(slide$rendered, slide2)
- return(slide)
- }
- #' Render slides based on specified layouts
- render_slides <- function(slides){
- lapply(slides, render_slide)
- }
- #' Render stylesheets based on mode
- render_stylesheets <- function(){
- tpl = '{{# css }}\n{{/ css}}'
- whisker.render(tpl)
- }
- #' Render deck
- deck$slides = deck$slides %|% render_slides
- main = deck$layout %||% 'deck'
- whisker.render(layouts[[main]], deck, partials = layouts)
-}
+#' Render a slide
+#'
+#' @param slide list containing elements of the parsed slide
+#' @param layouts list of layouts
+#' @param payload list containing site and page, useful for blogs
+#' @noRd
+# TOTHINK: Should partials also be passed along?
+render_slide <- function(slide, layouts, payload){
+ default = "{{{slide.header}}}\n{{{slide.content}}}"
+ layout = layouts[[slide$tpl %||% 'slide']] %||% slide$tpl2 %||% default
+ payload = modifyList(payload, list(slide = slide))
+ slide$rendered = whisker.render(layout, payload, partials = layouts) %|% update_classes
+ raw_slide = !is.null(slide$class) && grepl('RAW', slide$class)
+ if (!(raw_slide)){
+ slide$rendered = whisker.render(slide$rendered, payload, partials = layouts)
+ }
+
+ return(slide)
+}
+
+#' Render slides
+#' @noRd
+render_slides <- function(slides, layouts, payload){
+ lapply(slides, render_slide, layouts = layouts, payload = payload)
+}
+
+
+#' Render page
+#'
+#' @param page list containing the parsed page
+#' @param payload list containing site and pages
+# TODO: Refactor by splitting code into smaller manageable chunks
+render_page <- function(page, payload, return_page = FALSE, save_payload = FALSE){
+ in_dir(dirname(page$file), {
+ if (page$mode == 'selfcontained'){
+ page$url[['lib']] <- page$url[['lib']] %||% 'libraries'
+ with(page, copy_libraries(framework, highlighter, widgets, url$lib))
+ if (!is.null(page$ext_widgets)){
+ copy_external_widgets(page$ext_widgets, page$url$lib)
+ }
+ }
+
+ # add layouts, urls and stylesheets from frameworks, widgets and assets
+ page = page %|% add_urls %|% add_stylesheets %|% add_config_fr
+ if (!is.null(page$ext_widgets)){
+ page$widgets = c(page$widgets, basename(unlist(page$ext_widgets)))
+ }
+
+
+ widget_configs = read_configs(page$widgets, page$url$widgets)
+ widget_configs = modifyList(widget_configs, read_config('assets', "."))
+ widget_configs = modifyList(widget_configs, list(custom = page$assets))
+
+ if (page$onefile %?=% TRUE){
+ framework_config = read_config(page$framework, file.path(page$url$lib, 'frameworks'))
+ highlighter_config = read_config(page$highlighter,
+ file.path(page$url$lib, 'highlighters')
+ )
+ highlighter_config[[1]]$css = file.path(page$url$highlighters,
+ page$highlighter, "css", paste0(page$hitheme, '.css')
+ )
+ widget_configs = c(widget_configs, framework_config, highlighter_config)
+ }
+
+ page$assets = as.list(sapply(c('css', 'js', 'jshead', 'ready'), function(x){
+ return(get_assets(x, widget_configs, standalone = page$onefile))
+ }))
+
+ layouts = get_layouts(page$url$layouts)
+
+ # Quick Fix for Backward Compatibility with Older slidifyLibraries
+ path_to_partials = file.path(page$url$framework, 'partials')
+ if (file.exists(path_to_partials)){
+ partials = get_layouts(path_to_partials)
+ } else {
+ partials = get_layouts(file.path(page$url$framework, 'layouts'))
+ }
+ partials = modifyList(partials, list(javascripts = get_javascripts(page)))
+
+ payload = modifyList(payload, list(page = page))
+
+
+ page$slides = render_slides(page$slides, layouts, payload)
+ page$content = paste(lapply(page$slides, pluck('rendered')), collapse = '\n')
+ payload$page = page
+
+
+ # outputFile = gsub("*.[R]?md$", '.html', page$file)
+ outputFile = sprintf("%s.html", page$filename)
+ layout = layouts[[page$layout %||% 'deck']]
+ if (save_payload){
+ save(layout, payload, partials, file = "payload.RData")
+ }
+ writeLines(whisker.render(layout, payload, partials = partials),
+ con = outputFile,
+ useBytes = TRUE)
+
+ # create standalone deck if page mode is standalone
+ if (page$mode == 'standalone'){
+ outputFile = make_standalone(page, outputFile)
+ }
+
+ # Extract R Code from Page if purl = TRUE
+ if (page$purl %?=% TRUE) purl(page$file)
+ })
+ if (return_page){ return(page) }
+}
+
+
+#' Render pages
+#'
+#' @noRd
+render_pages <- function(pages, site, tags, ...){
+ payload = list(site = site, pages = pages, tags = tags)
+ invisible(lapply(pages, render_page, payload = payload, ...))
+}
+
+#' Render deck using layouts
+#'
+#' @keywords internal
+#' @noRd
+# This function has been replaced by render_page and needs to be DEPRECATED
+render_deck <- function(deck, layouts, partials){
+ #' Render a slide based on specified layout
+ render_slide <- function(slide){
+ tpl <- slide$tpl %||% 'slide'
+ slide2 <- modifyList(slide, list(deck = deck[names(deck) != 'slides']))
+ slide$rendered = whisker.render(layouts[tpl], slide) %|% update_classes
+ slide$rendered = whisker.render(slide$rendered, slide2)
+ return(slide)
+ }
+ #' Render slides based on specified layouts
+ render_slides <- function(slides){
+ lapply(slides, render_slide)
+ }
+ #' Render stylesheets based on mode
+ render_stylesheets <- function(){
+ tpl = '{{# css }}\n{{/ css}}'
+ whisker.render(tpl)
+ }
+ #' Render deck
+ deck$slides = deck$slides %|% render_slides
+ main = deck$layout %||% 'deck'
+ whisker.render(layouts[[main]], deck, partials = layouts)
+}
diff --git a/R/utils.R b/R/utils.R
index 4a452a8..bca51c4 100644
--- a/R/utils.R
+++ b/R/utils.R
@@ -1,299 +1,299 @@
-#' Run a slide Deck
-runDeck <- function(deckDir = ".", appDir = file.path(deckDir, "apps"),
- shiny = TRUE, ...){
- require(shiny)
- require(slidifyLibraries)
- .slidifyEnv = new.env()
- make_interactive()
- myDeckDir = file.path(deckDir, "libraries")
- if (!file.exists(myDeckDir)){
- dir.create(myDeckDir)
- }
- addResourcePath('libraries', file.path(deckDir, "libraries"))
- addResourcePath('assets', file.path(deckDir, "assets"))
-
- deckDir = normalizePath(deckDir)
- if (file.exists(appDir)){
- appDir = normalizePath(appDir)
- }
-
- render_markdown()
-
- shiny::runApp(list(
- ui = includeDeck(file.path(deckDir, 'index.Rmd')),
- server = function(input, output){
- apps = dir(appDir, pattern = '^app', full = T)
- for (app in apps){
- source(app, local = TRUE)
- }
- if (shiny){
- renderCodeCells(input, output, env = .slidifyEnv, deckDir)
- }
- }
- ), ...)
-}
-
-#' Include a slidify created html document in Shiny
-#' @noRd
-includeDeck <- function(path){
- shiny:::dependsOnFile(path)
- slidifyLibraries::make_interactive()
- slidify(path)
- html_file <- gsub('.Rmd$', '.html', path)
- lines <- c(
- readLines(html_file, warn=FALSE, encoding='UTF-8'),
- ""
- )
- return(HTML(paste(lines, collapse='\r\n')))
- # includeHTML(html_file)
-}
-
-#' Check for equality only if variable exists
-#'
-#' @noRd
-`%?=%` <- function(x, y){
- if (!is.null(x) && x == y){
- TRUE
- } else {
- FALSE
- }
-}
-
-#' Embed local images using base64
-#'
-#' @keywords internal
-#' @param html_in path to input html file
-#' @param html_out path to output html file
-#' @noRd
-embed_images <- function(html_in){
- html <- paste(readLines(html_in, warn = F), collapse = "\n")
- html <- markdown:::.b64EncodeImages(html)
- return(html)
-}
-
-#' Enable library files to be served from CDN
-#'
-#' @noRd
-enable_cdn <- function(html){
- cdn = 'http://slidifylibraries2.googlecode.com/git/inst/libraries/'
- html = gsub("libraries/", cdn, html, fixed = TRUE)
-}
-
-#' Zip vectors into a single list
-#'
-#' @noRd
-zip_vectors <- function(...){
- x = list(...)
- lapply(seq_along(x[[1]]), function(i) lapply(x, pluck(i)))
-}
-
-#' Stolen from Hadley's HOF package
-#'
-#' @keywords internal
-#' @noRd
-pluck <- function (element){
- function(x) x[[element]]
-}
-
-#' Combine stylesheets in a directory
-#'
-#' @param css_dir directory containing stylesheets
-#' @noRd
-combine_css <- function(css_dir){
- css_files = dir(css_dir, pattern = '*.css', full.names = T)
- out_file = file.path(css_dir, 'user.css')
- css = paste(lapply(css_files, read_file), collapse = '\n')
- writeLines(css, out_file)
- return(out_file)
-}
-
-#' Minify stylesheet using YUI Compressor
-#'
-#' @param css_file path to css file
-#' @noRd
-minify_css <- function(css_file){
- yui = system.file('libraries', 'utilities', 'yuicompressor-2.4.7.jar',
- package = 'slidifyLibraries')
- min_css_file = gsub('.css', '.min.css', css_file)
- cmd = 'java -jar %s %s -o %s'
- system(sprintf(cmd, yui, css_file, min_css_file))
- return(min_css_file)
-}
-
-#' Binary operator useful for function composition
-#'
-#' @keywords internal
-#' @noRd
-`%|%` <- function(x, f){
- f(x)
-}
-
-#' Binary operator useful from hadley's staticdocs package
-#'
-#' @keywords internal
-#' @noRd
-"%||%" <- function(a, b) {
- if (!is.null(a)) a else b
-}
-
-
-#' Read a text file into a single string
-#'
-#' @param doc path to text document
-#' @return string with document contents
-#' @keywords internal
-#' @noRd
-read_file <- function(doc, ...){
- paste(readLines(doc, ...), collapse = '\n')
-}
-
-#' Capture patterns matched by regular expression
-#'
-#' @keywords internal
-#' @noRd
-re_capture <- function(pattern, string, ...) {
- rex = list(src = string, names = list(),
- result = regexpr(pattern, string, perl = TRUE, ...))
-
- for (.name in attr(rex$result, 'capture.name')) {
- rex$names[[.name]] = substr(rex$src,
- attr(rex$result, 'capture.start')[,.name],
- attr(rex$result, 'capture.start')[,.name]
- + attr(rex$result, 'capture.length')[,.name]
- - 1)
- }
- return(rex)
-}
-
-#' Convert markdown document into html
-#'
-#' @import markdown
-#' @keywords internal
-#' @noRd
-md2html <- function(md){
- renderMarkdown(text = md, renderer.options = markdownExtensions())
-}
-
-#' Merge two lists by name
-#'
-#' This is a method that merges the contents of one list with another by
-#' adding the named elements in the second that are not in the first.
-#' In other words, the first list is the target template, and the second
-#' one adds any extra elements that it has
-#'
-#' @param x the list to which elements will be added
-#' @param y the list from which elements will be added to x, if they are not
-#' already there by name
-#' @keywords internal
-#' @noRd
-merge_list <- function (x, y, ...){
- if (length(x) == 0)
- return(y)
- if (length(y) == 0)
- return(x)
- i = match(names(y), names(x))
- i = is.na(i)
- if (any(i))
- x[names(y)[which(i)]] = y[which(i)]
- return(x)
-}
-
-#' Filter blanks
-#'
-#' @keywords internal
-#' @noRd
-filter_blank <- function(x){
- Filter(function(y) y != '', x)
-}
-
-#' Check if a package is installed
-#'
-#' @noRd
-is_installed <- function(mypkg) {
- is.element(mypkg, installed.packages()[,1])
-}
-
-#' Execute code in specified directory
-#'
-#' @noRd
-in_dir <- function(dir, expr) {
- if (is.null(getOption('slidify.changedir'))){
- owd = setwd(dir); on.exit(setwd(owd))
- }
- force(expr)
-}
-
-#' Multiple substitutions using gsub
-#'
-#' @noRd
-#' @keywords internal
-mgsub <- function(myrepl, mystring){
- gsub_ <- function(l, x){
- do.call('gsub', list(x = x, pattern = l[1], replacement = l[2]))
- }
- Reduce(gsub_, myrepl, init = mystring, right = T)
-}
-
-#' Create a standalone version of an HTML File
-#'
-#' It works by embedding all images, switching links to use Slidify's googlecode
-#' repository and inlining all user assets.
-#'
-#' @param deck parsed deck
-#' @param html_in html file with library files linked locally
-#' @noRd
-#' @keywords internal
-make_standalone <- function(deck, html_in){
- lib_cdn = paste0(deck$lib_cdn %||% 'http://slidifylibraries2.googlecode.com/git/inst/libraries', '/')
- lib_url = paste0(deck$url$lib, '/')
- html = read_file(html_in, warn = FALSE) %|% markdown:::.b64EncodeImages
- html = gsub(lib_url, lib_cdn, html)
- # html_out = sprintf('%s.html', basename(getwd()))
- cat(html, file = html_in)
- return(html_in)
-}
-
-
-#' Get the rmd source for each slide
-#'
-#' @keywords internal
-#' @noRd
-# Still repeats code and is hence not DRY
-get_slide_rmd <- function(doc){
- paste('---', (doc %|% to_deck)$slides %|% split_slides)
-}
-
-#' Combine two lists, component by component
-#'
-#' @keywords internal
-#' @noRd
-combine_lists <- function(x, y){
- nms = union(names(x), names(y))
- lapply(nms, function(nm){c(x[[nm]], y[[nm]])
- })
-}
-
-view_deck <- function(dir = "."){
- td <- file.path(tempdir(), basename(tempfile(pattern = 'slidify')))
- suppressMessages(copy_dir(".", td))
- tf <- file.path(td, 'index.html')
- rstudio::viewer(tf)
-}
-
-## This app requires OpenCPU 1.0.1 or higher !!!!
-##
-
-#' @export
-slidify_text <- function(text){
- writeLines(text, con="output.Rmd");
- # knit2html("input.Rmd", output="output.html");
- options(slidify.changedir = FALSE)
- slidify('output.Rmd')
- invisible();
-}
+#' Run a slide Deck
+runDeck <- function(deckDir = ".", appDir = file.path(deckDir, "apps"),
+ shiny = TRUE, ...){
+ require(shiny)
+ require(slidifyLibraries)
+ .slidifyEnv = new.env()
+ make_interactive()
+ myDeckDir = file.path(deckDir, "libraries")
+ if (!file.exists(myDeckDir)){
+ dir.create(myDeckDir)
+ }
+ addResourcePath('libraries', file.path(deckDir, "libraries"))
+ addResourcePath('assets', file.path(deckDir, "assets"))
+
+ deckDir = normalizePath(deckDir)
+ if (file.exists(appDir)){
+ appDir = normalizePath(appDir)
+ }
+
+ render_markdown()
+
+ shiny::runApp(list(
+ ui = includeDeck(file.path(deckDir, 'index.Rmd')),
+ server = function(input, output){
+ apps = dir(appDir, pattern = '^app', full = T)
+ for (app in apps){
+ source(app, local = TRUE)
+ }
+ if (shiny){
+ renderCodeCells(input, output, env = .slidifyEnv, deckDir)
+ }
+ }
+ ), ...)
+}
+
+#' Include a slidify created html document in Shiny
+#' @noRd
+includeDeck <- function(path){
+ shiny:::dependsOnFile(path)
+ slidifyLibraries::make_interactive()
+ slidify(path)
+ html_file <- gsub('.Rmd$', '.html', path)
+ lines <- c(
+ readLines(html_file, warn=FALSE, encoding='UTF-8'),
+ ""
+ )
+ return(HTML(paste(lines, collapse='\r\n')))
+ # includeHTML(html_file)
+}
+
+#' Check for equality only if variable exists
+#'
+#' @noRd
+`%?=%` <- function(x, y){
+ if (!is.null(x) && x == y){
+ TRUE
+ } else {
+ FALSE
+ }
+}
+
+#' Embed local images using base64
+#'
+#' @keywords internal
+#' @param html_in path to input html file
+#' @param html_out path to output html file
+#' @noRd
+embed_images <- function(html_in){
+ html <- paste(readLines(html_in, warn = F), collapse = "\n")
+ html <- markdown:::.b64EncodeImages(html)
+ return(html)
+}
+
+#' Enable library files to be served from CDN
+#'
+#' @noRd
+enable_cdn <- function(html){
+ cdn = 'http://slidifylibraries2.googlecode.com/git/inst/libraries/'
+ html = gsub("libraries/", cdn, html, fixed = TRUE)
+}
+
+#' Zip vectors into a single list
+#'
+#' @noRd
+zip_vectors <- function(...){
+ x = list(...)
+ lapply(seq_along(x[[1]]), function(i) lapply(x, pluck(i)))
+}
+
+#' Stolen from Hadley's HOF package
+#'
+#' @keywords internal
+#' @noRd
+pluck <- function (element){
+ function(x) x[[element]]
+}
+
+#' Combine stylesheets in a directory
+#'
+#' @param css_dir directory containing stylesheets
+#' @noRd
+combine_css <- function(css_dir){
+ css_files = dir(css_dir, pattern = '*.css', full.names = T)
+ out_file = file.path(css_dir, 'user.css')
+ css = paste(lapply(css_files, read_file), collapse = '\n')
+ writeLines(css, out_file)
+ return(out_file)
+}
+
+#' Minify stylesheet using YUI Compressor
+#'
+#' @param css_file path to css file
+#' @noRd
+minify_css <- function(css_file){
+ yui = system.file('libraries', 'utilities', 'yuicompressor-2.4.7.jar',
+ package = 'slidifyLibraries')
+ min_css_file = gsub('.css', '.min.css', css_file)
+ cmd = 'java -jar %s %s -o %s'
+ system(sprintf(cmd, yui, css_file, min_css_file))
+ return(min_css_file)
+}
+
+#' Binary operator useful for function composition
+#'
+#' @keywords internal
+#' @noRd
+`%|%` <- function(x, f){
+ f(x)
+}
+
+#' Binary operator useful from hadley's staticdocs package
+#'
+#' @keywords internal
+#' @noRd
+"%||%" <- function(a, b) {
+ if (!is.null(a)) a else b
+}
+
+
+#' Read a text file into a single string
+#'
+#' @param doc path to text document
+#' @return string with document contents
+#' @keywords internal
+#' @noRd
+read_file <- function(doc, ...){
+ paste(readLines(doc,encoding = "UTF-8", ...), collapse = '\n')
+}
+
+#' Capture patterns matched by regular expression
+#'
+#' @keywords internal
+#' @noRd
+re_capture <- function(pattern, string, ...) {
+ rex = list(src = string, names = list(),
+ result = regexpr(pattern, string, perl = TRUE, ...))
+
+ for (.name in attr(rex$result, 'capture.name')) {
+ rex$names[[.name]] = substr(rex$src,
+ attr(rex$result, 'capture.start')[,.name],
+ attr(rex$result, 'capture.start')[,.name]
+ + attr(rex$result, 'capture.length')[,.name]
+ - 1)
+ }
+ return(rex)
+}
+
+#' Convert markdown document into html
+#'
+#' @import markdown
+#' @keywords internal
+#' @noRd
+md2html <- function(md){
+ renderMarkdown(text = md, renderer.options = markdownExtensions())
+}
+
+#' Merge two lists by name
+#'
+#' This is a method that merges the contents of one list with another by
+#' adding the named elements in the second that are not in the first.
+#' In other words, the first list is the target template, and the second
+#' one adds any extra elements that it has
+#'
+#' @param x the list to which elements will be added
+#' @param y the list from which elements will be added to x, if they are not
+#' already there by name
+#' @keywords internal
+#' @noRd
+merge_list <- function (x, y, ...){
+ if (length(x) == 0)
+ return(y)
+ if (length(y) == 0)
+ return(x)
+ i = match(names(y), names(x))
+ i = is.na(i)
+ if (any(i))
+ x[names(y)[which(i)]] = y[which(i)]
+ return(x)
+}
+
+#' Filter blanks
+#'
+#' @keywords internal
+#' @noRd
+filter_blank <- function(x){
+ Filter(function(y) y != '', x)
+}
+
+#' Check if a package is installed
+#'
+#' @noRd
+is_installed <- function(mypkg) {
+ is.element(mypkg, installed.packages()[,1])
+}
+
+#' Execute code in specified directory
+#'
+#' @noRd
+in_dir <- function(dir, expr) {
+ if (is.null(getOption('slidify.changedir'))){
+ owd = setwd(dir); on.exit(setwd(owd))
+ }
+ force(expr)
+}
+
+#' Multiple substitutions using gsub
+#'
+#' @noRd
+#' @keywords internal
+mgsub <- function(myrepl, mystring){
+ gsub_ <- function(l, x){
+ do.call('gsub', list(x = x, pattern = l[1], replacement = l[2]))
+ }
+ Reduce(gsub_, myrepl, init = mystring, right = T)
+}
+
+#' Create a standalone version of an HTML File
+#'
+#' It works by embedding all images, switching links to use Slidify's googlecode
+#' repository and inlining all user assets.
+#'
+#' @param deck parsed deck
+#' @param html_in html file with library files linked locally
+#' @noRd
+#' @keywords internal
+make_standalone <- function(deck, html_in){
+ lib_cdn = paste0(deck$lib_cdn %||% 'http://slidifylibraries2.googlecode.com/git/inst/libraries', '/')
+ lib_url = paste0(deck$url$lib, '/')
+ html = read_file(html_in, warn = FALSE) %|% markdown:::.b64EncodeImages
+ html = gsub(lib_url, lib_cdn, html)
+ # html_out = sprintf('%s.html', basename(getwd()))
+ cat(html, file = html_in)
+ return(html_in)
+}
+
+
+#' Get the rmd source for each slide
+#'
+#' @keywords internal
+#' @noRd
+# Still repeats code and is hence not DRY
+get_slide_rmd <- function(doc){
+ paste('---', (doc %|% to_deck)$slides %|% split_slides)
+}
+
+#' Combine two lists, component by component
+#'
+#' @keywords internal
+#' @noRd
+combine_lists <- function(x, y){
+ nms = union(names(x), names(y))
+ lapply(nms, function(nm){c(x[[nm]], y[[nm]])
+ })
+}
+
+view_deck <- function(dir = "."){
+ td <- file.path(tempdir(), basename(tempfile(pattern = 'slidify')))
+ suppressMessages(copy_dir(".", td))
+ tf <- file.path(td, 'index.html')
+ rstudio::viewer(tf)
+}
+
+## This app requires OpenCPU 1.0.1 or higher !!!!
+##
+
+#' @export
+slidify_text <- function(text){
+ writeLines(text, con="output.Rmd");
+ # knit2html("input.Rmd", output="output.html");
+ options(slidify.changedir = FALSE)
+ slidify('output.Rmd')
+ invisible();
+}
diff --git a/README.md b/README.md
index b140628..8facb60 100644
--- a/README.md
+++ b/README.md
@@ -1,71 +1,22 @@
-![slidify_logo](https://f.cloud.github.com/assets/346288/650134/894eadd0-d455-11e2-8be5-8d463050f4ef.png)
-
-Slidify helps you create and publish beautiful HTML5 presentations from [RMarkdown](http://goo.gl/KKdaf)
-
-## Getting Started
-
-
-### Install ###
-
-Slidify is still under heavy development. You can install it from `github` using the `devtools` package. You will also need `slidifyLibraries` which contains all external libraries required by `slidify`.
-
-```r
-install_github('ramnathv/slidify')
-install_github('ramnathv/slidifyLibraries')
-```
-
-### Initialize ###
-
-You can initialize a presentation by running `create`. This will create a scaffold for your presentation and open an Rmd file for you to edit.
-
-```r
-library(slidify)
-author('mydeck')
-```
-
-### Author ###
-
-Write your presentation in RMarkdown, using a newline followed by three dashes to separate slides. You can mix markdown with code chunks to create a reproducible slide deck.
-
-### Generate ###
-
-Generate your presentation by running `slidify`. This will create a static HTML5 presentation that you can open locally in your browser.
-
-```r
-slidify('index.Rmd')
-```
-
-### Publish ###
-
-```r
-# publish to github
-# create an empty repo on github. replace USER and REPO with your repo details
-publish(user = USER, repo = REPO)
-
-# publish to rpubs
-publish(title = 'My Deck', 'index.html', host = 'rpubs')
-```
-
----
-
-## Customize ##
-
-Slidify is designed to be modular and provides a high degree of customization for the more advanced user. You can access the defaults using `slidifyDefaults()`. It is possible to override options by passing it to `slidify` as a named list or as a `yaml` file.
-
-```text
-framework : slide generation framework to use
-theme : theme to use for styling slide content
-highlighter : tool to use for syntax highlighting
-hitheme : style to use for syntax highlighting
-mode : selfcontained, standalone, draft
-url : paths to lib
-widgets : widgets to include
-```
-
-
-Slidify makes it easy to create, customize and publish, reproducible HTML5 slide decks from [`R Markdown`](http://goo.gl/KKdaf).
-
-It is designed to make it very easy for a HTML novice to generate a crisp, visually appealing `HTML5` slide deck, while at the same time giving advanced users several options to customize their presentation.
-
-The guiding philosophy of `slidify` is to completely separate writing of content from its rendering, so that content can be written once in `R Markdown`, and rendered as an `HTML5` presentation using any of the `HTML5` slide frameworks supported.
-
+![slidify_logo](https://f.cloud.github.com/assets/346288/650134/894eadd0-d455-11e2-8be5-8d463050f4ef.png)
+
+Slidify helps you create and publish beautiful HTML5 presentations from [RMarkdown](http://goo.gl/KKdaf)
+
+fork自ramnathv的[slidify](http://github.com/ramnathv/slidify).为了更好的支持中文,我做了一些修改,希望可以把Windows上中文坑踩过去
+
+This package is forked from Ramnathv's [slidify](http://github.com/ramnathv/slidify).
+In order to use slidify in Windows by Chinese users, I changed some codes.
+
+## Getting Started
+
+
+### Install ###
+
+Slidify is still under heavy development. You can install it from `github` using the `devtools` package. You will also need `slidifyLibraries` which contains all external libraries required by `slidify`.
+
+```r
+install_github('lchiffon/slidify')
+install_github('ramnathv/slidifyLibraries')
+```
+
+