[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
texinfo/tp Texinfo/Commands.pm Texinfo/Parser.p...
From: |
Patrice Dumas |
Subject: |
texinfo/tp Texinfo/Commands.pm Texinfo/Parser.p... |
Date: |
Fri, 12 Nov 2010 01:10:44 +0000 |
CVSROOT: /sources/texinfo
Module name: texinfo
Changes by: Patrice Dumas <pertusus> 10/11/12 01:10:44
Modified files:
tp/Texinfo : Commands.pm Parser.pm
tp/Texinfo/Convert: Line.pm Paragraph.pm Text.pm
tp/t : 02coverage.t test_utils.pl
tp/t/results/coverage: item_container.pl
tp/t/results/coverage_braces: footnote_ending_on_empty_line.pl
footnote_not_closed.pl
space_in_footnote.pl
tp/t/results/macro: empty_macro_in_text_no_arg.pl
paragraph_and_macro.pl
tp/t/results/paragraph: text_space_comment.pl
tp/t/results/value: bad_syntax.pl
Added files:
tp/Texinfo/Convert: Plaintext.pm
Log message:
Mark empty spaces before paragraphs especially.
Add a backend for plaintext output, work in progress.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Commands.pm?cvsroot=texinfo&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Parser.pm?cvsroot=texinfo&r1=1.147&r2=1.148
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/Line.pm?cvsroot=texinfo&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/Paragraph.pm?cvsroot=texinfo&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/Text.pm?cvsroot=texinfo&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/Plaintext.pm?cvsroot=texinfo&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/02coverage.t?cvsroot=texinfo&r1=1.24&r2=1.25
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/test_utils.pl?cvsroot=texinfo&r1=1.48&r2=1.49
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/results/coverage/item_container.pl?cvsroot=texinfo&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/results/coverage_braces/footnote_ending_on_empty_line.pl?cvsroot=texinfo&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/results/coverage_braces/footnote_not_closed.pl?cvsroot=texinfo&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/results/coverage_braces/space_in_footnote.pl?cvsroot=texinfo&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/results/macro/empty_macro_in_text_no_arg.pl?cvsroot=texinfo&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/results/macro/paragraph_and_macro.pl?cvsroot=texinfo&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/results/paragraph/text_space_comment.pl?cvsroot=texinfo&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/results/value/bad_syntax.pl?cvsroot=texinfo&r1=1.17&r2=1.18
Patches:
Index: Texinfo/Commands.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Commands.pm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- Texinfo/Commands.pm 6 Nov 2010 00:41:27 -0000 1.3
+++ Texinfo/Commands.pm 12 Nov 2010 01:10:43 -0000 1.4
@@ -344,6 +344,8 @@
# the next root command. @node and sectioning commands.
our %root_commands;
+our %sectioning_commands;
+
foreach my $sectioning_command (
'top',
'chapter',
@@ -374,6 +376,7 @@
} else {
$root_commands{$sectioning_command} = 1;
}
+ $sectioning_commands{$sectioning_command} = 1;
}
$root_commands{'node'} = 1;
Index: Texinfo/Parser.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Parser.pm,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -b -r1.147 -r1.148
--- Texinfo/Parser.pm 11 Nov 2010 15:15:40 -0000 1.147
+++ Texinfo/Parser.pm 12 Nov 2010 01:10:43 -0000 1.148
@@ -795,6 +795,7 @@
die "BUG: contents undef "._print_current($current)
if (!defined($current->{'contents'}));
+ # find whether an @indent precedes the paragraph
my $indent;
if (scalar(@{$current->{'contents'}})) {
my $index = scalar(@{$current->{'contents'}}) -1;
@@ -1237,7 +1238,13 @@
if ($current->{'contents'}->[-1]->{'text'} eq '') {
pop @{$current->{'contents'}}
} elsif ($current->{'contents'}->[-1]->{'type'} eq 'empty_line') {
+ # exactly the same condition than to begin a paragraph
+ if ((!$current->{'type'} or $type_with_paragraph{$current->{'type'}})
+ and !$no_paragraph_contexts{$self->{'context_stack'}->[-1]}) {
+ $current->{'contents'}->[-1]->{'type'} =
'empty_spaces_before_paragraph';
+ } else {
delete $current->{'contents'}->[-1]->{'type'};
+ }
} elsif ($current->{'contents'}->[-1]->{'type'} eq
'empty_line_after_command') {
$current->{'contents'}->[-1]->{'type'} = 'empty_spaces_after_command';
}
Index: Texinfo/Convert/Line.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Convert/Line.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- Texinfo/Convert/Line.pm 8 Nov 2010 23:50:47 -0000 1.1
+++ Texinfo/Convert/Line.pm 12 Nov 2010 01:10:43 -0000 1.2
@@ -69,6 +69,17 @@
return $width;
}
+# for debug
+sub dump($)
+{
+ my $self = shift;
+ my $word = 'UNDEF';
+ $word = $self->{'word'} if (defined($self->{'word'}));
+ my $end_sentence = 'UNDEF';
+ $end_sentence = $self->{'end_sentence'} if
(defined($self->{'end_sentence'}));
+ print STDERR "line ($self->{'line_beginning'}) word: $word, space
`$self->{'space'}' end_sentence: $self->{'end_sentence'}\n";
+}
+
# end a line.
sub end_line($)
{
Index: Texinfo/Convert/Paragraph.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Convert/Paragraph.pm,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- Texinfo/Convert/Paragraph.pm 8 Nov 2010 23:50:47 -0000 1.4
+++ Texinfo/Convert/Paragraph.pm 12 Nov 2010 01:10:43 -0000 1.5
@@ -44,8 +44,17 @@
bless $self, $class;
}
-# string fixed length size takeing into account that east asian characters
-# may take 2 spaces.
+# for debugging
+sub dump($)
+{
+ my $self = shift;
+ my $word = 'UNDEF';
+ $word = $self->{'word'} if (defined($self->{'word'}));
+ my $end_sentence = 'UNDEF';
+ $end_sentence = $self->{'end_sentence'} if
(defined($self->{'end_sentence'}));
+ print STDERR "para ($self->{'counter'}+$self->{'word_counter'}) word: $word,
space `$self->{'space'}' end_sentence: $self->{'end_sentence'}\n";
+}
+
# end a line.
sub end_line($)
{
Index: Texinfo/Convert/Text.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Convert/Text.pm,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- Texinfo/Convert/Text.pm 9 Nov 2010 23:02:46 -0000 1.17
+++ Texinfo/Convert/Text.pm 12 Nov 2010 01:10:43 -0000 1.18
@@ -518,8 +518,7 @@
},
);
-# node?
-my %kept_misc_commands;
+our %kept_misc_commands;
foreach my $command ('sp', 'center', 'exdent',
'item', 'itemx', 'tab', 'headitem',
'node',
@@ -551,7 +550,7 @@
my %ignored_types;
foreach my $type ('empty_line_after_command',
'empty_spaces_after_command', 'spaces_at_end',
- 'empty_spaces_before_argument') {
+ 'empty_spaces_before_argument', 'empty_spaces_before_paragraph') {
$ignored_types{$type} = 1;
}
Index: t/02coverage.t
===================================================================
RCS file: /sources/texinfo/texinfo/tp/t/02coverage.t,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -b -r1.24 -r1.25
--- t/02coverage.t 11 Nov 2010 15:15:42 -0000 1.24
+++ t/02coverage.t 12 Nov 2010 01:10:43 -0000 1.25
@@ -12,38 +12,9 @@
@majorheading majorheading @b{in b}
'],
-['arg_in_brace_no_arg_command',
-'@TeX{in tex}
-'],
['lettered_accent_and_spaces',
'@ringaccent a
'],
-['accents_errors',
-'accent at end of line @ringaccent
-accent at end of line and spaces @ringaccent
-accent followed by @@ @address@hidden
-
-accent character with spaces @~ following.
-accent character at end of line @~
-accent character followed by @@ @address@hidden
-
-With @@:
address@hidden @@. @^@@.
-'],
-['accent_no_closed',
-'@~{e'],
-['accent_no_closed_newline',
-'@~{e
-
-'],
-['accent_no_closed_paragraph',
-'@~{e
-
-other para.
-'],
-['accent_no_closed_comment',
-'@~{e @c comment
-'],
['math',
'Simple math
@math{{x^i}\over{\tan y}}
@@ -260,6 +231,37 @@
After quotation sp b a
@end group
+']);
+
+my @test_invalid = (
+['arg_in_brace_no_arg_command',
+'@TeX{in tex}
+'],
+['accents_errors',
+'accent at end of line @ringaccent
+accent at end of line and spaces @ringaccent
+accent followed by @@ @address@hidden
+
+accent character with spaces @~ following.
+accent character at end of line @~
+accent character followed by @@ @address@hidden
+
+With @@:
address@hidden @@. @^@@.
+'],
+['accent_no_closed',
+'@~{e'],
+['accent_no_closed_newline',
+'@~{e
+
+'],
+['accent_no_closed_paragraph',
+'@~{e
+
+other para.
+'],
+['accent_no_closed_comment',
+'@~{e @c comment
'],
['flushright_not_closed',
'@flushright
@@ -277,7 +279,11 @@
']
);
+foreach my $test (@test_cases) {
+ $test->[2]->{'test_formats'} = ['plaintext'];
+}
+
our ($arg_test_case, $arg_generate, $arg_debug);
-run_all ('coverage', address@hidden, $arg_test_case,
+run_all ('coverage', address@hidden, @test_invalid], $arg_test_case,
$arg_generate, $arg_debug);
Index: t/test_utils.pl
===================================================================
RCS file: /sources/texinfo/texinfo/tp/t/test_utils.pl,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -b -r1.48 -r1.49
--- t/test_utils.pl 11 Nov 2010 15:15:42 -0000 1.48
+++ t/test_utils.pl 12 Nov 2010 01:10:43 -0000 1.49
@@ -5,6 +5,8 @@
use Texinfo::Convert::Text;
use Texinfo::Convert::Texinfo;
use Texinfo::Structuring;
+use lib '../texi2html/lib/Unicode-EastAsianWidth/lib/';
+use Texinfo::Convert::Plaintext;
use File::Basename;
use Data::Dumper;
use Data::Compare;
@@ -156,10 +158,11 @@
sub filter_floats_keys { [grep {!$avoided_keys_floats{$_}}
( sort keys %{$_[0]} )] }
-sub convert_to_plaintext($)
+sub convert_to_plaintext($$)
{
+ my $self = shift;
my $tree = shift;
- my $converter = Texinfo::Convert::Plaintext::new();
+ my $converter = Texinfo::Convert::Plaintext::converter({'debug' =>
$self->{'debug'}});
return $converter->convert($tree);
}
@@ -185,6 +188,7 @@
my @tested_formats;
if ($parser_options and $parser_options->{'test_formats'}) {
push @tested_formats, @{$parser_options->{'test_formats'}};
+ delete $parser_options->{'test_formats'};
}
my $parser = Texinfo::Parser->parser({'test' => 1,
@@ -222,7 +226,8 @@
my %converted;
foreach my $format (@tested_formats) {
- $converted{$format} = &{$formats{$format}}($result);
+ # $converted{$format} = &{$formats{$format}}($self, $result);
+ # print STDERR "$format: \n$converted{$format}";
}
my $file = "t/results/$self->{'name'}/$test_name.pl";
Index: t/results/coverage/item_container.pl
===================================================================
RCS file: /sources/texinfo/texinfo/tp/t/results/coverage/item_container.pl,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- t/results/coverage/item_container.pl 10 Nov 2010 18:21:21 -0000
1.17
+++ t/results/coverage/item_container.pl 12 Nov 2010 01:10:43 -0000
1.18
@@ -128,7 +128,8 @@
},
{
'parent' => {},
- 'text' => ' '
+ 'text' => ' ',
+ 'type' => 'empty_spaces_before_paragraph'
},
{
'contents' => [
@@ -206,7 +207,7 @@
$result_texts{'item_container'} = '
i--tem +
- b--ullet
+b--ullet
';
$result_errors{'item_container'} = [];
Index: t/results/coverage_braces/footnote_ending_on_empty_line.pl
===================================================================
RCS file:
/sources/texinfo/texinfo/tp/t/results/coverage_braces/footnote_ending_on_empty_line.pl,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- t/results/coverage_braces/footnote_ending_on_empty_line.pl 1 Nov 2010
09:01:02 -0000 1.8
+++ t/results/coverage_braces/footnote_ending_on_empty_line.pl 12 Nov 2010
01:10:43 -0000 1.9
@@ -16,7 +16,8 @@
'contents' => [
{
'parent' => {},
- 'text' => ' '
+ 'text' => ' ',
+ 'type' => 'empty_spaces_before_paragraph'
},
{
'contents' => [
Index: t/results/coverage_braces/footnote_not_closed.pl
===================================================================
RCS file:
/sources/texinfo/texinfo/tp/t/results/coverage_braces/footnote_not_closed.pl,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- t/results/coverage_braces/footnote_not_closed.pl 1 Nov 2010 09:01:03
-0000 1.7
+++ t/results/coverage_braces/footnote_not_closed.pl 12 Nov 2010 01:10:43
-0000 1.8
@@ -16,7 +16,8 @@
'contents' => [
{
'parent' => {},
- 'text' => ' '
+ 'text' => ' ',
+ 'type' => 'empty_spaces_before_paragraph'
},
{
'contents' => [
Index: t/results/coverage_braces/space_in_footnote.pl
===================================================================
RCS file:
/sources/texinfo/texinfo/tp/t/results/coverage_braces/space_in_footnote.pl,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- t/results/coverage_braces/space_in_footnote.pl 1 Nov 2010 09:01:03
-0000 1.8
+++ t/results/coverage_braces/space_in_footnote.pl 12 Nov 2010 01:10:43
-0000 1.9
@@ -16,7 +16,8 @@
'contents' => [
{
'parent' => {},
- 'text' => ' '
+ 'text' => ' ',
+ 'type' => 'empty_spaces_before_paragraph'
},
{
'contents' => [
Index: t/results/macro/empty_macro_in_text_no_arg.pl
===================================================================
RCS file:
/sources/texinfo/texinfo/tp/t/results/macro/empty_macro_in_text_no_arg.pl,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- t/results/macro/empty_macro_in_text_no_arg.pl 1 Nov 2010 09:01:08
-0000 1.9
+++ t/results/macro/empty_macro_in_text_no_arg.pl 12 Nov 2010 01:10:44
-0000 1.10
@@ -40,7 +40,8 @@
},
{
'parent' => {},
- 'text' => ' '
+ 'text' => ' ',
+ 'type' => 'empty_spaces_before_paragraph'
},
{
'contents' => [
@@ -135,7 +136,7 @@
$result_texts{'empty_macro_in_text_no_arg'} = '
- This. It.
+This. It.
This 2 see. A.
Index: t/results/macro/paragraph_and_macro.pl
===================================================================
RCS file: /sources/texinfo/texinfo/tp/t/results/macro/paragraph_and_macro.pl,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- t/results/macro/paragraph_and_macro.pl 1 Nov 2010 09:01:09 -0000
1.15
+++ t/results/macro/paragraph_and_macro.pl 12 Nov 2010 01:10:44 -0000
1.16
@@ -148,7 +148,8 @@
},
{
'parent' => {},
- 'text' => ' '
+ 'text' => ' ',
+ 'type' => 'empty_spaces_before_paragraph'
},
{
'contents' => [
@@ -193,7 +194,8 @@
},
{
'parent' => {},
- 'text' => ' '
+ 'text' => ' ',
+ 'type' => 'empty_spaces_before_paragraph'
},
{
'contents' => [
@@ -271,13 +273,13 @@
- text after empty.
+text after empty.
- text after space.
+text after space.
';
$result_errors{'paragraph_and_macro'} = [];
Index: t/results/paragraph/text_space_comment.pl
===================================================================
RCS file:
/sources/texinfo/texinfo/tp/t/results/paragraph/text_space_comment.pl,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- t/results/paragraph/text_space_comment.pl 1 Nov 2010 09:01:10 -0000
1.11
+++ t/results/paragraph/text_space_comment.pl 12 Nov 2010 01:10:44 -0000
1.12
@@ -6,7 +6,8 @@
'contents' => [
{
'parent' => {},
- 'text' => ' '
+ 'text' => ' ',
+ 'type' => 'empty_spaces_before_paragraph'
},
{
'contents' => [
@@ -41,7 +42,7 @@
$result_texis{'text_space_comment'} = ' text @c space comment';
-$result_texts{'text_space_comment'} = ' text ';
+$result_texts{'text_space_comment'} = 'text ';
$result_errors{'text_space_comment'} = [];
Index: t/results/value/bad_syntax.pl
===================================================================
RCS file: /sources/texinfo/texinfo/tp/t/results/value/bad_syntax.pl,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- t/results/value/bad_syntax.pl 1 Nov 2010 09:01:14 -0000 1.17
+++ t/results/value/bad_syntax.pl 12 Nov 2010 01:10:44 -0000 1.18
@@ -45,7 +45,8 @@
{
'parent' => {},
'text' => '
-'
+',
+ 'type' => 'empty_spaces_before_paragraph'
},
{
'contents' => [
@@ -106,7 +107,6 @@
$result_texts{'bad_syntax'} = '
-
gurgl
Index: Texinfo/Convert/Plaintext.pm
===================================================================
RCS file: Texinfo/Convert/Plaintext.pm
diff -N Texinfo/Convert/Plaintext.pm
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Texinfo/Convert/Plaintext.pm 12 Nov 2010 01:10:43 -0000 1.1
@@ -0,0 +1,427 @@
+# Plaintext.pm: output tree as text.
+#
+# Copyright 2010 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 <address@hidden>
+
+package Texinfo::Convert::Plaintext;
+
+use 5.00405;
+use strict;
+
+use Texinfo::Commands;
+use Texinfo::Convert::Texinfo;
+use Texinfo::Convert::Text;
+use Texinfo::Convert::Paragraph;
+use Texinfo::Convert::Line;
+
+require Exporter;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
address@hidden = qw(Exporter);
+
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+
+# This allows declaration use Texinfo::Covert::Text ':all';
+# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
+# will save memory.
+%EXPORT_TAGS = ( 'all' => [ qw(
+ convert
+) ] );
+
address@hidden = ( @{ $EXPORT_TAGS{'all'} } );
+
address@hidden = qw(
+);
+
+$VERSION = '0.01';
+
+my %kept_misc_commands = %Texinfo::Convert::Text::kept_misc_commands;
+# 'sp', 'center', 'exdent',
+# 'item', 'itemx', 'tab', 'headitem',
+# 'node',
+
+foreach my $kept_command('verbatiminclude', 'insertcopying', 'printindex',
+ 'listoffloats', 'dircategory', 'paragraphindent', 'firstparagraphindent',
+ 'frenchspacing', 'documentencoding', 'footnotestyle', 'documentlanguage',
+ 'setshortcontentsaftertitlepage', 'setcontentsaftertitlepage',
+ 'contents', 'shortcontents', 'summarycontents',
+ 'author', 'shorttitle', 'shorttitlepage', 'settitle', 'subtitle',
+ 'title') {
+ $kept_misc_commands{$kept_command} = 1;
+}
+my %text_no_brace_commands = %Texinfo::Convert::Text::text_no_brace_commands;
+my %text_brace_no_arg_commands =
%Texinfo::Convert::Text::text_brace_no_arg_commands;
+my %accent_commands = %Texinfo::Commands::accent_commands;
+my %misc_commands = %Texinfo::Commands::misc_commands;
+my %sectioning_commands = %Texinfo::Commands::sectioning_commands;
+
+my %ignored_misc_commands;
+foreach my $misc_command (keys(%misc_commands)) {
+ $ignored_misc_commands{$misc_command} = 1
+ unless ($kept_misc_commands{$misc_command});
+}
+
+my %ignored_commands = %ignored_misc_commands;
+foreach my $ignored_brace_commands ('caption', 'shortcation',
+ 'hyphenation') {
+ $ignored_commands{$ignored_brace_commands} = 1;
+}
+
+# FIXME pass raw formats handled (or not handled)
+foreach my $ignored_block_commands ('ignore', 'macro', 'rmacro') {
+ $ignored_commands{$ignored_block_commands} = 1;
+}
+
+my %code_style_commands;
+foreach my $command ('code', 'command', 'env', 'file', 'kbd', 'key', 'option',
+ 'samp', 'indicateurl', 'verb') {
+ $code_style_commands{$command} = 1;
+}
+
+my %ignored_types;
+foreach my $type ('empty_line_after_command',
+ 'empty_spaces_after_command', 'spaces_at_end',
+ 'empty_spaces_before_argument', 'empty_spaces_before_paragraph') {
+ $ignored_types{$type} = 1;
+}
+
+# All those commands run with the text.
+# FIXME w may be diferent here.
+my %style_map = (
+ 'strong' => '*',
+ 'dfn' => '"',
+ 'emph' => '_',
+);
+
+foreach my $command (keys(%style_map)) {
+ $style_map{$command} = [$style_map{$command}, $style_map{$command}];
+}
+
+my @asis_commands = ('asis', 'w', 'b', 'ctrl', 'i', 'math', 'sc', 't', 'r',
+ 'slanted', 'sansserif', 'var', 'titlefont', 'verb', 'clickstyle',
+ 'headitemfont');
+
+foreach my $asis_command (@asis_commands) {
+ $style_map{$asis_command} = ['', ''];
+}
+
+my @quoted_commands = ('cite', 'code', 'command', 'env', 'file', 'kbd',
+ 'option', 'samp');
+
+foreach my $quoted_command (@quoted_commands) {
+ $style_map{$quoted_command} = ['`', "'"];
+}
+
+$style_map{'key'} = ['<', '>'];
+$style_map{'indicateurl'} = ['<', '>'];
+
+# in those commands, there is no addition of double space after a dot.
+my %no_punctation_munging_commands;
+foreach my $command ('var', 'cite', 'math', keys(%code_style_commands)) {
+ $no_punctation_munging_commands{$command} = 1;
+}
+
+my %defaults = (
+ 'frenchspacing' => 0,
+ 'paragraphindent' => 3,
+ 'firstparagraphindent' => 'none',
+ 'enable_encoding' => 1,
+ 'footnotestyle' => 'end',
+ 'fillcolumn' => 72,
+ 'documentencoding' => 'us-ascii',
+ 'number_footnotes' => 1,
+
+ 'debug' => 0
+);
+
+sub converter(;$)
+{
+ my $class = shift;
+ my $converter = { 'set' => {} };
+
+ my $conf;
+ my $name = 'converter';
+
+ if (ref($class) eq 'HASH') {
+ $conf = $class;
+ bless $converter;
+ } elsif (defined($class)) {
+ bless $converter, $class;
+ $name = ref($class);
+ $conf = shift;
+ } else {
+ bless $converter;
+ $conf = shift;
+ $name = ref($converter);
+ }
+ if (defined($conf)) {
+ foreach my $key (keys(%$conf)) {
+ if (!exists($defaults{$key})) {
+ warn "$key not a possible configuration in $name\n";
+ } else {
+ $converter->{$key} = $conf->{$key};
+ $converter->{'set'}->{$key} = 1;
+ }
+ }
+ }
+ foreach my $key (keys(%defaults)) {
+ $converter->{$key} = $defaults{$key} if (!$converter->{'set'}->{$key});
+ }
+ $converter->{'paragraph_conf'} = {
+ 'frenchspacing' => $converter->{'frenchspacing'},
+ 'max' => $converter->{'fillcolumn'},
+ # 'indent' => $converter->{'paragraphindent'},
+ # 'indent_length_next' => 0
+ };
+ $converter->{'context'} = ['_Root_context'];
+ $converter->{'containers'} = [];
+ return $converter;
+}
+
+sub _normalise_space($)
+{
+ return undef unless (defined ($_[0]));
+ my $text = shift;
+ $text =~ s/\s+/ /go;
+ $text =~ s/ $//;
+ $text =~ s/^ //;
+ return $text;
+}
+
+sub process_text($$)
+{
+ my $self = shift;
+ my $command = shift;
+ my $text = $command->{'text'};
+
+ $text = uc($text) if ($self->{'upper_case'});
+ if ($self->{'enable_encoding'} and $self->{'document_encoding'} eq 'utf-8') {
+ return Texinfo::Convert::Unicode($self, $command);
+ } elsif (!$self->{'code'} and !$self->{'context'}->[-1] eq 'preformatted') {
+ $text =~ s/---/\x{1F}/g;
+ $text =~ s/--/-/g;
+ $text =~ s/\x{1F}/--/g;
+ $text =~ s/``/"/g;
+ $text =~ s/\'\'/"/g;
+ }
+}
+
+# code
+# sp
+# var, sc -> 'upper_case'
+# preformatted
+sub convert($$);
+
+sub convert($$)
+{
+ my $self = shift;
+ my $root = shift;
+
+ if ($self->{'debug'}) {
+ print STDERR "root (@{$self->{'context'}})\n";
+ print STDERR " Command: $root->{'cmdname'}\n" if ($root->{'cmdname'});
+ print STDERR " Type: $root->{'type'}\n" if ($root->{'type'});
+ print STDERR " Text: $root->{'text'}\n" if (defined($root->{'text'}));
+ #print STDERR " Special def_command: $root->{'extra'}->{'def_command'}\n"
+ # if (defined($root->{'extra'}) and $root->{'extra'}->{'def_command'});
+ if (@{$self->{'containers'}}) {
+ print STDERR " Container:";
+ $self->{'containers'}->[-1]->dump();
+ }
+ }
+
+ # if it is a paragraph, process the text and commands.
+ # if it is a simple_text_command 'indicateurl',
+ # 'email', 'uref', 'url',
+ # 'dmn', 'ctrl'
+ # accent_commands it is returned with the inside expanded
+ # and further processed as text, with invalid_nesting commands ignored.
+ # another @command is incorporated
+ #
+ # other commands processed:
+ # verbatiminclude
+ # sp
+ # insertcopying
+ # printindex
+ # listoffloats
+ # dircategory
+ # paragraphindent firstparagraphindent frenchspacing documentencoding
+ # footnotestyle
+ # documentlanguage?
+ # center
+ # author (in quotation?)
+ # shorttitle/shorttitlepage/settitle/subtitle/title
+ # exdent
+# not info but plaintext
+# setshortcontentsaftertitlepage setcontentsaftertitlepage
+# @contents or @shortcontents
+
+ # paragraph left right center line
+
+ # NUMBER_FOOTNOTES SPLIT_SIZE IN_ENCODING FILLCOLUMN ENABLE_ENCODING
+ # OUT_ENCODING ENCODING_NAME
+
+ return '' if (($root->{'type'} and $ignored_types{$root->{'type'}})
+ or ($root->{'cmdname'} and
$ignored_commands{$root->{'cmdname'}}));
+ my $result = '';
+ my $paragraph;
+ my $line;
+ if (defined($root->{'text'})) {
+ $result .= $self->{'containers'}->[-1]->add_text($root->{'text'});
+ }
+ if ($root->{'cmdname'}) {
+ my $command = $root->{'cmdname'};
+ if (defined($text_no_brace_commands{$root->{'cmdname'}})) {
+ if ($command eq ':') {
+ $self->{'containers'}->[-1]->inhibit_end_sentence();
+ } elsif ($command eq '*') {
+ $result .= $self->{'containers'}->[-1]->add_pending_word();
+ $result .= $self->{'containers'}->[-1]->end_line();
+ } elsif ($command eq '.' or $command eq '?' or $command eq '!') {
+ $result .= $self->{'containers'}->[-1]->add_next($command, undef, 1),
+ } elsif ($command eq ' ' or $command eq "\n" or $command eq "\t") {
+ $result .=
$self->{'containers'}->[-1]->add_next($text_no_brace_commands{$root->{'cmdname'}});
+ } else {
+ $result .=
$self->{'containers'}->[-1]->add_text($text_no_brace_commands{$root->{'cmdname'}});
+ }
+ } elsif (defined($text_brace_no_arg_commands{$root->{'cmdname'}})) {
+ $command = $root->{'extra'}->{'clickstyle'}
+ if ($root->{'extra'}
+ and defined($root->{'extra'}->{'clickstyle'})
+ and
defined($text_brace_no_arg_commands{$root->{'extra'}->{'clickstyle'}}));
+ $result .=
$self->{'containers'}->[-1]->add_text($text_brace_no_arg_commands{$command});
+ # commands with braces
+ } elsif ($accent_commands{$root->{'cmdname'}}) {
+ $result .= $self->{'containers'}->[-1]->add_text(
+ Texinfo::Convert::Text::text_accents($root, $self->{'encoding'}));
+ return $result;
+ } elsif ($root->{'cmdname'} eq 'image') {
+ return $self->convert($root->{'args'}->[0]);
+ } elsif ($root->{'cmdname'} eq 'email') {
+
+ my @email_contents;
+ if ($root->{'extra'} and $root->{'extra'}->{'brace_command_contents'}) {
+ if (scalar (@{$root->{'extra'}->{'brace_command_contents'}}) == 2
+ and defined($root->{'extra'}->{'brace_command_contents'}->[-1])) {
+ @email_contents =
(@{$root->{'extra'}->{'brace_command_contents'}->[1]},
+ {'text' => ' '});
+ }
+ if (defined($root->{'extra'}->{'brace_command_contents'}->[0])) {
+ push @email_contents, {'cmdname' => 'indicateurl',
+ 'args' => [ { 'type' => 'brace_command_arg',
+ 'contents' =>
$root->{'extra'}->{'brace_command_contents'}->[0],
+ } ],
+ 'extra' => {'brace_command_contents' =>
[$root->{'extra'}->{'brace_command_contents'}->[0]] } };
+ }
+ unshift @{$self->{'current_contents'}->[-1]}, @email_contents;
+ }
+ return;
+ } elsif ($style_map{$command}) {
+ $result .=
$self->{'containers'}->[-1]->add_text($style_map{$command}->[0]);
+ $result .= $self->convert($root->{'args'}->[0]);
+ $result .=
$self->{'containers'}->[-1]->add_text($style_map{$command}->[1]);
+ } elsif ($command eq 'footnote') {
+ } elsif ($command eq 'anchor') {
+ } elsif ($root->{'args'} and $root->{'args'}->[0]
+ and (($root->{'args'}->[0]->{'type'}
+ and $root->{'args'}->[0]->{'type'} eq 'brace_command_arg')
+ or $root->{'cmdname'} eq 'math')) {
+ return $self->convert($root->{'args'}->[0]);
+ # block commands
+ } elsif (($root->{'cmdname'} eq 'quotation'
+ or $root->{'cmdname'} eq 'smallquotation')) {
+ if ($root->{'extra'} and
$root->{'extra'}->{'block_command_line_contents'}) {
+ my $quotation_arg = Texinfo::Convert::Texinfo::convert(
+ {'contents' =>
$root->{'extra'}->{'block_command_line_contents'}->[0]});
+ my $prepended = Texinfo::Parser::parse_texi_line (undef,
'@b{'.${quotation_arg}.':} ');
+ #return gdt('@b{{quotation_arg}:} ', {'quotation_arg' => $text},
{'keep_texi' => 1});
+ #$result = convert($root->{'args'}->[0]) ."\n";
+ }
+ } elsif ($root->{'cmdname'} eq 'node') {
+ # FIXME handle node
+ } elsif ($root->{'extra'} and ($root->{'extra'}->{'misc_content'}
+ or $root->{'extra'}->{'misc_args'})) {
+ if ($sectioning_commands{$root->{'cmdname'}}
+ or $root->{'cmdname'} eq 'item' or $root->{'cmdname'} eq
'itemx') {
+ # FIXME handle sectioning commands with their underline
+ # and item with their prepending
+ $line = Texinfo::Convert::Line->new($self->{'paragraph_conf'});
+ push @{$self->{'containers'}}, $line;
+ $result = $self->convert($root->{'args'}->[0]);
+ $result .= $line->end();
+ pop @{$self->{'containers'}};
+ chomp ($result);
+
+ $result .= "\n";
+ } elsif ($root->{'cmdname'} eq 'sp') {
+ if ($root->{'extra'}->{'misc_args'}->[0]) {
+ # this useless copy avoids perl changing the type to integer!
+ my $sp_nr = $root->{'extra'}->{'misc_args'}->[0];
+ $result .= "\n" x $sp_nr;
+ }
+ } else {
+ my $index_entry;
+ $index_entry = 1
+ if ($root->{'extra'} and $root->{'extra'}->{'index_entry'});
+ if ($root->{'cmdname'} eq 'item' or $root->{'cmdname'} eq 'itemx') {
+ $index_entry = 0;
+ }
+ if ($root->{'extra'} and $root->{'extra'}->{'index_entry'}) {
+ # FIXME do something for index entry?
+ }
+ }
+ }
+ } elsif ($root->{'type'} and $root->{'type'} eq 'paragraph') {
+ $self->{'empty_lines_count'} = 0;
+ $paragraph = Texinfo::Convert::Paragraph->new($self->{'paragraph_conf'});
+ push @{$self->{'containers'}}, $paragraph;
+ }
+ if ($root->{'type'} and $root->{'type'} eq 'def_line') {
+ #print STDERR "$root->{'extra'}->{'def_command'}\n";
+ $result = $self->convert($root->{'args'}->[0]) if ($root->{'args'});
+ } elsif ($root->{'type'} and $root->{'type'} eq 'menu_entry') {
+ foreach my $arg (@{$root->{'args'}}) {
+ $result .= $self->convert($arg);
+ }
+ }
+ if ($root->{'contents'}) {
+ my @contents = @{$root->{'contents'}};
+ push @{$self->{'current_contents'}}, address@hidden;
+ while (@contents) {
+ my $content = shift @contents;
+ if (!$paragraph and $content->{'type'}
+ and $content->{'type'} eq 'empty_line') {
+ $result .= "\n" if (!$self->{'empty_lines_count'});
+ $self->{'empty_lines_count'}++;
+ } else {
+ $result .= $self->convert($content);
+ }
+ }
+ pop @{$self->{'current_contents'}};
+ }
+ $result = '{'.$result.'}'
+ if ($root->{'type'} and $root->{'type'} eq 'bracketed'
+ and $self->{'context'}->[-1] eq 'math');
+ if ($paragraph) {
+ $result .= $paragraph->end();
+ pop @{$self->{'containers'}};
+ }
+ return $result;
+}
+
+1;