camel
Mодуль HTML::Phl
Для обработки HTML-документов, содержащих инструкции с кодом Perl

[help file from 22.12.2016]


Оглавление:

Спецификация PHL

  • Указатели

  • Разделители

  • Ключи

  • Функции

  • Модули-расширения

  • Конфигурационные настройки

Дистрибутив PHL


Спецификация PHL  ↑ 

В HTML документе perl-код размещается с помощью своеобразных инструкций. У каждой такой инструкции есть начало и конец, позволяющие идентифицировать код perl в документе.

В спецификации PHL определено три варианта написания инструкций:


1. Линейная инструкция:
   %pl [keys] [perl code] 
2. Инструкция в виде однострочного блока:
   <%pl[(:|=)[name]] [keys] [perl code] %>
3. Многострочный блок:
   <%pl[(:|=)[name]] [keys]
      [perl code]
   %>
где

'%pl', '<%pl', '%>' - указатели инструкции (определяют начало и конец кода Perl);

[name] - имя блока (используется при идентификации блоков, преимущественно при параллельном программировании);

':' или '=' - разделители (с одной стороны являются разделителями между указателями инструкции и именем блока, с другой стороны, обладают рядом дополнительных функциональных особенностей);

[keys] - управляющие ключи (позволяют видоизменять код Perl, заключенный в инструкции, перед тем как его передать интерпретатору на выполнение);

[perl code] - код Perl.


 1 %pl print sqrt(2);
 2    
 3 <%pl print $var; %>
 4 
 5 <%pl= $var; %>
 6 
 7 <%pl
 8    foreach my $key(keys(%ENV)) {
 9       print "$key - $ENV{$key}<br>";
 10    }
 11 %>

Управляющие элементы [name] и [keys] используются не так часто, и с успехом можно обойтись и без них, но их использование бывает весьма удобным.


 1 <%pl:f1 -fork
 2    # Код дочернего процесса
 3    my $f = "Данные дочернего процесса f1";
 4    sleep 1;
 5    return $f;
 6 %>
 7 
 8 <%pl -join=f1
 9    # Результат дочернего процесса f1
 10    print $phl_join{f1};
 11 %>

К стандартным функциям Perl в PHL дополнительно добавлена функция 'include()'), реализованная для возможности сборки документа из нескольких файлов.


 1 %pl include($file_name);
 2    
 3 <%pl include("$file_name", "socket"); %>
 4 
 5 <%pl
 6    my $result = include("$file_name", "open decode");
 7 %>

Указатели  ↑ 

По умолчанию указатели имеют вид: '<%pl', '%>' и '%pl'

Указатели можно переопределить в настройках файла 'Phl.pm' или в конфигурационном файле 'config.phl'. В результате, можно написать так <% ...code perl... %> или так [ ...code perl... ] или даже вoт так ♣ ...code perl... ♥.

При желании можно определить свои собственные (дополнительные) указатели инструкций или переопределить существующие. Это реализуется с помощью специально оформленных модулей.

К примеру, с помощью модуля 'HTML::Phl::Php' в дополнение к указателю инструкции '<%pl' добавляется указатель '<%php', позволяющий выполнить простой код языка программирования PHP.

Пример:

 1 %pl -ev use HTML::Phl::Php;
 2 
 3 <%php
 4   echo "PHP >> <b>OK</b><br>";
 5   echo date('H:i:s d.m.Y');
 6 %>

Результат

Разделители ↑ 

Задача разделителей - отделить указатель инструкции от имени блока.

В отличие от ':', разделитель '=' изменяет в анализаторе интерпретацию кода. При этом, результат применения разделителя '=' в однострочном и многострочном блоках различаются.


 1 %pl  my $test = "<b>тест</b>";
 2 
 3 1. Переменная '<%pl= $test %>' внутри однострочного блока.
 4 <br><br>
 5 
 6 <%pl=name1
 7    2. Переменная '$test' внутри
 8    многострочного блока '<b>$phl_blok[1]</b>' (разделитель '=').
 9 %>
 10 <br><br>
 11 
 12 <%pl:name2
 13    print "3. Переменная '$test'";
 14    print "внутри многострочного блока '<b>$phl_blok[2]</b>' (разделитель ':').";
 15 %>

