1## Copyright (C) 2014 Julien Bect <julien.bect@supelec.fr>
2## Copyright (C) 2008 Soren Hauberg <soren@hauberg.org>
3##
4## This program is free software; you can redistribute it and/or modify it
5## under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 3 of the License, or (at
7## your option) any later version.
8##
9## This program is distributed in the hope that it will be useful, but
10## WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12## General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; see the file COPYING.  If not, see
16## <http://www.gnu.org/licenses/>.
17
18## -*- texinfo -*-
19## @deftypefn {Function File} generate_operators (@var{outdir}, @var{options})
20## Generate a HTML page with a list of operators available in GNU Octave.
21## @end deftypefn
22
23function generate_operators (outdir = "htdocs", options = struct ())
24
25  ## Check input
26  if (!ischar (outdir))
27    error ("First input argument must be a string");
28  endif
29
30  ## Process input argument 'options'
31  if (ischar (options)) || (isstruct (options))
32    options = get_html_options (options);
33  else
34    error ("Second input argument must be a string or a structure");
35  endif
36
37  ## Create directories if needed
38  assert_dir (outdir);
39
40  name = fullfile (outdir, "operators.html");
41
42  ## Generate html
43
44  title = "Operators and Keywords";
45  options.body_command = 'onload="javascript:fix_top_menu ();"';
46
47  ## Initialize setopts.
48  setopts (options, struct ());
49
50  vpars = struct ("name", title,
51                  "pkgroot", "");
52  header = getopt ("overview_header", vpars);
53  title  = getopt ("overview_title",  vpars);
54  footer = getopt ("overview_footer", vpars);
55
56  fid = fopen (name, "w");
57  if (fid < 0)
58    error ("Couldn't open file for writing");
59  endif
60
61  fprintf (fid, "%s\n", header);
62
63  fprintf (fid, "<h2 class=\"tbdesc\">Operators</h2>\n\n");
64  write_list (__operators__, fid, false);
65
66  fprintf (fid, "<h2 class=\"tbdesc\">Keywords</h2>\n\n");
67  write_list (__keywords__, fid, true);
68
69  fprintf (fid, "\n%s\n", footer);
70  fclose (fid);
71endfunction
72
73function write_list (list, fid, write_anchors)
74  for k = 1:length (list)
75    elem = list{k};
76    [text, format] = get_help_text (elem);
77    if (strcmp (format, "texinfo"))
78      text = strip_defs (text);
79      text = __makeinfo__ (text, "plain text");
80    endif
81    if (write_anchors)
82      fprintf (fid, "<a name=\"%s\">\n", elem);
83    endif
84    fprintf (fid, "<div class=\"func\"><b>%s</b></div>\n", elem);
85    fprintf (fid, "<div class=\"ftext\">%s</div>\n", text); # XXX: don't use text
86    if (write_anchors)
87      fprintf (fid, "</a>\n\n");
88    endif
89  endfor
90endfunction
91
92function text = strip_defs (text)
93  ## Lines ending with "@\n" are continuation lines, so they should be concatenated
94  ## with the following line.
95  text = strrep (text, "@\n", " ");
96
97  ## Find, and remove, lines that start with @def. This should remove things
98  ## such as @deftypefn, @deftypefnx, @defvar, etc.
99  keep = true (size (text));
100  def_idx = strfind (text, "@def");
101  if (!isempty (def_idx))
102    endl_idx = find (text == "\n");
103    for k = 1:length (def_idx)
104      endl = endl_idx (find (endl_idx > def_idx (k), 1));
105      if (isempty (endl))
106        keep (def_idx (k):end) = false;
107      else
108        keep (def_idx (k):endl) = false;
109      endif
110    endfor
111
112    ## Remove the @end ... that corresponds to the @def we removed above
113    def1 = def_idx (1);
114    space_idx = find (text == " ");
115    space_idx = space_idx (find (space_idx > def1, 1));
116    bracket_idx = find (text == "{" | text == "}");
117    bracket_idx = bracket_idx (find (bracket_idx > def1, 1));
118    if (isempty (space_idx) && isempty (bracket_idx))
119      error ("Couldn't parse texinfo");
120    endif
121    sep_idx = min (space_idx, bracket_idx);
122    def_type = text (def1+1:sep_idx-1);
123
124    end_idx = strfind (text, sprintf ("@end %s", def_type));
125    if (isempty (end_idx))
126      error ("Couldn't parse texinfo");
127    endif
128    endl = endl_idx (find (endl_idx > end_idx, 1));
129    if (isempty (endl))
130      keep (end_idx:end) = false;
131    else
132      keep (end_idx:endl) = false;
133    endif
134
135    text = text (keep);
136  endif
137endfunction
138