Commit c00c10ed authored by Stan Hu's avatar Stan Hu

Merge branch 'issue-31818-asciidoc-mermaid-diagram' into 'master'

Add support for Mermaid diagram in AsciiDoc

See merge request gitlab-org/gitlab!36127
parents 61c2b486 7fbd70d3
...@@ -364,6 +364,89 @@ comment - content which is not included in the output document ...@@ -364,6 +364,89 @@ comment - content which is not included in the output document
|=== |===
``` ```
### Colors
It’s possible to have color written in `HEX`, `RGB`, or `HSL` format rendered with a color indicator.
Supported formats (named colors are not supported):
- HEX: `` `#RGB[A]` `` or `` `#RRGGBB[AA]` ``
- RGB: `` `RGB[A](R, G, B[, A])` ``
- HSL: `` `HSL[A](H, S, L[, A])` ``
Color written inside backticks will be followed by a color "chip":
```plaintext
- `#F00`
- `#F00A`
- `#FF0000`
- `#FF0000AA`
- `RGB(0,255,0)`
- `RGB(0%,100%,0%)`
- `RGBA(0,255,0,0.3)`
- `HSL(540,70%,50%)`
- `HSLA(540,70%,50%,0.3)`
```
### STEM
To activate equation and formula support,
set the `stem` attribute in the document's header to `latexmath`.
Equations and formulas will be rendered using [KaTeX](https://katex.org/):
```plaintext
:stem: latexmath
latexmath:[C = \alpha + \beta Y^{\gamma} + \epsilon]
[stem]
++++
sqrt(4) = 2
++++
A matrix can be written as stem:[[[a,b\],[c,d\]\]((n),(k))].
```
### Diagrams and flowcharts
It's possible to generate diagrams and flowcharts from text in GitLab using
[Mermaid](https://mermaidjs.github.io/) or [PlantUML](https://plantuml.com).
#### Mermaid
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31818) as a [community contribution](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36127) in GitLab 13.3.
Visit the [official page](https://mermaidjs.github.io/) for more details.
If you're new to using Mermaid or need help identifying issues in your Mermaid code,
the [Mermaid Live Editor](https://mermaid-js.github.io/mermaid-live-editor/) is a helpful tool
for creating and resolving issues within Mermaid diagrams.
In order to generate a diagram or flowchart, you should write your text inside the `mermaid` block:
```plaintext
[mermaid]
----
graph LR
A[Square Rect] -- Link text --> B((Circle))
A --> C(Round Rect)
B --> D{Rhombus}
C --> D
----
```
#### PlantUML
To make PlantUML available in GitLab, a GitLab administrator needs to enable it first.
Read more in [PlantUML & GitLab](../administration/integration/plantuml.md).
Once enabled, you should write your text inside the `plantuml` block:
```plaintext
[plantuml]
----
Bob -> Alice : hello
----
```
### Multimedia ### Multimedia
```plaintext ```plaintext
......
...@@ -8,6 +8,9 @@ module Banzai ...@@ -8,6 +8,9 @@ module Banzai
node.set_attribute('class', 'code math js-render-math') node.set_attribute('class', 'code math js-render-math')
end end
doc.search('[data-mermaid-style]').each do |node|
node.set_attribute('class', 'js-render-mermaid')
end
doc doc
end end
end end
......
...@@ -25,7 +25,7 @@ module Banzai ...@@ -25,7 +25,7 @@ module Banzai
# Allow data-math-style attribute in order to support LaTeX formatting # Allow data-math-style attribute in order to support LaTeX formatting
whitelist[:attributes]['code'] = %w(data-math-style) whitelist[:attributes]['code'] = %w(data-math-style)
whitelist[:attributes]['pre'] = %w(data-math-style) whitelist[:attributes]['pre'] = %w(data-math-style data-mermaid-style)
# Allow html5 details/summary elements # Allow html5 details/summary elements
whitelist[:elements].push('details') whitelist[:elements].push('details')
......
...@@ -14,7 +14,7 @@ module Banzai ...@@ -14,7 +14,7 @@ module Banzai
LANG_PARAMS_ATTR = 'data-lang-params' LANG_PARAMS_ATTR = 'data-lang-params'
def call def call
doc.search('pre:not([data-math-style]) > code').each do |node| doc.search('pre:not([data-math-style]):not([data-mermaid-style]) > code').each do |node|
highlight_node(node) highlight_node(node)
end end
......
...@@ -4,6 +4,7 @@ require 'asciidoctor' ...@@ -4,6 +4,7 @@ require 'asciidoctor'
require 'asciidoctor-plantuml' require 'asciidoctor-plantuml'
require 'asciidoctor/extensions' require 'asciidoctor/extensions'
require 'gitlab/asciidoc/html5_converter' require 'gitlab/asciidoc/html5_converter'
require 'gitlab/asciidoc/mermaid_block_processor'
require 'gitlab/asciidoc/syntax_highlighter/html_pipeline_adapter' require 'gitlab/asciidoc/syntax_highlighter/html_pipeline_adapter'
module Gitlab module Gitlab
...@@ -46,6 +47,7 @@ module Gitlab ...@@ -46,6 +47,7 @@ module Gitlab
def self.render(input, context) def self.render(input, context)
extensions = proc do extensions = proc do
include_processor ::Gitlab::Asciidoc::IncludeProcessor.new(context) include_processor ::Gitlab::Asciidoc::IncludeProcessor.new(context)
block ::Gitlab::Asciidoc::MermaidBlockProcessor
end end
extra_attrs = path_attrs(context[:requested_path]) extra_attrs = path_attrs(context[:requested_path])
......
# frozen_string_literal: true
require 'asciidoctor'
module Gitlab
module Asciidoc
# Mermaid BlockProcessor
class MermaidBlockProcessor < ::Asciidoctor::Extensions::BlockProcessor
use_dsl
named :mermaid
on_context :literal, :listing
parse_content_as :simple
def process(parent, reader, attrs)
create_mermaid_source_block(parent, reader.read, attrs)
end
private
def create_mermaid_source_block(parent, content, attrs)
# If "subs" attribute is specified, substitute accordingly.
# Be careful not to specify "specialcharacters" or your diagram code won't be valid anymore!
subs = attrs['subs']
content = parent.apply_subs(content, parent.resolve_subs(subs)) if subs
html = %(<div><pre data-mermaid-style="display">#{CGI.escape_html(content)}</pre></div>)
::Asciidoctor::Block.new(parent, :pass, {
content_model: :raw,
source: html,
subs: :default
}.merge(attrs))
end
end
end
end
...@@ -10,6 +10,12 @@ RSpec.describe Banzai::Filter::AsciiDocPostProcessingFilter do ...@@ -10,6 +10,12 @@ RSpec.describe Banzai::Filter::AsciiDocPostProcessingFilter do
expect(result).to eq('<pre data-math-style="inline" class="code math js-render-math">some code</pre><div data-math>and</div>') expect(result).to eq('<pre data-math-style="inline" class="code math js-render-math">some code</pre><div data-math>and</div>')
end end
it "adds class for elements with data-mermaid-style" do
result = filter('<pre data-mermaid-style="display">some code</pre>').to_html
expect(result).to eq('<pre data-mermaid-style="display" class="js-render-mermaid">some code</pre>')
end
it "keeps content when no data-math-style found" do it "keeps content when no data-math-style found" do
result = filter('<pre>some code</pre><div data-math>and</div>').to_html result = filter('<pre>some code</pre><div data-math>and</div>').to_html
expect(result).to eq('<pre>some code</pre><div data-math>and</div>') expect(result).to eq('<pre>some code</pre><div data-math>and</div>')
......
...@@ -26,6 +26,14 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do ...@@ -26,6 +26,14 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
include_examples "XSS prevention", "" include_examples "XSS prevention", ""
end end
context "when contains mermaid diagrams" do
it "ignores mermaid blocks" do
result = filter('<pre data-mermaid-style="display"><code>mermaid code</code></pre>')
expect(result.to_html).to eq('<pre data-mermaid-style="display"><code>mermaid code</code></pre>')
end
end
context "when a valid language is specified" do context "when a valid language is specified" do
it "highlights as that language" do it "highlights as that language" do
result = filter('<pre><code lang="ruby">def fun end</code></pre>') result = filter('<pre><code lang="ruby">def fun end</code></pre>')
......
...@@ -418,6 +418,50 @@ module Gitlab ...@@ -418,6 +418,50 @@ module Gitlab
expect(output).to include("a href=\"README.adoc\"") expect(output).to include("a href=\"README.adoc\"")
end end
end end
context 'with mermaid diagrams' do
it 'adds class js-render-mermaid to the output' do
input = <<~MD
[mermaid]
....
graph LR
A[Square Rect] -- Link text --> B((Circle))
A --> C(Round Rect)
B --> D{Rhombus}
C --> D
....
MD
output = <<~HTML
<pre data-mermaid-style="display" class="js-render-mermaid">graph LR
A[Square Rect] -- Link text --&gt; B((Circle))
A --&gt; C(Round Rect)
B --&gt; D{Rhombus}
C --&gt; D</pre>
HTML
expect(render(input, context)).to include(output.strip)
end
it 'applies subs in diagram block' do
input = <<~MD
:class-name: AveryLongClass
[mermaid,subs=+attributes]
....
classDiagram
Class01 <|-- {class-name} : Cool
....
MD
output = <<~HTML
<pre data-mermaid-style="display" class="js-render-mermaid">classDiagram
Class01 &lt;|-- AveryLongClass : Cool</pre>
HTML
expect(render(input, context)).to include(output.strip)
end
end
end end
context 'with project' do context 'with project' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment