From b261ba03f0e87c867efdbf32b8e2692e1485cdd1 Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Wed, 20 Mar 2013 13:24:02 -0400 Subject: [PATCH] Make vectors use the context's i,j,k values to obtian TeX and string representations (Parser/Lists/Vector.pm didn't do this, and Value/Vector.pm didn't do it well.) --- lib/Parser/Context/Constants.pm | 2 +- lib/Parser/Context/Default.pm | 32 ++++++++++++------------------- lib/Parser/List/Vector.pm | 24 ++++++++++++----------- lib/Parser/Value.pm | 1 + lib/Value/Vector.pm | 34 +++++++++++++++------------------ 5 files changed, 42 insertions(+), 51 deletions(-) diff --git a/lib/Parser/Context/Constants.pm b/lib/Parser/Context/Constants.pm index 2fcd96ba0c..344bfea00e 100644 --- a/lib/Parser/Context/Constants.pm +++ b/lib/Parser/Context/Constants.pm @@ -11,7 +11,7 @@ sub init { $self->{dataName} = 'constants'; $self->{name} = 'constant'; $self->{Name} = 'Constant'; - $self->{namePattern} = qr/[a-zA-Z][a-zA-Z0-9]*|_blank_/; + $self->{namePattern} = qr/[a-zA-Z][a-zA-Z0-9]*|_blank_|_0/; $self->{tokenType} = 'const'; } diff --git a/lib/Parser/Context/Default.pm b/lib/Parser/Context/Default.pm index 775f20483e..694609d569 100644 --- a/lib/Parser/Context/Default.pm +++ b/lib/Parser/Context/Default.pm @@ -133,10 +133,11 @@ $lists = { $constants = { 'e' => exp(1), - 'pi' => 4*atan2(1,1), - 'i' => Value::Complex->new(0,1), - 'j' => Value::Vector->new(0,1,0)->with(ijk=>1), - 'k' => Value::Vector->new(0,0,1)->with(ijk=>1), + 'pi' => {value => 4*atan2(1,1), TeX => '\pi ', perl => "pi"}, + 'i' => {value => Value::Complex->new(0,1), isConstant => 1, string => "i", perl => "i"}, + 'j' => {value => Value::Vector->new(0,1,0)->with(ijk=>1), TeX => '\boldsymbol{j}', string => "j", perl => "j"}, + 'k' => {value => Value::Vector->new(0,0,1)->with(ijk=>1), TeX => '\boldsymbol{k}', string => "k", perl => "k"}, + '_0' => {value => Value::Vector->new(0,0,0), hidden => 1, TeX => '\boldsymbol{0}', string => "0"}, '_blank_' => {value => 0, hidden => 1, string => "", TeX => ""}, }; @@ -264,13 +265,6 @@ $context = $context{Full} = new Parser::Context( reduction => $Parser::reduce, ); -$context->constants->set( - pi => {TeX => '\pi ', perl => 'pi'}, - i => {isConstant => 1, perl => 'i'}, - j => {TeX => '\boldsymbol{j}', perl => 'j'}, - k => {TeX => '\boldsymbol{k}', perl => 'k'}, -); - $context->usePrecedence('Standard'); $context->{name} = "Full"; @@ -296,18 +290,16 @@ $context->{name} = "Numeric"; $context = $context{Vector} = $context{Full}->copy; $context->variables->are(x=>'Real',y=>'Real',z=>'Real'); $context->functions->undefine('arg','mod','Re','Im','conj'); -$context->constants->replace(i=>Value::Vector->new(1,0,0)->with(ijk=>1)); -$context->constants->set(i=>{TeX=>'\boldsymbol{i}', perl=>'i'}); +$context->constants->set( + i => {value => Value::Vector->new(1,0,0)->with(ijk=>1), TeX => '\boldsymbol{i}'}, +); $context->parens->set('(' => {formMatrix => 0}); $context = $context{Vector2D} = $context{Vector}->copy; -$context->constants->replace( - i => Value::Vector->new(1,0)->with(ijk=>1), - j => Value::Vector->new(0,1)->with(ijk=>1), -); $context->constants->set( - i => {TeX=>'\boldsymbol{i}', perl=>'i'}, - j => {TeX=>'\boldsymbol{j}', perl=>'j'} + i => {value => Value::Vector->new(1,0)->with(ijk=>1)}, + j => {value => Value::Vector->new(0,1)->with(ijk=>1)}, + '_0' => {value => Value::Vector->new(0,0)}, ); $context->constants->remove("k"); $context->{name} = "Vector2D"; @@ -318,7 +310,7 @@ $context->{name} = "Vector2D"; $context = $context{Point} = $context{Vector}->copy; $context->operators->undefine("><","."); $context->functions->undefine('norm','unit'); -$context->constants->remove('i','j','k'); +$context->constants->remove('i','j','k','_0'); $context->parens->remove("<"); $context->{name} = "Point"; diff --git a/lib/Parser/List/Vector.pm b/lib/Parser/List/Vector.pm index e76c40c7ee..23d2a96cb5 100644 --- a/lib/Parser/List/Vector.pm +++ b/lib/Parser/List/Vector.pm @@ -24,40 +24,42 @@ sub _check { } } -my $ijk_string = ['i','j','k','0']; -my $ijk_TeX = ['\boldsymbol{i}','\boldsymbol{j}','\boldsymbol{k}','\boldsymbol(0)']; - sub ijk { - my $self = shift; - my $method = shift || 'TeX'; my $ijk = shift || $ijk_TeX; + my $self = shift; my $method = shift || 'string'; my @coords = @{$self->{coords}}; $self->Error("Method 'ijk' can only be used on vectors in three-space") unless (scalar(@coords) <= 3); + my @ijk = (); my $constants = $self->context->{constants}; + foreach my $x ('i','j','k','_0') { + my $v = (split(//,$x))[-1]; + push(@ijk,($constants->{$x}||{string=>$v,TeX=>"\\boldsymbol{$v}"})->{$method}); + } my $prec = $self->{equation}{context}->operators->get('*')->{precedence}; my $string = ''; my $n; my $term; foreach $n (0..scalar(@coords)-1) { $term = $coords[$n]->$method($prec); if ($term ne '0') { + $term =~ s/\((-(\d+(\.\d*)?|\.\d+))\)/\1/; $term = '' if $term eq '1'; $term = '-' if $term eq '-1'; $term = '+' . $term unless $string eq '' or $term =~ m/^-/; - $string .= $term . $ijk->[$n]; + $string .= $term . $ijk[$n]; } } - $string = $ijk->[3] if $string eq ''; + $string = $ijk[3] if $string eq ''; return $string; } sub TeX { my $self = shift; - if ($self->{ijk} || $self->{equation}{ijk} || $self->{equation}{context}->flag("ijk")) - {return $self->ijk} + return $self->ijk("TeX") + if $self->{ijk} || $self->{equation}{ijk} || $self->{equation}{context}->flag("ijk"); return $self->SUPER::TeX; } sub string { my $self = shift; - if ($self->{ijk} || $self->{equation}{ijk} || $self->{equation}{context}->flag("ijk")) - {return $self->ijk('string',$ijk_string)} + return $self->ijk("string") + if $self->{ijk} || $self->{equation}{ijk} || $self->{equation}{context}->flag("ijk"); return $self->SUPER::string; } diff --git a/lib/Parser/Value.pm b/lib/Parser/Value.pm index e1a391074e..dc7efb4a80 100644 --- a/lib/Parser/Value.pm +++ b/lib/Parser/Value.pm @@ -33,6 +33,7 @@ sub new { $type = $context->Package($type), $value = $type->new($context,@{$value}) unless $type eq 'value'; $type = $value->typeRef; + $value->inContext($context); # force context to be the equation's context my $c = bless { value => $value, type => $type, isConstant => 1, ref => $ref, equation => $equation, diff --git a/lib/Value/Vector.pm b/lib/Value/Vector.pm index 40b4000a6b..1d4d97add7 100644 --- a/lib/Value/Vector.pm +++ b/lib/Value/Vector.pm @@ -236,15 +236,6 @@ sub areParallel {(shift)->isParallel(@_)} # Generate the various output formats # -my $ijk_string = ['i','j','k','0']; -my $ijk_TeX = ['\boldsymbol{i}','\boldsymbol{j}','\boldsymbol{k}','\boldsymbol{0}']; - -sub string { - my $self = shift; my $equation = shift; - return $self->ijk($ijk_string) if $self->getFlag("ijk") && !$self->{ColumnVector}; - return $self->SUPER::string($equation,@_); -} - sub pdot { my $self = shift; my $string = $self->string; @@ -253,6 +244,12 @@ sub pdot { return $string; } +sub string { + my $self = shift; my $equation = shift; + return $self->ijk("string") if $self->getFlag("ijk") && !$self->{ColumnVector}; + return $self->SUPER::string($equation,@_); +} + sub TeX { my $self = shift; my $equation = shift; if ($self->{ColumnVector}) { @@ -270,21 +267,20 @@ sub TeX { } return $open.'\begin{array}{c}'.join('\\\\',@coords).'\\\\\end{array}'.$close; } - return $self->ijk if $self->getFlag("ijk"); + return $self->ijk("TeX") if $self->getFlag("ijk"); return $self->SUPER::TeX($equation,@_); } sub ijk { - my $self = shift; my $ijk = shift; - if (!$ijk) { - my $context = $self->context; - $ijk = []; $ijk->[3] = $ijk_TeX->[3]; - foreach my $i (0,1,2) - {$ijk->[$i] = $context->{constants}{$ijk_string->[$i]}{TeX} || $ijk_TeX->[$i]} - } + my $self = shift; my $type = shift || "string"; my @coords = @{$self->data}; Value::Error("Method 'ijk' can only be used on Vectors in 3-space") unless (scalar(@coords) <= 3); + my @ijk = (); my $constants = $self->context->{constants}; + foreach my $x ('i','j','k','_0') { + my $v = (split(//,$x))[-1]; + push(@ijk,($constants->{$x}||{string=>$v,TeX=>"\\boldsymbol{$v}"})->{$type}); + } my $string = ''; my $n; my $term; foreach $n (0..scalar(@coords)-1) { $term = $coords[$n]; $term = (Value::isValue($term))? $term->string : "$term"; @@ -292,10 +288,10 @@ sub ijk { $term = '' if $term eq '1'; $term = '-' if $term eq '-1'; $term = '('.$term.')' if $term =~ m/e/i; $term = '+' . $term unless $string eq '' or $term =~ m/^-/; - $string .= $term . $ijk->[$n]; + $string .= $term . $ijk[$n]; } } - $string = $ijk->[3] if $string eq ''; + $string = $ijk[3] if $string eq ''; return $string; }