Diff for /loncom/xml/lontexconvert.pm between versions 1.108 and 1.122

version 1.108, 2011/06/06 16:08:45 version 1.122, 2019/02/15 20:56:22
Line 50  use LONCAPA; Line 50  use LONCAPA;
 use URI::Escape;  use URI::Escape;
 use IO::Socket::INET;  use IO::Socket::INET;
   
   
   #
   # Table of substitutions to unicode characters.
   #
   
   my %unicode_harpoons = (
                           '\rightleftharpoons'  => 0x21cc,
                         );
   
   my %unicode_translations = (
   
   # Brackets - unicode for browsers/OS which support it.
   
       ''             => 0x23a1,
       ''             => 0x23a2,
       ''             => 0x23a3,
       ''             => 0x23a4,
       ''             => 0x23a5,
       ''             => 0x23a6,
   
   #  Parens - unicode for browsers/OS which support it
   
       ''              => 0x239b,
       ''              => 0x239c,
       ''              => 0x239d,
       ''              => 0x239e,
       ''              => 0x239f,
       ''              => 0x23a0,
   
   );
   
   my %ascii_8bit_translations = (
   
   # Brackets - pure 8-bit ascii ugliness for browsers/OS which can't handle unicode
   
       ''              => 0x5b,
       ''              => 0x5b,    # '['
       ''              => 0x5b,
       ''              => 0x5d,    # ']'
       ''              => 0x5d,
       ''              => 0x5d,
   
   # Parens - pure 8-bit ascii ugliness for browsers/OS which can't handle unicode
   
       ''              => 0x28,
       ''              => 0x28,      # '('
       ''              => 0x28,
       ''              => 0x29,
       ''              => 0x29,      # '('
       ''              => 0x29,
   
   );
   
   ##
   # Utility to convert elements of a string to unicode:
   #
   # @param input - Input string
   # @param pattern - Pattern to convert
   # @param unicode - Unicode to substitute for pattern.
   #
   # @return string - resulting string.
   # 
   sub unicode_subst {
       my ($input, $pattern, $unicode) = @_;
       
       my $char = pack('U', $unicode);
   
       $input =~ s/$pattern/$char/g;
   
       return $input;
   }
   
 # ====================================================================== Header  # ====================================================================== Header
   
 sub init_tth {  sub init_tth {
Line 106  sub convert_real { Line 178  sub convert_real {
     $xmlstring=~s/^\s*\<br clear\=\"all\"/\<br/s;      $xmlstring=~s/^\s*\<br clear\=\"all\"/\<br/s;
     $xmlstring=~s/^\s*//;      $xmlstring=~s/^\s*//;
     $xmlstring=~s/\s*$//;      $xmlstring=~s/\s*$//;
       $xmlstring=~s/^<br \/><table/<table/;
       &Apache::lonxml::end_alarm();
   
     #      #
     # \rightleftharpoons is not converted by tth but maps      # Several strings produced by tth require
     # reasonably well to &#8660;.  If we get many more of these,      # transliteration -> unicode equivalents to render reliably
     # we're going to need to have a translation sub.      # in browsers. %unicode_translations and %unicode_harpoons are tables of
     #      # string->substitution which we now apply. (%ascii_8bit_translations used
     my $lrharpoon = pack("U", 0x21cc);      # instead for Windows XP and mobile devices.
     $xmlstring=~s/\\rightleftharpoons/$lrharpoon/g;  
       my $use_ascii;
       if ($env{'browser.os'} eq 'win') {
           if (($env{'browser.osversion'}) && ($env{'browser.osversion'} < 6.0)) {
               $use_ascii = 1;
           }
       }
       if ($env{'browser.mobile'}) {
           $use_ascii = 1;
       }
   
       foreach my $pattern (keys(%unicode_translations)) {
    my $unicode = $unicode_translations{$pattern};
    if ($use_ascii) {
       $unicode = $ascii_8bit_translations{$pattern};
    }
    $xmlstring = &unicode_subst($xmlstring, $pattern, $unicode);
       }
   
       foreach my $pattern (keys(%unicode_harpoons)) {
           $xmlstring = &unicode_subst($xmlstring, $pattern, $unicode_harpoons{$pattern});
       }
   
     &Apache::lonxml::end_alarm();  
     return ($xmlstring,$errorstring);      return ($xmlstring,$errorstring);
 }  }
   
Line 174  sub displaystyle { Line 269  sub displaystyle {
     return 0;      return 0;
 }  }
   
 sub jsMath_converted {  sub MathJax_converted {
     my $texstring=shift;      my $texstring=shift;
     my $tag='span';      my ($tag,$startspan,$endspan);
     if (&displaystyle($texstring)) { $tag='div'; }      $tag='math/tex;';
       if (&displaystyle($texstring)) {
           $tag='math/tex; mode=display';
           $startspan='';
           $endspan='';
       } else {
           $startspan='<span style="display:inline-block;">';
           $endspan='</span>';
       }
     &clean_out_math_mode($texstring);      &clean_out_math_mode($texstring);
     return &jsMath_header().      return &MathJax_header().$startspan.
  '<'.$tag.' class="math">'.$$texstring.'</'.$tag.'>';        '<script type="'.$tag.'">'.$$texstring.'</script>'.$endspan;
 }  }
   
 {  {
     my @jsMath_sent_header;      #Relies heavily on the previous jsMath installation
     sub jsMath_reset {      my @MathJax_sent_header;
  undef(@jsMath_sent_header);      sub MathJax_reset {
     }          undef(@MathJax_sent_header);
     sub jsMath_push {      }
  push(@jsMath_sent_header,0);      sub MathJax_push {
     }          push(@MathJax_sent_header,0);
     sub jsMath_header {      }
  if (!@jsMath_sent_header) {      sub MathJax_header {
     &Apache::lonnet::logthis("mismatched calls of jsMath_header and jsMath_process");          if (!@MathJax_sent_header) {
     return '';              &Apache::lonnet::logthis("mismatched calls of MathJax_header and MathJax_process");
  }              return '';
  return '' if $jsMath_sent_header[-1];          }
  $jsMath_sent_header[-1]=1;          return '' if $MathJax_sent_header[-1];
  return          $MathJax_sent_header[-1]=1;
             '<script type="text/javascript">          return
                      function NoFontMessage () {}            '<script type="text/javascript" src="/adm/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>'."\n";
                      jsMath = {Parser: {prototype: {environments: {\'eqnarray*\' :[\'Array\',null,null,\'rcl\',[5/18,5/18],3,\'D\']}}}};      }
                    </script>'."\n".      #sub MathJax_process {
     '<script type="text/javascript" src="/adm/jsMath/jsMath.js"></script>'."\n";      #    my $state = pop(@MathJax_sent_header);
     }      #    return '' if !$state;
     sub jsMath_process {      #    return "\n".
  my $state = pop(@jsMath_sent_header);      #        '<script type="text/javascript">MathJax.Process()</script>'."\n";
  return '' if !$state;      #}
  return "\n".      #sub MathJax_state {
     '<script type="text/javascript">jsMath.Process()</script>'."\n";      #    my ($level) = @_;
     }      #    return $MathJax_sent_header[$level];
     sub jsMath_state {      #}
  my ($level) = @_;  
  return $jsMath_sent_header[$level];  
     }  
 }  }
   
 sub tex_engine {  sub tex_engine {
     if (exists($env{'form.texengine'})) {      if (exists($env{'form.texengine'})) {
  if ($env{'form.texengine'} ne '') {   if ($env{'form.texengine'} ne '') {
               if (lc($env{'form.texengine'}) eq 'jsmath') {
                   return 'MathJax';
               }
             return $env{'form.texengine'};              return $env{'form.texengine'};
         }          }
     }          }    
     if ($env{'request.course.id'}      if ($env{'request.course.id'}
  && exists($env{'course.'.$env{'request.course.id'}.'.texengine'})) {   && exists($env{'course.'.$env{'request.course.id'}.'.texengine'})) {
           if (lc($env{'course.'.$env{'request.course.id'}.'.texengine'}) eq 'jsmath') {
               return 'MathJax';
           }
  return $env{'course.'.$env{'request.course.id'}.'.texengine'};   return $env{'course.'.$env{'request.course.id'}.'.texengine'};
     }      }
     if (exists($env{'environment.texengine'})) {      if (exists($env{'environment.texengine'})) {
           if (lc($env{'environment.texengine'}) eq 'jsmath') {
               return 'MathJax';
           }
  return $env{'environment.texengine'};   return $env{'environment.texengine'};
     }      }
     return 'tth';      my $dom = $env{'request.role.domain'} || $env{'user.domain'};
       my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
       if ($domdefaults{'texengine'} ne '') {
           return $domdefaults{'texengine'};
       }
       return $Apache::lonnet::deftex;
 }  }
   
 sub init_math_support {  sub init_math_support {
     my ($inherit_jsmath) = @_;  
     &init_tth();      &init_tth();
     &Apache::lontexconvert::jsMath_push();      &Apache::lontexconvert::MathJax_push();
     if (lc(&tex_engine()) eq 'jsmath' ||      if (lc(&tex_engine()) eq 'mathjax') {
  ($inherit_jsmath && &jsMath_state(-2))) {          return &Apache::lontexconvert::MathJax_header();
  return &Apache::lontexconvert::jsMath_header();  
     }      }
     return;      return;
 }  }
Line 300  sub converted { Line 412  sub converted {
     if ($mode =~ /tth/i) {      if ($mode =~ /tth/i) {
  return &tth_converted($string);   return &tth_converted($string);
     } elsif ($mode =~ /jsmath/i) {      } elsif ($mode =~ /jsmath/i) {
  return &jsMath_converted($string);          return &MathJax_converted($string);
       } elsif ($mode =~ /mathjax/i) {
    return &MathJax_converted($string);
     } elsif ($mode =~ /mimetex/i) {      } elsif ($mode =~ /mimetex/i) {
  return &mimetex_converted($string);   return &mimetex_converted($string);
     } elsif ($mode =~ /raw/i) {      } elsif ($mode =~ /raw/i) {
Line 380  sub msgtexconverted { Line 494  sub msgtexconverted {
     foreach my $fragment (split(/(?:\&lt\;|\<)\/*algebra\s*(?:\&gt\;|\>)/i,      foreach my $fragment (split(/(?:\&lt\;|\<)\/*algebra\s*(?:\&gt\;|\>)/i,
  $message)) {   $message)) {
  if ($tex) {   if ($tex) {
         my $algebra = &algebra($fragment, 'web', undef, undef, undef, undef, 'tth');          my $algebra = &algebra($fragment, 'web', undef, undef, undef, 'tth');
     if ($email) {      if ($email) {
  $outmessage.='</pre><tt>'.$algebra.'</tt><pre>';   $outmessage.='</pre><tt>'.$algebra.'</tt><pre>';
  $tex=0;   $tex=0;
Line 447  sub postprocess_algebra { Line 561  sub postprocess_algebra {
     # $string =~s/\\fun/ /g;      # $string =~s/\\fun/ /g;
   
     # sqrt(3,4) means the 4 root of 3      # sqrt(3,4) means the 4 root of 3
     $string =~s/\\sqrt{([^,]+),([^\}]+)}/\\sqrt[$2]{$1}/gs;      $string =~s/\\sqrt\{([^,]+),([^\}]+)}/\\sqrt[$2]{$1}/gs;
   
     # log(3,4) means the log base 4 of 3      # log(3,4) means the log base 4 of 3
     $string =~s/\\log\\left\((.+?),(.+?)\\right\)/\\log_{$2}\\left($1\\right)/gs;      $string =~s/\\log\\left\((.+?),(.+?)\\right\)/\\log_{$2}\\left($1\\right)/gs;
Line 465  sub postprocess_algebra { Line 579  sub postprocess_algebra {
     $string =~s/\\lim\\left\((.+?),(.+?),(.+?)\\right\)/\\lim_{$2\\to $3}$1/gs;      $string =~s/\\lim\\left\((.+?),(.+?),(.+?)\\right\)/\\lim_{$2\\to $3}$1/gs;
     return $string;      return $string;
 }  }
   
   
 1;  1;
 __END__  __END__
   
Line 507  Header Line 623  Header
 =item displaystyle()  =item displaystyle()
   
   
 =item jsMath_converted()  =item MathJax_converted()
   
   
 =item tex_engine()  =item tex_engine()
   
   
 =item init_math_support()  =item init_math_support()
   
 =item mimetex_valign()  =item mimetex_valign()

Removed from v.1.108  
changed lines
  Added in v.1.122


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>