Код после анализатора:

 1 my $test = "<b>тест</b>";
 2  print <<'[HTML]';
 3  
 4 [HTML]
 5  print <<'[HTML]' =~ /(.*)/;
 6 1. Переменная '
 7 [HTML]
 8 print($test);
 9  print <<'[HTML]';
 10 ' внутри однострочного блока.
 11 [HTML]
 12  print <<'[HTML]';
 13 <br><br>
 14  
 15 [HTML]
 16  print <<"[HTML]";
 17    2. Переменная "$test" внутри
 18    многострочного блока "<b>$phl_blok[1]</b>" (разделитель "=").
 19 [HTML]
 20  print <<'[HTML]';
 21 <br><br>
 22  
 23 [HTML]
 24    print "3. Переменная '$test'";
 25    print "внутри многострочного блока '<b>$phl_blok[2]</b>' (разделитель ':').";

Результат

Ключи ↑ 

Ключи позволяют видоизменять код perl, размещенный в инструкциях.

Их можно указывать в полном или в сокращенном виде.

[keys] : -begin    <=> -bg
         -end      <=> -end
         -perl_all <=> -pl
         -eval     <=> -ev
         -fork     <=> -fk
         -thread   <=> -td
         -join     <=> -jn

• Ключи '-begin' [ '-bg' ] и '-end'

При использовании ключа '-begin' анализатор берет код perl, содержащийся в инструкции, и оборачивает его блоком 'BEGIN {}'.

То же самое происходит при использовании ключа '-end' - код perl помещается в блок 'END {}'.


Исходный код:

 1 1. Текст HTML<br>
 2 <%pl -end
 3    print "2. Первый end<br>";
 4 %>
 5 3. Текст HTML<br>
 6 
 7 <%pl -begin
 8    print "4. Первый begin<br>";
 9 %>
 10 5. Текст HTML<br>
 11 
 12 <%pl -end
 13    print "6. Второй end<br>";
 14 %>
 15 7. Текст HTML<br>
 16 
 17 <%pl -bg
 18    print "8. Второй begin<br>";
 19 %>
 20 9. Текст HTML<br>

После анализатора

Результат


• Ключ '-perl_all' [ '-pl' ]

При использовании данного ключа, отпадает необходимость ограничивать код perl указателями инструкций. Анализатор будет воспринимать весь текст документа, как Perl-код.


 1 %pl -pl
 2 
 3 use CGI;
 4 
 5 print "Content-type: text/html; charset=utf-8\n\n";
 6 
 7 my $test = "Текст";
 8 my $q = new CGI;
 9 
 10 print $q -> h4("$test из модуля CGI");
 11 print ("<H4>$test из Phl</H4>");

Результат


• Ключ '-eval' [ '-ev' ]

Ключ позволяет выполнить код, заключенный внутри инструкции, в процессе работы анализатора (перед его выполнением eval).

Например, попробуем с помощью данного ключа изменить указатели '<%pl' и др., разместив в коде следующую инструкцию:

 1 <%pl -eval
 2    $phl{lt} = '[';
 3    $phl{rt} = ']';
 4    $phl{ln} = '~';
 5    $phl{sh} = '';
 6 %>

Указатели инструкций приобрели совершенно другой вид.

Теперь инструкцию можно написать таким вот образом:

 1 [=
 2    Многострочный блок
 3 ]

или таким

 1 [ print "Однострочный блок" ]

или таким

 1 ~ print "Линейная инструкция"

• Ключ '-fork' [ '-fk' ]

Код, заключенный внутри инструкции, выполняется в параллельном дочернем процессе, созданном в результате запуска fork().


 1 <%pl:f1 -fork
 2    # Код дочернего процесса с именем f1
 3    my $f;
 4    sleep 1; # Параллельная обработка данных процессом f1
 5    return $f;
 6 %>  

• Ключ '-thread' [ '-td' ]

Код, заключенный внутри инструкции, выполняется в параллельном потоке ("нити", "ветке" процесса), созданном стандартным модулем 'threads' в рамках одного процесса.


 1 <%pl:t1 -thread
 2    # Код нити с именем t1
 3    my $t;
 4    sleep 1; # Параллельная обработка данных нитью t1
 5    return $t;
 6 %>  

• Ключ '-join' [ '-jn' ]

Ключ дает возможность получить результаты выполнения дочерних процессов и нитей.

Результаты размещаются в хэше %phl_join, ключами которого являются имена создаваемых процессов/потоков. Если при обращении за результатом нужные параллельные процессы ещё не завершились, программа ждет их завершения.



 1 <%pl -join
 2    # Результаты выполнения параллельных дочерних процессов и потоков
 3    foreach my $key(keys(%phl_join)) {
 4       if (ref $phl_join{$key}) {  # если значение - ссылка
 5          my @result = @{$phl_join{$key}};
 6          print "процесс '$key' - результат первого аргумента '$result[0]'";
 7       } else {
 8          print "процесс '$key' - результат '$phl_join{$key}'";
 9       }
 10    }
 11 %>

