diff --git a/setup.py b/setup.py
index adea4d67c810b266cac64abb21dfd1de5cda0ae6..87aa6d9f317426d601b42ba3cd1a5321871aef96 100644
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
 # beamer-slider
 setuptools.setup(
     name="coursebox",
-    version="0.1.18.6",
+    version="0.1.18.8",
     author="Tue Herlau",
     author_email="tuhe@dtu.dk",
     description="A course management system currently used at DTU",
diff --git a/src/coursebox.egg-info/PKG-INFO b/src/coursebox.egg-info/PKG-INFO
index b2d8dc646134f57d3b31c90b134d812c654a2625..ded783a19bbff26efc1a0b60568236a727a6d0ce 100644
--- a/src/coursebox.egg-info/PKG-INFO
+++ b/src/coursebox.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: coursebox
-Version: 0.1.18.6
+Version: 0.1.18.8
 Summary: A course management system currently used at DTU
 Home-page: https://lab.compute.dtu.dk/tuhe/coursebox
 Author: Tue Herlau
diff --git a/src/coursebox/core/info.py b/src/coursebox/core/info.py
index c3d81c1565a060c1a9315e76ba366bf0829fffff..efe3a417bbf1ba09cd85da12b7db8dd7a78f16a9 100644
--- a/src/coursebox/core/info.py
+++ b/src/coursebox/core/info.py
@@ -286,6 +286,8 @@ def class_information(verbose=False,
                 info = pickle.load(f)
                 info = _update_with_core_conf(info)
             return info
+    elif verbose:
+        print("Coursebox> Loaded configurations from file", paths['information.xlsx'])
 
     course_number = core_conf['course_number']
     piazza = 'https://piazza.com/dtu.dk/%s%s/%s' % (semester().lower(), year(), course_number)
@@ -294,6 +296,10 @@ def class_information(verbose=False,
     continuing_education_mode = core_conf['continuing_education_mode']
     faq = xlsx_to_dicts(paths['information.xlsx'], sheet='faq')
 
+    # sections = xlsx_to_dicts(paths['information.xlsx'], sheet='teachers')
+    if (sections := xlsx_to_dicts(paths['information.xlsx'], sheet='sections')) is not None:
+        sections = {v['id']: v for v in sections}
+
     d = {'year': year(),
          'piazza': piazza, # deprecated.
          'course_number': course_number,
@@ -436,10 +442,21 @@ def class_information(verbose=False,
 
         dd = timedelta(days=l.get('show_solutions_after', 1))
         d['release_rules'][str(n)] = dict(start=date+dd, end=date+timedelta(days=2000))
+    # Update with section information.
+    if sections is not None:
+        for l in d['lectures']:
+            # print(l['number'])
+
+            l['date_sections'] = {s['id'] : {'date': l['date'] + timedelta(days=int(s['lecture_date_delta'])   )  } for s in sections.values() }
+            l['date_sections'] = {k: {**v, **date2format(v['date']) } for k, v in l['date_sections'].items()  }
+            l['teacher_initials_sections'] = {k: v.strip() for k, v in zip( list( sections.keys() ),  l['teacher_initials'].split("/") ) }
+
 
     if update_with_core_conf:
         d = _update_with_core_conf(d)
 
+    d['sections'] = sections
+
     return d
 
 def _update_with_core_conf(d):
diff --git a/src/coursebox/material/homepage_lectures_exercises.py b/src/coursebox/material/homepage_lectures_exercises.py
index c6e122de68e90e3f79aa0565f2f33c5fa6364782..d844b814e279529b0feecaf8a8c220498367839a 100644
--- a/src/coursebox/material/homepage_lectures_exercises.py
+++ b/src/coursebox/material/homepage_lectures_exercises.py
@@ -1,12 +1,9 @@
-# -*- coding: utf-8 -*-
 import shutil, os, glob
 from datetime import datetime, timedelta
 import calendar
 import pickle
 import time
-# from line_profiler_pycharm import profile
 from coursebox.thtools_base import partition_list
-
 import slider
 from jinjafy import jinjafy_comment
 from jinjafy import jinjafy_template
@@ -19,9 +16,12 @@ from coursebox.core.info import class_information
 from coursebox.material.lecture_questions import lecture_question_compiler
 from slider import latexmk
 import coursebox
-# from line_profiler_pycharm import profile
+import asyncio
+import time
+from jinjafy.cache.simplecache import hash_file_
+import tempfile
 
-def get_feedback_groups():
+def get_feedback_groups(): # This is really getting deprecated...
     paths = get_paths()
     feedback_file = paths['semester'] +"/feedback_groups.pkl"
     if os.path.exists(feedback_file):
@@ -66,16 +66,13 @@ def get_feedback_groups():
         sum( [len(v) for k,v in fbg.items() ]) - sum( [len( set(v)) for k,v in fbg.items() ])
 
         with open(feedback_file, 'wb') as f:
-            pickle.dump(fbg,f)
-
+            pickle.dump(fbg, f)
     for k in fbg:
         g = fbg[k]
         g2 = []
         for s in g:
-
             if s in info['students']:
                 dl = info['students'][s]['firstname'] + " " + info['students'][s]['lastname']
-                # dl = [ss['firstname']+" "+ss['lastname'] for ss in if ss['id'] == s]
                 if not dl:
                     print("EMPTY LIST when making feedback groups. Probably an error in project correction sheets.")
                     continue
@@ -86,7 +83,7 @@ def get_feedback_groups():
 PRESENTATION = 0
 NOTES = 1
 HANDOUT = 2
-def make_lectures(week=None, mode=0, gather_pdf_out=True, gather_sixup=True, make_quizzes=True, dosvg=False, Linux=False):
+def make_lectures(week=None, mode=0, gather_pdf_out=True, gather_sixup=True, make_quizzes=True, dosvg=False, async_pool=-1):
     """
     Mode determines what is compiled into the pdfs. It can be:
 
@@ -94,6 +91,8 @@ def make_lectures(week=None, mode=0, gather_pdf_out=True, gather_sixup=True, mak
     mode = NOTES = 1: Version containing notes (used for self-study)
     mode = HANDOUT = 2: version handed out to students.
     """
+    assert mode in [PRESENTATION, NOTES, HANDOUT]
+
     paths = get_paths()
     if os.path.exists(paths['book']):
         book_frontpage_png = paths['shared']+"/figures/book.png" #paths['lectures']+"/static/book.png"
@@ -104,81 +103,175 @@ def make_lectures(week=None, mode=0, gather_pdf_out=True, gather_sixup=True, mak
     # course_number = info['course_number']
     if isinstance(week, int):
         week = [week]
-    all_pdfs = []
-    for lecture in info['lectures']:
-        w = lecture['number']
-        if week is not None and w not in week:
-            continue
 
-        ag = get_feedback_groups()
-
-        lecture['feedback_groups'] = ag.get(w, [])
-        info.update({'week': w})
-        info['lecture'] = lecture
-        info['lecture']['teacher'] = [t for t in info['teachers'] if t['initials'] == lecture['teacher_initials']].pop()
-
-        lecture_texdir = paths['lectures'] + '/Lecture_%s/Latex' % w
-        lecture_texfile =lecture_texdir + "/Lecture_%i.tex" % w
-
-        fix_shared(paths, output_dir=lecture_texdir, dosvg=dosvg)
-
-        if os.path.exists(lecture_texdir):
-            print("Latex directory found for lecture %i: %s"%(w,lecture_texdir))
-            lecture_texdir_generated = lecture_texdir +"/templates"
-            if not os.path.exists(lecture_texdir_generated):
-                # shutil.rmtree(lecture_texdir_generated)
-                # time.sleep(0.2)
-                os.mkdir(lecture_texdir_generated)
-
-        if mode == PRESENTATION:
-            info['slides_shownotes'] = False
-            info['slides_handout'] = False
-            odex = "/presentation"
-        elif mode == HANDOUT:
-            info['slides_shownotes'] = False
-            info['slides_handout'] = True
-            info['slides_showsolutions'] = False
-            odex = "/handout"
-        elif mode == NOTES:
-            info['slides_shownotes'] = True
-            info['slides_handout'] = True
-            odex = "/notes"
+    lectures_to_compile = [lecture for lecture in info['lectures'] if week is None or lecture['number'] in week]
+    t = time.time()
+
+    if async_pool <= 1:
+        all_pdfs = []
+        for lecture in lectures_to_compile: #info['lectures']:
+            pdf_out = _compile_single_lecture(dosvg=dosvg, lecture=lecture, make_quizzes=make_quizzes, mode=mode)
+            all_pdfs.append( (lecture['number'], pdf_out))
+    else:
+        # Do the async here.
+        cp_tasks = []
+        for lecture in lectures_to_compile: #info['lectures']:
+            tsk = _compile_single_lecture_async(dosvg=dosvg, lecture=lecture, make_quizzes=make_quizzes, mode=mode)
+            cp_tasks.append(tsk)
+        loop = asyncio.get_event_loop()
+        cm = asyncio.gather(*cp_tasks)
+        results = loop.run_until_complete(cm)
+        all_pdfs = [ (lecture['number'], pdf) for (lecture, pdf) in zip( lectures_to_compile, results ) ]
+    # raise Exception("no async here")
+    # pass
+    t2 = time.time() - t
+    print("main compile, t1, t2", t2)
+
+    if mode == PRESENTATION:
+        odex = "/presentation"
+    elif mode == HANDOUT:
+        odex = "/handout"
+    elif mode == NOTES:
+        odex = "/notes"
+    else:
+        odex = None
+
+    t = time.time()
+    if len(all_pdfs) and gather_pdf_out > 0:
+        if async_pool >= 2:
+            # if len(all_pdfs) > 0 and gather_pdf_out:
+            async_handle_pdf_collection(paths, all_pdfs, gather_sixup=gather_sixup, odir=odex)
         else:
-            raise Exception("Mode not recognized")
-
-        for f in glob.glob(paths['lectures'] + "/templates/*.tex"):
-            ex = "_partial.tex"
-            if f.endswith(ex):
-                # print(info)
-                print("Building file", f)
-                jinjafy_template(info, file_in=f, file_out=lecture_texdir + "/templates/"+os.path.basename(f)[:-len(ex)] + ".tex")
-
-        # Fix questions.
-        qtarg = lecture_texdir + "/questions"
-        if not os.path.exists(qtarg):
-            os.mkdir(qtarg)
-        for f in glob.glob(paths['lectures'] + "/static/questions/*"):
-            shutil.copy(f, qtarg)
-
-        # Fix questions for this lecture
-        if make_quizzes:
-            lecture_question_compiler(paths, info, lecture_texfile)
-
-        print("Making file", lecture_texfile, Linux)
-        # pdf_out = slider.latexmk(lecture_texfile, Linux=Linux)
-        try:
-            pdf_out = slider.latexmk(lecture_texfile, Linux=Linux)
-        except Exception as e:
-            log = lecture_texfile[:-4] + ".log"
-            print("loading log", log)
-            with open(log, 'r') as f:
-                print(f.read())
-            raise e
-        all_pdfs.append( (w,pdf_out))
-
-    if len(all_pdfs) > 0:
-        handle_pdf_collection(paths, all_pdfs, gather_pdf_out=gather_pdf_out, gather_sixup=gather_sixup, odir=odex)
+            # if len(all_pdfs) > 0:
+            handle_pdf_collection(paths, all_pdfs, gather_pdf_out=gather_pdf_out, gather_sixup=gather_sixup, odir=odex)
+    t2 = time.time() - t
+    print("t1, t2", t2)
+    a = 234
+
+def _setup_lecture_info(lecture, mode, dosvg, make_quizzes):
+    w = lecture['number']
+    info = class_information()
+    paths = get_paths()
+    # if week is not None and w not in week:
+    #     continue
+    ag = get_feedback_groups()
+    lecture['feedback_groups'] = ag.get(w, [])
+    info.update({'week': w})
+    info['lecture'] = lecture
+    info['lecture']['teacher'] = [t for t in info['teachers'] if t['initials'] == lecture['teacher_initials']].pop()
+    lecture_texdir = paths['lectures'] + '/Lecture_%s/Latex' % w
+    lecture_texfile = lecture_texdir + "/Lecture_%i.tex" % w
+    fix_shared(paths, output_dir=lecture_texdir, dosvg=dosvg)
+    # if os.path.exists(lecture_texdir):
+    #     print("Latex directory found for lecture %i: %s" % (w, lecture_texdir))
+    #     # lecture_texdir_generated = lecture_texdir + "/templates"
+    #     # if not os.path.exists(lecture_texdir_generated):
+    #     #     os.mkdir(lecture_texdir_generated)
+    if mode == PRESENTATION:
+        info['slides_shownotes'] = False
+        info['slides_handout'] = False
+        # odex = "/presentation"
+    elif mode == HANDOUT:
+        info['slides_shownotes'] = False
+        info['slides_handout'] = True
+        info['slides_showsolutions'] = False
+        # odex = "/handout"
+    elif mode == NOTES:
+        info['slides_shownotes'] = True
+        info['slides_handout'] = True
+        # odex = "/notes"
+    for f in glob.glob(paths['lectures'] + "/templates/*.tex"):
+        ex = "_partial.tex"
+        if f.endswith(ex):
+            jinjafy_template(info, file_in=f,
+                             file_out=lecture_texdir + "/templates/" + os.path.basename(f)[:-len(ex)] + ".tex")
+
+    # Fix questions.
+    qtarg = lecture_texdir + "/questions"
+    if not os.path.exists(qtarg):
+        os.mkdir(qtarg)
+    for f in glob.glob(paths['lectures'] + "/static/questions/*"):
+        shutil.copy(f, qtarg)
+    if make_quizzes:
+        lecture_question_compiler(paths, info, lecture_texfile)
+
+    return lecture_texfile
+    pass
+
+def _compile_single_lecture(dosvg, lecture, make_quizzes, mode):
+    lecture_texfile = _setup_lecture_info(lecture, mode, dosvg, make_quizzes)
+    # Fix questions for this lecture
+    try:
+        pdf_out = slider.latexmk(lecture_texfile)
+    except Exception as e:
+        log = lecture_texfile[:-4] + ".log"
+        print("loading log", log)
+        with open(log, 'r') as f:
+            print(f.read())
+        raise e
+    return pdf_out
+
+async def _compile_single_lecture_async(dosvg, lecture, make_quizzes, mode):
+    lecture_texfile = _setup_lecture_info(lecture, mode, dosvg, make_quizzes)
+    # Fix questions for this lecture
+    try:
+        pdf_out = slider.latexmk_async(lecture_texfile)
+    except Exception as e:
+        log = lecture_texfile[:-4] + ".log"
+        print("loading log", log)
+        with open(log, 'r') as f:
+            print(f.read())
+        raise e
+    return pdf_out
+
 # http://piazza.com/dtu.dk/spring2023/02465/home
+def async_handle_pdf_collection(paths, all_pdfs, gather_sixup, odir):
+    # tmp_dir = paths['lectures'] + '/Collected/tmp'
+    # if not os.path.isdir(tmp_dir):
+    #     os.mkdir(tmp_dir)
+    import tempfile
+    tasks = []
+    for sixup in [False, True]:
+        if sixup and not gather_sixup: continue
+        for (week, _) in all_pdfs:
+            tasks.append(_compile_single(paths, sixup, week))
+
+    loop = asyncio.get_event_loop()
+    cm = asyncio.gather(*tasks)
+    pdf_compiled_all_6up = loop.run_until_complete(cm)
+    for f in pdf_compiled_all_6up:
+        assert os.path.isfile(f)
+
+    for dpdf in pdf_compiled_all_6up:
+        output_dir = paths['pdf_out'] + odir
+        if not os.path.exists(output_dir):
+            os.makedirs(output_dir)
+        shutil.copy(dpdf, output_dir + "/" + os.path.basename(dpdf))
+
+    # for f in glob.glob(tmp_dir + "/*"):
+    #     os.remove(f)
+
+
+async def _compile_single(paths, sixup, week):
+    # tmp_dir = tempfile.gettempdir()
+    tmp_dir = tempfile.mkdtemp()
+    if True:
+        # with tempfile.TemporaryDirectory() as tmp_dir:
+        # if not os.path.isdir(tmp_dir):
+        #     os.mkdir(tmp_dir)
+        collect_template = paths['lectures'] + "/Collected/lecture_collector_partial.tex"
+        sixup_str = "-6up" if sixup else ""
+        tv = {'week': week,
+              'pdffiles': [paths['lectures'] + '/Lecture_%s/Latex/Lecture_%s.pdf' % (week, week)]}
+        if sixup:
+            tv['sixup'] = sixup
+            tex_out_sixup = tmp_dir + "/Lecture_%i%s.tex" % (week, sixup_str)
+            jinjafy_comment(data=tv, file_in=collect_template, file_out=tex_out_sixup, jinja_tag=None)
+            dpdf = await slider.latexmk_async(tex_out_sixup, cleanup=True)
+        else:
+            dpdf = tv['pdffiles'][0]
+    return dpdf
+
 
 def handle_pdf_collection(paths, all_pdfs, gather_pdf_out, gather_sixup, odir):
     tmp_dir = paths['lectures'] + '/Collected/tmp'
@@ -229,15 +322,13 @@ def compile_simple_files(paths, info, template_file_list, verbose=False):
         latexmk(tex_out, pdf_out= paths['pdf_out'] + "/" + os.path.basename(tex_out)[:-4]+".pdf")
 
 # rec_fix_shared(shared_base=paths['shared'], output_dir=output_dir)
-import time
+
 # import dirsync
 # dirsync.sync(paths['shared'], output_dir, 'diff')
-
-
 # Do smarter fixin'
 from pathlib import Path
 
-from jinjafy.cache.simplecache import hash_file_
+
 
 # @profile
 def get_hash_from_base(base):
@@ -514,7 +605,7 @@ def slide_converter(week=None, verbose=True, clean_temporary_files=False, copy_t
             pdf_out = texdir +"/Lecture_%i.pdf"%n
             shutil.copyfile(pdf_in, pdf_out)
 
-            print("operating...")
+            print("Importing slides OSVGS slides since they were deleted...")
             lecture_tex_out = li_import(pdf_out, output_dir=texdir)
             print("Wrote new main file: " + lecture_tex_out)
         else:
@@ -528,5 +619,4 @@ def slide_converter(week=None, verbose=True, clean_temporary_files=False, copy_t
                                   clean_temporary_files=clean_temporary_files,
                                   copy_template_resource_files=copy_template_resource_files,
                                   fix_broken_osvg_files=fix_broken_osvg_files, **kwargs)
-
     print("Slides converted!")