tag (end tag required)
sub start_center {
my ($target,$token) = @_;
- my $currentstring = '';
+ my $currentstring = &end_p(); # Close off any prior para.
if ($target eq 'web') {
- $currentstring = $token->[4];
+ $currentstring .= $token->[4];
} elsif ($target eq 'tex') {
- $currentstring = '\begin{center}';
+ $currentstring .= '\begin{center}';
}
return $currentstring;
}
@@ -597,13 +618,15 @@ sub end_center {
}
#-- tag (end tag required)
+# NOTE: In TeX mode disables internal
sub start_b {
my ($target,$token) = @_;
my $currentstring = '';
if ($target eq 'web') {
$currentstring = $token->[4];
} elsif ($target eq 'tex') {
- $currentstring = '\textbf{';
+ &disable_para();
+ $currentstring .= '\textbf{';
}
return $currentstring;
}
@@ -614,18 +637,21 @@ sub end_b {
if ($target eq 'web') {
$currentstring = $token->[2];
} elsif ($target eq 'tex') {
- $currentstring = '}';
+ &enable_para();
+ $currentstring = '}';
}
return $currentstring;
}
#-- tag (end tag required)
+# NOTE: in TeX mode disables internal
sub start_strong {
my ($target,$token) = @_;
my $currentstring = '';
if ($target eq 'web') {
$currentstring = $token->[4];
} elsif ($target eq 'tex') {
+ &disable_para();
$currentstring = '\textbf{';
}
return $currentstring;
@@ -637,6 +663,7 @@ sub end_strong {
if ($target eq 'web') {
$currentstring = $token->[2];
} elsif ($target eq 'tex') {
+ &enable_para();
$currentstring = '}';
}
return $currentstring;
@@ -645,7 +672,7 @@ sub end_strong {
#--
tag (end tag required)
sub start_h1 {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
- my $currentstring = '';
+ my $currentstring = &end_p(); # Close off any prior para.
if ($target eq 'web') {
$currentstring .= $token->[4];
} elsif ($target eq 'tex') {
@@ -662,7 +689,7 @@ sub start_h1 {
if (not defined $TeXsize) {$TeXsize="large";}
$currentstring .= '\strut\newline '.$pre.'{\\'.$TeXsize.' \textbf{';
} elsif ($target eq 'meta') {
- $currentstring='';
+ $currentstring.='';
&start_output($target);
}
return $currentstring;
@@ -694,7 +721,7 @@ sub end_h1 {
#--
tag
sub start_h2 {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
- my $currentstring = '';
+ my $currentstring = &end_p(); # Close off any prior para.
if ($target eq 'web') {
$currentstring .= $token->[4];
} elsif ($target eq 'tex') {
@@ -737,7 +764,7 @@ sub end_h2 {
#--
tag
sub start_h3 {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
- my $currentstring = '';
+ my $currentstring = &end_p(); # Close off any prior para.
if ($target eq 'web') {
$currentstring .= $token->[4];
} elsif ($target eq 'tex') {
@@ -780,7 +807,7 @@ sub end_h3 {
#--
tag
sub start_h4 {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
- my $currentstring = '';
+ my $currentstring = &end_p(); # Close off any prior para.
if ($target eq 'web') {
$currentstring .= $token->[4];
} elsif ($target eq 'tex') {
@@ -823,7 +850,7 @@ sub end_h4 {
#--
tag
sub start_h5 {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
- my $currentstring = '';
+ my $currentstring = &end_p(); # Close off any prior paras.
if ($target eq 'web') {
$currentstring .= $token->[4];
} elsif ($target eq 'tex') {
@@ -866,7 +893,7 @@ sub end_h5 {
#--
tag
sub start_h6 {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
- my $currentstring = '';
+ my $currentstring = &end_p(); # Close off any prior paras.
if ($target eq 'web') {
$currentstring .= $token->[4];
} elsif ($target eq 'tex') {
@@ -1113,52 +1140,80 @@ sub end_q {
return $currentstring;
}
+#
is a bit strange since it does not require a closing
+# However in latex, we must often output closing stuff to end
+# environments and {}'s etc. Therefore we do all the work
+# of figuring out the ending strings in the start tag processing,
+# and provide a mechanism to output the stop text external
+# to tag processing.
+#
+{
+
+ my $closing_string = ''; # String required to close
+
+# Some tags are
fragile meaning that
inside of them
+# does not work within TeX mode. This is managed via the
+# counter below:
+#
+
+ my $para_disabled = 0;
+
+sub disable_para {
+ $para_disabled++;
+}
+sub enable_para {
+ $para_disabled--;
+}
+
+
#--
tag (end tag optional)
#optional attribute - align="center|left|right"
sub start_p {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
my $currentstring = '';
if ($target eq 'web') {
+ $currentstring .= &end_p(); # close off prior para if in progress.
$currentstring .= $token->[4];
- } elsif ($target eq 'tex') {
+ if (! ($currentstring =~ /\//)) {
+ $closing_string = '
'; # Deal correctly with e.g.
+ }
+ } elsif ($target eq 'tex' && !$para_disabled) {
+ $currentstring .= &end_p(); # close off prior para if in progress.
my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
if ($align eq 'center') {
- $currentstring='\begin{center}\par';
+ $currentstring .='\begin{center}\par';
+ $closing_string = '\end{center}';
} elsif ($align eq 'right') {
- $currentstring='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{';
+ $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{';
+ $closing_string= '}}';
} elsif ($align eq 'left') {
- $currentstring='\noindent\makebox['.$env{'form.textwidth'}.']{\rlap{';
+ $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{\rlap{';
+ $closing_string = '}\hfill}';
} else {
- $currentstring='\par ';
+ $currentstring.='\par ';
+ $closing_string = '\strut\\\\\strut ';
}
- my $signal=1;#
does not work inside ...
- foreach my $tag (@$tagstack) {if (lc($tag) eq 'b') {$signal=0;}
- if (!$signal) {$currentstring = '';}
- }
+
}
return $currentstring;
}
-
+#
+# End paragraph processing just requires that we output the
+# closing string that was saved and blank it.
sub end_p {
- my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
- my $currentstring = '';
- if ($target eq 'web') {
- $currentstring .= $token->[2];
- } elsif ($target eq 'tex') {
- my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
- if (not defined $align) {
- $currentstring.='\strut\\\\\strut ';
- } elsif ($align eq 'center') {
- $currentstring .= '\end{center}';
- } elsif ($align eq 'right') {
- $currentstring .= '}}';
- } elsif ($align eq 'left') {
- $currentstring .= '}\hfill}';
- }
+ # Note only 'tex' mode uses disable_para and enable_para
+ # so we don't need to know the target in the check below:
+
+ if (!$para_disabled) {
+ my $current_string = $closing_string;
+ $closing_string = ''; # Not in a para anymore.
+ return $current_string;
+ } else {
+ return '';
}
- return $currentstring;
-}
+}
+}
#-- tag (end tag forbidden)
sub start_br {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
@@ -1168,6 +1223,9 @@ sub start_br {
} elsif ($target eq 'tex') {
my @tempo=@$tagstack;
my $signal=0;
+ # Not going to factor this to is_inside_of since that would require
+ # multiple stack traversals.
+ #
for (my $i=$#tempo;$i>=0;$i--) {
if (($tempo[$i] eq 'b') || ($tempo[$i] eq 'strong') ||
($tempo[$i] eq 'ol') || ($tempo[$i] eq 'ul') ||
@@ -1404,7 +1462,7 @@ sub end_sup {
#--
tag (end tag forbidden)
sub start_hr {
my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
- my $currentstring = '';
+ my $currentstring = &end_p(); # End enclosing para.
if ($target eq 'web') {
$currentstring .= $token->[4];
} elsif ($target eq 'tex') {
@@ -1442,12 +1500,44 @@ sub end_hr {
}
#--
tag (end tag required)
+{
+
+# Since div can be nested, the stack below is used
+# in 'tex' mode to store the ending strings
+# for the div stack.
+
+ my @div_end_stack;
+
sub start_div {
- my ($target,$token) = @_;
- my $currentstring = '';
+ my ($target,$token, $tagstack, $parstack, $parser, $safeeval) = @_;
+ my $currentstring = &end_p(); # Close enclosing para.
if ($target eq 'web') {
$currentstring .= $token->[4];
}
+ if ($target eq 'tex') {
+ # 4 possible alignments: left, right, center, and -missing-.
+
+ my $endstring = '';
+
+ my $align = lc(&Apache::lonxml::get_param('align', $parstack,
+ $safeeval, undef, 1));
+ if ($align eq 'center') {
+ $currentstring .= '\begin{center}';
+ $endstring = '\end{center}';
+ }
+ elsif ($align eq 'right') {
+ $currentstring .= '\begin{flushright}';
+ $endstring .= '\end{flushright}';
+ } elsif ($align eq 'left') {
+ $currentstring .= '\begin{flushleft}';
+ $endstring = '\end{flushleft}';
+ } else {
+
+ }
+ $currentstring .= "\n"; # For human readability.
+ $endstring = "\n$endstring\n"; # For human readability
+ push(@div_end_stack, $endstring);
+ }
return $currentstring;
}
@@ -1456,9 +1546,14 @@ sub end_div {
my $currentstring = '';
if ($target eq 'web') {
$currentstring .= $token->[2];
- }
+ }
+ if ($target eq 'tex') {
+ my $endstring = pop @div_end_stack;
+ $currentstring .= $endstring;
+ }
return $currentstring;
}
+}
#-- tag (end tag required)
sub start_a {
@@ -1526,9 +1621,9 @@ sub start_li {
sub end_li {
my ($target,$token) = @_;
- my $currentstring = '';
+ my $currentstring = &end_p(); # In case there's a