ocument_info->{'setfilename'})) { $setfilename = $document_info->{'setfilename'}; } my $input_basename_for_outfile = $input_basename; my $setfilename_for_outfile = $setfilename; # PREFIX overrides both setfilename and the input file base name if (defined($self->get_conf('PREFIX'))) { $setfilename_for_outfile = undef; $input_basename_for_outfile = $self->get_conf('PREFIX'); } # the document path, in general the outfile without # extension and can be set from setfilename if outfile is not set my $document_path; # determine output file and output file name my $output_file; if (!defined($self->get_conf('OUTFILE'))) { if (defined($setfilename_for_outfile)) { $document_path = $setfilename_for_outfile; $document_path =~ s/\.[^\.]*$//; if (!$self->get_conf('USE_SETFILENAME_EXTENSION')) { $output_file = $document_path; $output_file .= '.'.$self->get_conf('EXTENSION') if (defined($self->get_conf('EXTENSION')) and $self->get_conf('EXTENSION') ne ''); } else { $output_file = $setfilename_for_outfile; } } elsif ($input_basename_for_outfile ne '') { $output_file = $input_basename_for_outfile; $document_path = $input_basename_for_outfile; $output_file .= '.'.$self->get_conf('EXTENSION') if (defined($self->get_conf('EXTENSION')) and $self->get_conf('EXTENSION') ne ''); } else { $output_file = ''; $document_path = $output_file; } if (defined($self->get_conf('SUBDIR')) and $output_file ne '') { my $dir = File::Spec->canonpath($self->get_conf('SUBDIR')); $output_file = join('/', ($dir, $output_file)); } } else { $document_path = $self->get_conf('OUTFILE'); $document_path =~ s/\.[^\.]*$//; $output_file = $self->get_conf('OUTFILE'); } # the output file path, in general same as the outfile but can be # set from setfilename if outfile is not set. my $output_filepath = $output_file; # in this case one wants to get the result in a string and there # is a setfilename. The setfilename is used to get something. # This happens in the test suite. if ($output_file eq '' and defined($setfilename_for_outfile)) { $output_filepath = $setfilename_for_outfile; $document_path = $setfilename_for_outfile; $document_path =~ s/\.[^\.]*$//; } # $document_name is the name of the document, which is the output # file basename, $output_filename, without extension. my ($document_name, $output_filename, $directories, $suffix); # We may be handling setfilename there, so it is not obvious that we # want to use fileparse and not consider unixish separators. However, # if this is setfilename, it should be a simple file name, so it # should hopefully be harmless to use fileparse ($document_name, $directories, $suffix) = fileparse($document_path); ($output_filename, $directories, $suffix) = fileparse($output_filepath); my $destination_directory; if ($self->get_conf('SPLIT')) { if (defined($self->get_conf('OUTFILE'))) { $destination_directory = $self->get_conf('OUTFILE'); } elsif (defined($self->get_conf('SUBDIR'))) { $destination_directory = $self->get_conf('SUBDIR'); } else { $destination_directory = $document_name; if (defined($output_format) and $output_format ne '') { $destination_directory .= '_'.$output_format; } } } else { # $output_file_filename is not used, but $output_filename should be # the same as long as $output_file is the same as $output_filepath # which is the case except if $output_file is ''. # Note that fileparse may return a string for the directory part even # for a relative file without directory, ie # myfile.html -> $output_dir = './' # In that case the $destination_directory will never be ''. my ($output_file_filename, $output_dir, $suffix) = fileparse($output_file); $destination_directory = $output_dir; } if ($destination_directory ne '') { $destination_directory = File::Spec->canonpath($destination_directory); } return ($output_file, $destination_directory, $output_filename, $document_name, $input_basefile); } # determine the default, with $INIT_CONF if set, or the default common # to all the converters sub _command_init($$) { my $global_command = shift; my $init_conf = shift; if (exists($Texinfo::Common::document_settable_at_commands{$global_command})) { if (defined($init_conf->{$global_command})) { return $init_conf->{$global_command}; } elsif (defined($Texinfo::Common::document_settable_at_commands{$global_command})) { return $Texinfo::Common::document_settable_at_commands{$global_command}; } } return undef; } # $COMMANDS_LOCATION is 'before', 'last', 'preamble' or 'preamble_or_first' # 'before' means setting to the values before the document commands # (defaults and command-line). # 'preamble' means setting sequentially to the values in the preamble. # 'preamble_or_first' means setting to the first value for the command # in the document if the first command is not in the preamble, else set # sequentially to the values in the preamble. # 'last' means setting to the last value for the command in the document. # # Notice that the only effect is to use set_conf (directly or through # set_global_document_command), no @-commands setting side effects are done # and associated customization variables are not set/reset either. sub set_global_document_commands($$$) { my $self = shift; my $commands_location = shift; my $selected_commands = shift; my $init_conf; if (defined($self->{'output_init_conf'})) { # use in priority the initial customization per output $init_conf = $self->{'output_init_conf'}; } else { $init_conf = $self->{'converter_init_conf'}; } if (not defined($selected_commands)) { die "set_global_document_commands: requires selected commands"; } if ($commands_location eq 'before') { foreach my $global_command (@{$selected_commands}) { # for commands not appearing in the document, this should set the # same value, the converter initialization value $self->set_conf($global_command, _command_init($global_command, $init_conf)); # NOTE if the variable is set from an handler, or in the converter after # $init_conf was set, but before starting the conversion, it is ignored here # and the $init_conf value is set. The previously set value could be # in $self->get_conf(), but what is available from $self->get_conf() could # also be a value set by a previous call of set_global_document_commands. # There is no easy way to deal with this issue, other than making sure that # a customization value that is expected to be set early is set in $init_conf. } } else { my $global_commands; if ($self->{'document'}) { $global_commands = $self->{'document'}->global_commands_information(); } foreach my $global_command (@{$selected_commands}) { if ($self->get_conf('DEBUG')) { print STDERR "SET_global($commands_location) $global_command\n"; } my $element; if ($global_commands) { $element = Texinfo::Common::set_global_document_command($self, $global_commands, $global_command, $commands_location); } if (not defined($element)) { # commands not appearing in the document, this should set the # same value, the converter initialization value # the NOTE above in 'before' holds here too. $self->set_conf($global_command, _command_init($global_command, $init_conf)); } } } } sub present_bug_message($$;$) { my $self = shift; my $message = shift; my $current = shift; my $line_message = ''; my $current_element_message = ''; if ($current) { if ($current->{'source_info'}) { my $source_info = $current->{'source_info'}; my $file = $source_info->{'file_name'}; $line_message = "in: $source_info->{'file_name'}:$source_info->{'line_nr'}"; if ($source_info->{'macro'} ne '') { $line_message .= " (possibly involving $source_info->{'macro'})"; } $line_message .= "\n"; } if ($current) { $current_element_message = "current: ". Texinfo::Common::debug_print_element($current, 1); } } my $additional_information = ''; if ($line_message.$current_element_message ne '') { $additional_information = "Additional information:\n". $line_message.$current_element_message."\n"; } warn "You found a bug: $message\n\n".$additional_information; } # Reverse the decoding of the file name from the input encoding. # A wrapper around Texinfo::Utils::encoded_input_file_name() that # can be called in converters through an objet oriented syntax. sub encoded_input_file_name($$;$) { my $self = shift; my $file_name = shift; my $input_file_encoding = shift; return Texinfo::Convert::Utils::encoded_input_file_name($self, $file_name, $input_file_encoding); } # A wrapper around Texinfo::Utils::encoded_output_file_name() that # can be called in converters through an objet oriented syntax. sub encoded_output_file_name($$) { my $self = shift; my $file_name = shift; return Texinfo::Convert::Utils::encoded_output_file_name($self, $file_name); } # This is used when the formatted text has no comment nor new line, but # one want to add the comment or new line from the original arg sub format_comment_or_return_end_line($$) { my $self = shift; my $element = shift; my $end_line; my $comment = $element->{'args'}->[-1]->{'info'}->{'comment_at_end'} if $element->{'args'} and $element->{'args'}->[-1]->{'info'}; if ($comment) { $end_line = $self->convert_tree($comment); } elsif ($element->{'args'} and $element->{'args'}->[-1]->{'info'} and $element->{'args'}->[-1]->{'info'}->{'spaces_after_argument'}) { my $text = $element->{'args'}->[-1] ->{'info'}->{'spaces_after_argument'}->{'text'}; if (chomp($text)) { $end_line = "\n"; } else { $end_line = ''; } } else { $end_line = ''; } return $end_line; }