Remove dead texvc code from the math extension
In T74240 support for LaTeX based rendering of the <math/>-tags was removed. This change eliminates the unused code from the repository. Bug: T195871 Change-Id: Ic57d83fa49f090b574ce8b82fd2ebc84a5350318
This commit is contained in:
parent
8879b5b7a1
commit
4156f1c9b7
|
@ -1,117 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* MediaWiki math extension
|
||||
*
|
||||
* @copyright 2002-2015 Tomasz Wegrzanowski, Brion Vibber, Moritz Schubotz,
|
||||
* and other MediaWiki contributors
|
||||
* @license GPL-2.0-or-later
|
||||
* @author Moritz Schubotz
|
||||
*/
|
||||
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
|
||||
class MathInputCheckTexvc extends MathInputCheck {
|
||||
|
||||
/**
|
||||
* Converts an error returned by texvc to a localized exception
|
||||
*
|
||||
* @param string $texvcResult error result returned by texvc
|
||||
* @param bool|MathRenderer $errorRenderer
|
||||
* @return string
|
||||
*/
|
||||
public function convertTexvcError( $texvcResult, $errorRenderer = false ) {
|
||||
$texvcStatus = substr( $texvcResult, 0, 1 );
|
||||
$errDetails = htmlspecialchars( substr( $texvcResult, 1 ) );
|
||||
|
||||
if ( $errorRenderer === false ) {
|
||||
$errorRenderer = new MathSource( $this->inputTeX );
|
||||
}
|
||||
|
||||
switch ( $texvcStatus ) {
|
||||
case 'E':
|
||||
$errMsg = $errorRenderer->getError( 'math_lexing_error' );
|
||||
break;
|
||||
case 'S':
|
||||
$errMsg = $errorRenderer->getError( 'math_syntax_error' );
|
||||
break;
|
||||
case 'F':
|
||||
$errMsg = $errorRenderer->getError( 'math_unknown_function', $errDetails );
|
||||
break;
|
||||
default:
|
||||
$errMsg = $errorRenderer->getError( 'math_unknown_error' );
|
||||
}
|
||||
|
||||
return $errMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid() {
|
||||
$us = $this;
|
||||
$checkWork = new PoolCounterWorkViaCallback( 'MathTexvc-check', "", [
|
||||
'doWork' => function () use ( $us ) {
|
||||
return $us->doValidCheck();
|
||||
}
|
||||
] );
|
||||
return $checkWork->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function doValidCheck() {
|
||||
global $wgMathTexvcCheckExecutable;
|
||||
if ( $wgMathTexvcCheckExecutable === false ) {
|
||||
$texvcCheckExecutable = __DIR__ . '/texvccheck/texvccheck';
|
||||
} else {
|
||||
$texvcCheckExecutable = $wgMathTexvcCheckExecutable;
|
||||
}
|
||||
if ( !is_executable( $texvcCheckExecutable ) ) {
|
||||
$msg = 'Missing "texvccheck" executable. Please see math/README to configure.';
|
||||
trigger_error( $msg, E_USER_NOTICE );
|
||||
LoggerFactory::getInstance( 'Math' )->error( $msg );
|
||||
return true;
|
||||
}
|
||||
|
||||
$cmd = $texvcCheckExecutable . ' ' . wfEscapeShellArg( $this->inputTeX );
|
||||
|
||||
if ( wfIsWindows() ) {
|
||||
# Invoke it within cygwin sh, because texvc expects sh features in its default shell
|
||||
$cmd = 'sh -c ' . wfEscapeShellArg( $cmd );
|
||||
}
|
||||
|
||||
LoggerFactory::getInstance( 'Math' )->debug( "TeX check command: $cmd" );
|
||||
if ( strlen( $cmd ) > SHELL_MAX_ARG_STRLEN ) {
|
||||
LoggerFactory::getInstance( 'Math' )->error(
|
||||
"User input exceeded SHELL_MAX_ARG_STRLEN." );
|
||||
return $this->convertTexvcError( '' );
|
||||
}
|
||||
$contents = wfShellExec( $cmd );
|
||||
LoggerFactory::getInstance( 'Math' )->debug( "TeX check result: $contents\n---" );
|
||||
|
||||
if ( strlen( $contents ) === 0 ) {
|
||||
LoggerFactory::getInstance( 'Math' )->warning( 'TeX check output was empty.' );
|
||||
$this->lastError = $this->convertTexvcError( $contents );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$retval = substr( $contents, 0, 1 );
|
||||
|
||||
if ( $retval !== '+' ) {
|
||||
$this->lastError = $this->convertTexvcError( $contents );
|
||||
LoggerFactory::getInstance( 'Math' )->warning( 'checkTex failed: ' . $this->lastError );
|
||||
|
||||
return false;
|
||||
} else {
|
||||
$this->validTeX = substr( $contents, 1 );
|
||||
$this->isValid = true;
|
||||
LoggerFactory::getInstance( 'Math' )->debug(
|
||||
'checkTex successful tex is now: ' . $this->validTeX );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
493
MathTexvc.php
493
MathTexvc.php
|
@ -1,493 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* MediaWiki math extension
|
||||
*
|
||||
* @copyright 2002-2012 Tomasz Wegrzanowski, Brion Vibber, Moritz Schubotz,
|
||||
* and other MediaWiki contributors
|
||||
* @license GPL-2.0-or-later
|
||||
*
|
||||
* Contains the driver function for the texvc program
|
||||
* @file
|
||||
*/
|
||||
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
use Wikimedia\Rdbms\Blob;
|
||||
|
||||
/**
|
||||
* Takes LaTeX fragments, sends them to a helper program (texvc) for rendering
|
||||
* to rasterized PNG and HTML and MathML approximations. An appropriate
|
||||
* rendering form is picked and returned.
|
||||
*
|
||||
* @author Tomasz Wegrzanowski
|
||||
* @author Brion Vibber
|
||||
* @author Moritz Schubotz
|
||||
* @deprecated will be deleted in one of the next versions without further notice
|
||||
*/
|
||||
class MathTexvc extends MathRenderer {
|
||||
private $hash = '';
|
||||
private $html = '';
|
||||
private $conservativeness = 0;
|
||||
const CONSERVATIVE = 2;
|
||||
const MODERATE = 1;
|
||||
const LIBERAL = 0;
|
||||
const MW_TEXVC_SUCCESS = -1;
|
||||
|
||||
/**
|
||||
* Gets an array that matches the variables of the class to the database columns
|
||||
* @return array
|
||||
*/
|
||||
public function dbOutArray() {
|
||||
$out = [];
|
||||
$dbr = wfGetDB( DB_REPLICA );
|
||||
$outmd5_sql = $dbr->encodeBlob( pack( 'H32', $this->hash ) );
|
||||
if ( $outmd5_sql instanceof Blob ) {
|
||||
$outmd5_sql = $outmd5_sql->fetch();
|
||||
}
|
||||
$out['math_outputhash'] = $outmd5_sql;
|
||||
$out['math_html_conservativeness'] = $this->conservativeness;
|
||||
$out['math_html'] = $this->html;
|
||||
$out['math_mathml'] = utf8_encode( $this->getMathml() );
|
||||
$out['math_inputhash'] = $this->getInputHash();
|
||||
LoggerFactory::getInstance( 'Math' )->debug( 'Store Hashpath of image' .
|
||||
bin2hex( $outmd5_sql ) );
|
||||
return $out;
|
||||
}
|
||||
|
||||
protected function dbInArray() {
|
||||
return [ 'math_inputhash', 'math_outputhash',
|
||||
'math_html_conservativeness', 'math_html', 'math_mathml' ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stdClass $rpage
|
||||
* @return bool
|
||||
*/
|
||||
protected function initializeFromDatabaseRow( $rpage ) {
|
||||
parent::initializeFromDatabaseRow( $rpage );
|
||||
// get deprecated fields
|
||||
if ( $rpage->math_outputhash ) {
|
||||
$dbr = wfGetDB( DB_REPLICA );
|
||||
$xhash = unpack( 'H32md5',
|
||||
$dbr->decodeBlob( $rpage->math_outputhash ) . " " );
|
||||
$this->hash = $xhash['md5'];
|
||||
LoggerFactory::getInstance( 'Math' )->debug( 'Hashpath of PNG-File:' .
|
||||
bin2hex( $this->hash ) );
|
||||
$this->conservativeness = $rpage->math_html_conservativeness;
|
||||
$this->html = $rpage->math_html;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders TeX using texvc
|
||||
*
|
||||
* @return string rendered TeK
|
||||
*/
|
||||
public function render() {
|
||||
if ( !$this->readCache() ) { // cache miss
|
||||
$result = $this->callTexvc();
|
||||
if ( $result === self::MW_TEXVC_SUCCESS ) {
|
||||
return true;
|
||||
} else {
|
||||
$this->lastError = $result;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets path to store hashes in
|
||||
*
|
||||
* @return string Storage directory
|
||||
*/
|
||||
public function getHashPath() {
|
||||
$path = $this->getBackend()->getRootStoragePath() .
|
||||
'/math-render/' . $this->getHashSubPath();
|
||||
LoggerFactory::getInstance( 'Math' )->debug(
|
||||
"TeX: getHashPath, hash is: {$this->getHash()}, path is: $path" );
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets relative directory for this specific hash
|
||||
*
|
||||
* @return string Relative directory
|
||||
*/
|
||||
public function getHashSubPath() {
|
||||
return substr( $this->getHash(), 0, 1 )
|
||||
. '/' . substr( $this->getHash(), 1, 1 )
|
||||
. '/' . substr( $this->getHash(), 2, 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets URL for math image
|
||||
*
|
||||
* @return string image URL
|
||||
*/
|
||||
public function getMathImageUrl() {
|
||||
global $wgMathPath;
|
||||
$dir = $this->getHashSubPath();
|
||||
return "$wgMathPath/$dir/{$this->getHash()}.png";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets img tag for math image
|
||||
*
|
||||
* @return string img HTML
|
||||
*/
|
||||
public function getMathImageHTML() {
|
||||
$url = $this->getMathImageUrl();
|
||||
$attributes = [
|
||||
// the former class name was 'tex'
|
||||
// for backwards compatibility we keep that classname
|
||||
'class' => 'mwe-math-fallback-image-inline tex',
|
||||
'alt' => $this->getTex()
|
||||
];
|
||||
if ( $this->getMathStyle() === 'display' ) {
|
||||
// if DisplayStyle is true, the equation will be centered in a new line
|
||||
$attributes[ 'class' ] = 'mwe-math-fallback-image-display tex';
|
||||
}
|
||||
return Xml::element( 'img',
|
||||
$this->getAttributes(
|
||||
'img',
|
||||
$attributes,
|
||||
[
|
||||
'src' => $url
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an error returned by texvc to a localized exception
|
||||
*
|
||||
* @param string $texvcResult error result returned by texvc
|
||||
* @return string
|
||||
*/
|
||||
public function convertTexvcError( $texvcResult ) {
|
||||
$errorConverter = new MathInputCheckTexvc();
|
||||
return $errorConverter->convertTexvcError( $texvcResult, $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the actual call to texvc
|
||||
*
|
||||
* @return int|string MW_TEXVC_SUCCESS or error string
|
||||
*/
|
||||
public function callTexvc() {
|
||||
global $wgTexvc, $wgTexvcBackgroundColor, $wgHooks;
|
||||
if ( $wgTexvc === false ) {
|
||||
$texvc = __DIR__ . '/math/texvc';
|
||||
} else {
|
||||
$texvc = $wgTexvc;
|
||||
}
|
||||
$tmpDir = wfTempDir();
|
||||
if ( !is_executable( $texvc ) ) {
|
||||
LoggerFactory::getInstance( 'Math' )->error(
|
||||
"$texvc does not exist or is not executable." );
|
||||
return $this->getError( 'math_notexvc' );
|
||||
}
|
||||
|
||||
$escapedTmpDir = wfEscapeShellArg( $tmpDir );
|
||||
|
||||
$cmd = $texvc . ' ' .
|
||||
$escapedTmpDir . ' ' .
|
||||
$escapedTmpDir . ' ' .
|
||||
wfEscapeShellArg( $this->getUserInputTex() ) . ' ' .
|
||||
wfEscapeShellArg( 'UTF-8' ) . ' ' .
|
||||
wfEscapeShellArg( $wgTexvcBackgroundColor );
|
||||
|
||||
if ( wfIsWindows() ) {
|
||||
# Invoke it within cygwin sh, because texvc expects sh features in its default shell
|
||||
$cmd = 'sh -c ' . wfEscapeShellArg( $cmd );
|
||||
}
|
||||
LoggerFactory::getInstance( 'Math' )->debug( "TeX: $cmd" );
|
||||
LoggerFactory::getInstance( 'Math' )->debug( "Executing '$cmd'." );
|
||||
$retval = null;
|
||||
if ( strlen( $cmd ) > SHELL_MAX_ARG_STRLEN ) {
|
||||
LoggerFactory::getInstance( 'Math' )->error(
|
||||
"User input exceeded SHELL_MAX_ARG_STRLEN." );
|
||||
return $this->getError( 'math_unknown_error' );
|
||||
}
|
||||
$contents = wfShellExec( $cmd, $retval );
|
||||
LoggerFactory::getInstance( 'Math' )->debug( "TeX output:\n $contents\n---" );
|
||||
|
||||
if ( strlen( $contents ) == 0 ) {
|
||||
if ( !file_exists( $tmpDir ) || !is_writable( $tmpDir ) ) {
|
||||
LoggerFactory::getInstance( 'Math' )->error(
|
||||
"TeX output directory $tmpDir is missing or not writable" );
|
||||
return $this->getError( 'math_bad_tmpdir' );
|
||||
} else {
|
||||
LoggerFactory::getInstance( 'Math' )->error(
|
||||
"TeX command '$cmd' returned no output and status code $retval." );
|
||||
return $this->getError( 'math_unknown_error' );
|
||||
}
|
||||
}
|
||||
|
||||
$tempFsFile = new TempFSFile( "$tmpDir/{$this->getHash()}.png" );
|
||||
$tempFsFile->autocollect(); // destroy file when $tempFsFile leaves scope
|
||||
|
||||
$retval = substr( $contents, 0, 1 );
|
||||
$errmsg = '';
|
||||
if ( ( $retval == 'C' ) || ( $retval == 'M' ) || ( $retval == 'L' ) ) {
|
||||
if ( $retval == 'C' ) {
|
||||
$this->setConservativeness( self::CONSERVATIVE );
|
||||
} elseif ( $retval == 'M' ) {
|
||||
$this->setConservativeness( self::MODERATE );
|
||||
} else {
|
||||
$this->setConservativeness( self::LIBERAL );
|
||||
}
|
||||
$outdata = substr( $contents, 33 );
|
||||
|
||||
$i = strpos( $outdata, "\000" );
|
||||
|
||||
$this->setHtml( substr( $outdata, 0, $i ) );
|
||||
$this->setMathml( substr( $outdata, $i + 1 ) );
|
||||
} elseif ( ( $retval == 'c' ) || ( $retval == 'm' ) || ( $retval == 'l' ) ) {
|
||||
$this->setHtml( substr( $contents, 33 ) );
|
||||
if ( $retval == 'c' ) {
|
||||
$this->setConservativeness( self::CONSERVATIVE );
|
||||
} elseif ( $retval == 'm' ) {
|
||||
$this->setConservativeness( self::MODERATE );
|
||||
} else {
|
||||
$this->setConservativeness( self::LIBERAL );
|
||||
}
|
||||
$this->setMathml( null );
|
||||
} elseif ( $retval == 'X' ) {
|
||||
$this->setHtml( null );
|
||||
$this->setMathml( substr( $contents, 33 ) );
|
||||
$this->setConservativeness( self::LIBERAL );
|
||||
} elseif ( $retval == '+' ) {
|
||||
$this->setHtml( null );
|
||||
$this->setMathml( null );
|
||||
$this->setConservativeness( self::LIBERAL );
|
||||
} else {
|
||||
$errmsg = $this->convertTexvcError( $contents );
|
||||
}
|
||||
|
||||
if ( !$errmsg ) {
|
||||
$newHash = substr( $contents, 1, 32 );
|
||||
if ( $this->hash !== $newHash ) {
|
||||
// DB needs update in writeCache() (bug 60997)
|
||||
$this->isInDatabase();
|
||||
}
|
||||
$this->setHash( $newHash );
|
||||
}
|
||||
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$renderer = $this;
|
||||
Hooks::run( 'MathAfterTexvc', [ &$renderer, &$errmsg ] );
|
||||
|
||||
if ( $errmsg ) {
|
||||
return $errmsg;
|
||||
} elseif ( !preg_match( "/^[a-f0-9]{32}$/", $this->getHash() ) ) {
|
||||
return $this->getError( 'math_unknown_error' );
|
||||
} elseif ( !file_exists( "$tmpDir/{$this->getHash()}.png" ) ) {
|
||||
return $this->getError( 'math_image_error' );
|
||||
} elseif ( filesize( "$tmpDir/{$this->getHash()}.png" ) == 0 ) {
|
||||
return $this->getError( 'math_image_error' );
|
||||
}
|
||||
|
||||
$hashpath = $this->getHashPath(); // final storage directory
|
||||
|
||||
$backend = $this->getBackend();
|
||||
# Create any containers/directories as needed...
|
||||
if ( !$backend->prepare( [ 'dir' => $hashpath ] )->isOK() ) {
|
||||
return $this->getError( 'math_output_error' );
|
||||
}
|
||||
// Store the file at the final storage path...
|
||||
// Bug 56769: buffer the writes and do them at the end.
|
||||
if ( !isset( $wgHooks['ParserAfterParse']['FlushMathBackend'] ) ) {
|
||||
$backend->mathBufferedWrites = [];
|
||||
$wgHooks['ParserAfterParse']['FlushMathBackend'] = function () use ( $backend ) {
|
||||
global $wgHooks;
|
||||
unset( $wgHooks['ParserAfterParse']['FlushMathBackend'] );
|
||||
$backend->doQuickOperations( $backend->mathBufferedWrites );
|
||||
unset( $backend->mathBufferedWrites );
|
||||
};
|
||||
}
|
||||
$backend->mathBufferedWrites[] = [
|
||||
'op' => 'store',
|
||||
'src' => "$tmpDir/{$this->getHash()}.png",
|
||||
'dst' => "$hashpath/{$this->getHash()}.png",
|
||||
'ref' => $tempFsFile // keep file alive
|
||||
];
|
||||
|
||||
return self::MW_TEXVC_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets file backend
|
||||
*
|
||||
* @return FileBackend appropriate file backend
|
||||
*/
|
||||
public function getBackend() {
|
||||
global $wgMathFileBackend, $wgMathDirectory;
|
||||
if ( $wgMathFileBackend ) {
|
||||
return FileBackendGroup::singleton()->get( $wgMathFileBackend );
|
||||
} else {
|
||||
static $backend = null;
|
||||
if ( !$backend ) {
|
||||
$backend = new FSFileBackend( [
|
||||
'name' => 'math-backend',
|
||||
'wikiId' => wfWikiID(),
|
||||
'lockManager' => new NullLockManager( [] ),
|
||||
'containerPaths' => [ 'math-render' => $wgMathDirectory ],
|
||||
'fileMode' => 0777,
|
||||
'obResetFunc' => 'wfResetOutputBuffers',
|
||||
'streamMimeFunc' => [ 'StreamFile', 'contentTypeFromPath' ]
|
||||
] );
|
||||
}
|
||||
return $backend;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the HTML rendering
|
||||
*
|
||||
* @return string HTML string
|
||||
*/
|
||||
public function getHtmlOutput() {
|
||||
return $this->getMathImageHTML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides base class. Writes to database, and if configured, squid.
|
||||
* @return bool
|
||||
*/
|
||||
public function writeCache() {
|
||||
global $wgUseSquid;
|
||||
|
||||
$updated = parent::writeCache();
|
||||
// If we're replacing an older version of the image, make sure it's current.
|
||||
if ( $updated && $wgUseSquid ) {
|
||||
$urls = [ $this->getMathImageUrl() ];
|
||||
$u = new CdnCacheUpdate( $urls );
|
||||
$u->doUpdate();
|
||||
}
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the rendering information from the database. If configured, checks whether files exist
|
||||
*
|
||||
* @return bool true if retrieved, false otherwise
|
||||
*/
|
||||
public function readCache() {
|
||||
global $wgMathCheckFiles;
|
||||
|
||||
if ( $this->isInDatabase() ) {
|
||||
if ( !$wgMathCheckFiles ) {
|
||||
// Short-circuit the file existence & migration checks
|
||||
return true;
|
||||
}
|
||||
$filename = $this->getHashPath() . "/{$this->getHash()}.png"; // final storage path
|
||||
$backend = $this->getBackend();
|
||||
if ( $backend->fileExists( [ 'src' => $filename ] ) ) {
|
||||
if ( $backend->getFileSize( [ 'src' => $filename ] ) == 0 ) {
|
||||
// Some horrible error corrupted stuff :(
|
||||
$backend->quickDelete( [ 'src' => $filename ] );
|
||||
} else {
|
||||
return true; // cache hit
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getPng() {
|
||||
global $wgHooks;
|
||||
// Workaround for bugfix for Bug 56769
|
||||
if ( isset( $wgHooks['ParserAfterParse']['FlushMathBackend'] ) ) {
|
||||
// XXX: save any pending files so the read below works
|
||||
call_user_func( $wgHooks['ParserAfterParse']['FlushMathBackend'] );
|
||||
}
|
||||
$backend = $this->getBackend();
|
||||
return $backend->getFileContents(
|
||||
[ 'src' => $this->getHashPath() . "/" . $this->getHash() . '.png' ]
|
||||
);
|
||||
}
|
||||
|
||||
public function isInDatabase() {
|
||||
$return = parent::isInDatabase();
|
||||
if ( $this->hash && $return ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the hash calculated by texvc
|
||||
*
|
||||
* @return string hash
|
||||
*/
|
||||
public function getHash() {
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $hash
|
||||
*/
|
||||
public function setHash( $hash ) {
|
||||
$this->changed = true;
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the html-representation of the mathematical formula.
|
||||
* @return string
|
||||
*/
|
||||
public function getHtml() {
|
||||
return $this->html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $html
|
||||
*/
|
||||
public function setHtml( $html ) {
|
||||
$this->changed = true;
|
||||
$this->html = $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the so called 'conservativeness' calculated by texvc
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getConservativeness() {
|
||||
return $this->conservativeness;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $conservativeness
|
||||
*/
|
||||
public function setConservativeness( $conservativeness ) {
|
||||
$this->changed = true;
|
||||
$this->conservativeness = $conservativeness;
|
||||
}
|
||||
|
||||
protected function getMathTableName() {
|
||||
return 'math';
|
||||
}
|
||||
|
||||
public function setOutputHash( $hash ) {
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip tex check for texvc rendering mode.
|
||||
* Checking the tex code in texvc mode just adds a dependency to the
|
||||
* texvccheck binary which does not improve security since the same
|
||||
* checks are performed by texvc anyhow. Especially given the fact that
|
||||
* texvccheck was derived from texvc.
|
||||
* @return bool
|
||||
*/
|
||||
public function checkTeX() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
--
|
||||
-- Used by the math module to keep track
|
||||
-- of previously-rendered items.
|
||||
--
|
||||
CREATE TABLE /*$wgDBprefix*/math (
|
||||
math_inputhash varbinary(16) NOT NULL PRIMARY KEY,
|
||||
math_outputhash varbinary(16) NOT NULL,
|
||||
math_html_conservativeness tinyint NOT NULL,
|
||||
math_html NVARCHAR(MAX),
|
||||
math_mathml NVARCHAR(MAX),
|
||||
);
|
|
@ -1,21 +0,0 @@
|
|||
--
|
||||
-- Used by the math module to keep track
|
||||
-- of previously-rendered items.
|
||||
--
|
||||
CREATE TABLE /*_*/math (
|
||||
-- Binary MD5 hash of the latex fragment, used as an identifier key.
|
||||
math_inputhash varbinary(16) NOT NULL PRIMARY KEY,
|
||||
|
||||
-- Not sure what this is, exactly...
|
||||
math_outputhash varbinary(16) NOT NULL,
|
||||
|
||||
-- texvc reports how well it thinks the HTML conversion worked;
|
||||
-- if it's a low level the PNG rendering may be preferred.
|
||||
math_html_conservativeness tinyint NOT NULL,
|
||||
|
||||
-- HTML output from texvc, if any
|
||||
math_html text,
|
||||
|
||||
-- MathML output from texvc, or from LaTeXML
|
||||
math_mathml text
|
||||
) /*$wgDBTableOptions*/;
|
|
@ -1,8 +0,0 @@
|
|||
CREATE TABLE &mw_prefix.math (
|
||||
math_inputhash VARCHAR2(32) NOT NULL,
|
||||
math_outputhash VARCHAR2(32) NOT NULL,
|
||||
math_html_conservativeness NUMBER NOT NULL,
|
||||
math_html CLOB,
|
||||
math_mathml CLOB
|
||||
);
|
||||
CREATE UNIQUE INDEX &mw_prefix.math_u01 ON &mw_prefix.math (math_inputhash);
|
|
@ -1,7 +0,0 @@
|
|||
CREATE TABLE math (
|
||||
math_inputhash BYTEA NOT NULL UNIQUE,
|
||||
math_outputhash BYTEA NOT NULL,
|
||||
math_html_conservativeness SMALLINT NOT NULL,
|
||||
math_html TEXT,
|
||||
math_mathml TEXT
|
||||
);
|
|
@ -1,21 +0,0 @@
|
|||
--
|
||||
-- Used by the math module to keep track
|
||||
-- of previously-rendered items.
|
||||
--
|
||||
CREATE TABLE /*_*/math (
|
||||
-- Binary MD5 hash of the latex fragment, used as an identifier key.
|
||||
math_inputhash varbinary(16) NOT NULL PRIMARY KEY,
|
||||
|
||||
-- Not sure what this is, exactly...
|
||||
math_outputhash varbinary(16) NOT NULL,
|
||||
|
||||
-- texvc reports how well it thinks the HTML conversion worked;
|
||||
-- if it's a low level the PNG rendering may be preferred.
|
||||
math_html_conservativeness tinyint NOT NULL,
|
||||
|
||||
-- HTML output from texvc, if any
|
||||
math_html text,
|
||||
|
||||
-- MathML output from texvc, or from LaTeXML
|
||||
math_mathml text
|
||||
) /*$wgDBTableOptions*/;
|
|
@ -18,13 +18,11 @@
|
|||
"MathHooks": "src/MathHooks.php",
|
||||
"MathRenderer": "src/MathRenderer.php",
|
||||
"MathRestbaseInterface": "src/MathRestbaseInterface.php",
|
||||
"MathTexvc": "MathTexvc.php",
|
||||
"MathSource": "src/MathSource.php",
|
||||
"MathMathML": "src/MathMathML.php",
|
||||
"MathMathMLCli": "src/MathMathMLCli.php",
|
||||
"MathLaTeXML": "MathLaTeXML.php",
|
||||
"MathInputCheck": "src/MathInputCheck.php",
|
||||
"MathInputCheckTexvc": "MathInputCheckTexvc.php",
|
||||
"MathInputCheckRestbase": "src/MathInputCheckRestbase.php",
|
||||
"SpecialMathShowImage": "src/SpecialMathShowImage.php",
|
||||
"SpecialMathStatus": "src/SpecialMathStatus.php",
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
# Compiled source
|
||||
*.cmi
|
||||
*.cmx
|
||||
*.o
|
||||
parser.mli
|
||||
|
||||
# The binaries
|
||||
texvc
|
||||
texvc_test
|
||||
texvc_tex
|
|
@ -1 +0,0 @@
|
|||
Deny from all
|
|
@ -1,87 +0,0 @@
|
|||
.PHONY: clean all
|
||||
|
||||
OBJ=render_info.cmo tex.cmo texutil.cmo parser.cmo lexer.cmo texvc.cmo \
|
||||
render_info.cmx tex.cmx texutil.cmx parser.cmx lexer.cmx texvc.cmx \
|
||||
lexer.cmi parser.cmi render_info.cmi tex.cmi texutil.cmi texvc.cmi \
|
||||
lexer.o parser.o render_info.o tex.o texutil.o texvc.o \
|
||||
lexer.ml parser.ml parser.mli texvc texvc.bc texvc_test.cmo \
|
||||
texvc_test.cmx texvc_test.cmi texvc_test.o texvc_test util.o \
|
||||
util.cmo util.cmx util.cmi texvc_cgi.cmi texvc_cgi texvc_cgi.cmo \
|
||||
render.o render.cmi render.cmo render.cmx texvc_tex.cmx \
|
||||
texvc_tex.o texvc_tex.cmi texvc_tex html.cmi html.cmo html.cmx \
|
||||
html.o mathml.cmi mathml.cmo mathml.cmx mathml.o
|
||||
CGIPATH=-I /usr/lib/ocaml/cgi -I /usr/lib/ocaml/netstring -I /usr/lib/ocaml/pcre
|
||||
|
||||
COMMON_NATIVE_OBJ =util.cmx parser.cmx html.cmx mathml.cmx texutil.cmx lexer.cmx
|
||||
COMMON_BYTECODE_OBJ=util.cmo parser.cmo html.cmo mathml.cmo texutil.cmo lexer.cmo
|
||||
|
||||
all: texvc texvc_test texvc_tex
|
||||
cgi: texvc_cgi.cmo texvc_cgi
|
||||
clean:
|
||||
rm -f $(OBJ)
|
||||
|
||||
# Native versions
|
||||
texvc: $(COMMON_NATIVE_OBJ) render.cmx texvc.cmx
|
||||
ocamlopt -o $@ unix.cmxa $^
|
||||
texvc_test: $(COMMON_NATIVE_OBJ) lexer.cmx texvc_test.cmx
|
||||
ocamlopt -o $@ $^
|
||||
texvc_tex: $(COMMON_NATIVE_OBJ) texvc_tex.cmx
|
||||
ocamlopt -o $@ $^
|
||||
|
||||
# Bytecode version
|
||||
texvc.bc: $(COMMON_BYTECODE_OBJ) render.cmo texvc.cmo
|
||||
ocamlc -o $@ unix.cma $^
|
||||
|
||||
# CGI related targets:
|
||||
texvc_cgi.cmo: texvc_cgi.ml
|
||||
ocamlc -c $(CGIPATH) $<
|
||||
texvc_cgi: util.cmo parser.cmo texutil.cmo render.cmo lexer.cmo texvc_cgi.cmo
|
||||
ocamlc -o $@ unix.cma $(CGIPATH) pcre.cma netstring.cma cgi.cma $^
|
||||
chmod g-w $@
|
||||
|
||||
#
|
||||
# Pattern rules
|
||||
#
|
||||
|
||||
# .ml source .mli interface
|
||||
# .cmi compiled interface
|
||||
# .cmo object .cma library object
|
||||
# .cmx object file .cmxa library object file
|
||||
%.ml: %.mll
|
||||
ocamllex $<
|
||||
%.mli %.ml: %.mly
|
||||
ocamlyacc $<
|
||||
%.cmo: %.ml
|
||||
ocamlc -c $<
|
||||
%.cmx: %.ml
|
||||
ocamlopt -c $<
|
||||
%.cmi: %.mli
|
||||
ocamlc -c $<
|
||||
|
||||
# Various dependencies
|
||||
|
||||
html.cmo: render_info.cmi tex.cmi util.cmo html.cmi
|
||||
html.cmx: render_info.cmi tex.cmi util.cmx html.cmi
|
||||
html.cmi: tex.cmi
|
||||
lexer.cmo: parser.cmi render_info.cmi tex.cmi texutil.cmi
|
||||
lexer.cmx: parser.cmx render_info.cmi tex.cmi texutil.cmx
|
||||
mathml.cmo: tex.cmi mathml.cmi
|
||||
mathml.cmx: tex.cmi mathml.cmi
|
||||
mathml.cmi: tex.cmi
|
||||
parser.cmo: render_info.cmi tex.cmi parser.cmi
|
||||
parser.cmx: render_info.cmi tex.cmi parser.cmi
|
||||
parser.cmi: render_info.cmi tex.cmi
|
||||
render.cmo: texutil.cmi util.cmo
|
||||
render.cmx: texutil.cmx util.cmx
|
||||
tex.cmi: render_info.cmi
|
||||
texutil.cmo: html.cmi parser.cmi render_info.cmi tex.cmi util.cmo texutil.cmi
|
||||
texutil.cmx: html.cmx parser.cmx render_info.cmi tex.cmi util.cmx texutil.cmi
|
||||
texutil.cmi: parser.cmi tex.cmi
|
||||
texvc.cmo: html.cmi lexer.cmo mathml.cmi parser.cmi render.cmo texutil.cmi util.cmo
|
||||
texvc.cmx: html.cmx lexer.cmx mathml.cmx parser.cmx render.cmx texutil.cmx util.cmx
|
||||
texvc_cgi.cmo: lexer.cmo parser.cmi render.cmo texutil.cmi util.cmo
|
||||
texvc_cgi.cmx: lexer.cmx parser.cmx render.cmx texutil.cmx util.cmx
|
||||
texvc_test.cmo: html.cmi lexer.cmo parser.cmi texutil.cmi util.cmo
|
||||
texvc_test.cmx: html.cmx lexer.cmx parser.cmx texutil.cmx util.cmx
|
||||
texvc_tex.cmo: lexer.cmo parser.cmi texutil.cmi util.cmo
|
||||
texvc_tex.cmx: lexer.cmx parser.cmx texutil.cmx util.cmx
|
123
math/README
123
math/README
|
@ -1,123 +0,0 @@
|
|||
== About texvc ==
|
||||
|
||||
texvc takes LaTeX-compatible equations and produces formatted output in HTML,
|
||||
MathML, and (via LaTeX/dvipng) rasterized PNG images.
|
||||
Input data is parsed and scrutinized for safety, and the output includes an
|
||||
estimate of whether the code is simple enough that HTML rendering will look
|
||||
acceptable.
|
||||
|
||||
The program was written by Tomasz Wegrzanowski for use with MediaWiki; it's
|
||||
included as part of the MediaWiki package (http://www.mediawiki.org) and is
|
||||
under the GPL license.
|
||||
|
||||
Please report bugs at: https://bugzilla.wikimedia.org/
|
||||
with "MediaWiki extensions" as product and "Math" as component.
|
||||
|
||||
== Setup ==
|
||||
|
||||
=== Requirements ===
|
||||
|
||||
OCaml 3.06 or later is required to compile texvc; this can be acquired from
|
||||
http://caml.inria.fr/ if your system doesn't have it available.
|
||||
|
||||
The makefile requires GNU make.
|
||||
|
||||
Rasterization is done via LaTeX, dvipng. These need to be installed and in
|
||||
the PATH: latex, dvipng
|
||||
|
||||
AMS* packages for LaTeX also need to be installed. Without AMS* some equations
|
||||
will render correctly while others won't render. Most distributions of TeX
|
||||
already contain AMS*. In Debian/Ubuntu you need to install tetex-extra.
|
||||
|
||||
To work properly with rendering non-ASCII Unicode characters, a supplemental TeX
|
||||
package is needed (cjk-latex in Debian)
|
||||
|
||||
In Ubuntu Precise, all dependencies can be installed using:
|
||||
|
||||
$ sudo apt-get install build-essential dvipng ocaml \
|
||||
texlive-fonts-recommended texlive-lang-greek texlive-latex-recommended
|
||||
|
||||
=== Installation ===
|
||||
|
||||
Run 'make' (or 'gmake' if GNU make is not your default make). This should
|
||||
produce the texvc executable.
|
||||
|
||||
By default, MediaWiki will search in this directory for texvc, if you moved it elsewhere,
|
||||
you'll have to modify $wgTexvc and set it to the path of the texvc executable.
|
||||
|
||||
== Usage ==
|
||||
|
||||
Normally texvc is called from MediaWiki's Math.php modules and everything
|
||||
Just Works. It can be run manually for testing or for use in another app.
|
||||
|
||||
=== Command-line parameters ===
|
||||
|
||||
texvc <temp directory> <output directory> <TeX code> <encoding> <color>
|
||||
|
||||
Be sure to properly quote the TeX code!
|
||||
|
||||
Example:
|
||||
|
||||
texvc /home/wiki/tmp /home/wiki/math "y=x+2" iso-8859-1 "rgb 1.0 1.0 1.0"
|
||||
|
||||
=== Output format ===
|
||||
|
||||
Status codes and HTML/MathML transformations are returned on stdout.
|
||||
A rasterized PNG file will be written to the output directory, named
|
||||
for the MD5 hash code.
|
||||
|
||||
texvc output format is like this:
|
||||
+%5 ok, but not html or mathml
|
||||
c%5%h ok, conservative html, no mathml
|
||||
m%5%h ok, moderate html, no mathml
|
||||
l%5%h ok, liberal html, no mathml
|
||||
C%5%h\0%m ok, conservative html, with mathml
|
||||
M%5%h\0%m ok, moderate html, with mathml
|
||||
L%5%h\0%m ok, liberal html, with mathml
|
||||
X%5%m ok, no html, with mathml
|
||||
S syntax error
|
||||
E lexing error
|
||||
F%s unknown function %s
|
||||
- other error
|
||||
|
||||
\0 - null character
|
||||
%5 - md5, 32 hex characters
|
||||
%h - html code, without \0 characters
|
||||
%m - mathml code, without \0 characters
|
||||
|
||||
|
||||
== Troubleshooting ==
|
||||
|
||||
Unfortunately, many error conditions with rasterization are not well reported.
|
||||
texvc will return as though everything is successful, and the only obvious
|
||||
sign of problems for the user is a big X on a wiki page where an equation
|
||||
should be.
|
||||
|
||||
Try running texvc from the command line to ensure that the software it relies
|
||||
upon is all set up.
|
||||
|
||||
Ensure that the temporary and math directories exist and can be written to by
|
||||
the user account the web server runs under; if you don't control the server,
|
||||
you may have to make them world-writable.
|
||||
|
||||
If some equations render correctly while others don't, you probably don't have
|
||||
AMS* packages for LaTeX installed. Most distributions of TeX come with AMS*.
|
||||
In Debian/Ubuntu AMS* is in tetex-extra package.
|
||||
To check if that is the problem you can try those two equations:
|
||||
x + y
|
||||
x \implies y
|
||||
The first uses only standard LaTeX, while the second uses symbol \implies from AMS*.
|
||||
If the first renders, but the second doesn't, you need to install AMS*.
|
||||
|
||||
== Hacking ==
|
||||
|
||||
Before you start hacking on the math package its good to know the workflow,
|
||||
which is basically:
|
||||
|
||||
1. texvc gets called by Math/Math.body.php (check out the line beginning with "$cmd")
|
||||
2. texvc does its magic, which is basically to check for invalid latex code.
|
||||
3. texvc takes the user input if valid and creates a latex file containing it, see
|
||||
get_preface in texutil.ml
|
||||
4. dvipng(1) gets called to create a .png file
|
||||
See render.ml for this process (commenting out the removal of
|
||||
the temporary file is useful for debugging).
|
|
@ -1,3 +0,0 @@
|
|||
* It would be better if PNGs were transparent
|
||||
* CJK support
|
||||
* Documentation, in particular about instalation of Latex support for Unicode
|
144
math/html.ml
144
math/html.ml
|
@ -1,144 +0,0 @@
|
|||
open Render_info
|
||||
open Tex
|
||||
open Util
|
||||
|
||||
exception Too_difficult_for_html
|
||||
type context = CTX_NORMAL | CTX_IT | CTX_RM
|
||||
type conservativeness_t = CONSERVATIVE | MODERATE | LIBERAL
|
||||
|
||||
let conservativeness = ref CONSERVATIVE
|
||||
let html_liberal () = conservativeness := LIBERAL
|
||||
let html_moderate () = if !conservativeness = CONSERVATIVE then conservativeness := MODERATE else ()
|
||||
|
||||
|
||||
let new_ctx = function
|
||||
FONTFORCE_IT -> CTX_IT
|
||||
| FONTFORCE_RM -> CTX_RM
|
||||
let font_render lit = function
|
||||
(_, FONT_UFH) -> lit
|
||||
| (_, FONT_UF) -> lit
|
||||
| (CTX_IT,FONT_RTI) -> raise Too_difficult_for_html
|
||||
| (_, FONT_RTI) -> lit
|
||||
| (CTX_IT,FONT_RM) -> "<i>"^lit^"</i>"
|
||||
| (_, FONT_RM) -> lit
|
||||
| (CTX_RM,FONT_IT) -> lit
|
||||
| (_, FONT_IT) -> "<i>"^lit^"</i>"
|
||||
|
||||
let rec html_render_flat ctx = function
|
||||
TEX_LITERAL (HTMLABLE (ft,_,sh))::r -> (html_liberal (); (font_render sh (ctx,ft))^html_render_flat ctx r)
|
||||
| TEX_LITERAL (HTMLABLEC(ft,_,sh))::r -> (font_render sh (ctx,ft))^html_render_flat ctx r
|
||||
| TEX_LITERAL (MHTMLABLEC(ft,_,sh,_,_))::r -> (font_render sh (ctx,ft))^html_render_flat ctx r
|
||||
| TEX_LITERAL (HTMLABLEM(ft,_,sh))::r -> (html_moderate(); (font_render sh (ctx,ft))^html_render_flat ctx r)
|
||||
| TEX_LITERAL (HTMLABLE_BIG (_,sh))::r -> (html_liberal (); sh^html_render_flat ctx r)
|
||||
| TEX_FUN1hl (_,(f1,f2),a)::r -> f1^(html_render_flat ctx [a])^f2^html_render_flat ctx r
|
||||
| TEX_FUN1hf (_,ff,a)::r -> (html_render_flat (new_ctx ff) [a])^html_render_flat ctx r
|
||||
| TEX_DECLh (_,ff,a)::r -> (html_render_flat (new_ctx ff) a)^html_render_flat ctx r
|
||||
| TEX_CURLY ls::r -> html_render_flat ctx (ls @ r)
|
||||
| TEX_DQ (a,b)::r -> (html_liberal ();
|
||||
let bs = html_render_flat ctx [b] in match html_render_size ctx a with
|
||||
true, s -> raise Too_difficult_for_html
|
||||
| false, s -> s^"<sub>"^bs^"</sub>")^html_render_flat ctx r
|
||||
| TEX_UQ (a,b)::r -> (html_liberal ();
|
||||
let bs = html_render_flat ctx [b] in match html_render_size ctx a with
|
||||
true, s -> raise Too_difficult_for_html
|
||||
| false, s -> s^"<sup>"^bs^"</sup>")^html_render_flat ctx r
|
||||
| TEX_FQ (a,b,c)::r -> (html_liberal ();
|
||||
(let bs = html_render_flat ctx [b] in let cs = html_render_flat ctx [c] in
|
||||
match html_render_size ctx a with
|
||||
true, s -> raise Too_difficult_for_html
|
||||
| false, s -> s^"<sub>"^bs^"</sub><sup>"^cs^"</sup>")^html_render_flat ctx r)
|
||||
| TEX_DQN (a)::r -> (html_liberal ();
|
||||
let bs = html_render_flat ctx [a] in "<sub>"^bs^"</sub>")^html_render_flat ctx r
|
||||
| TEX_UQN (a)::r -> (html_liberal ();
|
||||
let bs = html_render_flat ctx [a] in "<sup>"^bs^"</sup>")^html_render_flat ctx r
|
||||
| TEX_FQN (a,b)::r -> (html_liberal ();
|
||||
(let bs = html_render_flat ctx [a] in let cs = html_render_flat ctx [b] in "<sub>"^bs^"</sub><sup>"^cs^"</sup>")^html_render_flat ctx r)
|
||||
| TEX_BOX (_,s)::r -> s^html_render_flat ctx r
|
||||
| TEX_LITERAL (TEX_ONLY _)::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN1 _::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN1nb _::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN2 _::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN2nb _::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN2h _::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN2sq _::_ -> raise Too_difficult_for_html
|
||||
| TEX_INFIX _::_ -> raise Too_difficult_for_html
|
||||
| TEX_INFIXh _::_ -> raise Too_difficult_for_html
|
||||
| TEX_MATRIX _::_ -> raise Too_difficult_for_html
|
||||
| TEX_LR _::_ -> raise Too_difficult_for_html
|
||||
| TEX_BIG _::_ -> raise Too_difficult_for_html
|
||||
| [] -> ""
|
||||
and html_render_size ctx = function
|
||||
TEX_LITERAL (HTMLABLE_BIG (_,sh)) -> true,sh
|
||||
| x -> false,html_render_flat ctx [x]
|
||||
|
||||
let rec html_render_deep ctx = function
|
||||
TEX_LITERAL (HTMLABLE (ft,_,sh))::r -> (html_liberal (); ("",(font_render sh (ctx,ft)),"")::html_render_deep ctx r)
|
||||
| TEX_LITERAL (HTMLABLEM(ft,_,sh))::r -> (html_moderate(); ("",(font_render sh (ctx,ft)),"")::html_render_deep ctx r)
|
||||
| TEX_LITERAL (HTMLABLEC(ft,_,sh))::r -> ("",(font_render sh (ctx,ft)),"")::html_render_deep ctx r
|
||||
| TEX_LITERAL (MHTMLABLEC(ft,_,sh,_,_))::r -> ("",(font_render sh (ctx,ft)),"")::html_render_deep ctx r
|
||||
| TEX_LITERAL (HTMLABLE_BIG (_,sh))::r -> (html_liberal (); ("",sh,"")::html_render_deep ctx r)
|
||||
| TEX_FUN2h (_,f,a,b)::r -> (html_liberal (); (f a b)::html_render_deep ctx r)
|
||||
| TEX_INFIXh (_,f,a,b)::r -> (html_liberal (); (f a b)::html_render_deep ctx r)
|
||||
| TEX_CURLY ls::r -> html_render_deep ctx (ls @ r)
|
||||
| TEX_DQ (a,b)::r -> (let bs = html_render_flat ctx [b] in match html_render_size ctx a with
|
||||
true, s -> "","<span style='font-size: x-large; font-family: serif;'>"^s^"</span>",bs
|
||||
| false, s -> "",(s^"<sub>"^bs^"</sub>"),"")::html_render_deep ctx r
|
||||
| TEX_UQ (a,b)::r -> (let bs = html_render_flat ctx [b] in match html_render_size ctx a with
|
||||
true, s -> bs,"<span style='font-size: x-large; font-family: serif;'>"^s^"</span>",""
|
||||
| false, s -> "",(s^"<sup>"^bs^"</sup>"),"")::html_render_deep ctx r
|
||||
| TEX_FQ (a,b,c)::r -> (html_liberal ();
|
||||
(let bs = html_render_flat ctx [b] in let cs = html_render_flat ctx [c] in
|
||||
match html_render_size ctx a with
|
||||
true, s -> (cs,"<span style='font-size: x-large; font-family: serif;'>"^s^"</span>",bs)
|
||||
| false, s -> ("",(s^"<sub>"^bs^"</sub><sup>"^cs^"</sup>"),""))::html_render_deep ctx r)
|
||||
| TEX_DQN (a)::r -> (let bs = html_render_flat ctx [a] in "",("<sub>"^bs^"</sub>"),"")::html_render_deep ctx r
|
||||
| TEX_UQN (a)::r -> (let bs = html_render_flat ctx [a] in "",("<sup>"^bs^"</sup>"),"")::html_render_deep ctx r
|
||||
| TEX_FQN (a,b)::r -> (html_liberal ();
|
||||
(let bs = html_render_flat ctx [a] in let cs = html_render_flat ctx [b] in
|
||||
("",("<sub>"^bs^"</sub><sup>"^cs^"</sup>"),""))::html_render_deep ctx r)
|
||||
| TEX_FUN1hl (_,(f1,f2),a)::r -> ("",f1,"")::(html_render_deep ctx [a]) @ ("",f2,"")::html_render_deep ctx r
|
||||
| TEX_FUN1hf (_,ff,a)::r -> (html_render_deep (new_ctx ff) [a]) @ html_render_deep ctx r
|
||||
| TEX_DECLh (_,ff,a)::r -> (html_render_deep (new_ctx ff) a) @ html_render_deep ctx r
|
||||
| TEX_BOX (_,s)::r -> ("",s,"")::html_render_deep ctx r
|
||||
| TEX_LITERAL (TEX_ONLY _)::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN1 _::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN1nb _::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN2 _::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN2nb _::_ -> raise Too_difficult_for_html
|
||||
| TEX_FUN2sq _::_ -> raise Too_difficult_for_html
|
||||
| TEX_INFIX _::_ -> raise Too_difficult_for_html
|
||||
| TEX_MATRIX _::_ -> raise Too_difficult_for_html
|
||||
| TEX_LR _::_ -> raise Too_difficult_for_html
|
||||
| TEX_BIG _::_ -> raise Too_difficult_for_html
|
||||
| [] -> []
|
||||
|
||||
let rec html_render_table = function
|
||||
sf,u,d,("",a,"")::("",b,"")::r -> html_render_table (sf,u,d,(("",a^b,"")::r))
|
||||
| sf,u,d,(("",a,"") as c)::r -> html_render_table (c::sf,u,d,r)
|
||||
| sf,u,d,((_,a,"") as c)::r -> html_render_table (c::sf,true,d,r)
|
||||
| sf,u,d,(("",a,_) as c)::r -> html_render_table (c::sf,u,true,r)
|
||||
| sf,u,d,((_,a,_) as c)::r -> html_render_table (c::sf,true,true,r)
|
||||
| sf,false,false,[] -> mapjoin (function (u,m,d) -> m) (List.rev sf)
|
||||
| sf,true,false,[] -> let ustr,mstr = List.fold_left (fun (us,ms) (u,m,d) -> (us^"<td>"^u^"</td>",ms^"<td>"^u^"</td>"))
|
||||
("","") (List.rev sf) in
|
||||
"\n<table>\n" ^
|
||||
"\t\t<tr style='text-align: center; vertical-align: bottom;'>" ^ ustr ^ "</tr>\n" ^
|
||||
"\t\t<tr style='text-align: center;'>" ^ mstr ^ "</tr>\n" ^
|
||||
"</table>\n"
|
||||
| sf,false,true,[] -> let mstr,dstr = List.fold_left (fun (ms,ds) (u,m,d) -> (ms^"<td>"^m^"</td>",ds^"<td>"^d^"</td>"))
|
||||
("","") (List.rev sf) in
|
||||
"\n<table>\n" ^
|
||||
"\t\t<tr style='text-align: center;'>" ^ mstr ^ "</tr>\n" ^
|
||||
"\t\t<tr style='text-align: center; vertical-align: top;'>" ^ dstr ^ "</tr>\n" ^
|
||||
"</table>\n"
|
||||
| sf,true,true,[] -> let ustr,mstr,dstr = List.fold_left (fun (us,ms,ds) (u,m,d) ->
|
||||
(us^"<td>"^u^"</td>",ms^"<td>"^m^"</td>",ds^"<td>"^d^"</td>")) ("","","") (List.rev sf) in
|
||||
"\n<table>\n" ^
|
||||
"\t\t<tr style='text-align: center; vertical-align: bottom;'>" ^ ustr ^ "</tr>\n" ^
|
||||
"\t\t<tr style='text-align: center;'>" ^ mstr ^ "</tr>\n" ^
|
||||
"\t\t<tr style='text-align: center; vertical-align: top;'>" ^ dstr ^ "</tr>\n" ^
|
||||
"</table>\n"
|
||||
|
||||
let html_render tree = html_render_table ([],false,false,html_render_deep CTX_NORMAL tree)
|
||||
|
||||
let render tree = try Some (html_render tree) with _ -> None
|
|
@ -1,5 +0,0 @@
|
|||
val render : Tex.t list -> string option
|
||||
val html_render : Tex.t list -> string
|
||||
|
||||
type conservativeness_t = CONSERVATIVE | MODERATE | LIBERAL
|
||||
val conservativeness : conservativeness_t ref
|
124
math/lexer.mll
124
math/lexer.mll
|
@ -1,124 +0,0 @@
|
|||
{
|
||||
open Parser
|
||||
open Render_info
|
||||
open Tex
|
||||
}
|
||||
let space = [' ' '\t' '\n' '\r']
|
||||
let alpha = ['a'-'z' 'A'-'Z']
|
||||
let literal_id = ['a'-'z' 'A'-'Z']
|
||||
let literal_mn = ['0'-'9']
|
||||
let literal_uf_lt = [',' ':' ';' '?' '!' '\'']
|
||||
let delimiter_uf_lt = ['(' ')' '.']
|
||||
let literal_uf_op = ['+' '-' '*' '=']
|
||||
let delimiter_uf_op = ['/' '|']
|
||||
let boxchars = ['0'-'9' 'a'-'z' 'A'-'Z' '+' '-' '*' ',' '=' '(' ')' ':' '/' ';' '?' '.' '!' '\'' '`' ' ' '\128'-'\255']
|
||||
let aboxchars = ['0'-'9' 'a'-'z' 'A'-'Z' '+' '-' '*' ',' '=' '(' ')' ':' '/' ';' '?' '.' '!' '\'' '`' ' ']
|
||||
let latex_function_names = "arccos" | "arcsin" | "arctan" | "arg" | "cos" | "cosh" | "cot" | "coth" | "csc"| "deg" | "det" | "dim" | "exp" | "gcd" | "hom" | "inf" | "ker" | "lg" | "lim" | "liminf" | "limsup" | "ln" | "log" | "max" | "min" | "Pr" | "sec" | "sin" | "sinh" | "sup" | "tan" | "tanh"
|
||||
let mediawiki_function_names = "arccot" | "arcsec" | "arccsc" | "sgn" | "sen"
|
||||
|
||||
rule token = parse
|
||||
space + { token lexbuf }
|
||||
| "\\text" space * '{' aboxchars + '}'
|
||||
{ Texutil.tex_use_ams (); let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\text", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\mbox" space * '{' aboxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\mbox", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\hbox" space * '{' aboxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\hbox", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\vbox" space * '{' aboxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\vbox", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\text" space * '{' boxchars + '}'
|
||||
{ Texutil.tex_use_ams (); let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
Texutil.tex_use_nonascii();
|
||||
BOX ("\\text", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\mbox" space * '{' boxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
Texutil.tex_use_nonascii();
|
||||
BOX ("\\mbox", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\hbox" space * '{' boxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
Texutil.tex_use_nonascii();
|
||||
BOX ("\\hbox", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\vbox" space * '{' boxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
Texutil.tex_use_nonascii();
|
||||
BOX ("\\vbox", String.sub str n (String.length str - n - 1)) }
|
||||
| literal_id { let str = Lexing.lexeme lexbuf in LITERAL (MHTMLABLEC (FONT_IT, str,str,MI,str)) }
|
||||
| literal_mn { let str = Lexing.lexeme lexbuf in LITERAL (MHTMLABLEC (FONT_RM, str,str,MN,str)) }
|
||||
| literal_uf_lt { let str = Lexing.lexeme lexbuf in LITERAL (HTMLABLEC (FONT_UFH, str,str)) }
|
||||
| delimiter_uf_lt { let str = Lexing.lexeme lexbuf in DELIMITER (HTMLABLEC (FONT_UFH, str,str)) }
|
||||
| "-" { let str = Lexing.lexeme lexbuf in LITERAL (MHTMLABLEC (FONT_UFH,"-"," − ",MO,str))}
|
||||
| literal_uf_op { let str = Lexing.lexeme lexbuf in LITERAL (MHTMLABLEC (FONT_UFH, str," "^str^" ",MO,str)) }
|
||||
| delimiter_uf_op { let str = Lexing.lexeme lexbuf in DELIMITER (MHTMLABLEC (FONT_UFH, str," "^str^" ",MO,str)) }
|
||||
| "\\operatorname" { Texutil.tex_use_ams(); FUN_AR1nb "\\operatorname" }
|
||||
| "\\sqrt" space * "[" { FUN_AR1opt "\\sqrt" }
|
||||
| "\\xleftarrow" space * "[" { Texutil.tex_use_ams(); FUN_AR1opt "\\xleftarrow" }
|
||||
| "\\xrightarrow" space * "[" { Texutil.tex_use_ams(); FUN_AR1opt "\\xrightarrow" }
|
||||
| "\\" (latex_function_names as name) space * "(" { LITERAL (HTMLABLEC(FONT_UFH,"\\" ^ name ^ "(", name ^ "(")) }
|
||||
| "\\" (latex_function_names as name) space * "[" { LITERAL (HTMLABLEC(FONT_UFH,"\\" ^ name ^ "[", name ^ "[")) }
|
||||
| "\\" (latex_function_names as name) space * "\\{" { LITERAL (HTMLABLEC(FONT_UFH,"\\" ^ name ^ "\\{", name ^ "{")) }
|
||||
| "\\" (latex_function_names as name) space * { LITERAL (HTMLABLEC(FONT_UFH,"\\" ^ name ^ " ", name ^ " ")) }
|
||||
| "\\" (mediawiki_function_names as name) space * "(" { (Texutil.tex_use_ams(); LITERAL (HTMLABLEC(FONT_UFH,"\\operatorname{" ^ name ^ "}(", name^ "("))) }
|
||||
| "\\" (mediawiki_function_names as name) space * "[" { (Texutil.tex_use_ams(); LITERAL (HTMLABLEC(FONT_UFH,"\\operatorname{" ^ name ^ "}[", name^ "["))) }
|
||||
| "\\" (mediawiki_function_names as name) space * "\\{" { (Texutil.tex_use_ams(); LITERAL (HTMLABLEC(FONT_UFH,"\\operatorname{" ^ name ^ "}\\{", name^ "{"))) }
|
||||
| "\\" (mediawiki_function_names as name) space * { (Texutil.tex_use_ams(); LITERAL (HTMLABLEC(FONT_UFH,"\\operatorname{" ^ name ^ "} ", name ^ " "))) }
|
||||
| "\\" alpha + { Texutil.find (Lexing.lexeme lexbuf) }
|
||||
| "\\," { LITERAL (HTMLABLE (FONT_UF, "\\,"," ")) }
|
||||
| "\\ " { LITERAL (HTMLABLE (FONT_UF, "\\ "," ")) }
|
||||
| "\\;" { LITERAL (HTMLABLE (FONT_UF, "\\;"," ")) }
|
||||
| "\\!" { LITERAL (TEX_ONLY "\\!") }
|
||||
| "\\{" { DELIMITER (HTMLABLEC(FONT_UFH,"\\{","{")) }
|
||||
| "\\}" { DELIMITER (HTMLABLEC(FONT_UFH,"\\}","}")) }
|
||||
| "\\|" { DELIMITER (HTMLABLE (FONT_UFH,"\\|","||")) }
|
||||
| "\\_" { LITERAL (HTMLABLEC(FONT_UFH,"\\_","_")) }
|
||||
| "\\#" { LITERAL (HTMLABLE (FONT_UFH,"\\#","#")) }
|
||||
| "\\%" { LITERAL (HTMLABLE (FONT_UFH,"\\%","%")) }
|
||||
| "\\$" { LITERAL (HTMLABLE (FONT_UFH,"\\$","$")) }
|
||||
| "\\&" { LITERAL (HTMLABLEC (FONT_RM,"\\&","&")) }
|
||||
| "&" { NEXT_CELL }
|
||||
| "\\\\" { NEXT_ROW }
|
||||
| "\\begin{matrix}" { Texutil.tex_use_ams(); BEGIN__MATRIX }
|
||||
| "\\end{matrix}" { END__MATRIX }
|
||||
| "\\begin{pmatrix}" { Texutil.tex_use_ams(); BEGIN_PMATRIX }
|
||||
| "\\end{pmatrix}" { END_PMATRIX }
|
||||
| "\\begin{bmatrix}" { Texutil.tex_use_ams(); BEGIN_BMATRIX }
|
||||
| "\\end{bmatrix}" { END_BMATRIX }
|
||||
| "\\begin{Bmatrix}" { Texutil.tex_use_ams(); BEGIN_BBMATRIX }
|
||||
| "\\end{Bmatrix}" { END_BBMATRIX }
|
||||
| "\\begin{vmatrix}" { Texutil.tex_use_ams(); BEGIN_VMATRIX }
|
||||
| "\\end{vmatrix}" { END_VMATRIX }
|
||||
| "\\begin{Vmatrix}" { Texutil.tex_use_ams(); BEGIN_VVMATRIX }
|
||||
| "\\end{Vmatrix}" { END_VVMATRIX }
|
||||
| "\\begin{array}" { Texutil.tex_use_ams(); BEGIN_ARRAY }
|
||||
| "\\end{array}" { END_ARRAY }
|
||||
| "\\begin{align}" { Texutil.tex_use_ams(); BEGIN_ALIGN }
|
||||
| "\\end{align}" { END_ALIGN }
|
||||
| "\\begin{alignat}" { Texutil.tex_use_ams(); BEGIN_ALIGNAT }
|
||||
| "\\end{alignat}" { END_ALIGNAT }
|
||||
| "\\begin{smallmatrix}" { Texutil.tex_use_ams(); BEGIN_SMALLMATRIX }
|
||||
| "\\end{smallmatrix}" { END_SMALLMATRIX }
|
||||
| "\\begin{cases}" { Texutil.tex_use_ams(); BEGIN_CASES }
|
||||
| "\\end{cases}" { END_CASES }
|
||||
| '>' { LITERAL (HTMLABLEC(FONT_UFH,">"," > ")) }
|
||||
| '<' { LITERAL (HTMLABLEC(FONT_UFH,"<"," < ")) }
|
||||
| '%' { LITERAL (HTMLABLEC(FONT_UFH,"\\%","%")) }
|
||||
| '$' { LITERAL (HTMLABLEC(FONT_UFH,"\\$","$")) }
|
||||
| '~' { LITERAL (HTMLABLE (FONT_UF, "~"," ")) }
|
||||
| '[' { DELIMITER (HTMLABLEC(FONT_UFH,"[","[")) }
|
||||
| ']' { SQ_CLOSE }
|
||||
| '{' { CURLY_OPEN }
|
||||
| '}' { CURLY_CLOSE }
|
||||
| '^' { SUP }
|
||||
| '_' { SUB }
|
||||
| eof { EOF }
|
|
@ -1,20 +0,0 @@
|
|||
open Tex
|
||||
open Render_info
|
||||
|
||||
type t = TREE_MN of string | TREE_MO of string | TREE_MI of string
|
||||
|
||||
let rec make_mathml_tree = function
|
||||
TREE_MN a::otr,TEX_LITERAL(MHTMLABLEC(_,_,_,MN,b))::itr -> make_mathml_tree(TREE_MN (a^b)::otr,itr)
|
||||
| otr,TEX_LITERAL(MHTMLABLEC(_,_,_,MN,a))::itr -> make_mathml_tree(TREE_MN a::otr,itr)
|
||||
| otr,TEX_LITERAL(MHTMLABLEC(_,_,_,MO,a))::itr -> make_mathml_tree(TREE_MO a::otr,itr)
|
||||
| otr,TEX_LITERAL(MHTMLABLEC(_,_,_,MI,a))::itr -> make_mathml_tree(TREE_MI a::otr,itr)
|
||||
| otr,TEX_CURLY(crl)::itr -> make_mathml_tree(otr,crl@itr)
|
||||
| otr,[] -> List.rev otr
|
||||
| _ -> failwith "failed to render mathml"
|
||||
|
||||
let render_mathml_tree = function
|
||||
TREE_MN s -> "<mn>"^s^"</mn>"
|
||||
| TREE_MI s -> "<mi>"^s^"</mi>"
|
||||
| TREE_MO s -> "<mo>"^s^"</mo>"
|
||||
|
||||
let render tree = try Some (Util.mapjoin render_mathml_tree (make_mathml_tree ([],tree))) with _ -> None
|
|
@ -1 +0,0 @@
|
|||
val render : Tex.t list -> string option
|
119
math/parser.mly
119
math/parser.mly
|
@ -1,119 +0,0 @@
|
|||
%{
|
||||
open Tex
|
||||
open Render_info
|
||||
|
||||
let sq_close_ri = HTMLABLEC(FONT_UFH,"]", "]")
|
||||
%}
|
||||
%token <Render_info.t> LITERAL DELIMITER
|
||||
%token <string> FUN_AR2 FUN_INFIX FUN_AR1 DECL FUN_AR1nb FUN_AR1opt BIG FUN_AR2nb
|
||||
%token <string*string> BOX
|
||||
%token <string*(string*string)> FUN_AR1hl
|
||||
%token <string*Render_info.font_force> FUN_AR1hf DECLh
|
||||
%token <string*(Tex.t->Tex.t->string*string*string)> FUN_AR2h
|
||||
%token <string*(Tex.t list->Tex.t list->string*string*string)> FUN_INFIXh
|
||||
%token EOF CURLY_OPEN CURLY_CLOSE SUB SUP SQ_CLOSE NEXT_CELL NEXT_ROW
|
||||
%token BEGIN__MATRIX BEGIN_PMATRIX BEGIN_BMATRIX BEGIN_BBMATRIX BEGIN_VMATRIX BEGIN_VVMATRIX BEGIN_CASES BEGIN_ARRAY BEGIN_ALIGN BEGIN_ALIGNAT BEGIN_SMALLMATRIX
|
||||
%token END__MATRIX END_PMATRIX END_BMATRIX END_BBMATRIX END_VMATRIX END_VVMATRIX END_CASES END_ARRAY END_ALIGN END_ALIGNAT END_SMALLMATRIX
|
||||
%token LEFT RIGHT
|
||||
%type <Tex.t list> tex_expr
|
||||
%start tex_expr
|
||||
|
||||
%%
|
||||
tex_expr:
|
||||
expr EOF { $1 }
|
||||
| ne_expr FUN_INFIX ne_expr EOF
|
||||
{ [TEX_INFIX($2,$1,$3)] }
|
||||
| ne_expr FUN_INFIXh ne_expr EOF
|
||||
{ let t,h=$2 in [TEX_INFIXh(t,h,$1,$3)] }
|
||||
expr:
|
||||
/* */ { [] }
|
||||
| ne_expr { $1 }
|
||||
ne_expr:
|
||||
lit_aq expr { $1 :: $2 }
|
||||
| litsq_aq expr { $1 :: $2 }
|
||||
| DECLh expr { let t,h = $1 in [TEX_DECLh(t,h,$2)] }
|
||||
litsq_aq:
|
||||
litsq_zq { $1 }
|
||||
| litsq_dq { let base,downi = $1 in TEX_DQ(base,downi) }
|
||||
| litsq_uq { let base,upi = $1 in TEX_UQ(base,upi)}
|
||||
| litsq_fq { $1 }
|
||||
litsq_fq:
|
||||
litsq_dq SUP lit { let base,downi = $1 in TEX_FQ(base,downi,$3) }
|
||||
| litsq_uq SUB lit { let base,upi = $1 in TEX_FQ(base,$3,upi) }
|
||||
litsq_uq:
|
||||
litsq_zq SUP lit { $1,$3 }
|
||||
litsq_dq:
|
||||
litsq_zq SUB lit { $1,$3 }
|
||||
litsq_zq:
|
||||
SQ_CLOSE { TEX_LITERAL sq_close_ri }
|
||||
expr_nosqc:
|
||||
/* */ { [] }
|
||||
| lit_aq expr_nosqc { $1 :: $2 }
|
||||
lit_aq:
|
||||
lit { $1 }
|
||||
| lit_dq { let base,downi = $1 in TEX_DQ(base,downi) }
|
||||
| lit_uq { let base,upi = $1 in TEX_UQ(base,upi)}
|
||||
| lit_dqn { TEX_DQN($1) }
|
||||
| lit_uqn { TEX_UQN($1) }
|
||||
| lit_fq { $1 }
|
||||
|
||||
lit_fq:
|
||||
lit_dq SUP lit { let base,downi = $1 in TEX_FQ(base,downi,$3) }
|
||||
| lit_uq SUB lit { let base,upi = $1 in TEX_FQ(base,$3,upi) }
|
||||
| lit_dqn SUP lit { TEX_FQN($1, $3) }
|
||||
|
||||
lit_uq:
|
||||
lit SUP lit { $1,$3 }
|
||||
lit_dq:
|
||||
lit SUB lit { $1,$3 }
|
||||
lit_uqn:
|
||||
SUP lit { $2 }
|
||||
lit_dqn:
|
||||
SUB lit { $2 }
|
||||
|
||||
|
||||
left:
|
||||
LEFT DELIMITER { $2 }
|
||||
| LEFT SQ_CLOSE { sq_close_ri }
|
||||
right:
|
||||
RIGHT DELIMITER { $2 }
|
||||
| RIGHT SQ_CLOSE { sq_close_ri }
|
||||
lit:
|
||||
LITERAL { TEX_LITERAL $1 }
|
||||
| DELIMITER { TEX_LITERAL $1 }
|
||||
| BIG DELIMITER { TEX_BIG ($1,$2) }
|
||||
| BIG SQ_CLOSE { TEX_BIG ($1,sq_close_ri) }
|
||||
| left expr right { TEX_LR ($1,$3,$2) }
|
||||
| FUN_AR1 lit { TEX_FUN1($1,$2) }
|
||||
| FUN_AR1nb lit { TEX_FUN1nb($1,$2) }
|
||||
| FUN_AR1hl lit { let t,h=$1 in TEX_FUN1hl(t,h,$2) }
|
||||
| FUN_AR1hf lit { let t,h=$1 in TEX_FUN1hf(t,h,$2) }
|
||||
| FUN_AR1opt expr_nosqc SQ_CLOSE lit { TEX_FUN2sq($1,TEX_CURLY $2,$4) }
|
||||
| FUN_AR2 lit lit { TEX_FUN2($1,$2,$3) }
|
||||
| FUN_AR2nb lit lit { TEX_FUN2nb($1,$2,$3) }
|
||||
| FUN_AR2h lit lit { let t,h=$1 in TEX_FUN2h(t,h,$2,$3) }
|
||||
| BOX { let bt,s = $1 in TEX_BOX (bt,s) }
|
||||
| CURLY_OPEN expr CURLY_CLOSE
|
||||
{ TEX_CURLY $2 }
|
||||
| CURLY_OPEN ne_expr FUN_INFIX ne_expr CURLY_CLOSE
|
||||
{ TEX_INFIX($3,$2,$4) }
|
||||
| CURLY_OPEN ne_expr FUN_INFIXh ne_expr CURLY_CLOSE
|
||||
{ let t,h=$3 in TEX_INFIXh(t,h,$2,$4) }
|
||||
| BEGIN__MATRIX matrix END__MATRIX { TEX_MATRIX ("matrix", $2) }
|
||||
| BEGIN_PMATRIX matrix END_PMATRIX { TEX_MATRIX ("pmatrix", $2) }
|
||||
| BEGIN_BMATRIX matrix END_BMATRIX { TEX_MATRIX ("bmatrix", $2) }
|
||||
| BEGIN_BBMATRIX matrix END_BBMATRIX { TEX_MATRIX ("Bmatrix", $2) }
|
||||
| BEGIN_VMATRIX matrix END_VMATRIX { TEX_MATRIX ("vmatrix", $2) }
|
||||
| BEGIN_VVMATRIX matrix END_VVMATRIX { TEX_MATRIX ("Vmatrix", $2) }
|
||||
| BEGIN_ARRAY matrix END_ARRAY { TEX_MATRIX ("array", $2) }
|
||||
| BEGIN_ALIGN matrix END_ALIGN { TEX_MATRIX ("aligned", $2) }
|
||||
| BEGIN_ALIGNAT matrix END_ALIGNAT { TEX_MATRIX ("alignedat", $2) }
|
||||
| BEGIN_SMALLMATRIX matrix END_SMALLMATRIX { TEX_MATRIX ("smallmatrix", $2) }
|
||||
| BEGIN_CASES matrix END_CASES { TEX_MATRIX ("cases", $2) }
|
||||
matrix:
|
||||
line { [$1] }
|
||||
| line NEXT_ROW matrix { $1::$3 }
|
||||
line:
|
||||
expr { [$1] }
|
||||
| expr NEXT_CELL line { $1::$3 }
|
||||
;;
|
|
@ -1,58 +0,0 @@
|
|||
(* vim: set sw=8 ts=8 et: *)
|
||||
|
||||
let cmd_dvips tmpprefix = "dvips -q -R -E " ^ tmpprefix ^ ".dvi -f >" ^ tmpprefix ^ ".ps"
|
||||
let cmd_latex tmpprefix = "latex " ^ tmpprefix ^ ".tex >/dev/null"
|
||||
|
||||
(* Putting -transparent white in converts arguments will sort-of give you transperancy *)
|
||||
let cmd_convert tmpprefix finalpath = "convert -quality 100 -density 120 " ^ tmpprefix ^ ".ps " ^ finalpath ^ " >/dev/null 2>/dev/null"
|
||||
|
||||
(* Putting -bg Transparent in dvipng's arguments will give full-alpha transparency *)
|
||||
(* Note that IE have problems with such PNGs and need an additional javascript snippet *)
|
||||
(* Putting -bg transparent in dvipng's arguments will give binary transparency *)
|
||||
let cmd_dvipng tmpprefix finalpath backcolor = "dvipng -bg \'" ^ backcolor ^ "\' -gamma 1.5 -D 120 -T tight --strict " ^ tmpprefix ^ ".dvi -o " ^ finalpath ^ " >/dev/null 2>/dev/null"
|
||||
|
||||
exception ExternalCommandFailure of string
|
||||
|
||||
let render tmppath finalpath outtex md5 backcolor =
|
||||
let tmpprefix0 = (string_of_int (Unix.getpid ()))^"_"^md5 in
|
||||
let tmpprefix = (tmppath^"/"^tmpprefix0) in
|
||||
let unlink_all () =
|
||||
begin
|
||||
(* Commenting this block out will aid in debugging *)
|
||||
Sys.remove (tmpprefix ^ ".dvi");
|
||||
Sys.remove (tmpprefix ^ ".aux");
|
||||
Sys.remove (tmpprefix ^ ".log");
|
||||
Sys.remove (tmpprefix ^ ".tex");
|
||||
if Sys.file_exists (tmpprefix ^ ".ps")
|
||||
then Sys.remove (tmpprefix ^ ".ps");
|
||||
end in
|
||||
|
||||
let f = (Util.open_out_unless_exists (tmpprefix ^ ".tex")) in
|
||||
begin
|
||||
(* Assemble final output in file 'f' *)
|
||||
output_string f (Texutil.get_preface ());
|
||||
output_string f outtex;
|
||||
output_string f (Texutil.get_footer ());
|
||||
close_out f;
|
||||
|
||||
(* TODO: document *)
|
||||
if Util.run_in_other_directory tmppath (cmd_latex tmpprefix0) != 0
|
||||
then (
|
||||
unlink_all (); raise (ExternalCommandFailure "latex")
|
||||
) else if (Sys.command (cmd_dvipng tmpprefix (finalpath^"/"^md5^".png") backcolor) != 0)
|
||||
then (
|
||||
if (Sys.command (cmd_dvips tmpprefix) != 0)
|
||||
then (
|
||||
unlink_all ();
|
||||
raise (ExternalCommandFailure "dvips")
|
||||
) else if (Sys.command (cmd_convert tmpprefix (finalpath^"/"^md5^".png")) != 0)
|
||||
then (
|
||||
unlink_all ();
|
||||
raise (ExternalCommandFailure "convert")
|
||||
) else (
|
||||
unlink_all ()
|
||||
)
|
||||
) else (
|
||||
unlink_all ()
|
||||
)
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
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 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
|
24
math/tex.mli
24
math/tex.mli
|
@ -1,24 +0,0 @@
|
|||
type t =
|
||||
TEX_LITERAL of Render_info.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_info.t * Render_info.t * t list
|
||||
| TEX_BOX of string * string
|
||||
| TEX_BIG of string * Render_info.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 * Render_info.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 * Render_info.font_force * t list
|
751
math/texutil.ml
751
math/texutil.ml
|
@ -1,751 +0,0 @@
|
|||
(* vim: set sw=8 ts=8 et: *)
|
||||
open Parser
|
||||
open Render_info
|
||||
open Tex
|
||||
open Util
|
||||
|
||||
let tex_part = function
|
||||
HTMLABLE (_,t,_) -> t
|
||||
| HTMLABLEM (_,t,_) -> t
|
||||
| HTMLABLEC (_,t,_) -> t
|
||||
| MHTMLABLEC (_,t,_,_,_) -> t
|
||||
| HTMLABLE_BIG (t,_) -> t
|
||||
| TEX_ONLY t -> t
|
||||
|
||||
let rec render_tex = function
|
||||
TEX_FQ (a,b,c) -> (render_tex a) ^ "_{" ^ (render_tex b) ^ "}^{" ^ (render_tex c) ^ "}"
|
||||
| TEX_DQ (a,b) -> (render_tex a) ^ "_{" ^ (render_tex b) ^ "}"
|
||||
| TEX_UQ (a,b) -> (render_tex a) ^ "^{" ^ (render_tex b) ^ "}"
|
||||
| TEX_FQN (a,b) -> "_{" ^ (render_tex a) ^ "}^{" ^ (render_tex b) ^ "}"
|
||||
| TEX_DQN (a) -> "_{" ^ (render_tex a) ^ "}"
|
||||
| TEX_UQN (a) -> "^{" ^ (render_tex a) ^ "}"
|
||||
| TEX_LITERAL s -> tex_part s
|
||||
| TEX_FUN1 (f,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
|
||||
| TEX_FUN1nb (f,a) -> f ^ " " ^ (render_tex a)
|
||||
| TEX_FUN1hl (f,_,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
|
||||
| TEX_FUN1hf (f,_,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
|
||||
| TEX_DECLh (f,_,a) -> "{" ^ f ^ "{" ^ (mapjoin render_tex a) ^ "}}"
|
||||
| TEX_FUN2 (f,a,b) -> "{" ^ f ^ " " ^ (render_tex a) ^ (render_tex b) ^ "}"
|
||||
| TEX_FUN2nb (f,a,b) -> f ^ (render_tex a) ^ (render_tex b)
|
||||
| TEX_FUN2h (f,_,a,b) -> "{" ^ f ^ " " ^ (render_tex a) ^ (render_tex b) ^ "}"
|
||||
| TEX_FUN2sq (f,a,b) -> "{" ^ f ^ "[ " ^ (render_tex a) ^ "]" ^ (render_tex b) ^ "}"
|
||||
| TEX_CURLY (tl) -> "{" ^ (mapjoin render_tex tl) ^ "}"
|
||||
| TEX_INFIX (s,ll,rl) -> "{" ^ (mapjoin render_tex ll) ^ " " ^ s ^ "" ^ (mapjoin render_tex rl) ^ "}"
|
||||
| TEX_INFIXh (s,_,ll,rl) -> "{" ^ (mapjoin render_tex ll) ^ " " ^ s ^ "" ^ (mapjoin render_tex rl) ^ "}"
|
||||
| TEX_BOX (bt,s) -> "{"^bt^"{" ^ s ^ "}}"
|
||||
| TEX_BIG (bt,d) -> "{"^bt^(tex_part d)^"}"
|
||||
| TEX_MATRIX (t,rows) -> "{\\begin{"^t^"}"^(mapjoine "\\\\" (mapjoine "&" (mapjoin render_tex)) rows)^"\\end{"^t^"}}"
|
||||
| TEX_LR (l,r,tl) -> "\\left "^(tex_part l)^(mapjoin render_tex tl)^"\\right "^(tex_part r)
|
||||
|
||||
|
||||
(* Dynamic loading*)
|
||||
type encoding_t = LATIN1 | LATIN2 | UTF8
|
||||
|
||||
(* module properties *)
|
||||
let modules_ams = ref false
|
||||
let modules_nonascii = ref false
|
||||
let modules_encoding = ref UTF8
|
||||
let modules_color = ref false
|
||||
let modules_teubner = ref false
|
||||
let modules_euro = ref false
|
||||
|
||||
(* wrappers to easily set / reset module properties *)
|
||||
let tex_use_ams () = modules_ams := true
|
||||
let tex_use_nonascii () = modules_nonascii := true
|
||||
let tex_use_color () = modules_color := true
|
||||
let tex_use_teubner () = modules_teubner := true
|
||||
let tex_use_euro () = modules_euro := true
|
||||
let tex_mod_reset () = (
|
||||
modules_ams := false;
|
||||
modules_nonascii := false;
|
||||
modules_encoding := UTF8;
|
||||
modules_color := false;
|
||||
modules_teubner := false;
|
||||
modules_euro := false;
|
||||
)
|
||||
|
||||
(* Return TeX fragment for one of the encodings in (UTF8,LATIN1,LATIN2) *)
|
||||
let get_encoding = function
|
||||
UTF8 -> "\\usepackage{ucs}\n\\usepackage[utf8]{inputenc}\n"
|
||||
| LATIN1 -> "\\usepackage[latin1]{inputenc}\n"
|
||||
| LATIN2 -> "\\usepackage[latin2]{inputenc}\n"
|
||||
|
||||
(* TeX fragment inserted before the output *)
|
||||
let get_preface () = "\\nonstopmode\n\\documentclass[12pt]{article}\n" ^
|
||||
(if !modules_nonascii then get_encoding !modules_encoding else "") ^
|
||||
(if !modules_ams then "\\usepackage{amsmath}\n\\usepackage{amsfonts}\n\\usepackage{amssymb}\n" else "") ^
|
||||
(if !modules_color then "\\usepackage[dvips,usenames]{color}\n" else "") ^
|
||||
(if !modules_teubner then "\\usepackage[greek]{babel}\n\\usepackage{teubner}\n" else "") ^
|
||||
(if !modules_euro then "\\usepackage{eurosym}\n" else "") ^
|
||||
"\\usepackage{cancel}\n\\pagestyle{empty}\n\\begin{document}\n$$\n"
|
||||
|
||||
(* TeX fragment appended after the content *)
|
||||
let get_footer () = "\n$$\n\\end{document}\n"
|
||||
|
||||
(* Default to UTF8 *)
|
||||
let set_encoding = function
|
||||
"ISO-8859-1" -> modules_encoding := LATIN1
|
||||
| "iso-8859-1" -> modules_encoding := LATIN1
|
||||
| "ISO-8859-2" -> modules_encoding := LATIN2
|
||||
| _ -> modules_encoding := UTF8
|
||||
|
||||
(* Turn that into hash table lookup *)
|
||||
exception Illegal_tex_function of string
|
||||
|
||||
let find = function
|
||||
"\\alpha" -> LITERAL (HTMLABLEC (FONT_UF, "\\alpha ", "α"))
|
||||
| "\\Alpha" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{A}", "Α")))
|
||||
| "\\beta" -> LITERAL (HTMLABLEC (FONT_UF, "\\beta ", "β"))
|
||||
| "\\Beta" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{B}", "Β")))
|
||||
| "\\gamma" -> LITERAL (HTMLABLEC (FONT_UF, "\\gamma ", "γ"))
|
||||
| "\\Gamma" -> LITERAL (HTMLABLEC (FONT_UF, "\\Gamma ", "Γ"))
|
||||
| "\\delta" -> LITERAL (HTMLABLEC (FONT_UF, "\\delta ", "δ"))
|
||||
| "\\Delta" -> LITERAL (HTMLABLEC (FONT_UF, "\\Delta ", "Δ"))
|
||||
| "\\epsilon" -> LITERAL (TEX_ONLY "\\epsilon ")
|
||||
| "\\Epsilon" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{E}", "Ε")))
|
||||
| "\\varepsilon" -> LITERAL (HTMLABLEC (FONT_UF, "\\varepsilon ", "ε"))
|
||||
| "\\zeta" -> LITERAL (HTMLABLEC (FONT_UF, "\\zeta ", "ζ"))
|
||||
| "\\Zeta" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{Z}", "Ζ")))
|
||||
| "\\eta" -> LITERAL (HTMLABLEC (FONT_UF, "\\eta ", "η"))
|
||||
| "\\Eta" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{H}", "Η")))
|
||||
| "\\theta" -> LITERAL (HTMLABLEC (FONT_UF, "\\theta ", "θ"))
|
||||
| "\\Theta" -> LITERAL (HTMLABLEC (FONT_UF, "\\Theta ", "Θ"))
|
||||
| "\\vartheta" -> LITERAL (HTMLABLE (FONT_UF, "\\vartheta ", "ϑ"))
|
||||
| "\\thetasym" -> LITERAL (HTMLABLE (FONT_UF, "\\vartheta ", "ϑ"))
|
||||
| "\\iota" -> LITERAL (HTMLABLEC (FONT_UF, "\\iota ", "ι"))
|
||||
| "\\Iota" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{I}", "Ι")))
|
||||
| "\\kappa" -> LITERAL (HTMLABLEC (FONT_UF, "\\kappa ", "κ"))
|
||||
| "\\Kappa" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{K}", "Κ")))
|
||||
| "\\lambda" -> LITERAL (HTMLABLEC (FONT_UF, "\\lambda ", "λ"))
|
||||
| "\\Lambda" -> LITERAL (HTMLABLEC (FONT_UF, "\\Lambda ", "Λ"))
|
||||
| "\\mu" -> LITERAL (HTMLABLEC (FONT_UF, "\\mu ", "μ"))
|
||||
| "\\Mu" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{M}", "Μ")))
|
||||
| "\\nu" -> LITERAL (HTMLABLEC (FONT_UF, "\\nu ", "ν"))
|
||||
| "\\Nu" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{N}", "Ν")))
|
||||
| "\\omicron" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{o}", "ο")))
|
||||
| "\\Omicron" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{O}", "Ο")))
|
||||
| "\\pi" -> LITERAL (HTMLABLEC (FONT_UF, "\\pi ", "π"))
|
||||
| "\\Pi" -> LITERAL (HTMLABLEC (FONT_UF, "\\Pi ", "Π"))
|
||||
| "\\varpi" -> LITERAL (TEX_ONLY "\\varpi ")
|
||||
| "\\rho" -> LITERAL (HTMLABLEC (FONT_UF, "\\rho ", "ρ"))
|
||||
| "\\Rho" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{P}", "Ρ")))
|
||||
| "\\varrho" -> LITERAL (TEX_ONLY "\\varrho ")
|
||||
| "\\sim" -> LITERAL (HTMLABLEC (FONT_UF, "\\sim ", "∼"))
|
||||
| "\\sigma" -> LITERAL (HTMLABLEC (FONT_UF, "\\sigma ", "σ"))
|
||||
| "\\Sigma" -> LITERAL (HTMLABLEC (FONT_UF, "\\Sigma ", "Σ"))
|
||||
| "\\varsigma" -> LITERAL (TEX_ONLY "\\varsigma ")
|
||||
| "\\tau" -> LITERAL (HTMLABLEC (FONT_UF, "\\tau ", "τ"))
|
||||
| "\\Tau" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{T}", "Τ")))
|
||||
| "\\upsilon" -> LITERAL (HTMLABLEC (FONT_UF, "\\upsilon ", "υ"))
|
||||
| "\\Upsilon" -> LITERAL (HTMLABLEC (FONT_UF, "\\Upsilon ", "Υ"))
|
||||
| "\\phi" -> LITERAL (HTMLABLEC (FONT_UF, "\\phi ", "ϕ"))
|
||||
| "\\Phi" -> LITERAL (HTMLABLEC (FONT_UF, "\\Phi ", "Φ"))
|
||||
| "\\varphi" -> LITERAL (HTMLABLEC (FONT_UF, "\\varphi ", "φ"))
|
||||
| "\\chi" -> LITERAL (HTMLABLEC (FONT_UF, "\\chi ", "χ"))
|
||||
| "\\Chi" -> (tex_use_ams (); LITERAL (HTMLABLEC (FONT_UF,
|
||||
"\\mathrm{X}", "Χ")))
|
||||
| "\\psi" -> LITERAL (HTMLABLEC (FONT_UF, "\\psi ", "ψ"))
|
||||
| "\\Psi" -> LITERAL (HTMLABLEC (FONT_UF, "\\Psi ", "Ψ"))
|
||||
| "\\omega" -> LITERAL (HTMLABLEC (FONT_UF, "\\omega ", "ω"))
|
||||
| "\\Omega" -> LITERAL (HTMLABLEC (FONT_UF, "\\Omega ", "Ω"))
|
||||
| "\\xi" -> LITERAL (HTMLABLEC (FONT_UF, "\\xi ", "ξ"))
|
||||
| "\\Xi" -> LITERAL (HTMLABLEC (FONT_UF, "\\Xi ", "Ξ"))
|
||||
| "\\aleph" -> LITERAL (HTMLABLE (FONT_UF, "\\aleph ", "ℵ"))
|
||||
| "\\alef" -> LITERAL (HTMLABLE (FONT_UF, "\\aleph ", "ℵ"))
|
||||
| "\\alefsym" -> LITERAL (HTMLABLE (FONT_UF, "\\aleph ", "ℵ"))
|
||||
| "\\larr" -> LITERAL (HTMLABLEM (FONT_UF, "\\leftarrow ", "←"))
|
||||
| "\\leftarrow" -> LITERAL (HTMLABLEM (FONT_UF, "\\leftarrow ", "←"))
|
||||
| "\\rarr" -> LITERAL (HTMLABLEM (FONT_UF, "\\rightarrow ", "→"))
|
||||
| "\\to" -> LITERAL (HTMLABLEM (FONT_UF, "\\to ", "→"))
|
||||
| "\\gets" -> LITERAL (HTMLABLEM (FONT_UF, "\\gets ", "←"))
|
||||
| "\\rightarrow" -> LITERAL (HTMLABLEM (FONT_UF, "\\rightarrow ", "→"))
|
||||
| "\\longleftarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\longleftarrow ", "←"))
|
||||
| "\\longrightarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\longrightarrow ", "→"))
|
||||
| "\\Larr" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftarrow ", "⇐"))
|
||||
| "\\lArr" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftarrow ", "⇐"))
|
||||
| "\\Leftarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftarrow ", "⇐"))
|
||||
| "\\Rarr" -> LITERAL (HTMLABLE (FONT_UF, "\\Rightarrow ", "⇒"))
|
||||
| "\\rArr" -> LITERAL (HTMLABLE (FONT_UF, "\\Rightarrow ", "⇒"))
|
||||
| "\\Rightarrow" -> LITERAL (HTMLABLEM (FONT_UF, "\\Rightarrow ", "⇒"))
|
||||
| "\\mapsto" -> LITERAL (HTMLABLE (FONT_UF, "\\mapsto ", "→"))
|
||||
| "\\longmapsto" -> LITERAL (HTMLABLE (FONT_UF, "\\longmapsto ", "→"))
|
||||
| "\\Longleftarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\Longleftarrow ", "⇐"))
|
||||
| "\\Longrightarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\Longrightarrow ", "⇒"))
|
||||
| "\\uarr" -> DELIMITER (HTMLABLEM (FONT_UF, "\\uparrow ", "↑"))
|
||||
| "\\uparrow" -> DELIMITER (HTMLABLEM (FONT_UF, "\\uparrow ", "↑"))
|
||||
| "\\uArr" -> DELIMITER (HTMLABLE (FONT_UF, "\\Uparrow ", "⇑"))
|
||||
| "\\Uarr" -> DELIMITER (HTMLABLE (FONT_UF, "\\Uparrow ", "⇑"))
|
||||
| "\\Uparrow" -> DELIMITER (HTMLABLE (FONT_UF, "\\Uparrow ", "⇑"))
|
||||
| "\\darr" -> DELIMITER (HTMLABLEM (FONT_UF, "\\downarrow ", "↓"))
|
||||
| "\\downarrow" -> DELIMITER (HTMLABLEM (FONT_UF, "\\downarrow ", "↓"))
|
||||
| "\\dArr" -> DELIMITER (HTMLABLE (FONT_UF, "\\Downarrow ", "⇓"))
|
||||
| "\\Darr" -> DELIMITER (HTMLABLE (FONT_UF, "\\Downarrow ", "⇓"))
|
||||
| "\\Downarrow" -> DELIMITER (HTMLABLE (FONT_UF, "\\Downarrow ", "⇓"))
|
||||
| "\\updownarrow" -> DELIMITER (TEX_ONLY "\\updownarrow ")
|
||||
| "\\Updownarrow" -> DELIMITER (TEX_ONLY "\\Updownarrow ")
|
||||
| "\\ulcorner" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\ulcorner "))
|
||||
| "\\urcorner" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\urcorner "))
|
||||
| "\\llcorner" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\llcorner "))
|
||||
| "\\lrcorner" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\lrcorner "))
|
||||
| "\\twoheadleftarrow" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\twoheadleftarrow "))
|
||||
| "\\twoheadrightarrow" -> (tex_use_ams (); DELIMITER (TEX_ONLY "\\twoheadrightarrow "))
|
||||
| "\\xleftarrow" -> (tex_use_ams (); FUN_AR1 "\\xleftarrow ")
|
||||
| "\\xrightarrow" -> (tex_use_ams (); FUN_AR1 "\\xrightarrow ")
|
||||
| "\\rightleftharpoons" -> DELIMITER (TEX_ONLY "\\rightleftharpoons ")
|
||||
| "\\leftrightarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\leftrightarrow ", "↔"))
|
||||
| "\\lrarr" -> LITERAL (HTMLABLE (FONT_UF, "\\leftrightarrow ", "↔"))
|
||||
| "\\harr" -> LITERAL (HTMLABLE (FONT_UF, "\\leftrightarrow ", "↔"))
|
||||
| "\\Leftrightarrow" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftrightarrow ", "⇔"))
|
||||
| "\\Lrarr" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftrightarrow ", "⇔"))
|
||||
| "\\Harr" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftrightarrow ", "⇔"))
|
||||
| "\\lrArr" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftrightarrow ", "⇔"))
|
||||
| "\\hAar" -> LITERAL (HTMLABLE (FONT_UF, "\\Leftrightarrow ", "⇔"))
|
||||
| "\\longleftrightarrow"->LITERAL (HTMLABLE (FONT_UF, "\\longleftrightarrow ", "↔"))
|
||||
| "\\Longleftrightarrow"->LITERAL (HTMLABLE (FONT_UF, "\\Longleftrightarrow ", "↔"))
|
||||
| "\\iff" -> LITERAL (HTMLABLE (FONT_UF, "\\iff ", "↔"))
|
||||
| "\\ll" -> LITERAL (TEX_ONLY "\\ll ")
|
||||
| "\\gg" -> LITERAL (TEX_ONLY "\\gg ")
|
||||
| "\\div" -> LITERAL (TEX_ONLY "\\div ")
|
||||
| "\\searrow" -> LITERAL (TEX_ONLY "\\searrow ")
|
||||
| "\\nearrow" -> LITERAL (TEX_ONLY "\\nearrow ")
|
||||
| "\\swarrow" -> LITERAL (TEX_ONLY "\\swarrow ")
|
||||
| "\\nwarrow" -> LITERAL (TEX_ONLY "\\nwarrow ")
|
||||
| "\\simeq" -> LITERAL (TEX_ONLY "\\simeq ")
|
||||
| "\\ast" -> LITERAL (TEX_ONLY "\\ast ")
|
||||
| "\\star" -> LITERAL (TEX_ONLY "\\star ")
|
||||
| "\\ell" -> LITERAL (TEX_ONLY "\\ell ")
|
||||
| "\\P" -> LITERAL (TEX_ONLY "\\P ")
|
||||
| "\\smile" -> LITERAL (TEX_ONLY "\\smile ")
|
||||
| "\\frown" -> LITERAL (TEX_ONLY "\\frown ")
|
||||
| "\\bigcap" -> LITERAL (TEX_ONLY "\\bigcap ")
|
||||
| "\\bigodot" -> LITERAL (TEX_ONLY "\\bigodot ")
|
||||
| "\\bigcup" -> LITERAL (TEX_ONLY "\\bigcup ")
|
||||
| "\\bigotimes" -> LITERAL (TEX_ONLY "\\bigotimes ")
|
||||
| "\\coprod" -> LITERAL (TEX_ONLY "\\coprod ")
|
||||
| "\\bigsqcup" -> LITERAL (TEX_ONLY "\\bigsqcup ")
|
||||
| "\\bigoplus" -> LITERAL (TEX_ONLY "\\bigoplus ")
|
||||
| "\\bigvee" -> LITERAL (TEX_ONLY "\\bigvee ")
|
||||
| "\\biguplus" -> LITERAL (TEX_ONLY "\\biguplus ")
|
||||
| "\\oint" -> LITERAL (TEX_ONLY "\\oint ")
|
||||
| "\\bigwedge" -> LITERAL (TEX_ONLY "\\bigwedge ")
|
||||
| "\\models" -> LITERAL (TEX_ONLY "\\models ")
|
||||
| "\\vdash" -> LITERAL (TEX_ONLY "\\vdash ")
|
||||
| "\\triangle" -> LITERAL (TEX_ONLY "\\triangle ")
|
||||
| "\\bowtie" -> LITERAL (TEX_ONLY "\\bowtie ")
|
||||
| "\\wr" -> LITERAL (TEX_ONLY "\\wr ")
|
||||
| "\\triangleleft" -> LITERAL (TEX_ONLY "\\triangleleft ")
|
||||
| "\\triangleright" -> LITERAL (TEX_ONLY "\\triangleright ")
|
||||
| "\\textvisiblespace" -> LITERAL (TEX_ONLY "\\mbox{\\textvisiblespace}")
|
||||
| "\\circ" -> LITERAL (TEX_ONLY "\\circ ")
|
||||
| "\\hbar" -> LITERAL (TEX_ONLY "\\hbar ")
|
||||
| "\\imath" -> LITERAL (TEX_ONLY "\\imath ")
|
||||
| "\\jmath" -> LITERAL (TEX_ONLY "\\jmath ")
|
||||
| "\\lnot" -> LITERAL (TEX_ONLY "\\lnot ")
|
||||
| "\\hookrightarrow" -> LITERAL (TEX_ONLY "\\hookrightarrow ")
|
||||
| "\\hookleftarrow" -> LITERAL (TEX_ONLY "\\hookleftarrow ")
|
||||
| "\\mp" -> LITERAL (TEX_ONLY "\\mp ")
|
||||
| "\\approx" -> LITERAL (HTMLABLE (FONT_UF, "\\approx ", "≈"))
|
||||
| "\\propto" -> LITERAL (TEX_ONLY "\\propto ")
|
||||
| "\\flat" -> LITERAL (TEX_ONLY "\\flat ")
|
||||
| "\\sharp" -> LITERAL (TEX_ONLY "\\sharp ")
|
||||
| "\\natural" -> LITERAL (TEX_ONLY "\\natural ")
|
||||
| "\\int" -> LITERAL (HTMLABLE_BIG ("\\int ", "∫"))
|
||||
| "\\sum" -> LITERAL (HTMLABLE_BIG ("\\sum ", "∑"))
|
||||
| "\\prod" -> LITERAL (HTMLABLE_BIG ("\\prod ", "∏"))
|
||||
| "\\vdots" -> LITERAL (TEX_ONLY "\\vdots ")
|
||||
| "\\limits" -> LITERAL (TEX_ONLY "\\limits ")
|
||||
| "\\nolimits" -> LITERAL (TEX_ONLY "\\nolimits ")
|
||||
| "\\top" -> LITERAL (TEX_ONLY "\\top ")
|
||||
| "\\bullet" -> LITERAL (HTMLABLE (FONT_UFH, "\\bullet ", "•"))
|
||||
| "\\bull" -> LITERAL (HTMLABLE (FONT_UFH, "\\bullet ", "•"))
|
||||
| "\\angle" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\angle ", "∠")))
|
||||
| "\\dagger" -> LITERAL (HTMLABLEM(FONT_UFH, "\\dagger ", "†"))
|
||||
| "\\ddagger" -> LITERAL (HTMLABLEM(FONT_UFH, "\\ddagger ", "‡"))
|
||||
| "\\Dagger" -> LITERAL (HTMLABLEM(FONT_UFH, "\\ddagger ", "‡"))
|
||||
| "\\colon" -> LITERAL (HTMLABLEC(FONT_UFH, "\\colon ", ":"))
|
||||
| "\\Vert" -> DELIMITER (HTMLABLEM(FONT_UFH, "\\Vert ", "||"))
|
||||
| "\\vert" -> DELIMITER (HTMLABLEM(FONT_UFH, "\\vert ", "|"))
|
||||
| "\\wp" -> LITERAL (HTMLABLE (FONT_UF, "\\wp ", "℘"))
|
||||
| "\\weierp" -> LITERAL (HTMLABLE (FONT_UF, "\\wp ", "℘"))
|
||||
| "\\wedge" -> LITERAL (HTMLABLE (FONT_UF, "\\wedge ", "∧"))
|
||||
| "\\and" -> LITERAL (HTMLABLE (FONT_UF, "\\land ", "∧"))
|
||||
| "\\land" -> LITERAL (HTMLABLE (FONT_UF, "\\land ", "∧"))
|
||||
| "\\vee" -> LITERAL (HTMLABLE (FONT_UF, "\\vee ", "∨"))
|
||||
| "\\or" -> LITERAL (HTMLABLE (FONT_UF, "\\lor ", "∨"))
|
||||
| "\\lor" -> LITERAL (HTMLABLE (FONT_UF, "\\lor ", "∨"))
|
||||
| "\\sub" -> LITERAL (HTMLABLE (FONT_UF, "\\subset ", "⊂"))
|
||||
| "\\supe" -> LITERAL (HTMLABLE (FONT_UF, "\\supseteq ", "⊇"))
|
||||
| "\\sube" -> LITERAL (HTMLABLE (FONT_UF, "\\subseteq ", "⊆"))
|
||||
| "\\supset" -> LITERAL (HTMLABLE (FONT_UF, "\\supset ", "⊃"))
|
||||
| "\\subset" -> LITERAL (HTMLABLE (FONT_UF, "\\subset ", "⊂"))
|
||||
| "\\supseteq" -> LITERAL (HTMLABLE (FONT_UF, "\\supseteq ", "⊇"))
|
||||
| "\\subseteq" -> LITERAL (HTMLABLE (FONT_UF, "\\subseteq ", "⊆"))
|
||||
| "\\sqsupset" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqsupset "))
|
||||
| "\\sqsubset" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqsubset "))
|
||||
| "\\sqsupseteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqsupseteq "))
|
||||
| "\\sqsubseteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqsubseteq "))
|
||||
| "\\perp" -> LITERAL (HTMLABLE (FONT_UF, "\\perp ", "⊥"))
|
||||
| "\\bot" -> LITERAL (HTMLABLE (FONT_UF, "\\bot ", "⊥"))
|
||||
| "\\lfloor" -> DELIMITER (HTMLABLE (FONT_UF, "\\lfloor ", "⌊"))
|
||||
| "\\rfloor" -> DELIMITER (HTMLABLE (FONT_UF, "\\rfloor ", "⌋"))
|
||||
| "\\lceil" -> DELIMITER (HTMLABLE (FONT_UF, "\\lceil ", "⌈"))
|
||||
| "\\rceil" -> DELIMITER (HTMLABLE (FONT_UF, "\\rceil ", "⌉"))
|
||||
| "\\lbrace" -> DELIMITER (HTMLABLEC(FONT_UFH, "\\lbrace ", "{"))
|
||||
| "\\rbrace" -> DELIMITER (HTMLABLEC(FONT_UFH, "\\rbrace ", "}"))
|
||||
| "\\infty" -> LITERAL (HTMLABLEM(FONT_UF, "\\infty ", "∞"))
|
||||
| "\\infin" -> LITERAL (HTMLABLEM(FONT_UF, "\\infty ", "∞"))
|
||||
| "\\isin" -> LITERAL (HTMLABLE (FONT_UF, "\\in ", "∈"))
|
||||
| "\\in" -> LITERAL (HTMLABLE (FONT_UF, "\\in ", "∈"))
|
||||
| "\\ni" -> LITERAL (HTMLABLE (FONT_UF, "\\ni ", "∋"))
|
||||
| "\\notin" -> LITERAL (HTMLABLE (FONT_UF, "\\notin ", "∉"))
|
||||
| "\\smallsetminus" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\smallsetminus "))
|
||||
| "\\And" -> (tex_use_ams (); LITERAL (HTMLABLEM(FONT_UFH, "\\And ", " & ")))
|
||||
| "\\forall" -> LITERAL (HTMLABLE (FONT_UFH, "\\forall ", "∀"))
|
||||
| "\\exists" -> LITERAL (HTMLABLE (FONT_UFH, "\\exists ", "∃"))
|
||||
| "\\exist" -> LITERAL (HTMLABLE (FONT_UFH, "\\exists ", "∃"))
|
||||
| "\\equiv" -> LITERAL (HTMLABLEM(FONT_UFH, "\\equiv ", "≡"))
|
||||
| "\\ne" -> LITERAL (HTMLABLEM(FONT_UFH, "\\neq ", "≠"))
|
||||
| "\\neq" -> LITERAL (HTMLABLEM(FONT_UFH, "\\neq ", "≠"))
|
||||
| "\\Re" -> LITERAL (HTMLABLE (FONT_UF, "\\Re ", "ℜ"))
|
||||
| "\\real" -> LITERAL (HTMLABLE (FONT_UF, "\\Re ", "ℜ"))
|
||||
| "\\Im" -> LITERAL (HTMLABLE (FONT_UF, "\\Im ", "ℑ"))
|
||||
| "\\image" -> LITERAL (HTMLABLE (FONT_UF, "\\Im ", "ℑ"))
|
||||
| "\\prime" -> LITERAL (HTMLABLE (FONT_UFH,"\\prime ", "′"))
|
||||
| "\\backslash" -> DELIMITER (HTMLABLEM(FONT_UFH,"\\backslash ", "\\"))
|
||||
| "\\setminus" -> LITERAL (HTMLABLEM(FONT_UFH,"\\setminus ", "\\"))
|
||||
| "\\times" -> LITERAL (HTMLABLEM(FONT_UFH,"\\times ", "×"))
|
||||
| "\\pm" -> LITERAL (HTMLABLEM(FONT_UFH,"\\pm ", "±"))
|
||||
| "\\plusmn" -> LITERAL (HTMLABLEM(FONT_UFH,"\\pm ", "±"))
|
||||
| "\\cdot" -> LITERAL (HTMLABLE (FONT_UFH,"\\cdot ", "⋅"))
|
||||
| "\\AA" -> LITERAL (HTMLABLE (FONT_UFH,"\\mbox{\\AA}", "Å"))
|
||||
| "\\cdots" -> LITERAL (HTMLABLE (FONT_UFH,"\\cdots ", "⋅⋅⋅"))
|
||||
| "\\sdot" -> LITERAL (HTMLABLE (FONT_UFH,"\\cdot ", "⋅"))
|
||||
| "\\oplus" -> LITERAL (HTMLABLE (FONT_UF, "\\oplus ", "⊕"))
|
||||
| "\\otimes" -> LITERAL (HTMLABLE (FONT_UF, "\\otimes ", "⊗"))
|
||||
| "\\cap" -> LITERAL (HTMLABLEM(FONT_UF, "\\cap ", "∩"))
|
||||
| "\\cup" -> LITERAL (HTMLABLE (FONT_UF, "\\cup ", "∪"))
|
||||
| "\\uplus" -> LITERAL (TEX_ONLY "\\uplus ")
|
||||
| "\\sqcap" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqcap "))
|
||||
| "\\sqcup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sqcup "))
|
||||
| "\\empty" -> LITERAL (HTMLABLE (FONT_UF, "\\emptyset ", "∅"))
|
||||
| "\\emptyset" -> LITERAL (HTMLABLE (FONT_UF, "\\emptyset ", "∅"))
|
||||
| "\\O" -> LITERAL (HTMLABLE (FONT_UF, "\\emptyset ", "∅"))
|
||||
| "\\S" -> LITERAL (HTMLABLEM(FONT_UFH,"\\S ", "§"))
|
||||
| "\\sect" -> LITERAL (HTMLABLEM(FONT_UFH,"\\S ", "§"))
|
||||
| "\\nabla" -> LITERAL (HTMLABLE (FONT_UF, "\\nabla ", "∇"))
|
||||
| "\\geq" -> LITERAL (HTMLABLE (FONT_UFH,"\\geq ", "≥"))
|
||||
| "\\ge" -> LITERAL (HTMLABLE (FONT_UFH,"\\geq ", "≥"))
|
||||
| "\\leq" -> LITERAL (HTMLABLE (FONT_UFH,"\\leq ", "≤"))
|
||||
| "\\le" -> LITERAL (HTMLABLE (FONT_UFH,"\\leq ", "≤"))
|
||||
| "\\cong" -> LITERAL (HTMLABLE (FONT_UF, "\\cong ", "≅"))
|
||||
| "\\ang" -> LITERAL (HTMLABLE (FONT_UF, "\\angle ", "∠"))
|
||||
| "\\part" -> LITERAL (HTMLABLEM(FONT_UF, "\\partial ", "∂"))
|
||||
| "\\partial" -> LITERAL (HTMLABLEM(FONT_UF, "\\partial ", "∂"))
|
||||
| "\\ldots" -> LITERAL (HTMLABLEM(FONT_UFH,"\\ldots ", "..."))
|
||||
| "\\dots" -> LITERAL (HTMLABLEM(FONT_UFH,"\\dots ", "..."))
|
||||
| "\\quad" -> LITERAL (HTMLABLE (FONT_UF, "\\quad "," "))
|
||||
| "\\qquad" -> LITERAL (HTMLABLE (FONT_UF, "\\qquad "," "))
|
||||
| "\\mid" -> LITERAL (HTMLABLEM(FONT_UFH,"\\mid ", " | "))
|
||||
| "\\neg" -> LITERAL (HTMLABLEM(FONT_UFH,"\\neg ", "¬"))
|
||||
| "\\langle" -> DELIMITER (HTMLABLE (FONT_UFH,"\\langle ","⟨"))
|
||||
| "\\rangle" -> DELIMITER (HTMLABLE (FONT_UFH,"\\rangle ","⟩"))
|
||||
| "\\lang" -> DELIMITER (HTMLABLE (FONT_UFH,"\\langle ","⟨"))
|
||||
| "\\rang" -> DELIMITER (HTMLABLE (FONT_UFH,"\\rangle ","⟩"))
|
||||
| "\\lbrack" -> DELIMITER (HTMLABLEC(FONT_UFH,"[","["))
|
||||
| "\\rbrack" -> DELIMITER (HTMLABLEC(FONT_UFH,"]","]"))
|
||||
| "\\surd" -> LITERAL (TEX_ONLY "\\surd ")
|
||||
| "\\ddots" -> LITERAL (TEX_ONLY "\\ddots ")
|
||||
| "\\clubs" -> LITERAL (TEX_ONLY "\\clubsuit ")
|
||||
| "\\clubsuit" -> LITERAL (TEX_ONLY "\\clubsuit ")
|
||||
| "\\spades" -> LITERAL (TEX_ONLY "\\spadesuit ")
|
||||
| "\\spadesuit" -> LITERAL (TEX_ONLY "\\spadesuit ")
|
||||
| "\\hearts" -> LITERAL (TEX_ONLY "\\heartsuit ")
|
||||
| "\\heartsuit" -> LITERAL (TEX_ONLY "\\heartsuit ")
|
||||
| "\\diamonds" -> LITERAL (TEX_ONLY "\\diamondsuit ")
|
||||
| "\\diamond" -> LITERAL (TEX_ONLY "\\diamond ")
|
||||
| "\\bigtriangleup" -> LITERAL (TEX_ONLY "\\bigtriangleup ")
|
||||
| "\\bigtriangledown" -> LITERAL (TEX_ONLY "\\bigtriangledown ")
|
||||
| "\\diamondsuit" -> LITERAL (TEX_ONLY "\\diamondsuit ")
|
||||
| "\\ominus" -> LITERAL (TEX_ONLY "\\ominus ")
|
||||
| "\\oslash" -> LITERAL (TEX_ONLY "\\oslash ")
|
||||
| "\\odot" -> LITERAL (TEX_ONLY "\\odot ")
|
||||
| "\\bigcirc" -> LITERAL (TEX_ONLY "\\bigcirc ")
|
||||
| "\\amalg" -> LITERAL (TEX_ONLY "\\amalg ")
|
||||
| "\\prec" -> LITERAL (TEX_ONLY "\\prec ")
|
||||
| "\\succ" -> LITERAL (TEX_ONLY "\\succ ")
|
||||
| "\\preceq" -> LITERAL (TEX_ONLY "\\preceq ")
|
||||
| "\\succeq" -> LITERAL (TEX_ONLY "\\succeq ")
|
||||
| "\\dashv" -> LITERAL (TEX_ONLY "\\dashv ")
|
||||
| "\\asymp" -> LITERAL (TEX_ONLY "\\asymp ")
|
||||
| "\\doteq" -> LITERAL (TEX_ONLY "\\doteq ")
|
||||
| "\\parallel" -> LITERAL (TEX_ONLY "\\parallel ")
|
||||
| "\\euro" -> (tex_use_euro (); LITERAL (HTMLABLEC (FONT_UF, "\\mbox{\\euro}", "€")))
|
||||
| "\\geneuro" -> (tex_use_euro (); LITERAL (TEX_ONLY "\\mbox{\\geneuro}"))
|
||||
| "\\geneuronarrow" -> (tex_use_euro (); LITERAL (TEX_ONLY "\\mbox{\\geneuronarrow}"))
|
||||
| "\\geneurowide" -> (tex_use_euro (); LITERAL (TEX_ONLY "\\mbox{\\geneurowide}"))
|
||||
| "\\officialeuro" -> (tex_use_euro (); LITERAL (TEX_ONLY "\\mbox{\\officialeuro}"))
|
||||
| "\\Coppa" -> (tex_use_teubner (); LITERAL (HTMLABLE (FONT_UF, "\\mbox{\\Coppa}", "Ϙ")))
|
||||
| "\\coppa" -> (tex_use_teubner (); LITERAL (HTMLABLE (FONT_UF, "\\mbox{\\coppa}", "ϙ")))
|
||||
| "\\varcoppa" -> (tex_use_teubner (); LITERAL (HTMLABLE (FONT_UF, "\\mbox{\\coppa}", "ϙ")))
|
||||
| "\\Digamma" -> (tex_use_teubner (); LITERAL (HTMLABLE (FONT_UF, "\\mbox{\\Digamma}", "Ϝ")))
|
||||
| "\\Koppa" -> (tex_use_teubner (); LITERAL (HTMLABLE (FONT_UF, "\\mbox{\\Koppa}", "Ϙ")))
|
||||
| "\\koppa" -> (tex_use_teubner (); LITERAL (HTMLABLE (FONT_UF, "\\mbox{\\koppa}", "ϟ")))
|
||||
| "\\Sampi" -> (tex_use_teubner (); LITERAL (TEX_ONLY "\\mbox{\\Sampi}"))
|
||||
| "\\sampi" -> (tex_use_teubner (); LITERAL (HTMLABLE (FONT_UF, "\\mbox{\\sampi}", "ϡ")))
|
||||
| "\\Stigma" -> (tex_use_teubner (); LITERAL (TEX_ONLY "\\mbox{\\Stigma}"))
|
||||
| "\\stigma" -> (tex_use_teubner (); LITERAL (HTMLABLE (FONT_UF, "\\mbox{\\stigma}", "ϛ")))
|
||||
| "\\varstigma" -> (tex_use_teubner (); LITERAL (TEX_ONLY "\\mbox{\\varstigma}"))
|
||||
| "\\implies" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\implies ", "⇒")))
|
||||
| "\\mod" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mod ", "mod")))
|
||||
| "\\Diamond" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\Diamond ", "◊")))
|
||||
| "\\dotsb" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\dotsb ", "⋅⋅⋅")))
|
||||
| "\\dotsc" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\dotsc ", "...")))
|
||||
| "\\dotsi" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\dotsi ", "⋅⋅⋅")))
|
||||
| "\\dotsm" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\dotsm ", "⋅⋅⋅")))
|
||||
| "\\dotso" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UF, "\\dotso ", "...")))
|
||||
| "\\reals" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{R}", "ℝ")))
|
||||
| "\\Reals" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{R}", "ℝ")))
|
||||
| "\\R" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{R}", "ℝ")))
|
||||
| "\\C" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{C}", "ℂ")))
|
||||
| "\\cnums" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{C}", "ℂ")))
|
||||
| "\\Complex" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{C}", "ℂ")))
|
||||
| "\\Z" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{Z}", "ℤ")))
|
||||
| "\\natnums" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{N}", "ℕ")))
|
||||
| "\\N" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{N}", "ℕ")))
|
||||
| "\\Q" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{Q}", "ℚ")))
|
||||
| "\\H" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\mathbb{H}", "ℍ")))
|
||||
| "\\lVert" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\lVert ", "||")))
|
||||
| "\\rVert" -> (tex_use_ams (); LITERAL (HTMLABLE (FONT_UFH,"\\rVert ", "||")))
|
||||
| "\\nmid" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nmid "))
|
||||
| "\\lesssim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lesssim "))
|
||||
| "\\ngeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ngeq "))
|
||||
| "\\smallsmile" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\smallsmile "))
|
||||
| "\\smallfrown" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\smallfrown "))
|
||||
| "\\nleftarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nleftarrow "))
|
||||
| "\\nrightarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nrightarrow "))
|
||||
| "\\trianglelefteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\trianglelefteq "))
|
||||
| "\\trianglerighteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\trianglerighteq "))
|
||||
| "\\square" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\square "))
|
||||
| "\\checkmark" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\checkmark "))
|
||||
| "\\supsetneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\supsetneq "))
|
||||
| "\\subsetneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\subsetneq "))
|
||||
| "\\Box" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Box "))
|
||||
| "\\nleq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nleq "))
|
||||
| "\\upharpoonright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\upharpoonright "))
|
||||
| "\\restriction" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\upharpoonright "))
|
||||
| "\\upharpoonleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\upharpoonleft "))
|
||||
| "\\downharpoonright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\downharpoonright "))
|
||||
| "\\downharpoonleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\downharpoonleft "))
|
||||
| "\\rightharpoonup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightharpoonup "))
|
||||
| "\\rightharpoondown" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightharpoondown "))
|
||||
| "\\leftharpoonup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftharpoonup "))
|
||||
| "\\leftharpoondown" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftharpoondown "))
|
||||
| "\\nless" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nless "))
|
||||
| "\\Vdash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Vdash "))
|
||||
| "\\vDash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\vDash "))
|
||||
| "\\varkappa" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varkappa "))
|
||||
| "\\digamma" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\digamma "))
|
||||
| "\\beth" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\beth "))
|
||||
| "\\daleth" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\daleth "))
|
||||
| "\\gimel" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gimel "))
|
||||
| "\\complement" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\complement "))
|
||||
| "\\eth" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\eth "))
|
||||
| "\\hslash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\hslash "))
|
||||
| "\\mho" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\mho "))
|
||||
| "\\Finv" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Finv "))
|
||||
| "\\Game" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Game "))
|
||||
| "\\varlimsup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varlimsup "))
|
||||
| "\\varliminf" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varliminf "))
|
||||
| "\\varinjlim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varinjlim "))
|
||||
| "\\varprojlim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varprojlim "))
|
||||
| "\\injlim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\injlim "))
|
||||
| "\\projlim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\projlim "))
|
||||
| "\\iint" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\iint "))
|
||||
| "\\iiint" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\iiint "))
|
||||
| "\\iiiint" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\iiiint "))
|
||||
| "\\varnothing" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varnothing "))
|
||||
| "\\left" -> LEFT
|
||||
| "\\right" -> RIGHT
|
||||
| "\\hat" -> FUN_AR1 "\\hat "
|
||||
| "\\hline" -> LITERAL (TEX_ONLY "\\hline ")
|
||||
| "\\vline" -> LITERAL (TEX_ONLY "\\vline ")
|
||||
| "\\widetilde" -> FUN_AR1 "\\widetilde "
|
||||
| "\\widehat" -> FUN_AR1 "\\widehat "
|
||||
| "\\overline" -> FUN_AR1 "\\overline "
|
||||
| "\\overbrace" -> FUN_AR1nb "\\overbrace "
|
||||
| "\\underline" -> FUN_AR1 "\\underline "
|
||||
| "\\underbrace" -> FUN_AR1nb "\\underbrace "
|
||||
| "\\overleftarrow" -> FUN_AR1 "\\overleftarrow "
|
||||
| "\\overrightarrow" -> FUN_AR1 "\\overrightarrow "
|
||||
| "\\overleftrightarrow"-> (tex_use_ams(); FUN_AR1 "\\overleftrightarrow ")
|
||||
| "\\check" -> FUN_AR1 "\\check "
|
||||
| "\\acute" -> FUN_AR1 "\\acute "
|
||||
| "\\grave" -> FUN_AR1 "\\grave "
|
||||
| "\\bar" -> FUN_AR1 "\\bar "
|
||||
| "\\vec" -> FUN_AR1 "\\vec "
|
||||
| "\\dot" -> FUN_AR1 "\\dot "
|
||||
| "\\ddot" -> FUN_AR1 "\\ddot "
|
||||
| "\\breve" -> FUN_AR1 "\\breve "
|
||||
| "\\tilde" -> FUN_AR1 "\\tilde "
|
||||
| "\\not" -> LITERAL (TEX_ONLY "\\not ")
|
||||
| "\\choose" -> FUN_INFIX "\\choose "
|
||||
| "\\atop" -> FUN_INFIX "\\atop "
|
||||
| "\\binom" -> (tex_use_ams (); FUN_AR2 "\\binom ")
|
||||
| "\\dbinom" -> (tex_use_ams (); FUN_AR2 "\\dbinom ")
|
||||
| "\\tbinom" -> (tex_use_ams (); FUN_AR2 "\\tbinom ")
|
||||
| "\\stackrel" -> FUN_AR2 "\\stackrel "
|
||||
| "\\sideset" -> (tex_use_ams (); FUN_AR2nb "\\sideset ")
|
||||
| "\\underset" -> (tex_use_ams (); FUN_AR2 "\\underset ")
|
||||
| "\\overset" -> (tex_use_ams (); FUN_AR2 "\\overset ")
|
||||
| "\\frac" -> FUN_AR2h ("\\frac ", fun num den -> Html.html_render [num], "<hr style=\"{background: black}\"/>", Html.html_render [den])
|
||||
| "\\dfrac" -> (tex_use_ams () ; FUN_AR2 "\\dfrac ")
|
||||
| "\\tfrac" -> (tex_use_ams () ; FUN_AR2h ("\\tfrac ", fun num den -> Html.html_render [num], "<hr style=\"background: black\">", Html.html_render [den]))
|
||||
| "\\cfrac" -> (tex_use_ams (); FUN_AR2h ("\\cfrac ", fun num den -> Html.html_render [num], "<hr style=\"{background: black}\">", Html.html_render [den]))
|
||||
| "\\over" -> FUN_INFIXh ("\\over ", fun num den -> Html.html_render num, "<hr style=\"{background: black}\"/>", Html.html_render den)
|
||||
| "\\sqrt" -> FUN_AR1 "\\sqrt "
|
||||
| "\\cancel" -> FUN_AR1 "\\cancel "
|
||||
| "\\bcancel" -> FUN_AR1 "\\bcancel "
|
||||
| "\\xcancel" -> FUN_AR1 "\\xcancel "
|
||||
| "\\cancelto" -> FUN_AR2 "\\cancelto "
|
||||
| "\\pmod" -> FUN_AR1hl ("\\pmod ", ("(mod ", ")"))
|
||||
| "\\bmod" -> FUN_AR1hl ("\\bmod ", ("mod ", ""))
|
||||
| "\\emph" -> FUN_AR1 "\\emph "
|
||||
| "\\texttt" -> FUN_AR1 "\\texttt "
|
||||
| "\\textbf" -> FUN_AR1 "\\textbf "
|
||||
| "\\textsf" -> FUN_AR1 "\\textsf "
|
||||
| "\\textit" -> FUN_AR1hf ("\\textit ", FONTFORCE_IT)
|
||||
| "\\textrm" -> FUN_AR1hf ("\\textrm ", FONTFORCE_RM)
|
||||
| "\\rm" -> DECLh ("\\rm ", FONTFORCE_RM)
|
||||
| "\\it" -> DECLh ("\\it ", FONTFORCE_IT)
|
||||
| "\\cal" -> DECL "\\cal "
|
||||
| "\\displaystyle" -> LITERAL (TEX_ONLY "\\displaystyle ")
|
||||
| "\\scriptstyle" -> LITERAL (TEX_ONLY "\\scriptstyle ")
|
||||
| "\\textstyle" -> LITERAL (TEX_ONLY "\\textstyle ")
|
||||
| "\\scriptscriptstyle"-> LITERAL (TEX_ONLY "\\scriptscriptstyle ")
|
||||
| "\\bf" -> DECL "\\bf "
|
||||
| "\\big" -> BIG "\\big "
|
||||
| "\\Big" -> BIG "\\Big "
|
||||
| "\\bigg" -> BIG "\\bigg "
|
||||
| "\\Bigg" -> BIG "\\Bigg "
|
||||
| "\\bigl" -> (tex_use_ams ();BIG "\\bigl ")
|
||||
| "\\bigr" -> (tex_use_ams ();BIG "\\bigr ")
|
||||
| "\\Bigl" -> (tex_use_ams ();BIG "\\Bigl ")
|
||||
| "\\Bigr" -> (tex_use_ams ();BIG "\\Bigr ")
|
||||
| "\\biggl" -> (tex_use_ams ();BIG "\\biggl ")
|
||||
| "\\biggr" -> (tex_use_ams ();BIG "\\biggr ")
|
||||
| "\\Biggl" -> (tex_use_ams ();BIG "\\Biggl ")
|
||||
| "\\Biggr" -> (tex_use_ams ();BIG "\\Biggr ")
|
||||
| "\\vartriangle" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\vartriangle "))
|
||||
| "\\triangledown" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\triangledown "))
|
||||
| "\\lozenge" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lozenge "))
|
||||
| "\\circledS" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circledS "))
|
||||
| "\\measuredangle" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\measuredangle "))
|
||||
| "\\nexists" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nexists "))
|
||||
| "\\Bbbk" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Bbbk "))
|
||||
| "\\backprime" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\backprime "))
|
||||
| "\\blacktriangle" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacktriangle "))
|
||||
| "\\blacktriangledown"-> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacktriangledown "))
|
||||
| "\\blacksquare" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacksquare "))
|
||||
| "\\blacklozenge" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacklozenge "))
|
||||
| "\\bigstar" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\bigstar "))
|
||||
| "\\sphericalangle" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\sphericalangle "))
|
||||
| "\\diagup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\diagup "))
|
||||
| "\\diagdown" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\diagdown "))
|
||||
| "\\dotplus" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\dotplus "))
|
||||
| "\\Cap" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Cap "))
|
||||
| "\\doublecap" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Cap "))
|
||||
| "\\Cup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Cup "))
|
||||
| "\\doublecup" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Cup "))
|
||||
| "\\barwedge" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\barwedge "))
|
||||
| "\\veebar" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\veebar "))
|
||||
| "\\doublebarwedge" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\doublebarwedge "))
|
||||
| "\\boxminus" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\boxminus "))
|
||||
| "\\boxtimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\boxtimes "))
|
||||
| "\\boxdot" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\boxdot "))
|
||||
| "\\boxplus" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\boxplus "))
|
||||
| "\\divideontimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\divideontimes "))
|
||||
| "\\ltimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ltimes "))
|
||||
| "\\rtimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rtimes "))
|
||||
| "\\leftthreetimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftthreetimes "))
|
||||
| "\\rightthreetimes" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightthreetimes "))
|
||||
| "\\curlywedge" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curlywedge "))
|
||||
| "\\curlyvee" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curlyvee "))
|
||||
| "\\circleddash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circleddash "))
|
||||
| "\\circledast" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circledast "))
|
||||
| "\\circledcirc" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circledcirc "))
|
||||
| "\\centerdot" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\centerdot "))
|
||||
| "\\intercal" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\intercal "))
|
||||
| "\\leqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leqq "))
|
||||
| "\\leqslant" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leqslant "))
|
||||
| "\\eqslantless" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\eqslantless "))
|
||||
| "\\lessapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lessapprox "))
|
||||
| "\\approxeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\approxeq "))
|
||||
| "\\lessdot" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lessdot "))
|
||||
| "\\lll" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lll "))
|
||||
| "\\lessgtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lessgtr "))
|
||||
| "\\lesseqgtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lesseqgtr "))
|
||||
| "\\lesseqqgtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lesseqqgtr "))
|
||||
| "\\doteqdot" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\doteqdot "))
|
||||
| "\\Doteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\doteqdot "))
|
||||
| "\\risingdotseq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\risingdotseq "))
|
||||
| "\\fallingdotseq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\fallingdotseq "))
|
||||
| "\\backsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\backsim "))
|
||||
| "\\backsimeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\backsimeq "))
|
||||
| "\\subseteqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\subseteqq "))
|
||||
| "\\Subset" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Subset "))
|
||||
| "\\preccurlyeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\preccurlyeq "))
|
||||
| "\\curlyeqprec" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curlyeqprec "))
|
||||
| "\\precsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\precsim "))
|
||||
| "\\precapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\precapprox "))
|
||||
| "\\vartriangleleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\vartriangleleft "))
|
||||
| "\\Vvdash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Vvdash "))
|
||||
| "\\bumpeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\bumpeq "))
|
||||
| "\\Bumpeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Bumpeq "))
|
||||
| "\\geqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\geqq "))
|
||||
| "\\geqslant" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\geqslant "))
|
||||
| "\\eqslantgtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\eqslantgtr "))
|
||||
| "\\gtrsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtrsim "))
|
||||
| "\\gtrapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtrapprox "))
|
||||
| "\\eqsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\eqsim "))
|
||||
| "\\gtrdot" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtrdot "))
|
||||
| "\\ggg" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ggg "))
|
||||
| "\\gggtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ggg "))
|
||||
| "\\gtrless" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtrless "))
|
||||
| "\\gtreqless" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtreqless "))
|
||||
| "\\gtreqqless" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gtreqqless "))
|
||||
| "\\eqcirc" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\eqcirc "))
|
||||
| "\\circeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circeq "))
|
||||
| "\\triangleq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\triangleq "))
|
||||
| "\\thicksim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\thicksim "))
|
||||
| "\\thickapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\thickapprox "))
|
||||
| "\\supseteqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\supseteqq "))
|
||||
| "\\Supset" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Supset "))
|
||||
| "\\succcurlyeq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succcurlyeq "))
|
||||
| "\\curlyeqsucc" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curlyeqsucc "))
|
||||
| "\\succsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succsim "))
|
||||
| "\\succapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succapprox "))
|
||||
| "\\vartriangleright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\vartriangleright "))
|
||||
| "\\shortmid" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\shortmid "))
|
||||
| "\\shortparallel" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\shortparallel "))
|
||||
| "\\between" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\between "))
|
||||
| "\\pitchfork" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\pitchfork "))
|
||||
| "\\varpropto" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varpropto "))
|
||||
| "\\blacktriangleleft"-> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacktriangleleft "))
|
||||
| "\\therefore" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\therefore "))
|
||||
| "\\backepsilon" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\backepsilon "))
|
||||
| "\\blacktriangleright"-> (tex_use_ams (); LITERAL (TEX_ONLY "\\blacktriangleright "))
|
||||
| "\\because" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\because "))
|
||||
| "\\nleqslant" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nleqslant "))
|
||||
| "\\nleqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nleqq "))
|
||||
| "\\lneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lneq "))
|
||||
| "\\lneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lneqq "))
|
||||
| "\\lvertneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lvertneqq "))
|
||||
| "\\lnsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lnsim "))
|
||||
| "\\lnapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\lnapprox "))
|
||||
| "\\nprec" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nprec "))
|
||||
| "\\npreceq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\npreceq "))
|
||||
| "\\precneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\precneqq "))
|
||||
| "\\precnsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\precnsim "))
|
||||
| "\\precnapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\precnapprox "))
|
||||
| "\\nsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsim "))
|
||||
| "\\nshortmid" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nshortmid "))
|
||||
| "\\nvdash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nvdash "))
|
||||
| "\\nVdash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nVdash "))
|
||||
| "\\ntriangleleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ntriangleleft "))
|
||||
| "\\ntrianglelefteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ntrianglelefteq "))
|
||||
| "\\nsubseteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsubseteq "))
|
||||
| "\\nsubseteqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsubseteqq "))
|
||||
| "\\varsubsetneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varsubsetneq "))
|
||||
| "\\subsetneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\subsetneqq "))
|
||||
| "\\varsubsetneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varsubsetneqq "))
|
||||
| "\\ngtr" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ngtr "))
|
||||
| "\\ngeqslant" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ngeqslant "))
|
||||
| "\\ngeqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ngeqq "))
|
||||
| "\\gneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gneq "))
|
||||
| "\\gneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gneqq "))
|
||||
| "\\gvertneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gvertneqq "))
|
||||
| "\\gnsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gnsim "))
|
||||
| "\\gnapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\gnapprox "))
|
||||
| "\\nsucc" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsucc "))
|
||||
| "\\nsucceq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsucceq "))
|
||||
| "\\succneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succneqq "))
|
||||
| "\\succnsim" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succnsim "))
|
||||
| "\\succnapprox" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\succnapprox "))
|
||||
| "\\ncong" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ncong "))
|
||||
| "\\nshortparallel" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nshortparallel "))
|
||||
| "\\nparallel" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nparallel "))
|
||||
| "\\nvDash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nvDash "))
|
||||
| "\\nVDash" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nVDash "))
|
||||
| "\\ntriangleright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ntriangleright "))
|
||||
| "\\ntrianglerighteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\ntrianglerighteq "))
|
||||
| "\\nsupseteq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsupseteq "))
|
||||
| "\\nsupseteqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nsupseteqq "))
|
||||
| "\\varsupsetneq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varsupsetneq "))
|
||||
| "\\supsetneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\supsetneqq "))
|
||||
| "\\varsupsetneqq" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\varsupsetneqq "))
|
||||
| "\\leftleftarrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftleftarrows "))
|
||||
| "\\leftrightarrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftrightarrows "))
|
||||
| "\\Lleftarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Lleftarrow "))
|
||||
| "\\leftarrowtail" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftarrowtail "))
|
||||
| "\\looparrowleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\looparrowleft "))
|
||||
| "\\leftrightharpoons"-> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftrightharpoons "))
|
||||
| "\\curvearrowleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curvearrowleft "))
|
||||
| "\\circlearrowleft" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circlearrowleft "))
|
||||
| "\\Lsh" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Lsh "))
|
||||
| "\\upuparrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\upuparrows "))
|
||||
| "\\rightrightarrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightrightarrows "))
|
||||
| "\\rightleftarrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightleftarrows "))
|
||||
| "\\Rrightarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Rrightarrow "))
|
||||
| "\\rightarrowtail" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightarrowtail "))
|
||||
| "\\looparrowright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\looparrowright "))
|
||||
| "\\curvearrowright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\curvearrowright "))
|
||||
| "\\circlearrowright" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\circlearrowright "))
|
||||
| "\\Rsh" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\Rsh "))
|
||||
| "\\downdownarrows" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\downdownarrows "))
|
||||
| "\\multimap" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\multimap "))
|
||||
| "\\leftrightsquigarrow"-> (tex_use_ams (); LITERAL (TEX_ONLY "\\leftrightsquigarrow "))
|
||||
| "\\rightsquigarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\rightsquigarrow "))
|
||||
| "\\nLeftarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nLeftarrow "))
|
||||
| "\\nleftrightarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nleftrightarrow "))
|
||||
| "\\nRightarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nRightarrow "))
|
||||
| "\\nLeftrightarrow" -> (tex_use_ams (); LITERAL (TEX_ONLY "\\nLeftrightarrow "))
|
||||
| "\\mathit" -> (tex_use_ams (); FUN_AR1hf ("\\mathit ", FONTFORCE_IT))
|
||||
| "\\mathrm" -> (tex_use_ams (); FUN_AR1hf ("\\mathrm ", FONTFORCE_RM))
|
||||
| "\\mathord" -> (tex_use_ams (); FUN_AR1 "\\mathord ")
|
||||
| "\\mathop" -> (tex_use_ams (); FUN_AR1 "\\mathop ")
|
||||
| "\\mathbin" -> (tex_use_ams (); FUN_AR1 "\\mathbin ")
|
||||
| "\\mathrel" -> (tex_use_ams (); FUN_AR1 "\\mathrel ")
|
||||
| "\\mathopen" -> (tex_use_ams (); FUN_AR1 "\\mathopen ")
|
||||
| "\\mathclose" -> (tex_use_ams (); FUN_AR1 "\\mathclose ")
|
||||
| "\\mathpunct" -> (tex_use_ams (); FUN_AR1 "\\mathpunct ")
|
||||
| "\\boldsymbol" -> (tex_use_ams (); FUN_AR1 "\\boldsymbol ")
|
||||
| "\\bold" -> (tex_use_ams (); FUN_AR1 "\\mathbf ")
|
||||
| "\\Bbb" -> (tex_use_ams (); FUN_AR1 "\\mathbb ")
|
||||
| "\\mathbf" -> (tex_use_ams (); FUN_AR1 "\\mathbf ")
|
||||
| "\\mathsf" -> (tex_use_ams (); FUN_AR1 "\\mathsf ")
|
||||
| "\\mathcal" -> (tex_use_ams (); FUN_AR1 "\\mathcal ")
|
||||
| "\\mathbb" -> (tex_use_ams (); FUN_AR1 "\\mathbb ")
|
||||
| "\\mathtt" -> (tex_use_ams (); FUN_AR1 "\\mathtt ")
|
||||
| "\\mathfrak" -> (tex_use_ams (); FUN_AR1 "\\mathfrak ")
|
||||
| "\\operatorname" -> (tex_use_ams (); FUN_AR1 "\\operatorname ")
|
||||
| "\\text" -> raise (Failure "malformatted \\text")
|
||||
| "\\mbox" -> raise (Failure "malformatted \\mbox")
|
||||
| "\\vbox" -> raise (Failure "malformatted \\vbox")
|
||||
| "\\hbox" -> raise (Failure "malformatted \\hbox")
|
||||
| "\\color" -> (tex_use_color (); LITERAL (TEX_ONLY "\\color"))
|
||||
| "\\pagecolor" -> (tex_use_color (); LITERAL (TEX_ONLY "\\pagecolor"))
|
||||
| "\\definecolor" -> (tex_use_color (); LITERAL (TEX_ONLY "\\definecolor"))
|
||||
| s -> raise (Illegal_tex_function s)
|
|
@ -1,11 +0,0 @@
|
|||
val render_tex : Tex.t -> string
|
||||
|
||||
val set_encoding : string -> unit
|
||||
val tex_use_nonascii: unit -> unit
|
||||
val tex_use_ams: unit -> unit
|
||||
|
||||
val get_preface : unit -> string
|
||||
val get_footer : unit -> string
|
||||
|
||||
exception Illegal_tex_function of string
|
||||
val find: string -> Parser.token
|
|
@ -1,57 +0,0 @@
|
|||
(* vim: set sw=8 ts=8 et: *)
|
||||
exception LexerException of string
|
||||
|
||||
(* *)
|
||||
let lexer_token_safe lexbuf =
|
||||
try Lexer.token lexbuf
|
||||
with Failure s -> raise (LexerException s)
|
||||
|
||||
(* *)
|
||||
let render tmppath finalpath tree backcolor =
|
||||
let outtex = Util.mapjoin Texutil.render_tex tree in
|
||||
let md5 = Digest.to_hex (Digest.string outtex) in
|
||||
begin
|
||||
let mathml = Mathml.render tree
|
||||
and html = Html.render tree
|
||||
in print_string (match (html,!Html.conservativeness,mathml) with
|
||||
None,_,None -> "+" ^ md5
|
||||
| Some h,Html.CONSERVATIVE,None -> "c" ^ md5 ^ h
|
||||
| Some h,Html.MODERATE,None -> "m" ^ md5 ^ h
|
||||
| Some h,Html.LIBERAL,None -> "l" ^ md5 ^ h
|
||||
| Some h,Html.CONSERVATIVE,Some m -> "C" ^ md5 ^ h ^ "\000" ^ m
|
||||
| Some h,Html.MODERATE,Some m -> "M" ^ md5 ^ h ^ "\000" ^ m
|
||||
| Some h,Html.LIBERAL,Some m -> "L" ^ md5 ^ h ^ "\000" ^ m
|
||||
| None,_,Some m -> "X" ^ md5 ^ m
|
||||
);
|
||||
Render.render tmppath finalpath outtex md5 backcolor
|
||||
end
|
||||
|
||||
(* Arguments:
|
||||
* 1st : temporary directory to use as scratch space
|
||||
* 2nd : target path
|
||||
* 3rd : LaTeX input
|
||||
* 4th : encoding (Default: UTF-8)
|
||||
* 5th : color (Default: rgb 1.0 1.0 1.0)
|
||||
*
|
||||
* Output one character:
|
||||
* S : Parsing error
|
||||
* E : Lexer exception raised
|
||||
* F : TeX function not recognized
|
||||
* - : Generic/Default failure code. Might be an invalid argument,
|
||||
* output file already exist, a problem with an external
|
||||
* command ...
|
||||
* *)
|
||||
let _ =
|
||||
Texutil.set_encoding (try Sys.argv.(4) with _ -> "UTF-8");
|
||||
try render Sys.argv.(1) Sys.argv.(2) (
|
||||
Parser.tex_expr lexer_token_safe (
|
||||
Lexing.from_string Sys.argv.(3))
|
||||
) (try Sys.argv.(5) with _ -> "rgb 1.0 1.0 1.0")
|
||||
with Parsing.Parse_error -> print_string "S"
|
||||
| LexerException _ -> print_string "E"
|
||||
| Texutil.Illegal_tex_function s -> print_string ("F" ^ s)
|
||||
| Util.FileAlreadyExists -> print_string "-"
|
||||
| Invalid_argument _ -> print_string "-"
|
||||
| Failure _ -> print_string "-"
|
||||
| Render.ExternalCommandFailure s -> ()
|
||||
| _ -> print_string "-"
|
|
@ -1,62 +0,0 @@
|
|||
open Netcgi;;
|
||||
open Netcgi_types;;
|
||||
open Netcgi_env;;
|
||||
open Netchannels;;
|
||||
|
||||
let cgi = new Netcgi.std_activation ()
|
||||
let out = cgi # output # output_string
|
||||
let math = cgi # argument_value ~default:"" "math"
|
||||
let tmppath = "/home/taw/public_html/wiki/tmp/"
|
||||
let finalpath = "/home/taw/public_html/wiki/math/"
|
||||
let finalurl = "http://wroclaw.taw.pl.eu.org/~taw/wiki/math/"
|
||||
;;
|
||||
|
||||
let h_header = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\""^
|
||||
" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"^
|
||||
"<html><head><title>texvc</title></head><body>"^
|
||||
"<form method=post action=\"http://wroclaw.taw.pl.eu.org/~taw/cgi-bin/newcodebase/math/texvc_cgi\">"^
|
||||
"<textarea name='math' rows=10 cols=80>"
|
||||
let h_middle = "</textarea><br /><input type=submit value=\"Preview\" name='preview'></form>"
|
||||
let h_footer = "</body></html>\n"
|
||||
|
||||
let render tmppath finalpath tree =
|
||||
let outtex = Texutil.mapjoin Texutil.print tree in
|
||||
let md5 = Digest.to_hex (Digest.string outtex) in
|
||||
begin
|
||||
out "<h3>TeX</h3>";
|
||||
out outtex; (* <, & and > should be protected *)
|
||||
(try out ("<h3>HTML</h3>" ^ (Texutil.html_render tree))
|
||||
with _ -> out "<h3>HTML could not be rendered</h3>");
|
||||
try Render.render tmppath finalpath outtex md5;
|
||||
out ("<h3>Image:</h3><img src=\""^finalurl^md5^".png\">")
|
||||
with Util.FileAlreadyExists -> out ("<h3>Image:</h3><img src=\""^finalurl^md5^".png\">")
|
||||
| Failure s -> out ("<h3>Other failure: " ^ s ^ "</h3>")
|
||||
| Render.ExternalCommandFailure "latex" -> out "<h3>latex failed</h3>"
|
||||
| Render.ExternalCommandFailure "dvips" -> out "<h3>dvips failed</h3>"
|
||||
| _ -> out "<h3>Other failure</h3>"
|
||||
end
|
||||
;;
|
||||
|
||||
cgi#set_header ();;
|
||||
|
||||
out h_header;;
|
||||
out math;;
|
||||
out h_middle;;
|
||||
|
||||
exception LexerException of string
|
||||
let lexer_token_safe lexbuf =
|
||||
try Lexer.token lexbuf
|
||||
with Failure s -> raise (LexerException s)
|
||||
;;
|
||||
if math = ""
|
||||
then ()
|
||||
else try
|
||||
render tmppath finalpath (Parser.tex_expr lexer_token_safe (Lexing.from_string math))
|
||||
with Parsing.Parse_error -> out "<h3>Parse error</h3>"
|
||||
| LexerException s -> out "<h3>Lexing failure</h3>"
|
||||
| Texutil.Illegal_tex_function s -> out ("<h3>Illegal TeX function: " ^ s ^ "</h3>")
|
||||
| Failure s -> out ("<h3>Other failure: " ^ s ^ "</h3>")
|
||||
| _ -> out "<h3>Other failure</h3>"
|
||||
;;
|
||||
|
||||
out h_footer
|
|
@ -1,24 +0,0 @@
|
|||
exception LexerException of string
|
||||
let lexer_token_safe lexbuf =
|
||||
try Lexer.token lexbuf
|
||||
with Failure s -> raise (LexerException s)
|
||||
|
||||
let rec foo () =
|
||||
try
|
||||
let line = input_line stdin in
|
||||
(try
|
||||
let tree = Parser.tex_expr lexer_token_safe (Lexing.from_string line) in
|
||||
(match Html.render tree with
|
||||
Some _ -> print_string "$^\n"
|
||||
| None -> print_string "$_\n";
|
||||
)
|
||||
with
|
||||
Texutil.Illegal_tex_function s -> print_string ("$T" ^ s ^ " " ^ line ^ "\n")
|
||||
| LexerException s -> print_string ("$L" ^ line ^ "\n")
|
||||
| _ -> print_string ("$ " ^ line ^ "\n"));
|
||||
flush stdout;
|
||||
foo ();
|
||||
with
|
||||
End_of_file -> ()
|
||||
;;
|
||||
foo ();;
|
|
@ -1,3 +0,0 @@
|
|||
Texutil.set_encoding (try Sys.argv.(2) with _ -> "UTF-8");
|
||||
try print_string (Util.mapjoin Texutil.render_tex (Parser.tex_expr Lexer.token (Lexing.from_string Sys.argv.(1))))
|
||||
with _ -> ()
|
26
math/util.ml
26
math/util.ml
|
@ -1,26 +0,0 @@
|
|||
(* vim: set sw=8 ts=8 et: *)
|
||||
|
||||
(* TODO document *)
|
||||
let mapjoin f l = (List.fold_left (fun a b -> a ^ (f b)) "" l)
|
||||
|
||||
(* TODO document *)
|
||||
let mapjoine e f = function
|
||||
[] -> ""
|
||||
| h::t -> (List.fold_left (fun a b -> a ^ e ^ (f b)) (f h) t)
|
||||
|
||||
(* Exception used by open_out_unless_exists below *)
|
||||
exception FileAlreadyExists
|
||||
|
||||
(* Wrapper which raise an exception when output path already exist *)
|
||||
let open_out_unless_exists path =
|
||||
if Sys.file_exists path
|
||||
then raise FileAlreadyExists
|
||||
else open_out path
|
||||
|
||||
(* *)
|
||||
let run_in_other_directory tmppath cmd =
|
||||
let prevdir = Sys.getcwd () in(
|
||||
Sys.chdir tmppath;
|
||||
let retval = Sys.command cmd in
|
||||
(Sys.chdir prevdir; retval)
|
||||
)
|
|
@ -317,19 +317,8 @@ class MathHooks {
|
|||
* @return bool
|
||||
*/
|
||||
static function onLoadExtensionSchemaUpdates( $updater = null ) {
|
||||
if ( is_null( $updater ) ) {
|
||||
throw new Exception( 'Math extension is only necessary in 1.18 or above' );
|
||||
}
|
||||
|
||||
$map = [ 'mysql', 'sqlite', 'postgres', 'oracle', 'mssql' ];
|
||||
|
||||
$type = $updater->getDB()->getType();
|
||||
|
||||
if ( !in_array( $type, $map ) ) {
|
||||
throw new Exception( "Math extension does not currently support $type database." );
|
||||
}
|
||||
$sql = __DIR__ . '/../db/math.' . $type . '.sql';
|
||||
$updater->addExtensionTable( 'math', $sql );
|
||||
if ( in_array( 'latexml', MathRenderer::getValidModes() ) ) {
|
||||
if ( in_array( $type, [ 'mysql', 'sqlite', 'postgres' ] ) ) {
|
||||
$sql = __DIR__ . '/../db/mathlatexml.' . $type . '.sql';
|
||||
|
|
|
@ -1,191 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @covers MathInputCheckTexvc
|
||||
*
|
||||
* @group Math
|
||||
*
|
||||
* @license GPL-2.0-or-later
|
||||
*/
|
||||
class MathInputCheckTexvcTest extends MediaWikiTestCase {
|
||||
|
||||
/**
|
||||
* @var MathInputCheckTexvc
|
||||
*/
|
||||
protected $BadObject;
|
||||
protected $GoodObject;
|
||||
|
||||
protected static $hasTexvccheck;
|
||||
protected static $texvccheckPath;
|
||||
|
||||
public static function setUpBeforeClass() {
|
||||
global $wgMathTexvcCheckExecutable;
|
||||
|
||||
if ( is_executable( $wgMathTexvcCheckExecutable ) ) {
|
||||
wfDebugLog( __CLASS__, " using build in texvccheck from "
|
||||
. "\$wgMathTexvcCheckExecutable = $wgMathTexvcCheckExecutable" );
|
||||
# Using build-in
|
||||
self::$hasTexvccheck = true;
|
||||
self::$texvccheckPath = $wgMathTexvcCheckExecutable;
|
||||
} else {
|
||||
# Attempt to compile
|
||||
wfDebugLog( __CLASS__, " compiling texvccheck..." );
|
||||
$cmd = 'cd ' . dirname( __DIR__ ) . '/texvccheck; make --always-make 2>&1';
|
||||
wfShellExec( $cmd, $retval );
|
||||
if ( $retval === 0 ) {
|
||||
self::$hasTexvccheck = true;
|
||||
self::$texvccheckPath = dirname( __DIR__ ) . '/texvccheck/texvccheck';
|
||||
wfDebugLog( __CLASS__, ' compiled texvccheck at ' . self::$texvccheckPath );
|
||||
} else {
|
||||
wfDebugLog( __CLASS__, ' ocaml not available or compilation of texvccheck failed' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->BadObject = new MathInputCheckTexvc( '\newcommand{\text{do evil things}}' );
|
||||
$this->GoodObject = new MathInputCheckTexvc( '\sin\left(\frac12x\right)' );
|
||||
|
||||
if ( ! self::$hasTexvccheck ) {
|
||||
$this->markTestSkipped( "No texvccheck installed on server" );
|
||||
} else {
|
||||
$this->setMwGlobals( 'wgMathTexvcCheckExecutable',
|
||||
self::$texvccheckPath );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is not a real phpUnit test.
|
||||
* It's just to discover whether setting default values dependent
|
||||
* on the existence of executables influences the performance reaonably.
|
||||
* The test is disabled by default. You can enable it via
|
||||
* php .../tests/phpunit/phpunit.php --group Utility ...
|
||||
* @group Utility
|
||||
*/
|
||||
public function testPerformanceIsExecutable() {
|
||||
global $wgMathTexvcCheckExecutable;
|
||||
/** @var int the number of runs used in that test */
|
||||
$numberOfRuns = 10;
|
||||
/** @var double the maximal average time accetable for a execution of is_executable in seconds*/
|
||||
$maxAvgTime = 0.001;
|
||||
$tstart = microtime( true );
|
||||
|
||||
for ( $i = 1; $i <= $numberOfRuns; $i++ ) {
|
||||
is_executable( $wgMathTexvcCheckExecutable );
|
||||
}
|
||||
|
||||
$time = microtime( true ) - $tstart;
|
||||
$this->assertTrue(
|
||||
$time < $maxAvgTime * $numberOfRuns,
|
||||
'function is_executable consumes too much time'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers MathInputCheckTexvc::getError
|
||||
*/
|
||||
public function testGetError() {
|
||||
$this->assertNull( $this->GoodObject->getError() );
|
||||
$this->assertNull( $this->BadObject->getError() );
|
||||
$this->BadObject->isValid();
|
||||
$this->GoodObject->isValid();
|
||||
$this->assertNull( $this->GoodObject->getError() );
|
||||
$expectedMessage = wfMessage(
|
||||
'math_unknown_function', '\newcommand'
|
||||
)->inContentLanguage()->escaped();
|
||||
$this->assertContains( $expectedMessage, $this->BadObject->getError() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers MathInputCheckTexvc::isValid
|
||||
*/
|
||||
public function testIsValid() {
|
||||
$this->assertFalse( $this->BadObject->isValid() );
|
||||
$this->assertTrue( $this->GoodObject->isValid() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers MathInputCheckTexvc::getValidTex
|
||||
*/
|
||||
public function testGetValidTex() {
|
||||
$this->assertNull( $this->GoodObject->getValidTex() );
|
||||
$this->assertNull( $this->BadObject->getValidTex() );
|
||||
$this->BadObject->isValid();
|
||||
$this->GoodObject->isValid();
|
||||
$this->assertNull( $this->BadObject->getValidTex() );
|
||||
|
||||
// Be aware of the additional brackets and spaces inserted here
|
||||
$this->assertEquals( $this->GoodObject->getValidTex(), "\\sin \\left({\\frac 12}x\\right)" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test corner cases of texvccheck conversion
|
||||
* @covers MathInputCheckTexvc::getValidTex
|
||||
*/
|
||||
public function testGetValidTexCornerCases() {
|
||||
$Object = new MathInputCheckTexvc( '\reals' );
|
||||
$Object->isValid();
|
||||
$this->assertEquals( "\\mathbb{R} ", $Object->getValidTex() );
|
||||
$Object = new MathInputCheckTexvc( '\lbrack' ); // Bug: 54624
|
||||
$Object->isValid();
|
||||
$this->assertEquals( '\\lbrack ', $Object->getValidTex() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests behavior of convertTexvcError
|
||||
* The method was moved from MathTexvc to MathInputCheckTexvc
|
||||
* @covers MathTexvc::convertTexvcError
|
||||
*/
|
||||
public function testConvertTexvcError() {
|
||||
$texvc = $this->getMockBuilder( 'MathInputCheckTexvc' )
|
||||
->setMethods( null )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$mathFailure = wfMessage( 'math_failure' )->inContentLanguage()->escaped();
|
||||
|
||||
$actualLexing = $texvc->convertTexvcError( 'E' );
|
||||
$expectedLexing = wfMessage( 'math_lexing_error', '' )->inContentLanguage()->escaped();
|
||||
$this->assertContains(
|
||||
$mathFailure, $actualLexing, 'Lexing error contains general math failure message'
|
||||
);
|
||||
$this->assertContains(
|
||||
$expectedLexing, $actualLexing, 'Lexing error contains detailed error for lexing'
|
||||
);
|
||||
|
||||
$actualSyntax = $texvc->convertTexvcError( 'S' );
|
||||
$expectedSyntax = wfMessage( 'math_syntax_error', '' )->inContentLanguage()->escaped();
|
||||
$this->assertContains(
|
||||
$mathFailure, $actualSyntax, 'Syntax error contains general math failure message'
|
||||
);
|
||||
$this->assertContains(
|
||||
$expectedSyntax, $actualSyntax, 'Syntax error contains detailed error for syntax'
|
||||
);
|
||||
|
||||
$unknownFunction = 'figureEightIntegral';
|
||||
$actualUnknownFunction = $texvc->convertTexvcError( "F$unknownFunction" );
|
||||
$expectedUnknownFunction = wfMessage(
|
||||
'math_unknown_function', $unknownFunction
|
||||
)->inContentLanguage()->escaped();
|
||||
$this->assertContains( $mathFailure, $actualUnknownFunction,
|
||||
'Unknown function error contains general math failure message'
|
||||
);
|
||||
$this->assertContains( $expectedUnknownFunction, $actualUnknownFunction,
|
||||
'Unknown function error contains detailed error for unknown function'
|
||||
);
|
||||
|
||||
$actualUnknownError = $texvc->convertTexvcError( 'Q' );
|
||||
$expectedUnknownError = wfMessage( 'math_unknown_error', '' )->inContentLanguage()->escaped();
|
||||
$this->assertContains(
|
||||
$mathFailure, $actualUnknownError, 'Unknown error contains general math failure message'
|
||||
);
|
||||
$this->assertContains( $expectedUnknownError, $actualUnknownError,
|
||||
'Unknown error contains detailed error for unknownError'
|
||||
);
|
||||
}
|
||||
}
|
|
@ -35,8 +35,8 @@ class MathDatabaseTest extends MediaWikiTestCase {
|
|||
// TODO: figure out why this is necessary
|
||||
$this->db = wfGetDB( DB_MASTER );
|
||||
// Create a new instance of MathSource
|
||||
$this->renderer = new MathTexvc( self::SOME_TEX );
|
||||
$this->tablesUsed[] = 'math';
|
||||
$this->renderer = new MathMathML( self::SOME_TEX );
|
||||
$this->tablesUsed[] = 'mathoid';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,8 +55,6 @@ class MathDatabaseTest extends MediaWikiTestCase {
|
|||
// set some values
|
||||
$this->renderer->setTex( self::SOME_TEX );
|
||||
$this->renderer->setMathml( self::SOME_MATHML );
|
||||
$this->renderer->setHtml( self::SOME_HTML );
|
||||
$this->renderer->setOutputHash( self::SOME_OUTPUTHASH );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,7 +65,7 @@ class MathDatabaseTest extends MediaWikiTestCase {
|
|||
public function testDBBasics() {
|
||||
$this->setValues();
|
||||
$this->renderer->writeToDatabase( $this->db );
|
||||
$renderer2 = new MathTexvc( self::SOME_TEX );
|
||||
$renderer2 = new MathMathML( self::SOME_TEX );
|
||||
$this->assertTrue( $renderer2->readFromDatabase(), 'Reading from database failed' );
|
||||
// comparing the class object does now work due to null values etc.
|
||||
$this->assertEquals(
|
||||
|
@ -77,7 +75,7 @@ class MathDatabaseTest extends MediaWikiTestCase {
|
|||
$this->renderer->getMathml(), $renderer2->getMathml(), "Check MathML encoding"
|
||||
);
|
||||
$this->assertEquals(
|
||||
$this->renderer->getHtml(), $renderer2->getHtml(), 'test if HTML is the same'
|
||||
$this->renderer->getHtmlOutput(), $renderer2->getHtmlOutput(), 'test if HTML is the same'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -86,16 +84,16 @@ class MathDatabaseTest extends MediaWikiTestCase {
|
|||
* @covers MathHooks::onLoadExtensionSchemaUpdates
|
||||
*/
|
||||
public function testCreateTable() {
|
||||
$this->setMwGlobals( 'wgMathValidModes', [ 'png' ] );
|
||||
$this->db->dropTable( "math", __METHOD__ );
|
||||
$this->setMwGlobals( 'wgMathValidModes', [ 'mathml' ] );
|
||||
$this->db->dropTable( "mathoid", __METHOD__ );
|
||||
$dbu = DatabaseUpdater::newForDB( $this->db );
|
||||
$dbu->doUpdates( [ "extensions" ] );
|
||||
$this->expectOutputRegex( '/(.*)Creating math table(.*)/' );
|
||||
$this->expectOutputRegex( '/(.*)Creating mathoid table(.*)/' );
|
||||
$this->setValues();
|
||||
$this->renderer->writeToDatabase();
|
||||
$res = $this->db->select( "math", "*" );
|
||||
$res = $this->db->select( "mathoid", "*" );
|
||||
$row = $res->fetchRow();
|
||||
$this->assertEquals( 10, count( $row ) );
|
||||
$this->assertEquals( 16, count( $row ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -107,13 +105,13 @@ class MathDatabaseTest extends MediaWikiTestCase {
|
|||
$inputHash = $this->renderer->getInputHash();
|
||||
$this->assertTrue( $this->renderer->isChanged() );
|
||||
$this->assertTrue( $this->renderer->writeCache(), "Write new entry" );
|
||||
$res = $this->db->selectField( "math", "math_inputhash",
|
||||
$res = $this->db->selectField( "mathoid", "math_inputhash",
|
||||
[ "math_inputhash" => $inputHash ] );
|
||||
$this->assertTrue( $res !== false, "Check database entry" );
|
||||
$this->assertTrue( $this->renderer->readFromDatabase(), "Read entry from database" );
|
||||
$this->assertFalse( $this->renderer->isChanged() );
|
||||
// modify the database entry manually
|
||||
$this->db->delete( "math", [ "math_inputhash" => $inputHash ] );
|
||||
$this->db->delete( "mathoid", [ "math_inputhash" => $inputHash ] );
|
||||
// the renderer should not be aware of the modification and should not recreate the entry
|
||||
$this->assertFalse( $this->renderer->writeCache() );
|
||||
// as a result no entry can be found in the database.
|
||||
|
|
|
@ -90,17 +90,4 @@ class MathInputCheckRestbaseTest extends MediaWikiTestCase {
|
|||
$this->assertEquals( $this->GoodObject->getValidTex(), '\\sin \\left({\\frac {1}{2}}x\\right)' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test corner cases of texvccheck conversion
|
||||
* @covers MathInputCheckTexvc::getValidTex
|
||||
*/
|
||||
public function testGetValidTexCornerCases() {
|
||||
$Object = new MathInputCheckTexvc( '\reals' );
|
||||
$Object->isValid();
|
||||
$this->assertEquals( "\\mathbb{R} ", $Object->getValidTex() );
|
||||
$Object = new MathInputCheckTexvc( '\lbrack' ); // Bug: 54624
|
||||
$Object->isValid();
|
||||
$this->assertEquals( '\\lbrack ', $Object->getValidTex() );
|
||||
}
|
||||
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* PHPUnit tests for MathTexvc.
|
||||
*
|
||||
* @covers MathTexvc
|
||||
*
|
||||
* @group Math
|
||||
*
|
||||
* @license GPL-2.0-or-later
|
||||
*/
|
||||
class MathTexvcTest extends MediaWikiTestCase {
|
||||
|
||||
/**
|
||||
* Tests behavior of render() upon a cache hit.
|
||||
* If the rendered object exists in the database cache, MathTexvc
|
||||
* just generates HTML from it, and skips shelling out to texvc
|
||||
* entirely.
|
||||
* @covers MathTexvc::render
|
||||
*/
|
||||
function testRenderCacheHit() {
|
||||
global $wgMathCheckFiles;
|
||||
|
||||
// Disable file checks. (This is permissable, because PHPUnit
|
||||
// will backup / restore global state on test setup / teardown.)
|
||||
$wgMathCheckFiles = false;
|
||||
|
||||
// Create a MathTexvc mock, replacing methods 'readFromDatabase',
|
||||
// 'callTexvc', and 'doHTMLRender' with test doubles.
|
||||
$texvc = $this->getMockBuilder( 'MathTexvc' )
|
||||
->setMethods( [ 'readCache', 'callTexvc', 'getHtmlOutput' ] )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
// When we call render() below, MathTexvc will ...
|
||||
|
||||
// ... first check if the item exists in the database cache:
|
||||
$texvc->expects( $this->once() )
|
||||
->method( 'readCache' )
|
||||
->with()
|
||||
->will( $this->returnValue( true ) );
|
||||
|
||||
// ... if cache lookup succeeded, it won't shell out to texvc:
|
||||
$texvc->expects( $this->never() )
|
||||
->method( 'callTexvc' );
|
||||
|
||||
// ... the output will not be generated if not requested
|
||||
$texvc->expects( $this->never() )
|
||||
->method( 'getHtmlOutput' );
|
||||
|
||||
$texvc->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test behavior of render() upon cache miss.
|
||||
* If the rendered object is not in the cache, MathTexvc will shell
|
||||
* out to texvc to generate it. If texvc succeeds, it'll use the
|
||||
* result to generate HTML.
|
||||
* @covers MathTexvc::render
|
||||
*/
|
||||
function testRenderCacheMiss() {
|
||||
$texvc = $this->getMockBuilder( 'MathTexvc' )
|
||||
->setMethods( [ 'readCache', 'callTexvc', 'getHtmlOutput' ] )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
// When we call render() below, MathTexvc will ...
|
||||
|
||||
// ... first look up the item in cache:
|
||||
$texvc->expects( $this->once() )
|
||||
->method( 'readCache' )
|
||||
->will( $this->returnValue( false ) );
|
||||
|
||||
// ... on cache miss, MathTexvc will shell out to texvc:
|
||||
$texvc->expects( $this->once() )
|
||||
->method( 'callTexvc' )
|
||||
->will( $this->returnValue( MathTexvc::MW_TEXVC_SUCCESS ) );
|
||||
|
||||
// ... the output will not be generated if not requested
|
||||
$texvc->expects( $this->never() )
|
||||
->method( 'getHtmlOutput' );
|
||||
|
||||
$texvc->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test behavior of render() when texvc fails.
|
||||
* If texvc returns a value other than MW_TEXVC_SUCCESS, render()
|
||||
* returns the error object and does not attempt to generate HTML.
|
||||
* @covers MathTexvc::render
|
||||
*/
|
||||
function testRenderTexvcFailure() {
|
||||
$texvc = $this->getMockBuilder( 'MathTexvc' )
|
||||
->setMethods( [ 'readCache', 'callTexvc', 'getHtmlOutput' ] )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
// When we call render() below, MathTexvc will ...
|
||||
|
||||
// ... first look up the item in cache:
|
||||
$texvc->expects( $this->any() )
|
||||
->method( 'readCache' )
|
||||
->will( $this->returnValue( false ) );
|
||||
|
||||
// ... on cache miss, shell out to texvc:
|
||||
$texvc->expects( $this->once() )
|
||||
->method( 'callTexvc' )
|
||||
->will( $this->returnValue( false ) );
|
||||
|
||||
// ... if texvc fails, render() will not generate HTML:
|
||||
$texvc->expects( $this->never() )
|
||||
->method( 'getHtmlOutput' );
|
||||
|
||||
// ... it will return the error result instead:
|
||||
$this->assertEquals( $texvc->render(), false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests behavior of convertTexvcError
|
||||
*
|
||||
* @covers MathTexvc::convertTexvcError
|
||||
*/
|
||||
public function testConvertTexvcError() {
|
||||
$texvc = $this->getMockBuilder( 'MathTexvc' )
|
||||
->setMethods( null )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$mathFailure = wfMessage( 'math_failure' )->inContentLanguage()->escaped();
|
||||
|
||||
$actualLexing = $texvc->convertTexvcError( 'E' );
|
||||
$expectedLexing = wfMessage( 'math_lexing_error', '' )->inContentLanguage()->escaped();
|
||||
$this->assertContains(
|
||||
$mathFailure, $actualLexing, 'Lexing error contains general math failure message'
|
||||
);
|
||||
$this->assertContains(
|
||||
$expectedLexing, $actualLexing, 'Lexing error contains detailed error for lexing'
|
||||
);
|
||||
|
||||
$actualSyntax = $texvc->convertTexvcError( 'S' );
|
||||
$expectedSyntax = wfMessage( 'math_syntax_error', '' )->inContentLanguage()->escaped();
|
||||
$this->assertContains(
|
||||
$mathFailure, $actualSyntax, 'Syntax error contains general math failure message'
|
||||
);
|
||||
$this->assertContains(
|
||||
$expectedSyntax, $actualSyntax, 'Syntax error contains detailed error for syntax'
|
||||
);
|
||||
|
||||
$unknownFunction = 'figureEightIntegral';
|
||||
$actualUnknownFunction = $texvc->convertTexvcError( "F$unknownFunction" );
|
||||
$expectedUnknownFunction = wfMessage(
|
||||
'math_unknown_function', $unknownFunction
|
||||
)->inContentLanguage()->escaped();
|
||||
$this->assertContains( $mathFailure, $actualUnknownFunction,
|
||||
'Unknown function error contains general math failure message'
|
||||
);
|
||||
$this->assertContains( $expectedUnknownFunction, $actualUnknownFunction,
|
||||
'Unknown function error contains detailed error for unknown function'
|
||||
);
|
||||
|
||||
$actualUnknownError = $texvc->convertTexvcError( 'Q' );
|
||||
$expectedUnknownError = wfMessage( 'math_unknown_error', '' )->inContentLanguage()->escaped();
|
||||
$this->assertContains(
|
||||
$mathFailure, $actualUnknownError, 'Unknown error contains general math failure message'
|
||||
);
|
||||
$this->assertContains( $expectedUnknownError, $actualUnknownError,
|
||||
'Unknown error contains detailed error for unknownError'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test behavior $change when the rendered hash was changed
|
||||
* @covers MathTexvc::setHash
|
||||
*/
|
||||
public function testChangeHash() {
|
||||
$renderer = $this->getMockBuilder( 'MathTexvc' )
|
||||
->setMethods( [ 'render', 'getMathTableName' ] )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->assertEquals(
|
||||
$renderer->isChanged(),
|
||||
false,
|
||||
"test if changed is initially false"
|
||||
);
|
||||
$renderer->setHash( '0000' );
|
||||
$this->assertEquals(
|
||||
$renderer->isChanged(),
|
||||
true,
|
||||
"assumes that changing a hash sets changed to true" );
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
# Compiled source
|
||||
*.cmi
|
||||
*.cmx
|
||||
*.o
|
||||
parser.mli
|
||||
|
||||
# The binaries
|
||||
texvccheck
|
|
@ -1,65 +0,0 @@
|
|||
.PHONY: clean all
|
||||
PREFIX = /usr/local
|
||||
DESTDIR = /usr
|
||||
SOURCEDIR = $(PWD)
|
||||
INSTALL = /usr/bin/install
|
||||
OBJ= tex.cmo texutil.cmo parser.cmo lexer.cmo texvccheck.cmo \
|
||||
tex.cmx texutil.cmx parser.cmx lexer.cmx texvccheck.cmx \
|
||||
lexer.cmi parser.cmi tex.cmi texutil.cmi texvccheck.cmi \
|
||||
lexer.o parser.o tex.o texutil.o texvccheck.o \
|
||||
lexer.ml parser.ml parser.mli texvccheck texvccheck.bc util.o \
|
||||
util.cmo util.cmx util.cmi \
|
||||
|
||||
COMMON_NATIVE_OBJ =util.cmx parser.cmx texutil.cmx lexer.cmx
|
||||
COMMON_BYTECODE_OBJ=util.cmo parser.cmo texutil.cmo lexer.cmo
|
||||
|
||||
all: texvccheck
|
||||
clean:
|
||||
rm -f $(OBJ)
|
||||
|
||||
# Native versions
|
||||
texvccheck: $(COMMON_NATIVE_OBJ) texvccheck.cmx
|
||||
ocamlopt -o $@ unix.cmxa $^
|
||||
|
||||
# Bytecode version
|
||||
texvccheck.bc: $(COMMON_BYTECODE_OBJ) texvccheck.cmo
|
||||
ocamlc -o $@ unix.cma $^
|
||||
|
||||
install: texvccheck
|
||||
$(INSTALL) -dm777 $(DESTDIR)/bin
|
||||
$(INSTALL) -m777 texvccheck $(DESTDIR)/bin
|
||||
|
||||
remove:
|
||||
rm -f $(DESTDIR)/bin/texvccheck
|
||||
|
||||
#
|
||||
# Pattern rules
|
||||
#
|
||||
|
||||
# .ml source .mli interface
|
||||
# .cmi compiled interface
|
||||
# .cmo object .cma library object
|
||||
# .cmx object file .cmxa library object file
|
||||
%.ml: %.mll
|
||||
ocamllex $<
|
||||
%.mli %.ml: %.mly
|
||||
ocamlyacc $<
|
||||
%.cmo: %.ml
|
||||
ocamlc -c $<
|
||||
%.cmx: %.ml
|
||||
ocamlopt -c $<
|
||||
%.cmi: %.mli
|
||||
ocamlc -c $<
|
||||
|
||||
# Various dependencies
|
||||
|
||||
lexer.cmo: parser.cmi tex.cmi texutil.cmi
|
||||
lexer.cmx: parser.cmx tex.cmi texutil.cmx
|
||||
parser.cmo: tex.cmi parser.cmi
|
||||
parser.cmx: tex.cmi parser.cmi
|
||||
parser.cmi: tex.cmi
|
||||
texutil.cmo: parser.cmi tex.cmi util.cmo texutil.cmi
|
||||
texutil.cmx: parser.cmx tex.cmi util.cmx texutil.cmi
|
||||
texutil.cmi: parser.cmi tex.cmi
|
||||
texvccheck.cmo: lexer.cmo parser.cmi texutil.cmi util.cmo
|
||||
texvccheck.cmx: lexer.cmx parser.cmx texutil.cmx util.cmx
|
|
@ -1,77 +0,0 @@
|
|||
== About texvccheck ==
|
||||
|
||||
texvc takes the user input validates it and replaces MediaWiki specific functions.
|
||||
Input data is parsed and scrutinized for safety.
|
||||
|
||||
texvc was written by Tomasz Wegrzanowski for use with MediaWiki; it's
|
||||
included as part of the MediaWiki package (http://www.mediawiki.org) and is
|
||||
under the GPL license.
|
||||
|
||||
texvc-lite, was extracted from the original texvc program in 2013 by
|
||||
Moritz Schubotz and uses only the sanitizing and customization part.
|
||||
|
||||
The list of all commands can be viewed by browsing the source files.
|
||||
Most commands are listed at
|
||||
http://sdrv.ms/15w2gVw
|
||||
there is also a tool for convenient whitelisting of special commands
|
||||
that are used in local wikis.
|
||||
|
||||
Please report bugs at: https://bugzilla.wikimedia.org/
|
||||
with "MediaWiki extensions" as product and "Math" as component.
|
||||
|
||||
== Setup ==
|
||||
|
||||
=== Requirements ===
|
||||
|
||||
OCaml 3.06 or later is required to compile texvc; this can be acquired from
|
||||
http://caml.inria.fr/ if your system doesn't have it available.
|
||||
|
||||
The makefile requires GNU make.
|
||||
|
||||
In Ubuntu Precise, all dependencies can be installed using:
|
||||
|
||||
$ sudo apt-get install ocaml
|
||||
|
||||
=== Installation ===
|
||||
|
||||
Run 'make' (or 'gmake' if GNU make is not your default make). This should
|
||||
produce the texvccheck executable.
|
||||
|
||||
By default,
|
||||
MediaWiki will search in this directory for texvc, if you moved it elsewhere,
|
||||
you'll have to modify $wgTexvc and set it to the path of the texvc executable.
|
||||
|
||||
== Usage ==
|
||||
|
||||
Normally texvc is called from MediaWiki's Math modules and everything
|
||||
Just Works. It can be run manually for testing or for use in another app.
|
||||
|
||||
=== Command-line parameters ===
|
||||
|
||||
texvccheck '\TeX input string'
|
||||
|
||||
Be sure to properly quote the TeX code!
|
||||
|
||||
Example:
|
||||
|
||||
texvc "y=x+2"
|
||||
|
||||
=== Output format ===
|
||||
|
||||
The output is the sanitized and customized tex string.
|
||||
|
||||
texvc output format is like this:
|
||||
+%s ok
|
||||
S syntax error
|
||||
E lexing error
|
||||
F%s unknown function %s
|
||||
- other error
|
||||
|
||||
== Hacking ==
|
||||
|
||||
Before you start hacking on the math package its good to know the workflow,
|
||||
which is basically:
|
||||
|
||||
1. texvc gets called by Math/Math.body.php (check out the line beginning with "$cmd")
|
||||
2. texvc does its magic, which is basically to check for invalid latex code.
|
||||
3. texvc takes the user input validates it and replaces MediaWiki specific functions
|
|
@ -1,119 +0,0 @@
|
|||
{
|
||||
open Parser
|
||||
open Tex
|
||||
}
|
||||
let space = [' ' '\t' '\n' '\r']
|
||||
let alpha = ['a'-'z' 'A'-'Z']
|
||||
let literal_id = ['a'-'z' 'A'-'Z']
|
||||
let literal_mn = ['0'-'9']
|
||||
let literal_uf_lt = [',' ':' ';' '?' '!' '\'']
|
||||
let delimiter_uf_lt = ['(' ')' '.']
|
||||
let literal_uf_op = ['+' '-' '*' '=']
|
||||
let delimiter_uf_op = ['/' '|']
|
||||
let boxchars = ['0'-'9' 'a'-'z' 'A'-'Z' '+' '-' '*' ',' '=' '(' ')' ':' '/' ';' '?' '.' '!' '\'' '`' ' ' '\128'-'\255']
|
||||
let aboxchars = ['0'-'9' 'a'-'z' 'A'-'Z' '+' '-' '*' ',' '=' '(' ')' ':' '/' ';' '?' '.' '!' '\'' '`' ' ']
|
||||
let latex_function_names = "arccos" | "arcsin" | "arctan" | "arg" | "cos" | "cosh" | "cot" | "coth" | "csc"| "deg" | "det" | "dim" | "exp" | "gcd" | "hom" | "inf" | "ker" | "lg" | "lim" | "liminf" | "limsup" | "ln" | "log" | "max" | "min" | "Pr" | "sec" | "sin" | "sinh" | "sup" | "tan" | "tanh"
|
||||
let mediawiki_function_names = "arccot" | "arcsec" | "arccsc" | "sgn" | "sen"
|
||||
|
||||
rule token = parse
|
||||
space + { token lexbuf }
|
||||
| "\\text" space * '{' aboxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\text", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\mbox" space * '{' aboxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\mbox", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\hbox" space * '{' aboxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\hbox", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\vbox" space * '{' aboxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\vbox", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\text" space * '{' boxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\text", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\mbox" space * '{' boxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\mbox", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\hbox" space * '{' boxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\hbox", String.sub str n (String.length str - n - 1)) }
|
||||
| "\\vbox" space * '{' boxchars + '}'
|
||||
{ let str = Lexing.lexeme lexbuf in
|
||||
let n = String.index str '{' + 1 in
|
||||
BOX ("\\vbox", String.sub str n (String.length str - n - 1)) }
|
||||
| literal_id { let str = Lexing.lexeme lexbuf in LITERAL (TEX_ONLY str) }
|
||||
| literal_mn { let str = Lexing.lexeme lexbuf in LITERAL (TEX_ONLY str) }
|
||||
| literal_uf_lt { let str = Lexing.lexeme lexbuf in LITERAL (TEX_ONLY str) }
|
||||
| delimiter_uf_lt { let str = Lexing.lexeme lexbuf in DELIMITER (TEX_ONLY str) }
|
||||
| "-" { let str = Lexing.lexeme lexbuf in LITERAL (TEX_ONLY str)}
|
||||
| literal_uf_op { let str = Lexing.lexeme lexbuf in LITERAL (TEX_ONLY str) }
|
||||
| delimiter_uf_op { let str = Lexing.lexeme lexbuf in DELIMITER (TEX_ONLY str) }
|
||||
| "\\operatorname" { FUN_AR1nb "\\operatorname" }
|
||||
| "\\sqrt" space * "[" { FUN_AR1opt "\\sqrt" }
|
||||
| "\\xleftarrow" space * "[" { FUN_AR1opt "\\xleftarrow" }
|
||||
| "\\xrightarrow" space * "[" { FUN_AR1opt "\\xrightarrow" }
|
||||
| "\\" (latex_function_names as name) space * "(" { LITERAL (TEX_ONLY ("\\" ^ name ^ "(")) }
|
||||
| "\\" (latex_function_names as name) space * "[" { LITERAL (TEX_ONLY ("\\" ^ name ^ "[") )}
|
||||
| "\\" (latex_function_names as name) space * "\\{" { LITERAL (TEX_ONLY ("\\" ^ name ^ "\\{")) }
|
||||
| "\\" (latex_function_names as name) space * { LITERAL (TEX_ONLY("\\" ^ name ^ " ")) }
|
||||
| "\\" (mediawiki_function_names as name) space * "(" { ( LITERAL (TEX_ONLY ("\\operatorname{" ^ name ^ "}("))) }
|
||||
| "\\" (mediawiki_function_names as name) space * "[" { ( LITERAL (TEX_ONLY ("\\operatorname{" ^ name ^ "}[")))}
|
||||
| "\\" (mediawiki_function_names as name) space * "\\{" { ( LITERAL (TEX_ONLY ("\\operatorname{" ^ name ^ "}\\{")))}
|
||||
| "\\" (mediawiki_function_names as name) space * { ( LITERAL (TEX_ONLY ("\\operatorname{" ^ name ^ "} "))) }
|
||||
| "\\" alpha + { Texutil.find (Lexing.lexeme lexbuf) }
|
||||
| "\\," { LITERAL (TEX_ONLY "\\,") }
|
||||
| "\\ " { LITERAL (TEX_ONLY "\\ ") }
|
||||
| "\\;" { LITERAL (TEX_ONLY "\\;") }
|
||||
| "\\!" { LITERAL (TEX_ONLY "\\!") }
|
||||
| "\\{" { DELIMITER (TEX_ONLY "\\{") }
|
||||
| "\\}" { DELIMITER (TEX_ONLY "\\}") }
|
||||
| "\\|" { DELIMITER (TEX_ONLY "\\|") }
|
||||
| "\\_" { LITERAL (TEX_ONLY "\\_") }
|
||||
| "\\#" { LITERAL (TEX_ONLY "\\#") }
|
||||
| "\\%" { LITERAL (TEX_ONLY "\\%") }
|
||||
| "\\$" { LITERAL (TEX_ONLY "\\$") }
|
||||
| "\\&" { LITERAL (TEX_ONLY "\\&") }
|
||||
| "&" { NEXT_CELL }
|
||||
| "\\\\" { NEXT_ROW }
|
||||
| "\\begin{matrix}" { BEGIN__MATRIX }
|
||||
| "\\end{matrix}" { END__MATRIX }
|
||||
| "\\begin{pmatrix}" { BEGIN_PMATRIX }
|
||||
| "\\end{pmatrix}" { END_PMATRIX }
|
||||
| "\\begin{bmatrix}" { BEGIN_BMATRIX }
|
||||
| "\\end{bmatrix}" { END_BMATRIX }
|
||||
| "\\begin{Bmatrix}" { BEGIN_BBMATRIX }
|
||||
| "\\end{Bmatrix}" { END_BBMATRIX }
|
||||
| "\\begin{vmatrix}" { BEGIN_VMATRIX }
|
||||
| "\\end{vmatrix}" { END_VMATRIX }
|
||||
| "\\begin{Vmatrix}" { BEGIN_VVMATRIX }
|
||||
| "\\end{Vmatrix}" { END_VVMATRIX }
|
||||
| "\\begin{array}" { BEGIN_ARRAY }
|
||||
| "\\end{array}" { END_ARRAY }
|
||||
| "\\begin{align}" { BEGIN_ALIGN }
|
||||
| "\\end{align}" { END_ALIGN }
|
||||
| "\\begin{alignat}" { BEGIN_ALIGNAT }
|
||||
| "\\end{alignat}" { END_ALIGNAT }
|
||||
| "\\begin{smallmatrix}" { BEGIN_SMALLMATRIX }
|
||||
| "\\end{smallmatrix}" { END_SMALLMATRIX }
|
||||
| "\\begin{cases}" { BEGIN_CASES }
|
||||
| "\\end{cases}" { END_CASES }
|
||||
| '>' { LITERAL (TEX_ONLY ">") }
|
||||
| '<' { LITERAL (TEX_ONLY "<") }
|
||||
| '%' { LITERAL (TEX_ONLY "\\%") }
|
||||
| '$' { LITERAL (TEX_ONLY "\\$") }
|
||||
| '~' { LITERAL (TEX_ONLY "~") }
|
||||
| '[' { DELIMITER (TEX_ONLY "[") }
|
||||
| ']' { SQ_CLOSE }
|
||||
| '{' { CURLY_OPEN }
|
||||
| '}' { CURLY_CLOSE }
|
||||
| '^' { SUP }
|
||||
| '_' { SUB }
|
||||
| eof { EOF }
|
|
@ -1,118 +0,0 @@
|
|||
%{
|
||||
open Tex
|
||||
|
||||
let sq_close_ri = HTMLABLEC(FONT_UFH,"]", "]")
|
||||
%}
|
||||
%token <Tex.render_t> LITERAL DELIMITER
|
||||
%token <string> FUN_AR2 FUN_INFIX FUN_AR1 DECL FUN_AR1nb FUN_AR1opt BIG FUN_AR2nb
|
||||
%token <string*string> BOX
|
||||
%token <string*(string*string)> FUN_AR1hl
|
||||
%token <string*Tex.font_force> FUN_AR1hf DECLh
|
||||
%token <string*(Tex.t->Tex.t->string*string*string)> FUN_AR2h
|
||||
%token <string*(Tex.t list->Tex.t list->string*string*string)> FUN_INFIXh
|
||||
%token EOF CURLY_OPEN CURLY_CLOSE SUB SUP SQ_CLOSE NEXT_CELL NEXT_ROW
|
||||
%token BEGIN__MATRIX BEGIN_PMATRIX BEGIN_BMATRIX BEGIN_BBMATRIX BEGIN_VMATRIX BEGIN_VVMATRIX BEGIN_CASES BEGIN_ARRAY BEGIN_ALIGN BEGIN_ALIGNAT BEGIN_SMALLMATRIX
|
||||
%token END__MATRIX END_PMATRIX END_BMATRIX END_BBMATRIX END_VMATRIX END_VVMATRIX END_CASES END_ARRAY END_ALIGN END_ALIGNAT END_SMALLMATRIX
|
||||
%token LEFT RIGHT
|
||||
%type <Tex.t list> tex_expr
|
||||
%start tex_expr
|
||||
|
||||
%%
|
||||
tex_expr:
|
||||
expr EOF { $1 }
|
||||
| ne_expr FUN_INFIX ne_expr EOF
|
||||
{ [TEX_INFIX($2,$1,$3)] }
|
||||
| ne_expr FUN_INFIXh ne_expr EOF
|
||||
{ let t,h=$2 in [TEX_INFIXh(t,h,$1,$3)] }
|
||||
expr:
|
||||
/* */ { [] }
|
||||
| ne_expr { $1 }
|
||||
ne_expr:
|
||||
lit_aq expr { $1 :: $2 }
|
||||
| litsq_aq expr { $1 :: $2 }
|
||||
| DECLh expr { let t,h = $1 in [TEX_DECLh(t,h,$2)] }
|
||||
litsq_aq:
|
||||
litsq_zq { $1 }
|
||||
| litsq_dq { let base,downi = $1 in TEX_DQ(base,downi) }
|
||||
| litsq_uq { let base,upi = $1 in TEX_UQ(base,upi)}
|
||||
| litsq_fq { $1 }
|
||||
litsq_fq:
|
||||
litsq_dq SUP lit { let base,downi = $1 in TEX_FQ(base,downi,$3) }
|
||||
| litsq_uq SUB lit { let base,upi = $1 in TEX_FQ(base,$3,upi) }
|
||||
litsq_uq:
|
||||
litsq_zq SUP lit { $1,$3 }
|
||||
litsq_dq:
|
||||
litsq_zq SUB lit { $1,$3 }
|
||||
litsq_zq:
|
||||
SQ_CLOSE { TEX_LITERAL sq_close_ri }
|
||||
expr_nosqc:
|
||||
/* */ { [] }
|
||||
| lit_aq expr_nosqc { $1 :: $2 }
|
||||
lit_aq:
|
||||
lit { $1 }
|
||||
| lit_dq { let base,downi = $1 in TEX_DQ(base,downi) }
|
||||
| lit_uq { let base,upi = $1 in TEX_UQ(base,upi)}
|
||||
| lit_dqn { TEX_DQN($1) }
|
||||
| lit_uqn { TEX_UQN($1) }
|
||||
| lit_fq { $1 }
|
||||
|
||||
lit_fq:
|
||||
lit_dq SUP lit { let base,downi = $1 in TEX_FQ(base,downi,$3) }
|
||||
| lit_uq SUB lit { let base,upi = $1 in TEX_FQ(base,$3,upi) }
|
||||
| lit_dqn SUP lit { TEX_FQN($1, $3) }
|
||||
|
||||
lit_uq:
|
||||
lit SUP lit { $1,$3 }
|
||||
lit_dq:
|
||||
lit SUB lit { $1,$3 }
|
||||
lit_uqn:
|
||||
SUP lit { $2 }
|
||||
lit_dqn:
|
||||
SUB lit { $2 }
|
||||
|
||||
|
||||
left:
|
||||
LEFT DELIMITER { $2 }
|
||||
| LEFT SQ_CLOSE { sq_close_ri }
|
||||
right:
|
||||
RIGHT DELIMITER { $2 }
|
||||
| RIGHT SQ_CLOSE { sq_close_ri }
|
||||
lit:
|
||||
LITERAL { TEX_LITERAL $1 }
|
||||
| DELIMITER { TEX_LITERAL $1 }
|
||||
| BIG DELIMITER { TEX_BIG ($1,$2) }
|
||||
| BIG SQ_CLOSE { TEX_BIG ($1,sq_close_ri) }
|
||||
| left expr right { TEX_LR ($1,$3,$2) }
|
||||
| FUN_AR1 lit { TEX_FUN1($1,$2) }
|
||||
| FUN_AR1nb lit { TEX_FUN1nb($1,$2) }
|
||||
| FUN_AR1hl lit { let t,h=$1 in TEX_FUN1hl(t,h,$2) }
|
||||
| FUN_AR1hf lit { let t,h=$1 in TEX_FUN1hf(t,h,$2) }
|
||||
| FUN_AR1opt expr_nosqc SQ_CLOSE lit { TEX_FUN2sq($1,TEX_CURLY $2,$4) }
|
||||
| FUN_AR2 lit lit { TEX_FUN2($1,$2,$3) }
|
||||
| FUN_AR2nb lit lit { TEX_FUN2nb($1,$2,$3) }
|
||||
| FUN_AR2h lit lit { let t,h=$1 in TEX_FUN2h(t,h,$2,$3) }
|
||||
| BOX { let bt,s = $1 in TEX_BOX (bt,s) }
|
||||
| CURLY_OPEN expr CURLY_CLOSE
|
||||
{ TEX_CURLY $2 }
|
||||
| CURLY_OPEN ne_expr FUN_INFIX ne_expr CURLY_CLOSE
|
||||
{ TEX_INFIX($3,$2,$4) }
|
||||
| CURLY_OPEN ne_expr FUN_INFIXh ne_expr CURLY_CLOSE
|
||||
{ let t,h=$3 in TEX_INFIXh(t,h,$2,$4) }
|
||||
| BEGIN__MATRIX matrix END__MATRIX { TEX_MATRIX ("matrix", $2) }
|
||||
| BEGIN_PMATRIX matrix END_PMATRIX { TEX_MATRIX ("pmatrix", $2) }
|
||||
| BEGIN_BMATRIX matrix END_BMATRIX { TEX_MATRIX ("bmatrix", $2) }
|
||||
| BEGIN_BBMATRIX matrix END_BBMATRIX { TEX_MATRIX ("Bmatrix", $2) }
|
||||
| BEGIN_VMATRIX matrix END_VMATRIX { TEX_MATRIX ("vmatrix", $2) }
|
||||
| BEGIN_VVMATRIX matrix END_VVMATRIX { TEX_MATRIX ("Vmatrix", $2) }
|
||||
| BEGIN_ARRAY matrix END_ARRAY { TEX_MATRIX ("array", $2) }
|
||||
| BEGIN_ALIGN matrix END_ALIGN { TEX_MATRIX ("aligned", $2) }
|
||||
| BEGIN_ALIGNAT matrix END_ALIGNAT { TEX_MATRIX ("alignedat", $2) }
|
||||
| BEGIN_SMALLMATRIX matrix END_SMALLMATRIX { TEX_MATRIX ("smallmatrix", $2) }
|
||||
| BEGIN_CASES matrix END_CASES { TEX_MATRIX ("cases", $2) }
|
||||
matrix:
|
||||
line { [$1] }
|
||||
| line NEXT_ROW matrix { $1::$3 }
|
||||
line:
|
||||
expr { [$1] }
|
||||
| expr NEXT_CELL line { $1::$3 }
|
||||
;;
|
|
@ -1,48 +0,0 @@
|
|||
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
|
|
@ -1,712 +0,0 @@
|
|||
(* vim: set sw=8 ts=8 et: *)
|
||||
open Parser
|
||||
open Tex
|
||||
open Util
|
||||
|
||||
|
||||
let tex_part = function
|
||||
HTMLABLE (_,t,_) -> t
|
||||
| HTMLABLEM (_,t,_) -> t
|
||||
| HTMLABLEC (_,t,_) -> t
|
||||
| MHTMLABLEC (_,t,_,_,_) -> t
|
||||
| HTMLABLE_BIG (t,_) -> t
|
||||
| TEX_ONLY t -> t
|
||||
|
||||
let rec render_tex = function
|
||||
TEX_FQ (a,b,c) -> (render_tex a) ^ "_{" ^ (render_tex b) ^ "}^{" ^ (render_tex c) ^ "}"
|
||||
| TEX_DQ (a,b) -> (render_tex a) ^ "_{" ^ (render_tex b) ^ "}"
|
||||
| TEX_UQ (a,b) -> (render_tex a) ^ "^{" ^ (render_tex b) ^ "}"
|
||||
| TEX_FQN (a,b) -> "_{" ^ (render_tex a) ^ "}^{" ^ (render_tex b) ^ "}"
|
||||
| TEX_DQN (a) -> "_{" ^ (render_tex a) ^ "}"
|
||||
| TEX_UQN (a) -> "^{" ^ (render_tex a) ^ "}"
|
||||
| TEX_LITERAL s -> tex_part s
|
||||
| TEX_FUN1 (f,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
|
||||
| TEX_FUN1nb (f,a) -> f ^ " " ^ (render_tex a)
|
||||
| TEX_FUN1hl (f,_,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
|
||||
| TEX_FUN1hf (f,_,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
|
||||
| TEX_DECLh (f,_,a) -> "{" ^ f ^ "{" ^ (mapjoin render_tex a) ^ "}}"
|
||||
| TEX_FUN2 (f,a,b) -> "{" ^ f ^ " " ^ (render_tex a) ^ (render_tex b) ^ "}"
|
||||
| TEX_FUN2h (f,_,a,b) -> "{" ^ f ^ " " ^ (render_tex a) ^ (render_tex b) ^ "}"
|
||||
| TEX_FUN2nb (f,a,b) -> f ^ (render_tex a) ^ (render_tex b)
|
||||
|
||||
| TEX_FUN2sq (f,a,b) -> "{" ^ f ^ "[ " ^ (render_tex a) ^ "]" ^ (render_tex b) ^ "}"
|
||||
| TEX_CURLY (tl) -> "{" ^ (mapjoin render_tex tl) ^ "}"
|
||||
| TEX_INFIX (s,ll,rl) -> "{" ^ (mapjoin render_tex ll) ^ " " ^ s ^ "" ^ (mapjoin render_tex rl) ^ "}"
|
||||
| TEX_INFIXh (s,_,ll,rl) -> "{" ^ (mapjoin render_tex ll) ^ " " ^ s ^ "" ^ (mapjoin render_tex rl) ^ "}"
|
||||
| TEX_BOX (bt,s) -> "{"^bt^"{" ^ s ^ "}}"
|
||||
| TEX_BIG (bt,d) -> "{"^bt^(tex_part d)^"}"
|
||||
| TEX_MATRIX (t,rows) -> "{\\begin{"^t^"}"^(mapjoine "\\\\" (mapjoine "&" (mapjoin render_tex)) rows)^"\\end{"^t^"}}"
|
||||
| TEX_LR (l,r,tl) -> "\\left"^(tex_part l)^(mapjoin render_tex tl)^"\\right"^(tex_part r)
|
||||
|
||||
|
||||
(* Turn that into hash table lookup *)
|
||||
exception Illegal_tex_function of string
|
||||
|
||||
let find cmd = match cmd with
|
||||
"\\aleph"
|
||||
| "\\alpha"
|
||||
| "\\amalg"
|
||||
| "\\And"
|
||||
| "\\angle"
|
||||
| "\\approx"
|
||||
| "\\approxeq"
|
||||
| "\\ast"
|
||||
| "\\asymp"
|
||||
| "\\backepsilon"
|
||||
| "\\backprime"
|
||||
| "\\backsim"
|
||||
| "\\backsimeq"
|
||||
| "\\barwedge"
|
||||
| "\\Bbbk"
|
||||
| "\\because"
|
||||
| "\\beta"
|
||||
| "\\beth"
|
||||
| "\\between"
|
||||
| "\\bigcap"
|
||||
| "\\bigcirc"
|
||||
| "\\bigcup"
|
||||
| "\\bigodot"
|
||||
| "\\bigoplus"
|
||||
| "\\bigotimes"
|
||||
| "\\bigsqcup"
|
||||
| "\\bigstar"
|
||||
| "\\bigtriangledown"
|
||||
| "\\bigtriangleup"
|
||||
| "\\biguplus"
|
||||
| "\\bigvee"
|
||||
| "\\bigwedge"
|
||||
| "\\blacklozenge"
|
||||
| "\\blacksquare"
|
||||
| "\\blacktriangle"
|
||||
| "\\blacktriangledown"
|
||||
| "\\blacktriangleleft"
|
||||
| "\\blacktriangleright"
|
||||
| "\\bot"
|
||||
| "\\bowtie"
|
||||
| "\\Box"
|
||||
| "\\boxdot"
|
||||
| "\\boxminus"
|
||||
| "\\boxplus"
|
||||
| "\\boxtimes"
|
||||
| "\\bullet"
|
||||
| "\\bumpeq"
|
||||
| "\\Bumpeq"
|
||||
| "\\cap"
|
||||
| "\\Cap"
|
||||
| "\\cdot"
|
||||
| "\\cdots"
|
||||
| "\\centerdot"
|
||||
| "\\checkmark"
|
||||
| "\\chi"
|
||||
| "\\circ"
|
||||
| "\\circeq"
|
||||
| "\\circlearrowleft"
|
||||
| "\\circlearrowright"
|
||||
| "\\circledast"
|
||||
| "\\circledcirc"
|
||||
| "\\circleddash"
|
||||
| "\\circledS"
|
||||
| "\\clubsuit"
|
||||
| "\\colon"
|
||||
| "\\color"
|
||||
| "\\complement"
|
||||
| "\\cong"
|
||||
| "\\coprod"
|
||||
| "\\cup"
|
||||
| "\\Cup"
|
||||
| "\\curlyeqprec"
|
||||
| "\\curlyeqsucc"
|
||||
| "\\curlyvee"
|
||||
| "\\curlywedge"
|
||||
| "\\curvearrowleft"
|
||||
| "\\curvearrowright"
|
||||
| "\\dagger"
|
||||
| "\\daleth"
|
||||
| "\\dashv"
|
||||
| "\\ddagger"
|
||||
| "\\ddots"
|
||||
| "\\definecolor"
|
||||
| "\\delta"
|
||||
| "\\Delta"
|
||||
| "\\diagdown"
|
||||
| "\\diagup"
|
||||
| "\\diamond"
|
||||
| "\\Diamond"
|
||||
| "\\diamondsuit"
|
||||
| "\\digamma"
|
||||
| "\\displaystyle"
|
||||
| "\\div"
|
||||
| "\\divideontimes"
|
||||
| "\\doteq"
|
||||
| "\\doteqdot"
|
||||
| "\\dotplus"
|
||||
| "\\dots"
|
||||
| "\\dotsb"
|
||||
| "\\dotsc"
|
||||
| "\\dotsi"
|
||||
| "\\dotsm"
|
||||
| "\\dotso"
|
||||
| "\\doublebarwedge"
|
||||
| "\\downdownarrows"
|
||||
| "\\downharpoonleft"
|
||||
| "\\downharpoonright"
|
||||
| "\\ell"
|
||||
| "\\emptyset"
|
||||
| "\\epsilon"
|
||||
| "\\eqcirc"
|
||||
| "\\eqsim"
|
||||
| "\\eqslantgtr"
|
||||
| "\\eqslantless"
|
||||
| "\\equiv"
|
||||
| "\\eta"
|
||||
| "\\eth"
|
||||
| "\\exists"
|
||||
| "\\fallingdotseq"
|
||||
| "\\Finv"
|
||||
| "\\flat"
|
||||
| "\\forall"
|
||||
| "\\frown"
|
||||
| "\\Game"
|
||||
| "\\gamma"
|
||||
| "\\Gamma"
|
||||
| "\\geq"
|
||||
| "\\geqq"
|
||||
| "\\geqslant"
|
||||
| "\\gets"
|
||||
| "\\gg"
|
||||
| "\\ggg"
|
||||
| "\\gimel"
|
||||
| "\\gnapprox"
|
||||
| "\\gneq"
|
||||
| "\\gneqq"
|
||||
| "\\gnsim"
|
||||
| "\\gtrapprox"
|
||||
| "\\gtrdot"
|
||||
| "\\gtreqless"
|
||||
| "\\gtreqqless"
|
||||
| "\\gtrless"
|
||||
| "\\gtrsim"
|
||||
| "\\gvertneqq"
|
||||
| "\\hbar"
|
||||
| "\\heartsuit"
|
||||
| "\\hline"
|
||||
| "\\hookleftarrow"
|
||||
| "\\hookrightarrow"
|
||||
| "\\hslash"
|
||||
| "\\iff"
|
||||
| "\\iiiint"
|
||||
| "\\iiint"
|
||||
| "\\iint"
|
||||
| "\\Im"
|
||||
| "\\imath"
|
||||
| "\\implies"
|
||||
| "\\in"
|
||||
| "\\infty"
|
||||
| "\\injlim"
|
||||
| "\\int"
|
||||
| "\\intercal"
|
||||
| "\\iota"
|
||||
| "\\jmath"
|
||||
| "\\kappa"
|
||||
| "\\lambda"
|
||||
| "\\Lambda"
|
||||
| "\\land"
|
||||
| "\\ldots"
|
||||
| "\\leftarrow"
|
||||
| "\\Leftarrow"
|
||||
| "\\leftarrowtail"
|
||||
| "\\leftharpoondown"
|
||||
| "\\leftharpoonup"
|
||||
| "\\leftleftarrows"
|
||||
| "\\leftrightarrow"
|
||||
| "\\Leftrightarrow"
|
||||
| "\\leftrightarrows"
|
||||
| "\\leftrightharpoons"
|
||||
| "\\leftrightsquigarrow"
|
||||
| "\\leftthreetimes"
|
||||
| "\\leq"
|
||||
| "\\leqq"
|
||||
| "\\leqslant"
|
||||
| "\\lessapprox"
|
||||
| "\\lessdot"
|
||||
| "\\lesseqgtr"
|
||||
| "\\lesseqqgtr"
|
||||
| "\\lessgtr"
|
||||
| "\\lesssim"
|
||||
| "\\limits"
|
||||
| "\\ll"
|
||||
| "\\Lleftarrow"
|
||||
| "\\lll"
|
||||
| "\\lnapprox"
|
||||
| "\\lneq"
|
||||
| "\\lneqq"
|
||||
| "\\lnot"
|
||||
| "\\lnsim"
|
||||
| "\\longleftarrow"
|
||||
| "\\Longleftarrow"
|
||||
| "\\longleftrightarrow"
|
||||
| "\\Longleftrightarrow"
|
||||
| "\\longmapsto"
|
||||
| "\\longrightarrow"
|
||||
| "\\Longrightarrow"
|
||||
| "\\looparrowleft"
|
||||
| "\\looparrowright"
|
||||
| "\\lor"
|
||||
| "\\lozenge"
|
||||
| "\\Lsh"
|
||||
| "\\ltimes"
|
||||
| "\\lVert"
|
||||
| "\\lvertneqq"
|
||||
| "\\mapsto"
|
||||
| "\\measuredangle"
|
||||
| "\\mho"
|
||||
| "\\mid"
|
||||
| "\\mod"
|
||||
| "\\models"
|
||||
| "\\mp"
|
||||
| "\\mu"
|
||||
| "\\multimap"
|
||||
| "\\nabla"
|
||||
| "\\natural"
|
||||
| "\\ncong"
|
||||
| "\\nearrow"
|
||||
| "\\neg"
|
||||
| "\\neq"
|
||||
| "\\nexists"
|
||||
| "\\ngeq"
|
||||
| "\\ngeqq"
|
||||
| "\\ngeqslant"
|
||||
| "\\ngtr"
|
||||
| "\\ni"
|
||||
| "\\nleftarrow"
|
||||
| "\\nLeftarrow"
|
||||
| "\\nleftrightarrow"
|
||||
| "\\nLeftrightarrow"
|
||||
| "\\nleq"
|
||||
| "\\nleqq"
|
||||
| "\\nleqslant"
|
||||
| "\\nless"
|
||||
| "\\nmid"
|
||||
| "\\nolimits"
|
||||
| "\\not"
|
||||
| "\\notin"
|
||||
| "\\nparallel"
|
||||
| "\\nprec"
|
||||
| "\\npreceq"
|
||||
| "\\nrightarrow"
|
||||
| "\\nRightarrow"
|
||||
| "\\nshortmid"
|
||||
| "\\nshortparallel"
|
||||
| "\\nsim"
|
||||
| "\\nsubseteq"
|
||||
| "\\nsubseteqq"
|
||||
| "\\nsucc"
|
||||
| "\\nsucceq"
|
||||
| "\\nsupseteq"
|
||||
| "\\nsupseteqq"
|
||||
| "\\ntriangleleft"
|
||||
| "\\ntrianglelefteq"
|
||||
| "\\ntriangleright"
|
||||
| "\\ntrianglerighteq"
|
||||
| "\\nu"
|
||||
| "\\nvdash"
|
||||
| "\\nVdash"
|
||||
| "\\nvDash"
|
||||
| "\\nVDash"
|
||||
| "\\nwarrow"
|
||||
| "\\odot"
|
||||
| "\\oint"
|
||||
| "\\omega"
|
||||
| "\\Omega"
|
||||
| "\\ominus"
|
||||
| "\\oplus"
|
||||
| "\\oslash"
|
||||
| "\\otimes"
|
||||
| "\\P"
|
||||
| "\\pagecolor"
|
||||
| "\\parallel"
|
||||
| "\\partial"
|
||||
| "\\perp"
|
||||
| "\\phi"
|
||||
| "\\Phi"
|
||||
| "\\pi"
|
||||
| "\\Pi"
|
||||
| "\\pitchfork"
|
||||
| "\\pm"
|
||||
| "\\prec"
|
||||
| "\\precapprox"
|
||||
| "\\preccurlyeq"
|
||||
| "\\preceq"
|
||||
| "\\precnapprox"
|
||||
| "\\precneqq"
|
||||
| "\\precnsim"
|
||||
| "\\precsim"
|
||||
| "\\prime"
|
||||
| "\\prod"
|
||||
| "\\projlim"
|
||||
| "\\propto"
|
||||
| "\\psi"
|
||||
| "\\Psi"
|
||||
| "\\qquad"
|
||||
| "\\quad"
|
||||
| "\\Re"
|
||||
| "\\rho"
|
||||
| "\\rightarrow"
|
||||
| "\\Rightarrow"
|
||||
| "\\rightarrowtail"
|
||||
| "\\rightharpoondown"
|
||||
| "\\rightharpoonup"
|
||||
| "\\rightleftarrows"
|
||||
| "\\rightrightarrows"
|
||||
| "\\rightsquigarrow"
|
||||
| "\\rightthreetimes"
|
||||
| "\\risingdotseq"
|
||||
| "\\Rrightarrow"
|
||||
| "\\Rsh"
|
||||
| "\\rtimes"
|
||||
| "\\rVert"
|
||||
| "\\S"
|
||||
| "\\scriptscriptstyle"
|
||||
| "\\scriptstyle"
|
||||
| "\\searrow"
|
||||
| "\\setminus"
|
||||
| "\\sharp"
|
||||
| "\\shortmid"
|
||||
| "\\shortparallel"
|
||||
| "\\sigma"
|
||||
| "\\Sigma"
|
||||
| "\\sim"
|
||||
| "\\simeq"
|
||||
| "\\smallfrown"
|
||||
| "\\smallsetminus"
|
||||
| "\\smallsmile"
|
||||
| "\\smile"
|
||||
| "\\spadesuit"
|
||||
| "\\sphericalangle"
|
||||
| "\\sqcap"
|
||||
| "\\sqcup"
|
||||
| "\\sqsubset"
|
||||
| "\\sqsubseteq"
|
||||
| "\\sqsupset"
|
||||
| "\\sqsupseteq"
|
||||
| "\\square"
|
||||
| "\\star"
|
||||
| "\\subset"
|
||||
| "\\Subset"
|
||||
| "\\subseteq"
|
||||
| "\\subseteqq"
|
||||
| "\\subsetneq"
|
||||
| "\\subsetneqq"
|
||||
| "\\succ"
|
||||
| "\\succapprox"
|
||||
| "\\succcurlyeq"
|
||||
| "\\succeq"
|
||||
| "\\succnapprox"
|
||||
| "\\succneqq"
|
||||
| "\\succnsim"
|
||||
| "\\succsim"
|
||||
| "\\sum"
|
||||
| "\\supset"
|
||||
| "\\Supset"
|
||||
| "\\supseteq"
|
||||
| "\\supseteqq"
|
||||
| "\\supsetneq"
|
||||
| "\\supsetneqq"
|
||||
| "\\surd"
|
||||
| "\\swarrow"
|
||||
| "\\tau"
|
||||
| "\\textstyle"
|
||||
| "\\therefore"
|
||||
| "\\theta"
|
||||
| "\\Theta"
|
||||
| "\\thickapprox"
|
||||
| "\\thicksim"
|
||||
| "\\times"
|
||||
| "\\to"
|
||||
| "\\top"
|
||||
| "\\triangle"
|
||||
| "\\triangledown"
|
||||
| "\\triangleleft"
|
||||
| "\\trianglelefteq"
|
||||
| "\\triangleq"
|
||||
| "\\triangleright"
|
||||
| "\\trianglerighteq"
|
||||
| "\\upharpoonleft"
|
||||
| "\\upharpoonright"
|
||||
| "\\uplus"
|
||||
| "\\upsilon"
|
||||
| "\\Upsilon"
|
||||
| "\\upuparrows"
|
||||
| "\\varepsilon"
|
||||
| "\\varinjlim"
|
||||
| "\\varkappa"
|
||||
| "\\varliminf"
|
||||
| "\\varlimsup"
|
||||
| "\\varnothing"
|
||||
| "\\varphi"
|
||||
| "\\varpi"
|
||||
| "\\varprojlim"
|
||||
| "\\varpropto"
|
||||
| "\\varrho"
|
||||
| "\\varsigma"
|
||||
| "\\varsubsetneq"
|
||||
| "\\varsubsetneqq"
|
||||
| "\\varsupsetneq"
|
||||
| "\\varsupsetneqq"
|
||||
| "\\vartheta"
|
||||
| "\\vartriangle"
|
||||
| "\\vartriangleleft"
|
||||
| "\\vartriangleright"
|
||||
| "\\vdash"
|
||||
| "\\Vdash"
|
||||
| "\\vDash"
|
||||
| "\\vdots"
|
||||
| "\\vee"
|
||||
| "\\veebar"
|
||||
| "\\vline"
|
||||
| "\\Vvdash"
|
||||
| "\\wedge"
|
||||
| "\\wp"
|
||||
| "\\wr"
|
||||
| "\\xi"
|
||||
| "\\Xi"
|
||||
| "\\zeta"
|
||||
-> LITERAL ( TEX_ONLY( cmd ^ " " ) )
|
||||
|
||||
| "\\big"
|
||||
| "\\Big"
|
||||
| "\\bigg"
|
||||
| "\\Bigg"
|
||||
| "\\biggl"
|
||||
| "\\Biggl"
|
||||
| "\\biggr"
|
||||
| "\\Biggr"
|
||||
| "\\bigl"
|
||||
| "\\Bigl"
|
||||
| "\\bigr"
|
||||
| "\\Bigr"
|
||||
-> BIG ( cmd ^ " " )
|
||||
|
||||
| "\\backslash"
|
||||
| "\\downarrow"
|
||||
| "\\Downarrow"
|
||||
| "\\langle"
|
||||
| "\\lbrace"
|
||||
| "\\lceil"
|
||||
| "\\lfloor"
|
||||
| "\\llcorner"
|
||||
| "\\lrcorner"
|
||||
| "\\rangle"
|
||||
| "\\rbrace"
|
||||
| "\\rceil"
|
||||
| "\\rfloor"
|
||||
| "\\rightleftharpoons"
|
||||
| "\\twoheadleftarrow"
|
||||
| "\\twoheadrightarrow"
|
||||
| "\\ulcorner"
|
||||
| "\\uparrow"
|
||||
| "\\Uparrow"
|
||||
| "\\updownarrow"
|
||||
| "\\Updownarrow"
|
||||
| "\\urcorner"
|
||||
| "\\Vert"
|
||||
| "\\vert"
|
||||
| "\\lbrack"
|
||||
| "\\rbrack"
|
||||
-> DELIMITER( TEX_ONLY( cmd ^ " ") )
|
||||
|
||||
| "\\acute"
|
||||
| "\\bar"
|
||||
| "\\bcancel"
|
||||
| "\\bmod"
|
||||
| "\\boldsymbol"
|
||||
| "\\breve"
|
||||
| "\\cancel"
|
||||
| "\\check"
|
||||
| "\\ddot"
|
||||
| "\\dot"
|
||||
| "\\emph"
|
||||
| "\\grave"
|
||||
| "\\hat"
|
||||
| "\\mathbb"
|
||||
| "\\mathbf"
|
||||
| "\\mathbin"
|
||||
| "\\mathcal"
|
||||
| "\\mathclose"
|
||||
| "\\mathfrak"
|
||||
| "\\mathit"
|
||||
| "\\mathop"
|
||||
| "\\mathopen"
|
||||
| "\\mathord"
|
||||
| "\\mathpunct"
|
||||
| "\\mathrel"
|
||||
| "\\mathrm"
|
||||
| "\\mathsf"
|
||||
| "\\mathtt"
|
||||
| "\\operatorname"
|
||||
| "\\overleftarrow"
|
||||
| "\\overleftrightarrow"
|
||||
| "\\overline"
|
||||
| "\\overrightarrow"
|
||||
| "\\pmod"
|
||||
| "\\sqrt"
|
||||
| "\\textbf"
|
||||
| "\\textit"
|
||||
| "\\textrm"
|
||||
| "\\textsf"
|
||||
| "\\texttt"
|
||||
| "\\tilde"
|
||||
| "\\underline"
|
||||
| "\\vec"
|
||||
| "\\widehat"
|
||||
| "\\widetilde"
|
||||
| "\\xcancel"
|
||||
| "\\xleftarrow"
|
||||
| "\\xrightarrow"
|
||||
-> FUN_AR1( cmd ^ " " )
|
||||
|
||||
| "\\binom"
|
||||
| "\\cancelto"
|
||||
| "\\cfrac"
|
||||
| "\\dbinom"
|
||||
| "\\dfrac"
|
||||
| "\\frac"
|
||||
| "\\overset"
|
||||
| "\\stackrel"
|
||||
| "\\tbinom"
|
||||
| "\\tfrac"
|
||||
| "\\underset"
|
||||
-> FUN_AR2( cmd ^ " " )
|
||||
| "\\atop"
|
||||
| "\\choose"
|
||||
| "\\over"
|
||||
-> FUN_INFIX( cmd ^ " " )
|
||||
|
||||
| "\\AA"
|
||||
| "\\Coppa"
|
||||
| "\\coppa"
|
||||
| "\\Digamma"
|
||||
| "\\euro"
|
||||
| "\\geneuro"
|
||||
| "\\geneuronarrow"
|
||||
| "\\geneurowide"
|
||||
| "\\Koppa"
|
||||
| "\\koppa"
|
||||
| "\\officialeuro"
|
||||
| "\\Sampi"
|
||||
| "\\sampi"
|
||||
| "\\Stigma"
|
||||
| "\\stigma"
|
||||
| "\\textvisiblespace"
|
||||
| "\\varstigma"
|
||||
-> LITERAL ( TEX_ONLY( "\\mbox{" ^ cmd ^ "} " ) )
|
||||
|
||||
| "\\C" -> LITERAL ( TEX_ONLY( "\\mathbb{C}" ^ " " ) )
|
||||
| "\\H" -> LITERAL ( TEX_ONLY( "\\mathbb{H}" ^ " " ) )
|
||||
| "\\N" -> LITERAL ( TEX_ONLY( "\\mathbb{N}" ^ " " ) )
|
||||
| "\\Q" -> LITERAL ( TEX_ONLY( "\\mathbb{Q}" ^ " " ) )
|
||||
| "\\R" -> LITERAL ( TEX_ONLY( "\\mathbb{R}" ^ " " ) )
|
||||
| "\\Z" -> LITERAL ( TEX_ONLY( "\\mathbb{Z}" ^ " " ) )
|
||||
|
||||
| "\\darr" -> DELIMITER( TEX_ONLY( "\\downarrow" ^ " " ) )
|
||||
| "\\dArr" -> DELIMITER( TEX_ONLY( "\\Downarrow" ^ " " ) )
|
||||
| "\\Darr" -> DELIMITER( TEX_ONLY( "\\Downarrow" ^ " " ) )
|
||||
| "\\lang" -> DELIMITER( TEX_ONLY( "\\langle" ^ " " ) )
|
||||
| "\\rang" -> DELIMITER( TEX_ONLY( "\\rangle" ^ " " ) )
|
||||
| "\\uarr" -> DELIMITER( TEX_ONLY( "\\uparrow" ^ " " ) )
|
||||
| "\\uArr" -> DELIMITER( TEX_ONLY( "\\Uparrow" ^ " " ) )
|
||||
| "\\Uarr" -> DELIMITER( TEX_ONLY( "\\Uparrow" ^ " " ) )
|
||||
|
||||
| "\\Bbb" -> FUN_AR1( "\\mathbb" ^ " " )
|
||||
| "\\bold" -> FUN_AR1( "\\mathbf" ^ " " )
|
||||
|
||||
| "\\alef" -> LITERAL ( TEX_ONLY( "\\aleph" ^ " " ) )
|
||||
| "\\alefsym" -> LITERAL ( TEX_ONLY( "\\aleph" ^ " " ) )
|
||||
| "\\Alpha" -> LITERAL ( TEX_ONLY( "\\mathrm{A}" ^ " " ) )
|
||||
| "\\and" -> LITERAL ( TEX_ONLY( "\\land" ^ " " ) )
|
||||
| "\\ang" -> LITERAL ( TEX_ONLY( "\\angle" ^ " " ) )
|
||||
| "\\Beta" -> LITERAL ( TEX_ONLY( "\\mathrm{B}" ^ " " ) )
|
||||
| "\\bull" -> LITERAL ( TEX_ONLY( "\\bullet" ^ " " ) )
|
||||
| "\\Chi" -> LITERAL ( TEX_ONLY( "\\mathrm{X}" ^ " " ) )
|
||||
| "\\clubs" -> LITERAL ( TEX_ONLY( "\\clubsuit" ^ " " ) )
|
||||
| "\\cnums" -> LITERAL ( TEX_ONLY( "\\mathbb{C}" ^ " " ) )
|
||||
| "\\Complex" -> LITERAL ( TEX_ONLY( "\\mathbb{C}" ^ " " ) )
|
||||
| "\\Dagger" -> LITERAL ( TEX_ONLY( "\\ddagger" ^ " " ) )
|
||||
| "\\diamonds" -> LITERAL ( TEX_ONLY( "\\diamondsuit" ^ " " ) )
|
||||
| "\\Doteq" -> LITERAL ( TEX_ONLY( "\\doteqdot" ^ " " ) )
|
||||
| "\\doublecap" -> LITERAL ( TEX_ONLY( "\\Cap" ^ " " ) )
|
||||
| "\\doublecup" -> LITERAL ( TEX_ONLY( "\\Cup" ^ " " ) )
|
||||
| "\\empty" -> LITERAL ( TEX_ONLY( "\\emptyset" ^ " " ) )
|
||||
| "\\Epsilon" -> LITERAL ( TEX_ONLY( "\\mathrm{E}" ^ " " ) )
|
||||
| "\\Eta" -> LITERAL ( TEX_ONLY( "\\mathrm{H}" ^ " " ) )
|
||||
| "\\exist" -> LITERAL ( TEX_ONLY( "\\exists" ^ " " ) )
|
||||
| "\\ge" -> LITERAL ( TEX_ONLY( "\\geq" ^ " " ) )
|
||||
| "\\gggtr" -> LITERAL ( TEX_ONLY( "\\ggg" ^ " " ) )
|
||||
| "\\hAar" -> LITERAL ( TEX_ONLY( "\\Leftrightarrow" ^ " " ) )
|
||||
| "\\harr" -> LITERAL ( TEX_ONLY( "\\leftrightarrow" ^ " " ) )
|
||||
| "\\Harr" -> LITERAL ( TEX_ONLY( "\\Leftrightarrow" ^ " " ) )
|
||||
| "\\hearts" -> LITERAL ( TEX_ONLY( "\\heartsuit" ^ " " ) )
|
||||
| "\\image" -> LITERAL ( TEX_ONLY( "\\Im" ^ " " ) )
|
||||
| "\\infin" -> LITERAL ( TEX_ONLY( "\\infty" ^ " " ) )
|
||||
| "\\Iota" -> LITERAL ( TEX_ONLY( "\\mathrm{I}" ^ " " ) )
|
||||
| "\\isin" -> LITERAL ( TEX_ONLY( "\\in" ^ " " ) )
|
||||
| "\\Kappa" -> LITERAL ( TEX_ONLY( "\\mathrm{K}" ^ " " ) )
|
||||
| "\\larr" -> LITERAL ( TEX_ONLY( "\\leftarrow" ^ " " ) )
|
||||
| "\\Larr" -> LITERAL ( TEX_ONLY( "\\Leftarrow" ^ " " ) )
|
||||
| "\\lArr" -> LITERAL ( TEX_ONLY( "\\Leftarrow" ^ " " ) )
|
||||
| "\\le" -> LITERAL ( TEX_ONLY( "\\leq" ^ " " ) )
|
||||
| "\\lrarr" -> LITERAL ( TEX_ONLY( "\\leftrightarrow" ^ " " ) )
|
||||
| "\\Lrarr" -> LITERAL ( TEX_ONLY( "\\Leftrightarrow" ^ " " ) )
|
||||
| "\\lrArr" -> LITERAL ( TEX_ONLY( "\\Leftrightarrow" ^ " " ) )
|
||||
| "\\Mu" -> LITERAL ( TEX_ONLY( "\\mathrm{M}" ^ " " ) )
|
||||
| "\\natnums" -> LITERAL ( TEX_ONLY( "\\mathbb{N}" ^ " " ) )
|
||||
| "\\ne" -> LITERAL ( TEX_ONLY( "\\neq" ^ " " ) )
|
||||
| "\\Nu" -> LITERAL ( TEX_ONLY( "\\mathrm{N}" ^ " " ) )
|
||||
| "\\O" -> LITERAL ( TEX_ONLY( "\\emptyset" ^ " " ) )
|
||||
| "\\omicron" -> LITERAL ( TEX_ONLY( "\\mathrm{o}" ^ " " ) )
|
||||
| "\\Omicron" -> LITERAL ( TEX_ONLY( "\\mathrm{O}" ^ " " ) )
|
||||
| "\\or" -> LITERAL ( TEX_ONLY( "\\lor" ^ " " ) )
|
||||
| "\\part" -> LITERAL ( TEX_ONLY( "\\partial" ^ " " ) )
|
||||
| "\\plusmn" -> LITERAL ( TEX_ONLY( "\\pm" ^ " " ) )
|
||||
| "\\rarr" -> LITERAL ( TEX_ONLY( "\\rightarrow" ^ " " ) )
|
||||
| "\\Rarr" -> LITERAL ( TEX_ONLY( "\\Rightarrow" ^ " " ) )
|
||||
| "\\rArr" -> LITERAL ( TEX_ONLY( "\\Rightarrow" ^ " " ) )
|
||||
| "\\real" -> LITERAL ( TEX_ONLY( "\\Re" ^ " " ) )
|
||||
| "\\reals" -> LITERAL ( TEX_ONLY( "\\mathbb{R}" ^ " " ) )
|
||||
| "\\Reals" -> LITERAL ( TEX_ONLY( "\\mathbb{R}" ^ " " ) )
|
||||
| "\\restriction" -> LITERAL ( TEX_ONLY( "\\upharpoonright" ^ " " ) )
|
||||
| "\\Rho" -> LITERAL ( TEX_ONLY( "\\mathrm{P}" ^ " " ) )
|
||||
| "\\sdot" -> LITERAL ( TEX_ONLY( "\\cdot" ^ " " ) )
|
||||
| "\\sect" -> LITERAL ( TEX_ONLY( "\\S" ^ " " ) )
|
||||
| "\\spades" -> LITERAL ( TEX_ONLY( "\\spadesuit" ^ " " ) )
|
||||
| "\\sub" -> LITERAL ( TEX_ONLY( "\\subset" ^ " " ) )
|
||||
| "\\sube" -> LITERAL ( TEX_ONLY( "\\subseteq" ^ " " ) )
|
||||
| "\\supe" -> LITERAL ( TEX_ONLY( "\\supseteq" ^ " " ) )
|
||||
| "\\Tau" -> LITERAL ( TEX_ONLY( "\\mathrm{T}" ^ " " ) )
|
||||
| "\\thetasym" -> LITERAL ( TEX_ONLY( "\\vartheta" ^ " " ) )
|
||||
| "\\varcoppa" -> LITERAL ( TEX_ONLY( "\\mbox{\\coppa}" ^ " " ) )
|
||||
| "\\weierp" -> LITERAL ( TEX_ONLY( "\\wp" ^ " " ) )
|
||||
| "\\Zeta" -> LITERAL ( TEX_ONLY( "\\mathrm{Z}" ^ " " ) )
|
||||
|
||||
| "\\rm"
|
||||
| "\\it"
|
||||
| "\\cal"
|
||||
| "\\bf"
|
||||
-> DECLh ( cmd ^ " ", FONTFORCE_RM ) (* see bug 54818 *)
|
||||
|
||||
| "\\overbrace" -> FUN_AR1nb "\\overbrace "
|
||||
| "\\underbrace" -> FUN_AR1nb "\\underbrace "
|
||||
| "\\sideset" -> FUN_AR2nb "\\sideset "
|
||||
| "\\left" -> LEFT
|
||||
| "\\right" -> RIGHT
|
||||
|
||||
| "\\text"
|
||||
| "\\mbox"
|
||||
| "\\vbox"
|
||||
| "\\hbox"
|
||||
-> raise (Failure ("malformatted " ^ cmd))
|
||||
|
||||
| s -> raise (Illegal_tex_function s)
|
||||
|
||||
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
(* vim: set sw=8 ts=8 et: *)
|
||||
exception LexerException of string
|
||||
|
||||
(* *)
|
||||
let lexer_token_safe lexbuf =
|
||||
try Lexer.token lexbuf
|
||||
with Failure s -> raise (LexerException s)
|
||||
|
||||
(* *)
|
||||
let render tree =
|
||||
let outtex = Util.mapjoin Texutil.render_tex tree in
|
||||
begin
|
||||
print_string ("+" ^ outtex);
|
||||
end
|
||||
|
||||
(* TODO: document
|
||||
* Arguments:
|
||||
* 1st : tex input string
|
||||
*
|
||||
* Output one character:
|
||||
* E : Lexer exception raised
|
||||
* F : TeX function not recognized
|
||||
* S : Parsing error
|
||||
* - : Generic/Default failure code. Might be an invalid argument,
|
||||
* output file already exist, a problem with an external
|
||||
* command ...
|
||||
*)
|
||||
let _ =
|
||||
try render (
|
||||
Parser.tex_expr lexer_token_safe (
|
||||
Lexing.from_string Sys.argv.(1))
|
||||
)
|
||||
with Parsing.Parse_error -> print_string "S"
|
||||
| LexerException _ -> print_string "E"
|
||||
| Texutil.Illegal_tex_function s -> print_string ("F" ^ s)
|
||||
| Invalid_argument _ -> print_string "-"
|
||||
| Failure _ -> print_string "-"
|
||||
| _ -> print_string "-"
|
|
@ -1,9 +0,0 @@
|
|||
(* vim: set sw=8 ts=8 et: *)
|
||||
|
||||
(* TODO document *)
|
||||
let mapjoin f l = (List.fold_left (fun a b -> a ^ (f b)) "" l)
|
||||
|
||||
(* TODO document *)
|
||||
let mapjoine e f = function
|
||||
[] -> ""
|
||||
| h::t -> (List.fold_left (fun a b -> a ^ e ^ (f b)) (f h) t)
|
Loading…
Reference in New Issue