mirror of
https://github.com/thomiceli/opengist.git
synced 2026-08-07 07:14:49 +00:00
Add mermaid (.mmd) file rendering support (#741)
This commit is contained in:
@@ -7,6 +7,8 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/alecthomas/chroma/v2"
|
"github.com/alecthomas/chroma/v2"
|
||||||
"github.com/alecthomas/chroma/v2/formatters/html"
|
"github.com/alecthomas/chroma/v2/formatters/html"
|
||||||
@@ -109,6 +111,9 @@ func HighlightGistPreview(gist *db.Gist) (RenderedGist, error) {
|
|||||||
if lexer.Config().Name == "markdown" {
|
if lexer.Config().Name == "markdown" {
|
||||||
return MarkdownGistPreview(gist)
|
return MarkdownGistPreview(gist)
|
||||||
}
|
}
|
||||||
|
if strings.EqualFold(filepath.Ext(gist.PreviewFilename), ".mmd") {
|
||||||
|
return MermaidGistPreview(gist)
|
||||||
|
}
|
||||||
|
|
||||||
formatter := html.New(html.WithClasses(true), html.PreventSurroundingPre(true))
|
formatter := html.New(html.WithClasses(true), html.PreventSurroundingPre(true))
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,29 @@ func renderMarkdownFile(file *git.File) (HighlightedFile, error) {
|
|||||||
Type: "Markdown",
|
Type: "Markdown",
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MermaidGistPreview(gist *db.Gist) (RenderedGist, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
wrapped := "```mermaid\n" + gist.Preview + "\n```"
|
||||||
|
err := newMarkdown().Convert([]byte(wrapped), &buf)
|
||||||
|
|
||||||
|
return RenderedGist{
|
||||||
|
Gist: gist,
|
||||||
|
HTML: buf.String(),
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderMermaidFile(file *git.File) (HighlightedFile, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
wrapped := "```mermaid\n" + file.Content + "\n```"
|
||||||
|
err := newMarkdown().Convert([]byte(wrapped), &buf)
|
||||||
|
|
||||||
|
return HighlightedFile{
|
||||||
|
File: file,
|
||||||
|
HTML: buf.String(),
|
||||||
|
Type: "Mermaid",
|
||||||
|
}, err
|
||||||
|
}
|
||||||
func MarkdownString(content string) (string, error) {
|
func MarkdownString(content string) (string, error) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
err := newMarkdownWithSvgExtension().Convert([]byte(content), &buf)
|
err := newMarkdownWithSvgExtension().Convert([]byte(content), &buf)
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ func processFile(file *git.File) RenderedFile {
|
|||||||
log.Error().Err(err).Msg("Error rendering markdown file for " + file.Filename)
|
log.Error().Err(err).Msg("Error rendering markdown file for " + file.Filename)
|
||||||
}
|
}
|
||||||
return rendered
|
return rendered
|
||||||
|
} else if mt.IsText() && filepath.Ext(file.Filename) == ".mmd" {
|
||||||
|
rendered, err := renderMermaidFile(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Error rendering mermaid file for " + file.Filename)
|
||||||
|
}
|
||||||
|
return rendered
|
||||||
} else if mt.IsSVG() {
|
} else if mt.IsSVG() {
|
||||||
rendered := renderSvgFile(file)
|
rendered := renderSvgFile(file)
|
||||||
return rendered
|
return rendered
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ func (s *Server) setFuncMap() {
|
|||||||
"isMarkdown": func(i string) bool {
|
"isMarkdown": func(i string) bool {
|
||||||
return strings.ToLower(filepath.Ext(i)) == ".md"
|
return strings.ToLower(filepath.Ext(i)) == ".md"
|
||||||
},
|
},
|
||||||
|
"isMermaid": func(i string) bool {
|
||||||
|
return strings.ToLower(filepath.Ext(i)) == ".mmd"
|
||||||
|
},
|
||||||
"isJupyter": func(i string) bool {
|
"isJupyter": func(i string) bool {
|
||||||
return strings.ToLower(filepath.Ext(i)) == ".ipynb"
|
return strings.ToLower(filepath.Ext(i)) == ".ipynb"
|
||||||
},
|
},
|
||||||
|
|||||||
Vendored
+4
@@ -183,6 +183,10 @@ dl.dl-config dd {
|
|||||||
background: #f6f8fa !important;
|
background: #f6f8fa !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark .mermaid {
|
||||||
|
background: #1f2937 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.hidden-important {
|
.hidden-important {
|
||||||
@apply hidden;
|
@apply hidden;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ document.querySelectorAll(".pdf").forEach((el) => {
|
|||||||
PDFObject.embed(el.dataset.src || "", el);
|
PDFObject.embed(el.dataset.src || "", el);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (document.querySelector('.mermaid') && document.documentElement.classList.contains('dark')) {
|
||||||
|
(window as any).mermaid?.initialize({ theme: 'dark', startOnLoad: true });
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
document.getElementById('user-btn')?.addEventListener("click" , () => {
|
document.getElementById('user-btn')?.addEventListener("click" , () => {
|
||||||
document.getElementById('user-menu')!.classList.toggle('hidden');
|
document.getElementById('user-menu')!.classList.toggle('hidden');
|
||||||
|
|||||||
Vendored
+2
@@ -80,6 +80,8 @@
|
|||||||
</table>
|
</table>
|
||||||
{{ else if isMarkdown $file.Filename }}
|
{{ else if isMarkdown $file.Filename }}
|
||||||
<div class="chroma markdown markdown-body p-8">{{ $file.HTML | safe }}</div>
|
<div class="chroma markdown markdown-body p-8">{{ $file.HTML | safe }}</div>
|
||||||
|
{{ else if isMermaid $file.Filename }}
|
||||||
|
<div class="chroma markdown markdown-body p-8">{{ $file.HTML | safe }}</div>
|
||||||
{{ else if $file.MimeType.IsSVG }}
|
{{ else if $file.MimeType.IsSVG }}
|
||||||
<div class="p-8 flex justify-center">{{ $file.HTML | safe }}</div>
|
<div class="p-8 flex justify-center">{{ $file.HTML | safe }}</div>
|
||||||
{{ else if isJupyter $file.Filename }}
|
{{ else if isJupyter $file.Filename }}
|
||||||
|
|||||||
Vendored
+2
@@ -38,6 +38,8 @@
|
|||||||
</table>
|
</table>
|
||||||
{{ else if isMarkdown $file.Filename }}
|
{{ else if isMarkdown $file.Filename }}
|
||||||
<div class="chroma markdown markdown-body p-8">{{ $file.HTML | safe }}</div>
|
<div class="chroma markdown markdown-body p-8">{{ $file.HTML | safe }}</div>
|
||||||
|
{{ else if isMermaid $file.Filename }}
|
||||||
|
<div class="chroma markdown markdown-body p-8">{{ $file.HTML | safe }}</div>
|
||||||
{{ else if $file.MimeType.IsSVG }}
|
{{ else if $file.MimeType.IsSVG }}
|
||||||
<div class="p-8 flex justify-center">{{ $file.HTML | safe }}</div>
|
<div class="p-8 flex justify-center">{{ $file.HTML | safe }}</div>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
|
|||||||
+2
@@ -90,6 +90,8 @@
|
|||||||
{{ else if .gist.Preview }}
|
{{ else if .gist.Preview }}
|
||||||
{{ if isMarkdown .gist.PreviewFilename }}
|
{{ if isMarkdown .gist.PreviewFilename }}
|
||||||
<div class="chroma preview markdown markdown-body p-8">{{ .gist.HTML | safe }}</div>
|
<div class="chroma preview markdown markdown-body p-8">{{ .gist.HTML | safe }}</div>
|
||||||
|
{{ else if isMermaid .gist.PreviewFilename }}
|
||||||
|
<div class="chroma preview markdown markdown-body p-8">{{ .gist.HTML | safe }}</div>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<table class="chroma table-code w-full {{ if .currentStyle }}{{ if .currentStyle.SoftWrap }}whitespace-pre-wrap{{ else }}whitespace-pre{{ end }}{{ else }}whitespace-pre{{ end }}" data-filename="{{ .gist.PreviewFilename }}" style="font-size: 0.8em; border-spacing: 0; border-collapse: collapse;">
|
<table class="chroma table-code w-full {{ if .currentStyle }}{{ if .currentStyle.SoftWrap }}whitespace-pre-wrap{{ else }}whitespace-pre{{ end }}{{ else }}whitespace-pre{{ end }}" data-filename="{{ .gist.PreviewFilename }}" style="font-size: 0.8em; border-spacing: 0; border-collapse: collapse;">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user