• Дополнительные ключи

При желании можно определить свои собственные (дополнительные) ключи или переопределить существующие. Это реализуется с помощью специально оформленных модулей.

Так, к примеру, с помощью модуля 'HTML::Phl::Utilit' и ключа '-import' [ '-im' ] можно просмотреть список всех указателей, ключей и параметров, в данный момент доступных программе.

Пример:

 1 %pl -ev use HTML::Phl::Utilit;
 2 
 3 %pl -import

Результат

Функции ↑ 

В PHL добавлена всего одна функция 'include()', реализованная для возможности сборки документа из нескольких файлов, содержащих HTML (TXT) или PHL разметку.

Функция 'include()' похожа на стандартную Perl функцию 'open()', с тем отличием, что первым аргументом является имя включаемого в документ файла, а вторым - один или несколько специальных управляющих параметров.


 1 %pl include($file_name);
 2    
 3 <%pl include("$file_name", "socket"); %>
 4 
 5 <%pl
 6    my $result = include("$file_name", "open decode");
 7 %>

В общем случае, написание функции 'include()' выглядит так:


include("file_name" [, "param" [, "name_process"]]);


file_name : "file_name.phl"
            "file_name.cgi"
            "file_path/file_name.phl"
            "/file_path/file_name.html"
            "http://domain/file_path/file_name.html"

[param] :
          phl        <=>  phl
          exist      <=>  ex
          head       <=>  hd
          abs        <=>  abs  
          no_abs     <=>  na   
          no_eval    <=>  ne   
          no_strict  <=>  ns   
          open       <=>  on   
          decode     <=>  dc  
          no_decode  <=>  nd   
          cgi        <=>  cgi  
          socket     <=>  sk   
          fork       <=>  fk   
          thread     <=>  td   

зависимости :
          phl [.phl] <= exist, head, abs, decode
          cgi [.cgi] <= require, decode
          open       <= decode, abs
          socket     <= exist, head, no_abs, decode, no_decode
          fork       <= waitpid, no_waitpid
          thread     <= join, detach


Первый аргумент 'file_name' кроме имени файла может содержать зарезервированные слова "JOIN", "CONFIG" или "TIMER".

Если файл 'file_name' имеет расширение '.phl', то такой файл идентифицируется, как файл формата PHL. Расширение может быть изменено в настройках с помощью $phl{pl}.

При вызове функции 'include()' в неопределенном контексте результат выполнения кода Perl помещается в тело документа внутри функции print().

При скалярном или списковом контексте результат возвращается в виде запрашиваемого значения переменной или списка значений соответственно.


 1 <%pl
 2    include("file_name.phl");
 3    my $result = include("file_name.phl");
 4    my @result = include("file_name.phl");
 5 %>

Второй аргумент функции 'include()' может содержать один или несколько специальных управляющих параметров.


• Параметр 'phl'

Данный параметр указывает обработчику, что код, содержащийся в подключаемом файле, представляет собой документ формата PHL.

Данные файла отправляются в анализатор, где преобразуются в perl-код и передаются 'eval'.

Параметр 'phl' выполняет аналогичные действия, если бы мы в имени включаемого файла просто указали расширение '.phl' (расширение можно изменить в настройках в '$phl{pl}').


 1 <%pl
 2    include("file_name.txt", "phl");
 3    my $result = include("file_name.html", "phl decode=utf-8");
 4    my @result = include("file_name", "phl abs");
 5 %>

• Параметр 'exist' ('ex')

Позволяет проверить существование файла.


 1 <%pl
 2    my $exist_file = include("$file_name", "exist");
 3    if ($exist_file) {
 4       print "Файл $file_name найден";
 5    } else {
 6       print "Файл $file_name не найден";
 7    }
 8 %>

• Параметр 'head' ('hd')

Возвращает список из 5 элементов: Content type, Document length, Modified time, Expires, Server.


 1 <%pl
 2    my @head = include("$file_name", "head");
 3 %>

• Параметр 'abs'

Если указан параметр 'abs', осуществляется преобразование относительных ссылок, указанных в файле, в абсолютные.


 1    %pl include("$file_name", "abs");

• Параметр 'no_eval' ('ne')

При указании данного параметра результат выполнения кода включаемого файла игнорируется.


 1 <%pl include("$file_name", "no_eval") %>

• Параметр 'no_strict' ('ns')

