Esempio n. 1
0
		object MathML.MathMLVisitor.Visit(MathMLApplyElement e, object args)
		{
			return ((Area)formatter.Visit(e, args)).BoundingBox;
		}
Esempio n. 2
0
 object MathML.MathMLVisitor.Visit(MathMLApplyElement e, object args)
 {
     return(args);
 }
Esempio n. 3
0
		/// <summary>
		/// Create a XmlElement. This is typically called by the base class when creating a DOM tree
		/// </summary>
		/// <param name="prefix"></param>
		/// <param name="localname"></param>
		/// <param name="nsURI"></param>
		/// <returns></returns>
		public override XmlElement CreateElement(string prefix, string localname, string nsURI)
		{
			XmlElement result = null;
			switch(localname)
			{
				case "math":
					result = new MathMLMathElement(prefix, localname, nsURI, this);
					break;
				case "mi":
				case "mn":
				case "mtext":
					result = new MathMLPresentationToken(prefix, localname, nsURI, this);
					break;
				case "mo":			
					result = new MathMLOperatorElement(prefix, localname, nsURI, this);
					break;
				case "mspace":			
					result = new MathMLSpaceElement(prefix, localname, nsURI, this);
					break;
				case "ms":			
					result = new MathMLStringLitElement(prefix, localname, nsURI, this);
					break;
				case "mglyph":			
					result = new MathMLGlyphElement(prefix, localname, nsURI, this);
					break;
				case "mrow":
				case "merror":
				case "mphantom":			
					result = new MathMLPresentationContainer(prefix, localname, nsURI, this);
					break;
				case "mfrac":			
					result = new MathMLFractionElement(prefix, localname, nsURI, this);
					break;
				case "msqrt":			
				case "mroot":			
					result = new MathMLRadicalElement(prefix, localname, nsURI, this);
					break;
				case "mstyle":			
					result = new MathMLStyleElement(prefix, localname, nsURI, this);
					break;
				case "mpadded":			
					result = new MathMLPaddedElement(prefix, localname, nsURI, this);
					break;
				case "mfenced":			
					result = new MathMLFencedElement(prefix, localname, nsURI, this);
					break;
				case "menclose":			
					result = new MathMLEncloseElement(prefix, localname, nsURI, this);
					break;
				case "msub":
				case "msup":
				case "msubsup":			
					result = new MathMLScriptElement(prefix, localname, nsURI, this);
					break;
				case "munder":			
				case "mover":			
				case "munderover":			
					result = new MathMLUnderOverElement(prefix, localname, nsURI, this);
					break;
				case "mmultiscripts":			
					result = new MathMLMultiScriptsElement(prefix, localname, nsURI, this);
					break;
				case "mtable":			
					result = new MathMLTableElement(prefix, localname, nsURI, this);
					break;
				case "mlabeledtr":			
					result = new MathMLLabeledRowElement(prefix, localname, nsURI, this);
					break;
				case "mtr":			
					result = new MathMLTableRowElement(prefix, localname, nsURI, this);
					break;
				case "mtd":			
					result = new MathMLTableCellElement(prefix, localname, nsURI, this);
					break;
				case "maligngroup":			
					result = new MathMLAlignGroupElement(prefix, localname, nsURI, this);
					break;
				case "malignmark":			
					result = new MathMLAlignMarkElement(prefix, localname, nsURI, this);
					break;
				case "maction":			
					result = new MathMLActionElement(prefix, localname, nsURI, this);
					break;
				case "cn":			
					result = new MathMLCnElement(prefix, localname, nsURI, this);
					break;
				case "ci":			
					result = new MathMLCiElement(prefix, localname, nsURI, this);
					break;
				case "csymbol":			
					result = new MathMLCsymbolElement(prefix, localname, nsURI, this);
					break;
				case "apply":			
					result = new MathMLApplyElement(prefix, localname, nsURI, this);
					break;
				case "fn":			
					result = new MathMLFnElement(prefix, localname, nsURI, this);
					break;
				case "interval":			
					result = new MathMLIntervalElement(prefix, localname, nsURI, this);
					break;
				case "inverse":			
				case "compose":	
				case "ident":		
				case "domain":			
				case "codomain":		
				case "image":		
				case "quotient":			
				case "exp":			
				case "factorial":			
				case "divide":			
				case "max":			
				case "min":			
				case "minus":			
				case "plus":			
				case "power":			
				case "rem":			
				case "times":			
				case "root":			
				case "gcd":			
				case "and":			
				case "or":			
				case "xor":			
				case "not":			
				case "implies":			
				case "forall":			
				case "exists":			
				case "abs":			
				case "conjugate":			
				case "arg":			
				case "real":			
				case "imaginary":			
				case "lcm":			
				case "floor":			
				case "ceiling":			
				case "eq":			
				case "neq":			
				case "gt":			
				case "lt":			
				case "geq":			
				case "leq":			
				case "equivalent":			
				case "approx":			
				case "factorof":			
				case "int":			
				case "diff":			
				case "partialdiff":		
				case "divergence":			
				case "grad":			
				case "curl":			
				case "laplacian":	
				case "union":			
				case "intersect":			
				case "in":			
				case "notin":			
				case "subset":			
				case "prsubset":			
				case "notsubset":			
				case "notprsubset":			
				case "setdiff":
				case "card":			
				case "cartesianproduct":			
				case "sum":			
				case "product":			
				case "limit":			
				case "tendsto":			
				case "ln":			
				case "log":			
				case "sin":			
				case "cos":			
				case "tan":			
				case "sec":			
				case "csc":			
				case "cot":			
				case "sinh":			
				case "cosh":			
				case "tanh":			
				case "sech":			
				case "csch":			
				case "coth":			
				case "arcsin":			
				case "arccos":			
				case "arctan":			
				case "arccosh":			
				case "arccot":			
				case "arccoth":			
				case "arccsc":			
				case "arccsch":			
				case "arcsec":			
				case "arcsech":			
				case "arcsinh":			
				case "arctanh":			
				case "mean":			
				case "sdev":			
				case "variance":			
				case "median":			
				case "mode":			
				case "moment":		
				case "determinant":			
				case "transpose":			
				case "selector":			
				case "vectorproduct":			
				case "scalarproduct":
				case "outerproduct":	
				case "integers":		
				case "reals":	
				case "rationals":	
				case "naturalnumbers":	
				case "complexes":	
				case "primes":	
				case "exponentiale":	
				case "imaginaryi":		
				case "notanumber":
				case "true":	
				case "false":			
				case "emptyset":			
				case "pi":			
				case "eulergamma":			
				case "infinity":			
					result = new MathMLPredefinedSymbol(prefix, localname, nsURI, this);
					break;
				case "condition":			
					result = new MathMLConditionElement(prefix, localname, nsURI, this);
					break;
				case "declare":			
					result = new MathMLDeclareElement(prefix, localname, nsURI, this);
					break;
				case "lambda":			
					result = new MathMLLambdaElement(prefix, localname, nsURI, this);
					break;
				case "piecewise":			
					result = new MathMLPiecewiseElement(prefix, localname, nsURI, this);
					break;
				case "piecev":			
					result = new MathMLCaseElement(prefix, localname, nsURI, this);
					break;
				case "reln":
				case "domainofapplication":	
				case "otherwise":			
				case "lowlimit":			
				case "uplimit":	
				case "degree":	
				case "momentabout":		
				case "logbase": // TODO is this correct, 'logbase' not specified in mathml docs????
					result = new MathMLContentContainer(prefix, localname, nsURI, this);
					break;
				case "bvar":			
					result = new MathMLBvarElement(prefix, localname, nsURI, this);
					break;
				case "set":			
					result = new MathMLSetElement(prefix, localname, nsURI, this);
					break;
				case "list":			
					result = new MathMLListElement(prefix, localname, nsURI, this);
					break;				
				case "vector":			
					result = new MathMLVectorElement(prefix, localname, nsURI, this);
					break;
				case "matrix":			
					result = new MathMLMatrixElement(prefix, localname, nsURI, this);
					break;
				case "matrixrow":			
					result = new MathMLMatrixRowElement(prefix, localname, nsURI, this);
					break;
				case "annotation":			
					result = new MathMLAnnotationElement(prefix, localname, nsURI, this);
					break;
				case "semantics":			
					result = new MathMLSemanticsElement(prefix, localname, nsURI, this);
					break;
				case "annotation-xml":			
					result = new MathMLXMLAnnotationElement(prefix, localname, nsURI, this);
					break;
				case "sep":
					result = new MathMLSeparator(prefix, localname, nsURI, this);
					break;
				case "placeholder":
					result = new MathMLPlaceholderElement(prefix, localname, nsURI, this);
					break;
				default:
					result = base.CreateElement(prefix, localname, nsURI);
					break;
			}
			return result;
		}
