w2tags 0.9.3
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.
- data/COPYING +340 -0
- data/LICENSE +6 -0
- data/MIT-LICENSE +18 -0
- data/Manifest.txt +95 -0
- data/README.rdoc +264 -0
- data/Rakefile +23 -0
- data/VERSION +1 -0
- data/bin/w2tags +143 -0
- data/doc/ERB.HOT.rdoc +82 -0
- data/doc/FAQ.rdoc +81 -0
- data/doc/HAML.rdoc +310 -0
- data/doc/HOT.rdoc +137 -0
- data/doc/History.rdoc +757 -0
- data/doc/W2TAGS.rdoc +150 -0
- data/example/common.hot +11 -0
- data/example/from_readme.erb +78 -0
- data/example/from_readme.w2erb +64 -0
- data/example/from_w2tags.erb +32 -0
- data/example/from_w2tags.w2erb +32 -0
- data/example/rails_basic.hot +10 -0
- data/hot/erb.hot +156 -0
- data/hot/erb_form.hot +42 -0
- data/hot/erb_head.hot +15 -0
- data/hot/erb_jquery.hot +8 -0
- data/hot/erb_merb.hot +12 -0
- data/hot/erb_table.hot +43 -0
- data/hot/html.hot +31 -0
- data/hot/jquery.hot +88 -0
- data/hot/nvelocity.hot +23 -0
- data/hot/rails/sc_zebra.hot +10 -0
- data/hot/rails/scaffold.hot +15 -0
- data/hot/vm.hot +9 -0
- data/hot/vm2.hot +34 -0
- data/hot/vm_crud.hot +34 -0
- data/hot/vm_popup.hot +74 -0
- data/hot/xul.hot +114 -0
- data/lib/w2tags/block/plain_text.rb +57 -0
- data/lib/w2tags/block/remark.rb +37 -0
- data/lib/w2tags/block/sass.rb +66 -0
- data/lib/w2tags/merb_hook.rb +15 -0
- data/lib/w2tags/parser.rb +975 -0
- data/lib/w2tags/rails_hook.rb +15 -0
- data/lib/w2tags/sinatra_hook.rb +50 -0
- data/lib/w2tags.rb +100 -0
- data/plugins//w2tags//README +2 -0
- data/plugins//w2tags//generators//w2scaffold//USAGE +29 -0
- data/plugins//w2tags//generators//w2scaffold//templates//controller.rb +85 -0
- data/plugins//w2tags//generators//w2scaffold//templates//functional_test.rb +45 -0
- data/plugins//w2tags//generators//w2scaffold//templates//helper.rb +2 -0
- data/plugins//w2tags//generators//w2scaffold//templates//helper_test.rb +4 -0
- data/plugins//w2tags//generators//w2scaffold//templates//layout.html.erb +17 -0
- data/plugins//w2tags//generators//w2scaffold//templates//style.css +54 -0
- data/plugins//w2tags//generators//w2scaffold//templates//view_edit.html.erb +18 -0
- data/plugins//w2tags//generators//w2scaffold//templates//view_edit.html.w2erb +17 -0
- data/plugins//w2tags//generators//w2scaffold//templates//view_index.html.erb +24 -0
- data/plugins//w2tags//generators//w2scaffold//templates//view_index.html.w2erb +14 -0
- data/plugins//w2tags//generators//w2scaffold//templates//view_new.html.erb +17 -0
- data/plugins//w2tags//generators//w2scaffold//templates//view_new.html.w2erb +16 -0
- data/plugins//w2tags//generators//w2scaffold//templates//view_show.html.erb +10 -0
- data/plugins//w2tags//generators//w2scaffold//templates//view_show.html.w2erb +9 -0
- data/plugins//w2tags//generators//w2scaffold//w2scaffold_generator.rb +106 -0
- data/plugins//w2tags//install.rb +1 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/w2tags_spec.rb +8 -0
- data/tasks/ann.rake +81 -0
- data/tasks/bones.rake +21 -0
- data/tasks/gem.rake +126 -0
- data/tasks/git.rake +41 -0
- data/tasks/manifest.rake +49 -0
- data/tasks/notes.rake +28 -0
- data/tasks/post_load.rake +39 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +57 -0
- data/tasks/setup.rb +268 -0
- data/tasks/spec.rake +55 -0
- data/tasks/svn.rake +48 -0
- data/tasks/test.rake +38 -0
- data/test/enlightning.hot +3 -0
- data/test/feature.hot +28 -0
- data/test/parser_test.rb +203 -0
- data/test/tricky.hot +8 -0
- data/test/vars.hot +30 -0
- data/test/w2tags_basic_usability.rb +187 -0
- data/test/w2tags_enlightning.rb +42 -0
- data/test/w2tags_form.rb +32 -0
- data/test/w2tags_hot.rb +85 -0
- data/test/w2tags_hot_var.rb +115 -0
- data/test/w2tags_no_parsing.rb +37 -0
- metadata +163 -0
@@ -0,0 +1,975 @@
|
|
1
|
+
module W2Tags
|
2
|
+
# Copyright (c) 2008 - 2009 Widi Harsojo
|
3
|
+
class Parser
|
4
|
+
attr_accessor :silent
|
5
|
+
#change debuging ex: obj.dbg[:parse] = true
|
6
|
+
attr_accessor :dbg
|
7
|
+
#set extention for ext auto loading HOT files
|
8
|
+
attr_accessor :ext
|
9
|
+
attr_reader :spc
|
10
|
+
|
11
|
+
block= ::W2Tags::Block.constants
|
12
|
+
include *(block.collect{|m|eval("::W2Tags::Block::#{m.to_s}")})
|
13
|
+
#initiall create instance object, default if no arguments will be
|
14
|
+
#target for html
|
15
|
+
def initialize(ext = 'html')
|
16
|
+
@dbg={
|
17
|
+
:hot =>nil,
|
18
|
+
:stack =>nil,
|
19
|
+
:parse =>nil,
|
20
|
+
:constanta=>nil
|
21
|
+
}
|
22
|
+
|
23
|
+
#regex for w2tags
|
24
|
+
@rg_tag = [
|
25
|
+
/^[ \t]*(%)([!]?[\w\-&\/:#.]+\{.*\}[=]*)!([^\n]*)\n/,
|
26
|
+
/^[ \t]*(%)([!]?[\w\-&\/:#.=]+)!([^\n]*)([\n])/]
|
27
|
+
|
28
|
+
#regex for function tags
|
29
|
+
@rg_hot = [
|
30
|
+
/(%)([!]?[ \t\$\w\-&\/:#.%=]+\{.*\}[=]*)~([^\n]*)\n/,
|
31
|
+
/(%)([!]?[ \t\$\w\-&\/:#.%=]+)~([^\n]*)\n/ ]
|
32
|
+
@rgx = nil #current regular expression
|
33
|
+
@ext = ext #target extension
|
34
|
+
@hot = 'hot' #source of file hot
|
35
|
+
@w2x = 'w2x' #source file to include
|
36
|
+
@src_path= '' #path for source file
|
37
|
+
@silent = false #for test
|
38
|
+
|
39
|
+
@spc = '' #current begining space of current source line
|
40
|
+
@ind = ' ' #indentation size
|
41
|
+
@row = 'row' #current source line
|
42
|
+
@key = 'key' #key extracted from regex function
|
43
|
+
|
44
|
+
@mem_hot= nil #@tg_nex will be use (for "%") if this var == nil
|
45
|
+
@mem_tag= {'^'=>"%div$*!"} #get memorize of w2tag
|
46
|
+
@mem_var= {'$me'=>"wharsojo"}
|
47
|
+
@mem_var['$basepath'] = File.basename(File.expand_path('.'))
|
48
|
+
|
49
|
+
@tg_hot = {} #{'div'=>[proc{|this|"%div$*!"},nil]} #collection of tag_hot after reading from source hot
|
50
|
+
@tg_nex = {} #tag next activate on shortcut tag "%"
|
51
|
+
@tg_end = [] #momorize tag end from regex function
|
52
|
+
@doc_src= []
|
53
|
+
@doc_out= []
|
54
|
+
|
55
|
+
@tg_nex['html' ]= [0,proc { @mem_tag["^"] = "%head $*\n"}]
|
56
|
+
@tg_nex['head' ]= [0,proc { @mem_tag["^"] = "%body $*\n"}]
|
57
|
+
@tg_nex['ol' ]= [0,proc { @mem_tag["^"] = "%li $0\n" }]
|
58
|
+
@tg_nex['ul' ]= [0,proc { @mem_tag["^"] = "%li $0\n" }]
|
59
|
+
@tg_nex['dl' ]= [0,proc { @mem_tag["^"] = "%dt $0\n" }]
|
60
|
+
@tg_nex['dd' ]= [0,proc { @mem_tag["^"] = "%dt $0\n" }]
|
61
|
+
@tg_nex['form' ]= [0,proc { @mem_tag["^"] = "%input $0\n"}]
|
62
|
+
@tg_nex['select']= [0,proc { @mem_tag["^"] = "%option $0\n"}]
|
63
|
+
@tg_nex['table' ]= [0,proc { @tg_nex['tr'][0]= 0 }]
|
64
|
+
@tg_nex['tr' ]= [0,proc {
|
65
|
+
@tg_nex['tr' ][0]+= 1
|
66
|
+
if @tg_nex['tr'][0]== 1
|
67
|
+
@mem_tag["^"] = "%th $0\n"
|
68
|
+
else
|
69
|
+
@mem_tag["^"] = "%td $0\n"
|
70
|
+
end
|
71
|
+
}]
|
72
|
+
|
73
|
+
@tagr = proc do |this|
|
74
|
+
@key.strip!
|
75
|
+
tags_created = "<#{@key}"
|
76
|
+
tags_created << " #{@mem_var["*all*"].strip}" if @mem_var["*all*"]!=''
|
77
|
+
#tags_created << " #{@att}" if @att!=''
|
78
|
+
if @txt=='/'
|
79
|
+
tags_created << "/>\n"
|
80
|
+
else
|
81
|
+
tags_created << '>'
|
82
|
+
@ln_end = " "
|
83
|
+
if @txt==''
|
84
|
+
@tg_end.push "#{@spc}</#{@key}>#{@ln_end}"
|
85
|
+
p "Stack: #{@tg_end}" if @dbg[:stack]
|
86
|
+
else
|
87
|
+
if @txt.gsub!(/\<$/,'')
|
88
|
+
@tg_end.push "#{@spc}</#{@key}>#{@ln_end}"
|
89
|
+
else
|
90
|
+
@ln_end = "</#{@key}>#{@ln_end}"
|
91
|
+
end
|
92
|
+
if @mem_var["*code*"] && @mem_var["*code*"]!=''
|
93
|
+
tags_created << @mem_var["*code*"].gsub('$*',@txt)
|
94
|
+
else
|
95
|
+
tags_created << @txt.gsub(/^ +/,'') #remove gsub if don't want auto trim left
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
tags_created
|
100
|
+
end
|
101
|
+
@skiper= []
|
102
|
+
public_methods.each do |f|
|
103
|
+
send(f) if /_initialize$/ =~ (meth= f.to_s)
|
104
|
+
@skiper << [$1,'_skip'].join.to_sym if /(.*)_skip$/ =~ meth
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
#parsing from fullpath source to the fullpath target/result
|
109
|
+
#with the option of auto add 'initialize' and 'finalize'
|
110
|
+
#for source file in w2tags only fill with LF it will not
|
111
|
+
#translate, since behaviour for "\n\n\n".split("\n")
|
112
|
+
#will result in empty array
|
113
|
+
#if hot available it will add w2tags in:
|
114
|
+
#firstline with @initialize()
|
115
|
+
#lastline with @finalize()
|
116
|
+
#to not add, supply this function with init_start=false
|
117
|
+
#ex: parsing("t.w2tst","t.tst",false)
|
118
|
+
def parsing(src,tgt,init_start=true)
|
119
|
+
puts ">>#{src}"
|
120
|
+
puts ">>#{tgt}"
|
121
|
+
parse_init
|
122
|
+
@src_path= File.dirname(src)
|
123
|
+
@doc_src = IO.read(src).delete("\r").split("\n")
|
124
|
+
@doc_src<< "%finallize" if @tg_hot['finallize' ]
|
125
|
+
|
126
|
+
while (@row = @doc_src.shift) do #;p "row:#{@row}"
|
127
|
+
if init_start && !(/!hot!/ =~ @row)
|
128
|
+
@doc_src,@row = [[@row]+@doc_src,"%initialize"] if @tg_hot['initialize']
|
129
|
+
p "HEAD:#{init_start}"
|
130
|
+
init_start = false
|
131
|
+
end
|
132
|
+
parse_row
|
133
|
+
end
|
134
|
+
if @dbg[:constanta]
|
135
|
+
p "const_ "
|
136
|
+
@mem_var.keys.sort.each {|k|p "#{k.ljust 10} : #{@mem_var[k]}"}
|
137
|
+
end
|
138
|
+
|
139
|
+
if @dbg[:hot]
|
140
|
+
@tg_hot.keys.sort.each_with_index do |v,i|
|
141
|
+
puts "hot keys: #{i}. #{v}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
open(tgt,'w') do |f|
|
146
|
+
@doc_out.each do |row|
|
147
|
+
f << row
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
#it use to clean all the definition and reloading the hot file
|
154
|
+
def parse_init
|
155
|
+
@tg_end = [] #momorize tag end from regex function
|
156
|
+
@doc_src = []
|
157
|
+
@doc_out = []
|
158
|
+
@tg_hot = {}
|
159
|
+
merge_tags
|
160
|
+
end
|
161
|
+
|
162
|
+
#to test parsing on source line and return will be the result,
|
163
|
+
#everytime it execude, it clean up and reloading the HOT files.
|
164
|
+
def parse_line row,init=true
|
165
|
+
parse_init if init
|
166
|
+
dbg[:parse]= false
|
167
|
+
@doc_src = row.delete("\r").split("\n") << ",/"
|
168
|
+
while (@row= @doc_src.shift) do #;p "row:#{@row}"
|
169
|
+
parse_row
|
170
|
+
end
|
171
|
+
@doc_out
|
172
|
+
end
|
173
|
+
|
174
|
+
#the actual parsing on row, but it use for parsing the files not to
|
175
|
+
#test the source line, since some of the row have a command that
|
176
|
+
#has effect on source, result and the row will be empty, please use
|
177
|
+
#parse_line if you want to test interactively on IRB.
|
178
|
+
def parse_row row=nil
|
179
|
+
@row = row if row
|
180
|
+
@row<<"\n" #;p "row:#{@row}"
|
181
|
+
p "_____> #{@row}" if @dbg[:parse] && @plt == 99 && @rmk == 99
|
182
|
+
|
183
|
+
parse_spc
|
184
|
+
|
185
|
+
@ln_end = "" #imediate ends tag
|
186
|
+
@row.gsub!(/\\\\/,'') #esc char \\
|
187
|
+
@row.gsub!('\}','') #esc char \)
|
188
|
+
@row.gsub!('\;','') #esc char \;
|
189
|
+
while (parse_all) do; end
|
190
|
+
@row.gsub!('','\\')
|
191
|
+
@row.gsub!('','}')
|
192
|
+
@row.gsub!('',';')
|
193
|
+
if @ln_end!=""
|
194
|
+
@row.gsub!(/([\n\t ]*$)/,'')
|
195
|
+
@row << "#{@ln_end.strip}\n"
|
196
|
+
end
|
197
|
+
if @row.strip!=""
|
198
|
+
p "#####> #{@row}" if @dbg[:parse]
|
199
|
+
@doc_out << @row.rstrip+"\n"
|
200
|
+
end
|
201
|
+
@row
|
202
|
+
end
|
203
|
+
|
204
|
+
#parse one w2tags, result will be name of the target file created
|
205
|
+
def parse_file(src,init_start=true,chk_date=false)
|
206
|
+
tgt,@ext = [src[/(.+\.)w2(\w+)$/,1]<<$2,$2]
|
207
|
+
|
208
|
+
return nil if !File.exist?(src) #p "src: #{src} not found..."
|
209
|
+
if chk_date && File.exist?(tgt)
|
210
|
+
return nil if File.mtime(src) <= File.mtime(tgt)
|
211
|
+
end
|
212
|
+
|
213
|
+
puts "\nParsing W2Tags File:#{src}"
|
214
|
+
parsing(src,tgt,init_start)
|
215
|
+
tgt
|
216
|
+
end
|
217
|
+
|
218
|
+
#parse multiple w2tags files, result will be array of target file created
|
219
|
+
def parse_files(srcs,init_start=true)
|
220
|
+
srcs.collect do |src|
|
221
|
+
src.gsub!(/\n/,'')
|
222
|
+
parse_file(src,init_start)
|
223
|
+
end.compact
|
224
|
+
end
|
225
|
+
|
226
|
+
def end_tags(arr)
|
227
|
+
@tg_end = @tg_end + arr
|
228
|
+
end
|
229
|
+
|
230
|
+
#call from proc hot before it render hots line
|
231
|
+
#see in source code "w2tags.rb::read_filehot"
|
232
|
+
#default behaviour for tag_nex will not execute
|
233
|
+
#since @mem_hot will assigned w/o nil
|
234
|
+
#assigned nil using "%!" in w2tags
|
235
|
+
def chg_mem_hot(nxt)
|
236
|
+
@mem_hot = nxt
|
237
|
+
@mem_tag["^"] = nxt if nxt
|
238
|
+
end
|
239
|
+
|
240
|
+
#pop up end tags from the stack
|
241
|
+
#result will be string contains end tags from stack
|
242
|
+
#who's space inside each end tags > current space
|
243
|
+
def multi_end(ttls)
|
244
|
+
rpls = ''
|
245
|
+
ttl = @tg_end.size-1
|
246
|
+
ttl = ttls-1 if ttls
|
247
|
+
ttl.downto(0) do |i|
|
248
|
+
sz = @tg_end[i][/^ +/].to_s.size
|
249
|
+
if ttls || @spc.size <= sz
|
250
|
+
send = @tg_end.pop.to_s
|
251
|
+
if send.strip[0,5]=="!run!"
|
252
|
+
scrpt = send.gsub("\n","\n#{@spc}").split("\n")
|
253
|
+
@doc_src = scrpt[1,99]+@doc_src
|
254
|
+
else
|
255
|
+
spc = send[/(^[ \t]*)/,1].to_s
|
256
|
+
rpls << send.gsub(/\n/,"\n#{spc}") + "\n"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
p "End..: #{rpls.strip}" if @dbg[:parse] && rpls!= ''
|
261
|
+
rpls
|
262
|
+
end
|
263
|
+
|
264
|
+
private
|
265
|
+
|
266
|
+
# try to shift empty line create document and add current
|
267
|
+
# row to source. but it means re parsing current row.
|
268
|
+
def swap_last_empt_src_with_end_tg(end_tg)
|
269
|
+
last = []
|
270
|
+
while @doc_out[-1] && @doc_out[-1].to_s.strip == ''
|
271
|
+
last << @doc_out.pop
|
272
|
+
end
|
273
|
+
end_tg.shift if end_tg[0].strip==''
|
274
|
+
@doc_src = end_tg + @doc_src
|
275
|
+
#p "Swp..: #{@doc_src[-1]}" if @dbg[:parse]
|
276
|
+
end
|
277
|
+
|
278
|
+
#merging file hot based on the target extension, and target
|
279
|
+
#extension it self based on source extension, example:
|
280
|
+
#suppose you have source of w2tags 'index.html.w2erb'
|
281
|
+
#it just like autoloading:
|
282
|
+
# !hot!erb
|
283
|
+
#it will search HOT files in current folder, if it not found
|
284
|
+
#it will search in gem/hot and merging the HOT
|
285
|
+
def merge_tags
|
286
|
+
hot1 = "#{@src_path}/#{@ext}.#{@hot}"
|
287
|
+
hot2 = "#{W2Tags::Dir}/../hot/#{@ext}.#{@hot}"
|
288
|
+
filehot = hot1 if File.exist?(hot1)
|
289
|
+
filehot = hot2 if File.exist?(hot2)
|
290
|
+
if filehot
|
291
|
+
puts '=>'+File.expand_path(filehot) if !@silent
|
292
|
+
@tg_hot.merge!(W2Tags.read_filehot(filehot))
|
293
|
+
end
|
294
|
+
@tg_hot
|
295
|
+
end
|
296
|
+
|
297
|
+
#define variable ( &var! or @var! )tobe use by parser in hot for
|
298
|
+
#the next line parsing, example on w2tags:
|
299
|
+
# &myvar=hello\n
|
300
|
+
# ^{.myclass &myvar!}
|
301
|
+
#
|
302
|
+
#it will translate on the fly to:
|
303
|
+
# ^{.myclass hello}
|
304
|
+
#
|
305
|
+
#for @var! is uniq value split by ";", example on w2tags:
|
306
|
+
# @myvar=hello;world\n
|
307
|
+
# @myvar=world;tags\n
|
308
|
+
# ^{.myclass @myvar!}
|
309
|
+
#
|
310
|
+
#it will translate on the fly to:
|
311
|
+
# ^{.myclass hello;world;tags}
|
312
|
+
def parse_set_var
|
313
|
+
if @row.gsub!( /^[ \t]*(&[\w]+)=([^\n]+)([\n])/,'')
|
314
|
+
@mem_var[$1+"!"] = $2.strip
|
315
|
+
elsif @row.gsub!(/^[ \t]*(@[\w]+)=([^\n]+)([\n])/,'')
|
316
|
+
k,v = [$1+"!",$2.strip] #;p v
|
317
|
+
#v << ';'+@mem_var[k].to_s if v[0,1]!=';' && @mem_var[k]
|
318
|
+
v = (@mem_var[k].to_s + ';' + v) if v[0,1]!=';' && @mem_var[k]
|
319
|
+
@mem_var[k] = v.split(';').uniq.select{|x|x!=''}.join(';')
|
320
|
+
p "uniq var> #{v}" if @dbg[:parse] #&& @plt == 99 && @rmk == 99
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
#when parsing and found tag
|
325
|
+
# !hot!filehot1;filehotN
|
326
|
+
#it will search HOT files in current folder, if it not found it will search
|
327
|
+
#in gem/hot and merging the HOT, this command can have multiple
|
328
|
+
#file HOT separate with ";"
|
329
|
+
def merge_hot
|
330
|
+
if(/!hot!([\w;]+)([`\n])/ =~ @row;@rgx = $~)
|
331
|
+
hots= @rgx[1].split(';').collect {|x|x+'.'+@hot}
|
332
|
+
rpl = ['']
|
333
|
+
hots.each do |hot|
|
334
|
+
fls = File.exist?(hot) ? hot :
|
335
|
+
File.exist?(@src_path+'/'+hot) ? @src_path+'/'+hot :
|
336
|
+
File.exist?(W2Tags::Dir+'/../hot/'+hot) ? W2Tags::Dir+'/../hot/'+hot : ''
|
337
|
+
if fls==''
|
338
|
+
rpl << "<!--"+hot+", Not Found-->\n"
|
339
|
+
else
|
340
|
+
puts '=>'+File.expand_path(fls) if !@silent
|
341
|
+
@tg_hot.merge!(W2Tags.read_filehot(fls))
|
342
|
+
end
|
343
|
+
end
|
344
|
+
@row.gsub!(@rgx.to_s,rpl.join)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
#when parsing and found tag
|
349
|
+
# !inc!fileinc
|
350
|
+
#it will include / replace current row from file inside .w2x, and after
|
351
|
+
#parser will try to get current row after merging to be evaluate
|
352
|
+
def merge_w2x
|
353
|
+
if(/!inc![ ]?([\/\w._]+)([`\n])/ =~ @row;@rgx = $~)
|
354
|
+
mac = @src_path+'/'+$1+'.'+@w2x
|
355
|
+
src = $~.to_s #;p mac
|
356
|
+
if File.exist?(mac)
|
357
|
+
pop = $~.captures.pop
|
358
|
+
new = IO.read(mac).delete("\r").gsub("\n","\n"+@spc) + ( pop=='`' ? "\n"+@spc : '' )
|
359
|
+
@doc_src= @row.gsub(src,new).split("\n")+@doc_src
|
360
|
+
@row= @doc_src.shift+"\n"
|
361
|
+
parse_spc
|
362
|
+
else
|
363
|
+
@row.gsub!(src,"<!--"+mac+", Not Found-->\n")
|
364
|
+
nil
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
#get space (tab and spaces) on the left of the code and save it to instance
|
370
|
+
#it will be use if row replace with more than one row and replacement row
|
371
|
+
#must continue with current column (indent).
|
372
|
+
def parse_spc
|
373
|
+
@spc = @row[/(^[ \t]+)/,1].to_s #sometime result is nil
|
374
|
+
end
|
375
|
+
|
376
|
+
#do the translation from the params inside function like:
|
377
|
+
# %a par1;par2;par3
|
378
|
+
#it do following job:
|
379
|
+
# * replace constanta (&var!) inside params of the function
|
380
|
+
# * replace constanta (&var!) inside new line of source code
|
381
|
+
# (inside instance var @new)
|
382
|
+
# * replace var $0 - $9 inside var @new from params if function have
|
383
|
+
# 3 params so 3 var $ will be replace from the params and if var @new
|
384
|
+
# have var # more than what function params suply, it will replace with
|
385
|
+
# an empty string
|
386
|
+
# * if in var @new define only 1 var $ and function params got more than
|
387
|
+
# 1, it will multiply the @new line with total number of lparams
|
388
|
+
# to get the illustrate I'll show you with an example:
|
389
|
+
# inside hot file :
|
390
|
+
# >>td
|
391
|
+
# <td>$0</td>
|
392
|
+
# --------------------
|
393
|
+
# function call: @td(col1;col2) # will result in
|
394
|
+
# --------------------
|
395
|
+
# <td>col1</td>
|
396
|
+
# <td>col2</td>
|
397
|
+
# * some of the replacement behaviour for var $ are :
|
398
|
+
# 1. optional meaning that var $ inside [ xxx $ xxxx ] sequare bracket are
|
399
|
+
# optional if not suply from params it will an emppty replacement
|
400
|
+
# 2. default value meaning that var $ inside [ xxx $ left sequare bracket
|
401
|
+
# are a default if not suply from params but if it suply from params it
|
402
|
+
# will empty the default and relace var $ from the params
|
403
|
+
# 3. execute String.method if var $ in the left got ":", example
|
404
|
+
# inside hot file:
|
405
|
+
# >>td
|
406
|
+
# <td>:capitalize$0</td>
|
407
|
+
# --------------------
|
408
|
+
# function call: @td(col1;col2) # will result in
|
409
|
+
# --------------------
|
410
|
+
# <td>Col1</td>
|
411
|
+
# <td>Col2</td>
|
412
|
+
def get_dollar(prms,ends=nil) #prms='@0;@1;@2' from hot
|
413
|
+
@mem_var.each do |k,v| #;p "#{k}, #{v}"
|
414
|
+
prms.gsub!(k,v)
|
415
|
+
if k[0,1]=='*' and Regexp.new("~([^~]+)~#{k}".gsub('*','\\*')) =~ @new
|
416
|
+
@new.gsub!($~.to_s,(v!='' ? v : $1))
|
417
|
+
else
|
418
|
+
@new.gsub!(k,v)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
prms = prms.split(';') #W2Tags::splitter(prms)
|
422
|
+
new_prms = @new.scan(/\$[0-9]/).uniq
|
423
|
+
new_alls = @new.scan(/\$\*/) #;p 'rpl:',new_alls,new_prms,prms
|
424
|
+
@new.gsub!($1,"<%= \"#{$2}\" %>") if /(==(\$[0-9]))/ =~ @new
|
425
|
+
@new.gsub!($1,"<%= #{$2} %>") if /(=(\$[0-9]))/ =~ @new
|
426
|
+
if /^@[0-9]$/ =~ prms[0]
|
427
|
+
rpl = prms.shift.gsub('@','$')
|
428
|
+
repeat = @new
|
429
|
+
repeat.gsub!('$0',prms.shift) #repeat.gsub!('$*',rpl)
|
430
|
+
@new = ''
|
431
|
+
prms.each_with_index do |x,i| #;p "$0 #{x} => #{repeat}"
|
432
|
+
@new += repeat.gsub(rpl,x)
|
433
|
+
if i+1<prms.size
|
434
|
+
@new += "\n"+@spc+ends.join("\n") if ends
|
435
|
+
@new += "\n"+@spc
|
436
|
+
end
|
437
|
+
end
|
438
|
+
elsif new_alls==[] && new_prms.size==1 && prms.size>1
|
439
|
+
tmp = ""
|
440
|
+
rpt = @rgx.to_s.gsub(@rgx[3]+"\n","")
|
441
|
+
prms.each_with_index do |x,i|
|
442
|
+
tmp<< rpt+x #tmp<< @new.gsub(new_prms[0],x)
|
443
|
+
tmp<< "\n#{@spc}" if i+1<prms.size
|
444
|
+
end
|
445
|
+
@new = tmp
|
446
|
+
else
|
447
|
+
i = new_prms.size - 1
|
448
|
+
new_prms.sort.reverse.each do |x|
|
449
|
+
opt_v = Regexp.new('~([^$|\n]*)\\'+x+'([^\|\n]*)~')
|
450
|
+
def_v = Regexp.new('~([^~]+)~\\'+x)
|
451
|
+
eva_v = Regexp.new('\\'+x+'.([^~$]+)~') #$1.upcase~
|
452
|
+
if opt_v =~ @new #;p $1
|
453
|
+
rpl = ''
|
454
|
+
rpl = "#{$1.to_s}#{prms[i]}#{$2.to_s}" if prms[i] && prms[i].strip!=""
|
455
|
+
@new.gsub!(opt_v,rpl)
|
456
|
+
#p "options: #{rpl} >> #{@new}"
|
457
|
+
elsif def_v =~ @new #;p $1
|
458
|
+
src = $~.to_s
|
459
|
+
rpl = (prms[i] && prms[i].strip!="" ? prms[i] : $1)
|
460
|
+
@new.gsub!(src,rpl)
|
461
|
+
#p "default: #{@new}"
|
462
|
+
end
|
463
|
+
while eva_v=~ "\n#{@new}" do
|
464
|
+
src = "#{x}.#{$1}~" ; #p "\n#{@new} => #{src}"
|
465
|
+
evl = "\"#{prms[i]}\".#{$1}"; #p "====> #{evl} <=="
|
466
|
+
rpl = prms[i] ? eval(evl).to_s : ""
|
467
|
+
@new.gsub!(src,rpl)
|
468
|
+
end
|
469
|
+
#p "rest: #{x} => #{prms[i].to_s}"
|
470
|
+
@new.gsub!(x,prms[i].to_s)
|
471
|
+
i = i -1
|
472
|
+
end
|
473
|
+
@new.gsub!(/\$\*/,prms[new_prms.size,99].to_a.join(';') )
|
474
|
+
@new.gsub!(/\n\t+$/,'') #remove line if only tabs
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
#pop up end tags from the stack
|
479
|
+
def multi_end2(ttls)
|
480
|
+
rpls = ''
|
481
|
+
ttl = @tg_end.size-1
|
482
|
+
ttl = ttls-1 if ttls
|
483
|
+
ttl.downto(0) do |i|
|
484
|
+
sz = @tg_end[i][/^ +/].to_s.size
|
485
|
+
if ttls || @spc.size <= sz
|
486
|
+
send = @tg_end.pop
|
487
|
+
if send.strip[0,5]=="!run!"
|
488
|
+
scrpt = send.gsub("\n","\n#{@spc}").split("\n")
|
489
|
+
@doc_src = scrpt[1,99]+@doc_src
|
490
|
+
else
|
491
|
+
spc = send[/(^[ \t]*)/,1].to_s
|
492
|
+
rpls << send.gsub(/\n/,"\n#{spc}") + "\n"
|
493
|
+
end
|
494
|
+
end
|
495
|
+
end
|
496
|
+
p "End2 : #{rpls.strip}" if @dbg[:parse] && rpls!= ''
|
497
|
+
rpls
|
498
|
+
end
|
499
|
+
|
500
|
+
#command execution "-key", internally parsed to "%_key~", so both command
|
501
|
+
#are the same except that command "-key" need to translate to "%_key~" and
|
502
|
+
#it goes to Hot files key definition to lookup to. some of these definition
|
503
|
+
# built in (for erb: %_if , %_elsif , %_else , %_end , ... etc)
|
504
|
+
# -if => %_if
|
505
|
+
# -li => %_li
|
506
|
+
def shortcut_exec(regex)
|
507
|
+
if(regex =~ @row;@rgx = $~)
|
508
|
+
srcs = @rgx.to_s
|
509
|
+
rplc = "#{@rgx[1]}%!_#{@rgx[2]}~ #{@rgx[3]}\n"
|
510
|
+
@row.gsub!(srcs,rplc)
|
511
|
+
p "reExe_ #{@row}" if @dbg[:parse]
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
#command execution "=", internally parsed to "%=~", so both command
|
516
|
+
#are the same except that command "=" need to translate to "%=~" and
|
517
|
+
#it goes to Hot files key definition to lookup to. you can redefine it.
|
518
|
+
def shortcut_equal(regex)
|
519
|
+
if(regex =~ @row;@rgx = $~)
|
520
|
+
srcs = @rgx.to_s
|
521
|
+
rplc = "#{@rgx[1]}%!=~#{@rgx[3]}\n"
|
522
|
+
@row.gsub!(srcs,rplc)
|
523
|
+
p "reEqu_ #{rplc}" if @dbg[:parse]
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
#this command is the selector from command
|
528
|
+
# %..key.. params1;paramsN \n
|
529
|
+
#ex:
|
530
|
+
# %div<space>params\n or %div<\n>.
|
531
|
+
#if key div fine in hot, it will translate to HOT tags, but if not
|
532
|
+
#it become w2tags
|
533
|
+
def get_hot_simple(regex)
|
534
|
+
if regex =~ @row ;@rgx = $~
|
535
|
+
chk1= @rgx[2][-1,1] + @rgx[3][0,2].to_s
|
536
|
+
chk2= @rgx[2][/"\}!/]
|
537
|
+
chk3= @rgx[2][/"\}~/]
|
538
|
+
# already become w2tags, ignore!!!
|
539
|
+
if (/[=\}][!~][ ]?/ !~ chk1 && chk2 == nil && chk3 == nil)
|
540
|
+
keys = @rgx[2].strip
|
541
|
+
opts = @rgx[3]
|
542
|
+
#p chk1
|
543
|
+
# FIX for:
|
544
|
+
# %form#dodol{action="<%= #{aaa} %>"} <%= #{bbb} %>
|
545
|
+
# <form id="dodol" action="<%= #{aaa} %>"><%= #{bbb}%></form>
|
546
|
+
# when wrong splitting, fix the splitting...
|
547
|
+
# assume last attribute don't have spaceses!!! ==>{opt="blah"}<==
|
548
|
+
fixd = keys.split('"} ')
|
549
|
+
if fixd.length>1
|
550
|
+
keys = fixd[0]+'"}'
|
551
|
+
opts = fixd[1]+opts
|
552
|
+
end
|
553
|
+
|
554
|
+
srcs = @rgx.captures.join
|
555
|
+
opts = $1 << opts if keys.gsub!(/(\/)$/,'')
|
556
|
+
hots = keys.gsub(/\{.*\}$/,'').gsub(/[:#.][\w\-#.=]*$/,'')
|
557
|
+
rplc = @tg_hot[hots]!=nil ?
|
558
|
+
"%!#{keys}~ #{opts}" :
|
559
|
+
"%!#{keys}! #{opts}"
|
560
|
+
@row.gsub!(srcs,rplc)
|
561
|
+
p "reHot> #{@row} << -H-O-T-" if @dbg[:parse]
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
#translation for tags with shortcut of name, id, or class and put in constants
|
567
|
+
# ex: %div:name#id.class{attribute}=
|
568
|
+
#will result in some of this var:
|
569
|
+
# @mem_var['$$' ] => :name#id.class{attribute}==
|
570
|
+
# @mem_var['$:' ] => :name
|
571
|
+
# @mem_var['$#' ] => #id
|
572
|
+
# @mem_var['$.' ] => .class
|
573
|
+
# @mem_var['$@' ] => {attribute}
|
574
|
+
# @mem_var['*:' ] => name
|
575
|
+
# @mem_var['*#' ] => id
|
576
|
+
# @mem_var['*.' ] => class
|
577
|
+
# @mem_var['*@' ] => attribute
|
578
|
+
# @mem_var['*all*' ] => name="name" id="id" class="class"
|
579
|
+
# @mem_var['*name*' ] => name="name"
|
580
|
+
# @mem_var['*id*' ] => id="id"
|
581
|
+
# @mem_var['*class*'] => class="class"
|
582
|
+
# this var will be use in parsing w2tags/hot command
|
583
|
+
def nameidclass_var()
|
584
|
+
#@key = keys = @rgx[2].strip.gsub(/(\{(.*)\})/,'') #greedy :)
|
585
|
+
@key = keys = @key.strip.gsub(/(\{(.*)\})/,'') #greedy :)
|
586
|
+
@att = $2.to_s.strip
|
587
|
+
@mem_var['$$' ]= ''
|
588
|
+
@mem_var['$&' ]= ''
|
589
|
+
@mem_var['$:' ]= ''
|
590
|
+
@mem_var['$#' ]= ''
|
591
|
+
@mem_var['$.' ]= ''
|
592
|
+
@mem_var['$@' ]= $1.to_s
|
593
|
+
@mem_var['*&' ]= ''
|
594
|
+
@mem_var['*:' ]= ''
|
595
|
+
@mem_var['*#' ]= ''
|
596
|
+
@mem_var['*.' ]= ''
|
597
|
+
@mem_var['*@' ]= @att=='' ? '' : @att+' '
|
598
|
+
@mem_var['*all*' ]= ''
|
599
|
+
@mem_var['*name*' ]= ''
|
600
|
+
@mem_var['*id*' ]= ''
|
601
|
+
@mem_var['*class*']= ''
|
602
|
+
@mem_var['*code*' ]= ''
|
603
|
+
#p keys
|
604
|
+
if @key.gsub!(/([&:#.=])([\/\t\w\-#.= ]*$)/,'')
|
605
|
+
keys = $1+$2
|
606
|
+
if keys.gsub!(/^&([\/\w\-.]*)/,'')
|
607
|
+
if $1!=''
|
608
|
+
@mem_var['$&' ] = "&#{$1}"
|
609
|
+
@mem_var['*&' ] = $1
|
610
|
+
@mem_var['$$' ]<< "&#{$1}"
|
611
|
+
end
|
612
|
+
end
|
613
|
+
if keys.gsub!(/^:([\w\-.]*)/,'')
|
614
|
+
if $1!=''
|
615
|
+
@mem_var['$:' ] = ":#{$1}"
|
616
|
+
@mem_var['*:' ] = $1
|
617
|
+
@mem_var['*name*' ] = "name=\"#{$1}\" "
|
618
|
+
@mem_var['*all*' ]<< "name=\"#{$1}\" "
|
619
|
+
@mem_var['$$' ]<< ":#{$1}"
|
620
|
+
end
|
621
|
+
end
|
622
|
+
if keys.gsub!(/^#([\w\-]*)/,'')
|
623
|
+
if $1!=''
|
624
|
+
@mem_var['$#' ] = "##{$1}"
|
625
|
+
@mem_var['*#' ] = $1
|
626
|
+
@mem_var['*id*' ] = "id=\"#{$1}\" "
|
627
|
+
@mem_var['*all*' ]<< "id=\"#{$1}\" "
|
628
|
+
@mem_var['$$' ]<< "##{$1}"
|
629
|
+
end
|
630
|
+
end
|
631
|
+
if keys.gsub!(/^\.([\w\-\.]*)/,'')
|
632
|
+
if $1!=''
|
633
|
+
cl = $1
|
634
|
+
cx = cl.split('.').collect {|x|x.strip}.join(' ')
|
635
|
+
@mem_var['$.' ] = ".#{cl}"
|
636
|
+
@mem_var['*.' ] = cl
|
637
|
+
@mem_var['*class*'] = "class=\"#{cx}\" "
|
638
|
+
@mem_var['*all*' ]<< "class=\"#{cx}\" "
|
639
|
+
@mem_var['$$' ]<< ".#{cl}"
|
640
|
+
end
|
641
|
+
end
|
642
|
+
@key << keys
|
643
|
+
end
|
644
|
+
@mem_var['$$' ] << @mem_var['$@']
|
645
|
+
@mem_var['*all*'] << @mem_var['*@']
|
646
|
+
@mem_var['*att*'] = @mem_var['*@']
|
647
|
+
if @key[0,1]!='='
|
648
|
+
if @key.gsub!(/==$/,'')
|
649
|
+
@mem_var['*code*'] = '<%= "$*" %>'
|
650
|
+
@mem_var['$$' ]<< "=="
|
651
|
+
elsif @key.gsub!(/=$/,'')
|
652
|
+
@mem_var['*code*'] = "<%= $* %>"
|
653
|
+
@mem_var['$$' ]<< "="
|
654
|
+
end
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
#these not really visible for end user, since user usualy see the command as
|
659
|
+
#a HAML like command and translate to this HOT files. the translation usually
|
660
|
+
#came from method in:
|
661
|
+
# shortcut_exec
|
662
|
+
# get_hot_simple
|
663
|
+
#format for this command is
|
664
|
+
# %...key...~..params1;paramsN..\n
|
665
|
+
def parse_hot
|
666
|
+
eva = ''
|
667
|
+
col = @row.split('%')
|
668
|
+
return false if col.size==1
|
669
|
+
(col.size-1).downto(0) do |c|
|
670
|
+
eva = "%#{col[c]}" << eva
|
671
|
+
@rg_hot.each do |ht|
|
672
|
+
if(ht =~ eva;@rgx = $~)
|
673
|
+
@key = @rgx[2]
|
674
|
+
prms = @rgx[3].to_s.strip
|
675
|
+
if /^\!/ =~ @key
|
676
|
+
@new = (multi_end2(nil)+@spc+@rgx.to_s.gsub('%!','%')).split("\n")
|
677
|
+
swap_last_empt_src_with_end_tg(@new)
|
678
|
+
@row = ''
|
679
|
+
else
|
680
|
+
nameidclass_var()
|
681
|
+
# Auto closing, see in "erb.hot": _elsif _else:
|
682
|
+
# when last doc out is <% end %> and hot command is %_elsif or %_else
|
683
|
+
# then remove the last doc out <% end %>
|
684
|
+
if @doc_out[-1] and @doc_out[-1].strip=='<% end %>'
|
685
|
+
@doc_out.pop if %w[else elsif].include? prms.split(' ')[0]
|
686
|
+
end
|
687
|
+
while prms[-1,1]=='\\' do #concenation line if params end with \
|
688
|
+
prms.gsub!(/\\$/,'') << @doc_src.shift.strip
|
689
|
+
end
|
690
|
+
@mem_var["$tag"] = @key
|
691
|
+
if @tg_hot[@key]
|
692
|
+
hots = @tg_hot[@key]
|
693
|
+
hots[1]='' if !hots[1] #remark if not error!
|
694
|
+
@new = hots[0].call(self).clone
|
695
|
+
if @new.strip=="" #&& @tg_end[-1]
|
696
|
+
@tg_end << "#{@spc}#{hots[1][0]}"
|
697
|
+
empt = @row.gsub!(@rgx.to_s,"").strip
|
698
|
+
@row = empt if empt == "" #remove if empty (only \t,\n)
|
699
|
+
else
|
700
|
+
@tg_end << "#{@spc}#{hots[1][0]}" if hots[1]
|
701
|
+
@new.gsub!(/( *~\^.*[^\n]+)/,"^~^~^")
|
702
|
+
setvar = $1 # don't parse SetMem ~^
|
703
|
+
@new.gsub!(/\n/,"\n#{@spc}")
|
704
|
+
get_dollar(prms,hots[1])
|
705
|
+
@new.gsub!(/\^~\^~\^/,setvar) if setvar #restore SetMem
|
706
|
+
srcs = @rgx.to_s
|
707
|
+
@doc_src = @row.gsub(srcs,@new).split("\n")+@doc_src
|
708
|
+
@row = @doc_src.shift+"\n"
|
709
|
+
parse_spc
|
710
|
+
end
|
711
|
+
p "Func>> #{@new}" if @dbg[:parse]
|
712
|
+
else
|
713
|
+
@row.gsub!(@rgx.to_s,"<!-- no hot for:#{@key} -->")
|
714
|
+
end
|
715
|
+
end
|
716
|
+
break
|
717
|
+
end
|
718
|
+
end
|
719
|
+
break if @rgx
|
720
|
+
end
|
721
|
+
@rgx!=nil
|
722
|
+
end
|
723
|
+
|
724
|
+
#internal use call from
|
725
|
+
# get_div
|
726
|
+
# get_input
|
727
|
+
def get_shortcut(regex,tag)
|
728
|
+
if(regex =~ @row;@rgx = $~)
|
729
|
+
src = @rgx.captures.join
|
730
|
+
keys= @rgx[1,2].join.strip
|
731
|
+
opts= @rgx[3].to_s
|
732
|
+
opts= $1 << opts if keys.gsub!(/(\/)$/,'')
|
733
|
+
#tgt = "%!#{tag}#{keys}!#{opts}"
|
734
|
+
tgt = "%#{tag}#{keys} #{opts}"
|
735
|
+
@row.gsub!(src,tgt)
|
736
|
+
p "to#{tag.capitalize[0,3]}: #{tgt}" if @dbg[:parse]
|
737
|
+
end
|
738
|
+
@rgx!=nil
|
739
|
+
end
|
740
|
+
|
741
|
+
#shortcut for
|
742
|
+
# "%...div...!params",
|
743
|
+
#and user no need to write
|
744
|
+
# "%div"
|
745
|
+
#if user supply the command with ID or CLASS.
|
746
|
+
# %div#key my key features
|
747
|
+
#same as:
|
748
|
+
# #key my key features
|
749
|
+
#
|
750
|
+
# %div.okey my key features
|
751
|
+
#same as:
|
752
|
+
# .okey my key features
|
753
|
+
def get_div( regex)
|
754
|
+
get_shortcut(regex,'div')
|
755
|
+
end
|
756
|
+
|
757
|
+
#shortcut for
|
758
|
+
# "%...input...!params",
|
759
|
+
#and user no need to write
|
760
|
+
# "%input"
|
761
|
+
#if user supply the command with NAME
|
762
|
+
# %input:wharsojo my key features
|
763
|
+
#same as:
|
764
|
+
# :wharsojo my key features
|
765
|
+
def get_input(regex)
|
766
|
+
get_shortcut(regex,'input')
|
767
|
+
end
|
768
|
+
|
769
|
+
#popup the closing tags when indentation are less than the previous.
|
770
|
+
def auto_close
|
771
|
+
if @tg_end.size>1
|
772
|
+
sz = @tg_end[-1][/^ +/].to_s.size
|
773
|
+
if @spc.size <= sz
|
774
|
+
ed = multi_end(nil).rstrip
|
775
|
+
p "AutE:#{ed}#{@row}" if @dbg[:parse]
|
776
|
+
@doc_out += [ed,@row]
|
777
|
+
@row = ''
|
778
|
+
true
|
779
|
+
end
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
783
|
+
#all regex for line will be parse in this methods return value of not nill
|
784
|
+
#will try to parse the line (@row) again, if finish parsing (return nil)
|
785
|
+
#it try to check the indentation to auto_close the line.
|
786
|
+
def parse_all
|
787
|
+
#check for skipping the block using add on module...
|
788
|
+
if @skiper.select{|f|send(f)}.length>0
|
789
|
+
p "skip > #{@row}" if @dbg[:parse]
|
790
|
+
else
|
791
|
+
@plt_opt= ''
|
792
|
+
#rtn= true if @selector.select{|f|send(f)}.length>0
|
793
|
+
rtn = true if shortcut_exec( /(^[\t ]*)\-([\w\-&\/:#.%]*\{.*\}[=]?) *([^\n]*)\n/)
|
794
|
+
rtn = true if shortcut_exec( /(^[\t ]*)\-([\w\-&\/:#.%=]*) *([^\n]*)\n/)
|
795
|
+
rtn = true if shortcut_equal( /(^[\t ]*)=([\w\-&\/:#.%=]*) *([^\n]*)\n/)
|
796
|
+
|
797
|
+
rtn = true if get_hot_simple(/^[\t ]*(%)([\$\w\-&\/:#.]+\{.*\}[= ]*)([^\n]*)\n/)
|
798
|
+
rtn = true if get_hot_simple(/^[\t ]*(%)([\$\w\-&\/:#.]+\{.*\}[= ]*)()\n/)
|
799
|
+
rtn = true if get_hot_simple(/^[\t ]*(%)([\$\w\-&\/:#.%=]+ )([^\n]*)\n/)
|
800
|
+
rtn = true if get_hot_simple(/^[\t ]*(%)([\$\w\-&\/:#.%=]+)()\n/)
|
801
|
+
|
802
|
+
rtn = true if get_div(/^[\t ]*([#.])([\w\-&\/.]*\{.*\}[= ]*)([^\n]*)\n/)
|
803
|
+
rtn = true if get_div(/^[\t ]*([#.])([\w\-&\/.]*\{.*\}[= ]*)()\n/)
|
804
|
+
rtn = true if get_div(/^[\t ]*([#.])([\w\-&\/.=]* )([^\n]*)\n/)
|
805
|
+
rtn = true if get_div(/^[\t ]*([#.])([\w\-&\/.=]*)()\n/)
|
806
|
+
rtn = true if get_input( /^[\t ]*(:)([\w\-&\/#.]*\{.*\}[= ]*)([^\n]*)\n/)
|
807
|
+
rtn = true if get_input( /^[\t ]*(:)([\w\-&\/#.]*\{.*\}[= ]*)()\n/)
|
808
|
+
rtn = true if get_input( /^[\t ]*(:)([\w\-&\/#.=]* )([^\n]*)\n/)
|
809
|
+
rtn = true if get_input( /^[\t ]*(:)([\w\-&\/#.=]*)()\n/)
|
810
|
+
rtn = true if parse_hot
|
811
|
+
rtn = true if merge_hot
|
812
|
+
rtn = true if merge_w2x
|
813
|
+
rtn = true if parse_set_var
|
814
|
+
rtn = true if parse_set_mem
|
815
|
+
rtn = true if parse_get_mem
|
816
|
+
rtn = true if inline_tag
|
817
|
+
rtn = true if parse_end
|
818
|
+
if parse_tags
|
819
|
+
rtn = nil
|
820
|
+
elsif !rtn
|
821
|
+
auto_close
|
822
|
+
end
|
823
|
+
end
|
824
|
+
rtn
|
825
|
+
end
|
826
|
+
|
827
|
+
#remember command "^", not really use but if you want less typing you can
|
828
|
+
#define this command inside HOT file for the next command to be execute like:
|
829
|
+
# HOT file:
|
830
|
+
# >>_tr
|
831
|
+
# ~^%td
|
832
|
+
#
|
833
|
+
# Source file:
|
834
|
+
# -tr
|
835
|
+
# ^ inside td
|
836
|
+
#I think its Ok.
|
837
|
+
def parse_set_mem
|
838
|
+
if @row.gsub!(/([ \t]*~\^)([^\n]+)(\n)/,'')
|
839
|
+
p "setMem ^ => #{$2+"\n"}" if @dbg[:parse]
|
840
|
+
@mem_tag["^"]= $2+"\n"
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
844
|
+
#call from parse_get_mem
|
845
|
+
def get_mem(regex)
|
846
|
+
if(regex =~ @row;@rgx = $~)
|
847
|
+
keys,tmp,prms,opt,ends= @rgx.captures
|
848
|
+
if opt=='!'
|
849
|
+
opt=''
|
850
|
+
@mem_hot=nil
|
851
|
+
end
|
852
|
+
|
853
|
+
@new = @mem_tag[keys].split(' ')
|
854
|
+
@new[0] << tmp
|
855
|
+
@new = @new.join(" ") << "\n"
|
856
|
+
get_dollar(prms)
|
857
|
+
rpl = @new #+opt.to_s+ends.to_s
|
858
|
+
p "stMem> #{rpl}" if @dbg[:parse]
|
859
|
+
@row.gsub!(@rgx.to_s,rpl)
|
860
|
+
rows = @row.split("\n")
|
861
|
+
if rows.size>1
|
862
|
+
@doc_src = rows+@doc_src
|
863
|
+
@row = @doc_src.shift+"\n"
|
864
|
+
end
|
865
|
+
end
|
866
|
+
@rgx!=nil
|
867
|
+
end
|
868
|
+
|
869
|
+
#remember command "^", not really use but if you want less typing you can
|
870
|
+
#define this command inside HOT file for the next command to be execute like:
|
871
|
+
# HOT file:
|
872
|
+
# >>_tr
|
873
|
+
# ~^%td
|
874
|
+
#
|
875
|
+
# Source file:
|
876
|
+
# -tr
|
877
|
+
# ^ inside td
|
878
|
+
#I think its Ok.
|
879
|
+
def parse_get_mem
|
880
|
+
get_mem(/([\^])([^ ]*) ([^\n]*)(\n)/)
|
881
|
+
end
|
882
|
+
|
883
|
+
#it call from parse_end
|
884
|
+
def get_end(regex)
|
885
|
+
if(regex =~ @row;@rgx = $~)
|
886
|
+
if @rgx[1]=='~'
|
887
|
+
@new = ''
|
888
|
+
@new = multi_end(1) if @tg_end.size>0
|
889
|
+
else
|
890
|
+
case @rgx[1]
|
891
|
+
when '!';@new = multi_end(nil)
|
892
|
+
when ',';@new = multi_end(@tg_end.size)
|
893
|
+
else ;@new = multi_end(@rgx[1].size)
|
894
|
+
end
|
895
|
+
end
|
896
|
+
@doc_src = @row.gsub(@rgx.to_s,@new).split("\n")+@doc_src
|
897
|
+
@row = ''
|
898
|
+
end
|
899
|
+
end
|
900
|
+
|
901
|
+
#user can popup the end tags using these folowing command:
|
902
|
+
# ,/ all end tags will be popup
|
903
|
+
# ~/ one or multi end tags will be popup (depend on how many ~ you write)
|
904
|
+
# !/ popup until the same indentation of "!/"
|
905
|
+
def parse_end
|
906
|
+
(get_end(/^(,)\/(\n)/) ? true : \
|
907
|
+
(get_end(/^[ \t]*(~+)\/(\n)/) ? true : \
|
908
|
+
get_end(/^[ \t]*(!)\/(\n)/)))
|
909
|
+
end
|
910
|
+
|
911
|
+
#parsing w2tags commands
|
912
|
+
def parse_tags
|
913
|
+
@rgx = nil
|
914
|
+
par = []
|
915
|
+
rgs = @rg_tag.collect {|r|par << (r =~ @row);$~}
|
916
|
+
if(max = par.compact.sort.pop) #have any to parse?
|
917
|
+
@rgx = rgs[par.index(max)]
|
918
|
+
@key = @rgx[2]
|
919
|
+
@txt = @rgx[3].strip
|
920
|
+
|
921
|
+
# when wrong splitting, fix the splitting...
|
922
|
+
# assume last attribute don't have spaceses!!! ==>{opt="blah"}<==
|
923
|
+
fixd = @key.split('"} ')
|
924
|
+
if fixd.length>1
|
925
|
+
@key = fixd[0]+'"}'
|
926
|
+
@txt = fixd[1]+@txt
|
927
|
+
end
|
928
|
+
|
929
|
+
if /^\!/ =~ @key
|
930
|
+
@new = (multi_end(nil)+@rgx.to_s.gsub('%!','%')).split("\n")
|
931
|
+
swap_last_empt_src_with_end_tg(@new)
|
932
|
+
@row = ''
|
933
|
+
p "W2Tag: try closing tag by indentation..." if @dbg[:parse]
|
934
|
+
return true
|
935
|
+
else
|
936
|
+
@mem_var["$tag"] = @key
|
937
|
+
nameidclass_var()
|
938
|
+
srcs = @rgx.to_s.gsub!(/^[ \t]*/,'')
|
939
|
+
tag_next = @tg_nex[@key] #;p "%mem_hot:#{@mem_hot}:#{@key}"
|
940
|
+
tag_next[1].call if tag_next && @mem_hot==nil
|
941
|
+
rplc = @tagr.call(self);
|
942
|
+
@mem_var.each do |k,v|
|
943
|
+
rplc.gsub!(k,v)
|
944
|
+
end
|
945
|
+
@row.gsub!(srcs,rplc)
|
946
|
+
end
|
947
|
+
p "W2Tag: #{@row}" if @dbg[:parse]
|
948
|
+
end
|
949
|
+
@rgx!=nil
|
950
|
+
end
|
951
|
+
|
952
|
+
#inline parsing
|
953
|
+
#I Like (%strong.bold{banana="boys"} (%i.italic cake%)%)!
|
954
|
+
#I Like <strong class="bold" banana="boys"><i class="italic">cake</i></strong>!
|
955
|
+
def inline_tag()
|
956
|
+
if(/\(%(.*?)%\)/ =~ @row;@rgx = $~)
|
957
|
+
src = $1.split(/\(%/)
|
958
|
+
txt = src.length>1 ? src.pop : src[0]
|
959
|
+
tmp = txt.lstrip.split(' ')
|
960
|
+
@key= tmp.shift
|
961
|
+
@txt= tmp.join(" ")
|
962
|
+
nameidclass_var()
|
963
|
+
@key.strip!
|
964
|
+
html= @mem_var["*code*"]
|
965
|
+
html= html=='' ? @txt : html.gsub("$*",@txt)
|
966
|
+
tags_created = "<#{@key}"
|
967
|
+
tags_created << " #{@mem_var["*all*"].strip}" if @mem_var["*all*"]!=''
|
968
|
+
tags_created << ">#{html}</#{@key}>"
|
969
|
+
@row.gsub!("(%#{txt}%)",tags_created)
|
970
|
+
p "InLin: #{@row}" if @dbg[:parse]
|
971
|
+
end
|
972
|
+
@rgx
|
973
|
+
end
|
974
|
+
end
|
975
|
+
end
|