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

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

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

OCamldoc может создавать документацию в различных форматах: HTML, LATEX, TeXinfo, страницы Unix man и графы зависимостей 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 каталог
Добавить каталог в список каталогов для поиска скомпилированных файлов интерфейса (.cmi файлы).
-H каталог
Как -I, но каталоги -H проверяются в последнюю очередь, и программа может не ссылаться напрямую на модули, добавленные в путь поиска таким образом.
-nolabels
Игнорировать не-необязательные метки в типах.
-rectypes
Разрешить произвольные рекурсивные типы. (См. опцию -rectypes в ocamlc.)

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

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

-all-params
Отобразить полный список параметров для функций и методов.
-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’.

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 игнорировать элементы, расположенные после этого комментария, до конца текущего класса, типа класса, модуля или типа модуля, или до следующего комментария 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.

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 Форматирование текста

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

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


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 Текст должен описывать, когда элемент был устаревшим, что использовать в качестве замены и, возможно, причину устаревания.
@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.

3 Настраиваемые генераторы

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

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

Пользователи могут предоставить собственный генератор документации для использования на этапе 2 вместо стандартных генераторов. Вся информация, полученная на этапе анализа, доступна через модуль 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) »
Авторское право © 2024 Institut National de Recherche en Informatique et en Automatique

© 1995-2024 INRIA.
https://ocaml.org/manual/5.2/ocamldoc.html

Spec-Zone.ru

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