Если указан параметр 'no_strict', то на код загружаемого файла '$file_name' действие прагмы 'use strict' не распространяется.


 1 <%pl
 2    include("$file_name", "ns");
 3 %>

• Параметр 'open' ( 'on' )

Как и функция 'open()', служит для открытия файла и извлечения из него каких-либо данных (возможность записи данных в файл отсутствует).


 1 <%pl
 2    include("$file_name", "open");
 3    my $result = include("$file_name", "open decode=koi8-r");
 4    my @result = include("$file_name", "on, decode=cp1251, abs");
 5 %>

В скалярном или неопределённом контексте данные считываются "побайтно":


 1    my $code;
 2    open(my $fh, "<$file_name");
 3       while (sysread($fh, my $bate, 8*1024)) {
 4          $code .= $bate;
 5       }
 6    close($fh);

В списковом контексте данные файла считываются построчно:


 1    open(my $fh, "$file_name");
 2       flock($fh, 1);
 3       @result = <$fh>;
 4    close($fh);

• Параметр 'decode' ('dc')

При наличии параметра 'decode' данные из указанной в параметрах кодировки (к примеру, 'decode=cp1251') декодируются во внутренний формат Perl.

Если кодировка не указана или отсутствует параметр 'decode', то при декодировании подразумевается, что кодировка включаемого файла соответствует $phl{encoding_in}, указанной в настройках phl.pm (или config.phl).


 1    $_ = decode($decode, $_);
 2    $_ = decode($phl{encoding_in}, $_);

Если кодировка результирующего документа отлична от 'utf-8', то дополнительно осуществляется кодирование данных в кодировку $phl{encoding_out}, указанную в настройках phl.pm (или config.phl).


 1    $_ = encode($phl{encoding_out}, $_);

Кодирование и декодирование данных осуществляется с использованием стандартного модуля 'Encode.pm'.


• Параметр 'cgi'

Данный параметр предназначен для подключения cgi-скриптов, написанных на Perl.


 1 <%pl
 2    include("file_name.cgi");
 3    include("$file_name", "cgi");
 4    include("$file_name", "cgi require");  
 5    include("file_name.cgi", "decode=cp866");
 6 %>

Совместно с параметром 'cgi' могут применяться дополнительные параметры 'decode', 'require'.

○ параметр 'decode' ('dc')

Служит для декодирования cgi-скриптов Perl, написанных не в UTF-8 кодировке.

○ параметр 'require' ('rq')

Указывает на подключение cgi-скриптов с помощью стандартной функции 'require'

.
 1    require "$file_name";


• Параметр 'socket' ('sk')

Применяется для загрузки web-документа с помощью стандартного модуля 'IO::Socket::INET'


 1 <%pl
 2    include("file_name.html", "socket");
 3    include("http://domain/");
 4    my $text = include("http://domain/file_path/file_name.html", "decode=cp1251");
 5    my @result = include("$file_name", "decode no_abs");
 6 %>

Если адрес включаемого в документ файла начинается с http или ftp, то указывать параметр 'socket' не обязательно.

Совместно с параметром 'socket' могут применяться дополнительные параметры 'exist', 'head', 'no_abs', 'decode', 'no_decode'.

○ параметр 'exist' ('ex')

Позволяет проверить существование домена, файла, адреса.


 1 <%pl
 2   my @include_name_file = (
 3     'dir1/name_file.html',
 4     '/dir2/name_file.php',
 5     'http://www.yandex.ru',
 6     'http://www.yandex/eklmnfjoeqxngsitwf.html',
 7     'http://eklmnfjoeqxngsitwfhoevd.ru'
 8   );
 9  
 10   foreach my $name_file (@include_name_file) {
 11     my $ex = include("$name_file", "socket exist");
 12     if ($ex) {
 13        print "Файл '$name_file' найден<br>";
 14     } elsif (!defined $ex) {
 15        print "Ресурс '$name_file' не отвечает<br>";   
 16     } else {
 17        print "Файл '$name_file' не найден<br>";
 18     }
 19   }
 20 %>

○ параметр 'head' ('hd')

Возвращает заголовок документа


 1 <%pl
 2   foreach my $name_file (@test_name_file) {
 3     my @head = include("$name_file", "socket head");
 4     if ($#head) {
 5        print "Заголовок от '$name_file' получен => '@head[0..3]'<br>";
 6     } else {
 7        print "Заголовка от '$name_file' нет => '@head'<br>";
 8     }
 9   }
 10 %>

○ параметр 'no_abs' ('na')

