structure CheckDriver: sig datatype driver = DVIPDFMX | DVIPS | DVISVGM | PDFTEX | XETEX | LUATEX val checkDriver: driver * {kind: string, path: string} list -> unit end = struct datatype driver = DVIPDFMX | DVIPS | DVISVGM | PDFTEX | XETEX | LUATEX fun toString DVIPDFMX = "dvipdfmx" | toString DVIPS = "dvips" | toString DVISVGM = "dvisvgm" | toString PDFTEX = "pdftex" | toString XETEX = "xetex" | toString LUATEX = "luatex" structure graphics = struct datatype driver = DVIPDFMX | DVIPS | DVISVGM | PDFTEX | XETEX | LUATEX | UNKNOWN fun toString DVIPDFMX = "dvipdfmx" | toString DVIPS = "dvips" | toString DVISVGM = "dvisvgm" | toString PDFTEX = "pdftex" | toString XETEX = "xetex" | toString LUATEX = "luatex" | toString UNKNOWN = "unknown" end structure expl3 = struct datatype driver = PDFMODE | DVISVGM | XDVIPDFMX | DVIPDFMX | DVIPS | PDFTEX | LUATEX | XETEX | UNKNOWN fun toString PDFMODE = "pdfmode" | toString DVISVGM = "dvisvgm" | toString XDVIPDFMX = "xdvipdfmx" | toString DVIPDFMX = "dvipdfmx" | toString DVIPS = "dvips" | toString PDFTEX = "pdftex" | toString LUATEX = "luatex" | toString XETEX = "xetex" | toString UNKNOWN = "unknown" end structure hyperref = struct datatype driver = DVIPDFMX | DVIPS | PDFTEX | LUATEX | XETEX | UNKNOWN fun toString DVIPDFMX = "dvipdfmx" | toString DVIPS = "dvips" | toString PDFTEX = "pdftex" | toString LUATEX = "luatex" | toString XETEX = "xetex" | toString UNKNOWN = "unknown" end structure xypic = struct datatype driver = PDF | DVIPS | UNKNOWN fun toString PDF = "pdf" | toString DVIPS = "dvips" | toString UNKNOWN = "unknown" end (*: val correctDrivers : driver -> { graphics : graphics.driver, expl3_old : expl3.driver, expl3_new : expl3.driver, hyperref : hyperref.driver option, xypic : xypic.driver option } *) fun correctDrivers DVIPS = { graphics = graphics.DVIPS , expl3_old = expl3.DVIPS , expl3_new = expl3.DVIPS , hyperref = SOME hyperref.DVIPS , xypic = SOME xypic.DVIPS } | correctDrivers DVIPDFMX = { graphics = graphics.DVIPDFMX , expl3_old = expl3.DVIPDFMX , expl3_new = expl3.DVIPDFMX , hyperref = SOME hyperref.DVIPDFMX , xypic = SOME xypic.PDF } | correctDrivers DVISVGM = { graphics = graphics.DVISVGM , expl3_old = expl3.DVISVGM , expl3_new = expl3.DVISVGM , hyperref = NONE (* What to do? *) , xypic = NONE (* What to do? *) } | correctDrivers XETEX = { graphics = graphics.XETEX , expl3_old = expl3.XDVIPDFMX , expl3_new = expl3.XETEX , hyperref = SOME hyperref.XETEX , xypic = SOME xypic.PDF } | correctDrivers PDFTEX = { graphics = graphics.PDFTEX , expl3_old = expl3.PDFMODE , expl3_new = expl3.PDFTEX , hyperref = SOME hyperref.PDFTEX , xypic = SOME xypic.PDF } | correctDrivers LUATEX = { graphics = graphics.LUATEX , expl3_old = expl3.PDFMODE , expl3_new = expl3.LUATEX , hyperref = SOME hyperref.LUATEX , xypic = SOME xypic.PDF } fun checkDriver (expected_driver, filelist) = let val () = if Message.getVerbosity () >= 1 then Message.info ("checkdriver: expects " ^ toString expected_driver) else () val loadedSet = List.foldl (fn ({kind, path}, set) => if kind = "input" then StringSet.add (set, PathUtil.basename path) else set) StringSet.empty filelist fun loaded name = StringSet.member (loadedSet, name) val graphics_driver = if loaded "graphics.sty" orelse loaded "color.sty" then SOME (if loaded "dvipdfmx.def" then graphics.DVIPDFMX else if loaded "dvips.def" then graphics.DVIPS else if loaded "dvisvgm.def" then graphics.DVISVGM else if loaded "pdftex.def" then graphics.PDFTEX else if loaded "luatex.def" then graphics.LUATEX else if loaded "xetex.def" then graphics.XETEX else (* Not supported: dvipdf, dvipsone, emtex, textures, pctexps, pctexwin, pctexhp, pctex32, truetex, tcidvi, vtex *) graphics.UNKNOWN) else NONE val expl3_driver = if loaded "expl3-code.tex" orelse loaded "expl3.sty" orelse loaded "l3backend-dvips.def" orelse loaded "l3backend-dvipdfmx.def" orelse loaded "l3backend-xdvipdfmx.def" orelse loaded "l3backend-pdfmode.def" orelse loaded "l3backend-pdftex.def" orelse loaded "l3backend-luatex.def" orelse loaded "l3backend-xetex.def" then SOME (if loaded "l3backend-pdfmode.def" then expl3.PDFMODE else if loaded "l3backend-dvisvgm.def" then expl3.DVISVGM else if loaded "l3backend-xdvipdfmx.def" then expl3.XDVIPDFMX else if loaded "l3backend-dvipdfmx.def" then expl3.DVIPDFMX else if loaded "l3backend-dvips.def" then expl3.DVIPS else if loaded "l3backend-pdftex.def" then expl3.PDFTEX else if loaded "l3backend-luatex.def" then expl3.LUATEX else if loaded "l3backend-xetex.def" then expl3.XETEX else expl3.UNKNOWN) else NONE val hyperref_driver = if loaded "hyperref.sty" then SOME (if loaded "hluatex.def" then hyperref.LUATEX else if loaded "hpdftex.def" then hyperref.PDFTEX else if loaded "hxetex.def" then hyperref.XETEX else if loaded "hdvipdfm.def" then hyperref.DVIPDFMX else if loaded "hdvips.def" then hyperref.DVIPS else (* Not supported: dvipson, dviwind, tex4ht, texture, vtex, vtexhtm, xtexmrk, hypertex *) hyperref.UNKNOWN) else NONE val xypic_driver = if loaded "xy.tex" then SOME (if loaded "xypdf.tex" then xypic.PDF (* pdftex, luatex, xetex, dvipdfmx *) else if loaded "xydvips.tex" then xypic.DVIPS else xypic.UNKNOWN) else NONE val () = if Message.getVerbosity () >= 1 then ( Message.info ("checkdriver: graphics=" ^ (case graphics_driver of NONE => "not loaded" | SOME d => graphics.toString d)) ; Message.info ("checkdriver: expl3=" ^ (case expl3_driver of NONE => "not loaded" | SOME d => expl3.toString d)) ; Message.info ("checkdriver: hyperref=" ^ (case hyperref_driver of NONE => "not loaded" | SOME d => hyperref.toString d)) ; Message.info ("checkdriver: xypic=" ^ (case xypic_driver of NONE => "not loaded" | SOME d => xypic.toString d)) ) else () val { graphics = expected_graphics , expl3_old = expected_expl3_old , expl3_new = expected_expl3_new , hyperref = expected_hyperref , xypic = expected_xypic } = correctDrivers expected_driver in case graphics_driver of NONE => () | SOME d => if d <> expected_graphics then ( Message.diag "The driver option for grahipcs(x)/color is missing or wrong." ; Message.diag ("Consider setting '" ^ graphics.toString expected_graphics ^ "' option.") ) else (); case expl3_driver of NONE => () | SOME d => if d <> expected_expl3_old andalso d <> expected_expl3_new then ( Message.diag "The driver option for expl3 is missing or wrong." ; Message.diag ("Consider setting 'driver=" ^ expl3.toString expected_expl3_new ^ "' option when loading expl3.") ; if expected_expl3_old <> expected_expl3_new then Message.diag ("You might need to instead set 'driver=" ^ expl3.toString expected_expl3_old ^ "' if you are using an older version of expl3.") else () ) else (); case (hyperref_driver, expected_hyperref) of (SOME actual, SOME expected) => if actual <> expected then ( Message.diag "The driver option for hyperref is missing or wrong." ; Message.diag ("Consider setting '" ^ hyperref.toString expected ^ "' option.") ) else () | _ => (); case (xypic_driver, expected_xypic) of (SOME actual, SOME expected) => if actual <> expected then ( Message.diag "The driver option for Xy-pic is missing or wrong." ; case (expected_driver, expected) of (DVIPDFMX, _) => Message.diag "Consider setting 'dvipdfmx' option or running \\xyoption{pdf}." | (PDFTEX, _) => Message.diag "Consider setting 'pdftex' option or running \\xyoption{pdf}." | (_, xypic.PDF) => Message.diag "Consider setting 'pdf' package option or running \\xyoption{pdf}." | (_, xypic.DVIPS) => Message.diag "Consider setting 'dvips' option." | (_, xypic.UNKNOWN) => () ) else () | _ => () end end;