diff --git a/.gitignore b/.gitignore
index 336ec0c212d5d5b12985ee19646fae4c94b075b1..a46e2b70462bd196c68062f4dc42aa4f8d757e08 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
 *~
-
 .*.swp
 .merlin
+.vscode
 
 elpi.*
 
diff --git a/Makefile b/Makefile
index 090c890251b6e6fcc484dcc280728b3b16f7c30a..1fa547c69f0259746984877439006bd0d3846253 100644
--- a/Makefile
+++ b/Makefile
@@ -51,11 +51,21 @@ install:
 doc:
 	dune build $(DUNE_OPTS) @doc
 
-doc-sphinx:
+doc-sphinx: doc
 	cp -r docs/base docs/source
-	python docs/engine/engine.py
+	python3 docs/engine/engine.py
 	cd docs && make html
 	rm -rf docs/source
+	cp -r _build/default/_doc/_html/elpi docs/build/html/
+	cp -r _build/default/_doc/_html/elpi-option-legacy-parser docs/build/html/
+	cp -r _build/default/_doc/_html/highlight.pack.js docs/build/html/
+	cp -r _build/default/_doc/_html/odoc.css docs/build/html/
+
+gh-pages: doc-sphinx
+	rm -rf /tmp/gh-pages
+	cp -r docs/build/html/ /tmp/gh-pages
+	git checkout gh-pages
+	rm -rf * && cp -r /tmp/gh-pages/* ./ && rm -rf /tmp/gh-pages && git add . && git commit -m "Updated gh-pages" && git push origin gh-pages && git checkout feature/doc
 
 clean:
 	rm -rf _build
@@ -117,4 +127,4 @@ menhir-complete-errormsgs:
 menhir-strip-errormsgs:
 	sed -e "/^##/d" -i.bak src/parser/error_messages.txt
 
-.PHONY: tests help install build clean
+.PHONY: tests help install build clean gh-pages
diff --git a/docs/base/a.elpi b/docs/base/a.elpi
new file mode 100644
index 0000000000000000000000000000000000000000..61b3d2afbbee668d0826d095656fac8216c692b4
--- /dev/null
+++ b/docs/base/a.elpi
@@ -0,0 +1,7 @@
+type s num -> num.
+type zero num.
+pred ack i:num, i:num, o:num.
+ack zero N V :- !, V = (s N).
+ack M zero V :- !, (s M2) = M, ack M2 (s zero) V.
+ack M N V :- (s M2) = M, (s N2) = N, ack M N2 V2, ack M2 V2 V.
+main :- ack (s (s (s zero))) (s zero) V, print "V =" V.
\ No newline at end of file
diff --git a/docs/base/about.rst b/docs/base/about.rst
index 293eca7ccb847c45d1a48d0fc300317a8cbad623..0bb345c18976e00dd727ad0d5934f82041f80a6d 100644
--- a/docs/base/about.rst
+++ b/docs/base/about.rst
@@ -19,16 +19,24 @@ To match the visuals used in the community (*e.g.* https://coq.inria.fr/distrib/
 
    pip install sphinx-rtd-theme
 
+On debian based systems, one can use the package manager:
+
+.. code-block:: console
+
+   apt install sphinx-doc
+   apt install python3-sphinx-rtd-theme
+   pip install in-place
+
 Extensions
 ----------
 
-This documentation can me use of the following plugins:
+This documentation can make use of the following plugins:
 
 .. code-block:: python
 
    extensions = [
-       'sphinx.ext.intersphinx',
-       'sphinx.ext.githubpages'
+      'sphinx.ext.intersphinx',
+      'sphinx.ext.githubpages'
    ]
 
 Namely, ``intersphinx`` (https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html) can generate links to the documentation of objects in external projects, either explicitly through the external role, or as a fallback resolution for any other cross-reference, and, ``githubpages`` (https://www.sphinx-doc.org/en/master/usage/extensions/githubpages.html#module-sphinx.ext.githubpages) which creates a ``.nojekyll`` file on generated HTML directory to publish the document on GitHub Pages.
@@ -43,3 +51,9 @@ Instead, use the ``doc-sphinx`` target of the source tree's root's ``Makefile``
 .. code-block:: python
 
     make doc-sphinx
+ 
+Or, to build and publish the documentation to github pages:
+
+.. code-block:: python
+
+    make gh-pages
diff --git a/docs/base/index.rst b/docs/base/index.rst
index 3b1be42e9a9947b674cca5aa4c7b33405fa3bd4f..5865ab9711096358250aaf63a66f71b6ebbfc2fb 100644
--- a/docs/base/index.rst
+++ b/docs/base/index.rst
@@ -13,9 +13,9 @@ Welcome to Elpi's documentation!
    about
    playground
 
-.. Indices and tables
-.. ==================
-
-.. * :ref:`genindex`
-.. * :ref:`modindex`
-.. * :ref:`search`
+.. toctree::
+   :maxdepth: 2
+   :caption: API:
+   
+   elpi <elpi/index.html#http://>
+   elpi-option-legacy-parser <elpi-option-legacy-parser/index.html#http://>
diff --git a/docs/base/playground.rst b/docs/base/playground.rst
index 6190a873f46b8f94997dad9a000ea9555c5bef27..91f67b44aa81869b70b8f5e3a5197f8dfa815157 100644
--- a/docs/base/playground.rst
+++ b/docs/base/playground.rst
@@ -1,7 +1,7 @@
 Playground
 ==========
 
-This page will be used to test hooks in order to run ``elpi`` on code snippets and inject its output within ``sphinx`` documentation sources.
+This page is used to test hooks in order to run ``elpi`` on code snippets and inject its output within ``sphinx`` documentation sources.
 
 Prerequisites
 -------------
@@ -22,19 +22,22 @@ It doesn't hurt to check that ``dune`` runs the locally built ``elpi`` correctly
 Syntax
 ------
 
-Elpi code blocks to be evaluated and injection from ``docs/base`` to ``docs/source`` are conventionally denoted in ``reStructuredText`` as ``.. elpi:: FILE``.
+Elpi code blocks to be evaluated and which output is to be injected from ``docs/base`` to ``docs/source`` are conventionally denoted in ``reStructuredText`` as ``.. elpi:: FILE``.
 
 .. literalinclude:: ../../tests/sources/chr.elpi
    :linenos:
    :language: elpi
 
-The injection engine will:
+The injection engine:
 
-* Retrieve all ``.. elpi::`` directives
-* Change them into ``literalinclude`` in the generated source with relevant options
-* Run ``dune exec elpi -- -test FILE`` on the ``FILE`` containing the ``elpi`` snippet, test or example.
-* Capture its output (``stdout``)
-* Create a ``code-block:: console`` just after it to inject the captured console output
+* Retrieves all ``.. elpi::`` directives
+* Changes them into ``literalinclude`` in the generated source with relevant options
+* Runs ``dune exec elpi -- -test FILE`` on the ``FILE`` containing the ``elpi`` snippet, test or example.
+* Captures its output (``stdout``)
+* Creates a ``code-block:: console`` just after it to inject the captured console output
+* Captures its output (``stderr``)
+* Creates a ``code-block:: console`` just after it to inject the captured console erros
+* In case of an assertion option for the ``elpi`` directive, the output is injected only if matched
 
 Result should look as follows:
 
@@ -71,11 +74,156 @@ Result should look as follows:
 
    State:
 
+Regexp Matching
+---------------
+
+This ``elpi`` directive should pass validation:
+
+.. code-block:: console
+   
+   .. elpi:: ./a.elpi
+      :assert: V = s \(.*\)
+
+.. elpi:: ./a.elpi
+   :assert: V = s \(.*\)
+
+This one should fail validation, only a message stating the regexp matching error will be printed:
+
+.. code-block:: console
+   
+   .. elpi:: ./a.elpi
+      :assert: /(?!)/
+
+.. elpi:: ./a.elpi
+   :assert: /(?!)/
+
 Test Bed
 --------
 
+.. elpi:: ../../tests/sources/accumulate_twice1.elpi
+.. elpi:: ../../tests/sources/accumulate_twice2.elpi
 .. elpi:: ../../tests/sources/accumulated.elpi
-
 .. elpi:: ../../tests/sources/ackermann.elpi
-
+.. elpi:: ../../tests/sources/asclause.elpi
+.. elpi:: ../../tests/sources/beta.elpi
+.. elpi:: ../../tests/sources/block.elpi
 .. elpi:: ../../tests/sources/chr.elpi
+.. elpi:: ../../tests/sources/chrGCD.elpi
+.. elpi:: ../../tests/sources/chrLEQ.elpi
+.. elpi:: ../../tests/sources/chr_nokey.elpi
+.. elpi:: ../../tests/sources/chr_nokey2.elpi
+.. elpi:: ../../tests/sources/chr_not_clique.elpi
+.. elpi:: ../../tests/sources/chr_sem.elpi
+.. elpi:: ../../tests/sources/conj2.elpi
+.. elpi:: ../../tests/sources/ctx_loading.elpi
+.. elpi:: ../../tests/sources/cut.elpi
+.. elpi:: ../../tests/sources/cut2.elpi
+.. elpi:: ../../tests/sources/cut3.elpi
+.. elpi:: ../../tests/sources/cut4.elpi
+.. elpi:: ../../tests/sources/cut5.elpi
+.. elpi:: ../../tests/sources/cut6.elpi
+.. elpi:: ../../tests/sources/deep_indexing.elpi
+.. elpi:: ../../tests/sources/discard.elpi
+.. elpi:: ../../tests/sources/elpi_only_llam.elpi
+.. elpi:: ../../tests/sources/end_comment.elpi
+.. elpi:: ../../tests/sources/eta.elpi
+.. elpi:: ../../tests/sources/eta_as.elpi
+.. elpi:: ../../tests/sources/even-odd.elpi
+.. elpi:: ../../tests/sources/findall.elpi
+.. elpi:: ../../tests/sources/fragment_exit.elpi
+.. elpi:: ../../tests/sources/fragment_exit2.elpi
+.. elpi:: ../../tests/sources/fragment_exit3.elpi
+.. elpi:: ../../tests/sources/general_case.elpi
+.. elpi:: ../../tests/sources/general_case2.elpi
+.. elpi:: ../../tests/sources/general_case3.elpi
+.. elpi:: ../../tests/sources/hc_interp.elpi
+.. elpi:: ../../tests/sources/hdclause.elpi
+.. elpi:: ../../tests/sources/heap_discard.elpi
+.. elpi:: ../../tests/sources/ho.elpi
+.. elpi:: ../../tests/sources/hollight.elpi
+.. elpi:: ../../tests/sources/hollight_legacy.elpi
+.. elpi:: ../../tests/sources/hyp_uvar.elpi
+.. elpi:: ../../tests/sources/impl.elpi
+.. elpi:: ../../tests/sources/impl2.elpi
+.. elpi:: ../../tests/sources/index2.elpi
+.. elpi:: ../../tests/sources/io_colon.elpi
+.. elpi:: ../../tests/sources/lambda.elpi
+.. elpi:: ../../tests/sources/lambda2.elpi
+.. elpi:: ../../tests/sources/lambda3.elpi
+.. elpi:: ../../tests/sources/list_as_conj.elpi
+.. elpi:: ../../tests/sources/list_comma.elpi
+.. elpi:: ../../tests/sources/llam.elpi
+.. elpi:: ../../tests/sources/llamchr.elpi
+.. elpi:: ../../tests/sources/map.elpi
+.. elpi:: ../../tests/sources/map_list.elpi
+.. elpi:: ../../tests/sources/map_list_opt.elpi
+.. elpi:: ../../tests/sources/name_builtin.elpi
+.. elpi:: ../../tests/sources/named_clauses00.elpi
+.. elpi:: ../../tests/sources/named_clauses01.elpi
+.. elpi:: ../../tests/sources/named_clauses02.elpi
+.. elpi:: ../../tests/sources/namespaces00.elpi
+.. elpi:: ../../tests/sources/namespaces01.elpi
+.. elpi:: ../../tests/sources/namespaces02.elpi
+.. elpi:: ../../tests/sources/namespaces03.elpi
+.. elpi:: ../../tests/sources/nil_cons.elpi
+.. elpi:: ../../tests/sources/notation.elpi
+.. elpi:: ../../tests/sources/notation_error.elpi
+.. elpi:: ../../tests/sources/notation_legacy.elpi
+.. elpi:: ../../tests/sources/patternunif.elpi
+.. elpi:: ../../tests/sources/patternunif2.elpi
+.. elpi:: ../../tests/sources/pi.elpi
+.. elpi:: ../../tests/sources/pi3.elpi
+.. elpi:: ../../tests/sources/pi5.elpi
+.. elpi:: ../../tests/sources/pnf.elpi
+.. elpi:: ../../tests/sources/polymorphic_variants.elpi
+.. elpi:: ../../tests/sources/printer.elpi
+.. elpi:: ../../tests/sources/queens.elpi
+.. elpi:: ../../tests/sources/quote_syntax.elpi
+.. elpi:: ../../tests/sources/random.elpi
+.. elpi:: ../../tests/sources/reduce_cbn.elpi
+.. elpi:: ../../tests/sources/reduce_cbv.elpi
+.. elpi:: ../../tests/sources/restriction.elpi
+.. elpi:: ../../tests/sources/restriction3.elpi
+.. elpi:: ../../tests/sources/restriction4.elpi
+.. elpi:: ../../tests/sources/restriction5.elpi
+.. elpi:: ../../tests/sources/restriction6.elpi
+.. elpi:: ../../tests/sources/rev.elpi
+.. elpi:: ../../tests/sources/rev14.elpi
+.. elpi:: ../../tests/sources/same_term.elpi
+.. elpi:: ../../tests/sources/self_assignment.elpi
+.. elpi:: ../../tests/sources/set.elpi
+.. elpi:: ../../tests/sources/shorten.elpi
+.. elpi:: ../../tests/sources/shorten2.elpi
+.. elpi:: ../../tests/sources/shorten_aux.elpi
+.. elpi:: ../../tests/sources/shorten_aux2.elpi
+.. elpi:: ../../tests/sources/shorten_builtin.elpi
+.. elpi:: ../../tests/sources/shorten_trie.elpi
+.. elpi:: ../../tests/sources/spill_and.elpi
+.. elpi:: ../../tests/sources/spill_impl.elpi
+.. elpi:: ../../tests/sources/spill_lam.elpi
+.. elpi:: ../../tests/sources/trace.elpi
+.. elpi:: ../../tests/sources/trace2.elpi
+.. elpi:: ../../tests/sources/trace_chr.elpi
+.. elpi:: ../../tests/sources/trace_cut.elpi
+.. elpi:: ../../tests/sources/trace_findall.elpi
+.. elpi:: ../../tests/sources/trail.elpi
+.. elpi:: ../../tests/sources/typeabbrv.elpi
+.. elpi:: ../../tests/sources/typeabbrv1.elpi
+.. elpi:: ../../tests/sources/typeabbrv10.elpi
+.. elpi:: ../../tests/sources/typeabbrv11.elpi
+.. elpi:: ../../tests/sources/typeabbrv12.elpi
+.. elpi:: ../../tests/sources/typeabbrv2.elpi
+.. elpi:: ../../tests/sources/typeabbrv3.elpi
+.. elpi:: ../../tests/sources/typeabbrv4.elpi
+.. elpi:: ../../tests/sources/typeabbrv5.elpi
+.. elpi:: ../../tests/sources/typeabbrv6.elpi
+.. elpi:: ../../tests/sources/typeabbrv7.elpi
+.. elpi:: ../../tests/sources/typeabbrv8.elpi
+.. elpi:: ../../tests/sources/typeabbrv9.elpi
+.. elpi:: ../../tests/sources/uminus.elpi
+.. elpi:: ../../tests/sources/uvar_chr.elpi
+.. elpi:: ../../tests/sources/var.elpi
+.. elpi:: ../../tests/sources/variadic_declare_constraints.elpi
+.. elpi:: ../../tests/sources/w.elpi
+.. elpi:: ../../tests/sources/w_legacy.elpi
+.. elpi:: ../../tests/sources/zebra.elpi
\ No newline at end of file
diff --git a/docs/engine/engine.py b/docs/engine/engine.py
index eb81512f9af3358c9f061b211650a3a374d56880..bbe9d7d40ae8729a5a8e95e65816621ab8599300 100644
--- a/docs/engine/engine.py
+++ b/docs/engine/engine.py
@@ -1,36 +1,69 @@
 #!/usr/bin/env python3
 
-import os, sys, in_place, pathlib, subprocess
+import os, sys, in_place, pathlib, subprocess, re
+
+def check(input, expression):
+    pattern = re.compile(expression, re.IGNORECASE)
+    return pattern.match(input)
 
 def exec(path, base_path):
     file = base_path / path
-    print('  - Executing elpi on', file.as_posix())
+    print('  - Executing elpi on', file.as_posix().rstrip())
     elpi = subprocess.Popen(['dune', 'exec', 'elpi', '--', '-test', file.as_posix()[:-1]], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
     output, errors = elpi.communicate()
     elpi.wait()
     return output, errors
 
 def process(source, base_path):
+    atext = '   :assert:'
     stext = '.. elpi::'
     rtext = '.. literalinclude::'
 
+    file_ = open(source, 'r')
+    lines = file_.readlines()
+
     with in_place.InPlace(source) as file:
+
+        index = 0
+        
         for line in file:
 
+            path = ''
+
             output = ''
             errors = ''
+            matchr = ''
+
+            if line.startswith(atext):
+                index += 1
+                file.write('')
+                continue
 
             if line.startswith(stext):
                 path = line[10:]
-                output, errors = exec(path, base_path)
-                # print('  - STDOUT:')
-                # print(output)
-                # print('  - STDERR:')
-                # print(errors)
 
-            line = line.replace(stext, rtext)
+                output, errors = exec(path, base_path)
+                
+                if index < len(lines)-1:
+                    next = lines[index+1]
+                    
+                    if next.startswith(atext):
+                        
+                        expression = next[12:].rstrip()
+                        
+                        if check(output, expression) is None:
+                            output = ''
+                            errors = ''
+                            matchr = 'Injection failure: result did not pass regexp check (' + expression + ')'
 
-            file.write(line)
+            if line.startswith(stext):
+                block = '**' + path + ':' + '**' + '\n' + '\n'
+                block += line.replace(stext, rtext)
+                block += '   :linenos:' + '\n'
+                block += '   :language: elpi' + '\n'
+                file.write(block)
+            else:
+                file.write(line)
 
             if len(output) > 0:
                 block  = '\n'
@@ -39,7 +72,7 @@ def process(source, base_path):
                 block += output.replace('\n', '\n   ')
                 block += '\n'
                 file.write(block)
-
+                
             if len(errors) > 0:
                 block  = '\n'
                 block += '.. code-block:: console' + '\n'
@@ -48,6 +81,17 @@ def process(source, base_path):
                 block += '\n'
                 file.write(block)
 
+            if len(matchr) > 0:
+                block  = '\n'
+                block += '.. raw:: html' + '\n'
+                block += '\n   '
+                block += '<div class="highlight-console notranslate"><div class="highlight" style="background-color: rgb(248, 148, 148);"><pre>'
+                block += matchr
+                block += '</pre></div></div>'
+                block += '\n'
+                file.write(block)
+            
+            index += 1
 
 def find(path):
     files = sorted(path.glob('**/**/*.rst'))