Commit d9e9ad22 authored by Horacio Sanson's avatar Horacio Sanson

PlantUML support for Markdown

Allow rendering of PlantUML diagrams in Markdown documents using fenced blocks:

    ```plantuml
    Bob -> Sara : Hello
    Sara -> Bob : Go away
    ```

Closes: #4048
parent e7d530a6
......@@ -109,7 +109,7 @@ gem 'org-ruby', '~> 0.9.12'
gem 'creole', '~> 0.5.0'
gem 'wikicloth', '0.8.1'
gem 'asciidoctor', '~> 1.5.2'
gem 'asciidoctor-plantuml', '0.0.6'
gem 'asciidoctor-plantuml', '0.0.7'
gem 'rouge', '~> 2.0'
gem 'truncato', '~> 0.7.8'
......
......@@ -54,7 +54,7 @@ GEM
faraday_middleware-multi_json (~> 0.0)
oauth2 (~> 1.0)
asciidoctor (1.5.3)
asciidoctor-plantuml (0.0.6)
asciidoctor-plantuml (0.0.7)
asciidoctor (~> 1.5)
ast (2.3.0)
attr_encrypted (3.0.3)
......@@ -841,7 +841,7 @@ DEPENDENCIES
allocations (~> 1.0)
asana (~> 0.4.0)
asciidoctor (~> 1.5.2)
asciidoctor-plantuml (= 0.0.6)
asciidoctor-plantuml (= 0.0.7)
attr_encrypted (~> 3.0.0)
awesome_print (~> 1.2.0)
babosa (~> 1.0.2)
......
---
title: PlantUML support for Markdown
merge_request: 8588
author: Horacio Sanson
# Touch the lexers so it is registered with Rouge
Rouge::Lexers::Plantuml
......@@ -3,8 +3,8 @@
> [Introduced][ce-7810] in GitLab 8.16.
When [PlantUML](http://plantuml.com) integration is enabled and configured in
GitLab we are able to create simple diagrams in AsciiDoc documents created in
snippets, wikis, and repos.
GitLab we are able to create simple diagrams in AsciiDoc and Markdown documents
created in snippets, wikis, and repos.
## PlantUML Server
......@@ -54,7 +54,7 @@ that, login with an Admin account and do following:
## Creating Diagrams
With PlantUML integration enabled and configured, we can start adding diagrams to
our AsciiDoc snippets, wikis and repos using blocks:
our AsciiDoc snippets, wikis and repos using delimited blocks:
```
[plantuml, format="png", id="myDiagram", width="200px"]
......@@ -64,7 +64,14 @@ Alice -> Bob : Go Away
--
```
The above block will be converted to an HTML img tag with source pointing to the
And in Markdown using fenced code blocks:
```plantuml
Bob -> Alice : hello
Alice -> Bob : Go Away
```
The above blocks will be converted to an HTML img tag with source pointing to the
PlantUML instance. If the PlantUML server is correctly configured, this should
render a nice diagram instead of the block:
......@@ -77,7 +84,7 @@ Inside the block you can add any of the supported diagrams by PlantUML such as
and [Object](http://plantuml.com/object-diagram) diagrams. You do not need to use the PlantUML
diagram delimiters `@startuml`/`@enduml` as these are replaced by the AsciiDoc `plantuml` block.
Some parameters can be added to the block definition:
Some parameters can be added to the AsciiDoc block definition:
- *format*: Can be either `png` or `svg`. Note that `svg` is not supported by
all browsers so use with care. The default is `png`.
......@@ -85,3 +92,4 @@ Some parameters can be added to the block definition:
- *width*: Width attribute added to the img tag.
- *height*: Height attribute added to the img tag.
Markdown does not support any parameters and will always use PNG format.
require "nokogiri"
require "asciidoctor-plantuml/plantuml"
module Banzai
module Filter
# HTML that replaces all `code plantuml` tags with PlantUML img tags.
#
class PlantumlFilter < HTML::Pipeline::Filter
def call
return doc unless doc.at('pre.plantuml') and settings.plantuml_enabled
plantuml_setup
doc.css('pre.plantuml').each do |el|
img_tag = Nokogiri::HTML::DocumentFragment.parse(
Asciidoctor::PlantUml::Processor.plantuml_content(el.content, {}))
el.replace img_tag
end
doc
end
private
def settings
ApplicationSetting.current || ApplicationSetting.create_from_defaults
end
def plantuml_setup
Asciidoctor::PlantUml.configure do |conf|
conf.url = settings.plantuml_url
conf.png_enable = settings.plantuml_enabled
conf.svg_enable = false
conf.txt_enable = false
end
end
end
end
end
......@@ -10,6 +10,7 @@ module Banzai
def self.filters
@filters ||= FilterArray[
Filter::SyntaxHighlightFilter,
Filter::PlantumlFilter,
Filter::SanitizationFilter,
Filter::MathFilter,
......
module Rouge
module Lexers
class Plantuml < Lexer
title "A passthrough lexer used for PlantUML input"
desc "A boring lexer that doesn't highlight anything"
tag 'plantuml'
mimetypes 'text/plain'
default_options token: 'Text'
def token
@token ||= Token[option :token]
end
def stream_tokens(string, &b)
yield self.token, string
end
end
end
end
require 'spec_helper'
describe Banzai::Filter::PlantumlFilter, lib: true do
include FilterSpecHelper
it 'should replace plantuml pre tag with img tag' do
stub_application_setting(plantuml_enabled: true, plantuml_url: "http://localhost:8080")
input = '<pre class="plantuml"><code>Bob -> Sara : Hello</code><pre>'
output = '<div class="imageblock"><div class="content"><img class="plantuml" src="http://localhost:8080/png/U9npoazIqBLJ24uiIbImKl18pSd91m0rkGMq"></div></div>'
doc = filter(input)
expect(doc.to_s).to eq output
end
it 'should not replace plantuml pre tag with img tag if disabled' do
stub_application_setting(plantuml_enabled: false)
input = '<pre class="plantuml"><code>Bob -> Sara : Hello</code><pre>'
output = '<pre class="plantuml"><code>Bob -&gt; Sara : Hello</code><pre></pre></pre>'
doc = filter(input)
expect(doc.to_s).to eq output
end
it 'should not replace plantuml pre tag with img tag if url is invalid' do
stub_application_setting(plantuml_enabled: true, plantuml_url: "invalid")
input = '<pre class="plantuml"><code>Bob -> Sara : Hello</code><pre>'
output = '<div class="listingblock"><div class="content"><pre class="plantuml plantuml-error"> PlantUML Error: cannot connect to PlantUML server at "invalid"</pre></div></div>'
doc = filter(input)
expect(doc.to_s).to eq output
end
end
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