File Coverage

blib/lib/SpeL/Object/Command.pm
Criterion Covered Total %
statement 50 63 79.3
branch 14 28 50.0
condition 1 3 33.3
subroutine 8 8 100.0
pod 1 1 100.0
total 74 103 71.8


line stmt bran cond sub pod time code
1             # -*- cperl -*-
2             package SpeL::Object::Command;
3             # ABSTRACT: SpeL command object
4              
5              
6 41     41   276 use strict;
  41         77  
  41         1951  
7 41     41   210 use warnings;
  41         107  
  41         2129  
8              
9 41     41   223 use parent 'Exporter';
  41         102  
  41         290  
10 41     41   3207 use Carp;
  41         119  
  41         2921  
11              
12 41     41   239 use SpeL::Object::Option;
  41         78  
  41         1914  
13 41     41   228 use SpeL::Object::ElementList;
  41         84  
  41         1846  
14              
15 41     41   19217 use SpeL::I18n;
  41         152  
  41         39162  
16              
17             our $macrohash = {};
18             our $labelhash = {};
19             our $citationhash = {};
20              
21              
22              
23             sub read {
24 46     46 1 103 my $self = shift;
25 46         96 my ( $level ) = @_;
26              
27 46         151 my $command = $self->{Name};
28              
29 46         149 my $returnvalue = ' ';
30              
31            
32             # 1. check if this macro can be found
33 46 50       189 if ( exists $SpeL::Object::Command::macrohash->{$command} ) {
34 46         104 my $macro = $SpeL::Object::Command::macrohash->{$command};
35              
36 46 100       210 $macro->{argc} = 0 if ( $macro->{argc} eq '-NoValue-' );
37            
38             # make parameter list
39 46         83 my @parameterlist;
40             # 1. perform sanity check: if the macro has a '-NoValue-' optarg,
41             # then there cannot be any field in the Command. Fatal error!
42             croak( "Error: usage of macro not consistent with its definition\n" .
43             "The definition \\$command does not specify optional values, " .
44             "while the usage specifies an optional argument.\n" )
45             if ( $macro->{optarg} eq '-NoValue-'
46 46 50 33     328 and exists $self->{Options} );
47              
48             # 2. Check if the field exists, then push this onto parameter list
49             # else, grab the optarg and if it is valid, push that on the list
50 46 50       127 if ( exists $self->{Options} ) {
51 0         0 push @parameterlist, $self->{Options}->read( $level + 1 );
52             } else {
53             push @parameterlist, $macro->{optarg}
54 46 50       164 unless $macro->{optarg} eq '-NoValue-';
55             }
56              
57             # 3. Push all remaining <[Args]> onto the parameter list
58 46         86 foreach my $arg ( @{$self->{Args}} ) {
  46         158  
59 19         96 push @parameterlist, $arg->read( $level + 1 );
60             }
61              
62             # 4. perform sanity check: the marco's argc should be equal or higher
63             # to length of the parameter list. Fatal error!
64             # too many arguments are just parsed as if they were in 'trailing'
65             # grouping brackets
66             croak( "Error: usage of macro not consistent with its definition\n" .
67             "The definition of \\$command does specify $macro->{argc} arguments " .
68 0         0 "while the usage specifies @{[ scalar @parameterlist ]} arguments.\n" )
69 46 50       187 if ( scalar @parameterlist < $macro->{argc} );
70              
71             # make the return value
72             # 5. replace the parameter tags in the 'reader' field of the macro, with
73             # the 'read' versions of the parameters.
74 46         104 my $returnvalue = ' ';
75              
76             # 1. check fi it is a LaTeX special macro:
77 46 50       269 if ( $command eq 'ref' ) {
    50          
    50          
78             # 1. Check whether this is a ref
79 0         0 my $arg = $parameterlist[0];
80             # say STDERR Data::Dumper->Dump( [ $SpeL::Object::Command::labelhash ], [ qw(lh) ] );
81             die( "Error: could not find reference '$arg'\n" )
82 0 0       0 unless exists $SpeL::Object::Command::labelhash->{$arg};
83             $returnvalue .=
84 0         0 $SpeL::Object::Command::labelhash->{$arg}->[0];
85             }
86             elsif ( $command eq 'pageref' ) {
87 0         0 my $arg = $parameterlist[0];
88             die( "Error: could not find reference '$arg'\n" )
89 0 0       0 unless exists $SpeL::Object::Command::labelhash->{$arg};
90             $returnvalue .=
91 0         0 $SpeL::Object::Command::labelhash->{$arg}->[1];
92             }
93             elsif ( $command eq 'cite' ) {
94 0         0 my $arg = $parameterlist[0];
95             die( "Error could not find citation '$arg'\n" )
96 0 0       0 unless exists $SpeL::Object::Command::citationhash->{$arg};
97             $returnvalue .=
98             '(see reference ' .
99 0         0 $SpeL::Object::Command::citationhash->{$arg} . ')';
100             }
101             else {
102             # strip any i18n constructs and replace them with... wat?
103 46         215 my @limbs = split( /(\@\{i18n\([^)]+\)\})/, $macro->{reader} );
104 46         104 foreach my $limb (@limbs) {
105             # treat i18n calls
106 52         87 my $i18nargs;
107 52 100       187 if ( ( $i18nargs ) = ( $limb =~ /^\@\{i18n\(([^)]+)\)\}/ ) ) {
108            
109 6         56 $limb = $SpeL::I18n::lh
110             ->maketext( split( /\s*,\s*/, $i18nargs ) );
111             }
112            
113             # then treat arguments
114 52         2213 for( my $i = 1; $i <= $macro->{argc}; ++$i ) {
115 27         408 $limb =~ s/##$i/$parameterlist[$i-1]/g;
116             }
117 52         193 $returnvalue .= $limb;
118             }
119             }
120              
121             # add trailing grouping brackets
122 46         166 for( my $i = $macro->{argc}; $i < @parameterlist ; ++$i ) {
123 0         0 $returnvalue .= ' ' . $parameterlist[$i];
124             }
125              
126 46 100       130 if ( $command eq 'text' ) {
127 8         22 $returnvalue =~ s/~/ /g;
128             }
129              
130             # 6. This is the return value
131 46         377 return $returnvalue;
132             }
133             else {
134 0           croak( "Error: there is no reader definition for the macro with name $command.\n" .
135             " Consider adding it to your LaTeX source using the \\spelmacad macro.\n" );
136             }
137             }
138              
139             1;
140              
141             __END__