Spec-Zone.ru › OCaml
☰Инструменты OCaml
  • Пакетная компиляция (ocamlc)
  • Система верхнего уровня или REPL (ocaml)
  • Система времени выполнения (ocamlrun)
  • Компиляция в машинный код (ocamlopt)
  • Генераторы лексических анализаторов и парсеров (ocamllex, ocamlyacc)
  • Генератор зависимостей (ocamldep)
  • Генератор документации (ocamldoc)
  • Отладчик (ocamldebug)
  • Отладка машинного кода (gdb, lldb)
  • Профилирование (ocamlprof, perf)
  • Взаимодействие C с OCaml
  • Оптимизация с помощью Flambda
  • Фаззинг с помощью afl-fuzz
  • Трассировка времени выполнения с помощью событий runtime
  • Преобразование программы «Tail Modulo Constructor»
  • Обнаружение гонок данных во время выполнения с помощью ThreadSanitizer

Глава 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.
  • Избегайте следующей конструкции:
    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
    В этом случае OCamldoc сопоставит Bar.x с x модуля Foo, определённого непосредственно выше, а не с Bar.x, определённым в открытом модуле Foo.

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 ::= {text-element}+
inline-text ::= {inline-text-element}+
text-element ::=
∣ inline-text-element
∣ blank-line принудительно начать новую строку.


inline-text-element ::=
∣ { { 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 Форматирование списков

list ::=
∣ { {- inline-text } }+
∣ { {li inline-text } }+

Для маркированных и нумерованных списков предусмотрен сокращённый синтаксис:

(** 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 работает в два этапа:

  1. анализ исходных файлов;
  2. создание документации с помощью генератора документации, являющегося объектом класса 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
« Генератор зависимостей (ocamldep)Отладчик (ocamldebug) »
Авторские права © 2026 Institut National de Recherche en Informatique et en Automatique

© 1995-2026 INRIA.
https://ocaml.org/manual/5.5/ocamldoc.html

Spec-Zone.ru

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