Skip to content

Commit

Permalink
Merge pull request #146 from dcrasch/all-references
Browse files Browse the repository at this point in the history
Fixes problems with parsing references using windows paths and url paths
  • Loading branch information
WillemJann authored May 19, 2022
2 parents 64187d8 + a5d8703 commit af3bee7
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 10 deletions.
160 changes: 156 additions & 4 deletions src/XLParser.Tests/FormulaAnalysisTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,6 @@ public void ExternalWorkbookUrlPathHttp()
public void ExternalWorkbookUrlPathHttpWithSpaceInPath()
{
// See [#138](https://github.com/spreadsheetlab/XLParser/issues/138)

List<ParserReference> references = new FormulaAnalyzer(@"='http://example.com/test folder/[Book1.xlsx]Sheet1'!$A$1").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Expand All @@ -375,7 +374,6 @@ public void ExternalWorkbookUrlPathHttpWithSpaceInPath()
public void ExternalWorkbookUrlPathHttpWithSpaceInDocument()
{
// See [#138](https://github.com/spreadsheetlab/XLParser/issues/138)

List<ParserReference> references = new FormulaAnalyzer(@"='http://example.com/testfolder/[Book 1.xlsx]Sheet1'!$A$1").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Expand All @@ -384,17 +382,113 @@ public void ExternalWorkbookUrlPathHttpWithSpaceInDocument()
Assert.AreEqual("Sheet1", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookNetworkPathWithSpace()
{
// See [#142](https://github.com/spreadsheetlab/XLParser/issues/142)
List<ParserReference> references = new FormulaAnalyzer(@"='\\networkshare\test folder$\[Book 1.xlsx]Sheet1'!$C$33").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"\\networkshare\test folder$\", references.First().FilePath);
Assert.AreEqual("Book 1.xlsx", references.First().FileName);
Assert.AreEqual("Sheet1", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookNetworkPathWithoutSpaceInFolder()
{
// See [#142](https://github.com/spreadsheetlab/XLParser/issues/142)
List<ParserReference> references = new FormulaAnalyzer(@"='\\networkshare\testfolder$\[Book 1.xlsx]Sheet1'!$C$33").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"\\networkshare\testfolder$\", references.First().FilePath);
Assert.AreEqual("Book 1.xlsx", references.First().FileName);
Assert.AreEqual("Sheet1", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookNetworkPathWithQuotes()
{
// See [#135](https://github.com/spreadsheetlab/XLParser/issues/135)
List<ParserReference> references = new FormulaAnalyzer(@"='\\SRV01\[TestFile.xls]TestSheet'!#REF!").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"\\SRV01\", references.First().FilePath);
Assert.AreEqual("TestFile.xls", references.First().FileName);
Assert.AreEqual("TestSheet", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookNetworkPathWithQuotesAndSpaces()
{
// See [#135](https://github.com/spreadsheetlab/XLParser/issues/135)
List<ParserReference> references = new FormulaAnalyzer(@"='\\SRV01\[Test File.xls]Test Sheet'!#REF!").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"\\SRV01\", references.First().FilePath);
Assert.AreEqual("Test File.xls", references.First().FileName);
Assert.AreEqual("Test Sheet", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookNetworkPathWithQuotesAndSpaceInFolder()
{
// See [#135](https://github.com/spreadsheetlab/XLParser/issues/135)
List<ParserReference> references = new FormulaAnalyzer(@"='\\SRV01\Test Folder\[TestFile.xls]Test Sheet'!#REF!").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"\\SRV01\Test Folder\", references.First().FilePath);
Assert.AreEqual("TestFile.xls", references.First().FileName);
Assert.AreEqual("Test Sheet", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookNetworkPathWithQuotesAndSpaceInDocument()
{
// See [#135](https://github.com/spreadsheetlab/XLParser/issues/135)
List<ParserReference> references = new FormulaAnalyzer(@"='\\SRV01\TestFolder\[Test File.xls]Test Sheet'!#REF!").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"\\SRV01\TestFolder\", references.First().FilePath);
Assert.AreEqual("Test File.xls", references.First().FileName);
Assert.AreEqual("Test Sheet", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookUrlPathHttps()
{
List<ParserReference> references = new FormulaAnalyzer(@"='https://d.docs.live.net/3fade139bf25879f/Documents/[Tracer.xlsx]Sheet2'!$C$5+Sheet10!J44").ParserReferences().ToList();
List<ParserReference> references = new FormulaAnalyzer(@"='https://d.docs.live.net/3fade139bf25879f/Documents/[Tracer.xlsx]Sheet2'!$C$5").ParserReferences().ToList();

Assert.AreEqual(2, references.Count);
Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"https://d.docs.live.net/3fade139bf25879f/Documents/", references.First().FilePath);
Assert.AreEqual("Tracer.xlsx", references.First().FileName);
Assert.AreEqual("Sheet2", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookDocumentWithoutBracketsWithSpace()
{
// See [#137](https://github.com/spreadsheetlab/XLParser/issues/137)
List<ParserReference> references = new FormulaAnalyzer(@"='https://preview.perfectxl.com/Financial Sample.xlsx'!financials").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"https://preview.perfectxl.com/", references.First().FilePath);
Assert.AreEqual("Financial Sample.xlsx", references.First().FileName);
Assert.AreEqual("financials", references.First().Name);
}

[TestMethod]
public void ExternalWorkbookDocumentWithoutBrackets()
{
// See [#137](https://github.com/spreadsheetlab/XLParser/issues/135)
List<ParserReference> references = new FormulaAnalyzer(@"='https://preview.perfectxl.com/FinancialSample.xlsx'!financials").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"https://preview.perfectxl.com/", references.First().FilePath);
Assert.AreEqual("FinancialSample.xlsx", references.First().FileName);
Assert.AreEqual("financials", references.First().Name);
}

[TestMethod]
public void ExternalWorkbookRelativePath()
{
Expand All @@ -406,6 +500,64 @@ public void ExternalWorkbookRelativePath()
Assert.AreEqual("Sheet1", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookRelativePathIsDefinedName()
{
List<ParserReference> references = new FormulaAnalyzer(@"=Test\Folder").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"Test\Folder", references.First().Name);
Assert.AreEqual(ReferenceType.UserDefinedName, references.First().ReferenceType);
}

[TestMethod]
public void ExternalWorkbookUrlPathHttpWithRoundBracketsInDocument()
{
// See [#140](https://github.com/spreadsheetlab/XLParser/issues/140)
List<ParserReference> references = new FormulaAnalyzer(@"='http://example.com/testfolder(brackets)/[Book 1.xlsx]Sheet1'!$A$1").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"http://example.com/testfolder(brackets)/", references.First().FilePath);
Assert.AreEqual("Book 1.xlsx", references.First().FileName);
Assert.AreEqual("Sheet1", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookUrlPathHttpWithRoundBrackets()
{
// See [#140](https://github.com/spreadsheetlab/XLParser/issues/140)
List<ParserReference> references = new FormulaAnalyzer(@"='http://example.com/testfolder(brackets)/[Book (1).xlsx]Sheet1'!$A$1").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"http://example.com/testfolder(brackets)/", references.First().FilePath);
Assert.AreEqual("Book (1).xlsx", references.First().FileName);
Assert.AreEqual("Sheet1", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookPathWithRoundBracketsInDocument()
{
// See [#140](https://github.com/spreadsheetlab/XLParser/issues/140)
List<ParserReference> references = new FormulaAnalyzer(@"='c:\My documents\[Book 1 (copy).xlsx]Sheet1'!$A$1").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"c:\My documents\", references.First().FilePath);
Assert.AreEqual("Book 1 (copy).xlsx", references.First().FileName);
Assert.AreEqual("Sheet1", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookPathWithRoundBrackets()
{
// See [#140](https://github.com/spreadsheetlab/XLParser/issues/140)
List<ParserReference> references = new FormulaAnalyzer(@"='c:\My documents (copy)\[Book 1 (copy).xlsx]Sheet1'!$A$1").ParserReferences().ToList();

Assert.AreEqual(1, references.Count);
Assert.AreEqual(@"c:\My documents (copy)\", references.First().FilePath);
Assert.AreEqual("Book 1 (copy).xlsx", references.First().FileName);
Assert.AreEqual("Sheet1", references.First().Worksheet);
}

[TestMethod]
public void ExternalWorkbookSingleCell()
{
Expand Down
15 changes: 9 additions & 6 deletions src/XLParser/ExcelFormulaGrammar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,18 +176,20 @@ public class ExcelFormulaGrammar : Grammar

private const string fileNameInBracketsRegex = @"\[[^\[\]]+\]";
public Terminal FileNameEnclosedInBracketsToken { get; } = new RegexBasedTerminal(GrammarNames.TokenFileNameEnclosedInBrackets, fileNameInBracketsRegex)
{ Priority = TerminalPriority.FileName };
{ Priority = TerminalPriority.FileName };

// Source: https://stackoverflow.com/a/14632579
private const string fileNameRegex = @"[^\.]+\..{1,4}";
private const string fileNameRegex = @"[^\.\\]+\..{1,4}";
public Terminal FileName { get; } = new RegexBasedTerminal(GrammarNames.TokenFileName, fileNameRegex)
{ Priority = TerminalPriority.FileName };
{ Priority = TerminalPriority.FileName };

// Source: http://stackoverflow.com/a/6416209/572635
private const string windowsFilePathRegex = @"(?:[a-zA-Z]:|\\?\\?[\w\.-]+\\[\w.$]+)\\(([^<>:""/\|?*\\]| )+\\)*";
private const string urlPathRegex = @"http(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_ ]*)?";
private const string windowsFilePathRegex = @"(?:[a-zA-Z]:|\\?\\?[\w\-.$ ]+)\\(([^<>:\""/\|?*\\]| )+\\)*";
private const string urlPathRegex = @"http(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*[/]([a-zA-Z0-9\-\.\?\,\'+&%\$#_ ()]*[/])*";
private const string filePathRegex = @"(" + windowsFilePathRegex + @"|" + urlPathRegex + @")";
public Terminal FilePathToken { get; } = new RegexBasedTerminal(GrammarNames.TokenFilePath, filePathRegex);
public Terminal FilePathToken { get; } = new RegexBasedTerminal(GrammarNames.TokenFilePath, filePathRegex)
{ Priority = TerminalPriority.FileNamePath };

#endregion

#endregion
Expand Down Expand Up @@ -494,6 +496,7 @@ private static class TerminalPriority
public const int ReservedName = -700;

public const int FileName = -500;
public const int FileNamePath = -800;

public const int SingleQuotedString = -100;

Expand Down

0 comments on commit af3bee7

Please sign in to comment.