Spec-Zone.ru › Perl 5.38

perlpodspec

СОДЕРЖАНИЕ

  • НАЗВАНИЕ
  • ОПИСАНИЕ
  • Определения Pod
  • Команды Pod
  • Форматирующие коды Pod
  • Замечания по реализации обработчиков Pod
  • О кодах L<...>
  • О регионах =over...=back
  • О абзацах данных и регионах "=begin/=end"
  • СМОТРИТЕ ТАКЖЕ
  • АВТОР

НАЗВАНИЕ

perlpodspec - Простой стандартный документ: спецификация формата и заметки

ОПИСАНИЕ

Этот документ содержит подробные заметки по языку разметки Pod. Большинству пользователей достаточно будет прочитать perlpod, чтобы научиться писать на Pod, но этот документ может ответить на некоторые случайные вопросы, связанные с парсингом и рендерингом Pod.

В этом документе "должен" / "не должен", "следует" / "не следует" и "может" имеют свои общепринятые (см. RFC 2119) значения: "X должен выполнить Y" означает, что если X не выполняет Y, это противоречит данной спецификации и должно быть исправлено. "X должен выполнить Y" означает, что это рекомендуется, но X может не выполнить Y, если есть веская причина. "X может выполнить Y" просто означает, что X может выполнить Y по своему усмотрению (хотя читателю следует определить любые коннотации "и я думаю, было бы хорошо, если бы X выполнил Y" по сравнению с "меня это в действительности не беспокоит, если X выполнил Y").

Важно отметить, что когда я говорю "парсер должен выполнить Y", парсер может не выполнить Y, если вызывающее приложение явно запросило, чтобы парсер не выполнял Y. Я часто формулирую это как "парсер должен по умолчанию выполнять Y". Это не требует от парсера предоставить опцию для отключения функции Y (например, расширения табуляции в абзацах verbatim), хотя это подразумевает, что такая опция может быть предоставлена.

Определения Pod

Pod встроен в файлы, обычно файлы исходного кода Perl, хотя вы можете написать файл, состоящий только из Pod.

Строка в файле состоит из нуля или более символов, не являющихся символами новой строки, завершенных либо символом новой строки, либо концом файла.

Последовательность новой строки обычно является платформозависимым понятием, но обработчики Pod должны понимать её как любой из символов CR (ASCII 13), LF (ASCII 10) или CRLF (ASCII 13, немедленно за которым следует ASCII 10), а также любое другое значение, специфичное для системы. Первая последовательность CR/CRLF/LF в файле может использоваться в качестве основы для определения последовательности новой строки для парсинга остальной части файла.

Пустая строка — это строка, состоящая целиком из нуля или более пробелов (ASCII 32) или табуляций (ASCII 9), и завершенная символом новой строки или концом файла. Непустая строка — это строка, содержащая один или более символов, отличных от пробела или табуляции (и завершенная символом новой строки или концом файла).

(Примечание: многие старые обработчики Pod не принимали строку, состоящую из пробелов/табуляций и затем новой строки, как пустую строку. Единственными строками, которые они считали пустыми, были строки, вообще не содержащие символов, завершенные символом новой строки.)

Пробелы в этом документе используются как общее обозначение для пробелов, табуляций и последовательностей новой строки. (Само по себе это слово обычно относится к буквальным пробелам. То есть, последовательностям пробельных символов в исходном коде Pod, в отличие от "E<32>", который является форматирующим кодом, который обозначает пробельный символ.)

Обработчик Pod — это модуль, предназначенный для парсинга Pod (неважно, включает ли это вызов обратных вызовов, построение дерева разбора или непосредственное форматирование). Форматировщик Pod (или переводчик Pod) — это модуль или программа, которые преобразуют Pod в другой формат (HTML, текстовый, TeX, PostScript, RTF). Обработчик Pod может быть форматировщиком или переводчиком, или это может быть программа, которая выполняет другие действия с Pod (например, подсчет слов, поиск точек индекса и т. д.).

Содержание Pod содержится в блоках Pod. Блок Pod начинается со строки, соответствующей m/\A=[a-zA-Z]/, и продолжается до следующей строки, соответствующей m/\A=cut/, или до конца файла, если нет строки m/\A=cut/.

Обратите внимание, что парсер не должен различать то, что выглядит как под, но находится в строке с кавычками, например, в документе "здесь".

Внутри блока Pod есть абзацы Pod. Абзац Pod состоит из непустых строк текста, разделенных одной или несколькими пустыми строками.

В целях обработки Pod существуют четыре типа абзацев в блоке Pod:

  • Абзац команды (также называемый "директивой"). Первая строка этого абзаца должна соответствовать m/\A=[a-zA-Z]/. Абзацы команд обычно состоят из одной строки, как в:

    =head1 NOTES
    
    =item *

    Но они могут занимать несколько (непустых) строк:

    =for comment
    Hm, I wonder what it would look like if
    you tried to write a BNF for Pod from this.
    
    =head3 Dr. Strangelove, or: How I Learned to
    Stop Worrying and Love the Bomb

    Некоторые абзацы команд допускают форматирующие коды в своем содержимом (т. е. после части, соответствующей m/\A=[a-zA-Z]\S*\s*/), как в:

    =head1 Did You Remember to C<use strict;>?

    Иными словами, обработчик Pod для "head1" применит ту же обработку к "Did You Remember to C<use strict;>?" что и к обычному абзацу (т. е. форматирующие коды, такие как "C<...>", анализируются и, предположительно, форматируются должным образом, а пробелы в виде буквальных пробелов и/или табуляций не имеют значения).

  • Абзац verbatim. Первая строка этого абзаца должна быть буквальным пробелом или табуляцией, и этот абзац не должен находиться внутри последовательности "=begin идентификатор", ... "=end идентификатор", если "идентификатор" не начинается с двоеточия (":"). То есть, если абзац начинается с буквального пробела или табуляции, но находится внутри региона "=begin идентификатор", ... "=end идентификатор", то это абзац данных, если "идентификатор" не начинается с двоеточия.

    Пробелы имеют значение в абзацах verbatim (хотя при обработке табуляции, вероятно, будут расширены).

  • Обычный абзац. Абзац является обычным абзацем, если его первая строка не соответствует ни m/\A=[a-zA-Z]/, ни m/\A[ \t]/, и если он не находится внутри последовательности "=begin идентификатор", ... "=end идентификатор", если "идентификатор" не начинается с двоеточия (":").

  • Абзац данных. Это абзац, который находится внутри последовательности "=begin идентификатор" ... "=end идентификатор", где "идентификатор" не начинается с буквального двоеточия (":"). В некотором смысле абзац данных вообще не является частью Pod (т. е. фактически он "вне диапазона"), так как он не подвержен большинству видов парсинга Pod; но он указан здесь, так как обработчики Pod должны уметь вызывать событие для него или хранить его в некотором виде в дереве разбора или, по крайней мере, просто анализировать его вокруг.

Например: рассмотрим следующие абзацы:

# <- that's the 0th column

=head1 Foo

Stuff

  $foo->bar

=cut

Здесь "=head1 Foo" и "=cut" являются абзацами команд, потому что первая строка каждого соответствует m/\A=[a-zA-Z]/. "[пробел][пробел]$foo->bar" — это абзац verbatim, потому что его первая строка начинается с буквального пробельного символа (и нет региона "=begin"..."=end").

Команды "=begin идентификатор" ... "=end идентификатор" останавливают абзацы, которые они окружают, от парсинга как обычных или verbatim абзацев, если идентификатор не начинается с двоеточия. Это подробно обсуждается в разделе "Об абзацах данных и регионах "=begin/=end".

Команды Pod

Этот раздел предназначен для дополнения и уточнения обсуждения в "Абзаца команд" в perlpod. Вот текущие распознаваемые команды Pod:

"=head1", "=head2", "=head3", "=head4", "=head5", "=head6"

Эта команда указывает, что текст в оставшейся части абзаца является заголовком. Этот текст может содержать коды форматирования. Примеры:

=head1 Object Attributes

=head3 What B<Not> to Do!

Оба =head5 и =head6 были добавлены в 2020 году и могут не поддерживаться всеми анализаторами Pod. Pod::Simple 3.41 был выпущен в октябре 2020 года и поддерживает оба этих элемента, обеспечивая поддержку всех анализаторов Pod на основе Pod::Simple.

"=pod"

