package parser import ( "asciigoat.org/core/lexer" ) // AcceptQuotedString consumes a quoted string from the source // and returns it unquoted. func (p *TextParser) AcceptQuotedString() (string, bool, error) { r, _, err := p.ReadRune() switch { case err != nil: // nothing here return "", false, err case r != RuneQuotes: // not for us p.UnreadRune() return "", false, nil default: // let's roll s, err := lexQuotedString(p) switch { case err != nil: // bad quoted string return "", false, err default: // success return s, true, nil } } } func lexQuotedString(p *TextParser) (string, *lexer.Error) { s, ok, err := lexQuotedStringNoEscape(p) switch { case err != nil: return "", err case ok: return s, nil default: // escape character detected return lexQuotedStringEscaped(p) } } func lexQuotedStringNoEscape(p *TextParser) (string, bool, *lexer.Error) { for { r, _, err := p.ReadRune() switch { case err != nil: // incomplete return "", false, NewErrIncompleteQuotedString(p) case r == RuneQuotes: // end, just remove the quotes s := p.String() l := len(s) return s[1 : l-2], true, nil case r == RuneEscape: // things just got complicated... return "", false, nil case IsNewLine(r): // new lines within quoted values are acceptable p.UnreadRune() p.AcceptNewLine() default: // continue } } } func lexQuotedStringEscaped(*TextParser) (string, *lexer.Error) { panic("not implemented") } // Unquoted removes quotes and unescapes the content func Unquoted(s string) (string, error) { var p TextParser if s == "" { return "", nil } p.InitString(s) unquoted, ok, err := p.AcceptQuotedString() switch { case err != nil: // bad string return "", err case ok: // success return unquoted, nil default: // not quoted return s, nil } }