Expose connection with Documentation parser and generator in ScalaJS artifact (#1002)

* Get string of HTML-code from generator

* Export doc parser generator to JS

* test

* ren
This commit is contained in:
Maciej Mikołajek 2020-07-17 11:25:09 +02:00 committed by GitHub
parent 40f44b5b9e
commit 2801f58ba9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 68 deletions

View File

@ -5,30 +5,32 @@ import org.enso.flexer.Reader
import org.enso.syntax.text.Parser.ParserError
import scala.scalajs.js.annotation._
import scala.scalajs.js
object Parse {
@JSExportTopLevel("parse")
def parse(program: String, idsJson: String): String = {
try {
val idmap = Parser.idMapFromJson(idsJson).left.map { error =>
throw new ParserError("Could not deserialize idmap.", error)
}.merge
new Parser().run(new Reader(program), idmap).toJson().noSpacesSortKeys
} catch {
// FIXME We wrap the error message in JavaScriptException, so that javascript
// can display it. This is no longer needed in scalajs 1.0
case e: Throwable => throw js.JavaScriptException(e.getMessage)
}
val idmap = Parser
.idMapFromJson(idsJson)
.left
.map { error =>
throw new ParserError("Could not deserialize idmap.", error)
}
.merge
new Parser().run(new Reader(program), idmap).toJson().noSpacesSortKeys
}
@JSExportTopLevel("parse_with_metadata")
def parse_with_metadata(program: String): String = {
try {
new Parser().runWithMetadata(program).asJson.noSpacesSortKeys
} catch {
// FIXME We wrap the error message in JavaScriptException, so that javascript
// can display it. This is no longer needed in scalajs 1.0
case e: Throwable => throw js.JavaScriptException(e.getMessage)
}
new Parser().runWithMetadata(program).asJson.noSpacesSortKeys
}
@JSExportTopLevel("doc_parser_generate_html_source")
def doc_parser_generate_html_source(program: String): String = {
val parser = new Parser()
val module = parser.run(program)
val dropMeta = parser.dropMacroMeta(module)
val doc = DocParserRunner.createDocs(dropMeta)
val htmlCode = DocParserHTMLGenerator.generateHTMLForEveryDocumented(doc)
htmlCode
}
}

View File

@ -36,10 +36,11 @@ class DocParser {
* @return - If it was able to retrieve Doc, then retrieved data, else
* exception with error message [[errMsg]]
*/
def runMatched(input: String): Doc = run(input) match {
case res(_, res.Success(v)) => v
case _ => throw new Exception(errMsg)
}
def runMatched(input: String): Doc =
run(input) match {
case res(_, res.Success(v)) => v
case _ => throw new Exception(errMsg)
}
/**
* Used to initialize Doc Parser with input string to get parsed Doc
@ -274,7 +275,6 @@ object DocParserRunner {
*
* Essentially it enables Doc Parser to create pretty HTML files from
* documented code.
*
*/
object DocParserHTMLGenerator {
@ -283,29 +283,26 @@ object DocParserHTMLGenerator {
* reformatted [[AST.Documented]]
*
* @param ast - parsed AST.Module and reformatted using Doc Parser
* @param path - path to save file
* @param cssFileName - name of file containing stylesheets for the HTML code
*/
def generateHTMLForEveryDocumented(
ast: AST,
path: String,
cssFileName: String
): Unit = {
cssFileName: String = "style.css"
): String = {
ast.map { elem =>
elem match {
case AST.Documented.any(d) =>
generateHTMLForEveryDocumented(d, path, cssFileName)
val file = onHTMLRendering(d, cssFileName)
println("\nFINISHED FILE: " + file.name)
// FIXME: For now prints out code. When decided how to save HTML's
// then it should be changed
println(file.code)
println()
case AST.Documented.any(documented) =>
val file = onHTMLRendering(documented, cssFileName)
return file.code.toString() + generateHTMLForEveryDocumented(
documented,
cssFileName
)
case _ =>
generateHTMLForEveryDocumented(elem, path, cssFileName)
generateHTMLForEveryDocumented(elem, cssFileName)
}
elem
}: Unit
}
new String
}
//////////////////////////////////////////////////////////////////////////////
@ -348,7 +345,7 @@ object DocParserHTMLGenerator {
def renderHTML(
ast: AST,
doc: Doc,
cssLink: String = "style.css"
cssLink: String
): TypedTag[String] = {
val title = ast.show().split("\n").head.split("=").head
val documentation = DocumentedToHtml(ast, doc)
@ -525,8 +522,8 @@ object DocParserHTMLGenerator {
def createInfixHtmlRepr(infix: AST.App.Infix): TypedTag[String] = {
val cls = HTML.`class` := "Infix"
val pageHref = HTML.`href` := infix.larg
.show()
.replaceAll(" ", "_") + ".html"
.show()
.replaceAll(" ", "_") + ".html"
val innerDiv = HTML.div(cls)(infix.larg.show())
HTML.a(pageHref)(innerDiv)
}

View File

@ -99,8 +99,6 @@ class InternalError(reason: String, cause: Throwable = None.orNull)
* note, that there is a special module parsing macro, which runs
* [[Pattern.Build]] on every line.
*
*
*
* ==Pattern Build Mechanism==
*
* The resolution of [[Pattern.Build]] is as interesting as the macro system.
@ -124,8 +122,6 @@ class InternalError(reason: String, cause: Throwable = None.orNull)
* where both "=" and "," operators are considered right-associative. See
* [[Operator]] and [[Prec]] for more information.
*
*
*
* ==Finalizers==
*
* A careful reader will notice that there was no description of how finalizers
@ -230,7 +226,7 @@ class Parser {
def run(input: Reader, idMap: IDMap): AST.Module = {
val tokenStream = engine.run(input).map(InHoisting.run)
val spanned = tokenStream.map(attachModuleLocations)
val spanned = tokenStream.map(attachModuleLocations)
val resolved = spanned.map(Macro.run) match {
case flexer.Parser.Result(_, flexer.Parser.Result.Success(mod)) =>
val mod2 = annotateModule(idMap, mod)
@ -309,16 +305,17 @@ class Parser {
* @return a version of the input AST with the absolute positioning info
* populated
*/
def attachLocations(ast: AST, startOffset: Int): AST = ast match {
case App.Prefix.any(app) =>
val locatedFn = attachLocations(app.func, startOffset)
val locatedArg =
attachLocations(app.arg, startOffset + locatedFn.span + app.off)
App.Prefix(locatedFn, app.off, locatedArg)
case AST.Block.any(block) => attachBlockLocations(block, startOffset)
case _ =>
ast.setLocation(Location(startOffset, startOffset + ast.span))
}
def attachLocations(ast: AST, startOffset: Int): AST =
ast match {
case App.Prefix.any(app) =>
val locatedFn = attachLocations(app.func, startOffset)
val locatedArg =
attachLocations(app.arg, startOffset + locatedFn.span + app.off)
App.Prefix(locatedFn, app.off, locatedArg)
case AST.Block.any(block) => attachBlockLocations(block, startOffset)
case _ =>
ast.setLocation(Location(startOffset, startOffset + ast.span))
}
def annotateModule(
idMap: IDMap,
@ -554,7 +551,7 @@ object Main extends scala.App {
println("--- PARSING ---")
val mod = parser.run(inp)
val mod = parser.run(inC)
println(Debug.pretty(mod.toString))
@ -574,21 +571,18 @@ object Main extends scala.App {
/** Invoking the Enso Documentation Parser */
println("===== DOCUMENTATION =====")
val droppedMeta = parser.dropMacroMeta(mod)
val documentation = DocParserRunner.createDocs(droppedMeta)
val htmlPath = "target/"
val cssFileName = "style.css"
val droppedMeta = parser.dropMacroMeta(mod)
val doc = DocParserRunner.createDocs(droppedMeta)
val cssFileName = "style.css"
println(Debug.pretty(documentation.toString))
println(Debug.pretty(doc.toString))
println("------")
println(documentation.show())
println(doc.show())
println("=========================")
val htmlCode = DocParserHTMLGenerator.generateHTMLForEveryDocumented(doc)
println("========== HTML ===========")
println(htmlCode)
println("=========================")
DocParserHTMLGenerator.generateHTMLForEveryDocumented(
documentation,
htmlPath,
cssFileName
)
println()
AST.main()