Эта команда указывает, что этот абзац начинается с блока Pod. (Если мы уже находимся в середине блока Pod, эта команда не оказывает никакого влияния.) Если в этом абзаце после "=pod" есть какой-либо текст, он должен быть проигнорирован. Примеры:

=pod

This is a plain Pod paragraph.

=pod This text is ignored.
"=cut"

Эта команда указывает, что эта строка является концом ранее начатого блока Pod. Если после "=cut" в строке есть какой-либо текст, он должен быть проигнорирован. Примеры:

=cut

=cut The documentation ends here.

=cut
# This is the first line of program text.
sub foo { # This is the second.

Попытка начать блок Pod с команды "=cut" является ошибкой. В этом случае процессор Pod должен остановить разбор входного файла и по умолчанию выдать предупреждение.

"=over"

Эта команда указывает, что это начало области списка/отступа. Если после "=over" есть какой-либо текст, он должен состоять только из положительного целого числа, отличного от нуля. Семантика этого числа поясняется в разделе "О регионах =over...=back", расположенном ниже. Коды форматирования не расширяются. Примеры:

=over 3

=over 3.5

=over
"=item"

Эта команда указывает, что элемент списка начинается здесь. Коды форматирования обрабатываются. Семантика (необязательного) текста в оставшейся части этого абзаца поясняется в разделе "О регионах =over...=back", расположенном ниже. Примеры:

=item

=item *

=item      *    

=item 14

=item   3.

=item C<< $thing->stuff(I<dodad>) >>

=item For transporting us beyond seas to be tried for pretended
offenses

=item He is at this time transporting large armies of foreign
mercenaries to complete the works of death, desolation and
tyranny, already begun with circumstances of cruelty and perfidy
scarcely paralleled in the most barbarous ages, and totally
unworthy the head of a civilized nation.
"=back"

Эта команда указывает, что это конец области, начатой самой последней командой "=over". После команды "=back" текст не допускается.

"=begin formatname"
"=begin formatname parameter"

Это отмечает следующие абзацы (до соответствующего "=end formatname") как предназначенные для некоторого специального вида обработки. Если "formatname" не начинается с двоеточия, содержащиеся абзацы без команд являются данными. Но если "formatname" начинается с двоеточия, то абзацы без команд являются обычными или данными. Это подробно обсуждается в разделе "Об абзацах данных и регионах "=begin/=end".

Рекомендуется, чтобы имена форматов соответствовали регулярному выражению m/\A:?[-a-zA-Z0-9_]+\z/. Все, что следует за пробелами после имени формата, является параметром, который может использоваться форматировщиком при работе с этой областью. Этот параметр не должен повторяться в абзаце "=end". Реализаторы должны предвидеть будущее расширение семантики и синтаксиса первого параметра "=begin"/"=end"/"=for".

"=end formatname"

Это отмечает конец области, открытой соответствующим регионом "=begin formatname". Если "formatname" не является именем формата последнего открытого региона "=begin formatname", то это ошибка, и должно быть сгенерировано сообщение об ошибке. Это подробно обсуждается в разделе "Об абзацах данных и регионах "=begin/=end".

"=for formatname text..."

Это синоним:

=begin formatname

text...

=end formatname

То есть, он создает область, состоящую из одного абзаца; этот абзац будет обрабатываться как обычный абзац, если "formatname" начинается с двоеточия; если "formatname" не начинается с двоеточия, то "text..." будет составлять абзац данных. Нет способа использовать "=for formatname text..." для выражения "text..." как абзаца без изменений.

"=encoding encodingname"

Эта команда, которая должна появиться в начале документа (по крайней мере, до любых данных, не являющихся ASCII!), объявляет, что этот документ закодирован в кодировке encodingname, которая должна быть именем кодировки, распознаваемой Encode. (Список поддерживаемых кодировок Encode в Encode::Supported здесь полезен.) Если анализатор Pod не может декодировать объявленную кодировку, он должен выдать предупреждение и может полностью прекратить разбор документа.

Документ, имеющий более одной строки "=encoding", должен считаться ошибкой. Процессоры Pod могут молчаливо терпеть это, если строки "=encoding", не являющиеся первыми, являются просто дубликатами первой (например, если есть строка "=encoding utf8", а затем еще одна строка "=encoding utf8"). Но процессоры Pod должны жаловаться, если в одном документе есть противоречивые строки "=encoding" (например, если в документе есть "=encoding utf8" в начале и "=encoding big5" позже). Процессоры Pod, которые распознают BOM, также могут жаловаться, если они видят строку "=encoding", которая противоречит BOM (например, если в документе с BOM UTF-16LE есть строка "=encoding shiftjis").

Если процессор Pod видит любую команду, отличную от перечисленных выше (например, "=head", или "=haed1", или "=stuff", или "=cuttlefish", или "=w123"), этот процессор по умолчанию должен рассматривать это как ошибку. Он не должен обрабатывать абзац, начинающийся с этой команды, по умолчанию должен предупредить об этой ошибке и может прервать разбор. Парсер Pod может позволить определённым приложениям добавить в этот список известных команд и указать для каждой дополнительной команды, следует ли обрабатывать коды форматирования.

В будущих версиях этого спецификации могут быть добавлены дополнительные команды.

Коды форматирования Pod

(Обратите внимание, что в предыдущих черновиках этого документа и perlpod коды форматирования назывались "внутренними последовательностями", и этот термин может все еще встречаться в документации по анализаторам Pod и в сообщениях об ошибках от процессоров Pod.)

Существует два синтаксиса для кодов форматирования:

  • Код форматирования начинается с заглавной буквы (только ASCII [A-Z]), за которой следует "<", любое количество символов и заканчивается первой соответствующей ">". Примеры:

    That's what I<you> think!
    
    What's C<CORE::dump()> for?
    
    X<C<chmod> and C<unlink()> Under Different Operating Systems>
  • Код форматирования начинается с заглавной буквы (только ASCII [A-Z]), за которой следуют две или более "<" , один или несколько пробелов, любое количество символов, один или несколько пробелов и заканчивается первой соответствующей последовательностью из двух или более ">" , где количество ">" равно количеству "<" в начале этого кода форматирования. Примеры:

    That's what I<< you >> think!
    
    C<<< open(X, ">>thing.dat") || die $! >>>
    
    B<< $foo->bar(); >>

    В этом синтаксисе пробелы после "C<<<" и перед ">>>" (или любой другой буквой) не отображаются. Они не обозначают пробелы, а просто являются частью самих кодов форматирования. То есть, все это равнозначно:

    C<thing>
    C<< thing >>
    C<<           thing     >>
    C<<<   thing >>>
    C<<<<
    thing
               >>>>

    и так далее.

    Наконец, форма с множеством угловых скобок не изменяет интерпретацию вложенных кодов форматирования, что означает, что следующие четыре строчки примеров имеют одинаковый смысл:

    B<example: C<$a E<lt>=E<gt> $b>>
    
    B<example: C<< $a <=> $b >>>
    
    B<example: C<< $a E<lt>=E<gt> $b >>>
    
    B<<< example: C<< $a E<lt>=E<gt> $b >> >>>

При разборе Pod заметной сложной частью является правильный разбор (возможно, вложенных!) кодов форматирования. Реализаторы должны обратиться к коду в процедуре parse_text в Pod::Parser в качестве примера правильной реализации.

I<text> -- курсивный текст

См. краткое обсуждение в "Коды форматирования" в perlpod.

B<text> -- полужирный текст

См. краткое обсуждение в "Коды форматирования" в perlpod.

C<code> -- текст кода

См. краткое обсуждение в "Коды форматирования" в perlpod.

F<filename> -- стиль для имён файлов

См. краткое обсуждение в "Коды форматирования" в perlpod.

X<topic name> -- запись в индекс

См. краткое обсуждение в "Коды форматирования" в perlpod.

Этот код необычен тем, что большинство форматировщиков полностью отбрасывают этот код и его содержимое. Другие форматировщики отобразят его невидимыми кодами, которые могут использоваться при построении индекса текущего документа.

Z<> -- нулевой (без эффекта) код форматирования

Кратко обсуждается в "Коды форматирования" в perlpod.

Этот код необычен тем, что его содержимое не должно быть. То есть, процессор может пожаловаться, если он увидит Z<potatoes>. Независимо от того, жалуется ли он или нет, текст potatoes должен игнорироваться.

L<name> -- гиперссылка

Сложные синтаксисы этого кода подробно обсуждаются в "Коды форматирования" в perlpod, а детали реализации обсуждаются ниже, в "О кодах L<...>". Разбор содержимого L<content> сложен. В частности, содержимое должно быть проверено на то, похоже ли оно на URL, или его нужно разделить по литеральным "|" и/или "/" (в правильном порядке!) и так далее, до разрешения кодов E<...>.

E<escape> -- escape символа

См. "Коды форматирования" в perlpod и несколько пунктов в "Примечания по реализации процессоров Pod".

S<text> -- текст содержит неразрывные пробелы

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

Рассмотрим:

C<$x ? $y    :  $z>

S<C<$x ? $y     :  $z>>

Оба означают текст с фиксированной шириной (стиль c[ode]), состоящий из "$x", одного пробела, "?", одного пробела, ":", одного пробела, "$z". Разница в том, что во втором случае, с кодом S, эти пробелы не являются "обычными" пробелами, а являются неразрывными пробелами.

Если процессор Pod видит любой код форматирования, отличный от перечисленных выше (например, "N<...>", или "Q<...>", и т. д.), этот процессор по умолчанию должен рассматривать это как ошибку. Парсер Pod может позволить определенным приложениям добавить в этот список известных кодов форматирования; парсер Pod может даже позволить указать для каждой дополнительной команды, требует ли она какой-либо специальной обработки, как L<...>.

В будущих версиях этого спецификации могут быть добавлены дополнительные коды форматирования.

Историческая справка: Некоторые старые процессоры Pod не рассматривали ">" как закрытие кода "C<", если ">" непосредственно предшествовал "-". Это было сделано для того, чтобы это:

C<$foo->bar>

было проанализировано как эквивалентное этому:

C<$foo-E<gt>bar>

а не как эквивалентное коду форматирования "C", содержащему только "$foo-", а затем "bar>" вне кода форматирования "C". Эта проблема с тех пор была решена путем добавления синтаксиса, такого как этот:

C<< $foo->bar >>

Соответствующие парсеры не должны рассматривать "->" как специальный символ.

Форматирующие коды категорически не могут охватывать абзацы. Если код открыт в одном абзаце, и закрывающий код не найден к концу этого абзаца, парсер Pod должен закрыть этот форматирующий код и выдать сообщение об ошибке (как в "Незакрытый код I в абзаце, начинающемся на строке 123: 'Time objects are not...'"). Поэтому эти два абзаца:

I<I told you not to do this!

Don't make me say it again!>

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

I<I told you not to do this!>

Don't make me say it again!E<gt>

(В терминологии SGMLish все команды Pod подобны блочным элементам, тогда как все форматирующие коды Pod подобны инлайновым элементам.)

Примечания по реализации обработчиков Pod

Следующее — это длинный раздел об общих требованиях и предложениях, касающихся обработки Pod.

  • Форматировщики Pod должны допускать строки в блоках verbatim любой длины, даже если это означает их разбиение (возможно, несколько раз, для очень длинных строк), чтобы избежать выхода текста за пределы страницы. Форматировщики Pod могут выдавать предупреждения о таком разбиении строк. Такие предупреждения особенно уместны для строк длиннее 100 символов, что обычно не является намеренным.

  • Парсеры Pod должны распознавать все три известных формата новой строки: CR, LF и CRLF. См. perlport.

  • Парсеры Pod должны принимать строки любой длины.

  • Поскольку Perl распознаёт метку порядка байтов Unicode в начале файлов как индикатор кодировки файла как Unicode в UTF-16 (как big-endian, так и little-endian) или UTF-8, парсеры Pod должны делать то же самое. В противном случае кодировка символов должна интерпретироваться как UTF-8, если последовательность байтов с старшим битом в начале файла кажется допустимой как последовательность UTF-8, или же как CP-1252 (предыдущие версии этого спецификации использовали Latin-1 вместо CP-1252).

    Будущие версии этой спецификации могут указать, как Pod может принимать другие кодировки. Предположительно, обработка других кодировок в анализе Pod будет аналогична обработке в XML-парсинге: независимо от кодировки, объявленной конкретным файлом Pod, содержимое будет храниться в памяти в виде символов Unicode.

  • Известные метки порядка байтов Unicode следующие: если файл начинается с двух буквальных значений байтов 0xFE 0xFF, это BOM для big-endian UTF-16. Если файл начинается с двух буквальных значений байтов 0xFF 0xFE, это BOM для little-endian UTF-16. На платформе ASCII, если файл начинается с трёх буквальных значений байтов 0xEF 0xBB 0xBF, это BOM для UTF-8. Механизм, переносимый на платформы EBCDIC, должен:

    my $utf8_bom = "\x{FEFF}";
    utf8::encode($utf8_bom);
  • Примитивный, но часто достаточный эвристический подход на платформах ASCII для проверки первой последовательности байтов с старшим битом в файле без BOM (будь то в коде или в Pod!), чтобы определить, является ли эта последовательность допустимой как UTF-8 (RFC 2279), заключается в проверке того, что первый байт в последовательности находится в диапазоне 0xC2 - 0xFD и что следующий байт находится в диапазоне 0x80 - 0xBF. В таком случае парсер может заключить, что этот файл находится в UTF-8, и все последовательности байтов с старшим битом в файле должны считаться UTF-8. В противном случае парсер должен обрабатывать файл как CP-1252. (Более надёжная проверка, которая работает и на платформах EBCDIC, заключается в передаче копии последовательности в utf8::decode(), которая выполняет полную проверку валидности последовательности и возвращает TRUE, если она является допустимой UTF-8, и FALSE в противном случае. Эта функция всегда предварительно загружена, быстрая, потому что написана на C, и будет вызвана не более одного раза, поэтому вам не нужно избегать её из-за проблем с производительностью.) В маловероятном случае, когда первая последовательность байтов с старшим битом в действительно не-UTF-8 файле случайно оказывается похожей на UTF-8, можно справиться с нашим эвристическим подходом (как и с любым более разумным эвристическим подходом), добавив в начало этой строки комментарий, содержащий последовательность байтов со старшим битом, которая явно не является допустимой как UTF-8. Достаточно строки, состоящей просто из символа "#", острого е и любого байта, не являющегося байтом со старшим битом.

  • Обработчики Pod должны рассматривать абзац "=for [label] [content...]" так же, как абзац "=begin [label]", его содержимое и абзац "=end [label]". (Парсер может объединить эти два конструкта или оставить их отдельными, ожидая, что форматировщик всё равно будет обрабатывать их одинаково.)

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

    %% POD::Pod2PS v3.14159, using POD::Parser v1.92
    
    <!-- Pod::HTML v3.14159, using POD::Parser v1.92 -->
    
    {\doccomm generated by Pod::Tree::RTF 3.14159 using Pod::Tree 1.08}
    
    .\" Pod::Man version 3.14159, using POD::Parser version 1.92

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

    Форматировщики также могут выбрать замечания об ошибках/предупреждениях как комментарии, помимо или вместо вывода их другим способом (например, сообщения в STDERR или dieing).

  • Парсеры Pod могут выводить предупреждения или сообщения об ошибках ("Неизвестный код E E<zslig>!") в STDERR (будь то путём вывода в STDERR, или warning/carping, или dieing/croaking), но должны допускать подавление всего такого вывода STDERR и вместо этого допускать возможность указания ошибок/предупреждений другим способом, будь то вызов обратного вызова, запись ошибок в атрибут объекта документа или аналогичный незаметный механизм – или даже добавление раздела «Ошибки Pod» в конец проанализированной формы документа.

  • В случаях с чрезвычайно аномальными документами парсеры Pod могут прервать разбор. Даже тогда, использование dieing/croaking следует избегать; по возможности, библиотека парсера может просто закрыть входной файл и добавить текст типа «*** Разбор прерван ***» в конец (частичного) документа в памяти.

  • В абзацах, где понимаются коды форматирования (например, E<...>, B<...>) (т.е., не абзацы verbatim, но включая обычные абзацы и абзацы команд, генерирующие отображаемый текст, такие как "=head1"), пробелы в буквальном смысле должны обычно считаться «незначимыми», так что один буквальный пробел имеет то же значение, что и любое (ненулевое) число буквальных пробелов, буквальных новых строк и буквальных табуляций (пока это не создаёт пустых строк, поскольку они завершали бы абзац). Парсеры Pod должны сжимать буквальные пробелы в каждом обработанном абзаце, но могут предоставить возможность отказаться от этого (поскольку некоторые задачи обработки не требуют этого) или могут следовать дополнительным специальным правилам (например, особенно обрабатывать последовательности точка-пробел-пробел или точка-новая строка).

  • Парсеры Pod по умолчанию не должны пытаться преобразовывать апострофы (') и кавычки (") в умные кавычки (маленькие 9', 66', 99' и т.д.), а также не должны пытаться преобразовать обратную апостроф (`) во что-либо, кроме одного символа обратной апострофа (различного от открывающей кавычки!), и не должны преобразовывать "--" во что-либо, кроме двух тире. Они никогда не должны делать ничего из этого для текста в кодах форматирования C<...> и никогда никогда для текста в verbatim-абзацах.

  • При отображении Pod в формате с двумя типами тире (-), одним, который является неразрывным тире, и другим, который является разрывным тире (как в «объектно-ориентированном», которое можно разделить на строки как «объект-», новая строка, «ориентированном»), форматировщикам рекомендуется обычно переводить «-» в неразрывное тире, но они могут применять эвристические правила для преобразования некоторых из них в разрывные тире.

  • Форматировщики Pod должны прилагать разумные усилия, чтобы не разделять слова кода Perl на строки. Например, "Foo::Bar" в некоторых системах форматирования рассматривается как разделимое на строки как "Foo::" новая строка "Bar" или даже "Foo::- новая строка "Bar". Это следует избегать, по возможности, либо отключив все разбиения строк в середине слова, либо заключив определённые слова с внутренней пунктуацией в коды «не разделяйте по строкам» (которые в некоторых форматах могут не быть одним кодом, а могут представлять собой вставку неразрывных нулевых пробелов между каждой парой символов в слове).

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

  • Парсеры Pod по умолчанию должны удалять новые строки из конца обычных и verbatim-абзацев перед передачей их форматировщику. Например, в то время как абзац, который вы сейчас читаете, может рассматриваться в исходном коде Pod как заканчивающийся (и содержащий) новой строкой(ами), которые его заканчивают, он должен обрабатываться как заканчивающийся (и содержащий) знаком точки, которым заканчивается это предложение.

  • Парсеры Pod при сообщении об ошибках должны прилагать усилия для указания приблизительного номера строки («Вложенные E<>'s в абзаце #52, около строки 633 в Thing/Foo.pm!»), вместо того, чтобы просто указывать номер абзаца («Вложенные E<>'s в абзаце #52 в Thing/Foo.pm!»). В проблематичных случаях номер абзаца должен сопровождаться фрагментом из этого абзаца («Вложенные E<>'s в абзаце #52 в Thing/Foo.pm, который начинается с 'Чтение/запись доступа к атрибуту C<ставка>...'»).

  • При обработке последовательности verbatim-абзацев один за другим парсеры Pod должны рассматривать их как один большой verbatim-абзац, который случайно содержит пустые строки. То есть эти две строки, между которыми есть пустая строка:

    use Foo;
    
    print Foo->VERSION

    должны быть объединены в один абзац ("\tuse Foo;\n\n\tprint Foo->VERSION") перед передачей форматировщику или другому процессору. Парсеры также могут предоставить возможность отказаться от этого.

    Хотя это может быть слишком громоздко для реализации в парсерах Pod на основе событий, это просто для парсеров, которые возвращают деревья разбора.

  • Форматировщикам Pod рекомендуется, по возможности, избегать разделения коротких verbatim-абзацев (менее двенадцати строк) на страницы.

  • Парсеры Pod должны обрабатывать строки, содержащие только пробелы и/или табуляции, как «пустые строки», такие как разделяющие абзацы. (Некоторые старые парсеры распознавали только две последовательные новые строки как «пустую строку», но не распознавали новую строку, пробел и новую строку как пустую строку. Это не соответствующее спецификации поведение.)

  • Авторы форматировщиков/обработчиков Pod должны прилагать все усилия, чтобы не писать собственный парсер Pod. Уже существует несколько таких парсеров в CPAN с широким спектром стилей интерфейса, и один из них, Pod::Simple, поставляется с современными версиями Perl.

  • Символы в документах Pod могут передаваться либо как буквальные, либо по номеру в кодах E<n>, или эквивалентным мнемоническим обозначениям, как в E<eacute>, которое точно эквивалентно E<233>. Числа — это значения Latin1/Unicode, даже на платформах EBCDIC.

    При ссылке на символы с использованием числового кода E<n>, числа в диапазоне 32-126 относятся к известным символам US-ASCII (они также определены в Unicode с тем же значением), и все форматировщики Pod должны отображать их верно. Символы, числовые коды E<> которых находятся в диапазонах 0-31 и 127-159, не должны использоваться (ни как буквальные, ни как коды E<число>), за исключением буквальных последовательностей байтов для новой строки (ASCII 13, ASCII 13 10 или ASCII 10) и табуляции (ASCII 9).

    Числа в диапазоне 160-255 относятся к символам Latin-1 (они также определены в Unicode с тем же значением). Числа выше 255 должны интерпретироваться как символы Unicode.

  • Будьте предупреждены, что некоторые форматировщики не могут надёжно отображать символы за пределами 32-126; и многие могут обрабатывать 32-126 и 160-255, но ничего выше 255.

  • Помимо известных кодов "E<lt>" и "E<gt>" для «меньше чем» и «больше чем», парсеры Pod должны понимать "E<sol>" для "/" (слеш), и "E<verbar>" для "|" (вертикальная черта). Парсеры Pod также должны понимать "E<lchevron>" и "E<rchevron>" как устаревшие коды для символов 171 и 187, т.е., «левая двойная угловая кавычка» = «левая направленная стрелка» и «правая двойная угловая кавычка» = «правая направленная стрелка». (Они похожи на маленькие «<<» и «>>», и теперь их предпочтительнее выражать кодами HTML/XHTML "E<laquo>" и "E<raquo>").

  • Парсеры Pod должны понимать все коды "E<html>" как определено в объявлениях сущностей в последнем спецификации XHTML по адресу www.W3.org. Парсеры Pod должны понимать по крайней мере сущности, которые определяют символы в диапазоне 160-255 (Latin-1). Парсеры Pod, столкнувшись с неизвестным кодом "E<идентификатор>", не должны просто заменять его на пустую строку (по умолчанию, по крайней мере), но могут передавать его как строку, состоящую из буквальных символов E, меньше-чем, идентификатор, больше-чем. Или парсеры Pod могут предложить альтернативный вариант обработки таких неизвестных кодов "E<идентификатор>" путём срабатывания события специально для таких кодов или добавлением специального типа узла в дерево памяти документа. Такие "E<идентификатор>" могут иметь специальное значение для некоторых процессоров, или некоторые процессоры могут выбрать их добавление в специальный отчёт об ошибках.

  • Парсеры Pod также должны поддерживать XHTML-коды "E<quot>" для символа 34 (двойная кавычка, "), "E<amp>" для символа 38 (амперсанд, &) и "E<apos>" для символа 39 (апостроф, ').

  • Обратите внимание, что во всех случаях "E<что-то>", что-то (будь то html-имя или число в любой системе счисления) должно состоять только из буквенно-цифровых символов — то есть, что-то должно соответствовать m/\A\w+\z/. Таким образом, "E< 0 1 2 3 >" является недопустимым, поскольку он содержит пробелы, которые не являются буквенно-цифровыми символами. Вероятно, обработчик Pod не нуждается в особом обращении с этим; " 0 1 2 3 " не выглядит как число в любой системе счисления, поэтому, предположительно, он будет просматриваться в таблице HTML-подобных имён. Поскольку нет (и не может быть) HTML-подобной сущности под названием " 0 1 2 3 ", это будет рассматриваться как ошибка. Однако, обработчики Pod могут рассматривать "E< 0 1 2 3 >" или "E<e-acute>" как синтаксически недопустимые, потенциально получая другое сообщение об ошибке, отличное от сообщения об ошибке (или предупреждения, или события), генерируемого просто неизвестным (но теоретически допустимым) html-именем, как в "E<qacute>" [sic]. Однако, парсеры Pod не обязаны делать это различие.

  • Обратите внимание, что E<число> не должен интерпретироваться как просто «кодовая точка число в текущей/родной кодировке». Это всегда означает только «символ, представленный кодовой точкой число в Unicode». (Это идентично семантике &#число; в XML.)

    Это, вероятно, потребует от многих форматировщиков иметь таблицы, сопоставляющие обрабатываемые кодовые точки Unicode (например, «\xE9» для символа e-acute) с последовательностями или кодами, необходимыми для передачи таких последовательностей в целевой формате вывода. Конвертер в *roff, например, будет знать, что «\xE9» (передаётся ли он буквально или через последовательность E<...>) должен быть передан как «e\\*'». Аналогично, программа, отображающая Pod в окне приложения Mac OS, предположительно, должна знать, что «\xE9» соответствует кодовой точке 142 в кодировке MacRoman, которая (на момент написания) является родной для Mac OS. Такие отображения Unicode2whatever, вероятно, уже широко доступны для распространённых форматов вывода. (Такие отображения могут быть неполными! От разработчиков не требуется прилагать чрезмерные усилия для рендеринга чёрокских слогов, этрусских рун, византийских музыкальных символов или любых других странных символов, которые может кодировать Unicode.) И если документ Pod использует символ, отсутствующий в таком отображении, форматировщик должен рассматривать его как неотображаемый символ.

  • Если, к удивлению, разработчик форматировщика Pod не может найти удовлетворительную существующую таблицу сопоставления от символов Unicode до экранированных последовательностей в целевом формате (например, хорошей таблицы символов Unicode к экранированным последовательностям *roff), необходимо будет создать такую таблицу. Если вы столкнулись с такой ситуацией, вы должны начать с символов в диапазоне 0x00A0 - 0x00FF, который в основном состоит из часто используемых символов с диакритическими знаками. Затем продолжайте (по мере того, как позволяет терпение и заставляет прилежность) через символы, которые группы стандартов (X)HTML сочли достаточно важными, чтобы заслужить мнемоники. Они объявлены в спецификациях (X)HTML на сайте www.W3.org. На момент написания (сентябрь 2001 года) самые последние файлы объявлений сущностей:

    http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
    http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent
    http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent

    Затем вы можете перейти к любым оставшимся важным символам Unicode в диапазоне 0x2000-0x204D (обратитесь к таблицам символов на www.unicode.org), и к чему бы ещё ни тянулась ваша фантазия. Например, в файле xhtml-symbol.ent есть запись:

    <!ENTITY infin    "&#8734;"> <!-- infinity, U+221E ISOtech -->

    Хотя отображение «infin» на символ «\x{221E}» (будем надеяться) уже было обработано парсером Pod, присутствие этого символа в этом файле означает, что он достаточно важен, чтобы включить его в таблицу форматировщика, которая сопоставляет заметные символы Unicode с кодами, необходимыми для их отображения. Так, для отображения Unicode в *roff, например, это потребует записи:

    "\x{221E}" => '\(in',

    С нетерпением ожидается, что в будущем всё больше форматов (и форматировщиков) будут поддерживать символы Unicode непосредственно (как (X)HTML поддерживает &infin;, &#8734;, или &#x221E;), что сократит необходимость в нестандартных отображениях Unicode-в-my_escapes.

  • Отдельным форматировщикам Pod предоставляется право использовать здравый смысл при столкновении с неотображаемым символом (что отличается от неизвестной последовательности E<что-то>, которую парсер не смог разрешить ни на что, отображаемое или нет). Хорошей практикой является сопоставление латинских букв с диакритическими знаками (например, «E<eacute>»/«E<233>») с соответствующими латинскими буквами без диакритики US-ASCII (например, простой символ 101, «e»), но, очевидно, это часто нецелесообразно, и неотображаемый символ может быть представлен как «?», или что-то подобное. При попытке разумного возврата (как от E<233> до «e»), форматировщики Pod могут использовать таблицу %Latin1Code_to_fallback в Pod::Escapes или Text::Unidecode, если они доступны.

    Например, этот текст Pod:

    magic is enabled if you set C<$Currency> to 'E<euro>'.

    может быть отображён как: «магия включена, если вы установите $Currency в «?» или как «магия включена, если вы установите $Currency в «[euro]», или как «магия включена, если вы установите $Currency в '[x20AC]', и т. д.

    Форматировщик Pod также может сделать заметку в комментарии или предупреждении со списком встретившихся неотображаемых символов.

  • E<...> может свободно появляться в любом коде форматирования (кроме другого E<...> или в Z<>). То есть, "X<Решение с E<euro>1 000 000>" допустимо, так же как и "L<Решение с E<euro>1 000 000|Million::Euros>".

  • Некоторые форматировщики Pod выводят в форматы, которые реализуют неразрывные пробелы как отдельный символ (который я буду называть «NBSP»), а другие выводят в форматы, которые реализуют неразрывные пробелы как пробелы, заключённые в код «не разрывать по строкам». Обратите внимание, что на уровне Pod могут встречаться оба вида кодов: Pod может содержать символ NBSP (будь то буквальный символ или код «E<160>» или «E<nbsp>»); и Pod может содержать коды «S<foo I<bar> baz>», где «простые пробелы» (символ 32) в таких кодах используются для представления неразрывных пробелов. Парсеры Pod должны рассмотреть возможность поддержки необязательного разбора «S<foo I<bar> baz>», как если бы это было «fooNBSPI<bar>NBSPbaz», и, в обратном направлении, необязательный разбор групп слов, соединённых с NBSP, как если бы каждая группа находилась в коде S<...>, так что форматировщики могут использовать представление, которое наилучшим образом соответствует требованиям формата вывода.

  • Некоторые процессоры могут обнаружить, что код S<...> проще всего реализовать, заменив каждый пробел в дереве разбора под содержимым S на NBSP. Но обратите внимание: замена должна применяться не к пробелам во всем тексте, а только к пробелам в отображаемом тексте. (Это различие может быть или не быть очевидным в конкретной модели дерева/события, реализованной парсером Pod.) Например, рассмотрим этот необычный случай:

    S<L</Autoloaded Functions>>

    Это означает, что пробел посередине текста видимой ссылки не должен разделяться по строкам. Другими словами, это то же самое, что и это:

    L<"AutoloadedE<160>Functions"/Autoloaded Functions>

    Однако, неправильно применённая замена пробелов на NBSP может (неверно) привести к чему-то эквивалентному этому:

    L<"AutoloadedE<160>Functions"/AutoloadedE<160>Functions>

    …что, почти наверняка, не будет работать как гиперссылка (предполагая, что этот форматировщик выводит формат, поддерживающий гипертекст).

    Форматировщики могут выбрать просто не поддерживать код формата S, особенно в тех случаях, когда в формате вывода просто нет символа/кода NBSP и нет кода «не разрывать это по строкам».

  • Помимо символа NBSP, обсуждаемого выше, разработчикам напоминают о существовании другого «специального» символа в Latin-1, символа «мягкого дефиса», также известного как «необязательный дефис», то есть E<173> = E<0xAD> = E<shy>). Этот символ выражает необязательную точку деления. То есть, он обычно отображается как пустой символ, но может отображаться как «-», если форматировщик разделяет слово в этом месте. Форматировщики Pod должны, в зависимости от ситуации, выполнить одно из следующих действий: 1) отобразить его с помощью кода с тем же значением (например, «\-» в RTF), 2) передать его в надежде, что форматировщик понимает этот символ как таковой, или 3) удалить его.

    Например:

    sigE<shy>action
    manuE<shy>script
    JarkE<shy>ko HieE<shy>taE<shy>nieE<shy>mi

    Это указывает форматировщику, что если ему нужно разделить «sigaction» или «manuscript», то это должно быть сделано как «sig-[перенос строки]action» или «manu-[перенос строки]script» (и если он не разбивает его, то E<shy> вообще не отображается). И если ему нужно разделить «Jarkko» и/или «Hietaniemi», он может сделать это только в местах, где есть код E<shy>.

    На практике ожидается, что этот символ не будет использоваться часто, но форматировщики должны либо поддерживать его, либо удалять.

  • Если вы думаете, что хотите добавить новую команду в Pod (например, команду "=biblio"), подумайте, можно ли получить тот же эффект с помощью последовательности for или begin/end: "=for biblio ..." или "=begin biblio" ... "=end biblio". Процессоры Pod, которые не понимают "=for biblio" и т.д., просто проигнорируют это, в то время как они могут громко пожаловаться, если увидят "=biblio".

  • В этом документе «Pod» используется как предпочтительное написание названия формата документации. Можно также использовать «POD» или «pod». Для документации, которая (как правило) в формате Pod, можно использовать «pod», «Pod» или «POD». Понимание этих различий полезно; но излишнее внимание к тому, как их писать, обычно не требуется.

О кодах L<...>

Как можно судить по быстрому взгляду на perlpod, код L<...> является наиболее сложным из кодов форматирования Pod. Следующие пункты, надеемся, прояснят его значение и то, как процессоры должны с ним работать.

  • При разборе кода L<...>, парсеры Pod должны различать как минимум четыре атрибута:

    Первый:

    Текст ссылки. Если его нет, то это должно быть undef. (Например, в «L<Perl Functions|perlfunc>» текстом ссылки является «Perl Functions». В «L<Time::HiRes>» и даже «L<|Time::HiRes>» текста ссылки нет. Обратите внимание, что текст ссылки может содержать форматирование.)

    Второй:

    Возможный вывод текста ссылки; то есть, если реального текста ссылки не было, то это текст, который мы выведем вместо него. (Например, для «L<Getopt::Std>» выведенным текстом ссылки является «Getopt::Std».)

    Третий:

    Имя или URL, или undef, если нет. (Например, в «L<Perl Functions|perlfunc>» имя (иногда его также называют страницей) равно «perlfunc». В «L</CAVEATS>» имя равно undef. )

    Четвёртый:

    Раздел (также известный как «элемент» в старых perlpod), или undef, если его нет. Например, в «L<Getopt::Std/DESCRIPTION>» «DESCRIPTION» является разделом. (Обратите внимание, что это не то же самое, что раздел справочной страницы, как «5» в «man 5 crontab». Раздел в смысле Pod означает часть текста, которая вводится заголовком или элементом, текст которого «Foo».)

    Парсеры Pod также могут отмечать дополнительные атрибуты, включая:

    Пятый:

    Флаг, указывающий, является ли элемент 3 (если он присутствует) URL (например, «http://lists.perl.org»), в этом случае атрибута раздела быть не должно; имя Pod (например, «perldoc» и «Getopt::Std»); или, возможно, имя страницы руководства (например, «crontab(5)»).

    Шестой:

    Исходное содержимое L<...>, до разделения текста по «|», «/» и т. д., и до расширения кодов E<...>.

    (Вышеперечисленные пункты были пронумерованы только для краткой ссылки ниже. Не требуется, чтобы эти данные передавались в виде фактического списка или массива.)

    Например:

    L<Foo::Bar>
      =>  undef,                         # link text
          "Foo::Bar",                    # possibly inferred link text
          "Foo::Bar",                    # name
          undef,                         # section
          'pod',                         # what sort of link
          "Foo::Bar"                     # original content
    
    L<Perlport's section on NL's|perlport/Newlines>
      =>  "Perlport's section on NL's",  # link text
          "Perlport's section on NL's",  # possibly inferred link text
          "perlport",                    # name
          "Newlines",                    # section
          'pod',                         # what sort of link
          "Perlport's section on NL's|perlport/Newlines"
                                         # original content
    
    L<perlport/Newlines>
      =>  undef,                         # link text
          '"Newlines" in perlport',      # possibly inferred link text
          "perlport",                    # name
          "Newlines",                    # section
          'pod',                         # what sort of link
          "perlport/Newlines"            # original content
    
    L<crontab(5)/"DESCRIPTION">
      =>  undef,                         # link text
          '"DESCRIPTION" in crontab(5)', # possibly inferred link text
          "crontab(5)",                  # name
          "DESCRIPTION",                 # section
          'man',                         # what sort of link
          'crontab(5)/"DESCRIPTION"'     # original content
    
    L</Object Attributes>
      =>  undef,                         # link text
          '"Object Attributes"',         # possibly inferred link text
          undef,                         # name
          "Object Attributes",           # section
          'pod',                         # what sort of link
          "/Object Attributes"           # original content
    
    L<https://www.perl.org/>
      =>  undef,                         # link text
          "https://www.perl.org/",       # possibly inferred link text
          "https://www.perl.org/",       # name
          undef,                         # section
          'url',                         # what sort of link
          "https://www.perl.org/"         # original content
    
    L<Perl.org|https://www.perl.org/>
      =>  "Perl.org",                    # link text
          "https://www.perl.org/",       # possibly inferred link text
          "https://www.perl.org/",       # name
          undef,                         # section
          'url',                         # what sort of link
          "Perl.org|https://www.perl.org/" # original content

    Обратите внимание, что вы можете отличить ссылки на URL от всего остального по тому, что они соответствуют m/\A\w+:[^:\s]\S*\z/. Таким образом, L<http://www.perl.com> является URL, но L<HTTP::Response> нет.

  • В случае кодов L<...> без части «текст|» в них старые форматировщики демонстрировали большие различия в фактическом отображении ссылки или перекрестной ссылки. Например, L<crontab(5)> отображался как «справочная страница crontab(5), или «на странице crontab(5) справочной страницы» или просто «crontab(5)».

    Обработчики Pod должны теперь рассматривать ссылки без «текст|» следующим образом:

    L<name>         =>  L<name|name>
    L</section>     =>  L<"section"|/section>
    L<name/section> =>  L<"section" in name|name/section>
  • Обратите внимание, что имена разделов могут содержать разметку. Например, если раздел начинается с:

    =head2 About the C<-M> Operator

    или с:

    =item About the C<-M> Operator

    то ссылка на него будет выглядеть так:

    L<somedoc/About the C<-M> Operator>

    Форматировщики могут выбрать игнорировать разметку для целей разрешения ссылки и использовать только рендерные символы в имени раздела, как в:

    <h1><a name="About_the_-M_Operator">About the <code>-M</code>
    Operator</h1>
    
    ...
    
    <a href="somedoc#About_the_-M_Operator">About the <code>-M</code>
    Operator" in somedoc</a>
  • Предыдущие версии perlpod различали L<name/"section"> ссылки от L<name/item> ссылок (и их целей). Эти ссылки были объединены синтаксически и семантически в текущем спецификации, и раздел может относиться как к команде "=headn Заголовок Содержимое", так и к команде "=item Элемент Содержимое". Эта спецификация не определяет, какое поведение должно быть в случае документа, содержащего несколько элементов, которые кажутся генерирующими один и тот же идентификатор раздела (например, в HTML, несколько элементов, генерирующие один и тот же имя_якоря в элементах <a name="имя_якоря">...</a>). Там, где обработчики Pod могут управлять этим поведением, они должны использовать первый такой якорь. То есть, L<Foo/Bar> относится к первому разделу «Bar» в «Foo».

    Однако для некоторых процессоров/форматов это нельзя легко контролировать; как и в случае с примером HTML, поведение нескольких неоднозначных <a name="имя_якоря">...</a> лучше всего оставить на усмотрение браузеров.

  • В коде L<text|...>, текст может содержать коды форматирования для форматирования или для экранирования E<...>, как в:

    L<B<ummE<234>stuff>|...>

    Для кодов L<...> без части «имя|», могут встречаться только коды E<...> и Z<>. То есть авторы не должны использовать «L<B<Foo::Bar>>».

    Однако коды форматирования и Z<> могут встречаться в любой части L<...> (т. е. в имени, разделе, тексте и url).

    Авторы не должны вкладывать коды L<...>. Например, «L<Страница справки L<Foo::Bar>>» должно обрабатываться как ошибка.

  • Обратите внимание, что авторы Pod могут использовать коды форматирования внутри части «текст» в «L<текст|имя>» (и так далее для L<текст|/"сек">).

    Другими словами, это допустимо:

    Go read L<the docs on C<$.>|perlvar/"$.">

    Некоторые форматы вывода, которые допускают отображение кодов «L<...>» в виде гипертекста, могут не позволять форматировать текст ссылки; в этом случае форматировщики должны просто игнорировать это форматирование.

  • На момент написания значения L<name> имеют два типа: либо имя страницы Pod, например, L<Foo::Bar> (что может быть реальным модулем или программой Perl в каталоге @INC/PATH или файлом .pod в этих местах); либо имя страницы руководства Unix, например, L<crontab(5)>. Теоретически, L<chmod> является неоднозначным между страницей Pod под названием «chmod» или справочной страницей Unix «chmod» (в любом разделе справочной страницы). Однако наличие строки в скобках, как в «crontab(5)», достаточно для того, чтобы указать, что обсуждается не страница Pod, а, предположительно, страница справки Unix. Это различие не важно для многих процессоров Pod, но некоторые процессоры, которые отображают гипертекстовые форматы, могут нуждаться в различении для того, чтобы знать, как отобразить данный L<foo> код.

  • Предыдущие версии perlpod допускали синтаксис L<section> (как в L<Object Attributes>), который сложно было отличить от синтаксиса L<name> и от синтаксиса L<"section">, который был немного менее неоднозначным. Этот синтаксис больше не поддерживается в спецификации и заменён на синтаксис L</section> (где слеш ранее был необязателен). Парсеры Pod должны допускать синтаксис L<"section"> по крайней мере какое-то время. Предлагаемая эвристика для различения L<section> от L<name> заключается в том, что если он содержит пробелы, то это раздел. Процессоры Pod должны предупреждать о том, что этот устаревший синтаксис.

О регионах =over...=back

"=over"..."=back" регионы используются для различных видов списков. (Я использую здесь термин «регион» просто как собирательный термин для всего, от «=over» до соответствующего «=back».)

  • Неравное нулю числовое значение indentlevel в "=over indentlevel" ... "=back" используется для указания форматировщику, на сколько «пробелов» (единиц em или примерно эквивалентных единиц) нужно сделать отступ, хотя многим форматировщикам придется преобразовать это в абсолютную меру, которая может не точно соответствовать размеру пробелов (или букв М) в базовом шрифте документа. Другие форматировщики могут вообще проигнорировать это число. Отсутствие явного параметра indentlevel эквивалентно значению indentlevel, равному 4. Обработчики Pod могут пожаловаться, если indentlevel присутствует, но не является положительным числом, соответствующим m/\A(\d*\.)?\d+\z/.

  • Авторам форматировщиков Pod напоминается, что "=over" ... "=back" может соответствовать нескольким различным конструкциям в выходном формате. Например, при преобразовании Pod в (X)HTML, это может соответствовать любому из <ul>...</ul>, <ol>...</ol>, <dl>...</dl> или <blockquote>...</blockquote>. Аналогично, "=item" может соответствовать <li> или <dt>.

  • Каждая область "=over" ... "=back" должна быть одной из следующих:

    • Область "=over" ... "=back", содержащая только команды "=item *", каждая из которых следует за некоторым количеством обычных/verbatim абзацев, другими вложенными областями "=over" ... "=back", абзацами "=for...", и областями "=begin"..."=end".

      (Обработчики Pod должны воспринимать просто "=item" как если бы это было "=item *".). Способ отображения "*" как литеральной звёздочки, "о", или какого-либо реального символа списка, зависит от форматировщика Pod и может зависеть от уровня вложенности.

    • Область "=over" ... "=back", содержащая только m/\A=item\s+\d+\.?\s*\z/ абзацев, каждый из которых (или каждая группа которых) следует за некоторым количеством обычных/verbatim абзацев, другими вложенными областями "=over" ... "=back", абзацами "=for...", и/или кодами "=begin"..."=end". Обратите внимание, что номера должны начинаться с 1 в каждом разделе и должны следовать в порядке, без пропуска чисел.

      (Обработчики Pod должны воспринимать строки вроде "=item 1" как "=item 1.", с точкой.)

    • Область "=over" ... "=back", содержащая только команды "=item [текст]", каждая из которых (или каждая группа которых) следует за некоторым количеством обычных/verbatim абзацев, другими вложенными областями "=over" ... "=back" или абзацами "=for...", и областями "=begin"..."=end".

      Абзац "=item [текст]" не должен соответствовать m/\A=item\s+\d+\.?\s*\z/ или m/\A=item\s+\*\s*\z/, а также не должен соответствовать только m/\A=item\s*\z/.

    • Область "=over" ... "=back", не содержащая вообще никаких команд "=item", и содержащая только некоторое количество обычных/verbatim абзацев, а также, возможно, некоторые вложенные области "=over" ... "=back", абзацы "=for..." и области "=begin"..."=end". Такая область "=over" ... "=back" без элементов "=item" в Pod эквивалентна элементу "<blockquote>...</blockquote>" в HTML.

    Обратите внимание, что во всех вышеперечисленных случаях вы можете определить, какой тип "=over" ... "=back" у вас есть, проверив первый (не "=cut", не "=pod") абзац Pod после команды "=over".

  • Форматировщики Pod обязаны обрабатывать произвольно большие объёмы текста в абзаце "=item текст...". На практике большинство таких абзацев короткие, как, например:

    =item For cutting off our trade with all parts of the world

    Но они могут быть произвольно длинными:

    =item For transporting us beyond seas to be tried for pretended
    offenses
    
    =item He is at this time transporting large armies of foreign
    mercenaries to complete the works of death, desolation and
    tyranny, already begun with circumstances of cruelty and perfidy
    scarcely paralleled in the most barbarous ages, and totally
    unworthy the head of a civilized nation.
  • Обработчики Pod должны обрабатывать команды "=item *" / "=item число" без сопровождающего абзаца. Средний элемент — пример:

    =over
    
    =item 1
    
    Pick up dry cleaning.
    
    =item 2
    
    =item 3
    
    Stop by the store.  Get Abba Zabas, Stoli, and cheap lawn chairs.
    
    =back
  • Ни одна область "=over" ... "=back" не может содержать заголовки. Обработчики могут рассматривать такой заголовок как ошибку.

  • Обратите внимание, что область "=over" ... "=back" должна иметь некоторое содержимое. То есть авторы не должны иметь пустую область, подобную этой:

    =over
    
    =back

    Обработчики Pod, обнаружившие такую пустую область "=over" ... "=back", могут проигнорировать её или могут сообщить об ошибке.

  • Обработчики должны обрабатывать список "=over", который выходит за пределы документа (т. е. у которого нет соответствующего "=back"), но они могут выдать предупреждение об таком списке.

  • Авторы форматировщиков Pod должны отметить, что эта конструкция:

    =item Neque
    
    =item Porro
    
    =item Quisquam Est
    
    Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci 
    velit, sed quia non numquam eius modi tempora incidunt ut
    labore et dolore magnam aliquam quaerat voluptatem.
    
    =item Ut Enim

    является семантически неоднозначной, что затрудняет принятие решений о форматировании. С одной стороны, это может быть упоминание элемента «Neque», упоминание другого элемента «Porro» и упоминание другого элемента «Quisquam Est», причём только для последнего требуется поясняющий абзац «Qui dolorem ipsum quia dolor...»; и затем элемент «Ut Enim». В этом случае вы захотите отформатировать это так:

    Neque
    
    Porro
    
    Quisquam Est
      Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci
      velit, sed quia non numquam eius modi tempora incidunt ut
      labore et dolore magnam aliquam quaerat voluptatem.
    
    Ut Enim

    Но это в равной мере может быть обсуждение трёх (связанных или эквивалентных) элементов «Neque», «Porro» и «Quisquam Est», за которым следует абзац, объясняющий их все, а затем новый элемент «Ut Enim». В этом случае вы, вероятно, захотите отформатировать это так:

    Neque
    Porro
    Quisquam Est
      Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci
      velit, sed quia non numquam eius modi tempora incidunt ut
      labore et dolore magnam aliquam quaerat voluptatem.
    
    Ut Enim

    Но (в обозримом будущем) Pod не предоставляет авторам Pod способ различать, какая группировка подразумевается в приведенной выше структуре "=item"-кластера. Поэтому форматировщики должны отформатировать это так:

    Neque
    
    Porro
    
    Quisquam Est
    
      Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci
      velit, sed quia non numquam eius modi tempora incidunt ut
      labore et dolore magnam aliquam quaerat voluptatem.
    
    Ut Enim

    То есть должно быть (по крайней мере приблизительно) одинаковое расстояние между элементами, как и между абзацами (хотя это расстояние может быть меньше полной высоты строки текста). Это оставляет за читателем использование (кон)текстуальных подсказок для определения того, относится ли абзац «Qui dolorem ipsum...» к элементу «Quisquam Est» или ко всем трём элементам «Neque», «Porro» и «Quisquam Est». Хотя это не идеальная ситуация, это предпочтительнее, чем предоставление подсказок форматирования, которые могут фактически противоречить намерениям автора.

О данных абзацах и областях "=begin/=end"

Данные абзацы обычно используются для вставки не-Pod данных, которые будут использоваться (обычно передаваться) при рендеринге документа в определённый формат:

=begin rtf

\par{\pard\qr\sa4500{\i Printed\~\chdate\~\chtime}\par}

=end rtf

В точности тот же эффект, между прочим, можно было бы достичь с помощью одного абзаца "=for":

=for rtf \par{\pard\qr\sa4500{\i Printed\~\chdate\~\chtime}\par}

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

Ещё один пример абзаца данных:

=begin html

I like <em>PIE</em>!

<hr>Especially pecan pie!

=end html

Если бы это были обычные абзацы, парсер Pod попытался бы расширить «E</em>» (в первом абзаце) как код форматирования, точно так же, как «E<lt>» или «E<eacute>». Но поскольку это находится в области "=begin идентификатор"..."=end идентификатор" и идентификатор "html" не начинается с префикса ":", содержимое этой области сохраняется как абзацы данных, а не обрабатывается как обычные абзацы (или, если они начинаются со пробелов и/или табуляций, как verbatim абзацы).

В качестве дополнительного примера: На момент написания не поддерживается идентификатор "biblio", но предположим, что какой-то процессор был написан для распознавания его как способа (скажем) обозначения библиографической ссылки (необязательно содержащей коды форматирования в обычных абзацах). Тот факт, что абзацы "biblio" предназначались для обычной обработки, обозначался бы префиксом каждого идентификатора "biblio" двоеточием:

=begin :biblio

Wirth, Niklaus.  1976.  I<Algorithms + Data Structures =
Programs.>  Prentice-Hall, Englewood Cliffs, NJ.

=end :biblio

Это означало бы парсеру, что абзацы в этой области begin...end подлежат нормальной обработке как обычные/verbatim абзацы (при этом по-прежнему помеченные как предназначенные только для процессоров, понимающих идентификатор "biblio"). То же самое можно было бы сделать с:

=for :biblio
Wirth, Niklaus.  1976.  I<Algorithms + Data Structures =
Programs.>  Prentice-Hall, Englewood Cliffs, NJ.

Двоеточие в этих идентификаторах означает просто «обработать это нормально, даже если результат будет для какой-то специальной цели». Я предлагаю, чтобы API парсера сообщали "biblio" как идентификатор цели, но также сообщают, что у него был префикс ":". (И аналогично, с вышеупомянутым "html", сообщать "html" как идентификатор цели и отмечать отсутствие префикса ":". )

Обратите внимание, что область "=begin идентификатор"..."=end идентификатор", где идентификатор начинается с двоеточия, может содержать команды. Например:

=begin :biblio

Wirth's classic is available in several editions, including:

=for comment
 hm, check abebooks.com for how much used copies cost.

=over

=item

Wirth, Niklaus.  1975.  I<Algorithmen und Datenstrukturen.>
Teubner, Stuttgart.  [Yes, it's in German.]

=item

Wirth, Niklaus.  1976.  I<Algorithms + Data Structures =
Programs.>  Prentice-Hall, Englewood Cliffs, NJ.

=back

=end :biblio

Однако обратите внимание, что область "=begin идентификатор"..."=end идентификатор", где идентификатор не начинается с двоеточия, не должна напрямую содержать команды "=head1" ... "=head4", "=over", "=back", "=item". Например, это может считаться недопустимым:

=begin somedata

This is a data paragraph.

=head1 Don't do this!

This is a data paragraph too.

=end somedata

Обработчик Pod может сообщить, что приведенный выше абзац (конкретно абзац "=head1") является ошибкой. Обратите внимание, однако, что следующее не должно рассматриваться как ошибка:

=begin somedata

This is a data paragraph.

=cut

# Yup, this isn't Pod anymore.
sub excl { (rand() > .5) ? "hoo!" : "hah!" }

=pod

This is a data paragraph too.

=end somedata

И это тоже допустимо:

=begin someformat

This is a data paragraph.

  And this is a data paragraph.

=begin someotherformat

This is a data paragraph too.

  And this is a data paragraph too.

=begin :yetanotherformat

=head2 This is a command paragraph!

This is an ordinary paragraph!

  And this is a verbatim paragraph!

=end :yetanotherformat

=end someotherformat

Another data paragraph!

=end someformat

Содержимое области "=begin :yetanotherformat" ... "=end :yetanotherformat" не является абзацами данных, потому что идентификатор непосредственно содержащей области (":yetanotherformat") начинается с двоеточия. На практике большинство областей, содержащих абзацы данных, будут содержать только абзацы данных; однако, приведенное выше вложение синтаксически допустимо как Pod, даже если это редко. Однако обработчики некоторых форматов, таких как "html", будут принимать только абзацы данных, а не вложенные области; и они могут пожаловаться, если увидят (направленные на них) вложенные области или команды, кроме "=end", "=pod" и "=cut".

Также обратите внимание на эту допустимую структуру:

=begin :biblio

Wirth's classic is available in several editions, including:

=over

=item

Wirth, Niklaus.  1975.  I<Algorithmen und Datenstrukturen.>
Teubner, Stuttgart.  [Yes, it's in German.]

=item

Wirth, Niklaus.  1976.  I<Algorithms + Data Structures =
Programs.>  Prentice-Hall, Englewood Cliffs, NJ.

=back

Buy buy buy!

=begin html

<img src='wirth_spokesmodeling_book.png'>

<hr>

=end html

Now now now!

=end :biblio

Там область "=begin html"..."=end html" вложена в более крупную область "=begin :biblio"..."=end :biblio". Обратите внимание, что содержимое области "=begin html"..."=end html" является абзацем(ами) данных, потому что идентификатор непосредственно содержащей области ("html") не начинается с двоеточия.

Парсеры Pod, обрабатывая ряд абзацев данных один за другим (в пределах одной области), должны рассматривать их как один большой абзац данных, который содержит пустые строки. Итак, содержимое вышеприведённой области "=begin html"..."=end html" может храниться как два абзаца данных (один, состоящий из "<img src='wirth_spokesmodeling_book.png'>\n", и другой — из "<hr>\n"), но должен храниться как один абзац данных (состоящий из "<img src='wirth_spokesmodeling_book.png'>\n\n<hr>\n").

Обработчики Pod должны обрабатывать пустые области "=begin что-то"..."=end что-то", пустые области "=begin :что-то"..."=end :что-то" и пустые абзацы "=for что-то" и "=for :что-то". То есть это должно поддерживаться:

=for html

=begin html

=end html

=begin :biblio

=end :biblio

Кстати, нет простого способа выразить абзац данных, начинающийся с чего-то, что выглядит как команда. Рассмотрим:

=begin stuff

=shazbot

=end stuff

Там "=shazbot" будет обработано как команда Pod "shazbot", а не как абзац данных "=shazbot\n". Однако вы можете выразить абзац данных, состоящий из "=shazbot\n", используя этот код:

=for stuff =shazbot

Ситуация, когда это необходимо, по-видимому, довольно редкая.

Обратите внимание, что команды =end должны соответствовать текущей открытой команде =begin. То есть они должны правильно вкладываться. Например, это допустимо:

=begin outer

X

=begin inner

Y

=end inner

Z

=end outer

в то время как это недопустимо:

=begin outer

X

=begin inner

Y

=end outer

Z

=end inner

Это последнее неверно, потому что, когда видна команда "=end outer", текущая открытая область имеет имя формата "inner", а не "outer". (Просто так получается, что "outer" — имя формата области выше.) Это ошибка. Обработчики по умолчанию должны сообщать об этом как об ошибке и могут остановить обработку документа, содержащего эту ошибку. Следствием этого является то, что области не могут «перекрываться». То есть последний блок выше не представляет область, называемую «outer», которая содержит X и Y, перекрывающую область, называемую «inner», которая содержит Y и Z. Но поскольку это недействительно (как и все, по-видимому, перекрывающиеся области), это не представляет ни этого, ни чего-либо.

Аналогично, это недействительно:

=begin thing

=end hting

Это ошибка, потому что область открыта "thing", а "=end" пытается закрыть "hting" [sic].

Это также неверно:

=begin thing

=end

Это неверно, потому что каждая команда "=end" должна иметь параметр formatname.

ДРУГОЕ

perlpod, "PODs: Встроенная документация" в perlsyn, podchecker

АВТОР

Sean M. Burke

© 1993–2023 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.38.0/perlpodspec

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API