diff options
Diffstat (limited to 'scalatexApi/src/main')
4 files changed, 54 insertions, 29 deletions
diff --git a/scalatexApi/src/main/scala/scalatex/package.scala b/scalatexApi/src/main/scala/scalatex/package.scala index eb3ba6e..e2566cf 100644 --- a/scalatexApi/src/main/scala/scalatex/package.scala +++ b/scalatexApi/src/main/scala/scalatex/package.scala @@ -78,13 +78,9 @@ package object scalatex { def compile(s: String): c.Tree = { val realPos = new OffsetPosition(source, point).asInstanceOf[c.universe.Position] - Compiler(c)(realPos, new Parser(s).Body.run().get) - } - def normalize(str: String) = { - val lines = str.split("\n") - val offset = lines.iterator.map(_.takeWhile(_ == ' ').length).min - lines.iterator.map(_.drop(offset)).mkString("\n") + Compiler(c)(realPos, Parser(stages.Trim(s))) } + import c.Position try { diff --git a/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala b/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala index a305199..19cec10 100644 --- a/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala +++ b/scalatexApi/src/main/scala/scalatex/stages/Compiler.scala @@ -6,9 +6,7 @@ import scala.reflect.macros.whitebox.Context import scala.reflect.internal.util.{Position, OffsetPosition} /** - * Walks the parsed AST, converting it into an un-structured Scala source-blob - * which when compiled results in a function that can be used to generate the - * given Frag at runtime. + * Walks the parsed AST, converting it into a structured Scala c.Tree */ object Compiler{ @@ -17,7 +15,7 @@ object Compiler{ import c.universe._ def fragType = tq"scalatags.Text.all.Frag" - + println(template) def compileChain(code: String, parts: Seq[Ast.Chain.Sub], offset: Int): c.Tree = { parts.foldLeft(c.parse(code)){ case (curr, Ast.Chain.Prop(str, offset2)) => q"$curr.${TermName(str)}" diff --git a/scalatexApi/src/main/scala/scalatex/stages/Parser.scala b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala index d8878de..0bba713 100644 --- a/scalatexApi/src/main/scala/scalatex/stages/Parser.scala +++ b/scalatexApi/src/main/scala/scalatex/stages/Parser.scala @@ -4,26 +4,15 @@ package stages import org.parboiled2._ import torimatomeru.ScalaSyntax import Util._ -trait Ast{ - def offset: Int -} -object Ast{ - case class Block(parts: Seq[Block.Sub], offset: Int = 0) extends Chain.Sub - object Block{ - trait Sub extends Ast - case class Text(txt: String, offset: Int = 0) extends Block.Sub - } - case class Chain(lhs: String, parts: Seq[Chain.Sub], offset: Int = 0) extends Block.Sub - object Chain{ - trait Sub extends Ast - case class Prop(str: String, offset: Int = 0) extends Sub - case class TypeArgs(str: String, offset: Int = 0) extends Sub - case class Args(str: String, offset: Int = 0) extends Sub - } -} -object Parser{ - def parse(input: String): Ast.Block = { +/** + * Parses the input text into a roughly-structured AST. This AST + * is much simpler than the real Scala AST, but serves us well + * enough until we stuff the code-strings into the real Scala + * parser later + */ +object Parser extends (String => Ast.Block){ + def apply(input: String): Ast.Block = { new Parser(input).Body.run().get } } @@ -95,3 +84,22 @@ class Parser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(input) { } } } + +trait Ast{ + def offset: Int +} +object Ast{ + case class Block(parts: Seq[Block.Sub], offset: Int = 0) extends Chain.Sub + object Block{ + trait Sub extends Ast + case class Text(txt: String, offset: Int = 0) extends Block.Sub + } + + case class Chain(lhs: String, parts: Seq[Chain.Sub], offset: Int = 0) extends Block.Sub + object Chain{ + trait Sub extends Ast + case class Prop(str: String, offset: Int = 0) extends Sub + case class TypeArgs(str: String, offset: Int = 0) extends Sub + case class Args(str: String, offset: Int = 0) extends Sub + } +}
\ No newline at end of file diff --git a/scalatexApi/src/main/scala/scalatex/stages/Trim.scala b/scalatexApi/src/main/scala/scalatex/stages/Trim.scala new file mode 100644 index 0000000..02d9cc4 --- /dev/null +++ b/scalatexApi/src/main/scala/scalatex/stages/Trim.scala @@ -0,0 +1,23 @@ +package scalatex.stages + +/** + * Preprocesses the input string to normalize things related to whitespace + * + * Find the "first" non-whitespace-line of the text and remove the front + * of every line to align that first line with the left margin. + * + * Remove all trailing whitespace from each line. + */ +object Trim extends (String => String){ + def apply(str: String) = { + val lines = str.split("\n") + val offset = lines.iterator + .filter(_.length > 0) + .next() + .takeWhile(_ == ' ') + .length + lines.iterator + .map(_.drop(offset).replaceFirst("\\s+$", "")) + .mkString("\n") + } +} |