Spec-Zone.ru › OCaml 5.0

Глава 19 Генератор документации (ocamldoc)

  • 19.1 Использование
  • 19.2 Синтаксис комментариев документации
  • 19.3 Пользовательские генераторы
  • 19.4 Добавление параметров командной строки

В этой главе описывается OCamldoc, инструмент, который генерирует документацию из специальных комментариев, встроенных в исходные файлы. Комментарии, используемые OCamldoc, имеют вид (**…*) и следуют формату, описанному в разделе 19.2.

OCamldoc может создавать документацию в различных форматах: HTML, LATEX, TeXinfo, страницы Unix man и графы зависимостей dot. Кроме того, пользователи могут добавлять свои собственные пользовательские генераторы, как объясняется в разделе 19.3.

В этой главе слово элемент используется для обозначения любой из следующих частей файла исходного кода OCaml: объявление типа, значение, модуль, исключение, тип модуля, конструктор типа, поле записи, класс, тип класса, метод класса, значение класса или пункт наследования класса.

19.1 Использование

19.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 или --help
Вывести краткое описание использования и завершить работу.

Параметры проверки типов

OCamldoc вызывает OCaml-проверяющий типов, чтобы получить информацию о типах. Следующие параметры влияют на фазу проверки типов. Они имеют то же значение, что и для команд ocamlc и ocamlopt.

-I directory
Добавить directory в список каталогов для поиска скомпилированных файлов интерфейсов (.cmi-файлы).
-nolabels
Игнорировать необязательные метки в типах.
-rectypes
Разрешить произвольные рекурсивные типы. (См. параметр -rectypes для ocamlc).

Параметры для генерации страниц HTML

Следующие параметры применяются совместно с параметром -html:

-all-params
Отобразить полный список параметров для функций и методов.
-charset charset
Добавить информацию о кодировке символов charset (по умолчанию iso-8859-1).
-colorize-code
Выделить цветным цветом код OCaml, заключенный в [ ] и {[ ]}, используя цвета для выделения ключевых слов и т. д. Если фрагменты кода не являются синтаксически корректными, цвет не добавляется.
-css-style имя_файла
Использовать имя_файла как файл таблицы стилей Cascading Style Sheet.
-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 префикс
Указать префикс для меток значений в генерируемом документе 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 номер,стиль
Связать номер стиля номер с заданной командой разбиения LATEX стиль, например, 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 цвета
Указать цвета для использования в сгенерированном коде dot. При генерации зависимостей модулей ocamldoc использует разные цвета для модулей в зависимости от каталогов, в которых они находятся. При генерации зависимостей типов ocamldoc использует разные цвета для типов в зависимости от модулей, в которых они определены. цвета — список имён цветов, разделенных символом ’,’, как в Красный,Синий,Зелёный. Доступные цвета — те, которые поддерживает инструмент dot.
-dot-include-all
Включить все модули в выходные данные dot, а не только модули, указанные в командной строке или загруженные с параметром -load.
-dot-reduce
Выполнить редукцию по транзитивности графа зависимостей перед выводом кода dot. Это может быть полезно, если есть много транзитивных зависимостей, которые загромождают граф.
-dot-types
Вывести код dot, описывающий граф зависимостей типов, а не граф зависимостей модулей.

Параметры для генерации файлов man

Следующие параметры применяются совместно с параметром -man:

-man-mini
Сгенерировать страницы man только для модулей, типов модулей, классов и типов классов, а не страниц для всех элементов.
-man-suffix суффикс
Установить суффикс, используемый для сгенерированных имён файлов man. По умолчанию ’3o’, как в List.3o.
-man-section раздел
Установить номер раздела, используемый для сгенерированных имён файлов man. По умолчанию ’3’.

19.1.2 Объединение информации о модулях

