| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- <?php
- global $options;
- $steps = 10;
- function user_consent($msg,$defaultyes = null,$defaultno = null)
- {
- global $options;
- if (isset($options["-n"]))
- return false;
- if ($defaultyes !== null && isset($options[$defaultyes]))
- return true;
- if ($defaultno !== null && isset($options[$defaultno]))
- return false;
- $response = false;
- do
- {
- echo "$msg (y/n)\n";
- $response = rtrim(fgets(STDIN));
- if ($response === "n" || $response == "N")
- return false;
- } while ($response !== "y" && $response !== "Y" && $response !== "");
- return true;
- }
- function user_prompt($msg,$default)
- {
- global $options;
- echo "$msg [Default: $default]\n";
- $response = "";
- if (!isset($options["-n"]))
- $response = rtrim(fgets(STDIN));
- if ($response == "")
- $response = $default;
- echo "You entered: '$response'\n";
- return $response;
- }
- function print_help()
- {
- $name = basename(__FILE__);
- echo<<<END
- Usage: php $name /path/folder1/main.tex /path/folder2/article.tex ... /path/folderN/paper.tex\n
- Generate a thesis template from the provided paper tex files and folders.
- The absolute minimum for a cumulative thesis is currently 3 papers first-authored and 6 in total.
- --force-overwrite overwrite files and folders
- --no-overwrite do not overwrite files and folders
- --no-compile-check do not perform a compile check
- --use-backups restore backups before making changes
- -n skip all prompts (implies --no-overwrite)
- --help display this help and exit
- END;
- exit(0);
- }
- function error_exit($msg,$usage = false)
- {
- echo "ERROR: $msg\n";
- if ($usage)
- echo "Usage: php ".basename(__FILE__)." /path/folder1/main.tex /path/folder2/article.tex ... /path/folderN/paper.tex\n";
- exit(-1);
- }
- function check_software()
- {
- if (!str_starts_with(shell_exec("latexmk --version"),"Latexmk,"))
- error_exit("latexmk not installed");
- if (!str_starts_with(shell_exec("pdftotext --help 2>&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";
- $mapping = array_combine($sourcedirs,$targets);
- //print_r($mapping);
- foreach ($mapping as $s => $t)
- {
- 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)
- {
- 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 = [])
- {
- foreach ($papers as $d => $f)
- {
- $tex = file_get_and_backup("$d/$f");
- $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);
- file_put_contents($file,$bib);
- }
- 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 array();
- }
- 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)
- {
- if ($precopy)
- $papers = array_combine($papers,$papers);
- foreach ($papers as $p => $f)
- {
- 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";
- }
- }
- 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);
- 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");
- ob_start();
- require "main.tex.php";
- $maintex_content = ob_get_contents();
- ob_end_clean();
- if (!file_exists("main.bib"))
- file_put_contents("main.bib","");
- //if (!file_exists("main.tex") || user_consent("main.tex already exists. overwrite?")) // TODO: enable this check
- file_put_contents("main.tex",$maintex_content);
- ?>
|