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# Texinfo 7.0 changed the syntax of various functions. 24# Provide a shim for older versions. 25sub ff_set_from_init_file($$) { 26 my $key = shift; 27 my $value = shift; 28 if (exists &{'texinfo_set_from_init_file'}) { 29 texinfo_set_from_init_file($key, $value); 30 } else { 31 set_from_init_file($key, $value); 32 } 33} 34 35sub ff_get_conf($) { 36 my $key = shift; 37 if (exists &{'texinfo_get_conf'}) { 38 texinfo_get_conf($key); 39 } else { 40 get_conf($key); 41 } 42} 43 44sub get_formatting_function($$) { 45 my $obj = shift; 46 my $func = shift; 47 48 my $sub = $obj->can('formatting_function'); 49 if ($sub) { 50 return $obj->formatting_function($func); 51 } else { 52 return $obj->{$func}; 53 } 54} 55 56# determine texinfo version 57my $program_version_num = version->declare(ff_get_conf('PACKAGE_VERSION'))->numify; 58my $program_version_6_8 = $program_version_num >= 6.008000; 59 60# no navigation elements 61ff_set_from_init_file('HEADERS', 0); 62 63sub ffmpeg_heading_command($$$$$) 64{ 65 my $self = shift; 66 my $cmdname = shift; 67 my $command = shift; 68 my $args = shift; 69 my $content = shift; 70 71 my $result = ''; 72 73 # not clear that it may really happen 74 if ($self->in_string) { 75 $result .= $self->command_string($command) ."\n" if ($cmdname ne 'node'); 76 $result .= $content if (defined($content)); 77 return $result; 78 } 79 80 my $element_id = $self->command_id($command); 81 $result .= "<a name=\"$element_id\"></a>\n" 82 if (defined($element_id) and $element_id ne ''); 83 84 print STDERR "Process $command " 85 .Texinfo::Structuring::_print_root_command_texi($command)."\n" 86 if ($self->get_conf('DEBUG')); 87 my $element; 88 if ($Texinfo::Common::root_commands{$command->{'cmdname'}} 89 and $command->{'parent'} 90 and $command->{'parent'}->{'type'} 91 and $command->{'parent'}->{'type'} eq 'element') { 92 $element = $command->{'parent'}; 93 } 94 if ($element) { 95 $result .= &{get_formatting_function($self, 'format_element_header')}($self, $cmdname, 96 $command, $element); 97 } 98 99 my $heading_level; 100 # node is used as heading if there is nothing else. 101 if ($cmdname eq 'node') { 102 if (!$element or (!$element->{'extra'}->{'section'} 103 and $element->{'extra'}->{'node'} 104 and $element->{'extra'}->{'node'} eq $command 105 # bogus node may not have been normalized 106 and defined($command->{'extra'}->{'normalized'}))) { 107 if ($command->{'extra'}->{'normalized'} eq 'Top') { 108 $heading_level = 0; 109 } else { 110 $heading_level = 3; 111 } 112 } 113 } else { 114 $heading_level = $command->{'level'}; 115 } 116 117 my $heading = $self->command_text($command); 118 # $heading not defined may happen if the command is a @node, for example 119 # if there is an error in the node. 120 if (defined($heading) and $heading ne '' and defined($heading_level)) { 121 122 if ($Texinfo::Common::root_commands{$cmdname} 123 and $Texinfo::Common::sectioning_commands{$cmdname}) { 124 my $content_href = $self->command_contents_href($command, 'contents', 125 $self->{'current_filename'}); 126 if ($content_href) { 127 my $this_href = $content_href =~ s/^\#toc-/\#/r; 128 $heading .= '<span class="pull-right">'. 129 '<a class="anchor hidden-xs" '. 130 "href=\"$this_href\" aria-hidden=\"true\">". 131 ($ENV{"FA_ICONS"} ? '<i class="fa fa-link"></i>' 132 : '#'). 133 '</a> '. 134 '<a class="anchor hidden-xs"'. 135 "href=\"$content_href\" aria-hidden=\"true\">". 136 ($ENV{"FA_ICONS"} ? '<i class="fa fa-navicon"></i>' 137 : 'TOC'). 138 '</a>'. 139 '</span>'; 140 } 141 } 142 143 if ($self->in_preformatted()) { 144 $result .= $heading."\n"; 145 } else { 146 # if the level was changed, set the command name right 147 if ($cmdname ne 'node' 148 and $heading_level ne $Texinfo::Common::command_structuring_level{$cmdname}) { 149 $cmdname 150 = $Texinfo::Common::level_to_structuring_command{$cmdname}->[$heading_level]; 151 } 152 # format_heading_text expects an array of headings for texinfo >= 7.0 153 if ($program_version_num >= 7.000000) { 154 $heading = [$heading]; 155 } 156 $result .= &{get_formatting_function($self,'format_heading_text')}( 157 $self, $cmdname, $heading, 158 $heading_level + 159 $self->get_conf('CHAPTER_HEADER_LEVEL') - 1, $command); 160 } 161 } 162 $result .= $content if (defined($content)); 163 return $result; 164} 165 166foreach my $command (keys(%Texinfo::Common::sectioning_commands), 'node') { 167 texinfo_register_command_formatting($command, \&ffmpeg_heading_command); 168} 169 170# print the TOC where @contents is used 171if ($program_version_6_8) { 172 ff_set_from_init_file('CONTENTS_OUTPUT_LOCATION', 'inline'); 173} else { 174 ff_set_from_init_file('INLINE_CONTENTS', 1); 175} 176 177# make chapters <h2> 178ff_set_from_init_file('CHAPTER_HEADER_LEVEL', 2); 179 180# Do not add <hr> 181ff_set_from_init_file('DEFAULT_RULE', ''); 182ff_set_from_init_file('BIG_RULE', ''); 183 184# Customized file beginning 185sub ffmpeg_begin_file($$$) 186{ 187 my $self = shift; 188 my $filename = shift; 189 my $element = shift; 190 191 my $command; 192 if ($element and $self->get_conf('SPLIT')) { 193 $command = $self->element_command($element); 194 } 195 196 my ($title, $description, $encoding, $date, $css_lines, 197 $doctype, $bodytext, $copying_comment, $after_body_open, 198 $extra_head, $program_and_version, $program_homepage, 199 $program, $generator); 200 if ($program_version_num >= 7.000000) { 201 ($title, $description, $encoding, $date, $css_lines, 202 $doctype, $bodytext, $copying_comment, $after_body_open, 203 $extra_head, $program_and_version, $program_homepage, 204 $program, $generator) = $self->_file_header_information($command); 205 } else { 206 ($title, $description, $encoding, $date, $css_lines, 207 $doctype, $bodytext, $copying_comment, $after_body_open, 208 $extra_head, $program_and_version, $program_homepage, 209 $program, $generator) = $self->_file_header_informations($command); 210 } 211 212 my $links = $self->_get_links ($filename, $element); 213 214 my $head1 = $ENV{"FFMPEG_HEADER1"} || <<EOT; 215<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 216<html> 217<!-- Created by $program_and_version, $program_homepage --> 218 <head> 219 <meta charset="utf-8"> 220 <title> 221EOT 222 my $head_title = <<EOT; 223 $title 224EOT 225 226 my $head2 = $ENV{"FFMPEG_HEADER2"} || <<EOT; 227 </title> 228 <meta name="viewport" content="width=device-width,initial-scale=1.0"> 229 <link rel="stylesheet" type="text/css" href="bootstrap.min.css"> 230 <link rel="stylesheet" type="text/css" href="style.min.css"> 231 </head> 232 <body> 233 <div class="container"> 234 <h1> 235EOT 236 237 my $head3 = $ENV{"FFMPEG_HEADER3"} || <<EOT; 238 </h1> 239EOT 240 241 return $head1 . $head_title . $head2 . $head_title . $head3; 242} 243if ($program_version_6_8) { 244 texinfo_register_formatting_function('format_begin_file', \&ffmpeg_begin_file); 245} else { 246 texinfo_register_formatting_function('begin_file', \&ffmpeg_begin_file); 247} 248 249sub ffmpeg_program_string($) 250{ 251 my $self = shift; 252 if (defined($self->get_conf('PROGRAM')) 253 and $self->get_conf('PROGRAM') ne '' 254 and defined($self->get_conf('PACKAGE_URL'))) { 255 return $self->convert_tree( 256 $self->gdt('This document was generated using @uref{{program_homepage}, @emph{{program}}}.', 257 { 'program_homepage' => $self->get_conf('PACKAGE_URL'), 258 'program' => $self->get_conf('PROGRAM') })); 259 } else { 260 return $self->convert_tree( 261 $self->gdt('This document was generated automatically.')); 262 } 263} 264if ($program_version_6_8) { 265 texinfo_register_formatting_function('format_program_string', \&ffmpeg_program_string); 266} else { 267 texinfo_register_formatting_function('program_string', \&ffmpeg_program_string); 268} 269 270# Customized file ending 271sub ffmpeg_end_file($) 272{ 273 my $self = shift; 274 my $program_string = &{get_formatting_function($self,'format_program_string')}($self); 275 my $program_text = <<EOT; 276 <p style="font-size: small;"> 277 $program_string 278 </p> 279EOT 280 my $footer = $ENV{FFMPEG_FOOTER} || <<EOT; 281 </div> 282 </body> 283</html> 284EOT 285 return $program_text . $footer; 286} 287if ($program_version_6_8) { 288 texinfo_register_formatting_function('format_end_file', \&ffmpeg_end_file); 289} else { 290 texinfo_register_formatting_function('end_file', \&ffmpeg_end_file); 291} 292 293# Dummy title command 294# Ignore title. Title is handled through ffmpeg_begin_file(). 295ff_set_from_init_file('USE_TITLEPAGE_FOR_TITLE', 1); 296sub ffmpeg_title($$$$) 297{ 298 return ''; 299} 300 301texinfo_register_command_formatting('titlefont', 302 \&ffmpeg_title); 303 304# Customized float command. Part of code borrowed from GNU Texinfo. 305sub ffmpeg_float($$$$$) 306{ 307 my $self = shift; 308 my $cmdname = shift; 309 my $command = shift; 310 my $args = shift; 311 my $content = shift; 312 313 my ($caption, $prepended); 314 if ($program_version_num >= 7.000000) { 315 ($caption, $prepended) = Texinfo::Convert::Converter::float_name_caption($self, 316 $command); 317 } else { 318 ($caption, $prepended) = Texinfo::Common::float_name_caption($self, 319 $command); 320 } 321 my $caption_text = ''; 322 my $prepended_text; 323 my $prepended_save = ''; 324 325 if ($self->in_string()) { 326 if ($prepended) { 327 $prepended_text = $self->convert_tree_new_formatting_context( 328 $prepended, 'float prepended'); 329 } else { 330 $prepended_text = ''; 331 } 332 if ($caption) { 333 $caption_text = $self->convert_tree_new_formatting_context( 334 {'contents' => $caption->{'args'}->[0]->{'contents'}}, 335 'float caption'); 336 } 337 return $prepended.$content.$caption_text; 338 } 339 340 my $id = $self->command_id($command); 341 my $label; 342 if (defined($id) and $id ne '') { 343 $label = "<a name=\"$id\"></a>"; 344 } else { 345 $label = ''; 346 } 347 348 if ($prepended) { 349 if ($caption) { 350 # prepend the prepended tree to the first paragraph 351 my @caption_original_contents = @{$caption->{'args'}->[0]->{'contents'}}; 352 my @caption_contents; 353 my $new_paragraph; 354 while (@caption_original_contents) { 355 my $content = shift @caption_original_contents; 356 if ($content->{'type'} and $content->{'type'} eq 'paragraph') { 357 %{$new_paragraph} = %{$content}; 358 $new_paragraph->{'contents'} = [@{$content->{'contents'}}]; 359 unshift (@{$new_paragraph->{'contents'}}, {'cmdname' => 'strong', 360 'args' => [{'type' => 'brace_command_arg', 361 'contents' => [$prepended]}]}); 362 push @caption_contents, $new_paragraph; 363 last; 364 } else { 365 push @caption_contents, $content; 366 } 367 } 368 push @caption_contents, @caption_original_contents; 369 if ($new_paragraph) { 370 $caption_text = $self->convert_tree_new_formatting_context( 371 {'contents' => \@caption_contents}, 'float caption'); 372 $prepended_text = ''; 373 } 374 } 375 if ($caption_text eq '') { 376 $prepended_text = $self->convert_tree_new_formatting_context( 377 $prepended, 'float prepended'); 378 if ($prepended_text ne '') { 379 $prepended_save = $prepended_text; 380 $prepended_text = '<p><strong>'.$prepended_text.'</strong></p>'; 381 } 382 } 383 } else { 384 $prepended_text = ''; 385 } 386 387 if ($caption and $caption_text eq '') { 388 $caption_text = $self->convert_tree_new_formatting_context( 389 $caption->{'args'}->[0], 'float caption'); 390 } 391 if ($prepended_text.$caption_text ne '') { 392 if ($program_version_num >= 7.000000) { 393 $prepended_text = $self->html_attribute_class('div',['float-caption']). '>' 394 . $prepended_text; 395 } else { 396 $prepended_text = $self->_attribute_class('div','float-caption'). '>' 397 . $prepended_text; 398 } 399 $caption_text .= '</div>'; 400 } 401 my $html_class = ''; 402 if ($prepended_save =~ /NOTE/) { 403 $html_class = 'info'; 404 $prepended_text = ''; 405 $caption_text = ''; 406 } elsif ($prepended_save =~ /IMPORTANT/) { 407 $html_class = 'warning'; 408 $prepended_text = ''; 409 $caption_text = ''; 410 } 411 if ($program_version_num >= 7.000000) { 412 return $self->html_attribute_class('div', [$html_class]). '>' . "\n" . 413 $prepended_text . $caption_text . $content . '</div>'; 414 } else { 415 return $self->_attribute_class('div', $html_class). '>' . "\n" . 416 $prepended_text . $caption_text . $content . '</div>'; 417 } 418} 419 420texinfo_register_command_formatting('float', 421 \&ffmpeg_float); 422 4231; 424