Remove documentation style sheet, fix code blocks (#1202)

This commit is contained in:
Maciej Mikołajek 2020-10-08 14:59:18 +02:00 committed by GitHub
parent 1fbf3ad692
commit 91346a41fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 483 additions and 894 deletions

View File

@ -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

View File

@ -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()

View File

@ -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)
}
}

View File

@ -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

View File

@ -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("------")