asciidoctor-chart 1.0.0.alpha.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +38 -0
- data/README.adoc +89 -3
- data/asciidoctor-chart.gemspec +18 -11
- data/lib/asciidoctor/chart/block_macro_processor.rb +1 -3
- data/lib/asciidoctor/chart/block_processor.rb +1 -3
- data/lib/asciidoctor/chart/chart_block.rb +45 -0
- data/lib/asciidoctor/chart/converter/c3js.rb +231 -0
- data/lib/asciidoctor/chart/converter/chartist.rb +81 -0
- data/lib/asciidoctor/chart/converter/chartjs.rb +102 -0
- data/lib/asciidoctor/chart/converter.rb +13 -0
- data/lib/asciidoctor/chart/docinfo_processor.rb +69 -20
- data/lib/asciidoctor/chart/html5_chart_converter_ext.rb +25 -0
- data/lib/asciidoctor/chart/preprocessor.rb +13 -0
- data/lib/asciidoctor/chart/registry.rb +17 -0
- data/lib/asciidoctor/chart/version.rb +1 -1
- data/lib/asciidoctor/chart.rb +36 -4
- metadata +33 -12
- data/lib/asciidoctor/chart/backend.rb +0 -58
- data/lib/asciidoctor/chart/c3js/chart_builder.rb +0 -226
- data/lib/asciidoctor/chart/chartist/chart_builder.rb +0 -88
- data/lib/asciidoctor/chart/chartjs/chart_builder.rb +0 -66
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
module Converter
|
6
|
+
class Html5ChartjsConverter < Asciidoctor::Chart::Converter::Base
|
7
|
+
CSS_VALUE_UNIT_RX = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/.freeze
|
8
|
+
DEFAULT_COLORS = [{ r: 220, g: 220, b: 220 }, { r: 151, g: 187, b: 205 }].freeze
|
9
|
+
|
10
|
+
def convert_line_chart node
|
11
|
+
data, labels = prepare_data node
|
12
|
+
datasets = data.map do |set|
|
13
|
+
color = DEFAULT_COLORS[data.index(set) % 2]
|
14
|
+
color_rgba = "rgba(#{color[:r]},#{color[:g]},#{color[:b]},1.0)"
|
15
|
+
<<~JSON
|
16
|
+
{
|
17
|
+
borderColor: "#{color_rgba}",
|
18
|
+
backgroundColor: "#{color_rgba}",
|
19
|
+
fill: false,
|
20
|
+
tension: 0.1,
|
21
|
+
data: #{set.to_s}
|
22
|
+
}
|
23
|
+
JSON
|
24
|
+
end.join ','
|
25
|
+
|
26
|
+
chart_id = node.attr 'id'
|
27
|
+
inline_styles = []
|
28
|
+
if (chart_height = get_height node)
|
29
|
+
inline_styles.push("height: #{chart_height}")
|
30
|
+
end
|
31
|
+
if (chart_width = get_width node)
|
32
|
+
inline_styles.push("max-width: #{chart_width}")
|
33
|
+
end
|
34
|
+
maintain_aspect_ratio = chart_height.nil? && chart_width.nil?
|
35
|
+
title_element = node.title? ? %(\n <div class="title">#{node.captioned_title}</div>) : ''
|
36
|
+
<<~HTML
|
37
|
+
<div class="chartblock">
|
38
|
+
<div class="content chartjs-content" style="#{inline_styles.join('; ')}">
|
39
|
+
<canvas id="#{chart_id}"></canvas>
|
40
|
+
</div>#{title_element}
|
41
|
+
</div>
|
42
|
+
<script>
|
43
|
+
window.addEventListener('load', function(event) {
|
44
|
+
var data = {
|
45
|
+
labels: #{labels.to_s},
|
46
|
+
datasets: [#{datasets}]
|
47
|
+
}
|
48
|
+
var chart = new Chart(document.getElementById("#{chart_id}").getContext("2d"), {
|
49
|
+
type: 'line',
|
50
|
+
data: data,
|
51
|
+
options: {
|
52
|
+
interaction: {
|
53
|
+
mode: 'index'
|
54
|
+
},
|
55
|
+
responsive : true,
|
56
|
+
maintainAspectRatio: #{maintain_aspect_ratio},
|
57
|
+
plugins: {
|
58
|
+
legend: {
|
59
|
+
display: false
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
})
|
64
|
+
})
|
65
|
+
</script>
|
66
|
+
HTML
|
67
|
+
end
|
68
|
+
|
69
|
+
def prepare_data node
|
70
|
+
raw_data = node.attr 'data-raw', []
|
71
|
+
return [[], []] if raw_data.length <= 1 # question: should we warn?
|
72
|
+
|
73
|
+
labels = raw_data[0]
|
74
|
+
raw_data.shift
|
75
|
+
[raw_data, labels]
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def get_height node
|
81
|
+
return unless (height = node.attr 'height')
|
82
|
+
|
83
|
+
to_css_size height
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_width node
|
87
|
+
return unless (width = node.attr 'width')
|
88
|
+
|
89
|
+
to_css_size width
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_css_size str
|
93
|
+
return str unless (parts = str.match(CSS_VALUE_UNIT_RX))
|
94
|
+
|
95
|
+
value, unit = parts.captures
|
96
|
+
unit = 'px' if unit == ''
|
97
|
+
"#{value}#{unit}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -6,26 +6,75 @@ module Asciidoctor
|
|
6
6
|
use_dsl
|
7
7
|
# at_location :head
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
9
|
+
C3JS_DIR_ATTR = 'c3jsdir'
|
10
|
+
C3JS_DEFAULT_PATH = 'https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.20/'
|
11
|
+
|
12
|
+
CHARTJS_DIR_ATTR = 'chartjsdir'
|
13
|
+
CHARTJS_DEFAULT_PATH = 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/'
|
14
|
+
|
15
|
+
CHARTIST_DIR_ATTR = 'chartistdir'
|
16
|
+
CHARTIST_DEFAULT_PATH = 'https://cdn.jsdelivr.net/npm/chartist@0.11.x/dist/'
|
17
|
+
|
18
|
+
D3JS_DIR_ATTR = 'd3jsdir'
|
19
|
+
D3JS_DEFAULT_PATH = 'https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/'
|
20
|
+
|
21
|
+
DEFAULT_STYLE = <<~HTML.chomp
|
22
|
+
<style>
|
23
|
+
.chartblock {
|
24
|
+
margin-bottom: 1.25em;
|
25
|
+
}
|
26
|
+
.chartblock > .title {
|
27
|
+
text-rendering: optimizeLegibility;
|
28
|
+
text-align: left;
|
29
|
+
font-size: 1rem;
|
30
|
+
font-style: italic;
|
31
|
+
line-height: 1.45;
|
32
|
+
color: #7a2518;
|
33
|
+
font-weight: 400;
|
34
|
+
}
|
35
|
+
.chartblock > .chartjs-content {
|
36
|
+
position: relative;
|
37
|
+
margin-bottom: 0.25em;
|
38
|
+
}
|
39
|
+
</style>
|
40
|
+
HTML
|
41
|
+
|
42
|
+
def process(doc)
|
43
|
+
engines = doc.x_chart[:engines]
|
44
|
+
(engines.map {|engine| send(engine, doc) }.to_a + [DEFAULT_STYLE]).join "\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def get_path(doc, attr_name, default_path, asset_to_include)
|
50
|
+
doc.normalize_web_path asset_to_include, (doc.attr attr_name, default_path), false
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_script_directive(doc, attr_name, default_path, asset_to_include)
|
54
|
+
%(<script src="#{get_path doc, attr_name, default_path, asset_to_include}"></script>)
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_link_css_directive(doc, attr_name, default_path, asset_to_include)
|
58
|
+
%(<link rel="stylesheet" href="#{get_path doc, attr_name, default_path, asset_to_include}">)
|
59
|
+
end
|
60
|
+
|
61
|
+
def chartjs(doc)
|
62
|
+
create_script_directive(doc, CHARTJS_DIR_ATTR, CHARTJS_DEFAULT_PATH, 'chart.min.js')
|
63
|
+
end
|
64
|
+
|
65
|
+
def chartist(doc)
|
66
|
+
result = []
|
67
|
+
result << create_link_css_directive(doc, CHARTIST_DIR_ATTR, CHARTIST_DEFAULT_PATH, 'chartist.min.css')
|
68
|
+
result << create_script_directive(doc, CHARTIST_DIR_ATTR, CHARTIST_DEFAULT_PATH, 'chartist.min.js')
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
def c3js(doc)
|
73
|
+
result = []
|
74
|
+
result << create_link_css_directive(doc, C3JS_DIR_ATTR, C3JS_DEFAULT_PATH, 'c3.min.css')
|
75
|
+
result << create_script_directive(doc, D3JS_DIR_ATTR, D3JS_DEFAULT_PATH, 'd3.min.js')
|
76
|
+
result << create_script_directive(doc, C3JS_DIR_ATTR, C3JS_DEFAULT_PATH, 'c3.min.js')
|
77
|
+
result
|
29
78
|
end
|
30
79
|
end
|
31
80
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
module Html5ChartConverterExt
|
6
|
+
def convert_chart node
|
7
|
+
chart_engine = node.attr 'engine'
|
8
|
+
chart_type = node.attr 'type'
|
9
|
+
chart_converter = Asciidoctor::Chart::Registry.for chart_engine
|
10
|
+
|
11
|
+
if chart_converter
|
12
|
+
if chart_converter.handles? chart_type
|
13
|
+
chart_converter.send "convert_#{chart_type}_chart", node
|
14
|
+
else
|
15
|
+
logger.warn %(missing chart convert handler for type '#{chart_type}' in #{chart_converter})
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
else
|
19
|
+
logger.warn %(missing chart convert for engine '#{chart_engine}')
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Chart
|
5
|
+
module Registry
|
6
|
+
@registry = {}
|
7
|
+
|
8
|
+
def self.register converter, engine
|
9
|
+
@registry[engine] = converter
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.for engine
|
13
|
+
@registry[engine]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/asciidoctor/chart.rb
CHANGED
@@ -1,19 +1,51 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'asciidoctor/extensions'
|
4
|
+
require 'tilt'
|
5
|
+
require_relative 'chart/html5_chart_converter_ext'
|
6
|
+
require_relative 'chart/registry'
|
7
|
+
require_relative 'chart/preprocessor'
|
4
8
|
require_relative 'chart/block_macro_processor'
|
5
9
|
require_relative 'chart/block_processor'
|
6
10
|
require_relative 'chart/docinfo_processor'
|
7
|
-
require_relative 'chart/
|
11
|
+
require_relative 'chart/chart_block'
|
8
12
|
require_relative 'chart/plain_ruby_csv'
|
9
13
|
require_relative 'chart/plain_ruby_random'
|
10
|
-
require_relative 'chart/
|
11
|
-
require_relative 'chart/
|
12
|
-
require_relative 'chart/chartist
|
14
|
+
require_relative 'chart/converter'
|
15
|
+
require_relative 'chart/converter/c3js'
|
16
|
+
require_relative 'chart/converter/chartist'
|
17
|
+
require_relative 'chart/converter/chartjs'
|
18
|
+
|
19
|
+
CHART_HTML_TEMPLATE = Tilt.new('chart.html.erb', format: :html5, pretty: true, disable_escape: true) do |_t|
|
20
|
+
<<-ERB
|
21
|
+
<%= Class.new.extend(Asciidoctor::Chart::Html5ChartConverterExt).convert_chart self %>
|
22
|
+
ERB
|
23
|
+
end
|
24
|
+
|
25
|
+
# providers
|
26
|
+
Asciidoctor::Chart::Registry.register Asciidoctor::Chart::Converter::Html5ChartjsConverter.new, 'chartjs'
|
27
|
+
Asciidoctor::Chart::Registry.register Asciidoctor::Chart::Converter::Html5ChartistConverter.new, 'chartist'
|
28
|
+
Asciidoctor::Chart::Registry.register Asciidoctor::Chart::Converter::Html5C3jsConverter.new, 'c3js'
|
29
|
+
|
30
|
+
def register_chart_converter converter
|
31
|
+
if (converter.instance_of? Asciidoctor::Converter::TemplateConverter) || (converter.respond_to? 'register')
|
32
|
+
# Template based converter
|
33
|
+
converter.register 'chart', CHART_HTML_TEMPLATE
|
34
|
+
else
|
35
|
+
converter.extend(Asciidoctor::Chart::Html5ChartConverterExt)
|
36
|
+
end
|
37
|
+
end
|
13
38
|
|
14
39
|
Asciidoctor::Extensions.register do
|
15
40
|
return unless document.basebackend? 'html'
|
16
41
|
|
42
|
+
converter = document.converter
|
43
|
+
if converter.instance_of? Asciidoctor::Converter::CompositeConverter
|
44
|
+
register_chart_converter(converter.converters[0])
|
45
|
+
else
|
46
|
+
register_chart_converter(converter)
|
47
|
+
end
|
48
|
+
preprocessor Asciidoctor::Chart::Preprocessor
|
17
49
|
block_macro Asciidoctor::Chart::BlockMacroProcessor
|
18
50
|
block Asciidoctor::Chart::BlockProcessor
|
19
51
|
docinfo_processor Asciidoctor::Chart::DocinfoProcessor
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-chart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guillaume Grossetie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: tilt
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.0.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,35 +66,42 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: 3.9.0
|
55
|
-
description:
|
56
|
-
|
69
|
+
description: |-
|
70
|
+
A set of Asciidoctor extensions that add a chart block and block macro to AsciiDoc
|
71
|
+
for including charts in your AsciiDoc document.
|
57
72
|
email: ggrossetie@gmail.com
|
58
73
|
executables: []
|
59
74
|
extensions: []
|
60
75
|
extra_rdoc_files: []
|
61
76
|
files:
|
77
|
+
- CHANGELOG.adoc
|
62
78
|
- LICENSE.adoc
|
63
79
|
- README.adoc
|
64
80
|
- asciidoctor-chart.gemspec
|
65
81
|
- lib/asciidoctor-chart.rb
|
66
82
|
- lib/asciidoctor/chart.rb
|
67
|
-
- lib/asciidoctor/chart/backend.rb
|
68
83
|
- lib/asciidoctor/chart/block_macro_processor.rb
|
69
84
|
- lib/asciidoctor/chart/block_processor.rb
|
70
|
-
- lib/asciidoctor/chart/
|
71
|
-
- lib/asciidoctor/chart/
|
72
|
-
- lib/asciidoctor/chart/
|
85
|
+
- lib/asciidoctor/chart/chart_block.rb
|
86
|
+
- lib/asciidoctor/chart/converter.rb
|
87
|
+
- lib/asciidoctor/chart/converter/c3js.rb
|
88
|
+
- lib/asciidoctor/chart/converter/chartist.rb
|
89
|
+
- lib/asciidoctor/chart/converter/chartjs.rb
|
73
90
|
- lib/asciidoctor/chart/docinfo_processor.rb
|
91
|
+
- lib/asciidoctor/chart/html5_chart_converter_ext.rb
|
74
92
|
- lib/asciidoctor/chart/plain_ruby_csv.rb
|
75
93
|
- lib/asciidoctor/chart/plain_ruby_random.rb
|
94
|
+
- lib/asciidoctor/chart/preprocessor.rb
|
95
|
+
- lib/asciidoctor/chart/registry.rb
|
76
96
|
- lib/asciidoctor/chart/version.rb
|
77
97
|
homepage: https://asciidoctor.org
|
78
98
|
licenses:
|
79
99
|
- MIT
|
80
100
|
metadata:
|
81
101
|
bug_tracker_uri: https://github.com/asciidoctor/asciidoctor-chart/issues
|
82
|
-
|
102
|
+
community_chat_uri: https://asciidoctor.zulipchat.com
|
83
103
|
source_code_uri: https://github.com/asciidoctor/asciidoctor-chart
|
104
|
+
rubygems_mfa_required: 'true'
|
84
105
|
post_install_message:
|
85
106
|
rdoc_options: []
|
86
107
|
require_paths:
|
@@ -92,11 +113,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
113
|
version: '0'
|
93
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
115
|
requirements:
|
95
|
-
- - "
|
116
|
+
- - ">="
|
96
117
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
118
|
+
version: '0'
|
98
119
|
requirements: []
|
99
|
-
rubygems_version: 3.0.3
|
120
|
+
rubygems_version: 3.0.3.1
|
100
121
|
signing_key:
|
101
122
|
specification_version: 4
|
102
123
|
summary: Adds a chart block and block macro to AsciiDoc
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Asciidoctor
|
4
|
-
module Chart
|
5
|
-
class Backend
|
6
|
-
def self.resolve_engine attrs, document
|
7
|
-
if attrs.key? 'engine'
|
8
|
-
attrs['engine'].downcase
|
9
|
-
elsif document.attributes.key? 'chart-engine'
|
10
|
-
document.attributes['chart-engine'].downcase
|
11
|
-
else
|
12
|
-
'c3js'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.process engine, attrs, raw_data
|
17
|
-
# TODO: Check that the engine can process the required type (bar, line, step...)
|
18
|
-
type = attrs['type']
|
19
|
-
case engine
|
20
|
-
when 'c3js'
|
21
|
-
if type == 'pie'
|
22
|
-
C3js::ChartBuilder.pie raw_data, attrs
|
23
|
-
else
|
24
|
-
data, labels = C3js::ChartBuilder.prepare_data raw_data
|
25
|
-
case type
|
26
|
-
when 'bar'
|
27
|
-
C3js::ChartBuilder.bar data, labels, attrs
|
28
|
-
when 'line'
|
29
|
-
C3js::ChartBuilder.line data, labels, attrs
|
30
|
-
when 'step'
|
31
|
-
C3js::ChartBuilder.step data, labels, attrs
|
32
|
-
when 'spline'
|
33
|
-
C3js::ChartBuilder.spline data, labels, attrs
|
34
|
-
else
|
35
|
-
# By default chart line
|
36
|
-
C3js::ChartBuilder.line data, labels, attrs
|
37
|
-
end
|
38
|
-
end
|
39
|
-
when 'chartist'
|
40
|
-
data, labels = Chartist::ChartBuilder.prepare_data raw_data
|
41
|
-
case type
|
42
|
-
when 'bar'
|
43
|
-
Chartist::ChartBuilder.bar data, labels, attrs
|
44
|
-
when 'line'
|
45
|
-
Chartist::ChartBuilder.line data, labels, attrs
|
46
|
-
else
|
47
|
-
# By default chart line
|
48
|
-
Chartist::ChartBuilder.line data, labels, attrs
|
49
|
-
end
|
50
|
-
when 'chartjs'
|
51
|
-
data, labels = Chartjs::ChartBuilder.prepare_data raw_data
|
52
|
-
# By default chart line
|
53
|
-
Chartjs::ChartBuilder.line data, labels, attrs
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|