diff --git a/BibtexLibrary.Documentation/BibtexLibrary.Documentation.shfbproj b/BibtexLibrary.Documentation/BibtexLibrary.Documentation.shfbproj
new file mode 100644
index 0000000..f778cb5
--- /dev/null
+++ b/BibtexLibrary.Documentation/BibtexLibrary.Documentation.shfbproj
@@ -0,0 +1,135 @@
+
+
+
+
+ Debug
+ AnyCPU
+ 2.0
+ 617b9073-b902-49a2-b28d-4d790595d7cd
+ 2017.9.26.0
+
+ BibtexLibrary.Documentation
+ BibtexLibrary.Documentation
+ BibtexLibrary.Documentation
+
+ .NET Framework 4.5
+ ..\..\doc\BibTex\
+ BibtexLibrary.Documentation
+ en-US
+
+
+
+
+
+
+
+
+
+
+
+
+ Website
+ C#
+ VS2013
+ True
+ True
+ False
+ False
+ OnlyWarningsAndErrors
+ 100
+ BibtexLibrary
+ 1.0.0.0
+ MemberName
+ AboveNamespaces
+ False
+ True
+ 2
+ False
+ Blank
+ AutoDocumentCtors, AutoDocumentDispose
+ False
+
+
+ {@TokenFiles}
+
+
+
+
+ {@HelpFormatOutputPaths}
+
+
+
+
+
+
+
+ {@SyntaxFilters}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OnBuildSuccess
+
+
\ No newline at end of file
diff --git a/BibtexLibrary.Documentation/Content/VersionHistory/VersionHistory.aml b/BibtexLibrary.Documentation/Content/VersionHistory/VersionHistory.aml
new file mode 100644
index 0000000..444028f
--- /dev/null
+++ b/BibtexLibrary.Documentation/Content/VersionHistory/VersionHistory.aml
@@ -0,0 +1,33 @@
+
+
+
+
+ The topics in this section describe the various changes made to the [TODO: Project Title] over the
+life of the project.
+
+
+
+ Version History
+
+ Select a version below to see a description of its changes.
+
+
+
+
+
+
+
+ [TODO: Add links to each specific version page]
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BibtexLibrary.Documentation/Content/VersionHistory/v1.0.0.0.aml b/BibtexLibrary.Documentation/Content/VersionHistory/v1.0.0.0.aml
new file mode 100644
index 0000000..8d20206
--- /dev/null
+++ b/BibtexLibrary.Documentation/Content/VersionHistory/v1.0.0.0.aml
@@ -0,0 +1,28 @@
+
+
+
+
+ Version [TODO: Version] was released on [TODO: Date].
+
+
+
+
+ Changes in This Release
+
+
+
+
+ [TODO: Add change items here]
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BibtexLibrary.Documentation/Content/Welcome.aml b/BibtexLibrary.Documentation/Content/Welcome.aml
new file mode 100644
index 0000000..1233b4d
--- /dev/null
+++ b/BibtexLibrary.Documentation/Content/Welcome.aml
@@ -0,0 +1,55 @@
+
+
+
+
+ This is a sample conceptual topic. You can use this as a starting point for adding more conceptual
+content to your help project.
+
+
+
+ Getting Started
+
+ To get started, add a documentation source to the project (a Visual Studio solution, project, or
+assembly and XML comments file). See the Getting Started topics in the Sandcastle Help
+File Builder's help file for more information. The following default items are included in this project:
+
+
+
+ ContentLayout.content - Use the content layout file to manage the
+conceptual content in the project and define its layout in the table of contents.
+
+
+
+ The .\media folder - Place images in this folder that you will reference
+from conceptual content using medialLink or mediaLinkInline
+elements. If you will not have any images in the file, you may remove this folder.
+
+
+
+ The .\icons folder - This contains a default logo for the help file. You
+may replace it or remove it and the folder if not wanted. If removed or if you change the file name, update
+the Transform Args project properties page by removing or changing the filename in the
+logoFile transform argument. Note that unlike images referenced from conceptual topics,
+the logo file should have its BuildAction property set to Content.
+
+
+
+ The .\Content folder - Use this to store your conceptual topics. You may
+name the files and organize them however you like. One suggestion is to lay the files out on disk as you have
+them in the content layout file as shown in this project but the choice is yours. Files can be added via the
+Solution Explorer or from within the content layout file editor. Files must appear in the content layout file
+in order to be compiled into the help file.
+
+
+
+ See the Conceptual Content topics in the Sandcastle Help File Builder's
+help file for more information. See the Sandcastle MAML Guide for details on Microsoft
+Assistance Markup Language (MAML) which is used to create these topics.
+
+
+
+
+
+
+
+
diff --git a/BibtexLibrary.Documentation/ContentLayout.content b/BibtexLibrary.Documentation/ContentLayout.content
new file mode 100644
index 0000000..1e04cbc
--- /dev/null
+++ b/BibtexLibrary.Documentation/ContentLayout.content
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BibtexLibrary.Documentation/icons/Help.png b/BibtexLibrary.Documentation/icons/Help.png
new file mode 100644
index 0000000..945e89f
Binary files /dev/null and b/BibtexLibrary.Documentation/icons/Help.png differ
diff --git a/BibtexLibrary.Standard/BibtexEntry.cs b/BibtexLibrary.Standard/BibtexEntry.cs
new file mode 100644
index 0000000..88ae1a7
--- /dev/null
+++ b/BibtexLibrary.Standard/BibtexEntry.cs
@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+
+namespace BibtexLibrary
+{
+ ///
+ /// Single entry in Bibtex file
+ ///
+ public class BibtexEntry
+ {
+ ///
+ /// The tags
+ ///
+ private Dictionary _tags = new Dictionary();
+ ///
+ /// Gets or sets the type.
+ ///
+ ///
+ /// The type.
+ ///
+ public string Type { get; set; }
+
+ ///
+ /// Gets or sets the key.
+ ///
+ ///
+ /// The key.
+ ///
+ public string Key { get; set; }
+
+ ///
+ /// Gets or sets the tags.
+ ///
+ ///
+ /// The tags.
+ ///
+ public Dictionary Tags
+ {
+ get { return _tags; }
+ set { _tags = value; }
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/BibtexFile.cs b/BibtexLibrary.Standard/BibtexFile.cs
new file mode 100644
index 0000000..1ea2b61
--- /dev/null
+++ b/BibtexLibrary.Standard/BibtexFile.cs
@@ -0,0 +1,45 @@
+using System.Collections.Generic;
+
+namespace BibtexLibrary
+{
+ ///
+ /// Collection of Bibtex entries
+ ///
+ public class BibtexFile
+ {
+ private ICollection _entries = new List();
+ private Dictionary _stringDefinitions = new Dictionary();
+
+ ///
+ /// Gets or sets the string definitions.
+ ///
+ ///
+ /// The string definitions.
+ ///
+ public Dictionary StringDefinitions
+ {
+ get { return _stringDefinitions; }
+ set { _stringDefinitions = value; }
+ }
+
+ ///
+ /// Gets or sets the preamble.
+ ///
+ ///
+ /// The preamble.
+ ///
+ public ICollection Preamble { get; set; }
+
+ ///
+ /// Gets or sets the entries.
+ ///
+ ///
+ /// The entries.
+ ///
+ public ICollection Entries
+ {
+ get { return _entries; }
+ set { _entries = value; }
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/BibtexImporter.cs b/BibtexLibrary.Standard/BibtexImporter.cs
new file mode 100644
index 0000000..ba1a013
--- /dev/null
+++ b/BibtexLibrary.Standard/BibtexImporter.cs
@@ -0,0 +1,38 @@
+using BibtexLibrary.Parser;
+using BibtexLibrary.Tokenizer;
+using System;
+using System.IO;
+
+namespace BibtexLibrary
+{
+ ///
+ /// Parser
+ ///
+ public class BibtexImporter
+ {
+
+
+ ///
+ /// Froms the string.
+ ///
+ /// The text.
+ ///
+ public static BibtexFile FromString(string text)
+ {
+ BibtexParser file = new BibtexParser(new Tokenizer.Tokenizer(new ExpressionDictionary(), text));
+
+ return file.Parse();
+ }
+
+ ///
+ /// Froms the stream.
+ ///
+ /// The reader.
+ ///
+ ///
+ public static BibtexFile FromStream(StreamReader reader)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/BibtexLibrary.Standard.csproj b/BibtexLibrary.Standard/BibtexLibrary.Standard.csproj
new file mode 100644
index 0000000..b913eba
--- /dev/null
+++ b/BibtexLibrary.Standard/BibtexLibrary.Standard.csproj
@@ -0,0 +1,80 @@
+
+
+
+ netstandard2.0;net45;net40
+ imbSCI - Copy.ico
+ True
+ imbSCI.BibtexLibrary.Standard
+ 1.5.28
+ BibtexLibrary .NET Standard - for imbSCI
+
+ http://doc.veles.rs/imbSCI.ico
+ http://blog.veles.rs/
+ http://doc.veles.rs/LICENCE.txt
+ Copyright (C) 2018
+ Maikel Hofman's BibtexLibrary - multi-target / cross-platform fork by Goran Grubić (imbVeles).
+
+Original repository: https://github.com/MaikelH/BibtexLibrary
+ en-US
+ Targets: .NET 4.0*, .NET 4.5 and .NET Core 2.0 i.e ready for use in cross-platform application development.
+
+ BibTex, Excel
+ https://github.com/gorangrubic/BibtexLibrary
+ GitHub
+ Maikel Hofman, Goran Grubić
+ imbVeles
+ 1.5.1.2
+ 1.5.1.2
+ imbSCI.BibtexLibrary.Standard
+ False
+ BibtexLibrary
+ true
+ key.snk
+
+
+
+
+ NETCORE;NETSTANDARD;NETSTANDARD2_0
+
+
+
+ NET40
+
+
+
+ NET45;NETFULL
+
+
+
+ $(OutputPath)$(PackageId).xml
+
+
+
+ True
+ True
+ False
+ False
+ False
+ True
+ SettingsVersion
+ None
+ 0
+
+
+
+ True
+ True
+ False
+ False
+ False
+ True
+ SettingsVersion
+ None
+
+
+
+
+
+
+
+
diff --git a/BibtexLibrary.Standard/BibtexLibrary.Standard.xml b/BibtexLibrary.Standard/BibtexLibrary.Standard.xml
new file mode 100644
index 0000000..0c8e20d
--- /dev/null
+++ b/BibtexLibrary.Standard/BibtexLibrary.Standard.xml
@@ -0,0 +1,184 @@
+
+
+
+ BibtexLibrary.Standard
+
+
+
+
+ Single entry in Bibtex file
+
+
+
+
+ The tags
+
+
+
+
+ Gets or sets the type.
+
+
+ The type.
+
+
+
+
+ Gets or sets the key.
+
+
+ The key.
+
+
+
+
+ Gets or sets the tags.
+
+
+ The tags.
+
+
+
+
+ Collection of Bibtex entries
+
+
+
+
+ Gets or sets the string definitions.
+
+
+ The string definitions.
+
+
+
+
+ Gets or sets the preamble.
+
+
+ The preamble.
+
+
+
+
+ Gets or sets the entries.
+
+
+ The entries.
+
+
+
+
+ Parser
+
+
+
+
+ Froms the string.
+
+ The text.
+
+
+
+
+ Froms the stream.
+
+ The reader.
+
+
+
+
+
+ Initializes a new instance of the class.
+
+ The tokenizer.
+
+
+
+ Parses this instance.
+
+
+
+
+
+ Converts the parse node.
+
+ The node.
+
+
+
+
+ Parses the input.
+
+ The tokenizer.
+
+
+
+
+ Entries the specified tokenizer.
+
+ The tokenizer.
+
+
+
+
+ Texts the specified tokenizer.
+
+ The tokenizer.
+
+ Expected type Text but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+
+
+
+ Openings the brace.
+
+ The tokenizer.
+ Expected type OpeningBrace but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+
+
+
+ Closings the brace.
+
+ The tokenizer.
+ Expected type ClosingBrace but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+
+
+
+ Commas the specified tokenizer.
+
+ The tokenizer.
+ if set to true [optional].
+ Expected type Comma but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+
+
+
+ Retrieves the tag values from the input.
+
+ The tokenizer.
+
+
+
+
+ Return all the tokens in the inputstring.
+
+ List of tokens
+
+
+
+ Checks whether the scanner is at the end of the input.
+
+
+
+
+ Returns the previous n characters.
+
+
+ Previous characters in the tokenizer
+
+
+
+ Base class for tokens
+
+
+
+
diff --git a/BibtexLibrary.Standard/Parser/BibtexParser.cs b/BibtexLibrary.Standard/Parser/BibtexParser.cs
new file mode 100644
index 0000000..7cc234d
--- /dev/null
+++ b/BibtexLibrary.Standard/Parser/BibtexParser.cs
@@ -0,0 +1,370 @@
+using BibtexLibrary.Parser.Nodes;
+using BibtexLibrary.Tokens;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace BibtexLibrary.Parser
+{
+ public class BibtexParser
+ {
+ private readonly Tokenizer.Tokenizer _tokenizer;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The tokenizer.
+ public BibtexParser(Tokenizer.Tokenizer tokenizer)
+ {
+ _tokenizer = tokenizer;
+ }
+
+ ///
+ /// Parses this instance.
+ ///
+ ///
+ public BibtexFile Parse()
+ {
+ ParseNode node = ParseInput(_tokenizer);
+ BibtexFile fileObject = convertParseNode(node);
+
+ return fileObject;
+ }
+
+ ///
+ /// Converts the parse node.
+ ///
+ /// The node.
+ ///
+ private BibtexFile convertParseNode(ParseNode node)
+ {
+ Nodes.BibtexFile parseFile = (Nodes.BibtexFile)node;
+
+ BibtexFile bibtex = new BibtexFile();
+
+ foreach (Entry entry in parseFile.Entries)
+ {
+ if (entry.Type == "String")
+ {
+ bibtex.StringDefinitions.Add(entry.Tags.First().Key, entry.Tags.First().Value);
+ }
+ else
+ {
+ BibtexEntry bibtexEntry = new BibtexEntry { Key = entry.Key, Type = entry.Type };
+
+ entry.Tags.ToList().ForEach(x => bibtexEntry.Tags.Add(x.Key, x.Value));
+
+ bibtex.Entries.Add(bibtexEntry);
+ }
+ }
+
+ return bibtex;
+ }
+
+ ///
+ /// Parses the input.
+ ///
+ /// The tokenizer.
+ ///
+ private ParseNode ParseInput(Tokenizer.Tokenizer tokenizer)
+ {
+ Nodes.BibtexFile file = new Nodes.BibtexFile();
+
+ while (!tokenizer.EndOfInput)
+ {
+ AbstractToken token = tokenizer.NextToken();
+
+ if (token.GetType() == typeof(At))
+ {
+ file.Entries.Add(Entry(tokenizer));
+ }
+ }
+
+ return file;
+ }
+
+ ///
+ /// Entries the specified tokenizer.
+ ///
+ /// The tokenizer.
+ ///
+ private Entry Entry(Tokenizer.Tokenizer tokenizer)
+ {
+ Entry entry = new Entry();
+
+ entry.Type = Text(tokenizer);
+ OpeningBrace(tokenizer);
+
+ if (!entry.Type.Equals("String", StringComparison.OrdinalIgnoreCase))
+ {
+ entry.Key = Text(tokenizer);
+ Comma(tokenizer);
+ }
+
+ entry.Tags = Tags(tokenizer);
+ ClosingBrace(tokenizer);
+
+ return entry;
+ }
+
+ ///
+ /// Texts the specified tokenizer.
+ ///
+ /// The tokenizer.
+ ///
+ /// Expected type Text but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+ private String Text(Tokenizer.Tokenizer tokenizer)
+ {
+ AbstractToken token = tokenizer.NextToken();
+
+ if (token.GetType() == typeof(Comma) || token.GetType() == typeof(Text))
+ {
+ return token.GetValue();
+ }
+
+ throw new ParseException("Expected type Text but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25));
+ }
+
+ ///
+ /// Openings the brace.
+ ///
+ /// The tokenizer.
+ /// Expected type OpeningBrace but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+ private void OpeningBrace(Tokenizer.Tokenizer tokenizer)
+ {
+ AbstractToken token = tokenizer.NextToken();
+
+ if (token.GetType() == typeof(OpeningBrace))
+ {
+ return;
+ }
+
+ throw new ParseException("Expected type OpeningBrace but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25));
+ }
+
+ ///
+ /// Closings the brace.
+ ///
+ /// The tokenizer.
+ /// Expected type ClosingBrace but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+ private void ClosingBrace(Tokenizer.Tokenizer tokenizer)
+ {
+ AbstractToken token = tokenizer.NextToken();
+
+ if (token.GetType() == typeof(ClosingBrace))
+ {
+ return;
+ }
+
+ throw new ParseException("Expected type ClosingBrace but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25));
+ }
+
+ ///
+ /// Commas the specified tokenizer.
+ ///
+ /// The tokenizer.
+ /// if set to true [optional].
+ /// Expected type Comma but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+ private void Comma(Tokenizer.Tokenizer tokenizer, Boolean optional = false)
+ {
+ AbstractToken token = tokenizer.Peek();
+
+ if (token.GetType() == typeof(Comma))
+ {
+ tokenizer.NextToken();
+ return;
+ }
+
+ if (optional)
+ {
+ return;
+ }
+
+ throw new ParseException("Expected type Comma but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25));
+ }
+
+ public static Boolean MUTE_PEEK_EXCEPTIONS = true;
+ public static Int32 PARSER_EXCEPTIONS_LIMIT = 0;
+
+ public List ParsingExceptions { get; set; } = new List();
+
+
+ ///
+ /// Retrieves the tag values from the input.
+ ///
+ /// The tokenizer.
+ ///
+ private ICollection Tags(Tokenizer.Tokenizer tokenizer)
+ {
+ // This function needs some refactoring.
+ List tags = new List();
+
+ while (tokenizer.Peek().GetType() != typeof(ClosingBrace))
+ {
+ Tag tag = new Tag { Key = Text(tokenizer) };
+ Equals(tokenizer);
+ AbstractToken startToken = ValueStart(tokenizer);
+
+ List tokens = new List();
+
+ bool keepProcessing = true;
+ int balance = 1;
+
+ while (keepProcessing)
+ {
+ Type nextTokenType = null;
+
+ // ------------------------------------ format failure protection
+ if (!MUTE_PEEK_EXCEPTIONS)
+ {
+ nextTokenType = tokenizer.Peek().GetType();
+ }
+ else
+ {
+ try
+ {
+ nextTokenType = tokenizer.Peek().GetType();
+ }
+ catch (Exception ex)
+ {
+ ParsingExceptions.Add(ex);
+ if (ParsingExceptions.Count() > PARSER_EXCEPTIONS_LIMIT)
+ {
+ throw;
+ }
+ }
+ }
+
+ if (nextTokenType == null)
+ {
+ tokenizer.NextToken();
+
+ if (ParsingExceptions.Count() > PARSER_EXCEPTIONS_LIMIT)
+ {
+ keepProcessing = false;
+
+ }
+
+ continue;
+
+ }
+
+ // ------------------------------------ format failure protection
+
+
+
+ if (nextTokenType == typeof(OpeningBrace))
+ {
+ balance++;
+ }
+
+ if ((startToken.GetType() == typeof(OpeningBrace) && nextTokenType == typeof(ClosingBrace)))
+ {
+ if (balance == 1)
+ {
+ keepProcessing = false;
+ ValueStop(tokenizer);
+ }
+ }
+
+ if (nextTokenType == typeof(ClosingBrace))
+ {
+ if (balance > 1)
+ {
+ balance--;
+ }
+ }
+
+ // Double quotes are much more difficult to handle then the braces. The problem is that there is no distinction between
+ // start and stop quotes. This means we need to look forward to see what is behind the quote to see if it is a quote @ the end
+ // or the start of a new quote.
+ if (nextTokenType == typeof(ValueQuote))
+ {
+ AbstractToken quote = tokenizer.NextToken();
+
+ Type nextType = tokenizer.Peek().GetType();
+ if ((nextType == typeof(ClosingBrace) && balance == 1) ||
+ nextType == typeof(Comma))
+ {
+ // end of line found.
+ keepProcessing = false;
+ }
+ else
+ {
+ tokens.Add(quote);
+ continue;
+ }
+ }
+
+ if (keepProcessing)
+ {
+ tokens.Add(tokenizer.NextToken());
+ }
+ }
+
+ tag.Value = tokens.Aggregate("", (s, token) => s + token.RawValue);
+
+ Comma(tokenizer, true);
+ NewLine(tokenizer, true);
+
+ tags.Add(tag);
+ }
+
+ return tags;
+ }
+
+ private void Equals(Tokenizer.Tokenizer tokenizer)
+ {
+ AbstractToken token = tokenizer.NextToken();
+
+ if (token.GetType() == typeof(Equals))
+ {
+ return;
+ }
+
+ throw new ParseException("Expected type Equals but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25));
+ }
+
+ private AbstractToken ValueStart(Tokenizer.Tokenizer tokenizer)
+ {
+ AbstractToken token = tokenizer.NextToken();
+
+ if (token.GetType() == typeof(OpeningBrace) || token.GetType() == typeof(ValueQuote))
+ {
+ return token;
+ }
+
+ throw new ParseException("Expected type Openingbrace or ValueQuote but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25));
+ }
+
+ private AbstractToken ValueStop(Tokenizer.Tokenizer tokenizer)
+ {
+ AbstractToken token = tokenizer.NextToken();
+
+ if (token.GetType() == typeof(ClosingBrace) || token.GetType() == typeof(ValueQuote))
+ {
+ return token;
+ }
+
+ throw new ParseException("Expected type ClosingBrace or ValueQuote but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25));
+ }
+
+ private void NewLine(Tokenizer.Tokenizer tokenizer, Boolean optional = false)
+ {
+ AbstractToken token = tokenizer.Peek();
+
+ if (token.GetType() == typeof(NewLine))
+ {
+ tokenizer.NextToken();
+ return;
+ }
+
+ if (optional)
+ {
+ return;
+ }
+
+ throw new ParseException("Expected type Comma but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25));
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/Parser/Nodes/BibtexFile.cs b/BibtexLibrary.Standard/Parser/Nodes/BibtexFile.cs
new file mode 100644
index 0000000..1d08657
--- /dev/null
+++ b/BibtexLibrary.Standard/Parser/Nodes/BibtexFile.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BibtexLibrary.Parser.Nodes
+{
+ public class BibtexFile : ParseNode
+ {
+ private ICollection _entries = new List();
+
+ public ICollection Entries
+ {
+ get { return _entries; }
+ set { _entries = value; }
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/Parser/Nodes/Entry.cs b/BibtexLibrary.Standard/Parser/Nodes/Entry.cs
new file mode 100644
index 0000000..765ad02
--- /dev/null
+++ b/BibtexLibrary.Standard/Parser/Nodes/Entry.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BibtexLibrary.Parser.Nodes
+{
+ public class Entry : ParseNode
+ {
+ public String Type { get; set; }
+
+ public String Key { get; set; }
+
+ public ICollection Tags { get; set; }
+ }
+}
diff --git a/BibtexLibrary.Standard/Parser/Nodes/ParseNode.cs b/BibtexLibrary.Standard/Parser/Nodes/ParseNode.cs
new file mode 100644
index 0000000..96b7efa
--- /dev/null
+++ b/BibtexLibrary.Standard/Parser/Nodes/ParseNode.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BibtexLibrary.Parser.Nodes
+{
+ public abstract class ParseNode
+ {
+
+ }
+}
diff --git a/BibtexLibrary.Standard/Parser/Nodes/Tag.cs b/BibtexLibrary.Standard/Parser/Nodes/Tag.cs
new file mode 100644
index 0000000..02c63d7
--- /dev/null
+++ b/BibtexLibrary.Standard/Parser/Nodes/Tag.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace BibtexLibrary.Parser.Nodes
+{
+ public class Tag
+ {
+ public String Key { get; set; }
+ public String Value { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/BibtexLibrary.Standard/Parser/ParseException.cs b/BibtexLibrary.Standard/Parser/ParseException.cs
new file mode 100644
index 0000000..ec64f8a
--- /dev/null
+++ b/BibtexLibrary.Standard/Parser/ParseException.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace BibtexLibrary.Parser
+{
+ public class ParseException : Exception
+ {
+ public ParseException(string s) : base(s)
+ {
+
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/BibtexLibrary.Standard/Tokenizer/ExpressionDictionary.cs b/BibtexLibrary.Standard/Tokenizer/ExpressionDictionary.cs
new file mode 100644
index 0000000..cb8396b
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokenizer/ExpressionDictionary.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using BibtexLibrary.Tokens;
+
+namespace BibtexLibrary.Tokenizer
+{
+ public class ExpressionDictionary : Dictionary
+ {
+ public ExpressionDictionary()
+ {
+ Init();
+ }
+
+ private void Init()
+ {
+ Add(typeof(Comment), "^(\\s)?\\%(.*)$");
+ Add(typeof(At), "^(\\s)*@");
+ Add(typeof(Preamble), "(\\s)*Preamble");
+ Add(typeof(OpeningBrace), "^(\\s)*{");
+ Add(typeof(ClosingBrace), "^(\\s)*}");
+ Add(typeof(Equals), "^\\s*=");
+ Add(typeof(ValueQuote), "^(\\s)*\"");
+ Add(typeof(Text), "^\\s*['~\\*\\[\\]\\+%|<>#\\w\\d:\\.\\s-;(\\)/\\?&\\?&\\\\]+");
+ Add(typeof(Comma), "^\\s*,");
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokenizer/MatchException.cs b/BibtexLibrary.Standard/Tokenizer/MatchException.cs
new file mode 100644
index 0000000..caf7cd2
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokenizer/MatchException.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Text;
+
+namespace LexicalAnalyzer
+{
+ public class MatchException : Exception
+ {
+ private readonly string _character;
+ private readonly int _position;
+
+ public const Int32 windowWidth = 100;
+ public Int32 lineNumber { get; set; } = 0;
+ public String line { get; set; } = "";
+ public String window { get; set; } = "";
+ ///
+ /// The whole input
+ ///
+ public String input = "";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The input.
+ /// The character.
+ /// The position.
+ public MatchException(String _input, String character, int position)
+ {
+ _character = character;
+ input = _input;
+ Int32 windowStart = Math.Max(position - windowWidth, 0);
+ Int32 windowEnd = _input.IndexOf(Environment.NewLine, position);
+
+ var inputLines = input.Split(new String[] { Environment.NewLine }, StringSplitOptions.None);
+ Int32 head = 0;
+
+ while (head < position)
+ {
+ lineNumber++;
+ line = inputLines[lineNumber];
+ head += line.Length;
+ }
+ window = input.Substring(windowStart, windowEnd);
+
+ _position = position;
+
+ }
+
+ ///
+ /// Gets a message that describes the current exception.
+ ///
+ public override string Message
+ {
+ get
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine("BibTexLibrary: Could not match character: " + _character + " at position " + _position + " - ln:" + lineNumber);
+ sb.AppendLine("> Line: [" + line + "]");
+ sb.AppendLine("> Window: [" + window + "]");
+ return sb.ToString();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/BibtexLibrary.Standard/Tokenizer/Tokenizer.cs b/BibtexLibrary.Standard/Tokenizer/Tokenizer.cs
new file mode 100644
index 0000000..2c3b607
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokenizer/Tokenizer.cs
@@ -0,0 +1,121 @@
+using BibtexLibrary.Tokens;
+using LexicalAnalyzer;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text.RegularExpressions;
+
+namespace BibtexLibrary.Tokenizer
+{
+ public class Tokenizer
+ {
+ private readonly ExpressionDictionary _dictionary;
+ private readonly string _input;
+ private int _counter;
+
+ public Tokenizer(ExpressionDictionary dictionary, string input)
+ {
+ _dictionary = dictionary;
+ _input = input;
+ }
+
+ public AbstractToken NextToken()
+ {
+
+ // Loop through all tokens and check if they match the input string
+ foreach (KeyValuePair pair in _dictionary)
+ {
+ Match match;
+
+ if (pair.Key == typeof(Comment))
+ {
+ match = Regex.Match(_input.Substring(_counter), pair.Value, RegexOptions.Multiline);
+ }
+ else
+ {
+ // TODO: See if substring does not impose a to harsh performance drop
+ match = Regex.Match(_input.Substring(_counter), pair.Value);
+ }
+
+ if (!match.Success)
+ {
+ continue;
+ }
+ _counter += match.Value.Length;
+
+ if (!pair.Key.IsSubclassOf(typeof(AbstractToken)))
+ {
+ continue;
+ }
+
+ // Create new instance of the specified type with the found value as parameter
+ AbstractToken token = (AbstractToken)Activator.CreateInstance(pair.Key, new object[] { match.Value, _counter - match.Value.Length }, null);
+
+ return token;
+ }
+
+ throw new MatchException(_input, _input[_counter].ToString(CultureInfo.InvariantCulture), _counter);
+ }
+
+ public AbstractToken Peek()
+ {
+ // Loop through all tokens and check if they match the input string
+ foreach (KeyValuePair pair in _dictionary)
+ {
+ var test = _input.Length;
+ // TODO: See if substring does not impose a to harsh performance drop
+ Match match = Regex.Match(_input.Substring(_counter), pair.Value);
+
+ if (match.Success)
+ {
+ if (pair.Key.IsSubclassOf(typeof(AbstractToken)))
+ {
+ // Create new instance of the specified type with the found value as parameter
+ AbstractToken token = (AbstractToken)Activator.CreateInstance(pair.Key, new object[] { match.Value, _counter }, null);
+
+ return token;
+ }
+
+ }
+ }
+
+ throw new MatchException(_input, _input[_counter].ToString(CultureInfo.InvariantCulture), _counter);
+ }
+
+ ///
+ /// Return all the tokens in the inputstring.
+ ///
+ /// List of tokens
+ public ICollection GetAllTokens()
+ {
+ List tokens = new List();
+
+ while (!EndOfInput)
+ {
+ tokens.Add(NextToken());
+ }
+
+ return tokens;
+ }
+
+ ///
+ /// Checks whether the scanner is at the end of the input.
+ ///
+ public bool EndOfInput
+ {
+ get { return (_counter >= (_input.Length)); }
+ }
+
+ ///
+ /// Returns the previous n characters.
+ ///
+ ///
+ /// Previous characters in the tokenizer
+ public string GetPreviousCharacters(int n)
+ {
+ return _input.Substring(_counter - n, n);
+ }
+
+
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/AbstractToken.cs b/BibtexLibrary.Standard/Tokens/AbstractToken.cs
new file mode 100644
index 0000000..6967c00
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/AbstractToken.cs
@@ -0,0 +1,58 @@
+using System;
+
+namespace BibtexLibrary.Tokens
+{
+ ///
+ /// Base class for tokens
+ ///
+ public class AbstractToken
+ {
+ public AbstractToken(String value)
+ {
+ Value = value;
+ }
+
+ public AbstractToken(String value, int position)
+ {
+ RawValue = value;
+ Value = value.Trim();
+ _position = position;
+ }
+
+ protected bool Equals(AbstractToken other)
+ {
+ return string.Equals(Value, other.Value) && _position == other._position;
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return ((Value != null ? Value.GetHashCode() : 0) * 397) ^ _position;
+ }
+ }
+
+ protected readonly string Value;
+ private readonly int _position;
+
+ public String GetValue()
+ {
+ return Value;
+ }
+
+ public int Position
+ {
+ get { return _position; }
+ }
+
+ public string RawValue { get; private set; }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+ return Equals((AbstractToken)obj);
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/At.cs b/BibtexLibrary.Standard/Tokens/At.cs
new file mode 100644
index 0000000..fcea6ae
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/At.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BibtexLibrary.Tokens
+{
+ public class At : AbstractToken
+ {
+ public At(String Value) :base(Value) { }
+
+ public At(String Value, int Postion) : base(Value, Postion) { }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/ClosingBrace.cs b/BibtexLibrary.Standard/Tokens/ClosingBrace.cs
new file mode 100644
index 0000000..ba548c9
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/ClosingBrace.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace BibtexLibrary.Tokens
+{
+ public class ClosingBrace : AbstractToken
+ {
+ public ClosingBrace(String value)
+ : base(value)
+ {
+ }
+
+ public ClosingBrace(String value, int postion)
+ : base(value, postion)
+ {
+
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/Comma.cs b/BibtexLibrary.Standard/Tokens/Comma.cs
new file mode 100644
index 0000000..f11c50b
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/Comma.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BibtexLibrary.Tokens
+{
+ public class Comma : AbstractToken
+ {
+ public Comma(string value) : base(value)
+ {
+ }
+
+ public Comma(string value, int position) : base(value, position)
+ {
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/Comment.cs b/BibtexLibrary.Standard/Tokens/Comment.cs
new file mode 100644
index 0000000..3242830
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/Comment.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BibtexLibrary.Tokens
+{
+ class Comment : AbstractToken
+ {
+ public Comment(String value)
+ : base(value)
+ {
+ }
+
+ public Comment(String value, int postion)
+ : base(value, postion)
+ {
+ {
+ }
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/Equals.cs b/BibtexLibrary.Standard/Tokens/Equals.cs
new file mode 100644
index 0000000..eabcec6
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/Equals.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BibtexLibrary.Tokens
+{
+ public class Equals : AbstractToken
+ {
+ public Equals(string value) : base(value)
+ {
+ }
+
+ public Equals(string value, int position) : base(value, position)
+ {
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/NewLine.cs b/BibtexLibrary.Standard/Tokens/NewLine.cs
new file mode 100644
index 0000000..02ec2d1
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/NewLine.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BibtexLibrary.Tokens
+{
+ class NewLine : AbstractToken
+ {
+ public NewLine(String Value) :base(Value) { }
+ public NewLine(String Value, int Postion) : base(Value, Postion) { }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/OpeningBrace.cs b/BibtexLibrary.Standard/Tokens/OpeningBrace.cs
new file mode 100644
index 0000000..135b300
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/OpeningBrace.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BibtexLibrary.Tokens
+{
+ public class OpeningBrace : AbstractToken
+ {
+ public OpeningBrace(String Value) :base(Value) { }
+ public OpeningBrace(String Value, int Postion) : base(Value, Postion) { }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/Preamble.cs b/BibtexLibrary.Standard/Tokens/Preamble.cs
new file mode 100644
index 0000000..0cc9932
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/Preamble.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BibtexLibrary.Tokens
+{
+ public class Preamble : AbstractToken
+ {
+ public Preamble(String Value) :base(Value) { }
+ public Preamble(String Value, int Postion) : base(Value, Postion) { }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/Text.cs b/BibtexLibrary.Standard/Tokens/Text.cs
new file mode 100644
index 0000000..3f4afff
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/Text.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace BibtexLibrary.Tokens
+{
+ public class Text : AbstractToken
+ {
+ public Text(String value)
+ : base(value)
+ {
+ }
+
+ public Text(String value, int postion)
+ : base(value, postion)
+ {
+
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/Tokens/ValueQuote.cs b/BibtexLibrary.Standard/Tokens/ValueQuote.cs
new file mode 100644
index 0000000..8dc0f53
--- /dev/null
+++ b/BibtexLibrary.Standard/Tokens/ValueQuote.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BibtexLibrary.Tokens
+{
+ public class ValueQuote : AbstractToken
+ {
+ public ValueQuote(string value) : base(value)
+ {
+ }
+
+ public ValueQuote(string value, int position) : base(value, position)
+ {
+ }
+ }
+}
diff --git a/BibtexLibrary.Standard/imbSCI - Copy.ico b/BibtexLibrary.Standard/imbSCI - Copy.ico
new file mode 100644
index 0000000..bae3c80
Binary files /dev/null and b/BibtexLibrary.Standard/imbSCI - Copy.ico differ
diff --git a/BibtexLibrary.Standard/imbSCI.BibtexLibrary.Standard.xml b/BibtexLibrary.Standard/imbSCI.BibtexLibrary.Standard.xml
new file mode 100644
index 0000000..9d30eb3
--- /dev/null
+++ b/BibtexLibrary.Standard/imbSCI.BibtexLibrary.Standard.xml
@@ -0,0 +1,202 @@
+
+
+
+ BibtexLibrary.Standard
+
+
+
+
+ Single entry in Bibtex file
+
+
+
+
+ The tags
+
+
+
+
+ Gets or sets the type.
+
+
+ The type.
+
+
+
+
+ Gets or sets the key.
+
+
+ The key.
+
+
+
+
+ Gets or sets the tags.
+
+
+ The tags.
+
+
+
+
+ Collection of Bibtex entries
+
+
+
+
+ Gets or sets the string definitions.
+
+
+ The string definitions.
+
+
+
+
+ Gets or sets the preamble.
+
+
+ The preamble.
+
+
+
+
+ Gets or sets the entries.
+
+
+ The entries.
+
+
+
+
+ Parser
+
+
+
+
+ Froms the string.
+
+ The text.
+
+
+
+
+ Froms the stream.
+
+ The reader.
+
+
+
+
+
+ Initializes a new instance of the class.
+
+ The tokenizer.
+
+
+
+ Parses this instance.
+
+
+
+
+
+ Converts the parse node.
+
+ The node.
+
+
+
+
+ Parses the input.
+
+ The tokenizer.
+
+
+
+
+ Entries the specified tokenizer.
+
+ The tokenizer.
+
+
+
+
+ Texts the specified tokenizer.
+
+ The tokenizer.
+
+ Expected type Text but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+
+
+
+ Openings the brace.
+
+ The tokenizer.
+ Expected type OpeningBrace but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+
+
+
+ Closings the brace.
+
+ The tokenizer.
+ Expected type ClosingBrace but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+
+
+
+ Commas the specified tokenizer.
+
+ The tokenizer.
+ if set to true [optional].
+ Expected type Comma but found: " + token.GetType() + " after " + tokenizer.GetPreviousCharacters(25)
+
+
+
+ Retrieves the tag values from the input.
+
+ The tokenizer.
+
+
+
+
+ Return all the tokens in the inputstring.
+
+ List of tokens
+
+
+
+ Checks whether the scanner is at the end of the input.
+
+
+
+
+ Returns the previous n characters.
+
+
+ Previous characters in the tokenizer
+
+
+
+ Base class for tokens
+
+
+
+
+ The whole input
+
+
+
+
+ Initializes a new instance of the class.
+
+ The input.
+ The character.
+ The position.
+
+
+
+ Gets a message that describes the current exception.
+
+
+
+
diff --git a/BibtexLibrary.Standard/key.snk b/BibtexLibrary.Standard/key.snk
new file mode 100644
index 0000000..3d275d8
Binary files /dev/null and b/BibtexLibrary.Standard/key.snk differ
diff --git a/BibtexLibrary.sln b/BibtexLibrary.sln
index f1ec045..49f9b97 100644
--- a/BibtexLibrary.sln
+++ b/BibtexLibrary.sln
@@ -1,12 +1,16 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.21005.1
+# Visual Studio 15
+VisualStudioVersion = 15.0.27703.2026
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BibtexLibrary", "BibtexLibrary\BibtexLibrary.csproj", "{BF36652A-A0D7-4877-8AE0-B3E8362019C1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BibtexLibrary.Tests", "BibtexLibrary.Tests\BibtexLibrary.Tests.csproj", "{5ACEB9AA-F461-4918-8CA9-12156446B0B2}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BibtexLibrary.Standard", "BibtexLibrary.Standard\BibtexLibrary.Standard.csproj", "{4071ADF7-1703-4BE2-A0FB-42B11DD88B5A}"
+EndProject
+Project("{7CF6DF6D-3B04-46F8-A40B-537D21BCA0B4}") = "BibtexLibrary.Documentation", "BibtexLibrary.Documentation\BibtexLibrary.Documentation.shfbproj", "{617B9073-B902-49A2-B28D-4D790595D7CD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,8 +25,19 @@ Global
{5ACEB9AA-F461-4918-8CA9-12156446B0B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5ACEB9AA-F461-4918-8CA9-12156446B0B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5ACEB9AA-F461-4918-8CA9-12156446B0B2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4071ADF7-1703-4BE2-A0FB-42B11DD88B5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4071ADF7-1703-4BE2-A0FB-42B11DD88B5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4071ADF7-1703-4BE2-A0FB-42B11DD88B5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4071ADF7-1703-4BE2-A0FB-42B11DD88B5A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {617B9073-B902-49A2-B28D-4D790595D7CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {617B9073-B902-49A2-B28D-4D790595D7CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {617B9073-B902-49A2-B28D-4D790595D7CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {617B9073-B902-49A2-B28D-4D790595D7CD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {EC420422-CBDC-43B2-B86F-D2C4F9419E90}
+ EndGlobalSection
EndGlobal