diff --git a/MathMLToCSharp.sln b/MathMLToCSharp.sln
index 7a037fe..70b71b9 100644
--- a/MathMLToCSharp.sln
+++ b/MathMLToCSharp.sln
@@ -1,18 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.26730.12
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29306.81
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Article", "Article", "{01843432-5BFE-490C-8C0F-196BB3461020}"
ProjectSection(SolutionItems) = preProject
- .\Article\MmlSharp.htm = .\Article\MmlSharp.htm
+ .gitignore = .gitignore
+ LICENSE = LICENSE
+ Article\MmlSharp.htm = Article\MmlSharp.htm
+ README.md = README.md
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MathMLToCSharp", ".\MathMLToCSharp\MathMLToCSharp.csproj", "{9C1737F0-6DCC-4CC5-8C8E-F9B4073683F8}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MathMLToCSharpLib", "MathMLToCSharpLib\MathMLToCSharpLib.csproj", "{7E67AAFD-564C-4362-B93F-7FDB912E2DF7}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", ".\Tests\Tests.csproj", "{320B2668-663F-49D1-9ADC-60D7674D1BAC}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MathMLToCSharp", "MathMLToCSharp\MathMLToCSharp.csproj", "{9C1737F0-6DCC-4CC5-8C8E-F9B4073683F8}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MathMLToCSharpLib", ".\MathMLToCSharpLib\MathMLToCSharpLib.csproj", "{3909E9A8-4E8A-4358-A8A9-3BA634090378}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{320B2668-663F-49D1-9ADC-60D7674D1BAC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -20,6 +23,10 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7E67AAFD-564C-4362-B93F-7FDB912E2DF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7E67AAFD-564C-4362-B93F-7FDB912E2DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7E67AAFD-564C-4362-B93F-7FDB912E2DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7E67AAFD-564C-4362-B93F-7FDB912E2DF7}.Release|Any CPU.Build.0 = Release|Any CPU
{9C1737F0-6DCC-4CC5-8C8E-F9B4073683F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C1737F0-6DCC-4CC5-8C8E-F9B4073683F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C1737F0-6DCC-4CC5-8C8E-F9B4073683F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -28,10 +35,6 @@ Global
{320B2668-663F-49D1-9ADC-60D7674D1BAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{320B2668-663F-49D1-9ADC-60D7674D1BAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{320B2668-663F-49D1-9ADC-60D7674D1BAC}.Release|Any CPU.Build.0 = Release|Any CPU
- {3909E9A8-4E8A-4358-A8A9-3BA634090378}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3909E9A8-4E8A-4358-A8A9-3BA634090378}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3909E9A8-4E8A-4358-A8A9-3BA634090378}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3909E9A8-4E8A-4358-A8A9-3BA634090378}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/MathMLToCSharp/App.xaml.cs b/MathMLToCSharp/App.xaml.cs
index 91c78fa..6c05369 100644
--- a/MathMLToCSharp/App.xaml.cs
+++ b/MathMLToCSharp/App.xaml.cs
@@ -2,6 +2,7 @@
using System.Windows;
using System.Windows.Threading;
using MathMLToCSharp.Properties;
+using MathMLToCSharpLib;
namespace MathMLToCSharp
{
diff --git a/MathMLToCSharp/BuildContext.cs b/MathMLToCSharp/BuildContext.cs
deleted file mode 100644
index dbd1560..0000000
--- a/MathMLToCSharp/BuildContext.cs
+++ /dev/null
@@ -1,190 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using MathMLToCSharp.Entities;
-using Wintellect.PowerCollections;
-
-namespace MathMLToCSharp
-{
- ///
- /// Represents runtime data that is kept while the code is being
- /// assembled from the model.
- ///
- public sealed class BuildContext
- {
- private readonly IList errors = new List();
- private readonly List> sums = new List>();
- private readonly IList tokens = new ArrayList();
- private readonly ICollection vars = new OrderedSet();
- private readonly IList possibleDivisionsByZero = new List();
- internal IList PossibleDivisionsByZero
- {
- get
- {
- return possibleDivisionsByZero;
- }
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public BuildContext() : this(new BuildContextOptions()) { }
-
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Build options.
- internal BuildContext(BuildContextOptions options)
- {
- Options = options;
- }
-
- ///
- /// Options used for building the code.
- ///
- internal BuildContextOptions Options { get; private set; }
-
- ///
- /// Errors encountered during build.
- ///
- public IList Errors
- {
- get { return errors; }
- }
-
- ///
- /// Variables that have been defined during build.
- ///
- public ICollection Vars
- {
- get { return vars; }
- }
-
- ///
- /// Tokens that have been met during build.
- ///
- public IList Tokens
- {
- get { return tokens; }
- }
-
- ///
- /// Returns the last token encountered, or null if there are none.
- ///
- public Object LastToken
- {
- get
- {
- return tokens.Count > 0 ? tokens[tokens.Count - 1] : null;
- }
- }
-
- ///
- /// Returns true if last token suggests the use of times before identifier.
- ///
- public bool LastTokenRequiresTimes
- {
- get
- {
- if (LastToken == null) return false;
-
- // times is required in all cases, except when
- // - last token was an operator and not a closing brace
- object t = LastToken;
- bool isMo = t is Mo;
- bool isClosing = false;
- if (isMo)
- isClosing = ((Mo)t).IsClosingBrace;
-
- if (isClosing)
- {
- Trace.WriteLine("No * due to closing brace.");
- return true;
- }
- if (isMo)
- {
- Trace.WriteLine("No * as last token is Mo.");
- return false;
- }
-
- if (t is Msup | t is Mrow) return false;
-
- Trace.WriteLine("Need *. Last token is " + t.GetType().Name);
- return true;
- }
- }
-
- ///
- /// Indicates whether we are on the right-hand side (after =) of the equation.
- ///
- public bool OnRhs
- {
- get
- {
- // note: completely wrong. = can appear in, e.g., sum subscripts
- foreach (var v in tokens)
- if (v is Mo && (v as Mo).IsEquals)
- return true;
- return false;
- }
- }
-
-
- public IList> Sums
- {
- get
- {
- return sums;
- }
- }
- public bool InMatrixDeterminate { get; set; }
-
- //string: function name, bool: go through bracket
- public Stack> BuiltinFuncPair = new Stack>();
-
- ///
- /// Adds a sum.
- ///
- /// The sum.
- public void AddSum(ISum sum)
- {
- for (char c = 'a'; c < 'z'; ++c)
- {
- char c1 = c;
- if (!vars.Contains(c1.ToString()) &&
- sums.FindIndex(i => i.Second == c1) == -1)
- {
- sums.Add(new Pair(sum, c));
- vars.Add(c.ToString());
- return;
- }
- }
- // todo: make this more civil later on
- throw new Exception("Out of variables!");
- }
-
- public char GetSumIdentifier(ISum sum)
- {
- int idx = sums.FindIndex(i => i.First == sum);
- if (idx != -1)
- return sums[idx].Second;
- else return '?';
- }
- }
-
- internal class BuildContextSum
- {
- private IBuildable[] initTokens;
- private IBuildable[] limitTokens;
- private IBuildable[] statement;
- }
-
- public enum EquationDataType
- {
- Float,
- Double,
- Decimal
- }
-}
diff --git a/MathMLToCSharp/BuildContextOptions.cs b/MathMLToCSharp/BuildContextOptions.cs
deleted file mode 100644
index 79688ec..0000000
--- a/MathMLToCSharp/BuildContextOptions.cs
+++ /dev/null
@@ -1,210 +0,0 @@
-using System;
-using System.ComponentModel;
-
-namespace MathMLToCSharp
-{
- ///
- /// Options used for building the code.
- ///
- [Serializable]
- internal sealed class BuildContextOptions : INotifyPropertyChanged
- {
- private bool deltaPartOfIdent = true;
- private EquationDataType eqnDataType = EquationDataType.Double;
- private bool greekToRoman;
- private int maxInlinePower = 2;
- private bool numberPostfix;
- private bool parallelize;
- private bool reduceFractions = true;
- private bool replaceEWithMathE;
- private bool replaceExpWithMathExp = true;
- private bool replacePiWithMathPI;
- private bool singleLetterVars = true;
- private bool treatSigmaAsSum = true;
-
- internal BuildContextOptions()
- {
- ReplacePiWithMathPI = true;
- }
-
- ///
- /// When set, prevents the builder from adding variables or appending * in front of them.
- /// Also, superscripts are treated as ordinary Mn elements when this is set.
- ///
- internal bool SubscriptMode { get; set; }
-
- [Category("Substitution")]
- [DisplayName("Replace exp with Math.Exp")]
- [Description("Instances of exp(x) are replaced with Math.Exp(x).")]
- public bool ReplaceExpWithMathExp
- {
- get
- {
- return replaceExpWithMathExp;
- }
- set
- {
- replaceExpWithMathExp = value;
- NotifyPropertyChanged("ReplaceExpWithMathExp");
- }
- }
-
- [Category("Substitution")]
- [DisplayName("Max Inline Power")]
- public int MaxInlinePower
- {
- get
- {
- return maxInlinePower;
- }
- set
- {
- maxInlinePower = value;
- NotifyPropertyChanged("MaxInlinePower");
- }
- }
-
- [Category("Substitution")]
- [DisplayName("Replace π with Math.PI")]
- [Description("Instances of Math.Pow(n, 2) are replaced with n*n.")]
- public bool ReplacePiWithMathPI
- {
- get { return replacePiWithMathPI; }
- set
- {
- replacePiWithMathPI = value;
- NotifyPropertyChanged("ReplacePiWithMathPI");
- }
- }
-
- [Category("Substitution")]
- [DisplayName("Replace e with Math.E")]
- public bool ReplaceEWithMathE
- {
- get { return replaceEWithMathE; }
- set
- {
- replaceEWithMathE = value;
- NotifyPropertyChanged("ReplaceeWithMathE");
- }
- }
-
- [DisplayName("Single-letter variables")]
- [Category("Keep Options")]
- [Description("When set, multi-letter variables (e.g., 'abc') will be split into single-letter ones (e.g., 'a', 'b', 'c').")]
- public bool SingleLetterVars
- {
- get { return singleLetterVars; }
- set
- {
- singleLetterVars = value;
- NotifyPropertyChanged("SingleLetterVars");
- }
- }
-
- [Category("Substitution")]
- [DisplayName("Greek to Roman")]
- [Description("When set, Greek identifiers will be replaced with their romanized names.")]
- public bool GreekToRoman
- {
- get { return greekToRoman; }
- set
- {
- greekToRoman = value;
- NotifyPropertyChanged("GreekToRoman");
- }
- }
-
- [DisplayName("Data type")]
- [Description("The default data type used by the code generator")]
- public EquationDataType EqnDataType
- {
- get { return eqnDataType; }
- set
- {
- eqnDataType = value;
- NotifyPropertyChanged("EqnDataType");
- }
- }
-
- [DisplayName("Number postfix")]
- [Description("When set, all numbers will have a postfix corresponding to their data type.")]
- public bool NumberPostfix
- {
- get { return numberPostfix; }
- set
- {
- numberPostfix = value;
- NotifyPropertyChanged("NumberPostfix");
- }
- }
-
- [DisplayName("Keep Δ attached")]
- [Category("Keep Options")]
- [Description("When set, the letter Δ will be stuck to the letter that follows it (if any).")]
- public bool DeltaPartOfIdent
- {
- get { return deltaPartOfIdent; }
- set
- {
- deltaPartOfIdent = value;
- NotifyPropertyChanged("DeltaPartOfIdent");
- }
- }
-
- [Category("Substitution")]
- [DisplayName("Treat Σ as sum")]
- [Description("When set, the letter Σ will be treated as a summation operator, and appropriate code will be emitted.")]
- public bool TreatSigmaAsSum
- {
- get { return treatSigmaAsSum; }
- set
- {
- treatSigmaAsSum = value;
- NotifyPropertyChanged("TreatSigmaAsSum");
- }
- }
-
- [Description("When set, causes all loops to be defined using Parallel Extensions.")]
- public bool Parallelize
- {
- get
- {
- return parallelize;
- }
- set
- {
- parallelize = value;
- NotifyPropertyChanged("Parallelize");
- }
- }
-
- [Category("Substitution")]
- [DisplayName("Reduce Fractions")]
- [Description("When set, simple fractions (e.g., 1/2) are substituted by their result (e.g., 0.5).")]
- public bool ReduceFractions
- {
- get { return reduceFractions; }
- set
- {
- reduceFractions = value;
- NotifyPropertyChanged("ReduceFractions");
- }
- }
-
- #region INotifyPropertyChanged Members
-
- public event PropertyChangedEventHandler PropertyChanged;
-
- #endregion
-
- private void NotifyPropertyChanged(string propertyName)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged(this,
- new PropertyChangedEventArgs(propertyName));
- }
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Annotation.cs b/MathMLToCSharp/Entities/Annotation.cs
deleted file mode 100644
index 07a832e..0000000
--- a/MathMLToCSharp/Entities/Annotation.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- public class Annotation : WithTextContent
- {
- public Annotation(string content):base(content) {}
- public override void Visit(StringBuilder sb, BuildContext bc)
- {
- if (!string.IsNullOrEmpty(content) && content.Length > 0)
- {
- // no way - MathType annotations are just junk
- }
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/BuildablePlainSum.cs b/MathMLToCSharp/Entities/BuildablePlainSum.cs
deleted file mode 100644
index e575e97..0000000
--- a/MathMLToCSharp/Entities/BuildablePlainSum.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- public class BuildablePlainSum : ISum
- {
- private readonly IBuildable expression;
- public BuildablePlainSum(IBuildable expression)
- {
- this.expression = expression;
- }
-
- #region ISum Members
-
- public void Visit(StringBuilder sb, BuildContext bc)
- {
- sb.Append(bc.GetSumIdentifier(this));
- }
-
- public string Expression(BuildContext context)
- {
- // get the target
- StringBuilder target = new StringBuilder();
- expression.Visit(target, context);
-
- StringBuilder sb = new StringBuilder();
- sb.AppendFormat("for (int i{0} = 0; i{0} < {1}.Length; ++i{0})",
- context.GetSumIdentifier(this), target);
- sb.AppendLine();
- sb.Append(" ");
- sb.AppendFormat("{0} += {1}[i{0}];", context.GetSumIdentifier(this), target);
- return sb.ToString();
- }
-
- #endregion
- }
-}
diff --git a/MathMLToCSharp/Entities/IBuildable.cs b/MathMLToCSharp/Entities/IBuildable.cs
deleted file mode 100644
index aed6355..0000000
--- a/MathMLToCSharp/Entities/IBuildable.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// This interface must be implemented by all types of expression
- /// objects in the tree.
- ///
- public interface IBuildable
- {
- ///
- /// Builds a textual (C#) representation of the model existing at the root of this node.
- ///
- /// The builder that aggregates the text.
- /// Run-time build information.
- void Visit(StringBuilder sb, BuildContext bc);
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/ISum.cs b/MathMLToCSharp/Entities/ISum.cs
deleted file mode 100644
index 4420747..0000000
--- a/MathMLToCSharp/Entities/ISum.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace MathMLToCSharp.Entities
-{
- public interface ISum : IBuildable
- {
- string Expression(BuildContext context);
- }
-}
diff --git a/MathMLToCSharp/Entities/Math.cs b/MathMLToCSharp/Entities/Math.cs
deleted file mode 100644
index 1a4053a..0000000
--- a/MathMLToCSharp/Entities/Math.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System;
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Root element in MathML. Not to be confused with System.Math.
- ///
- public class Math : WithBuildableContents
- {
- public Math(string content) : base(new IBuildable []{}) { /* just in case */ }
- public Math(IBuildable content) : base(new[]{content}) {}
- public Math(IBuildable[] contents) : base(contents) {}
- public override void Visit(StringBuilder sb, BuildContext context)
- {
- base.Visit(sb, context);
-
- // todo: this assumes that there is only one statement, which may not be the case
- if (sb.ToString().Length > 0)
- sb.Append(";");
-
- // sums
- int j = context.Sums.Count;
- if (j > 0)
- {
- var builder = new StringBuilder();
- foreach (var v in context.Sums)
- {
- builder.AppendLine(v.First.Expression(context));
- }
- sb.Insert(0, builder.ToString());
- }
-
- // variables
- int i = context.Vars.Count;
- if (i > 0)
- {
- var builder = new StringBuilder();
- foreach (var v in context.Vars)
- {
- builder.Append(Enum.GetName(typeof(EquationDataType), context.Options.EqnDataType).ToLower());
- builder.Append(" ");
- builder.Append(v);
- builder.Append(" = 0.0"); // this is a *must*
- if (context.Options.NumberPostfix)
- builder.Append(Semantics.postfixForDataType(context.Options.EqnDataType));
- builder.AppendLine(";");
- }
- foreach (IBuildable ib in context.PossibleDivisionsByZero)
- {
- var b = new StringBuilder();
- ib.Visit(b, new BuildContext(App.BuildOptions));
- builder.AppendFormat("Debug.Assert({0} != 0, \"Expression {0} is about to cause division by zero.\");",
- b);
- builder.AppendLine();
- }
- sb.Insert(0, builder.ToString());
- }
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mfenced.cs b/MathMLToCSharp/Entities/Mfenced.cs
deleted file mode 100644
index 8ce5b3c..0000000
--- a/MathMLToCSharp/Entities/Mfenced.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Code in brackets.
- ///
- public class Mfenced : WithBuildableContent
- {
- public Mfenced(IBuildable content) : base(content) {}
- public override void Visit(StringBuilder sb, BuildContext bc)
- {
- bc.Tokens.Add(this);
-
- if (bc.LastTokenRequiresTimes)
- sb.Append("*");
-
- // todo: brackets do not need to be added if there is only one element (e.g., braces around a matrix)
- sb.Append("(");
- base.Visit(sb, bc);
- sb.Append(")");
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mfrac.cs b/MathMLToCSharp/Entities/Mfrac.cs
deleted file mode 100644
index b13b66e..0000000
--- a/MathMLToCSharp/Entities/Mfrac.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Fraction.
- ///
- // note: it might be worthwhile somehow differentiating between fraction and
- // ordinary division, e.g., having fraction parts evaluate as temporary variables.
- public class Mfrac : WithBinaryContent
- {
- public Mfrac(IBuildable first, IBuildable second) : base(first, second) {}
-
- public override void Visit(StringBuilder sb, BuildContext bc)
- {
- bc.Tokens.Add(this);
-
- bool needReduce = false;
- // note: the use of double is a judgement call here
- double result = 0.0;
- if (bc.Options.ReduceFractions)
- {
- Mrow row1 = first as Mrow;
- Mrow row2 = second as Mrow;
- if (row1 != null && row2 != null && row1.Contents.Length > 0 && row2.Contents.Length > 0)
- {
- Mn mn1 = row1.Contents[0] as Mn;
- Mn mn2 = row2.Contents[0] as Mn;
- if (mn1 != null && mn2 != null)
- {
- try
- {
- double _1, _2;
- if (double.TryParse(mn1.Content, out _1) &&
- double.TryParse(mn2.Content, out _2) &&
- _2 != 0.0)
- {
- result = _1/_2;
- needReduce = true;
- }
- }
- catch
- {
- }
- }
- }
- }
-
- if (needReduce)
- {
- sb.Append(result);
- }
- else
- {
- sb.Append("((");
- first.Visit(sb, bc);
- sb.Append(") / (");
- second.Visit(sb, bc);
- sb.Append("))");
-
- // add to checks
- bc.PossibleDivisionsByZero.Add(second);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mi.cs b/MathMLToCSharp/Entities/Mi.cs
deleted file mode 100644
index a122a78..0000000
--- a/MathMLToCSharp/Entities/Mi.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Reflection;
-using System.Text;
-using Wintellect.PowerCollections;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Identifier (a.k.a. variable).
- ///
- public class Mi : WithTextContent
- {
- public Mi(string content) : base(content) { }
-
- ///
- /// Returns true if this is a function not supported by System.Math.
- ///
- public bool IsUnsupportedFunction
- {
- get
- {
- return content == "sec" || content == "sech" ||
- content == "csc" || content == "csch" ||
- content == "cot" || content == "coth";
- }
- }
-
- public override void Visit(StringBuilder sb, BuildContext bc)
- {
- if (string.IsNullOrEmpty(content))
- return;
-
- //postfix Built-in function detection
- if (content == "Eigenvectors" || content == "Eigenvalues")
- {
- bc.BuiltinFuncPair.Push(new Pair(content, false));
- bc.Tokens.Add(this);
- return;
- }
-
- // get every single variable, unless this is a function name rather than a variable name
- // this assumes that nobody intends to call a variable, e.g., 'sin'
- // also, the variable is not converted if it starts with a delta and we've chosen to
- // keep delta as part of identifier
- List vars = (bc.Options.SingleLetterVars && !Semantics.rep.ContainsKey(content) &&
- !(bc.Options.DeltaPartOfIdent && content[0] == '∆'))
- ?
- new List(Array.ConvertAll(content.ToCharArray(), c => c.ToString()))
- :
- new List { content };
-
- for (int i = 0; i < vars.Count; i++)
- {
- string varName = vars[i];
-
- bool needReplace = false;
- string replaceTerm = string.Empty;
- if (Semantics.rep.ContainsKey(varName))
- {
- Pair p = Semantics.rep[varName];
- replaceTerm = p.First;
- if (string.IsNullOrEmpty(p.Second))
- needReplace = true;
- else
- {
- Type bct = typeof(BuildContextOptions);
- PropertyInfo pi = bct.GetProperty(p.Second);
- Debug.Assert(pi != null);
- needReplace = (bool)pi.GetValue(bc.Options, null);
- }
- }
-
- // if variable not subject to replacement, check to see if it requires conversion from greek
- if (!needReplace && varName.Length == 1 && bc.Options.GreekToRoman)
- {
- varName = Util.GreekLetterName(varName[0]);
- }
-
- // can only declare variable if
- // 1) if it hasn't already been declared
- // 2) if there needn't be a replacement, e.g., of e with Math.E
- // 3) it hasn't been explicitly blocked
- if (!bc.Vars.Contains(varName) && !needReplace && !bc.Options.SubscriptMode)
- bc.Vars.Add(varName);
-
- // use implicit multiplication if necessary
- if (bc.LastTokenRequiresTimes && !bc.Options.SubscriptMode)
- sb.Append("*");
- // add type to context
- if (needReplace)
- {
- sb.Append(replaceTerm);
- }
- else
- {
- sb.Append(varName);
- }
- // unless this is the last variable, add multiplication sign after it
- if (i + 1 != vars.Count)
- sb.Append("*");
- }
-
- bc.Tokens.Add(this);
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mn.cs b/MathMLToCSharp/Entities/Mn.cs
deleted file mode 100644
index cc2b8d2..0000000
--- a/MathMLToCSharp/Entities/Mn.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Number.
- ///
- public class Mn : WithTextContent
- {
- public Mn(string content) : base(content) {}
-
- ///
- /// Returns true if the content is an integer greater than 1 (i.e., 2, 3, etc.)
- ///
- public bool IsIntegerGreaterThan1
- {
- get
- {
- try
- {
- double d = double.Parse(content);
- if (System.Math.Floor(d) == d)
- if (d > 1.0)
- return true;
- return false;
- }
- catch
- {
- return false;
- }
- }
- }
-
- public int IntegerValue
- {
- get
- {
- return int.Parse(content);
- }
- }
-
- public override void Visit(StringBuilder sb, BuildContext bc)
- {
- base.Visit(sb, bc);
- if (bc.Options.NumberPostfix && !bc.Options.SubscriptMode)
- sb.Append(Semantics.postfixForDataType(bc.Options.EqnDataType));
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mo.cs b/MathMLToCSharp/Entities/Mo.cs
deleted file mode 100644
index 34ee872..0000000
--- a/MathMLToCSharp/Entities/Mo.cs
+++ /dev/null
@@ -1,180 +0,0 @@
-using System.Collections.Specialized;
-using System.Diagnostics;
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Operator.
- ///
- public class Mo : WithTextContent
- {
- private static readonly StringDictionary rep;
- static Mo()
- {
- // replacements in lieu of the actual operator
- rep = new StringDictionary
- {
- {"!", ".Factorial()"},
- {"-", "-"}, // this one is *really* nasty :)
- {"−", "-"}, // this one is also annoying (thanks MathType)
- {"÷", "/"},
- {"×", "*"},
- {"∗", "*"}, // << unpleasant too!
- {"[", "("},
- {"]", ")"},
- {"{", "("},
- {"}", ")"}
- };
- }
-
- public Mo(string content) : base(content) { }
-
- ///
- /// Returns true if this is an equals operator.
- ///
- ///
- /// Useful for determining whether we are on the RHS or LHS of an assignment.
- ///
- public bool IsEquals
- {
- get
- {
- return content == "=";
- }
- }
-
- ///
- /// Returns true if this is a closing brace.
- ///
- public bool IsClosingBrace
- {
- get
- {
- return content == ")";
- }
- }
-
- ///
- /// Returns true if this is an opening brace.
- ///
- public bool IsOpeningBrace
- {
- get
- {
- return content == "(";
- }
- }
-
- ///
- /// Returns true if this is a printable operator.
- ///
- public bool IsPrintableOperator
- {
- get
- {
- return (content != "\u2061" && content != "\u2062" && content != "\u2063");
- }
- }
-
- ///
- /// Gets a value indicating whether the content is uppercase sigma.
- ///
- /// true if the content is sigma; otherwise, false.
- public bool IsSigma
- {
- get
- {
- return content == "∑";
- }
- }
-
- ///
- /// Gets a value indicating whether the content is uppercase delta.
- ///
- /// true if the content is delta; otherwise, false.
- public bool IsDelta
- {
- get
- {
- return content == "∆";
- }
- }
-
- ///
- /// Gets a value indicating whether this instance is times or star.
- ///
- ///
- /// true if this instance is times or star; otherwise, false.
- ///
- public bool IsTimesOrStar
- {
- get
- {
- return "*∗".Contains(content);
- }
- }
-
- public override void Visit(StringBuilder sb, BuildContext bc)
- {
- bc.Tokens.Add(this);
- //| matrix | detrminate
- if (content == "|")
- {
- if (bc.InMatrixDeterminate)
- {
- sb.Append(".Determinant()");
- bc.InMatrixDeterminate = false;
- }
- else
- bc.InMatrixDeterminate = true;
- return;
- }
-
- //Built in function
- if (content == "(" && bc.BuiltinFuncPair.Count != 0 && bc.BuiltinFuncPair.Peek().Second == false)
- {
- var pr = bc.BuiltinFuncPair.Pop();
- pr.Second = true;
- bc.BuiltinFuncPair.Push(pr);
- return;
- }
- else if (content == ")" && bc.BuiltinFuncPair.Count != 0 && bc.BuiltinFuncPair.Peek().Second == true)
- {
- switch (bc.BuiltinFuncPair.Peek().First)
- {
- default:
- sb.Append(")");
- break;
- case "Eigenvalues":
- sb.Append(".Evd().EigenValues");
- break;
- case "Eigenvectors":
- sb.Append(".Evd().EigenVectors");
- break;
- }
- bc.BuiltinFuncPair.Pop();
- return;
- }
-
- // if we are in subscript mode, adding an operator is not necessary, but neither can we ignore it
- if (bc.Options.SubscriptMode)
- {
- sb.Append("_");
- }
- else if (rep.ContainsKey(content))
- sb.Append(rep[content]);
- else
- {
- Trace.Assert(content.Length == 1, "We only support 1-char operators (for now).");
- if (IsPrintableOperator)
- {
- if (IsOpeningBrace && bc.LastTokenRequiresTimes)
- sb.Append("*");
-
- sb.Append(content);
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mroot.cs b/MathMLToCSharp/Entities/Mroot.cs
deleted file mode 100644
index 759c042..0000000
--- a/MathMLToCSharp/Entities/Mroot.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Radical. These do not exist in C#, so cubic root of N is encoded as Math.Pow(N, 1/3).
- ///
- public class Mroot : WithBinaryContent
- {
- public Mroot(IBuildable first, IBuildable second) : base(first, second) { }
-
- public override void Visit(StringBuilder sb, BuildContext bc)
- {
- sb.Append("Math.Pow(");
- first.Visit(sb, bc);
- sb.Append(", 1 / ");
- second.Visit(sb, bc);
- sb.Append(")");
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mrow.cs b/MathMLToCSharp/Entities/Mrow.cs
deleted file mode 100644
index 80e823e..0000000
--- a/MathMLToCSharp/Entities/Mrow.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// A fairly generic element that does not mean anything.
- ///
- public class Mrow : WithBuildableContents
- {
- public Mrow(IBuildable[] content) : base(content)
- {
-
- }
-
- public Mrow(IBuildable first, IBuildable second) : this(new[] { first, second })
- {
- }
-
- public Mrow(IBuildable content) : this(new[] { content })
- {
- }
-
- public IBuildable[] Contents
- {
- get { return contents; }
- }
-
- ///
- /// Returns true if this contains a single .
- ///
- public bool ContainsSingleMi
- {
- get
- {
- return contents.Length == 1 && contents[0] is Mi;
- }
- }
-
- ///
- /// Gets a value indicating whether this Mrow contains a single Mn.
- ///
- /// true if this row contains a single Mn; otherwise, false.
- public bool ContainsSingleMn
- {
- get
- {
- return contents.Length == 1 && contents[0] is Mn;
- }
- }
-
- ///
- /// Returns true if this contains a single .
- ///
- public bool ContainsSingleMtable
- {
- get
- {
- return contents.Length == 1 && contents[0] is Mtable;
- }
- }
- public override void Visit(StringBuilder sb, BuildContext context)
- {
- base.Visit(sb, context);
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Msqrt.cs b/MathMLToCSharp/Entities/Msqrt.cs
deleted file mode 100644
index 180cbea..0000000
--- a/MathMLToCSharp/Entities/Msqrt.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Square root.
- ///
- public class Msqrt : WithBuildableContents
- {
- public Msqrt(IBuildable content) : base(new[]{content}) {}
- public Msqrt(IBuildable[] contents) : base(contents) {}
-
- public override void Visit(StringBuilder sb, BuildContext bc)
- {
- bc.Tokens.Add(this);
- sb.Append("Math.Sqrt(");
- base.Visit(sb, bc);
- sb.Append(")");
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mstyle.cs b/MathMLToCSharp/Entities/Mstyle.cs
deleted file mode 100644
index a1815f1..0000000
--- a/MathMLToCSharp/Entities/Mstyle.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace MathMLToCSharp.Entities
-{
- class Mstyle : WithBuildableContents
- {
- public Mstyle(IBuildable content) : base(new[]{content}) {}
- public Mstyle(IBuildable[] contents) : base(contents) {}
- }
-}
diff --git a/MathMLToCSharp/Entities/Msub.cs b/MathMLToCSharp/Entities/Msub.cs
deleted file mode 100644
index eb40ac7..0000000
--- a/MathMLToCSharp/Entities/Msub.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Subscript.
- ///
- public class Msub : WithBinaryContent
- {
- public Msub(IBuildable first, IBuildable second) : base(first, second) {}
-
- public override void Visit(StringBuilder sb, BuildContext bc)
- {
- bc.Tokens.Add(this);
-
- bool last = bc.Options.SubscriptMode;
- bc.Options.SubscriptMode = true;
-
- StringBuilder b = new StringBuilder();
-
- first.Visit(b, bc);
- b.Append("_");
- second.Visit(b, bc);
-
- string varName = b.ToString();
- if (!bc.Vars.Contains(varName))
- if (!last) // unless we are already in a subscript-entering mode...
- bc.Vars.Add(varName);
-
- sb.Append(varName);
-
- bc.Options.SubscriptMode = last;
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Msubsup.cs b/MathMLToCSharp/Entities/Msubsup.cs
deleted file mode 100644
index 015c316..0000000
--- a/MathMLToCSharp/Entities/Msubsup.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Subscript and superscript one one variable.
- ///
- public class Msubsup : WithBuildableContents
- {
- public Msubsup(IBuildable[] contents)
- { // handle star superscript
- List localCopy = new List(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();
- }
- public override void Visit(StringBuilder sb, BuildContext context)
- {
- Debug.Assert(contents.Length == 2 || contents.Length == 3);
- Msub sub = new Msub(contents[0], contents[1]);
- switch (contents.Length) {
- case 2:
- sub.Visit(sb, context);
- break;
- case 3:
- Msup sup = new Msup(sub, contents[2]);
- sup.Visit(sb, context);
- break;
- default:
- throw new ApplicationException("Incorrect number of arguments in Msubsup");
- }
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Msup.cs b/MathMLToCSharp/Entities/Msup.cs
deleted file mode 100644
index a919467..0000000
--- a/MathMLToCSharp/Entities/Msup.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-using System.Text;
-using Wintellect.PowerCollections;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Superscript. Taken to mean 'power of' unless the superscript parses into a *.
- ///
- public class Msup : WithBinaryContent
- {
- public Msup(IBuildable first, IBuildable second) : base(first, second) { }
-
- public Pair Values
- {
- get
- {
- return new Pair(first, second);
- }
- }
-
- 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((first is Mrow) && ((first as Mrow).ContainsSingleMtable))
- {
- if((second is Mrow) && ((second as Mrow).ContainsSingleMi) &&((second as Mrow).LastElement as Mi).Content == "T")
- {
- first.Visit(sb, bc);
- sb.Append(".Transpose()");
- }
- else if ((second is Mrow) && ((second as Mrow).ContainsSingleMn) &&((second as Mrow).LastElement as Mn).IsIntegerGreaterThan1)
- {
- first.Visit(sb, bc);
- sb.Append(".Power(");
- second.Visit(sb, bc);
- sb.Append(")");
- }
- else if ((second is Mrow) && ((second as Mrow).ContainsSingleMn) && ((second as Mrow).LastElement as Mn).Content=="-1")
- {
- first.Visit(sb, bc);
- sb.Append(".Inverse()");
- }
- bc.Tokens.Add(this);
- return;
- }
-
- 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;
- bool mustInlinePower = false;
- int power = 0;
- if (secondIsIntegralPower)
- {
- power = ((second as Mrow).LastElement as Mn).IntegerValue;
- mustInlinePower = power <= bc.Options.MaxInlinePower;
- }
- if (mustInlinePower)
- {
- for (int i = 0; i < power; ++i)
- {
- if (i != 0 && (first is Mrow) && ((first as Mrow).ContainsSingleMn))
- sb.Append("*"); //for the case mn^2 not appended * automatically
- 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);
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mtable.cs b/MathMLToCSharp/Entities/Mtable.cs
deleted file mode 100644
index 62af3ee..0000000
--- a/MathMLToCSharp/Entities/Mtable.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Text;
-using MathNet.Numerics.LinearAlgebra;
-using MathNet.Numerics.LinearAlgebra.Double;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// A table. Typically used for matrices.
- ///
- public class Mtable : WithBuildableContents
- {
- static int level = 0;
- public Mtable(IBuildable[] contents) : base(contents) { }
- public override void Visit(StringBuilder sb, BuildContext context)
- {
- level++;
- Matrix m = DenseMatrix.OfArray(new double[,] { { 1, 2 }, { 3, 4 } });
- var c = m.Evd().EigenVectors;
- if (level == 1)
- sb.Append("DenseMatrix.OfArray(new double[,] {");//matrix
- else
- sb.Append("{");//matrix
- for (int i = 0; i < contents.Length; ++i)
- {
- contents[i].Visit(sb, context);
- if (i + 1 != contents.Length)
- sb.Append(", ");
- }
- if (level == 1)
- sb.Append("})");
- else
- sb.Append("}");
- level--;
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mtd.cs b/MathMLToCSharp/Entities/Mtd.cs
deleted file mode 100644
index 0e2a64b..0000000
--- a/MathMLToCSharp/Entities/Mtd.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Table cell.
- ///
- public class Mtd : WithBuildableContent
- {
- public Mtd(IBuildable content) : base(content) {}
- public override void Visit(StringBuilder sb, BuildContext bc)
- {
- bc.Tokens.Add(this);
- content.Visit(sb, bc);
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Mtr.cs b/MathMLToCSharp/Entities/Mtr.cs
deleted file mode 100644
index 86c2fc7..0000000
--- a/MathMLToCSharp/Entities/Mtr.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Table row.
- ///
- public class Mtr : WithBuildableContents
- {
- public Mtr(IBuildable[] contents) : base(contents) {}
- public Mtr(IBuildable first, IBuildable second) : base(new[]{first, second}) {}
- public override void Visit(StringBuilder sb, BuildContext context)
- {
- sb.Append("{");
- for (int i = 0; i < contents.Length; ++i)
- {
- contents[i].Visit(sb, context);
- if (i + 1 != contents.Length)
- sb.Append(", ");
- }
- sb.Append("}");
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/Munderover.cs b/MathMLToCSharp/Entities/Munderover.cs
deleted file mode 100644
index 79e220f..0000000
--- a/MathMLToCSharp/Entities/Munderover.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- class Munderover : WithBuildableContents
- {
- public Munderover(IBuildable[] contents) : base(contents) {}
- public override void Visit(StringBuilder sb, BuildContext context)
- {
- if (contents.Length == 3)
- {
- // is the first one an operator?
- Mo mo = contents[0] as Mo;
- if (mo != null)
- {
- if (mo.IsSigma)
- {
- //todo: summation!
-
- }
- }
- }
- else
- {
- sb.Append("Munderover must have 3 items");
- }
- }
- }
-}
diff --git a/MathMLToCSharp/Entities/Null.cs b/MathMLToCSharp/Entities/Null.cs
deleted file mode 100644
index 1ec9a3c..0000000
--- a/MathMLToCSharp/Entities/Null.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace MathMLToCSharp.Entities
-{
- [Obsolete("Do not use", true)]
- class Null
- {
- }
-}
diff --git a/MathMLToCSharp/Entities/Semantics.cs b/MathMLToCSharp/Entities/Semantics.cs
deleted file mode 100644
index a960e9f..0000000
--- a/MathMLToCSharp/Entities/Semantics.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using Wintellect.PowerCollections;
-
-namespace MathMLToCSharp.Entities
-{
- ///
- /// Completely spurious element that MathType 6 insists on generating.
- ///
- public class Semantics : WithBuildableContents
- {
- internal const string starPrefix = "_star";
-
- ///
- /// Functions which need replacement.
- ///
- internal static readonly List knownFuncts;
-
- ///
- /// Symbols and function names that can be replaced.
- ///
- internal static readonly Dictionary> rep;
- ///
- /// Trig functions which have an inverse, and their inverse values.
- ///
- internal static StringDictionary inverseTrigs;
-
-
- static Semantics()
- {
- rep = new Dictionary>
- {
- {"∞", new Pair("double.MaxValue", null)},
- {"π", new Pair("Math.PI", "ReplacePiWithMathPI")},
- {"e", new Pair("Math.E", "ReplaceEWithMathE")},
- {"exp", new Pair("Math.Exp", "ReplaceExpWithMathExp")},
- {"*", new Pair("star", null)},
-
- // functions
- {"cos", new Pair("Math.Cos(", null)},
- {"cosh", new Pair("Math.Cosh(", null)},
- {"sec", new Pair("1/Math.Cos(", null)},
- {"sech", new Pair("1/Math.Cosh(", null)},
- {"sin", new Pair("Math.Sin(", null)},
- {"sinh", new Pair("Math.Sinh(", null)},
- {"csc", new Pair("1/Math.Sin(", null)},
- {"csch", new Pair("1/Math.Sinh(", null)},
- {"tan", new Pair("Math.Tan(", null)},
- {"tanh", new Pair("Math.Tanh(", null)},
- {"cot", new Pair("1/Math.Tan(", null)},
- {"coth", new Pair("1/Math.Tanh(", null)},
- {"ln", new Pair("Math.Log(", null)},
- {"log", new Pair("Math.Log10(", null)},
-
- // inverse trig functions
- {"arcsin", new Pair("Math.Asin(", null)},
- {"arccos", new Pair("Math.Acos(", null)},
- {"arctan", new Pair("Math.Atan(", null)},
- {"arccsc", new Pair("Math.Asin(1/", null)},
- {"arcsec", new Pair("Math.Acos(1/", null)},
- {"arccot", new Pair("Math.Atan(1/", null)}
- };
-
- inverseTrigs = new StringDictionary
- {
- {"sin", "arcsin"},
- {"cos", "arccos"},
- {"tan", "arctan"},
- {"csc", "arccsc"},
- {"sec", "arcsec"},
- {"cot", "arccot"}
- };
-
- knownFuncts = new List
- {
- "cos",
- "cosh",
- "arcsin",
- "sec",
- "sech",
- "arcsec",
- "sin",
- "sinh",
- "arcsin",
- "csc",
- "csch",
- "arccsc",
- "tan",
- "tanh",
- "arctan",
- "cot",
- "coth",
- "arccot",
- "ln",
- "log",
- "exp" // exponent, should be user-selectable
- };
- }
-
- public Semantics(IBuildable[] contents) : base(contents) {}
-
- internal static string postfixForDataType(EquationDataType type)
- {
- switch (type)
- {
- case EquationDataType.Decimal:
- return "M";
- case EquationDataType.Float:
- return "f";
- default:
- return string.Empty;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/WithBinaryContent.cs b/MathMLToCSharp/Entities/WithBinaryContent.cs
deleted file mode 100644
index a968226..0000000
--- a/MathMLToCSharp/Entities/WithBinaryContent.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System.Text;
-using Wintellect.PowerCollections;
-
-namespace MathMLToCSharp.Entities
-{
- public abstract class WithBinaryContent : IBuildable
- {
- protected readonly IBuildable first, second;
- protected WithBinaryContent(IBuildable first, IBuildable second)
- {
- this.first = first;
- this.second = second;
- }
-
- public Pair Contents
- {
- get
- {
- return new Pair(first, second);
- }
- }
-
- #region IBuildable Members
-
- public abstract void Visit(StringBuilder sb, BuildContext bc);
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/WithBuildableContent.cs b/MathMLToCSharp/Entities/WithBuildableContent.cs
deleted file mode 100644
index 7a7e179..0000000
--- a/MathMLToCSharp/Entities/WithBuildableContent.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- public abstract class WithBuildableContent : IBuildable
- {
- protected readonly IBuildable content;
- protected WithBuildableContent(IBuildable content)
- {
- this.content = content;
- }
-
- #region IBuildable Members
-
- public virtual void Visit(StringBuilder sb, BuildContext bc)
- {
- bc.Tokens.Add(this);
- content.Visit(sb, bc);
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/WithBuildableContents.cs b/MathMLToCSharp/Entities/WithBuildableContents.cs
deleted file mode 100644
index b3f81a5..0000000
--- a/MathMLToCSharp/Entities/WithBuildableContents.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Text;
-using Wintellect.PowerCollections;
-
-namespace MathMLToCSharp.Entities
-{
- public abstract class WithBuildableContents : IBuildable
- {
- protected IBuildable[] contents;
- protected WithBuildableContents()
- {
- }
-
- protected WithBuildableContents(IBuildable[] contents)
- {
- this.contents = contents;
-
- ReplaceInverseTrigFunctions(contents);
- }
-
- public IBuildable LastElement
- {
- get
- {
- if (contents.Length > 0)
- return contents[contents.Length - 1];
- return null;
- }
- }
-
- #region IBuildable Members
-
- 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 ctxCopy = new List(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 appears before an
- 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 = 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);
- }
- }
-
- #endregion
-
- ///
- /// This function replaces all known inverse trig functions (in the msup blocks)
- /// by inverse names, so that sin^-1 becomes arcsin.
- ///
- /// Buidlable contents
- 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;
- Pair terms = (c as Msup).Values;
- if (terms.First is Mrow)
- {
- Mrow row1 = terms.First 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.Second is Mrow)
- {
- Mrow row2 = terms.Second 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 with an inverse
- if (funcIsTrig && radixIsNeg1)
- {
- Mi mi = new Mi(Semantics.inverseTrigs[trigFunction]);
- contents[i] = mi;
- }
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/Entities/WithTextContent.cs b/MathMLToCSharp/Entities/WithTextContent.cs
deleted file mode 100644
index 69599df..0000000
--- a/MathMLToCSharp/Entities/WithTextContent.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Text;
-
-namespace MathMLToCSharp.Entities
-{
- public abstract class WithTextContent : IBuildable
- {
- protected string content;
- protected WithTextContent(string content) {
- this.content = content;
- }
-
- public string Content
- {
- get { return content; }
- set { content = value; }
- }
-
- #region IBuildable Members
-
- public virtual void Visit(StringBuilder sb, BuildContext bc)
- {
- bc.Tokens.Add(this);
- sb.Append(content);
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/MathMLToCSharp/MainFrame.xaml.cs b/MathMLToCSharp/MainFrame.xaml.cs
index 2cfb3c0..93804b6 100644
--- a/MathMLToCSharp/MainFrame.xaml.cs
+++ b/MathMLToCSharp/MainFrame.xaml.cs
@@ -10,95 +10,99 @@
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Linq;
+
using MathMLToCSharp.Properties;
+
+using MathMLToCSharpLib;
+
using Microsoft.CSharp;
namespace MathMLToCSharp
{
- ///
- /// Interaction logic for MainFrame.xaml
- ///
- public partial class MainFrame : Window
- {
- // Using a DependencyProperty as the backing store for ShowTree. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty ShowTreeProperty =
- DependencyProperty.Register("ShowTree", typeof(bool), typeof(MainFrame), new UIPropertyMetadata(false));
-
- public MainFrame()
+ ///
+ /// Interaction logic for MainFrame.xaml
+ ///
+ public partial class MainFrame : Window
{
- InitializeComponent();
- WindowState = (WindowState)Settings.Default["WindowState"];
+ // Using a DependencyProperty as the backing store for ShowTree. This enables animation, styling, binding, etc...
+ public static readonly DependencyProperty ShowTreeProperty =
+ DependencyProperty.Register("ShowTree", typeof(bool), typeof(MainFrame), new UIPropertyMetadata(false));
+
+ public MainFrame()
+ {
+ InitializeComponent();
+ WindowState = (WindowState)Settings.Default["WindowState"];
- Version version = Assembly.GetAssembly(GetType()).GetName().Version;
- Title += string.Format(" v.{0}.{1}.{2}", version.Major, version.Minor, version.Build);
+ Version version = Assembly.GetAssembly(GetType()).GetName().Version;
+ Title += string.Format(" v.{0}.{1}.{2}", version.Major, version.Minor, version.Build);
#if DEBUG
- Title += " DEBUG";
- ShowTree = true;
+ Title += " DEBUG";
+ ShowTree = true;
#endif
- propGrid.SelectedObject = App.BuildOptions;
- App.BuildOptions.PropertyChanged += delegate { tbIn_TextChanged(this, null); };
- }
+ propGrid.SelectedObject = App.BuildOptions;
+ App.BuildOptions.PropertyChanged += delegate { tbIn_TextChanged(this, null); };
+ }
- ///
- /// When set, shows the MathML tree.
- ///
- public bool ShowTree
- {
- get { return (bool)GetValue(ShowTreeProperty); }
- set { SetValue(ShowTreeProperty, value); }
- }
+ ///
+ /// When set, shows the MathML tree.
+ ///
+ public bool ShowTree
+ {
+ get { return (bool)GetValue(ShowTreeProperty); }
+ set { SetValue(ShowTreeProperty, value); }
+ }
- private void tbIn_TextChanged(object sender, TextChangedEventArgs e)
- {
- tbOut.Text = string.Empty;
- // try parsing the root
- XElement root;
- try
- {
- string str = tbIn.Text;
- root = XElement.Parse(str);
- }
- catch (Exception ex)
- {
- tbOut.Text = ex.Message;
- return;
- }
- // fill the tree with xml elements
- FillTree(root);
-
- // now set output content
+ private void tbIn_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ tbOut.Text = string.Empty;
+ // try parsing the root
+ XElement root;
+ try
+ {
+ string str = tbIn.Text;
+ root = XElement.Parse(str);
+ }
+ catch (Exception ex)
+ {
+ tbOut.Text = ex.Message;
+ return;
+ }
+ // fill the tree with xml elements
+ FillTree(root);
+
+ // now set output content
#if RELEASE
try
{
#endif
- var m = Parser.Parse(root);
- var sb = new StringBuilder();
- m.Visit(sb, new BuildContext(App.BuildOptions));
- string s = sb.ToString();
- bool useHacks = true;
-
- if (useHacks)
- {
- // here's what happens when you realize string.Replace doesn't work as it should
- s = s.Replace("**", "*");
- s = s.Replace("(*", "(");
- s = s.Replace(")(", ")*(");
- s = s.Replace(")Math", ")*Math");
- s = s.Replace("+*", "+");
- s = s.Replace("-*", "-");
- s = s.Replace("/*", "/");
-
- // hack: even nastier hack here
- Regex re = new Regex(@"(\d)(\()");
- foreach (Match match in re.Matches(sb.ToString()))
- {
- string toReplace = match.Value;
- string toReplaceWith = match.Groups[1].Value + "*" + match.Groups[2].Value;
- s = s.Replace(toReplace, toReplaceWith);
- }
- }
-
- tbOut.Text = s;
+ var m = Parser.Parse(root);
+ var sb = new StringBuilder();
+ m.Visit(sb, new BuildContext(App.BuildOptions));
+ string s = sb.ToString();
+ bool useHacks = true;
+
+ if (useHacks)
+ {
+ // here's what happens when you realize string.Replace doesn't work as it should
+ s = s.Replace("**", "*");
+ s = s.Replace("(*", "(");
+ s = s.Replace(")(", ")*(");
+ s = s.Replace(")Math", ")*Math");
+ s = s.Replace("+*", "+");
+ s = s.Replace("-*", "-");
+ s = s.Replace("/*", "/");
+
+ // hack: even nastier hack here
+ Regex re = new Regex(@"(\d)(\()");
+ foreach (Match match in re.Matches(sb.ToString()))
+ {
+ string toReplace = match.Value;
+ string toReplaceWith = match.Groups[1].Value + "*" + match.Groups[2].Value;
+ s = s.Replace(toReplace, toReplaceWith);
+ }
+ }
+
+ tbOut.Text = s;
#if RELEASE
}
catch (Exception ex)
@@ -108,137 +112,137 @@ private void tbIn_TextChanged(object sender, TextChangedEventArgs e)
ex.StackTrace;
}
#endif
- }
-
+ }
- private void FillTree(XElement root)
- {
- if (root == null) throw new ArgumentNullException("root");
- // remove all items
- mmlTree.Items.Clear();
- // add root
- var rootItem = new TreeViewItem
- {
- Header = root.Name.LocalName,
- IsExpanded = true
- };
- mmlTree.Items.Add(rootItem);
-
- // add other items recursively
- AddTreeNodes(rootItem, root.Elements());
- }
- private static void AddTreeNodes(ItemsControl rootItem, IEnumerable elems)
- {
- if (rootItem == null) throw new ArgumentNullException("rootItem");
- if (elems == null) throw new ArgumentNullException("elems");
- foreach (var elem in elems)
- {
- var thisItem = new TreeViewItem
+ private void FillTree(XElement root)
{
- Header = elem.Name.LocalName +
- (elem.HasElements ? "" : " [" +
- (elem.Value.Length > 20 ? string.Empty : elem.Value)
- + "]"),
- IsExpanded = true
- };
-
- // if the type for this node does not exist in our wonderful little app,
- // make it bold and red!
- try
- {
- Type t = Type.GetType("MathMLToCSharp.Entities." + Parser.camel(elem.Name.LocalName));
- if (t == null)
- throw new NullReferenceException();
- thisItem.Foreground = Brushes.Black;
- thisItem.FontWeight = FontWeights.Normal;
+ if (root == null) throw new ArgumentNullException("root");
+ // remove all items
+ mmlTree.Items.Clear();
+ // add root
+ var rootItem = new TreeViewItem
+ {
+ Header = root.Name.LocalName,
+ IsExpanded = true
+ };
+ mmlTree.Items.Add(rootItem);
+
+ // add other items recursively
+ AddTreeNodes(rootItem, root.Elements());
}
- catch
+
+ private static void AddTreeNodes(ItemsControl rootItem, IEnumerable elems)
{
- thisItem.Foreground = Brushes.Red;
- thisItem.FontWeight = FontWeights.Bold;
+ if (rootItem == null) throw new ArgumentNullException("rootItem");
+ if (elems == null) throw new ArgumentNullException("elems");
+ foreach (var elem in elems)
+ {
+ var thisItem = new TreeViewItem
+ {
+ Header = elem.Name.LocalName +
+ (elem.HasElements ? "" : " [" +
+ (elem.Value.Length > 20 ? string.Empty : elem.Value)
+ + "]"),
+ IsExpanded = true
+ };
+
+ // if the type for this node does not exist in our wonderful little app,
+ // make it bold and red!
+ try
+ {
+ Type t = Type.GetType("MathMLToCSharp.Entities." + elem.Name.LocalName);
+ if (t == null)
+ throw new NullReferenceException();
+ thisItem.Foreground = Brushes.Black;
+ thisItem.FontWeight = FontWeights.Normal;
+ }
+ catch
+ {
+ thisItem.Foreground = Brushes.Red;
+ thisItem.FontWeight = FontWeights.Bold;
+ }
+
+ rootItem.Items.Add(thisItem);
+ AddTreeNodes(thisItem, elem.Elements());
+ }
}
- rootItem.Items.Add(thisItem);
- AddTreeNodes(thisItem, elem.Elements());
- }
- }
-
- private void lnkCopy_Click(object sender, RoutedEventArgs e)
- {
- Clipboard.SetText(tbOut.Text);
- }
-
- private void lnkPaste_Click(object sender, RoutedEventArgs e)
- {
- tbIn.Text = Clipboard.GetText();
- }
-
- private void myWindow_Closing(object sender, CancelEventArgs e)
- {
- Settings.Default["WindowState"] = WindowState;
- }
+ private void lnkCopy_Click(object sender, RoutedEventArgs e)
+ {
+ Clipboard.SetText(tbOut.Text);
+ }
- private void lnkFormat_Click(object sender, RoutedEventArgs e)
- {
- try
- {
- XElement xe = XElement.Parse(tbIn.Text);
- tbIn.Text = xe.ToString();
- }
- catch (Exception ex)
- {
- tbOut.Text = ex.Message;
- }
- }
+ private void lnkPaste_Click(object sender, RoutedEventArgs e)
+ {
+ tbIn.Text = Clipboard.GetText();
+ }
- private void myWindow_KeyDown(object sender, KeyEventArgs e)
- {
- // set window to fixed size for screenshots
-#if DEBUG
- if (e.Key == Key.F12)
- {
- Width = 640;
- Height = 480;
- ShowTree = false;
- }
-#endif
- }
+ private void myWindow_Closing(object sender, CancelEventArgs e)
+ {
+ Settings.Default["WindowState"] = WindowState;
+ }
- ///
- /// Handles the Click event of the lnkVerify control.
- ///
- /// The source of the event.
- /// The instance containing the event data.
- private void lnkVerify_Click(object sender, RoutedEventArgs e)
- { // let's check to see if the code we generated compiles or not
- try
- {
- CSharpCodeProvider p = new CSharpCodeProvider();
- CompilerParameters cp = new CompilerParameters();
- string source = "using System;" + Environment.NewLine +
- "using System.Diagnostics;" + Environment.NewLine +
- "namespace A { class B { static void Main() {" + Environment.NewLine +
- tbOut.Text + Environment.NewLine +
- "}}}";
- CompilerResults cr = p.CompileAssemblyFromSource(cp, source);
- if (cr.Errors.HasErrors)
+ private void lnkFormat_Click(object sender, RoutedEventArgs e)
{
- tbOut.Text = source + Environment.NewLine;
- foreach (CompilerError err in cr.Errors)
- tbOut.Text += err + Environment.NewLine;
+ try
+ {
+ XElement xe = XElement.Parse(tbIn.Text);
+ tbIn.Text = xe.ToString();
+ }
+ catch (Exception ex)
+ {
+ tbOut.Text = ex.Message;
+ }
}
- else
+
+ private void myWindow_KeyDown(object sender, KeyEventArgs e)
{
- MessageBox.Show(
- "Code has been verified. No errors were found.",
- "Verification", MessageBoxButton.OK, MessageBoxImage.Information);
+ // set window to fixed size for screenshots
+#if DEBUG
+ if (e.Key == Key.F12)
+ {
+ Width = 640;
+ Height = 480;
+ ShowTree = false;
+ }
+#endif
}
- }
- catch
- {
- }
+ ///
+ /// Handles the Click event of the lnkVerify control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void lnkVerify_Click(object sender, RoutedEventArgs e)
+ { // let's check to see if the code we generated compiles or not
+ try
+ {
+ CSharpCodeProvider p = new CSharpCodeProvider();
+ CompilerParameters cp = new CompilerParameters();
+ string source = "using System;" + Environment.NewLine +
+ "using System.Diagnostics;" + Environment.NewLine +
+ "namespace A { class B { static void Main() {" + Environment.NewLine +
+ tbOut.Text + Environment.NewLine +
+ "}}}";
+ CompilerResults cr = p.CompileAssemblyFromSource(cp, source);
+ if (cr.Errors.HasErrors)
+ {
+ tbOut.Text = source + Environment.NewLine;
+ foreach (CompilerError err in cr.Errors)
+ tbOut.Text += err + Environment.NewLine;
+ }
+ else
+ {
+ MessageBox.Show(
+ "Code has been verified. No errors were found.",
+ "Verification", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ }
+ catch
+ {
+
+ }
+ }
}
- }
}
diff --git a/MathMLToCSharp/MathMLToCSharp.csproj b/MathMLToCSharp/MathMLToCSharp.csproj
index 2552bf1..63ad981 100644
--- a/MathMLToCSharp/MathMLToCSharp.csproj
+++ b/MathMLToCSharp/MathMLToCSharp.csproj
@@ -43,27 +43,13 @@
-
- packages\MathNet.Numerics.3.20.0\lib\net35\MathNet.Numerics.dll
-
-
- False
- .\PowerCollections.dll
-
3.5
-
- packages\TaskParallelLibrary.1.0.2856.0\lib\Net35\System.Threading.dll
-
3.5
-
- 3.5
-
-
@@ -88,33 +74,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Code
@@ -128,20 +89,13 @@
Settings.settings
True
-
-
-
-
-
-
ResXFileCodeGenerator
Resources.Designer.cs
Designer
-
SettingsSingleFileGenerator
Settings.Designer.cs
@@ -150,7 +104,12 @@
-
+
+
+
+ {7e67aafd-564c-4362-b93f-7fdb912e2df7}
+ MathMLToCSharpLib
+
+
+ c
+
+ 2
+
+
+";
+ var result = Utils.ParseAndOutput(input, new BuildContextOptions()
+ {
+ InitializeVariables = false,
+ MaxInlinePower = 1
+ });
+ Assert.AreEqual(@"E=m*Math.Pow(c, 2);", result);
+ }
+
+ [Test]
+ public void A030_MathML_Einstein_Mass_Equation()
+ {
+ const string input = @""
+ ;
+
+ var result = Utils.ParseAndOutput(input, new BuildContextOptions()
+ {
+ InitializeVariables = false,
+ MaxInlinePower = 1
+ });
+ Assert.AreEqual(@"E_nergy=M_ass*Math.Pow(c_lightSpeed, 2);", result);
+ }
+
+
+ [Test]
+ public void A040_CreateGrouped_Variables()
+ {
+ // Note: Still waiting for a fix for https://github.com/verybadcat/CSharpMath/issues/59
+ const string input =
+ @""
+ ;
+ var result = Utils.ParseAndOutput(input, new BuildContextOptions()
+ {
+ InitializeVariables = false,
+ MaxInlinePower = 1
+ });
+ Assert.AreEqual(@"Math.Pow(Gap, 2);", result);
+ }
+
+ [Test]
+ public void A041_CreateGrouped_Variables()
+ {
+ // Note: Still waiting for a fix for https://github.com/verybadcat/CSharpMath/issues/59
+ const string input =
+ @""
+ ;
+ var result = Utils.ParseAndOutput(input, new BuildContextOptions()
+ {
+ InitializeVariables = false,
+ MaxInlinePower = 1
+ });
+ Assert.AreEqual(@"Math.Pow(Gap, 2)*gb;", result);
+ }
+
+
+ ///
+ [Test]
+ public void A045_CreateGrouped_Variable()
+ {
+ // Note: Still waiting for a fix for https://github.com/verybadcat/CSharpMath/issues/59
+ const string input =
+ @""
+ ;
+ var result = Utils.ParseAndOutput(input, new BuildContextOptions()
+ {
+ InitializeVariables = false,
+ MaxInlinePower = 1
+ });
+ Assert.AreEqual(@"F_n=Math.Pow(Gap, 2);", result);
+ }
+
+
+
+ }
+}
diff --git a/Tests/ConversionTests.cs b/Tests/ConversionTests.cs
index d008a5a..34bec11 100644
--- a/Tests/ConversionTests.cs
+++ b/Tests/ConversionTests.cs
@@ -1,85 +1,82 @@
-using MathMLToCSharp.Entities;
-using NUnit.Framework;
-using MathMLToCSharp;
+using System;
using System.Text;
using System.Xml.Linq;
-using System;
+
+using MathMLToCSharpLib;
+using MathMLToCSharpLib.Entities;
+
+using NUnit.Framework;
namespace Tests
{
- [TestFixture]
- public class ConversionTests
- {
- private static void Main() { }
-
- private static string ParseAndOutput(string mathML)
+ [TestFixture]
+ public class ConversionTests
{
- return ParseAndOutput(mathML, new BuildContextOptions());
- }
+ private static void Main() { }
- private static string ParseAndOutput(string mathML, BuildContextOptions options)
- {
- IBuildable b = Parser.Parse(XElement.Parse(mathML));
- StringBuilder sb = new StringBuilder();
- b.Visit(sb, new BuildContext(options));
- return sb.ToString();
- }
+ private static string ParseAndOutput(string mathML)
+ {
+ return ParseAndOutput(mathML, new BuildContextOptions());
+ }
- [Test]
- public void EmptyMathTest()
- {
- Assert.AreEqual(
- "",
- ParseAndOutput(""),
- "Empty math element must render to nothing.");
- }
+ private static string ParseAndOutput(string mathML, BuildContextOptions options)
+ {
+ IBuildable b = Parser.Parse(XElement.Parse(mathML));
+ StringBuilder sb = new StringBuilder();
+ b.Visit(sb, new BuildContext(options));
+ return sb.ToString();
+ }
- [Test]
- public void MathWithNumberTest()
- {
- Assert.AreEqual("2;",
- ParseAndOutput(""),
- "Basic mn block must render properly.");
- }
+ [Test]
+ public void EmptyMathTest()
+ {
+ Assert.AreEqual(
+ "",
+ ParseAndOutput(""),
+ "Empty math element must render to nothing.");
+ }
- [Test]
- public void BasicAssignmentTest()
- {
- Assert.AreEqual(
- "double n = 0.0;" + Environment.NewLine + "n=2;",
- ParseAndOutput(""),
- "Declaration and assignment ought to be together.");
- }
+ [Test]
+ public void MathWithNumberTest()
+ {
+ Assert.AreEqual("2;",
+ ParseAndOutput(""),
+ "Basic mn block must render properly.");
+ }
- [Test]
- public void BasicSubscriptTest()
- {
- Assert.AreEqual(
- "double a_b = 0.0;" + Environment.NewLine + "a_b;",
- ParseAndOutput(""));
- }
+ [Test]
+ public void BasicAssignmentTest()
+ {
+ Assert.AreEqual(
+ "double n = 0.0;" + Environment.NewLine + "n=2;",
+ ParseAndOutput(""),
+ "Declaration and assignment ought to be together.");
+ }
+
+ [Test]
+ public void BasicSubscriptTest()
+ {
+ Assert.AreEqual(
+ "double a_b = 0.0;" + Environment.NewLine + "a_b;",
+ ParseAndOutput(""));
+ }
+
+ [Test]
+ public void DoubleSubscriptTest()
+ {
+ Assert.AreEqual(
+ "double a_b_c = 0.0;" + Environment.NewLine + "a_b_c;",
+ ParseAndOutput(""));
+ }
+
+ [Test]
+ public void DoubleMultiSubscriptTest()
+ {
+ // LaTeX == a_{boost_{charge}}
+ Assert.AreEqual(
+ "double a_boost_charge = 0.0;" + Environment.NewLine + "a_boost_charge;",
+ ParseAndOutput(""));
+ }
- [Test]
- public void DoubleSubscriptTest()
- {
- Assert.AreEqual(
- "double a_b_c = 0.0;" + Environment.NewLine + "a_b_c;",
- ParseAndOutput(@"
-"));
}
- }
}
diff --git a/Tests/SimpleEquations.cs b/Tests/SimpleEquations.cs
new file mode 100644
index 0000000..167a1e3
--- /dev/null
+++ b/Tests/SimpleEquations.cs
@@ -0,0 +1,66 @@
+using NUnit.Framework;
+
+namespace MathMLToCSharpLib.Tests
+{
+ public class SimpleEquations
+ {
+ ///
+ /// https://en.wikipedia.org/wiki/Froude_number
+ ///
+ [Test]
+ public void Modified_FroudeNumber_Equation()
+ {
+ const string input =
+ @""
+ ;
+
+ var result = Utils.ParseAndOutput(input, new BuildContextOptions()
+ {
+ InitializeVariables = false,
+ MaxInlinePower = 1
+ });
+ Assert.AreEqual(@"F_n=((0.515*V_m) / (Math.Sqrt(g*L_WL)));", result);
+ }
+
+
+
+ }
+}
diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
index 0bbfcb6..54ba917 100644
--- a/Tests/Tests.csproj
+++ b/Tests/Tests.csproj
@@ -1,5 +1,6 @@
+
Debug
AnyCPU
@@ -22,6 +23,8 @@
3.5
+
+
true
@@ -41,7 +44,9 @@
4
-
+
+ ..\packages\NUnit.3.12.0\lib\net35\nunit.framework.dll
+
3.5
@@ -59,25 +64,30 @@
+
-
-
-
+
+
- {3909e9a8-4e8a-4358-a8a9-3ba634090378}
+ {7e67aafd-564c-4362-b93f-7fdb912e2df7}
MathMLToCSharpLib
-
- {9c1737f0-6dcc-4cc5-8c8e-f9b4073683f8}
- MathMLToCSharp
-
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+