Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for matrix elements #100

Closed
KennethHaugland opened this issue Jan 5, 2018 · 9 comments · Fixed by #155
Closed

Support for matrix elements #100

KennethHaugland opened this issue Jan 5, 2018 · 9 comments · Fixed by #155
Assignees

Comments

@KennethHaugland
Copy link

First off I have to say that this is extremely useful to me. However, I could not find any support for implementing matrices here are there any plans to do that?

Also, are there any plans to write a technical documentation on how the code is organized, and how to implement new functions etc?

Kenneth

@ForNeVeR
Copy link
Owner

ForNeVeR commented Jan 5, 2018

Hello and thanks for your interest.

Unfortunately, currently we haven't implemented matrices yet. There's a feature request for \begin{array}: #81. Is it the same you're asking?

We have plans to add some technical documentation (including XML definitions and documentation for contributors), but I don't think anyone is currently working on it.

Regarding implementation of that feature, I think that we'll need a separate environment handler for blocks \begin{stuff} … \end{stuff}, as we currently lack the feature.

As a start, one could implement a \begin command and then work from that. Most of our non-trivial custom command handling code currently resides in TexFormulaParser.ProcessCommand function, so I think that you could start from that (add a \begin / \end environment stack, and then handle the atoms inside of the environments).

About the render implementation for arrays and/or matrices: I think that you actually could create grid constructs from a combination of already existing HorizontalBox and VerticalBox boxes (it's not possible from the LaTeX code, but should be possible if you create the construct in C# and pass it to the renderer).

So, we have some basic ideas about what to do on both sides of the problem: parsing and rendering. We just need to find someone with enough of spare time to implement that :)

@KennethHaugland
Copy link
Author

Thanks for the quick reply. I was thinking of implementing some of these:
https://math-linux.com/latex-26/faq/latex-faq/article/how-to-write-matrices-in-latex-matrix-pmatrix-bmatrix-vmatrix-vmatrix

I guess that tex uses an array as a base to begin drawing of all of these different matrices. But, I don't think the parsing of the input would be so difficult if one uses regex with balanced grouping:
https://www.codeproject.com/Articles/21183/In-Depth-with-NET-RegEx-Balanced-Grouping
But glancing at the code I had no idea on how to proceed.

@ForNeVeR
Copy link
Owner

ForNeVeR commented Jan 5, 2018

Okay, I see how your feature request differs from #81. Although I'd recommend to start from the array and then implement new environments based on it (looks like they're just wrappers around array with various types of braces?)

Regarding the parsing: I don't think we need any regex here. We already have a decent parser engine that splits the text into tokens, so for now we just need the code to handle the \begin{} and \end{} command with the corresponding arguments. I'm not saying it's an easy task though.

@B3zaleel
Copy link
Contributor

B3zaleel commented Sep 22, 2018

You can check out #155 . I have a version that handles the \begin{...} and \end{} stuff, but it uses delegates to process the environment, since having all the environments handled in the "begin" command block would get messy. Though it uses commands, converting to the begin and end style is not a big change since the data from the source it retrieves is processed in a separate method.

@B3zaleel
Copy link
Contributor

B3zaleel commented Oct 11, 2018

Here's a mock-up code.

namespace WpfMath.Parsers
{
    /// <summary>
    /// Represents the method that will handle the tex environment.
    /// </summary>
    public delegate Atom TexEnvironmentHandler(TexFormula formula, SourceSpan environmentSource);

