Смекни!
smekni.com

Программирование и разработка приложений в Maple (стр. 122 из 135)

Между тем, способ обновления (дополнение/удаление) справочной базы через GUI недостаточно надежен и в ряде случаев не дает результата, прежде всего при попытке обновления существующих справочных страниц. Поэтому, более надежным средством пополнения/обновления справочной базы библиотек является процедура makehelp, имеющая формат кодирования следующего вида:

makehelp(<Раздел>, <mws-файл> {, <Библиотека>})

где раздел определяет имя создаваемой справочной страницы, второй аргумент указывает имя или полный путь к mws-файлу, содержащему содержимое сохраняемой страницы, и библиотека определяет имя или полный путь к библиотеке, чья справочная база обновляется. Все фактические аргументы процедуры должны иметь symbol-тип. Имя раздела может быть простым, например, `имя` или сложным, например, `имя1/имя2`. При этом, третий аргумент необязателен, в этом случае указанный вторым аргументом файл выводится на экран в формате стандартной справочной страницы. Как правило, это делается для проверки созданной страницы перед сохранением ее в справочную базу. В любом случае, если вызов makehelp-процедуры завершается точкой с запятой (;), то файл выводится на экран в формате стандартной справочной страницы. В качестве второго аргумента может указываться как mws-файл (наиболее удобно в плане оформления), так и текстовый файл. В нашем конкретном случае вызов makehelp-процедуры может иметь следующий вид:

> makehelp(savem1, `D:/Academy/UserLib6789/Common/HelpBase/savem.mws`,

`C:&bsol;Program Files&bsol;Maple 10&bsol;UserLib`);

по которому в справочную базу нашей UserLib-библиотеки помещается справочная страница под именем savem, создаваемая на основе одноименного mws-файла, расположенного по адресу, указанному вторым фактическим аргументом. При этом, в случае завершения вызова точкой с запятой (;), данный файл выводится на экран в формате справочной страницы.

Для автоматизации функций поддержки ведения справочных баз пользовательских библиотек, аналогичных главной Maple-библиотеке пакета, нами была создана процедура helpman. Процедура helpman(R, L, U {, Z}) имеет 3 обязательных и 1 необязательный аргументы. Первый аргумент R определяет режим работы со справочной базой библиотеки, полный путь к которой (но не имя) определен вторым фактическим L аргументом, а именно:

R = insert – вставка в справочную базу библиотеки L новых справочных разделов (topics), имена которых определены третьим фактическим U аргументом типа {list, dir}; если тип аргумента U – список, то четвертый аргумент Z определяет список путей к mws-файлам со справочными разделами; при этом, между списками U и Z предполагается наличие взаимно-однозначного соответствия; если тип U аргумента – каталог, то вызов процедуры должен иметь только три фактических аргумента, где U аргумент определяет каталог с mws-файлами со справочными разделами. Во втором случае процедура выбирает все mws-файлы из указанного U каталога (если они действительно существуют) и на их основе формирует разделы в справочной базе библиотеки L. При этом, справочные разделы базы получают имена, определенные главными именами соответствующих mwsфайлов U каталога. Например, справочный раздел базы для средства 'XyZ' содержится в файле “XyZ.mws”. Процедура предполагает, что имена файлов со справочными разделами для имен объектов вида 'a/b' должны кодироваться как “a,b.mws” при их создании. При этом, процедура поддерживает регистро-зависимый режим для имен справочных разделов и эти имена не должны содержать пробелов.

R = delete – удаление справочного раздела базы с именем, заданным третьим U аргументом типа {symbol, string}, из базы данных, определенной вторым аргументом L.

R = display – вывод на экран справочного раздела, чье имя определено третьим аргументом U.

При этом, следует иметь в виду следующие обстоятельства: (1) доступ к главной библиотеке пакета (кроме режима 'display') запрещен, и (2) режимы 'display' и 'delete' предполагают только один справочный раздел; для первого режима такой подход является естественным, тогда как для второго он обеспечивает больший уровень безопасности. Процедура helpman обрабатывает основные ошибочные и особые ситуации, инициируя ошибки либо выводя соответствующие информационные сообщения.

Таким образом, процедура helpman представляет достаточно удобное средство для обновления справочной базы данных библиотек пользователя на основе заранее подготовленных mws-файлов, обеспечивая возможность создания одним вызовом несколько справочных разделов, тогда как их просмотр и удаление производится по одному для каждого вызова процедуры. Кроме того, необходимо обратить внимание на одно важное обстоятельство. В некоторых случаях цепочкой функций "Help -> Save to Database" GUI пакета помещение в пользовательскую справочную базу данных раздела не гарантируется

(при регистрации его в соответствующем индексном файле 'Maple.ind'), тогда как процедура helpman свободна от данного недостатка. Именно данное обстоятельство и послужило причиной создания helpman-процедуры.

Ниже представлен исходный текст процедуры и примеры ее применения. Именно данной процедуре, зарекомендовавшей свои эксплуатационные качества, мы отдаем предпочтение при работу со справочными базами своих Maple-библиотек. Во многих случаях она помогала решать задачу обновления справочных баз наших Maple-библиотек там, где стандартные стрдства GUI пакета оказывались бессильными.

helpman := proc( R symbol:: , L::{string symbol, }, N::{string symbol dir, , , list {( string symbol, })}) local k a b c d f g h p n m, , , , , , , , , , ; global libname;

