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 URI:s pointing to directories that contain 263%% EDoc-generated documentation. URI without a `scheme://' part are 264%% taken as relative to `file://'. (Note that such paths must use 265%% `/' as separator, regardless of the host operating system.) 266%% </dd> 267%% <dt>{@type {doclet, Module::atom()@}} 268%% </dt> 269%% <dd>Specifies a callback module to be used for creating the 270%% documentation. The module must export a function `run(Cmd, Ctxt)'. 271%% The default doclet module is {@link edoc_doclet}; see {@link 272%% edoc_doclet:run/2} for doclet-specific options. 273%% </dd> 274%% <dt>{@type {file_suffix, string()@}} 275%% </dt> 276%% <dd>Specifies the suffix used for output files. The default value is 277%% `".html"'. Note that this also affects generated references. 278%% </dd> 279%% <dt>{@type {new, boolean()@}} 280%% </dt> 281%% <dd>If the value is `true', any existing `edoc-info' file in the 282%% target directory will be ignored and overwritten. The default 283%% value is `false'. 284%% </dd> 285%% <dt>{@type {source_path, [filename()]@}} 286%% </dt> 287%% <dd>Specifies a list of file system paths used to locate the source 288%% code for packages. 289%% </dd> 290%% <dt>{@type {source_suffix, string()@}} 291%% </dt> 292%% <dd>Specifies the expected suffix of input files. The default 293%% value is `".erl"'. 294%% </dd> 295%% <dt>{@type {subpackages, boolean()@}} 296%% </dt> 297%% <dd>If the value is `true', all subpackages of specified packages 298%% will also be included in the documentation. The default value is 299%% `false'. `no_subpackages' is an alias for `{subpackages, 300%% false}'. 301%% 302%% Subpackage source files are found by recursively searching 303%% for source code files in subdirectories of the known source code 304%% root directories. (Also see the `source_path' option.) Directory 305%% names must begin with a lowercase letter and contain only 306%% alphanumeric characters and underscore, or they will be ignored. 307%% (For example, a subdirectory named `test-files' will not be 308%% searched.) 309%% </dd> 310%% </dl> 311%% 312%% @see files/2 313%% @see application/2 314 315%% NEW-OPTIONS: source_path, application 316%% INHERIT-OPTIONS: init_context/1 317%% INHERIT-OPTIONS: expand_sources/2 318%% INHERIT-OPTIONS: target_dir_info/5 319%% INHERIT-OPTIONS: edoc_lib:find_sources/2 320%% INHERIT-OPTIONS: edoc_lib:run_doclet/2 321%% INHERIT-OPTIONS: edoc_lib:get_doc_env/3 322 323run(Files, Opts0) -> 324 Opts = expand_opts(Opts0), 325 Ctxt = init_context(Opts), 326 Dir = Ctxt#context.dir, 327 Path = proplists:append_values(source_path, Opts), 328 Ss = sources(Path, Opts), 329 {Ss1, Ms} = expand_sources(expand_files(Files) ++ Ss, Opts), 330 App = proplists:get_value(application, Opts, ?NO_APP), 331 {App1, Ms1} = target_dir_info(Dir, App, Ms, Opts), 332 Ms2 = edoc_lib:unique(lists:sort(Ms1)), 333 Env = edoc_lib:get_doc_env(App1, Ms2, Opts), 334 Ctxt1 = Ctxt#context{env = Env}, 335 Cmd = #doclet_gen{sources = Ss1, 336 app = App1, 337 modules = Ms2 338 }, 339 F = fun (M) -> 340 M:run(Cmd, Ctxt1) 341 end, 342 edoc_lib:run_doclet(F, Opts). 343 344expand_opts(Opts0) -> 345 proplists:substitute_negations(opt_negations(), 346 Opts0 ++ opt_defaults()). 347 348%% NEW-OPTIONS: dir 349%% DEFER-OPTIONS: run/2 350 351init_context(Opts) -> 352 #context{dir = proplists:get_value(dir, Opts, ?CURRENT_DIR), 353 opts = Opts 354 }. 355 356%% INHERIT-OPTIONS: edoc_lib:find_sources/2 357 358sources(Path, Opts) -> 359 edoc_lib:find_sources(Path, Opts). 360 361%% Expand user-specified sets of files. 362 363expand_files([F | Fs]) -> 364 [{filename:basename(F), filename:dirname(F)} | 365 expand_files(Fs)]; 366expand_files([]) -> 367 []. 368 369%% Create the (assumed) full module names. Keep only the first source 370%% for each module, but preserve the order of the list. 371 372%% NEW-OPTIONS: source_suffix 373%% DEFER-OPTIONS: run/2 374 375expand_sources(Ss, Opts) -> 376 Suffix = proplists:get_value(source_suffix, Opts, 377 ?DEFAULT_SOURCE_SUFFIX), 378 Ss1 = [{F,D} || {F,D} <- Ss], 379 expand_sources(Ss1, Suffix, sets:new(), [], []). 380 381expand_sources([{F, D} | Fs], Suffix, S, As, Ms) -> 382 M = list_to_atom(filename:rootname(F, Suffix)), 383 case sets:is_element(M, S) of 384 true -> 385 expand_sources(Fs, Suffix, S, As, Ms); 386 false -> 387 S1 = sets:add_element(M, S), 388 expand_sources(Fs, Suffix, S1, [{M, F, D} | As], 389 [M | Ms]) 390 end; 391expand_sources([], _Suffix, _S, As, Ms) -> 392 {lists:reverse(As), lists:reverse(Ms)}. 393 394%% NEW-OPTIONS: new 395 396target_dir_info(Dir, App, Ms, Opts) -> 397 case proplists:get_bool(new, Opts) of 398 true -> 399 {App, Ms}; 400 false -> 401 {App1, Ms1} = edoc_lib:read_info_file(Dir), 402 {if App == ?NO_APP -> App1; 403 true -> App 404 end, 405 Ms ++ Ms1} 406 end. 407 408 409%% @hidden Not official yet 410 411toc(Dir) -> 412 toc(Dir, []). 413 414%% @equiv toc(Dir, Paths, []) 415%% @hidden Not official yet 416 417%% NEW-OPTIONS: doc_path 418 419toc(Dir, Opts) -> 420 Paths = proplists:append_values(doc_path, Opts) 421 ++ edoc_lib:find_doc_dirs(), 422 toc(Dir, Paths, Opts). 423 424%% @doc Create a meta-level table of contents. 425%% @hidden Not official yet 426 427%% INHERIT-OPTIONS: init_context/1 428%% INHERIT-OPTIONS: edoc_lib:run_doclet/2 429%% INHERIT-OPTIONS: edoc_lib:get_doc_env/3 430 431toc(Dir, Paths, Opts0) -> 432 Opts = expand_opts(Opts0 ++ [{dir, Dir}]), 433 Ctxt = init_context(Opts), 434 Env = edoc_lib:get_doc_env('', [], Opts), 435 Ctxt1 = Ctxt#context{env = Env}, 436 F = fun (M) -> 437 M:run(#doclet_toc{paths=Paths}, Ctxt1) 438 end, 439 edoc_lib:run_doclet(F, Opts). 440 441 442%% @spec read(File::filename()) -> string() 443%% @equiv read(File, []) 444 445read(File) -> 446 read(File, []). 447 448%% @spec read(File::filename(), Options::proplist()) -> string() 449%% 450%% @doc Reads and processes a source file and returns the resulting 451%% EDoc-text as a string. See {@link get_doc/2} and {@link layout/2} for 452%% options. 453%% 454%% @see file/2 455 456%% INHERIT-OPTIONS: get_doc/2, layout/2 457 458read(File, Opts) -> 459 {_ModuleName, Doc} = get_doc(File, Opts), 460 layout(Doc, Opts). 461 462 463%% @spec layout(Doc::edoc_module()) -> string() 464%% @equiv layout(Doc, []) 465 466layout(Doc) -> 467 layout(Doc, []). 468 469%% @spec layout(Doc::edoc_module(), Options::proplist()) -> string() 470%% 471%% @doc Transforms EDoc module documentation data to text. The default 472%% layout creates an HTML document. 473%% 474%% Options: 475%% <dl> 476%% <dt>{@type {layout, Module::atom()@}} 477%% </dt> 478%% <dd>Specifies a callback module to be used for formatting. The 479%% module must export a function `module(Doc, Options)'. The 480%% default callback module is {@link edoc_layout}; see {@link 481%% edoc_layout:module/2} for layout-specific options. 482%% </dd> 483%% </dl> 484%% 485%% @see layout/1 486%% @see run/2 487%% @see read/2 488%% @see file/2 489 490%% INHERIT-OPTIONS: edoc_lib:run_layout/2 491 492layout(Doc, Opts) -> 493 F = fun (M) -> 494 M:module(Doc, Opts) 495 end, 496 edoc_lib:run_layout(F, Opts). 497 498 499%% @spec (File) -> [comment()] 500%% @type comment() = {Line, Column, Indentation, Text} 501%% where 502%% Line = integer(), 503%% Column = integer(), 504%% Indentation = integer(), 505%% Text = [string()] 506%% @equiv read_comments(File, []) 507 508read_comments(File) -> 509 read_comments(File, []). 510 511%% @spec read_comments(File::filename(), Options::proplist()) -> 512%% [comment()] 513%% 514%% @doc Extracts comments from an Erlang source code file. See the 515%% module {@link //syntax_tools/erl_comment_scan} for details on the 516%% representation of comments. Currently, no options are avaliable. 517 518read_comments(File, _Opts) -> 519 erl_comment_scan:file(File). 520 521 522%% @spec (File) -> [syntaxTree()] 523%% @equiv read_source(File, []) 524 525read_source(Name) -> 526 read_source(Name, []). 527 528%% @spec read_source(File::filename(), Options::proplist()) -> 529%% [syntaxTree()] 530%% 531%% @type syntaxTree() = //syntax_tools/erl_syntax:syntaxTree() 532%% 533%% @doc Reads an Erlang source file and returns the list of "source code 534%% form" syntax trees. 535%% 536%% Options: 537%% <dl> 538%% <dt>{@type {preprocess, boolean()@}} 539%% </dt> 540%% <dd>If the value is `true', the source file will be read via the 541%% Erlang preprocessor (`epp'). The default value is `false'. 542%% `no_preprocess' is an alias for `{preprocess, false}'. 543%% 544%% Normally, preprocessing is not necessary for EDoc to work, but 545%% if a file contains too exotic definitions or uses of macros, it 546%% will not be possible to read it without preprocessing. <em>Note: 547%% comments in included files will not be available to EDoc, even 548%% with this option enabled.</em> 549%% </dd> 550%% <dt>{@type {includes, Path::[string()]@}} 551%% </dt> 552%% <dd>Specifies a list of directory names to be searched for include 553%% files, if the `preprocess' option is turned on. Also used with 554%% the `@headerfile' tag. The default value is the empty list. The 555%% directory of the source file is always automatically appended to 556%% the search path. 557%% </dd> 558%% <dt>{@type {macros, [{atom(), term()@}]@}} 559%% </dt> 560%% <dd>Specifies a list of pre-defined Erlang preprocessor (`epp') 561%% macro definitions, used if the `preprocess' option is turned on. 562%% The default value is the empty list.</dd> 563%% <dt>{@type {report_missing_types, boolean()@}} 564%% </dt> 565%% <dd>If the value is `true', warnings are issued for missing types. 566%% The default value is `false'. 567%% `no_report_missing_types' is an alias for 568%% `{report_missing_types, false}'. 569%% </dd> 570%% </dl> 571%% 572%% @see get_doc/2 573%% @see //syntax_tools/erl_syntax 574 575%% NEW-OPTIONS: [no_]preprocess (preprocess -> includes, macros) 576 577read_source(Name, Opts0) -> 578 Opts = expand_opts(Opts0), 579 case read_source_1(Name, Opts) of 580 {ok, Forms} -> 581 check_forms(Forms, Name, Opts), 582 Forms; 583 {error, R} -> 584 edoc_report:error({"error reading file '~ts'.", 585 [edoc_lib:filename(Name)]}), 586 exit({error, R}) 587 end. 588 589read_source_1(Name, Opts) -> 590 case proplists:get_bool(preprocess, Opts) of 591 true -> 592 read_source_2(Name, Opts); 593 false -> 594 epp_dodger:quick_parse_file(Name, Opts ++ [{no_fail, false}]) 595 end. 596 597read_source_2(Name, Opts) -> 598 Includes = proplists:append_values(includes, Opts) 599 ++ [filename:dirname(Name)], 600 Macros = proplists:append_values(macros, Opts), 601 %% epp:parse_file(Name, Includes, Macros). 602 parse_file(Name, Includes, Macros). 603 604%% The code below has been copied from epp.erl. 605%% 606%% Copy the line of the last token to the last token that will be 607%% part of the parse tree. 608%% 609%% The last line is used in edoc_extract:find_type_docs() to determine 610%% if a type declaration is followed by a comment. 611%% <example> 612%% -type t() :: [ 613%% {tag, integer()} 614%% ]. 615%% %% Protocol options. 616%% </example> 617%% The line of the dot token will be copied to the integer token. 618 619parse_file(Name, Includes, Macros) -> 620 case parse_file(utf8, Name, Includes, Macros) of 621 invalid_unicode -> 622 parse_file(latin1, Name, Includes, Macros); 623 Ret -> 624 Ret 625 end. 626 627parse_file(DefEncoding, Name, Includes, Macros) -> 628 Options = [{name, Name}, 629 {includes, Includes}, 630 {macros, Macros}, 631 {default_encoding, DefEncoding}], 632 case epp:open([extra | Options]) of 633 {ok, Epp, Extra} -> 634 try parse_file(Epp) of 635 Forms -> 636 Encoding = proplists:get_value(encoding, Extra), 637 case find_invalid_unicode(Forms) of 638 invalid_unicode when Encoding =/= utf8 -> 639 invalid_unicode; 640 _ -> 641 {ok, Forms} 642 end 643 after _ = epp:close(Epp) 644 end; 645 Error -> 646 Error 647 end. 648 649find_invalid_unicode([H|T]) -> 650 case H of 651 {error,{_Line,file_io_server,invalid_unicode}} -> 652 invalid_unicode; 653 _Other -> 654 find_invalid_unicode(T) 655 end; 656find_invalid_unicode([]) -> none. 657 658parse_file(Epp) -> 659 case scan_and_parse(Epp) of 660 {ok, Form} -> 661 [Form | parse_file(Epp)]; 662 {error, E} -> 663 [{error, E} | parse_file(Epp)]; 664 {eof, Location} -> 665 [{eof, Location}] 666 end. 667 668scan_and_parse(Epp) -> 669 case epp:scan_erl_form(Epp) of 670 {ok, Toks0} -> 671 Toks = fix_last_line(Toks0), 672 case erl_parse:parse_form(Toks) of 673 {ok, Form} -> 674 {ok, Form}; 675 Else -> 676 Else 677 end; 678 Else -> 679 Else 680 end. 681 682fix_last_line(Toks0) -> 683 Toks1 = lists:reverse(Toks0), 684 LastLine = erl_scan:line(hd(Toks1)), 685 fll(Toks1, LastLine, []). 686 687fll([{Category, Anno0, Symbol} | L], LastLine, Ts) -> 688 Anno = erl_anno:set_line(LastLine, Anno0), 689 lists:reverse(L, [{Category, Anno, Symbol} | Ts]); 690fll([T | L], LastLine, Ts) -> 691 fll(L, LastLine, [T | Ts]); 692fll(L, _LastLine, Ts) -> 693 lists:reverse(L, Ts). 694 695check_forms(Fs, Name, Opts) -> 696 Fun = fun (F) -> 697 case erl_syntax:type(F) of 698 error_marker -> 699 case erl_syntax:error_marker_info(F) of 700 {L, M, D} -> 701 edoc_report:error(L, Name, {format_error, M, D}), 702 case proplists:get_bool(preprocess, Opts) of 703 true -> 704 ok; 705 false -> 706 helpful_message(Name) 707 end; 708 Other -> 709 edoc_report:report(Name, "unknown error in " 710 "source code: ~w.", [Other]) 711 end, 712 exit(error); 713 _ -> 714 ok 715 end 716 end, 717 lists:foreach(Fun, Fs). 718 719helpful_message(Name) -> 720 Ms = ["If the error is caused by too exotic macro", 721 "definitions or uses of macros, adding option", 722 "{preprocess, true} can help. See also edoc(3)."], 723 lists:foreach(fun(M) -> edoc_report:report(Name, M, []) end, Ms). 724 725%% @spec get_doc(File::filename()) -> {ModuleName, edoc_module()} 726%% @equiv get_doc(File, []) 727 728get_doc(File) -> 729 get_doc(File, []). 730 731%% @spec get_doc(File::filename(), Options::proplist()) -> 732%% {ModuleName, edoc_module()} 733%% ModuleName = atom() 734%% 735%% @type edoc_module(). The EDoc documentation data for a module, 736%% expressed as an XML document in {@link //xmerl. XMerL} format. See 737%% the file <a href="edoc.dtd">`edoc.dtd'</a> for details. 738%% 739%% @doc Reads a source code file and extracts EDoc documentation data. 740%% Note that without an environment parameter (see {@link get_doc/3}), 741%% hypertext links may not be correct. 742%% 743%% Options: 744%% <dl> 745%% <dt>{@type {def, Macros@}} 746%% </dt> 747%% <dd><ul> 748%% <li>`Macros' = {@type Macro | [Macro]}</li> 749%% <li>`Macro' = {@type {Name::atom(), Text::string()@}}</li> 750%% </ul> 751%% Specifies a set of EDoc macro definitions. See 752%% <a href="overview-summary.html#Macro_expansion">Inline macro expansion</a> 753%% for details. 754%% </dd> 755%% <dt>{@type {hidden, boolean()@}} 756%% </dt> 757%% <dd>If the value is `true', documentation of hidden functions will 758%% also be included. The default value is `false'. 759%% </dd> 760%% <dt>{@type {private, boolean()@}} 761%% </dt> 762%% <dd>If the value is `true', documentation of private functions will 763%% also be included. The default value is `false'. 764%% </dd> 765%% <dt>{@type {todo, boolean()@}} 766%% </dt> 767%% <dd>If the value is `true', To-Do notes written using `@todo' or 768%% `@TODO' tags will be included in the documentation. The default 769%% value is `false'. 770%% </dd> 771%% </dl> 772%% 773%% See {@link read_source/2}, {@link read_comments/2} and {@link 774%% edoc_lib:get_doc_env/3} for further options. 775%% 776%% @see get_doc/3 777%% @see run/2 778%% @see edoc_extract:source/5 779%% @see read/2 780%% @see layout/2 781 782%% INHERIT-OPTIONS: get_doc/3 783%% INHERIT-OPTIONS: edoc_lib:get_doc_env/3 784 785get_doc(File, Opts) -> 786 Env = edoc_lib:get_doc_env(Opts), 787 get_doc(File, Env, Opts). 788 789%% @spec get_doc(File::filename(), Env::edoc_lib:edoc_env(), 790%% Options::proplist()) -> {ModuleName, edoc_module()} 791%% ModuleName = atom() 792%% 793%% @doc Like {@link get_doc/2}, but for a given environment 794%% parameter. `Env' is an environment created by {@link 795%% edoc_lib:get_doc_env/3}. 796 797%% INHERIT-OPTIONS: read_source/2, read_comments/2, edoc_extract:source/5 798%% DEFER-OPTIONS: get_doc/2 799 800get_doc(File, Env, Opts) -> 801 edoc_extract:source(File, Env, Opts). 802