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" будет применять ту же обработку к "Вы вспомнили 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]/. "[space][space]$foo->bar" является абзацем verbatim, потому что его первая строка начинается с буквального пробельного символа (и нет области "=begin"..."=end").
Команды "=begin идентификатор" ... "=end идентификатор" предотвращают обработку окружающих абзацев как обычных или verbatim абзацев, если идентификатор не начинается с двоеточия. Это подробно описано в разделе "О абзацах данных и разделах "=begin/=end".
Команды Pod
Этот раздел предназначен для дополнения и уточнения обсуждения в "Абзац команды" в perlpod. Это текущие распознаваемые команды Pod:
- "=head1", "=head2", "=head3", "=head4"
-
Эта команда указывает, что текст в оставшейся части абзаца является заголовком. Этот текст может содержать коды форматирования. Примеры:
=head1 Object Attributes =head3 What B<Not> to Do! - "=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"
-
Эта команда, которая должна встречаться в начале документа (по крайней мере, перед любыми данными, отличными от US-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.)
Существуют два синтаксиса для кодов форматирования:
-
Код форматирования начинается с заглавной буквы (только US-ASCII [A-Z]), за которой следует "<", любое количество символов и заканчивается первой соответствующей ">". Примеры:
That's what I<you> think! What's C<dump()> for? X<C<chmod> and C<unlink()> Under Different Operating Systems> -
Код форматирования начинается с заглавной буквы (только US-ASCII [A-Z]), за которой следуют две или более "<"'s, один или более пробелов, любое количество символов, один или более пробелов и заканчивается первой соответствующей последовательностью двух или более ">"'s, где количество ">"'s равно количеству "<"'s в открытии этого кода форматирования. Примеры:
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>. В любом случае текст картофель должен быть проигнорирован. -
L<name>-- гиперссылка -
Сложные синтаксисы этого кода подробно обсуждаются в "Коды форматирования" в perlpod, а детали реализации обсуждаются ниже в "Об L<...> кодах". Парсинг содержимого L<content> сложен. В частности, содержимое нужно проверить на соответствие виду URL или на разделение по буквам "|" и/или "/" (в правильном порядке!) и так далее, до разрешения кодов E<...>.
-
E<escape>-- escape-код символа -
См. "Коды форматирования" в perlpod и несколько пунктов в "Примечания по реализации процессоров Pod".
-
S<text>-- текст содержит неразрывные пробелы -
Этот код форматирования имеет простой синтаксис, но сложную семантику. Это означает, что каждый пробел в печатном содержимом этого кода обозначает неразрывный пробел.
Рассмотрим:
C<$x ? $y : $z> S<C<$x ? $y : $z>>Оба означают текст с одинаковым шириной ($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: 'Объекты времени не...'"). Так что эти два абзаца:
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> (В терминологии SGML все команды 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. Достаточно строки, состоящей только из "#", острого e, и любого байта без высокого бита, чтобы установить кодировку этого файла.
-
Обработчики Pod должны рассматривать абзац "=for [метка] [содержимое...]" так же, как абзац "=begin [метка]", содержимое и абзац "=end [метка]". (Парсер может объединить эти два конструкта или оставить их отдельными, с тем чтобы форматировщик все равно обрабатывал их одинаково.)
-
При рендеринге 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 или
die). -
Парсеры Pod могут выводить предупреждения или сообщения об ошибках ("Неизвестный код E E<zslig>!") в STDERR (будь то вывод в STDERR или
warn/carpилиdie/croak), но должны позволять подавление всего такого вывода STDERR и вместо этого позволять параметр для отчётности об ошибках/предупреждениях другим способом, будь то путем запуска обратного вызова, или отметок об ошибках в каком-либо атрибуте объекта документа, или подобным незаметным механизмом – или даже путем добавления раздела «Ошибки Pod» в конец разобранной формы документа. -
В случаях с чрезвычайно нестандартными документами парсеры Pod могут прервать разбор. Даже в этом случае использование
die/croakследует избегать; где это возможно, библиотека парсера может просто закрыть входной файл и добавить текст, такой как «*** Разбор прерван ***», в конец (частичного) документа в памяти. -
В абзацах, где понимаются коды форматирования (например, 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<interest rate>...'").
-
При обработке последовательности 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<number>), за исключением буквенных последовательностей байтов для новой строки (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» для символа «е с острою») и последовательностями или кодами, необходимыми для передачи таких последовательностей в целевой формате вывода. Конвертер в *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 "∞"> <!-- infinity, U+221E ISOtech -->Хотя отображение «infin» на символ «\x{221E}» (надеюсь) уже обработано парсером Pod, наличие этого символа в этом файле означает, что он достаточно важен, чтобы включить его в таблицу форматировщика, отображающую соответствие между важными символами Unicode и кодами, необходимыми для их отображения. Таким образом, для отображения Unicode в *roff, например, это будет соответствовать записи:
"\x{221E}" => '\(in',Искренне надеемся, что в будущем всё большее количество форматов (и форматировщиков) будут напрямую поддерживать символы Unicode (как это делает (X)HTML с
∞,∞, или∞), уменьшая необходимость в специфичных отображениях 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» — раздел. (Обратите внимание, что это не то же самое, что раздел справки man, например, «5» в «man 5 crontab». Раздел в смысле Pod означает часть текста, которая вводится заголовком или элементом, текст которого «Foo».)
Парсеры Pod также могут отметить дополнительные атрибуты, включая:
- Пятый:
-
Флаг, указывающий, является ли элемент 3 (если он есть) URL (например, «http://lists.perl.org»), в этом случае атрибута раздела быть не должно; имя Pod (например, «perldoc» и «Getopt::Std»); или, возможно, имя страницы man (например, «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<http://www.perl.org/> => undef, # link text "http://www.perl.org/", # possibly inferred link text "http://www.perl.org/", # name undef, # section 'url', # what sort of link "http://www.perl.org/" # original content L<Perl.org|http://www.perl.org/> => "Perl.org", # link text "http://www.perl.org/", # possibly inferred link text "http://www.perl.org/", # name undef, # section 'url', # what sort of link "Perl.org|http://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)> отобразился бы как «страница man
crontab(5)», или «на странице mancrontab(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, несколько вещей, все производящих один и тот же anchorname в элементах <a name="anchorname">...</a>). Там, где процессоры Pod могут контролировать это поведение, они должны использовать первый такой якорь. То есть,L<Foo/Bar>относится к первому разделу «Bar» в Foo.Но для некоторых процессоров/форматов это нельзя легко контролировать; как и в случае с примером HTML, поведение нескольких неоднозначных <a name="anchorname">...</a> проще всего оставить на усмотрение браузеров.
-
В коде
L<text|...>, текст может содержать коды форматирования для форматирования или для экранирования E<...>, как в:L<B<ummE<234>stuff>|...>Для кодов
L<...>без части «имя|» могут встречаться только кодыE<...>иZ<>. То есть, авторы не должны использовать «L<B<Foo::Bar>>».Однако, коды форматирования и Z<> могут встречаться во всех частях L<...> (т.е., в имени, разделе, тексте и url).
Авторы не должны вкладывать коды L<...>. Например, «L<Страница справки man 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» (в любом разделе справки man). Однако наличие строки в скобках, например «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" без элементов в 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" [опечатка].
Это также недействительно:
=begin thing
=end Это недействительно, потому что каждая команда "=end" должна иметь параметр formatname.
СМОТРИТЕ ТАКЖЕ
perlpod, "PODs: Embedded Documentation" в perlsyn, podchecker
АВТОР
Шон М. Берк
© 1993–2020 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.28.3/perlpodspec