diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index be0121aedb8404e17c94f264aae6bd2e24657a74..0ac3d574ea0bc53763baae627097432726a5552b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,22 +7,22 @@ test_snipper:
   stage: test
   script:
     - echo "Testing student files"
-#    - pwd
     - apt-get update -y
     - apt install -y python3-pip
     - apt install -y python3.10 python-is-python3
+    - apt install -y git
+    - apt install -y xvfb # Virtual framebuffer for GL stuff.
+    - pip install -e ./
+    - cd tests
+    - xvfb-run -s "-screen 0 1400x900x24" python -m unittest test_python.py
+    - echo "Buy world"
+
+
+
 #    - apt install -y python-is-python3
 #    - python --version
 #    - locate python
-    - apt install -y git
-    - apt install -y xvfb # Virtual framebuffer for GL stuff.
 #    - apt install -y inkscape pdftk
 #    - apt install -y latexmk  poppler-utils # latexmk and pdftocairo
 #    - DEBIAN_FRONTEND='noninteractive' apt install -y texlive-latex-recommended texlive-latex-extra texlive-science pdf2svg
 #    - pip install -U Pillow
-    - pip install -e ./
-    - cd tests
-    - xvfb-run -s "-screen 0 1400x900x24" python -m unittest test_python.py
-#    - latexmk --version
-#    - ls tests_images/*
-
diff --git a/src/codesnipper.egg-info/PKG-INFO b/src/codesnipper.egg-info/PKG-INFO
index 055fae08a3ba7de7f27371026f392ee3c4273a02..5857de15c15935e628f0ba525b6df4d322db1b89 100644
--- a/src/codesnipper.egg-info/PKG-INFO
+++ b/src/codesnipper.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: codesnipper
-Version: 0.1.14
+Version: 0.1.17
 Summary: A lightweight framework for censoring student solutions files and extracting code + output
 Home-page: https://lab.compute.dtu.dk/tuhe/snipper
 Author: Tue Herlau
diff --git a/src/snipper/fix_bf.py b/src/snipper/fix_bf.py
index 345b2586f28312108b61c85e41f6ffad47236435..0f8cb0cf5075ee016412c7086ed729dff36b6736 100644
--- a/src/snipper/fix_bf.py
+++ b/src/snipper/fix_bf.py
@@ -66,7 +66,7 @@ def fix_f(lines, debug, keep=False):
     return lines2
 
 # stats = {'n': 0}
-def _block_fun(lines, start_extra, end_extra, keep=False, permute=False, questionmarks=False, halfquestionmarks=False, silent=False):
+def _block_fun(lines, start_extra, end_extra, keep=False, permute=False, questionmarks=False, halfquestionmarks=False, silent=False, nolines=False):
     methods = {'remove': 0}
     # if method not in ['remove', 'permute', 'questionmark', 'halfquestionmark']:
     #     assert False
