Daniel Gruss 2 년 전
부모
커밋
9137391707
2개의 변경된 파일1047개의 추가작업 그리고 1037개의 파일을 삭제
  1. 228 228
      main.tex.php
  2. 819 809
      thesiscomposer.php

+ 228 - 228
main.tex.php

@@ -1,228 +1,228 @@
-\documentclass[paper=a4,fontsize=11pt,twoside,titlepage,parskip=half-,openright,draft]{scrbook} % TODO remove draft
-
-\overfullrule=20pt % TODO fix the overfull hboxes
-
-\newif\ifbeischnittzugabe\beischnittzugabefalse % TODO set to true for final upload (required by flyeralarm)
-
-%%% papering %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Flyeralarm / content: 170mm x 240mm / mit buffer: 176mm x 246mm
-\ifbeischnittzugabe
-  \usepackage[paperwidth=17.6cm, paperheight=24.6cm, 
-              lmargin = 2.7cm, rmargin = 2.7cm, top = 2.3cm, headsep = 0.6cm, textheight = 19.3cm, footskip = 1.0cm]{geometry}
-\else
-  \usepackage[paperwidth=17.0cm, paperheight=24.0cm, 
-              lmargin = 2.4cm, rmargin = 2.4cm, top = 2.0cm, headsep = 0.6cm, textheight = 19.3cm, footskip = 1.0cm]{geometry}
-\fi
-
-\usepackage{tugraz_defaults}
-\addbibresource{main.bib}
-<?php 
-foreach ($bibresources as $br => $bib)
-{
-  echo '\addbibresource{'.$bib.'}
-';
-}
-if (isset($options["--cv"]))
-  echo '\addbibresource{cv.bib}
-';
-?>
-
-\begin{document}
-%\includepdf[pages=-]{front.pdf}
-\frontmatter
-%\counterwithin{lstlisting}{section}
-\counterwithin{listing}{section}
-\title{<?php echo $thesis_title ?>}
-\author{<?php echo $thesis_author ?>}
-\date{<?php echo $thesis_date ?>}
-%\pagenumbering{gobble}
-
-\newcommand{\tugsq}{\raisebox{0.5ex}{\tikzset{external/export next=false}\tikz{\fill (0,0) rectangle (0.5ex,0.5ex);}}}
-\sodef\so{}{0.45em}{1.4em}{0em}
-
-\begin{titlepage}%
-  \pagestyle{empty}
-\tikzset{external/export next=false}
-  \begin{tikzpicture}[remember picture,overlay]
-    \node at (current page.south west){
-    \tikzset{external/export next=false}
-      \begin{tikzpicture}[remember picture, overlay]
-        \fill[white] (0,0) rectangle (\paperwidth,\paperheight);
-        \shade[shading=axis,bottom color=black!35,top color=white] 
-          (0,0) rectangle (\paperwidth,0.92\paperheight);
-        \node[anchor=south west,inner sep=0pt] at (-2.8,1) {\includegraphics[width=152.5mm]{figures/background.png}};
-      \end{tikzpicture}};
-    \node at (current page.south east){
-    \tikzset{external/export next=false}
-      \begin{tikzpicture}[remember picture, overlay]
-        \node[anchor=north east] at ($({\paperwidth-19cm},1)$) {
-          \color{black}\fontsize{9}{9}\selectfont\so{\sffamily SCIENCE \tugsq{} PASSION \tugsq{} TECHNOLOGY}
-          };
-          \node [anchor=north east] at ($({\paperwidth-16cm},1.4)$) {\resizebox{1in}{!}{
-\includegraphics{figures/TU_Graz_Logo}
-}};
-      \end{tikzpicture}};
-    \node at (current page.east){
-      \begin{tikzpicture}[remember picture, overlay]
-        \node[anchor=east,xshift=-1.075cm,yshift=-3.6cm] (inst) {
-          \color{black}\sffamily <?php echo $thesis_institute ?>
-        };
-            \node[below=of inst.east,anchor=east,yshift=0.4cm] {\sffamily Graz University of Technology};	        
-      \end{tikzpicture}};
-  \end{tikzpicture}
-
-  \vspace{1cm}
-
-  {\sffamily\large\noindent 
-  \theauthor}
-
-  \vspace{0.15cm}
-  \hrule 
-  \vspace{0.3cm}
-
-  {\sffamily\huge\noindent \thetitle}
-
-  \vspace{0.2cm}
-  \hrule
-
-  \vspace{2cm}
-
-  {\sffamily\Large\noindent <?php echo $thesis_type ?>}\\[0.2cm]
-  {\sffamily\noindent Assessors: <?php echo $thesis_assessors ?>}\\[0.2cm]
-  {\sffamily\noindent <?php echo $thesis_date ?>}\\[0.2cm]
-  \vspace{6cm}
-\end{titlepage}%
-
-\cleardoublepage
-
-\addtocontents{toc}{\vspace*{\baselineskip}}
-
-\addtocontents{toc}{\vspace*{\baselineskip}}
-
-\tikzset{external/export next=true}
-\input{abstract}
-
-\cleardoublepage
-
-\tableofcontents
-\addcontentsline{toc}{chapter}{Contents}
-
-\cleardoublepage
-\mainmatter
-
-\addtocontents{toc}{\vspace*{\baselineskip}}
-
-\part[<?php echo $thesis_part1_title ?>]{<?php echo $thesis_part1_title ?>}
-
-\bgroup
-\begin{refsection}
-
-\input{intro}
-
-<?php echo $sloppy_begin; ?>
-\printbibliography[title={References}, heading=bibintoc]
-<?php echo $sloppy_end; ?>
-\end{refsection}
-\egroup
-
-\addtocontents{toc}{\vspace*{\baselineskip}}
-
-\cleardoublepage
-
-\part{Publications}
-\addtocontents{toc}{\protect\setcounter{tocdepth}{0}}
-\renewcommand*\thesection{\arabic{section}}
-
-\bgroup
-\begin{refsection}
-\chapter*{List of Publications}
-\label{sec:publicationlist}
-\addcontentsline{toc}{chapter}{List of Publications}
-
-During my thesis, I contributed to <?php echo $num_publications ?> publications in conference proceedings, <?php echo $num_publications_in_thesis ?> of which are included in this thesis as shown below.
-
-\newrefcontext[sorting=ydnt]
-\nocite{CV:*}
-
-<?php echo $sloppy_begin; ?>
-\printbibliography[title={Publications in this Thesis}, type=inproceedings, heading=subbibliography, keyword={mine}]
-
-\printbibliography[title={Other Contributions}, type=inproceedings, heading=subbibliography, keyword={mine_other}]
-<?php echo $sloppy_end; ?>
-
-\end{refsection}
-\egroup
-
-<?php
-foreach ($papers as $p => $f)
-{
-echo '
-
-  \bgroup
-  \begin{refsection}
-  \pgfplotsset{
-    table/search path={'.$p.'/},
-  }
-  \subimport*{'.$p.'/}{'.$f.'}
-  \end{refsection}
-  \egroup
-  
-  \newpage
-
-';
-}
-?>
-<?php
-if (isset($options['--cv']))
-{
-echo <<<'END'
-\cleardoublepage
-
-\appendix 
-\part*{Appendix}
-\addcontentsline{toc}{part}{Appendix}
-
-\addtocontents{toc}{\protect\setcounter{tocdepth}{0}}
-\renewcommand*\thesection{\arabic{section}}
-
-\addtocontents{toc}{\vspace*{\baselineskip}}
-
-\chapter*{Curriculum Vitae}
-
-\bgroup
-\begin{refsection}
-\input{cv}
-\end{refsection}
-\egroup
-
-\cleardoublepage
-
-\chapter*{Academic Field ``Applied Computer Science''}
-
-\bgroup
-\begin{refsection}
-
-\input{academicfield}
-
-\end{refsection}
-\egroup
-
-\cleardoublepage
-
-END;
-}
-?>
-<?php
-if (!isset($options['--no-statutory-declaration']))
-{
-echo <<<'END'
-\chapter*{Statutory Declaration}
-
-I declare that I have authored this thesis independently, that I have not used other than the declared sources / resources, and that I have explicitly marked all material which has been quoted either literally or by content from the used sources.
-
-END;
-}
-?>
-
-\end{document}
-
+\documentclass[paper=a4,fontsize=11pt,twoside,titlepage,parskip=half-,openright,draft]{scrbook} % TODO remove draft
+
+\overfullrule=20pt % TODO fix the overfull hboxes
+
+\newif\ifbeischnittzugabe\beischnittzugabefalse % TODO set to true for final upload (required by flyeralarm)
+
+%%% papering %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Flyeralarm / content: 170mm x 240mm / mit buffer: 176mm x 246mm
+\ifbeischnittzugabe
+  \usepackage[paperwidth=17.6cm, paperheight=24.6cm, 
+              lmargin = 2.7cm, rmargin = 2.7cm, top = 2.3cm, headsep = 0.6cm, textheight = 19.3cm, footskip = 1.0cm]{geometry}
+\else
+  \usepackage[paperwidth=17.0cm, paperheight=24.0cm, 
+              lmargin = 2.4cm, rmargin = 2.4cm, top = 2.0cm, headsep = 0.6cm, textheight = 19.3cm, footskip = 1.0cm]{geometry}
+\fi
+
+\usepackage{tugraz_defaults}
+\addbibresource{main.bib}
+<?php 
+foreach ($bibresources as $br => $bib)
+{
+  echo '\addbibresource{'.$bib.'}
+';
+}
+if (isset($options["--cv"]))
+  echo '\addbibresource{cv.bib}
+';
+?>
+
+\begin{document}
+%\includepdf[pages=-]{front.pdf}
+\frontmatter
+%\counterwithin{lstlisting}{section}
+\counterwithin{listing}{section}
+\title{<?php echo $thesis_title ?>}
+\author{<?php echo $thesis_author ?>}
+\date{<?php echo $thesis_date ?>}
+%\pagenumbering{gobble}
+
+\newcommand{\tugsq}{\raisebox{0.5ex}{\tikzset{external/export next=false}\tikz{\fill (0,0) rectangle (0.5ex,0.5ex);}}}
+\sodef\so{}{0.45em}{1.4em}{0em}
+
+\begin{titlepage}%
+  \pagestyle{empty}
+\tikzset{external/export next=false}
+  \begin{tikzpicture}[remember picture,overlay]
+    \node at (current page.south west){
+    \tikzset{external/export next=false}
+      \begin{tikzpicture}[remember picture, overlay]
+        \fill[white] (0,0) rectangle (\paperwidth,\paperheight);
+        \shade[shading=axis,bottom color=black!35,top color=white] 
+          (0,0) rectangle (\paperwidth,0.92\paperheight);
+        \node[anchor=south west,inner sep=0pt] at (-2.8,1) {\includegraphics[width=152.5mm]{figures/background.png}};
+      \end{tikzpicture}};
+    \node at (current page.south east){
+    \tikzset{external/export next=false}
+      \begin{tikzpicture}[remember picture, overlay]
+        \node[anchor=north east] at ($({\paperwidth-19cm},1)$) {
+          \color{black}\fontsize{9}{9}\selectfont\so{\sffamily SCIENCE \tugsq{} PASSION \tugsq{} TECHNOLOGY}
+          };
+          \node [anchor=north east] at ($({\paperwidth-16cm},1.4)$) {\resizebox{1in}{!}{
+\includegraphics{figures/TU_Graz_Logo}
+}};
+      \end{tikzpicture}};
+    \node at (current page.east){
+      \begin{tikzpicture}[remember picture, overlay]
+        \node[anchor=east,xshift=-1.075cm,yshift=-3.6cm] (inst) {
+          \color{black}\sffamily <?php echo $thesis_institute ?>
+        };
+            \node[below=of inst.east,anchor=east,yshift=0.4cm] {\sffamily Graz University of Technology};	        
+      \end{tikzpicture}};
+  \end{tikzpicture}
+
+  \vspace{1cm}
+
+  {\sffamily\large\noindent 
+  \theauthor}
+
+  \vspace{0.15cm}
+  \hrule 
+  \vspace{0.3cm}
+
+  {\sffamily\huge\noindent \thetitle}
+
+  \vspace{0.2cm}
+  \hrule
+
+  \vspace{2cm}
+
+  {\sffamily\Large\noindent <?php echo $thesis_type ?>}\\[0.2cm]
+  {\sffamily\noindent Assessors: <?php echo $thesis_assessors ?>}\\[0.2cm]
+  {\sffamily\noindent <?php echo $thesis_date ?>}\\[0.2cm]
+  \vspace{6cm}
+\end{titlepage}%
+
+\cleardoublepage
+
+\addtocontents{toc}{\vspace*{\baselineskip}}
+
+\addtocontents{toc}{\vspace*{\baselineskip}}
+
+\tikzset{external/export next=true}
+\input{abstract}
+
+\cleardoublepage
+
+\tableofcontents
+\addcontentsline{toc}{chapter}{Contents}
+
+\cleardoublepage
+\mainmatter
+
+\addtocontents{toc}{\vspace*{\baselineskip}}
+
+\part[<?php echo $thesis_part1_title ?>]{<?php echo $thesis_part1_title ?>}
+
+\bgroup
+\begin{refsection}
+
+\input{intro}
+
+<?php echo $sloppy_begin; ?>
+\printbibliography[title={References}, heading=bibintoc]
+<?php echo $sloppy_end; ?>
+\end{refsection}
+\egroup
+
+\addtocontents{toc}{\vspace*{\baselineskip}}
+
+\cleardoublepage
+
+\part{Publications}
+\addtocontents{toc}{\protect\setcounter{tocdepth}{0}}
+\renewcommand*\thesection{\arabic{section}}
+
+\bgroup
+\begin{refsection}
+\chapter*{List of Publications}
+\label{sec:publicationlist}
+\addcontentsline{toc}{chapter}{List of Publications}
+
+During my thesis, I contributed to <?php echo $num_publications ?> publications in conference proceedings, <?php echo $num_publications_in_thesis ?> of which are included in this thesis as shown below.
+
+\newrefcontext[sorting=ydnt]
+\nocite{CV:*}
+
+<?php echo $sloppy_begin; ?>
+\printbibliography[title={Publications in this Thesis}, type=inproceedings, heading=subbibliography, keyword={mine}]
+
+\printbibliography[title={Other Contributions}, type=inproceedings, heading=subbibliography, keyword={mine_other}]
+<?php echo $sloppy_end; ?>
+
+\end{refsection}
+\egroup
+
+<?php
+foreach ($papers as $p => $f)
+{
+echo '
+
+  \bgroup
+  \begin{refsection}
+  \pgfplotsset{
+    table/search path={'.$p.'/},
+  }
+  \subimport*{'.$p.'/}{'.$f.'}
+  \end{refsection}
+  \egroup
+  
+  \newpage
+
+';
+}
+?>
+<?php
+if (isset($options['--cv']))
+{
+echo <<<'END'
+\cleardoublepage
+
+\appendix 
+\part*{Appendix}
+\addcontentsline{toc}{part}{Appendix}
+
+\addtocontents{toc}{\protect\setcounter{tocdepth}{0}}
+\renewcommand*\thesection{\arabic{section}}
+
+\addtocontents{toc}{\vspace*{\baselineskip}}
+
+\chapter*{Curriculum Vitae}
+
+\bgroup
+\begin{refsection}
+\input{cv}
+\end{refsection}
+\egroup
+
+\cleardoublepage
+
+\chapter*{Academic Field ``Applied Computer Science''}
+
+\bgroup
+\begin{refsection}
+
+\input{academicfield}
+
+\end{refsection}
+\egroup
+
+\cleardoublepage
+
+END;
+}
+?>
+<?php
+if (!isset($options['--no-statutory-declaration']))
+{
+echo <<<'END'
+\chapter*{Statutory Declaration}
+
+I declare that I have authored this thesis independently, that I have not used other than the declared sources / resources, and that I have explicitly marked all material which has been quoted either literally or by content from the used sources.
+
+END;
+}
+?>
+
+\end{document}
+

