:- compiler_options([ciao_directives]).

:- export   supported_format/1,            supported_format_suffix/2,
	    index_comment/2,               option_comment/2,
	    format_front_matter/19,        format_intro/10,
	    format_module_usage/10, 	   format_predicate_begin/6,
	    format_predicates_begin/4,
	    format_predicate_comment/3,    format_predicate_end/2,
	    format_native_declaration/3,     
	    format_predicates_end/2,
	    format_multiple_usage_header/3,format_usage_header/2,
	    format_head_descriptor/5,      format_other_assrt_header/2,
	    format_site_begin/4,           format_site_end/2,
	    format_properties_begin/2,     format_property/7,
	    format_properties_end/2,       format_description/3,
	    format_other_info/10,           
	    format_includes_and_end_matter/6,
	    format_tabling_declaration/3,
	    verbatimize_string/3,

	    typeindex/5, texinfo_escape_ats_etc/2. 	% for rewrite_command

/* The following are to avoid useinfer messages */
:- export supported_option/1.		



:- import format/3 from format.
:- import member/2 from basics.
:- import display/2, 
	  error_message/2, 
	  list_concat/2, 
	  optional_message/2, 
	  xsbdoc_warning/1
	from ciaoaux.
:- import (data)/1 from ciaoaux.

:- import current_infixop/4, current_postfixop/3, current_prefixop/3
	from xsb_ciao.

:- import concat_atom/2 from string.
:- import write_term/3 from write_term.
:- import version_descriptor/1, stringcommand/1 from comments.
:- import rewrite_command/4 from rewrite_command.
x
%% ---------------------------------------------------------------------------
%% Intro
%% ---------------------------------------------------------------------------

:- comment(title,"Low level documentation format definitions").

:- comment(author,"Manuel Hermenegildo").