По умолчанию, все относительные ссылки заменяются на абсолютные, но если указан параметр 'no_abs', то этого не происходит.


 1 %pl include("$file_name", "socket no_abs");

○ параметр 'decode' ('dc')

Служит для декодирования документов из кодировки, указанной параметром 'decode', во внутренний формат Perl и далее в кодировку, указанную в настройках в $phl{encoding_out}.

Если параметр 'decode' используется без указания исходной кодировки запрашиваемого файла, то декодирование осуществляется с учетом кодировки, указанной в заголовке файла в 'charset' (при наличии).

Если параметр 'decode' не используется, по умолчанию подразумевается, что наш файл в кодировке utf-8.

При использовании параметра 'no_decode' ('nd') никакого декодирования данных не происходит.


 1 <%pl
 2    include("http://www.rbc.ru", "decode=utf-8");
 3    include("http://www.mail.ru", "decode");
 4    my $html_text1 = include("http://ru.motorsport.com");
 5    my $html_text2 = include("http://www.google.com", "nd");
 6 %>

• Параметр 'fork' ('fk')

Код загружаемого файла выполняется в параллельном дочернем процессе, созданном в результате запуска 'fork()'.


 1 <%pl
 2    include("$file_name", "fork");
 3 %>

Результат выполнения параллельного процесса можно вернуть в родительский, используя 'return' в тексте инструкции включаемого файла.


 1 <%pl
 2    # Код дочернего процесса $phl_var{name}
 3    my $f = "Передаваемые данные";
 4    sleep 1;
 5    return $f;
 6 %>

В третьем аргументе функции 'include()' можно указать уникальное имя дочернего процесса, чтобы затем обратиться за результатом выполнения дочернего процесса "по имени".


 1 <%pl
 2    include("$file_name", "fork", "f1");
 3 %>

○ параметр 'waitpid' ('wd')

Для того, чтобы вернуть результат выполнения дочернего процесса в точку вызова функции 'include()', необходимо дополнительно к параметру 'fork' указать параметр 'waitpid' или в качестве третьего аргумента функции 'include()' указать 'waitpid'.

Результат отработки параллельного процесса можно вернуть обратно в родительский процесс, вызвав 'include()' в скалярном или списковом контексте.


 1 <%pl
 2    $result = include("$file_name", "fork waitpid");
 3    @result = include("$file_name", "fork", "waitpid");
 4 %>

На самом деле, можно вообще отказаться от параметра 'waitpid', как во втором так и в третьем аргументе. В таком случае, программа всё равно будет ждать завершения дочернего процесса, а функция 'include()' получается менее громоздкой.


 1 <%pl
 2    @result = include("$file_name", "fork", "");
 3    $result = include("$file_name", "fk");
 4 %>

○ параметр 'no_waitpid' ('nw')

Результат выполнения процесса вернуть не удастся, если только, не попробовать что-либо записать в файл или вывести на экран.


 1 <%pl
 2    include("$file_name", "fork no_waitpid");
 3    include("$file_name", "fork", "no_waitpid");
 4 %>

○ аргумент 'JOIN'

Для обращения за результатом выполнения дочернего процесса можно использовать функцию 'include()', где в качестве первого аргумента необходимо указать зарезервированное слово 'JOIN', вторым аргументом - имя или имена дочерних процессов.


 1 <%pl
 2    include("$file_name", "fork", "f1");
 3   
 4    # Далее может следовать тело программы с некоторым кодом
 5 
 6    my $rezult = include("JOIN", "f1");
 7 %>

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


 1 <%pl
 2    my %join_2_3 = include("JOIN", "f2 f3"); 
 3    print "Результат процесса 'f2' = $join_2_3{f2}<br>";
 4 
 5    my %join_all = include("JOIN");
 6    foreach my $key(keys(%join_all)) {
 7       if (ref $join_all{$key}) {
 8          my @result = @{$join_all{$key}};
 9          print "Результат процесса '$key' = '$join_all{$key}' => и первый разыменованный элемент массива = '$result[0]'<br>";
 10       } else {
 11          print "Результат процесса '$key' = '$join_all{$key}'<br>";
 12       }
 13    }
 14 %>

• Параметр 'thread' ('td')

Создается, так называемая, "нить" ("поток") - своеобразная ветка процесса, в которой возможно выполнение кода параллельно коду породившего нить процесса.

Для создания нити используется стандартный модуль 'thread' (в свою очередь, Perl должен быть настроен на работу с тредами).


 1 <%pl
 2    include("$file_name", "thread");
 3 %>

