| # DebugTexinfo::DebugTree.pm: debug a Texinfo::Parser tree. |
| # |
| # Copyright 2011, 2012, 2013 Free Software Foundation, Inc. |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, |
| # or (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| # |
| # Original author: Patrice Dumas <pertusus@free.fr> |
| |
| # Example of calls |
| # with creation of elements corresponding to sections: |
| # ./texi2any.pl --set TEXINFO_OUTPUT_FORMAT=debugtree --set USE_NODES=0 file.texi |
| # with creation of elements corresponding to nodes: |
| # ./texi2any.pl --set TEXINFO_OUTPUT_FORMAT=debugtree --set USE_NODES=1 file.texi |
| # no elements |
| # ./texi2any.pl --set TEXINFO_OUTPUT_FORMAT=debugtree file.texi |
| # |
| # Some unofficial info about the --debug command line option ... with |
| # --debug=1, the tree is not printed, |
| # --debug=10 (or more), the tree is printed at the end of the run, |
| # --debug=100 (or more), the tree is printed at each newline. |
| |
| use strict; |
| |
| package DebugTexinfo::DebugTree; |
| |
| # also for __( |
| use Texinfo::Common; |
| use Texinfo::Structuring; |
| use Texinfo::Convert::Converter; |
| |
| use vars qw($VERSION @ISA); |
| @ISA = qw(Texinfo::Convert::Converter); |
| |
| my %defaults = ( |
| 'EXTENSION' => 'debugtree', |
| 'OUTFILE' => '-', |
| ); |
| |
| sub converter_defaults($$) |
| { |
| return %defaults; |
| } |
| |
| sub output($$) |
| { |
| my $self = shift; |
| my $root = shift; |
| |
| my ($output_file, $destination_directory) = $self->determine_files_and_directory(); |
| # REMARK for this format SPLIT does not means diverse files created |
| # so the way the directory is determined/created if there is already |
| # a file with the same name does not make sense for this format. |
| # Given that this format is only to be used for debugging, this is |
| # not an issue that really needs fixing. |
| |
| my $elements; |
| if ($self) { |
| if ($self->get_conf('USE_NODES')) { |
| $elements = Texinfo::Structuring::split_by_node($root); |
| } elsif (defined($self->get_conf('USE_NODES'))) { |
| #print STDERR "U sections\n"; |
| $elements = Texinfo::Structuring::split_by_section($root); |
| } |
| # Currently the information added is not used further. |
| if ($elements and ($self->get_conf('SPLIT') |
| or !$self->get_conf('MONOLITHIC'))) { |
| #print STDERR "S ".$self->get_conf('SPLIT')."\n"; |
| Texinfo::Structuring::split_pages($elements, |
| $self->get_conf('SPLIT')); |
| } |
| } |
| if ($elements) { |
| $root = {'type' => 'elements_root', |
| 'contents' => $elements }; |
| } |
| |
| my ($encoded_destination_directory, $dir_encoding) |
| = $self->encoded_output_file_name($destination_directory); |
| my $succeeded |
| = $self->create_destination_directory($encoded_destination_directory, |
| $destination_directory); |
| return undef unless $succeeded; |
| |
| my $fh; |
| my $encoded_output_file; |
| if (! $output_file eq '') { |
| my $path_encoding; |
| ($encoded_output_file, $path_encoding) |
| = $self->encoded_output_file_name($output_file); |
| my $error_message; |
| ($fh, $error_message) = Texinfo::Common::output_files_open_out( |
| $self->output_files_information(), $self, |
| $encoded_output_file); |
| if (!$fh) { |
| $self->document_error($self, |
| sprintf(__("could not open %s for writing: %s"), |
| $output_file, $error_message)); |
| return undef; |
| } |
| } |
| my $result = $self->write_or_return(_print_tree($self, $root), $fh); |
| # NOTE that we close STDOUT too here |
| if ($fh) { |
| Texinfo::Common::output_files_register_closed( |
| $self->output_files_information(), $encoded_output_file); |
| if (!close ($fh)) { |
| $self->document_error($self, |
| sprintf(__("error on closing %s: %s"), |
| $output_file, $!)); |
| return undef; |
| } |
| } |
| return $result; |
| } |
| |
| sub convert($$) |
| { |
| my $self = shift; |
| my $root = shift; |
| |
| return _print_tree($self, $root); |
| } |
| |
| sub convert_tree($$) |
| { |
| my $self = shift; |
| my $root = shift; |
| |
| return _print_tree($self, $root); |
| } |
| |
| sub _print_tree($$;$$); |
| |
| sub _protect_text($) |
| { |
| my $text = shift; |
| $text =~ s/\n/\\n/g; |
| $text =~ s/\f/\\f/g; |
| $text =~ s/\r/\\r/g; |
| return $text; |
| } |
| |
| sub _print_tree($$;$$) |
| { |
| my $self = shift; |
| my $element = shift; |
| my $level = shift; |
| my $argument = shift; |
| $level = 0 if (!defined($level)); |
| |
| my $result = ' ' x $level; |
| if ($argument) { |
| $result .= '%'; |
| $level++; |
| } |
| if ($element->{'cmdname'}) { |
| $result .= "\@$element->{'cmdname'} "; |
| } |
| if (defined($element->{'type'})) { |
| $result .= "$element->{'type'} "; |
| } |
| if (defined($element->{'text'})) { |
| my $text = _protect_text($element->{'text'}); |
| $result .= "|$text|"; |
| } |
| if ($element->{'info'} |
| and defined($element->{'info'}->{'spaces_before_argument'})) { |
| $result .= ' ' |
| .'b/'._protect_text($element->{'info'}->{'spaces_before_argument'}).'/'; |
| } |
| if ($element->{'info'} |
| and defined($element->{'info'}->{'spaces_after_argument'})) { |
| $result .= ' ' |
| .'a/'._protect_text($element->{'info'}->{'spaces_after_argument'}).'/'; |
| } |
| $result .= "\n"; |
| if ($element->{'info'} |
| and defined($element->{'info'}->{'comment_at_end'})) { |
| $result .= ' ' x ($level + 1).'/comment_at_end/'."\n"; |
| $result .= _print_tree ($self, $element->{'info'}->{'comment_at_end'}, |
| $level +2); |
| } |
| if ($element->{'args'}) { |
| foreach my $arg (@{$element->{'args'}}) { |
| $result .= _print_tree ($self, $arg, $level +1, 1); |
| } |
| } |
| if ($element->{'contents'}) { |
| foreach my $content (@{$element->{'contents'}}) { |
| $result .= _print_tree ($self, $content, $level+1); |
| } |
| } |
| return $result; |
| } |