# NimYAML - YAML implementation in Nim # (c) Copyright 2015 Felix Krause # # See the file "copying.txt", included in this # distribution, for details about the copyright. import jester, asyncdispatch, json, streams, strutils import packages.docutils.rstgen, packages.docutils.highlite import ../yaml routes: get "/": headers["Content-Type"] = "text/plain" resp "I am a friendly NimYAML parser webservice." post "/": var style: PresentationStyle resultNode = newJObject() msg: string retStatus = Http200 contentType = "application/json" headers["Access-Control-Allow-Origin"] = "*" headers["Pragma"] = "no-cache" headers["Cache-Control"] = "no-cache" headers["Expires"] = "0" try: case @"style" of "minimal": style = psMinimal of "canonical": style = psCanonical of "default": style = psDefault of "json": style = psJson of "block": style = psBlockOnly of "tokens": var output = "+STR\n" parser = newYamlParser() events = parser.parse(newStringStream(@"input")) for event in events: output.add(parser.display(event) & "\n") output &= "-STR" resultNode["code"] = %0 resultNode["output"] = %output msg = resultNode.pretty else: retStatus = Http400 msg = "Invalid style: " & escape(@"style") contentType = "text/plain;charset=utf8" if isNil(msg): var output = newStringStream() highlighted = "" transform(newStringStream(@"input"), output, defineOptions(style), true) # syntax highlighting (stolen and modified from stlib's rstgen) var g: GeneralTokenizer g.initGeneralTokenizer(output.data) while true: g.getNextToken(langYaml) case g.kind of gtEof: break of gtNone, gtWhitespace: highlighted.add(substr(output.data, g.start, g.length + g.start - 1)) else: highlighted.addf("$1", "\\span$2{$1}", [ esc(outHtml, substr(output.data, g.start, g.length+g.start-1)), tokenClassToStr[g.kind]]) resultNode["code"] = %0 resultNode["output"] = %highlighted msg = resultNode.pretty except YamlParserError: let e = (ref YamlParserError)(getCurrentException()) resultNode["code"] = %1 resultNode["line"] = %e.line resultNode["column"] = %e.column resultNode["message"] = %e.msg resultNode["detail"] = %e.lineContent msg = resultNode.pretty except YamlPresenterJsonError: let e = getCurrentException() resultNode["code"] = %2 resultNode["message"] = %e.msg msg = resultNode.pretty except: let e = getCurrentException() msg = "Name: " & $e.name & "\nMessage: " & e.msg & "\nTrace:\n" & e.getStackTrace retStatus = Http500 contentType = "text/plain;charset=utf-8" resp retStatus, msg, contentType runForever()