diff --git a/.gitignore b/.gitignore
index 3d9824cbf36e06a6ccfa8c71b0729912aa1afc99..4eb8fae0a71e7ab0a8dd6585c7576fd028093c55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,5 @@
-main.*
-!main.tex
 sagetex.sty
-sage-plots-for-main.tex/
-dependency-newcommands.tex
-dependency-packages.tex
+generated-tex/
 tilt.rs
+latex_output
+tex/aux_files
diff --git a/.gitmodules b/.gitmodules
index b5205a9bd5ca0cdcbf31685fc9fd6dfe11a978fc..eb8e390f429336119ce63da7683bea12616a4c7a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,14 +2,14 @@
 	path = edinburgh-math-latex
 	url = https://github.com/Foggalong/edinburgh-math-latex.git
 [submodule "general-semi-homog-presentation"]
-	path = general-semi-homog-presentation
+	path = subprojects/general-semi-homog-presentation
 	url = git@git.ecdf.ed.ac.uk:personal-latex-documents/research/general-semi-homog-presentation.git
 [submodule "max-destabilizer-rank"]
-	path = max-destabilizer-rank
+	path = subprojects/max-destabilizer-rank
 	url = git@git.ecdf.ed.ac.uk:personal-latex-documents/research/max-destabilizer-rank.git
 [submodule "stabilizer-subgroups-of-CFMT-PPAS"]
-	path = stabilizer-subgroups-of-CFMT-PPAS
+	path = subprojects/stabilizer-subgroups-of-CFMT-PPAS
 	url = git@git.ecdf.ed.ac.uk:personal-latex-documents/research/general-irrational-beta-minus.git
 [submodule "transferring-characteristic-walls"]
-	path = transferring-characteristic-walls
+	path = subprojects/transferring-characteristic-walls
 	url = git@git.ecdf.ed.ac.uk:personal-latex-documents/research/transferring-characteristic-walls.git
diff --git a/Makefile b/Makefile
index 6d4bca67ccedfb38bbfc5d6a61e8993357df0dbe..1b91e20cb0f9edc02d3939b1ef52c7ec2534c70f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,39 +1,30 @@
 # Requires GNU sed, a latex distribution, sage
 # and sagetex.sty visible in TEXINPUTS
 
-#MAINTEXFILE = main.tex
-PREAMBLEFILES = newcommands.tex packages.tex theoremstyles.tex dependency-packages.tex
-CHAPTERDIRS = general-semi-homog-presentation max-destabilizer-rank stabilizer-subgroups-of-CFMT-PPAS transferring-characteristic-walls
-#TEXFILES = main.tex ${PREAMBLEFILES} $(addsuffix /content.tex, ${CHAPTERDIRS})
-#BIBFILES = $(addsuffix /references.bib, ${CHAPTERDIRS})
+pretex: chapter_deps preamble_deps tilt.rs notebook_tex rust_tex
 
