1%% ===================================================================== 2%% Licensed under the Apache License, Version 2.0 (the "License"); you may 3%% not use this file except in compliance with the License. You may obtain 4%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0> 5%% 6%% Unless required by applicable law or agreed to in writing, software 7%% distributed under the License is distributed on an "AS IS" BASIS, 8%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9%% See the License for the specific language governing permissions and 10%% limitations under the License. 11%% 12%% Alternatively, you may use this file under the terms of the GNU Lesser 13%% General Public License (the "LGPL") as published by the Free Software 14%% Foundation; either version 2.1, or (at your option) any later version. 15%% If you wish to allow use of your version of this file only under the 16%% terms of the LGPL, you should delete the provisions above and replace 17%% them with the notice and other provisions required by the LGPL; see 18%% <http://www.gnu.org/licenses/>. If you do not delete the provisions 19%% above, a recipient may use your version of this file under the terms of 20%% either the Apache License or the LGPL. 21%% 22%% @copyright 2001-2007 Richard Carlsson 23%% @author Richard Carlsson <carlsson.richard@gmail.com> 24%% @version {@version} 25%% @end 26%% ===================================================================== 27 28%% TODO: check weirdness in name generation for @spec f(TypeName, ...) -> ... 29%% TODO: option for ignoring functions matching some pattern ('..._test_'/0) 30%% TODO: @private_type tag, opaque unless generating private docs? 31%% TODO: document the record type syntax 32%% TODO: some 'skip' option for ignoring particular modules? 33%% TODO: multiline comment support (needs modified comment representation) 34%% TODO: config-file for default settings 35%% TODO: config: locations of all local docdirs; generate local doc-index page 36%% TODO: config: URL:s of offline apps 37%% TODO: config: default stylesheet 38%% TODO: config: default header/footer, etc. 39%% TODO: offline linkage 40%% TODO: including source code, explicitly and/or automatically 41 42%% @doc EDoc - the Erlang program documentation generator. 43%% 44%% This module provides the main user interface to EDoc. 45%% <ul> 46%% <li><a href="overview-summary.html">EDoc User Manual</a></li> 47%% <li><a href="overview-summary.html#Running_EDoc">Running EDoc</a></li> 48%% </ul> 49 50-module(edoc). 51 52-export([files/1, files/2, 53 application/1, application/2, application/3, 54 toc/1, toc/2, toc/3, 55 run/2, 56 file/1, file/2, 57 read/1, read/2, 58 layout/1, layout/2, 59 get_doc/1, get_doc/2, get_doc/3, 60 read_comments/1, read_comments/2, 61 read_source/1, read_source/2]). 62 63-compile({no_auto_import,[error/1]}). 64 65-include("edoc.hrl"). 66 67 68%% @spec (Name::filename()) -> ok 69%% @equiv file(Name, []) 70%% @deprecated See {@link file/2} for details. 71 72file(Name) -> 73 file(Name, []). 74 75%% @spec file(filename(), proplist()) -> ok 76%% 77%% @type filename() = //kernel/file:filename() 78%% @type proplist() = [term()] 79%% 80%% @deprecated This is part of the old interface to EDoc and is mainly 81%% kept for backwards compatibility. The preferred way of generating 82%% documentation is through one of the functions {@link application/2} 83%% and {@link files/2}. 84%% 85%% @doc Reads a source code file and outputs formatted documentation to 86%% a corresponding file. 87%% 88%% Options: 89%% <dl> 90%% <dt>{@type {dir, filename()@}} 91%% </dt> 92%% <dd>Specifies the output directory for the created file. (By 93%% default, the output is written to the directory of the source 94%% file.) 95%% </dd> 96%% <dt>{@type {source_suffix, string()@}} 97%% </dt> 98%% <dd>Specifies the expected suffix of the input file. The default 99%% value is `".erl"'. 100%% </dd> 101%% <dt>{@type {file_suffix, string()@}} 102%% </dt> 103%% <dd>Specifies the suffix for the created file. The default value is 104%% `".html"'. 105%% </dd> 106%% </dl> 107%% 108%% See {@link get_doc/2} and {@link layout/2} for further 109%% options. 110%% 111%% For running EDoc from a Makefile or similar, see 112%% {@link edoc_run:file/1}. 113%% 114%% @see read/2 115 116%% NEW-OPTIONS: source_suffix, file_suffix, dir 117%% INHERIT-OPTIONS: read/2 118 119file(Name, Options) -> 120 Text = read(Name, Options), 121 SrcSuffix = proplists:get_value(source_suffix, Options, 122 ?DEFAULT_SOURCE_SUFFIX), 123 BaseName = filename:basename(Name, SrcSuffix), 124 Suffix = proplists:get_value(file_suffix, Options, 125 ?DEFAULT_FILE_SUFFIX), 126 Dir = proplists:get_value(dir, Options, filename:dirname(Name)), 127 Encoding = [{encoding, edoc_lib:read_encoding(Name, [])}], 128 edoc_lib:write_file(Text, Dir, BaseName ++ Suffix, Encoding). 129 130 131%% TODO: better documentation of files/1/2, application/1/2/3 132 133%% @spec (Files::[filename()]) -> ok 134 135files(Files) -> 136 files(Files, []). 137 138%% @spec (Files::[filename()], 139%% Options::proplist()) -> ok 140%% @doc Runs EDoc on a given set of source files. See {@link run/2} for 141%% details, including options. 142%% @equiv run([], Files, Options) 143 144files(Files, Options) -> 145 run(Files, Options). 146 147%% @spec (Application::atom()) -> ok 148%% @equiv application(Application, []) 149 150application(App) -> 151 application(App, []). 152 153%% @spec (Application::atom(), Options::proplist()) -> ok 154%% @doc Run EDoc on an application in its default app-directory. See 155%% {@link application/3} for details. 156%% @see application/1 157 158application(App, Options) when is_atom(App) -> 159 case code:lib_dir(App) of 160 Dir when is_list(Dir) -> 161 application(App, Dir, Options); 162 _ -> 163 edoc_report:report("cannot find application directory for '~s'.", 164 [App]), 165 exit(error) 166 end. 167 168%% @spec (Application::atom(), Dir::filename(), Options::proplist()) 169%% -> ok 170%% @doc Run EDoc on an application located in the specified directory. 171%% Tries to automatically set up good defaults. Unless the user 172%% specifies otherwise: 173%% <ul> 174%% <li>The `doc' subdirectory will be used as the target directory, if 175%% it exists; otherwise the application directory is used. 176%% </li> 177%% <li>The source code is assumed to be located in the `src' 178%% subdirectory, if it exists, or otherwise in the application 179%% directory itself. 180%% </li> 181%% <li>The {@link run/2. `subpackages'} option is turned on. All found 182%% source files will be processed. 183%% </li> 184%% <li>The `include' subdirectory is automatically added to the 185%% include path. (Only important if {@link read_source/2. 186%% preprocessing} is turned on.) 187%% </li> 188%% </ul> 189%% 190%% See {@link run/2} for details, including options. 191%% 192%% @see application/2 193 194application(App, Dir, Options) when is_atom(App) -> 195 Src = edoc_lib:try_subdir(Dir, ?SOURCE_DIR), 196 Overview = filename:join(edoc_lib:try_subdir(Dir, ?EDOC_DIR), 197 ?OVERVIEW_FILE), 198 Opts = Options ++ [{source_path, [Src]}, 199 subpackages, 200 {title, io_lib:fwrite("The ~ts application", [App])}, 201 {overview, Overview}, 202 {dir, filename:join(Dir, ?EDOC_DIR)}, 203 {includes, [filename:join(Dir, "include")]}], 204 Opts1 = set_app_default(App, Dir, Opts), 205 %% Recursively document all subpackages of '' - i.e., everything. 206 run([], [{application, App} | Opts1]). 207 208%% Try to set up a default application base URI in a smart way if the 209%% user has not specified it explicitly. 210 211set_app_default(App, Dir0, Opts) -> 212 case proplists:get_value(app_default, Opts) of 213 undefined -> 214 AppName = atom_to_list(App), 215 Dir = edoc_lib:simplify_path(filename:absname(Dir0)), 216 AppDir = case filename:basename(Dir) of 217 AppName -> 218 filename:dirname(Dir); 219 _ -> 220 ?APP_DEFAULT 221 end, 222 [{app_default, AppDir} | Opts]; 223 _ -> 224 Opts 225 end. 226 227opt_defaults() -> 228 []. 229 230opt_negations() -> 231 [{no_preprocess, preprocess}, 232 {no_subpackages, subpackages}, 233 {no_report_missing_types, report_missing_types}]. 234 235%% @spec run(Files::[filename()], 236%% Options::proplist()) -> ok 237%% @doc Runs EDoc on a given set of source files. Note 238%% that the doclet plugin module has its own particular options; see the 239%% `doclet' option below. 240%% 241%% Also see {@link layout/2} for layout-related options, and 242%% {@link get_doc/2} for options related to reading source 243%% files. 244%% 245%% Options: 246%% <dl> 247%% <dt>{@type {app_default, string()@}} 248%% </dt> 249%% <dd>Specifies the default base URI for unknown applications. 250%% </dd> 251%% <dt>{@type {application, App::atom()@}} 252%% </dt> 253%% <dd>Specifies that the generated documentation describes the 254%% application `App'. This mainly affects generated references. 255%% </dd> 256%% <dt>{@type {dir, filename()@}} 257%% </dt> 258%% <dd>Specifies the target directory for the generated documentation. 259%% </dd> 260%% <dt>{@type {doc_path, [string()]@}} 261%% </dt> 262%% <dd>Specifies a list of file system paths pointing to directories that 263%% contain EDoc-generated documentation. All paths for applications 264%% in the code path are automatically added. 265%% </dd> 266%% <dt>{@type {doclet, Module::atom()@}} 267%% </dt> 268%% <dd>Specifies a callback module to be used for creating the 269%% documentation. The module must export a function `run(Cmd, Ctxt)'. 270%% The default doclet module is {@link edoc_doclet}; see {@link 271%% edoc_doclet:run/2} for doclet-specific options. 272%% </dd> 273%% <dt>{@type {file_suffix, string()@}} 274%% </dt> 275%% <dd>Specifies the suffix used for output files. The default value is 276%% `".html"'. Note that this also affects generated references. 277%% </dd> 278%% <dt>{@type {new, boolean()@}} 279%% </dt> 280%% <dd>If the value is `true', any existing `edoc-info' file in the 281%% target directory will be ignored and overwritten. The default 282%% value is `false'. 283%% </dd> 284%% <dt>{@type {source_path, [filename()]@}} 285%% </dt> 286%% <dd>Specifies a list of file system paths used to locate the source 287%% code for packages. 288%% </dd> 289%% <dt>{@type {source_suffix, string()@}} 290%% </dt> 291%% <dd>Specifies the expected suffix of input files. The default 292%% value is `".erl"'. 293%% </dd> 294%% <dt>{@type {subpackages, boolean()@}} 295%% </dt> 296%% <dd>If the value is `true', all subpackages of specified packages 297%% will also be included in the documentation. The default value is 298%% `false'. `no_subpackages' is an alias for `{subpackages, 299%% false}'. 300%% 301%% Subpackage source files are found by recursively searching 302%% for source code files in subdirectories of the known source code 303%% root directories. (Also see the `source_path' option.) Directory 304%% names must begin with a lowercase letter and contain only 305%% alphanumeric characters and underscore, or they will be ignored. 306%% (For example, a subdirectory named `test-files' will not be 307%% searched.) 308%% </dd> 309%% </dl> 310%% 311%% @see files/2 312%% @see application/2 313 314%% NEW-OPTIONS: source_path, application 315%% INHERIT-OPTIONS: init_context/1 316%% INHERIT-OPTIONS: expand_sources/2 317%% INHERIT-OPTIONS: target_dir_info/5 318%% INHERIT-OPTIONS: edoc_lib:find_sources/2 319%% INHERIT-OPTIONS: edoc_lib:run_doclet/2 320%% INHERIT-OPTIONS: edoc_lib:get_doc_env/3 321 322run(Files, Opts0) -> 323 Opts = expand_opts(Opts0), 324 Ctxt = init_context(Opts), 325 Dir = Ctxt#context.dir, 326 Path = proplists:append_values(source_path, Opts), 327 Ss = sources(Path, Opts), 328 {Ss1, Ms} = expand_sources(expand_files(Files) ++ Ss, Opts), 329 App = proplists:get_value(application, Opts, ?NO_APP), 330 {App1, Ms1} = target_dir_info(Dir, App, Ms, Opts), 331 Ms2 = edoc_lib:unique(lists:sort(Ms1)), 332 Env = edoc_lib:get_doc_env(App1, Ms2, Opts), 333 Ctxt1 = Ctxt#context{env = Env}, 334 Cmd = #doclet_gen{sources = Ss1, 335 app = App1, 336 modules = Ms2 337 }, 338 F = fun (M) -> 339 M:run(Cmd, Ctxt1) 340 end, 341 edoc_lib:run_doclet(F, Opts). 342 343expand_opts(Opts0) -> 344 proplists:substitute_negations(opt_negations(), 345 Opts0 ++ opt_defaults()). 346 347%% NEW-OPTIONS: dir 348%% DEFER-OPTIONS: run/2 349 350init_context(Opts) -> 351 #context{dir = proplists:get_value(dir, Opts, ?CURRENT_DIR), 352 opts = Opts 353 }. 354 355%% INHERIT-OPTIONS: edoc_lib:find_sources/2 356 357sources(Path, Opts) -> 358 edoc_lib:find_sources(Path, Opts). 359 360%% Expand user-specified sets of files. 361 362expand_files([F | Fs]) -> 363 [{filename:basename(F), filename:dirname(F)} | 364 expand_files(Fs)]; 365expand_files([]) -> 366 []. 367 368%% Create the (assumed) full module names. Keep only the first source 369%% for each module, but preserve the order of the list. 370 371%% NEW-OPTIONS: source_suffix 372%% DEFER-OPTIONS: run/2 373 374expand_sources(Ss, Opts) -> 375 Suffix = proplists:get_value(source_suffix, Opts, 376 ?DEFAULT_SOURCE_SUFFIX), 377 Ss1 = [{F,D} || {F,D} <- Ss], 378 expand_sources(Ss1, Suffix, sets:new(), [], []). 379 380expand_sources([{F, D} | Fs], Suffix, S, As, Ms) -> 381 M = list_to_atom(filename:rootname(F, Suffix)), 382 case sets:is_element(M, S) of 383 true -> 384 expand_sources(Fs, Suffix, S, As, Ms); 385 false -> 386 S1 = sets:add_element(M, S), 387 expand_sources(Fs, Suffix, S1, [{M, F, D} | As], 388 [M | Ms]) 389 end; 390expand_sources([], _Suffix, _S, As, Ms) -> 391 {lists:reverse(As), lists:reverse(Ms)}. 392 393%% NEW-OPTIONS: new 394 395target_dir_info(Dir, App, Ms, Opts) -> 396 case proplists:get_bool(new, Opts) of 397 true -> 398 {App, Ms}; 399 false -> 400 {App1, Ms1} = edoc_lib:read_info_file(Dir), 401 {if App == ?NO_APP -> App1; 402 true -> App 403 end, 404 Ms ++ Ms1} 405 end. 406 407 408%% @hidden Not official yet 409 410toc(Dir) -> 411 toc(Dir, []). 412 413%% @equiv toc(Dir, Paths, []) 414%% @hidden Not official yet 415 416%% NEW-OPTIONS: doc_path 417 418toc(Dir, Opts) -> 419 Paths = proplists:append_values(doc_path, Opts) 420 ++ edoc_lib:find_doc_dirs(), 421 toc(Dir, Paths, Opts). 422 423%% @doc Create a meta-level table of contents. 424%% @hidden Not official yet 425 426%% INHERIT-OPTIONS: init_context/1 427%% INHERIT-OPTIONS: edoc_lib:run_doclet/2 428%% INHERIT-OPTIONS: edoc_lib:get_doc_env/3 429 430toc(Dir, Paths, Opts0) -> 431 Opts = expand_opts(Opts0 ++ [{dir, Dir}]), 432 Ctxt = init_context(Opts), 433 Env = edoc_lib:get_doc_env('', [], Opts), 434 Ctxt1 = Ctxt#context{env = Env}, 435 F = fun (M) -> 436 M:run(#doclet_toc{paths=Paths}, Ctxt1) 437 end, 438 edoc_lib:run_doclet(F, Opts). 439 440 441%% @spec read(File::filename()) -> string() 442%% @equiv read(File, []) 443 444read(File) -> 445 read(File, []). 446 447%% @spec read(File::filename(), Options::proplist()) -> string() 448%% 449%% @doc Reads and processes a source file and returns the resulting 450%% EDoc-text as a string. See {@link get_doc/2} and {@link layout/2} for 451%% options. 452%% 453%% @see file/2 454 455%% INHERIT-OPTIONS: get_doc/2, layout/2 456 457read(File, Opts) -> 458 {_ModuleName, Doc} = get_doc(File, Opts), 459 layout(Doc, Opts). 460 461 462%% @spec layout(Doc::edoc_module()) -> string() 463%% @equiv layout(Doc, []) 464 465layout(Doc) -> 466 layout(Doc, []). 467 468%% @spec layout(Doc::edoc_module(), Options::proplist()) -> string() 469%% 470%% @doc Transforms EDoc module documentation data to text. The default 471%% layout creates an HTML document. 472%% 473%% Options: 474%% <dl> 475%% <dt>{@type {layout, Module::atom()@}} 476%% </dt> 477%% <dd>Specifies a callback module to be used for formatting. The 478%% module must export a function `module(Doc, Options)'. The 479%% default callback module is {@link edoc_layout}; see {@link 480%% edoc_layout:module/2} for layout-specific options. 481%% </dd> 482%% </dl> 483%% 484%% @see layout/1 485%% @see run/2 486%% @see read/2 487%% @see file/2 488 489%% INHERIT-OPTIONS: edoc_lib:run_layout/2 490 491layout(Doc, Opts) -> 492 F = fun (M) -> 493 M:module(Doc, Opts) 494 end, 495 edoc_lib:run_layout(F, Opts). 496 497 498%% @spec (File) -> [comment()] 499%% @type comment() = {Line, Column, Indentation, Text} 500%% where 501%% Line = integer(), 502%% Column = integer(), 503%% Indentation = integer(), 504%% Text = [string()] 505%% @equiv read_comments(File, []) 506 507read_comments(File) -> 508 read_comments(File, []). 509 510%% @spec read_comments(File::filename(), Options::proplist()) -> 511%% [comment()] 512%% 513%% @doc Extracts comments from an Erlang source code file. See the 514%% module {@link //syntax_tools/erl_comment_scan} for details on the 515%% representation of comments. Currently, no options are avaliable. 516 517read_comments(File, _Opts) -> 518 erl_comment_scan:file(File). 519 520 521%% @spec (File) -> [syntaxTree()] 522%% @equiv read_source(File, []) 523 524read_source(Name) -> 525 read_source(Name, []). 526 527%% @spec read_source(File::filename(), Options::proplist()) -> 528%% [syntaxTree()] 529%% 530%% @type syntaxTree() = //syntax_tools/erl_syntax:syntaxTree() 531%% 532%% @doc Reads an Erlang source file and returns the list of "source code 533%% form" syntax trees. 534%% 535%% Options: 536%% <dl> 537%% <dt>{@type {preprocess, boolean()@}} 538%% </dt> 539%% <dd>If the value is `true', the source file will be read via the 540%% Erlang preprocessor (`epp'). The default value is `false'. 541%% `no_preprocess' is an alias for `{preprocess, false}'. 542%% 543%% Normally, preprocessing is not necessary for EDoc to work, but 544%% if a file contains too exotic definitions or uses of macros, it 545%% will not be possible to read it without preprocessing. <em>Note: 546%% comments in included files will not be available to EDoc, even 547%% with this option enabled.</em> 548%% </dd> 549%% <dt>{@type {includes, Path::[string()]@}} 550%% </dt> 551%% <dd>Specifies a list of directory names to be searched for include 552%% files, if the `preprocess' option is turned on. Also used with 553%% the `@headerfile' tag. The default value is the empty list. The 554%% directory of the source file is always automatically appended to 555%% the search path. 556%% </dd> 557%% <dt>{@type {macros, [{atom(), term()@}]@}} 558%% </dt> 559%% <dd>Specifies a list of pre-defined Erlang preprocessor (`epp') 560%% macro definitions, used if the `preprocess' option is turned on. 561%% The default value is the empty list.</dd> 562%% <dt>{@type {report_missing_types, boolean()@}} 563%% </dt> 564%% <dd>If the value is `true', warnings are issued for missing types. 565%% The default value is `false'. 566%% `no_report_missing_types' is an alias for 567%% `{report_missing_types, false}'. 568%% </dd> 569%% </dl> 570%% 571%% @see get_doc/2 572%% @see //syntax_tools/erl_syntax 573 574%% NEW-OPTIONS: [no_]preprocess (preprocess -> includes, macros) 575 576read_source(Name, Opts0) -> 577 Opts = expand_opts(Opts0), 578 case read_source_1(Name, Opts) of 579 {ok, Forms} -> 580 check_forms(Forms, Name, Opts), 581 Forms; 582 {error, R} -> 583 edoc_report:error({"error reading file '~ts'.", 584 [edoc_lib:filename(Name)]}), 585 exit({error, R}) 586 end. 587 588read_source_1(Name, Opts) -> 589 case proplists:get_bool(preprocess, Opts) of 590 true -> 591 read_source_2(Name, Opts); 592 false -> 593 epp_dodger:quick_parse_file(Name, Opts ++ [{no_fail, false}]) 594 end. 595 596read_source_2(Name, Opts) -> 597 Includes = proplists:append_values(includes, Opts) 598 ++ [filename:dirname(Name)], 599 Macros = proplists:append_values(macros, Opts), 600 %% epp:parse_file(Name, Includes, Macros). 601 parse_file(Name, Includes, Macros). 602 603%% The code below has been copied from epp.erl. 604%% 605%% Copy the line of the last token to the last token that will be 606%% part of the parse tree. 607%% 608%% The last line is used in edoc_extract:find_type_docs() to determine 609%% if a type declaration is followed by a comment. 610%% <example> 611%% -type t() :: [ 612%% {tag, integer()} 613%% ]. 614%% %% Protocol options. 615%% </example> 616%% The line of the dot token will be copied to the integer token. 617 618parse_file(Name, Includes, Macros) -> 619 case parse_file(utf8, Name, Includes, Macros) of 620 invalid_unicode -> 621 parse_file(latin1, Name, Includes, Macros); 622 Ret -> 623 Ret 624 end. 625 626parse_file(DefEncoding, Name, Includes, Macros) -> 627 Options = [{name, Name}, 628 {includes, Includes}, 629 {macros, Macros}, 630 {default_encoding, DefEncoding}], 631 case epp:open([extra | Options]) of 632 {ok, Epp, Extra} -> 633 try parse_file(Epp) of 634 Forms -> 635 Encoding = proplists:get_value(encoding, Extra), 636 case find_invalid_unicode(Forms) of 637 invalid_unicode when Encoding =/= utf8 -> 638 invalid_unicode; 639 _ -> 640 {ok, Forms} 641 end 642 after _ = epp:close(Epp) 643 end; 644 Error -> 645 Error 646 end. 647 648find_invalid_unicode([H|T]) -> 649 case H of 650 {error,{_Line,file_io_server,invalid_unicode}} -> 651 invalid_unicode; 652 _Other -> 653 find_invalid_unicode(T) 654 end; 655find_invalid_unicode([]) -> none. 656 657parse_file(Epp) -> 658 case scan_and_parse(Epp) of 659 {ok, Form} -> 660 [Form | parse_file(Epp)]; 661 {error, E} -> 662 [{error, E} | parse_file(Epp)]; 663 {eof, Location} -> 664 [{eof, Location}] 665 end. 666 667scan_and_parse(Epp) -> 668 case epp:scan_erl_form(Epp) of 669 {ok, Toks0} -> 670 Toks = fix_last_line(Toks0), 671 case erl_parse:parse_form(Toks) of 672 {ok, Form} -> 673 {ok, Form}; 674 Else -> 675 Else 676 end; 677 Else -> 678 Else 679 end. 680 681fix_last_line(Toks0) -> 682 Toks1 = lists:reverse(Toks0), 683 LastLine = erl_scan:line(hd(Toks1)), 684 fll(Toks1, LastLine, []). 685 686fll([{Category, Anno0, Symbol} | L], LastLine, Ts) -> 687 Anno = erl_anno:set_line(LastLine, Anno0), 688 lists:reverse(L, [{Category, Anno, Symbol} | Ts]); 689fll([T | L], LastLine, Ts) -> 690 fll(L, LastLine, [T | Ts]); 691fll(L, _LastLine, Ts) -> 692 lists:reverse(L, Ts). 693 694check_forms(Fs, Name, Opts) -> 695 Fun = fun (F) -> 696 case erl_syntax:type(F) of 697 error_marker -> 698 case erl_syntax:error_marker_info(F) of 699 {L, M, D} -> 700 edoc_report:error(L, Name, {format_error, M, D}), 701 case proplists:get_bool(preprocess, Opts) of 702 true -> 703 ok; 704 false -> 705 helpful_message(Name) 706 end; 707 Other -> 708 edoc_report:report(Name, "unknown error in " 709 "source code: ~w.", [Other]) 710 end, 711 exit(error); 712 _ -> 713 ok 714 end 715 end, 716 lists:foreach(Fun, Fs). 717 718helpful_message(Name) -> 719 Ms = ["If the error is caused by too exotic macro", 720 "definitions or uses of macros, adding option", 721 "{preprocess, true} can help. See also edoc(3)."], 722 lists:foreach(fun(M) -> edoc_report:report(Name, M, []) end, Ms). 723 724%% @spec get_doc(File::filename()) -> {ModuleName, edoc_module()} 725%% @equiv get_doc(File, []) 726 727get_doc(File) -> 728 get_doc(File, []). 729 730%% @spec get_doc(File::filename(), Options::proplist()) -> 731%% {ModuleName, edoc_module()} 732%% ModuleName = atom() 733%% 734%% @type edoc_module(). The EDoc documentation data for a module, 735%% expressed as an XML document in {@link //xmerl. XMerL} format. See 736%% the file <a href="edoc.dtd">`edoc.dtd'</a> for details. 737%% 738%% @doc Reads a source code file and extracts EDoc documentation data. 739%% Note that without an environment parameter (see {@link get_doc/3}), 740%% hypertext links may not be correct. 741%% 742%% Options: 743%% <dl> 744%% <dt>{@type {def, Macros@}} 745%% </dt> 746%% <dd><ul> 747%% <li>`Macros' = {@type Macro | [Macro]}</li> 748%% <li>`Macro' = {@type {Name::atom(), Text::string()@}}</li> 749%% </ul> 750%% Specifies a set of EDoc macro definitions. See 751%% <a href="overview-summary.html#Macro_expansion">Inline macro expansion</a> 752%% for details. 753%% </dd> 754%% <dt>{@type {hidden, boolean()@}} 755%% </dt> 756%% <dd>If the value is `true', documentation of hidden functions will 757%% also be included. The default value is `false'. 758%% </dd> 759%% <dt>{@type {private, boolean()@}} 760%% </dt> 761%% <dd>If the value is `true', documentation of private functions will 762%% also be included. The default value is `false'. 763%% </dd> 764%% <dt>{@type {todo, boolean()@}} 765%% </dt> 766%% <dd>If the value is `true', To-Do notes written using `@todo' or 767%% `@TODO' tags will be included in the documentation. The default 768%% value is `false'. 769%% </dd> 770%% </dl> 771%% 772%% See {@link read_source/2}, {@link read_comments/2} and {@link 773%% edoc_lib:get_doc_env/3} for further options. 774%% 775%% @see get_doc/3 776%% @see run/2 777%% @see edoc_extract:source/5 778%% @see read/2 779%% @see layout/2 780 781%% INHERIT-OPTIONS: get_doc/3 782%% INHERIT-OPTIONS: edoc_lib:get_doc_env/3 783 784get_doc(File, Opts) -> 785 Env = edoc_lib:get_doc_env(Opts), 786 get_doc(File, Env, Opts). 787 788%% @spec get_doc(File::filename(), Env::edoc_lib:edoc_env(), 789%% Options::proplist()) -> {ModuleName, edoc_module()} 790%% ModuleName = atom() 791%% 792%% @doc Like {@link get_doc/2}, but for a given environment 793%% parameter. `Env' is an environment created by {@link 794%% edoc_lib:get_doc_env/3}. 795 796%% INHERIT-OPTIONS: read_source/2, read_comments/2, edoc_extract:source/5 797%% DEFER-OPTIONS: get_doc/2 798 799get_doc(File, Env, Opts) -> 800 edoc_extract:source(File, Env, Opts). 801