casetdown 0.9.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.
- checksums.yaml +7 -0
- data/CasetDown/bin/cm +73 -0
- data/CasetDown/bin/cml +41 -0
- data/CasetDown/casetable.rb +80 -0
- data/CasetDown/casetcode.rb +228 -0
- data/CasetDown/casetdoc.rb +117 -0
- data/CasetDown/casetdown.rb +13 -0
- data/CasetDown/casetter.rb +72 -0
- data/EnData/api-app.rb +89 -0
- data/EnData/endata-app.rb +62 -0
- data/EnData/endata.rb +81 -0
- data/Tabot/newtab.rb +14 -0
- data/Tabot/simtab.rb +258 -0
- data/TextUtils/text_absparser.rb +42 -0
- data/TextUtils/text_abstract.rb +84 -0
- data/TextUtils/text_mind.rb +180 -0
- data/TinText/cache.rb +24 -0
- data/TinText/tin_text.rb +44 -0
- data/TinText/tintext.rb +4 -0
- data/TinText/tum.rb +13 -0
- data/XMLUtils/XmlUtils.rb +207 -0
- metadata +61 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 7db61cc282539ad38b94b953931b8801cc91dbd43c1bfe2941c7a56fce92abaa
|
|
4
|
+
data.tar.gz: 79034f081e7a5bcc75b0e00a579ed5c26c312a4acfc909457c0247b5cb806052
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f6a439b490240278afb3e86d3f6061b3b8115023d6daada7f5075ad3ceb6f304a671332b45089904ac571892078598db3e0e757cab62d08f979e4abfdd794981
|
|
7
|
+
data.tar.gz: d0c622a8dde0dbe7457ba7909bfa82bf8a8a25fda7275eceaed39589bb4070dcbe7d2637a770d2698c428de7e9322158a2e9873bd1cbea9c44e604e599ab5d10
|
data/CasetDown/bin/cm
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#coding:utf-8
|
|
3
|
+
require 'CasetDown/casetdown'
|
|
4
|
+
|
|
5
|
+
pool,check,source = ARGV,false,false
|
|
6
|
+
|
|
7
|
+
if pool.include?('-h') or pool.include?('--help')
|
|
8
|
+
puts %Q{<<LIST>>
|
|
9
|
+
cm [options] <filename>[.md]
|
|
10
|
+
|
|
11
|
+
options:
|
|
12
|
+
--help 查看帮助
|
|
13
|
+
--check 检查文档结构
|
|
14
|
+
--source 查看文档中的源代码
|
|
15
|
+
--rtab 导入外部表格到文档中
|
|
16
|
+
--wtab 导出内部表格到外部文件
|
|
17
|
+
--input 导出源代码文件并渲染文档
|
|
18
|
+
--output 导出代码运行结果
|
|
19
|
+
--all 导出源代码和运行结果(input+output)
|
|
20
|
+
--preview 预览渲染文档(不生成渲染结果)
|
|
21
|
+
--debug 调试开关, 不删除中间代码
|
|
22
|
+
--rendfile 渲染文档并生成一个时间戳(默认)
|
|
23
|
+
};exit
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if pool.include?('--check')
|
|
27
|
+
check = true
|
|
28
|
+
pool.delete '--check'
|
|
29
|
+
end
|
|
30
|
+
if pool.include?('--source')
|
|
31
|
+
source = true
|
|
32
|
+
pool.delete '--source'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
table,file = [],[]
|
|
36
|
+
['--rtab','--wtab'].each do|tag|
|
|
37
|
+
if pool.include?(tag)
|
|
38
|
+
table << tag
|
|
39
|
+
pool.delete tag
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
['--input','--output','--all','--preview','--debug'].each do|tag|
|
|
43
|
+
if pool.include?(tag)
|
|
44
|
+
file << tag
|
|
45
|
+
pool.delete tag
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
path = pool.last
|
|
50
|
+
path = Dir["./*.md"].last unless path
|
|
51
|
+
exit unless path
|
|
52
|
+
|
|
53
|
+
if File.exist?(path)
|
|
54
|
+
cds = CasetDown.load path
|
|
55
|
+
elsif File.exist?("#{path}.md")
|
|
56
|
+
cds = CasetDown.load "#{path}.md"
|
|
57
|
+
else
|
|
58
|
+
puts "File #{path} not exist.";exit
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if check
|
|
62
|
+
puts "checking>>>>"
|
|
63
|
+
pp CasetDown::Check.all(cds)
|
|
64
|
+
exit
|
|
65
|
+
end
|
|
66
|
+
if source
|
|
67
|
+
puts "source>>>>"
|
|
68
|
+
pp CasetDown.search_codes(cds)
|
|
69
|
+
exit
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
tmp = CasetDown.render_table(cds, opt: table.map{|i|i[2..-1].to_sym})
|
|
73
|
+
CasetDown.run_to_file cds, stream: tmp[:text], data: tmp[:data], fact: tmp[:fact], file: file.map{|i|i[2..-1].to_sym}+[:rendfile]
|
data/CasetDown/bin/cml
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#coding:utf-8
|
|
3
|
+
require 'digest'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
if ARGV.empty?
|
|
7
|
+
cd = Dir.pwd
|
|
8
|
+
fs = '*'
|
|
9
|
+
else
|
|
10
|
+
cd = ARGV.first
|
|
11
|
+
fs = ARGV.size>1 ? ARGV.last : '*'
|
|
12
|
+
(warn "No file(#{cd}/#{fs}) exist.";exit) unless File.exist?("#{cd}/#{fs}")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
warn "DONT USE POSTFIX .latest.md, FILENAME.latest.md WONT BE UPDATED!"
|
|
16
|
+
|
|
17
|
+
table = {}
|
|
18
|
+
loop do
|
|
19
|
+
Dir["#{cd}/#{fs}"].each do|path|
|
|
20
|
+
next unless path[-3..-1]=='.md'
|
|
21
|
+
next if path[-10..-1]=='.latest.md'
|
|
22
|
+
unless table[path]
|
|
23
|
+
table[path] = [File.stat(path).atime, File.stat(path).size, Digest::MD5.hexdigest(File.read(path))]
|
|
24
|
+
end
|
|
25
|
+
otime, osize, odigest = table[path]
|
|
26
|
+
atime = File.stat(path).atime
|
|
27
|
+
asize = File.stat(path).size
|
|
28
|
+
if atime>otime # && (asize != osize || asize == osize)
|
|
29
|
+
adigest = Digest::MD5.hexdigest File.read(path)
|
|
30
|
+
if adigest!= odigest
|
|
31
|
+
`cm #{path}`
|
|
32
|
+
table[path] = [atime, asize, adigest]
|
|
33
|
+
latpath = (Dir["#{path[0..-4]}.*.md"] - ["#{path[0..-4]}.latest.md"]).max
|
|
34
|
+
File.delete("#{path[0..-4]}.latest.md")
|
|
35
|
+
puts ">#{path} changed -> #{latpath}(#{adigest}).";$stdout.flush
|
|
36
|
+
FileUtils.copy_file(latpath, "#{path[0..-4]}.latest.md")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
sleep 1
|
|
41
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#coding:utf-8
|
|
2
|
+
require 'csv'
|
|
3
|
+
|
|
4
|
+
module CasetDown
|
|
5
|
+
module_function
|
|
6
|
+
|
|
7
|
+
# handle table
|
|
8
|
+
def loadcsv path,format=:raw
|
|
9
|
+
begin
|
|
10
|
+
csv = File.read(path).force_encoding("GBK").encode("UTF-8")
|
|
11
|
+
rescue
|
|
12
|
+
csv = File.read(path).encode("UTF-8")
|
|
13
|
+
end
|
|
14
|
+
content = CSV.parse(csv, headers:(format==:csv))
|
|
15
|
+
table = content.绑定表头 content[0]
|
|
16
|
+
return table
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def maketab table
|
|
20
|
+
printab = table.map{|row|"|"+row.join("|")+"|"}
|
|
21
|
+
printab.insert 1, Array.new(table[0].size, '|---').join+"|"
|
|
22
|
+
return printab.join("\n")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def render_table cds, option={ stream: nil, opt: []} # empty, :wtab, :rtab, :rendfile
|
|
26
|
+
$_tmp_endata_ = {}
|
|
27
|
+
# write table to csv file
|
|
28
|
+
docs = CasetDown::Check.all(cds)
|
|
29
|
+
docs.each_with_index do|doc,index|
|
|
30
|
+
if doc[:name]=='table'
|
|
31
|
+
table_name = ( index-1 >= 0 && docs[index-1][:name]=='p' && docs[index-1][:text].strip[0..1]=='((' && docs[index-1][:text].strip[-2..-1]=='))' ) ? docs[index-1][:text][2..-3].strip : 'Anonymous'
|
|
32
|
+
table_body = [doc[:head]]+doc[:body]
|
|
33
|
+
$_tmp_endata_["[table@endata ~]$ruby #{table_name}"] = table_body.to_s
|
|
34
|
+
CSV.open(table_name+".csv","w")do|writer|
|
|
35
|
+
table_body.each do|record|
|
|
36
|
+
writer << record
|
|
37
|
+
end
|
|
38
|
+
end if option[:opt].include?(:wtab)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# load table from csv file
|
|
43
|
+
result = {}
|
|
44
|
+
codtab = docs.select{|doc|doc[:name]=='code'}
|
|
45
|
+
codtab.each do|code|
|
|
46
|
+
interpreter, namespace, config, target, flow, segment, input, output, rows, cols = magic_head code
|
|
47
|
+
next unless output.to_s[-4..-1]=='.csv'
|
|
48
|
+
tab = loadcsv(output)
|
|
49
|
+
seltab = rows.inject([tab[0]]) do|seltab,row|
|
|
50
|
+
seltab += [tab[row]] if row.is_a?(Integer)
|
|
51
|
+
seltab += tab[row] if row.is_a?(Range)
|
|
52
|
+
seltab
|
|
53
|
+
end
|
|
54
|
+
seltab.绑定表头 seltab[0]
|
|
55
|
+
newtab = seltab.选择(*cols)
|
|
56
|
+
result[output] = maketab(newtab)
|
|
57
|
+
$_tmp_endata_["[table@endata ~]$ruby #{output}"] = newtab.to_s
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
$_tmp_endata_.each do|head, table|
|
|
61
|
+
($_scr_tail_ ||= "__END__") << "\n#{head}\n#{table}\n"
|
|
62
|
+
($_erl_tail_ ||= "") << "\n\n"+ToErlang.fact(head.split('$ruby ')[1], ToErlang.table(eval(table)))
|
|
63
|
+
end
|
|
64
|
+
origin_text = option[:stream] || cds[:doc].text
|
|
65
|
+
result.each do|output, newtab|
|
|
66
|
+
wrapped = "((#{output}))\n\n#{newtab}"
|
|
67
|
+
origins = CasetDown.search_output(origin_text, output)
|
|
68
|
+
origins.each do|origin|
|
|
69
|
+
origin_text = origin_text.gsub(origin, wrapped)
|
|
70
|
+
end
|
|
71
|
+
end if option[:opt].include?(:rtab)
|
|
72
|
+
|
|
73
|
+
if option[:opt].include?(:rendfile)
|
|
74
|
+
pazz = cds[:path].split('.')
|
|
75
|
+
pazz.insert(-2,Time.new.strftime("%Y%m%d%H%M%S"))
|
|
76
|
+
File.write pazz.join('.'), origin_text
|
|
77
|
+
end
|
|
78
|
+
return { text: origin_text, data: $_scr_tail_, fact: ($_erl_tail_||nil)}
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
#coding:utf-8
|
|
2
|
+
|
|
3
|
+
module CasetDown
|
|
4
|
+
module_function
|
|
5
|
+
|
|
6
|
+
def textchange text
|
|
7
|
+
text.gsub('>','>').gsub('<','<')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def wrap_output text, id, tag='output'
|
|
11
|
+
output_start = "```shell\n##{tag}>#{id}"
|
|
12
|
+
output_finish= "```"
|
|
13
|
+
return [output_start, text, output_finish].join("\n")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def search_output text, id, tag='output'
|
|
17
|
+
# [TODO] REFACTORING for recognition between '#output>path' and '#output> path'
|
|
18
|
+
output_start = "```shell\n##{tag}>#{id}"
|
|
19
|
+
output_finish= "```"
|
|
20
|
+
match = TextAbstract.match_paragraph text, output_start, output_finish
|
|
21
|
+
return match.map{|m|[output_start, m, output_finish].join}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def magic_head code
|
|
25
|
+
states = textchange(code[:code]).split("\n")
|
|
26
|
+
interpreter = code[:class]
|
|
27
|
+
script = states.find{|s|s[0..4]=='#src>'||s[0..7]=='#script>'}.to_s.split('>')[1]
|
|
28
|
+
interpreter = script if script # :default
|
|
29
|
+
|
|
30
|
+
namespace = states.find{|s|s[0..3]=='#ns>'||s[0..10]=='#namespace>'}.to_s.split('>')[1] || :ns
|
|
31
|
+
config = states.find{|s|s[0..5]=='#conf>'||s[0..7]=='#config>'}.to_s.split('>')[1] || :conf
|
|
32
|
+
target = states.find{|s|s[0..4]=='#dst>'||s[0..7]=='#target>'}.to_s.split('>')[1]
|
|
33
|
+
|
|
34
|
+
flow = states.find{|s|s[0..5]=='#flow>'||s[0..5]=='#step>'}.to_s.split('>')[1] || :flow
|
|
35
|
+
segment = states.find{|s|s[0..4]=='#seg>'||s[0..8]=='#segment>'}.to_s.split('>')[1] || :seg
|
|
36
|
+
|
|
37
|
+
input = states.find{|s|s[0..3]=='#in>'||s[0..6]=='#input>'}.to_s.split('>')[1] || :in
|
|
38
|
+
output = states.find{|s|s[0..4]=='#out>'||s[0..7]=='#output>'}.to_s.split('>')[1] || :out
|
|
39
|
+
|
|
40
|
+
[interpreter, namespace, target, flow, segment, input, output].each{|tag|tag.strip! if tag.instance_of?(String)}
|
|
41
|
+
|
|
42
|
+
rows = if row = states.find{|s|s[0..4]=='#row>'}.to_s.split('>')[1]
|
|
43
|
+
row.gsub('~','..').split(',').map{|r|eval(r)}
|
|
44
|
+
else
|
|
45
|
+
:rows
|
|
46
|
+
end
|
|
47
|
+
cols = if col = states.find{|s|s[0..4]=='#col>'}.to_s.split('>')[1]
|
|
48
|
+
col.split(',').map{|c|
|
|
49
|
+
c.split('').inject(true){|f,chr|
|
|
50
|
+
f&&(('0'..'9').to_a+['-','~']).include?(chr)
|
|
51
|
+
} ? eval(c.gsub('~','..')) : c.strip
|
|
52
|
+
}
|
|
53
|
+
else
|
|
54
|
+
:cols
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
return interpreter, namespace, config, target, flow, segment, input, output, rows, cols
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def search_codes cds
|
|
61
|
+
codes = CasetDown::Check.all(cds).select{|cd|cd[:name]=='code'}
|
|
62
|
+
|
|
63
|
+
table = codes.inject({}) do|table, code|
|
|
64
|
+
interpreter, namespace, config, target, flow, segment, input, output, rows, cols = magic_head code
|
|
65
|
+
|
|
66
|
+
content = textchange(code[:code]).split("\n")[1..-1].select{|s|
|
|
67
|
+
!['#ns>','#in>'].include?(s[0..3]) &&
|
|
68
|
+
!['#out>','#src>','#dst>','#seg>','#row>','#col>'].include?(s[0..4]) &&
|
|
69
|
+
!['#flow>','#step>','#conf>'].include?(s[0..5]) &&
|
|
70
|
+
!['#input>'].include?(s[0..6]) &&
|
|
71
|
+
!['#script>','#target>','#output>','#config>'].include?(s[0..7]) &&
|
|
72
|
+
!['#segment>'].include?(s[0..8]) &&
|
|
73
|
+
!['#namespace>'].include?(s[0..10])
|
|
74
|
+
}.join("\n")
|
|
75
|
+
table[[code.object_id, interpreter, namespace, config, target, [rows,cols], flow, segment, input, output]] = content
|
|
76
|
+
table
|
|
77
|
+
end
|
|
78
|
+
return table
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def run cds
|
|
82
|
+
table = CasetDown.search_codes(cds)
|
|
83
|
+
$_tmp_global_ = {}
|
|
84
|
+
$_scr_head_ = ['#coding:utf-8','["EnData/endata","EnData/endata-app","TinText/tum","TinText/cache","TinText/tin_text","TinText/tintext","Tabot/newtab","Tabot/simtab"].each{|mod|require(mod)}'].join("\n")
|
|
85
|
+
result = {}
|
|
86
|
+
table.each do|key, text|
|
|
87
|
+
oid, interpreter, ns, conf, target, range, flow, seg, input, output = key
|
|
88
|
+
unless conf==:conf # 注意全局配置累积生效,所以有先后顺序
|
|
89
|
+
$_tmp_global_.merge!(
|
|
90
|
+
(File.exist?(conf) ? YAML.load(File.read conf) : {}) ||
|
|
91
|
+
(File.exist?("#{conf}.yml") ? YAML.load(File.read "#{conf}.yml") : {}) ||
|
|
92
|
+
(File.exist?("#{conf}.yaml") ? YAML.load(File.read "#{conf}.yaml") : {})
|
|
93
|
+
)
|
|
94
|
+
$_scr_tail_ = "\n__END__\n[global@endata ~]$ruby global\n#{$_tmp_global_.to_s}"
|
|
95
|
+
$_erl_tail_ = $_tmp_global_.empty? ? '' : ToErlang.fact('global', (ToErlang.hash($_tmp_global_)) )
|
|
96
|
+
end
|
|
97
|
+
if interpreter=='shell' || interpreter==:default
|
|
98
|
+
if RUBY_PLATFORM.include?('mingw')
|
|
99
|
+
else
|
|
100
|
+
File.write "./~tmp.sh",text
|
|
101
|
+
running = `bash ./~tmp.sh`
|
|
102
|
+
File.delete "./~tmp.sh"
|
|
103
|
+
end
|
|
104
|
+
elsif interpreter=='ruby'
|
|
105
|
+
File.write "./~tmp.rb","#{$_scr_head_}\n\n#{text}\n\n#{$_scr_tail_}"
|
|
106
|
+
running = `ruby ./~tmp.rb`
|
|
107
|
+
File.delete "./~tmp.rb"
|
|
108
|
+
elsif interpreter=='erlang' || interpreter=='erl'
|
|
109
|
+
File.write "./_tmp.erl","-module(_tmp).\n-export([main/1]).\n\n#{text}\n\n#{$_erl_tail_}\n\nfact(UnknownMessage)->\n io:format(\"~p\",[UnknownMessage])."
|
|
110
|
+
running = `escript ./_tmp.erl`
|
|
111
|
+
File.delete "./_tmp.erl"
|
|
112
|
+
elsif interpreter=='python3' || interpreter=='python'
|
|
113
|
+
File.write "./~tmp.py",text
|
|
114
|
+
running = `python ./~tmp.py`
|
|
115
|
+
File.delete "./~tmp.py"
|
|
116
|
+
elsif interpreter=='lms'
|
|
117
|
+
running = `lms "#{text}"`
|
|
118
|
+
elsif interpreter=='lmx'
|
|
119
|
+
running = `lmx "#{text}"`
|
|
120
|
+
else
|
|
121
|
+
end
|
|
122
|
+
result[input] = running
|
|
123
|
+
end
|
|
124
|
+
return result
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def run_to_file cds,option={stream: nil, data: nil, fact: nil,file:[]} # empty, :input, :output, :all
|
|
128
|
+
$_tmp_global_ = {}
|
|
129
|
+
$_scr_head_ = ['#coding:utf-8','["EnData/endata","EnData/endata-app","TinText/tum","TinText/cache","TinText/tin_text","TinText/tintext","Tabot/newtab","Tabot/simtab"].each{|mod|require(mod)}'].join("\n")
|
|
130
|
+
$_scr_tail_ = option[:data] ? option[:data] : ''
|
|
131
|
+
$_erl_tail_ = option[:fact] ? option[:fact] : ''
|
|
132
|
+
|
|
133
|
+
table = CasetDown.search_codes(cds)
|
|
134
|
+
result = {}
|
|
135
|
+
table.each do|key, text|
|
|
136
|
+
oid, interpreter, ns, conf, target, range, flow, seg, input, output = key
|
|
137
|
+
unless conf==:conf # 注意全局配置累积生效,所以有先后顺序
|
|
138
|
+
$_tmp_global_.merge!(
|
|
139
|
+
(File.exist?(conf) ? YAML.load(File.read conf) : {}) ||
|
|
140
|
+
(File.exist?("#{conf}.yml") ? YAML.load(File.read "#{conf}.yml") : {}) ||
|
|
141
|
+
(File.exist?("#{conf}.yaml") ? YAML.load(File.read "#{conf}.yaml") : {})
|
|
142
|
+
)
|
|
143
|
+
$_scr_tail_ = $_scr_tail_.empty? ? "\n__END__\n[global@endata ~]$ruby global\n#{$_tmp_global_.to_s}" : "#{$_scr_tail_}\n[global@endata ~]$ruby global\n#{$_tmp_global_.to_s}"
|
|
144
|
+
$_erl_tail_ = $_tmp_global_.empty? ? $_erl_tail_ : $_erl_tail_+"\n\n"+ToErlang.fact('global', (ToErlang.hash($_tmp_global_)) )
|
|
145
|
+
end
|
|
146
|
+
if interpreter==:default
|
|
147
|
+
# NOTHING
|
|
148
|
+
elsif interpreter=='shell' || interpreter=='bash'
|
|
149
|
+
if RUBY_PLATFORM.include?('mingw')
|
|
150
|
+
else
|
|
151
|
+
File.write "./~tmp.sh",text
|
|
152
|
+
running = `bash ./~tmp.sh`
|
|
153
|
+
File.delete "./~tmp.sh" unless option[:file].include?(:debug)
|
|
154
|
+
end
|
|
155
|
+
elsif interpreter=='ruby'
|
|
156
|
+
File.write "./~tmp.rb","#{$_scr_head_}\n\n#{text}\n\n#{$_scr_tail_}"
|
|
157
|
+
running = `ruby ./~tmp.rb`
|
|
158
|
+
File.delete "./~tmp.rb" unless option[:file].include?(:debug)
|
|
159
|
+
elsif interpreter=='erlang' || interpreter=='erl'
|
|
160
|
+
File.write "./_tmp.erl","-module(_tmp).\n-export([main/1]).\n\n#{text}\n\n#{$_erl_tail_}\n\nfact(UnknownMessage)->\n io:format(\"~p\",[UnknownMessage])."
|
|
161
|
+
running = `escript ./_tmp.erl`
|
|
162
|
+
File.delete "./_tmp.erl" unless option[:file].include?(:debug)
|
|
163
|
+
elsif interpreter=='python3' || interpreter=='python'
|
|
164
|
+
File.write "./~tmp.py",text
|
|
165
|
+
running = `python ./~tmp.py`
|
|
166
|
+
File.delete "./~tmp.py" unless option[:file].include?(:debug)
|
|
167
|
+
elsif interpreter=='lms'
|
|
168
|
+
running = `lms "#{text}"`
|
|
169
|
+
elsif interpreter=='lmx'
|
|
170
|
+
running = `lmx "#{text}"`
|
|
171
|
+
else
|
|
172
|
+
end
|
|
173
|
+
result[input] = running
|
|
174
|
+
File.write input, text if !(option[:file] & [:input, :all]).empty? && input.instance_of?(String)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
origin_text = option[:stream] || cds[:doc].text
|
|
178
|
+
result.each do|input, running| # input == output
|
|
179
|
+
File.write input, running if !(option[:file] & [:output, :all]).empty? && input.instance_of?(String)
|
|
180
|
+
origins = CasetDown.search_output(origin_text, input)
|
|
181
|
+
wrapped = CasetDown.wrap_output(running,input)
|
|
182
|
+
if origins.empty?
|
|
183
|
+
origins = CasetDown.search_output(origin_text, input, 'out')
|
|
184
|
+
wrapped = CasetDown.wrap_output(running,input, 'out')
|
|
185
|
+
end
|
|
186
|
+
origins.each do|origin|
|
|
187
|
+
# [TODO] 无法解决不同后缀的前置匹配替换问题,待修复
|
|
188
|
+
origin_text = origin_text.gsub(origin, wrapped)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
if option[:file].include?(:rendfile)
|
|
193
|
+
if option[:file].include?(:preview)
|
|
194
|
+
prvw = cds[:path].split('.')
|
|
195
|
+
prvw.insert(-2,'preview')
|
|
196
|
+
File.write prvw.join('.'), origin_text
|
|
197
|
+
else
|
|
198
|
+
pazz = cds[:path].split('.')
|
|
199
|
+
pazz.insert(-2,Time.new.strftime("%Y%m%d%H%M%S"))
|
|
200
|
+
File.write pazz.join('.'), origin_text
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
return origin_text
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
module ToErlang
|
|
208
|
+
module_function
|
|
209
|
+
|
|
210
|
+
def table data
|
|
211
|
+
fields = data.first
|
|
212
|
+
erlang_data = data.drop(1).map do |row|
|
|
213
|
+
row_data = fields.zip(row).map do |field, value|
|
|
214
|
+
"{\"#{field}\", \"#{value}\"}"
|
|
215
|
+
end.join(",")
|
|
216
|
+
"{#{row_data}}"
|
|
217
|
+
end
|
|
218
|
+
"[#{erlang_data.join(", ")}]"
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def hash data
|
|
222
|
+
"{"+data.map{|k,v|"{\"#{k}\", \"#{v}\"}"}.join(",")+"}"
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def fact name, body
|
|
226
|
+
"fact(\"#{name.to_s}\")->\n #{body};"
|
|
227
|
+
end
|
|
228
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#coding:utf-8
|
|
2
|
+
|
|
3
|
+
module CasetDown
|
|
4
|
+
module Check
|
|
5
|
+
module_function
|
|
6
|
+
|
|
7
|
+
def all cds
|
|
8
|
+
epool = cds[:src].stack.inject([]) do|epool, cd|
|
|
9
|
+
res = nil
|
|
10
|
+
[:head, :table, :para, :pre, :list, :quote].each do|tag|
|
|
11
|
+
res ||= CasetDown::Check.send tag, cd
|
|
12
|
+
end
|
|
13
|
+
epool += res.instance_of?(Array) ? res : [res]
|
|
14
|
+
end.compact
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def head cd
|
|
18
|
+
if %w{h1 h2 h3 h4 h5 h6}.include? cd.name
|
|
19
|
+
unless cd.elements.empty?
|
|
20
|
+
ha = {name: cd.name, text: cd.attributes[:text], inline: [] }
|
|
21
|
+
cd.elements.each{|sub|ha[:inline]<<(sub.name=='a' ? a(sub) : {})}
|
|
22
|
+
ha
|
|
23
|
+
else
|
|
24
|
+
{name: cd.name, text: cd.attributes[:text] }
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def table cd
|
|
32
|
+
if cd.name=='table'
|
|
33
|
+
hd = cd.to_doc['table'][1]['thead'][1]['tr'][1..-1].map{|th|th['th'][0][:text]}
|
|
34
|
+
bd = cd.to_doc['table'][2]['tbody'][1..-1].map{|tr|tr['tr'][1..-1].map{|td|td['td'][0][:text]}}
|
|
35
|
+
{name: 'table', head: hd, body: bd}
|
|
36
|
+
else
|
|
37
|
+
nil
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def para cd
|
|
42
|
+
if cd.name=='p'
|
|
43
|
+
cur = []
|
|
44
|
+
cur << (cd.attributes[:text] ? {name: 'p', text: cd.attributes[:text]||cd.attributes["text"]} : nil)
|
|
45
|
+
cd.elements.each do|cs|
|
|
46
|
+
cur << code(cs)
|
|
47
|
+
cur << img(cs)
|
|
48
|
+
cur << a(cs)
|
|
49
|
+
end
|
|
50
|
+
return cur
|
|
51
|
+
else
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def img cd
|
|
57
|
+
if cd.name=='img'
|
|
58
|
+
{name: 'img', src: cd.attributes['src'], alt: cd.attributes['alt']}
|
|
59
|
+
else
|
|
60
|
+
nil
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def a cd
|
|
65
|
+
if cd.name=='a'
|
|
66
|
+
{name: 'a', href: cd.attributes['href'], text: cd.attributes[:text]}
|
|
67
|
+
else
|
|
68
|
+
nil
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def pre cd
|
|
73
|
+
if cd.name=='pre'
|
|
74
|
+
code(cd.elements.first)
|
|
75
|
+
else
|
|
76
|
+
nil
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def code cd
|
|
81
|
+
if cd.name=='code'
|
|
82
|
+
{name: 'code', class: (cd.attributes['class'] ? cd.attributes['class'] : :default), code: cd.attributes[:text]}
|
|
83
|
+
else
|
|
84
|
+
nil
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def list cd
|
|
89
|
+
# TODO: ONLY TOP LEVEL, PENDING TO RECURSION
|
|
90
|
+
if cd.name=='ul'
|
|
91
|
+
subs = cd.elements.inject([]) do|subs, li|
|
|
92
|
+
sub = {name: 'li', text: li.attributes[:text]}
|
|
93
|
+
li.elements.each do|subsub|
|
|
94
|
+
sub.merge!(inline: quote(subsub)) if subsub.name=='blockquote'
|
|
95
|
+
sub.merge!(inline: code(subsub)) if subsub.name=='code'
|
|
96
|
+
sub.merge!(inline: img(subsub)) if subsub.name=='img'
|
|
97
|
+
sub.merge!(inline: a(subsub)) if subsub.name=='a'
|
|
98
|
+
end
|
|
99
|
+
subs << sub
|
|
100
|
+
end
|
|
101
|
+
{name: 'ul', list: subs}
|
|
102
|
+
else
|
|
103
|
+
nil
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def quote cd
|
|
108
|
+
# TODO: ONLY TOP LEVEL, PENDING TO RECURSION
|
|
109
|
+
if cd.name=='blockquote'
|
|
110
|
+
{name: 'blockquote', quote: cd.to_doc['blockquote'][1]['p'][0][:text]}
|
|
111
|
+
else
|
|
112
|
+
nil
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#coding:utf-8
|
|
2
|
+
#USE: XMLUtils/XmlUtils
|
|
3
|
+
#USE: TextUtils/text_abstract
|
|
4
|
+
#USE: Tabot/simtab
|
|
5
|
+
|
|
6
|
+
[
|
|
7
|
+
'EnData/endata', 'EnData/endata-app',
|
|
8
|
+
'Tabot/newtab', 'Tabot/simtab',
|
|
9
|
+
'TextUtils/text_abstract', 'TextUtils/text_absparser', 'TextUtils/text_mind',
|
|
10
|
+
'TinText/tum', 'TinText/cache', 'TinText/tin_text', 'TinText/tintext',
|
|
11
|
+
'XMLUtils/XmlUtils',
|
|
12
|
+
'CasetDown/casetter', 'CasetDown/casetdoc', 'CasetDown/casetcode', 'CasetDown/casetable'
|
|
13
|
+
].each{|lib|require lib}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#coding:utf-8
|
|
2
|
+
require 'rdiscount'
|
|
3
|
+
|
|
4
|
+
module CasetDown
|
|
5
|
+
module_function
|
|
6
|
+
|
|
7
|
+
#################################################################################################
|
|
8
|
+
# Loader #
|
|
9
|
+
#################################################################################################
|
|
10
|
+
def load path, option={}
|
|
11
|
+
args = {path: path}.merge(option)
|
|
12
|
+
text = (File.read path).gsub("\r","").split("\n").map{|line|line.rstrip}.join("\n")
|
|
13
|
+
return self.parse(text, args)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#################################################################################################
|
|
17
|
+
# InlineStructs #
|
|
18
|
+
#################################################################################################
|
|
19
|
+
def parse text, option={}
|
|
20
|
+
args = {
|
|
21
|
+
parser: RDiscount, # parser := {Kramdown::Document | RDiscount} ★ Kramdown::Document无法处理好多重空行问题
|
|
22
|
+
doc: true,
|
|
23
|
+
tree: true,
|
|
24
|
+
src: true,
|
|
25
|
+
path: 'tmp'
|
|
26
|
+
}.merge(option)
|
|
27
|
+
document = args[:parser].new(text)
|
|
28
|
+
html = "<html>"+document.to_html+"</html>"
|
|
29
|
+
script, tree = [],{}
|
|
30
|
+
XmlParser.parse(html).elements.each do|node|
|
|
31
|
+
doc = node.to_a
|
|
32
|
+
script << node
|
|
33
|
+
tree[doc[0]] ||= []
|
|
34
|
+
tree[doc[0]] << node
|
|
35
|
+
end
|
|
36
|
+
result = {path: args[:path]}
|
|
37
|
+
result[:src] = Script.new(native: script) if args[:src]
|
|
38
|
+
result[:tree] = Tree.new(native: tree) if args[:tree]
|
|
39
|
+
result[:doc] = document if args[:doc]
|
|
40
|
+
return result
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class Tree
|
|
44
|
+
def initialize options={}
|
|
45
|
+
@content ||= options[:native]
|
|
46
|
+
@content ||= JSON.parse(options[:json]) if options[:json]
|
|
47
|
+
@content ||= CasetDown.load(options[:path])[-1] if options[:path]
|
|
48
|
+
@content ||= CasetDown.parse(options[:doc])[-1] if options[:doc]
|
|
49
|
+
@content ||= {}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def nodes &block
|
|
53
|
+
block = lambda{|content|content} unless block
|
|
54
|
+
block.call(@content)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class Script
|
|
59
|
+
def initialize options={}
|
|
60
|
+
@content ||= options[:native]
|
|
61
|
+
@content ||= JSON.parse(options[:json]) if options[:json]
|
|
62
|
+
@content ||= CasetDown.load(options[:path])[0] if options[:path]
|
|
63
|
+
@content ||= CasetDown.parse(options[:doc])[0] if options[:doc]
|
|
64
|
+
@content ||= []
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def stack &block
|
|
68
|
+
block = lambda{|content|content} unless block
|
|
69
|
+
block.call(@content)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|