python_uml_class 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +86 -0
- data/LICENSE +21 -0
- data/README.md +2 -0
- data/Rakefile +8 -0
- data/bin/start_python_uml_class.rb +52 -0
- data/bin/start_python_uml_class.rbw +52 -0
- data/lib/app_load.rb +2 -0
- data/lib/config/browser.json +4 -0
- data/lib/config/setting.json +47 -0
- data/lib/config.ru +107 -0
- data/lib/create_uml_class.rb +352 -0
- data/lib/css/index.css +178 -0
- data/lib/del_comment.py +36 -0
- data/lib/html/index.html +80 -0
- data/lib/js/main.js +466 -0
- data/lib/my_app_sample.rb +36 -0
- data/lib/python_uml_class/version.rb +5 -0
- data/lib/python_uml_class.rb +55 -0
- data/lib/server.rb +58 -0
- data/lib/server_app_base.rb +63 -0
- data/lib/start.rb +130 -0
- data/lib/wsserver.rb +148 -0
- data/python_uml_class.gemspec +43 -0
- data/sig/PythonUmlClass.rbs +4 -0
- metadata +102 -0
@@ -0,0 +1,352 @@
|
|
1
|
+
require "tempfile"
|
2
|
+
require "facter"
|
3
|
+
|
4
|
+
CStruct = Struct.new(:type,
|
5
|
+
:file_name,
|
6
|
+
:name,
|
7
|
+
:block_count,
|
8
|
+
:var_list,
|
9
|
+
:method_list,
|
10
|
+
:inherit_list,
|
11
|
+
:composition_list)
|
12
|
+
|
13
|
+
def get_formatter_path
|
14
|
+
return @config["formatter_path"] if @config["formatter_path"].to_s != ""
|
15
|
+
|
16
|
+
""
|
17
|
+
end
|
18
|
+
|
19
|
+
def print_uml(out, out_list)
|
20
|
+
out_list.each do |o_list|
|
21
|
+
if o_list.type == :class_start
|
22
|
+
# nop
|
23
|
+
elsif o_list.type == :module_start
|
24
|
+
out.push "namespace \"#{o_list.name}\" {"
|
25
|
+
elsif o_list.type == :class_end
|
26
|
+
pp o_list if o_list.name == ""
|
27
|
+
out.push "class \"#{o_list.name}\" {"
|
28
|
+
# インスタンス変数の出力
|
29
|
+
o_list.var_list.uniq.each do |iv|
|
30
|
+
out.push iv
|
31
|
+
end
|
32
|
+
# メソッドの出力
|
33
|
+
o_list.method_list.each do |ml|
|
34
|
+
out.push ml
|
35
|
+
end
|
36
|
+
out.push "}"
|
37
|
+
# 継承リストの出力
|
38
|
+
o_list.inherit_list.each do |ih|
|
39
|
+
out.push "\"#{o_list.name}\" -[##{@config["inherit_color"]}]-|> \"#{ih}\""
|
40
|
+
end
|
41
|
+
# compo
|
42
|
+
o_list.composition_list.uniq.each do |co|
|
43
|
+
out.push "\"#{o_list.name}\" *-[##{@config["composition_color"]}]- \"#{co}\""
|
44
|
+
end
|
45
|
+
elsif o_list.type == :module_end
|
46
|
+
# インスタンス変数がある場合はモジュール名と同じクラスを定義
|
47
|
+
if o_list.var_list.size != 0 or
|
48
|
+
o_list.method_list.size != 0 or
|
49
|
+
o_list.inherit_list.size != 0 or
|
50
|
+
o_list.composition_list.size != 0
|
51
|
+
pp o_list if o_list.name == ""
|
52
|
+
out.push "class #{o_list.name} {"
|
53
|
+
# インスタンス変数の出力
|
54
|
+
o_list.var_list.uniq.each do |iv|
|
55
|
+
out.push iv
|
56
|
+
end
|
57
|
+
# メソッドの出力
|
58
|
+
o_list.method_list.each do |ml|
|
59
|
+
out.push ml
|
60
|
+
end
|
61
|
+
out.push "}"
|
62
|
+
# 継承リストの出力
|
63
|
+
o_list.inherit_list.each do |ih|
|
64
|
+
out.push "\"#{o_list.name}\" -[##{@config["inherit_color"]}]-|> \"#{ih}\""
|
65
|
+
end
|
66
|
+
# compo
|
67
|
+
o_list.composition_list.uniq.each do |co|
|
68
|
+
out.push "\"#{o_list.name}\" *-[##{@config["composition_color"]}]- \"#{co}\""
|
69
|
+
end
|
70
|
+
end
|
71
|
+
out.push "}"
|
72
|
+
else
|
73
|
+
# error
|
74
|
+
puts "error!"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
out
|
78
|
+
end
|
79
|
+
|
80
|
+
def create_uml_class(in_dir, _out_file)
|
81
|
+
out = []
|
82
|
+
out.push "@startuml"
|
83
|
+
|
84
|
+
puts "in_dir = #{in_dir}"
|
85
|
+
global_var = []
|
86
|
+
out_list = []
|
87
|
+
def_list = []
|
88
|
+
import_list = []
|
89
|
+
|
90
|
+
Dir.glob("#{in_dir}/**/*.py") do |f|
|
91
|
+
import_list.push File.basename(f).split(".")[0]
|
92
|
+
end
|
93
|
+
|
94
|
+
Dir.glob("#{in_dir}/**/*.py") do |f|
|
95
|
+
puts f
|
96
|
+
puts @config["exclude_path"]
|
97
|
+
if @config["exclude_path"] != ""
|
98
|
+
if f =~ Regexp.new(@config["exclude_path"])
|
99
|
+
puts "skip #{f}"
|
100
|
+
next
|
101
|
+
end
|
102
|
+
end
|
103
|
+
buf = ""
|
104
|
+
file_name = File.basename(f).split(".")[0]
|
105
|
+
Tempfile.create("pylint") do |tmp_file|
|
106
|
+
# FileUtils.cp(f, tmp_file.path)
|
107
|
+
kernel = Facter.value(:kernel)
|
108
|
+
if kernel == "windows"
|
109
|
+
open("|#{get_formatter_path} #{f} > #{tmp_file.path}") do |ff|
|
110
|
+
if ff.read.to_s != ""
|
111
|
+
puts "pylint error #{ff}"
|
112
|
+
return
|
113
|
+
else
|
114
|
+
buf = File.binread tmp_file.path
|
115
|
+
end
|
116
|
+
end
|
117
|
+
else
|
118
|
+
open("|#{get_formatter_path} #{f} > #{tmp_file.path}") do |ff|
|
119
|
+
puts "|#{get_formatter_path} #{f} > #{tmp_file.path}"
|
120
|
+
if ff.read.to_s != ""
|
121
|
+
puts "pylint error #{ff}"
|
122
|
+
return
|
123
|
+
else
|
124
|
+
buf = File.binread tmp_file.path
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
cstruct_list = []
|
131
|
+
block_count = 0
|
132
|
+
method_type = :public
|
133
|
+
class_name = ""
|
134
|
+
file_struct_list = []
|
135
|
+
file_struct_list.push CStruct.new(:class_start, file_name, file_name + ".global", block_count, [], [], [], [])
|
136
|
+
file_struct_list.push CStruct.new(:class_end, file_name, file_name + ".global", block_count, [], [], [], [])
|
137
|
+
is_def = false
|
138
|
+
|
139
|
+
# ソースを解析
|
140
|
+
buf.each_line do |line|
|
141
|
+
next if line =~ /^[\r\n]*$/ # 空行は対象外
|
142
|
+
|
143
|
+
line.chomp!
|
144
|
+
# ブロックの開始/終了
|
145
|
+
indent_num = line.match(/^ +/).to_s.size / 4
|
146
|
+
puts "block_count=#{indent_num} cstruct_size=#{cstruct_list.size} is_def=#{is_def} #{line}"
|
147
|
+
if block_count == indent_num
|
148
|
+
# 変化なし
|
149
|
+
elsif block_count > indent_num
|
150
|
+
# ブロックの終了
|
151
|
+
block_count = indent_num
|
152
|
+
# 関数の終了
|
153
|
+
if is_def == true and def_list[-1].block_count >= block_count
|
154
|
+
is_def = false
|
155
|
+
method_type = :public
|
156
|
+
end
|
157
|
+
# クラスの終了
|
158
|
+
if cstruct_list.size != 0 && cstruct_list[-1].block_count >= block_count # block_countが一致
|
159
|
+
puts "end of #{cstruct_list[-1].name}"
|
160
|
+
out_list.push cstruct_list[-1]
|
161
|
+
cstruct_list.slice!(-1) # 最後の要素を削除
|
162
|
+
method_type = :public
|
163
|
+
end
|
164
|
+
else
|
165
|
+
# ブロックの開始
|
166
|
+
block_count = indent_num
|
167
|
+
end
|
168
|
+
#puts "block_count=#{indent_num} class_count=#{cstruct_list.size} def_count=#{def_list.size} #{line}"
|
169
|
+
|
170
|
+
# method_type
|
171
|
+
if line =~ /@staticmethod/
|
172
|
+
method_type = :private
|
173
|
+
end
|
174
|
+
|
175
|
+
# import
|
176
|
+
line.match(/import \S+/) do |m|
|
177
|
+
import_name = m.to_s.gsub(/import /, "")
|
178
|
+
if 0 != import_list.select { |im| im == import_name }.size and file_name != import_name
|
179
|
+
if cstruct_list.size != 0
|
180
|
+
cstruct_list[-1].composition_list.push import_name
|
181
|
+
else
|
182
|
+
file_struct_list[-1].composition_list.push import_name
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# クラスの開始
|
188
|
+
if line =~ /^\s*class.*:/
|
189
|
+
work = line.gsub(/class\s/, "")
|
190
|
+
class_name = work.split("\(")[0].to_s.gsub(/:/, "")
|
191
|
+
base_name = work.match(/\(.*\)/).to_s.gsub(/[()]/, "")
|
192
|
+
class_name = "#{file_name}.#{class_name}"
|
193
|
+
puts "class_name=#{class_name}"
|
194
|
+
puts "base_name=#{base_name}"
|
195
|
+
out_list.push CStruct.new(:class_start, file_name, class_name, block_count, [], [], [], [])
|
196
|
+
cstruct_list.push CStruct.new(:class_end, file_name, class_name, block_count, [], [], [], [])
|
197
|
+
# pp line if class_name == ""
|
198
|
+
if base_name != ""
|
199
|
+
if base_name =~ /,/
|
200
|
+
base_name.split(",").each do |name|
|
201
|
+
cstruct_list[-1].inherit_list.push name
|
202
|
+
end
|
203
|
+
else
|
204
|
+
cstruct_list[-1].inherit_list.push base_name
|
205
|
+
end
|
206
|
+
end
|
207
|
+
next
|
208
|
+
end
|
209
|
+
|
210
|
+
if line =~ /^\s*private$/
|
211
|
+
method_type = :private
|
212
|
+
elsif line =~ /^\s*protected$/
|
213
|
+
method_type = :protected
|
214
|
+
elsif line =~ /^\s*public$/
|
215
|
+
method_type = :public
|
216
|
+
end
|
217
|
+
|
218
|
+
if line =~ /^\s*def\s/
|
219
|
+
# 関数名を取り出す
|
220
|
+
method = line.chomp.gsub(/\s*def\s*/, "")
|
221
|
+
unless method =~ /\(/
|
222
|
+
# 関数名にカッコをつける
|
223
|
+
sp = method.split(" ")
|
224
|
+
method = if sp.size > 1
|
225
|
+
sp[0].to_s + "(" + sp[1..-1].to_s + ")"
|
226
|
+
else
|
227
|
+
method + "()"
|
228
|
+
end
|
229
|
+
end
|
230
|
+
if cstruct_list.size != 0
|
231
|
+
method_list = cstruct_list[-1].method_list
|
232
|
+
case method_type
|
233
|
+
when :public
|
234
|
+
method_list.push "+ #{method}"
|
235
|
+
when :private
|
236
|
+
method_list.push "- #{method}"
|
237
|
+
when :protected
|
238
|
+
method_list.push "# #{method}"
|
239
|
+
end
|
240
|
+
else
|
241
|
+
method_list = file_struct_list[-1].method_list
|
242
|
+
method_list.push "+ #{method}"
|
243
|
+
end
|
244
|
+
def_list.push CStruct.new(:method_start, file_name, method, block_count, [], [], [], [])
|
245
|
+
is_def = true
|
246
|
+
end
|
247
|
+
|
248
|
+
# composition_list
|
249
|
+
# クラスの呼び出し箇所
|
250
|
+
line.match(/\s([A-Z][a-zA-Z]+)\.[a-z]/) do |m|
|
251
|
+
c_name = m.to_s.split(".")[0].gsub(/ /, "")
|
252
|
+
puts "compo c_name=#{c_name}"
|
253
|
+
if cstruct_list.size != 0
|
254
|
+
cstruct_list[-1].composition_list.push c_name
|
255
|
+
else
|
256
|
+
file_struct_list[-1].composition_list.push c_name
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# クラスの初期化箇所
|
261
|
+
line.match(/[\s\.][A-Z][A-Za-z]+\(/) do |m|
|
262
|
+
c_name = m.to_s.gsub(/\(/, "").gsub(/[\s\.]/, "")
|
263
|
+
puts "compo c_name=#{c_name}"
|
264
|
+
if cstruct_list.size != 0
|
265
|
+
cstruct_list[-1].composition_list.push c_name
|
266
|
+
else
|
267
|
+
file_struct_list[-1].composition_list.push c_name
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# インスタンス変数
|
272
|
+
if line =~ /^\s*self\.[a-zA-Z0-9_]+\s+=/ and cstruct_list.size != 0
|
273
|
+
line.match(/self\.[a-zA-Z0-9_]+/) do |m|
|
274
|
+
instance_var = cstruct_list[-1].var_list
|
275
|
+
val = m.to_s.gsub(/self\./, "")
|
276
|
+
case method_type
|
277
|
+
when :public
|
278
|
+
instance_var.push "+ #{val}"
|
279
|
+
when :private
|
280
|
+
instance_var.push "- #{val}"
|
281
|
+
when :protected
|
282
|
+
instance_var.push "# #{val}"
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
# クラス変数
|
288
|
+
if line =~ /^\s*[a-zA-Z0-9_]+\s+=/ and cstruct_list.size != 0 and is_def == false
|
289
|
+
line.match(/[a-zA-Z0-9_]+/) do |m|
|
290
|
+
instance_var = cstruct_list[-1].var_list
|
291
|
+
val = m.to_s
|
292
|
+
instance_var.push "- #{val}"
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# 外部変数
|
297
|
+
if line =~ /^\s*[a-zA-Z0-9_]+\s+=/ and cstruct_list.size == 0 and is_def == false
|
298
|
+
line.match(/\$*[a-zA-Z0-9_]+/) do |m|
|
299
|
+
file_struct_list[-1].var_list.push "+ #{m}"
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# ファイルの終了
|
305
|
+
if block_count != 0
|
306
|
+
puts "endf of #{f}"
|
307
|
+
# クラスの終了
|
308
|
+
if cstruct_list.size != 0
|
309
|
+
puts "end of #{cstruct_list[-1].name}"
|
310
|
+
out_list.push cstruct_list[-1]
|
311
|
+
cstruct_list.slice!(-1) # 最後の要素を削除
|
312
|
+
end
|
313
|
+
file_struct_list.each do |fs|
|
314
|
+
out_list.push fs
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# 継承リストとコンポジションリストのチュエック
|
320
|
+
out_list.each_index do |i|
|
321
|
+
out_list[i].composition_list.each_index do |j|
|
322
|
+
# compo_nameがfile_name.class_nameに変更可能かチェック
|
323
|
+
compo_name = out_list[i].composition_list[j]
|
324
|
+
out_list.select { |a| a.name.split(".")[-1] == compo_name }.each do |m|
|
325
|
+
puts "m=#{m.name}"
|
326
|
+
out_list[i].composition_list[j] = m.name
|
327
|
+
end
|
328
|
+
def_list.each do |def_struct|
|
329
|
+
# comp_nameが自分で定義した関数名の場合は削除
|
330
|
+
#puts "#{compo_name} == #{def_struct.name.split("(")[0]}"
|
331
|
+
if compo_name == def_struct.name.split("(")[0]
|
332
|
+
puts "match_def #{compo_name} == #{def_struct.name.split("(")[0]}"
|
333
|
+
out_list[i].composition_list.delete_at(j)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
out_list[i].inherit_list.each_index do |j|
|
338
|
+
# compo_nameがfile_name.class_nameに変更可能かチェック
|
339
|
+
inherit_name = out_list[i].inherit_list[j]
|
340
|
+
out_list.select { |a| a.name.split(".")[-1] == inherit_name }.each do |m|
|
341
|
+
puts "m=#{m.name}"
|
342
|
+
out_list[i].inherit_list[j] = m.name
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
# UMLの出力
|
348
|
+
out = print_uml(out, out_list)
|
349
|
+
|
350
|
+
out.push "@enduml"
|
351
|
+
out.join("\n")
|
352
|
+
end
|
data/lib/css/index.css
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
body {
|
2
|
+
color: #000000;
|
3
|
+
background-color: #cac3ec4f;
|
4
|
+
overflow: hidden;
|
5
|
+
font-size: 12px;
|
6
|
+
}
|
7
|
+
|
8
|
+
hr {
|
9
|
+
color: #ffffff;
|
10
|
+
background-color: #000000;
|
11
|
+
height: 1px;
|
12
|
+
/* 線の太さ */
|
13
|
+
border: 1px;
|
14
|
+
/* 枠の太さ */
|
15
|
+
border-style: solid;
|
16
|
+
/* 枠の種類 */
|
17
|
+
}
|
18
|
+
|
19
|
+
.error {
|
20
|
+
color: red;
|
21
|
+
}
|
22
|
+
|
23
|
+
.outarea {
|
24
|
+
background-color: #FFFFFF;
|
25
|
+
margin: 5px;
|
26
|
+
padding: 5px;
|
27
|
+
width: 95vw;
|
28
|
+
height: 50vh;
|
29
|
+
overflow: auto;
|
30
|
+
}
|
31
|
+
|
32
|
+
.inarea {
|
33
|
+
border: thin solid #000000;
|
34
|
+
margin: 5px;
|
35
|
+
padding: 5px;
|
36
|
+
width: 98%;
|
37
|
+
}
|
38
|
+
|
39
|
+
input.long {
|
40
|
+
width: 98%;
|
41
|
+
background-color: #FAFAFA;
|
42
|
+
margin: 5px;
|
43
|
+
padding: 5px;
|
44
|
+
}
|
45
|
+
|
46
|
+
textarea.long {
|
47
|
+
width: 95vw;
|
48
|
+
height: 50vh;
|
49
|
+
}
|
50
|
+
|
51
|
+
.ui-widget {
|
52
|
+
font-size: 12px;
|
53
|
+
}
|
54
|
+
|
55
|
+
.ui-autocomplete {
|
56
|
+
max-height: 45vh;
|
57
|
+
max-width: 90wh;
|
58
|
+
overflow-y: auto;
|
59
|
+
overflow-x: auto;
|
60
|
+
padding-right: 10px;
|
61
|
+
}
|
62
|
+
|
63
|
+
#jquery-ui-autocomplete label {
|
64
|
+
float: left;
|
65
|
+
margin-right: 0.5em;
|
66
|
+
color: black;
|
67
|
+
}
|
68
|
+
|
69
|
+
.ui-autocomplete.ui-front {
|
70
|
+
max-height: 250px;
|
71
|
+
overflow-y: auto;
|
72
|
+
/* prevent horizontal scrollbar */
|
73
|
+
overflow-x: hidden;
|
74
|
+
/* add padding to account for vertical scrollbar */
|
75
|
+
z-index: 1000 !important;
|
76
|
+
}
|
77
|
+
|
78
|
+
.ui-dialog {
|
79
|
+
position: absolute;
|
80
|
+
top: 0;
|
81
|
+
left: 0;
|
82
|
+
padding: .2em;
|
83
|
+
outline: 0;
|
84
|
+
}
|
85
|
+
|
86
|
+
.long {
|
87
|
+
width: 90%;
|
88
|
+
}
|
89
|
+
|
90
|
+
#setting_dialog {
|
91
|
+
color: #ffffff;
|
92
|
+
background-color: #000000;
|
93
|
+
}
|
94
|
+
|
95
|
+
.setting_name {
|
96
|
+
width: 200px;
|
97
|
+
color: #ffffff;
|
98
|
+
background-color: #000000;
|
99
|
+
}
|
100
|
+
|
101
|
+
.setting_value {
|
102
|
+
width: 300px;
|
103
|
+
color: #ffffff;
|
104
|
+
background-color: #000000;
|
105
|
+
}
|
106
|
+
|
107
|
+
.setting_checkbox {
|
108
|
+
color: #ffffff;
|
109
|
+
background-color: #000000;
|
110
|
+
}
|
111
|
+
|
112
|
+
ul.log {
|
113
|
+
list-style-type: none;
|
114
|
+
font-size: 12px;
|
115
|
+
color: #000000;
|
116
|
+
}
|
117
|
+
|
118
|
+
input[type="search"] {
|
119
|
+
-webkit-appearance: searchfield;
|
120
|
+
}
|
121
|
+
|
122
|
+
input[type="search"]::-webkit-search-cancel-button {
|
123
|
+
-webkit-appearance: searchfield-cancel-button;
|
124
|
+
}
|
125
|
+
|
126
|
+
/* menu */
|
127
|
+
.menu {
|
128
|
+
display: flex;
|
129
|
+
justify-content: flex-start;
|
130
|
+
list-style-type: none;
|
131
|
+
color: #393737;
|
132
|
+
padding: 0;
|
133
|
+
font-size: 12px;
|
134
|
+
font-weight: bold;
|
135
|
+
}
|
136
|
+
|
137
|
+
.menu li {
|
138
|
+
position: relative;
|
139
|
+
width: 100px;
|
140
|
+
margin-left: 1px;
|
141
|
+
padding: 5px;
|
142
|
+
background: #d8dada;
|
143
|
+
list-style-type: none;
|
144
|
+
}
|
145
|
+
|
146
|
+
.menu li a {
|
147
|
+
color: rgb(20, 114, 192);
|
148
|
+
}
|
149
|
+
|
150
|
+
.menu li a:hover {
|
151
|
+
background: #eba399;
|
152
|
+
}
|
153
|
+
|
154
|
+
.menuSub {
|
155
|
+
position: absolute;
|
156
|
+
margin-left: -6px;
|
157
|
+
padding: 0;
|
158
|
+
display: none;
|
159
|
+
}
|
160
|
+
|
161
|
+
/*.openが付与された時、表示の設定*/
|
162
|
+
.menuSub.open {
|
163
|
+
display: block;
|
164
|
+
}
|
165
|
+
|
166
|
+
.menuSub li a {
|
167
|
+
padding: 5px;
|
168
|
+
margin-left: -5px;
|
169
|
+
margin-right: -5px;
|
170
|
+
margin-bottom: -5px;
|
171
|
+
display: block;
|
172
|
+
color: rgb(20, 114, 192);
|
173
|
+
text-decoration: none;
|
174
|
+
}
|
175
|
+
|
176
|
+
.menuSub li a:hover {
|
177
|
+
background: #eba399;
|
178
|
+
}
|
data/lib/del_comment.py
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
import sys
|
4
|
+
import ast
|
5
|
+
import astor
|
6
|
+
import pprint
|
7
|
+
|
8
|
+
def remove_comments_from_code(code):
|
9
|
+
# コードをASTに変換
|
10
|
+
tree = ast.parse(code)
|
11
|
+
|
12
|
+
#print("----------")
|
13
|
+
#print(ast.dump(tree, indent=4))
|
14
|
+
#print("----------")
|
15
|
+
|
16
|
+
# ASTを操作してコメントを削除
|
17
|
+
for node in ast.walk(tree):
|
18
|
+
|
19
|
+
#print(vars(node))
|
20
|
+
#print("--------------------------------------------------")
|
21
|
+
#pprint.pprint(vars(node))
|
22
|
+
if isinstance(node, ast.Expr) and isinstance(node.value, ast.Str) and isinstance(node.value.s, str):
|
23
|
+
# 文字列としてコメントが格納されているExprノードを削除
|
24
|
+
if node.value.s.startswith(("#", '"""', "'''")):
|
25
|
+
node.value.s = "" # コメントを空文字列に設定
|
26
|
+
|
27
|
+
# ASTからコードに変換
|
28
|
+
modified_code = astor.to_source(tree)
|
29
|
+
|
30
|
+
return modified_code
|
31
|
+
|
32
|
+
if __name__ == "__main__":
|
33
|
+
file = sys.argv[1]
|
34
|
+
f = open(file, "r")
|
35
|
+
code_without_comments = remove_comments_from_code(f.read())
|
36
|
+
print(code_without_comments)
|
data/lib/html/index.html
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
7
|
+
<title>PythonUMLClass</title>
|
8
|
+
<!-- jQuery -->
|
9
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
10
|
+
<!-- jQuery UI -->
|
11
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
|
12
|
+
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
|
13
|
+
|
14
|
+
<script src="js/main.js"></script>
|
15
|
+
<link rel="stylesheet" href="css/index.css" type="text/css">
|
16
|
+
</head>
|
17
|
+
|
18
|
+
<body>
|
19
|
+
<div id="msg_dialog" style="display:none;">
|
20
|
+
<div id="msg_text">message</div>
|
21
|
+
</div>
|
22
|
+
<hr>
|
23
|
+
<!-- menu -->
|
24
|
+
<div id="setting_dialog" style="display:none;">
|
25
|
+
<dl id="wrap"></dl>
|
26
|
+
</div>
|
27
|
+
<div>
|
28
|
+
<ul class="menu">
|
29
|
+
<Li><a href="#" id="exec" name="exec">実行</a></li>
|
30
|
+
<li><a href="#" id="stop" name="stop">停止</a></li>
|
31
|
+
<li>
|
32
|
+
設定
|
33
|
+
<ul class="menuSub">
|
34
|
+
<li><a href="#" id="setting">設定</a></li>
|
35
|
+
<li><a href="#" id="save_setting">設定保存</a></li>
|
36
|
+
<li><a href="#" id="load_setting">設定読み込み</a></li>
|
37
|
+
</ul>
|
38
|
+
</li>
|
39
|
+
<!--
|
40
|
+
<li>
|
41
|
+
menu3
|
42
|
+
<ul class="menuSub">
|
43
|
+
<li><a href="#">menu3-1</a></li>
|
44
|
+
<li><a href="#">menu3-2</a></li>
|
45
|
+
</ul>
|
46
|
+
</li>
|
47
|
+
-->
|
48
|
+
</ul>
|
49
|
+
</div>
|
50
|
+
|
51
|
+
<table>
|
52
|
+
<tr>
|
53
|
+
<td>
|
54
|
+
<div id="dialog1" style="display:none;">
|
55
|
+
<input class="inarea" type="search" name="search_str" id="search_str">
|
56
|
+
</div>
|
57
|
+
</td>
|
58
|
+
<td class="long"><input class="inarea" type="search" id="inDir" name="inDir"></td>
|
59
|
+
<td><input type="button" id="select_dir" value="対象フォルダ" /></td>
|
60
|
+
</tr>
|
61
|
+
<tr>
|
62
|
+
<td>
|
63
|
+
<div id="dialog2" style="display:none;">
|
64
|
+
<input class="inarea" type="search" name="search_str2" id="search_str2">
|
65
|
+
</div>
|
66
|
+
</td>
|
67
|
+
<td class="long"><input class="inarea" type="search" id="outFile" name="outFile"></td>
|
68
|
+
<td><input type="button" id="select_file" value="出力ファイル" /></td>
|
69
|
+
<td><input type="button" id="open_file" value="開く" /></td>
|
70
|
+
</tr>
|
71
|
+
</table>
|
72
|
+
|
73
|
+
<div class="outarea">
|
74
|
+
<ul name="log" id="log" class="log">
|
75
|
+
</ul>
|
76
|
+
</div>
|
77
|
+
|
78
|
+
</body>
|
79
|
+
|
80
|
+
</html>
|