Предыдущая версия справа и слеваПредыдущая версия | |
wiki:devel:parser [2025/01/17 13:05] – [Формат данных инструкций] vladpolskiy | wiki:devel:parser [2025/01/17 13:53] (текущий) – [Преобразователь] vladpolskiy |
---|
Пример массив инструкций страницы с описанием [[wiki:syntax|синтаксиса]] можно найти [[wiki:devel:parser:sample_instructions|здесь]]. | Пример массив инструкций страницы с описанием [[wiki:syntax|синтаксиса]] можно найти [[wiki:devel:parser:sample_instructions|здесь]]. |
| |
==== Преобразователь ==== | ==== Renderer (преобразователь) ==== |
| |
Преобразователь --- это класс (или коллекция функций), определяемый вами. Его интерфейс описан в файле ''inc/parser/renderer.php'' и выглядит так: | Renderer (преобразователь) --- это класс (или коллекция функций), определяемый вами. Его интерфейс описан в файле ''inc/parser/renderer.php'' и выглядит так: |
| |
<code php> | <code php> |
class Doku_Renderer { | class Doku_Renderer { |
| |
// snip | // вырезка |
| |
function header($text, $level) {} | public function header($text, $level) {} |
| |
function section_open($level) {} | public function section_open($level) {} |
| |
function section_close() {} | public function section_close() {} |
| |
function cdata($text) {} | public function cdata($text) {} |
| |
function p_open() {} | public function p_open() {} |
| |
function p_close() {} | public function p_close() {} |
| |
function linebreak() {} | public function linebreak() {} |
| |
function hr() {} | public function hr() {} |
| |
// snip | // вырезка |
} | } |
</code> | </code> |
| |
Он используется для документирования преобразователя, хотя также может быть расширен, если вы захотите написать преобразователь, который лишь перехватывает определённые вызовы. | Он используется для документирования Renderer, хотя его также можно расширить, если вы хотите написать Renderer, который захватывает только определенные вызовы. |
| |
Основной принцип того, как инструкции, возвращаемые парсером, используются преобразователем, близок по смыслу к [[wp>ru:SAX|SAX XML API]] --- инструкции являются перечнем имён функций / методов и их аргуменов. Каждая инструкция может быть вызвана через преобразователь (т. е. реализуемые им методы являются [[wp>ru:Callback_(программирование)|обратными]]). В отличие от «SAX API», где доступно совсем немного, достаточно общих, обратно вызываемых методов (например, tag_start, tag_end, cdata и т. д.), преобразователь определяет более точную API, где методы обычно соответствуют один-к-одному действию по генерации выходных данных. | Основной принцип того, как инструкции, возвращаемые парсером, используются против Renderer, аналогичен понятию [[wp>Simple_API_for_XML|SAX XML API]] - инструкции представляют собой список имен функций/методов и их аргументов. Проходя по списку инструкций, каждая инструкция может быть вызвана против Renderer (т. е. методы, предоставляемые Renderer, являются [[wp>Callback_(computer_science)|callbacks]]). Unlike the SAX API, where only a few, fairly general, callbacks are available (e.g. tag_start, tag_end, cdata etc.). В отличие от SAX API , где доступно только несколько, довольно общих, обратных вызовов (например, tag_start, tag_end, cdata и т. д.), Renderer определяет более явный API , где методы обычно соответствуют один к одному акту генерации вывода. В разделе Renderer, показанном выше, методы ''p_open'' и ''p_close'' будут использоваться для вывода тегов ''%%<p>%%'' и ''%%</p>%%'' в XHTML, соответственно, в то время как ''header'' функция принимает два аргумента — некоторый текст для отображения и «уровень» заголовка, поэтому вызов типа ''%%header('Some Title', 1)%%'' будет выведен в XHTML типа ''%%<h1>Some Title</h1>%%''. |
| |
Во фрагменте преобразователя, показанном выше методы ''p_open'' и ''p_close'' будут использованы для вывода тэгов ''%%<p>%%'' и ''%%</p>%%'' в XHTML, соответственно, в то время, как функция ''header'' принимает два аргумента --- некоторый текст для отображения и «уровень» заголовка, так что вызов типа ''%%header('Some Title',1)%%'' выведет в XHTML ''%%<h1>Some Title</h1>%%''. | === Вызов рендерера с инструкциями === |
| |
=== Вызов преобразователя через инструкции === | Клиентскому коду, использующему Parser, остается выполнить список инструкций для Renderer. Обычно это делается с помощью функции PHP [[phpfn>call_user_func_array()]] function. Например; |
| |
К **клиентскому коду** относится использование парсера для выполнения перечня инструкций через преобразователь. Обычно это делается использованием php-функции «[[phpfn>call_user_func_array]]». Например: | |
| |
<code php> | <code php> |
// Получить перечень инструкций из парсера | // Получить список инструкций от парсера |
$instructions = $Parser->parse($rawDoc); | $instructions = $parser->parse($rawDoc); |
| |
// Создать преобразователь | // Создаем рендерер |
$Renderer = & new Doku_Renderer_XHTML(); | $renderer = new Doku_Renderer_xhtml(); |
| |
// Пройтись по всем инструкциям | // Проходим по инструкциям |
foreach ( $instructions as $instruction ) { | foreach ($instructions as $instruction) { |
| // Выполняем обратный вызов для Renderer |
// Выполнить инструкции через преобразователь | call_user_func_array([$renderer, $instruction[0]], $instruction[1]); |
call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]); | |
} | } |
</code> | </code> |
| |
=== Методы преобразователя для ссылок === | === Методы связи с рендерером === |
| |
Ключевыми методами преобразователя для обработки различного рода ссылок являются: | Ключевые методы Renderer для обработки различных типов ссылок: |
| |
* ''%%function camelcaselink($link) {} // $link вида «SomePage"%%'' | * ''function [[xref>camelcaselink($link)]] %%{} // $link like "SomePage"%%'' |
* Возможно, это будет проигнорировано проверкой на спам-адрес --- маловероятно, что кто-нибудь подобным образом поставить ссылку вне сайта. | *Вероятно, это можно проигнорировать для проверки на спам — никто не должен иметь возможности ссылаться на сторонние сайты с таким синтаксисом. |
* ''%%function internallink($link, $title = NULL) {} // $link вида «[[syntax]]"%%'' | * ''function [[xref>internallink($link, $title = null)]]%% {} // $link like "[[syntax]]"%%'' |
* Хотя ''$link'' сама по себе является внутренней, ''$title'' может быть недоступным изображением, так что требуется проверка. | *Хотя ''$link'' сам по себе является внутренним, ''$title'' может быть изображением, которое находится вне сайта, поэтому необходимо проверить |
* ''%%function externallink($link, $title = NULL) {}%%'' | * ''function [[xref>externallink($link, $title = null)]] {}'' |
* И ''$link'', и ''$title'' (изображение) требуют проверки. | *Оба изображения ''$link'' и ''$title'' (изображения) нуждаются в проверке |
* ''%%function interwikilink($link, $title = NULL, $wikiName, $wikiUri) {}%%'' | * ''function [[xref>interwikilink($link, $title = null, $wikiName, $wikiUri)]] {}'' |
* ''$title'' требует проверки для изображений. | *Необходимость ''$title'' проверки изображений |
* ''%%function filelink($link, $title = NULL) {}%%'' | * ''function [[xref>filelink($link, $title = null)]] {}'' |
* Технически, только годные ''%%file://%%'' URL будут совпадать, но всё равно лучше проверить плюс проверка ''$title'', которое может быть недоступным изображением. | *Технически должны совпадать только действительные ''%%file://%%'' URL-адреса, но, вероятно, лучше все равно проверить, плюс ''$title'' может быть стороннее изображение |
* ''%%function windowssharelink($link, $title = NULL) {}%%'' | * ''function [[xref>windowssharelink($link, $title = null)]] {}'' |
* Требуется проверить только годные адреса доступа к общим ресурсам Windows, но всё равно лучше проверить плюс проверка ''$title'', которое может быть недоступным изображением. | *Должен соответствовать только допустимым URL-адресам общих ресурсов Windows, но в любом случае проверять наличие ''$title'' изображений |
* ''%%function email($address, $title = NULL) {}%%'' | * ''function [[xref>emaillink($address, $title = null)]] {}'' |
* ''$title'' может быть изображением. Проверять ли адрес электропочты? | *''$title'' может быть изображение. Проверить почту тоже?$titleможет быть изображение. Проверить почту тоже? |
* ''%%function internalmedialink ($src,$title=NULL,$align=NULL,$width=NULL,$height=NULL,$cache=NULL) {}%%'' | * ''function [[xref>internalmedialink($src, $title = null, $align = null, $width = null, $height = null, $cache = null)]] {}'' |
* Здесь проверка не требуется --- следует только поставить ссылки на локальные изображения. ''$title'' сам по себе не может быть изображением. | *Это не требует проверки — должно ссылаться только на локальные изображения. ''$title'' само по себе не может быть изображением |
* ''%%function externalmedialink($src,$title=NULL,$align=NULL,$width=NULL,$height=NULL,$cache=NULL) {}%%'' | * ''function [[xref>externalmedialink($src, $title = null, $align = null, $width = null, $height = null, $cache = null)]] {}'' |
* ''$src'' требует проверки. | *''$src'' нуждается в проверке |
| |
Особое внимание следует уделит методам, принимающим в качестве параметра ''%%$title%%'', который представляет видимый текст ссылки, например: | Особого внимания требуют методы, которые принимаютe ''%%$title%%'' аргумент, представляющий видимый текст ссылки, например; |
| |
<code html> | <code html> |
<a href="http://www.example.com/">This is the title</a> | <a href="https://www.example.com">This is the title</a> |
</code> | </code> |
| |
Аргумент ''%%$title%%'' может принимать три возможных типа значений: | Аргумент ''%%$title%%'' может иметь три возможных типа значений; |
| |
- ''NULL'': у документа вики нет заголовка; | - ''null'': в вики-документе заголовок не указан. |
- строка: в качестве заголовка использована простая тестовая строка; | - string: в качестве заголовка использовалась простая текстовая строка |
- массив (хэш): в качестве заголовка использовано изображение. | - array (hash): в качестве заголовка использовано изображение. |
| |
Если ''%%$title%%'' является массивом, он будет содержать ассоциированные значения, описывающие изображение: | Если это ''%%$title%%'' массив, он будет содержать ассоциативные значения, описывающие изображение; |
| |
<code php> | <code php> |
$title = array( | $title = [ |
// Может быть 'internalmedia' (локальное изображение) или 'externalmedia' (внешнее изображение) | // Может быть 'internalmedia' (локальное изображение) или 'externalmedia' (внешнее изображение) |
'type'=>'internalmedia', | 'type' => 'internalmedia', |
| |
// URL изображения (может быть вики-URL или http://static.example.com/img.png) | // URL-адрес изображения (может быть URL-адресом wiki или https://static.example.com/img.png) |
'src'=>'wiki:php-powered.png', | 'src' => 'wiki:php-powered.png', |
| |
// Для альтернативного атрибута - a string or NULL | // Для атрибута alt - строка или null |
'title'=>'Powered by PHP', | 'title' => 'Powered by PHP', |
| |
// 'left', 'right', 'center' или NULL | // 'left', 'right', 'center' или null |
'align'=>'right', | 'align' => 'right', |
| |
// Ширина в пикселях или NULL | // Ширина в пикселях или null |
'width'=> 50, | 'width' => 50, |
| |
// Высота в пикселях или NULL | // Высота в пикселях или null |
'height'=>75, | 'height' => 75, |
| |
// Следует ли кэшировать изображение (для внешних изображений)? | // Кэшировать ли изображение (для внешних изображений) |
'cache'=>FALSE, | 'cache' => false, |
); | ]; |
</code> | </code> |
| |