From 971af254abdcdd06c49850031510da7cbd141e45 Mon Sep 17 00:00:00 2001
From: Tue Herlau <tuhe@dtu.dk>
Date: Sun, 5 Sep 2021 15:02:48 +0200
Subject: [PATCH] Refactor dir snip

---
 dist/codesnipper-0.0.2-py3-none-any.whl       | Bin 0 -> 14584 bytes
 dist/codesnipper-0.0.2.tar.gz                 | Bin 0 -> 13342 bytes
 docs/build_docs.py                            |   8 +-
 .../load_references.cpython-38.pyc            | Bin
 examples/block_processor.py                   |  63 +++++++
 {example => examples}/citations.py            |   0
 examples/cs101_instructor/homework1.py        |  20 +++
 {example => examples}/exercise1.py            |   0
 {example => examples}/latex/br.pdf            | Bin
 {example => examples}/latex/index.aux         |   0
 {example => examples}/latex/index.bbl         |   0
 {example => examples}/latex/index.blg         |   0
 {example => examples}/latex/index.log         |   0
 {example => examples}/latex/index.out         |   0
 {example => examples}/latex/index.pdf         | Bin
 {example => examples}/latex/index.synctex.gz  | Bin
 {example => examples}/latex/index.tex         |   0
 {example => examples}/latex/library.bib       |   0
 {example => examples}/load_references.py      |   2 +-
 {example => examples}/output/citations.py     |   0
 .../output/load_references_a.py               |   2 +-
 .../output/load_references_b.py               |   0
 examples/process_cs101.py                     |  25 +++
 src/codesnipper.egg-info/PKG-INFO             | 158 +++++++++++++++++-
 src/codesnipper.egg-info/SOURCES.txt          |   5 +-
 src/codesnipper.egg-info/requires.txt         |   4 +-
 .../__pycache__/citations.cpython-38.pyc      | Bin 5040 -> 0 bytes
 src/snipper/__pycache__/fix_s.cpython-38.pyc  | Bin 3629 -> 3728 bytes
 src/snipper/block_parsing.py                  |  78 +++++++++
 src/snipper/fix_bf.py                         |   0
 src/snipper/fix_cite.py                       |  65 +++----
 src/snipper/fix_s.py                          | 105 +-----------
 .../{citations.py => load_citations.py}       |   0
 src/snipper/snip_dir.py                       |  10 +-
 src/snipper/snipper_main.py                   |   1 -
 35 files changed, 399 insertions(+), 147 deletions(-)
 create mode 100644 dist/codesnipper-0.0.2-py3-none-any.whl
 create mode 100644 dist/codesnipper-0.0.2.tar.gz
 rename {example => examples}/__pycache__/load_references.cpython-38.pyc (100%)
 create mode 100644 examples/block_processor.py
 rename {example => examples}/citations.py (100%)
 create mode 100644 examples/cs101_instructor/homework1.py
 rename {example => examples}/exercise1.py (100%)
 rename {example => examples}/latex/br.pdf (100%)
 rename {example => examples}/latex/index.aux (100%)
 rename {example => examples}/latex/index.bbl (100%)
 rename {example => examples}/latex/index.blg (100%)
 rename {example => examples}/latex/index.log (100%)
 rename {example => examples}/latex/index.out (100%)
 rename {example => examples}/latex/index.pdf (100%)
 rename {example => examples}/latex/index.synctex.gz (100%)
 rename {example => examples}/latex/index.tex (100%)
 rename {example => examples}/latex/library.bib (100%)
 rename {example => examples}/load_references.py (93%)
 rename {example => examples}/output/citations.py (100%)
 rename {example => examples}/output/load_references_a.py (71%)
 rename {example => examples}/output/load_references_b.py (100%)
 create mode 100644 examples/process_cs101.py
 delete mode 100644 src/snipper/__pycache__/citations.cpython-38.pyc
 create mode 100644 src/snipper/block_parsing.py
 create mode 100644 src/snipper/fix_bf.py
 rename src/snipper/{citations.py => load_citations.py} (100%)

