Browse Source

[commands] Added handling for unicode quotes

pull/1120/head
b-hodges 7 years ago
committed by Rapptz
parent
commit
ea061ef9b2
  1. 57
      discord/ext/commands/view.py

57
discord/ext/commands/view.py

@ -108,13 +108,42 @@ class StringView:
# Parser # Parser
# map from opening quotes to closing quotes
_quotes = {
'"': '"',
"'": "'",
"«": "»",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"«": "»",
"": "",
"": "",
"": "",
}
_all_quotes = set(_quotes.keys()) | set(_quotes.values())
def quoted_word(view): def quoted_word(view):
current = view.current current = view.current
if current is None: if current is None:
return None return None
is_quoted = current == '"' close_quote = _quotes.get(current)
is_quoted = bool(close_quote)
if is_quoted:
open_quote = current
result = [] if is_quoted else [current] result = [] if is_quoted else [current]
while not view.eof: while not view.eof:
@ -122,7 +151,7 @@ def quoted_word(view):
if not current: if not current:
if is_quoted: if is_quoted:
# unexpected EOF # unexpected EOF
raise BadArgument('Expected closing "') raise BadArgument('Expected closing {}.'.format(close_quote))
return ''.join(result) return ''.join(result)
# currently we accept strings in the format of "hello world" # currently we accept strings in the format of "hello world"
@ -133,32 +162,32 @@ def quoted_word(view):
# string ends with \ and no character after it # string ends with \ and no character after it
if is_quoted: if is_quoted:
# if we're quoted then we're expecting a closing quote # if we're quoted then we're expecting a closing quote
raise BadArgument('Expected closing "') raise BadArgument('Expected closing {}.'.format(close_quote))
# if we aren't then we just let it through # if we aren't then we just let it through
return ''.join(result) return ''.join(result)
if next_char == '"': if next_char in ((open_quote, close_quote) if is_quoted else _all_quotes):
# escaped quote # escaped quote
result.append('"') result.append(next_char)
else: else:
# different escape character, ignore it # different escape character, ignore it
view.undo() view.undo()
result.append(current) result.append(current)
continue continue
if not is_quoted and current in _all_quotes:
# we aren't quoted
raise BadArgument('Unexpected quote mark in non-quoted string')
# closing quote # closing quote
if current == '"': if is_quoted and current == close_quote:
next_char = view.get() next_char = view.get()
valid_eof = not next_char or next_char.isspace() valid_eof = not next_char or next_char.isspace()
if is_quoted: if not valid_eof:
if not valid_eof: raise BadArgument('Expected space after closing quotation')
raise BadArgument('Expected space after closing quotation')
# we're quoted so it's okay # we're quoted so it's okay
return ''.join(result) return ''.join(result)
else:
# we aren't quoted
raise BadArgument('Unexpected quote mark in non-quoted string')
if current.isspace() and not is_quoted: if current.isspace() and not is_quoted:
# end of word found # end of word found

Loading…
Cancel
Save