+ 819 - 809
generator.php → thesiscomposer.php

@@ -1,810 +1,820 @@
-<?php
-  global $options;
-  global $preamble;
-  global $sloppy_begin;
-  global $sloppy_end;
-  $preamble = "";
-  global $kpsefiles;
-  $kpsefiles = [];
-  global $ignore_packages;
-  $ignore_packages = [];
-  global $existing_mathops;
-  $existing_mathops = [];
-  global $tikzlibs;
-  $tikzlibs = [];
-  global $included_usepackages;
-  $included_usepackages = [];
-  global $additional_usepackages;
-  $additional_usepackages = [];
-  $steps = 10;
-  function user_consent($msg,$defaultyes = null,$defaultno = null)
-  {
-    global $options;
-    if ($defaultyes !== null && isset($options[$defaultyes]))
-      return true;
-    if ($defaultno !== null && isset($options[$defaultno]))
-      return false;
-    if (isset($options["-n"]))
-      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.
-You can also provide pdf files instead of tex files or a mix of both.
-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
---no-cover               do not generate book cover pdf files
---compile                run latexmk on the resulting main.tex of your generated thesis
---not-sloppy             disable use of sloppypar around places that struggle without
-                         (mainly the bibliographies)
---cv                     add a CV
-                         (unusual for PhD theses, required for habilitation theses)
---no-stat-declaration    do not add the statutory declaration
-                         (required for PhD thesis, unusual for habilitation theses)
--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 (strpos(shell_exec("latexmk --version"),"Latexmk,") === false)
-      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";
-    $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);
-          $bib = str_replace('{\i}','{i}',$bib);
-          $bib = str_replace('$\textregistered$','\textregistered',$bib);
-          $bib = str_replace('{$\textquoteright$}','\'',$bib);
-          file_put_contents($file,$bib);
-          $bibresources[$d] = $file;
-        }
-        else
-        {
-          $tex = file_get_and_backup($file);
-          // labels of lstlistings etc
-          $tex = preg_replace("/(lstlisting.*[\[,]\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>{((?:[^{}]+|(?&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>{((?:[^{}]+|(?&R))*)})([^{}]*)|\\\\[^\{]*)(?<P>{((?:[^{}]+|(?&P))*)})(?<Q>{((?:[^{}]+|(?&Q))*)})?(?<S>{((?:[^{}]+|(?&S))*)})?(?<T>{((?:[^{}]+|(?&T))*)})?)/i",$tex,$mathops);
-    if (isset($mathops[4]))
-      return [$mathops[1],$mathops[3]];
-    return [[],[]];
-  }
-  function gettikzlibs($tex)
-  {
-    preg_match_all("/\\\\usetikzlibrary\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex,$matches);
-    if (isset($matches[2]))
-      return [$matches[0],$matches[2]];
-    else
-      return [[],[]];
-  }
-  function flatten($d,$f)
-  {
-    global $kpsefiles;
-    $tex = file_get_and_backup("$d/$f",".interm_bak");
-    preg_match_all("/\\n([^%]*?)(\\\\(input|include|usepackage)\s*\\\\*?\s*(?<R>{(?<RR>((?:[^{}]+|(?&R))*))}))/i",$tex,$inputs);
-    $files = [];
-    global $ignore_packages;
-    if (count($inputs) > 0)
-    {
-      for ($i = 0; $i < count($inputs[0]); $i++)
-      {
-        $exts = ['.tex'];
-        $f2 = $inputs['RR'][$i];
-        if (strtolower($inputs[3][$i]) === 'usepackage')
-        {
-          if (strpos($f2,",") !== false || in_array($f2,$ignore_packages) || in_array("$f2.sty",$kpsefiles))
-            continue;
-          $f2 .= ".sty";
-        }
-        while (!file_exists("$d/$f2") && count($exts) > 0)
-          $f2 = $inputs['RR'][$i].array_shift($exts);
-        if (file_exists("$d/$f2"))
-          $files[] = [$d,$f2,$inputs[2][$i]];
-      }
-    }
-    preg_match_all("/\\n([^%]*?)(\\\\(import|subimport)\s*\\\\*?\s*(?<R>{(?<RR>((?:[^{}]+|(?&R))*))})\s*(?<Q>{(?<QQ>((?:[^{}]+|(?&Q))*))}))/i",$tex,$inputs);
-    if (count($inputs) > 0)
-    {
-      for ($i = 0; $i < count($inputs[0]); $i++)
-      {
-        $exts = ['.tex'];
-        $f2 = $inputs['QQ'][$i].'/'.$inputs['RR'][$i];
-        while (!file_exists("$d/$f2") && count($exts) > 0)
-          $f2 = $inputs['QQ'][$i].'/'.$inputs['RR'][$i].array_shift($exts);
-        if (!file_exists("$d/$f2"))
-          $files[] = [$d,$f2,$inputs[2][$i]];
-      }
-    }
-    foreach ($files as $file)
-    {
-      $content = flatten($file[0],$file[1]);
-      $tex = str_replace($file[2],$content,$tex);
-    }
-    file_put_contents("$d/$f",$tex);
-    return $tex;
-  }
-  function adjust_papers($papers)
-  {
-    $tex = "";
-    $paper_fulltitle = "";
-    $authors = "";
-    $institute = "";
-    $header = "";
-    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=<<<END
-\chapter[$paper_shorttitle]{{$paper_fulltitle}}\label{chapter:$d}
-\section*{Publication Data}
-\\fullcite{TODO}
-
-\section*{Contributions}
-TODO
-
-\includepdf[pages=-]{{$d}/{$f}}
-END;
-file_put_contents("$d/main.tex",$header);
-        continue;
-      }
-      $file = "$d/$f";
-      $authors = "";
-      $institute = "";
-      $title = "";
-      $paper_fulltitle = "";
-      $paper_shorttitle = "";
-      $tex = file_get_and_backup($file,".interm_bak");
-      if ($authors == "" && preg_match("/\n\s*\\\\author\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex) == 1)
-      {
-        preg_match_all("/\n\s*\\\\author\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex,$authors);
-        if (isset($authors[2]))
-          $authors = trim(stripformatting(implode(" ",$authors[2])));
-      }
-      if ($institute == "" && preg_match("/\n\s*\\\\institute\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex) == 1)
-      {
-        preg_match_all("/\n\s*\\\\institute\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex,$institute);
-        if (isset($institute[2]) && isset($institute[2][0]))
-          $institute = trim(stripformatting($institute[2][0]));
-      }
-      if ($paper_shorttitle == "" && preg_match("/\n\s*\\\\title\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex) == 1)
-      {
-        preg_match_all("/\n\s*\\\\title\s*(?<R>{((?:[^{}]+|(?&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"));
-      }
-      if ($paper_fulltitle != "" && $paper_shorttitle != "" && $authors != "")
-      {
-        $header=<<<END
-\chapter[$paper_shorttitle]{{$paper_fulltitle}}\label{chapter:$d}
-\section*{Publication Data}
-\\fullcite{TODO}
-
-\section*{Contributions}
-TODO
-
-
-\\newpage
-\begin{center}
-{\Large \bfseries
-
-$paper_fulltitle
-}\\vspace{0.6cm}
-{\large $authors%
-} % TODO: check author list
-{\large $institute%
-} % TODO: check institutes
-\\end{center}
-END;
-      }
-
-      [$mathopsfull,$mathops] = getmathops($tex);
-      global $existing_mathops;
-      global $preamble;
-      $addmathops = array_diff($mathops,$existing_mathops);
-      $existing_mathops = array_unique($existing_mathops);
-      $addmathops = array_unique($addmathops);
-      foreach ($addmathops as $k => $v)
-      {
-        $preamble .= $mathopsfull[$k] . "\n";
-        $existing_mathops[] = $v;
-      }
-
-      global $tikzlibs;
-      [$foundlibsfull,$foundlibs] = gettikzlibs($tex);
-      $addlibs = array_diff($foundlibs,$tikzlibs);
-      $tikzlibs = array_unique($tikzlibs);
-      $addlibs = array_unique($addlibs);
-      foreach ($addlibs as $k => $v)
-      {
-        $preamble .= $foundlibsfull[$k] . "\n";
-        $tikzlibs[] = $v;
-      }
-
-
-      $tex = preg_replace("/\\\documentclass.*\\n/i","
-",$tex);
-      if (preg_match("/\\\begin{document}/i",$tex) == 1)
-      {
-        $tex = preg_replace("/\\\begin{document}/i",$header,$tex);
-        $header = "";
-      }
-      $tex = preg_replace("/\\\begin{abstract}/i",'\section*{Abstract}',$tex);
-      $tex = preg_replace("/\\\\newcommand/i",'\declarecommand',$tex);
-      $tex = preg_replace("/\\\\renewcommand/i",'\declarecommand',$tex);
-      $tex = preg_replace("/\\\\DeclareRobustCommand\s*(?<R>{((?:[^{}]+|(?&R))*)})\s*(?<Q>{((?:[^{}]+|(?&Q))*)})/i",'\declarecommand',$tex);
-      $tex = preg_replace("/\\\\newenvironment/i",'\declareenvironment',$tex);
-      $tex = preg_replace("/\\\\renewenvironment/i",'\declareenvironment',$tex);
-      $tex = preg_replace("/\\\\NewDocumentEnvironment/i",'\DeclareDocumentEnvironment',$tex);
-      $tex = preg_replace("/\\\\ReNewDocumentEnvironment/i",'\DeclareDocumentEnvironment',$tex);
-      $tex = preg_replace("/\\\\end{abstract}/i",'',$tex);
-      $tex = preg_replace("/\\\\onecolumn/i",'',$tex);
-      $tex = preg_replace("/\\\\pagenumbering\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\\\\special\s*(?<R>{((?:[^{}]+|(?&R))*)})/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",'%$0',$tex);
-      $tex = preg_replace("/\\\\PassOptionsToPackage\s*(?<R>{((?:[^{}]+|(?&R))*)})(?<Q>{((?:[^{}]+|(?&Q))*)})/i",'',$tex);
-      $tex = preg_replace("/(\\\\csvautobooktabular\s*([^{}]*)\s*)(?<R>{((?:[^{}]+|(?&R))*)})/i","\\1{{$d}/\\4}",$tex);
-      $tex = preg_replace("/\\\\bibliographystyle\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",'%$0',$tex);
-      $tex = preg_replace("/\\\\usetikzlibrary\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",'%$0',$tex);
-      $tex = preg_replace("/\\\\DeclareFloatFont\s*(?<R>{((?:[^{}]+|(?&R))*)})(?<Q>{((?:[^{}]+|(?&Q))*)})/i","",$tex);
-      $tex = preg_replace("/\\\\captionsetup\s*(?<R>\[((?:[^\[\]]+|(?&R))*)\])?(?<Q>{((?:[^{}]+|(?&Q))*)})/i","",$tex);
-      $tex = preg_replace("/\\\\RequirePackage\s*(?<R>\[((?:[^\[\]]+|(?&R))*)\])?(?<Q>{((?:[^{}]+|(?&Q))*)})/i","",$tex);
-      $tex = preg_replace("/\\\\tikzexternalize\s*(?<R>\[((?:[^\[\]]+|(?&R))*)\])/i","",$tex);
-      $tex = preg_replace("/\\\\floatsetup\s*(?<R>\[((?:[^\[\]]+|(?&R))*)\])(?<Q>{((?:[^{}]+|(?&Q))*)})/i","",$tex);
-      $tex = preg_replace("/\\\\newfloat\s*(?<R>{((?:[^{}]+|(?&R))*)})(?<Q>{((?:[^{}]+|(?&Q))*)})(?<P>{((?:[^{}]+|(?&P))*)})/i","",$tex);
-      $tex = preg_replace("/\s*\\\\bibliography\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","\n".'\begin{sloppypar}
-\printbibliography[title={References}, heading=subbibliography]
-\end{sloppypar}',$tex);
-      $tex = preg_replace("/\\\\end{document}/i",'',$tex);
-      $tex = preg_replace("/\n\s*\\\\author\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\\\\tag\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\n\s*\\\\authorrunning\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\n\s*\\\\institute\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\n\s*\\\\title\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\n\s*\\\\date\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\\\\includegraphics\s*(?<R>\[((?:[^\[\]]+|(?&R))*)\])(?<Q>{((?:[^{}]+|(?&Q))*)})/i",'\includegraphics${1}{'.$d.'/${4}}',$tex);
-      if (preg_match("/\\\\maketitle/i",$tex) == 1)
-      {
-        $tex = preg_replace("/\\\\maketitle/i",$header,$tex);
-        $header = "";
-      }
-      $tex = preg_replace("/\\\\IEEEoverridecommandlockouts/i","",$tex);
-      $tex = preg_replace("/\\\\IEEEauthorblock[AN]/i","",$tex);
-      $tex = preg_replace("/\\\\IEEEauthorrefmark/i","\\textsuperscript",$tex);
-      $tex = preg_replace("/\\\\twocolumn/i","",$tex);
-      $tex = preg_replace("/\\\\SetWatermarkText\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\\\\ProvidesPackage\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\\\\SetWatermarkScale\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\\\\SetWatermarkLightness\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/\n\s*\\\\tikzexternalize/i","",$tex);
-      [$ups,$ps] = getusepackages($tex);
-      global $ignore_packages;
-      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,$ignore_packages) && !($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>{((?:[^{}]+|(?&R))*)})/i","",$tex);
-      $tex = preg_replace("/^\s*\\\\usepackage([^{}]*)(?<R>{((?:[^{}]+|(?&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);
-      if (!str_starts_with($tex,"\\makeatletter\n\def\\relativepath{\\import@path}\n\\makeatother\n"))
-        $tex = "\\makeatletter\n\def\\relativepath{\\import@path}\n\\makeatother\n" . $tex;
-      $tex .= "\n\graphicspath{}";
-      file_put_contents($file,$tex);
-    }
-    return;
-  }
-  function check_options($argv)
-  {
-    $options = [];
-    foreach ($argv as $a)
-    {
-      if (str_starts_with($a,"-"))
-        $options[$a] = 1;
-    }
-    if (isset($options["-n"]) && !isset($options["--force-overwrite"]))
-      $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);
-  }
-  echo "\n=== Step 1/$steps: Check Software and Command Line Options ===\n\n";
-  check_software();
-  $options = check_options($argv);
-  if (isset($options["--help"]))
-    print_help();
-
-  $sloppy_begin = "";
-  $sloppy_end = "";
-  if (!isset($options["--no-sloppy"]))
-  {
-    $sloppy_begin = '\begin{sloppypar}';
-    $sloppy_end = '\end{sloppypar}';
-  }
-  
-  echo "\n=== Step 2/$steps: Check Folders ===\n\n";
-  [$targets,$texfiles,$sourcedirs] = check_folders($argv);
-
-  echo "\n=== Step 3/$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 4/$steps: Copying Files ===\n\n";
-  $papers = check_and_copy_folders($argv);
-  echo "\n=== Step 5/$steps: Adjusting References (in *.bib *.tex *.tikz) ===\n\n";
-  $bibresources = adjust_references($papers,[".bib",".tex",".tikz"]);
-  echo "\n=== Step 6/$steps: Post-Copy Compile Check ===\n\n";
-  if (isset($options["--no-compile-check"]))
-    echo "Skipping...\n";
-  else
-    compile_check($papers);
-  echo "\n=== Step 7/$steps: Initialize KPSE Database ===\n\n";
-  init_kpse();
-  global $ignore_packages;
-  $ignore_packages = explode(",",user_prompt("Enter a comma-separated list of packages that should be considered ignored (e.g. publisher or conference styles, as well as packages that modify font or page formats)","usenix,epsfig,endnotes,flushend,mathptmx,pslatex,fontenc,microtype,draftwatermark,usenixbadges,cite,csvenhanced,etex,filecontents"));
-  echo "\n=== Step 8/$steps: Flattening Papers ===\n\n";
-  foreach ($papers as $d => $f)
-    flatten($d,$f);
-  echo "\n=== Step 9/$steps: Post-Flattening Compile Check ===\n\n";
-  if (isset($options["--no-compile-check"]))
-    echo "Skipping...\n";
-  else
-    compile_check($papers);
-  echo "\n=== Step 10/$steps: Preparing Extraction of Used Packages, Tikz Libs, Math Ops etc. ===\n\n";
-  [$_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);
-
-  echo "\n=== Step 12/$steps: Adjusting Papers ===\n\n";
-  adjust_papers($papers);
-  foreach ($papers as $k => $v)
-  {
-    if (str_ends_with($papers[$k],".pdf"))
-      $papers[$k] = 'main.tex';
-  }
-  echo "\n=== Step 12/$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");
-
-  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",array_unique($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",'@inproceedings{Kocher2019,
-  author = {Paul Kocher and Jann Horn and Anders Fogh and Daniel Genkin and Daniel Gruss and Werner Haas and Mike Hamburg and Moritz Lipp and Stefan Mangard and Thomas Prescher and Michael Schwarz and Yuval Yarom},
-  booktitle = {S\&P},
-  title = {{Spectre Attacks: Exploiting Speculative Execution}},
-  year = {2019}
-}');
-  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!");
-  }
-
-  if (!isset($options["--no-cover"]))
-  {
-    ob_start();
-    require "cover1.tex.php";
-    $covertex_content = ob_get_contents();
-    ob_end_clean();
-    if (!file_exists("cover1.tex") || user_consent("cover1.tex already exists. overwrite?"))
-      file_put_contents("cover1.tex",$covertex_content);
-    
-    shell_exec('latexmk -latexoption="-shell-escape" -g -pdf cover1.tex 1>/dev/null 2>/dev/null');
-
-    ob_start();
-    require "cover2.tex.php";
-    $covertex_content = ob_get_contents();
-    ob_end_clean();
-    if (!file_exists("cover2.tex") || user_consent("cover2.tex already exists. overwrite?"))
-      file_put_contents("cover2.tex",$covertex_content);
-
-    shell_exec('latexmk -latexoption="-shell-escape" -g -pdf cover2.tex 1>/dev/null 2>/dev/null');
-  }
-  if (isset($options["--compile"]))
-  {
-    passthru('latexmk -latexoption="-shell-escape" -g -pdf main.tex');
-  }
-  else
-  {
-    echo "=== done ===\nNext step, run this command:\nlatexmk -latexoption=\"-shell-escape\" -g -pdf main.tex\n";
-  }
+<?php
+  global $options;
+  $options = [];
+  global $preamble;
+  global $sloppy_begin;
+  global $sloppy_end;
+  $preamble = "";
+  global $kpsefiles;
+  $kpsefiles = [];
+  global $ignore_packages;
+  $ignore_packages = [];
+  global $existing_mathops;
+  $existing_mathops = [];
+  global $tikzlibs;
+  $tikzlibs = [];
+  global $included_usepackages;
+  $included_usepackages = [];
+  global $additional_usepackages;
+  $additional_usepackages = [];
+  $steps = 10;
+  function user_consent($msg,$defaultyes = null,$defaultno = null)
+  {
+    global $options;
+    if ($defaultyes !== null && isset($options[$defaultyes]))
+      return true;
+    if ($defaultno !== null && isset($options[$defaultno]))
+      return false;
+    if (isset($options["-n"]))
+      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 thesiscomposer.php /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.
+You can also provide pdf files instead of tex files or a mix of both.
+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
+--no-cover               do not generate book cover pdf files
+--compile                run latexmk on the resulting main.tex of your generated thesis
+--not-sloppy             disable use of sloppypar around places that struggle without
+                         (mainly the bibliographies)
+--cv                     add a CV
+                         (unusual for PhD theses, required for habilitation theses)
+--no-stat-declaration    do not add the statutory declaration
+                         (required for PhD thesis, unusual for habilitation theses)
+-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 (strpos(shell_exec("latexmk --version"),"Latexmk,") === false)
+      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)
+  {
+    $sourcedirs = [];
+    foreach ($argv 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);
+          $bib = str_replace('{\i}','{i}',$bib);
+          $bib = str_replace('$\textregistered$','\textregistered',$bib);
+          $bib = str_replace('{$\textquoteright$}','\'',$bib);
+          file_put_contents($file,$bib);
+          $bibresources[$d] = $file;
+        }
+        else
+        {
+          $tex = file_get_and_backup($file);
+          // labels of lstlistings etc
+          $lstlistings = [];
+          preg_match_all("/\\\\begin{lstlisting}.*?\\\\end{lstlisting}/sim",$tex,$lstlistings);
+          if (count($lstlistings[0]) > 0)
+          foreach ($lstlistings[0] as $l)
+          {
+            $l2 = preg_replace("/(label\s*=\s*)(?!$d)/i",'${1}'.$d.':',$l);
+            $tex = str_replace($l,$l2,$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>{((?:[^{}]+|(?&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>{((?:[^{}]+|(?&R))*)})([^{}]*)|\\\\[^\{]*)(?<P>{((?:[^{}]+|(?&P))*)})(?<Q>{((?:[^{}]+|(?&Q))*)})?(?<S>{((?:[^{}]+|(?&S))*)})?(?<T>{((?:[^{}]+|(?&T))*)})?)/i",$tex,$mathops);
+    if (isset($mathops[4]))
+      return [$mathops[1],$mathops[3]];
+    return [[],[]];
+  }
+  function gettikzlibs($tex)
+  {
+    preg_match_all("/\\\\usetikzlibrary\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex,$matches);
+    if (isset($matches[2]))
+      return [$matches[0],$matches[2]];
+    else
+      return [[],[]];
+  }
+  function flatten($d,$f)
+  {
+    global $kpsefiles;
+    $tex = file_get_and_backup("$d/$f",".interm_bak");
+    preg_match_all("/\\n([^%]*?)(\\\\(input|include|usepackage)\s*\\\\*?\s*(?<R>{(?<RR>((?:[^{}]+|(?&R))*))}))/i",$tex,$inputs);
+    $files = [];
+    global $ignore_packages;
+    if (count($inputs) > 0)
+    {
+      for ($i = 0; $i < count($inputs[0]); $i++)
+      {
+        $exts = ['.tex'];
+        $f2 = $inputs['RR'][$i];
+        if (strtolower($inputs[3][$i]) === 'usepackage')
+        {
+          if (strpos($f2,",") !== false || in_array($f2,$ignore_packages) || in_array("$f2.sty",$kpsefiles))
+            continue;
+          $f2 .= ".sty";
+        }
+        while (!file_exists("$d/$f2") && count($exts) > 0)
+          $f2 = $inputs['RR'][$i].array_shift($exts);
+        if (file_exists("$d/$f2"))
+          $files[] = [$d,$f2,$inputs[2][$i]];
+      }
+    }
+    preg_match_all("/\\n([^%]*?)(\\\\(import|subimport)\s*\\\\*?\s*(?<R>{(?<RR>((?:[^{}]+|(?&R))*))})\s*(?<Q>{(?<QQ>((?:[^{}]+|(?&Q))*))}))/i",$tex,$inputs);
+    if (count($inputs) > 0)
+    {
+      for ($i = 0; $i < count($inputs[0]); $i++)
+      {
+        $exts = ['.tex'];
+        $f2 = $inputs['QQ'][$i].'/'.$inputs['RR'][$i];
+        while (!file_exists("$d/$f2") && count($exts) > 0)
+          $f2 = $inputs['QQ'][$i].'/'.$inputs['RR'][$i].array_shift($exts);
+        if (!file_exists("$d/$f2"))
+          $files[] = [$d,$f2,$inputs[2][$i]];
+      }
+    }
+    foreach ($files as $file)
+    {
+      $content = flatten($file[0],$file[1]);
+      $tex = str_replace($file[2],$content,$tex);
+    }
+    file_put_contents("$d/$f",$tex);
+    return $tex;
+  }
+  function adjust_papers($papers)
+  {
+    $tex = "";
+    $paper_fulltitle = "";
+    $authors = "";
+    $institute = "";
+    $header = "";
+    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=<<<END
+\chapter[$paper_shorttitle]{{$paper_fulltitle}}\label{chapter:$d}
+\section*{Publication Data}
+\\fullcite{TODO}
+
+\section*{Contributions}
+TODO
+
+\includepdf[pages=-]{{$d}/{$f}}
+END;
+file_put_contents("$d/main.tex",$header);
+        continue;
+      }
+      $file = "$d/$f";
+      $authors = "";
+      $institute = "";
+      $title = "";
+      $paper_fulltitle = "";
+      $paper_shorttitle = "";
+      $tex = file_get_and_backup($file,".interm_bak");
+      if ($authors == "" && preg_match("/\n\s*\\\\author\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex) == 1)
+      {
+        preg_match_all("/\n\s*\\\\author\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex,$authors);
+        if (isset($authors[2]))
+          $authors = trim(stripformatting(implode(" ",$authors[2])));
+      }
+      if ($institute == "" && preg_match("/\n\s*\\\\institute\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex) == 1)
+      {
+        preg_match_all("/\n\s*\\\\institute\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex,$institute);
+        if (isset($institute[2]) && isset($institute[2][0]))
+          $institute = trim(stripformatting($institute[2][0]));
+      }
+      if ($paper_shorttitle == "" && preg_match("/\n\s*\\\\title\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",$tex) == 1)
+      {
+        preg_match_all("/\n\s*\\\\title\s*(?<R>{((?:[^{}]+|(?&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"));
+      }
+      if ($paper_fulltitle != "" && $paper_shorttitle != "" && $authors != "")
+      {
+        $header=<<<END
+\chapter[$paper_shorttitle]{{$paper_fulltitle}}\label{chapter:$d}
+\section*{Publication Data}
+\\fullcite{TODO}
+
+\section*{Contributions}
+TODO
+
+
+\\newpage
+\begin{center}
+{\Large \bfseries
+
+$paper_fulltitle
+}\\vspace{0.6cm}
+{\large $authors%
+} % TODO: check author list
+{\large $institute%
+} % TODO: check institutes
+\\end{center}
+END;
+      }
+
+      [$mathopsfull,$mathops] = getmathops($tex);
+      global $existing_mathops;
+      global $preamble;
+      $addmathops = array_diff($mathops,$existing_mathops);
+      $existing_mathops = array_unique($existing_mathops);
+      $addmathops = array_unique($addmathops);
+      foreach ($addmathops as $k => $v)
+      {
+        $preamble .= $mathopsfull[$k] . "\n";
+        $existing_mathops[] = $v;
+      }
+
+      global $tikzlibs;
+      [$foundlibsfull,$foundlibs] = gettikzlibs($tex);
+      $addlibs = array_diff($foundlibs,$tikzlibs);
+      $tikzlibs = array_unique($tikzlibs);
+      $addlibs = array_unique($addlibs);
+      foreach ($addlibs as $k => $v)
+      {
+        $preamble .= $foundlibsfull[$k] . "\n";
+        $tikzlibs[] = $v;
+      }
+
+
+      $tex = preg_replace("/\\\documentclass.*\\n/i","
+",$tex);
+      if (preg_match("/\\\begin{document}/i",$tex) == 1)
+      {
+        $tex = preg_replace("/\\\begin{document}/i",$header,$tex);
+        $header = "";
+      }
+      $tex = preg_replace("/\\\begin{abstract}/i",'\section*{Abstract}',$tex);
+      $tex = preg_replace("/\\\\newcommand/i",'\declarecommand',$tex);
+      $tex = preg_replace("/\\\\renewcommand/i",'\declarecommand',$tex);
+      $tex = preg_replace("/\\\\DeclareRobustCommand\s*(?<R>{((?:[^{}]+|(?&R))*)})\s*(?<Q>{((?:[^{}]+|(?&Q))*)})/i",'',$tex);
+      $tex = preg_replace("/\\\\newenvironment/i",'\declareenvironment',$tex);
+      $tex = preg_replace("/\\\\renewenvironment/i",'\declareenvironment',$tex);
+      $tex = preg_replace("/\\\\NewDocumentEnvironment/i",'\DeclareDocumentEnvironment',$tex);
+      $tex = preg_replace("/\\\\ReNewDocumentEnvironment/i",'\DeclareDocumentEnvironment',$tex);
+      $tex = preg_replace("/\\\\end{abstract}/i",'',$tex);
+      $tex = preg_replace("/\\\\onecolumn/i",'',$tex);
+      $tex = preg_replace("/\\\\pagenumbering\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\\\\special\s*(?<R>{((?:[^{}]+|(?&R))*)})/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",'%$0',$tex);
+      $tex = preg_replace("/\\\\PassOptionsToPackage\s*(?<R>{((?:[^{}]+|(?&R))*)})(?<Q>{((?:[^{}]+|(?&Q))*)})/i",'',$tex);
+      $tex = preg_replace("/(\\\\csvautobooktabular\s*([^{}]*)\s*)(?<R>{((?:[^{}]+|(?&R))*)})/i","\\1{{$d}/\\4}",$tex);
+      $tex = preg_replace("/\\\\bibliographystyle\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",'%$0',$tex);
+      $tex = preg_replace("/\\\\usetikzlibrary\s*(?<R>{((?:[^{}]+|(?&R))*)})/i",'%$0',$tex);
+      $tex = preg_replace("/\\\\DeclareFloatFont\s*(?<R>{((?:[^{}]+|(?&R))*)})(?<Q>{((?:[^{}]+|(?&Q))*)})/i","",$tex);
+      $tex = preg_replace("/\\\\captionsetup\s*(?<R>\[((?:[^\[\]]+|(?&R))*)\])?(?<Q>{((?:[^{}]+|(?&Q))*)})/i","",$tex);
+      $tex = preg_replace("/\\\\RequirePackage\s*(?<R>\[((?:[^\[\]]+|(?&R))*)\])?(?<Q>{((?:[^{}]+|(?&Q))*)})/i","",$tex);
+      $tex = preg_replace("/\\\\tikzexternalize\s*(?<R>\[((?:[^\[\]]+|(?&R))*)\])/i","",$tex);
+      $tex = preg_replace("/\\\\floatsetup\s*(?<R>\[((?:[^\[\]]+|(?&R))*)\])(?<Q>{((?:[^{}]+|(?&Q))*)})/i","",$tex);
+      $tex = preg_replace("/\\\\newfloat\s*(?<R>{((?:[^{}]+|(?&R))*)})(?<Q>{((?:[^{}]+|(?&Q))*)})(?<P>{((?:[^{}]+|(?&P))*)})/i","",$tex);
+      $tex = preg_replace("/\s*\\\\bibliography\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","\n".'\begin{sloppypar}
+\printbibliography[title={References}, heading=subbibliography]
+\end{sloppypar}',$tex);
+      $tex = preg_replace("/\\\\end{document}/i",'',$tex);
+      $tex = preg_replace("/\n\s*\\\\author\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\\\\tag\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\n\s*\\\\authorrunning\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\n\s*\\\\institute\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\n\s*\\\\title\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\n\s*\\\\date\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\\\\includegraphics\s*(?<R>\[((?:[^\[\]]+|(?&R))*)\])(?<Q>{((?:[^{}]+|(?&Q))*)})/i",'\includegraphics${1}{'.$d.'/${4}}',$tex);
+      if (preg_match("/\\\\maketitle/i",$tex) == 1)
+      {
+        $tex = preg_replace("/\\\\maketitle/i",$header,$tex);
+        $header = "";
+      }
+      $tex = preg_replace("/\\\\IEEEoverridecommandlockouts/i","",$tex);
+      $tex = preg_replace("/\\\\IEEEauthorblock[AN]/i","",$tex);
+      $tex = preg_replace("/\\\\IEEEauthorrefmark/i","\\textsuperscript",$tex);
+      $tex = preg_replace("/\\\\twocolumn/i","",$tex);
+      $tex = preg_replace("/\\\\SetWatermarkText\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\\\\ProvidesPackage\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\\\\SetWatermarkScale\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\\\\SetWatermarkLightness\s*(?<R>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/\n\s*\\\\tikzexternalize/i","",$tex);
+      [$ups,$ps] = getusepackages($tex);
+      global $ignore_packages;
+      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,$ignore_packages) && !($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>{((?:[^{}]+|(?&R))*)})/i","",$tex);
+      $tex = preg_replace("/^\s*\\\\usepackage([^{}]*)(?<R>{((?:[^{}]+|(?&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);
+      if (!str_starts_with($tex,"\\makeatletter\n\def\\relativepath{\\import@path}\n\\makeatother\n"))
+        $tex = "\\makeatletter\n\def\\relativepath{\\import@path}\n\\makeatother\n" . $tex;
+      $tex .= "\n\graphicspath{}";
+      file_put_contents($file,$tex);
+    }
+    return;
+  }
+  function check_options($argv)
+  {
+    global $options;
+    $rest = [];
+    array_shift($argv);
+    foreach ($argv as $a)
+    {
+      if (str_starts_with($a,"-"))
+        $options[$a] = 1;
+      else
+        $rest[] = $a;
+    }
+    if (isset($options["-n"]) && !isset($options["--force-overwrite"]))
+      $options["--no-overwrite"] = 1;
+    return $rest;
+  }
+  function compile_check($papers,$precopy = false)
+  {
+    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=\"-file-line-error -shell-escape -interaction=nonstopmode\" -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);
+  }
+  echo "\n=== Step 1/$steps: Check Software and Command Line Options ===\n\n";
+  check_software();
+  $argv = check_options($argv);
+  if (isset($options["--help"]))
+    print_help();
+
+  $sloppy_begin = "";
+  $sloppy_end = "";
+  if (!isset($options["--no-sloppy"]))
+  {
+    $sloppy_begin = '\begin{sloppypar}';
+    $sloppy_end = '\end{sloppypar}';
+  }
+  
+  echo "\n=== Step 2/$steps: Check Folders ===\n\n";
+  [$targets,$texfiles,$sourcedirs] = check_folders($argv);
+
+  echo "\n=== Step 3/$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 4/$steps: Copying Files ===\n\n";
+  $papers = check_and_copy_folders($argv);
+  echo "\n=== Step 5/$steps: Adjusting References (in *.bib *.tex *.tikz) ===\n\n";
+  $bibresources = adjust_references($papers,[".bib",".tex",".tikz"]);
+  echo "\n=== Step 6/$steps: Post-Copy Compile Check ===\n\n";
+  if (isset($options["--no-compile-check"]))
+    echo "Skipping...\n";
+  else
+    compile_check($papers);
+  echo "\n=== Step 7/$steps: Initialize KPSE Database ===\n\n";
+  init_kpse();
+  global $ignore_packages;
+  $ignore_packages = explode(",",user_prompt("Enter a comma-separated list of packages that should be considered ignored (e.g. publisher or conference styles, as well as packages that modify font or page formats)","usenix,epsfig,endnotes,flushend,mathptmx,pslatex,fontenc,microtype,draftwatermark,usenixbadges,cite,csvenhanced,etex,filecontents"));
+  echo "\n=== Step 8/$steps: Flattening Papers ===\n\n";
+  foreach ($papers as $d => $f)
+    flatten($d,$f);
+  echo "\n=== Step 9/$steps: Post-Flattening Compile Check ===\n\n";
+  if (isset($options["--no-compile-check"]))
+    echo "Skipping...\n";
+  else
+    compile_check($papers);
+  echo "\n=== Step 10/$steps: Preparing Extraction of Used Packages, Tikz Libs, Math Ops etc. ===\n\n";
+  [$_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);
+
+  echo "\n=== Step 12/$steps: Adjusting Papers ===\n\n";
+  adjust_papers($papers);
+  foreach ($papers as $k => $v)
+  {
+    if (str_ends_with($papers[$k],".pdf"))
+      $papers[$k] = 'main.tex';
+  }
+  echo "\n=== Step 12/$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");
+
+  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",array_unique($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",'@inproceedings{Kocher2019,
+  author = {Paul Kocher and Jann Horn and Anders Fogh and Daniel Genkin and Daniel Gruss and Werner Haas and Mike Hamburg and Moritz Lipp and Stefan Mangard and Thomas Prescher and Michael Schwarz and Yuval Yarom},
+  booktitle = {S\&P},
+  title = {{Spectre Attacks: Exploiting Speculative Execution}},
+  year = {2019}
+}');
+  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!");
+  }
+
+  if (!isset($options["--no-cover"]))
+  {
+    ob_start();
+    require "cover1.tex.php";
+    $covertex_content = ob_get_contents();
+    ob_end_clean();
+    if (!file_exists("cover1.tex") || user_consent("cover1.tex already exists. overwrite?"))
+      file_put_contents("cover1.tex",$covertex_content);
+    
+    shell_exec('latexmk -latexoption="-file-line-error -shell-escape -interaction=nonstopmode" -g -pdf cover1.tex 1>/dev/null 2>/dev/null');
+
+    ob_start();
+    require "cover2.tex.php";
+    $covertex_content = ob_get_contents();
+    ob_end_clean();
+    if (!file_exists("cover2.tex") || user_consent("cover2.tex already exists. overwrite?"))
+      file_put_contents("cover2.tex",$covertex_content);
+
+    shell_exec('latexmk -latexoption="-file-line-error -shell-escape -interaction=nonstopmode" -g -pdf cover2.tex 1>/dev/null 2>/dev/null');
+  }
+  if (isset($options["--compile"]))
+  {
+    passthru('latexmk -latexoption="-file-line-error -shell-escape" -g -pdf main.tex');
+  }
+  else
+  {
+    echo "=== done ===\nNext step, run this command:\nlatexmk -latexoption=\"-shell-escape\" -g -pdf main.tex\n";
+  }
 ?>