Esempio n. 4
0
 object MathML.MathMLVisitor.Visit(MathMLApplyElement e, object args)
 {
     return(((Area)formatter.Visit(e, args)).BoundingBox);
 }
Esempio n. 5
0
        /// <summary>
        /// format an apply element
        /// </summary>
        /// <param name="e"></param>
        /// <param name="args"></param>
        /// <returns></returns>
		public object Visit(MathMLApplyElement e, object args) 
		{
			Area cache = Area.GetArea(e);
			if(cache != null) return cache;

            // document to create tmp elements
			MathMLDocument document = new MathMLDocument();
			Area area = null;
			IFormattingContext ctx = ((IFormattingContext)args).Clone();			

			if(e.Operator is MathMLPredefinedSymbol)
			{
				MathMLPredefinedSymbol predefSymbol = (MathMLPredefinedSymbol)e.Operator;
				PredefinedSymbolInfo info = PredefinedSymbolInfo.Get(predefSymbol.Name);
				if(info != null)
				{
					switch(info.Type)
					{
						case PredefinedSymbolType.Function:
						{
							MathMLNodeList arguments = e.Arguments;
							ArrayList argList = new ArrayList(arguments.Count);
							foreach(Object o in arguments)
							{
								argList.Add(o);
							}
							Area[] areas = new Area[3];
							areas[0] = AreaFactory.String(ctx, info.Value);
							areas[1] = GlyphFactory.GetGlyph(ctx, ctx.Size, PredefinedSymbolInfo.ApplyFunction[0]);
							ctx.Parens = false;
							areas[2] = FormatFencedContainer(e, ctx, argList, new Char[] {','}, "(", ")");
							area = AreaFactory.Horizontal(areas);							
						} break;
						case PredefinedSymbolType.Fraction:
						{
							bool parens = ctx.Parens;
							ctx.Parens = false;
							IEnumerator arguments = e.Arguments.GetEnumerator();
							arguments.MoveNext();
							MathMLElement n = (MathMLElement)arguments.Current;
							Area numerator = (Area)n.Accept(this, ctx);
							// idea is we can have lots of arguments, so keep dividing the numerator
							// by the denominator
							while(arguments.MoveNext())
							{
								MathMLElement d = (MathMLElement)arguments.Current;
								Area denominator = (Area)d.Accept(this, ctx);
								numerator = AreaFactory.Fraction(ctx, numerator, denominator, 5);
							}
							area = numerator;

							if(parens)
							{
								area = FenceArea(ctx, area, ctx.Size, '(', ')');
							}
							
						} break;
						case PredefinedSymbolType.Infix:
						{							
							// make a MathMLOperatorElement for the operator symbol
							MathMLOperatorElement opElement = (MathMLOperatorElement)document.CreateElement("mo");
							XmlNode text = opElement.OwnerDocument.CreateTextNode(info.Value);
							opElement.AppendChild(text);

							int argCount = e.ArgumentCount;

							// count of items + operators
							int itemCount = 2 * argCount - 1;
							
							// list of items to format
							ArrayList items = new ArrayList(itemCount + (info.Parens && ctx.Parens ? 2 : 0));

							// only one arg, so make it a prefix op
							if(argCount == 1)
							{
								items.Add(opElement);
								IEnumerator en = e.Arguments.GetEnumerator();
								en.MoveNext();
								items.Add(en.Current);
							}
							else
							{
								foreach(MathMLElement arg in e.Arguments)
								{
									items.Add(arg);
									if(items.Count + 1 < itemCount)
									{
										items.Add(opElement);
									}
								}
							}

							// add open and close parens if we want them
							if(info.Parens && ctx.Parens)
							{
								MathMLOperatorElement open = (MathMLOperatorElement)document.CreateElement("mo");
								MathMLOperatorElement close = (MathMLOperatorElement)document.CreateElement("mo");
								open.AppendChild(document.CreateTextNode("("));
								close.AppendChild(document.CreateTextNode(")"));
								items.Insert(0, open);
								items.Add(close);
							}

							ctx.Parens = info.ChildParens;						
							area = FormatContainer(e, ctx, items);
						
						} break;
						case PredefinedSymbolType.Postfix:
						{							
							// make a MathMLOperatorElement for the operator symbol
							MathMLOperatorElement opElement = (MathMLOperatorElement)document.CreateElement("mo");
							XmlNode text = opElement.OwnerDocument.CreateTextNode(info.Value);
							opElement.AppendChild(text);
							
							// list of items to format
							ArrayList items = new ArrayList(2 + (info.Parens && ctx.Parens ? 2 : 0));

							// a postfix element only expect one arg							
							IEnumerator en = e.Arguments.GetEnumerator();
							en.MoveNext();
							items.Add(en.Current);
							items.Add(opElement);
							

							// add open and close parens if we want them
							if(ctx.Parens && info.Parens)
							{
								MathMLOperatorElement open = (MathMLOperatorElement)document.CreateElement("mo");
								MathMLOperatorElement close = (MathMLOperatorElement)document.CreateElement("mo");
								open.AppendChild(document.CreateTextNode("("));
								close.AppendChild(document.CreateTextNode(")"));
								items.Insert(0, open);
								items.Add(close);
							}

							ctx.Parens = true;
							area = FormatContainer(e, ctx, items);
						
						} break;
						case PredefinedSymbolType.Root:
						{
							MathMLContentContainer indexElement = null;
							MathMLElement radicandElement = null;
							foreach(XmlNode node in e.ChildNodes)
							{
								if(node == e.Operator)
								{
									continue;
								}
								if(indexElement ==  null && node is MathMLContentContainer && node.Name == "degree")
								{
									indexElement = (MathMLContentContainer)node;
									continue;
								}

								if(radicandElement == null && node is MathMLElement)
								{
									radicandElement = (MathMLElement)node;
								}
							}
							if(radicandElement != null)
							{
                IFormattingContext indexCtx = ctx.Clone();
								indexCtx.ScriptLevel++;
								Area index = (Area)indexElement.Accept(this, indexCtx);
								area = AreaFactory.Radical(ctx, (Area)radicandElement.Accept(this, ctx), index);
							}
						} break;
						case PredefinedSymbolType.Power:
						{
							MathMLNodeList arguments = e.Arguments;
							int argCount = arguments.Count;
							
							Area bseArea = null, scriptArea = null;

							if(argCount > 0) 
							{
                IFormattingContext bseCtx = ctx.Clone();
								bseCtx.Parens = true;
								MathMLElement bse = (MathMLElement)arguments.Item(0);
								bseArea = (Area)bse.Accept(this, bseCtx);
							}

							if(argCount > 1)
							{
                IFormattingContext scriptCtx = ctx.Clone();
								scriptCtx.ScriptLevel++;
								scriptCtx.Parens = true;
								MathMLElement script = (MathMLElement)arguments.Item(1);
								scriptArea = (Area)script.Accept(this, scriptCtx);
							}
                            
							if(bseArea != null)
							{
								area = AreaFactory.Script(ctx, bseArea, null, new Length(LengthType.Undefined), 
									scriptArea, new Length(LengthType.Undefined));
							}
							else
							{
								// TODO error msg
							}
						} break;
						case PredefinedSymbolType.Exp:
						{
							MathMLNodeList arguments = e.Arguments;
							int argCount = arguments.Count;
							
							Area bseArea = null, scriptArea = null;

							MathMLElement baseElm = (MathMLElement)document.CreateElement("mi");
							baseElm.AppendChild(document.CreateTextNode(info.Value));
							bseArea = (Area)baseElm.Accept(this, ctx);

							if(argCount > 0)
							{
                IFormattingContext scriptCtx = ctx.Clone();
								scriptCtx.ScriptLevel++;
								scriptCtx.Parens = true;
								MathMLElement script = (MathMLElement)arguments.Item(0);
								scriptArea = (Area)script.Accept(this, scriptCtx);
							}
                            
							area = AreaFactory.Script(ctx, bseArea, null, new Length(LengthType.Undefined), 
									scriptArea, new Length(LengthType.Undefined));
				
						} break;
						case PredefinedSymbolType.Fenced:
						{
							MathMLNodeList arguments = e.Arguments;
							if(arguments.Count > 0)
							{
								MathMLElement argument = (MathMLElement)arguments.Item(0);
								ArrayList argList = new ArrayList(1);
								argList.Add(argument);
								area = FormatFencedContainer(argument, ctx, argList, new char[0], 
									info.Value[0].ToString(), info.Value[1].ToString());
							}

						} break;
						case PredefinedSymbolType.Log:
						{
							MathMLElement arg = null;
							ArrayList argList = new ArrayList(1);
							MathMLElement logbase = null;
							Area bseArea = AreaFactory.String(ctx, info.Value);
							Area logbaseArea = null;
							foreach(XmlNode n in e.ChildNodes)
							{
								if(n == e.Operator)
									continue;
								else if(logbase == null && n is MathMLElement && n.Name == "logbase")
								{
									logbase = (MathMLElement)n;
                  IFormattingContext scriptCtx = ctx.Clone();
									scriptCtx.ScriptLevel++;
									logbaseArea = (Area)logbase.Accept(this, scriptCtx);
									continue;
								}
								else if(arg == null && n is MathMLElement)
								{
                                    arg = (MathMLElement)n; 
                                    argList.Add(arg);    
								}
							}
							area = AreaFactory.Script(ctx, bseArea, logbaseArea, new Length(LengthType.Undefined), 
								null, new Length(LengthType.Undefined));
							Area[] areas = new Area[3];
							areas[0] = area;
							areas[1] = GlyphFactory.GetGlyph(ctx, ctx.Size, PredefinedSymbolInfo.ApplyFunction[0]);
							ctx.Parens = false;
							areas[2] = FormatFencedContainer(e, ctx, argList, new Char[] {','}, "(", ")");
							area = AreaFactory.Horizontal(areas);	


						} break;
					}
				}				
			}
			else if(e.Operator is MathMLApplyElement)
			{
				MathMLNodeList arguments = e.Arguments;
				ArrayList argList = new ArrayList(arguments.Count);
				foreach(Object o in arguments)
				{
					argList.Add(o);
				}
				Area[] areas = new Area[3];

				ctx.Parens = true;
				areas[0] = (Area)e.Operator.Accept(this, ctx);
				areas[1] = GlyphFactory.GetGlyph(ctx, ctx.Size, PredefinedSymbolInfo.ApplyFunction[0]);
				ctx.Parens = false;
				areas[2] = FormatFencedContainer(e, ctx, argList, new Char[] {','}, "(", ")");
				area = AreaFactory.Horizontal(areas);	
			}

			if(area == null)
			{
				area = AreaFactory.String((IFormattingContext)args, "?");
			}

			return CompleteArea(ctx, e, area);
		}