Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Preparation for interpolated text

  • Loading branch information...
commit 70bf13db687ceed102f9141f5ae2b30176b0889e 1 parent cd4036c
Tymon Tobolski authored
10 naja-compiler/src/main/scala/naja/compiler/AST.scala
@@ -3,7 +3,12 @@ package naja.compiler
3 3 import scala.util.parsing.input.Positional
4 4
5 5 sealed trait Expr extends Positional
6   -case class LiteralText(content: String) extends Expr
  6 +sealed trait TextExpr extends Expr
  7 +
  8 +case class Text(content: List[TextExpr]) extends Expr
  9 +case class LiteralText(content: String) extends TextExpr
  10 +case class InterpolatedText(content: String) extends TextExpr
  11 +
7 12 case class Tag(name: Option[String],
8 13 id: Option[String] = None,
9 14 classes: List[String] = Nil,
@@ -12,5 +17,8 @@ case class Tag(name: Option[String],
12 17 content: Option[Expr] = None,
13 18 body: List[Expr] = Nil) extends Expr
14 19
  20 +case class Evaluated(content: String) extends Expr
  21 +case class Statement(content: String, body: List[Expr] = Nil) extends Expr
  22 +
15 23 case class Template(signature: String, body: List[Node])
16 24 case class Node(content: Expr, body: List[Node] = Nil)
24 naja-compiler/src/main/scala/naja/compiler/HamlParser.scala
@@ -24,18 +24,21 @@ trait IndentedParser extends RegexParsers {
24 24
25 25 object HamlParser extends IndentedParser {
26 26 def signature = "@" ~> ".+".r <~ nl
  27 + def validName = """[A-Za-z0-9_-]+""".r
27 28
28   - def literalText = """[\w ]+""".r ^^ { LiteralText(_) }
  29 + // def interpolatedText = """#{""" ~> """[^}]+""".r <~ """}""" ^^ Evaluated
  30 + def literalText = ("""(\\#)[^#]*""".r | """[^#\n\r]+""".r) ^^ LiteralText
29 31
30   - def tagName = """%\w+""".r ^^ { _.drop(1) }
31   - def tagId = """#[A-Za-z0-9_-]+""".r ^^ { _.drop(1) }
32   - def tagClass = """\.\w+""".r ^^ { _.drop(1) }
  32 + def text = rep1(literalText) ^^ Text //rep(interpolatedText | literalText) ^^ Text
  33 +
  34 + def tagName = "%" ~> validName
  35 + def tagId = "#" ~> validName
  36 + def tagClass = "." ~> validName
33 37 def tagClasses = rep(tagClass)
34   - def tagAttributesKey = """\w+""".r
35   - def tagAttributesValue = "\"" ~> literalText <~ "\""
  38 + def tagAttributesKey = validName
  39 + def tagAttributesValue = "\"" ~> /*literalText*/validName <~ "\"" ^^ { s => Text(LiteralText(s) :: Nil) } // TODO!
36 40 def tagAttributes = "(" ~> rep(tagAttributesKey ~ ("=" ~> tagAttributesValue) <~ " *".r) <~ ")"
37 41
38   -
39 42 def tagStartingWithName: Parser[(Option[String], Option[String], List[String])] = (tagName ~ tagClasses ~ opt(tagId) ~ tagClasses) ^^ {
40 43 case name ~ classes1 ~ idOpt ~ classes2 => (Some(name), idOpt, classes1 ::: classes2)
41 44 }
@@ -56,7 +59,12 @@ object HamlParser extends IndentedParser {
56 59 Tag(nameOpt, idOpt, classes, attrs, autoclose.isDefined, contentOpt)
57 60 }
58 61
59   - def notTag = positioned(literalText)
  62 + def scalaExpression = """ *[^\n]+""".r
  63 +
  64 + def evaluated = "=" ~> scalaExpression ^^ { e => Evaluated(e.dropWhile(' '==)) }
  65 + def statement = "-" ~> scalaExpression ^^ { e => Statement(e.dropWhile(' '==)) }
  66 +
  67 + def notTag = positioned(evaluated | statement | text)
60 68 def element = positioned(tag | notTag)
61 69
62 70 def parser = opt(signature) ~ nestedBlocks(element) <~ rep(nl) ^^ {
44 naja-compiler/src/test/scala/naja/compiler/HamlParserSpec.scala
@@ -20,9 +20,15 @@ class ParserSpec extends Specification {
20 20 check("""""", Template("()", Nil))
21 21 }
22 22
23   - "Parse @signature" in {
  23 + "Parse empty signature" in {
24 24 check("""@()""", Template("()", Nil))
  25 + }
  26 +
  27 + "Parse simple signature" in {
25 28 check("""@(a: Int)""", Template("(a: Int)", Nil))
  29 + }
  30 +
  31 + "Parse more complicated signature" in {
26 32 check("""
27 33 |@(a: Int, b: String)(implicit ev: Ev[Int])
28 34 |
@@ -33,16 +39,16 @@ class ParserSpec extends Specification {
33 39
34 40 "Basic HAML" should {
35 41 "literal text" in {
36   - checkBody("""some text""", Node(LiteralText("some text")) :: Nil)
  42 + checkBody("""some text""", Node(Text(LiteralText("some text") :: Nil)) :: Nil)
37 43
38 44 checkBody("""
39 45 |some text
40 46 |on multiple
41 47 |lines
42 48 """,
43   - Node(LiteralText("some text")) ::
44   - Node(LiteralText("on multiple")) ::
45   - Node(LiteralText("lines")) ::
  49 + Node(Text(LiteralText("some text") :: Nil)) ::
  50 + Node(Text(LiteralText("on multiple") :: Nil)) ::
  51 + Node(Text(LiteralText("lines") :: Nil)) ::
46 52 Nil
47 53 )
48 54 }
@@ -111,7 +117,7 @@ class ParserSpec extends Specification {
111 117 }
112 118
113 119 "html attributes" in {
114   - checkBody("""%span(a="1" b="2")""", Node(Tag(Some("span"), attributes = Map("a" -> LiteralText("1"), "b" -> LiteralText("2")))) :: Nil)
  120 + checkBody("""%span(a="1" b="2")""", Node(Tag(Some("span"), attributes = Map("a" -> Text(LiteralText("1") :: Nil), "b" -> Text(LiteralText("2") :: Nil)))) :: Nil)
115 121 }
116 122
117 123 "autoclosed tag" in {
@@ -120,7 +126,31 @@ class ParserSpec extends Specification {
120 126 }
121 127
122 128 "tag with content" in {
123   - checkBody("""%span Some content""", Node(Tag(Some("span"), content = Some(LiteralText("Some content")))) :: Nil)
  129 + checkBody("""%span Some content""", Node(Tag(Some("span"), content = Some(Text(LiteralText("Some content") :: Nil)))) :: Nil)
  130 + }
  131 + }
  132 +
  133 + "interpolated text" in {
  134 + checkBody(
  135 + """One plus two is #{1+2} yea! #{x} really""",
  136 + Node(Text(
  137 + LiteralText("One plus two is ") ::
  138 + InterpolatedText("1+2") ::
  139 + LiteralText(" yea! ") ::
  140 + InterpolatedText("x") ::
  141 + LiteralText("really") ::
  142 + Nil)
  143 + ) :: Nil
  144 + )
  145 + }.pendingUntilFixed
  146 +
  147 + "print scala evaluated statement (= )" should {
  148 + "very simple statement" in {
  149 + checkBody("""= 1 + 2""", Node(Evaluated("1 + 2")) :: Nil)
124 150 }
125 151 }
126 152 }
  153 +
  154 +
  155 +
  156 +

0 comments on commit 70bf13d

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