-SAGESCRIPT = main.sagetex.sage
-
-SAGEARTIFACT = main.sagetex.sout
-
-${SAGEARTIFACT}: ${SAGESCRIPT} chapter_deps
-	PYTHONPATH=`echo $(CHAPTERDIRS) | sed 's/ \+/:/g'` sage ${SAGESCRIPT}
+CHAPTERDIRS = $(wildcard subprojects/*)
+#
+# Autogenerated sections of preamble generated from subprojects (chapters)
 
-#${SAGESCRIPT}: ${TEXFILES}
-	#latexmk || echo this is meant to fail
-	# seems to be a bug with sagetex, only works if patched:
-	#sed -i -e 's;version_check=)$$;version_check=True);' $@
+preamble_deps: $(addprefix generated-tex/, \
+	dependency-packages.tex dependency-newcommands.tex \
+)
 
-CHAPTERPACKAGES = $(addsuffix /packages.tex , ${CHAPTERDIRS})
-dependency-packages.tex: ${CHAPTERPACKAGES}
+CHAPTERPACKAGES = $(addsuffix /tex/packages.tex , ${CHAPTERDIRS})
+generated-tex/dependency-packages.tex: ${CHAPTERPACKAGES}
 	( \
 		echo "% Package list generated from chapters:"; \
 		cat $^ | sed -e '/^%/d' -e '/^$$/d' | sort | uniq \
 	) > $@
 packages.tex: dependency-packages.tex
 
-CHAPTERNEWCOMMANDS = $(addsuffix /newcommands.tex , ${CHAPTERDIRS})
-dependency-newcommands.tex: ${CHAPTERNEWCOMMANDS}
+CHAPTERNEWCOMMANDS = $(addsuffix /tex/newcommands.tex , ${CHAPTERDIRS})
+generated-tex/dependency-newcommands.tex: ${CHAPTERNEWCOMMANDS}
 	( \
 		echo "% newcommands generated from chapters:"; \
 		cat $^ | sed -e '/^%/d' -e '/^$$/d' | sort | uniq \
 	) > $@
-newcommands.tex:  dependency-newcommands.tex
 
 chapter_deps:
 	for dir in $(CHAPTERDIRS); do \
@@ -58,8 +49,7 @@ $(1).tex: $(1).ipynb
 	-i  $(1).tex
 endef
 
-NOTEBOOKBASENAMES=$(basename $(wildcard **/*.ipynb))
-#plots_and_expressions examples characteristic_curves rank_zero_case other_P_choice
+NOTEBOOKBASENAMES=$(basename $(wildcard subprojects/*/notebooks/*.ipynb))
 
 $(foreach _base, $(NOTEBOOKBASENAMES), $(eval $(call NOTEBOOK_TO_TEX_RULE, $(_base))))
 
@@ -78,8 +68,6 @@ $(foreach _base, $(RUSTBASENAMES), $(eval $(call RUST_TO_TEX_RULE, $(_base))))
 
 rust_tex: $(addsuffix .tex, $(RUSTBASENAMES))
 
-pretex: chapter_deps ${PREAMBLEFILES} tilt.rs notebook_tex rust_tex
-
 .PHONY: clean
 clean:
 	latexmk -C
diff --git a/appendix.tex b/appendix.tex
deleted file mode 100644
index 7ae925708293782518272c1c95fc072a53df2dbd..0000000000000000000000000000000000000000
--- a/appendix.tex
+++ /dev/null
@@ -1,52 +0,0 @@
-\appendix
-\chapter{Computing Pseudowalls Program}
-
-\section{Library, Utils CLI Frontend}
-
-\rustlisting{tilt.rs/src/}{main.tex}
-\rustlisting{tilt.rs/src/}{lib.tex}
-\rustlisting{tilt.rs/src/}{utils.tex}
-
-\section{Chern Character Submodule}
-
-\rustlisting{tilt.rs/src/}{chern_character.tex}
-\rustlisting{tilt.rs/src/}{chern_character/terms.tex}
-
-\section{Tilt Stability Submodule}
-
-\rustlisting{tilt.rs/src/}{tilt_stability.tex}
-\rustlisting{tilt.rs/src/}{tilt_stability/twisted.tex}
-\rustlisting{tilt.rs/src/}{tilt_stability/wall.tex}
-
-\subsection{Left Pseudowalls Submodule}
-
-\rustlisting{tilt.rs/src/}{tilt_stability/left_pseudo_semistabilizers.tex}
-
-\subsubsection{Fixed $\chern_1^\beta(u)$ Submodule}
-
-\rustlisting{tilt.rs/src/}{tilt_stability/left_pseudo_semistabilizers/fixed_q_beta.tex}
-
-\subsubsection{Fixed $\chern_0(u)$ Submodule}
-
-\rustlisting{tilt.rs/src/}{tilt_stability/left_pseudo_semistabilizers/fixed_q_beta/fixed_r.tex}
-\rustlisting{tilt.rs/src/}{tilt_stability/left_pseudo_semistabilizers/fixed_q_beta/fixed_r/bound_on_d.tex}
-
-\chapter{Jupyter Notebooks}
-
-\bgroup
-{\scriptsize
-	\input{notebook-commands.tex}
-	\section{Characteristic Curves}
-	\import{max-destabilizer-rank/}{characteristic_curves}
-	\section{Rank Zero Case}
-	\import{max-destabilizer-rank/}{rank_zero_case}
-	\section{Examples}
-	\import{max-destabilizer-rank/}{examples}
-	\section{Other P Choice}
-	\import{max-destabilizer-rank/}{other_P_choice}
-	\section{Existence of Wall Argument}
-	\import{general-semi-homog-presentation/}{existence_of_wall_argument}
-	\section{Transferring Walls via FMT}
-	\import{transferring-characteristic-walls/}{transferring_walls}
-}
-\egroup
diff --git a/compose.yaml b/compose.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d64c217bb3060c116850e6b3ab6837d2dab0897d
--- /dev/null
+++ b/compose.yaml
@@ -0,0 +1,13 @@
+version: "3.8"
+services:
+  dev:
+    build:
+      context: ./.devcontainer
+    volumes:
+      - type: bind
+        source: .
+        target: /root/workdir/
+    entrypoint: ["/usr/bin/bash", "-i"]
+    stdin_open: true # docker run -i
+    tty: true        # docker run -t
+    privileged: true
diff --git a/general-semi-homog-presentation b/general-semi-homog-presentation
deleted file mode 160000
index 4abef92e19d5772ab8e4737dfc90cab44ff222df..0000000000000000000000000000000000000000
--- a/general-semi-homog-presentation
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 4abef92e19d5772ab8e4737dfc90cab44ff222df
diff --git a/latexmkrc b/latexmkrc
index 7d4e76722387623ca6357a7272e25139e9e99f12..53b6baef18eaffee926fced4c5c5fa33a90418c3 100644
--- a/latexmkrc
+++ b/latexmkrc
@@ -1,6 +1,14 @@
-ensure_path("TEXINPUTS","edinburgh-math-latex/");
-@default_files = ('main.tex');
+use File::Spec;
+
+# I don't understand how this path isn't expanded before changing into the
+# default file directory... but somehow it does...
+ensure_path("TEXINPUTS", File::Spec->canonpath("../edinburgh-math-latex/"));
+@default_files = ('tex/main.tex');
 $pdf_mode = 1;
 $pdflatex = 'lualatex -shell-escape -interaction=nonstopmode %O %S';
 $max_repeat = 8;
-@generated_exts = (@generated_exts, 'synctex.gz');
+$use_make_for_missing_files = 1;
+$do_cd = 1;
+$aux_dir = 'aux_files';
+$out_dir = '../latex_output';
+$jobname = 'max-destabilizer-rank';
diff --git a/max-destabilizer-rank b/max-destabilizer-rank
deleted file mode 160000
index 746eec5a44005f8224022e62537352571c0772cb..0000000000000000000000000000000000000000
--- a/max-destabilizer-rank
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 746eec5a44005f8224022e62537352571c0772cb
diff --git a/newcommands.tex b/newcommands.tex
deleted file mode 100644
index 6222d850323a9a6fb4dd7724e9439a71a233dba4..0000000000000000000000000000000000000000
--- a/newcommands.tex
+++ /dev/null
@@ -1 +0,0 @@
-\input{dependency-newcommands.tex}
diff --git a/stabilizer-subgroups-of-CFMT-PPAS b/stabilizer-subgroups-of-CFMT-PPAS
deleted file mode 160000
index 9fd76d7407a8aebd3f4ca924c3bcf58ecce4fcc7..0000000000000000000000000000000000000000
--- a/stabilizer-subgroups-of-CFMT-PPAS
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 9fd76d7407a8aebd3f4ca924c3bcf58ecce4fcc7
diff --git a/subprojects/general-semi-homog-presentation b/subprojects/general-semi-homog-presentation
new file mode 160000
index 0000000000000000000000000000000000000000..787b065317f4dc140c480a02fb13887cad704702
--- /dev/null
+++ b/subprojects/general-semi-homog-presentation
@@ -0,0 +1 @@
+Subproject commit 787b065317f4dc140c480a02fb13887cad704702
diff --git a/subprojects/max-destabilizer-rank b/subprojects/max-destabilizer-rank
new file mode 160000
index 0000000000000000000000000000000000000000..794277b1ccd1b252794c64cbcb4f0be39249626f
--- /dev/null
+++ b/subprojects/max-destabilizer-rank
@@ -0,0 +1 @@
+Subproject commit 794277b1ccd1b252794c64cbcb4f0be39249626f
diff --git a/subprojects/stabilizer-subgroups-of-CFMT-PPAS b/subprojects/stabilizer-subgroups-of-CFMT-PPAS
new file mode 160000
index 0000000000000000000000000000000000000000..7a8de1b28d6af4163cc864cb3082fdec6b24ec87
--- /dev/null
+++ b/subprojects/stabilizer-subgroups-of-CFMT-PPAS
@@ -0,0 +1 @@
+Subproject commit 7a8de1b28d6af4163cc864cb3082fdec6b24ec87
diff --git a/subprojects/transferring-characteristic-walls b/subprojects/transferring-characteristic-walls
new file mode 160000
index 0000000000000000000000000000000000000000..0973c9c0cd90b83c690eea7291434eaac816a8e2
--- /dev/null
+++ b/subprojects/transferring-characteristic-walls
@@ -0,0 +1 @@
+Subproject commit 0973c9c0cd90b83c690eea7291434eaac816a8e2
diff --git a/tex/Makefile b/tex/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..de23d0825cdaba17334ae3e39c50a526bf8ccd6f
--- /dev/null
+++ b/tex/Makefile
@@ -0,0 +1,10 @@
+SAGETEXARTIFACT=main.sagetex.sout
+SAGETEXSCRIPT=main.sagetex.sage # generated by latex compile
+CHAPTERDIRS=$(wildcard ../../subprojects/*)
+
+aux_files/${SAGETEXARTIFACT}: aux_files/${SAGETEXSCRIPT} notebook_py_libs
+	cd aux_files && \
+	PYTHONPATH=`echo $(CHAPTERDIRS) | sed 's/ \+/:/g'` sage ${SAGETEXSCRIPT}
+
+notebook_py_libs:
+	$(MAKE) -C .. pretex
diff --git a/tex/appendix.tex b/tex/appendix.tex
new file mode 100644
index 0000000000000000000000000000000000000000..78ad6e683fa390c92976b3798480d90eb75e68c6
--- /dev/null
+++ b/tex/appendix.tex
@@ -0,0 +1,52 @@
+\appendix
+\chapter{Computing Pseudowalls Program}
+
+\section{Library, Utils CLI Frontend}
+
+\rustlisting{../tilt.rs/src/}{main.tex}
+\rustlisting{../tilt.rs/src/}{lib.tex}
+\rustlisting{../tilt.rs/src/}{utils.tex}
+
+\section{Chern Character Submodule}
+
+\rustlisting{../tilt.rs/src/}{chern_character.tex}
+\rustlisting{../tilt.rs/src/}{chern_character/terms.tex}
+
+\section{Tilt Stability Submodule}
+
+\rustlisting{../tilt.rs/src/}{tilt_stability.tex}
+\rustlisting{../tilt.rs/src/}{tilt_stability/twisted.tex}
+\rustlisting{../tilt.rs/src/}{tilt_stability/wall.tex}
+
+\subsection{Left Pseudowalls Submodule}
+
+\rustlisting{../tilt.rs/src/}{tilt_stability/left_pseudo_semistabilizers.tex}
+
+\subsubsection{Fixed $\chern_1^\beta(u)$ Submodule}
+
+\rustlisting{../tilt.rs/src/}{tilt_stability/left_pseudo_semistabilizers/fixed_q_beta.tex}
+
+\subsubsection{Fixed $\chern_0(u)$ Submodule}
+
+\rustlisting{../tilt.rs/src/}{tilt_stability/left_pseudo_semistabilizers/fixed_q_beta/fixed_r.tex}
+\rustlisting{../tilt.rs/src/}{tilt_stability/left_pseudo_semistabilizers/fixed_q_beta/fixed_r/bound_on_d.tex}
+
+\chapter{Jupyter Notebooks}
+
+\bgroup
+{\scriptsize
+	\input{notebook-commands.tex}
+	\section{Characteristic Curves}
+	\import{../subprojects/max-destabilizer-rank/}{characteristic_curves}
+	\section{Rank Zero Case}
+	\import{../subprojects/max-destabilizer-rank/}{rank_zero_case}
+	\section{Examples}
+	\import{../subprojects/max-destabilizer-rank/}{examples}
+	\section{Other P Choice}
+	\import{../subprojects/max-destabilizer-rank/}{other_P_choice}
+	\section{Existence of Wall Argument}
+	\import{../subprojects/general-semi-homog-presentation/}{existence_of_wall_argument}
+	\section{Transferring Walls via FMT}
+	\import{../subprojects/transferring-characteristic-walls/}{transferring_walls}
+}
+\egroup
diff --git a/chromalisting.lua b/tex/chromalisting.lua
similarity index 100%
rename from chromalisting.lua
rename to tex/chromalisting.lua
diff --git a/chromalisting.sty b/tex/chromalisting.sty
similarity index 100%
rename from chromalisting.sty
rename to tex/chromalisting.sty
diff --git a/lstlistsettings.tex b/tex/lstlistsettings.tex
similarity index 100%
rename from lstlistsettings.tex
rename to tex/lstlistsettings.tex
diff --git a/main.tex b/tex/main.tex
similarity index 56%
rename from main.tex
rename to tex/main.tex
index 9fe20f1eae4cc062f5e54c05817c1bf098a85e8b..8cff2b024e3e4bcadec46d060504611df0cdcda8 100644
--- a/main.tex
+++ b/tex/main.tex
@@ -3,7 +3,7 @@
 \input{packages.tex}
 \input{theoremstyles.tex}
 \input{newcommands.tex}
-\input{max-destabilizer-rank/newunicodes.tex}
+\input{../subprojects/max-destabilizer-rank/tex/newunicodes.tex}
 \input{notebook-preamble.tex}
 \input{lstlistsettings.tex}
 
@@ -11,8 +11,8 @@
 style=alphabetic,
 sorting=ynt
 ]{biblatex}
-\addbibresource{max-destabilizer-rank/references.bib}
-\addbibresource{general-semi-homog-presentation/references.bib}
+\addbibresource{../subprojects/max-destabilizer-rank/tex/references.bib}
+\addbibresource{../subprojects/general-semi-homog-presentation/tex/references.bib}
 
 \title{Clarifying the Criterion for the Accumulation of $\nu$-Walls}
 \author{Luke Naylor}
@@ -27,23 +27,23 @@ sorting=ynt
 	\newpage
 
 	\chapter{Preliminaries}
-		\import{transferring-characteristic-walls/}{preliminaries}
+		\import{../subprojects/transferring-characteristic-walls/tex/}{preliminaries}
 
 	\chapter{Bounds on Pseudo-Semistabilizers}
 		\minitoc
-		\import{max-destabilizer-rank/}{content}
+		\import{../subprojects/max-destabilizer-rank/tex/}{content}
 
 	\chapter{General Semi-Homogeneous Presentations}
 		\minitoc
-		\import{general-semi-homog-presentation/}{content}
+		\import{../subprojects/general-semi-homog-presentation/tex/}{content}
 
 	\chapter{Stabilizer Subgroups of CFMT}
 		\minitoc
-		\import{stabilizer-subgroups-of-CFMT-PPAS/}{content}
+		\import{../subprojects/stabilizer-subgroups-of-CFMT-PPAS/tex/}{content}
 
 	\chapter{Transferring Canonical Walls via FMTs}
 		\minitoc
-		\import{transferring-characteristic-walls/}{content}
+		\import{../subprojects/transferring-characteristic-walls/tex/}{content}
 
 	\newpage
 	\printbibliography
diff --git a/tex/newcommands.tex b/tex/newcommands.tex
new file mode 100644
index 0000000000000000000000000000000000000000..46126813a3753c0679cb512dcc9bdd9ac200880d
--- /dev/null
+++ b/tex/newcommands.tex
@@ -0,0 +1 @@
+\input{../generated-tex/dependency-newcommands.tex}
diff --git a/notebook-commands.tex b/tex/notebook-commands.tex
similarity index 100%
rename from notebook-commands.tex
rename to tex/notebook-commands.tex
diff --git a/notebook-preamble.tex b/tex/notebook-preamble.tex
similarity index 100%
rename from notebook-preamble.tex
rename to tex/notebook-preamble.tex
diff --git a/packages.tex b/tex/packages.tex
similarity index 76%
rename from packages.tex
rename to tex/packages.tex
index e5a19c03d4edde2f44e1c3b2d85af2e1c2e5f9bd..9891efa490c1f7503de706159877cfc4d52152ea 100644
--- a/packages.tex
+++ b/tex/packages.tex
@@ -1,5 +1,5 @@
 %\usepackage{newpxmath}
-\input{dependency-packages.tex}
+\input{../generated-tex/dependency-packages.tex}
 \usepackage[phd]{edmaths}
 \usepackage{newpxtext}
 \usepackage{minitoc}
diff --git a/theoremstyles.tex b/tex/theoremstyles.tex
similarity index 100%
rename from theoremstyles.tex
rename to tex/theoremstyles.tex
diff --git a/transferring-characteristic-walls b/transferring-characteristic-walls
deleted file mode 160000
index 53a1d9ac92379d4783d16c11f016ba9edaa85666..0000000000000000000000000000000000000000
--- a/transferring-characteristic-walls
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 53a1d9ac92379d4783d16c11f016ba9edaa85666