Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/google/docsy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Deininger <adeininger@urbanonline.de>2022-05-11 17:49:45 +0300
committerGeri Ochoa <gerino@protonmail.com>2022-05-24 21:13:44 +0300
commit1731334ab7c402133eed28920336c35af04febbd (patch)
tree71ff2bee052b9d045fde5b72a496f113ea3c6a0a
parent5c1ec637c0be803b8267536e966a9dce9637c488 (diff)
Shortcodes for tabbed panes:
- allow tab content in markdown - tab header can now be given as unnamed parameter - tab(s) can now be disabled - improve storage of active language - new option to turn storage of active language off - improvements and fixes - documentation update
-rw-r--r--assets/scss/main.scss1
-rw-r--r--assets/scss/shortcodes.scss2
-rw-r--r--assets/scss/shortcodes/cards-pane.scss19
-rw-r--r--assets/scss/shortcodes/tabbed-pane.scss39
-rw-r--r--layouts/shortcodes/tab.html33
-rw-r--r--layouts/shortcodes/tabpane.html113
-rw-r--r--package.json2
-rw-r--r--static/css/shortcodes.css2
-rw-r--r--static/css/shortcodes/cards-pane.css21
-rw-r--r--static/css/shortcodes/tabbed-pane.css18
-rw-r--r--static/js/tabpane-persist.js6
-rw-r--r--userguide/content/en/docs/Adding content/Shortcodes/flags/de.pngbin0 -> 1428 bytes
-rw-r--r--userguide/content/en/docs/Adding content/Shortcodes/flags/tz.pngbin0 -> 2139 bytes
-rw-r--r--userguide/content/en/docs/Adding content/Shortcodes/flags/uk.pngbin0 -> 2749 bytes
-rw-r--r--userguide/content/en/docs/Adding content/Shortcodes/index.md82
15 files changed, 231 insertions, 107 deletions
diff --git a/assets/scss/main.scss b/assets/scss/main.scss
index f1a1aa6..ed21add 100644
--- a/assets/scss/main.scss
+++ b/assets/scss/main.scss
@@ -28,6 +28,7 @@
@import "pageinfo";
@import "taxonomy";
@import "drawio";
+@import "shortcodes";
@if $td-enable-google-fonts {
@import url($web-font-path);
diff --git a/assets/scss/shortcodes.scss b/assets/scss/shortcodes.scss
new file mode 100644
index 0000000..5d1f94f
--- /dev/null
+++ b/assets/scss/shortcodes.scss
@@ -0,0 +1,2 @@
+@import "shortcodes/tabbed-pane.scss";
+@import "shortcodes/cards-pane.scss";
diff --git a/assets/scss/shortcodes/cards-pane.scss b/assets/scss/shortcodes/cards-pane.scss
new file mode 100644
index 0000000..00f00f9
--- /dev/null
+++ b/assets/scss/shortcodes/cards-pane.scss
@@ -0,0 +1,19 @@
+.card-deck {
+ max-width: 83%;
+}
+.card {
+ max-width: 80%;
+ .highlight {
+ border: none;
+ }
+}
+.card-body.code {
+ background-color: #f8f9fa;
+ padding: 0 0 0 1ex;
+}
+.card-body {
+ pre {
+ margin: 0;
+ padding: 0 1rem 1rem 1rem;
+ }
+}
diff --git a/assets/scss/shortcodes/tabbed-pane.scss b/assets/scss/shortcodes/tabbed-pane.scss
new file mode 100644
index 0000000..15e5470
--- /dev/null
+++ b/assets/scss/shortcodes/tabbed-pane.scss
@@ -0,0 +1,39 @@
+.td-content {
+ .highlight {
+ margin: 0rem 0 2rem 0;
+ }
+}
+.tab-content {
+ .tab-pane {
+ .highlight {
+ border: none;
+ max-width: 100%;
+ }
+ pre {
+ border-left: 1px solid rgba(0, 0, 0, 0.125);
+ border-right: 1px solid rgba(0, 0, 0, 0.125);
+ border-bottom: 1px solid rgba(0, 0, 0, 0.125);
+ }
+ margin: 0rem;
+ max-width: 80%;
+ border-left: none;
+ border-right: none;
+ border-bottom: none;
+ }
+}
+
+.tab-body {
+ font-weight: $font-weight-medium;
+ background: $gray-100;
+ color: inherit;
+ border-radius: 0;
+ padding: 1.5rem;
+
+ @each $color, $value in $theme-colors {
+ &-#{$color} {
+
+ border-style: solid;
+ border-color: $value;
+ }
+ }
+}
diff --git a/layouts/shortcodes/tab.html b/layouts/shortcodes/tab.html
index a907de7..5a644bc 100644
--- a/layouts/shortcodes/tab.html
+++ b/layouts/shortcodes/tab.html
@@ -1,28 +1,39 @@
<!-- Make sure that we are enclosed within a tabpane shortcode block -->
{{ with $.Parent }}
-{{- if ne $.Parent.Name "tabpane" -}}
-{{- errorf "tab must be used within a tabpane block" -}}
-{{- end -}}
+ {{- if ne $.Parent.Name "tabpane" -}}
+ {{- errorf "shortcode 'tab' must be used within a 'tabpane' block" -}}
+ {{- end -}}
{{- end -}}
-<!-- Prefill header if not given as parameter -->
-{{ $header := default (printf "Tab %v" ( add $.Ordinal 1)) (.Get "header") }}
+{{ $header := "Tab" }}
+{{ if and (not .IsNamedParams) (.Get 0) }}
+ {{ $header = (.Get 0) }}
+{{ else }}
+ <!-- Prefill header if not given as named or unnamed parameter -->
+ {{ $header = default (printf "Tab %v" ( add $.Ordinal 1)) (.Get "header") }}
+{{ end }}
<!-- store all tab info in dict tab -->
{{ $tab := dict "header" $header }}
{{ with $.Get "lang" }}
-{{ $tab = merge $tab (dict "language" ($.Get "lang")) }}
+ {{ $tab = merge $tab (dict "language" ($.Get "lang")) }}
{{ end }}
{{ with $.Get "highlight" }}
-{{ $tab = merge $tab (dict "highlight" ($.Get "highlight")) }}
+ {{ $tab = merge $tab (dict "highlight" ($.Get "highlight")) }}
+{{ end }}
+{{ with $.Get "code" }}
+ {{ $tab = merge $tab (dict "code" ($.Get "code")) }}
+{{ end }}
+{{ with $.Get "disabled" }}
+ {{ $tab = merge $tab (dict "disabled" ($.Get "disabled")) }}
{{ end }}
{{ with $.Inner }}
-<!-- Trim any leading and trailing newlines from .Inner, this avoids
- spurious lines during syntax highlighting -->
-{{ $tab = merge $tab (dict "content" (trim $.Inner "\n")) }}
+ <!-- Trim any leading and trailing newlines from .Inner, this avoids
+ spurious lines during syntax highlighting -->
+ {{ $tab = merge $tab (dict "content" $.Inner ) }}
{{ end }}
<!-- add dict tab to parent's scratchpad -->
{{ with .Parent }}
-{{- $.Parent.Scratch.SetInMap "tabs" (printf "%v" $.Ordinal) $tab -}}
+ {{- $.Parent.Scratch.SetInMap "tabs" (printf "%v" $.Ordinal) $tab -}}
{{ end }} \ No newline at end of file
diff --git a/layouts/shortcodes/tabpane.html b/layouts/shortcodes/tabpane.html
index 51709a6..88c93e0 100644
--- a/layouts/shortcodes/tabpane.html
+++ b/layouts/shortcodes/tabpane.html
@@ -1,46 +1,123 @@
-<!-- Scratchpad gets populated through call to .Inner -->
+<!-- Check parameter types -->
+{{ with .Get "langEqualsHeader" }}
+{{ if ne ( printf "%T" . ) "bool" }}
+{{- errorf "shortcode tabpane: parameter 'langEqualsHeader' must be either true or false" -}}
+{{ end }}
+{{ end }}
+
+{{ with .Get "code" }}
+{{ if ne ( printf "%T" . ) "bool" }}
+{{- errorf "shortcode tabpane: parameter 'code' must be either true or false" -}}
+{{ end }}
+{{ end }}
+
+{{ with .Get "persistLang" }}
+{{ if ne ( printf "%T" . ) "bool" }}
+{{- errorf "shortcode tabpane: parameter 'persistLang' must be either true or false" -}}
+{{ end }}
+{{ end }}
+
+<!-- Set values given defined within tabpane -->
+{{- $langPane := default "" ($.Get "lang") -}}
+{{- $hloptionsPane := default "" ($.Get "highlight") -}}
+{{- $codePane := default true ($.Get "code") -}}
+{{- $langEqualsHeader := default false ($.Get "langEqualsHeader") -}}
+{{- $persistLang := default true ($.Get "persistLang") -}}
+{{- $disabled := false -}}
+{{- $activeSet := false -}}
+
+<!-- Scratchpad gets populated through call to .Inner -->
{{- .Inner -}}
<ul class="nav nav-tabs" id="tabs-{{- $.Ordinal -}}" role="tablist">
{{- range $index, $element := $.Scratch.Get "tabs" -}}
+
+ {{- $lang := $langPane -}}
+ {{- if $langEqualsHeader -}}
+ {{- $lang = $element.header -}}
+ {{end}}
+ {{- with $element.language -}}
+ {{- $lang = $element.language -}}
+ {{- end -}}
+
+ {{- $disabled := false -}}
+ {{- with $element.disabled -}}
+ {{ if ne ( printf "%T" . ) "bool" }}
+ {{- errorf "shortcode tab: parameter 'disabled' must be either true or false" -}}
+ {{ end }}
+ {{- $disabled = . }}
+ {{- end -}}
+
+ <!-- Replace space and +, not valid for css selectors -->
+ {{- $lang := replaceRE "[\\s+]" "-" $lang -}}
+
<li class="nav-item">
<!-- Generate the IDs for the <a> and the <div> elements -->
{{- $tabid := printf "tabs-%v-%v-tab" $.Ordinal $index | anchorize -}}
{{- $entryid := printf "tabs-%v-%v" $.Ordinal $index | anchorize -}}
- <!-- Replace space and + from tabname to set class -->
- {{- $tabname := replaceRE "(\\s)" "-" $element.header -}}
- {{- $tabname := replaceRE "(\\+)" "-" $tabname -}}
- <a class="nav-link{{ if eq $index "0" }} active{{ end }} tab-{{ $tabname }}"
- id="{{ $tabid }}" data-toggle="tab" href="#{{ $entryid }}" role="tab" onclick="handleClick({{ $tabname }});"
- aria-controls="{{ $entryid }}" aria-selected="{{- cond (eq $index "0") "true" "false" -}}">
- {{ index . "header" }}
+
+ <a class="nav-link{{ if and ( not $activeSet ) ( not $disabled ) }} active{{ end }}{{ if eq $disabled true }} disabled{{ end }}{{ if ne $lang "" }}{{ if $persistLang }} persistLang-{{- $lang -}}{{ end }}{{ end }}"
+ id="{{- $tabid -}}" data-toggle="tab" href="#{{ $entryid }}" role="tab"
+ {{ if ne $lang "" }}{{- if $persistLang -}}onclick="persistLang({{- $lang -}});"{{end}}{{end}}
+ aria-controls="{{- $entryid -}}" aria-selected="{{- cond (eq $index "0") "true" "false" -}}">
+ {{- index . "header" | markdownify -}}
</a>
</li>
+
+ {{ if not $disabled }}
+ {{ $activeSet = true }}
+ {{ end }}
+
{{- end -}}
</ul>
+{{ $activeSet = false }}
+
<!-- Inner content -->
<div class="tab-content" id="tabs-{{- $.Ordinal -}}-content">
{{- range $index, $element := $.Scratch.Get "tabs" -}}
- {{- $lang := default $.Site.Language.Lang ($.Get "lang") -}}
- {{with $.Get "langEqualsHeader"}}
- {{ if $.Get "langEqualsHeader"}}
- {{ $lang = $element.header }}
- {{end}}
+ {{- $lang := $langPane -}}
+ {{- if $langEqualsHeader -}}
+ {{- $lang = $element.header -}}
{{end}}
- {{- $hloptions := default "" ($.Get "highlight") -}}
{{- with $element.language -}}
- {{ $lang = $element.language }}
+ {{- $lang = $element.language -}}
{{- end -}}
+
+ {{- $disabled := false -}}
+ {{- with $element.disabled -}}
+ {{- $disabled = . }}
+ {{- end -}}
+
+ {{- $hloptions := $hloptionsPane -}}
{{- with $element.highlight -}}
- {{ $hloptions = $element.highlight }}
+ {{- $hloptions = $element.highlight -}}
{{- end -}}
+
+ {{- $code := $codePane -}}
+ {{- with $element.code -}}
+ {{ if ne ( printf "%T" . ) "bool" }}
+ {{- errorf "shortcode tab: parameter 'code' must be either true or false" -}}
+ {{ end }}
+ {{- $code = . }}
+ {{- end -}}
+
{{- $tabid := printf "tabs-%v-%v-tab" $.Ordinal $index | anchorize -}}
{{- $entryid := printf "tabs-%v-%v" $.Ordinal $index | anchorize -}}
- <div class="tab-pane fade{{ if eq $index "0" }} show active{{ end }}"
+
+ <div class="{{ if not $code }}tab-body {{end}}tab-pane fade{{ if and ( not $activeSet ) ( not $disabled ) }} show active{{ end }}"
id="{{ $entryid }}" role="tabpanel" aria-labelled-by="{{ $tabid }}">
- {{- highlight (index . "content") $lang $hloptions -}}
+ {{ if $code }}
+ {{- highlight (trim (index . "content") "\n") $lang $hloptions -}}
+ {{- else -}}
+ {{- index . "content" -}}
+ {{- end -}}
</div>
+
+ {{ if not $disabled }}
+ {{ $activeSet = true }}
+ {{ end }}
+
{{ end }}
</div>
diff --git a/package.json b/package.json
index 4f432be..e71aae7 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,6 @@
"bootstrap": "^4.6.1"
},
"devDependencies": {
- "hugo-extended": "0.98.0"
+ "hugo-extended": "0.99.1"
}
}
diff --git a/static/css/shortcodes.css b/static/css/shortcodes.css
deleted file mode 100644
index 0aa1c0f..0000000
--- a/static/css/shortcodes.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import "shortcodes/tabbed-pane.css";
-@import "shortcodes/cards-pane.css";
diff --git a/static/css/shortcodes/cards-pane.css b/static/css/shortcodes/cards-pane.css
deleted file mode 100644
index 34c8545..0000000
--- a/static/css/shortcodes/cards-pane.css
+++ /dev/null
@@ -1,21 +0,0 @@
-.card-deck {
- max-width: 83%;
-}
-
-.card {
- max-width: 80%;
-}
-
-.card-body.code {
- background-color: #f8f9fa;
- padding: 0 0 0 1ex;
-}
-
-.card-body pre {
- margin: 0;
- padding: 0 1rem 1rem 1rem;
-}
-
-.card .highlight {
- border: none;
-}
diff --git a/static/css/shortcodes/tabbed-pane.css b/static/css/shortcodes/tabbed-pane.css
deleted file mode 100644
index 3016398..0000000
--- a/static/css/shortcodes/tabbed-pane.css
+++ /dev/null
@@ -1,18 +0,0 @@
-.td-content .highlight {
- margin: 0rem 0 2rem 0;
-}
-
-.tab-content .highlight {
- border: none;
-}
-
-.tab-content {
- margin: 0rem;
- max-width: 80%;
-}
-
-.tab-content pre {
- border-left: 1px solid rgba(0, 0, 0, 0.125);
- border-right: 1px solid rgba(0, 0, 0, 0.125);
- border-bottom: 1px solid rgba(0, 0, 0, 0.125);
-}
diff --git a/static/js/tabpane-persist.js b/static/js/tabpane-persist.js
index 8a02bb6..0df34c6 100644
--- a/static/js/tabpane-persist.js
+++ b/static/js/tabpane-persist.js
@@ -2,16 +2,16 @@ if (typeof Storage !== 'undefined') {
const activeLanguage = localStorage.getItem('active_language');
if (activeLanguage) {
document
- .querySelectorAll('.tab-' + activeLanguage)
+ .querySelectorAll('.persistLang-' + activeLanguage)
.forEach((element) => {
$('#' + element.id).tab('show');
});
}
}
-function handleClick(language) {
+function persistLang(language) {
if (typeof Storage !== 'undefined') {
localStorage.setItem('active_language', language);
- document.querySelectorAll('.tab-' + language)
+ document.querySelectorAll('.persistLang-' + language)
.forEach((element) => {
$('#' + element.id).tab('show');
});
diff --git a/userguide/content/en/docs/Adding content/Shortcodes/flags/de.png b/userguide/content/en/docs/Adding content/Shortcodes/flags/de.png
new file mode 100644
index 0000000..0256951
--- /dev/null
+++ b/userguide/content/en/docs/Adding content/Shortcodes/flags/de.png
Binary files differ
diff --git a/userguide/content/en/docs/Adding content/Shortcodes/flags/tz.png b/userguide/content/en/docs/Adding content/Shortcodes/flags/tz.png
new file mode 100644
index 0000000..d8786c4
--- /dev/null
+++ b/userguide/content/en/docs/Adding content/Shortcodes/flags/tz.png
Binary files differ
diff --git a/userguide/content/en/docs/Adding content/Shortcodes/flags/uk.png b/userguide/content/en/docs/Adding content/Shortcodes/flags/uk.png
new file mode 100644
index 0000000..eaa4a7e
--- /dev/null
+++ b/userguide/content/en/docs/Adding content/Shortcodes/flags/uk.png
Binary files differ
diff --git a/userguide/content/en/docs/Adding content/Shortcodes/index.md b/userguide/content/en/docs/Adding content/Shortcodes/index.md
index 735e2a8..de79d11 100644
--- a/userguide/content/en/docs/Adding content/Shortcodes/index.md
+++ b/userguide/content/en/docs/Adding content/Shortcodes/index.md
@@ -266,10 +266,10 @@ in the response headers." you __CAN__ embed it, but when the test says "Great! X
## Tabbed panes
-Sometimes it's very useful to have tabbed panes when authoring content. One common use-case is to show multiple syntax highlighted code blocks that showcase the same problem, and how to solve it in different programming languages. As an example, the table below shows the language-specific variants of the famous `Hello world!` program one usually writes first when learning a new programming language from scratch:
+Sometimes it's very useful to have tabbed panes when authoring content. One common use-case is to show multiple syntax highlighted code blocks that showcase the same problem, and how to solve it in different programming languages. As an example, the tabbed pane below shows the language-specific variants of the famous `Hello world!` program one usually writes first when learning a new programming language:
{{< tabpane langEqualsHeader=true >}}
- {{< tab header="C" >}}
+ {{< tab "C" >}}
#include <stdio.h>
#include <stdlib.h>
@@ -279,7 +279,7 @@ int main(void)
return EXIT_SUCCESS;
}
{{< /tab >}}
-{{< tab header="C++" >}}
+{{< tab "C++" >}}
#include <iostream>
int main()
@@ -287,82 +287,98 @@ int main()
std::cout << "Hello World!" << std::endl;
}
{{< /tab >}}
-{{< tab header="Go" >}}
+{{< tab "Go" >}}
package main
import "fmt"
func main() {
fmt.Printf("Hello World!\n")
}
{{< /tab >}}
-{{< tab header="Java" >}}
+{{< tab "Java" >}}
class HelloWorld {
static public void main( String args[] ) {
System.out.println( "Hello World!" );
}
}
{{< /tab >}}
-{{< tab header="Kotlin" >}}
+{{< tab "Kotlin" >}}
fun main(args : Array<String>) {
println("Hello, world!")
}
{{< /tab >}}
-{{< tab header="Lua" >}}
+{{< tab "Lua" >}}
print "Hello world"
{{< /tab >}}
-{{< tab header="PHP" >}}
+{{< tab PHP >}}
<?php
echo 'Hello World!';
?>
{{< /tab >}}
-{{< tab header="Python" >}}
+{{< tab "Python" >}}
print("Hello World!")
{{< /tab >}}
-{{< tab header="Ruby" >}}
+{{< tab "Ruby" >}}
puts "Hello World!"
{{< /tab >}}
-{{< tab header="Scala" >}}
+{{< tab "Scala" >}}
object HelloWorld extends App {
println("Hello world!")
}
{{< /tab >}}
{{< /tabpane >}}
-The Docsy template provides two shortcodes `tabpane` and `tab` that let you easily create tabbed panes. To see how to use them, have a look at the following code block, which renders to a pane with three tabs:
+The Docsy template provides two shortcodes `tabpane` and `tab` that let you easily create tabbed panes. To see how to use them, have a look at the following code block, which renders to a pane with one disabled and three active tabs:
```go-html-template
-{{</* tabpane */>}}
- {{</* tab header="English" */>}}
- Welcome!
+{{</* tabpane code=false */>}}
+ {{</* tab header="**Languages**:" disabled=true */>}}
{{</* /tab */>}}
- {{</* tab header="German" */>}}
- Herzlich willkommen!
+ {{%/* tab header="English" lang="en" */%}}
+ ![Flag United Kingdom](flags/uk.png)
+ Welcome!
+ {{%/* /tab */%}}
+ {{</* tab header="German" lang="de" */>}}
+ <b>Herzlich willkommen!</b>
+ <img src="flags/de.png" style="float: right; padding: 0 0 0 0px">
{{</* /tab */>}}
- {{</* tab header="Swahili" */>}}
- Karibu sana!
- {{</* /tab */>}}
-{{</* /tabpane */>}}
+ {{%/* tab header="Swahili" lang="sw" */%}}
+ ![Flag Tanzania](flags/tz.png)
+ **Karibu sana!**
+ {{%/* /tab */%}}
+{{%/* /tabpane */%}}
```
This code translates to the tabbed pane below, showing a `Welcome!` greeting in English, German or Swahili:
-{{< tabpane >}}
-{{< tab header="English" >}}
-Welcome!
-{{< /tab >}}
-{{< tab header="German" lang="de" >}}
-Herzlich willkommen!
-{{< /tab >}}
-{{< tab header="Swahili" >}}
-Karibu sana!
-{{< /tab >}}
+{{< tabpane code=false >}}
+ {{% tab header="**Languages**:" disabled=true %}}
+ {{% /tab %}}
+ {{% tab header="English" lang="en" %}}
+ ![Flag United Kingdom](flags/uk.png)
+ **Welcome!**
+ {{% /tab %}}
+ {{< tab header="German" lang="de" >}}
+ <b>Herzlich willkommen!</b>
+ <img src="flags/de.png" style="float: right; padding: 0 0 0 0px">
+ {{< /tab >}}
+ {{% tab header="Swahili" lang="sw" %}}
+ ![Flag Tanzania](flags/tz.png)
+ **Karibu sana!**
+ {{% /tab %}}
{{< /tabpane >}}
### Shortcode details
Tabbed panes are implemented using two shortcodes:
-* The `tabpane` shortcode, which is the container element for the tabs. This shortcode can optionally hold the named parameters `lang` and/or `highlight`. The values of these optional parameters are passed on as second `LANG` and third `OPTIONS` arguments to Hugo's built-in [`highlight`](https://gohugo.io/functions/highlight/) function which is used to render the code blocks of the individual tabs. In case the header text of the tab equals the `language` used in the tab's code block (as in the first tabbed pane example above), you may specify `langEqualsHeader=true` in the surrounding `tabpane` shortcode. Then, the header text of the individual tab is automatically set as `language` parameter of the respective tab.
-* The various `tab` shortcodes which actually represent the tabs you would like to show. We recommend specifying the named parameter `header` for each text in order to set the header text of each tab. If needed, you can additionally specify the named parameters `lang` and `highlight` for each tab. This allows you to overwrite the settings given in the parent `tabpane` shortcode. If the language is neither specified in the `tabpane` nor in the `tab`shortcode, it defaults to Hugo's site variable `.Site.Language.Lang`.
+* The `tabpane` shortcode, which is the container element for the tabs. This shortcode can optionally hold the named parameters `lang` and/or `highlight`. The values of these optional parameters are passed on as second `LANG` and third `OPTIONS` arguments to Hugo's built-in [`highlight`](https://gohugo.io/functions/highlight/) function which is used to render the code blocks of the individual tabs. In case the header text of the tab equals the language used in the tab's code block (as in the first tabbed pane example above), you may specify `langEqualsHeader=true` in the surrounding `tabpane` shortcode. Then, the header text of the individual tab is automatically set as `lang` parameter of the respective tab.
+* The various `tab` shortcodes represent the tabs you would like to show. Specify the named parameter `header` for each tab in order to set the header text of the tab. If the `header` parameter is the only parameter inside your tab shortcode, you can specify the header as unnamed parameter, something like `{ tab "My header" }} … {{ /tab }}`. If your `tab` shortcode does not have any parameters, the header of the tab will default to `Tab n`. You can disable a tab by specifying the parameter `disabled=true`. For enabled tabs, there are two modes for content display, `code` representation and _textual_ representation:
+ * By default, the tab's content is rendered as `code block`. In order to get proper syntax highlighting, specify the named parameter `lang` --and optionally the parameter `highlight`-- for each tab. Parameters set in the parent `tabpane` shortcode will be overwritten.
+ * If the contents of your tabs should be rendered as text with different styles and with optional images, specify `code=false` as parameter of your `tabpane` (or your `tab`). If your content is markdown, use the percent sign `%` as outermost delimiter of your `tab` shortcode, your markup should look like `{{%/* tab */%}}`Your \*\*markdown\*\* content`{{%/* /tab */%}}`. In case of HTML content, use square brackets `<>` as outermost delimiters: `{{</* tab */>}}`Your &lt;b&gt;HTML&lt;/b&gt; content`{{</* /tab */>}}`.
+
+{{% alert title="Info" %}}
+By default, the language of the selected tab is stored and preserved between different browser sessions. If the content length within your tabs differs greatly, this may lead to unwanted scrolling when switching between tabs. To disable this unwanted behaviour, specify `persistLang=false` within your `tabpane` shortcode.
+{{% /alert %}}
## Card panes