From eadeaa326215e457ddb935d1a1205e5cc58fd861 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= <hugo@lysator.liu.se>
Date: Tue, 19 Sep 2023 07:05:44 +0200
Subject: [PATCH] Emit code even when parsing failes.

If `parse_puppet` crashed, instead format the the raw code, adding an
error marker on the erroring character if possible. The error message is
also added.
---
 muppet/format.py      | 18 +++++++++++++++---
 static-src/style.scss | 15 +++++++++++++++
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/muppet/format.py b/muppet/format.py
index 3cc0996..9e5be76 100644
--- a/muppet/format.py
+++ b/muppet/format.py
@@ -150,7 +150,6 @@ def format_class(d_type: DefinedType | PuppetClass) -> Tuple[str, str]:
     name, body = format_docstring(d_type.name, d_type.docstring)
     out += body
 
-    out += '<pre class="highlight-muppet"><code class="puppet">'
     # ------ Old ---------------------------------------
     # t = parse_puppet(d_type.source)
     # data = parse(t, 0, ['root'])
@@ -158,11 +157,24 @@ def format_class(d_type: DefinedType | PuppetClass) -> Tuple[str, str]:
     # out += render(renderer, data)
     # ------ New ---------------------------------------
     try:
-        out += parse_puppet(d_type.source, d_type.name)
+        result = parse_puppet(d_type.source, d_type.name)
+        out += '<pre class="highlight-muppet"><code class="puppet">'
+        out += result
+        out += '</code></pre>'
     except ParseError as e:
         logger.error("Parsing %(name)s failed: %(err)s",
                      {'name': d_type.name, 'err': e})
-    out += '</code></pre>'
+        out += f'<div class="error">{e}</div>'
+        out += '<pre><code class="puppet">'
+        if e.pos:
+            out += d_type.source[:e.pos]
+            out += '<span class="error">'
+            out += d_type.source[e.pos]
+            out += '</span>'
+            out += d_type.source[e.pos+1:]
+        else:
+            out += d_type.source
+        out += '</code></pre>'
     return name, out
 
 
diff --git a/static-src/style.scss b/static-src/style.scss
index 57c4387..ec677d7 100644
--- a/static-src/style.scss
+++ b/static-src/style.scss
@@ -183,6 +183,21 @@ ul.toc {
 
 /* -------------------------------------------------- */
 
+div.error {
+	white-space: pre;
+	background: pink;
+	border: 2px solid red;
+	border-radius: 1pt;
+	font-family: mono;
+}
+
+span.error {
+	background: red;
+	color: white;
+}
+
+/* -------------------------------------------------- */
+
 @import "colorscheme_default";
 
 .highlight-pygments {
-- 
GitLab