LaTeX and TikZ
现有插件的情况
目前我已经尝试过PGFTikZ, mathtex, texvc等诸多插件,但都不能用,或是版本过旧,或是不支持一些代码。 但https://www.mediawiki.org/wiki/MediaWiki_and_LaTeX_on_a_host_with_shell_access 给了我一些启发,或许自己编写插件是可行的。
上述链接中,所需的插件需要完成的功能有:
- 使用hook功能,提取目标标签中的内容
- 将提取的内容写入到.tex文件中
- 将.tex文件编译,得到对应的输出(pdf或dvi)
- 将输出文件转换为图像(如png和svg)
- 将图像命名,并返回一个链接,使图像能够在页面上显示
后台软件支持的安装
经测试,latex命令似乎不能编译所需要的(例如含tikz代码的).tex文件,而pdflatex命令可以,因此使用pdflatex。它生成的文件格式是pdf,因此还需要将pdf装成png。
首先安装texlive,为节省磁盘空间和加快安装速度,经测试安装一个最基本的版本与一些扩展包即可。使用以下命令进行安装
- $ apt-get install texlive-latex-base
- $ apt-get install texlive-latex-extra
如果想要比较方便地测试,也可以安装图形化的编辑器texmaker
- $ apt-get install texmaker
其中texlive-latex-base和texlive-latex-extra加在一起不到1GB(对于全新的系统),texmaker不到150MB,比起texlive-full的超过2GB的大小算是比较小的了。
(可选)使用texmaker进行测试,输入一段比较简单的、含有tikz的代码,例如
\documentclass[tikz]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw (0,0) -- (1,1);
\end{tikzpicture}
\end{document}
在编译方式中需要选择PDFLaTeX,查看方式选择View PDF即可。编译并查看,效果如下
但是如果使用LaTeX的编译方式,则会出错。这可能是之前一直失败的原因之一。
接下来切换到命令行,编写一个.tex文件,例如叫test.tex,使用命令
- $ pdflatex test.tex
进行编译,如果编译成功,则会得到一个test.pdf文件。
接下来就需要将pdf转换为png图像,在此使用ImageMagick(IM)进行转换,Ubuntu系统默认是自带这个软件的,对应的命令是convert。 但是系统在默认状态下是不可以直接使用的,会报convert-im6.q16: not authorized错误。需要先进行一些设置。 编辑/etc/ImageMagick-6/policy.xml文件,找到行
- <policy domain="coder" rights="none" pattern="PDF" />
将其修改为
- <policy domain="coder" rights="read|write" pattern="PDF" />
- <policy domain="coder" rights="read|write" pattern="LABEL" />
其作用是给pdf和png文件加上读写权限。修改完成后,使用
- $ convert File1.pdf File2.png
即可完成pdf到png的转换。该命令还可以加一些参数,例如
- $ convert -density 300 -quality 300 File1.pdf File2.png
可以设定期望的图像质量和分辨率。
至此,后台的准备已经完成,要使用该功能,只需要以下操作
- 完成.tex文件的编辑,例如保存为main.tex
- 编译.tex文件,使用命令
- $ pdflatex main.tex
- 此时已经生成main.pdf文件(如果编译成功的话),再使用以下命令将其转换为png图像
- $ convert -density 300 -quality 300 main.pdf main.png
- 最后根据需要将main.png复制至需要的路径即可
插件的编写
mathtex的示例
调用mathtex的插件代码如下
<?php
$wgExtensionFunctions[] = "wfMtag";
function wfMtag() {
global $wgParser;
$wgParser->setHook( "m", "returnMtagged" ); #里面的m是可供调用的标签名,是可以改的
}
function returnMtagged( $code, $argv)
{
$txt='<img src="/cgi-bin/mathtex.cgi?'.$code.'">'; #这里使用了cgi程序来生成图像
return $txt;
}
?>
调用这个插件只需要在LocalSettings.php中添加一行
- include './extensions/my_tag.php';
之后即可使用<m></m>标签调用该功能(这个标签名是可以改的)。
插件基本功能的编写
因为php本身就可以调用外部命令,因此就不再需要额外编写cgi程序了。在extensions目录中新建一个文件夹,例如称作FreeTex(因为这个插件的目的就是实现让用户直接输入tex代码),在创建FreeTex.php,在其中写入
<?php
$wgExtensionFunctions[] = "wfFreeTex";
function wfFreeTex() {
global $wgParser;
$wgParser->setHook("tex", "returnTexImg");
}
function returnTexImg($code, $argv) {
$hash=md5($code);
file_put_contents($hash.".tex", $code);
$cmd_gen="pdflatex ".$hash.".tex";
$cmd_cvt="convert -quality 100 -density 100 ".$hash.".pdf /xlp_data/images/teximg/".$hash.".png";
exec($cmd_gen);
exec($cmd_cvt);
exec("rm ".$hash.".aux");
exec("rm ".$hash.".pdf");
exec("rm ".$hash.".tex");
exec("rm ".$hash.".log");
$url_return='<img src="/images/teximg/'.$hash.'.png">';
return $url_return;
}
?>
以上代码主要流程如下:
- 提取标签中的tex代码,取其md5码作为储存的文件名(可以防止随便取名字造成的文件名冲突,以及相同代码造成的文件名重复)
- 将代码写入一个临时的.tex文件中
- 调用pdflatex命令对临时.tex文件进行编译,生成.pdf文件(如果编译成功的话)
- 将.pdf文件转换为.png图片,并储存到专门的图像文件夹中(/xlp_data/images/teximg)
- 删除所有的临时文件
- 生成一个指向该文件的<img>标签,并返回给wiki,显示在网页上
调用时,在LocalSettings.php中添加
- include '/xlp_dev/extensions/FreeTex/FreeTex.php';
一些额外功能
以上代码只实现了最基本的编译和显示功能,并没有涉及自动显示报错信息、合并多张图像(因为有时候可能会生成有多页的pdf)的附加功能。这些功能可以按需求继续添加。
其中,显示报错信息的功能可以利用exec()函数的返回值来实现。合并多张图像可能不是必要的,因为可以在编写代码时就控制只生成一页(有相关的代码)。
另外,以上代码只使用了$code的参数,还有$argv参数为使用。如果使用,可以完成诸如自定义图像尺寸、DPI等操作。