Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added script and style tags like similar to slim #17

Merged
merged 1 commit into from Apr 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 43 additions & 2 deletions README.md
Expand Up @@ -48,24 +48,42 @@ end
doctype html
html
head
meta name="viewport" content="width=device-width,initial-scale=1.0"
title This is a title
css:
h1 {color: red;}
p {color: green;}
style h2 {color: blue;}
body
/ Multi-line comment
span this is wrapped in a comment
/[if IE]
p Dat browser is old.
h1 This is a slang file
h2 This is blue
span#some-id.classname
#hello.world.world2
- some_var = "hello world haha"
span
span data-some-var=some_var two-attr="fun" and a #{p("hello")}
span
span.deep_nested
p
| text inside of <p>
= Process.pid
| text node
' other text node
span.alongside pid=Process.pid
custom-tag#with-id pid="#{Process.pid}"
- ["ah", "oh"].each do |s|
span = s

/ This is an invisible comment
#amazing-div some-attr="hello"
/! This is a visible comment
script var num1 = 8*4;

javascript:
var num2 = 8*3;
```

Given the context:
Expand All @@ -81,18 +99,35 @@ Compiles to HTML:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>This is a title</title>
<style>
h1 {color: red;}
p {color: green;}
</style>
<style>h2 {color: blue;}</style>
</head>
<body>
<!--Multi-line comment
<span>this is wrapped in a comment</span>
-->
<!--[if IE]>
<p>Dat browser is old.</p>
<![endif]-->
<h1>This is a slang file</h1>
<h2>This is blue</h2>
<span id="some-id" class="classname">
<div id="hello" class="world world2">
<span>
<span data-some-var="hello world haha" two-attr="fun">and a hello</span>
<span>
<span class="deep_nested">
<p>
text inside of &lt;p&gt;
</p>
#{Process.pid}
text node
other text node
other text node
</span>
</span>
</span>
Expand All @@ -105,6 +140,12 @@ Compiles to HTML:
</div>
</span>
<div id="amazing-div" some-attr="hello"></div>
<!--This is a visible comment-->
<script>var num1 = 8*4;</script>
<script>
var num2 = 8*3;
alert("8 * 3 + 8 * 4 = " + (num1 + num2);
</script>
</body>
</html>
```
Expand Down
15 changes: 14 additions & 1 deletion spec/fixtures/basic.slang
Expand Up @@ -3,18 +3,26 @@ html
head
meta name="viewport" content="width=device-width,initial-scale=1.0"
title This is a title
css:
h1 {color: red;}
p {color: green;}
style h2 {color: blue;}
body
/ Multi-line comment
span this is wrapped in a comment
/[if IE]
p Dat browser is old.
h1 This is a slang file
h2 This is blue
span#some-id.classname
#hello.world.world2
- some_var = "hello world haha"
span
span data-some-var=some_var two-attr="fun" and a #{p("hello")}
span
span.deep_nested
p
| text inside of <p>
= Process.pid
| text node
' other text node
Expand All @@ -24,4 +32,9 @@ html
span = s
/ This is an invisible comment
#amazing-div some-attr="hello"
/! This is a visible comment
/! This is a visible comment
script var num1 = 8*4;

