[Tex/LaTex] Compile Tex inside Microsoft C#.net

pdftextex-core

I know there are some command-line applications like pdflatex that can help me to compile a LaTex document from C#.Net (using the System.Diagnostics.Process class) .

I wanna know that what's the best command-line tool for compiling a TeX document ?

Best Answer

So we meet again, C#. :)

It's not so easy for to provide an answer, but I'll try.

Most of the time, we end up with complex documents which might require several runs in order to reach a steady state. So, it's likely you'll need more than one run to get the correct output.

If you stick with the engines like pdflatex, you'll probably need to ensure the miminal amount of calls to it and/or other helper programs (e.g, makeindex). That might be a burden, specially when you don't know the steps in advance.

Tools like latexmk and rubber were created to ease the compilation process in the sense of trying to guess if your document needs another run, or calling other programs. They even give up on compilation if you have a document which will never reach a steady state. So, they might make your life easier. But of course we have the human factor. :) Those tools might not work as expected (e.g, rubber doesn't recognize biber), so you might need to end up tuning those tools with configuration files or directives.

And now there's arara, a humble project of mine (sorry for the shameless self-promotion). This tool is different from latexmk and rubber because, well, it will execute only what you tell it to. There's no guessing, no auxiliary file parsing or other cool stuff. By adding directives to the source code, (e.g, % arara: pdflatex: { shell: yes }, arara will expand those instructions based on well defined rules to commands and then execute them. It might be powerful if you really know what it's going on in the bowels of your engine, otherwise it might be difficult to digest the concept. The project is still in heavy development, thanks to the great contributions of Marco Daniel (project collaborator) and Joseph Wright.

Now, back to your question. :)

It would be great if you tell us about your C# application. Sometimes, based on your needs, a more reliable solution is available. For example, Forgiver's answer is an interesting way of calling pdflatex. If you need a more generic configuration, you could use something among these lines:

using System;
using System.Xml;
using System.Diagnostics;

namespace MyProgram
{
    class MyTeXWrapper
    {
        static void Main(string[] args)
        {

            if (args.Length != 2)
            {
                Console.WriteLine("Sorry, I expect 2 arguments.");
                System.Environment.Exit(-1);
            }

            string command = "";
            string arguments = "";

            try
            {

                XmlDocument document = new XmlDocument();
                document.Load(args[1]);
                XmlElement rootElement = document.DocumentElement;
                XmlNodeList nodes = rootElement.ChildNodes;
                foreach (XmlNode node in nodes)
                {
                    if (node.Name.Equals("command"))
                    {
                        command = node.InnerText;
                    }
                    else
                    {
                        if (node.Name.Equals("arg"))
                        {
                            if (node.Attributes.Count == 1)
                            {
                                if (node.Attributes.Item(0).Name.Equals("value"))
                                {
                                    arguments = arguments + node.Attributes.Item(0).Value + " ";
                                }
                            }
                        }
                    }

                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            arguments = arguments + args[0];

            Process process = new Process();
            process.StartInfo.FileName = command;
            process.StartInfo.Arguments = arguments;
            process.StartInfo.UseShellExecute = false;
            process.Start();
            process.WaitForExit();
            if (process.ExitCode == 0)
            {
                Console.WriteLine("Command was successfully executed.");
            }
            else
            {
                Console.WriteLine("An error occurred.");
            }
        }
    }
}

The idea is to have a XML-based configuration file which will determine how the command should be invoked. A sample configuration file:

<configuration>
    <command>pdflatex</command>
    <arg value="--interaction=nonstopmode"/>
    <arg value="--shell-escape"/>
</configuration>

Consider the following tex file:

\documentclass{article}

\begin{document}

Hello world!

\end{document}

Now, I can run my code with MyProgram.exe hello config.xml:

Program output

I use Mono. :)

Note that I used --interaction=nonstopmode as an argument. Depending of how your application should behave, having interactive commands might be a problem. For example, if our tex code above had a syntax typo, and without --interaction=nonstopmode, pdflatex would prompt you a message and wait for your input. For arara I redirected the output streams (stdout and stderr) to separated threads, but I'm still struggling with the input stream (stdin). As an example, TeXworks can prompt an input box if the program requires interaction:

TeXworks

Thankfully the TeX programs provide exit status, so you can check if the run was successful. If you have a very complex document, maybe it's wise to create a worker thread and let it handle the call, avoiding blocking your application (David mentioned in the chatroom that Frank's book took about 20 minutes to compile). :)

Now, which tool is the best? I have absolutely no idea. :) My thoughts: if you want to have more control on your workflow, stick with the original command line programs. Now, flexibility and ease to use are keywords here, give latexmk or rubber a try. :)

Related Question