    public class TexFormulaParser
    {
        //...
        /// <summary>
        /// Gets or sets the environments recognized by this <see cref="TexFormulaParser"/> and their associated methods.
        /// </summary>
        public Dictionary<string, TexEnvironmentHandler> TexEnvironments { get; private set; }
        //...
        private Atom ProcessCommand(TexFormula formula, SourceSpan value, ref int position, string command, bool allowClosingDelimiter, ref bool closedDelimiter)
        {
            int start = position - command.Length;
            SkipWhiteSpace(value, ref position);
            if(command=="begin")
            {
                //Syntax: \begin{Environment-Name}...\end{Environment-Name}
                if (position == value.Length)
                    throw new TexParseException("illegal end!");
                SkipWhiteSpace(value, ref position);

                var beginEnvironmentName = ReadArgumentGroup(value, ref position, leftGroupChar, rightGroupChar).ToString().Trim();
                if (!TexEnvironments.ContainsKey(beginEnvironmentName))
                {
                    throw new TexParseException($"The environment, \"{beginEnvironmentName}\" is unavailable at the moment");
                }
                SkipWhiteSpace(value, ref position);
                bool environmentEndReached = false;
                int environmentDeepness = 0;
                int environmentSourceStart = position;
                int environmentSourceLength = 0;
                
                while (position < value.Length && environmentEndReached == false)
                {
                    if (value[position] == escapeChar)
                    {
                        position++;
                        if (position<value.Length)
                        {
                            if (Char.IsLetter(value[position]))
                            {
                                StringBuilder commandStrBuilder = new StringBuilder(value[position]);

                                while (position < value.Length && Char.IsLetter(value[position]))
                                {
                                    commandStrBuilder.Append(value[position].ToString());
                                    position++;
                                }

                                if (commandStrBuilder.ToString() == "begin")
                                {
                                    environmentDeepness++;
                                    environmentSourceLength += 6;
                                }
                                else if (commandStrBuilder.ToString() == "end")
                                {
                                    if (environmentDeepness == 0)
                                    {
                                        //try to check if the ending environment name is equal to the beginning environment name
                                        var endEnvironmentName = ReadArgumentGroup(value, ref position, leftGroupChar, rightGroupChar).ToString().Trim();
                                        if (endEnvironmentName == beginEnvironmentName)
                                        {
                                            environmentEndReached = true;
                                        }
                                        else
                                        {
                                            throw new TexParseException($"The environment name \"{beginEnvironmentName}\" does not match the ending environment name, \"{endEnvironmentName}\"");
                                        }
                                    }
                                    else
                                    {
                                        environmentDeepness--;
                                        environmentSourceLength += 4;
                                    }
                                }
                                else
                                {
                                    environmentSourceLength += commandStrBuilder.Length + 1;
                                }
                            }
                            else
                            {
                                position++;
                                environmentSourceLength += 2;
                            }
                        }
                    }
                    else
                    {
                        position++;
                        environmentSourceLength++;
                    }
                }

                if (environmentEndReached)
                {
                    //process it
                    if (TexEnvironments.ContainsKey(beginEnvironmentName))
                    {
                        try
                        {
                            return TexEnvironments[beginEnvironmentName].Invoke(formula, value.Segment(environmentSourceStart, environmentSourceLength));
                        }
                        catch (Exception e)
                        {
                            //Show that the error was from an environment and show the environment error message
                            throw new TexParseException($"The \"{beginEnvironmentName}\" environment data is invalid.\n{e.Message}");
                        }
                    }
                    else
                    {
                        throw new TexParseException($"The environment\"{beginEnvironmentName}\" has not been registered");
                    }
                }
                else
                {
                    throw new TexParseException($"The end of the environment, \"{beginEnvironmentName}\", cannot be found");
                }
        }
        else
        {
            //Handle other commands.
        }



    }
}

@troelschristensen
Copy link

@B3zaleel @ForNeVeR

Are there any news on, when this feature will be coming to wpf-math? I can see, that @B3zaleel already has come up with a mock-up. It would be great, if this feature could come any time soon.
I'm not so keen on installing the files in my Visual Studio solution. Have looked into it @B3zaleel. But I think I stick to getting the packages from Nuget.org via the nuget manager inside VS.

@ForNeVeR
Copy link
Owner

@troelschristensen the issue is just I was having a little vacation from the project, and it's almost over for now.

Thanks for your question, I'll prioritize the corresponding PR on my TODO list. And yes, I'll publish a new WPF-Math release on the NuGet soon (after merging of a couple of PRs).

@troelschristensen
Copy link

Hi @ForNeVeR . Thank you for the reply. I don't think you should work in your vacation. So I wish you a nice and pleasant vacation and look forward to see, what is in the next update, when you return. Kind regards.

@ForNeVeR ForNeVeR mentioned this issue Jan 7, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Feb 23, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Mar 7, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Mar 13, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Mar 23, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Apr 1, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Apr 2, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue May 26, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 4, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 4, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 4, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 4, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 4, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 4, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
Now there're no special atoms for matrices, because we can reuse the
original FencedAtom.
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 11, 2019
It is completely replaced by ReadElementGroup.
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 18, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 18, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 18, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 18, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 18, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 18, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 18, 2019
ForNeVeR added a commit to B3zaleel/xaml-math that referenced this issue Aug 19, 2019
@ForNeVeR
Copy link
Owner

ForNeVeR commented Aug 24, 2019

We've successfully implemented some of the matrix commands in #155, and I've created a successor task in #201.

@ForNeVeR ForNeVeR self-assigned this Aug 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants