From 938debb1d9d3b40869895c498b45f558dd80b4cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Weber?= Date: Sat, 19 Mar 2022 20:18:21 +0100 Subject: [PATCH] mermaid: support differing themes for color variant switch #219 --- exampleSite/config.toml | 2 +- .../content/basics/migration/_index.en.md | 3 ++ exampleSite/content/shortcodes/mermaid.en.md | 18 ++++--- .../_markup/render-codeblock-mermaid.html | 2 +- layouts/partials/footer.html | 9 +++- static/css/theme-neon.css | 2 + static/css/theme-relearn-dark.css | 2 + static/css/theme.css | 4 ++ static/css/variant.css | 2 + static/js/theme.js | 34 ++++++++++--- static/js/variant.js | 48 +++++++++++++++++++ 11 files changed, 109 insertions(+), 17 deletions(-) diff --git a/exampleSite/config.toml b/exampleSite/config.toml index cc484a1012..2ffcf7e1f6 100644 --- a/exampleSite/config.toml +++ b/exampleSite/config.toml @@ -40,7 +40,7 @@ title = "Hugo Relearn Documentation" # this is for the stylesheet genertor to allow for interactivity in mermaid # graphs; you usually will not need it and you should remove this for # security reasons - mermaidInitialize = "{ \"securityLevel\": \"loose\"}" + mermaidInitialize = "{ \"securityLevel\": \"loose\" }" [outputs] # add JSON to the home page to support lunr search; This is a mandatory setting diff --git a/exampleSite/content/basics/migration/_index.en.md b/exampleSite/content/basics/migration/_index.en.md index 3cea3bd34e..d144ab2fa6 100644 --- a/exampleSite/content/basics/migration/_index.en.md +++ b/exampleSite/content/basics/migration/_index.en.md @@ -21,6 +21,9 @@ This document shows you what's new in the latest release. For a detailed list of The option is still useful in case you are using scripting to set up your graph. In this case no shortcode or codefence is involved and the library is not loaded by default. In this case you can set `disableMermaid=false` in your frontmatter to force the library to be loaded. See the [theme variant generator]({{%relref "basics/generator" %}}) of the exampleSite for an example. **This change requires at least Hugo 0.93.0 to be used**. The minimum requirement will be reported during build on the console if not met. + +- **New**: Additional color variant variable `--MERMAID-theme` to set the variant's Mermaid theme. This causes the Mermaid theme to switch with the color variant if it defers from the setting of the formerly selected color variant. + --- ## 3.1.0 diff --git a/exampleSite/content/shortcodes/mermaid.en.md b/exampleSite/content/shortcodes/mermaid.en.md index c1800b2625..98652534dd 100644 --- a/exampleSite/content/shortcodes/mermaid.en.md +++ b/exampleSite/content/shortcodes/mermaid.en.md @@ -5,6 +5,10 @@ title = "Mermaid" [Mermaid](https://mermaidjs.github.io/) is a library helping you to generate diagram and flowcharts from text, in a similar manner as Markdown. +{{% notice warning %}} +Due to limitations with [Mermaid](https://github.com/mermaid-js/mermaid/issues/1846), it is currently not possible to use Mermaid code fences in an initially collapsed `expand` shortcode. This is a know issue and [can't be fixed by this theme](https://github.com/McShelby/hugo-theme-relearn/issues/187). +{{% /notice %}} + ## Usage Just insert your Mermaid code in the `mermaid` shortcode like this: @@ -34,6 +38,7 @@ The generated graphs can be be panned by dragging them and zoomed by using the m ### Flowchart {{< mermaid align="left" >}} +%%{init:{"theme":"forest"}}%% graph LR; A[Hard edge] -->|Link text| B(Round edge) B --> C{Decision} @@ -44,6 +49,7 @@ graph LR; {{% expand "Show markup" "true" %}} ````go {{}} +%%{init:{"theme":"forest"}}%% graph LR; A[Hard edge] -->|Link text| B(Round edge) B --> C{Decision} @@ -199,16 +205,16 @@ stateDiagram-v2 ## Configuration -Mermaid is configured with default settings. You can customize Mermaid's default settings for all of your files thru a JSON object in your `config.toml` or override these settings sidewise thru your pages frontmatter. +Mermaid is configured with default settings. You can customize Mermaid's default settings for all of your files thru a JSON object in your `config.toml`, override these settings per page thru your pages frontmatter or override these setting per diagramm thru [diagram directives](https://mermaid-js.github.io/mermaid/#/directives?id=directives). -This JSON object is forwarded into Mermaid's `mermaid.initialize()` function. +The JSON object of your `config.toml` / frontmatter is forwarded into Mermaid's `mermaid.initialize()` function. -See [Mermaid documentation](http://mermaid-js.github.io/mermaid/getting-started/Setup.html#mermaidapi-configuration-defaults) for all allowed settings. +See [Mermaid documentation](http://mermaid-js.github.io/mermaid/#/Setup?id=mermaidapi-configuration-defaults) for all allowed settings. -Also, if you want to use mermaid codefences, you have to turn off `guessSyntax` for the `markup.highlight` setting. +The `theme` setting is somewhat special as it can be set by your used color variant. This will be the sitewide default and can - again - be overridden by your settings in `config.toml`, frontmatter or diagram directives. -{{% notice warning %}} -Due to limitations with [Mermaid](https://github.com/mermaid-js/mermaid/issues/1846), it is currently not possible to use Mermaid code fences in an initially collapsed `expand` shortcode. This is a know issue and [can't be fixed by this theme](https://github.com/McShelby/hugo-theme-relearn/issues/187). +{{% notice note %}} +If you want to use mermaid codefences, you have to turn off `guessSyntax` for the `markup.highlight` setting. {{% /notice %}} ### Example diff --git a/layouts/_default/_markup/render-codeblock-mermaid.html b/layouts/_default/_markup/render-codeblock-mermaid.html index d8a5029244..91940913f8 100644 --- a/layouts/_default/_markup/render-codeblock-mermaid.html +++ b/layouts/_default/_markup/render-codeblock-mermaid.html @@ -1,4 +1,4 @@ -
+
{{- safeHTML .Inner -}}
{{- .Page.Store.Set "hasMermaid" true }} diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html index 62380f7970..19a9d705aa 100644 --- a/layouts/partials/footer.html +++ b/layouts/partials/footer.html @@ -25,11 +25,16 @@ {{- else if isset .Site.Params "mermaidinitialize" }} {{- $.Scratch.Set "mermaidInitialize" .Site.Params.mermaidInitialize }} {{- else }} - {{- $.Scratch.Set "mermaidInitialize" "{ \"startOnLoad\": true }" }} + {{- $.Scratch.Set "mermaidInitialize" "{}" }} {{- end }} {{- end }} diff --git a/static/css/theme-neon.css b/static/css/theme-neon.css index 5c91811f58..e8bde6be42 100644 --- a/static/css/theme-neon.css +++ b/static/css/theme-neon.css @@ -27,6 +27,8 @@ --CODE-INLINE-BG-color: #282a36; /* color for inline code background */ --CODE-INLINE-BORDER-color: #464646; /* color of inline code border */ + --MERMAID-theme: dark; /* name of the default mermaid theme for this variant, can be overridden in config.toml */ + --TAG-BG-color: #04d1b5; /* Background color of menu header */ --MENU-HOME-LINK-color: #323232; /* Color of the home button text */ diff --git a/static/css/theme-relearn-dark.css b/static/css/theme-relearn-dark.css index ed66f930c6..fa9f36d116 100644 --- a/static/css/theme-relearn-dark.css +++ b/static/css/theme-relearn-dark.css @@ -22,6 +22,8 @@ --CODE-INLINE-BG-color: #2d2d2d; /* color for inline code background */ --CODE-INLINE-BORDER-color: #464646; /* color of inline code border */ + --MERMAID-theme: dark; /* name of the default mermaid theme for this variant, can be overridden in config.toml */ + --MENU-HOME-LINK-color: #323232; /* Color of the home button text */ --MENU-HOME-LINK-HOVER-color: #5e5e5e; /* Color of the hovered home button text */ diff --git a/static/css/theme.css b/static/css/theme.css index 70a4924ae2..d48bad54d0 100644 --- a/static/css/theme.css +++ b/static/css/theme.css @@ -1210,6 +1210,10 @@ option { border-color: rgba( 134, 134, 134, .333 ); } +.mermaid-code { + display: none; +} + .include.hide-first-heading h1:first-of-type, .include.hide-first-heading h2:first-of-type, .include.hide-first-heading h3:first-of-type, diff --git a/static/css/variant.css b/static/css/variant.css index 204585dcdf..37bf77c32d 100644 --- a/static/css/variant.css +++ b/static/css/variant.css @@ -21,6 +21,8 @@ --INTERNAL-CODE-INLINE-BG-color: var(--CODE-INLINE-BG-color, #fffae9); --INTERNAL-CODE-INLINE-BORDER-color: var(--CODE-INLINE-BORDER-color, #fbf0cb); + --INTERNAL-MERMAID-theme: var(--CONFIG-MERMAID-theme, var(--MERMAID-theme, default)); + --INTERNAL-TAG-BG-color: var(--TAG-BG-color, var(--INTERNAL-MENU-HEADER-BG-color)); /* initially use section background to avoid flickering on load when a non default variant is active; diff --git a/static/js/theme.js b/static/js/theme.js index 65d6ee48fb..f8731289ee 100644 --- a/static/js/theme.js +++ b/static/js/theme.js @@ -62,14 +62,34 @@ function restoreTabSelections() { } function initMermaid() { - $('code.language-mermaid').each(function(index, element) { - var content = $(element).html().replace(/&/g, '&'); - $(element).parent().replaceWith('
' + content + '
'); - }); - if (typeof mermaid != 'undefined' && typeof mermaid.mermaidAPI != 'undefined') { - mermaid.mermaidAPI.initialize( Object.assign( {}, mermaid.mermaidAPI.getSiteConfig(), { startOnLoad: true } ) ); - mermaid.contentLoaded(); + document.querySelectorAll('.mermaid').forEach( function( element ){ + var content = element.innerHTML.replace(/&/g, '&').trim(); + + var d = /^(%%\s*\{\s*\w+\s*:([^%]*?)%%\s*\n?)/g; + var m = d.exec( content ); + var dir = {}; + if( m && m.length == 3 ){ + dir = JSON.parse( '{ "dummy": ' + m[2] ).dummy; + content = content.substring( d.lastIndex ); + } + + if( dir.theme ){ + dir.relearn_user_theme = true; + } + if( !dir.relearn_user_theme ){ + dir.theme = getComputedStyle( document.documentElement ).getPropertyValue( '--INTERNAL-MERMAID-theme' ).replace( /\s/g, "" ); + } + dir.relearn_initialized = true; + content = '%%{init: ' + JSON.stringify( dir ) + '}%%\n' + content; + + element.innerHTML = content; + var new_element = document.createElement( 'div' ); + new_element.classList.add( 'mermaid-container' ); + new_element.innerHTML = '
' + content + '
' + element.outerHTML; + element.parentNode.replaceChild( new_element, element ); + }); + mermaid.init(); $(".mermaid svg").svgPanZoom({}); } } diff --git a/static/js/variant.js b/static/js/variant.js index faca654678..827968983f 100644 --- a/static/js/variant.js +++ b/static/js/variant.js @@ -35,6 +35,46 @@ var variants = { if( variant && select.value != variant ){ select.value = variant; } + setTimeout( function(){ + if( typeof mermaid != 'undefined' && typeof mermaid.mermaidAPI != 'undefined' && document.querySelector( '.mermaid > svg' ) ){ + var is_intialized = false; + var theme = this.getColorValue( 'MERMAID-theme' ); + document.querySelectorAll( '.mermaid-container' ).forEach( function( e ){ + var element = e.querySelector( '.mermaid' ); + var code = e.querySelector( '.mermaid-code' ); + var content = this.decodeHTML( code.innerHTML ); + + var d = /^(%%\s*\{\s*\w+\s*:([^%]*?)%%\s*\n?)/g; + var m = d.exec( content ); + var dir = {}; + if( m && m.length == 3 ){ + dir = JSON.parse( '{ "dummy": ' + m[2] ).dummy; + content = content.substring( d.lastIndex ); + } + + if( !dir.relearn_initialized ){ + return; + } + is_initialized = true; + if( dir.relearn_user_theme ){ + return; + } + + if( dir.theme != theme ){ + dir.theme = theme; + content = '%%{init: ' + JSON.stringify( dir ) + '}%%\n' + content; + element.removeAttribute('data-processed'); + element.innerHTML = content; + code.innerHTML = content; + } + }.bind( this ) ); + if( is_initialized ){ + mermaid.init(); + $(".mermaid svg").svgPanZoom({}); + } + } + }.bind( this ), 25 ); + // remove selection, because if some uses an arrow navigation" // by pressing the left or right cursor key, we will automatically // select a different style @@ -204,6 +244,12 @@ var variants = { a.click(); }, + decodeHTML: function( html ){ + var txt = document.createElement( 'textarea' ); + txt.innerHTML = html; + return txt.value; + }, + getStylesheet: function(){ this.download( this.generateStylesheet(), 'text/css', 'theme-' + this.customvariantname + '.css' ); }, @@ -469,6 +515,8 @@ var variants = { { name: 'CODE-INLINE-BG-color', group: 'inline code', default: '#fffae9', tooltip: 'background color of inline code', }, { name: 'CODE-INLINE-BORDER-color', group: 'inline code', default: '#fbf0cb', tooltip: 'border color of inline code', }, + { name: 'MERMAID-theme', group: 'mermaid', default: 'default', tooltip: 'name of the default mermaid theme for this variant, can be overridden in config.toml', }, + { name: 'MENU-HEADER-BG-color', group: 'header', default: '#7dc903', tooltip: 'background color of menu header', }, { name: 'MENU-HEADER-BORDER-color', group: 'header', fallback: 'MENU-HEADER-BG-color', tooltip: 'separator color of menu header', }, { name: 'MENU-HOME-LINK-color', group: 'header', default: '#323232', tooltip: 'home button color if configured', },