PageRenderTime 1186ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/extensions/LatexDoc/LatexDoc.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 156 lines | 111 code | 33 blank | 12 comment | 15 complexity | ae10292412a9517786b6458ea701890c MD5 | raw file
  1. <?php
  2. if ( !defined( 'MEDIAWIKI' ) ) {
  3. die( "Not a valid entry point\n" );
  4. }
  5. $wgExtensionCredits['other'][] = array(
  6. 'path' => __FILE__,
  7. 'version' => '0.2',
  8. 'name' => 'LatexDoc',
  9. 'author' => 'Tim Starling',
  10. 'url' => 'http://www.mediawiki.org/wiki/Extension:LatexDoc',
  11. 'descriptionmsg' => 'latexdoc-desc',
  12. );
  13. $dir = dirname(__FILE__) . '/';
  14. $wgExtensionMessagesFiles['LatexDoc'] = $dir . 'LatexDoc.i18n.php';
  15. class LatexDoc {
  16. var $latexCommand = 'latex';
  17. var $pdflatexCommand = 'pdflatex';
  18. var $workingDir;
  19. var $workingPath;
  20. function __construct() {
  21. global $wgUploadDirectory, $wgUploadPath;
  22. $this->workingDir = "$wgUploadDirectory/latexdoc";
  23. $this->workingPath = "$wgUploadPath/latexdoc";
  24. return true;
  25. }
  26. function onUnknownAction( $action, &$article ) {
  27. global $wgOut, $wgRequest;
  28. // Respond only to latexdoc action
  29. if ( $action != 'latexdoc' ) {
  30. return true;
  31. }
  32. // Check for non-existent article
  33. if ( !$article || !( $text = $article->fetchContent() ) ) {
  34. $wgOut->addWikiText( wfMsg( 'latexdoc_no_text' ) );
  35. return false;
  36. }
  37. // Check permissions
  38. if ( !$article->mTitle->userCanRead() ) {
  39. $wgOut->loginToUse();
  40. return false;
  41. }
  42. $ext = $wgRequest->getText( 'ext' );
  43. $wgOut->setArticleFlag( false );
  44. $wgOut->setArticleRelated( true );
  45. $wgOut->setRobotPolicy( 'noindex,nofollow' );
  46. $wgOut->setPageTitle( $article->mTitle->getPrefixedText() );
  47. if ( $ext == 'pdf' ) {
  48. $this->runLatex( $text, $this->pdflatexCommand, 'pdf' );
  49. } else {
  50. $this->runLatex( $text, $this->latexCommand, 'dvi' );
  51. }
  52. return false;
  53. }
  54. function runLatex( $text, $command, $ext ) {
  55. global $wgOut, $IP;
  56. // Filter out obvious insecure control sequences
  57. $text = preg_replace( "/\\\\(input|openin|openout|read|write|escapechar)/",
  58. '\begin{math}\backslash\end{math}\1', $text );
  59. // Get path
  60. if ( !is_dir( $this->workingDir ) ) {
  61. if ( !mkdir( $this->workingDir, 0777 ) ) {
  62. $wgOut->addWikiText( wfMsg( 'latexdoc_cant_create_dir', $this->workingDir ) );
  63. return;
  64. }
  65. }
  66. $hash = md5( $text );
  67. $fn = $this->workingDir . '/' . 'ltd_' . $hash;
  68. $url = $this->workingPath . '/' . 'ltd_' . $hash;
  69. if ( !file_exists( "$fn.$ext" ) ) {
  70. // Write input file
  71. $inFile = fopen( "$fn.tex", 'w' );
  72. if ( !$inFile ) {
  73. $wgOut->addWikiText( wfMsg( 'latexdoc_cant_write', "$fn.tex" ) );
  74. return;
  75. }
  76. fwrite( $inFile, $text );
  77. fclose( $inFile );
  78. // Run LaTeX
  79. $cmd = $command .
  80. ' -interaction=batchmode -quiet ' .
  81. '\input ' . wfEscapeShellArg( "$fn.tex" ) . ' 2>&1';
  82. chdir( $this->workingDir );
  83. $errorText = shell_exec( $cmd );
  84. chdir( $IP );
  85. // Report errors
  86. if ( !file_exists( "$fn.$ext" ) ){
  87. wfSuppressWarnings();
  88. $log = '<pre>' . file_get_contents( "$fn.log" ) . '</pre>';
  89. wfRestoreWarnings();
  90. $wgOut->addWikiText( wfMsg( 'latexdoc_error', $cmd, $errorText, $log ) );
  91. return;
  92. }
  93. }
  94. // Redirect to output file
  95. $wgOut->redirect( "$url.$ext" );
  96. // Delete temporary files
  97. @unlink( "$fn.tex" );
  98. @unlink( "$fn.aux" );
  99. @unlink( "$fn.log" );
  100. }
  101. function onParserBeforeStrip( &$parser, &$text, &$stripState ) {
  102. // If the article looks vaguely like TeX, render it as a pre, with a button for DVI generation
  103. if ( strpos( $text, '\begin{document}' ) !== false ) {
  104. $sk =& $parser->getOptions()->getSkin();
  105. $dviLink = $sk->makeKnownLinkObj( $parser->getTitle(), wfMsg( 'latexdoc_get_dvi' ),
  106. 'action=latexdoc&ext=dvi' );
  107. $pdfLink = $sk->makeKnownLinkObj( $parser->getTitle(), wfMsg( 'latexdoc_get_pdf' ),
  108. 'action=latexdoc&ext=pdf' );
  109. $htmlLatex = nl2br( htmlspecialchars( $text ) );
  110. // FIXME: hard coded pipe-separator (use $wgLang->pipeList( array ) if possible.
  111. $framedLatex = <<<ENDTEXT
  112. $dviLink | $pdfLink
  113. <hr />
  114. <tt>$htmlLatex</tt>
  115. ENDTEXT;
  116. $text = $parser->insertStripItem( $framedLatex, $stripState );
  117. }
  118. return true;
  119. }
  120. }
  121. $wgLatexDoc = new LatexDoc;
  122. $wgHooks['UnknownAction'][] = &$wgLatexDoc;
  123. $wgHooks['ParserBeforeStrip'][] = &$wgLatexDoc;