dynflow 0.7.6 → 0.7.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +11 -3
- data/doc/pages/.gitignore +7 -0
- data/doc/pages/Gemfile +8 -0
- data/doc/pages/Rakefile +26 -0
- data/doc/pages/_config.yml +38 -0
- data/doc/pages/plugins/alert_block.rb +27 -0
- data/doc/pages/plugins/div_tag.rb +24 -0
- data/doc/pages/plugins/graphviz.rb +121 -0
- data/doc/pages/plugins/plantuml.rb +85 -0
- data/doc/pages/plugins/play.rb +13 -0
- data/doc/pages/plugins/tags.rb +138 -0
- data/doc/pages/plugins/toc.rb +20 -0
- data/doc/pages/source/.nojekyll +0 -0
- data/doc/pages/source/404.md +6 -0
- data/doc/pages/source/_includes/disqus.html +25 -0
- data/doc/pages/source/_includes/google_analytics.html +12 -0
- data/doc/pages/source/_includes/google_plus_one.html +2 -0
- data/doc/pages/source/_includes/menu.html +19 -0
- data/doc/pages/source/_includes/menu_brand.html +2 -0
- data/doc/pages/source/_includes/menu_right.html +1 -0
- data/doc/pages/source/_includes/post_item.html +10 -0
- data/doc/pages/source/_includes/scroll_to.html +24 -0
- data/doc/pages/source/_includes/twitter_sharing.html +9 -0
- data/doc/pages/source/_layouts/default.html +70 -0
- data/doc/pages/source/_layouts/page.html +47 -0
- data/doc/pages/source/_layouts/post.html +19 -0
- data/doc/pages/source/_layouts/presentation.html +39 -0
- data/doc/pages/source/_layouts/tag_page.html +12 -0
- data/doc/pages/source/_sass/_bootstrap-compass.scss +9 -0
- data/doc/pages/source/_sass/_bootstrap-mincer.scss +19 -0
- data/doc/pages/source/_sass/_bootstrap-sprockets.scss +9 -0
- data/doc/pages/source/_sass/_bootstrap-variables.sass +865 -0
- data/doc/pages/source/_sass/_bootstrap.scss +50 -0
- data/doc/pages/source/_sass/_specific.scss +16 -0
- data/doc/pages/source/_sass/_style.scss +172 -0
- data/doc/pages/source/_sass/bootstrap/_alerts.scss +73 -0
- data/doc/pages/source/_sass/bootstrap/_badges.scss +67 -0
- data/doc/pages/source/_sass/bootstrap/_breadcrumbs.scss +26 -0
- data/doc/pages/source/_sass/bootstrap/_button-groups.scss +243 -0
- data/doc/pages/source/_sass/bootstrap/_buttons.scss +160 -0
- data/doc/pages/source/_sass/bootstrap/_carousel.scss +269 -0
- data/doc/pages/source/_sass/bootstrap/_close.scss +36 -0
- data/doc/pages/source/_sass/bootstrap/_code.scss +69 -0
- data/doc/pages/source/_sass/bootstrap/_component-animations.scss +38 -0
- data/doc/pages/source/_sass/bootstrap/_dropdowns.scss +214 -0
- data/doc/pages/source/_sass/bootstrap/_forms.scss +570 -0
- data/doc/pages/source/_sass/bootstrap/_glyphicons.scss +301 -0
- data/doc/pages/source/_sass/bootstrap/_grid.scss +84 -0
- data/doc/pages/source/_sass/bootstrap/_input-groups.scss +166 -0
- data/doc/pages/source/_sass/bootstrap/_jumbotron.scss +50 -0
- data/doc/pages/source/_sass/bootstrap/_labels.scss +66 -0
- data/doc/pages/source/_sass/bootstrap/_list-group.scss +124 -0
- data/doc/pages/source/_sass/bootstrap/_media.scss +61 -0
- data/doc/pages/source/_sass/bootstrap/_mixins.scss +39 -0
- data/doc/pages/source/_sass/bootstrap/_modals.scss +148 -0
- data/doc/pages/source/_sass/bootstrap/_navbar.scss +663 -0
- data/doc/pages/source/_sass/bootstrap/_navs.scss +244 -0
- data/doc/pages/source/_sass/bootstrap/_normalize.scss +427 -0
- data/doc/pages/source/_sass/bootstrap/_pager.scss +54 -0
- data/doc/pages/source/_sass/bootstrap/_pagination.scss +88 -0
- data/doc/pages/source/_sass/bootstrap/_panels.scss +265 -0
- data/doc/pages/source/_sass/bootstrap/_popovers.scss +135 -0
- data/doc/pages/source/_sass/bootstrap/_print.scss +107 -0
- data/doc/pages/source/_sass/bootstrap/_progress-bars.scss +87 -0
- data/doc/pages/source/_sass/bootstrap/_responsive-embed.scss +35 -0
- data/doc/pages/source/_sass/bootstrap/_responsive-utilities.scss +177 -0
- data/doc/pages/source/_sass/bootstrap/_scaffolding.scss +150 -0
- data/doc/pages/source/_sass/bootstrap/_tables.scss +234 -0
- data/doc/pages/source/_sass/bootstrap/_theme.scss +273 -0
- data/doc/pages/source/_sass/bootstrap/_thumbnails.scss +38 -0
- data/doc/pages/source/_sass/bootstrap/_tooltip.scss +103 -0
- data/doc/pages/source/_sass/bootstrap/_type.scss +298 -0
- data/doc/pages/source/_sass/bootstrap/_utilities.scss +56 -0
- data/doc/pages/source/_sass/bootstrap/_variables.scss +862 -0
- data/doc/pages/source/_sass/bootstrap/_wells.scss +29 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_alerts.scss +14 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_background-variant.scss +11 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_border-radius.scss +18 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_buttons.scss +52 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_center-block.scss +7 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_clearfix.scss +22 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_forms.scss +88 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_gradients.scss +58 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_grid-framework.scss +81 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_grid.scss +122 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_hide-text.scss +21 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_image.scss +33 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_labels.scss +12 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_list-group.scss +31 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_nav-divider.scss +10 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_nav-vertical-align.scss +9 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_opacity.scss +8 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_pagination.scss +23 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_panels.scss +24 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_progress-bar.scss +10 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_reset-filter.scss +8 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_resize.scss +6 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_responsive-visibility.scss +21 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_size.scss +10 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_tab-focus.scss +9 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_table-row.scss +28 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_text-emphasis.scss +11 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_text-overflow.scss +8 -0
- data/doc/pages/source/_sass/bootstrap/mixins/_vendor-prefixes.scss +222 -0
- data/doc/pages/source/atom.xml +32 -0
- data/doc/pages/source/bootstrap/config.json +429 -0
- data/doc/pages/source/bootstrap/css/bootstrap-theme.css +479 -0
- data/doc/pages/source/bootstrap/css/bootstrap-theme.min.css +10 -0
- data/doc/pages/source/bootstrap/css/bootstrap.css +6564 -0
- data/doc/pages/source/bootstrap/css/bootstrap.min.css +10 -0
- data/doc/pages/source/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
- data/doc/pages/source/bootstrap/fonts/glyphicons-halflings-regular.svg +288 -0
- data/doc/pages/source/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/doc/pages/source/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
- data/doc/pages/source/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/doc/pages/source/bootstrap/js/bootstrap.js +2309 -0
- data/doc/pages/source/bootstrap/js/bootstrap.min.js +12 -0
- data/doc/pages/source/css/app.scss +10 -0
- data/doc/pages/source/css/syntax.css +60 -0
- data/doc/pages/source/documentation/index.md +977 -0
- data/doc/pages/source/faq/index.md +16 -0
- data/doc/pages/source/images/dynflow-logos.svg +423 -0
- data/doc/pages/source/images/logo-long.png +0 -0
- data/doc/pages/source/images/logo-long.svg +116 -0
- data/doc/pages/source/images/logo-square.png +0 -0
- data/doc/pages/source/images/logo-square.svg +75 -0
- data/doc/pages/source/images/noise.png +0 -0
- data/doc/pages/source/images/screenshot.png +0 -0
- data/doc/pages/source/index.md +64 -0
- data/doc/pages/source/media/index.md +20 -0
- data/doc/pages/source/projects/index.md +32 -0
- data/dynflow.gemspec +2 -3
- data/examples/sub_plans.rb +37 -0
- data/lib/dynflow/action.rb +28 -8
- data/lib/dynflow/action/polling.rb +6 -5
- data/lib/dynflow/action/with_sub_plans.rb +162 -0
- data/lib/dynflow/execution_plan.rb +25 -7
- data/lib/dynflow/execution_plan/steps/abstract.rb +5 -2
- data/lib/dynflow/execution_plan/steps/plan_step.rb +6 -2
- data/lib/dynflow/execution_plan/steps/run_step.rb +4 -0
- data/lib/dynflow/persistence.rb +5 -0
- data/lib/dynflow/persistence_adapters/sequel.rb +12 -2
- data/lib/dynflow/persistence_adapters/sequel_migrations/003_parent_action.rb +9 -0
- data/lib/dynflow/version.rb +1 -1
- data/lib/dynflow/web_console.rb +21 -7
- data/lib/dynflow/world.rb +26 -2
- data/test/action_test.rb +107 -0
- data/test/persistance_adapters_test.rb +2 -2
- data/test/test_helper.rb +1 -1
- data/web/views/flow_step.erb +3 -0
- metadata +137 -4
data/README.md
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
-
![Dynflow](doc/images/logo.png)
|
1
|
+
![Dynflow](doc/pages/source/images/logo-long.png)
|
2
2
|
=======
|
3
3
|
|
4
|
-
![Build](https://
|
4
|
+
![Build](https://img.shields.io/travis/Dynflow/dynflow/master.svg?style=flat)
|
5
|
+
![Issues](https://img.shields.io/github/issues/Dynflow/dynflow.svg?style=flat)
|
6
|
+
![Gem version](https://img.shields.io/gem/v/dynflow.svg?style=flat)
|
7
|
+
![License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)
|
5
8
|
|
6
|
-
|
9
|
+
**Note:** *There is a project page and documentation being build in url <http://http://dynflow.github.io/>.
|
10
|
+
It's still work in progress but you may find useful information there. It'll eventually replace
|
11
|
+
this README.*
|
12
|
+
|
13
|
+
[Dynflow [DYN(amic work)FLOW]](http://dynflow.github.io/) is a workflow engine
|
7
14
|
written in Ruby that allows to:
|
8
15
|
|
9
16
|
* keep track of the progress of running process
|
@@ -29,6 +36,7 @@ implementations as well).
|
|
29
36
|
|
30
37
|
![Screenshot](doc/images/screenshot.png)
|
31
38
|
|
39
|
+
* [Documentation](http://dynflow.github.io/documentation/) *in progress*
|
32
40
|
* [Current status](#current-status)
|
33
41
|
* [How it works](#how-it-works)
|
34
42
|
* [Examples](#examples)
|
data/doc/pages/Gemfile
ADDED
data/doc/pages/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
root = File.dirname __FILE__
|
5
|
+
|
6
|
+
task :default => :publish
|
7
|
+
|
8
|
+
def system(cmd)
|
9
|
+
puts ">> #{cmd}"
|
10
|
+
super cmd
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'push to Github'
|
14
|
+
task :publish do
|
15
|
+
Dir.chdir(root) do
|
16
|
+
Dir.chdir(root + '/public') do
|
17
|
+
system 'git fetch --all'
|
18
|
+
system 'git reset --hard origin/master'
|
19
|
+
end
|
20
|
+
system 'jekyll build'
|
21
|
+
Dir.chdir(root + '/public') do
|
22
|
+
system 'git ac -m Update'
|
23
|
+
system 'git push'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
---
|
2
|
+
name: Dynflow
|
3
|
+
title: Dynflow
|
4
|
+
url: http://dynflow.github.io
|
5
|
+
markdown: redcarpet
|
6
|
+
highlighter: pygments
|
7
|
+
|
8
|
+
source: ./source
|
9
|
+
destination: ./public
|
10
|
+
plugins: ./plugins
|
11
|
+
include:
|
12
|
+
- .nojekyll
|
13
|
+
|
14
|
+
tag_page_layout: tag_page
|
15
|
+
tag_page_dir: tag
|
16
|
+
|
17
|
+
permalink: /blog/:year/:month/:day/:title/
|
18
|
+
|
19
|
+
favicon: /images/logo-square.png
|
20
|
+
|
21
|
+
disqus_short_name: dynflow
|
22
|
+
twitter_user: pitr_ch
|
23
|
+
google_analytics_tracking_id: UA-60290609-1
|
24
|
+
|
25
|
+
sass:
|
26
|
+
sass_dir: _sass
|
27
|
+
|
28
|
+
redcarpet:
|
29
|
+
extensions:
|
30
|
+
- with_toc_data
|
31
|
+
- html_toc
|
32
|
+
- strikethrough
|
33
|
+
|
34
|
+
plantuml:
|
35
|
+
plantuml_jar: .bin/plantuml.jar # path to plantuml jar
|
36
|
+
tmp_folder: tmp # tmp folder to put generated image files
|
37
|
+
background_color: transparent # [optional] UML image background color
|
38
|
+
# dot_exe: /usr/local/bin/dot # [optional] path to Graphviz dot execution
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative 'div_tag'
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
class AlertBlock < DivTag
|
5
|
+
def initialize(tag_name, markup, tokens)
|
6
|
+
@alert_type = tag_name.split('_').first
|
7
|
+
super tag_name, markup + ' alert alert-' + @alert_type, tokens
|
8
|
+
end
|
9
|
+
|
10
|
+
def tag
|
11
|
+
'div'
|
12
|
+
end
|
13
|
+
|
14
|
+
HEADER = { 'info' => 'Note',
|
15
|
+
'warning' => 'Warning',
|
16
|
+
'danger' => 'Danger' }
|
17
|
+
|
18
|
+
def render_content(context, content)
|
19
|
+
super context, "**#{HEADER[@alert_type]}** \n" + content
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Liquid::Template.register_tag('info_block', Jekyll::AlertBlock)
|
25
|
+
Liquid::Template.register_tag('warning_block', Jekyll::AlertBlock)
|
26
|
+
Liquid::Template.register_tag('danger_block', Jekyll::AlertBlock)
|
27
|
+
# Liquid::Template.register_tag('success_block', Jekyll::AlertBlock)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Jekyll
|
2
|
+
class DivTag < Liquid::Block
|
3
|
+
def render(context)
|
4
|
+
content = super
|
5
|
+
|
6
|
+
<<-HTML.gsub(/^ +\|/, '')
|
7
|
+
|<#{tag} class="#{@markup}">
|
8
|
+
| #{render_content context, content}
|
9
|
+
|</#{tag}>
|
10
|
+
HTML
|
11
|
+
end
|
12
|
+
|
13
|
+
def tag
|
14
|
+
@tag_name.split('_').first
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_content(context, content)
|
18
|
+
context.registers[:site].converters.find { |c| c.is_a? Jekyll::Converters::Markdown }.convert(content)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Liquid::Template.register_tag('div_tag', Jekyll::DivTag)
|
24
|
+
Liquid::Template.register_tag('span_tag', Jekyll::DivTag)
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# taken from https://raw.githubusercontent.com/kui/octopress-graphviz/master/graphviz_block.rb
|
2
|
+
|
3
|
+
require 'open3'
|
4
|
+
|
5
|
+
module Jekyll
|
6
|
+
class GraphvizBlock < Liquid::Block
|
7
|
+
|
8
|
+
DIV_CLASS_ATTR = 'graphviz-wrapper'
|
9
|
+
DEFAULT_GRAPH_NAME = 'Graphviz'
|
10
|
+
DOT_OPTS = '-Tsvg'
|
11
|
+
DOT_EXEC = 'dot'
|
12
|
+
DOT_EXTS = (ENV['PATHEXT'] || '.exe;.bat;.com').split(";")
|
13
|
+
DOT_EXTS.unshift ''
|
14
|
+
DOT_PATH = ENV['PATH'].split(File::PATH_SEPARATOR)
|
15
|
+
.map { |a| File.join a, DOT_EXEC }
|
16
|
+
.map { |a| DOT_EXTS.map { |ex| a+ex } }.flatten
|
17
|
+
.find { |c| File.executable_real? c }
|
18
|
+
raise "not found a executable file: #{DOT_EXEC}" if DOT_PATH.nil?
|
19
|
+
DOT_CMD = "#{DOT_PATH} #{DOT_OPTS}"
|
20
|
+
|
21
|
+
def initialize(tag_name, markup, tokens)
|
22
|
+
super
|
23
|
+
@tag_name = tag_name
|
24
|
+
|
25
|
+
@title = markup or ""
|
26
|
+
@title.strip!
|
27
|
+
|
28
|
+
@src = ""
|
29
|
+
end
|
30
|
+
|
31
|
+
def render(context)
|
32
|
+
code = super
|
33
|
+
title = if @title.empty? then
|
34
|
+
DEFAULT_GRAPH_NAME
|
35
|
+
else
|
36
|
+
@title
|
37
|
+
end
|
38
|
+
|
39
|
+
case @tag_name
|
40
|
+
when 'graphviz' then
|
41
|
+
render_graphviz code
|
42
|
+
when 'graph' then
|
43
|
+
render_graph 'graph', title, code
|
44
|
+
when 'digraph' then
|
45
|
+
render_graph 'digraph', title, code
|
46
|
+
else
|
47
|
+
raise "unknown liquid tag name: #{@tag_name}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def render_graphviz(code)
|
52
|
+
@src = code
|
53
|
+
svg = generate_svg code
|
54
|
+
filter_for_inline_svg svg
|
55
|
+
end
|
56
|
+
|
57
|
+
def filter_for_inline_svg(code)
|
58
|
+
code = remove_declarations code
|
59
|
+
code = remove_xmlns_attrs code
|
60
|
+
code = add_desc_attrs code
|
61
|
+
code = insert_desc_elements code
|
62
|
+
code = wrap_with_div code
|
63
|
+
code = code.gsub /<polygon fill="white" stroke="none"/, '<polygon fill="transparent" stroke="none"'
|
64
|
+
code
|
65
|
+
end
|
66
|
+
|
67
|
+
def generate_svg code
|
68
|
+
Open3.popen3(DOT_CMD) do |stdin, stdout, stderr|
|
69
|
+
stdout.binmode
|
70
|
+
stdin.print code
|
71
|
+
stdin.close
|
72
|
+
|
73
|
+
err = stderr.read
|
74
|
+
if not (err.nil? || err.strip.empty?)
|
75
|
+
raise "Error from #{DOT_CMD}:\n#{err}"
|
76
|
+
end
|
77
|
+
|
78
|
+
svg = stdout.read
|
79
|
+
svg.force_encoding 'UTF-8'
|
80
|
+
|
81
|
+
return svg
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def remove_declarations(svg)
|
86
|
+
svg.sub(/<!DOCTYPE .+?>/im, '').sub(/<\?xml .+?\?>/im, '')
|
87
|
+
end
|
88
|
+
|
89
|
+
def remove_xmlns_attrs(svg)
|
90
|
+
svg.sub(%[xmlns="http://www.w3.org/2000/svg"], '')
|
91
|
+
.sub(%[xmlns:xlink="http://www.w3.org/1999/xlink"], '')
|
92
|
+
end
|
93
|
+
|
94
|
+
def add_desc_attrs(svg)
|
95
|
+
svg.sub!("<svg", %[<svg aria-label="#{CGI::escapeHTML @title}"])
|
96
|
+
svg.sub!("<svg", %[<svg role="img"])
|
97
|
+
|
98
|
+
return svg
|
99
|
+
end
|
100
|
+
|
101
|
+
def insert_desc_elements(svg)
|
102
|
+
inserted_elements = %[<title>#{CGI::escapeHTML @title}</title>\n]
|
103
|
+
inserted_elements << %[<desc>#{CGI::escapeHTML @src}</desc>\n]
|
104
|
+
svg.sub!(/(<svg [^>]*>)/, "\\1\n#{inserted_elements}")
|
105
|
+
|
106
|
+
return svg
|
107
|
+
end
|
108
|
+
|
109
|
+
def wrap_with_div(svg)
|
110
|
+
%[<div class="#{DIV_CLASS_ATTR}">#{svg}</div>]
|
111
|
+
end
|
112
|
+
|
113
|
+
def render_graph(type, title, code)
|
114
|
+
render_graphviz %[#{type} "#{title}" { #{code} }]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
Liquid::Template.register_tag('graphviz', Jekyll::GraphvizBlock)
|
120
|
+
Liquid::Template.register_tag('graph', Jekyll::GraphvizBlock)
|
121
|
+
Liquid::Template.register_tag('digraph', Jekyll::GraphvizBlock)
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Title: PlantUML Code Blocks for Jekyll
|
2
|
+
# Author: YJ Park (yjpark@gmail.com)
|
3
|
+
# https://github.com/yjpark/jekyll-plantuml
|
4
|
+
# Description: Integrate PlantUML into Jekyll and Octopress.
|
5
|
+
#
|
6
|
+
# Syntax:
|
7
|
+
# {% plantuml %}
|
8
|
+
# plantuml code
|
9
|
+
# {% endplantuml %}
|
10
|
+
#
|
11
|
+
require 'open3'
|
12
|
+
require 'fileutils'
|
13
|
+
|
14
|
+
module Jekyll
|
15
|
+
|
16
|
+
class PlantUMLBlock < Liquid::Block
|
17
|
+
attr_reader :config
|
18
|
+
|
19
|
+
def render(context)
|
20
|
+
site = context.registers[:site]
|
21
|
+
self.config = site.config['plantuml']
|
22
|
+
|
23
|
+
tmproot = File.expand_path(tmp_folder)
|
24
|
+
folder = "/images/plantuml/"
|
25
|
+
create_tmp_folder(tmproot, folder)
|
26
|
+
|
27
|
+
code = @nodelist.join + background_color
|
28
|
+
filename = Digest::MD5.hexdigest(code) + ".png"
|
29
|
+
filepath = tmproot + folder + filename
|
30
|
+
if !File.exist?(filepath)
|
31
|
+
plantuml_jar = File.expand_path(plantuml_jar_path)
|
32
|
+
cmd = "java -Djava.awt.headless=true -jar " + plantuml_jar + dot_cmd + " -pipe > " + filepath
|
33
|
+
result, status = Open3.capture2e(cmd, :stdin_data=>code)
|
34
|
+
Jekyll.logger.debug(filepath + " -->\t" + status.inspect() + "\t" + result)
|
35
|
+
end
|
36
|
+
|
37
|
+
site.static_files << Jekyll::StaticFile.new(site, tmproot, folder, filename)
|
38
|
+
|
39
|
+
# source = "<img class=\"img-thumbnail\" src='" + folder + filename + "'>"
|
40
|
+
source = "<img src='" + folder + filename + "'>"
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def config=(cfg)
|
46
|
+
@config = cfg || Jekyll.logger.abort_with("Missing 'plantuml' configurations.")
|
47
|
+
end
|
48
|
+
|
49
|
+
def background_color
|
50
|
+
config['background_color'].nil? ? '' : " skinparam backgroundColor " + config['background_color']
|
51
|
+
end
|
52
|
+
|
53
|
+
def plantuml_jar_path
|
54
|
+
config['plantuml_jar'] || Jekyll.logger.abort_with("Missing configuration 'plantuml.plantuml_jar'.")
|
55
|
+
end
|
56
|
+
|
57
|
+
def tmp_folder
|
58
|
+
config['tmp_folder'] || Jekyll.logger.abort_with("Missing configuration 'plantuml.tmp_folder'.")
|
59
|
+
end
|
60
|
+
|
61
|
+
def dot_cmd
|
62
|
+
@dot_cmd ||= begin
|
63
|
+
dotpath = File.expand_path(config['dot_exe'] || '__NULL__')
|
64
|
+
if File.exist?(dotpath)
|
65
|
+
# Jekyll.logger.info("PlantUML: Use graphviz dot: " + dotpath)
|
66
|
+
" -graphvizdot " + dotpath
|
67
|
+
else
|
68
|
+
# Jekyll.logger.info("PlantUML: Assume graphviz dot is in PATH.")
|
69
|
+
''
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_tmp_folder(tmproot, folder)
|
75
|
+
folderpath = tmproot + folder
|
76
|
+
if !File.exist?(folderpath)
|
77
|
+
FileUtils::mkdir_p folderpath
|
78
|
+
Jekyll.logger.info("Create PlantUML image folder: " + folderpath)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end # PlantUMLBlock
|
83
|
+
end
|
84
|
+
|
85
|
+
Liquid::Template.register_tag('plantuml', Jekyll::PlantUMLBlock)
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'nuggets/range/quantile'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module Jekyll
|
5
|
+
|
6
|
+
class Tagger < Generator
|
7
|
+
|
8
|
+
safe true
|
9
|
+
|
10
|
+
attr_accessor :site
|
11
|
+
|
12
|
+
@types = [:page, :feed]
|
13
|
+
|
14
|
+
class << self; attr_accessor :types, :site; end
|
15
|
+
|
16
|
+
def generate(site)
|
17
|
+
self.class.site = self.site = site
|
18
|
+
|
19
|
+
generate_tag_pages
|
20
|
+
add_tag_cloud
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# Generates a page per tag and adds them to all the pages of +site+.
|
26
|
+
# A <tt>tag_page_layout</tt> have to be defined in your <tt>_config.yml</tt>
|
27
|
+
# to use this.
|
28
|
+
def generate_tag_pages
|
29
|
+
active_tags.each { |tag, posts| new_tag(tag, posts) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def new_tag(tag, posts)
|
33
|
+
self.class.types.each { |type|
|
34
|
+
if layout = site.config["tag_#{type}_layout"]
|
35
|
+
data = { 'layout' => layout, 'posts' => posts.sort.reverse!, 'tag' => tag, 'title' => tag }
|
36
|
+
|
37
|
+
name = yield data if block_given?
|
38
|
+
name ||= tag
|
39
|
+
|
40
|
+
tag_dir = site.config["tag_#{type}_dir"]
|
41
|
+
tag_dir = File.join(tag_dir, (pretty? ? name : ''))
|
42
|
+
|
43
|
+
page_name = "#{pretty? ? 'index' : name}#{site.layouts[data['layout']].ext}"
|
44
|
+
|
45
|
+
site.pages << TagPage.new(
|
46
|
+
site, site.source, tag_dir, page_name, data
|
47
|
+
)
|
48
|
+
end
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_tag_cloud(num = 5, name = 'tag_data')
|
53
|
+
s, t = site, { name => calculate_tag_cloud(num) }
|
54
|
+
s.respond_to?(:add_payload) ? s.add_payload(t) : s.config.update(t)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Calculates the css class of every tag for a tag cloud. The possible
|
58
|
+
# classes are: set-1..set-5.
|
59
|
+
#
|
60
|
+
# [[<TAG>, <CLASS>], ...]
|
61
|
+
def calculate_tag_cloud(num = 5)
|
62
|
+
range = 0
|
63
|
+
|
64
|
+
tags = active_tags.map { |tag, posts|
|
65
|
+
[tag.to_s, range < (size = posts.size) ? range = size : size]
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
range = 1..range
|
70
|
+
|
71
|
+
tags.sort!.map! { |tag, size| [tag, range.quantile(size, num)] }
|
72
|
+
end
|
73
|
+
|
74
|
+
def active_tags
|
75
|
+
return site.tags unless site.config["ignored_tags"]
|
76
|
+
site.tags.reject { |t| site.config["ignored_tags"].include? t[0] }
|
77
|
+
end
|
78
|
+
|
79
|
+
def pretty?
|
80
|
+
@pretty ||= (site.permalink_style == :pretty || site.config['tag_permalink_style'] == 'pretty')
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
class TagPage < Page
|
86
|
+
|
87
|
+
def initialize(site, base, dir, name, data = {})
|
88
|
+
self.content = data.delete('content') || ''
|
89
|
+
self.data = data
|
90
|
+
|
91
|
+
super(site, base, dir[-1, 1] == '/' ? dir : '/' + dir, name)
|
92
|
+
end
|
93
|
+
|
94
|
+
def read_yaml(*)
|
95
|
+
# Do nothing
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
module Filters
|
101
|
+
|
102
|
+
def tag_cloud(site)
|
103
|
+
active_tag_data.map { |tag, set|
|
104
|
+
tag_link(tag, tag_url(tag), :class => "set-#{set} label label-default")
|
105
|
+
}.join(' ')
|
106
|
+
end
|
107
|
+
|
108
|
+
def tag_link(tag, url = tag_url(tag), html_opts = nil)
|
109
|
+
html_opts &&= ' ' << html_opts.map { |k, v| %Q{#{k}="#{v}"} }.join(' ')
|
110
|
+
%Q{<a href="#{url}"#{html_opts}>#{tag}</a>}
|
111
|
+
end
|
112
|
+
|
113
|
+
def tag_url(tag, type = :page, site = Tagger.site)
|
114
|
+
# FIXME generate full url for atom.xml page
|
115
|
+
url = File.join('', site.config["tag_#{type}_dir"], ERB::Util.u(tag))
|
116
|
+
site.permalink_style == :pretty || site.config['tag_permalink_style'] == 'pretty' ? url : url << '.html'
|
117
|
+
end
|
118
|
+
|
119
|
+
def tags(obj)
|
120
|
+
tags = obj['tags'].dup
|
121
|
+
tags.map! { |t| t.first } if tags.first.is_a?(Array)
|
122
|
+
tags.map! { |t| tag_link(t, tag_url(t), rel: 'tag', class: 'label label-default') if t.is_a?(String) }.compact!
|
123
|
+
tags.join(' ')
|
124
|
+
end
|
125
|
+
|
126
|
+
def keywords(obj)
|
127
|
+
return '' if not obj['tags']
|
128
|
+
tags = obj['tags'].dup
|
129
|
+
tags.join(',')
|
130
|
+
end
|
131
|
+
|
132
|
+
def active_tag_data(site = Tagger.site)
|
133
|
+
return site.config['tag_data'] unless site.config["ignored_tags"]
|
134
|
+
site.config["tag_data"].reject { |tag, set| site.config["ignored_tags"].include? tag }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|