Как и в случае с параметром 'fork', при использовании нитей существует возможность вернуть результат выполнения созданной нити, как в точку вызова функции 'include()', так и в произвольную точку программы или вообще "забыть" о результате, ничего не возвращая.

○ параметр 'join' ('jn')

Результат выполнения нити возвращается в точку вызова, при этом родительский процесс временно прекращает своё выполнение и ждет получения данных (от созданных потоков).


 1 <%pl
 2    $result = include("$file_name", "thread join");
 3    @result = include("$file_name", "thread", "join");
 4    %result = include("$file_name", "thread");
 5 %>

○ параметр 'detach' ('dh')

Нить создается, но что в ней происходит основная ветка процесса не знает.


 1 <%pl
 2    include("$file_name", "thread detach");
 3    include("$file_name", "thread", "detach");
 4 %>

Вернуть данные в любую точку основной ветки процесса можно, присвоив нити имя (по аналогии с дочерним процессом, создаваемым параметром 'fork').


 1 <%pl
 2    include("$file_name", "thread", "t1");
 3    include("$file_name", "thread", "t2");
 4    include("$file_name", "thread", "t3");
 5   
 6    my $rezult = include("JOIN", "t2");
 7    print "Результат нити 't2' = '$rezult'<br>";
 8 
 9    my %join = include("JOIN", "t1 t3"); 
 10    print "Результат нити 't1' = '$join{t1}'<br>";
 11    print "Результат нити 't3' = '$join{t3}'<br>";
 12 %>

• Дополнительные параметры

При желании можно определить свои собственные (дополнительные) параметры или переопределить существующие. Это реализуется с помощью специально оформленных модулей.

Так, к примеру, с помощью модуля 'HTML::Phl::Utilit' и параметра 'analyzer' ('az') появляется возможность просмотреть сформированный анализатором код perl включаемого файла перед его выполнением eval.

пример:

 1 %pl -ev use HTML::Phl::Utilit;
 2 
 3 <%pl
 4    include("$file_name", "as");
 5 %>

Листинг

Результат

Модули-расширения PHL ↑ 

Для достижения большей гибкости работы в PHL реализована возможность задавать собственные указатели инструкции [sh], ключи [keys], первый аргумент [include] и параметры [param] функции 'include()'.

   <%[sh] [keys]
      ...
      include("[include]", "[param]");
      ...
   %>

Новые ключи, параметры и указатели импортируются в phl.pm из специально написанных для данных целей модулей.


Для примера в PHL включены 4 модуля:


 1   use HTML::Phl::Utilit;
 2   use HTML::Phl::Psimple;
 3   use HTML::Phl::Php;
 4   use HTML::Phl::Ru;

Модули можно подключить как в файле 'phl.pm' или 'config.phl', так и в файле PHL.

 1 %pl -ev use HTML::Phl::Utilit
 2 
 3 <%pl
 4    # код perl
 5 %>

• Модуль 'HTML::Phl::Utilit'

Модуль экспортирует в программу 5 ключей, 2 параметра и 2 аргумента для функции 'include()'.

[keys] : 
        -listing   <=>  -lt
        -analys    <=>  -as
        -config    <=>  -cf
        -timer     <=>  -tm   
        -no_timer  <=>  -nt   

[param] :
        listing    <=>  lt
        analys     <=>  as

[include] : 
        CONFIG
        TIMER

Ключи '-listing' [ '-lt' ] и '-analys' [ '-as' ] и параметры 'listing' ( 'lt' ) и 'analys' ( 'as' ) дают, возможность просмотреть листинг программы или сформированный анализатором код perl перед его выполнением eval.


Ключ '-listing' [ '-lt' ]

 1 Текст HTML 1
 2 <br><br>
 3 
 4 <%pl -lt
 5    my $test = "Текст Perl<br>";
 6    print "$test";
 7 %>
 8 <br>
 9 
 10 Текст HTML 2

Результат

Ключ '-analys' [ '-as' ]

 1 %pl -as
 2 
 3 <%pl
 4    my $test = "Текст Perl<br>";
 5    print ("$test");
 6 %>
 7 
 8 Текст HTML и <%pl= $test %>

Результат

Ключ '-config' [ '-cf' ] или аргумент 'CONFIG' функции 'include()' выводят на печать хэш %phl конфигурационных переменных.


 1 %pl -config
 2 
 3 или так
 4 
 5 <%pl
 6    include("CONFIG");
 7 %>

Результат


