Fixed parser bug, added option to output YAML 1.1

* Fixed a parser bug that got confused when looking for an implicit
   map key in a plain scalar that contains &, * or !
 * Added OutputYamlVersion to PresentationOptions
This commit is contained in:
Felix Krause 2016-03-20 10:27:09 +01:00
parent 5688499650
commit eef247b2e8
3 changed files with 36 additions and 15 deletions

View File

@ -346,6 +346,7 @@ template handlePossibleMapStart(flow: bool = false,
while p.lexer.buf[pos] notin {'\'', '\l', '\c', EndOfFile}:
pos.inc()
of '&', '*', '!':
if pos == p.lexer.bufpos or p.lexer.buf[p.lexer.bufpos] in {'\t', ' '}:
pos.inc()
while p.lexer.buf[pos] notin {' ', '\t', '\l', '\c', EndOfFile}:
pos.inc()
@ -776,8 +777,8 @@ template handleFlowPlainScalar() {.dirty.} =
template ensureCorrectIndentation() {.dirty.} =
if level.indentation != indentation:
startToken()
parserError("Invalid indentation (expected indentation of " &
$level.indentation & ")")
parserError("Invalid indentation: " & $indentation &
" (expected indentation of " & $level.indentation & ")")
template tagHandle(lexer: var BaseLexer, content: var string,
shorthandEnd: var int) =
@ -868,7 +869,8 @@ template blockScalar(lexer: BaseLexer, content: var string,
blockIndent = int(lexer.buf[lexer.bufpos]) - int('\x30')
detectedIndent = true
of spaceOrLineEnd: break
else: lexerError(lexer, "Illegal character in block scalar header")
else: lexerError(lexer, "Illegal character in block scalar header: '" &
lexer.buf[lexer.bufpos] & "'")
lexer.lineEnding()
case lexer.buf[lexer.bufpos]
of '\l': lexer.bufpos = lexer.handleLF(lexer.bufpos)

View File

@ -15,10 +15,12 @@ type
sLiteral, sFolded, sPlain, sDoubleQuoted
proc defineOptions*(style: PresentationStyle = psDefault,
indentationStep: int = 2, newlines:
NewLineStyle = nlOSDefault): PresentationOptions =
result = PresentationOptions(style: style, indentationStep: indentationStep,
newlines: newlines)
indentationStep: int = 2,
newlines: NewLineStyle = nlOSDefault,
outputVersion: OutputYamlVersion = ov1_2):
PresentationOptions =
PresentationOptions(style: style, indentationStep: indentationStep,
newlines: newlines, outputVersion: outputVersion)
proc inspect(scalar: string, indentation: int,
words, lines: var seq[tuple[start, finish: int]]):
@ -30,7 +32,8 @@ proc inspect(scalar: string, indentation: int,
curWord, curLine: tuple[start, finish: int]
canUseFolded = true
canUseLiteral = true
canUsePlain = scalar.len > 0 and scalar[0] notin {'@', '`'}
canUsePlain = scalar.len > 0 and
scalar[0] notin {'@', '`', '|', '>', '&', '*', '!', ' ', '\t'}
for i, c in scalar:
case c
of ' ':
@ -338,7 +341,10 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
if options.style != psJson:
# TODO: tag directives
try:
target.write("%YAML 1.2" & newline)
case options.outputVersion
of ov1_2: target.write("%YAML 1.2" & newline)
of ov1_1: target.write("%YAML 1.1" & newLine)
of ovNone: discard
if tagLib.secondaryPrefix != yamlTagRepositoryPrefix:
target.write("%TAG !! " &
tagLib.secondaryPrefix & newline)

View File

@ -211,11 +211,23 @@ type
## sequence (CRLF on Windows, LF everywhere else).
nlLF, nlCRLF, nlOSDefault
OutputYamlVersion* = enum
## Specify which YAML version number the presenter shall emit. The
## presenter will always emit content that is valid YAML 1.1, but by
## default will write a directive ``%YAML 1.2``. For compatibility with
## other YAML implementations, it is possible to change this here.
##
## It is also possible to specify that the presenter shall not emit any
## YAML version. The generated content is then guaranteed to be valid
## YAML 1.1 and 1.2 (but not 1.0 or any newer YAML version).
ov1_2, ov1_1, ovNone
PresentationOptions* = object
## Options for generating a YAML character stream
style*: PresentationStyle
indentationStep*: int
newlines*: NewLineStyle
outputVersion*: OutputYamlVersion
RefNodeData = object
p: pointer
@ -512,9 +524,10 @@ proc parse*(p: YamlParser, s: Stream): YamlStream {.raises: [].}
## Parse the given stream as YAML character stream.
proc defineOptions*(style: PresentationStyle = psDefault,
indentationStep: int = 2, newlines:
NewLineStyle = nlOSDefault): PresentationOptions
{.raises: [].}
indentationStep: int = 2,
newlines: NewLineStyle = nlOSDefault,
outputVersion: OutputYamlVersion = ov1_2):
PresentationOptions {.raises: [].}
## Define a set of options for presentation. Convenience proc that requires
## you to only set those values that should not equal the default.