From 91346a41fcee9b3bc8c8c530be7bca987420f453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Miko=C5=82ajek?= Date: Thu, 8 Oct 2020 14:59:18 +0200 Subject: [PATCH] Remove documentation style sheet, fix code blocks (#1202) --- .../scala/org/enso/syntax/text/ast/Doc.scala | 32 +- .../enso/syntax/text/spec/DocParserDef.scala | 847 ++++++++++-------- .../org/enso/syntax/text/DocParser.scala | 51 +- .../syntax/text/DocParserStyle/style.sass | 446 --------- .../scala/org/enso/syntax/text/Parser.scala | 1 - 5 files changed, 483 insertions(+), 894 deletions(-) delete mode 100644 lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/DocParserStyle/style.sass diff --git a/lib/scala/syntax/definition/src/main/scala/org/enso/syntax/text/ast/Doc.scala b/lib/scala/syntax/definition/src/main/scala/org/enso/syntax/text/ast/Doc.scala index f13cbb83037..eb7678a9ac4 100644 --- a/lib/scala/syntax/definition/src/main/scala/org/enso/syntax/text/ast/Doc.scala +++ b/lib/scala/syntax/definition/src/main/scala/org/enso/syntax/text/ast/Doc.scala @@ -169,12 +169,8 @@ object Doc { * * @param elems - lines of code */ - /*TODO [MM]: Next PR - Code showing button - we need other design here. - Basically we don't want to display always button - we want to be able to display it maybe as a button on website - and completely differently in gui, it should be configurable*/ - final case class CodeBlock(elems: List1[CodeBlock.Line]) extends Elem { + final case class CodeBlock(elems: List1[CodeBlock.Line], isInGui: Boolean) + extends Elem { val newLn: Elem = Elem.Newline val repr: Repr.Builder = R + elems.head + elems.tail.map(R + newLn + _) val html: HTML = { @@ -182,22 +178,28 @@ object Doc { val uniqueIDBtn = Random.alphanumeric.take(8).mkString("") val htmlIdCode = HTML.`id` := uniqueIDCode val htmlIdBtn = HTML.`id` := uniqueIDBtn + val htmlStyle = HTML.`style` := "inline-block" val elemsHTML = elems.toList.map(elem => elem.html) val btnAction = onclick := - s"""var code = document.getElementById("$uniqueIDCode"); - |var btn = document.getElementById("$uniqueIDBtn").firstChild; - |btn.data = btn.data == "Show" ? "Hide" : "Show"; - |code.style.display = code.style.display == - |"inline-block" ? "none" : "inline-block";""".stripMargin - .replaceAll("\n", "") + s"""var code = document.getElementById("$uniqueIDCode"); + |var btn = document.getElementById("$uniqueIDBtn").firstChild; + |btn.data = btn.data == "Show" ? "Hide" : "Show"; + |code.style.display = code.style.display == + |"inline-block" ? "none" : "inline-block";""".stripMargin + .replaceAll("\n", "") val btn = HTML.button(btnAction)(htmlIdBtn)("Show") - Seq(HTML.div(btn, HTML.div(htmlCls())(htmlIdCode)(elemsHTML))) + if (isInGui) { + Seq(HTML.div(htmlCls())(htmlStyle)(elemsHTML)) + } else { + Seq(HTML.div(btn, HTML.div(htmlCls())(htmlIdCode)(elemsHTML))) + } } } object CodeBlock { - def apply(elem: CodeBlock.Line): CodeBlock = CodeBlock(List1(elem)) + def apply(elem: CodeBlock.Line): CodeBlock = + CodeBlock(List1(elem), isInGui = true) def apply(elems: CodeBlock.Line*): CodeBlock = - CodeBlock(List1(elems.head, elems.tail.toList)) + CodeBlock(List1(elems.head, elems.tail.toList), isInGui = true) /** Inline - line of code which is in line with other elements * Line - elem which is a part of Code Block diff --git a/lib/scala/syntax/definition/src/main/scala/org/enso/syntax/text/spec/DocParserDef.scala b/lib/scala/syntax/definition/src/main/scala/org/enso/syntax/text/spec/DocParserDef.scala index 6d95991f123..ad832d109b8 100644 --- a/lib/scala/syntax/definition/src/main/scala/org/enso/syntax/text/spec/DocParserDef.scala +++ b/lib/scala/syntax/definition/src/main/scala/org/enso/syntax/text/spec/DocParserDef.scala @@ -26,25 +26,27 @@ case class DocParserDef() extends Parser[Doc] { var doc: Option[Doc] = None var stack: List[Elem] = Nil - def push(): Unit = logger.trace { - if (current.isDefined) { - logger.log(s"Pushed: $current") - stack +:= current.get - current = None - } else { - logger.err("Undefined current") + def push(): Unit = + logger.trace { + if (current.isDefined) { + logger.log(s"Pushed: $current") + stack +:= current.get + current = None + } else { + logger.err("Undefined current") + } } - } - def pop(): Unit = logger.trace { - if (stack.nonEmpty) { - current = Some(stack.head) - stack = stack.tail - logger.log(s"New result: $current") - } else { - logger.err("Trying to pop empty AST stack") + def pop(): Unit = + logger.trace { + if (stack.nonEmpty) { + current = Some(stack.head) + stack = stack.tail + logger.log(s"New result: $current") + } else { + logger.err("Trying to pop empty AST stack") + } } - } } ////////////////////////////////////////////////////////////////////////////// @@ -71,34 +73,37 @@ case class DocParserDef() extends Parser[Doc] { /** text - used to manage normal text, made of Strings */ final object text { - def onPushing(in: String): Unit = logger.trace { - if (documentation.isBeginning()) { - if (!tags.checkIfTagExistInPushedText(in)) { + def onPushing(in: String): Unit = + logger.trace { + if (documentation.isBeginning()) { + if (!tags.checkIfTagExistInPushedText(in)) { + val text = removeWhitespaces(in) + push(text) + } + } else if (section.isBeginning()) { val text = removeWhitespaces(in) push(text) - } - } else if (section.isBeginning()) { - val text = removeWhitespaces(in) - push(text) - } else { - push(in) - } - } - - def removeWhitespaces(in: String): String = logger.trace { - var text = in - if (text.nonEmpty) { - while (text.head == ' ' && text.length > 1) { - text = text.tail + } else { + push(in) } } - text - } - def push(in: String): Unit = logger.trace { - result.current = Some(Elem.Text(in)) - result.push() - } + def removeWhitespaces(in: String): String = + logger.trace { + var text = in + if (text.nonEmpty) { + while (text.head == ' ' && text.length > 1) { + text = text.tail + } + } + text + } + + def push(in: String): Unit = + logger.trace { + result.current = Some(Elem.Text(in)) + result.push() + } } ROOT || normalText || text.onPushing(currentMatch) @@ -135,33 +140,35 @@ case class DocParserDef() extends Parser[Doc] { result.current = None } - def checkIfTagExistInPushedText(in: String): Boolean = logger.trace { - val inArray = in.split(" ") - var containsTag = false + def checkIfTagExistInPushedText(in: String): Boolean = + logger.trace { + val inArray = in.split(" ") + var containsTag = false - def tryFindingTagInAvailableTags(elem: String): Unit = logger.trace { - for (tagType <- possibleTagsList) { - if (elem == tagType.toString.toUpperCase) { - containsTag = true - val tagDet = in.replaceFirst(tagType.toString.toUpperCase, "") - pushTag(section.currentIndentRaw, tagType, tagDet) + def tryFindingTagInAvailableTags(elem: String): Unit = + logger.trace { + for (tagType <- possibleTagsList) { + if (elem == tagType.toString.toUpperCase) { + containsTag = true + val tagDet = in.replaceFirst(tagType.toString.toUpperCase, "") + pushTag(section.currentIndentRaw, tagType, tagDet) + } + } + if (!containsTag && !elem.contains(newline)) { + pushTag(section.currentIndentRaw, Tags.Tag.Unrecognized, in) + containsTag = true + } + } + + for (elem <- inArray) { + if (elem.isEmpty) { + section.currentIndentRaw += 1 + } else if (elem == elem.toUpperCase) { + tryFindingTagInAvailableTags(elem) } } - if (!containsTag && !elem.contains(newline)) { - pushTag(section.currentIndentRaw, Tags.Tag.Unrecognized, in) - containsTag = true - } + containsTag } - - for (elem <- inArray) { - if (elem.isEmpty) { - section.currentIndentRaw += 1 - } else if (elem == elem.toUpperCase) { - tryFindingTagInAvailableTags(elem) - } - } - containsTag - } } ////////////////////////////////////////////////////////////////////////////// @@ -171,29 +178,32 @@ case class DocParserDef() extends Parser[Doc] { /** code - used to manage code in documentation */ final object code { - def onPushingInline(in: String): Unit = logger.trace { - val code = in.substring(1).dropRight(1) - result.current = Some(Elem.CodeBlock.Inline(code)) - result.push() - } - - def onPushingMultiline(in: String): Unit = logger.trace { - val dummyLine = Elem.CodeBlock.Line(0, "") - do { - result.pop() - } while (result.current.get == Elem.Newline) - result.current match { - case Some(code @ (_: Elem.CodeBlock)) => - val newElem = Elem.CodeBlock.Line(indent.current, in) - if (code.elems.head == dummyLine) { - result.current = Some(Elem.CodeBlock(newElem)) - } else { - result.current = Some(Elem.CodeBlock(code.elems.append(newElem))) - } - case Some(_) | None => result.push() + def onPushingInline(in: String): Unit = + logger.trace { + val code = in.substring(1).dropRight(1) + result.current = Some(Elem.CodeBlock.Inline(code)) + result.push() + } + + def onPushingMultiline(in: String): Unit = + logger.trace { + val dummyLine = Elem.CodeBlock.Line(0, "") + do { + result.pop() + } while (result.current.get == Elem.Newline) + result.current match { + case Some(code @ (_: Elem.CodeBlock)) => + val newElem = Elem.CodeBlock.Line(indent.current, in) + if (code.elems.head == dummyLine) { + result.current = Some(Elem.CodeBlock(newElem)) + } else { + result.current = + Some(Elem.CodeBlock(code.elems.append(newElem), isInGui = true)) + } + case Some(_) | None => result.push() + } + result.push() } - result.push() - } val inlineCodeTrigger = '`' val inlinePattern: Pattern = @@ -204,7 +214,7 @@ case class DocParserDef() extends Parser[Doc] { val CODE: State = state.define("Code") ROOT || code.inlinePattern || code.onPushingInline(currentMatch) - CODE || newline || { state.end(); state.begin(NEWLINE) } + CODE || newline || { state.end(); state.begin(NEWLINE) } CODE || notNewLine || code.onPushingMultiline(currentMatch) CODE || eof || { state.end(); documentation.onEOF() } @@ -237,7 +247,9 @@ case class DocParserDef() extends Parser[Doc] { def getElemsFromStack(typ: Elem.Formatter.Type): List[Elem] = logger.trace { var listOfFormattedAST: List[Elem] = Nil - while (result.stack.head != Elem.Formatter(typ) && result.stack.nonEmpty) { + while ( + result.stack.head != Elem.Formatter(typ) && result.stack.nonEmpty + ) { result.pop() result.current match { case Some(value) => listOfFormattedAST +:= value @@ -247,38 +259,41 @@ case class DocParserDef() extends Parser[Doc] { listOfFormattedAST } - def addEmptyToStack(typ: Elem.Formatter.Type): Unit = logger.trace { - stack +:= typ - result.current = Some(Elem.Formatter(typ)) - result.push() - } + def addEmptyToStack(typ: Elem.Formatter.Type): Unit = + logger.trace { + stack +:= typ + result.current = Some(Elem.Formatter(typ)) + result.push() + } def decideWhichToCheckIfUnclosed( typ: Elem.Formatter.Type - ): List[Elem.Formatter.Type] = logger.trace { - typ match { - case Elem.Formatter.Strikeout => - List(Elem.Formatter.Bold, Elem.Formatter.Italic) - case Elem.Formatter.Italic => - List(Elem.Formatter.Bold, Elem.Formatter.Strikeout) - case Elem.Formatter.Bold => - List(Elem.Formatter.Italic, Elem.Formatter.Strikeout) - case _ => throw new Error("Trying to use non-existing formatter") - } - } - - def checkForUnclosed(typ: Elem.Formatter.Type): Unit = logger.trace { - if (stack.nonEmpty) { - if (stack.head == typ) { - val listOfFormattedAST: List[Elem] = getElemsFromStack(typ) - result.pop() - result.current = - Some(Elem.Formatter.Unclosed(typ, listOfFormattedAST)) - stack = stack.tail - result.push() + ): List[Elem.Formatter.Type] = + logger.trace { + typ match { + case Elem.Formatter.Strikeout => + List(Elem.Formatter.Bold, Elem.Formatter.Italic) + case Elem.Formatter.Italic => + List(Elem.Formatter.Bold, Elem.Formatter.Strikeout) + case Elem.Formatter.Bold => + List(Elem.Formatter.Italic, Elem.Formatter.Strikeout) + case _ => throw new Error("Trying to use non-existing formatter") + } + } + + def checkForUnclosed(typ: Elem.Formatter.Type): Unit = + logger.trace { + if (stack.nonEmpty) { + if (stack.head == typ) { + val listOfFormattedAST: List[Elem] = getElemsFromStack(typ) + result.pop() + result.current = + Some(Elem.Formatter.Unclosed(typ, listOfFormattedAST)) + stack = stack.tail + result.push() + } } } - } val boldTrigger: Char = Elem.Formatter.Bold.marker val italicTrigger: Char = Elem.Formatter.Italic.marker @@ -301,31 +316,33 @@ case class DocParserDef() extends Parser[Doc] { /** header - used to create section headers in Documentation */ final object header { - def create(): Unit = logger.trace { - section.current match { - case Some(_) => loopThroughStackToFindHeader() - case None => - result.pop() - result.current match { - case Some(_: Section.Header) => loopThroughStackToFindHeader() - case _ => result.push() - } + def create(): Unit = + logger.trace { + section.current match { + case Some(_) => loopThroughStackToFindHeader() + case None => + result.pop() + result.current match { + case Some(_: Section.Header) => loopThroughStackToFindHeader() + case _ => result.push() + } + } } - } - def loopThroughStackToFindHeader(): Unit = logger.trace { - var listForHeader: List[Elem] = Nil - do { - result.pop() - listForHeader +:= result.current.get - } while (result.current.get != Elem.Newline && result.stack.nonEmpty) - if (result.current.get == Elem.Newline) { + def loopThroughStackToFindHeader(): Unit = + logger.trace { + var listForHeader: List[Elem] = Nil + do { + result.pop() + listForHeader +:= result.current.get + } while (result.current.get != Elem.Newline && result.stack.nonEmpty) + if (result.current.get == Elem.Newline) { + result.push() + listForHeader = listForHeader.tail + } + result.current = Some(Section.Header(listForHeader.reverse)) result.push() - listForHeader = listForHeader.tail } - result.current = Some(Section.Header(listForHeader.reverse)) - result.push() - } } ////////////////////////////////////////////////////////////////////////////// @@ -337,53 +354,60 @@ case class DocParserDef() extends Parser[Doc] { * there are 2 possible link types - Image and normal URL */ final object link { - def onCreatingURL(): Unit = logger.trace { - if (currentMatch.contains("]") && currentMatch.contains("(")) { - val in = currentMatch.substring(1).dropRight(1).split(']') - val name = in(0) - val url = in(1).substring(1) - pushURL(name, url) - } else { - onInvalidLink() + def onCreatingURL(): Unit = + logger.trace { + if (currentMatch.contains("]") && currentMatch.contains("(")) { + val in = currentMatch.substring(1).dropRight(1).split(']') + val name = in(0) + val url = in(1).substring(1) + pushURL(name, url) + } else { + onInvalidLink() + } } - } - def pushURL(name: String, url: String): Unit = logger.trace { - result.current = Some(Elem.Link.URL(name, url)) - result.push() - } - - def onCreatingImage(): Unit = logger.trace { - if (currentMatch.contains("]") && currentMatch.contains("(")) { - val in = currentMatch.substring(2).dropRight(1).split(']') - val name = in(0) - val url = in(1).substring(1) - pushImage(name, url) - } else { - onInvalidLink() + def pushURL(name: String, url: String): Unit = + logger.trace { + result.current = Some(Elem.Link.URL(name, url)) + result.push() } - } - def pushImage(name: String, url: String): Unit = logger.trace { - result.current = Some(Elem.Link.Image(name, url)) - result.push() - } + def onCreatingImage(): Unit = + logger.trace { + if (currentMatch.contains("]") && currentMatch.contains("(")) { + val in = currentMatch.substring(2).dropRight(1).split(']') + val name = in(0) + val url = in(1).substring(1) + pushImage(name, url) + } else { + onInvalidLink() + } + } - def onInvalidLink(): Unit = logger.trace { - result.current = Some(Elem.Link.Invalid(currentMatch)) - result.push() - } + def pushImage(name: String, url: String): Unit = + logger.trace { + result.current = Some(Elem.Link.Image(name, url)) + result.push() + } - def onInvalidLinkNewline(): Unit = logger.trace { - result.current = Some(Elem.Link.Invalid(currentMatch.dropRight(1))) - result.push() - indent.onPushingNewLine() - } + def onInvalidLink(): Unit = + logger.trace { + result.current = Some(Elem.Link.Invalid(currentMatch)) + result.push() + } - def onInvalidLinkEOF(): Unit = logger.trace { - onInvalidLink() - documentation.onEOF() - } + def onInvalidLinkNewline(): Unit = + logger.trace { + result.current = Some(Elem.Link.Invalid(currentMatch.dropRight(1))) + result.push() + indent.onPushingNewLine() + } + + def onInvalidLinkEOF(): Unit = + logger.trace { + onInvalidLink() + documentation.onEOF() + } val urlNameTrigger: String = "[" val imageNameTrigger: String = Elem.Link.Image().marker.get + urlNameTrigger @@ -413,65 +437,71 @@ case class DocParserDef() extends Parser[Doc] { */ final object indent { var stack: List[Int] = Nil - def current: Int = stack match { - case Nil => 0 - case ::(head, _) => head - } - - def onIndent(): Unit = logger.trace { - val diff = currentMatch.length - current - if (diff < 0 && list.inListFlag) { - list.appendInnerToOuter() - stack = stack.tail - } else if (currentMatch.length > section.currentIndentRaw && result.stack.nonEmpty) { - tryToFindCodeInStack() - stack +:= currentMatch.length - state.begin(CODE) - } else { - section.currentIndentRaw = currentMatch.length + def current: Int = + stack match { + case Nil => 0 + case ::(head, _) => head } - } - def tryToFindCodeInStack(): Unit = logger.trace { - result.pop() - result.stack.head match { - case _: Elem.CodeBlock => - case _ => - result.push() - val dummyLine = Elem.CodeBlock.Line(0, "") - result.current = Some(Elem.CodeBlock(dummyLine)) + def onIndent(): Unit = + logger.trace { + val diff = currentMatch.length - current + if (diff < 0 && list.inListFlag) { + list.appendInnerToOuter() + stack = stack.tail + } else if ( + currentMatch.length > section.currentIndentRaw && result.stack.nonEmpty + ) { + tryToFindCodeInStack() + stack +:= currentMatch.length + state.begin(CODE) + } else { + section.currentIndentRaw = currentMatch.length + } + } + + def tryToFindCodeInStack(): Unit = + logger.trace { + result.pop() + result.stack.head match { + case _: Elem.CodeBlock => + case _ => + result.push() + val dummyLine = Elem.CodeBlock.Line(0, "") + result.current = Some(Elem.CodeBlock(dummyLine)) + } + result.push() } - result.push() - } def onIndentForListCreation( indent: Int, typ: Elem.List.Type, content: String - ): Unit = logger.trace { - val diff = indent - current - if (diff > 0) { - /* NOTE - * Used to push new line before pushing first list - */ - if (!list.inListFlag) onPushingNewLine() - stack +:= indent - list.inListFlag = true - list.addNew(indent, typ, content) - } else if (diff == 0 && list.inListFlag) { - list.addContent(content) - } else if (diff < 0 && list.inListFlag) { - if (stack.tail.head != indent) { - onInvalidIndent(indent, typ, content) - } else { - list.appendInnerToOuter() + ): Unit = + logger.trace { + val diff = indent - current + if (diff > 0) { + /* NOTE + * Used to push new line before pushing first list + */ + if (!list.inListFlag) onPushingNewLine() + stack +:= indent + list.inListFlag = true + list.addNew(indent, typ, content) + } else if (diff == 0 && list.inListFlag) { list.addContent(content) - stack = stack.tail + } else if (diff < 0 && list.inListFlag) { + if (stack.tail.head != indent) { + onInvalidIndent(indent, typ, content) + } else { + list.appendInnerToOuter() + list.addContent(content) + stack = stack.tail + } + } else { + onInvalidIndent(indent, typ, content) } - } else { - onInvalidIndent(indent, typ, content) } - } def onInvalidIndent( indent: Int, @@ -493,33 +523,37 @@ case class DocParserDef() extends Parser[Doc] { } } - def onPushingNewLine(): Unit = logger.trace { - result.current = Some(Elem.Newline) - result.push() - } - - def onEmptyLine(): Unit = logger.trace { - if (list.inListFlag) { - list.appendInnerToOuter() - list.inListFlag = false + def onPushingNewLine(): Unit = + logger.trace { + result.current = Some(Elem.Newline) + result.push() } - onPushingNewLine() - section.onEOS() - } - def onIndentPattern(): Unit = logger.trace { - state.end() - if (result.stack.nonEmpty) { + def onEmptyLine(): Unit = + logger.trace { + if (list.inListFlag) { + list.appendInnerToOuter() + list.inListFlag = false + } + onPushingNewLine() + section.onEOS() + } + + def onIndentPattern(): Unit = + logger.trace { + state.end() + if (result.stack.nonEmpty) { + indent.onPushingNewLine() + } + indent.onIndent() + } + + def onEOFPattern(): Unit = + logger.trace { + state.end() indent.onPushingNewLine() + documentation.onEOF() } - indent.onIndent() - } - - def onEOFPattern(): Unit = logger.trace { - state.end() - indent.onPushingNewLine() - documentation.onEOF() - } val emptyLine: Pattern = whitespace.opt >> newline val indentPattern: Pattern = whitespace.opt.many @@ -549,55 +583,63 @@ case class DocParserDef() extends Parser[Doc] { result.push() } - def addContent(content: Elem): Unit = logger.trace { - result.pop() - result.current match { - case Some(list @ (_: Elem.List)) => - var currentContent = list.elems - currentContent = currentContent.append(content) - result.current = - Some(Elem.List(list.indent, list.typ, currentContent)) - case _ => + def addContent(content: Elem): Unit = + logger.trace { + result.pop() + result.current match { + case Some(list @ (_: Elem.List)) => + var currentContent = list.elems + currentContent = currentContent.append(content) + result.current = + Some(Elem.List(list.indent, list.typ, currentContent)) + case _ => + } + result.push() } - result.push() - } - def appendInnerToOuter(): Unit = logger.trace { - result.pop() - val innerList = result.current.orNull - result.stack.head match { - case outerList @ (_: Elem.List) => - var outerContent = outerList.elems - innerList match { - case Elem.Newline => - case _ => outerContent = outerContent.append(innerList) - } - result.pop() - result.current = - Some(Elem.List(outerList.indent, outerList.typ, outerContent)) - case _ => + def appendInnerToOuter(): Unit = + logger.trace { + result.pop() + val innerList = result.current.orNull + result.stack.head match { + case outerList @ (_: Elem.List) => + var outerContent = outerList.elems + innerList match { + case Elem.Newline => + case _ => outerContent = outerContent.append(innerList) + } + result.pop() + result.current = + Some(Elem.List(outerList.indent, outerList.typ, outerContent)) + case _ => + } + result.push() + innerList match { + case Elem.Newline => indent.onPushingNewLine() + case _ => + } } - result.push() - innerList match { - case Elem.Newline => indent.onPushingNewLine() - case _ => - } - } - def onOrdered(): Unit = logger.trace { - state.end() - val matchedContent = currentMatch.split(orderedListTrigger) - val listIndent = matchedContent(0).length - val listElems = matchedContent(1) - indent.onIndentForListCreation(listIndent, Elem.List.Ordered, listElems) - } - def onUnordered(): Unit = logger.trace { - state.end() - val matchedContent = currentMatch.split(unorderedListTrigger) - val listIndent = matchedContent(0).length - val listElems = matchedContent(1) - indent.onIndentForListCreation(listIndent, Elem.List.Unordered, listElems) - } + def onOrdered(): Unit = + logger.trace { + state.end() + val matchedContent = currentMatch.split(orderedListTrigger) + val listIndent = matchedContent(0).length + val listElems = matchedContent(1) + indent.onIndentForListCreation(listIndent, Elem.List.Ordered, listElems) + } + def onUnordered(): Unit = + logger.trace { + state.end() + val matchedContent = currentMatch.split(unorderedListTrigger) + val listIndent = matchedContent(0).length + val listElems = matchedContent(1) + indent.onIndentForListCreation( + listIndent, + Elem.List.Unordered, + listElems + ) + } val orderedListTrigger: Char = Elem.List.Ordered.marker val unorderedListTrigger: Char = Elem.List.Unordered.marker @@ -642,11 +684,12 @@ case class DocParserDef() extends Parser[Doc] { current = typ } - def onNewMarked(typ: Section.Marked.Type): Unit = logger.trace { - createMarkedSectionIndent(typ) - onNew(Some(typ)) - currentIndentRaw += currentMatch.length - } + def onNewMarked(typ: Section.Marked.Type): Unit = + logger.trace { + createMarkedSectionIndent(typ) + onNew(Some(typ)) + currentIndentRaw += currentMatch.length + } def createMarkedSectionIndent(typ: Section.Marked.Type): Unit = logger.trace { @@ -663,69 +706,77 @@ case class DocParserDef() extends Parser[Doc] { indentAfterMarker = inArr.tail.head.length - 1 } - def onNewRaw(): Unit = logger.trace { - indent.onEmptyLine() - onNew(None) - } + def onNewRaw(): Unit = + logger.trace { + indent.onEmptyLine() + onNew(None) + } - def onNewRawWithHeader(): Unit = logger.trace { - state.end() - onNewRaw() - result.current = Some(Section.Header()) - result.push() - } + def onNewRawWithHeader(): Unit = + logger.trace { + state.end() + onNewRaw() + result.current = Some(Section.Header()) + result.push() + } - def isBeginning(): Boolean = logger.trace { - result.stack.isEmpty || result.stack.head.isInstanceOf[Section.Header] - } + def isBeginning(): Boolean = + logger.trace { + result.stack.isEmpty || result.stack.head.isInstanceOf[Section.Header] + } //// End of Section //// - def checkForUnclosedFormattersOnEOS(): Unit = logger.trace { - formatter.checkForUnclosed(Elem.Formatter.Bold) - formatter.checkForUnclosed(Elem.Formatter.Italic) - formatter.checkForUnclosed(Elem.Formatter.Strikeout) - } - - def reverseStackOnEOS(): Unit = logger.trace { - result.stack = result.stack.reverse - } - - def push(): Unit = logger.trace { - result.stack match { - case Nil => - /* NOTE - * We don't want to push an empty section into stack - * in case of parsing for example empty file - * Then we want to get back Doc(None) and not Doc(Section()) - */ - case _ => - section.current match { - case Some(marker) => - section.stack +:= Section.Marked( - indentBeforeMarker, - indentAfterMarker, - marker, - result.stack - ) - case None => - section.stack +:= Section.Raw(currentIndentRaw, result.stack) - } + def checkForUnclosedFormattersOnEOS(): Unit = + logger.trace { + formatter.checkForUnclosed(Elem.Formatter.Bold) + formatter.checkForUnclosed(Elem.Formatter.Italic) + formatter.checkForUnclosed(Elem.Formatter.Strikeout) } - } - def cleanupOnEOS(): Unit = logger.trace { - result.current = None - result.stack = Nil - formatter.stack = Nil - } + def reverseStackOnEOS(): Unit = + logger.trace { + result.stack = result.stack.reverse + } - def onEOS(): Unit = logger.trace { - checkForUnclosedFormattersOnEOS() - reverseStackOnEOS() - header.create() - push() - cleanupOnEOS() - } + def push(): Unit = + logger.trace { + result.stack match { + case Nil => + /* NOTE + * We don't want to push an empty section into stack + * in case of parsing for example empty file + * Then we want to get back Doc(None) and not Doc(Section()) + */ + case _ => + section.current match { + case Some(marker) => + section.stack +:= Section.Marked( + indentBeforeMarker, + indentAfterMarker, + marker, + result.stack + ) + case None => + section.stack +:= Section.Raw(currentIndentRaw, result.stack) + } + } + } + + def cleanupOnEOS(): Unit = + logger.trace { + result.current = None + result.stack = Nil + formatter.stack = Nil + } + + def onEOS(): Unit = + logger.trace { + checkForUnclosedFormattersOnEOS() + reverseStackOnEOS() + header.create() + push() + cleanupOnEOS() + } val importantTrigger: Char = Section.Marked.Important.marker val infoTrigger: Char = Section.Marked.Info.marker @@ -763,56 +814,64 @@ case class DocParserDef() extends Parser[Doc] { * is it just ran as DocParser - for example in test suite */ final object documentation { - def reverseSectionsStackOnEOF(): Unit = logger.trace { - section.stack = section.stack.reverse - } - - def reverseTagsStackOnEOF(): Unit = logger.trace { - tags.stack = tags.stack.reverse - } - - def createDoc(): Unit = logger.trace { - val tags: Option[Tags] = createTags() - val synopsis: Option[Synopsis] = createSynopsis() - val body: Option[Body] = createBody() - result.doc = Some(Doc(tags, synopsis, body)) - } - - def createTags(): Option[Tags] = logger.trace { - tags.stack match { - case Nil => None - case x :: xs => Some(Tags(List1(x, xs))) + def reverseSectionsStackOnEOF(): Unit = + logger.trace { + section.stack = section.stack.reverse } - } - def createSynopsis(): Option[Synopsis] = logger.trace { - section.stack match { - case Nil => None - case x :: _ => Some(Synopsis(x)) + def reverseTagsStackOnEOF(): Unit = + logger.trace { + tags.stack = tags.stack.reverse } - } - def createBody(): Option[Body] = logger.trace { - section.stack match { - case Nil => None - case _ :: xs => - xs match { - case Nil => None - case y :: ys => Some(Body(List1(y, ys))) - } + def createDoc(): Unit = + logger.trace { + val tags: Option[Tags] = createTags() + val synopsis: Option[Synopsis] = createSynopsis() + val body: Option[Body] = createBody() + result.doc = Some(Doc(tags, synopsis, body)) } - } - def onEOF(): Unit = logger.trace { - section.onEOS() - reverseSectionsStackOnEOF() - reverseTagsStackOnEOF() - createDoc() - } + def createTags(): Option[Tags] = + logger.trace { + tags.stack match { + case Nil => None + case x :: xs => Some(Tags(List1(x, xs))) + } + } - def isBeginning(): Boolean = logger.trace { - result.stack.isEmpty && section.stack.isEmpty - } + def createSynopsis(): Option[Synopsis] = + logger.trace { + section.stack match { + case Nil => None + case x :: _ => Some(Synopsis(x)) + } + } + + def createBody(): Option[Body] = + logger.trace { + section.stack match { + case Nil => None + case _ :: xs => + xs match { + case Nil => None + case y :: ys => Some(Body(List1(y, ys))) + } + } + } + + def onEOF(): Unit = + logger.trace { + section.onEOS() + reverseSectionsStackOnEOF() + reverseTagsStackOnEOF() + createDoc() + } + + def isBeginning(): Boolean = + logger.trace { + result.stack.isEmpty && section.stack.isEmpty + } } ROOT || eof || documentation.onEOF() diff --git a/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/DocParser.scala b/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/DocParser.scala index 313c7e992c5..c1b9637feab 100644 --- a/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/DocParser.scala +++ b/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/DocParser.scala @@ -283,22 +283,17 @@ object DocParserHTMLGenerator { * reformatted [[AST.Documented]] * * @param ast - parsed AST.Module and reformatted using Doc Parser - * @param cssFileName - name of file containing stylesheets for the HTML code */ - def generateHTMLForEveryDocumented( - ast: AST, - cssFileName: String = "style.css" - ): String = { + def generateHTMLForEveryDocumented(ast: AST): String = { ast.map { elem => elem match { case AST.Documented.any(documented) => - val file = onHTMLRendering(documented, cssFileName) + val file = onHTMLRendering(documented) return file.code.toString() + generateHTMLForEveryDocumented( - documented, - cssFileName + documented ) case _ => - generateHTMLForEveryDocumented(elem, cssFileName) + generateHTMLForEveryDocumented(elem) } elem } @@ -309,14 +304,10 @@ object DocParserHTMLGenerator { * Function to generate HTML File from pure doc comment w/o connection to AST * * @param doc - Doc from Doc Parser - * @param cssLink - string containing CSS file name * @return - HTML Code from Doc */ - def generateHTMLPureDoc( - doc: Doc, - cssLink: String = "style.css" - ): String = { - HTML.html(createHTMLHead("", cssLink), HTML.body(doc.html)).toString() + def generateHTMLPureDoc(doc: Doc): String = { + HTML.html(createHTMLHead(""), HTML.body(doc.html)).toString() } ////////////////////////////////////////////////////////////////////////////// @@ -328,14 +319,10 @@ object DocParserHTMLGenerator { * Runner finished it's job * * @param documented - documented made by Doc Parser Runner from AST and Doc - * @param cssFileName - name of file containing stylesheets for the HTML code * @return - HTML code with file name */ - def onHTMLRendering( - documented: AST.Documented, - cssFileName: String - ): htmlFile = { - val htmlCode = renderHTML(documented.ast, documented.doc, cssFileName) + def onHTMLRendering(documented: AST.Documented): htmlFile = { + val htmlCode = renderHTML(documented.ast, documented.doc) val astLines = documented.ast.show().split("\n") val fileName = astLines.head @@ -352,18 +339,13 @@ object DocParserHTMLGenerator { * * @param ast - AST from Parser * @param doc - Doc from Doc Parser - * @param cssLink - string containing CSS file name * @return - HTML Code from Doc and contents of [[AST.Def]] or * [[AST.App.Infix]], with optional title made from AST */ - def renderHTML( - ast: AST, - doc: Doc, - cssLink: String - ): TypedTag[String] = { + def renderHTML(ast: AST, doc: Doc): TypedTag[String] = { val title = ast.show().split("\n").head.split("=").head val documentation = DocumentedToHtml(ast, doc) - HTML.html(createHTMLHead(title, cssLink), HTML.body(documentation)) + HTML.html(createHTMLHead(title), HTML.body(documentation)) } /** @@ -376,10 +358,7 @@ object DocParserHTMLGenerator { * @return - HTML Code from Doc and contents of [[AST.Def]] or * [[AST.App.Infix]] */ - def DocumentedToHtml( - ast: AST, - doc: Doc - ): TypedTag[String] = { + def DocumentedToHtml(ast: AST, doc: Doc): TypedTag[String] = { val docClass = HTML.`class` := "Documentation" val astHeadCls = HTML.`class` := "ASTHead" val astHTML = createHTMLFromAST(ast) @@ -576,18 +555,14 @@ object DocParserHTMLGenerator { * Function invoked by [[DocumentedToHtml]] to create HTML.Head part of file * * @param title - HTML page title - * @param cssLink - string containing CSS file name * @return - HTML Head Code */ - def createHTMLHead(title: String, cssLink: String): TypedTag[String] = { + def createHTMLHead(title: String): TypedTag[String] = { val metaEquiv = HTML.httpEquiv := "Content-Type" val metaCont = HTML.content := "text/html" val metaChar = HTML.charset := "UTF-8" val meta = HTML.meta(metaEquiv)(metaCont)(metaChar) - val cssRel = HTML.rel := "stylesheet" - val cssHref = HTML.href := cssLink - val css = HTML.link(cssRel)(cssHref) val fileTitle = scalatags.Text.tags2.title(title) - HTML.head(meta, css)(fileTitle) + HTML.head(meta)(fileTitle) } } diff --git a/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/DocParserStyle/style.sass b/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/DocParserStyle/style.sass deleted file mode 100644 index 5e7bf482ebf..00000000000 --- a/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/DocParserStyle/style.sass +++ /dev/null @@ -1,446 +0,0 @@ -/*/////////// -//// DOM //// -///////////*/ - -$defaultLineHeight: 1.52947 -$defaultFontSize: 17px -$defaultFontFamily: "SF Pro Text", "SF Pro Icons", "Helvetica Neue", "Helvetica", "Arial", sans-serif -$defaultFontWeight: 400 -$defaultBoldFontWeight: 600 -$defaultHeaderFontWeight: 500 -$defaultLetterSpacing: -0.021em -$defaultTextColor: #333333 -$defaultCodeColor: #0070c9 - - -body - -webkit-font-smoothing: antialiased - font-style: normal - word-wrap: break-word - font-size: $defaultFontSize - line-height: $defaultLineHeight - font-weight: $defaultFontWeight - letter-spacing: $defaultLetterSpacing - font-family: $defaultFontFamily - background-color: white - color: $defaultTextColor - margin: 0 - padding: 0 - -p - display: block - margin-block-start: 1em - margin-block-end: 1em - margin-inline-start: 0 - margin-inline-end: 0 - -a:hover - color: $defaultCodeColor !important - text-decoration: inherit - -a - color: $defaultTextColor - background-color: transparent - text-decoration: inherit - display: inline-block - transition: all 0.3s ease - -img - display: block - -code - color: $defaultCodeColor - background-color: transparent - font-size: inherit - font-family: $defaultFontFamily - line-height: inherit - display: inline-block - white-space: pre-wrap - -button - display: inline-block - padding: 8px 30px - margin: 10px 0 - outline: none - background-color: transparent - border: 1px solid $defaultTextColor - color: $defaultTextColor - border-radius: 5px - font-size: 13px - vertical-align: top - transition: all 0.3s ease - -button:hover - background-color: $defaultTextColor - color: #e5e5e5 - -b - font-weight: $defaultBoldFontWeight - -h1 - font-size: 34px - line-height: 1.08824 - font-weight: $defaultHeaderFontWeight - letter-spacing: 0.01em - - -h2 - font-size: 28px - line-height: 1.1073 - font-weight: $defaultHeaderFontWeight - letter-spacing: 0.012em - - -.Body h2 - margin: 0.65rem 0 0 - -li - padding-left: 10px - - -/*/////////////////// -//// Invalid AST //// -///////////////////*/ - -// Creator - a special mode for displaying parsing errors in output -.creator - .Unclosed, - .invalidIndent, - .invalidLink - display: inline - color: orangered - - .Tags - .UNRECOGNIZED - border: 2px solid - color: orangered - -.Unclosed, -.invalidIndent, -.invalidLink - display: inline - -/*////////////// -//// Header //// -//////////////*/ - -.Header - font-size: 19px - font-weight: $defaultHeaderFontWeight - - -.Important .Header, -.Info .Header, -.Example .Header - margin-bottom: 0.7em - font-weight: $defaultBoldFontWeight - letter-spacing: $defaultLetterSpacing - line-height: $defaultFontSize - font-synthesis: none - font-family: $defaultFontFamily - -/*//////////// -//// Tags //// -////////////*/ - -.Tags - margin-left: auto - margin-right: auto - margin-bottom: 20px - padding-top: 15px - - .DEPRECATED, - .MODIFIED, - .ADDED, - .UPCOMING, - .REMOVED, - .UNRECOGNIZED - line-height: 1.5 - font-weight: $defaultFontWeight - border-radius: 4px - font-size: 12px - letter-spacing: $defaultLetterSpacing - display: inline-flex - padding: 5px 15px - margin: 2px - white-space: nowrap - background: transparent - - .DEPRECATED - $col: #d20606 - border: 1px solid $col - color: $col - - .MODIFIED - $col: #003ec3 - border: 1px solid $col - color: $col - - .ADDED - $col: #79A129 - border: 1px solid $col - color: $col - - .UPCOMING, - .REMOVED, - .UNRECOGNIZED - $col: #666666 - border: 1px solid $col - color: $col - -.ExtForTagDetails - margin: 0 3px - color: #999999 - -/*//////////////// -//// Sections //// -////////////////*/ - -.Raw, -.Important, -.Info, -.CodeBlock, -.Example - margin-top: 0 - margin-left: auto - margin-right: auto - position: relative - text-decoration: inherit - - -.Body .Raw - margin-bottom: 0.6rem - font-size: $defaultFontSize - line-height: $defaultLineHeight - font-weight: $defaultFontWeight - letter-spacing: $defaultLetterSpacing - font-family: $defaultFontFamily - color: $defaultTextColor - font-style: normal - -.Important, -.Info, -.CodeBlock, -.Example - font-size: $defaultFontSize - padding: 15px 10px 15px 20px - border: 0 - border-radius: 6px - margin: 0.7em 0 - - -.Important - background-color: #FBECC2 - - -.Info - background-color: #D6E1CA - - -.Example - background-color: #fafafa - -.CodeBlock - background-color: #fefefe - margin: 10px 20px - display: none - - code - font-family: monospace - - -/*/////////////////////////////////// -//// HTML generated - Def, Infix //// -///////////////////////////////////*/ - -.Def - margin: 40px auto auto - padding: 0 15px - text-decoration: inherit - - .Synopsis, - .Body, - .Tags, - .ASTData - padding-left: 0 - text-decoration: inherit - - .Synopsis - padding: 0 - margin-bottom: 15px - font-size: $defaultFontSize - font-weight: $defaultFontWeight - color: $defaultTextColor - font-style: normal - - .constr - padding: 25px 0 - margin: 0 - - .DefDoc - .Body - display: none - - .documentation - display: inline-flex - width: 100% - margin-bottom: 10px - - - .ASTHead - width: 30% !important - margin: 10px 0 - - .DefTitle, - .Infix - padding: 0 - font-size: $defaultFontSize - font-weight: $defaultFontWeight - font-style: normal - text-decoration: inherit - - .ASTData - width: 70% !important - - .Doc - text-decoration: inherit - - .Synopsis - text-decoration: inherit - margin: 10px 0 - - .Tags - margin: 2px 0 0 auto - padding: 0 - - .DefNoDoc - padding-bottom: 10px - -.DefTitle - display: inline-flex - font-size: x-large - font-weight: $defaultFontWeight - margin-bottom: 20px - - -.DefArgs - margin-left: 5px - font-weight: $defaultFontWeight - color: $defaultCodeColor - -/*///////////////////////// -//// Synopsis & Detail //// -/////////////////////////*/ - -.Synopsis, -.Body - margin: 0 auto - padding: 5px - text-align: left - - -.Synopsis - margin-top: 35px - font-size: 20px - -.Documentation - .ASTData, - .ASTHead - text-align: left - line-height: 1.05 - border-radius: 6px - - .ASTData - width: 100% - background-color: #fafafa - - - .ASTHead - margin: 20px auto 5px - background-color: #ffffff - - .DefTitle - font-size: 42px - margin: 0 - - .ASTData - .ASTHead - background-color: #fafafa - - .DefTitle - font-size: x-large - - .Documented - margin: 0 - width: 100% - background-color: #ffffff - - .DefNoBody - text-decoration: inherit - - -/*/////////////////////////// -//// RWD //// -///////////////////////////*/ -@media (max-width: 500px) - .Synopsis, - .Body, - .Tags, - .Documentation .ASTData .Def - max-width: 380px - - .Documentation .ASTHead, - .DefNoBody, - .DefBody - max-width: 400px - - .Def - padding: 5px - -@media (min-width: 500px) - .Synopsis, - .Body, - .Tags, - .Documentation .ASTData .Def - max-width: 440px - - .Documentation .ASTHead, - .DefNoBody, - .DefBody - max-width: 470px - -@media (min-width: 600px) - .Synopsis, - .Body, - .Tags, - .Documentation .ASTData .Def - max-width: 490px - - .Documentation .ASTHead, - .DefNoBody, - .DefBody - max-width: 520px - -@media (min-width: 900px) - .Synopsis, - .Body, - .Tags, - .Documentation .ASTData .Def - max-width: 680px - - .Documentation .ASTHead, - .DefNoBody, - .DefBody - max-width: 710px - -@media (min-width: 1300px) - .Synopsis, - .Body, - .Tags, - .Documentation .ASTData .Def - max-width: 790px - - .Documentation .ASTHead, - .DefNoBody, - .DefBody - max-width: 820px \ No newline at end of file diff --git a/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/Parser.scala b/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/Parser.scala index 4078077fd20..4952b768b12 100644 --- a/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/Parser.scala +++ b/lib/scala/syntax/specialization/shared/src/main/scala/org/enso/syntax/text/Parser.scala @@ -573,7 +573,6 @@ object Main extends scala.App { println("===== DOCUMENTATION =====") val droppedMeta = parser.dropMacroMeta(mod) val doc = DocParserRunner.createDocs(droppedMeta) - val cssFileName = "style.css" println(Debug.pretty(doc.toString)) println("------")