#
# Functions to illustrate how to convert a MathML tree an
# R expression.
#
#
mathml <-
# generic method that converts an XMLNode
# object to an R/S expression.
function(node)
{
UseMethod("mathml", node)
}
mathml.XMLDocument <-
function(doc)
{
return(mathml(doc$doc$children))
}
mathml.default <-
#
# Attempts to create an expression from the Math ML
# document tree given to it.
# This is an example using the mathml.xml and is not
# in any way intended to be a general MathML "interpreter"
# for R/S.
#
function(children)
{
expr <- list()
for(i in children) {
if(class(i) == "XMLComment")
next
expr <- c(expr, mathml(i))
}
return(expr)
}
mergeMathML <-
#
# This takes a list of objects previously converted to R terms
# from MathML and aggregates them by collapsing elements
# such as
# term operator term
# into R calls.
#
# see mathml.XMLNode
#
function(els)
{
#cat("Merging",length(els));
#print(els)
ans <- list()
more <- T
ctr <- 1
while(more) {
i <- els[[ctr]]
if(inherits(i, "MathMLOperator")) {
ans <- c(i, ans, els[[ctr+1]])
mode(ans) <- "call"
ctr <- ctr + 1
} else if(inherits(i,"MathMLGroup")) {
#print("MathMLGroup")
ans <- c(ans, i)
mode(ans) <- "call"
} else
ans <- c(ans, i)
ctr <- ctr + 1
more <- (ctr <= length(els))
}
#cat("Merged: "); print(ans)
return(ans)
}
mathml.XMLNode <-
#
# Interprets a MathML node and converts it
# to an R expression term. This handles tags
# such as mi, mo, mn, msup, mfrac, mrow, mfenced,
# msqrt, mroot
#
# Other tags include:
# msub
# msubsup
# munder
# mover
# munderover
# mmultiscripts
#
# mtable
# mtr
# mtd
#
# set, interval, vector, matrix
# cn
# matrix, matrixrow
# transpose
# Attributes for mfenced: open, close "["
function(node)
{
nm <- name(node)
if(nm == "msup" || nm == "mfrac") {
op <- switch(nm, msup="^", mfrac="/")
a <- mathml(node$children[[1]])
b <- mathml(node$children[[2]])
expr <- list(as.name(op), a, b)
mode(expr) <- "call"
val <- expr
} else if(nm == "mi" || nm == "ci") {
# display in italics
if(!is.null(node$children[[1]]$value))
val <- as.name(node$children[[1]]$value)
} else if(nm == "mo") {
if(inherits(node$children[[1]],"XMLEntityRef")) {
# node$children[[1]]$value
val <- as.name("*")
class(val) <- "MathMLOperator"
} else {
# operator
tmp <- node$children[[1]]$value
if(!is.null(tmp)) {
if(tmp == "=") {
# or we could use "=="
# to indicate equality, not assignment.
tmp <- "<-"
}
val <- as.name(tmp)
class(val) <- "MathMLOperator"
}
}
} else if(nm == "text") {
val <- node$value
} else if(nm == "matrix"){
val <- mathml.matrix(node)
} else if(nm == "vector"){
val <- mathml.vector(node)
} else if(nm == "mn" || nm == "cn") {
# number tag.
if(!is.null(node$children[[1]]$value))
val <- as.numeric(node$children[[1]]$value)
} else if(nm == "mrow" || nm == "mfenced" || nm == "msqrt" || nm == "mroot") {
# group of elements (displayed in a single row)
ans <- vector("list", length(node$children))
ctr <- 1
for(i in node$children) {
ans[[ctr]] <- mathml(i)
#cat(ctr,i$name,length(ans),"\n")
ctr <- ctr + 1
}
ans <- mergeMathML(ans)
# if this is an mfenced, msqrt or mroot element, add the
# enclosing parentheses or function call.
# ....
if(nm == "msqrt") {
ans <- c(as.name("sqrt"), ans)
mode(ans) <- "call"
} else if(nm == "mfenced") {
class(ans) <- "MathMLGroup"
}
val <- ans
} else if(nm == "reln") {
val <- mathml(node$children)
mode(val) <- "call"
} else if(nm == "eq") {
val <- as.name("==")
} else if(nm == "apply") {
val <- mathml(node$children)
cat("apply:",length(val),"\n")
print(val)
mode(val) <- "call"
} else if(nm == "times") {
val <- as.name("%*%")
} else if(nm == "transpose") {
val <- as.name("t")
}
return(val)
}
mathml.matrix <-
#
#
#
#
function(node)
{
m <- matrix(character(1), length(node$children), length(node$children[[1]]$children))
i <- 1
for(row in node$children) {
j <- 1
for(cell in row$children) {
tmp <- mathml(cell)
m[i,j] <- as.character((tmp))
j <- j + 1
}
i <- i + 1
}
print(m)
return(m)
}
mathml.vector <-
function(node)
{
ans <- character(length(node$children))
for(i in 1:length(node$children)) {
tmp <- mathml(node$children[[i]])
ans[i] <- as.character(tmp)
}
print(ans)
return(ans)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.