&1"),"pdftotext version")) error_exit("pdftotext not installed"); } function rrmdir($dir) { if (is_dir($dir)) { $files = scandir($dir); foreach ($files as $file) if ($file != "." && $file != "..") rrmdir("$dir/$file"); rmdir($dir); } else if (file_exists($dir)) unlink($dir); } function rcopy($src, $dst) { if (file_exists($dst)) rrmdir($dst); if (is_dir($src)) { mkdir($dst); $files = scandir($src); foreach ($files as $file) if ($file != "." && $file != "..") rcopy("$src/$file", "$dst/$file"); } else if (file_exists($src)) copy($src, $dst); } function rscandir($dir,$extensions = []) { $result = []; if (!str_ends_with($dir,"/")) $dir .= "/"; if (str_ends_with($dir,"latex.out/")) return $result; $array = scandir($dir); foreach ($array as $item) { if (!str_starts_with($item,".")) { if (!is_dir($dir.$item)) { $extension_match = true; if ($extensions != []) { $extension_match = false; foreach ($extensions as $e) { if (str_ends_with($item,"$e")) { $extension_match = true; } } } if ($extension_match) $result[] = $dir.$item; } else $result = array_merge($result, rscandir($dir.$item,$extensions)); } } return $result; } function unique_targets($targets) { $parts_required = 1; $unique_targets = []; while (count($unique_targets) != count($targets)) { foreach ($targets as $t) { $tparts = explode("/",$t); $tpcount = count($tparts); $tparts = array_splice($tparts,$tpcount-$parts_required,$parts_required); $t = implode("_",$tparts); if (isset($unique_targets[$t])) { $parts_required++; $unique_targets = []; break; } $unique_targets[$t] = 1; } } return array_keys($unique_targets); } function check_folders($argv) { $args = array_slice($argv,1); $sourcedirs = []; foreach ($args as $a) { if (!str_starts_with($a,"-")) $sourcedirs[] = $a; } if (count($sourcedirs) < 1) { error_exit("Too few papers. Need at least one paper to run this.",true); } if (count($sourcedirs) < 3) { echo "Warning: Too few papers. The statutes require as an absolute minimum for a cumulative thesis at least 3 first-author papers and at least 6 in total."; } if (count($sourcedirs) < 5) { echo "Warning: Few papers. Check your institute guidelines to see how many papers are recommended. Also the statutes require as an absolute minimum for a cumulative thesis at least 6 papers in total."; } $texfiles = []; for ($i = 0; $i < count($sourcedirs); $i++) { $texfiles[$i] = basename($sourcedirs[$i]); $sourcedirs[$i] = dirname($sourcedirs[$i]); } $targets = unique_targets($sourcedirs); return [$targets,$texfiles,$sourcedirs]; } function check_and_copy_folders($argv) { [$targets,$texfiles,$sourcedirs] = check_folders($argv); //echo "Source -> Target Directory Mapping:\n"; $n = count($sourcedirs); //print_r($mapping); for ($i = 0; $i < $n; $i++) { $s = $sourcedirs[$i]; $t = $targets[$i]; $f = $texfiles[$i]; if (str_ends_with($f,".pdf")) { if (!file_exists("$s/$f")) error_exit("$s/$f not found"); if (file_exists("$t/$f.pdf") && !user_consent("$t/$f.pdf already exists... overwrite?","--force-overwrite","--no-overwrite")) { echo "Skipping $s/$f, $t/$f.pdf already exists...\n"; } else { echo "Copying $s/$f to $t/$f...\n"; if (!file_exists($t)) mkdir($t); rcopy("$s/$f","$t/$f"); } } else { if (!file_exists($s)) error_exit("$s not found"); if (file_exists($t) && !user_consent("$t already exists... overwrite?","--force-overwrite","--no-overwrite")) { echo "Skipping ".$s.", ".$t." already exists...\n"; } else { echo "Copying ".$s." to ".$t."...\n"; rcopy($s,$t); } } } return array_combine($targets,$texfiles); } function file_get_and_backup($f,$bak = ".orig_bak") { global $options; if (isset($options["--use-backups"])) { if (file_exists("$f$bak")) copy("$f$bak", $f); } $content = file_get_contents("$f"); if (!file_exists("$f$bak")) file_put_contents("$f$bak",$content); return $content; } function adjust_references($papers,$extensions = []) { $bibresources = []; foreach ($papers as $d => $f) { if (str_ends_with($f,".pdf")) continue; $files = rscandir($d,$extensions); foreach ($files as $file) { if (str_ends_with($file,".bib")) { $bib = file_get_and_backup($file); $bib = preg_replace("/(^\s*@\s*[a-z]+\s*\{\s*)((?!$d)\S)/i",'${1}'.$d.':${2}',$bib); $bib = preg_replace("/(\n\s*@\s*[a-z]+\s*\{\s*)((?!$d)\S)/i",'${1}'.$d.':${2}',$bib); $bib = preg_replace("/([\{\"].*)[^\\\\]#(.*)/i",'${1}\#${2}',$bib); file_put_contents($file,$bib); $bibresources[$d] = $file; } else { $tex = file_get_and_backup($file); // labels of lstlistings etc $tex = preg_replace("/([\[,]\s*label\s*=\s*)((?!$d)[^\[,]+[\[,])/i",'${1}'.$d.':${2}',$tex); // normal labels $tex = preg_replace("/(\\\label\s*\{\s*)((?!$d)[^}]+\})/i",'${1}'.$d.':${2}',$tex); // cref ref autoref $refs = []; preg_match_all("/\\\(cref|ref|autoref)\s*\{\s*[^}]+\}/i",$tex,$refs); foreach ($refs[0] as $ref) { $oldref = $ref; $ref = preg_replace("/([{,])\s*((?!$d)[^,}]+[},])/i",'${1}'.$d.':${2}',$ref); $ref = preg_replace("/([{,])\s*((?!$d)[^,}]+[},])/i",'${1}'.$d.':${2}',$ref); $tex = str_replace($oldref,$ref,$tex); } // cite citeA citeauthor etc $cites = []; preg_match_all("/\\\([a-z]*cite[a-z]*)\s*\{\s*[^}]+\}/i",$tex,$cites); foreach ($cites[0] as $cite) { $oldcite = $cite; $cite = preg_replace("/([{,])\s*((?!$d)[^,}]+[},])/i",'${1}'.$d.':${2}',$cite); $cite = preg_replace("/([{,])\s*((?!$d)[^,}]+[},])/i",'${1}'.$d.':${2}',$cite); $tex = str_replace($oldcite,$cite,$tex); } file_put_contents($file,$tex); } } } return $bibresources; } function handle_appendix($tex) { $appendix = false; $lines = explode("\n",$tex); for ($i = 0; $i < count($lines); $i++) { if ($appendix) { $lines[$i] = str_replace(['\subsubsection','\subsection','\section'],['\paragraph','\subsubsection','\subsection'],$lines[$i]); } if (str_starts_with($lines[$i],'\appendices') || str_starts_with($lines[$i],'\appendix')) { $lines[$i] = '\section*{Appendix}'; $appendix = true; } } $tex = implode("\n",$lines); return $tex; } function stripformatting($tex) { return str_ireplace(['\Large ','\bf ','\rm ','\\\\'],[' ',' ',' ',' '],$tex); } function getusepackages($tex) { $packages = []; preg_match_all("/\n\s*(\\\\usepackage([^{}]*)(?{((?:[^{}]+|(?&R))*)}))/i",$tex,$packages); if (isset($packages[1])) { return [$packages[1],$packages[4]]; } return [[],[]]; } function getmathops($tex) { $mathops = []; preg_match_all("/\n\s*(\\\\DeclareMath(Operator|Alphabet)\\*?((?{((?:[^{}]+|(?&R))*)})([^{}]*)|\\\\[^\{]*)(?

{((?:[^{}]+|(?&P))*)})(?{((?:[^{}]+|(?&Q))*)})?(?{((?:[^{}]+|(?&S))*)})?(?{((?:[^{}]+|(?&T))*)})?)/i",$tex,$mathops); if (isset($mathops[4])) return [$mathops[1],$mathops[3]]; return []; } function getnewcommands($tex) { $newcommands = []; preg_match_all("/\n\s*(\\\\newcommand([^{}]*)(?{((?:[^{}]+|(?&R))*)})([^{}]*)(?

{((?:[^{}]+|(?&P))*)}))/i",$tex,$newcommands); if (isset($newcommands[4])) return $newcommands[4]; return []; } function adjust_papers($papers,$extensions = []) { $tex = ""; $paper_fulltitle = ""; $authors = ""; $institute = ""; foreach ($papers as $d => $f) { if (str_ends_with($f,".pdf")) { $paper_fulltitle = trim(user_prompt("Please enter the full title for the paper in folder '$d'","TODO")); $paper_shorttitle = trim(user_prompt("Please enter a short title for the paper in folder '$d'","TODO")); $authors = trim(user_prompt("Please enter the author list for paper '$d'","TODO")); $header=<<{((?:[^{}]+|(?&R))*)})/i",$tex,$authors); if (isset($authors[2]) && isset($authors[2][0])) $authors = trim(stripformatting($authors[2][0])); } if ($institute == "" && preg_match("/\n\s*\\\\institute/i",$tex) == 1) { preg_match_all("/\n\s*\\\\institute\s*(?{((?:[^{}]+|(?&R))*)})/i",$tex,$institute); if (isset($institute[2]) && isset($institute[2][0])) $institute = trim(stripformatting($institute[2][0])); } if ($paper_fulltitle == "" && preg_match("/\n\s*\\\\title/i",$tex) == 1) { preg_match_all("/\n\s*\\\\title\s*(?{((?:[^{}]+|(?&R))*)})/i",$tex,$title); if (isset($title[2]) && isset($title[2][0])) $title = trim(stripformatting($title[2][0])); else $title = $d; $shorttitle = $title; if (strpos($title,":") !== false) $shorttitle = trim(explode(":",$title)[0]); $paper_fulltitle = trim(user_prompt("Please enter the full title for the paper in folder '$d'","$title")); $paper_shorttitle = trim(user_prompt("Please enter a short title for the paper in folder '$d'","$shorttitle")); } $header = ""; if ($paper_fulltitle != "" && $authors != "") { $header=<< $v) { $preamble .= $mathopsfull[$k] . "\n"; $existing_mathops[] = $v; } $tex = preg_replace("/\\\documentclass.*\\n/i"," ",$tex); $tex = preg_replace("/\\\begin{document}/i",$header,$tex); $tex = preg_replace("/\\\begin{abstract}/i",'\section*{Abstract}',$tex); $tex = preg_replace("/\\\\newcommand/i",'\providecommand',$tex); $tex = preg_replace("/\\\\renewcommand/i",'\providecommand',$tex); $tex = preg_replace("/\\\\end{abstract}/i",'',$tex); $tex = preg_replace("/\\\\DeclareMathOperator/i",'%$0',$tex); $tex = preg_replace("/\\\\DeclareMathAlphabet/i",'%$0',$tex); $tex = preg_replace("/\\\\usepackage[cache=false]{minted}/i",'\usepackage{minted}',$tex); $tex = preg_replace("/\\\\thispagestyle{empty}/i",'',$tex); $tex = preg_replace("/\\\\PassOptionsToPackage\s*(?{((?:[^{}]+|(?&R))*)})(?{((?:[^{}]+|(?&Q))*)})/i",'',$tex); $tex = preg_replace("/(\\\\csvautobooktabular\s*([^{}]*)\s*)(?{((?:[^{}]+|(?&R))*)})/i","\\1{{$d}/\\4}",$tex); $tex = preg_replace("/\\\\bibliographystyle\s*(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $tex = preg_replace("/\\\\usetikzlibrary\s*(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $tex = preg_replace("/\\\\DeclareFloatFont\s*(?{((?:[^{}]+|(?&R))*)})(?{((?:[^{}]+|(?&Q))*)})/i","",$tex); $tex = preg_replace("/\\\\captionsetup\s*(?\[((?:[^\[\]]+|(?&R))*)\])?(?{((?:[^{}]+|(?&Q))*)})/i","",$tex); $tex = preg_replace("/\\\\tikzexternalize\s*(?\[((?:[^\[\]]+|(?&R))*)\])/i","",$tex); $tex = preg_replace("/\\\\floatsetup\s*(?\[((?:[^\[\]]+|(?&R))*)\])(?{((?:[^{}]+|(?&Q))*)})/i","",$tex); $tex = preg_replace("/\s*\\\\bibliography\s*(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $tex = preg_replace("/\\\\end{document}/i",'',$tex); $tex = preg_replace("/\n\s*\\\\author\s*(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $tex = preg_replace("/\n\s*\\\\authorrunning\s*(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $tex = preg_replace("/\n\s*\\\\institute\s*(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $tex = preg_replace("/\n\s*\\\\title\s*(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $tex = preg_replace("/\n\s*\\\\date\s*(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $tex = preg_replace("/\\\\includegraphics\s*(?\[((?:[^\[\]]+|(?&R))*)\])(?{((?:[^{}]+|(?&Q))*)})/i",'\includegraphics${1}{'.$d.'/${4}}',$tex); $tex = preg_replace("/\n\s*\\\\maketitle/i","",$tex); $tex = preg_replace("/\\\\IEEEoverridecommandlockouts/i","",$tex); $tex = preg_replace("/\n\s*\\\\tikzexternalize/i","",$tex); [$ups,$ps] = getusepackages($tex); global $included_usepackages; global $additional_usepackages; foreach (array_diff($ps,$included_usepackages) as $k => $v) { if (in_array($v,['minted'])) { $additional_usepackages[] = "\usepackage{minted}"; $included_usepackages[] = $v; } else if (!in_array($v,['usenix','usenix,epsfig,endnotes','usenixbadges','cite','csvenhanced']) && !($v == 'floatrow' && in_array('float',$included_usepackages))) { $additional_usepackages[] = $ups[$k]; $included_usepackages[] = $v; } } array_unique($additional_usepackages); $tex = preg_replace("/\n\s*\\\\usepackage([^{}]*)(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $tex = preg_replace("/^\s*\\\\usepackage([^{}]*)(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $newcommands = getnewcommands($tex); global $existing_commands; $rmcommands = array_intersect($newcommands,$existing_commands); foreach ($rmcommands as $rmc) { $tex = preg_replace("/\n\s*\\\\newcommand([^{}]*)({\s*\\".$rmc."\s*}.*\n)/i","\n",$tex); } $matches = []; $tex = preg_replace("/\n\s*\\\\pgfplotsset\s*(?{((?:[^{}]+|(?&R))*)})/i","",$tex); $tex = preg_replace("/\n\s*\\\\setlength{\s*\\\marginparwidth.*\n/i","\n",$tex); if (stripos($tex,"\appendices") !== false || stripos($tex,"\appendix") !== false) $tex = handle_appendix($tex); file_put_contents($file,$tex); } } return; } function check_options($argv) { $options = []; foreach ($argv as $a) { if (str_starts_with($a,"-")) $options[$a] = 1; if ($a == "-n") $options["--no-overwrite"] = 1; } return $options; } function compile_check($papers,$precopy = false) { //array_shift($papers); weird... if ($precopy) $papers = array_combine($papers,$papers); foreach ($papers as $p => $f) { if (str_ends_with($f,".pdf")) { echo "======= Skipping PDF: $f =======\n"; continue; } echo "======= Paper $p -> $f START =======\n"; if ($precopy) { echo "$p\n"; if (strpos($p,"/") === false || str_starts_with($p,".") || !is_dir(dirname($p))) continue; $f = basename($p); $p = dirname($p); } else { shell_exec("cd $p; latexmk -c 2>/dev/null; latexmk -C 2>/dev/null; rm -f *.bbl"); } $str = shell_exec("cd $p; latexmk -latexoption=\"-shell-escape\" -g -pdf $f 2>&1"); $lines = explode("\n",$str); $skip = true; $failed = false; foreach($lines as $l) { if (str_starts_with($l,"Latexmk: ====List of undefined refs and citations:")) $skip = false; if ($skip) continue; if (stripos($l,"fail") !== false) $failed = true; echo "$l\n"; } if ($failed || user_consent("Please check the PDF file. Are there any problems with invalid references to figures, tables or with the bibliography?","--","--no-overwrite")) error_exit("The paper did not compile properly, please fix the errors next before continuing."); echo "======= Paper $p -> $f END =======\n"; } } function init_kpse() { global $kpsefiles; $kpsepath = shell_exec("kpsepath tex"); $kpsepath = explode(":",$kpsepath); foreach ($kpsepath as $k) { $k = str_replace(["!!","\n","///","//"],["","","/","/"],$k); if (str_starts_with($k,".")) continue; $found = null; if (is_dir($k)) $found = rscandir($k,[".sty"]); if ($found != null) { for ($i = 0; $i < count($found); $i++) $found[$i] = basename($found[$i]); $kpsefiles = array_unique(array_merge($kpsefiles,$found)); } } sort($kpsefiles); } check_software(); $options = check_options($argv); if (isset($options["--help"])) print_help(); echo "\n=== Step 1/$steps: Check Folders ===\n\n"; [$targets,$texfiles,$sourcedirs] = check_folders($argv); echo "\n=== Step 2/$steps: Pre-Copy Compile Check ===\n\n"; $targets_exist = true; foreach ($targets as $t) if (!is_dir($t)) $targets_exist = false; if (isset($options["--no-compile-check"]) || $targets_exist) echo "Skipping...\n"; else compile_check($argv,true); echo "\n=== Step 3/$steps: Copying Files ===\n\n"; $papers = check_and_copy_folders($argv); echo "\n=== Step 4/$steps: Adjusting References (in *.bib *.tex *.tikz) ===\n\n"; $bibresources = adjust_references($papers,[".bib",".tex",".tikz"]); echo "\n=== Step 5/$steps: Compile Check ===\n\n"; if (isset($options["--no-compile-check"])) echo "Skipping...\n"; else compile_check($papers); [$_t,$usepackages1] = getusepackages(file_get_contents("main.tex.php")); [$_t,$usepackages2] = getusepackages(file_get_contents("tugraz_defaults.sty")); global $included_usepackages; $included_usepackages = array_unique(array_merge($usepackages1, $usepackages2)); sort($included_usepackages); $cmds1 = getnewcommands(file_get_contents("main.tex.php")); $cmds2 = getnewcommands(file_get_contents("tugraz_defaults.sty")); global $existing_commands; $existing_commands = array_unique(array_merge($cmds1, $cmds2)); [$del,$mathops1] = getmathops(file_get_contents("main.tex.php")); [$del,$mathops2] = getmathops(file_get_contents("tugraz_defaults.sty")); global $existing_mathops; $existing_mathops = array_unique(array_merge($mathops1, $mathops2)); echo "\n=== Step 5/$steps: Adjusting Papers (checking *.tex and *.tikz files) ===\n\n"; adjust_papers($papers,[".tex",".tikz",".sty"]); init_kpse(); foreach ($papers as $k => $v) { if (str_ends_with($papers[$k],".pdf")) $papers[$k] = 'main.tex'; else { $stys = rscandir($k,[".sty"]); foreach ($stys as $styf) { $styfb = basename($styf); if (in_array($styfb,$kpsefiles) === false && !file_exists("./$styfb")) { echo "Copying $styf to ./$styfb...\n"; copy($styf,"./$styfb"); } } } } echo "\n=== Step 6/$steps: Generate main.tex ===\n\n"; $thesis_type = user_prompt("Enter Thesis Type ","PhD Thesis"); $thesis_title = user_prompt("Enter Thesis Title ","Security of TODO"); $thesis_part1_title = user_prompt("Enter Introductory Part Title ","Introduction to the Security of TODO"); $thesis_author = user_prompt("Enter Your Name ","Harry Potter"); $thesis_date = user_prompt("Enter Prospective Defense Month", "July 1998"); $thesis_institute = user_prompt("Enter Your Institute","Institute for Applied Information Processing and Communications"); $thesis_assessors = user_prompt("Enter Names of your Assessors (comma-separated)","Severus Snape, Minerva McGonagall"); $num_publications_in_thesis = count($papers); $num_publications = user_prompt("How many publications did you co-author during your PhD? (6 is the absolute minimum for a cumulative thesis)","6"); $sloppy_begin = ""; $sloppy_end = ""; if (!isset($options["--no-sloppy"])) { $sloppy_begin = '\begin{sloppypar}'; $sloppy_end = '\end{sloppypar}'; } ob_start(); require "main.tex.php"; $maintex_content = ob_get_contents(); ob_end_clean(); if (!file_exists("main.tex") || user_consent("main.tex already exists. overwrite?")) file_put_contents("main.tex",$maintex_content); if (!file_exists("mypreamble.sty") || user_consent("mypreamble.sty already exists... overwrite?","--force-overwrite","--no-overwrite")) file_put_contents("mypreamble.sty","\ProvidesPackage{mypreamble}\n\n".implode("\n",$additional_usepackages)."\n\n".$preamble); @mkdir("tikz"); if (!file_exists("abstract.tex")) file_put_contents("abstract.tex",""); if (!file_exists("intro.tex")) file_put_contents("intro.tex",""); if (!file_exists("main.bib")) file_put_contents("main.bib",""); if (isset($options["--cv"])) { if (!file_exists("cv.bib")) file_put_contents("cv.bib",""); if (!file_exists("cv.tex")) file_put_contents("cv.tex","This is my CV! Thanks for checking it out!"); } echo "=== done ===\nNext step, run this command:\nlatexmk -latexoption=\"-shell-escape\" -g -pdf main.tex\n"; ?>