Advertisement
Guest User

sackara

a guest
Apr 4th, 2020
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.26 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO;
  5. using System.Text.RegularExpressions;
  6. using System.Xml;
  7. using System.Linq;
  8. using System.Linq.Expressions;
  9. using System.Runtime.CompilerServices;
  10.  
  11.  
  12. namespace latexparse_csharp
  13. {
  14.     internal enum SearchMode
  15.     {
  16.         BeginCommand,
  17.         CommandSequence,
  18.         Parameters,
  19.         Text
  20.     }
  21.  
  22.  
  23.     public class LatexParser
  24.     {
  25.         private static string FileData { get; set; }
  26.  
  27.         private static List<Command> Commands { get; set; }
  28.  
  29.         public static List<CommandBase> ParseFile(string filepath)
  30.         {
  31.             //Get File Data
  32.             FileData = File.ReadAllText(filepath, Encoding.UTF8).Replace("\r", "").Replace("\n", "");
  33.  
  34.             //Create Command Dictionary
  35.             Commands = new List<Command>();
  36.  
  37.  
  38.             using (XmlReader reader = XmlReader.Create(new StringReader(Properties.Resources.CommandDictionary),
  39.                 new XmlReaderSettings() { IgnoreComments = true }))
  40.             {
  41.  
  42.                 //Read XMl Command Dictionary
  43.                 XmlDocument doc = new XmlDocument();
  44.                 doc.Load(reader);
  45.  
  46.  
  47.                 //Get all used packages to load Commands into Dictionary
  48.                 Regex regex = new Regex(@"\\usepackage(\[(.*?)\])?\{(.*?)\}");
  49.  
  50.                 //Iterate through Regex Matches
  51.                 foreach (Match match in regex.Matches(FileData))
  52.                 {
  53.                     for (int i = 0; i < doc.ChildNodes.Count; i++)
  54.                     {
  55.                         if (doc.ChildNodes[i].Name == match.Groups[3].Value || doc.ChildNodes[i].Name == "base")
  56.                         {
  57.                             foreach (XmlNode cmdnode in doc.ChildNodes[i])
  58.                             {
  59.                                 Commands.Add(Command.Parse(cmdnode));
  60.                             }
  61.                         }
  62.  
  63.                     }
  64.                 }
  65.             }
  66.             GParameter param = new GParameter("test", Parametertypes.Required, false);
  67.             int counter = 0;
  68.             GetSubCommands(ref param, ref counter);
  69.             return param.SubCommands;
  70.         }
  71.  
  72.         private static void GetSubCommands(ref GParameter parentparam, ref int counter)
  73.         {
  74.             char endingchar;
  75.             //Get Character that can end this Parameter
  76.             switch (parentparam.Parametertype)
  77.             {
  78.                 case Parametertypes.Required:
  79.                     endingchar = (parentparam.CanHaveBody) ? '\\' : '}';
  80.                     break;
  81.  
  82.                 default:
  83.                     endingchar = ']';
  84.                     break;
  85.             }
  86.  
  87.             //Set Search Mode
  88.             SearchMode mode = SearchMode.BeginCommand;
  89.  
  90.             //Setup Variables for recording commands
  91.             int startindex = counter;
  92.             Command currcmd = null;
  93.  
  94.             for (int i = counter; i < FileData.Length; i++)
  95.             {
  96.  
  97.                 if (FileData[i] == endingchar)
  98.                 {
  99.                     if (mode == SearchMode.Text)
  100.                     {
  101.                         string txtcontent = new string(new ArraySegment<char>(FileData.ToCharArray(),
  102.                             startindex, i - startindex).ToArray());
  103.  
  104.                         //Add Command and adjust counter + mode accordingly
  105.                         ((GParameter)parentparam).SubCommands.Add(new TextCommand(txtcontent));
  106.                     }
  107.                     else
  108.                     {
  109.                         if (currcmd != null)
  110.                         {
  111.                             parentparam.SubCommands.Add(currcmd);
  112.                         }
  113.                     }
  114.  
  115.                     counter = i;
  116.                     return;
  117.                 }
  118.                 else if (mode == SearchMode.BeginCommand)
  119.                 {
  120.                     if (FileData[i] == '\\')
  121.                     {
  122.                         //Start Initiating Command Authorization
  123.                         startindex = i;
  124.                         mode = SearchMode.CommandSequence;
  125.                     }
  126.                     else
  127.                     {
  128.                         startindex = i;
  129.                         mode = SearchMode.Text;
  130.                     }
  131.                 }
  132.                 else if (mode == SearchMode.CommandSequence)
  133.                 {
  134.                     if (!Char.IsLetter(FileData[i]))
  135.                     {
  136.                         //Get Command Signature
  137.                         startindex++;
  138.                         string cmdname = new string(new ArraySegment<char>(FileData.ToCharArray(),
  139.                             startindex, i - startindex).ToArray());
  140.  
  141.                         Command res = Commands.First(x => x.Name == cmdname);
  142.                         //Verify if Command is loaded
  143.                         if (res != null)
  144.                         {
  145.                             //Update Mode
  146.                             mode = SearchMode.Parameters;
  147.  
  148.                             //Add Command to Parentparam (can either be acutal parameter or constructed in ParseFile)
  149.                             parentparam.SubCommands.Add(res);
  150.  
  151.                             //Set Current Command as Copy of recognized Command
  152.                             currcmd = (Command)res.Clone();
  153.  
  154.  
  155.                             //Tune back counter to enable parameter detection
  156.                             i--;
  157.                         }
  158.                     }
  159.                 }
  160.                 else if (mode == SearchMode.Parameters)
  161.                 {
  162.                     switch (FileData[i])
  163.                     {
  164.                         case '{':
  165.                             GParameter currparam = currcmd.Parameters.OfType<GParameter>()
  166.                                 .First(x => x.Parametertype == Parametertypes.Required && !x.ValueRecorded);
  167.                             i++;
  168.                             GetSubCommands(ref currparam, ref i);
  169.                             currparam.ValueRecorded = true;
  170.                             break;
  171.                         case '[':
  172.                             GParameter curroparam = currcmd.Parameters.OfType<GParameter>()
  173.                                 .FirstOrDefault(x => x.Parametertype == Parametertypes.Optional && !x.ValueRecorded);
  174.                             i++;
  175.                             GetSubCommands(ref curroparam, ref i);
  176.                             curroparam.ValueRecorded = true;
  177.                             break;
  178.                         default:
  179.                             try
  180.                             {
  181.                                 SCParameter param = currcmd.Parameters.OfType<SCParameter>()
  182.                                     .First(x => !x.ValueRecorded);
  183.                                 if (param != null && FileData[i] == param.Key)
  184.                                 {
  185.                                     param.ValueRecorded = true;
  186.                                     param.Enabled = true;
  187.                                 }
  188.                             }
  189.                             catch (NullReferenceException exc)
  190.                             {
  191.                                 if (currcmd.Parameters.Exists(x => !x.ValueRecorded &&
  192.                                                                    ((GParameter)x).Parametertype == Parametertypes.Required))
  193.                                 {
  194.                                     GParameter param = (GParameter)currcmd.Parameters.First(x =>
  195.                                         !x.ValueRecorded &&
  196.                                         ((GParameter)x).Parametertype == Parametertypes.Required);
  197.                                     if (FileData[i] != ' ')
  198.                                     {
  199.  
  200.                                         if (param.CanHaveBody)
  201.                                         {
  202.                                             GetSubCommands(ref param, ref i);
  203.                                             param.ValueRecorded = true;
  204.                                         }
  205.                                         else
  206.                                             param.SubCommands.Add(new TextCommand(FileData[i].ToString()));
  207.                                     }
  208.                                 }
  209.                             }
  210.                             break;
  211.                     }
  212.  
  213.                     if (currcmd.Parameters.All(x => x.ValueRecorded))
  214.                     {
  215.                         mode = SearchMode.BeginCommand;
  216.                     }
  217.  
  218.                 }
  219.                 else if (mode == SearchMode.Text)
  220.                 {
  221.                     if (FileData[i] == '\\')
  222.                     {
  223.                         //Get string content and load it into a textcomment
  224.                         string txtcontent = new string(new ArraySegment<char>(FileData.ToCharArray(),
  225.                             startindex, i - startindex).ToArray());
  226.  
  227.                         //Add Command and adjust counter + mode accordingly
  228.                         ((GParameter)parentparam).SubCommands.Add(new TextCommand(txtcontent));
  229.                         i--;
  230.                         mode = SearchMode.BeginCommand;
  231.                     }
  232.                 }
  233.  
  234.             }
  235.         }
  236.     }
  237. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement