summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--browset.css8
-rwxr-xr-xbrowset.py3
-rw-r--r--mime/highlightedcode.py45
3 files changed, 56 insertions, 0 deletions
diff --git a/browset.css b/browset.css
index c729e54..f738943 100644
--- a/browset.css
+++ b/browset.css
@@ -26,3 +26,11 @@ Preformatted {
 Preformatted > Static {
 		width: auto;
 }
+HighlightedCode {
+	overflow: auto;
+	max-height: 100%;
+}
+HighlightedCode > * {
+	width: auto;
+	height: auto;
+}
diff --git a/browset.py b/browset.py
index 3e65fff..37e04b1 100755
--- a/browset.py
+++ b/browset.py
@@ -6,6 +6,7 @@ from rich.markdown import Markdown
 from textual.binding import Binding
 from mime.gemtext import Gemtext
 from mime.plaintext import Plaintext
+from mime.highlightedcode import HighlightedCode,mimetolexer
 from protocol.gemini import GeminiProtocol
 
 class Browset(App):
@@ -72,6 +73,8 @@ class Browset(App):
         self.query_one("#content").remove()
         if "text/gemini" in mime:
           content = Gemtext(fp=fp, id="content")
+        elif mime in mimetolexer:
+          content = HighlightedCode(fp=fp, id="content", mime=mime)
         else:
           content = Plaintext(fp=fp, id="content")
         self.mount(content)
diff --git a/mime/highlightedcode.py b/mime/highlightedcode.py
new file mode 100644
index 0000000..63defef
--- /dev/null
+++ b/mime/highlightedcode.py
@@ -0,0 +1,45 @@
+from textual.widgets import Static
+from textual.containers import Container
+from rich.syntax import Syntax
+
+# mime list from gemini://geminispace.info/statistics
+mimetolexer = {
+    "text/x-diff": "diff",
+    "text/x-csrc": "c",
+    "text/x-python": "python",
+    "text/markdown": "markdown",
+    "text/x-patch": "diff",
+    "text/x-c++src": "cpp",
+    "text/x-pascal": "pascal",
+    "text/x-c++hdr": "cpp",
+    "text/x-go": "go",
+    "text/x-rust": "rust",
+    "text/css": "css",
+    "text/x-php": "php",
+    # Hopefully, future handlers will take care of these mimes first.
+    "application/json": "json",
+    "text/html": "html",
+    "application/xml": "xml",
+    "application/atom+xml": "xml",
+    "text/xml": "xml",
+    "image/svg+xml": "xml",
+}
+
+class HighlightedCode(Static):
+    """Plaintext widget."""
+
+    def __init__(self, fp, id, mime):
+        super().__init__(id=id)
+        self.addblock(fp, mime)
+
+    def addblock(self, fp, mime):
+        code = ""
+        # Read the whole file first, then render it all.
+        # Hopefully not a problem, because source code should have terminal length.
+        for lin in fp:
+            line = lin
+            if type(line) is bytes:
+                line = line.decode("UTF-8")
+            code += line
+        lexer = mimetolexer[mime]
+        self.mount(Static(Syntax(code,lexer=lexer)))