Первая инструкция
сопоставляет идентификатору файл, вторая - перенаправляет к другой
записи.
Помимо всего прочего при загрузке документа, ему могут быть переданы
некие дополнительные параметры, которые могут повлиять на его поведение.
Параметры могут быть также прописаны и в инструкциях перенаправления.
По мере прохождения по инструкциям параметры накапливаются. Например,
если мы делали обрашение "/ param1 value1", а файл сопоставлений был:
(/ view /some param2 value2)
(/some file "myfile.scm")
То будет загружен файл документа "myfile.scm" и переданы ему параметры
param1 и param2 со значениями value1 и value2 соответсвенно.
Перейдём далее к более подробному описанию структуры документа. На
данный момент, структура сложилась следующая.
На самом верхнем уровне неявно присутствуют глобальные переменные
переданные документу,
Доступ к ним осуществляется через кострукцию
global, например
(global 'param1) вернёт значение
value1 в нашем случае.
Далее следует собственно тело документа. В документе присутствует
два вида инструкций, одни, начинающиеся с префикса "document:",
отвечают за общую структуру, оставшиеся - за его содержимое, включая
разметку.
При загрузке документ последовательно проходит через ряд трансформаций,
превращающих его в последовательность более простых инструкций, которые
в свою очередь поступают на вход к главному двигателю , а отнего к
драйверу того или иного интерфейса. Поэтому при рассказе про общую
структуру, я буду показывать во что трансформируются те или иные
инструкции.
Замечание:
В текущей стабильной
версии alterator уровень абстракции, который я называю тут "общая
структура документа" отсутствует, присутвует только описание виджетов
(второй уровень)
Начнём с общей структуры.
Документ состоит из последовательности "сред", среды могут быть вложены
друг в друга (чем то похоже на TeX)
Начало среды ознаменуется инструкцией
(document:envelop имя-среды параметры).
Окончание среды
-
(document:envelop имя-среды).
Если окончание среды не обнаружено, то она простирается вплоть до
окончания файла обрабатываемого документа.
Трансформация состоит в том, что содержимое среды фактически
оборачивается функцией "имя среды".
То есть:
(a)
(document:envelop
with-translation _ "alterator-common")
(b)
(document:end-envelop
with-translation)
(with-translation _
"alterator-common" (b))
(c))
А:
(a)
(document:envelop
with-translation _ "alterator-common")
(b)
(c)
Превратится в:
((a)
(with-translation _ "alterator-common" (b) (c)))
Другая инструкция занимается организацией явной связью между
документами -
document:link.
Связь может быть нескольких видов:
- insert - содержимое
другого документа вставляется в данный "как есть"
- popup - в данном месте
появляется активный элемент, например кнопка, при нажатии на который
возникает всплывающее окошко, содержащие другой документ
- rollup - также как в
предыдущем случае появляется активный элемент, при нажатии на который
прямо в данном документе появляется и исчезает (выкатывается и
скатывается обратно) другой документ
- subdocument - равносильно
использованию инструкции document:subdocument. Очень похоже на insert,
другой документ вставляется в текущий, однако:
- используемые в нём локальные переменные будут "скрыты" от
посторонних глаз. Вы получите от него только элементы интерфейса,
однако вся "динамика" будет работать в функциях, недоступных вам.
- включаемый документ получает собственный расширенный фрейм
глобальных переменных: то есть ему будут доступны все глобальные
переменные родительского документа, а его глобальные переменные не
будут нигде фигурировать в родительском документе.
Таким образом простое изменение типа связи - и вы получаете другое
представление документа.
Самая простейшая трансформация происходит в случае типа insert, Поэтому
рассмотрим пример для insert.
Пусть вставляемый документ:
(0)
(1)
(2)
Основной документ:
(a)
(document:link to ("/a") type insert)
(b)
(c)
Результат трансформации:
((a) (0) (1) (2) (b) (c))
Последний способ задания структуры - инструкция
document:surround - "укутывание".
Чем же "укутывание" отличается от "заворачивания"? А вот чем.
Когда мы включаем документ, то ,если в нём есть определение "конверта"
без завершающего тега, то он будет автоматически закрыт по окончанию
включаемого документа.
Например, если включаемый документ есть:
(0)
(document:envelop under-envelop)
(1)
(2)
То:
(a)
(document:link to ("/a") type insert)
(b)
Превратится в:
((a)
(0)
(under-envelop
(1)
(2))
(b))
Обратите внимание, что элемент (b) не попал в конверт, поскольку тот
автоматически закрылся по окончанию файла включаемого документа. Однако
иногда хочется в некотором файле сохранить описание
стандартных сред, в которыми будет "обёртываться" наш документ.
Для этого есть инструкция
document:surround.
Если document:link в предыдущем примере заменить на новую
инструкцию, то:
(a)
(document:surround "/a")
(b)
Превратится в:
((a)
(0)
(under-envelop
(1)
(2)
(b)))
Обратите внимание, что весь хвост документа попал в "конверт" . Это
равносильно как будто бы сделать "включение наоборот". Как будто бы в
включаемом файле была такая инструкция:
(0)
(document:envelop
under-envelop)
(1)
(2)
(document:link to
(оставшийся хвост документа) type insert)
Поиск инструкций
document:* проходит
в глубину документа, если вы хотите защитить какой-нибудь фрагмент
документа от таких трансформаций, то просто заключите его в кострукцию
document:quote.
Таким образом:
(a)
(b)
(document:quote
(document:link to
("/a") type insert))
Превратится в:
(a)
(b)
(document:link to ("/a") type
insert)
Теперь перейдём от статического назначения связей к "динамике". В ходе
работы документ может быть замещён другим документом, для этого служит
инструкция
document:replace.
Можно также явно вызвать выплывающее окно с другим документом - это
делает инструкция
document:popup.
Ну а закрывается текущий документ командой
document:end.
Инструкция
document:replace
заменяет документ внутри некоторого фрейма. По-умолчанию, этот фрейм
совпадает со всем документом, поэтому
document:replace
- заменит документ полностью.
Есть возможность назначать свои собственные фреймы в документе, тогда
инструкция
document:replace выполненная
из элемента интерфейса, находящегося во фрейме заменит содержимое
только в этом фрейме.
Сочетание
document:frame и
document:subdocument создаёт полный
аналог фреймов в html страницах.
Ну с общей структурой всё, остальное потом ....
Замечание:
До введения слоя
абстракции управляемого инструкиями document:*, некоторые инструкции
назвались иначе:
goto
|
document:replace
|
run-dialog
|
document:popup
|
end-dialog
|
document:end
|
goto-frame
|
document:frame
|
load-url
|
document:subdocument
|
include,include-as-is
|
document:link
|