Physikerwelt has submitted this change and it was merged. Change subject: Taylor LaTeXML to Mediawiki needs ......................................................................
Taylor LaTeXML to Mediawiki needs includes texvc forces additional serverside texvc check Change-Id: If79c854556729c0cab9649541a452d8bba9daa70 --- A .gitignore M Makefile.PL A bin/MediawikiSvg2Png A bin/MediawikiTex2Svg A bin/latexmlmediawiki A latexml.php A lib/LaTeXML/Util/Svg.pm A lib/LaTeXML/Util/Texvc.pm A stupid.sh A texvc/tex.mli 10 files changed, 287 insertions(+), 1 deletion(-) Approvals: Physikerwelt: Verified; Looks good to me, approved diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34696d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +MYMETA.yml +Makefile +blib/ +debian/files +debian/latexml-wmf.debhelper.log +debian/latexml-wmf.substvars +debian/latexml-wmf/ +pm_to_blib diff --git a/Makefile.PL b/Makefile.PL index ebde7ce..4d6e530 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -69,7 +69,7 @@ 'HTTP::Request::Common' => 0, }, EXE_FILES => [ 'bin/latexml','bin/latexmlpost','bin/latexmlfind','bin/latexmlmath','bin/latexmlc','bin/latexmls', - 'bin/latexml.psgi'], + 'bin/latexml.psgi', 'bin/latexmlmediawiki','bin/MediawikiTex2Svg','bin/MediawikiSvg2Png'], macro => $MORE_MACROS, ); diff --git a/bin/MediawikiSvg2Png b/bin/MediawikiSvg2Png new file mode 100755 index 0000000..8ff98aa --- /dev/null +++ b/bin/MediawikiSvg2Png @@ -0,0 +1,8 @@ +#!/bin/bash +TMP=$(mktemp -d) +cd $TMP +echo $1>input.svg +echo "<!--The input-SVG:-->">&2 +cat input.svg >&2 +rsvg-convert input.svg +rm -rf $TMP \ No newline at end of file diff --git a/bin/MediawikiTex2Svg b/bin/MediawikiTex2Svg new file mode 100755 index 0000000..12f87c7 --- /dev/null +++ b/bin/MediawikiTex2Svg @@ -0,0 +1,15 @@ +#!/bin/bash +TMP=$(mktemp -d) +cd $TMP +echo $1>input.tex +echo "<!--The input-TeXFile:->>">&2 +cat input.tex 1>&2 +echo "<!--pdflatex-->">&2 +time pdflatex input.tex -interaction=batchmode +echo "<!--pdfcrop-->">&2 +time pdfcrop input.pdf crop.pdf 1>&2 +echo "<!--pdf2svg-->">&2 +time pdf2svg crop.pdf out.svg 1>&2 +echo "<!--END-->">&2 +cat out.svg +rm -rf $TMP \ No newline at end of file diff --git a/bin/latexmlmediawiki b/bin/latexmlmediawiki new file mode 100755 index 0000000..a2ab55a --- /dev/null +++ b/bin/latexmlmediawiki @@ -0,0 +1,124 @@ +#!/usr/bin/perl -w +use strict; +use warnings; + +use File::Basename 'dirname'; +use File::Spec::Functions 'catdir'; +my $FILE_BASE; +BEGIN { + $FILE_BASE = dirname(__FILE__); +} +use File::Path; +use Encode; +use JSON::XS qw(encode_json decode_json); +use lib $FILE_BASE."/../lib"; +use lib $FILE_BASE."/lib"; +use Data::Dumper qw(Dumper); + +use LaTeXML::Util::Svg; +use LaTeXML::Util::Texvc; +use LaTeXML::Util::Config; +use LaTeXML::Util::Pathname; +use LaTeXML::Converter; +use URI::Escape; +use String::ShellQuote qw(shell_quote); +use Time::HiRes qw( time ); + +my $input = $ARGV[0]; + +sub parse_request_query { + my $parameters = [map {scalar(@{$_})==1 ? (@{$_},'') : @{$_}} + map { [split(/=/,$_)] } map {split(/\&/,$_)} $input ]; + return $parameters; +} +sub php_escapeshellarg { + my $str = @_ ? shift : $_; + $str =~ s/((?:^|[^\\])(?:\\\\)*)'/$1\\'/g; + return "'$str'"; +} +my $all_params= parse_request_query(); +#print Dumper $all_params; +#__END__ +my $source = ''; + my $opts = []; + # Ugh, disallow 'null' as a value!!! (TODO: Smarter fix??) + while (my ($key,$value) = splice($all_params,0,2)) { + if ($key =~ /^(tex)|(source)$/) { + # TeX is data, separate + $source = $value; + next; + } elsif ($key=~/local|path/) { + # You don't get to specify harddrive info in the web service + next; + } + $value = '' if ($value && ($value eq 'null')); + push @$opts, ($key,uri_unescape($value)); + } + #print Dumper $source; + $source = uri_unescape($source); + push @$opts, ('source', $source); # Set in options hash, to e.g. guess bibTeX jobs + #print Dumper $source; + my $config = LaTeXML::Util::Config->new(); + $config->read_keyvals($opts); + my $latexheader = ''; + $latexheader = $config->get('preamble'); + #print Dumper $latexheader; + $config->delete('preamble'); + my ($passed,$outtex,$texvlog) = LaTeXML::Util::Texvc->checkTex($source); + if ( ! $passed ){ + print encode_json({result => '', status => "Failed to check tex", status_code=>3, + log => $texvlog,'texvc_error'=>$outtex}); +} else { + $source = $outtex; + print "HEOADF".$outtex; + my $svgIN = $latexheader ."\n\$\$\n".$source."\n\$\$\n\\end{document}"; + my ($svg,$png,$image_log) = LaTeXML::Util::Svg->createSVG($svgIN); + #print $svg; + my $base = $config->get('base'); + my $saved_cdir; + if ($base && !pathname_is_url($base)) { + my $canonical_base = pathname_canonical($base); + if ($canonical_base ne pathname_cwd()) { + $saved_cdir = pathname_cwd(); + chdir $canonical_base + or croak("Fatal:server:chdir Can't chdir to $canonical_base: $!"); + $LaTeXML::Util::Pathname::Pathname_CWD=$canonical_base; + } + } + + # We now have a LaTeXML config object - $config. + my $converter = LaTeXML::Converter->get_converter($config); + #Override/extend with session-specific options in $opt: + $converter->prepare_session($config); + # If there are no protocols, use literal: as default: + if ((! defined $source) || (length($source)<1)) { + print encode_json({result => '', status => "Fatal:input:empty No TeX provided on input", status_code=>3, + log => "Status:conversion:3\nFatal:input:empty No TeX provided on input"}); + } else { + #$source = "literal:".$source unless (pathname_is_url($source)); + #Send a request: + my $start = time(); + my $response = $converter->convert($source); + + my ($result, $status, $status_code, $log); + if (defined $response) { + ($result, $status, $status_code, $log) = map { $response->{$_} } qw(result status status_code log); + } + my $duration = time() - $start; + # Delete converter if Fatal occurred + undef $converter unless defined $result; + if (defined $saved_cdir) { + $LaTeXML::Util::Pathname::Pathname_CWD = $saved_cdir; + chdir $saved_cdir; + } + # 3. Return conversion results + # print STDERR "Result: \n",$result,"\n"; + # print STDERR "Log: \n",$log,"\n"; + # print STDERR "Status: \n",$status,"\n"; + $log = $texvlog.$image_log.$log."\n\nLaTeXML-time:$duration\n\n"; + print encode_json({result=>$result,status=>$status,status_code=>$status_code,log=>$log + ,'svg'=>$svg,'png'=>$png}); + #print Dumper $log; +}} +1; +__END__ \ No newline at end of file diff --git a/latexml.php b/latexml.php new file mode 100644 index 0000000..a4395f3 --- /dev/null +++ b/latexml.php @@ -0,0 +1,5 @@ +<?php +#echo 'test'; +#chroot('/tmp'); +$post = file_get_contents('php://input'); +system('latexmlmediawiki '.escapeshellarg( $post )) or die('error:' . $post); \ No newline at end of file diff --git a/lib/LaTeXML/Util/Svg.pm b/lib/LaTeXML/Util/Svg.pm new file mode 100644 index 0000000..0c87575 --- /dev/null +++ b/lib/LaTeXML/Util/Svg.pm @@ -0,0 +1,33 @@ +package LaTeXML::Util::Svg; + +use strict; +use warnings; +use MIME::Base64; +use IO::CaptureOutput qw/capture_exec/; +use Time::HiRes qw( time ); +#use Data::Dumper qw(Dumper); + +sub createSVG { + my($svgSource)=$_[1]; + + my @args = ("timeout",'60','MediawikiTex2Svg', $svgSource); + #print Dumper @args; + my $time = time(); + my($svg, $svg_log, $success, $exit_code) = capture_exec( @args ); + my $duration = time() - $time; + $svg_log .= "\n\nSVG-time:$duration\n\n"; + + @args = ("timeout",'60','MediawikiSvg2Png', $svg); + + $time = time(); + my($png, $png_log, $success_png, $exit_code_png) = capture_exec( @args ); + $duration = time() - $time; + + $png_log .= "\n\nPNG-time:$duration\n\n"; + $png = encode_base64($png); + #print Dumper $svg_log; + + return ($svg, $png, $svg_log."\n\n<!--PNG-->\n\n".$png_log); +} +1; +__END__ \ No newline at end of file diff --git a/lib/LaTeXML/Util/Texvc.pm b/lib/LaTeXML/Util/Texvc.pm new file mode 100644 index 0000000..910c982 --- /dev/null +++ b/lib/LaTeXML/Util/Texvc.pm @@ -0,0 +1,34 @@ +package LaTeXML::Util::Texvc; + +use strict; +use warnings; +use MIME::Base64; +use IO::CaptureOutput qw/capture_exec/; +use Time::HiRes qw( time ); +#use Data::Dumper qw(Dumper); + +sub checkTex { + my($intex) = $_[1]; + my $passed = 0; + my $outtex; + + #Hack to avoid wrong encoded output + #$intex =~ s/\\/\\\\/g; + #$intex =~ s/\n/\\n/g; + + my @args = ("timeout",'5','texvc', $intex); + #print Dumper @args; + my $start = time(); + my($stdout, $sdterr, $success, $exit_code) = capture_exec( @args ); + my $duration = time() - $start; + #print "\nin: $intex ->$stdout \n"; + if(substr($stdout,0,1) eq '+'){ + $passed = 1; + $outtex = substr($stdout,1,-1); + } else { + $outtex = $stdout; + } + return ($passed,$outtex, "\n\nTexvc-time:$duration\n\n"); +} +1; +__END__ \ No newline at end of file diff --git a/stupid.sh b/stupid.sh new file mode 100644 index 0000000..0c41c8c --- /dev/null +++ b/stupid.sh @@ -0,0 +1,11 @@ +#!/bin/bash +COUNTER=0 +while [ $COUNTER -lt 1 ]; do + #perl Makefile.PL + make + sudo make install + sudo service apache2 restart + curl -d 'format=xhtml&whatsin=math&whatsout=math&pmml&cmml&nodefaultresources&preload=LaTeX.pool&preload=article.cls&preload=amsmath.sty&preload=amsthm.sty&preload=amstext.sty&preload=amssymb.sty&preload=eucal.sty&preload=%5Bdvipsnames%5Dxcolor.sty&preload=url.sty&preload=hyperref.sty&preload=%5Bids%5Dlatexml.sty&preload=texvc&latexheader=%27%5Cdocumentclass%5B12pt%5D%7Barticle%7D%0A%0A%5Cusepackage%7Bucs%7D%0A%5Cusepackage%5Butf8x%5D%7Binputenc%7D%0A%0A%5Cnonstopmode%0A%0A%5Cusepackage%7Bamsmath%7D%0A%5Cusepackage%7Bamsfonts%7D%0A%5Cusepackage%7Bamssymb%7D%0A%5Cusepackage%5Bdvips%2Cusenames%5D%7Bcolor%7D%0A%5Cusepackage%5Bgreek%5D%7Bbabel%7D%0A%5Cusepackage%7Bteubner%7D%0A%5Cusepackage%7Beurosym%7D%0A%5Cusepackage%7Bcancel%7D%0A%0A%5Cpagestyle%7Bempty%7D%0A%5Cbegin%7Bdocument%7D%24%24%7B%5Ctextstyle+%5Csum+_%7B%7Bi%3D1%7D%7D%5E%7B%7B%5Cinfty+%7D%7D%5Cleft+%28%7B%5Cfrac++12%7D%5Cright+%29%5E%7Bi%7D%3D1%7D%24%24%5Cend%7BDocument%7D%27&tex=%7B%5Ctextstyle+%5Csum+_%7B%7Bi%3D1%7D%7D%5E%7B%7B%5Cinfty+%7D%7D%5Cleft+%28%7B%5Cfrac++12%7D%5Cright+%29%5E%7Bi%7D%3D1%7D' http://localhost + #curl -d 'latexheader=%5Cdocumentclass%5B12pt%5D%7Barticle%7D%0A%0A%5Cusepackage%7Bucs%7D%0A%5Cusepackage%5Butf8%5D%7Binputenc%7D%0A%0A%5Cnonstopmode%0A%0A%5Cusepackage%7Bamsmath%7D%0A%5Cusepackage%7Bamsfonts%7D%0A%5Cusepackage%7Bamssymb%7D%0A%5Cusepackage%5Bdvips%2Cusenames%5D%7Bcolor%7D%0A%5Cusepackage%5Bgreek%5D%7Bbabel%7D%0A%5Cusepackage%7Bteubner%7D%0A%5Cusepackage%7Beurosym%7D%0A%5Cusepackage%7Bcancel%7D%0A%0A%5Cpagestyle%7Bempty%7D%0A%5Cbegin%7Bdocument%7D&format=xhtml&whatsin=math&whatsout=math&pmml&cmml&nodefaultresources&preload=LaTeX.pool&preload=article.cls&preload=amsmath.sty&preload=amsthm.sty&preload=amstext.sty&preload=amssymb.sty&preload=eucal.sty&preload=[dvipsnames]xcolor.sty&preload=url.sty&preload=hyperref.sty&preload=[ids]latexml.sty&preload=texvc&tex=%7B%5Ctextstyle+%5Csum+_%7B%7Bi%3D1%7D%7D%5E%7B%7B%5Cinfty+%7D%7D%5Cleft+%28%7B%5Cfrac++12%7D%5Cright+%29%5E%7Bi%7D%3D1%7D' http://localhost + let COUNTER=COUNTER+1 +done \ No newline at end of file diff --git a/texvc/tex.mli b/texvc/tex.mli new file mode 100644 index 0000000..834df14 --- /dev/null +++ b/texvc/tex.mli @@ -0,0 +1,48 @@ +type font_force = + FONTFORCE_IT + | FONTFORCE_RM + +type font_class = + FONT_IT (* IT default, may be forced to be RM *) + | FONT_RM (* RM default, may be forced to be IT *) + | FONT_UF (* not affected by IT/RM setting *) + | FONT_RTI (* RM - any, IT - not available in HTML *) + | FONT_UFH (* in TeX UF, in HTML RM *) + +type math_class = + MN + | MI + | MO + +type render_t = + HTMLABLEC of font_class * string * string + | HTMLABLEM of font_class * string * string + | HTMLABLE of font_class * string * string + | MHTMLABLEC of font_class * string * string * math_class * string + | HTMLABLE_BIG of string * string + | TEX_ONLY of string + +type t = + TEX_LITERAL of render_t + | TEX_CURLY of t list + | TEX_FQ of t * t * t + | TEX_DQ of t * t + | TEX_UQ of t * t + | TEX_FQN of t * t + | TEX_DQN of t + | TEX_UQN of t + | TEX_LR of render_t * render_t * t list + | TEX_BOX of string * string + | TEX_BIG of string * render_t + | TEX_FUN1 of string * t + | TEX_FUN1nb of string * t + | TEX_FUN2 of string * t * t + | TEX_FUN2nb of string * t * t + | TEX_INFIX of string * t list * t list + | TEX_FUN2sq of string * t * t + | TEX_FUN1hl of string * (string * string) * t + | TEX_FUN1hf of string * font_force * t + | TEX_FUN2h of string * (t -> t -> string * string * string) * t * t + | TEX_INFIXh of string * (t list -> t list -> string * string * string) * t list * t list + | TEX_MATRIX of string * t list list list + | TEX_DECLh of string * font_force * t list -- To view, visit https://gerrit.wikimedia.org/r/85646 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: If79c854556729c0cab9649541a452d8bba9daa70 Gerrit-PatchSet: 6 Gerrit-Project: operations/debs/latexml Gerrit-Branch: master Gerrit-Owner: Physikerwelt <w...@physikerwelt.de> Gerrit-Reviewer: Deyan <d.gi...@jacobs-university.de> Gerrit-Reviewer: Dginev <d.gi...@jacobs-university.de> Gerrit-Reviewer: Physikerwelt <w...@physikerwelt.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits