inst/examples/mathmlPlot.R

#
# Functions to illustrate how to convert a MathML tree
# to an R expression that can be used to annotate a plot 
# as an argument to plotmath.
#

#
# mchar
# mfrac
# !=, ==, <=, >=, etc.to the 
# sqrt,
# sub-, super-script [], ^
# times %*%
# %~~%
# %subset%, %subseteq%
# %supset%, %supseteq%
# %in%
# %notin%
# hat
# tilde
# group("(",list(a, b),"]")
# inf(S)

# sum(x[i],i==1,n)

#
# 
#
#

mathmlPlot <-
function(node)
{
 UseMethod("mathmlPlot",node)
}

mathmlPlot.XMLDocument <-
function(doc)
{
 return(mathmlPlot(doc$doc$children))
}

mathmlPlot.default <-
function(children)
{
  expr <- expression()
  i <- 1
  ok <- (i <= length(children))



  while(ok) {
#cat(i,"\n")
    child <- children[[i]]

   if(is.null(child)) {
       i <- i+1
       ok <- (i <= length(children))
       next
   }

    if(!is.null(class(child)) && class(child) == "XMLComment") {
       i <- i+1
       ok <- (i <= length(children))
       next
    }

#    if(inherits(child,"XMLNode")) {}
#if(is.null(class(child))) cat("Null child:",child,"\n")
     if(xmlName(child) == "mo") {
        op <- child$children[[1]]$value
        if(op == "sum") {
               # needs to get operand.
          tmp <- c(as.name(op), quote(x[i]),mathmlPlot(children[[i+1]]), mathmlPlot(children[[i+2]]))
          expr <- c(expr, tmp)
          i <- i+2
        } else {
          expr <- c(mathmlPlot(child), expr , mathmlPlot(children[[i+1]]))
        }

        mode(expr) <- "call"
        i <- i+1
     } else {
        expr <- c(expr, mathmlPlot(child))
     }

    i <- i+1
    ok <- (i <= length(children))
#cat(i,length(children),"\n")
  }

  return(expr)
}

mathmlPlot.XMLEntityRef <-
function(node)
{
  nm <- xmlName(node)

  val <- switch(nm,
           PlusMinus=as.name("%+-%"),
           InvisibleTimes=as.name("*"),
           int=as.name("integral"),
           infty = as.name("infinity"),
           NULL
          )

  if(is.null(val)) {
    val <- as.name(nm)
  }
    
  
 return(val)
}


mathmlPlot.XMLNode <-
function(node)
{
 nm <- name(node)

  if(nm == "mi" || nm == "ci") {
    val <- c(as.name("italic"),mathmlPlot(node$children))
    mode(val) <- "call"
  } else if(nm == "msqrt") {
     val <- c(as.name("sqrt"), mathmlPlot(node$children))
     mode(val) <- "call"
  } else if(nm == "msubsup") {
    tmp <- c(as.name("^"), mathmlPlot(node$children[[1]]),mathmlPlot(node$children[[2]]))
    mode(tmp) <- "call"
    val <- c(as.name("["), tmp, mathmlPlot(node$children[[3]]))
    mode(val) <- "call"
  } else if(nm == "mrow") {
    val <- mathmlPlot(node$children)
  } else if(nm == "text") {
    val <- node$value
  } else if(nm == "mo") {
    if(inherits(node$children[[1]],"XMLEntityRef"))
      val <- mathmlPlot(node$children[[1]])
    else {
      op <- node$children[[1]]$value
      tmp <- switch(op,
              "=" = "==",
              op)
      val <- as.name(tmp)
      
    }
  } else if(nm == "mfrac") {
    val <- list(as.name("frac"), mathmlPlot(node$children[[1]]), mathmlPlot(node$children[[2]]))
    mode(val) <- "call"
  } else if(nm == "msup" || nm == "msub") {
    op <- switch(nm, "msup" = "^", "msub"="[")
    val <- c(as.name(op), mathmlPlot(node$children[[1]]), mathmlPlot(node$children[[2]]))
    mode(val) <- "call"
  } else if(nm == "mn" || nm == "cn") {
     val <- as.numeric(node$children[[1]]$value)
  } else if(nm == "mstyle") {
    val <- mathmlPlot(node$children)
  } else if(nm == "munderover") {
    val <- mathmlPlot(node$children)
  } else if(nm == "mroot") {
    val <- c(as.name("sqrt"), mathmlPlot(node$children[[1]]), mathmlPlot(node$children[[2]]))
    mode(val) <- "call"
  } else if(nm == "reln") {
    val <- mathmlPlot(node$children)
    mode(val) <- "call"
  } else if(nm == "eq") {
    val <- as.name("==")
  } else if(nm == "geq") {
    val <- as.name(">=")
  } else if(nm == "set") {
       # This looks for a <condition> tag and takes 
       # everything before that as preceeding the `|'
    n <- min( (1:length(node$children))[sapply(node$children, xmlName) == "condition"])
cat("Condition @",n,"\n")
    args <- c(mathmlPlot(node$children[1:(n-1)]), "|", mathmlPlot(node$children[n:length(node$children)]))
    args <- c(as.name("paste"), args)
    mode(args) <- "call"
    val <- list(as.name("group"),"{", args,"}")
    mode(val) <- "call"
  } else if(nm == "bvar") {
    val <- mathmlPlot(node$children)
  } else if(nm == "condition") {
    val <- mathmlPlot(node$children)
  } else if(nm == "interval") {
     sep <- xmlAttrs(node)[["closure"]]
     sep <- switch(sep,
              open=c("(",")"),
              closed=c("[","]"),
              "closed-open"=c("[",")"),
              "open-closed"=c("(","]"),
            )
    els <- mathmlPlot(node$children)
    els <- c(as.name("paste"), els[[1]],",",els[[2]])
    mode(els) <- "call"
    val <- list(as.name("group"),sep[1], els ,sep[2])
    mode(val) <- "call"
  } else if(nm == "power") {
    val <- c(as.name("^"), mathmlPlot(node$children[[1]]), mathmlPlot(node$children[[2]]))
#    mode(val) <- "call"
  } else if(nm == "plus") {
     val <- as.name("+")
  } else if(nm == "apply") {
    val <- mathmlPlot.apply(node)
  }

 return(val)
}

mathmlPlot.apply <-
function(node)
{
  sub <- mathmlPlot(node$children)

  nm <- xmlName(node$children[[1]])
print(node$children[[1]])
  if(nm == "plus" || nm == "minus" || nm == "times" || nm == "div" ) {
print(sub[[1]])
    val <- c(mathmlPlot(node$children[[1]]), sub[[2]], sub[[3]])
    mode(val) <- "call"
    for(i in 4:length(sub)) {
     tmp <- c(mathmlPlot(node$children[[1]]), val, sub[[i]])
     mode(tmp) <- "call"
     val <- tmp
    }
  } else {
   val <- sub
   mode(val) <- "call"
  }

 return(val)
}

Try the XML package in your browser

Any scripts or data that you put into this service are public.

XML documentation built on Nov. 3, 2023, 1:14 a.m.