Ключи '-timer' [ '-tm' ] и '-no_timer' [ '-nt' ] позволяют изменить механизм вывода на экран временных промежутков работы компонентов программы, а используя аргумент 'TIMER' функции 'include()' можно задать свой таймер.


 1 <%pl
 2 # запуск встроенного таймера
 3 %pl -timer
 4 
 5 # остановка встроенного таймера
 6 %pl -nt
 7 %>

Пример

 1 <%pl
 2   # пример создания своего таймера
 3   include("TIMER", "имя таймера");
 4 %>

Пример

• Модуль 'HTML::Phl::Php'

Экспортирует указатель 'php', превращая указатель инструкции '<%pl' в '<%php', для возможности работы с кодом языка программирования PHP;


 1 %pl -ev use HTML::Phl::Php;
 2 
 3 %pl our $pl = 5;
 4 
 5 Исходная переменная PERL: $pl = <b>'<%pl= $pl %>'</b>.
 6 <br><br>
 7 
 8 <%php
 9    echo "Значение переменной \$pl передаем в PHP (\$pl -> \$php).<br>";
 10    OUT_PERL($pl -> $php);
 11  
 12    echo "<li>переменная \$php = $php.</li><br>";
 13 
 14    echo "В PHP изменяем значение переменной: \$php = 2 * \$php + 1.5.<br><br>";
 15    $php = 2 * $php + 1.5;
 16 
 17    echo "Возвращаем значение переменной \$php в PERL (\$php -> \$pl).<br>";
 18    IN_PERL($php -> $pl);
 19 %>
 20 
 21 <li>Результирующая переменная PERL: $pl = <b>'<%pl= $pl %>'</b></li>.

Результат

• Модуль 'HTML::Phl::Ru'

Экспортирует указатель 'рус', превращая указатель инструкции '<%pl' в '<%рус', позволяя работать с некоторыми функциями и операторами кириллического написания.


 1 %pl -ev use HTML::Phl::Ru;
 2 
 3 <%рус
 4   my @имена_файлов = (
 5     'file_exist.phl',
 6     'http://www.pushkinmuseum.ru',
 7     'http://www.pushkinmuseum.ru/467899',
 8     'http://eklmn12344556778.ru'
 9   );
 10  
 11   foreach my $имя_файла (@имена_файлов) {
 12     my $найдено = ВКЛЮЧИТЬ("$имя_файла", "socket exist");
 13     ЕСЛИ ($найдено) {
 14          ПЕЧАТЬ "'$имя_файла' - <B>найден</B><br>";
 15     } ИЛИ ЕСЛИ (!defined $найдено) {
 16          ПЕЧАТЬ "'$имя_файла' - <B>не отвечает</B><br>";   
 17     } ИНАЧЕ {
 18          ПЕЧАТЬ ("'$имя_файла' - <B>не найден</B><br>");
 19     }
 20   }
 21 %>

Результат

• Модуль 'HTML::Phl::Psimple'

Экспортирует параметр 'Simple' ['sl'] для работы со стандартным модулем Perl 'LWP::Simple';


Спецификация модулей-расширений

Для возможности экспорта ключей, параметров и указателей модули должны размещаться в определенной папке (по умолчанию - в 'Phl', находящейся рядом с основным файлом программы 'phl.pm') и содержать двумерный хэш '%phl_import', в котором ключами второго хеша будут экспортируемые ключи, параметры и указатели.

Хэш '%phl_import' может включать 5 ключей - 'sh', 'key', 'param', 'include' и 'eval'.


 1    our %phl_import = (
 2       key    => {
 3                   tm    => \&HTML::Phl::Utilit::key_timer,
 4                   im    => \&HTML::Phl::Utilit::print_import,
 5                 },
 6       include => {
 7                   TIMER  => \&HTML::Phl::Utilit::my_timer,
 8                   CONFIG => \&HTML::Phl::Utilit::config,
 9                 },
 10       param   => {lt    => \&HTML::Phl::Utilit::open_listing},
 11       sh      => {'рус'  => \&HTML::Phl::Ru::ru_perl},
 12       eval    => {as    => \&HTML::Phl::Utilit::eval_code}
 13    );

○ Ключ хэша 'sh'

Позволяет использовать иное написание инструкций совместно с принятым по умолчанию в настройках.

К примеру, наряду с использованием конструкции '<%pl ... %>' для Perl-кода можно задать блоки инструкций вида '<%xml ... %>' для кода XML.

Значением ключа хэша 'sh', в таком случае, должен являться анонимный хэш, ключом которого будет новое расширение (в нашем случае - 'xml'), значением - ссылка на подпрограмму обработки кода, заложенного в инструкции (к примеру '\&HTML::Phl::Name_module::my_xml').

