Exemple #1
0
        public Msubsup(IBuildable[] contents)
        { // handle star superscript
            List <IBuildable> localCopy = new List <IBuildable>(contents);

            if (localCopy.Count == 3)
            {
                Mo mo = localCopy[2] as Mo;
                if (mo != null && mo.IsTimesOrStar)
                {
                    Mi subscript = localCopy[1] as Mi;
                    if (subscript != null)
                    {
                        subscript.Content += Semantics.starPrefix;
                        localCopy.RemoveAt(2);
                    }
                    else
                    {
                        // maybe the subscript is an mrow
                        Mrow row = localCopy[1] as Mrow;
                        if (row != null && row.LastElement != null && row.LastElement is WithTextContent)
                        {
                            WithTextContent lastElem = (WithTextContent)row.LastElement;
                            lastElem.Content += Semantics.starPrefix;
                            localCopy.RemoveAt(2);
                        }
                    }
                }
            }
            base.contents = localCopy.ToArray();
        }
Exemple #2
0
        public override void Visit(StringBuilder sb, BuildContext bc)
        {
            if (bc.Options.SubscriptMode)
            {
                // separate by double underscore to differentiate from Msub and prevent clashes
                first.Visit(sb, bc);
                sb.Append("__");
                second.Visit(sb, bc);
            }
            else if (second is Mo && (second as Mo).IsTimesOrStar && first is Mi)
            {
                // this isn't really a superscript - it's part of the variable
                Mi mi    = (Mi)first;
                Mi newMi = new Mi(mi.Content + Semantics.starPrefix);
                newMi.Visit(sb, bc);
            }
            else
            {
                if (bc.LastTokenRequiresTimes)
                {
                    sb.Append("*");
                }

                // determine whether power must be inlined
                bool firstIsMrowMi         = (first is Mrow) && ((first as Mrow).ContainsSingleMi);
                bool secondIsIntegralPower = (second is Mrow) && ((second as Mrow).ContainsSingleMn) &&
                                             ((second as Mrow).LastElement as Mn).IsIntegerGreaterThan1;
                int  power           = ((second as Mrow).LastElement as Mn).IntegerValue;
                bool mustInlinePower = power <= bc.Options.MaxInlinePower;
                if (mustInlinePower)
                {
                    for (int i = 0; i < power; ++i)
                    {
                        first.Visit(sb, bc); // * sign appended automatically
                    }
                }
                else
                {
                    sb.Append("Math.Pow(");
                    first.Visit(sb, bc);
                    sb.Append(", ");
                    second.Visit(sb, bc);
                    sb.Append(")");
                }
            }

            bc.Tokens.Add(this);
        }
Exemple #3
0
 /// <summary>
 /// This function replaces all known inverse trig functions (in the msup blocks)
 /// by inverse names, so that sin^-1 becomes arcsin.
 /// </summary>
 /// <param name="contents">Buidlable contents</param>
 private static void ReplaceInverseTrigFunctions(IBuildable[] contents)
 {
     for (int i = 0; i < contents.Length; i++)
     {
         IBuildable c            = contents[i];
         string     trigFunction = string.Empty;
         if (c is Msup)
         {
             bool funcIsTrig = false, radixIsNeg1 = false;
             Tuple <IBuildable, IBuildable> terms = (c as Msup).Values;
             if (terms.Item1 is Mrow)
             {
                 Mrow row1 = terms.Item1 as Mrow;
                 if (row1.Contents.Length > 0 && row1.Contents[0] is Mi)
                 {
                     if (Semantics.inverseTrigs.ContainsKey((row1.Contents[0] as Mi).Content))
                     {
                         trigFunction = (row1.Contents[0] as Mi).Content;
                         funcIsTrig   = true;
                     }
                 }
             }
             if (terms.Item2 is Mrow)
             {
                 Mrow          row2 = terms.Item2 as Mrow;
                 StringBuilder sb   = new StringBuilder();
                 BuildContext  bc   = new BuildContext();
                 row2.Visit(sb, bc);
                 if (sb.ToString() == "-1")
                 {
                     radixIsNeg1 = true;
                 }
             }
             // if this is an inverse function, replace an <msup> with an inverse <mi>
             if (funcIsTrig && radixIsNeg1)
             {
                 Mi mi = new Mi(Semantics.inverseTrigs[trigFunction]);
                 contents[i] = mi;
             }
         }
     }
 }
Exemple #4
0
        public virtual void Visit(StringBuilder sb, BuildContext context)
        {
            bool containsFunct = false;
            int  numFuncts     = 0;

            if (sb == null || context == null || contents == null || contents.Length == 0)
            {
                return;
            }

            // copy contents into list
            List <IBuildable> ctxCopy = new List <IBuildable>(contents);

            // check if the Sigma operator acts as a sum
            if (context.Options.TreatSigmaAsSum)
            {
                // look for the plain sigma operator
                int index;
                while ((index = ctxCopy.FindIndex(a => (a is Mo && (a as Mo).IsSigma))) != -1)
                {
                    // so long as it is not the last element
                    if (index != ctxCopy.Count - 1)
                    {
                        BuildablePlainSum bps = new BuildablePlainSum(ctxCopy[index + 1]);
                        ctxCopy.RemoveAt(index + 1);
                        ctxCopy[index] = bps;

                        context.AddSum(bps);
                    }
                }
            }

            // check if delta <mo> appears before an <mi>
            if (context.Options.DeltaPartOfIdent)
            {
                int index;
                while ((index = ctxCopy.FindIndex(a => (a is Mo && (a as Mo).IsDelta))) != -1)
                {
                    // check that it's not the last element
                    if (index != ctxCopy.Count - 1)
                    {
                        // check that the next element is <mi>
                        Mi mi = ctxCopy[index + 1] as Mi;
                        if (mi != null)
                        {
                            // change Mi's content to incorporate the delta
                            Mi newMi = new Mi("∆" + mi.Content);
                            ctxCopy[index + 1] = newMi;
                            // remove the delta
                            ctxCopy.RemoveAt(index);
                            Trace.WriteLine(newMi.Content);
                        }
                    }
                }
            }
            else
            {
                // change delta from mo to mi
                int index;
                while ((index = ctxCopy.FindIndex(a => (a is Mo && (a as Mo).IsDelta))) != -1)
                {
                    ctxCopy[index] = new Mi("∆");
                }
            }

            // Scan for functions.
            // If one is found, increment the number. Because nested
            // functions which do not contain parentheses (e.g. sin sin x)
            // are contained in the same row element (in non-Word generated markup),
            // this allows us to determine how many close parens we need.
            foreach (IBuildable v in ctxCopy)
            {
                if (v is Mi && Semantics.knownFuncts.Contains((v as Mi).Content))
                {
                    containsFunct = true;
                    numFuncts++;
                }
            }

            if (containsFunct)
            {
                // Only process if this is not the spurious function.
                if (ctxCopy.Count != 1 || (!Semantics.knownFuncts.Contains((ctxCopy[0] as Mi).Content)))
                {
                    foreach (IBuildable v in ctxCopy)
                    {
                        v.Visit(sb, context);
                    }

                    for (; numFuncts > 0; numFuncts--)
                    {
                        sb.Append(")");
                    }
                }
            }
            // No function was found, so process in the normal fashion.
            else
            {
                foreach (var v in ctxCopy)
                {
                    v.Visit(sb, context);
                }
            }
        }