Новости | FAQ | Авторы | Документация | В действии | Библиотека |
Инструменты | Полезные ссылки | Хостинги | Скачать | Примеры | Форум |
Yuriy V. Vorontsov (Че) 25.04.2004 19:39 / 25.04.2004 19:48
Неплохо доработал класс:# коммен- # тарий @method[params][locals] ...code ...Т.е. отельно комментарий, название метода, сам код!
type parent value comment code file /library/autodocs//autodocs.p MyCLASS not avaliable MAIN Расширение базовых функций Parser3 method MAIN @auto[] \n$CONTENT[^table::create{path}]\n\n\n global MAIN $CONTENT defined @auto[] $CONTENT method MAIN @create[init] \n Конструктор\n 1.... global MAIN $PATH global MAIN $MASK global MAIN $INSIDE global MAIN $MAKEFILE defined @create[init] $PATH defined @create[init] $MASK defined @create[init] $INSIDE defined @create[init] $MAKEFILE ...Структура файла
type – тип объекта ( file – имя обработанного файла, MyCLASS – данные из @CLASS, MyUSE – данные из @USE, MyBASE – данные из @BASE, method – имя макроса (метода), global – статическое поля класса, defined – определённая переменная в методе ) parent – владелец переменной value – значение объекта (имя класса, метода, переменной или значение поля) comment – комментарий к данному code – код метода, только для методовЗамеченные баги:
@default[param1;param2] $result[^if(def $param1){$param1}{$param2}] @checked[param;value;isDefault] $result[^if($param eq $value || (!def $param && def $isDefault)){checked}] @main[] <title>Самодокументирование парсерного кода</title> <form method="GET"> Путь к папке: <input name="library" value="^default[$form:library;/]"><br> Просматривать: <input type="radio" name="mask" id="a" value="\.p^$" ^checked[$form:mask;\.p^$;x]> <label for=a>Библиотеки (.p)</label> / <input type="radio" name="mask" id="b" value="\.html^$" ^checked[$form:mask;\.html^$]> <label for=b>Файлы (.html)</label> / <input type="radio" name="mask" id="c" value="\.(html|p)^$" ^checked[$form:mask;\.(html|p)^$]> <label for=c>Библиотеки и файлы (.p и .html)</label> <br> Просмотривать вложенные папки: <input type="radio" name="in" id="1" value="1" ^checked[$form:in;1;x]> <label for=1>Да</label> / <input type="radio" name="in" id="0" value="0" ^checked[$form:in;0]> <label for=0>Нет</label> <br> Кэш файл формировать?: <input type="radio" name="file" id="I" value="1" ^checked[$form:file;1]> <label for=I>Да</label> / <input type="radio" name="file" id="II" value="0" ^checked[$form:file;0;x]> <label for=II>Нет</label> <br> <input type="hidden" name="run" value="1"> <input name="do" type="submit"> </form> ^if(def $form:run){ <HR width="100%"> $autodocs[^autodocs::create[ $.path[$form:library] $.mask[^untaint[as-is]{$form:mask}] $.in(^form:in.int(0)) $.file(^form:file.int(0)) ]] ^autodocs.scan[] } ######################################## @CLASS autodocs @auto[] $CONTENT[^table::create{path}] # Конструктор # 1. init = путь к папку где сканировать # 2. init.path = путь к папку где сканировать # init.mask = маска в regexp # init.in = (1/0) открывать вложенные папки @create[init] $PATH[/] $MASK[\.p^$] $INSIDE(0) $MAKEFILE(0) ^if($init is string){ $PATH[$init] }{ ^if($init is hash){ ^if(def $init.path){ $PATH[$init.path] } ^if(def $init.mask){ $MASK[$init.mask] } ^if(def $init.in){ $INSIDE(^init.in.int(1)) } ^if(def $init.file){ $MAKEFILE(^init.file.int(1)) } }{ ^throw[autodocs.create;$init;Входной параметр задан не верно, это может быть string или hash.] } } # Начать сканирование @scan[] ^scandir[$PATH] ^if($CONTENT){ ^CONTENT.menu{ ^open[$CONTENT.path] } } #$result[] # Рекурсивный просмотр папок @scandir[folder][folder;list] $list[^file:list[$folder]] ^list.menu{ ^if(^list.name.match[$MASK][]){ ^add[$folder/$list.name] } ^if($INSIDE && (-d "$folder/$list.name")){ ^scandir[$folder/$list.name] } } #$result[] # Добавить файл в стэк обработки @add[file] ^CONTENT.append{$file} #$result[] # Обрезать ужас моего не знания regexp'а @cut[string;also] ^if(def $string){ $string[^string.match[\n$also][g]{}] $result[^string.match[\n+^$][g]{}] }{ $result[] } # Обрезать ужас моего не знания regexp'а и символы комментариев @change_comment[string] ^if(def $string){ $result[^string.match[#+][g]{}] }{ $result[] } @unescape_br[string] ^if(def $string){ $string[^string.match[^^\s*][g]{}] $string[^string.match[\s*^$][g]{}] $string[^string.match[\n\n+][g]{<p>}] $string[^string.match[\n][g]{<br>}] $result[$string] }{ $result[] } # открыть файл @open[file][f;HELP;table;GHELP] ^if(-f $file){ $f[^file::load[text;$file]] $f[$f.text] $HELP[^table::create{method comment code}] $GHELP[^hash::create[]] $table[^f.match[ # Сам текст комментария ( (?: (?:^^|\n)\#+ ^[^^\n^]* )* )? # Разделитель между комментарием и методом (?: \s* )? # Макрос / Метод / CLASS / BASE / USE ( \n@^[^^\n^]* ) # Код / Содержание ( (?: \n^[^^\n^]* (?! (?: (?: \n\#+^[^^\n^]* )* )? (?: \s+ )? (?: \n@^[^^\n^]* ) ) )* ) ][gxs]] $f[] ^table.menu{ ^if(^table.2.match[@(CLASS|BASE|USE)][]){ $GHELP.[My^cut[$table.2;@]][ $.value[^cut[$table.3]] $.comment[^change_comment[$table.1]] ] }{ ^HELP.append{^cut[$table.2] ^change_comment[$table.1] $table.3} } } $table[] ^make[$file;$GHELP;$HELP] $HELP[] $GHELP[] # $result[] }{ ^throw[autodocs.open;$file;${file}: Такой файл не найден] } # Получить локальные переменные # except имена какие исключить @getlocals[string;except] ^if(def $string && (def $except && $except is table || !def $except) ){ $string[^string.match[ # Сам текст комментария ( (?: (?:^^|\n)\#+ ^[^^\n^]* )* )? # Объект (?: # Пока буду брать только вменяемые имена (у egr'а вариант такой ^^^$@^;()#) # \n\s*(\^$^[^^\n^]+) \n\s*(\^$^[\w\d\-_^]+)^[\^[\^{\(^] ) ][gxs]] $string[^string.select(!^string.2.match[^^\^$result^$][])] $result[^table::create{name comment}] ^string.menu{ ^if(!^result.locate[name;$string.2] && (def $except && !^except.locate[name;$string.2] || !def $except) ){ ^result.append{$string.2 $string.1} } } }{ $result[^table::create{name comment}] } # Получить параметры макроса, в том числе и локальные переменные, copy paste с egr'а @getparams[string][table] ^if(def $string){ $table[^string.match[ ^^\s* # Имя метода @([^^^$@^;()#]+?) # Передаваемые параметры \^[ (.*?) \^] # Локальные переменные (?: \^[ (.*?) \^] )? \s*^$ ][gxs]] # Параметры и переменные $table[^;${table.2}^;${table.3}^;] $table[^table.split[^;]] $table[^table.select(def $table.piece)] $result[^table::create{name}] ^table.menu{ ^result.append{^$$table.piece} } }{ $result[^table::create{name}] } ########################## # taint to sql @sql-taint[string][ws_pack_replace] $ws_pack_replace[^table::create[nameless]{\ \\ ^taint[^#0A] \n ^taint[^#09] \t}] ^if(def $string){ $result[^string.replace[$ws_pack_replace]] ; $result[] } ########################## # taint to sql @sql-untaint[string][ws_unpack_replace] $ws_unpack_replace[^table::create[nameless]{\n ^taint[^#0A] \t ^taint[^#09] \\ \}] ^if(def $string){ $result[^string.replace[$ws_unpack_replace]] ; $result[] } ############################################################ # метод для записи таблицы в файл, с предварительной заменой символов перевод строки и табуляция на \n и \t # copy paste с Misha.3 @table_save[table;file_name][col;tmp] $col[^table.columns[]] $tmp[^col.menu{$col.column}[^#09]^#0A^table.menu{^col.menu{^sql-taint[$table.[$col.column]]^#09}}[^#0A]] ^tmp.save[$file_name] $result[] # Сделать структуру @make[file;GHELP;HELP][container;VARS;PARAMS;GLOBAL;MyCLASS] $container[^table::create{type parent value comment code}] $GLOBAL[^table::create{name comment method}] # $file: ^container.append{file $file } # GHELP # конфигурационные данные ^if(def $GHELP.MyCLASS){ ^container.append{MyCLASS not avaliable $GHELP.MyCLASS.value $GHELP.MyCLASS.value } $MyCLASS[$GHELP.MyCLASS.value] }{ ^container.append{MyCLASS not avaliable MAIN Расширение базовых функций Parser3 } $MyCLASS[MAIN] } ^if(def $GHELP.MyBASE){ ^container.append{MyBASE $MyCLASS $GHELP.MyBASE.value $GHELP.MyBASE.comment } } ^if(def $GHELP.MyUSE){ ^container.append{MyUSE $MyCLASS $GHELP.MyUSE.value $GHELP.MyUSE.comment } } # HELP ^if($HELP){ ^HELP.menu{ ^container.append{method $MyCLASS $HELP.method $HELP.comment $HELP.code} ^if(def $HELP.code){ # Переменные метода $VARS[^getlocals[$HELP.code;^getparams[$HELP.method]]] ^if($VARS){ ^VARS.menu{ ^if(!^GLOBAL.locate[name;$VARS.name]){ ^GLOBAL.append{$VARS.name $VARS.comment $HELP.method} ^container.append{global $MyCLASS $VARS.name $VARS.comment } } } } $VARS[^getlocals[$HELP.code]] ^if($VARS){ ^VARS.menu{ ^container.append{defined $HELP.method $VARS.name $VARS.comment } } } } } } # Сделать файл? ^if($MAKEFILE){ ^table_save[$container;^file.match[[/\.]][g]{_}.cfg] } $result[^show[$file;$GHELP;$HELP;$GLOBAL]] @show[file;GHELP;HELP;GLOBAL][VARS] $result[ ^if(def $GHELP.MyCLASS){ <H1>Класс: $GHELP.MyCLASS.value</H1> ^if(def $GHELP.MyCLASS.comment){ <h4><ul>^unescape_br[$GHELP.MyCLASS.comment]</ul></h4> } }{ <H1>Класс: MAIN</H1> <h3>Расширение базовых функций Parser3</h3> } <H2>Файл $file</H2> ^if($GLOBAL){ <H2>Статические поля класса:</H2> <ol> ^GLOBAL.menu{ <li> <strong>$GLOBAL.name</strong> (определяется в <a href="#$GLOBAL.method">$GLOBAL.method</a>): ^if(def $GLOBAL.comment){ <br> <i>^change_comment[$GLOBAL.comment]</i> } </li> }[<p>] </ol> } ^if($HELP){ <table border=1> ^HELP.menu{ <tr> <td align="left" valign="top" width="10%"> <a name="$HELP.method"/> <pre>$HELP.method</pre> <ul>^unescape_br[$HELP.comment]</ul> # <p>^unescape_br[$HELP.code] $VARS[^getlocals[$HELP.code]] ^if($VARS){ <p>Объявленные в методе переменные: <ol> ^VARS.menu{ <li> <strong>$VARS.name</strong>: ^if(def $VARS.comment){ <br> <i>^change_comment[$VARS.comment]</i> } </li> }[<p>] </ol> } </td> </tr> } </table> } <HR width=100%> ]