@@ -105,7 +105,12 @@ def _block_fun(lines, start_extra, end_extra, keep=False, permute=False, questio
                 lines = f3(lines)
                 insert_lines = True
             if not insert_lines:
-                lines = [id + f"# TODO: {cc} lines missing."]
+                if nolines:
+                    todo = f"# TODO: Code has been removed from here."
+                else:
+                    todo = f"# TODO: {cc} lines missing."
+
+                lines = [id + todo]
             else:
                 lines = msg + lines
             lines += [id + f'raise NotImplementedError("{ee}")']
diff --git a/src/snipper/fix_cite.py b/src/snipper/fix_cite.py
index b27dc91d73113ae4b8cd2ca6cac62a637aaf4eec..45c6aa19a900a09d366dcaadcb130c125b3ae352 100644
--- a/src/snipper/fix_cite.py
+++ b/src/snipper/fix_cite.py
@@ -9,8 +9,8 @@ def fix_citations(lines, references, strict=True, file=None):
     I.e. rst files should get rst references.
 
     """
-    if str(file).endswith(".rst"):
-        print(file)
+    # if str(file).endswith(".rst"):
+    #     print(file)
     # lines = fix_aux(lines, )
     lines = fix_single_reference(lines, aux=references.get('aux', {}), cmd="\\ref", strict=True)
     for cm in references.get('commands', []):
@@ -99,7 +99,7 @@ def fix_single_reference(lines, cmd, aux, strict=True):
         rtxt = r['nicelabel']
         s = s[:i] + rtxt + s[j + 1:]
         i = i + len(rtxt)
-        print(cmd, rtxt)
+        # print(cmd, rtxt)
 
     lines = s.splitlines(keepends=False)
     return lines
\ No newline at end of file
diff --git a/src/snipper/fix_i.py b/src/snipper/fix_i.py
index 296dc0ccb1842780a315aa7fe0e73c47a064bdb3..a4988755667ff68edbbf847cab5f3c54b259ffe0 100644
--- a/src/snipper/fix_i.py
+++ b/src/snipper/fix_i.py
@@ -14,7 +14,7 @@ def rsession(analyzer, lines, extra):
     dbug = False
     # analyzer = we.spawn("python", encoding="utf-8", timeout=20)
     # analyzer.expect([">>>"])
-    if "BetterBasicDog" in "\n".join(lines) and False:
+    if "You can group" in "\n".join(lines): # in "\n".join(lines):
         print("\n".join(lines))
         print("-"*50)
         for k in extra['session_results']:
@@ -23,20 +23,27 @@ def rsession(analyzer, lines, extra):
 
         import time
         an = we.spawn("python", encoding="utf-8", timeout=20)
+        an.setwinsize(400, 400) # set window size to avoid truncated output or input.
         an.expect([">>>"])
         l3 = """
-import numpy as np 
-from scipy.linalg import norm
-x = np.asarray([3, 4])
-x  # What is x?
-norm(x)"""
+2 + 4 # Add two integers
+50 - 5 * 6
+(2 + 2) * (3 - 1) # You can group operations using parenthesis
+width = 20 # Assign the variable 'width' to a value of 20
+height = 5*9 # And also height is assigned the value of 5 * 9 = 45
+area = 2*3 # Compute the area of a rectangle and assign it to area now the text will be longer is that an issue
+area # This line shows us the value of 'area' #!i=b
+"""
         lines2 = l3.strip().splitlines()
+        from collections import defaultdict
+        dd = defaultdict(list)
 
         for l in lines2:
-            an.sendline(l)
+            dd['code'].append(l)
+            an.sendline(l.rstrip())
             an.expect_exact([">>>", "..."])
-            print("INPUT", l)
-            print(">>>", an.before.strip())
+            dd["output"].append(an.before.strip())
+            # print(">>>", an.before.strip())
             if len(an.after.strip()) > 4:
                 print(">>>>>>>>>>>>> That was a long after?")
             # analyzer.be
@@ -44,6 +51,9 @@ norm(x)"""
         print('*' * 50)
         # analyzer = an
         dbug = True
+        import tabulate
+        print(tabulate.tabulate(dd, headers='keys'))
+
     lines = "\n".join(lines).replace("\r", "").splitlines()
 
     for i, l in enumerate(lines):
@@ -68,16 +78,15 @@ norm(x)"""
         while True:
             time.sleep(0.05)
             analyzer.expect_exact([">>>", "..."])
-            if dbug and "total_cost" in word:
-                aaa = 23234
+            # if dbug and "total_cost" in word:
+            #     aaa = 23234
             before += analyzer.before
             # if dbug:
-            print(">  analyzer.before...", analyzer.before.strip(), "...AFTER...", analyzer.after.strip())
+            # print(">  analyzer.before...", analyzer.before.strip(), "...AFTER...", analyzer.after.strip())
             # AFTER =
             if analyzer.before.endswith("\n"):
-                print("> BREAKING LOOP")
+                # print("> BREAKING LOOP")
                 break
-                pass
             else:
                 before += analyzer.after
             break
@@ -108,6 +117,8 @@ norm(x)"""
 
 
 def run_i(lines, file, output):
+    if 'python0A' in str(file):
+        print(234)
     extra = dict(python=None, output=output, evaluated_lines=0, session_results=[])
     def block_fun(lines, start_extra, end_extra, art, head="", tail="", output=None, extra=None):
         outf = output + ("_" + art if art is not None and len(art) > 0 else "") + ".shell"
@@ -119,6 +130,7 @@ def run_i(lines, file, output):
 
         if extra['python'] is None:
             an = we.spawn("python", encoding="utf-8", timeout=20)
+            an.setwinsize(400, 400)  # set window size to avoid truncated output or input.
             an.expect([">>>"])
             extra['python'] = an
 
@@ -141,8 +153,8 @@ def run_i(lines, file, output):
             for outf in kvs:
                 out = "\n".join( ["\n".join(v[1]) for v in c if v[0] == outf] )
                 out = out.replace("\r", "")
-                if outf.endswith("python0B_e4.shell"):
-                    print(outf)
+                # if outf.endswith("python0B_e4.shell"):
+                #     print(outf)
 
                 with open(outf, 'w') as f:
                     f.write(out)
diff --git a/src/snipper/fix_s.py b/src/snipper/fix_s.py
index a6eff7e8024db8eb6011f39db9b9f4eff1d7aa27..73b6561872a8e263bfacec6286628dc53049b0d0 100644
--- a/src/snipper/fix_s.py
+++ b/src/snipper/fix_s.py
@@ -17,8 +17,9 @@ def get_s(lines):
             pass
         if 'dse' in c['start_tag_args']:
             print("asdfasdfs")
-        print(c['start_tag_args'])
+        # print(c['start_tag_args'])
         if 'nodoc' in c['start_tag_args'] and c['start_tag_args']['nodoc']:
+            c['block'] = rm_docstring(c['block'])
             print("No documentation!")
         blocks[c['name']].append(c)
 
@@ -48,6 +49,8 @@ def get_s(lines):
     return output
 
 def rm_docstring(lines):
+    slines = lines
+    slines = dedent(lines)
     source = "\n".join(slines)
     import ast
     node = ast.parse(source)
@@ -58,7 +61,7 @@ def rm_docstring(lines):
     def rm_ds(f, ll2):
         if slines[f.lineno].strip().startswith('"' * 3):
             # print("got a docstrnig")
-            for k in range(f.lineno, f.end_lineno + 1):
+            for k in range(f.lineno-1, f.end_lineno + 1):
                 l = slines[k] if k != f.lineno else slines[k].strip()[3:]
                 if l.find('"' * 3) >= 0:
                     break
@@ -74,7 +77,18 @@ def rm_docstring(lines):
     for c in classes:
         for f in c.body:
             rm_ds(f, ll2)
-    return [l for l in ll2 if l is not None]
+        rm_ds(c, ll2)
+    nodoc = [l for l in ll2 if l is not None]
+    # print("\n".join(nodoc))
+    return nodoc
+
+
+def dedent(lines):
+    ll = lines
+    id = [indent(l) for l in ll if len(l.strip()) > 0]
+    id_len = [len(i) for i in id]
+    mindex = id_len[id_len.index(min(id_len))]
+    return [l[mindex:] for l in ll]
 
 
 # def _s_block_process():
diff --git a/src/snipper/load_citations.py b/src/snipper/load_citations.py
index 18bedf70677d8b30944e9a172badf7695af3b441..b571c4f7b26658fa6fe21f5e50f6ba476a250de8 100644
--- a/src/snipper/load_citations.py
+++ b/src/snipper/load_citations.py
@@ -30,9 +30,9 @@ def get_aux(auxfile):
         if not os.path.dirname(auxdir):
             print("Directory for auxfile does not exist:", auxdir)
         else:
-            print("Auxfile did not exist, but directory did. Printing the contents:")
-            for f in glob.glob(os.path.dirname(auxfile) + "/*"):
-                print(f)
+            print("Auxfile did not exist, but directory did. Probably missing latex compile command.")
+            # for f in glob.glob(os.path.dirname(auxfile) + "/*"):
+            #     print(f)
 
         return {}
 
diff --git a/src/snipper/snip_dir.py b/src/snipper/snip_dir.py
index b538303a7f81112f902c3a1d40f2174227555891..62ece1ef22d62f51925633b3ffa0b3e68d86cc50 100644
--- a/src/snipper/snip_dir.py
+++ b/src/snipper/snip_dir.py
@@ -20,7 +20,7 @@ def snip_dir(source_dir,  # Sources
              verbose=True,
              ):
 
-    print("Snipper fixing", source_dir)
+    print(f"Snipper fixing {source_dir} {cut_files=}, {censor_files=}, {output_dir=}")
     if dest_dir == None:
         dest_dir = tempfile.mkdtemp()
         print("[snipper]", "no destination dir was specified so using nonsense destination:", dest_dir)
@@ -70,18 +70,7 @@ def snip_dir(source_dir,  # Sources
     for f, accept in acceptable:
         if os.path.isdir(f) or str(f).endswith("_grade.py"):
             continue
-        # if os.path.isdir(f) or not str(f).endswith(".py") or str(f).endswith("_grade.py"):
-        #     continue
-        # if accept and str(f).endswith(".rst"):
-        #     nrem, cut = censor_file(f, run_files=run_files, run_out_dirs=output_dir, cut_files=cut_files,
-        #                             # solution_list=solution_list,
-        #                             base_path=dest_dir,
-        #                             references=references,
-        #                             license_head=license_head,
-        #                             censor_files=censor_files,
-        #                             **kwargs)
 
-            # print("rst file")
         if accept and (str(f).endswith(".py") or str(f).endswith(".rst")):
             # if f.endswith("rst"):
             #     pass
@@ -109,5 +98,5 @@ def snip_dir(source_dir,  # Sources
             else:
                 if os.path.isdir(rm_file+"/"):
                     shutil.rmtree(rm_file)
-    print("[snipper]", "done")
+    # print("[snipper]", "done")
     return n, cutouts
diff --git a/src/snipper/snipper_main.py b/src/snipper/snipper_main.py
index ff5b29990dbc5d86f0600459a771d49f47e99b39..3ed8374e8ccef5c4f2299bf2e97bcb0878c98890 100644
--- a/src/snipper/snipper_main.py
+++ b/src/snipper/snipper_main.py
@@ -48,8 +48,8 @@ def censor_file(file, run_files=True, run_out_dirs=None, cut_files=True,
         s = s.lstrip()
         lines = s.split("\n")
         for k, l in enumerate(lines):
-            if l.find(" # !") > 0:
-                print(f"{file}:{k}> bad snipper tag, fixing")
+            # if l.find(" # !") > 0:
+            #     print(f"{file}:{k}> bad snipper tag, fixing")
             lines[k] = l.replace("# !", "#!")
 
         try:
diff --git a/src/snipper/version.py b/src/snipper/version.py
index f3b45743bddc02aadc17cb38557a5867e733caf7..86205cbacce07cad520162a70c860826f4692172 100644
--- a/src/snipper/version.py
+++ b/src/snipper/version.py
@@ -1 +1 @@
-__version__ = "0.1.15"
+__version__ = "0.1.17"
diff --git a/tests/demo1_correct/output/tree_a.shell b/tests/demo1_correct/output/tree_a.shell
index f1a6a456de100126a19878a15d33013bfceccef5..ef337701306f375428bccf56d37c77866de56133 100644
--- a/tests/demo1_correct/output/tree_a.shell
+++ b/tests/demo1_correct/output/tree_a.shell
@@ -1,3 +1,13 @@
->>>
 >>> for _ in range(10):
-...     print("hi")
\ No newline at end of file
+...     print("hi")
+... 
+hi
+hi
+hi
+hi
+hi
+hi
+hi
+hi
+hi
+hi
\ No newline at end of file
diff --git a/tests/demo1_correct/output/tree_a_stripped.py b/tests/demo1_correct/output/tree_a_stripped.py
new file mode 100644
index 0000000000000000000000000000000000000000..b3e2198a7426b41ea2b0c6527a271d008de63179
--- /dev/null
+++ b/tests/demo1_correct/output/tree_a_stripped.py
@@ -0,0 +1,8 @@
+# tree.py
+class TreeNode(object): 
+    def __init__(self, x): 
+
+def sorted_array_to_bst(nums):
+    if not nums: 
+        return None 
+    mid_val = len(nums) // 2 
\ No newline at end of file
diff --git a/tests/demo1_correct/output/tree_b.shell b/tests/demo1_correct/output/tree_b.shell
index 922b7549fe26677c3f4f3ad83cefa333527d74ec..3e6d47376e7489f5c0e08e1a4891000eba4a29dc 100644
--- a/tests/demo1_correct/output/tree_b.shell
+++ b/tests/demo1_correct/output/tree_b.shell
@@ -1,7 +1,8 @@
->>>
->>>
 >>> print("hello")
 hello
 >>> def myfun(a):
 ...     return a*2
-...
\ No newline at end of file
+...
+>>>
+>>> print(myfun(4))
+8
\ No newline at end of file
diff --git a/tests/demo1_correct/output/tree_myfile.py b/tests/demo1_correct/output/tree_myfile.py
index ea738ec9b82bee9e93a468c502f1ff17f060bacf..900f89bbfda7f14940aa056d74482ee49e77c072 100644
--- a/tests/demo1_correct/output/tree_myfile.py
+++ b/tests/demo1_correct/output/tree_myfile.py
@@ -1,4 +1,4 @@
-# tree.py
+        # tree.py
         return None 
     mid_val = len(nums) // 2 
     node = TreeNode(nums[mid_val]) 
diff --git a/tests/demo1_correct/output/tree_myfile_stripped.py b/tests/demo1_correct/output/tree_myfile_stripped.py
new file mode 100644
index 0000000000000000000000000000000000000000..900f89bbfda7f14940aa056d74482ee49e77c072
--- /dev/null
+++ b/tests/demo1_correct/output/tree_myfile_stripped.py
@@ -0,0 +1,15 @@
+        # tree.py
+        return None 
+    mid_val = len(nums) // 2 
+    node = TreeNode(nums[mid_val]) 
+    node.left = sorted_array_to_bst(nums[:mid_val])
+    node.right = sorted_array_to_bst(nums[mid_val + 1:]) 
+    return node 
+print("hello world asdfasd")
+
+#!o=a
+def preOrder(node):
+    if not node: 
+        return
+    print(node.val)
+    preOrder(node.left)
\ No newline at end of file
diff --git a/tests/demo1_tmp/output/tree_a.shell b/tests/demo1_tmp/output/tree_a.shell
index f1a6a456de100126a19878a15d33013bfceccef5..ef337701306f375428bccf56d37c77866de56133 100644
--- a/tests/demo1_tmp/output/tree_a.shell
+++ b/tests/demo1_tmp/output/tree_a.shell
@@ -1,3 +1,13 @@
->>>
 >>> for _ in range(10):
-...     print("hi")
\ No newline at end of file
+...     print("hi")
+... 
+hi
+hi
+hi
+hi
+hi
+hi
+hi
+hi
+hi
+hi
\ No newline at end of file
diff --git a/tests/demo1_tmp/output/tree_a_stripped.py b/tests/demo1_tmp/output/tree_a_stripped.py
new file mode 100644
index 0000000000000000000000000000000000000000..b3e2198a7426b41ea2b0c6527a271d008de63179
--- /dev/null
+++ b/tests/demo1_tmp/output/tree_a_stripped.py
@@ -0,0 +1,8 @@
+# tree.py
+class TreeNode(object): 
+    def __init__(self, x): 
+
+def sorted_array_to_bst(nums):
+    if not nums: 
+        return None 
+    mid_val = len(nums) // 2 
\ No newline at end of file
diff --git a/tests/demo1_tmp/output/tree_b.shell b/tests/demo1_tmp/output/tree_b.shell
index 922b7549fe26677c3f4f3ad83cefa333527d74ec..3e6d47376e7489f5c0e08e1a4891000eba4a29dc 100644
--- a/tests/demo1_tmp/output/tree_b.shell
+++ b/tests/demo1_tmp/output/tree_b.shell
@@ -1,7 +1,8 @@
->>>
->>>
 >>> print("hello")
 hello
 >>> def myfun(a):
 ...     return a*2
-...
\ No newline at end of file
+...
+>>>
+>>> print(myfun(4))
+8
\ No newline at end of file
diff --git a/tests/demo1_tmp/output/tree_myfile.py b/tests/demo1_tmp/output/tree_myfile.py
index ea738ec9b82bee9e93a468c502f1ff17f060bacf..900f89bbfda7f14940aa056d74482ee49e77c072 100644
--- a/tests/demo1_tmp/output/tree_myfile.py
+++ b/tests/demo1_tmp/output/tree_myfile.py
@@ -1,4 +1,4 @@
-# tree.py
+        # tree.py
         return None 
     mid_val = len(nums) // 2 
     node = TreeNode(nums[mid_val]) 
diff --git a/tests/demo1_tmp/output/tree_myfile_stripped.py b/tests/demo1_tmp/output/tree_myfile_stripped.py
new file mode 100644
index 0000000000000000000000000000000000000000..900f89bbfda7f14940aa056d74482ee49e77c072
--- /dev/null
+++ b/tests/demo1_tmp/output/tree_myfile_stripped.py
@@ -0,0 +1,15 @@
+        # tree.py
+        return None 
+    mid_val = len(nums) // 2 
+    node = TreeNode(nums[mid_val]) 
+    node.left = sorted_array_to_bst(nums[:mid_val])
+    node.right = sorted_array_to_bst(nums[mid_val + 1:]) 
+    return node 
+print("hello world asdfasd")
+
+#!o=a
+def preOrder(node):
+    if not node: 
+        return
+    print(node.val)
+    preOrder(node.left)
\ No newline at end of file
diff --git a/tests/test_python.py b/tests/test_python.py
index c7ca14ef4468723bc8f8ecc3213aff38dea92a29..17f8e909b375a9beb0b958155431fb2b25fe4a92 100644
--- a/tests/test_python.py
+++ b/tests/test_python.py
@@ -40,7 +40,6 @@ class TestPython(TestCase):
 
     def test_demo2(self):
         from setup_test_files import setup, setup_keep
-        # base = 'demo2'
         setup_keep("demo2/framework.py", "demo2/framework_tmp.txt")
         with open("demo2/framework_tmp.txt") as f:
             tmp = f.read()