Информация о модуле может быть извлечена из файла .mli или .ml, или из обоих, в зависимости от файлов, указанных в командной строке. Когда для одного модуля заданы файлы .mli и .ml, информация, извлечённая из этих файлов, объединяется по следующим правилам:

  • Только элементы (значения, типы, классы, ...), объявленные в файле .mli, сохраняются. Другими словами, определения из файла .ml, которые не экспортированы в файл .mli, не документируются.
  • Описание элементов и описания в тегах @ обрабатываются следующим образом. Если описание для одного и того же элемента или в том же теге @ одного и того же элемента присутствует в обоих файлах, то описание из файла .ml добавляется к описанию в файле .mli, если соответствующий флаг -m задан в командной строке. Если описание присутствует в файле .ml и отсутствует в файле .mli, описание из файла .ml сохраняется. В любом случае, вся информация, предоставленная в файле .mli, сохраняется.

19.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.

19.2 Синтаксис комментариев документации

Комментарии, содержащие материал документации, называются специальными комментариями и пишутся между (** и *). Специальные комментарии должны начинаться точно с (**. Комментарии, начинающиеся с ( и содержащие более двух *, игнорируются.

19.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

19.2.2 Специальный комментарий Stop

Специальный комментарий (**/**) сообщает OCamldoc о необходимости игнорировать элементы, размещённые после этого комментария, вплоть до конца текущего класса, типа класса, модуля или типа модуля или до следующего комментария stop. Например:

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.

19.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 для переменной экземпляра класса игнорируется.

Наконец, (**) — это пустой комментарий документации.

19.2.4 Форматирование текста

Ниже приведена грамматика БНФ для простого языка разметки, используемого для форматирования текстовых описаний.

текст ::= {элемент-текста}+
текст-в-строке ::= {элемент-текста-в-строке}+
элемент-текста ::=
∣ элемент-текста-в-строке
∣ пустая-строка вынуждает новую строку.


элемент-текста-в-строке ::=
∣ { { 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 в стиле verbatim.
∣ {% 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 набрать заданную строку как есть; специальные символы (’{’, ’}’, ’[’, ’]’ и ’@’) должны быть экранированы символом ’\’


19.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.*)

Такой же сокращённый синтаксис доступен для нумерованных списков, с использованием ’+’ вместо ’-’. Обратите внимание, что с помощью этого сокращённого синтаксиса в вложенных списках можно определить только один список.

19.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} извне модуля.

19.2.4.3 Первое предложение

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

  • не встретится первая точка, за которой следует пробел, или
  • не встретится первая пустая строка

вне следующих форматов текста: {ul list } , {ol list } , [ string ] , {[ string ]} , {v string v} , {% string %} , {! string } , {^ text } , {_ text } .

19.2.4.4 Форматирование, специфичное для целевой платформы

Содержимое внутри {%foo: ... %} специфично для целевой платформы и будет интерпретироваться только бэкендом foo, а другими — игнорироваться. Бэкенды дистрибутива — latex, html, texi и man. Если целевой бэкенд не указан (синтаксис {% ... %}), по умолчанию выбирается latex. Пользовательские генераторы могут поддерживать собственные префиксы целевой платформы.

19.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] ..}.

19.2.5 Теги документации (@-теги)

Предопределённые теги

В следующей таблице перечислены предопределённые @-теги, их синтаксис и значение.

@author string Автор элемента. Один автор на один тег @author. Для одного элемента может быть несколько тегов @author.
@deprecated 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 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.

19.3 Пользовательские генераторы

OCamldoc работает в два этапа:

  1. анализ исходных файлов;
  2. генерация документации с помощью генератора документации, который является объектом класса Odoc_args.class_generator.

Пользователи могут предоставить собственный генератор документации, который будет использоваться на этапе 2 вместо генераторов по умолчанию. Вся информация, полученная на этапе анализа, доступна через модуль Odoc_info, который предоставляет доступ ко всем типам и функциям, представляющим элементы, найденные в заданных модулях, со связанным описанием.

Файлы, которые можно использовать для определения пользовательских генераторов, установлены в подкаталоге ocamldoc стандартной библиотеки OCaml.

19.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.

19.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.

Для других генераторов

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

19.4 Добавление опций командной строки

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

        Odoc_args.add_option : string * Arg.spec * string -> unit

Примечание: существующие опции командной строки могут быть переопределены с помощью этой функции.

19.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-2022 INRIA.
https://v2.ocaml.org/releases/5.0/htmlman/ocamldoc.html

Spec-Zone.ru

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