dyndoc-ruby-core 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/dyndoc/.DS_Store +0 -0
- data/dyndoc/Dyn/.postload +1 -0
- data/dyndoc/Dyn/.preload +1 -0
- data/dyndoc/Dyn/After.dyn +3 -0
- data/dyndoc/Dyn/Base.dyn +18 -0
- data/dyndoc/Dyn/Minimum.dyn +20 -0
- data/dyndoc/Model/Html/DefaultPost_html.dyn +5 -0
- data/dyndoc/Model/Html/DefaultPre_html.dyn +15 -0
- data/dyndoc/Model/Odt/DefaultPost_content.xml +3 -0
- data/dyndoc/Model/Odt/DefaultPost_tmpl_content.xml +3 -0
- data/dyndoc/Model/Odt/DefaultPre_content.xml +8 -0
- data/dyndoc/Model/Odt/DefaultPre_tmpl_content.xml +8 -0
- data/dyndoc/Model/Tex/ContentPost_tmpl.tex +1 -0
- data/dyndoc/Model/Tex/ContentPre_tmpl.tex +6 -0
- data/dyndoc/Model/Tex/DefaultPost_tmpl.tex +73 -0
- data/dyndoc/Model/Tex/DefaultPre_tmpl.tex +16 -0
- data/dyndoc/Model/Ttm/DefaultPost_tmpl.ttm +3 -0
- data/dyndoc/Model/Ttm/DefaultPre_tmpl.ttm +16 -0
- data/dyndoc/Std/Array.dyn +96 -0
- data/dyndoc/Std/Composer.dyn +38 -0
- data/dyndoc/Std/DevTag.dyn +101 -0
- data/dyndoc/Std/DynVar.dyn +23 -0
- data/dyndoc/Std/File.dyn +55 -0
- data/dyndoc/Std/Git.dyn +34 -0
- data/dyndoc/Std/List.dyn +46 -0
- data/dyndoc/Std/OOP.dyn +32 -0
- data/dyndoc/Std/Signal.dyn +18 -0
- data/dyndoc/Std/String.dyn +22 -0
- data/dyndoc/Std/Styles.dyn +1 -0
- data/dyndoc/Std/Test.dyn +282 -0
- data/dyndoc/Std/Utils.dyn +42 -0
- data/dyndoc/Std/Verb.dyn +5 -0
- data/dyndoc/Style/Notation/Math.dyn +7 -0
- data/dyndoc/Style/Notation/Stat/Classic.dyn +8 -0
- data/dyndoc/Style/Notation/Stat/Cqls.dyn +44 -0
- data/dyndoc/Style/Text/Std.dyn +5 -0
- data/dyndoc/Style/Text/StdAlias.dyn +3 -0
- data/dyndoc/Style/Text/StdTex.dyn +17 -0
- data/dyndoc/Style/Text/Txt.dyn +1 -0
- data/dyndoc/Tex/.postload +1 -0
- data/dyndoc/Tex/.preload +1 -0
- data/dyndoc/Tex/10pt_tmpl.tex +1 -0
- data/dyndoc/Tex/11pt_tmpl.tex +1 -0
- data/dyndoc/Tex/12pt_tmpl.tex +1 -0
- data/dyndoc/Tex/Article_tmpl.tex +1 -0
- data/dyndoc/Tex/Beamer.dyn_tex +35 -0
- data/dyndoc/Tex/BeamerHandout_tmpl.tex +2 -0
- data/dyndoc/Tex/Book_tmpl.tex +1 -0
- data/dyndoc/Tex/DefaultFirst_tmpl.tex +1 -0
- data/dyndoc/Tex/DefaultLast_tmpl.tex +8 -0
- data/dyndoc/Tex/Default_tmpl.tex +9 -0
- data/dyndoc/Tex/First_tmpl.tex +8 -0
- data/dyndoc/Tex/Fr_tmpl.tex +17 -0
- data/dyndoc/Tex/Header_tmpl.tex +3 -0
- data/dyndoc/Tex/InclGraph_tmpl.tex +19 -0
- data/dyndoc/Tex/InclSpatProc_tmpl.tex +70 -0
- data/dyndoc/Tex/InclSumMI_tmpl.tex +4 -0
- data/dyndoc/Tex/LargeA4_tmpl.tex +5 -0
- data/dyndoc/Tex/Last_tmpl.tex +1 -0
- data/dyndoc/Tex/Option_tmpl.tex +8 -0
- data/dyndoc/Tex/Png_tmpl.tex +1 -0
- data/dyndoc/Tex/RefCite2_tmpl.tex +16 -0
- data/dyndoc/Tex/RefCite_tmpl.tex +16 -0
- data/dyndoc/Tex/Report_tmpl.tex +1 -0
- data/dyndoc/Tex/Theorem_tmpl.tex +14 -0
- data/dyndoc/Tools/.DS_Store +0 -0
- data/dyndoc/Tools/Atom.dyn/index.dyn +42 -0
- data/dyndoc/Tools/AtomDyndocker.dyn/index.dyn +43 -0
- data/dyndoc/Tools/R/Fig.dyn +144 -0
- data/dyndoc/Tools/R/Tools.dyn +344 -0
- data/dyndoc/Tools/Tex/Beamer.dyn +204 -0
- data/dyndoc/Tools/Tex/BeamerSlide.dyn_tex +199 -0
- data/dyndoc/Tools/Tex/Pgf.dyn +115 -0
- data/dyndoc/Tools/Tex/Table.dyn +278 -0
- data/dyndoc/Tools/Tex/Tools.dyn +37 -0
- data/dyndoc/Tools/Tex/Verb.dyn +77 -0
- data/dyndoc/Tools/Web/.DS_Store +0 -0
- data/dyndoc/Tools/Web/Ace.dyn +54 -0
- data/dyndoc/Tools/Web/Code.dyn +129 -0
- data/dyndoc/Tools/Web/DHtmlX.dyn +39 -0
- data/dyndoc/Tools/Web/DataTable.dyn_html +354 -0
- data/dyndoc/Tools/Web/Html.dyn +286 -0
- data/dyndoc/Tools/Web/Html/JQuery.dyn +123 -0
- data/dyndoc/Tools/Web/Html/Styles.dyn +4 -0
- data/dyndoc/Tools/Web/JQueryTools.dyn +87 -0
- data/dyndoc/Tools/Web/Layout.dyn +86 -0
- data/dyndoc/Tools/Web/Layout/CQLS.dyn +6 -0
- data/dyndoc/Tools/Web/Layout/LJK.dyn +41 -0
- data/dyndoc/Tools/Web/TabBar.dyn +37 -0
- data/dyndoc/Tools/Web/Ttm.dyn +20 -0
- data/dyndoc/Tools/Web/Txtl.dyn +14 -0
- data/lib/dyndoc-core.rb +59 -0
- data/lib/dyndoc/base/envir.rb +541 -0
- data/lib/dyndoc/base/filter/call.rb +127 -0
- data/lib/dyndoc/base/filter/filter_mngr.rb +637 -0
- data/lib/dyndoc/base/filter/server.rb +882 -0
- data/lib/dyndoc/base/filters.rb +3 -0
- data/lib/dyndoc/base/helpers.rb +9 -0
- data/lib/dyndoc/base/helpers/core.rb +32 -0
- data/lib/dyndoc/base/helpers/parser.rb +188 -0
- data/lib/dyndoc/base/scanner.rb +886 -0
- data/lib/dyndoc/base/tags.rb +4 -0
- data/lib/dyndoc/base/tags/keys_mngr.rb +401 -0
- data/lib/dyndoc/base/tags/part_tag.rb +194 -0
- data/lib/dyndoc/base/tags/tag_mngr.rb +125 -0
- data/lib/dyndoc/base/tags/user_tag.rb +216 -0
- data/lib/dyndoc/base/tmpl.rb +6 -0
- data/lib/dyndoc/base/tmpl/eval.rb +581 -0
- data/lib/dyndoc/base/tmpl/extension.rb +337 -0
- data/lib/dyndoc/base/tmpl/manager.rb +450 -0
- data/lib/dyndoc/base/tmpl/oop.rb +57 -0
- data/lib/dyndoc/base/tmpl/parse_do.rb +2446 -0
- data/lib/dyndoc/base/tmpl/rbenvir.rb +54 -0
- data/lib/dyndoc/base/utils.rb +367 -0
- data/lib/dyndoc/common/dynArray.rb +234 -0
- data/lib/dyndoc/common/file.rb +52 -0
- data/lib/dyndoc/common/init.rb +2 -0
- data/lib/dyndoc/common/tilt.rb +149 -0
- data/lib/dyndoc/common/utils.rb +61 -0
- data/lib/dyndoc/common/uv.rb +163 -0
- data/lib/dyndoc/init/config.rb +296 -0
- data/lib/dyndoc/init/home.rb +9 -0
- data/lib/dyndoc/plugins/tex.rb +4 -0
- data/lib/dyndoc/plugins/tex/beamer.rb +208 -0
- data/lib/dyndoc/plugins/tex/tex_eval.rb +69 -0
- data/lib/dyndoc/plugins/tex/tex_parse_do.rb +25 -0
- data/lib/dyndoc/plugins/tex/tex_user_tag.rb +32 -0
- data/share/R/dyndocMsys2.R +5 -0
- data/share/R/dyndocTools.R +9 -0
- data/share/R/test.R +14 -0
- data/share/R/tools/dynArray.R +34 -0
- data/share/R/tools/dynCapture.R +84 -0
- data/share/R/tools/dynMsys2.R +54 -0
- data/share/julia/dynArray.jl +93 -0
- data/share/julia/dyndoc.jl +110 -0
- data/share/julia/ruby.jl +37 -0
- metadata +202 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'dyndoc/base/helpers/core'
|
2
|
+
|
3
|
+
#Dyndoc.warn "path helpers",File.join(File.dirname(__FILE__),"helpers/**/*.rb").gsub('\\','/')
|
4
|
+
#Dyndoc.warn "helpers",Dir[File.join(File.dirname(__FILE__),"helpers/**/*.rb").gsub('\\','/')]
|
5
|
+
|
6
|
+
Dir[File.join(File.dirname(__FILE__),"helpers/**/*.rb").gsub('\\','/')].each{|lib|
|
7
|
+
require lib unless File.basename(lib,".rb")=="core"
|
8
|
+
}
|
9
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#Inside a ruby block all the methods of the class TemplateManager are accessible
|
2
|
+
#because a new envir is created as in the body of such a method called new_envir
|
3
|
+
|
4
|
+
#The main difference between this kind of helpers and a simple file containing definition of functions
|
5
|
+
#is that these functions are executed in the Object module as a normal ruby function does.
|
6
|
+
|
7
|
+
module Dyndoc
|
8
|
+
|
9
|
+
module Ruby
|
10
|
+
|
11
|
+
module Helpers
|
12
|
+
|
13
|
+
# Helpers are functions (in fact methods) used inside a ruby block!
|
14
|
+
# Put here only system helpers!
|
15
|
+
# The user is pleased to create helpers in the dyndoc/helpers directory
|
16
|
+
# and require them by the [#helpers] tag. The following is just an example!
|
17
|
+
|
18
|
+
def hello!(who="everybody")
|
19
|
+
puts "Hello "+who+"!"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
class TemplateManager
|
25
|
+
|
26
|
+
include Helpers
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
module Dyndoc;module Ruby;module Helpers
|
2
|
+
|
3
|
+
|
4
|
+
# preprocessing for parsing a string
|
5
|
+
# convert name to #{name!} in order to be executed!
|
6
|
+
def process_bang(str)
|
7
|
+
str.gsub(/[#{FilterManager.letters}]*\:?[#{FilterManager.letters}]*\!/) {|e| "\#{" + e + "}"}
|
8
|
+
end
|
9
|
+
|
10
|
+
## TODO: improve this by using lookbehind with Regepr
|
11
|
+
def detect_string_inside_string(str)
|
12
|
+
ary=str.split(/(\")/)
|
13
|
+
inside,res=false,[""]
|
14
|
+
ary.each_index do |cpt|
|
15
|
+
if ary[cpt]=="\"" and cpt>0 and ary[cpt-1][-1,1]!="\\" #lookbehind
|
16
|
+
if inside
|
17
|
+
res[-1] += "\"" #end of the previous string
|
18
|
+
res << "" unless cpt == ary.length-1 #new string
|
19
|
+
else
|
20
|
+
res << "\"" #beginning of a string
|
21
|
+
end
|
22
|
+
inside = !inside
|
23
|
+
else
|
24
|
+
res[-1]+=ary[cpt]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
return res
|
28
|
+
end
|
29
|
+
|
30
|
+
def process_rb(str)
|
31
|
+
|
32
|
+
part=detect_string_inside_string(str)
|
33
|
+
#p part
|
34
|
+
part.each_index{|i|
|
35
|
+
delim=(i%2==0 ? "\"" : "\\\"" ) #depending on inside or outside string!!!!
|
36
|
+
part[i].gsub!(/<[\w\.\_\-]+\@>/) {|e|
|
37
|
+
"@vars.extract_raw(#{delim}"+e[1...-1]+"#{delim})[:rb]"
|
38
|
+
}
|
39
|
+
part[i].gsub!(/<([\w\.\_\-]+)((?:[\$\[][^>])+(?:(?!\$>).){0,500})?\$>/) {|e|
|
40
|
+
var=$1+"$"
|
41
|
+
#puts "process_rb:<var$>";p $1;p $2
|
42
|
+
if (arg=$2)
|
43
|
+
#@vars.extract_raw(var)[:r].arg=arg
|
44
|
+
#puts "arg";p arg;p @vars.extract_raw(var)[:r].value_with_arg
|
45
|
+
"@vars.extract_raw(#{delim}"+var+"#{delim})[:r].set_arg(#{delim}"+arg+"#{delim}).value_with_arg"
|
46
|
+
else
|
47
|
+
"@vars.extract_raw(#{delim}"+var+"#{delim})[:r].value"
|
48
|
+
end
|
49
|
+
}
|
50
|
+
|
51
|
+
part[i].gsub!(/<([\w\.\_\-]+)((?:[\&\[][^>])+(?:(?!\&>).){0,500})?\&>/) {|e|
|
52
|
+
var=$1+"&"
|
53
|
+
#puts "process_rb:<var$>";p $1;p $2
|
54
|
+
if (arg=$2)
|
55
|
+
#@vars.extract_raw(var)[:r].arg=arg
|
56
|
+
#puts "arg";p arg;p @vars.extract_raw(var)[:r].value_with_arg
|
57
|
+
"@vars.extract_raw(#{delim}"+var+"#{delim})[:jl].set_arg(#{delim}"+arg+"#{delim}).value_with_arg"
|
58
|
+
else
|
59
|
+
"@vars.extract_raw(#{delim}"+var+"#{delim})[:jl].value"
|
60
|
+
end
|
61
|
+
}
|
62
|
+
#=end
|
63
|
+
part[i].gsub!(/<[\w\.\_\-]+\:>/) {|e|
|
64
|
+
"@vars.extract_raw(#{delim}"+e[1...-2]+"#{delim})[:val][0]"
|
65
|
+
}
|
66
|
+
## dynArray var
|
67
|
+
part[i].gsub!(/<[\w\.\_\-]+\%>/) {|e|
|
68
|
+
#p e[1...-1]
|
69
|
+
#p @vars.extract_raw(e[1...-1])
|
70
|
+
#@vars.extract_raw(e[1...-1])[:rb][0]-= 10
|
71
|
+
#(Dyndoc::Vector.get[@vars.extract_raw(e[1...-1])[:rb].ids(:rb)])[0]=10
|
72
|
+
@vars.extract_raw(e[1...-1])[:rb].wrapper(:rb)
|
73
|
+
}
|
74
|
+
|
75
|
+
}
|
76
|
+
#-| TO DEBUG: Dyndoc.warn part.join("") if part.join("")!=str
|
77
|
+
#p part.join("")
|
78
|
+
str.replace(part.join(""))
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
=begin
|
83
|
+
def process_rb(str)
|
84
|
+
#puts "str";p str
|
85
|
+
str.gsub!(/<[\w\.\_\-]+\@>/) {|e|
|
86
|
+
"@vars.extract_raw(\""+e[1...-1]+"\")[:rb]"
|
87
|
+
}
|
88
|
+
#puts "str(suite)";p str
|
89
|
+
#=begin
|
90
|
+
# str.gsub!(/<([\w\.\_\-]+)((?:[\@\[][^>])+(?:(?!\@>).)*)?\@>/) {|e|
|
91
|
+
#p $1;p $2
|
92
|
+
# arg = ( $2 ? ( $2[0,1]=="@" ? "."+$2[1..-1] : $2 ) : "" )
|
93
|
+
#p arg
|
94
|
+
# "@vars.extract_raw(\""+$1+"@\")[:rb]"+arg
|
95
|
+
# }
|
96
|
+
#=end
|
97
|
+
#=begin
|
98
|
+
# str.gsub!(/<[\w\.\_\-]+\$>/) {|e|
|
99
|
+
# "@vars.extract_raw(\""+e[1...-1]+"\")[:r].value"
|
100
|
+
# }
|
101
|
+
#=end
|
102
|
+
#=begin
|
103
|
+
str.gsub!(/<([\w\.\_\-]+)((?:[\$\[][^>])+(?:(?!\$>).){0,500})?\$>/) {|e|
|
104
|
+
var=$1+"$"
|
105
|
+
#puts "process_rb:<var$>";p $1;p $2
|
106
|
+
if (arg=$2)
|
107
|
+
#@vars.extract_raw(var)[:r].arg=arg
|
108
|
+
#puts "arg";p arg;p @vars.extract_raw(var)[:r].value_with_arg
|
109
|
+
"@vars.extract_raw(\""+var+"\")[:r].set_arg(\""+arg+"\").value_with_arg"
|
110
|
+
else
|
111
|
+
"@vars.extract_raw(\""+var+"\")[:r].value"
|
112
|
+
end
|
113
|
+
}
|
114
|
+
#=end
|
115
|
+
str.gsub!(/<[\w\.\_\-]+\:>/) {|e|
|
116
|
+
"@vars.extract_raw(\""+e[1...-2]+"\")[:val][0]"
|
117
|
+
}
|
118
|
+
#p str
|
119
|
+
end
|
120
|
+
=end
|
121
|
+
|
122
|
+
def process_r(str)
|
123
|
+
#str.gsub!(/<[\w\.\_\-]+\@>/) {|e|
|
124
|
+
# "dynVar[["+e[1...-2]+"]]"
|
125
|
+
#}
|
126
|
+
str2=str.dup
|
127
|
+
## ruby var
|
128
|
+
str.gsub!(/<([\w\.\_\-]+)(\@)?((?:[\@\[][^>])+(?:(?!\@>).){0,500})?\@>/) {|e|
|
129
|
+
#puts "process_r: ("+$1+","+($2 ? $2 : "nil" )+","+($3 ? $3 : "nil")+")"
|
130
|
+
if $3
|
131
|
+
arg =( $3[0,1]=="@" ? "."+$3[1..-1] : $3 )
|
132
|
+
#p arg
|
133
|
+
#p "dynRbVar[\""+$1+"@\",\""+arg+"\"]"
|
134
|
+
"dynVarWithArg[[\""+$1+"\",\""+arg+"\",mode=\"@\"]]"
|
135
|
+
else
|
136
|
+
"dynVar[["+$1+",mode=\"@\","+($2 ? "FALSE" : "TRUE")+"]]"
|
137
|
+
end
|
138
|
+
}
|
139
|
+
## Julia var
|
140
|
+
str.gsub!(/<([\w\.\_\-]+)(\&)?((?:[\&\[][^>])+(?:(?!\&>).){0,500})?\&>/) {|e|
|
141
|
+
#puts "process_r(jl): ("+$1+","+($2 ? $2 : "nil" )+","+($3 ? $3 : "nil")+")"
|
142
|
+
if $3
|
143
|
+
arg =( $3[0,1]=="&" ? "."+$3[1..-1] : $3 ) #TODO: try to apply
|
144
|
+
#p arg
|
145
|
+
#p "dynRbVar[\""+$1+"@\",\""+arg+"\"]"
|
146
|
+
"dynVarWithArg[[\""+$1+"\",\""+arg+"\",mode=\"&\"]]"
|
147
|
+
else
|
148
|
+
"dynVar[["+$1+",mode=\"&\","+($2 ? "FALSE" : "FALSE")+"]]"
|
149
|
+
end
|
150
|
+
}
|
151
|
+
## R var
|
152
|
+
str.gsub!(/<[\w\.\_\-]+\$>/) {|e|
|
153
|
+
".dynStack$rb"+@vars.extract_raw(e[1...-1]).object_id.abs.to_s
|
154
|
+
}
|
155
|
+
## dynArray var
|
156
|
+
str.gsub!(/<[\w\.\_\-]+\%>/) {|e|
|
157
|
+
#p e[1...-1]
|
158
|
+
#p @vars.extract_raw(e[1...-1])
|
159
|
+
@vars.extract_raw(e[1...-1])[:rb].wrapper(:r)
|
160
|
+
}
|
161
|
+
## Dyndoc var
|
162
|
+
str.gsub!(/<[\w\.\_\-]+\:>/) {|e|
|
163
|
+
"dynVar["+e[1...-2]+"]"
|
164
|
+
}
|
165
|
+
#-| TO DEBUG: Dyndoc.warn str if str!=str2
|
166
|
+
end
|
167
|
+
|
168
|
+
def process_jl(str)
|
169
|
+
str2=str.dup
|
170
|
+
## dynArray var
|
171
|
+
str.gsub!(/<[\w\.\_\-]+\%>/) {|e|
|
172
|
+
#p e[1...-1]
|
173
|
+
#p @vars.extract_raw(e[1...-1])
|
174
|
+
@vars.extract_raw(e[1...-1])[:rb].wrapper(:jl)
|
175
|
+
}
|
176
|
+
#-| TO DEBUG: Dyndoc.warn str if str!=str2
|
177
|
+
end
|
178
|
+
|
179
|
+
def clean_block_without_bracket(code)
|
180
|
+
#puts "initial code";p code
|
181
|
+
if code[0][0]==:main and code[0][1] =~ /^\s*\[/ and code[-1][0]==:main and code[-1][1] =~ /\]\s*$/
|
182
|
+
code[0][1].sub!(/^(\s*)(\[)/) {|e| $1}
|
183
|
+
code[-1][1]=code[-1][1].reverse.sub(/^(\s*)(\])/) {|e| $1}.reverse
|
184
|
+
#puts "cleaned code";p code
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
end;end;end
|
@@ -0,0 +1,886 @@
|
|
1
|
+
# Objectif du Scanner:
|
2
|
+
# 1) Gestion du parsing en mode dtag
|
3
|
+
# .) Imbrication des blocs :dtag {%...%}
|
4
|
+
# .) Bloc texte est splitté en une alternance de blocs :main et de blocs :dtag {%...%}
|
5
|
+
# .) Sortie de process en une structure:
|
6
|
+
# ex: [[:main,"..."] [:if, [:args,"...",[...]"],[:main,"..."],:else,[:main,"..."]]
|
7
|
+
# .) NEW: un bloc peut être inséré dans un argument :args
|
8
|
+
# TODO: 1) desescaper le délimiteur dans :args
|
9
|
+
# 2) Gestion du parsing des appels fonctions @{...}@
|
10
|
+
# TODO
|
11
|
+
# 3) TODO: imbrication des modes #{} :{} et :R{} à gérer
|
12
|
+
# RMK: 1) a-t-on besoin d'autant de mode? A réfléchir mais c'est en fonction des priorités d'exécution.
|
13
|
+
# 2) Il y a 4 grands modes d'utilisation:
|
14
|
+
# a) Mode imbriqué blocks dtag : {% ...%}
|
15
|
+
# rmk: exécution d'un block intérieur après le bloc :main précédent du block principal!
|
16
|
+
# b) Mode séquentiel Part tags : %() utiles dans pour le multi-output
|
17
|
+
# c) Mode séquentiel Utilisateur : [#...]
|
18
|
+
# d) Mode imbriqué dans blocks texte : #[r,R,Rb]{}, :[R,r]{} , @{}@
|
19
|
+
# rmk: exécution des blocks intérieurs avant le block principal
|
20
|
+
|
21
|
+
require 'strscan'
|
22
|
+
|
23
|
+
if RUBY_VERSION < "1.9"
|
24
|
+
|
25
|
+
class String
|
26
|
+
alias :byteslice :"[]"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
module Dyndoc
|
32
|
+
class Scanner
|
33
|
+
|
34
|
+
@@type={}
|
35
|
+
|
36
|
+
@@close={"("=>")","["=>"]","{"=>"}"}
|
37
|
+
@@open={"}"=>"{",")"=>"(","]"=>"["}
|
38
|
+
|
39
|
+
#IMPORTANT: start and close delimiters are unique and not useable inside text!
|
40
|
+
#RMK: this differs from the actual CallManager
|
41
|
+
|
42
|
+
attr_reader :scan
|
43
|
+
|
44
|
+
def initialize(type,start=nil,stop=nil,mode=nil,escape=nil)
|
45
|
+
@tag_type=type
|
46
|
+
@tag=@@type[type]
|
47
|
+
@start=@tag[:start] unless start
|
48
|
+
@start=/#{@start}/ if @start.is_a? String
|
49
|
+
@stop=@tag[:stop] unless stop
|
50
|
+
@stop=/#{@stop}/ if @stop.is_a? String
|
51
|
+
@mode=@tag[:mode] unless mode
|
52
|
+
@escape={:start=>@tag[:escape_start],:stop=>@tag[:escape_stop]} unless escape
|
53
|
+
#mode corresponds to @start[@mode[:start],@mode[:length]] and @stop[@mode[:stop],@mode[:length]]
|
54
|
+
init_strange
|
55
|
+
@scan=StringScanner.new("")
|
56
|
+
end
|
57
|
+
|
58
|
+
######################################
|
59
|
+
# stack is a sequence of delimiters
|
60
|
+
# clean_stack selects only the associated open and closed delimiters!
|
61
|
+
#####################################
|
62
|
+
def clean_stack(stack)
|
63
|
+
open_stack,keep=[],{}
|
64
|
+
stack.each do |elt|
|
65
|
+
if elt[1]==1
|
66
|
+
open_stack << elt
|
67
|
+
else
|
68
|
+
if open_stack.empty?
|
69
|
+
##too many closed delimiters
|
70
|
+
else
|
71
|
+
keep[elt]=true
|
72
|
+
keep[open_stack.pop]=true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
=begin
|
77
|
+
if Dyndoc.cfg_dir[:debug]
|
78
|
+
tmp=stack.select{|elt| !keep[elt]}.select{|e| @tag_type==:call and e[2] and e[1]==1 and e[2]!='{'}
|
79
|
+
begin p @txt;p tmp end unless tmp.empty?
|
80
|
+
end
|
81
|
+
=end
|
82
|
+
stack.select{|elt| keep[elt]}
|
83
|
+
end
|
84
|
+
|
85
|
+
def token_stack
|
86
|
+
@scan.string=@txt
|
87
|
+
@scan.pos=0
|
88
|
+
stack,s=[],0
|
89
|
+
mode=-2 #stop
|
90
|
+
begin
|
91
|
+
if mode!=-1
|
92
|
+
p1=@scan.check_until(@start)
|
93
|
+
if p1
|
94
|
+
s1=@scan.pre_match.size
|
95
|
+
m1=@scan.matched
|
96
|
+
end
|
97
|
+
end
|
98
|
+
if mode!=1
|
99
|
+
p2=@scan.check_until(@stop)
|
100
|
+
if p2
|
101
|
+
s2=@scan.pre_match.size
|
102
|
+
m2=@scan.matched
|
103
|
+
end
|
104
|
+
end
|
105
|
+
if p1 and p2
|
106
|
+
mode=(s1<s2 ? 1 : -1)
|
107
|
+
elsif p2 and !p1
|
108
|
+
mode=-1
|
109
|
+
elsif !p2 and p1
|
110
|
+
mode=-3 #error
|
111
|
+
elsif !p2 and !p1
|
112
|
+
mode=-2 #stop
|
113
|
+
end
|
114
|
+
if mode==1
|
115
|
+
stack << [s1,mode,m1] unless @escape[:start] and @escape[:start].include? m1
|
116
|
+
@scan.scan_until(@start)
|
117
|
+
elsif mode==-1
|
118
|
+
s=s2
|
119
|
+
stack << [s2,mode,m2] unless @escape[:stop] and @escape[:stop].include? m2
|
120
|
+
@scan.scan_until(@stop)
|
121
|
+
end
|
122
|
+
s=@scan.pos
|
123
|
+
end while mode>-2
|
124
|
+
return clean_stack(stack)
|
125
|
+
end
|
126
|
+
|
127
|
+
def init_atom
|
128
|
+
if @tag[:atom]
|
129
|
+
@txt.gsub!(@tag[:atom][:match]){|w|
|
130
|
+
m=@tag[:atom][:match].match(w)
|
131
|
+
res=""
|
132
|
+
(1...m.size).each{|i|
|
133
|
+
res << (@tag[:atom][:replace][i] ? @tag[:atom][:replace][i] : m[i])
|
134
|
+
}
|
135
|
+
res
|
136
|
+
}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def tokenize(txt)
|
141
|
+
@txt=txt
|
142
|
+
init_atom
|
143
|
+
stack=token_stack
|
144
|
+
#p txt
|
145
|
+
#p stack
|
146
|
+
stack2=[]
|
147
|
+
root=block={:inside=>[]} #init bloc
|
148
|
+
while !stack.empty?
|
149
|
+
elt=stack.shift
|
150
|
+
#puts "stack2";p stack2
|
151
|
+
if elt[1]==1
|
152
|
+
#new bloc
|
153
|
+
parent=block
|
154
|
+
block={:type=>elt[2][0...-1],:start=>elt[0],:inside=>[]}
|
155
|
+
stack2 << [block,parent]
|
156
|
+
elsif elt[1]==-1
|
157
|
+
block,parent=stack2.pop
|
158
|
+
block[:stop]=elt[0]+elt[2].size-1
|
159
|
+
if parent[:start]
|
160
|
+
block[:start] -= parent[:start]
|
161
|
+
block[:stop] -= parent[:start]
|
162
|
+
end
|
163
|
+
parent[:inside] << block
|
164
|
+
block=parent
|
165
|
+
end
|
166
|
+
end
|
167
|
+
return (@token={:txt=> @txt,:inside=> (root[:inside])})
|
168
|
+
end
|
169
|
+
|
170
|
+
## Extract a structure with a root block which is a text block and the child blocks which are dtag blocks.
|
171
|
+
@@strange="_[_?_]_"
|
172
|
+
|
173
|
+
def init_strange(strange=@@strange)
|
174
|
+
@strange=strange
|
175
|
+
@re_strange=/#{Regexp.escape(@strange)}/
|
176
|
+
@re_strange2=/(#{Regexp.escape(@strange)})/
|
177
|
+
end
|
178
|
+
|
179
|
+
def extract(res=nil,txt=nil,type=nil)
|
180
|
+
if res
|
181
|
+
start=0
|
182
|
+
txt2=""
|
183
|
+
ind=0
|
184
|
+
res2=res.map{|r|
|
185
|
+
txt2 << txt[start...(r[:start])]
|
186
|
+
txt2 << @@strange
|
187
|
+
ind += 1
|
188
|
+
r2={}
|
189
|
+
start=r[:stop]+1
|
190
|
+
if r[:inside].empty?
|
191
|
+
r2[:txt]=txt[(r[:start])..(r[:stop])]
|
192
|
+
r2[:type]=r[:type]
|
193
|
+
r2
|
194
|
+
else
|
195
|
+
tmp=extract(r[:inside],txt[(r[:start])..(r[:stop])],r[:type])
|
196
|
+
tmp
|
197
|
+
end
|
198
|
+
}
|
199
|
+
txt2 << txt[start..-1]
|
200
|
+
{:txt=>txt2,:type=>type,:inside=> res2}
|
201
|
+
else
|
202
|
+
res=@token[:inside].dup
|
203
|
+
return extract(res,@token[:txt])
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def rebuild_after_filter(res,filter=nil)
|
208
|
+
txt=""
|
209
|
+
start=0
|
210
|
+
#p res
|
211
|
+
parts=res[:txt].split(@re_strange,-1)
|
212
|
+
##puts "parts";p parts
|
213
|
+
##puts "inside";p res[:inside]
|
214
|
+
res[:inside].map do |e|
|
215
|
+
txt << parts.shift
|
216
|
+
|
217
|
+
txt2= (e[:inside] ? rebuild_after_filter(e,filter) : e[:txt] )
|
218
|
+
#puts "txt2";p txt2; p [res[:type],e[:type]]
|
219
|
+
#IMPORTANT: process has to have as the second argument e[:type] corresponding to the inside_type and as the third argument res[:type] corresponding to the out_type
|
220
|
+
##Dyndoc.warn "scan",txt2,e[:type],res[:type],(filter ? filter.process(txt2,e[:type],res[:type]) : txt2)
|
221
|
+
txt2=((filter and !(txt2=~/\[HTML\]/)) ? filter.process(txt2,e[:type],res[:type]) : txt2)
|
222
|
+
##p txt2
|
223
|
+
txt << txt2
|
224
|
+
end
|
225
|
+
#puts "txt";p txt
|
226
|
+
txt << parts.shift unless parts.empty?
|
227
|
+
txt
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
|
232
|
+
class CallScanner < Scanner
|
233
|
+
|
234
|
+
@@type[:call]={
|
235
|
+
:start=>/\\?(?:\#|\#\#|@|#F|#R|#r|\:R|\:r|#Rb|#rb|\:|\:Rb|\:rb|\:jl|#jl)?\{/,
|
236
|
+
:stop=> /\\?\}/,
|
237
|
+
:mode=>{:start=>-1,:stop=>0,:length=>1},
|
238
|
+
:escape_start=>['\{'], #doivent être parsable dans start
|
239
|
+
:escape_stop=>['\}'], #doivent être parsable dans stop
|
240
|
+
}
|
241
|
+
|
242
|
+
def initialize(type=:call,start=nil,stop=nil,mode=nil,escape=nil)
|
243
|
+
super
|
244
|
+
@type_stop_filter="#!"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
class DevTagScanner < Scanner
|
249
|
+
|
250
|
+
=begin TO_REMOVE
|
251
|
+
@@type[:dtag] = {
|
252
|
+
:start=>'\{%(\w*)',
|
253
|
+
:stop=> '%\}',
|
254
|
+
:keyword=>['%',''],
|
255
|
+
:block=> '[\]|]',
|
256
|
+
:mode=>{:start=>0,:stop=>-1,:length=>1}
|
257
|
+
}
|
258
|
+
=end
|
259
|
+
@@type[:dtag] = {
|
260
|
+
:start=>'\{[\#\@]([\w\:\|-]*[<>]?[=?!><]?(\.\w*)?)\]',
|
261
|
+
:stop=> '\[[\#\@]([\w\:\|-]*[<>]?[=?!><]?)\}',
|
262
|
+
:atom=>{:match=>/(\{[\#\@][\w\:\|]*)([\#\@]\})/,:replace=>{2=>"][#}"}},
|
263
|
+
:block=> '\]', #no longer |
|
264
|
+
:keyword=>['\[[\#\@]','\]'],
|
265
|
+
:mode=>{:start=>0,:stop=>-1,:length=>1}
|
266
|
+
}
|
267
|
+
|
268
|
+
def get_tag_blck
|
269
|
+
@@tagblck_set
|
270
|
+
end
|
271
|
+
|
272
|
+
|
273
|
+
def initialize(type=:dtag,start=nil,stop=nil,mode=nil,escape=nil)
|
274
|
+
super
|
275
|
+
init_tag(@tag_type) if [:dtag].include? @tag_type
|
276
|
+
end
|
277
|
+
|
278
|
+
@@tagblck_set=[:<<,:<,:do,:>>,:>,:">!",:out,:nl,:"\\n",:"r<",:"R<",:"rb<",:"m<",:"M<",:"jl<",:"r>>",:"R>>",:rverb,:"rb>>",:rbverb,:"jl>>",:jlverb,:rout,:"r>",:"R>",:"rb>",:"m>",:"M>",:"jl>",:"_<",:"_>",:"__>",:"html>",:"tex>",:"txtl>",:"ttm>",:"md>",:"adoc>",:tag,:"??",:"?",:yield,:"=",:"-",:+,:"%"]
|
279
|
+
#Rmk: when a symbol is included in another one, you have to place it before! Ex: :>> before :> and also :<< before :<
|
280
|
+
|
281
|
+
@@tagblck_dyndoc_set = [:main,:content,:before,:after,:require,:helpers,:preamble,:postamble,:style,:title,:path,:first,:last,:default,:cfg]
|
282
|
+
@@tagblck_tex_set=[:class,:optclass,:package,:texinputs]
|
283
|
+
@@tagblck_html_set=[:js,:css,:header,:footer]
|
284
|
+
|
285
|
+
TXT_DTAG=[:txt,:code,:>,:<,:<<]
|
286
|
+
|
287
|
+
@@dtag={
|
288
|
+
:dtag => {
|
289
|
+
:instr=>["newBlck","input","require","hide","format","txt",">","<","<<",">>","code","verb","if","unless","for","loop","case","var","set","def","func","meth","new","super","do","out","blck","blckAnyTag","saved","b>","call","R","r","m","M","jl","renv","rverb","rbverb","jlverb","rout","rb","eval","ifndef","tags","keys","opt","document","yield","get","part"],
|
290
|
+
:alias=>{
|
291
|
+
:vars=>:var,
|
292
|
+
:dyn=>:eval,
|
293
|
+
:rmk=>:hide,
|
294
|
+
:static => :saved,
|
295
|
+
:comment=>:hide,
|
296
|
+
:>> => [:blck,:>],
|
297
|
+
#:"b>" => [:blck, :>],
|
298
|
+
:"rb>" => [:blck, :"rb>"],
|
299
|
+
:"R>" => [:blck, :"R>"],
|
300
|
+
:"jl>" => [:blck, :"jl>"],
|
301
|
+
:"jl>>" => [:blck, :"jl>>"],
|
302
|
+
:"rb<" => [:blck, :"rb<"],
|
303
|
+
:"R<" => [:blck, :"R<"],
|
304
|
+
:"jl<" => [:blck, :"jl<"],
|
305
|
+
:"r>>" => [:blck, :"r>>"],
|
306
|
+
:"R>>" => [:blck, :"r>>"],
|
307
|
+
:"*<" => [:blck, :"*<"],
|
308
|
+
:"*>" => [:blck, :"*>"],
|
309
|
+
:"_>" => [:blck, :"_>"],
|
310
|
+
:"tex>" => [:blck, :"tex>"],
|
311
|
+
:"html>" => [:blck, :"html>"],
|
312
|
+
:"txtl>" => [:blck, :"txtl>"],
|
313
|
+
:"md>" => [:blck, :"md>"],
|
314
|
+
:"adoc>" => [:blck, :"adoc>"],
|
315
|
+
:"ttm>" => [:blck, :"ttm>"]
|
316
|
+
},
|
317
|
+
:empty_keyword=>["?","empty"],
|
318
|
+
:keyword=>{
|
319
|
+
:document => @@tagblck_dyndoc_set + @@tagblck_tex_set + @@tagblck_html_set,
|
320
|
+
:if=> [:else,:elsif,:if,:unless],
|
321
|
+
:unless=> [:else,:elsif,:if,:unless],
|
322
|
+
:for=>[],
|
323
|
+
:loop=>[:break],
|
324
|
+
:case=>[:when,:else],
|
325
|
+
:var=>[:","],
|
326
|
+
:set=>[],
|
327
|
+
:def=>[:",",:binding],
|
328
|
+
:meth=>[:","],
|
329
|
+
:new=>[:",",:of,:in,:blck],
|
330
|
+
:super=>[:",",:parent,:blck],
|
331
|
+
:do=>[],
|
332
|
+
:out=>[],
|
333
|
+
:blck=>[],
|
334
|
+
:saved=>[],
|
335
|
+
:call=> [:",",:blck,:"->"],
|
336
|
+
:style=> [:of,:",",:blck,:default],
|
337
|
+
:input=>[:","],
|
338
|
+
:r=>[:in],
|
339
|
+
:rverb=>[:in,:mode],
|
340
|
+
:rbverb=>[:mode],
|
341
|
+
:jlverb=>[:mode],
|
342
|
+
:rout=>[:in,:mode],
|
343
|
+
:eval=>[:to],
|
344
|
+
:ifndef=>[:<<],
|
345
|
+
:tags=>[:when],
|
346
|
+
:keys=> [],
|
347
|
+
:part=>[],
|
348
|
+
:get=>[:blck]
|
349
|
+
},
|
350
|
+
:keyword_reg=>{ #to overpass :keyword
|
351
|
+
:new=> '[%.\w,><?=+:-]+',
|
352
|
+
:call=> '[%.\w,><?=+:-]+(?:\@|\$)?',
|
353
|
+
:style=>'[%.\w,><?=+:-]+',
|
354
|
+
:newBlck=>'[%.\w,><?=+:-]+',
|
355
|
+
:blckAnyTag=>'[%.\w,><?=+:-]+',
|
356
|
+
},
|
357
|
+
:with_tagblck =>[:document,:if,:unless,:for,:loop,:case,:set,:def,:meth,:new,:super,:do,:out,:blck,:saved,:call,:style,:rverb,:rbverb,:jlverb,:rout,:tags,:keys,:part],
|
358
|
+
:named_tag=>{
|
359
|
+
#=begin
|
360
|
+
:> => {:tag=>'(_TAG_)(?:[^\]]+)?',:rest=>/^>([^\]]*)$/},
|
361
|
+
:>> => {:tag=>'(_TAG_)(?:[^\]]+)?',:rest=>/^>>([^\]]*)$/},
|
362
|
+
:"r>" => {:tag=>'(_TAG_)(?:[^\]]+)?',:rest=>/^r>([^\]]*)$/},
|
363
|
+
:"rb>" => {:tag=>'(_TAG_)(?:[^\]]+)?',:rest=>/^rb>([^\]]*)$/},
|
364
|
+
:"=" => {:tag=>'(_TAG_)(?:[^\]]+)?',:rest=>/^=([^\]]*)$/}
|
365
|
+
#=end
|
366
|
+
},
|
367
|
+
:mode_arg=>:next_block,
|
368
|
+
:tag_code=>[:code,:<,:>,:<<,:txt], #used for arg mode!
|
369
|
+
:arg=>[:if,:unless,:elsif,:for,:case,:def,:func,:meth,:new,:super,:call,:input,:when,:break,:set,:style,:keys,:"?",:"rb<",:"r<",:"R<",:"m<",:"M<",:"jl<"],
|
370
|
+
:blck=>{
|
371
|
+
:instr=>[:document,:if,:unless,:case,:loop,:set,:tag,:keys,:rverb,:rbverb,:jlverb,:for],
|
372
|
+
:keyword=>{
|
373
|
+
:document=>@@tagblck_dyndoc_set + @@tagblck_tex_set + @@tagblck_html_set,
|
374
|
+
:set=>[:set],
|
375
|
+
:if=>[:if,:unless,:elsif,:else],
|
376
|
+
:unless=>[:if,:unless,:elsif,:else],
|
377
|
+
:case=>[:when,:else],
|
378
|
+
:loop=>[:loop,:break],
|
379
|
+
:tags=>[:when],
|
380
|
+
:rverb=>[:rverb,:in,:mode],
|
381
|
+
:rbverb=>[:rbverb,:mode],
|
382
|
+
:jlverb=>[:jlverb,:mode],
|
383
|
+
:rout=>[:rout,:in,:mode]
|
384
|
+
}
|
385
|
+
},
|
386
|
+
:style=>"@" #specify that the scanner recognize a style instead a call when blck[:type].include? "@"
|
387
|
+
}
|
388
|
+
}
|
389
|
+
|
390
|
+
attr_accessor :dtag
|
391
|
+
|
392
|
+
def init_tag(type=:dtag)
|
393
|
+
@dtag=@@dtag[type]
|
394
|
+
@tag_instr=@dtag[:instr]+@dtag[:alias].keys.map{|e| e.to_s}
|
395
|
+
@tag_alias=@dtag[:alias]
|
396
|
+
@tag_keyword=@dtag[:keyword]
|
397
|
+
@tag_keyword_reg=@dtag[:keyword_reg]
|
398
|
+
@tag_arg=@dtag[:arg]
|
399
|
+
@tag_code=(@dtag[:tag_code] ? @dtag[:tag_code] : [] )
|
400
|
+
@tag_style=@dtag[:style]
|
401
|
+
@tag_blck=@dtag[:blck]
|
402
|
+
## deal with fixed blck tags
|
403
|
+
@named_tags=[]
|
404
|
+
@@keystagblck=@@tagblck_set.map{|e| complete_tag(e)}.compact.join("|") #only once!
|
405
|
+
@@named_tags_blck=@named_tags
|
406
|
+
end
|
407
|
+
|
408
|
+
def merge_tag(dtag)
|
409
|
+
if dtag
|
410
|
+
@tag_instr += dtag[:instr] if dtag[:instr]
|
411
|
+
@tag_instr += dtag[:alias].keys.map{|e| e.to_s} if dtag[:alias]
|
412
|
+
@tag_alias.merge!(dtag[:alias]) if dtag[:alias]
|
413
|
+
@tag_keyword.merge!(dtag[:keyword]) if dtag[:keyword]
|
414
|
+
@tag_keyword_reg.merge!(dtag[:keyword_reg]) if dtag[:keyword_reg]
|
415
|
+
@tag_arg += dtag[:arg] if dtag[:arg]
|
416
|
+
if dtag[:blck]
|
417
|
+
@tag_blck[:instr] += dtag[:blck][:instr] if dtag[:blck][:instr]
|
418
|
+
@tag_blck[:keyword].merge!(dtag[:blck][:keyword]) if dtag[:blck][:keyword]
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
## update an existing tag keywork (ex: document for html structure by adding #css #js #menu or anything needed in the model)
|
424
|
+
def update_tag_keyword(keyword,tags_set=[],args={})
|
425
|
+
@tag_keyword[keyword] += tags_set
|
426
|
+
@tag_blck[:keyword][keyword] += new_tags_set if args[:mode] && args[:mode] == :blck
|
427
|
+
end
|
428
|
+
|
429
|
+
## Types of result block:
|
430
|
+
## 1) :main
|
431
|
+
## 2) :args
|
432
|
+
## 3) :instr (:if, :case, ...)
|
433
|
+
## Types of parsed block:
|
434
|
+
## 1) :text -> main block alternating text and dtag blocks
|
435
|
+
## 2) :dtag -> {% ...%}
|
436
|
+
|
437
|
+
def find_args(inside)
|
438
|
+
## Instruction delimiter
|
439
|
+
delim=@block[@scan.pos,1]
|
440
|
+
#p delim
|
441
|
+
@scan.pos += delim.bytesize #.length
|
442
|
+
st=@scan.pos
|
443
|
+
delim=@@close[delim] if @@close[delim]
|
444
|
+
#p delim
|
445
|
+
## Arguments
|
446
|
+
begin
|
447
|
+
@scan.scan_until(/#{Regexp.escape(delim)}/)
|
448
|
+
end while @block[@scan.pos-2,1]=='\\'
|
449
|
+
sp=@scan.pos - delim.bytesize - 1 #.length - 1
|
450
|
+
args=@block.byteslice(st..sp) #@block[st..sp]
|
451
|
+
inside2=[]
|
452
|
+
(1..(args.split(@re_strange,-1).length-1)).each{ inside2 << inside.shift }
|
453
|
+
return [:args,{:txt=>args,:inside=>inside2}]
|
454
|
+
end
|
455
|
+
|
456
|
+
def find_text(from,key,inside)
|
457
|
+
#p ["key=",key]
|
458
|
+
res,to=nil,nil
|
459
|
+
pre=(@next_pre ? @next_pre : nil )
|
460
|
+
@next_pre=nil
|
461
|
+
if @scan[1].nil? or @scan[1].empty? or @is_arg
|
462
|
+
#p ["key=",key,@tag_selected]
|
463
|
+
if @tag_selected
|
464
|
+
@next_pre=key[2...-1].scan(@dtag[:named_tag][@tag_selected.to_sym][:rest])[0][0]
|
465
|
+
@next_pre=nil if @next_pre.empty?
|
466
|
+
end
|
467
|
+
@scan.scan_until(/#{Regexp.escape(key)}/)
|
468
|
+
to=@scan.pre_match.bytesize #.length
|
469
|
+
##Dyndoc.warn "TOOOOOOOOOOO",[@scan.pre_match,to]
|
470
|
+
res=@block.byteslice(from...to) #@block[from...to]
|
471
|
+
else
|
472
|
+
#p ["pre_match=",@scan.pre_match,"to=",@scan.pre_match.bytesize]
|
473
|
+
to=@scan.pre_match.bytesize #.length
|
474
|
+
##Dyndoc.warn "TOOOOOOOOOOO2222",[@scan.pre_match,to]
|
475
|
+
delim2=@scan[1]
|
476
|
+
delim2=@@open[delim2] if @@open[delim2]
|
477
|
+
#p ["delim2=",delim2,/#{Regexp.escape(delim2)}/]
|
478
|
+
#p @block[from...-1]
|
479
|
+
@scan.exist?(/#{Regexp.escape(delim2)}/)
|
480
|
+
to_tmp=@scan.pre_match.bytesize #.length
|
481
|
+
#p ["to_tmp=",to_tmp]
|
482
|
+
## pre=@block[from...to_tmp].strip unless pre
|
483
|
+
#p [:pre,pre]
|
484
|
+
pre=@block.byteslice(from...to_tmp).strip unless pre
|
485
|
+
#p ["pre=",pre]
|
486
|
+
from=to_tmp+1
|
487
|
+
#p ["key:",key,@scan.matched,from,@block[from-1,1]]
|
488
|
+
@scan.scan_until(/#{@tag[:block]}\s*#{Regexp.escape(key)}/)
|
489
|
+
=begin
|
490
|
+
@scan.scan_until(/[\]|]\s*#{key}/)
|
491
|
+
=end
|
492
|
+
#p ["matched=",@scan.matched]
|
493
|
+
#p @scan.pre_match
|
494
|
+
#to=@scan.pre_match.length
|
495
|
+
res=@block.byteslice(from...to) #does not work for ruby2 => @block[from...to]
|
496
|
+
pre=nil if pre.empty?
|
497
|
+
#p ["res=",from,to,res,@block.byteslice(from...to)]
|
498
|
+
end
|
499
|
+
inside2=[]
|
500
|
+
(1..(res.split(@re_strange,-1).length-1)).each{ inside2 << inside.shift }
|
501
|
+
return [:text,{:name=>pre,:txt=>res,:inside=>inside2}] if pre
|
502
|
+
return [(@is_arg ? :args : :text),{:txt=>res,:inside=>inside2}]
|
503
|
+
end
|
504
|
+
|
505
|
+
|
506
|
+
def complete_tag(key,add=true)
|
507
|
+
#Regexp.escape(key.to_s)+((@dtag[:named_tag][key]) ? @dtag[:named_tag][key] : "")
|
508
|
+
if @dtag[:named_tag][key]
|
509
|
+
if add
|
510
|
+
@named_tags << key
|
511
|
+
return nil
|
512
|
+
else
|
513
|
+
@dtag[:named_tag][key][:tag].sub("_TAG_",Regexp.escape( key.to_s ))
|
514
|
+
end
|
515
|
+
else
|
516
|
+
return Regexp.escape(key.to_s)
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
def check_until_for_named_tags
|
521
|
+
#if res
|
522
|
+
@named_tags.each_index{|i|
|
523
|
+
if @scan[3+i]
|
524
|
+
@tag_selected=@scan[3+i].to_sym
|
525
|
+
#puts "here we go: #{@tag_selected}"
|
526
|
+
break
|
527
|
+
end
|
528
|
+
}
|
529
|
+
#end
|
530
|
+
#return res
|
531
|
+
end
|
532
|
+
|
533
|
+
## ATTENTION: Ne pas faire de recurrence dans convert_block à cause de @scan! qui est en unique exemplaire!
|
534
|
+
def convert_block(blck)
|
535
|
+
#puts "split_block";p blck
|
536
|
+
@block= blck[:txt]
|
537
|
+
inside=blck[:inside]
|
538
|
+
style=blck[:type].include? @tag_style
|
539
|
+
pre_res=[]
|
540
|
+
res=[]
|
541
|
+
=begin
|
542
|
+
## Mode -> unused now!
|
543
|
+
mode=@block[0,@mode[:length]]
|
544
|
+
mode2=(@@close[mode] ? @@close[mode] : mode)
|
545
|
+
=end
|
546
|
+
@scan.string=@block
|
547
|
+
@scan.pos=0
|
548
|
+
## Instruction
|
549
|
+
#@scan.scan_until(/(?:#{@tag_instr.join("|")})/)
|
550
|
+
@scan.scan_until(@start)
|
551
|
+
instr=@scan[1] #@scan.matched
|
552
|
+
#p [:instr,instr]
|
553
|
+
# next block is a arg block?
|
554
|
+
@is_arg=false
|
555
|
+
if @tag_instr.include? instr
|
556
|
+
instr=instr.to_sym
|
557
|
+
instr=@tag_alias[instr] if @tag_alias.include? instr
|
558
|
+
if instr.is_a? Array
|
559
|
+
res += instr
|
560
|
+
instr=instr[0]
|
561
|
+
else
|
562
|
+
res << instr
|
563
|
+
end
|
564
|
+
if (@tag_arg+@tag_code).include? instr
|
565
|
+
case @dtag[:mode_arg]
|
566
|
+
when :find
|
567
|
+
res << find_args(inside)
|
568
|
+
when :next_block
|
569
|
+
@is_arg=true
|
570
|
+
end
|
571
|
+
end
|
572
|
+
else
|
573
|
+
instr2=(style ? :style : :call)
|
574
|
+
#pour un éventuel ajout de > ou < à la fin
|
575
|
+
if [">","<"].include? instr[-1,1]
|
576
|
+
instr2,instr=(instr2.to_s+instr[-1,1]).to_sym,instr[0...-1]
|
577
|
+
end
|
578
|
+
res << instr2 << [:args, {:txt=>instr,:inside=>[]}]
|
579
|
+
instr=instr2
|
580
|
+
end
|
581
|
+
## Text block
|
582
|
+
## find keywords
|
583
|
+
from=true
|
584
|
+
#p "todoooo"
|
585
|
+
while from
|
586
|
+
from=@scan.pos
|
587
|
+
#p @tag_keyword[instr]
|
588
|
+
#p /(#{@tag[:block]}?)\s*(#{@tag[:keyword][0]}(?:#{keytags=(@tag_keyword[instr] ? @tag_keyword[instr] : [] ).map{|e| Regexp.escape(e.to_s)}.join("|")})#{@dtag[:empty_keyword][0]}#{@tag[:keyword][1]})/
|
589
|
+
tag_keyword=nil
|
590
|
+
if @dtag[:empty_keyword][0].empty?
|
591
|
+
#no empty tag!
|
592
|
+
tag_keyword=@tag_keyword[instr] if @tag_keyword[instr]
|
593
|
+
else
|
594
|
+
tag_keyword=(@tag_keyword[instr] ? @tag_keyword[instr] : [] )
|
595
|
+
end
|
596
|
+
keytags=nil
|
597
|
+
@named_tags,@tag_selected=[],nil
|
598
|
+
if tag_keyword
|
599
|
+
#p tag_keyword
|
600
|
+
if @tag_keyword_reg and @tag_keyword_reg[instr]
|
601
|
+
tag_keyword=@tag_keyword_reg[instr]
|
602
|
+
blocktag_reg=/(#{@tag[:block]}?)\s*(#{@tag[:keyword][0]}#{tag_keyword}#{@dtag[:empty_keyword][0]}#{@tag[:keyword][1]})/
|
603
|
+
tag_reg=/#{tag_keyword}/
|
604
|
+
else
|
605
|
+
keytags=tag_keyword.map{|e| complete_tag(e)}.compact.join("|")
|
606
|
+
#puts "keytags(1)";p keytags
|
607
|
+
#puts "INSTR="; p instr
|
608
|
+
if @dtag[:with_tagblck].include? instr
|
609
|
+
keytags += "|" unless keytags.empty?
|
610
|
+
keytags += @@keystagblck
|
611
|
+
@named_tags += @@named_tags_blck
|
612
|
+
end
|
613
|
+
##puts "keytags(2)";p keytags
|
614
|
+
tag_reg=/(?:#{keytags})/
|
615
|
+
unless @named_tags.empty?
|
616
|
+
keytags += "|"+(@named_tags.map{|tag| complete_tag(tag,nil)}.join("|"))
|
617
|
+
end
|
618
|
+
##Dyndoc.warn "keytags",keytags
|
619
|
+
blocktag_reg=/(#{@tag[:block]}?)\s*(#{@tag[:keyword][0]}(?:#{keytags})#{@dtag[:empty_keyword][0]}#{@tag[:keyword][1]})/
|
620
|
+
end
|
621
|
+
##Dyndoc.warn "to scan", @scan.string[@scan.pos..-1]
|
622
|
+
##Dyndoc.warn "tag_reg",[blocktag_reg,tag_reg]
|
623
|
+
end
|
624
|
+
if (tag_keyword and (@scan.check_until(blocktag_reg))) #or (!@named_tags.empty? and check_until_for_named_tags)
|
625
|
+
check_until_for_named_tags unless @named_tags.empty?
|
626
|
+
key=@scan[2]
|
627
|
+
##Dyndoc.warn "keyword",[key,@scan[0],@scan[1],@scan[2]]
|
628
|
+
##Dyndoc.warn "pre_math,tag_selected",[@scan.pre_match,@tag_selected] if key=="[#tag]"
|
629
|
+
res << find_text(from,key,inside)
|
630
|
+
@is_arg=false if @is_arg
|
631
|
+
##Dyndoc.warn "key(AV)",[key,tag_reg] if key=="[#tag]"
|
632
|
+
if @tag_selected
|
633
|
+
#puts "tag_selected";p @tag_selected
|
634
|
+
res << (key=@tag_selected)
|
635
|
+
else
|
636
|
+
#key=tag_reg.match(key)[0]
|
637
|
+
key= key.scan(tag_reg)[0]
|
638
|
+
##Dyndoc.warn "key(AP)",key if key=="tag"
|
639
|
+
res << (key=key.to_sym) if key and !key.empty?
|
640
|
+
end
|
641
|
+
#res << (key=key[1..-1].to_sym)
|
642
|
+
#p @tag_arg
|
643
|
+
if @tag_arg.include? key #without @tag_code inside a block
|
644
|
+
case @dtag[:mode_arg]
|
645
|
+
when :find
|
646
|
+
res << find_args(inside)
|
647
|
+
from=@scan.pos
|
648
|
+
when :next_block
|
649
|
+
@is_arg=true
|
650
|
+
end
|
651
|
+
end
|
652
|
+
else
|
653
|
+
#Last text block!
|
654
|
+
#p /(#{@tag[:block]}?)\s*(#{@tag[:stop]})/
|
655
|
+
@scan.check_until(/(#{@tag[:block]}?)\s*(#{@tag[:stop]})/)
|
656
|
+
#puts "last"; p @scan[2];p @scan[0]; p @scan[1]
|
657
|
+
#p @scan.pre_match
|
658
|
+
res << find_text(from,@scan[2],inside)
|
659
|
+
#p res
|
660
|
+
from=false
|
661
|
+
end
|
662
|
+
#puts "from2";p from
|
663
|
+
end
|
664
|
+
#puts "res";p res
|
665
|
+
return res
|
666
|
+
end
|
667
|
+
|
668
|
+
def parse_block(blck)
|
669
|
+
res=convert_block(blck)
|
670
|
+
#puts "res";p res
|
671
|
+
##Stop scan when :txt instruction to avoid parsing!
|
672
|
+
if TXT_DTAG.include? res[0]
|
673
|
+
res2=[res[0],rebuild_after_filter(res[1][1])]
|
674
|
+
# NO MORE POSSIBLE! res2 << res[1][1][:name] if res[1][1][:name]
|
675
|
+
#p res2
|
676
|
+
return res2
|
677
|
+
end
|
678
|
+
res2=[]
|
679
|
+
res.each{|e|
|
680
|
+
#p e
|
681
|
+
if e.is_a? Array
|
682
|
+
case e[0]
|
683
|
+
when :args
|
684
|
+
res2 << parse_args(e[1])
|
685
|
+
when :text
|
686
|
+
res2 += parse_text(e[1])
|
687
|
+
end
|
688
|
+
else
|
689
|
+
res2 << e
|
690
|
+
end
|
691
|
+
}
|
692
|
+
#p res2
|
693
|
+
#make :blck block if necessary
|
694
|
+
res2=ajust_with_blck(res2)
|
695
|
+
#puts "res2";p res2
|
696
|
+
return res2
|
697
|
+
end
|
698
|
+
|
699
|
+
def ajust_with_blck(res)
|
700
|
+
return res unless @tag_blck[:keyword].include? res[0]
|
701
|
+
instr=@tag_blck[:keyword][res[0]]
|
702
|
+
res_blck,blck=[],nil
|
703
|
+
begin
|
704
|
+
b=res.shift
|
705
|
+
if instr.include? b
|
706
|
+
#create the :blck block
|
707
|
+
res_blck << b
|
708
|
+
#is there an :args block?
|
709
|
+
res_blck << res.shift if @tag_arg.include? b
|
710
|
+
#if no first tag_blck then put the default :out tag
|
711
|
+
blck=[:blck]
|
712
|
+
blck << :out unless @@tagblck_set.include? res[0]
|
713
|
+
else
|
714
|
+
if blck
|
715
|
+
blck << b
|
716
|
+
else
|
717
|
+
#needed for example :case block
|
718
|
+
res_blck << b
|
719
|
+
end
|
720
|
+
#is the end of blck?
|
721
|
+
if res.empty? or (instr.include? res[0])
|
722
|
+
res_blck << blck if blck
|
723
|
+
blck=nil
|
724
|
+
end
|
725
|
+
end
|
726
|
+
end until res.empty?
|
727
|
+
res_blck
|
728
|
+
end
|
729
|
+
|
730
|
+
def parse_args(blck)
|
731
|
+
res=[:args]
|
732
|
+
#puts ":args";p blck[:txt]
|
733
|
+
parts=blck[:txt].split(@re_strange,-1)
|
734
|
+
#p parts
|
735
|
+
#p blck[:inside]
|
736
|
+
blck[:inside].map do |e|
|
737
|
+
res << [:main,parts.shift]
|
738
|
+
res << parse_block(e)
|
739
|
+
end
|
740
|
+
res << [:main,parts.shift]
|
741
|
+
res
|
742
|
+
end
|
743
|
+
|
744
|
+
def parsed_block_with_modifier(res_block)
|
745
|
+
res=nil
|
746
|
+
instr=res_block[0,1].to_s
|
747
|
+
if !["<","<<",">"].include? instr and [">","<"].include?(modif=instr[-1,1])
|
748
|
+
res=modif.to_sym
|
749
|
+
res_block[0,1]=instr[0...-1].to_sym
|
750
|
+
end
|
751
|
+
res
|
752
|
+
end
|
753
|
+
|
754
|
+
def parse_text(blck)
|
755
|
+
#puts "blck";p blck
|
756
|
+
res=[]
|
757
|
+
blck[:txt].split(@re_strange2,-1).each{|e|
|
758
|
+
if e==@strange
|
759
|
+
|
760
|
+
b=blck[:inside].shift
|
761
|
+
res_b=parse_block(b)
|
762
|
+
if (res_modif=parsed_block_with_modifier(res_b))
|
763
|
+
res << res_modif
|
764
|
+
end
|
765
|
+
#puts "parse_text: res_b";p res_b
|
766
|
+
res << res_b
|
767
|
+
else
|
768
|
+
res << [:main,e]
|
769
|
+
end
|
770
|
+
}
|
771
|
+
res=[[:named,blck[:name]]+res] if blck[:name]
|
772
|
+
res
|
773
|
+
end
|
774
|
+
|
775
|
+
def rebuild_after_parse(res)
|
776
|
+
txt=""
|
777
|
+
start=0
|
778
|
+
parts=res[:txt].split(@re_strange,-1)
|
779
|
+
res[:inside].map do |e|
|
780
|
+
txt << parts.shift
|
781
|
+
txt << (e[:inside] ? rebuild_after_parse(e) : e[:txt])
|
782
|
+
end
|
783
|
+
txt << parts.shift
|
784
|
+
txt
|
785
|
+
end
|
786
|
+
|
787
|
+
def process(txt)
|
788
|
+
tokenize(txt)
|
789
|
+
parse_text(extract)
|
790
|
+
end
|
791
|
+
|
792
|
+
def pretty_print(res,tab=0)
|
793
|
+
res.each{|b|
|
794
|
+
if b.is_a? Array
|
795
|
+
pretty_print(b,tab+1)
|
796
|
+
else
|
797
|
+
puts " "*tab+b.inspect+"\n"
|
798
|
+
end
|
799
|
+
}
|
800
|
+
end
|
801
|
+
|
802
|
+
end
|
803
|
+
|
804
|
+
class VarsScanner < Scanner
|
805
|
+
|
806
|
+
@@type[:vars]={
|
807
|
+
:start=>'<<([\w\@]*)\s*\[',
|
808
|
+
:stop=> '\]',
|
809
|
+
:mode=>{:start=>-1,:stop=>0,:length=>1}
|
810
|
+
}
|
811
|
+
|
812
|
+
def initialize(type=:vars,start=nil,stop=nil,mode=nil,escape=nil)
|
813
|
+
super
|
814
|
+
end
|
815
|
+
|
816
|
+
def make_vars(res)
|
817
|
+
vars=[]
|
818
|
+
start=0
|
819
|
+
parts=res[:txt].split(@re_strange,-1).join("").strip
|
820
|
+
#puts "parts";p parts
|
821
|
+
#p res
|
822
|
+
#puts "inside";p res[:inside]
|
823
|
+
res[:inside].map do |e|
|
824
|
+
vars2= [e[:type][2..-1].strip,(e[:inside] ? make_vars(e) : e[:txt][(e[:type].bytesize+1)...-1] )] #instead of length
|
825
|
+
vars << vars2
|
826
|
+
end
|
827
|
+
#puts "vars";p vars
|
828
|
+
vars
|
829
|
+
end
|
830
|
+
|
831
|
+
def build_dyn_vars(res)
|
832
|
+
#puts "res";p res
|
833
|
+
is_arr=res.map{|k,v| k}.join("").empty?
|
834
|
+
cpt=-1
|
835
|
+
res2=[]
|
836
|
+
res.each{|k,v|
|
837
|
+
#p k;p v
|
838
|
+
key2=(k.empty? ? (is_arr ? "" : "key")+(cpt+=1).to_s : k)
|
839
|
+
res0=((v.is_a? Array) ? build_dyn_vars(v) : [["",v]])
|
840
|
+
#puts "res0";p res0
|
841
|
+
res2+=res0.map{|k0,v0| [key2+(k0.empty? ? "" : "." )+k0,v0]}
|
842
|
+
#puts "res2";p res2
|
843
|
+
}
|
844
|
+
#puts "res2";p res2
|
845
|
+
res2
|
846
|
+
end
|
847
|
+
|
848
|
+
def build_rb_vars(res)
|
849
|
+
#puts "res";p res
|
850
|
+
is_arr=res.map{|k,v| k}.join("").empty?
|
851
|
+
cpt=0
|
852
|
+
res2=(is_arr ? [] : {})
|
853
|
+
res.each{|k,v|
|
854
|
+
#p k;p v
|
855
|
+
v2=((v.is_a? Array) ? build_rb_vars(v) : v)
|
856
|
+
if is_arr
|
857
|
+
res2 << v2
|
858
|
+
else
|
859
|
+
key2=(is_arr ? (cpt+=1) : (k.empty? ? "key"+(cpt+=1).to_s : k).to_sym)
|
860
|
+
res2[key2]=v2
|
861
|
+
end
|
862
|
+
}
|
863
|
+
#puts "res2";p res2
|
864
|
+
res2
|
865
|
+
end
|
866
|
+
|
867
|
+
|
868
|
+
def build_vars(txt,type=:dyn)
|
869
|
+
#puts "txt";p txt
|
870
|
+
return nil unless txt[0,2]=="<<"
|
871
|
+
res=tokenize(txt)
|
872
|
+
return nil if res[:inside].empty?
|
873
|
+
res=make_vars(extract)
|
874
|
+
case type
|
875
|
+
when :dyn
|
876
|
+
#puts "res in build_vars";p res
|
877
|
+
build_dyn_vars(res)
|
878
|
+
when :rb
|
879
|
+
build_rb_vars(res)
|
880
|
+
when :r
|
881
|
+
end
|
882
|
+
end
|
883
|
+
|
884
|
+
|
885
|
+
end
|
886
|
+
end
|