diff --git a/dist/codesnipper-0.0.2-py3-none-any.whl b/dist/codesnipper-0.0.2-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..a3de71167725d94f82ba94271db109d7a5baa198
GIT binary patch
literal 14584
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
LW(J0XrXU^wg_8;?

literal 0
HcmV?d00001

diff --git a/dist/codesnipper-0.0.2.tar.gz b/dist/codesnipper-0.0.2.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..128343f9db99e65419e5a8c62fb3bed6fa91d662
GIT binary patch
literal 13342
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

literal 0
HcmV?d00001

diff --git a/docs/build_docs.py b/docs/build_docs.py
index 02f7791..46e7a45 100644
--- a/docs/build_docs.py
+++ b/docs/build_docs.py
@@ -20,10 +20,8 @@ if __name__ == "__main__":
     from snipper.fix_s import save_s
     from snipper.snipper_main import censor_file
 
-
-    #
-    # EX_BASE = "../examples"
-    # np = EX_BASE + "/new_project"
+    EX_BASE = "../examples"
+    np = EX_BASE + "/latex"
 
     # if os.path.isdir(np):
     #     shutil.rmtree(np)
@@ -40,7 +38,7 @@ if __name__ == "__main__":
     # my_nup(np + "/index.pdf")
     # my_nup(f"{np_basic1}/index.pdf")
     #
-    # # convert.pdf2png(np + "/index.pdf", "./index0.png")
+    convert.pdf2png(np + "/index.pdf", "./index.png", scale_to=600)
     # output = np +"/index_2up.pdf"
     #
     # data = {}
diff --git a/example/__pycache__/load_references.cpython-38.pyc b/examples/__pycache__/load_references.cpython-38.pyc
similarity index 100%
rename from example/__pycache__/load_references.cpython-38.pyc
rename to examples/__pycache__/load_references.cpython-38.pyc
diff --git a/examples/block_processor.py b/examples/block_processor.py
new file mode 100644
index 0000000..c8662f7
--- /dev/null
+++ b/examples/block_processor.py
@@ -0,0 +1,63 @@
+from snipper.fix_s import get_s #!s
+from snipper.block_parsing import block_split
+import textwrap
+import numpy as np
+
+# Implement a sieve here.
+def primes_sieve(limit):
+    limitn = limit+1 #!b
+    primes = range(2, limitn)
+
+    for i in primes:
+        factors = list(range(i, limitn, i))
+        for f in factors[1:]:
+            if f in primes:
+                primes.remove(f)
+    return primes #!b
+#!s
+
+def obscure(blk, fun):
+    blok = block_split(blk, "#!b")
+    lines2 = blok['first'] + fun(blok['block']) + blok['last']
+    s = '\n'.join(lines2)
+    print(s)
+    return s
+
+# driver program
+if __name__ == '__main__':
+    with open(__file__, 'r') as f:
+        s = f.read().splitlines()
+    blk = get_s(s)['']
+
+    def cmnt(lines):
+        whitespace = " " * (len(lines[0]) - len(lines[0].lstrip()))
+        lines = textwrap.dedent("\n".join(lines)).splitlines()
+        lines = ["# " + l for l in lines]
+        return lines, whitespace
+
+    def f1(lines):
+        lines, whitespace = cmnt(lines)
+        lines = [lines[i] for i in np.random.permutation(len(lines))]
+        lines = textwrap.indent("\n".join(lines), whitespace).splitlines()
+        return lines
+
+    obscure(blk, f1)
+
+    def f2(lines):
+        lines, whitespace = cmnt(lines)
+        kp = """#'"[](){},.+-012345679:="""
+        l2 = []
+        for line in lines:
+            line2 = []
+            for w in line.split(' '):
+                if w in ['', 'return', 'if', 'else' '=', '#', "for", "in"]:
+                    line2.append(w)
+                else:
+                    w2 = "".join( [ (t if t in kp else '?') for t in w] )
+                    line2.append(w2)
+            l2.append(" ".join(line2))
+        lines = l2
+        lines = textwrap.indent("\n".join(lines), whitespace).splitlines()
+        return lines
+
+    obscure(blk, f2)
diff --git a/example/citations.py b/examples/citations.py
similarity index 100%
rename from example/citations.py
rename to examples/citations.py
diff --git a/examples/cs101_instructor/homework1.py b/examples/cs101_instructor/homework1.py
new file mode 100644
index 0000000..49ed989
--- /dev/null
+++ b/examples/cs101_instructor/homework1.py
@@ -0,0 +1,20 @@
+def myfun(): #!s
+    """
+    Simple aux references \ref{eq1} in \ref{sec1}.
+    Simple bibtex citations: \cite{bertsekasII} and \cite[Somewhere around the middle]{herlau}
+
+    Example of custom command (reference notes)
+    > \nref{fig1}
+
+    Other example of custom command (reference assignment)
+    > \aref2{sec1}
+    """
+    print("See \\ref{sec1}")  # Also works.
+    return 42 #!s
+
+def fun1(l1, l2):
+    s1 = sum(l1) #!s
+    s2 = sum(l2)
+    print("Hello worlds!") #!s
+    return s1 + s2
+
diff --git a/example/exercise1.py b/examples/exercise1.py
similarity index 100%
rename from example/exercise1.py
rename to examples/exercise1.py
diff --git a/example/latex/br.pdf b/examples/latex/br.pdf
similarity index 100%
rename from example/latex/br.pdf
rename to examples/latex/br.pdf
diff --git a/example/latex/index.aux b/examples/latex/index.aux
similarity index 100%
rename from example/latex/index.aux
rename to examples/latex/index.aux
diff --git a/example/latex/index.bbl b/examples/latex/index.bbl
similarity index 100%
rename from example/latex/index.bbl
rename to examples/latex/index.bbl
diff --git a/example/latex/index.blg b/examples/latex/index.blg
similarity index 100%
rename from example/latex/index.blg
rename to examples/latex/index.blg
diff --git a/example/latex/index.log b/examples/latex/index.log
similarity index 100%
rename from example/latex/index.log
rename to examples/latex/index.log
diff --git a/example/latex/index.out b/examples/latex/index.out
similarity index 100%
rename from example/latex/index.out
rename to examples/latex/index.out
diff --git a/example/latex/index.pdf b/examples/latex/index.pdf
similarity index 100%
rename from example/latex/index.pdf
rename to examples/latex/index.pdf
diff --git a/example/latex/index.synctex.gz b/examples/latex/index.synctex.gz
similarity index 100%
rename from example/latex/index.synctex.gz
rename to examples/latex/index.synctex.gz
diff --git a/example/latex/index.tex b/examples/latex/index.tex
similarity index 100%
rename from example/latex/index.tex
rename to examples/latex/index.tex
diff --git a/example/latex/library.bib b/examples/latex/library.bib
similarity index 100%
rename from example/latex/library.bib
rename to examples/latex/library.bib
diff --git a/example/load_references.py b/examples/load_references.py
similarity index 93%
rename from example/load_references.py
rename to examples/load_references.py
index 9718dde..aad5a0f 100644
--- a/example/load_references.py
+++ b/examples/load_references.py
@@ -3,7 +3,7 @@ import os
 
 def reference_example():
     # Load references and insert them.
-    from snipper.citations import get_bibtex, get_aux #!s=a
+    from snipper.load_citations import get_bibtex, get_aux #!s=a
     bibfile = "latex/library.bib"
     auxfile = 'latex/index.aux'
     bibtex = get_bibtex(bibfile)
diff --git a/example/output/citations.py b/examples/output/citations.py
similarity index 100%
rename from example/output/citations.py
rename to examples/output/citations.py
diff --git a/example/output/load_references_a.py b/examples/output/load_references_a.py
similarity index 71%
rename from example/output/load_references_a.py
rename to examples/output/load_references_a.py
index 304c800..672cac2 100644
--- a/example/output/load_references_a.py
+++ b/examples/output/load_references_a.py
@@ -1,5 +1,5 @@
 # load_references.py
-    from snipper.citations import get_bibtex, get_aux 
+    from snipper.load_citations import get_bibtex, get_aux
     bibfile = "latex/library.bib"
     auxfile = 'latex/index.aux'
     bibtex = get_bibtex(bibfile)
diff --git a/example/output/load_references_b.py b/examples/output/load_references_b.py
similarity index 100%
rename from example/output/load_references_b.py
rename to examples/output/load_references_b.py
diff --git a/examples/process_cs101.py b/examples/process_cs101.py
new file mode 100644
index 0000000..0268b19
--- /dev/null
+++ b/examples/process_cs101.py
@@ -0,0 +1,25 @@
+def main():
+    from snipper.snip_dir import snip_dir
+    from snipper.load_citations import get_aux, get_bibtex
+    bibfile = get_bibtex('latex/library.bib')
+    auxfile = get_aux('latex/index.aux')
+
+    references = dict(bibtex=bibfile,
+                      aux=auxfile,
+                      commands=[
+                          dict(command='\\aref2', output="(Assignment 2, \\ref{%s})", aux=auxfile),
+                          dict(command='\\href', output="\cite[\\ref{%s}]{herlau}", aux=auxfile),
+                        ]
+                      )
+
+
+    output = snip_dir(source_dir="./cs101_instructorm", dest_dir="./cs101_students", output_dir="./cs101_output",
+             references=references,
+             )
+
+    a = 234
+
+
+
+if __name__ == "__main__":
+    main()
\ No newline at end of file
diff --git a/src/codesnipper.egg-info/PKG-INFO b/src/codesnipper.egg-info/PKG-INFO
index 487bc49..070de1a 100644
--- a/src/codesnipper.egg-info/PKG-INFO
+++ b/src/codesnipper.egg-info/PKG-INFO
@@ -1,11 +1,11 @@
 Metadata-Version: 2.1
 Name: codesnipper
-Version: 0.0.1
+Version: 0.0.2
 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
 Author-email: tuhe@dtu.dk
-License: UNKNOWN
+License: MIT
 Project-URL: Bug Tracker, https://lab.compute.dtu.dk/tuhe/snipper/issues
 Platform: UNKNOWN
 Classifier: Programming Language :: Python :: 3
@@ -15,8 +15,158 @@ Requires-Python: >=3.8
 Description-Content-Type: text/markdown
 License-File: LICENSE
 
-# Snip
-A lightweight framework for removing code from student solutions. Currently used at DTU. 
+# Snipper
+A lightweight framework for removing code from student solutions.
+## Installation
+```console
+pip install codesnipper
+```
+## What it does
+This project address the following three challenges for administering a python-based course
 
+ - You need to maintain a (working) version for debugging as well as a version handed out to students (with code missing)
+ - You ideally want to make references in source code to course material *"(see equation 2.1 in exercise 5)"* but these tend to go out of date
+ - You want to include code snippets and code output in lectures notes/exercises/beamer slides
+ - You want to automatically create student solutions
 
+This framework address these problems and allow you to maintain a **single**, working project repository. 
+
+The project is currently used in **02465** at DTU. An example of student code can be found at:
+ - https://gitlab.gbar.dtu.dk/02465material/02465students/blob/master/irlc/ex02/dp.py
+
+A set of lectures notes where all code examples/output are automatically generated from the working repository can be found a
+- https://lab.compute.dtu.dk/tuhe/books (see **Sequential decision making**)
+ 
+## How it works
+The basic functionality is quite simple. You start with your working script in your private repository and add special tags to the script. 
+In this case I have added the tags `#!b` (cut a block) and `#!f` (cut function scope). 
+```python
+def myfun(): #!f The error I am going to raise
+    """ The function docstring will not be removed"""
+    print("This is a function")
+    return 42
+    
+def a_long_function():
+    a = 234
+    print("a line")
+    print("a line") #!b
+    print("a line")
+    print("a line") #!b Insert three missing print statements. 
+    print("a line")
+    return a
+    
+if __name__ == "__main__":
+    myfun()
+```
+This will produce the following file:
+```python
+def myfun():
+    """ The function docstring will not be removed"""
+    # TODO: 2 lines missing.
+    raise NotImplementedError("The error I am going to raise")
+    
+def a_long_function():
+    a = 234
+    print("a line")
+    # TODO: 3 lines missing.
+    raise NotImplementedError("Insert three missing print statements.")
+    print("a line")
+    return a
+    
+if __name__ == "__main__":
+    myfun()
+```
+You can also use the framework to capture code snippets, outputs and interactive python output. 
+To do this, save the following in `foo.py`
+```python
+def myfun(): #!s This snippet will be saved to foo.py in the output directory. 
+    print("Hello") #!s 
+
+print("Do not capture me") 
+for i in range(4): #!o
+    print("Output", i)
+print("Goodbuy world") #!o
+print("don't capture me")
+
+# Interactive pythong example
+print("Hello World") #!i #!i # this is a single-line cutout.
+````
+These block-tags will create a file `foo.py` (in the output directory) containing
+```python
+def myfun():
+    print("Hello") 
+```
+A file `foo.txt` containing the captured output
+```txt
+Output 0
+Output 1
+Output 2
+Output 3
+Goodbuy world
+```
+and a typeset version of an interactive python session in `foo.pyi` (use `pycon` in minted; this gitlab server appears not to support `pycon`)
+```pycon
+>>> print("hello world")
+Hello World"
+```
+All these files can be directly imported into `LaTeX` using e.g. `minted`: You never need to mix `LaTeX` code and python again!
+
+
+## References: 
+Bibliography references can be loaded from `references.bib`-files and in-document references from the `.aux` file. 
+For this example, we will insert references shown in the `examples/latex/index.tex`-document. To do so, we can use these tags:
+```python
+def myfun(): #!s
+    """
+    To solve this exercise, look at \ref{eq1} in \ref{sec1}.
+    You can also look at \cite{bertsekasII} and \cite{herlau}
+    More specifically, look at \cite[Equation 117]{bertsekasII} and \cite[\ref{fig1}]{herlau}
+
+    We can also write a special tag to reduce repetition: \nref{fig1} and \nref{sec1}.
+    """
+    return 42 #!s
+
+```
+We can manually compile this example by first loading the aux-files and the bibliographies as follows:
+```python 
+# load_references.py
+    from snipper.citations import get_bibtex, get_aux 
+    bibfile = "latex/library.bib"
+    auxfile = 'latex/index.aux'
+    bibtex = get_bibtex(bibfile)
+    aux = get_aux(auxfile) 
+```
+Next, we load the python file containing the reference code and fix all references based on the aux and bibliography data. 
+```python 
+# load_references.py
+    file = "citations.py" 
+    with open(file, 'r') as f:
+        lines = f.read().splitlines()
+    lines = fix_aux(lines, aux=aux)
+    lines = fix_aux_special(lines, aux=aux, command='\\nref', bibref='herlau')
+    lines = fix_bibtex(lines, bibtex=bibtex)
+    with open('output/citations.py', 'w') as f:
+        f.write("\n".join(lines)) 
+```
+The middle command is a convenience feature: It allows us to specify a special citation command `\nref{..}` which always compiles to `\cite[\ref{...}]{herlau}`. This is useful if e.g. `herlau` is the bibtex key for your lecture notes. The result is as follows:
+```python 
+"""
+References:
+  [Ber07] Dimitri P. Bertsekas. Dynamic Programming and Optimal Control, Vol. II. Athena Scientific, 3rd edition, 2007. ISBN 1886529302.
+  [Her21] Tue Herlau. Sequential decision making. (See 02465_Notes.pdf), 2021.
+"""
+def myfun(): #!s
+    """
+    To solve this exercise, look at eq. (1) in Section 1.
+    You can also look at (Ber07) and (Her21)
+    More specifically, look at (Ber07, Equation 117) and (Her21, Figure 1)
+
+    We can also write a special tag to reduce repetition: (Her21, Figure 1) and (Her21, Section 1).
+    """
+    return 42 #!s
+```
+Note this example uses the low-level api. Normally you would just pass the bibtex and aux-file to the main censor-file command.
+
+## Additional features:
+-  You can name tags using `#!s=bar` to get a `foo_bar.py` snippet. This is useful when you need to cut multiple sessions. This also works for the other tags. 
 
diff --git a/src/codesnipper.egg-info/SOURCES.txt b/src/codesnipper.egg-info/SOURCES.txt
index 8b9ec96..0064f64 100644
--- a/src/codesnipper.egg-info/SOURCES.txt
+++ b/src/codesnipper.egg-info/SOURCES.txt
@@ -9,5 +9,8 @@ src/codesnipper.egg-info/dependency_links.txt
 src/codesnipper.egg-info/requires.txt
 src/codesnipper.egg-info/top_level.txt
 src/snipper/__init__.py
+src/snipper/citations.py
+src/snipper/fix_cite.py
+src/snipper/fix_s.py
 src/snipper/snip_dir.py
-src/snipper/snipper.py
\ No newline at end of file
+src/snipper/snipper_main.py
\ No newline at end of file
diff --git a/src/codesnipper.egg-info/requires.txt b/src/codesnipper.egg-info/requires.txt
index 7f7afbf..4ba7d8f 100644
--- a/src/codesnipper.egg-info/requires.txt
+++ b/src/codesnipper.egg-info/requires.txt
@@ -1 +1,3 @@
-jinja2
+pexpect
+wexpect
+pybtex
diff --git a/src/snipper/__pycache__/citations.cpython-38.pyc b/src/snipper/__pycache__/citations.cpython-38.pyc
deleted file mode 100644
index 9a647f415713b55177e96ceff6c8c791938806ce..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5040
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
Q2=lOTsB?I5@pHHX0KU?#RsaA1

diff --git a/src/snipper/__pycache__/fix_s.cpython-38.pyc b/src/snipper/__pycache__/fix_s.cpython-38.pyc
index a4e3cf8604fe8f78dcdcc41bf88f448690de8363..b161b2c89e36fa9e9f5a4b97990c7c3ba4833196 100644
GIT binary patch
delta 583
zcmZ20GeMR&l$V!_fq{YH?go>@dmDL=Ffj=*O}@;u*^n!RA)Be_MhRmI*8-**h8mU>
zhE^s?hJ}pHjEoE=%qiR*jLl3<j5RDZT-i($7>nE{_cPm?vefW&FsAVIGS%|d@TTxe
zGAv+S$iT=@!&JlD%vi&l!e_%!!yC*{!;r#I!vZp|hB<|QG9!yHuYe6hJ3~8T8dHj3
ziqK?57EwiE8-^O@6cHPS8onBa8ZJqO8t!JM7^WKL6j88@*yL~)Yh7L&km=0Lj5W+)
z)7fj7Q^ai;YS>fQBtiNmKx%^-QW%06G$l9hXSu{AcZ-p$O421WMIkT0L?JCRFGV3Y
zu_QSoGcR4CBr$#RME0$WQIp*{R2dy6=W-Y`YENFsp(V>!B*4JHaErB|C^N65NEXEA
zbgf8EEhx#%&zpRa!$T~JDbpy5Da+^<Q;ty-Q?gN!E=bX2eNI_Mm&v}I3hay=jAD#j
z%$xH#wHX<sCePxEVKklmol8qHn1O+zm=6>UOdO1Sj3SIIi~@`zj72t+t++3-7HKgs
zFihs>k!G}+tj#0CXgS$~M_Vh3E5Ed)ptK}DC9^1sGc7YGHNGIRBqNGFIX|x?HLs*d
zpMilPiYX^2YVuqjImY<Odw8T7JtyDb31-xqtix;17&SSESD)L4fq|jO5kz=SUdAgY
vW(8tef(Rav>lw?63_!Nu;k6RC<KW_8;!tMc<zVJv6kz0H<YVMwVPOOS*H($G

delta 561
zcmbOryH<ubl$V!_fq{WR|Bi8D^hVwzOiV8rCtqgT%*j&2mCZDPu}E(6c4pgp#u}au
z#uTnzrdr+_-V|<0h6PLu85kLAm}+>N8Ebe`cx)JIc!L>g7*ZH&SX!AR8ETkQcx@PJ
z7;3muIK&xJ7@%T&HVo|y?Tl$mDf}q{EgZFcHGDM;H7t@0HLT4{F-$egDS|d2y+Sq&
zU>Pn+h8pf>CLXYqFjz`tay^T+F1HQHa^_~n8fLKN>^00OqBaaQ>?v$u%f&!ygBem7
zf*CZ$H$P{&#5DOj`&PzVlY2Q-8EqzS<}hZ|n*5wYi;cNRfPsNwvL2_0*e#|^qbQ~<
zqgzZlMo~=3Mn$>|3=C0|dpKno?Iy3{RA6M<e34U|kuhxYU#=KN<H=FnT9W<@3=GA5
zpb%u@VB}*IVPs(xU=(32vYI@X`;z=EMy_9s`Y-?f|Np;;k%58X7Gr!BvtB{vEyi+9
z?jozn6L@48%_pzr(e}K>m0wy?P+Ah7l38?%Gc7YGHNGIRB;yu)a(-S(YF<f^KFBRh
zIXSnO^Gi!^F{TxPEQJvKAd}gO6U$QLi=!ti@=7!MOt$3>X0)C>k=LH_*5r%4`rK9w
z3=BmMAi`%dH=mq@1&C=5B6vW$8Ov_578GUXl}xthvl6%B;NoE7P-fxfVCG>IVB})t
KW8`9CVFUop^@~{m

diff --git a/src/snipper/block_parsing.py b/src/snipper/block_parsing.py
new file mode 100644
index 0000000..0b1009c
--- /dev/null
+++ b/src/snipper/block_parsing.py
@@ -0,0 +1,78 @@
+def f2(lines, tag, i=0, j=0):
+    for k in range(i, len(lines)):
+        index = lines[k].find(tag, j if k == i else 0)
+        if index >= 0:
+            return k, index
+    return None, None
+
+
+def block_iterate(lines, tag):
+    contents = {'joined': lines}
+    while True:
+        contents = block_split(contents['joined'], tag)
+        if contents is None:
+            break
+
+        yield  contents
+
+
+def block_split(lines, tag):
+    stag = tag[:2]  # Start of any next tag.
+
+    def join(contents):
+        return contents['first'] + [contents['block'][0] + contents['post1']] + contents['block'][1:-1] \
+                + [contents['block'][-1] + contents['post2']] + contents['last']
+    contents = {}
+    i, j = f2(lines, tag)
+
+    def get_tag_args(line):
+        k = line.find(" ")
+        tag_args = (line[:k + 1] if k >= 0 else line)[len(tag):]
+        if len(tag_args) == 0:
+            return {'': ''}  # No name.
+        tag_args = dict([t.split("=") for t in tag_args.split(";")])
+        return tag_args
+
+    if i is None:
+        return None
+    else:
+        start_tag_args = get_tag_args(lines[i][j:])
+        START_TAG = f"{tag}={start_tag_args['']}" if '' in start_tag_args else tag
+        END_TAG = START_TAG
+        i2, j2 = f2(lines, END_TAG, i=i, j=j+1)
+        if i2 == None:
+            END_TAG = tag
+            i2, j2 = f2(lines, END_TAG, i=i, j=j+1)
+        if i2 == None:
+            print("\n".join( lines[i:]))
+            raise Exception("Did not find matching tag", tag)
+
+
+    if i == i2:
+        # Splitting a single line. To reduce confusion, this will be treated slightly differently:
+        l2 = lines[:i] + [lines[i][:j2], lines[i][j2:]] + lines[i2+1:]
+        c2 = block_split(l2, tag=tag)
+        c2['block'].pop()
+        c2['joined'] = join(c2)
+        return c2
+    else:
+        contents['first'] = lines[:i]
+        contents['last'] = lines[i2+1:]
+
+        def argpost(line, j):
+            nx_tag = line.find(stag, j+1)
+            arg1 = line[j+len(tag):nx_tag]
+            if nx_tag >= 0:
+                post = line[nx_tag:]
+            else:
+                post = ''
+            return arg1, post
+
+        contents['arg1'], contents['post1'] = argpost(lines[i], j)
+        contents['arg2'], contents['post2'] = argpost(lines[i2], j2)
+        blk = [lines[i][:j]] + lines[i+1:i2] + [lines[i2][:j2]]
+        contents['block'] = blk
+        contents['joined'] = join(contents)
+        contents['start_tag_args'] = start_tag_args
+        contents['name'] = start_tag_args['']
+        return contents
\ No newline at end of file
diff --git a/src/snipper/fix_bf.py b/src/snipper/fix_bf.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/snipper/fix_cite.py b/src/snipper/fix_cite.py
index 475e44d..7fbc1b4 100644
--- a/src/snipper/fix_cite.py
+++ b/src/snipper/fix_cite.py
@@ -1,34 +1,10 @@
-from snipper.citations import find_tex_cite
+from snipper.load_citations import find_tex_cite
 from snipper.snipper_main import COMMENT
 
-def fix_references(lines, info, strict=True):
-    for cmd in info['new_references']:
-        lines = fix_single_reference(lines, cmd, info['new_references'][cmd], strict=strict)
-    return lines
 
-def fix_single_reference(lines, cmd, aux, strict=True):
-    references = aux
-    s = "\n".join(lines)
-    i = 0
-    while True:
-        (i, j), reference, txt = find_tex_cite(s, start=i, key=cmd)
-        if i < 0:
-            break
-        if reference not in references:
-            er = "cref label not found for label: " + reference
-            if strict:
-                raise IndexError(er)
-            else:
-                print(er)
-                continue
-        r = references[reference]
-        rtxt = r['nicelabel']
-        s = s[:i] + rtxt + s[j + 1:]
-        i = i + len(rtxt)
-        print(cmd, rtxt)
-
-    lines = s.splitlines(keepends=False)
-    return lines
+def fix_citations():
+    # This should be the master function.
+    pass
 
 
 def fix_aux_special(lines, aux, command='\\nref', bibref='herlau'):
@@ -70,4 +46,35 @@ def fix_bibtex(lines, bibtex):
         s = s[:i] + "References:\n" + "\n".join(all_refs) +"\n"+ s[i:]
 
     # s = s.replace(cpr, info['code_copyright'])
-    return s.splitlines()
\ No newline at end of file
+    return s.splitlines()
+
+
+
+def fix_references(lines, info, strict=True):
+    for cmd in info['new_references']:
+        lines = fix_single_reference(lines, cmd, info['new_references'][cmd], strict=strict)
+    return lines
+
+def fix_single_reference(lines, cmd, aux, strict=True):
+    references = aux
+    s = "\n".join(lines)
+    i = 0
+    while True:
+        (i, j), reference, txt = find_tex_cite(s, start=i, key=cmd)
+        if i < 0:
+            break
+        if reference not in references:
+            er = "cref label not found for label: " + reference
+            if strict:
+                raise IndexError(er)
+            else:
+                print(er)
+                continue
+        r = references[reference]
+        rtxt = r['nicelabel']
+        s = s[:i] + rtxt + s[j + 1:]
+        i = i + len(rtxt)
+        print(cmd, rtxt)
+
+    lines = s.splitlines(keepends=False)
+    return lines
\ No newline at end of file
diff --git a/src/snipper/fix_s.py b/src/snipper/fix_s.py
index 0eed3c8..b8f1d9b 100644
--- a/src/snipper/fix_s.py
+++ b/src/snipper/fix_s.py
@@ -1,79 +1,6 @@
-import functools
 from collections import defaultdict
-from snipper.snipper_main import full_strip, block_process
-
-def f2(lines, tag, i=0, j=0):
-    for k in range(i, len(lines)):
-        index = lines[k].find(tag, j if k == i else 0)
-        if index >= 0:
-            return k, index
-    return None, None
-
-def block_iterate(lines, tag):
-    contents = {'joined': lines}
-    while True:
-        contents = block_split(contents['joined'], tag)
-        if contents is None:
-            break
-
-        yield  contents
-
-def block_split(lines, tag):
-    stag = tag[:2]  # Start of any next tag.
-
-    def join(contents):
-        return contents['first'] + [contents['block'][0] + contents['post1']] + contents['block'][1:-1] \
-                + [contents['block'][-1] + contents['post2']] + contents['last']
-    contents = {}
-    i, j = f2(lines, tag)
-
-    def get_tag_args(line):
-        k = line.find(" ")
-        tag_args = (line[:k + 1] if k >= 0 else line)[len(tag):]
-        if len(tag_args) == 0:
-            return {'': ''}  # No name.
-        tag_args = dict([t.split("=") for t in tag_args.split(";")])
-        return tag_args
-
-    if i is None:
-        return None
-    else:
-        start_tag_args = get_tag_args(lines[i][j:])
-        START_TAG = f"{tag}={start_tag_args['']}" if '' in start_tag_args else tag
-        END_TAG = START_TAG
-        i2, j2 = f2(lines, END_TAG, i=i, j=j+1)
-        if i2 == None:
-            END_TAG = tag
-            i2, j2 = f2(lines, END_TAG, i=i, j=j+1)
-
-    if i == i2:
-        # Splitting a single line. To reduce confusion, this will be treated slightly differently:
-        l2 = lines[:i] + [lines[i][:j2], lines[i][j2:]] + lines[i2+1:]
-        c2 = block_split(l2, tag=tag)
-        c2['block'].pop()
-        c2['joined'] = join(c2)
-        return c2
-    else:
-        contents['first'] = lines[:i]
-        contents['last'] = lines[i2+1:]
-
-        def argpost(line, j):
-            nx_tag = line.find(stag, j+1)
-            arg1 = line[j+len(tag):nx_tag]
-            if nx_tag >= 0:
-                post = line[nx_tag:]
-            else:
-                post = ''
-            return arg1, post
-
-        contents['arg1'], contents['post1'] = argpost(lines[i], j)
-        contents['arg2'], contents['post2'] = argpost(lines[i2], j2)
-        blk = [lines[i][:j]] + lines[i+1:i2] + [lines[i2][:j2]]
-        contents['block'] = blk
-        contents['joined'] = join(contents)
-        contents['start_tag_args'] = start_tag_args
-        contents['name'] = start_tag_args['']
-        return contents
+import os
+from snipper.block_parsing import block_iterate
 
 
 def get_s(lines):
@@ -86,8 +13,6 @@ def get_s(lines):
         output[name] = [l for c in co for l in c['block']]
     return output
 
-import os
-
 def save_s(lines, output_dir, file_path): # save file snips to disk
     content = get_s(lines)
     if not os.path.isdir(output_dir):
@@ -99,30 +24,6 @@ def save_s(lines, output_dir, file_path): # save file snips to disk
         with open(output_dir + "/" + os.path.basename(file_path)[:-3] + ("_" + name if len(name) > 0 else name) + ".py", 'w') as f:
             f.write(out)
 
-        # out = "\n".join([f"# {include_path_base}"] + ["\n".join(v[1]) for v in c if v[0] == outf])
-        # with open(outf, 'w') as f:
-        #     f.write(out)
-
-    # def block_fun(lines, start_extra, end_extra, art, output, **kwargs):
-    #     outf = output + ("_" + art if art is not None and len(art) > 0 else "") + ".py"
-    #     lines = full_strip(lines)
-    #     return lines, [outf, lines]
-    # try:
-    #     a,b,c,_ = block_process(lines, tag="#!s", block_fun=functools.partial(block_fun, output=output))
-    #     if len(c)>0:
-    #         kvs= { v[0] for v in c}
-    #         for outf in kvs:
-    #             out = "\n".join([f"# {include_path_base}"]  + ["\n".join(v[1]) for v in c if v[0] == outf] )
-    #             with open(outf, 'w') as f:
-    #                 f.write(out)
-    #
-    # except Exception as e:
-    #     print("lines are")
-    #     print("\n".join(lines))
-    #     print("Bad thing in #!s command in file", file)
-    #     raise e
-    # return lines
-
 s1 = """
 L1
 L2 #!s=a
@@ -147,5 +48,3 @@ if __name__ == "__main__":
     # contents = block_split(s1.splitlines(), tag="#!s")
     # contents = block_split(contents['joined'], tag="#!s")
     # lines2 = contents['first'] +
-    a = 234
-    pass
\ No newline at end of file
diff --git a/src/snipper/citations.py b/src/snipper/load_citations.py
similarity index 100%
rename from src/snipper/citations.py
rename to src/snipper/load_citations.py
diff --git a/src/snipper/snip_dir.py b/src/snipper/snip_dir.py
index 0a68a9d..15657af 100644
--- a/src/snipper/snip_dir.py
+++ b/src/snipper/snip_dir.py
@@ -5,7 +5,15 @@ import time
 import fnmatch
 
 
-def snip_dir(source_dir, dest_dir, exclude=None, clean_destination_dir=True):
+def snip_dir(source_dir,  # Sources
+             dest_dir,  # Will write to this directory
+             output_dir=None, # Where snippets are going to be stored
+             references=None, # Reference database
+             exclude=None, clean_destination_dir=True):
+
+    if references == None:
+        references = dict(aux=None, bibtex=None,  commands=[])
+
     if exclude == None:
         exclude = []
     if not os.path.exists(dest_dir):
diff --git a/src/snipper/snipper_main.py b/src/snipper/snipper_main.py
index 1886033..dc6bbdc 100644
--- a/src/snipper/snipper_main.py
+++ b/src/snipper/snipper_main.py
@@ -315,7 +315,6 @@ def censor_code(lines, keep=True):
 
 
 
-
 def censor_file(file, info, paths, run_files=True, run_out_dirs=None, cut_files=True, solution_list=None,
                 censor_files=True,
                 include_path_base=None,
-- 
GitLab