Глава 19 Генератор документации (ocamldoc)
В этой главе описывается OCamldoc — инструмент, который создает документацию на основе специальных комментариев, встроенных в исходные файлы. Комментарии, используемые OCamldoc, имеют вид (**…*) и соответствуют формату, описанному в разделе 19.2.
OCamldoc может создавать документацию в различных форматах: HTML, LATEX, TeXinfo, справочные страницы Unix и графы зависимостей dot. Кроме того, пользователи могут добавлять собственные генераторы, как описано в разделе 19.3.
В этой главе слово элемент обозначает любую из следующих частей исходного файла OCaml: объявление типа, значение, модуль, исключение, тип модуля, конструктор типа, поле записи, класс, тип класса, метод класса, значение класса или предложение наследования класса.
1 Использование
1.1 Вызов
OCamldoc запускается командой ocamldoc следующим образом:
ocamldoc options sourcefiles
Параметры выбора формата вывода
Следующие параметры определяют формат создаваемой документации.
- -html
- Создать документацию в формате HTML по умолчанию. Созданные HTML-страницы сохраняются в текущем каталоге или в каталоге, заданном параметром -d. Настроить стиль созданных страниц можно, отредактировав файл style.css или указав собственную таблицу стилей с помощью параметра -css-style. Файл style.css не создается, если он уже существует или используется параметр -css-style.
- -latex
- Создать документацию в формате LATEX по умолчанию. Созданный документ LATEX сохраняется в файле ocamldoc.out или в файле, заданном параметром -o. В документе используется файл стилей ocamldoc.sty. Этот файл создается при использовании параметра -latex, если он еще не существует. Вы можете изменить этот файл, чтобы настроить стиль документации LATEX.
- -texi
- Создать документацию в формате TeXinfo по умолчанию. Созданный документ LATEX сохраняется в файле ocamldoc.out или в файле, заданном параметром -o.
- -man
- Создать документацию в виде набора справочных страниц Unix man. Созданные страницы сохраняются в текущем каталоге или в каталоге, заданном параметром -d.
- -dot
- Создать граф зависимостей для модулей верхнего уровня в формате, подходящем для отображения и обработки с помощью dot. Инструмент dot доступен на сайте https://graphviz.org/. Текстовое представление графа записывается в файл ocamldoc.out или в файл, заданный параметром -o. Для отображения используйте команду dot ocamldoc.out.
- -g file.cm[o,a,xs]
- Динамически загрузить указанный файл, определяющий пользовательский генератор документации. См. раздел 19.4.1. Этот параметр поддерживается командой ocamldoc (для загрузки файлов .cmo и .cma) и ее версией для машинного кода ocamldoc.opt (для загрузки файлов .cmxs). Если указано простое имя файла и его нет в текущем каталоге, ocamldoc ищет его в каталоге пользовательских генераторов по умолчанию и в каталогах, заданных необязательными параметрами -i.
- -customdir
- Показать каталог пользовательских генераторов по умолчанию.
- -i directory
- Добавить указанный каталог в путь поиска пользовательских генераторов.
Общие параметры
- -d dir
- Создавать файлы в каталоге dir, а не в текущем каталоге.
- -dump file
- Записать собранные сведения в файл file. Эти сведения можно прочитать с помощью параметра -load при последующем вызове ocamldoc.
- -hide modules
- Скрыть указанные полные имена модулей в создаваемой документации. modules — это список полных имен модулей, разделенных символом ’,’, без пробелов. Например: Stdlib,M2.M3.
- -inv-merge-ml-mli
- Изменить приоритет реализации и интерфейса при объединении. Сохраняются все элементы из файлов реализации, а параметр -m указывает, какие части комментариев из файлов интерфейса объединяются с комментариями из файлов реализации.
- -keep-code
- Всегда сохранять исходный код значений, методов и переменных экземпляра, если он доступен.
- -load file
- Загрузить сведения из файла file, созданного командой ocamldoc -dump. Можно указать несколько параметров -load.
- -m flags
- Задать параметры объединения интерфейсов и реализаций. (Подробности см. в разделе 19.1.2.) flags может содержать один или несколько следующих символов:
- d
- объединить описание
- a
- объединить @author
- v
- объединить @version
- l
- объединить @see
- s
- объединить @since
- b
- объединить @before
- o
- объединить @deprecated
- p
- объединить @param
- e
- объединить @raise
- r
- объединить @return
- A
- объединить все
- -no-custom-tags
- Запретить пользовательские теги @ (см. раздел 19.2.5).
- -no-stop
- Сохранять элементы, расположенные после/между специальными комментариями (**/**) (см. раздел 19.2).
- -o file
- Записать созданную документацию в файл file вместо ocamldoc.out. Этот параметр имеет смысл только совместно с параметрами -latex, -texi или -dot.
- -pp command
- Передать исходные файлы через препроцессор command.
- -impl filename
- Обработать файл filename как файл реализации, даже если его расширение не .ml.
- -intf filename
- Обработать файл filename как файл интерфейса, даже если его расширение не .mli.
- -text filename
- Обработать файл filename как текстовый файл, даже если его расширение не .txt.
- -sort
- Сортировать список модулей верхнего уровня перед созданием документации.
- -stars
- Удалять пробельные символы до первой звездочки (’*’) в каждой строке комментариев.
- -t title
- Использовать title в качестве заголовка создаваемой документации.
- -intro file
- Использовать содержимое файла file как текст введения ocamldoc (только для HTML, LATEX и TeXinfo). Для HTML этот файл используется для создания всего файла index.html.
- -v
- Подробный режим. Отображать сведения о ходе выполнения.
- -version
- Вывести строку версии и завершить работу.
- -vnum
- Вывести краткий номер версии и завершить работу.
- -warn-error
- Считать предупреждения Ocamldoc ошибками.
- -hide-warnings
- Не выводить предупреждения OCamldoc.
- -help or --help
- Показать краткую сводку по использованию и завершить работу.
Параметры проверки типов
OCamldoc вызывает средство проверки типов OCaml, чтобы получить информацию о типах. Следующие параметры влияют на этап проверки типов. Они имеют то же значение, что и в командах ocamlc и ocamlopt.
- -I directory
- Добавить directory в список каталогов поиска скомпилированных файлов интерфейса (файлов .cmi).
- -H directory
- Подобно -I, но поиск в каталогах -H выполняется в последнюю очередь, а программа не может напрямую обращаться к модулям, добавленным таким образом в путь поиска.
- -nolabels
- Игнорировать необязательные метки в типах.
- -rectypes
- Разрешить произвольные рекурсивные типы. (См. параметр -rectypes команды ocamlc.)
Параметры создания HTML-страниц
Следующие параметры используются совместно с параметром -html:
- -all-params
- Отображать полный список параметров функций и методов.
- -charset charset
- Добавить сведения о кодировке символов charset (по умолчанию — iso-8859-1).
- -colorize-code
- Раскрашивать код OCaml, заключенный в [ ] и {[ ]}, выделяя цветом ключевые слова и другие элементы. Если фрагменты кода синтаксически некорректны, раскраска не применяется.
- -css-style filename
- Использовать filename в качестве файла каскадных таблиц стилей.
- -index-only
- Создавать только индексные файлы.
- -short-functors
- Использовать краткую форму отображения функторов:
module M : functor (A:Module) -> functor (B:Module2) -> sig .. end
отображается так:module M (A:Module) (B:Module2) : sig .. end
Параметры создания файлов LATEX
Следующие параметры используются совместно с параметром -latex:
- -latex-value-prefix prefix
- Задать префикс меток значений в создаваемом документе LATEX. По умолчанию используется пустая строка. Также можно использовать параметры -latex-type-prefix, -latex-exception-prefix, -latex-module-prefix, -latex-module-type-prefix, -latex-class-prefix, -latex-class-type-prefix, -latex-attribute-prefix и -latex-method-prefix.
Эти параметры полезны, например, если у вас есть тип и значение с одинаковым именем. Если префиксы не указаны, LATEX сообщит об определении меток с одинаковыми именами.
- -latextitle n,style
- Связать номер стиля n с указанной командой структурирования разделов LATEX style, например section или subsection. (Только для LATEX.) Это полезно при включении созданного документа в другой документ LATEX на заданном уровне разделов. По умолчанию используются соответствия: 1 для section, 2 для subsection, 3 для subsubsection, 4 для paragraph и 5 для subparagraph.
- -noheader
- Не добавлять заголовок в создаваемую документацию.
- -notoc
- Не создавать оглавление.
- -notrailer
- Не добавлять завершающую часть в создаваемую документацию.
- -sepfiles
- Создавать отдельный файл .tex для каждого модуля верхнего уровня вместо общего файла ocamldoc.out.
Параметры создания файлов TeXinfo
Следующие параметры используются совместно с параметром -texi:
- -esc8
- Экранировать символы с диакритическими знаками в файлах Info.
- -info-entry
- Задать запись в каталоге Info.
- -info-section
- Задать раздел каталога Info.
- -noheader
- Не добавлять заголовок в создаваемую документацию.
- -noindex
- Не создавать индекс для файлов Info.
- -notrailer
- Не добавлять завершающую часть в создаваемую документацию.
Параметры создания графов dot
Следующие параметры используются совместно с параметром -dot:
- -dot-colors colors
- Задать цвета для создаваемого кода dot. При создании графа зависимостей модулей ocamldoc использует разные цвета для модулей в зависимости от каталогов, в которых они находятся. При создании графа зависимостей типов ocamldoc использует разные цвета для типов в зависимости от модулей, в которых они определены. colors — это список названий цветов, разделенных символом ’,’, например Red,Blue,Green. Доступны цвета, поддерживаемые инструментом dot.
- -dot-include-all
- Включать в вывод dot все модули, а не только модули, указанные в командной строке или загруженные с помощью параметра -load.
- -dot-reduce
- Выполнить транзитивное сокращение графа зависимостей перед выводом кода dot. Это может быть полезно, если в графе слишком много транзитивных зависимостей.
- -dot-types
- Вывести код dot, описывающий граф зависимостей типов, вместо графа зависимостей модулей.
Параметры создания справочных страниц man
Следующие параметры используются совместно с параметром -man:
- -man-mini
- Создавать справочные страницы только для модулей, типов модулей, классов и типов классов, а не для всех элементов.
- -man-suffix suffix
- Задать суффикс создаваемых имен файлов man. По умолчанию используется ’3o’, как в List.3o.
- -man-section section
- Задать номер раздела для создаваемых имен файлов man. По умолчанию используется ’3’.
1.2 Объединение сведений о модулях
Сведения о модуле можно извлечь из файла .mli или .ml, либо из обоих файлов — в зависимости от того, какие файлы указаны в командной строке. Если для одного модуля указаны файлы .mli и .ml, сведения, извлеченные из этих файлов, объединяются по следующим правилам:
- Сохраняются только элементы (значения, типы, классы и т. д.), объявленные в файле .mli. Иными словами, определения из файла .ml, не экспортированные в файле .mli, не документируются.
- Описания элементов и описания в тегах @ обрабатываются следующим образом. Если описание одного и того же элемента или одного и того же тега @ этого элемента присутствует в обоих файлах, описание из файла .ml присоединяется к описанию из файла .mli, если в командной строке указан соответствующий флаг -m. Если описание присутствует в файле .ml, но отсутствует в файле .mli, сохраняется описание из .ml. В обоих случаях сохраняется вся информация, указанная в файле .mli.
1.3 Правила кодирования
Чтобы избежать конфликтов имён, приводящих к ошибкам перекрёстных ссылок, необходимо соблюдать следующие правила:
- В модуле не должно быть двух модулей, двух типов модулей или модуля и типа модуля с одинаковыми именами. В генераторе HTML по умолчанию модули ab и AB будут записаны в один и тот же файл в файловых системах, нечувствительных к регистру.
- В модуле не должно быть двух классов, двух типов классов или класса и типа класса с одинаковыми именами.
- В модуле не должно быть двух значений, двух типов или двух исключений с одинаковыми именами.
- Значения, определённые в кортеже, как в let (x,y,z) = (1,2,3), не сохраняются OCamldoc.
- Избегайте следующей конструкции: В этом случае OCamldoc сопоставит Bar.x с x модуля Foo, определённого непосредственно выше, а не с Bar.x, определённым в открытом модуле Foo.
open Foo (* which has a module Bar with a value x *) module Foo = struct module Bar = struct let x = 1 end end let dummy = Bar.x
2 Синтаксис комментариев документации
Комментарии, содержащие документацию, называются специальными комментариями и записываются между (** и *). Специальные комментарии должны начинаться строго с (**. Комментарии, начинающиеся с ( и содержащие более двух символов *, игнорируются.
2.1 Размещение комментариев документации
OCamldoc может связывать комментарии с некоторыми элементами языка, встречающимися в исходных файлах. Связь устанавливается в соответствии с расположением комментариев относительно элементов языка. Расположение комментариев в файлах .mli и .ml различается.
Комментарии в файлах .mli
Специальный комментарий связывается с элементом, если он расположен перед этим элементом или после него.
Специальный комментарий перед элементом связывается с ним, если:
- Между специальным комментарием и элементом нет пустой строки или другого специального комментария. Однако между специальным комментарием и элементом может находиться обычный комментарий.
- Специальный комментарий ещё не связан с предыдущим элементом.
- Специальный комментарий не является первым комментарием модуля верхнего уровня.
Специальный комментарий после элемента связывается с этим элементом, если между комментарием и элементом нет пустой строки или другого комментария.
Есть два исключения: для конструкторов и полей записей в определениях типов связанный комментарий может располагаться только после определения конструктора или поля, без пустых строк или других комментариев между ними. Специальный комментарий для конструктора, за которым следует другой конструктор, должен располагаться перед символом ’|’, разделяющим эти два конструктора.
Следующий пример файла интерфейса foo.mli иллюстрирует правила размещения комментариев в файлах .mli.
(** The first special comment of the file is the comment associated
with the whole module.*)
(** Special comments can be placed between elements and are kept
by the OCamldoc tool, but are not associated to any element.
@-tags in these comments are ignored.*)
(*******************************************************************)
(** Comments like the one above, with more than two asterisks,
are ignored. *)
(** The comment for function f. *)
val f : int -> int -> int
(** The continuation of the comment for function f. *)
(** Comment for exception My_exception, even with a simple comment
between the special comment and the exception.*)
(* Hello, I'm a simple comment :-) *)
exception My_exception of (int -> int) * int
(** Comment for type weather *)
type weather =
| Rain of int (** The comment for constructor Rain *)
| Sun (** The comment for constructor Sun *)
(** Comment for type weather2 *)
type weather2 =
| Rain of int (** The comment for constructor Rain *)
| Sun (** The comment for constructor Sun *)
(** I can continue the comment for type weather2 here
because there is already a comment associated to the last constructor.*)
(** The comment for type my_record *)
type my_record = {
foo : int ; (** Comment for field foo *)
bar : string ; (** Comment for field bar *)
}
(** Continuation of comment for type my_record *)
(** Comment for foo *)
val foo : string
(** This comment is associated to foo and not to bar. *)
val bar : string
(** This comment is associated to bar. *)
(** The comment for class my_class *)
class my_class :
object
(** A comment to describe inheritance from cl *)
inherit cl
(** The comment for attribute tutu *)
val mutable tutu : string
(** The comment for attribute toto. *)
val toto : int
(** This comment is not attached to titi since
there is a blank line before titi, but is kept
as a comment in the class. *)
val titi : string
(** Comment for method toto *)
method toto : string
(** Comment for method m *)
method m : float -> int
end
(** The comment for the class type my_class_type *)
class type my_class_type =
object
(** The comment for variable x. *)
val mutable x : int
(** The comment for method m. *)
method m : int -> int
end
(** The comment for module Foo *)
module Foo :
sig
(** The comment for x *)
val x : int
(** A special comment that is kept but not associated to any element *)
end
(** The comment for module type my_module_type. *)
module type my_module_type =
sig
(** The comment for value x. *)
val x : int
(** The comment for module M. *)
module M :
sig
(** The comment for value y. *)
val y : int
(* ... *)
end
end
Комментарии в файлах .ml
Специальный комментарий связывается с элементом, если он расположен перед элементом и между комментарием и элементом нет пустой строки. При этом между специальным комментарием и элементом может находиться обычный комментарий. Есть два исключения: для конструкторов и полей записей в определениях типов связанный комментарий должен располагаться после определения конструктора или поля, без пустой строки между ними. Специальный комментарий для конструктора, за которым следует другой конструктор, должен располагаться перед символом ’|’, разделяющим эти два конструктора.
Следующий пример файла toto.ml показывает, где размещать комментарии в файле .ml.
(** The first special comment of the file is the comment associated
to the whole module. *)
(** The comment for function f *)
let f x y = x + y
(** This comment is not attached to any element since there is another
special comment just before the next element. *)
(** Comment for exception My_exception, even with a simple comment
between the special comment and the exception.*)
(* A simple comment. *)
exception My_exception of (int -> int) * int
(** Comment for type weather *)
type weather =
| Rain of int (** The comment for constructor Rain *)
| Sun (** The comment for constructor Sun *)
(** The comment for type my_record *)
type my_record = {
foo : int ; (** Comment for field foo *)
bar : string ; (** Comment for field bar *)
}
(** The comment for class my_class *)
class my_class =
object
(** A comment to describe inheritance from cl *)
inherit cl
(** The comment for the instance variable tutu *)
val mutable tutu = "tutu"
(** The comment for toto *)
val toto = 1
val titi = "titi"
(** Comment for method toto *)
method toto = tutu ^ "!"
(** Comment for method m *)
method m (f : float) = 1
end
(** The comment for class type my_class_type *)
class type my_class_type =
object
(** The comment for the instance variable x. *)
val mutable x : int
(** The comment for method m. *)
method m : int -> int
end
(** The comment for module Foo *)
module Foo =
struct
(** The comment for x *)
let x = 0
(** A special comment in the class, but not associated to any element. *)
end
(** The comment for module type my_module_type. *)
module type my_module_type =
sig
(* Comment for value x. *)
val x : int
(* ... *)
end
2.2 Специальный комментарий Stop
Специальный комментарий (**/**) указывает OCamldoc отбросить элементы, расположенные после этого комментария, до конца текущего класса, типа класса, модуля или типа модуля либо до следующего комментария остановки. Например:
class type foo =
object
(** comment for method m *)
method m : string
(**/**)
(** This method won't appear in the documentation *)
method bar : int
end
(** This value appears in the documentation, since the Stop special comment
in the class does not affect the parent module of the class.*)
val foo : string
(**/**)
(** The value bar does not appear in the documentation.*)
val bar : string
(**/**)
(** The type t appears since in the documentation since the previous stop comment
toggled off the "no documentation mode". *)
type t = string
Параметр -no-stop программы ocamldoc приводит к тому, что специальные комментарии Stop игнорируются.
2.3 Синтаксис комментариев документации
Содержимое комментариев документации (**…*) состоит из текста в свободной форме с необязательными аннотациями форматирования, за которым могут следовать необязательные теги, содержащие более конкретную информацию о параметрах, версии, авторах и т. д. Теги обозначаются начальным символом @. Таким образом, комментарий документации имеет следующий вид:
(** The comment begins with a description, which is text formatted according to the rules described in the next section. The description continues until the first non-escaped '@' character. @author Mr Smith @param x description for parameter x *)
Некоторые элементы поддерживают только часть всех тегов @. Теги, не относящиеся к документируемому элементу, просто игнорируются. Например, все теги игнорируются при документировании конструкторов типов, полей записей и предложений наследования классов. Аналогично, тег @param для переменной экземпляра класса игнорируется.
Наконец, (**) — это пустой комментарий документации.
2.4 Форматирование текста
Ниже приведена грамматика BNF простого языка разметки, используемого для форматирования текстовых описаний.
|
|
| text-element | ::= |
| ∣ | inline-text-element | |
| ∣ | blank-line | принудительно начать новую строку. |
| ∣ | { { 0 … 9 }+ inline-text } | форматировать text как заголовок раздела; целое число после { задаёт уровень заголовка. |
| ∣ | { { 0 … 9 }+ : label inline-text } | то же самое, но также связывает имя label с текущей точкой. На эту точку можно сослаться по её полному имени метки в команде {!, как и на любой другой элемент. |
| ∣ | {b inline-text } | выделить text полужирным шрифтом. |
| ∣ | {i inline-text } | выделить text курсивом. |
| ∣ | {e inline-text } | подчеркнуть text. |
| ∣ | {C inline-text } | выровнять text по центру. |
| ∣ | {L inline-text } | выровнять text по левому краю. |
| ∣ | {R inline-text } | выровнять text по правому краю. |
| ∣ | {ul list } | создать маркированный список. |
| ∣ | {ol list } | создать нумерованный список. |
| ∣ | {{: string } inline-text } | добавить ссылку на указанный адрес (заданный как string) к указанному text. |
| ∣ | [ string ] | задать для указанной строки string стиль исходного кода. |
| ∣ | {[ string ]} | задать для указанной строки string стиль предварительно отформатированного исходного кода. |
| ∣ | {v string v} | задать для указанной строки string стиль дословного текста. |
| ∣ | {% string %} | содержимое, зависящее от целевого формата (по умолчанию код LATEX; подробности см. в разделе 19.2.4.4) |
| ∣ | {! string } | вставить перекрёстную ссылку на элемент (синтаксис перекрёстных ссылок см. в разделе 19.2.4.2). |
| ∣ | {{! string } inline-text } | вставить перекрёстную ссылку с указанным текстом. |
| ∣ | {!modules: string string ... } | вставить индексную таблицу для указанных имён модулей. Используется только в HTML. |
| ∣ | {!indexlist} | вставить таблицу ссылок на различные указатели (типы, значения, модули и т. д.). Используется только в HTML. |
| ∣ | {^ inline-text } | задать для текста надстрочное начертание. |
| ∣ | {_ inline-text } | задать для текста подстрочное начертание. |
| ∣ | escaped-string | вывести указанную строку без изменений; специальные символы (’{’, ’}’, ’[’, ’]’ и ’@’) необходимо экранировать символом ’\’ |
2.4.1 Форматирование списков
|
Для маркированных и нумерованных списков предусмотрен сокращённый синтаксис:
(** Here is a {b list}
- item 1
- item 2
- item 3
The list is ended by the blank line.*)
эквивалентно следующему:
(** Here is a {b list}
{ul {- item 1}
{- item 2}
{- item 3}}
The list is ended by the blank line.*)
Для нумерованных списков доступно такое же сокращение, но вместо ’-’ используется ’+’. Обратите внимание: во вложенных списках с помощью этого сокращения можно определить только один список.
2.4.2 Форматирование перекрёстных ссылок
Перекрёстные ссылки — это полные имена элементов, например {!Foo.Bar.t}. Такая ссылка неоднозначна, поскольку может обозначать имя типа, значение, класс и т. д. Желаемый синтаксический класс можно указать явно: {!type:Foo.Bar.t} обозначает тип, а {!val:Foo.Bar.t} — значение с тем же именем.
Список возможных синтаксических классов:
| tag | синтаксический класс |
| module: | модуль |
| modtype: | тип модуля |
| class: | класс |
| classtype: | тип класса |
| val: | значение |
| type: | тип |
| exception: | исключение |
| attribute: | атрибут |
| method: | метод класса |
| section: | раздел OCamldoc |
| const: | конструктор варианта |
| recfield: | поле записи |
Для конструкторов вариантов и полей записей перед именем конструктора или поля следует указывать имя соответствующего типа, чтобы избежать неоднозначности, возникающей, когда несколько типов имеют конструкторы с одинаковыми именами. Например, на конструктор Node типа tree можно сослаться как {!tree.Node} или {!const:tree.Node}, а из-за пределов модуля — также как {!Mod1.Mod2.tree.Node}.
2.4.3 Первое предложение
В описании значения, типа, исключения, модуля, типа модуля, класса или типа класса первое предложение иногда используется в указателях или когда требуется только часть описания. Первое предложение состоит из начальных символов описания и заканчивается
- первой точкой, за которой следует пробел, или
- первой пустой строкой
вне следующих конструкций форматирования текста: {ul list } , {ol list } , [ string ] , {[ string ]} , {v string v} , {% string %} , {! string } , {^ text } , {_ text } .
2.4.4 Форматирование для конкретной цели
Содержимое внутри {%foo: ... %} зависит от целевого формата и обрабатывается только генератором foo; остальные генераторы его игнорируют. В поставку входят генераторы latex, html, texi и man. Если цель не указана (синтаксис {% ... %}), по умолчанию выбирается latex. Пользовательские генераторы могут поддерживать собственные префиксы целей.
2.4.5 Распознаваемые HTML-теги
HTML-теги <b>..</b>, <code>..</code>, <i>..</i>, <ul>..</ul>, <ol>..</ol>, <li>..</li>, <center>..</center> и <h[0-9]>..</h[0-9]> можно использовать вместо соответственно {b ..} , [..] , {i ..} , {ul ..} , {ol ..} , {li ..} , {C ..} и {[0-9] ..}.
2.5 Теги документации (теги @)
Предопределённые теги
В следующей таблице приведён список предопределённых тегов @, их синтаксис и значение.
| @author string | Автор элемента. Один автор на тег @author. Для одного элемента может быть указано несколько тегов @author. |
| @deprecated text | text должен описывать, когда элемент был объявлен устаревшим, что следует использовать вместо него и, возможно, причину, по которой он был объявлен устаревшим. |
| @param id text | Связать данное описание (text) с указанным именем параметра id. Этот тег используется для функций, методов, классов и функторов. |
| @raise Exc text | Указать, что элемент может вызвать исключение Exc. |
| @return text | Описать возвращаемое значение и возможные его значения. Этот тег используется для функций и методов. |
| @see < URL > text | Добавить ссылку на URL с указанным text в качестве комментария. |
| @see 'filename' text | Добавить ссылку на указанное имя файла (в одинарных кавычках) с указанным text в качестве комментария. |
| @see "document-name" text | Добавить ссылку на указанное имя документа (в двойных кавычках) с указанным text в качестве комментария. |
| @since string | Указать, когда был добавлен элемент. |
| @before version text | Связать данное описание (text) с указанной version, чтобы задокументировать проблемы совместимости. |
| @version string | Номер версии элемента. |
Пользовательские теги
В комментариях документации можно использовать пользовательские теги, но они не будут иметь эффекта, если используемый генератор их не обрабатывает. Чтобы использовать пользовательский тег, например foo, просто добавьте в комментарий @foo с каким-либо текстом, например:
(** My comment to show you a custom tag. @foo this is the text argument to the [foo] custom tag. *)
Чтобы обрабатывать пользовательские теги, необходимо определить пользовательский генератор, как описано в разделе 19.3.2.
3 Пользовательские генераторы
OCamldoc работает в два этапа:
- анализ исходных файлов;
- создание документации с помощью генератора документации, являющегося объектом класса Odoc_args.class_generator.
Пользователи могут указать собственный генератор документации, который будет использоваться на втором этапе вместо генераторов по умолчанию. Все сведения, полученные на этапе анализа, доступны через модуль Odoc_info, предоставляющий доступ ко всем типам и функциям, представляющим элементы, найденные в заданных модулях, и связанным с ними описаниям.
Файлы, которые можно использовать для определения пользовательских генераторов, устанавливаются в подкаталог ocamldoc стандартной библиотеки OCaml.
3.1 Модули генераторов
Тип модуля генератора зависит от вида создаваемой документации. Ниже приведён список типов модулей генераторов и имя класса генератора в соответствующем модуле:
- для HTML: Odoc_html.Html_generator (класс html),
- для LATEX: Odoc_latex.Latex_generator (класс latex),
- для TeXinfo: Odoc_texi.Texi_generator (класс texi),
- для man-страниц: Odoc_man.Man_generator (класс man),
- для graphviz (dot): Odoc_dot.Dot_generator (класс dot),
- для других видов: Odoc_gen.Base (класс generator).
Иными словами, чтобы определить новый генератор, нужно реализовать модуль с ожидаемой сигнатурой и указанным классом генератора, предоставив метод generate в качестве точки входа для создания документации по заданному списку модулей:
method generate : Odoc_info.Module.t_module list -> unit
Этот метод будет вызван со списком проанализированных и, возможно, объединённых структур Odoc_info.t_module.
Рекомендуется наследовать генератор от существующего генератора того же вида, что и определяемый. Это позволяет загружать несколько пользовательских генераторов и объединять улучшения, внесённые каждым из них.
Это делается с помощью модулей первого класса (см. главу 12.5).
Самый простой способ определить пользовательский генератор — следовать примеру ниже, расширяющему текущий генератор HTML. Не нужно знать, является ли он исходным генератором HTML, определённым в ocamldoc, или уже был расширен ранее загруженным пользовательским генератором:
module Generator (G : Odoc_html.Html_generator) =
struct
class html =
object(self)
inherit G.html as html
(* ... *)
method generate module_list =
(* ... *)
()
(* ... *)
end
end;;
let _ = Odoc_args.extend_html_generator (module Generator : Odoc_gen.Html_functor);;
Чтобы узнать, какие методы следует переопределить и/или какие методы доступны, обратитесь к соответствующим базовым реализациям в зависимости от вида расширяемого генератора:
- для HTML: odoc_html.ml,
- для LATEX: odoc_latex.ml,
- для TeXinfo: odoc_texi.ml,
- для man-страниц: odoc_man.ml,
- для graphviz (dot): odoc_dot.ml.
3.2 Обработка пользовательских тегов
Заставить пользовательский генератор обрабатывать пользовательские теги (см. 19.2.5) очень просто.
Для HTML
Ниже описано, как разработать генератор HTML, обрабатывающий пользовательские теги.
Класс Odoc_html.Generator.html наследует класс Odoc_html.info, содержащий поле tag_functions — список пар, состоящих из пользовательского тега (например, "foo") и функции, принимающей text и возвращающей HTML-код (типа string). Чтобы обрабатывать новый тег bar, расширьте текущий генератор HTML и заполните поле tag_functions:
module Generator (G : Odoc_html.Html_generator) =
struct
class html =
object(self)
inherit G.html
(** Return HTML code for the given text of a bar tag. *)
method html_of_bar t = (* your code here *)
initializer
tag_functions <- ("bar", self#html_of_bar) :: tag_functions
end
end
let _ = Odoc_args.extend_html_generator (module Generator : Odoc_gen.Html_functor);;
Другой метод класса Odoc_html.info ищет функцию, связанную с пользовательским тегом, и применяет её к тексту, переданному этому тегу. Если с пользовательским тегом не связана никакая функция, метод выводит предупреждение в stderr.
Для других генераторов
Аналогичным образом можно поступить и с генераторами других видов.
4 Добавление параметров командной строки
Анализ командной строки выполняется после загрузки модуля с генератором документации, поэтому можно добавлять параметры командной строки к уже существующему списку. Добавить параметр можно с помощью функции
Odoc_args.add_option : string * Arg.spec * string -> unit
Примечание: существующие параметры командной строки можно переопределить с помощью этой функции.
4.1 Компиляция и использование
Определение класса пользовательского генератора в одном файле
Пусть custom.ml — файл, в котором определён новый класс генератора. Файл custom.ml можно скомпилировать следующей командой:
ocamlc -I +ocamldoc -c custom.ml
Будет создан файл custom.cmo, который можно использовать следующим образом:
ocamldoc -g custom.cmo other-options source-files
Параметры, выбирающие встроенный генератор для ocamldoc, например -html, не действуют, если с помощью -g указан пользовательский генератор того же вида. Если виды не совпадают, используется выбранный встроенный генератор, а пользовательский игнорируется.
Определение класса пользовательского генератора в нескольких файлах
Класс генератора можно определить в нескольких модулях, расположенных в файлах file1.ml[i], file2.ml[i], ..., filen.ml[i]. Необходимо создать библиотечный файл .cma, включающий все эти файлы.
Следующие команды создают файл custom.cma из файлов file1.ml[i], ..., filen.ml[i]:
ocamlc -I +ocamldoc -c file1.ml[i] ocamlc -I +ocamldoc -c file2.ml[i] ... ocamlc -I +ocamldoc -c filen.ml[i] ocamlc -o custom.cma -a file1.cmo file2.cmo ... filen.cmo
Затем следующая команда использует custom.cma в качестве пользовательского генератора:
ocamldoc -g custom.cma other-options source-files
© 1995-2026 INRIA.
https://ocaml.org/manual/5.5/ocamldoc.html