jejune 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+ #--
4
+ # Copyright (c) 2010-2011 Kyle C. Yetter
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #++
25
+
26
+
27
+ module Jejune::Data
28
+ define_string DOC, :outdent
29
+ define_string DDOC, :interpolate, :outdent
30
+ define_string STRING
31
+ define_string DSTRING, :interpolate
32
+
33
+ define_string( 'Q', :interpolate, :outdent )
34
+
35
+ define( 'q', :outdent => true ) do | manager, blob |
36
+ manager.jstring( blob.data, true )
37
+ end
38
+
39
+ define( 'w' ) do | manager, blob |
40
+ manager.split_words( blob.data ).to_json
41
+ end
42
+
43
+ define( 'embed' ) do | manager, blob |
44
+ lib = manager.string_value( blob.data )
45
+ path = manager.find_resource( lib, '', blob.delimiter == '<' ) ||
46
+ manager.find_library( lib, blob.delimiter == '<' )
47
+
48
+ manager.add_dependency( path )
49
+ content = path =~ /\.jjs$/i ? manager.load_file( path ).translate : File.read( path )
50
+ content.to_json
51
+ end
52
+
53
+ define( 'r' ) do | manager, blob |
54
+ data = blob.data
55
+ data.gsub!( /(\\*)(\s)/ ) { $1.length.even? ? $1 : $1[ 1, $1.length ] << $2 }
56
+ data.gsub!( %r(/), '\/' )
57
+ '/' << data << '/' << blob.flags
58
+ end
59
+
60
+ define( 'sass', :outdent => true ) do | manager, blob |
61
+ defined?( gem ) or require 'rubygems'
62
+ begin
63
+ gem 'sass'
64
+ rescue LoadError
65
+ end
66
+ require 'sass'
67
+
68
+ sass_source = manager.string_value( blob.data )
69
+ css = Sass.compile( sass_source )
70
+ blob.flags.include?( 'c' ) and css = manager.compress( css, 'css' )
71
+ manager.jstring( css )
72
+ end
73
+
74
+ define( 'loadSass' ) do | manager, blob |
75
+ lib = manager.string_value( blob.data )
76
+ path = manager.find_resource( lib, 'sass|scss|css|', blob.delimiter == '<' )
77
+ source = File.read( path )
78
+ manager.add_dependency( path )
79
+
80
+ defined?( gem ) or require 'rubygems'
81
+ begin
82
+ gem 'sass'
83
+ rescue LoadError
84
+ end
85
+ require 'sass'
86
+
87
+ css = Sass.compile( source )
88
+ blob.flags.include?( 'c' ) and css = manager.compress( css, 'css' )
89
+ manager.jstring( css )
90
+ end
91
+
92
+ define( 'y', :outdent => true ) do | manager, blob |
93
+ ::JSON.dump( ::YAML.load( blob.data ) )
94
+ end
95
+
96
+ define( 'loadYAML' ) do | manager, blob |
97
+ lib = manager.string_value( blob.data )
98
+ path = manager.find_resource( lib, 'yaml|yml|', blob.delimiter == '<' )
99
+ manager.add_dependency( path )
100
+ YAML.load_file( path ).to_json
101
+ end
102
+
103
+ define( 't', :outdent => true ) do | manager, blob |
104
+ require 'jejune/ejjs'
105
+ Jejune::EJJS.new( blob.data, :line => blob.line, :file => blob.file ).as_eval
106
+ end
107
+ end
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+ #--
4
+ # Copyright (c) 2010-2011 Kyle C. Yetter
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #++
25
+
26
+ module Jejune
27
+ module Constants
28
+ include TokenData
29
+
30
+ # pseudo-type used by the interpolation parser
31
+ CODE = PROGRAM
32
+
33
+ PROPERTY_DEFINITION_TYPES = Set[ GET, SET, COLON, ARROW ]
34
+ EXPRESSION_TYPES = Set[
35
+ AMP_ASGN, AND, AREF, ARRAY, ASGN, CALL, COLON, COMMA, DECR,
36
+ DELETE, DOT, EQ, EQQ, FALSE, GEQ, GREATER, HAT, HAT_ASGN,
37
+ ID, IN, INCR, INSTANCEOF, ITER, IVAR, LEQ, LESS, LSHIFT,
38
+ LSHIFT_ASGN, MINUS, MINUS_ASGN, MOD, MOD_ASGN, NEQ, NEQQ,
39
+ NEW, NOT, NULL, NUMBER, OBJECT, OR, PIPE, PIPE_ASGN, PLUS,
40
+ PLUS_ASGN, POST_DECR, POST_INCR, QMARK, REGEX, RSHIFT,
41
+ RSHIFT3, RSHIFT3_ASGN, RSHIFT_ASGN, SLASH, SLASH_ASGN, STAR,
42
+ STAR_ASGN, STRING, THIS, TILDE, TRUE, TYPEOF, UNDEFINED,
43
+ VOID, FUNCTION, ARROW, DSTRING, DDOC, DGENERAL, UPLUS, UMINUS
44
+ ]
45
+ PROPERTY_TYPES = Set[ STRING, ID, NUMBER ]
46
+
47
+ CATCH_TYPES = Set[ CATCH, FINALLY ]
48
+ FUNCTION_TYPES = Set[ ARROW, FUNCTION ]
49
+
50
+ OPERATOR_PRECEDENCE = Hash.new do | h, k |
51
+ name = TOKEN_NAMES[ k ] and
52
+ warn( "Jejune Token Type `#{ name }[#{ k }]' is not Jejune::Constants::OPERATOR_PRECEDENCE" )
53
+ h[ k ] = -1
54
+ end
55
+
56
+ op_list = <<-END
57
+ COMMA
58
+ ASGN AMP_ASGN HAT_ASGN LSHIFT_ASGN MINUS_ASGN MOD_ASGN OR_ASGN PIPE_ASGN PLUS_ASGN RSHIFT3_ASGN RSHIFT_ASGN SLASH_ASGN STAR_ASGN
59
+ QMARK
60
+ OR
61
+ AND
62
+ PIPE
63
+ HAT
64
+ AMP
65
+ EQ EQQ NEQ NEQQ
66
+ LESS GREATER LEQ GEQ INSTANCEOF IN
67
+ LSHIFT RSHIFT RSHIFT3
68
+ PLUS MINUS
69
+ STAR SLASH MOD
70
+ DELETE VOID TYPEOF INCR DECR UPLUS UMINUS TILDE NOT
71
+ POST_INCR POST_DECR
72
+ NEW CALL AREF DOT ITER
73
+ THIS IVAR ID NULL TRUE FALSE UNDEFINED STRING DOC REGEX ARRAY OBJECT FUNCTION
74
+ END
75
+
76
+ # use the list above to give each expression node
77
+ # a precedence number for use in situations such
78
+ # as determining whether code needs to be surrounded
79
+ # in parentheses to protect operator precedence in an expression
80
+ op_list.strip.split( $/ ).each_with_index do | line, index |
81
+ for name in line.strip.split( /\s+/ )
82
+ value = TokenData.const_get( name )
83
+ OPERATOR_PRECEDENCE[ value ] = index
84
+ end
85
+ end
86
+
87
+ DELIMS =
88
+ {
89
+ "@"=>"@", "+"=>"+", "`"=>"`", ","=>",", "!"=>"!", "-"=>"-",
90
+ "\""=>"\"", "."=>".", "#"=>"#", ":"=>":", "/"=>"/",
91
+ "$"=>"$", ";"=>";", "%"=>"%", "{"=>"}", "["=>"]", "|"=>"|",
92
+ "\\"=>"\\", "&"=>"&", "<"=>">", "="=>"=", "'"=>"'",
93
+ "~"=>"~", "^"=>"^", "("=>")", "?"=>"?", "*"=>"*"
94
+ }
95
+ OPEN_DELIM = /([#{ Regexp.escape( DELIMS.keys.join( '' ) ) }])/
96
+
97
+ DEFAULT_EXT = "jjs|js|"
98
+ BROWSERS = %w( opera firefox chrome )
99
+ end
100
+ end
101
+
102
+ module Jejune
103
+ include ANTLR3
104
+ RewriteStream = TokenRewriteStream
105
+ end
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ #--
5
+ # Copyright (c) 2010-2011 Kyle C. Yetter
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining
8
+ # a copy of this software and associated documentation files (the
9
+ # "Software"), to deal in the Software without restriction, including
10
+ # without limitation the rights to use, copy, modify, merge, publish,
11
+ # distribute, sublicense, and/or sell copies of the Software, and to
12
+ # permit persons to whom the Software is furnished to do so, subject to
13
+ # the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be
16
+ # included in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ #++
26
+
27
+ module Jejune
28
+ module Data
29
+ class Handler
30
+ include Constants
31
+ include Utils
32
+
33
+ attr_reader :type, :processor
34
+
35
+ def initialize( type, options = {}, &processor )
36
+ @type = type
37
+ @string = @outdent = @interpolate = false
38
+ @processor = nil
39
+ configure( options, &processor )
40
+ end
41
+
42
+ def configure( options, &processor )
43
+ @processor = processor || options.fetch( :processor, @processor )
44
+ @interpolate = options.fetch( :interpolate, @interpolate )
45
+ @outdent = options.fetch( :outdent, @outdent )
46
+ @string = options.fetch( :string, @string )
47
+ end
48
+
49
+ def process( manager, blob )
50
+ blob.data = prepare( manager, blob )
51
+ @processor and blob.data = @processor.call( manager, blob )
52
+ return( blob.data )
53
+ end
54
+
55
+ def prepare( manager, blob )
56
+ @interpolate and return manager.interpolate( blob, @outdent )
57
+ source = blob.data
58
+ @outdent and source = manager.outdent( source )
59
+ @string ? blob.delimiter == "'" ? manager.jstring( source, "'" ) : manager.jstring( source ) : source
60
+ end
61
+
62
+ end
63
+
64
+ unless defined?( Blob )
65
+ Blob = Struct.new(
66
+ :type, :data, :delimiter, :prefix,
67
+ :flags, :file, :line, :column
68
+ )
69
+ end
70
+
71
+ class Blob
72
+ include Constants
73
+
74
+ def self.extract( token, type = nil )
75
+ source = token.text
76
+ if source =~ /\A%?\s*(\w*\s*)/
77
+ prefix, source = $&, $'
78
+ signifier = $1.to_s.strip
79
+ type ||= signifier.empty? ? 'Q' : signifier
80
+ else
81
+ prefix = ''
82
+ end
83
+ source =~ OPEN_DELIM or raise( "%p doesn't have a delimiter" % source )
84
+ delimiter, source, closer = $&, $', DELIMS[ $1 ]
85
+
86
+ data, d, flags = source.rpartition( closer )
87
+ new(
88
+ type || delimiter, data,
89
+ delimiter, prefix, flags,
90
+ token.source_name, token.line, token.column
91
+ )
92
+ end
93
+
94
+ def inspect
95
+ '' << prefix << delimiter << data << DELIMS[ delimiter ] << flags
96
+ end
97
+
98
+ def data_column
99
+ column + prefix.length + delimiter.length
100
+ end
101
+ end
102
+
103
+ end
104
+ end
105
+
106
+
107
+ module Jejune
108
+ module Data
109
+ include Constants
110
+ defined?( @@global_handlers ) or @@global_handlers = {}
111
+
112
+ def self.define( type, options = {}, &action )
113
+ @@global_handlers[ type ] = Handler.new( type, options, &action )
114
+ end
115
+
116
+ def self.define_string( type, *opts )
117
+ options = { :string => true }
118
+ for opt in opts
119
+ options[ opt ] = true
120
+ end
121
+ define( type, options )
122
+ end
123
+
124
+
125
+ # lazy attribute reader for
126
+ def data_handlers
127
+ @data_handlers ||= {}
128
+ end
129
+
130
+ def define_handler( type, options = {}, &action )
131
+ @data_handler[ type ] = Handler.new( type, options, &action )
132
+ end
133
+
134
+ def handler_for( blob )
135
+ type = blob.type
136
+ data_handlers.fetch( type ) do
137
+ @@global_handlers.fetch( type ) do
138
+ raise( "no data handler defined for `#{ type }'" )
139
+ end
140
+ end
141
+ end
142
+
143
+ end
144
+ end
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+ #
4
+ # author: Kyle Yetter
5
+ #
6
+
7
+ module Jejune
8
+ class DependencyScanner
9
+ include Constants
10
+ include Utils
11
+
12
+ attr_accessor :manager, :dependency_map, :file_stack, :file
13
+
14
+ def initialize( manager )
15
+ @manager = manager
16
+ @dependency_map = {}
17
+ @file_stack = []
18
+ end
19
+
20
+ def dependencies
21
+ out = {}
22
+ for path, set in @dependency_map
23
+ out[ path ] = set.to_a.sort
24
+ end
25
+ return out
26
+ end
27
+
28
+ def scan( file )
29
+ file = File.expand_path( file )
30
+ deps = @dependency_map[ file ] and return( deps )
31
+
32
+ deps = Set.new
33
+ dir = File.dirname( file )
34
+
35
+ open( file ) do | f |
36
+ f.grep( /^\s*%%\s*(include|require)\s*(\S.*)/ ) do
37
+ type, target = $1, $2.strip
38
+ case type
39
+ when 'require'
40
+ if dep = find_in_path_list( @manager.load_path, target, DEFAULT_EXT )
41
+ deps.add File.expand_path( dep )
42
+ end
43
+ when 'include'
44
+ if dep = find_in_directory( dir, target, DEFAULT_EXT )
45
+ deps.add File.expand_path( dep )
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ @dependency_map[ file ] = deps
52
+ @file_stack.each do | f |
53
+ @dependency_map[ file ].merge( deps )
54
+ end
55
+
56
+ begin
57
+ @file_stack.push( file )
58
+ deps.grep( /\.jjs$/i ) do | child |
59
+ scan( child )
60
+ end
61
+ ensure
62
+ @file_stack.pop
63
+ end
64
+
65
+ return deps
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+ #--
4
+ # Copyright (c) 2010-2011 Kyle C. Yetter
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #++
25
+
26
+ #require 'jejune/lo-fi-lexer'
27
+
28
+ module Jejune
29
+ class EJJS
30
+
31
+ #class Lexer < LoFiLexer::StatefulLexer
32
+ # state :line_start, :go_to => :template do
33
+ # rule( :indentation, /[^\n\r]+?(?=%\|)/ )
34
+ # rule( :comment_line, /(?:[^\n\r%\\]|\\[^\n\r])*%#([\n\r]*)\r?\n/, :text => 1 )
35
+ # delimited( :insert_indented, /%\|=?/, /\r?\n|\z/, :text => :body )
36
+ # delimited( :control_line, '%', /\r?\n|\z/, :text => :body )
37
+ # end
38
+ #
39
+ # state :template do
40
+ # rule( :newline, /\r?\n/, :go_to => :line_start )
41
+ # delimited( :comment, '<%#', '%>', :text => :body )
42
+ # delimited( :insert, '<%=', '%>', :text => :body )
43
+ # delimited( :control, '<%', '%>', :text => :body )
44
+ # rule( :literal, /(?:[^\r\n\\<]|\\[^\r\n]|<(?!%)|\\)+(?=<%|\r?\n|\z)/ )
45
+ # end
46
+ #end # class Lexer
47
+
48
+ module Compile
49
+ module_function
50
+
51
+ def scan( source, options = {} )
52
+ block_given? or return( enum_for( :scan, source, options ) )
53
+
54
+ s = SourceScanner.new( source, options )
55
+ line_start = true
56
+ until s.eos?
57
+ if line_start
58
+ case
59
+ when s.scan( %r< % \# ((?: [^\\\r\n]+ | \\ \r? \n | \\ . )*) (?: \r? \n | \z ) >x )
60
+ yield( :comment_line, s[ 1 ] )
61
+ when s.scan( %r< % ((?: [^\\\r\n]+ | \\ \r? \n | \\ . )*) (?: \r? \n | \z ) >x )
62
+ yield( :control_line, s[ 1 ] )
63
+ else
64
+ line_start = false
65
+ end
66
+ else
67
+ case
68
+ when s.scan( /\r?\n/ )
69
+ line_start = true
70
+ yield( :newline, s.matched )
71
+ when m = s.nested!( '<%#', '%>' )
72
+ content = m[ 3, m.length - 5 ].to_s
73
+ yield( :comment, content )
74
+ when m = s.nested!( '<%=', '%>' )
75
+ content = m[ 3, m.length - 5 ].to_s
76
+ yield( :insert, content )
77
+ when m = s.nested!( '<%', '%>' )
78
+ content = m[ 2, m.length - 4 ].to_s
79
+ yield( :control, content )
80
+ when s.scan( /(?:[^\r\n\\<]|\\[^\r\n]|<(?!%)|\\)+(?=<%|\r?\n|\z)/ )
81
+ text = s.matched
82
+ yield( :literal, text )
83
+ end
84
+ end
85
+
86
+
87
+ end
88
+ end
89
+
90
+ def compile( source, options = {} )
91
+ #lexer = Lexer.new( source.to_s, options )
92
+ var = options.fetch( :variable, '__data__' )
93
+ lines = []
94
+ line = []
95
+ indentation = ''
96
+ previous = nil
97
+ clear_line = false
98
+
99
+ scan( source, options ) do | type, text |
100
+ case type
101
+ when :literal
102
+ line << %(#{ var }.push( #{ str( text ) } ))
103
+ when :comment_line
104
+ line << "//" << text
105
+ clear_line = true
106
+ when :insert
107
+ line << %[#{ var }.push( #{ text } )]
108
+ when :newline
109
+ line << %[#{ var }.push( #{ str( text ) } )]
110
+ clear_line = true
111
+ when :control
112
+ line << text
113
+ when :control_line
114
+ line << text
115
+ clear_line = true
116
+ else
117
+ raise( "BUG: unknown token type `#{ type }' -- this shouldn't happen" )
118
+ end
119
+
120
+ if clear_line
121
+ lines << line.join( '; ' )
122
+ line = []
123
+ indentation = ''
124
+ clear_line = false
125
+ end
126
+ #previous = token.type
127
+ end
128
+
129
+ lines << line.join( '; ' )
130
+ return lines.join( "\n" )
131
+ end
132
+
133
+ def str( text )
134
+ JString.jstring( text )
135
+ end
136
+
137
+ end # module Compile
138
+
139
+ include Compile
140
+
141
+ attr_accessor :file, :line, :source, :parameters, :variable, :name, :js_body
142
+
143
+ def initialize( source, options = nil )
144
+ @source = source
145
+ if options
146
+ @variable = options.fetch( :variable, '__text__' )
147
+ @file = options.fetch( :file, '(erb)' )
148
+ @line = options.fetch( :line, 1 )
149
+ @name = options[ :name ]
150
+ @parameters = options[ :parameters ]
151
+ else
152
+ @variable = '__text__'
153
+ @file = '(ejs)'
154
+ @line = 1
155
+ @name = nil
156
+ @parameters = nil
157
+ end
158
+ jjs_output = compile( source, :variable => @variable, :file => @file, :line => @line )
159
+ @js_body = Jejune.translate( jjs_output, :file => @file, :line => @line )
160
+ end
161
+
162
+ def as_eval
163
+ "(#{ as_function })()"
164
+ end
165
+
166
+ def as_function
167
+ code = "function"
168
+ @name and code << " " << @name
169
+ code << ( @parameters ? @parameters.declaration : '()' )
170
+ code << " { var #{ @variable } = []; "
171
+ @parameters and code << @parameters.parsing_source
172
+ code << @js_body << "; "
173
+ code << "return #{ @variable }.join( '' ) }"
174
+ return code
175
+ end
176
+
177
+ end
178
+ end