structure TeXEngine : sig type engine_type type run_options = { engine_executable : string option , halt_on_error : bool , interaction : InteractionMode.interaction option , file_line_error : bool , synctex : string option , shell_escape : ShellEscape.shell_escape option , jobname : string option , output_directory : string option , extra_options : string list , output_format : OutputFormat.format , draftmode : bool (* pdfTeX / XeTeX / LuaTeX *) , fmt : string option , lua_initialization_script : string option (* LuaTeX only *) } type engine = { name : string , executable : string , supports_pdf_generation : bool , dvi_extension : string , supports_draftmode : bool , engine_type : engine_type } val isLuaTeX : engine -> bool val isPdfTeX : engine -> bool val isXeTeX : engine -> bool val buildCommand : engine * string * run_options -> string val get : string -> engine option end = struct datatype engine_type = PDFTEX | XETEX | LUATEX | OTHER type run_options = { engine_executable : string option , halt_on_error : bool , interaction : InteractionMode.interaction option , file_line_error : bool , synctex : string option , shell_escape : ShellEscape.shell_escape option , jobname : string option , output_directory : string option , extra_options : string list , output_format : OutputFormat.format , draftmode : bool (* pdfTeX / XeTeX / LuaTeX *) , fmt : string option , lua_initialization_script : string option (* LuaTeX only *) } type engine = { name : string , executable : string , dvi_extension : string , supports_pdf_generation : bool , supports_draftmode : bool , engine_type : engine_type } fun isLuaTeX ({ engine_type, ... } : engine) = engine_type = LUATEX fun isPdfTeX ({ engine_type, ... } : engine) = engine_type = PDFTEX fun isXeTeX ({ engine_type, ... } : engine) = engine_type = XETEX fun buildCommand (engine : engine, inputline, options : run_options) = let val executable = Option.getOpt (#engine_executable options, #executable engine) val revCommand = ["-recorder", executable] val revCommand = case #fmt options of NONE => revCommand | SOME fmt => "-fmt=" ^ fmt :: revCommand val revCommand = case #halt_on_error options of false => revCommand | true => "-halt-on-error" :: revCommand val revCommand = case #interaction options of NONE => revCommand | SOME mode => "-interaction=" ^ InteractionMode.toString mode :: revCommand val revCommand = case #file_line_error options of false => revCommand | true => "-file-line-error" :: revCommand val revCommand = case #synctex options of NONE => revCommand | SOME synctex => "-synctex=" ^ ShellUtil.escape synctex :: revCommand val revCommand = case #shell_escape options of NONE => revCommand | SOME ShellEscape.FORBIDDEN => "-no-shell-escape" :: revCommand | SOME ShellEscape.RESTRICTED => "-shell-restricted" :: revCommand | SOME ShellEscape.ALLOWED => "-shell-escape" :: revCommand val revCommand = case #jobname options of NONE => revCommand | SOME jobname => "-jobname=" ^ ShellUtil.escape jobname :: revCommand val revCommand = case #output_directory options of NONE => revCommand | SOME dir => "-output-directory=" ^ ShellUtil.escape dir :: revCommand val revCommand = case #engine_type engine of OTHER => revCommand | PDFTEX => let val revCommand = if #draftmode options then "-draftmode" :: revCommand else revCommand in case #output_format options of OutputFormat.DVI => "-output-format=dvi" :: revCommand | OutputFormat.PDF => revCommand end | XETEX => if #draftmode options orelse #output_format options = OutputFormat.DVI then "-no-pdf" :: revCommand else revCommand | LUATEX => let val revCommand = case #lua_initialization_script options of NONE => revCommand | SOME script => "--lua=" ^ ShellUtil.escape script :: revCommand val revCommand = if #draftmode options then "--draftmode" :: revCommand else revCommand in case #output_format options of OutputFormat.DVI => "--output-format=dvi" :: revCommand | OutputFormat.PDF => revCommand end val revCommand = List.revAppend (#extra_options options, revCommand) val revCommand = ShellUtil.escape inputline :: revCommand in String.concatWith " " (List.rev revCommand) end val pdftex_or_pdflatex = { supports_pdf_generation = true , dvi_extension = "dvi" , supports_draftmode = true , engine_type = PDFTEX } val pdftex : engine = { name = "pdftex", executable = "pdftex", ... = pdftex_or_pdflatex } val pdflatex : engine = { name = "pdflatex", executable = "pdflatex", ... = pdftex_or_pdflatex } val luatex_or_lualatex = { supports_pdf_generation = true , dvi_extension = "dvi" , supports_draftmode = true , engine_type = LUATEX } val luatex : engine = { name = "luatex", executable = "luatex", ... = luatex_or_lualatex } val lualatex : engine = { name = "lualatex", executable = "lualatex", ... = luatex_or_lualatex } val luajittex : engine = { name = "luajittex", executable = "luajittex", ... = luatex_or_lualatex } val xetex_or_xelatex = { supports_pdf_generation = true , dvi_extension = "xdv" , supports_draftmode = true , engine_type = XETEX } val xetex : engine = { name = "xetex", executable = "xetex", ... = xetex_or_xelatex } val xelatex : engine = { name = "xelatex", executable = "xelatex", ... = xetex_or_xelatex } val other_engine = { supports_pdf_generation = false , dvi_extension = "dvi" , supports_draftmode = false , engine_type = OTHER } val tex : engine = { name = "tex", executable = "tex", ... = other_engine } val etex : engine = { name = "etex", executable = "etex", ... = other_engine } val latex : engine = { name = "latex", executable = "latex", ... = other_engine } val ptex : engine = { name = "ptex", executable = "ptex", ... = other_engine } val eptex : engine = { name = "eptex", executable = "eptex", ... = other_engine } val platex : engine = { name = "platex", executable = "platex", ... = other_engine } val uptex : engine = { name = "uptex", executable = "uptex", ... = other_engine } val euptex : engine = { name = "euptex", executable = "euptex", ... = other_engine } val uplatex : engine = { name = "uplatex", executable = "uplatex", ... = other_engine } fun get "pdftex" = SOME pdftex | get "pdflatex" = SOME pdflatex | get "luatex" = SOME luatex | get "lualatex" = SOME lualatex | get "luajittex" = SOME luajittex | get "xetex" = SOME xetex | get "xelatex" = SOME xelatex | get "tex" = SOME tex | get "etex" = SOME etex | get "latex" = SOME latex | get "ptex" = SOME ptex | get "eptex" = SOME eptex | get "platex" = SOME platex | get "uptex" = SOME uptex | get "euptex" = SOME euptex | get "uplatex" = SOME uplatex | get _ = NONE end;