diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs
index 96b946444..bc535ff74 100644
--- a/src/Discord.Net.Commands/CommandParser.cs
+++ b/src/Discord.Net.Commands/CommandParser.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text;
using System.Threading.Tasks;
@@ -14,19 +15,32 @@ namespace Discord.Commands
QuotedParameter
}
- ///
- /// Checks to see if the supplied character is a quotation mark
- /// from either the default " character, or the list of aliases
- /// if they are provided.
- ///
- ///
- ///
- private static bool isQuotationChar(char c, char[] aliases)
+ private static bool isOpenQuote(Dictionary map, char c)
{
- if (aliases == null) return c == '\"';
- return Array.Exists(aliases, x => x == c);
+ // determine if the map contains the key for this value
+ if(map != null)
+ {
+ return map.ContainsKey(c);
+ }
+ // or if the value is a normal quote "
+ return c == '\"';
+ }
+
+ // get the corresponding matching quote for the key
+ private static char getMatch(Dictionary map, char c)
+ {
+ if (map != null)
+ {
+ char value;
+ if( map.TryGetValue(c, out value))
+ {
+ return value;
+ }
+ }
+
+ return '\"';
}
-
+
public static async Task ParseArgsAsync(CommandInfo command, ICommandContext context, bool ignoreExtraArgs, IServiceProvider services, string input, int startPos)
{
ParameterInfo curParam = null;
@@ -37,7 +51,7 @@ namespace Discord.Commands
var argList = ImmutableArray.CreateBuilder();
var paramList = ImmutableArray.CreateBuilder();
bool isEscaping = false;
- char c;
+ char c, matchQuote = '\0';
for (int curPos = startPos; curPos <= endPos; curPos++)
{
@@ -87,9 +101,11 @@ namespace Discord.Commands
argBuilder.Append(c);
continue;
}
- if (isQuotationChar(c, command._quotationAliases))
+
+ if(isOpenQuote(command._quotationAliases, c))
{
curPart = ParserPart.QuotedParameter;
+ matchQuote = getMatch(command._quotationAliases, c);
continue;
}
curPart = ParserPart.Parameter;
@@ -110,7 +126,9 @@ namespace Discord.Commands
}
else if (curPart == ParserPart.QuotedParameter)
{
- if (isQuotationChar(c, command._quotationAliases))
+ //if (findQuotationChar(c, false, out matchingQuotation))
+ //if( matchingQuotation != null && matchingQuotation.Right == c)
+ if(c == matchQuote)
{
argString = argBuilder.ToString(); //Remove quotes
lastArgEndPos = curPos + 1;
diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs
index 67d721dbb..02f1da5c3 100644
--- a/src/Discord.Net.Commands/CommandService.cs
+++ b/src/Discord.Net.Commands/CommandService.cs
@@ -32,7 +32,7 @@ namespace Discord.Commands
internal readonly RunMode _defaultRunMode;
internal readonly Logger _cmdLogger;
internal readonly LogManager _logManager;
- internal readonly char[] _quotationMarkAliases;
+ internal readonly Dictionary _quotationMarkAliasMap;
public IEnumerable Modules => _moduleDefs.Select(x => x);
public IEnumerable Commands => _moduleDefs.SelectMany(x => x.Commands);
@@ -46,7 +46,7 @@ namespace Discord.Commands
_ignoreExtraArgs = config.IgnoreExtraArgs;
_separatorChar = config.SeparatorChar;
_defaultRunMode = config.DefaultRunMode;
- _quotationMarkAliases = config.QuotationMarkAliases;
+ _quotationMarkAliasMap = config.QuotationMarkAliasMap;
if (_defaultRunMode == RunMode.Default)
throw new InvalidOperationException("The default run mode cannot be set to Default.");
diff --git a/src/Discord.Net.Commands/CommandServiceConfig.cs b/src/Discord.Net.Commands/CommandServiceConfig.cs
index 3985a39a7..6de61f939 100644
--- a/src/Discord.Net.Commands/CommandServiceConfig.cs
+++ b/src/Discord.Net.Commands/CommandServiceConfig.cs
@@ -1,4 +1,5 @@
-namespace Discord.Commands
+using System.Collections.Generic;
+namespace Discord.Commands
{
public class CommandServiceConfig
{
@@ -16,8 +17,29 @@
/// Determines whether RunMode.Sync commands should push exceptions up to the caller.
public bool ThrowOnError { get; set; } = true;
- /// List of aliases for string parsing
- public char[] QuotationMarkAliases { get; set; } = new char[] { '\"', '“', '”', '«', '»', '‹', '›' };
+ /// Collection of aliases that can wrap strings for command parsing.
+ /// represents the opening quotation mark and the value is the corresponding closing mark.
+ public Dictionary QuotationMarkAliasMap { get; set; }
+ = new Dictionary()
+ {
+ {'\"', '\"' },
+ {'«', '»' },
+ {'‘', '’' },
+ {'“', '”' },
+ {'„', '‟' },
+ {'‹', '›' },
+ {'‚', '‛' },
+ {'《', '》' },
+ {'〈', '〉' },
+ {'「', '」' },
+ {'『', '』' },
+ {'〝', '〞' },
+ {'﹁', '﹂' },
+ {'﹃', '﹄' },
+ {'"', '"' },
+ {''', ''' },
+ {'「', '」' }
+ };
/// Determines whether extra parameters should be ignored.
public bool IgnoreExtraArgs { get; set; } = false;
diff --git a/src/Discord.Net.Commands/Info/CommandInfo.cs b/src/Discord.Net.Commands/Info/CommandInfo.cs
index 781a0212f..4dee863b5 100644
--- a/src/Discord.Net.Commands/Info/CommandInfo.cs
+++ b/src/Discord.Net.Commands/Info/CommandInfo.cs
@@ -20,7 +20,7 @@ namespace Discord.Commands
private readonly CommandService _commandService;
private readonly Func _action;
- internal readonly char[] _quotationAliases;
+ internal readonly Dictionary _quotationAliases;
public ModuleInfo Module { get; }
public string Name { get; }
@@ -66,7 +66,7 @@ namespace Discord.Commands
HasVarArgs = builder.Parameters.Count > 0 ? builder.Parameters[builder.Parameters.Count - 1].IsMultiple : false;
_action = builder.Callback;
- _quotationAliases = service._quotationMarkAliases;
+ _quotationAliases = service._quotationMarkAliasMap;
_commandService = service;
}