javascript:
var num2 = 8*3;
alert("8 * 3 + 8 * 4 = " + (num1 + num2);
2 changes: 1 addition & 1 deletion spec/fixtures/output.slang
@@ -1,2 +1,2 @@
div
= p "hello"
= p "hello"
5 changes: 5 additions & 0 deletions spec/fixtures/script.slang
@@ -0,0 +1,5 @@
javascript:
var num = 8*3;
console.log(num);

script var num = 8*4;
4 changes: 4 additions & 0 deletions spec/fixtures/style.slang
@@ -0,0 +1,4 @@
css:
h1 {color:red;}
p {color:blue;}
style h2 {color:green;}
39 changes: 39 additions & 0 deletions spec/slang_spec.cr
Expand Up @@ -9,6 +9,11 @@ describe Slang do
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>This is a title</title>
<style>
h1 {color: red;}
p {color: green;}
</style>
<style>h2 {color: blue;}</style>
</head>
<body>
<!--Multi-line comment
Expand All @@ -17,12 +22,17 @@ describe Slang do
<!--[if IE]>
<p>Dat browser is old.</p>
<![endif]-->
<h1>This is a slang file</h1>
<h2>This is blue</h2>
<span id="some-id" class="classname">
<div id="hello" class="world world2">
<span>
<span data-some-var="hello world haha" two-attr="fun">and a hello</span>
<span>
<span class="deep_nested">
<p>
text inside of &lt;p&gt;
</p>
#{Process.pid}
text node
other text node
Expand All @@ -39,6 +49,11 @@ describe Slang do
</span>
<div id="amazing-div" some-attr="hello"></div>
<!--This is a visible comment-->
<script>var num1 = 8*4;</script>
<script>
var num2 = 8*3;
alert("8 * 3 + 8 * 4 = " + (num1 + num2);
</script>
</body>
</html>
HTML
Expand Down Expand Up @@ -216,4 +231,28 @@ describe Slang do
HTML
end
end

describe "raw text" do
it "renders javascript" do
res = render_file "spec/fixtures/script.slang"
res.should eq <<-HTML
<script>
var num = 8*3;
console.log(num);
</script>
<script>var num = 8*4;</script>
HTML
end

it "renders stylesheets" do
res = render_file "spec/fixtures/style.slang"
res.should eq <<-HTML
<style>
h1 {color:red;}
p {color:blue;}
</style>
<style>h2 {color:green;}</style>
HTML
end
end
end
22 changes: 18 additions & 4 deletions src/slang/lexer.cr
@@ -1,5 +1,6 @@
module Slang
class Lexer
RAWSTUFF = {"javascript:": "script", "css:": "style"}
getter token

def initialize(string)
Expand All @@ -8,16 +9,20 @@ module Slang
@line_number = 1
@column_number = 1
@last_token = @token
@raw_text_column = 0
end

def next_token
skip_whitespace

@token = Token.new
@token.line_number = @line_number
@token.column_number = @column_number

inline = @last_token.type == :ELEMENT && @last_token.line_number == @line_number
if @raw_text_column > 0 && @column_number < @raw_text_column
@raw_text_column = 0
end

inline = @raw_text_column > 0 || (@last_token.type == :ELEMENT && @last_token.line_number == @line_number)

case current_char
when '\0'
Expand Down Expand Up @@ -51,7 +56,7 @@ module Slang
end
end

@token.inline = inline
@token.inline = inline unless @raw_text_column > 0
@last_token = @token
@token
end
Expand Down Expand Up @@ -101,7 +106,7 @@ module Slang
end

private def consume_element_name
@token.name = consume_html_valid_name
@token.name = check_raw_text_header(consume_html_valid_name)
if @token.name == "doctype"
@token.type = :DOCTYPE
next_char if current_char == ' '
Expand Down Expand Up @@ -135,6 +140,15 @@ module Slang
end
end

private def check_raw_text_header(name : String)
if RAWSTUFF.has_key?(name)
@raw_text_column = (@column_number - name.size) + 2
RAWSTUFF[name]
else
name
end
end

private def consume_comment
@token.type = :COMMENT
next_char
Expand Down
6 changes: 5 additions & 1 deletion src/slang/node.cr
@@ -1,7 +1,7 @@
module Slang
abstract class Node
getter :parent, :token
delegate :value, :column_number, :line_number, :escaped, :inline, to: @token
delegate :value, :column_number, :line_number, :name, :escaped, :inline, to: @token

def initialize(@parent : Node, @token : Token)
end
Expand All @@ -14,6 +14,10 @@ module Slang
nodes.size > 0
end

def allow_children_to_escape?
true
end

def document?
false
end
Expand Down
6 changes: 5 additions & 1 deletion src/slang/nodes/element.cr
Expand Up @@ -2,7 +2,7 @@ module Slang
module Nodes
class Element < Node
SELF_CLOSING_TAGS = ["area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "menuitem", "meta", "param", "source", "track", "wbr"]
RAW_TEXT_TAGS = ["script", "style"]
RAW_TEXT_TAGS = %w(script style)

delegate :name, :id, :attributes, to: @token

Expand All @@ -11,6 +11,10 @@ module Slang
names.join(" ")
end

def allow_children_to_escape?
!RAW_TEXT_TAGS.includes?(name)
end

def to_s(str, buffer_name)
str << "#{buffer_name} << \"\n\"\n" unless str.empty?
str << "#{buffer_name} << \"#{indentation}\"\n" if indent?
Expand Down
2 changes: 1 addition & 1 deletion src/slang/nodes/text.cr
Expand Up @@ -5,7 +5,7 @@ module Slang
str << "#{buffer_name} << \"\n\"\n" unless str.empty? || inline
str << "#{buffer_name} << \"#{indentation}\"\n" if indent?
str << "#{buffer_name} << "
if escaped
if escaped && parent.not_nil!.allow_children_to_escape?
str << "HTML.escape((#{value}).to_s)"
else
str << "(#{value})"
Expand Down
2 changes: 0 additions & 2 deletions src/slang/parser.cr
@@ -1,6 +1,5 @@
module Slang
class Parser

@current_node : Node

def initialize(string)
Expand All @@ -14,7 +13,6 @@ module Slang
def parse(io_name = Slang::DEFAULT_BUFFER_NAME)
String.build do |str|
loop do
# puts token.inspect
case token.type
when :EOF
break
Expand Down
1 change: 0 additions & 1 deletion src/slang/token.cr
Expand Up @@ -33,6 +33,5 @@ module Slang
@attributes[name] = value
end
end

end
end