diff --git a/demos/.gitignore b/demos/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..1bc4697d1eeab460a7055f492a2da7ad782c06ee
--- /dev/null
+++ b/demos/.gitignore
@@ -0,0 +1 @@
+parser.pdf
diff --git a/demos/Makefile.demo b/demos/Makefile.demo
index 5bf5df40675ab04d25428c271ae5553192edeaec..7eb6eb4ced5e6d45c8fd684eff10a2fefc805c4e 100644
--- a/demos/Makefile.demo
+++ b/demos/Makefile.demo
@@ -35,3 +35,14 @@ show: test
 .PHONY: api
 api: test
 	more $(IMAGE)/parser.mli
+
+# [make view] shows a .pdf image of the LR(1) automaton.
+
+VIEW = $(shell \
+  if command -v open >/dev/null ; then echo open ; else echo evince ; fi)
+
+.PHONY: view
+view: all
+	dune exec ../../src/stage2/main.exe -- --infer --automaton-graph parser.mly && rm -f parser.{ml,mli}
+	dot -Tpdf parser.dot > parser.pdf && rm -f parser.dot
+	$(VIEW) parser.pdf
diff --git a/demos/calc-mini/Makefile b/demos/calc-mini/Makefile
index 5465ca9094670af79f137afd49dd302885eb5892..3b640d4f7b37e7774ccecb2283019c81d0cc650f 100644
--- a/demos/calc-mini/Makefile
+++ b/demos/calc-mini/Makefile
@@ -1,10 +1 @@
 include ../Makefile.demo
-
-# Choosing a PDF viewer.
-VIEW := $(shell \
-  if command -v open >/dev/null ; then echo open ; else echo evince ; fi)
-
-# Viewing a .pdf image of the LR(1) automaton.
-.PHONY: view
-view: all
-	$(VIEW) $(IMAGE)/parser.pdf
diff --git a/demos/calc-mini/Makefile.demo b/demos/calc-mini/Makefile.demo
new file mode 120000
index 0000000000000000000000000000000000000000..88bd4c764ef5a01367a54a15e8cf780266285c28
--- /dev/null
+++ b/demos/calc-mini/Makefile.demo
@@ -0,0 +1 @@
+../Makefile.demo
\ No newline at end of file
diff --git a/demos/calc-mini/dune b/demos/calc-mini/dune
index 721befad345c53698f6972d5d977eb54b43fc31b..d7e98aaa8c66eb4fb16f1d336a431c0cdb8a42e5 100644
--- a/demos/calc-mini/dune
+++ b/demos/calc-mini/dune
@@ -14,22 +14,6 @@
   (name calc)
 )
 
-;; ------------------------------------------------------------------------------
-;; Visualizing the LR(1) automaton.
-
-(rule
-  (target parser.dot)
-  (action
-    (run menhir --infer
-       %{dep:parser.mly}
-       --automaton-graph
-)))
-
-(rule
-  (with-stdout-to parser.pdf
-    (system "dot -Tpdf %{dep:parser.dot}")
-))
-
 ;; ------------------------------------------------------------------------------
 ;; The following declarations are used to test this demo.
 
diff --git a/demos/calc-stratified/Makefile b/demos/calc-stratified/Makefile
index 5465ca9094670af79f137afd49dd302885eb5892..3b640d4f7b37e7774ccecb2283019c81d0cc650f 100644
--- a/demos/calc-stratified/Makefile
+++ b/demos/calc-stratified/Makefile
@@ -1,10 +1 @@
 include ../Makefile.demo
-
-# Choosing a PDF viewer.
-VIEW := $(shell \
-  if command -v open >/dev/null ; then echo open ; else echo evince ; fi)
-
-# Viewing a .pdf image of the LR(1) automaton.
-.PHONY: view
-view: all
-	$(VIEW) $(IMAGE)/parser.pdf
diff --git a/demos/calc-stratified/Makefile.demo b/demos/calc-stratified/Makefile.demo
new file mode 120000
index 0000000000000000000000000000000000000000..88bd4c764ef5a01367a54a15e8cf780266285c28
--- /dev/null
+++ b/demos/calc-stratified/Makefile.demo
@@ -0,0 +1 @@
+../Makefile.demo
\ No newline at end of file
diff --git a/demos/calc-stratified/dune b/demos/calc-stratified/dune
index 89dc2ca44805fa6698ee7ae90e149db093a2ccbe..cab8b753d58856e2159bacb0ead0292e0eded774 100644
--- a/demos/calc-stratified/dune
+++ b/demos/calc-stratified/dune
@@ -14,22 +14,6 @@
   (name calc)
 )
 
-;; ------------------------------------------------------------------------------
-;; Visualizing the LR(1) automaton.
-
-(rule
-  (target parser.dot)
-  (action
-    (run menhir --infer
-       %{dep:parser.mly}
-       --automaton-graph
-)))
-
-(rule
-  (with-stdout-to parser.pdf
-    (system "sed -i.bak 's/LR/TB/;s/landscape/portrait/' %{dep:parser.dot} && dot -Tpdf %{dep:parser.dot}")
-))
-
 ;; ------------------------------------------------------------------------------
 ;; The following declarations are used to test this demo.