:- comment(module," 

   This module defines the interface for the auxiliary predicates
   needed by the automatic documentation generation library: these
   predicates determine the precise format in which the output is
   written. 

   Also, this module includes definitions of these predicates for a
   few formats. The main output format supported is @tt{texinfo} (see
   The GNU Texinfo Documentation System manual for more info), from
   which printed manuals and several other printing and on-line
   formats can be easily generated automatically (including info,
   html, etc.). There is also some limited support for direct output
   in unix @tt{man} format and direct @tt{html} (but note that html
   can also be generated in a better way by first generating texinfo
   and then using one of the available converters). For texinfo, the
   documentation for a module is a texinfo chapter, suitable for
   inclusion in a wrapper ``main'' document file.  A simple example of
   the use of this library for generating a texinfo reference manual
   (including a driver script, useful Makefiles, etc.) is included
   with the library source code. Other examples can be found in the
   CIAO documentation directory (i.e., the CIAO manuals themselves).

").

%% ---------------------------------------------------------------------------
/*
:- regtype supported_format(Format) 

	# "@tt{Format} is a supported typesetting format.".
*/
%% ---------------------------------------------------------------------------

supported_format(texinfo).
supported_format(html).
supported_format(ascii).
%supported_format(man).

%% ---------------------------------------------------------------------------
/*
:- pred supported_format_suffix(Format,Suffix) 

	=> supported_format * atom

        # "@var{Format} is a format for which formatting code is
           available.  @var{Suffix} is the suffix that should be used
           for the generated files. @cindex{supported documentation
           formats}".
*/
%% ---------------------------------------------------------------------------

supported_format_suffix(texinfo,texic).
supported_format_suffix(html,html).
supported_format_suffix(man,manl).
supported_format_suffix(ascii,txt).

%% ---------------------------------------------------------------------------
:- pred index_comment(Index,Text) 

	=> atom * string

        # "@var{Type} is a type of index which is
          supported. @var{Text} describes the index contents.".
%% ---------------------------------------------------------------------------

index_comment(Type,Text) :-
	typeindex(Type,_,_,Text,_).

%% ---------------------------------------------------------------------------
:- prop supported_option(Option) 

	# "@tt{Option} is a supported documentation option.".
%% ---------------------------------------------------------------------------

%% not recognized as a type :-(
supported_option(X) :- 
	option_comment(X,_).

%% ---------------------------------------------------------------------------
:- pred option_comment(Option,Text) 

	=> supported_option * string

        # "@var{Option} is a documentation option which is
          supported. @var{Text} describes the effect of selecting that
          option. Currently supported options are:

@begin{verbatim}
@includedef{option_comment/2}          
@end{verbatim}
          ".
%% ---------------------------------------------------------------------------

option_comment('-v',           'Verbose output (good for debugging).        ').
option_comment('-noauthors',   'Do not include author names.                ').
option_comment('-shorttoc',    'Produce shorter table of contents (no entries
                                for individual defs of preds, props, etc.).').
option_comment('-norefs',      'Do not include a ''References'' appendix.     ').

option_comment('-nobugs',      'Do not include information on bugs.         ').
option_comment('-noversion',   'Do not include version information.         ').
option_comment('-nochangelog', 'Do not include change log.                  ').
option_comment('-nopatches',   'Do not include comments for patches.        ').
option_comment('-literalprops','Do not use text to document properties.     ').
option_comment('-nopropnames', 'Do not include property names in prop text. ').
option_comment('-noundefined', 'Do not signal undefined properties in text. ').
option_comment('-nopropsepln', 'Do not put each property in a separate line.').

option_comment('-nobullet',    'Do not generate initial bullet index        
                                (.htmlbullet) with .htmlindex file. Select if
                                only one manual will be installed in DOCDIR.').
option_comment('-nosysmods',   'Do not include system modules in list of 
                                libraries used.').
%option_comment('-noisoline',   'Do not include *textual* description that a 
%                                given usage conforms to the ISO standard.').
option_comment('-propmods',    'Include module name to which props belong.').
option_comment('-onesided',    'For printing on one side (default is two).').

%% ---------------------------------------------------------------------------
:- pred typeindex(Type,Index,IType,Name,Comment) 

	=> atom * string * string * string * string

        # "@var{Index} is the index in which objects of type
           @var{Type} go. @var{Name} is the title of the index in the
           documentation. @var{IType} is the type of index; an empty
           string means normal. code@var{Comment} is a comment to
           include before the index.".
%% ---------------------------------------------------------------------------

%%%% Should not be empty...?
:- data(typeindex/5).

   typeindex(pred,   "pdindex","code",'Predicate Definition Index','').
   typeindex(op,     "opindex","code",'Operator Definition Index',        '').
   typeindex(concept,"coindex",""    ,'Concept Definition Index',         '').
%% Some versions of makeinfo get confused by this one (core dump!)
   typeindex(global, "glindex","code",'Global Index',
'This is a global index containing pointers to places where concepts, 
 predicates, modes, properties, types, applications, etc., are referred to
 in the text of the document. Note that due to limitations of the
 @code{info} format unfortunately only the first reference will appear in
 online versions of the document.').

%   typeindex(lib,    "liindex","code",'Library/Module Definition Index',  '').
%   typeindex(apl,    "apindex","code",'Application Index',                '').
%% typeindex(func,   "fuindex","code",'Function/Method Definition Index', '').
%  typeindex(regtype,"teindex","code",'Regular Type Definition Index',    '').
%  typeindex(modedef,"moindex","code",'Mode Definition Index',            '').
%  typeindex(file,   "fiindex","code",'File/Directory Index',             '').
%   typeindex(prop,   "prindex","code",'Property Definition Index',        '').
%   typeindex(decl,   "deindex","code",'Declaration Definition Index',     '').

concepttype(index).
concepttype(cindex).
concepttype(concept).

%% ---------------------------------------------------------------------------
%% Should really use sourcename, but not really supported until we eliminate 
%% the makefile completely
:- regtype filename(X) # "@var{X} is the name of a file.".

filename(X) :- atom(X).

%% ---------------------------------------------------------------------------
:- comment(
   format_front_matter(Format,ModuleType,MainOrComp,Name,NDName,Version,GVers,
       Title,Authors,Subtitle,Copyright,Summary,Indices,StartPage,PaperType,
       Opts,I,O,OS),

  "This predicate defines the first part of the format of the main
   file of a manual. @var{Format} is the type of output (e.g.,
   texinfo, latex, etc.)  -- different clauses of the predicate can be
   defined for different formats. @var{Name} is the name of the
   application (taken from the name of the input file). @var{NDName}
   is the same, but without @tt{_doc}, if applicable. @var{Version} is
   the version of the first @pred{comment/2} entry which specifies a
   version number (which should be the current version). This is the
   version of the last local change. @var{GVers} is the global
   version.  @var{Title} is the intended title of the application
   (taken from the approriate @pred{comment/2}
   declaration). @var{Authors} is a (possibly empty) list of author
   names. @var{Subtitle} is a (possibly empty) list of subtitle (e.g.,
   address, explanation) lines.  @var{Copyright} is the copyright text
   (taken from the appropriate @pred{comment/2} declaration).
   @var{Summary} is a brief summary of the contents of the manual
   (taken from the appropriate @pred{comment/2}
   declaration). @var{Indices} is a list of index names (the indices
   to be generated). @var{StartPage} is the page number of the first
   page of the manual. @var{I} and @var{O} are the names of the input
   and output files being processed (which can be used for example to
   put a comment in the generated file saying that the file has been
   generated automatically from these files and therefore should
   probably not be edited by hand).  @var{OS} is the output stream to
   which writes should be made (normally points to the output
   file).").

:- pred format_front_matter(Format,ModuleType,MainOrComp,Name,NDName,Version,
                            GVers,Title,Authors,Subtitle,Copyright,Summary,
			    Indices,StartPage,PaperType,Opts,I,O,OS)

        : (Format=texinfo, atom(Name), atom(NDName), 
           version_descriptor(Version), string(Title), list(Authors,string),
	   list(Subtitle,string), string(Copyright), string(Summary), 
           list(Indices,atom), int(StartPage), atom(PaperType), 
	   list(Opts,supported_option), 
	   filename(I), filename(O), stream(OS))

        # "A texinfo main file is generated. @var{Name} is used as the
           name of the file. @var{Title} is used as the title of the
           document. The @var{Version}, @var{Authors}, and the
           @var{Subtitle} will go in the title page. @var{Copyright}
           goes in the back of the title page.".
%% ---------------------------------------------------------------------------

format_header(OS,IName,INDName,ITitle,Title,Indices,Ifile,Ofile,
							PaperType,Opts):- 
	optional_message('Generating document cover...',Opts),
	texinfo_escape_ats_etc_all_atoms(IName,Name),
	texinfo_escape_ats_etc_all_atoms(INDName,NDName),
	(  ITitle = []
	-> atom_codes(NDName,NDNameS),
	   list_concat([ NDNameS, " Reference Manual" ], Title)
	;  Title = ITitle ),
	% Texinfo headers and indices
        writeln(OS,'\raggedbottom '),
        writeln(OS,'\input texinfo @c -*- texinfo -*- '),
 	writeln(OS,'@c ------------------------------------------------'),
 	format(OS,"@c WARNING: Do not edit this file (~w)~n"      ,[Ofile]),
 	writeln(OS,'@c It has been generated automatically from file:  '),
 	format(OS,"@c ~w~n"                                       ,[Ifile]),
 	writeln(OS,'@c ------------------------------------------------'),
	writeln(OS,'@c %**start of header     '),
	format(OS,"@setfilename ~w           ~n",[Name]),
	format(OS,"@settitle ~s              ~n",[Title]),
	writeln(OS,'@c @paragraphindent 0     '),
	(  member('-twosided',Opts) 
	-> writeln(OS,'@setchapternewpage odd ')
	;  writeln(OS,'@setchapternewpage on  ')),
	writeln(OS,'@c @footnotestyle separate'),
	
	findall(_, ( typeindex(IdxName,Index,IType,_ITitle,_IComment),
	             (member(IdxName,Indices); Indices=[all]),
	             list_concat([ IndexId, "index" ],Index),
		     format(OS,"@def~sindex ~s~n",[IType,IndexId]) ),
		_),

	writeln(OS,'@iftex                    '),
	writeln(OS,'@c @smallbook             '),
	format(OS,"@~w                       ~n",[PaperType]),
	writeln(OS,'@tolerance 10000          '),
	writeln(OS,'@hbadness 10000           '),
	writeln(OS,'@end iftex                '),
	writeln(OS,'@c %**end of header       '),
	writeln(OS,'                       ').

format_title_page(OS,Title,Subtitle,Authors,GVers,Copyright,StartPage):- 
	%% Title page
	writeln(OS,' '),
	writeln(OS,'@titlepage            '),
	format(OS,"@title ~s                 ~n",[Title]),
	writeln(OS,'@c @font@authorrm=cmbx10 scaled @magstep2'),

	format_lines(Subtitle,"subtitle",OS),

	format_version(GVers, "@subtitle Version", OS),
	writeln(OS,' '),

	(  Authors = []
	-> format(OS,"@author ~n",[]) % Nicer front pg than if no auth command
	;  format_lines(Authors,"author",OS) ),

	%% Copyright page
	writeln(OS,'@c Copyright page         '),
	writeln(OS,'@page                     '),
	writeln(OS,'@vskip 0pt plus 1filll    '),
	format(OS,"~s                        ~n",[Copyright]),
	writeln(OS,'@end titlepage            '),
	writeln(OS,'                          '),
	writeln(OS,'@iftex                    '),
	format(OS,"@pageno ~w                ~n",[StartPage]),
	writeln(OS,'@end iftex                '),
	writeln(OS,'                     '),
	writeln(OS,'@ifinfo                   '),
	format(OS,"@node Top, ~s,(dir),(dir) ~n",[Title]),
	format(OS,"@top ~s                   ~n~n",[Title]).

format_front_matter(texinfo,_FileType,main(_),IName,INDName,_Version,GVers,
                    ITitle,Authors,Subtitle,Copyright,Summary,Indices,
                    StartPage,PaperType,Opts,Ifile,Ofile,OS) :-
        !,
	format_header(OS,IName,INDName,ITitle,Title,Indices,Ifile,Ofile,
						PaperType,Opts),
	
	%% These are the Summary and Copyright which appear as headers
	%% in the info file, but are not seen otherwise
	writeln(OS,'                       '),
	writeln(OS,'@ifinfo                '),

	format(OS,"~s                        ~n",[Summary]),

	format_version(GVers, 
               "~n@sp 1~nThis documentation corresponds to version", OS),
	(  GVers \== []
	-> writeln(OS,'.')
	;  true ),
	writeln(OS,' '),
	format(OS,"~s                        ~n",[Copyright]),
	writeln(OS,'@end ifinfo        '),

	format_title_page(OS,Title,Authors,Subtitle,GVers,Copyright,StartPage),
	writeln(OS,'@end ifinfo               '),writeln(OS,' ').

format_front_matter(texinfo,FileType,component,_IName,INDName,Version,GVers,
                    ITitle,Authors,_Subtitle,_Copyright,_Summary,_Indices,
		    _StartPage,_PaperType,Opts,I,O,OS) :-
	optional_message('Generating chapter heading...',Opts),
	texinfo_escape_ats_etc_all_atoms(INDName,NDName),
	(  ITitle = []
	-> atom_codes(NDName,NTitle),
	   (  FileType = part
	      -> NTitle = Title
	      ;  list_concat([ NTitle, " (library)"     ], Title) )
	;  Title = ITitle ),

	(  FileType = part
	-> format(OS,"~n~n@node ~s, next,  previous,  up~n",
                     [[0'*,0'*,0'*,0' |Title]]),
 	   writeln(OS,'@comment node-name, next,  previous,  up'),
           format_texinfo_section_no_node(0,Title,OS),
	   writeln(OS,'@iftex~n@vfill~n@cartouche~n@sp~n@ ~n@end iftex')
	;  format_texinfo_section(1,Title,OS) ),

/* TLS: Not supporting library indices 
	(  FileType \== part
	   TI = lib,
	   (  ( member(TI,Indices);Indices=[all] ),
	        typeindex(TI,Index,_,_,_)
	   -> format(OS,"@~s ~w~n",[Index,NDName])
	   ;  true )
	; true ),
*/
 	writeln(OS,'@c -------------------------------------------------'),
 	format(OS,"@c WARNING: Do not edit this file (~w)~n",[O]),
 	writeln(OS,'@c It has been generated automatically from file:  '),
 	format(OS,"@c ~w~n"                                              ,[I]),
	writeln(OS,'@c -------------------------------------------------'),
	
        (  Authors = []
	-> true
	;  format(OS,"~n@strong{Author(s):} ",[]),
	   format_list_commas_period(Authors,OS) ),

	format_version(GVers,   "~n@strong{Version:}", OS),
	format(OS, "~n", []),
	( Version == GVers
	-> true
	;  format_version(Version, "~n@strong{Version of last change:}", OS),
	   writeln(OS, ' ') ).

format_version([], _, _) :-
	!.
format_version(Version, Prefix, OS) :-
	( Version = version(Ver*Sub+0,Date) 
	; Version = version(Ver*Sub+0,Date,[]) ),
	!,
	list_concat([ Prefix," ~w.~w (~w)" ],Format),
	format(OS,Format,[Ver,Sub,Date]).
format_version(version(Ver*Sub+0,Date,H:M*S+Z), Prefix, OS) :-
	!,
	list_concat([ Prefix, " ~w.~w (~w, ~w:~w:~w ~w)" ],Format),
	format(OS,Format,[Ver,Sub,Date,H,M,S,Z]).
format_version(Version, Prefix, OS) :-
	( Version = version(Ver*Sub+Patch,Date) 
	; Version = version(Ver*Sub+Patch,Date,[]) ),
	!,
	list_concat([ Prefix, " ~w.~w#~w (~w)" ],Format),
	format(OS,Format,[Ver,Sub,Patch,Date]).
format_version(version(Ver*Sub+Patch,Date,H:M*S+Z), Prefix, OS) :-
	!,
	list_concat([ Prefix, " ~w.~w#~w (~w, ~w:~w:~w ~w)" ],Format),
	format(OS,Format,[Ver,Sub,Patch,Date,H,M,S,Z]).
format_version(Version,_,_) :-
	xsbdoc_warning(['unrecognized version format: ',Version]).
	

format_lines([],_Command,_OS).
format_lines([Line|Lines],Command,OS) :-
	format(OS,"@~s ~s~n",[Command,Line]),
	format_lines(Lines,Command,OS).

format_list_commas_period([],_OS) :-
	!.
format_list_commas_period([A],OS) :-
	!,
	format(OS,"~s.~n",[A]).
format_list_commas_period([A|As],OS) :-
	format(OS,"~s, ",[A]),
	format_list_commas_period(As,OS).


%% ---------------------------------------------------------------------------

%% ---------------------------------------------------------------------------
:-
   comment(format_intro(Format,FileType,ModuleType,Name,NDName,Summary,Version,
   Comment,OS,IntroOS),"This predicate defines the format of the
   introduction and some auxiliary information. @var{Format} is the
   type of output (e.g., texinfo, latex, etc.). @var{FileType} is the
   type of file (main, component, etc.).  @var{ModuleType} is how the
   module is used (use_module, etc.).  @var{Name} is the
   module/application name.  @var{NDName} is the same, but without
   @tt{_doc}, if applicable.  @var{Summary} is a brief summary of the
   contents of the manual (taken from the appropriate @pred{comment/2}
   declaration, if available). @var{Version} is the version of the
   first @pred{comment/2} entry which specifies a version number
   (which should be the current version).  @var{Comment} is the
   introductory text for the module (taken from the @pred{comment/2}
   declaration, if available).  @var{OS} is the output stream to which
   writes should be made (normally points to the output
   file). @var{IntroOS} is the output stream for the introduction.").

:- pred format_intro(Format,FileType,ModuleType,Name,NDName,Summary,Version,
                     Comment,OS,IntroOS)

        : '='(texinfo) * term * atom * string * string * string * 
          version_descriptor * string * stream * stream

        # "Formats intro stuff: summary, intro, etc.".
%% ---------------------------------------------------------------------------

format_intro(texinfo,main(MainType),_FileType,Name,NDName,Summary,Version,
	              Comment,OS,IntroOS) :-

        (  Version \== [] 
	-> format(OS,"~n@ifinfo~n",[]),
	   format_version(Version, 
	      "~n@sp 1~nThis documentation corresponds to version", OS),
	   format(OS,".~n@end ifinfo~n",[]) 
	;  true ),
	% This unfortunately must be before the Summary.
	writeln(OS,'@c Contents:'),
	writeln(OS,'@c @summarycontents'),
	format(OS,"@contents~n~n",[]),
	( Summary = [] 
	-> true
	;  supported_format_suffix(texinfo,Suff),
	   concat_atom([Name,'summary.',Suff],SummaryName),
	   format_texinfo_components_include([SummaryName],OS),
	   open(SummaryName,write,SummaryOS),
	   format_texinfo_section(0,"Summary",SummaryOS),
	   format(SummaryOS,"~n~s~n",[Summary]),
	   (  Version \== [] 
           -> format(SummaryOS,"~n@ifnotinfo~n",[]),
	      format_version(Version, 
              "~n@sp 1~nThis documentation corresponds to version", SummaryOS),
	      format(SummaryOS,".~n@end ifnotinfo~n",[]) 
	   ;  true ),
	   close(SummaryOS) ),

	supported_format_suffix(texinfo,Suff),
	concat_atom([Name,'intro.',Suff],IntroName),
	format_texinfo_components_include([IntroName],OS),
	open(IntroName,write,IntroOS),
	(  MainType = standalone
	-> atom_codes(NDName,NDNameS),
	   format_texinfo_section(0,NDNameS,IntroOS)
	;  format_texinfo_section(1,"Introduction",IntroOS) ),
	format(IntroOS,"~n~s~n~n",[Comment]).
format_intro(texinfo,component,FileType,_Name,_NDName,_Summary,_Version,
	              Comment,OS,_IntroOS) :-
	format(OS,"~n~s~n~n",Comment),
	(  FileType = part
	-> format(OS,"@iftex~n@sp ~n@end cartouche~n@vfill~n@end iftex~n",[])
	;  true ).


%% ---------------------------------------------------------------------------

:-
   comment(format_includes_and_end_matter(Format,Name,
                                          Components,Indices,Opts,OS),
   "This predicate generates code for including the components of a
   complex document if needed, and produces the final matter of the
   main file. @var{Format} is the type of output (e.g., texinfo,
   latex, etc.) -- different clauses of the predicate can be defined
   for different formats. @var{Name} is the name of the application
   (taken from the name of the input file). If the manual should
   include other files (e.g., as chapters) @var{Components} is
   nonempty and contains the complete names of the component
   files. These files will appear in the manual in the order in which
   they appear in @var{Components}. These files can be written
   manually or generated automatically by @pred{document_module/2} or
   any other means, but must be in a format compatible with
   @var{Format}. @var{Indices} contains the index names (the indices
   to be generated). @var{OS} is the output stream to which writes
   should be made (normally points to the output file).").

:- pred format_includes_and_end_matter(Format,Name,Components,Indices,Opts,OS)

        : '='(texinfo) * filename * list(filename) * list(atom) 
          * list(atom) * stream

        # "The components in @var{Components}, if any, are included as
           chapters. @var{Name} is used as the basename of the index
           component files. If no components, then everything should
           go in-line (including indices).".
%% ---------------------------------------------------------------------------


format_includes_and_end_matter(texinfo,Name,Components,Indices,Opts,OS) :-

	format_texinfo_components_include(Components,OS),
	(  member('-norefs',Opts)
	-> true
	;  supported_format_suffix(texinfo,Suff),
	   format(OS,"~n@c (references)~n@include ~wrefs.~w~n",[Name,Suff]) ),

	findall(_, ( typeindex(IdxName,Index,_IType,ITitle,IComment),
	             (member(IdxName,Indices); Indices=[all]),
		     list_concat([ IndexId, "index" ],Index),
		     format_index(Name,ITitle,IComment,IndexId,OS)),
                _),
	format(OS,"@bye~n~n",[]).


format_texinfo_components_include([],_OS).
format_texinfo_components_include([Component|Components],OS) :-
	format(OS,"@c (component)~n@include ~w~n",[Component]),
	format_texinfo_components_include(Components,OS).


%% Each index goes in a separate file unless no components 
%% (then they go inline) 
format_index(Name,Titleat,Commentat,IndexId,OS) :- 

	atom_codes(Titleat,Title),
	atom_codes(Commentat,Comment),

	atom_codes(Name,NameS),
	supported_format_suffix(texinfo,Suff),
	atom_codes(Suff,SuffS),
	list_concat([NameS,IndexId,"index.",SuffS],FileNameS),
	atom_codes(FileName,FileNameS),
	format(OS,"@c (index)~n@include ~w~n",[FileName]),
	open(FileName,write,IndexOS),
	format(IndexOS,"@node ~s, , , Top~n",[Title]),
	format(IndexOS,"@comment  node-name,  next,  previous,  up~n",[]),
	format(IndexOS,"@unnumbered ~s~n",[Title]),
	format(IndexOS,"~n~s~n~n",[Comment]),
	format(IndexOS,"@printindex ~s~n~n",[IndexId]),
	close(IndexOS).

%% ---------------------------------------------------------------------------
:- comment( format_module_usage(Format,Name,Type,Exports,Mults,
   UMods,IUMods,SMods,Ops,NDecls,NModes,Indices,OS), "This
   predicate defines the format of the usage info for the
   module. @var{Format} is the type of output (e.g., texinfo, latex,
   etc.). @var{Name} is the name of the module. @var{Exports} contains
   the predicates exported by the module (taken from the @pred{export/2}
   declaration). @var{UMods} contains the user modules imported by the
   module. @var{SMods} contains the system modules imported by the
   module.  @var{Ops} contains any exported operator
   definitions.  @var{NModes} contains any new mode
   definitions. @var{Indices} is a list of index names (the indices to
   be generated). @var{OS} is the output stream to which writes should
   be made (normally points to the output file).").

:- pred  format_module_usage(Format,Name,Type,Exports,Mults,
                           UMods,IUMods,SysMods,EngMods,Ops,NDecls,Indices,OS)
 : (Format=texinfo,atom(Name),modtype(Type),list(Exports,predname),
   list(Exports,predname),list(UMods,atom),list(IUMods,atom),list(SysMods,atom),
   list(Ops),list(NDecls,atom),list(NModes,atom),
   list(Indices,atom),stream(OS)) 

# "The module header info is documented as the first section of the
   chapter.".
%% ---------------------------------------------------------------------------

format_module_usage(texinfo,Name,Type,CExports,UMods,SysMods,Ops,NDecls,
		    Indices,OS) :-
	texinfo_escape_ats_etc_all_atoms(Name,EName),
	format_texinfo_section_name(EName,2,"Usage and interface",OS),
	writeln(OS,'@cartouche'),
	writeln(OS,'@itemize @bullet{}'),

	( Type = comment(Comment) -> 
	      format(OS,"~n@item @strong{Library usage:}~n~n",[]),
	      format(OS,"~s~n",[Comment])
            ; true),

	format_exports_for_module(CExports,OS,Indices),
	format_operators_for_module(Ops,OS,Indices),
	format_decls_for_module(NDecls,OS,Indices),
	format_inputs_for_module(UMods,SysMods,OS,Indices).

format_exports_for_module(CExports,OS,Indices):- 
	( CExports = [] -> true
	; nl(OS),writeln(OS,'@item @strong{Exports:}'),
	  writeln(OS,'@itemize @minus'),nl(OS),

% 	  filter_export_by_type(CExports,"PREDICATE",Predicates),
	  handle_export_cases(CExports,'Predicates',Indices,OS),

/*	  filter_export_by_type(CExports,"PROPERTY",Properties),
	  handle_export_cases(Properties,
	                           'Properties',Indices,OS),
*/
	  nl(OS),writeln(OS,'@end itemize'),nl(OS) ).

format_operators_for_module(Ops,OS,Indices):- 
	( Ops = [] -> true
        ; nl(OS),writeln(OS,'@item @strong{New operators defined:}'),nl(OS),
	  format_ops(Ops,Indices,OS) ).

format_decls_for_module(NDecls,OS,Indices):- 
	(NDecls = [] -> true
           ; 
  	     nl(OS),writeln(OS,'@item @strong{Module Level Declarations:}'),
	     nl(OS),
	     format_term_list_commas_period(NDecls,global,Indices,OS) ).

format_inputs_for_module(UMods,SysMods,OS,Indices):- 
	( UMods = [], SysMods = [] -> true
        ; 
	nl(OS),writeln(OS,'@item @strong{Other modules used:}'),
	       writeln(OS,'@itemize @minus'),nl(OS),
	     handle_library_used_cases(UMods,  
	        'Application modules', Indices,OS),
	     handle_library_used_cases(SysMods,
	        'System library modules',Indices,OS),
	  nl(OS),writeln(OS,'@end itemize'),nl(OS) ),
%	format(OS, "@end itemize~n@end cartouche~n",[]).
	writeln(OS,'@end itemize'),writeln(OS,'@end cartouche').


handle_export_cases([],_Type,_Indices,_OS).
handle_export_cases([Exp|Exps],Type,Indices,OS) :- 
	format(OS,"~n@item @emph{~w:}~n~n",[Type]),
	format_term_list_commas_period([Exp|Exps],global,Indices,OS).

handle_library_used_cases([],_Type,_Indices,_OS).
handle_library_used_cases([Lib|Libs],Type,Indices,OS) :- 
	format(OS,"~n@item @emph{~w:}~n~n",[Type]),
	format_term_list_commas_period([Lib|Libs],global,Indices,OS).

format_term_list_commas_period([],_Type,_Indices,_OS) :-
	!.
format_term_list_commas_period([C],Type,Indices,OS) :-
	!,
	write_code_and_ref(C,Type,".\n",Indices,OS).
format_term_list_commas_period([C|Cs],Type,Indices,OS) :-
	write_code_and_ref(C,Type,", ",Indices,OS), 
	format_term_list_commas_period(Cs,Type,Indices,OS).	

write_code_and_ref(C,no_ref,Sep,_Indices,OS) :-
	!,
	texinfo_escape_ats_etc_all_atoms(C,EC),
	%% This is to avoid parenthesis around operators...
	(  EC = F/A
	-> format(OS,"@code{~w/~w}~s",[F,A,Sep])
	;  format(OS,"@code{~w}~s",[EC,Sep]) ).
write_code_and_ref(C,Type,Sep,Indices,OS) :-
	!,
	texinfo_escape_ats_etc_all_atoms(C,EC),
	format_ref(texinfo,Type,EC,Indices,OS),
%% Seems like new versions of texinfo prefer @ etc escaped in indices...
%%	format_ref(texinfo,Type,C,Indices,OS),
	%% This is to avoid parenthesis around operators...
	(  EC = F/A
	-> format(OS,"@code{~w/~w}~s~n",[F,A,Sep])
	;  format(OS,"@code{~w}~s~n",[EC,Sep]) ).

format_ref(texinfo,Type,(F)/A,Indices,OS) :- 
	!,
	(  ( member(Type,Indices); Indices=[all] ),
	   typeindex(Type,Index,_,_,_) 
	-> unescape_ampersands(F,NF),
	   format(OS,"@~s ~w/~w~n",[Index,NF,A])
	;  true ).
format_ref(texinfo,Type,library(C),Indices,OS) :- 
	!,
	(  ( member(Type,Indices); Indices=[all] ),
	   typeindex(Type,Index,_,_,_)
	-> unescape_ampersands(C,NC),
	   format(OS,"@~s ~w~n",[Index,NC])
	;  true ).
format_ref(texinfo,Type,C,Indices,OS) :- 
	!,
	(  ( member(Type,Indices); Indices=[all] ),
	   typeindex(Type,Index,_,_,_)
	-> (  C = F/A
	   -> unescape_ampersands(F,NF),
	      format(OS,"@~s ~w/~w~n",[Index,NF,A])
	   ;  unescape_ampersands(C,NC),
	      format(OS,"@~s ~w~n",[Index,NC]) )
	;  true ).

%% Terrible kludge because of texinfo's very weird treatoment of '&': has 
%% to be escaped in, e.g., deffn, but not in index entries!
unescape_ampersands(T,T) :- 
	var(T),
	!.
unescape_ampersands(T,ET) :- 
	functor(T,F,A),
	unescape_ampersands_atom(F,EF),
	functor(ET,EF,A),
	unescape_ampersands_arg(A,T,ET).

unescape_ampersands_arg(0,_T,_ET) :-
	!.
unescape_ampersands_arg(A,T,ET) :-
	A>0,
	!,
	arg(A,T,TArg),
	unescape_ampersands(TArg,ETArg),
	arg(A,ET,ETArg),
	NA is A-1,
	unescape_ampersands_arg(NA,T,ET).

unescape_ampersands_atom(F,NF) :-
	atom_codes(F,FS),
	unescape_ampersands_str(FS,NFS),
	atom_codes(NF,NFS).

unescape_ampersands_str([],[]).
unescape_ampersands_str([0'@,0'&|R],[0'&|NR]) :-
	!,
	unescape_ampersands_str(R,NR).
unescape_ampersands_str([X|R],[X|NR]) :-
	unescape_ampersands_str(R,NR).
	

format_ops([Op],Indices,OS) :-
	!,
	format_op(Op,".",Indices,OS).
format_ops([Op|Ops],Indices,OS) :-
	format_op(Op,", ",Indices,OS),
	format_ops(Ops,Indices,OS).

format_op(op(Prec,Type,Functor),Sep,Indices,OS) :- 
	texinfo_escape_ats_etc_atom(Functor,EFunctor),
	op_arity(Type,Arity),
	format_ref(texinfo,op,EFunctor/Arity,Indices,OS),
	format_ref(texinfo,global,EFunctor/Arity,Indices,OS),
	format(OS,"@code{~w/~w} [~w,~w]~s~n",[EFunctor,Arity,Prec,Type,Sep]).

op_arity(fy,1).
op_arity(yf,1).
op_arity(fx,1).
op_arity(xf,1).
op_arity(xfx,2).
op_arity(xfy,2).
op_arity(yfx,2).


format_texinfo_section_name(Name,Level,Section,OS) :-
	check_texinfo_section_name_syntax(Section),
	format(OS,"~n~n@node ~s (~w), next,  previous,  up~n",[Section,Name]),
 	format(OS,"@comment node-name, next,  previous,  up~n",[]),
	format_texinfo_section_no_node_name(Name,Level,Section,OS).

format_texinfo_section(Level,Section,OS) :-
	check_texinfo_section_name_syntax(Section),
	format(OS,"~n~n@node ~s, next,  previous,  up~n",[Section]),
 	format(OS,"@comment node-name, next,  previous,  up~n",[]),
	format_texinfo_section_no_node(Level,Section,OS).

format_texinfo_section_no_node_name(Name,0,Section,OS) :-
	format(OS,"@unnumbered ~s (@code{~w})~n",[Section,Name]).
format_texinfo_section_no_node_name(Name,1,Section,OS) :-
	format(OS,"@chapter ~s (@code{~w})~n",[Section,Name]).
format_texinfo_section_no_node_name(Name,2,Section,OS) :-
	format(OS,"@section ~s (@code{~w})~n",[Section,Name]).

format_texinfo_section_no_node(0,Section,OS) :-
	format(OS,"@unnumbered ~s~n",[Section]).
format_texinfo_section_no_node(1,Section,OS) :-
	format(OS,"@chapter ~s~n",[Section]).
format_texinfo_section_no_node(2,Section,OS) :-
	format(OS,"@section ~s~n",[Section]).

:- comment(check_texinfo_section_name_syntax/1,"Issue an error message
   if the section name contains characters that info will not like.").

check_texinfo_section_name_syntax(Section) :-
	check_texinfo_section_name_syntax_(Section,0,Section).

check_texinfo_section_name_syntax_([],_PrevChar,_Section).
check_texinfo_section_name_syntax_([H|T],_PrevChar,Section) :-
	illegal_texinfo_section_name_char(H),
	!,
	error_message(
     "info format does not support character ""~c"" in section names (""~s"")",
	                [H,Section]),
	check_texinfo_section_name_syntax_(T,H,Section).
check_texinfo_section_name_syntax_([H|T],PrevChar,Section) :-
	illegal_texinfo_section_name_repeated_char(H),
	PrevChar == H,
	!,
	error_message(
     "info format does not support chars ""~c~c"" in section names (""~s"")",
	                [H,H,Section]),
	check_texinfo_section_name_syntax_(T,H,Section).
check_texinfo_section_name_syntax_([H|T],_PrevChar,Section) :-
	check_texinfo_section_name_syntax_(T,H,Section).

:- regtype illegal_texinfo_section_name_char/1.

illegal_texinfo_section_name_char(0':).
illegal_texinfo_section_name_char(0',).

:- regtype illegal_texinfo_section_name_repeated_char/1.

illegal_texinfo_section_name_repeated_char(0'-).

%% ---------------------------------------------------------------------------
:- comment(format_predicates_begin(Format,Name,Text,OS),"This
   predicate defines the format of the first part of the documentation
   for a set of predicates. @var{Format} is the type of output (e.g.,
   texinfo, latex, etc.). @var{Name} is the module name.  @var{Text}
   describes which set of predicates is being documented (e.g.,
   exported predicates, imported predicates, etc.).  @var{OS} is the
   output stream to which writes should be made (normally points to
   the output file).").

:- pred format_predicates_begin(Format,Name,Text,OS) 
   : '='(texinfo) * atom * string * stream

# "Predicates will formatted as an itemized list. Corresponds to a
   begin itemize.".
%% ---------------------------------------------------------------------------

format_predicates_begin(texinfo,Name,Text,OS) :-
	format_texinfo_section_name(Name,2,Text,OS).

%% ---------------------------------------------------------------------------
:- comment(format_predicates_end(Format,OS),"This predicate defines
   the format of the last part of the documentation for a set of
   predicates. @var{Format} is the type of output (e.g., texinfo,
   latex, etc.). @var{OS} is the output stream to which writes should
   be made (normally points to the output file).").

:- pred format_predicates_end(Format,OS) : '='(texinfo) * stream

# "Predicates will formatted as an itemized list. Corresponds to an
   end itemize.".
%% ---------------------------------------------------------------------------

format_predicates_end(texinfo,_OS).

%% ---------------------------------------------------------------------------
:-
   comment(format_predicate_begin(Format,Type,Pred,Indices,Opts,OS),"This
   predicate defines the format of the first part of the documentation
   for a predicate (the header). @var{Format} is the type of output
   (e.g., texinfo, latex, etc.). @var{Type} is the type of predicate
   being documented (predicate, property, type, etc.). @var{Pred} is
   the name of the predicate. @var{Indices} is a list of index names
   (the indices to be generated). @var{Opts} are the formatting
   options. @var{OS} is the output stream to which writes should be
   made (normally points to the output file). ").

:- pred format_predicate_begin(Format,Type,Pred,Indices,Opts,OS) 
   : '='(texinfo) * atom * predname * list(atom) * 
     list(supported_option) * stream

# "Each predicate is an item in an itemized list.".
%% ---------------------------------------------------------------------------

format_predicate_begin(texinfo,Type,PN,Indices,Opts,OS) :-
	texinfo_escape_ats_etc_all_atoms(PN,F/A),
	typetext(Type,Text,_Prefix,_Postfix),
	(  member('-shorttoc', Opts)
	-> true
	;  format(OS,"@iftex~n@edef@temp{@noexpand@writetocentry{",[]),
	   format(OS,"@realbackslash unnumbsubsubsecentry{",[]),
	   format(OS,"~w (~w)}}}~n@temp~n@end iftex~n",[F/A,Type]) ),
	(  ( member(Type,Indices); Indices=[all] ),
	   typeindex(Type,Index,_,_,_)
	-> unescape_ampersands(F,NF),
	   format(OS,"@~s ~w/~w ~n",[Index,NF,A])
	;  true ),
	(  ( member(global,Indices); Indices=[all] ),
	   typeindex(global,UIndex,_,_,_)
	-> unescape_ampersands(F,NF),
	   format(OS,"@~s ~w/~w ~n",[UIndex,NF,A])
	;  true ),
	format(OS,"@deffn ~s ~w/~w:~n",[Text,F,A]),
	format(OS,"~n~n",[]).
%%	format(OS,"~n@sp 1~n~n",[]).

:- pred typetext(Type,Text,Prefix,Postfix) 
	: assrt_type * string * string * string
	# "@var{Text} is an appropriate text for the header for
           @var{Type}.  Same for @var{Prefix} and @var{Postfix}".

typetext(tpred,    "TABLED_PREDICATE",   "",    "").
typetext(pred,    "PREDICATE",   "",    "").
typetext(compat,  "PREDICATE",   "",    "").
typetext(calls,   "PREDICATE",   "",    "").
typetext(success, "PREDICATE",   "",    "").
typetext(comp,    "PREDICATE",   "",    "").
%% typetext(func,    "FUNCTION",    "",    "").
typetext(prop,    "PROPERTY",    "",    "").
%typetext(regtype, "REGTYPE",     "",    "").
typetext(decl,    "DECLARATION", ":- ", ".").
%typetext(modedef, "MODE",        "",    "").
%typetext(entry,   "ENTRY POINT", "",    "").
%% This one just for undocumented reexports:
%typetext(udreexp, "(UNDOC_REEXPORT)",     "",    "").
typetext(_,       "UNKNOWN",     "",    "").


%% ---------------------------------------------------------------------------
:- comment(format_predicate_comment(Format,Comment,OS),"This predicate
   defines the format of @var{Comment}, an introductory text for the
   predicate (taken from the @pred{comment/2} declaration, if
   available).  @var{Format} is the type of output (e.g., texinfo,
   latex, etc.). @var{OS} is the output stream to which writes should
   be made (normally points to the output file).").

:- pred format_predicate_comment(Format,Comment,OS) 
	: '='(texinfo) * string * stream

        # "Predicate comments are output as is (in a separate paragraph).".
%% ---------------------------------------------------------------------------

format_predicate_comment(texinfo,Comment,OS) :-
	format(OS,"~n~s~n~n",[Comment]).

%% ---------------------------------------------------------------------------
:- pred format_native_declaration(Format,Decl,OS) 
	: '='(texinfo) * term * stream

	# "This predicate defines the format for documenting
          miscellaneous declarations such as @decl{dynamic/1}.
          @var{Format} is the type of output (e.g., texinfo, latex,
          etc.). @var{Decl} contains the declaration info. @var{OS} is
          the output stream to which writes should be made (normally
          points to the output file). ".
%% ---------------------------------------------------------------------------

format_native_declaration(texinfo,Type,OS) :-
	texinfo_escape_ats_etc_all_atoms(Type,EType),
	format(OS,"~nThe predicate is of type @emph{~w}.~n~n",[EType]).

%% ---------------------------------------------------------------------------

format_tabling_declaration(texinfo,TType,OS) :-
	texinfo_escape_ats_etc_all_atoms(TType,EType),
	format(OS,"~nThe predicate uses @emph{~w} tabling.~n~n",[EType]).

%% ---------------------------------------------------------------------------
:- comment(format_predicate_end(Format,OS),"This predicate defines the
   format of the last part of the documentation for a
   predicate. @var{Format} is the type of output (e.g., texinfo,
   latex, etc.). @var{OS} is the output stream to which writes should
   be made (normally points to the output file).").

:- pred format_predicate_end(Format,OS) 

	: '='(texinfo) * stream

        # "Noop (each predicate is an item in an itemized list).".
%% ---------------------------------------------------------------------------

format_predicate_end(texinfo,OS) :-
	format(OS,"@end deffn~n@sp 1~n~n",[]).
%%	format(OS,"@end deffn~n",[]).

%% ---------------------------------------------------------------------------
:- comment(format_head_descriptor(Format,HD,Type,Standard,OS), "This
   predicate defines the format of a predicate
   descriptor. @var{Format} is the type of output (e.g., texinfo,
   latex, etc.). @var{HD} describes the head of the predicate (as a
   structure whose argunents are the variable names).  @var{Type} is
   the type of predicate (predicate, function, declaration, ...).
   @var{Standard} contains the atom @tt{iso} if the predicate is
   iso-compliant. @var{OS} is the output stream to which writes should
   be made (normally points to the output file.").

:- pred format_head_descriptor(Format,HD,Type,Standard,OS) 
 
        : atom * term * atom * atom * stream

        # "Head descriptors are formatted literally, in @tt{@@code}
           format. ISO compliance is formatted using the @tt{@@key}
           command.".
%% ---------------------------------------------------------------------------

format_head_descriptor(texinfo,P,Type,Standard,OS) :- 
	(  P=_F/_A 
	-> true 
	;  typetext(Type,_Text,Prefix,Postfix),
	   texinfo_escape_ats_etc_all_atoms(P,EP),
	   format(OS,"~s@code{",[Prefix]),
	   sp_write(OS,EP),
	   format(OS,"}~s",[Postfix]) ),
	format_standard(Standard,OS).

format_standard(iso,OS) :-
	!,
	rewrite_command(texinfo,iso(""),[],NewAll),
        %% some versions of makeinfo do not seem to like @hfill... 
 	format(OS,"~n@iftex~n@hfill~n@end iftex~n~s",[NewAll]).
format_standard(_Standard,_OS).

%% ---------------------------------------------------------------------------
:- comment(format_usage_header(Format,OS), "This predicate defines the
   format of the header describing a single usage for a
   predicate. @var{Format} is the type of output (e.g., texinfo,
   latex, etc.).  @var{OS} is the output stream to which writes should
   be made (normally points to the output file).").

:- pred format_usage_header(Format,OS) 

	: '='(texinfo) * stream

	# "Usage header in bold in separate paragraph.".
%% ---------------------------------------------------------------------------

format_usage_header(texinfo,OS) :-
	format(OS,"~n@strong{Usage:} ",[]).

%% ---------------------------------------------------------------------------
:- comment(format_multiple_usage_header(Format,N,OS), "This predicate defines
   the format of the header describing each usage for a predicate with
   multiple declarations. @var{Format} is the type of output (e.g.,
   texinfo, latex, etc.).  @var{N} is the usage number. @var{OS} is
   the output stream to which writes should be made (normally points
   to the output file).").

:- pred format_multiple_usage_header(Format,N,OS) 

	: '='(texinfo) * integer * stream

	# "Usage header in bold in separate paragraph.".
%% ---------------------------------------------------------------------------

format_multiple_usage_header(texinfo,N,OS) :-
	format(OS,"~n@strong{Usage ~w:} ",[N]).

%% ---------------------------------------------------------------------------
:- comment(format_other_assrt_header(Format,OS), "This predicate
   defines the format of the header general properties of a
   predicate. @var{Format} is the type of output (e.g., texinfo,
   latex, etc.).  @var{OS} is the output stream to which writes should
   be made (normally points to the output file).").

:- pred format_other_assrt_header(Format,OS) 

	: '='(texinfo) * stream

	# "Header in bold in separate paragraph.".
%% ---------------------------------------------------------------------------

format_other_assrt_header(texinfo,OS) :-
	format(OS,"~n@strong{General properties:} ",[]).

%% ---------------------------------------------------------------------------
:- comment(format_site_begin(Format,Text,Bullet,OS),"This predicate
   defines the format of the header of the description of a set of
   properties for a given @em{site} (at calls, on success, global
   properties, etc.). @var{Format} is the type of output (e.g.,
   texinfo, latex, etc.).  @var{Text} describes the site. @var{Bullet}
   says if a bullet should precede the text. @var{OS} is the output
   stream to which writes should be made (normally points to the
   output file).").

:- pred format_site_begin(Format,Text,Bullet,OS) : 
	'='(texinfo) * string * atom * stream

   # "Each site is an item in an itemized list.".
%% ---------------------------------------------------------------------------

format_site_begin(texinfo,Text,bullet,OS) :- 
        format(OS,"@item @emph{~s}~n",[Text]).
format_site_begin(texinfo,Text,nobullet,OS) :- 
        format(OS,"~n~n@emph{~s}~n",[Text]).
	
%% ---------------------------------------------------------------------------
:- comment(format_site_end(Format,OS),"This predicate defines the
   format of the end of the description of a set of properties for a
   given site. @var{Format} is the type of output (e.g., texinfo,
   latex, etc.).  @var{OS} is the output stream to which writes should
   be made (normally points to the output file).").

:- pred format_site_end(Format,OS) : '='(texinfo) * stream

   # "Simply end of item (a newline).".
%% ---------------------------------------------------------------------------

format_site_end(texinfo,OS) :-
        format(OS,"~n",[]).

%% ---------------------------------------------------------------------------
:- comment(format_properties_begin(Format,OS),"This predicate defines
   the beginning of the description of the properties for a given
   predicate. @var{Format} is the type of output (e.g., texinfo,
   latex, etc.).  @var{N} is the usage number. @var{OS} is the output
   stream to which writes should be made (normally points to the
   output file).").

:- pred format_properties_begin(Format,OS) : '='(texinfo) * stream

   # "Properties are formatted as a (second level) itemized list.".
%% ---------------------------------------------------------------------------

format_properties_begin(texinfo,OS) :-
	format(OS,"~n@itemize @minus~n",[]).

%% ---------------------------------------------------------------------------
:- comment(format_property(Format, Prop, PM, DocString, VarNames,Opts,
   OS),"This predicate defines the formatting for a property.
   @var{Format} is the type of output (e.g., texinfo, latex, etc.).
   @var{Prop} is the actual property (a term).  @var{PM} is the module
   in which the property is defined. @var{VarNames} is a list of
   (possibly repeated) variable names, corresponding to the names in
   the head pattern.  @var{DocString} contains @tt{~s} in the places
   where the variables names should appear. Note that this is suitable
   for use as arguments for a call to @pred{format/2}. @var{OS} is the
   output stream to which writes should be made (normally points to
   the output file).").

:- pred format_property(Format, Prop, PM, DocString, VarNames,   Opts,   OS) 
   : atom * term * atom * string * list(string) * list(supported_option) * stream

   # "Properties are formatted as running text.".
%% ---------------------------------------------------------------------------

%% -literalprops -nopropnames -noundefined -nopropsepln

format_property(texinfo,Prop,PM,DocString,VarNames,Opts,OS) :- 
	!,
	texinfo_escape_ats_etc_all_atoms(Prop,EProp),
	texinfo_escape_ats_etc_all_atoms(PM,EPM),
 	(  member('-nopropsepln',Opts)
	-> format(OS," ",[])
	;  format(OS,"~n~n",[]) ),
	(  ( member('-literalprops',Opts) 
	   ; DocString==[] 
	   ; DocString==undefined )
	-> format(OS,"@code{~w}",[EProp])
	;  texinfo_escape_ats_etc_all_atoms(VarNames,RVarNames),
	   (  ( member('-nopropsepln',Opts),
	        list_concat([ NewDocString, "." ], DocString) )
	   -> %% Just to make it nicer: get rid of final full stop.
	      format(OS,NewDocString,RVarNames)
	   ;  format(OS,DocString,RVarNames) ) ),
 	(  member('-nopropsepln',Opts)
	-> true
	;  format(OS,"~n@iftex~n@hfill~n@end iftex~n",[]) ),
	(  DocString\==undefined ; member('-noundefined',Opts)
	-> true 
	;  format(OS," (undefined property)", []) ),
	(  ( DocString==undefined 
	   ; member('-nopropnames',Opts)
	   ; member('-literalprops',Opts) )
	-> true 
	;  functor(Prop,F,A),
	   texinfo_escape_ats_etc_all_atoms(F/A,Desc),
	   (  EPM \== ''
           -> format(OS," (@code{~w:~w})",[EPM,Desc]) 
	   ;  format(OS," (@code{~w})",[Desc]) ) ),
 	(  member('-nopropsepln',Opts)
	-> format(OS,".",[])
	;  true ).
format_property(texinfo,Prop,PM,_DocString,_VarNames,_Opts,_OS) :- 
	error_message("could not format property ~w:~w",[PM,Prop]).


%% ---------------------------------------------------------------------------
:- comment(format_properties_end(Format,OS),"This predicate defines
   the end of the description of the properties for a given
   predicate. @var{Format} is the type of output (e.g., texinfo,
   latex, etc.).  @var{N} is the usage number. @var{OS} is the output
   stream to which writes should be made (normally points to the
   output file).").

:- pred format_properties_end(Format,OS) : '='(texinfo) * stream

   # "End of the (second level) itemized list.".
%% ---------------------------------------------------------------------------

format_properties_end(texinfo,OS) :-
	format(OS,"@end itemize~n",[]).

%% ---------------------------------------------------------------------------
:- comment(format_description(Format,Desc,OS),"This predicate defines
   the format of @var{Desc}, an introductory text for the predicate
   (taken from the comment part of a @pred{pred/1} declaration, if
   available).  These coments are generally used to describe a
   particular usage of the predicate. @var{Format} is the type of
   output (e.g., texinfo, latex, etc.). @var{OS} is the output stream
   to which writes should be made (normally points to the output
   file).").

:- pred format_description(Format,Desc,OS) : atom * string * stream

   # "The description of the usage is a separate item in the site item list.".
%% ---------------------------------------------------------------------------

format_description(texinfo,Desc,OS) :-
        format(OS,"@item @emph{Description:} ~s ~n",[Desc]).
	
%% ---------------------------------------------------------------------------
:- comment(
  format_other_info(Format,Level,Name,NDName,Appendix,Ack,Changes,Bugs,OS),
  "This predicate defines the format of some auxiliary
  information. @var{Format} is the type of output (e.g., texinfo,
  latex, etc.). @var{Level} is the level of nesting of the
  corresponding sections (e.g., 0=unnumbered, 1=chapter,
  2=section,...). @var{Name} is the module/application
  name. @var{NDName} is the same, but without @tt{_doc}, if
  applicable. @var{Changes} contains the changelog. @var{Bugs}
  contains documentation on the known bugs. @var{OS} is the output
  stream to which writes should be made (normally points to the output
  file).").

:- pred 
   format_other_info(Format,Level,Name,NDName,Appendix,Ack,Changes,Bugs,OS)
   : (atom(Format),integer(Level),atom(Name),atom(NDName),string(Appendix),
      string(Ack),list(Changes,change),list(Bugs,string),stream(OS))

   # "Appendix is formatted as a simple text body. Bugs and changes are
     formatted as itemized lists in separate sections.".
%% ---------------------------------------------------------------------------

format_other_info(texinfo,_FileType,_Name,_NDName,[],[],[],[],_OS,_IntroOS) :-
	!.
%% If level is 0 do not uniquify
format_other_info(texinfo,main(standalone),Name,_NDName,Appendix,Ack,
	          Changes,Bugs,OS,IntroOS) :-
	!,
	close(IntroOS),
	supported_format_suffix(texinfo,Suff),
	Level = 0,
	(  Appendix = []
        -> true 
	;  concat_atom([Name,'appdx.',Suff],AppdxName),
	   format_texinfo_components_include([AppdxName],OS),
	   open(AppdxName,write,AppdxOS),
	   format_texinfo_section(Level,"Other information",AppdxOS),
	   format(AppdxOS,"~n~s~n~n",[Appendix]),
	   close(AppdxOS)
	),
	(  Ack = []
        -> true 
	;  concat_atom([Name,'ack.',Suff],AckName),
	   format_texinfo_components_include([AckName],OS),
	   open(AckName,write,AckOS),
	   format_texinfo_section(Level,"Acknowledgements",AckOS),
	   format(AckOS,"~n~s~n~n",[Ack]),
	   close(AckOS)
	),
	(  Bugs = []
        -> true 
	;  concat_atom([Name,'bugs.',Suff],BugsName),
	   format_texinfo_components_include([BugsName],OS),
	   open(BugsName,write,BugsOS),
	   format_texinfo_section(Level,
             "Known bugs and planned improvements",BugsOS),
	   format(BugsOS,"~n@itemize @bullet{}~n",[]),
	   format_itemize_body(Bugs,BugsOS),
	   format(BugsOS,"@end itemize~n",[]),
	   close(BugsOS)
	),
	(  Changes = []
        -> true 
	;  concat_atom([Name,'changes.',Suff],ChName),
	   format_texinfo_components_include([ChName],OS),
	   open(ChName,write,ChOS),
	   format_texinfo_section(Level,"Version/Change Log",ChOS),
	   format(ChOS,"~n@table @strong~n",[]),
	   format_itemize_body(Changes,ChOS),
	   format(ChOS,"@end table~n",[]),
	   close(ChOS)
	).
format_other_info(texinfo,FileLevel,_Name,INDName,Appendix,Ack,Changes,Bugs,
	          NOS,IntroOS) :-
	( (FileLevel = component, OS = NOS)
	; (FileLevel = main(withcomponents), OS = IntroOS) ),
	!,
	texinfo_escape_ats_etc_all_atoms(INDName,NDName),
	Level = 2,
	(  Appendix = []
        -> true 
	;  format_texinfo_section_name(NDName,Level,
	          "Other information",OS),
	   format(OS,"~n~s~n~n",[Appendix])
	),
	(  Ack = []
        -> true 
	;  format_texinfo_section_name(NDName,Level,
	          "Acknowledgments",OS),
	   format(OS,"~n~s~n~n",[Ack])
	),
	(  Bugs = []
        -> true 
	;  format_texinfo_section_name(NDName,Level,
                  "Known bugs and planned improvements",OS),
	   format(OS,"~n@itemize @bullet{}~n",[]),
	   format_itemize_body(Bugs,OS),
	   format(OS,"@end itemize~n",[])
	),
	(  Changes = []
        -> true 
	;  format_texinfo_section_name(NDName,Level,"Version/Change Log",OS),
	   format(OS,"~n@table @strong~n",[]),
	   format_itemize_body(Changes,OS),
	   format(OS,"@end table~n",[])
	),
	(  FileLevel = main(withcomponents)
	-> close(IntroOS)
	;  true ).
	


format_itemize_body([],_OS).
format_itemize_body([change(Version,Change)|Changes],OS) :-
	format_version(Version,"~n@item Version",OS),
	format(OS,"~n~s~n",[Change]),
	format_itemize_body(Changes,OS).
format_itemize_body([Bug|Bugs],OS) :-
	format(OS,"~n@item~n~s~n",[Bug]),
	format_itemize_body(Bugs,OS).

%% ---------------------------------------------------------------------------
:- pred texinfo_escape_ats_etc_all_atoms/2

   # "Handle complications from the possible presence of @@ in
     predicate names, modes, args, etc.".
%% ---------------------------------------------------------------------------

texinfo_escape_ats_etc_all_atoms(T,T) :- 
	var(T),
	!.
texinfo_escape_ats_etc_all_atoms(T,ET) :- 
	functor(T,F,A),
	texinfo_escape_ats_etc_atom(F,EF),
	functor(ET,EF,A),
	texinfo_escape_ats_etc_all_atoms_arg(A,T,ET).

texinfo_escape_ats_etc_all_atoms_arg(0,_T,_ET) :-
	!.
texinfo_escape_ats_etc_all_atoms_arg(A,T,ET) :-
	A>0,
	!,
	arg(A,T,TArg),
	texinfo_escape_ats_etc_all_atoms(TArg,ETArg),
	arg(A,ET,ETArg),
	NA is A-1,
	texinfo_escape_ats_etc_all_atoms_arg(NA,T,ET).
	
%% ---------------------------------------------------------------------------
:- pred texinfo_escape_ats_etc_atom/2 : atom * term => atom * atom

   # "Handle complications from the possible presence of @@ in
     predicate names, etc.".
%% ---------------------------------------------------------------------------

texinfo_escape_ats_etc_atom(A,A) :-
	number(A),
	!.
texinfo_escape_ats_etc_atom(A,EA) :-
	atom_codes(A,S),
	texinfo_escape_ats_etc(S,ES),
	atom_codes(EA,ES).

%% ---------------------------------------------------------------------------
:- pred verbatimize_string/3 
   : supported_format * string * term => supported_format * string * string

   # "Escapes needed characters in string as needed for the verbatim
     command supported natively by the format.".
%% ---------------------------------------------------------------------------

verbatimize_string(texinfo,NS,VS) :-
	texinfo_escape_ats_etc(NS,VS).
%% These two need to be studied...
verbatimize_string(html,S,S).
verbatimize_string(man,S,S).

%% ---------------------------------------------------------------------------
:- pred texinfo_escape_ats_etc/2 : string * term => string * string

   # "Handle complications from the possible presence of @@, @{, and
     @} in predicate names, etc. Also, converts tabs to 8 spaces: not
     ideal, but sufficient in many cases. There is an additional
     complication with &, which has to be treated differently in index
     entries (!).".
%% ---------------------------------------------------------------------------

texinfo_escape_ats_etc([],[]).
texinfo_escape_ats_etc([0'@|S],[0'@,0'@|ES]) :-
	!,
	texinfo_escape_ats_etc(S,ES).
texinfo_escape_ats_etc([0'{|S],[0'@,0'{|ES]) :-
	!,
	texinfo_escape_ats_etc(S,ES).
texinfo_escape_ats_etc([0'}|S],[0'@,0'}|ES]) :-
	!,
	texinfo_escape_ats_etc(S,ES).
texinfo_escape_ats_etc([0'&|S],[0'@,0'&|ES]) :-
	!,
	texinfo_escape_ats_etc(S,ES).
texinfo_escape_ats_etc([0'\t|S],[0' ,0' ,0' ,0' ,0' ,0' ,0' ,0' |ES]) :-
	!,
	texinfo_escape_ats_etc(S,ES).
texinfo_escape_ats_etc([C|S],[C|ES]) :-
	!,
	texinfo_escape_ats_etc(S,ES).
	

%% ---------------------------------------------------------------------------

:- pred sp_write/2 : stream * term 

   # "Same as @pred{write/2}, but puts space around operators. This
      makes them easier to read in documents.".
%% ---------------------------------------------------------------------------

sp_write(OS,T) :-
        nonvar(T),
        functor(T, F, A),
        sp_write_(OS,A, F, T), !.
sp_write(OS,T) :- write(OS,T).

sp_write_(OS,1, F, T) :-
        current_postfixop(F, P, _), !,
        arg(1, T, A),
        write_term(OS, A, [priority(P), numbervars(true)]),
        put_code(OS,0' ),
        display(OS,F).
sp_write_(OS,1, F, T) :-
        current_prefixop(F, _, P), !,
        display(OS,F),
        put_code(OS,0' ),
        arg(1, T, A),
        write_term(OS, A, [priority(P), numbervars(true)]).
sp_write_(OS,2, F, T) :-
        current_infixop(F, P, _, Q), !,
        arg(1, T, A),
        write_term(OS, A, [priority(P), numbervars(true)]),
        put_code(OS,0' ),
        display(OS,F),
        put_code(OS,0' ),
        arg(2, T, B),
        write_term(OS, B, [priority(Q), numbervars(true)]).
   
%% ---------------------------------------------------------------------------
	
end_of_file.

:- comment(version_maintenance,dir('../version')).

:- comment(version(1*9+50,2000/04/18,03:22*13+'CEST'), "Fixed spurious
   chars in ascii output.  (Manuel Hermenegildo)").

:- comment(version(1*9+48,2000/04/03,19:22*22+'CEST'), "Formatting for
   printing on one side can now be selected.  (Manuel Hermenegildo)").

:- comment(version(1*9+42,1999/12/10,19:19*01+'MET'), "Fixed the
   unescaping of ampersands.  (Manuel Hermenegildo)").

:- comment(version(1*9+37,1999/12/09,01:21*44+'CET'), "The fact that a
   predicate is @em{implicit} (@decl{impl_defined/1}) is now not
   documented.  (Manuel Hermenegildo)").

:- comment(version(1*9+36,1999/12/09,00:31*35+'CET'), "Added new
   option @tt{-regtypeprops}.  (Manuel Hermenegildo)").

:- comment(version(1*9+34,1999/12/09,00:09*33+'CET'), "Formatting of &
   finally fixed (non-trivial due to texinfo's weird behaviour with
   &).  (Manuel Hermenegildo)").

:- comment(version(1*9+33,1999/12/05,21:42*21+'CET'), "Fixed escaping
   of @tt{&} (was not escaped before in texinfo ouput).  (Manuel
   Hermenegildo)").

:- comment(version(1*9+32,1999/12/05,21:00*27+'CET'), "Added chapter
   appendix and ack formatting code.  (Manuel Hermenegildo)").

:- comment(version(1*9+19,1999/11/19,19:32*30+'MET'), "Changed
   @em{tolerance} and @em{hbadness} in the generated @tt{texinfo}
   output so that fewer messages are written (this makes it easier to
   spot real errors when running @apl{tex}).  (Manuel Hermenegildo)").

:- comment(version(1*9+18,1999/11/18,23:58*55+'MET'), "Added bullet
   selection in @pred{format_site_begin/4}.  (Manuel Hermenegildo)").

:- comment(version(1*9+15,1999/11/18,13:46*33+'MET'), "Imported
   @pred{modtype} from @lib{autodoc}).  (Manuel Hermenegildo)").

:- comment(version(1*9+12,1999/11/18,13:22*18+'MET'), "Moved contents
   to beginning of document--horray!  (Manuel Hermenegildo)").

:- comment(version(1*8+27,1999/04/12,15:06*23+'MEST'), "Now a warning
   is issued if characters unsupported by info are used in section
   names.  (Manuel Hermenegildo)").

:- comment(version(1*8+26,1999/04/12,12:29*34+'MEST'), "Navigation in
   html docs improved by moving the location of indexing commands in
   texinfo files up a bit.  (Manuel Hermenegildo)").

:- comment(version(1*8+18,1999/04/07,13:58*05+'MEST'), "Generated
   files now have @tt{texic} suffix, since they are a @em{texinfo
   component}.  (Manuel Hermenegildo)").

:- comment(version(1*8+15,1999/03/31,19:34*54+'MEST'),
   "@@begin@{cartouche@} and @@end@{cartouche@} commands now
   supported.  (Manuel Hermenegildo)").

:- comment(version(1*8+14,1999/03/31,19:04*46+'MEST'), "@@foonote
   command now supported.  (Manuel Hermenegildo)").

:- comment(version(1*8+12,1999/03/31,10:13*44+'CEST'), "Old @em{usage}
   index is now called, more appropriately, @em{global}
   index. Correspondingly, changed things so that now every definition
   goes to the global index in addition to its definitional index.
   (Manuel Hermenegildo)").

:- comment(version(1*8+11,1999/03/30,23:52*01+'MEST'), "The individual
   descriptions of predicates, props, regtypes, declarations, etc. now
   appear as entries in the table of contents of the printed manual.
   This can be shut off with the @tt{-shorttoc} option.  (Manuel
   Hermenegildo)").

:- comment(version(1*8+8,1999/03/30,22:13*32+'MEST'), "Implemented
   support for the new definitions of @@index, @@cindex, @@concept.
   (Manuel Hermenegildo)").

:- comment(version(1*8+7,1999/03/30,20:08*29+'MEST'), "Added support
   for @em{part} filetype.  (Manuel Hermenegildo)").

:- comment(version(1*8+6,1999/03/30,20:06*04+'MEST'), "Added
   'cartouche' around usage and interface.  (Manuel Hermenegildo)").

:- comment(version(1*7+28,1999/03/21,19:16*25+'CET'), "Changed spacing
   between the definitions of the predicates.  (Manuel
   Hermenegildo)").

:- comment(version(1*7+24,1999/03/18,15:11*56+'CET'), "Fixed some
   typing errors flagged by the documenter.  (Manuel Hermenegildo)").

:- comment(version(1*7+20,1999/03/06,19:52*30+'CET'), "A module is now
   documented even if exports nothing at all.  (Manuel Hermenegildo)").

:- comment(version(1*7+19,1999/03/06,19:48*29+'CET'), "Engine modules
   used now documented even if no other modules used (was a reported
   bug).  (Manuel Hermenegildo)").

:- comment(version(1*7+18,1999/03/06,19:28*48+'CET'), "Operators now
   correctly formatted under ciao-0.8.  (Manuel Hermenegildo)").

:- comment(version(1*7+16,1999/03/03,18:49*11+'MET'), "Minor change in
   version reporting for components ('Version (of last change)').
   (Manuel Hermenegildo)").

:- comment(version(1*7+15,1999/03/02,13:06*25+'MET'), "Fixed indexing
   of names containing @@ etc. for newer versions of texinfo.  (Manuel
   Hermenegildo)").

:- comment(version(1*7+13,1999/02/26,17:05*42+'MET'), "Tabs now
   converted to a number of spaces (8) in verbatim modes. Not perfect,
   but produces better output than leaving the tabs in.  (Manuel
   Hermenegildo)").

:- comment(version(1*7+12,1999/02/15,19:46*14+'MET'), "Name of changes
   texinfo file corrected.  (Manuel Hermenegildo)").

:- comment(version(1*7+10,1999/01/13,03:45*52+'MET'), "Added
   @@noindent command.  (Manuel Hermenegildo)").

:- comment(version(1*7+4,1998/12/04,11:53*22+'MET'), "Fixed some
   typing bugs.  (Manuel Hermenegildo)").

:- comment(version(1*6+21,1998/09/25,16:26*45+'MEST'), "Enumerated
   lists now supported (partially sometimes) on some formats. Added
   description list commands.  (Manuel Hermenegildo)").

:- comment(version(1*6+20,1998/09/25,14:57*56+'MEST'), "Added some
   symbols (bullet, result). Improved support of special characters in
   html. (Manuel Hermenegildo)").

:- comment(version(1*6+19,1998/09/25,14:00*25+'MEST'), "Concept index
   now close to the end by default.  (Manuel Hermenegildo)").

:- comment(version(1*6+18,1998/09/25,13:11*21+'MEST'), "Usage index
   now contains all references (and can thus be used as a global
   index).  (Manuel Hermenegildo)").

:- comment(version(1*6+17,1998/09/25,12:46*16+'MEST'), "Using
   @pred{list_concat/2} (makes source easier to read).  (Manuel
   Hermenegildo)").

:- comment(version(1*6+16,1998/09/24,11:28*05+'MEST'), "No extra
   spaces appear any more between end of indexing commands and
   following puctuation mark.  (Manuel Hermenegildo)").

:- comment(version(1*6+15,1998/09/24,11:08*27+'MEST'), "Summary is now
   a separate chapter (work around a @apl{texi2html} bug).  (Manuel
   Hermenegildo)").

:- comment(version(1*6+14,1998/09/24,10:29*53+'MEST'), "Version info
   in summaries now separated by a blank line.  (Manuel
   Hermenegildo)").

:- comment(version(1*6+13,1998/09/24,10:17*14+'MEST'), "Added
   @tt{@@sp} command. Fixed a bug in @tt{@@tt} for html format.
   (Manuel Hermenegildo)").

:- comment(version(1*6+11,1998/09/22,17:20*38+'MEST'), "Added @@index
   command: adds entry to concept index, but prints in a normal font.
   (Manuel Hermenegildo)").

:- comment(version(1*6+1,1998/09/09,14:38*06+'MEST'), "Added @@key
   command (after all, it is typeset nicely in texinfo).  (Manuel
   Hermenegildo)").

:- comment(version(1*5+7,1998/09/02,17:43*57+'MEST'), "Greatly
   improved and simplified treatoment of newlines (at the cost of two
   passes).  (Manuel Hermenegildo)").

:- comment(version(1*5+4,1998/08/29,08:12*45+'EST'), "Fixed some
   serious bugs (sigh) in man format.  (Manuel Hermenegildo)").

:- comment(version(1*5+2,1998/08/29,04:10*23+'EST'), "Simplified code,
   fixed some minor formatting bugs.  (Manuel Hermenegildo)").

:- comment(version(1*3+4,1998/07/14,11:29*47+'MET DST'), "User and
   system modules used now separated in the documentation.  (Manuel
   Hermenegildo)").

:- comment(version(1*2+6,1998/07/02,20:54*25+'MET DST'), "'Usage:' now
   included in header even if only one use.  (Manuel Hermenegildo)").

:- comment(version(1*2+5,1998/07/02,20:33*04+'MET DST'), "Changed
   formatting of predicates in texinfo to use texinfo deffn command.
   (Manuel Hermenegildo)").

:- comment(version(1*2+3,1998/06/29,14:37*44+'MET DST'), "Periods now
   included in the appropriate places after printing version numbers.
   (Manuel Hermenegildo)").

:- comment(version(1*1+27,1998/05/23,07:06*11+'EST'), "Fixed some bugs
   in new formatting of properties.  (Manuel Hermenegildo)").

:- comment(version(1*1+23,1998/05/01,06:34*34+'EST'), "Added support
   for comment(usage,...).  (Manuel Hermenegildo)").

:- comment(version(1*1+17,1998/04/15,10:12*49+'MET DST'), "Fixed
   formatting of versions when date is present.  (Manuel
   Hermenegildo)").

:- comment(version(1*1+10,1998/4/11), "Added support for file index.
   (Manuel Hermenegildo)").

:- comment(version(1*1+9,1998/4/11), "Words in @concept now appear
   emphasized.  (Manuel Hermenegildo)").

:- comment(version(1*1+7,1998/4/9), "Changed message for general
   properties.  (Manuel Hermenegildo)").

:- comment(version(1*1+4,1998/4/7), "Several improvements (e.g.,
   treatoment of newlines) to formatting of unix man files.  (Manuel
   Hermenegildo)").

:- comment(version(0*9+1,1998/2/24), "File version is now global
   lpdoc version.  (Manuel Hermenegildo)").

:- comment(version(0*3+11,1998/2/20), "Added ascii format. (Manuel
   Hermenegildo)").

:- comment(version(0*3+10,1998/2/20), "Eliminated multiple arity
   predicates. (Manuel Hermenegildo)").

:- comment(version(0*3+9,1997/11/5), "Fixed acute accent for
   i. (Manuel Hermenegildo)").

:- comment(version(0*3+8,1997/9/19), "Fixed minor bug in texinfo
   section header generation. (Manuel Hermenegildo)").

:- comment(version(0*3+7,1997/9/19), "Fixed intro name. (Manuel
   Hermenegildo)").

:- comment(version(0*3+6,1997/9/17), "Added support for reexported
   predicates. (Manuel Hermenegildo)").

:- comment(version(0*3+5,1997/9/15), "Fixed problem with bodies of
   concept commands not being included when no index being
   generated. (Manuel Hermenegildo)").

:- comment(version(0*3+4,1997/07/29), "Added support for optional
   selection of indices to be generated.").

:- comment(version(0*3+3,1997/07/25), "Added support for nroff -m
   formatting (e.g., for man pages).").

:- comment(version(0*3+2,1997/07/25), "Added partial support for html
   formatting.").

:- comment(version(0*3+1,1997/07/25), "Added version handling:
   included it in cover.").

:- comment(version(0*0+0,1996/10/10),"First prototype.").

%% ---------------------------------------------------------------------------


%% -modes and -headprops are used by normalizer!
option_comment('-headprops',   'Do not move head properties to body.        ').
option_comment('-modes',       'Do not translate modes and their arguments
	                        (except for properties)                     ').
option_comment('-regtypeprops','Include in the doc for regtypes the global
                                prop stating that they are indeed regtypes.').

filter_export_by_type([],_Type,[]).
filter_export_by_type([export(F/A,Type)|CExps],TypeStr,[F/A|FExps]) :-
	typetext(Type,TypeStr,_,_),
	!,
	filter_export_by_type(CExps,TypeStr,FExps).
filter_export_by_type([_|CExps],TypeStr,FExps) :-
	!,
	filter_export_by_type(CExps,TypeStr,FExps).



syntax highlighted by Code2HTML, v. 0.9.1