doc: Do not use the headings as links to TOC anchors
[ffmpeg.git] / doc / t2h.pm
1 # makeinfo HTML output init file
2 #
3 # Copyright (c) 2011, 2012 Free Software Foundation, Inc.
4 # Copyright (c) 2014 Andreas Cadhalpun
5 # Copyright (c) 2014 Tiancheng "Timothy" Gu
6 #
7 # This file is part of FFmpeg.
8 #
9 # FFmpeg is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # FFmpeg is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 # General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public
20 # License along with FFmpeg; if not, write to the Free Software
21 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
23 # no navigation elements
24 set_from_init_file('HEADERS', 0);
25
26 sub ffmpeg_heading_command($$$$$)
27 {
28     my $self = shift;
29     my $cmdname = shift;
30     my $command = shift;
31     my $args = shift;
32     my $content = shift;
33
34     my $result = '';
35
36     # not clear that it may really happen
37     if ($self->in_string) {
38         $result .= $self->command_string($command) ."\n" if ($cmdname ne 'node');
39         $result .= $content if (defined($content));
40         return $result;
41     }
42
43     my $element_id = $self->command_id($command);
44     $result .= "<a name=\"$element_id\"></a>\n"
45         if (defined($element_id) and $element_id ne '');
46
47     print STDERR "Process $command "
48         .Texinfo::Structuring::_print_root_command_texi($command)."\n"
49             if ($self->get_conf('DEBUG'));
50     my $element;
51     if ($Texinfo::Common::root_commands{$command->{'cmdname'}}
52         and $command->{'parent'}
53         and $command->{'parent'}->{'type'}
54         and $command->{'parent'}->{'type'} eq 'element') {
55         $element = $command->{'parent'};
56     }
57     if ($element) {
58         $result .= &{$self->{'format_element_header'}}($self, $cmdname,
59                                                        $command, $element);
60     }
61
62     my $heading_level;
63     # node is used as heading if there is nothing else.
64     if ($cmdname eq 'node') {
65         if (!$element or (!$element->{'extra'}->{'section'}
66             and $element->{'extra'}->{'node'}
67             and $element->{'extra'}->{'node'} eq $command
68              # bogus node may not have been normalized
69             and defined($command->{'extra'}->{'normalized'}))) {
70             if ($command->{'extra'}->{'normalized'} eq 'Top') {
71                 $heading_level = 0;
72             } else {
73                 $heading_level = 3;
74             }
75         }
76     } else {
77         $heading_level = $command->{'level'};
78     }
79
80     my $heading = $self->command_text($command);
81     # $heading not defined may happen if the command is a @node, for example
82     # if there is an error in the node.
83     if (defined($heading) and $heading ne '' and defined($heading_level)) {
84
85         if ($Texinfo::Common::root_commands{$cmdname}
86             and $Texinfo::Common::sectioning_commands{$cmdname}) {
87             my $content_href = $self->command_contents_href($command, 'contents',
88                                                             $self->{'current_filename'});
89             if ($content_href) {
90                 my $this_href = $content_href =~ s/^\#toc-/\#/r;
91                 $heading .= '<span class="pull-right">'.
92                               '<a class="anchor hidden-xs" '.
93                                  "href=\"$this_href\" aria-hidden=\"true\">".
94             ($ENV{"FA_ICONS"} ? '<i class="fa fa-link"></i>'
95                               : '#').
96                               '</a> '.
97                               '<a class="anchor hidden-xs"'.
98                                  "href=\"$content_href\" aria-hidden=\"true\">".
99             ($ENV{"FA_ICONS"} ? '<i class="fa fa-navicon"></i>'
100                               : 'TOC').
101                               '</a>'.
102                             '</span>';
103             }
104         }
105
106         if ($self->in_preformatted()) {
107             $result .= $heading."\n";
108         } else {
109             # if the level was changed, set the command name right
110             if ($cmdname ne 'node'
111                 and $heading_level ne $Texinfo::Common::command_structuring_level{$cmdname}) {
112                 $cmdname
113                     = $Texinfo::Common::level_to_structuring_command{$cmdname}->[$heading_level];
114             }
115             $result .= &{$self->{'format_heading_text'}}(
116                         $self, $cmdname, $heading,
117                         $heading_level +
118                         $self->get_conf('CHAPTER_HEADER_LEVEL') - 1, $command);
119         }
120     }
121     $result .= $content if (defined($content));
122     return $result;
123 }
124
125 foreach my $command (keys(%Texinfo::Common::sectioning_commands), 'node') {
126     texinfo_register_command_formatting($command, \&ffmpeg_heading_command);
127 }
128
129 # print the TOC where @contents is used
130 set_from_init_file('INLINE_CONTENTS', 1);
131
132 # make chapters <h2>
133 set_from_init_file('CHAPTER_HEADER_LEVEL', 2);
134
135 # Do not add <hr>
136 set_from_init_file('DEFAULT_RULE', '');
137 set_from_init_file('BIG_RULE', '');
138
139 # Customized file beginning
140 sub ffmpeg_begin_file($$$)
141 {
142     my $self = shift;
143     my $filename = shift;
144     my $element = shift;
145
146     my $command;
147     if ($element and $self->get_conf('SPLIT')) {
148         $command = $self->element_command($element);
149     }
150
151     my ($title, $description, $encoding, $date, $css_lines,
152         $doctype, $bodytext, $copying_comment, $after_body_open,
153         $extra_head, $program_and_version, $program_homepage,
154         $program, $generator) = $self->_file_header_informations($command);
155
156     my $links = $self->_get_links ($filename, $element);
157
158     my $head1 = $ENV{"FFMPEG_HEADER1"} || <<EOT;
159 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
160 <html>
161 <!-- Created by $program_and_version, $program_homepage -->
162   <head>
163     <meta charset="utf-8">
164     <title>
165 EOT
166     my $head_title = <<EOT;
167       $title
168 EOT
169
170     my $head2 = $ENV{"FFMPEG_HEADER2"} || <<EOT;
171     </title>
172     <link rel="stylesheet" type="text/css" href="bootstrap.min.css">
173     <link rel="stylesheet" type="text/css" href="style.min.css">
174   </head>
175   <body>
176     <div style="width: 95%; margin: auto">
177       <h1>
178 EOT
179
180     my $head3 = $ENV{"FFMPEG_HEADER3"} || <<EOT;
181       </h1>
182 EOT
183
184     return $head1 . $head_title . $head2 . $head_title . $head3;
185 }
186 texinfo_register_formatting_function('begin_file', \&ffmpeg_begin_file);
187
188 # Customized file ending
189 sub ffmpeg_end_file($)
190 {
191     my $self = shift;
192     my $program_string = &{$self->{'format_program_string'}}($self);
193     my $program_text = <<EOT;
194       <p style="font-size: small;">
195         $program_string
196       </p>
197 EOT
198     my $footer = $ENV{FFMPEG_FOOTER} || <<EOT;
199     </div>
200   </body>
201 </html>
202 EOT
203     return $program_text . $footer;
204 }
205 texinfo_register_formatting_function('end_file', \&ffmpeg_end_file);
206
207 # Dummy title command
208 # Ignore title. Title is handled through ffmpeg_begin_file().
209 set_from_init_file('USE_TITLEPAGE_FOR_TITLE', 1);
210 sub ffmpeg_title($$$$)
211 {
212     return '';
213 }
214
215 texinfo_register_command_formatting('titlefont',
216                                     \&ffmpeg_title);
217
218 # Customized float command. Part of code borrowed from GNU Texinfo.
219 sub ffmpeg_float($$$$$)
220 {
221     my $self = shift;
222     my $cmdname = shift;
223     my $command = shift;
224     my $args = shift;
225     my $content = shift;
226
227     my ($caption, $prepended) = Texinfo::Common::float_name_caption($self,
228                                                                 $command);
229     my $caption_text = '';
230     my $prepended_text;
231     my $prepended_save = '';
232
233     if ($self->in_string()) {
234         if ($prepended) {
235             $prepended_text = $self->convert_tree_new_formatting_context(
236                 $prepended, 'float prepended');
237         } else {
238             $prepended_text = '';
239         }
240         if ($caption) {
241             $caption_text = $self->convert_tree_new_formatting_context(
242                 {'contents' => $caption->{'args'}->[0]->{'contents'}},
243                 'float caption');
244         }
245         return $prepended.$content.$caption_text;
246     }
247
248     my $id = $self->command_id($command);
249     my $label;
250     if (defined($id) and $id ne '') {
251         $label = "<a name=\"$id\"></a>";
252     } else {
253         $label = '';
254     }
255
256     if ($prepended) {
257         if ($caption) {
258             # prepend the prepended tree to the first paragraph
259             my @caption_original_contents = @{$caption->{'args'}->[0]->{'contents'}};
260             my @caption_contents;
261             my $new_paragraph;
262             while (@caption_original_contents) {
263                 my $content = shift @caption_original_contents;
264                 if ($content->{'type'} and $content->{'type'} eq 'paragraph') {
265                     %{$new_paragraph} = %{$content};
266                     $new_paragraph->{'contents'} = [@{$content->{'contents'}}];
267                     unshift (@{$new_paragraph->{'contents'}}, {'cmdname' => 'strong',
268                              'args' => [{'type' => 'brace_command_arg',
269                                                     'contents' => [$prepended]}]});
270                     push @caption_contents, $new_paragraph;
271                     last;
272                 } else {
273                     push @caption_contents, $content;
274                 }
275             }
276             push @caption_contents, @caption_original_contents;
277             if ($new_paragraph) {
278                 $caption_text = $self->convert_tree_new_formatting_context(
279                  {'contents' => \@caption_contents}, 'float caption');
280                 $prepended_text = '';
281             }
282         }
283         if ($caption_text eq '') {
284             $prepended_text = $self->convert_tree_new_formatting_context(
285                 $prepended, 'float prepended');
286             if ($prepended_text ne '') {
287                 $prepended_save = $prepended_text;
288                 $prepended_text = '<p><strong>'.$prepended_text.'</strong></p>';
289             }
290         }
291     } else {
292         $prepended_text = '';
293     }
294
295     if ($caption and $caption_text eq '') {
296         $caption_text = $self->convert_tree_new_formatting_context(
297             $caption->{'args'}->[0], 'float caption');
298     }
299     if ($prepended_text.$caption_text ne '') {
300         $prepended_text = $self->_attribute_class('div','float-caption'). '>'
301                 . $prepended_text;
302         $caption_text .= '</div>';
303     }
304     my $html_class = '';
305     if ($prepended_save =~ /NOTE/) {
306         $html_class = 'info';
307         $prepended_text = '';
308         $caption_text   = '';
309     } elsif ($prepended_save =~ /IMPORTANT/) {
310         $html_class = 'warning';
311         $prepended_text = '';
312         $caption_text   = '';
313     }
314     return $self->_attribute_class('div', $html_class). '>' . "\n" .
315         $prepended_text . $caption_text . $content . '</div>';
316 }
317
318 texinfo_register_command_formatting('float',
319                                     \&ffmpeg_float);
320
321 1;