Skip to content
Browse files

Preparation for interpolated text

  • Loading branch information...
1 parent cd4036c commit 70bf13db687ceed102f9141f5ae2b30176b0889e @teamon committed May 14, 2012
View
10 naja-compiler/src/main/scala/naja/compiler/AST.scala
@@ -3,7 +3,12 @@ package naja.compiler
import scala.util.parsing.input.Positional
sealed trait Expr extends Positional
-case class LiteralText(content: String) extends Expr
+sealed trait TextExpr extends Expr
+
+case class Text(content: List[TextExpr]) extends Expr
+case class LiteralText(content: String) extends TextExpr
+case class InterpolatedText(content: String) extends TextExpr
+
case class Tag(name: Option[String],
id: Option[String] = None,
classes: List[String] = Nil,
@@ -12,5 +17,8 @@ case class Tag(name: Option[String],
content: Option[Expr] = None,
body: List[Expr] = Nil) extends Expr
+case class Evaluated(content: String) extends Expr
+case class Statement(content: String, body: List[Expr] = Nil) extends Expr
+
case class Template(signature: String, body: List[Node])
case class Node(content: Expr, body: List[Node] = Nil)
View
24 naja-compiler/src/main/scala/naja/compiler/HamlParser.scala
@@ -24,18 +24,21 @@ trait IndentedParser extends RegexParsers {
object HamlParser extends IndentedParser {
def signature = "@" ~> ".+".r <~ nl
+ def validName = """[A-Za-z0-9_-]+""".r
- def literalText = """[\w ]+""".r ^^ { LiteralText(_) }
+ // def interpolatedText = """#{""" ~> """[^}]+""".r <~ """}""" ^^ Evaluated
+ def literalText = ("""(\\#)[^#]*""".r | """[^#\n\r]+""".r) ^^ LiteralText
- def tagName = """%\w+""".r ^^ { _.drop(1) }
- def tagId = """#[A-Za-z0-9_-]+""".r ^^ { _.drop(1) }
- def tagClass = """\.\w+""".r ^^ { _.drop(1) }
+ def text = rep1(literalText) ^^ Text //rep(interpolatedText | literalText) ^^ Text
+
+ def tagName = "%" ~> validName
+ def tagId = "#" ~> validName
+ def tagClass = "." ~> validName
def tagClasses = rep(tagClass)
- def tagAttributesKey = """\w+""".r
- def tagAttributesValue = "\"" ~> literalText <~ "\""
+ def tagAttributesKey = validName
+ def tagAttributesValue = "\"" ~> /*literalText*/validName <~ "\"" ^^ { s => Text(LiteralText(s) :: Nil) } // TODO!
def tagAttributes = "(" ~> rep(tagAttributesKey ~ ("=" ~> tagAttributesValue) <~ " *".r) <~ ")"
-
def tagStartingWithName: Parser[(Option[String], Option[String], List[String])] = (tagName ~ tagClasses ~ opt(tagId) ~ tagClasses) ^^ {
case name ~ classes1 ~ idOpt ~ classes2 => (Some(name), idOpt, classes1 ::: classes2)
}
@@ -56,7 +59,12 @@ object HamlParser extends IndentedParser {
Tag(nameOpt, idOpt, classes, attrs, autoclose.isDefined, contentOpt)
}
- def notTag = positioned(literalText)
+ def scalaExpression = """ *[^\n]+""".r
+
+ def evaluated = "=" ~> scalaExpression ^^ { e => Evaluated(e.dropWhile(' '==)) }
+ def statement = "-" ~> scalaExpression ^^ { e => Statement(e.dropWhile(' '==)) }
+
+ def notTag = positioned(evaluated | statement | text)
def element = positioned(tag | notTag)
def parser = opt(signature) ~ nestedBlocks(element) <~ rep(nl) ^^ {
View
44 naja-compiler/src/test/scala/naja/compiler/HamlParserSpec.scala
@@ -20,9 +20,15 @@ class ParserSpec extends Specification {
check("""""", Template("()", Nil))
}
- "Parse @signature" in {
+ "Parse empty signature" in {
check("""@()""", Template("()", Nil))
+ }
+
+ "Parse simple signature" in {
check("""@(a: Int)""", Template("(a: Int)", Nil))
+ }
+
+ "Parse more complicated signature" in {
check("""
|@(a: Int, b: String)(implicit ev: Ev[Int])
|
@@ -33,16 +39,16 @@ class ParserSpec extends Specification {
"Basic HAML" should {
"literal text" in {
- checkBody("""some text""", Node(LiteralText("some text")) :: Nil)
+ checkBody("""some text""", Node(Text(LiteralText("some text") :: Nil)) :: Nil)
checkBody("""
|some text
|on multiple
|lines
""",
- Node(LiteralText("some text")) ::
- Node(LiteralText("on multiple")) ::
- Node(LiteralText("lines")) ::
+ Node(Text(LiteralText("some text") :: Nil)) ::
+ Node(Text(LiteralText("on multiple") :: Nil)) ::
+ Node(Text(LiteralText("lines") :: Nil)) ::
Nil
)
}
@@ -111,7 +117,7 @@ class ParserSpec extends Specification {
}
"html attributes" in {
- checkBody("""%span(a="1" b="2")""", Node(Tag(Some("span"), attributes = Map("a" -> LiteralText("1"), "b" -> LiteralText("2")))) :: Nil)
+ checkBody("""%span(a="1" b="2")""", Node(Tag(Some("span"), attributes = Map("a" -> Text(LiteralText("1") :: Nil), "b" -> Text(LiteralText("2") :: Nil)))) :: Nil)
}
"autoclosed tag" in {
@@ -120,7 +126,31 @@ class ParserSpec extends Specification {
}
"tag with content" in {
- checkBody("""%span Some content""", Node(Tag(Some("span"), content = Some(LiteralText("Some content")))) :: Nil)
+ checkBody("""%span Some content""", Node(Tag(Some("span"), content = Some(Text(LiteralText("Some content") :: Nil)))) :: Nil)
+ }
+ }
+
+ "interpolated text" in {
+ checkBody(
+ """One plus two is #{1+2} yea! #{x} really""",
+ Node(Text(
+ LiteralText("One plus two is ") ::
+ InterpolatedText("1+2") ::
+ LiteralText(" yea! ") ::
+ InterpolatedText("x") ::
+ LiteralText("really") ::
+ Nil)
+ ) :: Nil
+ )
+ }.pendingUntilFixed
+
+ "print scala evaluated statement (= )" should {
+ "very simple statement" in {
+ checkBody("""= 1 + 2""", Node(Evaluated("1 + 2")) :: Nil)
}
}
}
+
+
+
+

0 comments on commit 70bf13d

Please sign in to comment.
Something went wrong with that request. Please try again.