readIPyNotebook = function(filename, rlist = fromJSON(filename, encoding="UTF-8"), ...)
{
fspec = rlist[!(names(rlist) %in% c("metadata", "worksheets"))]
doc = dynDoc$new(metadata = as.list(rlist$metadata), formatSpecific =as.list(fspec))
ws = rlist[["worksheets"]][[1]]
sapply(ws$cells, processEl, parent = doc)
doc
}
#TODO I should probably be using S3 method dispatch for this...
processEl = function(el, parent= NULL)
{
if(is.null(parent))
parent = dynDoc$new()
switch(el$cell_type,
"code" = codeElFromIPN(el, parent),
"markdown" = mdElFromIPN(el, parent),
"raw" = textElFromIPN(el, parent),
"heading" = , # not sure what to do about this yet sections?
"altset" = altsetElFromIPN(el, parent),
"alt" = altElFromIPN(el, parent),
"interactivecode" = intcodeElFromIPN(el, parent),
"task" = taskElFromIPN(el,parent),
#This happens in the code, not independently "output" = outputElFromIPN(el, parent),
stop(paste("Unrecognized cell_type:", el$cell_type))
)
# parent
}
mdElFromIPN = function(el, parent)
{
mdat = splitMetadata(el$metadata)
newel = mdElement$new(content=el$source, encoding = "UTF-8", parent = parent, attributes = mdat$attrs, formatSpecific = list(metadata = mdat$formspec))
parent$addChild(newel)
newel
}
textElFromIPN = function(el, parent)
{
mdat = splitMetadata(el$metadata)
newel = textElement$new(content=el$source, encoding="UTF-8", parent = parent, attributes = mdat$attrs, formatSpecific = list(metadata = mdat$formspec))
parent$addChild(newel)
# parent
newel
}
codeElFromIPN = function(el, parent)
{
newcode = codeToCodeEl(el, parent)
if(!is.null(el$outputs))
{
newouts = lapply(el$outputs, outToOutputEl, code = newcode, parent = parent)
if(!is.list(newouts))
list(newouts)
newcode$outputs = as(newouts, "ElementList")
}
parent$addChild(newcode) # do we also add newouts?
# parent
newcode
}
intcodeElFromIPN = function(el, parent)
{
newcode = intcodeToIntCodeEl(el, parent)
if(!is.null(el$outputs))
{
newouts = lapply(el$outputs, outToOutputEl, code = newcode, parent = parent)
if(!is.list(newouts))
list(newouts)
newcode$outputs = as(newouts, "ElementList")
}
parent$addChild(newcode) # do we also add newouts?
#parent
newcode
}
altsetElFromIPN = function(el, parent)
{
mdat = splitMetadata(el$metadata)
newel = branchSetElement$new(parent = parent, attributes = mdat$attrs, formatSpecific = list(metadata = mdat$formspec))
newel$children = lapply(el$cells, processEl, parent = newel)
parent$addChild(newel)
# parent
newel
}
altElFromIPN = function(el, parent)
{
mdat = splitMetadata(el$metadata)
newel = branchElement$new(parent = parent, attributes = mdat$attrs, formatSpecific = list(metadata = mdat$formspec))
newel$children = lapply(el$cells, processEl, parent = newel)
parent$addChild(newel)
# parent
newel
}
taskElFromIPN = function(el, parent)
{
mdat = splitMetadata(el$metadata)
newel = taskElement$new(parent = parent, attributes = mdat$attrs, formatSpecific = list(metadata = mdat$formspec))
newel$children = lapply(el$cells, processEl, parent = newel)
parent$addChild(newel)
# parent
newel
}
intcodeToIntCodeEl = function(code, parent)
{
content = code$input
language = code$language
formatSpecific = code[!grepl("(input|outputs|widgets|metadata)", names(code))]
widgets = as(lapply(code$widgets, IPyNBWidgetToWidget), "WidgetsList")
if(language == "python" && length(grep("%%R", content)))
{
#TODO: need to deal with arguments passed to the rmagic eg push pull etc
#the first line is the %%R... we need to keep this around so we can put it back, but it shouldn't be in the content(code) for the RCodeElement object
#formatSpecific$rmagicLine = content[1]
#content = content[-1]
#don't include \\n
if(length(content) == 1)
{
# formatSpecific$rmagicLine = gsub("(%%R[^\\n]*)\\n.*", "\\1", content)
formatSpecific$rmagicLine = gsub("(%%R[^\n]*)\n.*", "\\1", content)
#do include \\n
content = gsub("%%R[^\n]*\n", "", content)
} else {
#if it is on multiple lines the %%R must be the first
formatSpecific$rmagicLine = content[1]
content = content[-1]
}
language = "R"
}
#formatSpecific = code[!grepl("(input|outputs|language)", names(code))]
mdat = splitMetadata(code$metadata)
formatSpecific$metadata = mdat$formspec
constructor = switch(language,
python = intPyCodeElement$new,
R = intRCodeElement$new,
stop(paste("Unrecognised language:", language))
)
constructor(content=content, parent = parent, formatSpecific=formatSpecific, widgets = widgets, attributes = mdat$attrs)
}
codeToCodeEl = function(code, parent, interactive = FALSE)
{
content = code$input
if(!length(content))
content = ""
language = code$language
formatSpecific = code[!grepl("(input|outputs|metadata)", names(code))]
if(language == "python" && length(grep("%%R", content)))
{
#TODO: need to deal with arguments passed to the rmagic eg push pull etc
#the first line is the %%R... we need to keep this around so we can put it back, but it shouldn't be in the content(code) for the RCodeElement object
#formatSpecific$rmagicLine = content[1]
#content = content[-1]
#don't include \\n
if(length(content) == 1)
{
formatSpecific$rmagicLine = gsub("(%%R[^\\\n]*)\\\n.*", "\\1", content)
#do include \\n
content = gsub("%%R[^\\\n]*\\\n", "", content)
} else {
#if it is on multiple lines the %%R must be the first
formatSpecific$rmagicLine = content[1]
content = content[-1]
}
language = "R"
}
#formatSpecific = code[!grepl("(input|outputs|language)", names(code))]
mdat = splitMetadata(code$metadata)
formatSpecific$metadata = mdat$formspec
constructor = switch(language,
python = pyCodeElement$new,
R = rCodeElement$new,
stop(paste("Unrecognised language:", language))
)
constructor(content=content, parent = parent, formatSpecific=formatSpecific, attributes = mdat$attrs)
}
outToOutputEl = function(outel, code, parent)
{
if(!is.list(outel))
outel = as.list(outel)
content = outel$text
format = outel$output_type
metadata = outel$metadata
formatSpecific = outel[!grepl("(text|output_type|metadata)", names(outel))]
mdat = splitMetadata(metadata)
attrs = mdat$attrs
formatSpecific$metadata = mdat$formspec
outputElement$new(codeElement = code, parent = parent, content = content, format = format, attributes = attrs, formatSpecific = formatSpecific)
}
writeIPyNB = function(doc, file = NULL, ...)
{
if(!is.null(doc$formatSpecific))
listout = do.call(list, doc$formatSpecific)
else
listout=list()
listout$metadata = doc$metadata
#TODO not handling metadata on worksheets right now.
listout$worksheets = list(list(cells = lapply(doc$children, renderCellIPyNB)))
json = toJSON(listout)
if(!is.null(file))
cat(json, file=file)
else
json
}
splitMetadata = function(meta)
{
if(is.null(meta) || length(meta) == 0)
list(attrs = NULL, formspec = NULL)
attrs = list()
if(!is.list(meta))
meta = as.list(meta)
# if(!is.null(meta[["id"]]))
# attrs$id = meta[["id"]]
# if(!is.null(
attrs = c(id=meta[["id"]], meta[["dyndocmodel"]])
if(!is.list(attrs))
attrs = as.list(attrs)
formspec = meta[-which(names(meta) %in% c("id", "dyndocmodel"))]
list(attrs = attrs, formspec = formspec)
}
removeFancyQuotes = function(content)
{
gsub("(\u201c|\u201d)", "\"", content, useBytes = TRUE)
}
insertFancyQuotes = function(content)
{
content = gsub("\"([^\"]*)\"", replacement= "\u201c\\1\u201d", content, useBytes = TRUE)
single = grep("^[^\"]*\"[^\"]*$", content, useBytes = TRUE)
if(length(single == 1))
content[single] = gsub("\"", "\u201c", useBytes = TRUE, content[single])
else if(length(single) > 1)
{
for(i in seq(1, length(single), by=2))
{
content[ single[i] ] = gsub("\"", "\u201c", useBytes = TRUE, content[single[i]])
content[ single[i+1] ] = gsub("\"", "\u201d", useBytes = TRUE, content[single[i+1]])
}
}
content
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.