`if`( not member( ,R {'display', 'delete', 'insert'}), ERROR(

"the 1st argument should be {insert, display, delete}, but has received <%1>",

R), `if`(Path(L) = Path cat(( CDM( ), "&bsol;LIB")) and R ≠ 'display', ERROR "access prohibition to the main Maple library", `if`(( ) not type( ,L 'dir'), ERROR "path to library <%1> does not exist",( L), assign(c = cat(L, "&bsol;maple.txt"), d = cat(L, "&bsol;maple.hdb")))));

if not type(d, 'file') then

WARNING(

"Help database for library <%1> does not exist; it has been created", L); if N = [ ] then writeline(c, "Empty Help database for your library" close( )), c , makehelp(Empty, `` c || , `` L || ), fremove( )c , RETURN(WARNING( "Empty Help database for library <%1> has been created", L)) else writeline(c, ""), close( )c , makehelp(Empty, `` c || , `` L || ), fremove( )c , procname args( )

end if

end if; if R = 'display' then if type(N, 'symbol') then return eval((proc()

libname := libname L, ;

parse cat("INTERFACE_HELP('display','topic'=",( convert(N, 'string1'), ")"))

end proc )( ))

else error

"third argument should has type 'symbol', but has received type <%1>", whattype(N)

end if end if; if R = 'delete' then if type(N, 'symbol') then return (proc(N L, ) eval parse cat("INTERFACE_HELP('delete', 'topic'=",( ( convert(N, 'string1'), ",'library'="" convert( ,, L 'string'), "")")))

end proc )(N, L)

else error "third argument %1 is invalid", [N] end if

end if;

`if`(R = 'insert' and nargs = 4 and type(N, 'list'({'symbol', 'string'})) and type(args[4], 'list'({'symbol', 'string'})), `if`(nops(N) = nops(args[4]), assign(' 'b = 14), ERROR( "mismatching of quantities of names and mws-files: %1<>%2"nops(, N), nops args[4] ))( ) , NULL);

if b = 14 then

for k to nops(N) do try makehelp convert(( N k[ ], 'symbol'), convert(args 4[ ][ ]k , 'symbol'), convert(L, 'symbol'))

catch "file or directory does not exist":

WARNING "file <%1> does not exist, the operation with it has&bsol; ( been ignored", args[4][k]);

next

catch "file or directory, %1, does not exist": WARNING("file <%1> does not exist, the operation with it has&bsol; been ignored", args 4[ ][ ]k );

next

end try

end do;

RETURN WARNING("Work has been done!")( )

elif R = 'insert' and type(N, 'dir') then

[assign(n = [ ], m = [ ]), writeto(f), Dir(N), writeto('terminal')]; do h := readline( )f ; if h = 0 then fremove( )f ; break else h := SLD(h, " "); `if`(cat "aaa", [( h -1])[-4 .. -1] = ".mws", assign(' 'p = [op(p), h[-1]]), NULL)

end if

end do end if; if p ≠ [ ] then for k to nops(p) do n := [op(n), p k[ ][1 .. -5]]; m := [op(m), cat(Path(N), "&bsol;", p k[ ])]

end do;

RETURN(procname(R, L, n, m)) else RETURN(WARNING "mws-files have not been saved in Help database"( )) end if;

WARNING "Work has not been done, mistakes at the call encoding: %1,"(

'procname args )( )'

end proc

> helpman(insert, "С:/program files/maple 10/LIB/userlib", ["DF1"], ["С:/temp/df1.mws"]); вставка справочного раздела по процедуре DF1 в справочную базу библиотеки UserLib Warning, Work has been done!

> helpman(insert, "C:/Program Files/maple 10/LIB/UserLib", ["AFdes", `a,b`],

["C:&bsol;Temp&bsol;AFdes.mws", "C:&bsol;Temp/RANS&bsol;IAN&bsol;a,b.mws"]);

Warning, file <C:/Temp/RANS&bsol;IAN/a,b.mws> does not exist, the operation with it has been ignored

Warning, Work has been done!

> helpman(insert, "С:/program files/maple 10/LIB/userlib", "С:/temp"); # вставка справоч- ного раздела в справочную базу библиотеки UserLib на основе mws-файлов каталога “C:&bsol;Temp”

Warning, Work has been done!

> helpman(display, "С:/program files/maple 10/LIB/userlib", "AFdes"); # вывод справочно- го раздела по процедуре AFdes

> helpman(delete, libname[1], ArtKr); # удаление справочного раздела ArtKr из справоч- ной базы библиотеки, путь к которой находится в начале цепочки библиотек libname- переменной

Таким образом, нами представлены довольно простые пути создания и основных функций ведения пользовательских библиотек, аналогичных главной Maple-библиотеке. Для резюмирования рассмотренного материала создадим на его основе простую процедуру, обеспечивающую базовые функции ведения пользовательских Maple-библиотек.

Процедура ulibrary имеет два формальных аргумента, но допускает любое число дополнительных в зависимости от значения первого О-аргумента, получающего значения из диапазона 1..10 и определяющего тип запроса на обработку библиотеки, определенной именем или полным путем к ней L. Аргумент О определяет следующие типы обработки библиотеки L:

1 – создание новой библиотеки, определенной L-аргументом; может определяться именем или полным путем, во втором случае допускается любой уровень вложенности каталогов 2 – сохранение в библиотеке L объектов с именами, определяемыми фактическими аргументами, начиная с 3-го; неопределенное имя в библиотеке не сохраняется