В подпрограмму в таком случае, будут переданы следующие элементы @_ = ($code, $sh, $nota, $key),
где
$code - код, заключенный внутри инструкции;
$sh - наше новое расширение инструкции;
$nota, $key - разделитель и ключи блока инструкции (при их наличии).

Подпрограмма модуля должна вернуть обратно в программу измененный perl-код для дальнейшего его выполнения eval.


○ Ключ хэша 'key'

Позволяет использовать ключи, отличные от используемых по умолчанию.

Если анализатор среди ключей инструкций найдет ключ, соответствующий ключу анонимного хэша 'key', в подпрограмму, указанную в анонимном хэше, будет передан массив @_ = ("$code", "$number_blok", "$key"),
где $number_blok - номер блока инструкции.


○ Ключ хэша 'param'

Позволяет использовать свои параметры в функции 'include()'.

В подпрограмму, указанную в анонимном хэше, будет передан массив @_ = ("$file_include", "$param", "$name_process", "$file_url", "$file_name"),
где
$file_include - первый аргумент функции 'include()';
$param - параметры, указанные в 'include()';
$name_process - имя дочернего процесса или потока (нити) ;
$file_url - путь к файлу, включающий доменное имя;
$file_name - имя файла, выделенное из $file_include.


○ Ключ хэша 'include'

Позволяет перехватить выполнение функции 'include()', передав управление модулю.

В подпрограмму, указанную в анонимном хэше, будет передан массив @_ = ("$include", "$param", "$name_process", "$file_url", "$file_name"),
где
$include - первый аргумент функции 'include()'.

○ Ключ хэша 'eval'

Позволяет выполнять манипуляции с кодом перед его выполнением eval.

В подпрограмму, указанную в анонимном хэше, будет передан массив @_ = ("$code", "$param", "$phl_var{name}", "$file_include").


Конфигурационные настройки ↑ 

Конфигурационные файлы 'config.phl' позволяют переопределять базовые переменные. Их можно размещать в любой web-директории, содержащей PHL файлы.

Конфигурационные файлы разрабатываются в формате Perl и содержат значения ключей хеша %phl.


# Расширение файлов, обрабатываемых анализатором программы, как файлы формата PHL (по умолчанию принято расширение - '.phl')

$phl{pl} = 'phl';


# Имя файла, которое ищет функция 'include()' в директории, если не указан загружаемый файл, к примеру http://domain.ru/file_path/

$phl{index} = 'index.phl';


# Осуществлять или не осуществлять поиск конфигурационных файлов 'config.phl' в директории загружаемых include() файлов [ yes/no ]

$phl{finde_config} = "yes";


# Определение указателей инструкций [ по умолчанию, '<%pl code_perl %>', '%pl line_code_perl' ]

$phl{lt} = '<%'; # начало блока инструкции

$phl{rt} = '%>'; # конец блока инструкции

$phl{ln} = '%'; # линейная инструкция

$phl{sh} = 'pl'; # указатель принадлежности к языковой конструкции (в данном случае к perl)

# Заголовок документа [ к примеру, "Content-type: text/html; charset=utf-8\n\n"; $phl_header = "" - нет заголовка ]

$phl{header} = "";


# Верхний колонтитул

$phl{top} = "";


# Нижний колонтитул

$phl{bottom} = "";


# Сброс буфера [ "1" соответствует => $| = 1, "0" соответствует => $| = 0 ]

$phl{bufer} = 1;


# Использование потоков (нитей) [ 1/0 ]

$phl{threads} = 1;


# Подсчитывается время загрузки компонентов [ различная степень детализации => "0" - нет, "1"..."4" - да ]

$phl{timer} = 0;


# Кодировка файлов [ cp1251, utf8, koi8-r, iso-8859-5, cp866 ... ]

$phl{encoding_in} = "utf8"; # кодировка загружаемых include() файлов

$phl{encoding_out} = "utf8"; # кодировка результирующего документа

$phl{locale} = "utf8"; # кодировка имен файлов файловой системы



Дистрибутив PHL ↑ 

Модуль 'HTML::Phl' вместе с дополнительными модулями-расширениями, тестами и примерами можно скачать здесь.

При желании опробовать работу модуля в ОС Android, необходимо установить SL4A, позволяющий в данной среде запускать perl-программы, в частности веб-сервер, способный генерировать HTML страницы по запросам Perl.

Как написать свой веб-сервер на Perl под Android можно ознакомиться здесь или скачать немного измененный под работу с PHL вариант здесь.