asciinurse 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.idea/.name +1 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/asciinurse.iml +35 -0
- data/.idea/compiler.xml +22 -0
- data/.idea/copyright/profiles_settings.xml +3 -0
- data/.idea/misc.xml +14 -0
- data/.idea/modules.xml +8 -0
- data/.idea/uiDesigner.xml +124 -0
- data/.idea/vcs.xml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.adoc +127 -0
- data/Rakefile +2 -0
- data/asciinurse.gemspec +26 -0
- data/config/asciinurse.yml +22 -0
- data/examples/charts/browsers-googlecharts.json +21 -0
- data/examples/charts/browsers-highcharts.json +64 -0
- data/examples/charts/browsers.csv +7 -0
- data/examples/charts/googlecharts.adoc +83 -0
- data/examples/charts/googlecharts.html +652 -0
- data/examples/charts/googlecharts.pdf +0 -0
- data/examples/charts/highcharts.adoc +83 -0
- data/examples/charts/highcharts.html +1126 -0
- data/examples/charts/highcharts.pdf +0 -0
- data/examples/charts/indicators.csv +13 -0
- data/examples/convert.rb +10 -0
- data/i18n/en_US.yml +12 -0
- data/i18n/pt_BR.yml +12 -0
- data/lib/asciinurse.rb +76 -0
- data/lib/asciinurse/extensions/charts/chart_data.rb +57 -0
- data/lib/asciinurse/extensions/charts/extension.rb +124 -0
- data/lib/asciinurse/version.rb +3 -0
- data/resources/googlecharts/converter/googlecharts-convert.js +25 -0
- data/resources/googlecharts/converter/template.html +24 -0
- data/resources/googlecharts/javascripts/global.js +8 -0
- data/resources/googlecharts/templates/chart.html.erb +6 -0
- data/resources/googlecharts/templates/charts/bar.json.erb +22 -0
- data/resources/googlecharts/templates/charts/column.json.erb +22 -0
- data/resources/googlecharts/templates/charts/donut.json.erb +14 -0
- data/resources/googlecharts/templates/charts/line.json.erb +13 -0
- data/resources/googlecharts/templates/charts/pie.json.erb +13 -0
- data/resources/highcharts/converter/broken-axis.js +6 -0
- data/resources/highcharts/converter/data.js +26 -0
- data/resources/highcharts/converter/drilldown.js +17 -0
- data/resources/highcharts/converter/funnel.js +13 -0
- data/resources/highcharts/converter/heatmap.js +23 -0
- data/resources/highcharts/converter/highcharts-3d.js +46 -0
- data/resources/highcharts/converter/highcharts-convert.js +620 -0
- data/resources/highcharts/converter/highcharts-more.js +54 -0
- data/resources/highcharts/converter/highcharts.js +325 -0
- data/resources/highcharts/converter/highmaps.js +353 -0
- data/resources/highcharts/converter/jquery.1.9.1.min.js +5 -0
- data/resources/highcharts/converter/map.js +56 -0
- data/resources/highcharts/converter/no-data-to-display.js +12 -0
- data/resources/highcharts/converter/solid-gauge.js +14 -0
- data/resources/highcharts/converter/treemap.js +30 -0
- data/resources/highcharts/javascripts/global.js +6 -0
- data/resources/highcharts/javascripts/highcharts.min.js +325 -0
- data/resources/highcharts/javascripts/jquery.min.js +4 -0
- data/resources/highcharts/templates/chart.html.erb +6 -0
- data/resources/highcharts/templates/charts/generic.json.erb +15 -0
- data/resources/highcharts/templates/charts/pie.json.erb +45 -0
- metadata +163 -0
Binary file
|
data/examples/convert.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'asciidoctor'
|
2
|
+
require 'asciidoctor-pdf'
|
3
|
+
require_relative '../lib/asciinurse'
|
4
|
+
|
5
|
+
@pdf = ARGV[0] == '--pdf'
|
6
|
+
|
7
|
+
Dir['**/*.adoc'].each do |file|
|
8
|
+
Asciidoctor.convert_file file, header_footer: true, safe: :unsafe
|
9
|
+
Asciidoctor.convert_file file, backend: 'pdf', header_footer: true, safe: :unsafe if @pdf
|
10
|
+
end
|
data/i18n/en_US.yml
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
en_US:
|
2
|
+
document:
|
3
|
+
figure-caption: Figure
|
4
|
+
table-caption: Table
|
5
|
+
warning-caption: Warning
|
6
|
+
caution-caption: Caution
|
7
|
+
important-caption: Important
|
8
|
+
note-caption: Note
|
9
|
+
tip-caption: Tip
|
10
|
+
example-caption: Example
|
11
|
+
toc-title: Table of Contents
|
12
|
+
last-update-label: Last updated
|
data/i18n/pt_BR.yml
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
pt_BR:
|
2
|
+
document:
|
3
|
+
figure-caption: Figura
|
4
|
+
table-caption: Tabela
|
5
|
+
warning-caption: Atenção
|
6
|
+
caution-caption: Cuidado
|
7
|
+
important-caption: Importante
|
8
|
+
note-caption: Nota
|
9
|
+
tip-caption: Dica
|
10
|
+
example-caption: Exemplo
|
11
|
+
toc-title: Índice
|
12
|
+
last-update-label: Atualizado em
|
data/lib/asciinurse.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'asciidoctor'
|
2
|
+
require 'yaml'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
require_relative 'asciinurse/version'
|
7
|
+
|
8
|
+
ENV['ASCIINURSE_USER_DIR'] ||= ('%s/.asciinurse' % ENV['HOME'])
|
9
|
+
|
10
|
+
module Asciinurse
|
11
|
+
|
12
|
+
RESOURCE_PRECEDENCE = [
|
13
|
+
ENV['ASCIINURSE_USER_DIR'],
|
14
|
+
File.expand_path(File.dirname(__FILE__) + '/..')
|
15
|
+
]
|
16
|
+
|
17
|
+
def self.add_custom_path(path)
|
18
|
+
RESOURCE_PRECEDENCE.insert 1, path
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.find(path)
|
22
|
+
result = []
|
23
|
+
RESOURCE_PRECEDENCE.each do |basedir|
|
24
|
+
result += Dir["#{basedir}/#{path}"]
|
25
|
+
end
|
26
|
+
result
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.find_resource(path)
|
30
|
+
find("resources/#{path}").first
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.read_resource(path)
|
34
|
+
IO.read find_resource(path)
|
35
|
+
end
|
36
|
+
|
37
|
+
CONFIG = {}
|
38
|
+
|
39
|
+
def self.config(key)
|
40
|
+
result = CONFIG
|
41
|
+
key.to_s.split('.').each do |obj|
|
42
|
+
result = result[obj]
|
43
|
+
end
|
44
|
+
result
|
45
|
+
end
|
46
|
+
|
47
|
+
# reverse order so custom config can take precedence over built-in config
|
48
|
+
find('config/asciinurse.yml').reverse_each do |file|
|
49
|
+
CONFIG.merge! YAML::load_file(file)
|
50
|
+
end
|
51
|
+
|
52
|
+
TEMP_DIRS = Set::new
|
53
|
+
|
54
|
+
def self.tmp_dir(document)
|
55
|
+
basedir = document.attributes['docdir']
|
56
|
+
tmpdir = "#{basedir}/tmp"
|
57
|
+
FileUtils.mkpath tmpdir unless File.exist? tmpdir
|
58
|
+
TEMP_DIRS << tmpdir if document.attributes['backend'] == 'pdf'
|
59
|
+
tmpdir
|
60
|
+
end
|
61
|
+
|
62
|
+
at_exit do
|
63
|
+
TEMP_DIRS.each do |tmpdir|
|
64
|
+
FileUtils.rmtree tmpdir
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
require_relative 'asciinurse/extensions/charts/extension'
|
71
|
+
require_relative 'asciinurse/extensions/i18n/extension'
|
72
|
+
|
73
|
+
if File.exist? ENV['ASCIINURSE_USER_DIR']
|
74
|
+
custom_script = '%s/asciinurse.rb' % ENV['ASCIINURSE_USER_DIR']
|
75
|
+
require custom_script if File.exist? custom_script
|
76
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'csv'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module Asciinurse
|
6
|
+
module Chart
|
7
|
+
|
8
|
+
class CSVData
|
9
|
+
def initialize(engine, attrs, csv_content)
|
10
|
+
defaults = Asciinurse.config "charts.#{engine}.defaults"
|
11
|
+
options = defaults.merge attrs if defaults
|
12
|
+
options ||= attrs
|
13
|
+
@engine = engine
|
14
|
+
@title = options['title']
|
15
|
+
@type = options['type']
|
16
|
+
@width = options['width']
|
17
|
+
@height = options['height']
|
18
|
+
@csv = CSV.parse(csv_content, :converters => :all)
|
19
|
+
parse_data
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_chart_json
|
23
|
+
ERB.new(get_template).result binding
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def get_template(default = 'generic.json.erb')
|
29
|
+
template = Asciinurse.find_resource "#{@engine}/templates/charts/#{@type}.json.erb"
|
30
|
+
template ||= Asciinurse.find_resource "#{@engine}/templates/charts/#{default}"
|
31
|
+
raise "Template not found for #{@engine}:#{@type}" unless template
|
32
|
+
IO.read template
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_data
|
36
|
+
@target = @csv[0][0]
|
37
|
+
@elements = @csv.size - 1
|
38
|
+
@series = []
|
39
|
+
@header = []
|
40
|
+
@elements.times do |n|
|
41
|
+
@header << @csv[n + 1].first
|
42
|
+
end
|
43
|
+
(@csv[0].size - 1).times do |n|
|
44
|
+
row = {
|
45
|
+
name: @csv[0][n + 1],
|
46
|
+
data: []
|
47
|
+
}
|
48
|
+
@elements.times do |el|
|
49
|
+
row[:data] << @csv[el + 1][n + 1]
|
50
|
+
end
|
51
|
+
@series << row
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'asciidoctor/extensions'
|
2
|
+
|
3
|
+
require_relative 'chart_data'
|
4
|
+
|
5
|
+
module Asciinurse
|
6
|
+
module Chart
|
7
|
+
module ChartCreator
|
8
|
+
|
9
|
+
def get_engine(doc)
|
10
|
+
doc.attributes['charts'] || Asciinurse.config('charts.default')
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_chart(parent, attrs, config)
|
14
|
+
document = parent.document
|
15
|
+
backend = document.attributes['backend']
|
16
|
+
if backend == 'html5'
|
17
|
+
html = create_from_json document, config
|
18
|
+
create_pass_block parent, html, attrs, subs: nil
|
19
|
+
else
|
20
|
+
attrs['target'] = create_image document, config, attrs
|
21
|
+
attrs['width'] ||= 480
|
22
|
+
attrs['height'] ||= 250
|
23
|
+
|
24
|
+
create_image_block parent, attrs
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_from_json(document, config)
|
29
|
+
id = 'chart_%s' % document.counter(:chart_id)
|
30
|
+
engine = get_engine document
|
31
|
+
template = Asciinurse.read_resource "#{engine}/templates/chart.html.erb"
|
32
|
+
ERB.new(template).result binding
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_from_csv(engine, data, attrs)
|
36
|
+
csv_data = CSVData::new engine, attrs, data
|
37
|
+
csv_data.to_chart_json
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_image(document, config, attrs)
|
41
|
+
engine = get_engine document
|
42
|
+
converter_file = Asciinurse.config "charts.#{engine}.convert.file"
|
43
|
+
tmpdir = Asciinurse.tmp_dir document
|
44
|
+
id = document.counter(:chart_id)
|
45
|
+
|
46
|
+
config_file = "#{tmpdir}/config-#{id}.json"
|
47
|
+
image_file = "#{tmpdir}/chart-#{id}.png"
|
48
|
+
|
49
|
+
IO.write config_file, config
|
50
|
+
|
51
|
+
converter = Asciinurse.find_resource "#{engine}/converter/#{converter_file}"
|
52
|
+
command = Asciinurse.config("charts.#{engine}.convert.command") %
|
53
|
+
[converter, config_file, image_file]
|
54
|
+
|
55
|
+
`#{command}`
|
56
|
+
image_file
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
class ChartBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
|
62
|
+
include ChartCreator
|
63
|
+
|
64
|
+
use_dsl
|
65
|
+
named :chart
|
66
|
+
name_positional_attributes 'type', 'width', 'height'
|
67
|
+
|
68
|
+
def process(parent, target, attrs)
|
69
|
+
engine = get_engine parent.document
|
70
|
+
data_path = parent.normalize_asset_path(target, 'target')
|
71
|
+
data = parent.read_asset(data_path, warn_on_failure: true, normalize: true)
|
72
|
+
data = create_from_csv engine, data, attrs if data_path.end_with? '.csv'
|
73
|
+
create_chart parent, attrs, data
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
class ChartBlockProcessor < Asciidoctor::Extensions::BlockProcessor
|
79
|
+
include ChartCreator
|
80
|
+
|
81
|
+
use_dsl
|
82
|
+
named :chart
|
83
|
+
on_context :literal
|
84
|
+
name_positional_attributes 'type', 'width', 'height'
|
85
|
+
parse_content_as :raw
|
86
|
+
|
87
|
+
def process(parent, reader, attrs)
|
88
|
+
engine = get_engine parent.document
|
89
|
+
data = create_from_csv engine, reader.source, attrs
|
90
|
+
create_chart parent, attrs, data
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class ChartAssetsDocinfoProcessor < Asciidoctor::Extensions::DocinfoProcessor
|
95
|
+
include ChartCreator
|
96
|
+
|
97
|
+
use_dsl
|
98
|
+
at_location :header
|
99
|
+
|
100
|
+
def process(doc)
|
101
|
+
engine = get_engine(doc)
|
102
|
+
scripts = Asciinurse.config "charts.#{engine}.include"
|
103
|
+
if doc.attributes['backend'] == 'html5'
|
104
|
+
(scripts.collect do |script|
|
105
|
+
if script.start_with? 'http'
|
106
|
+
"<script type='text/javascript' src='#{script}'></script>"
|
107
|
+
else
|
108
|
+
%(<script type="text/javascript">
|
109
|
+
#{Asciinurse.read_resource "#{engine}/javascripts/#{script}"}
|
110
|
+
</script>)
|
111
|
+
end
|
112
|
+
end).join $/
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
Asciidoctor::Extensions.register do |registry|
|
121
|
+
registry.block_macro Asciinurse::Chart::ChartBlockMacro
|
122
|
+
registry.block Asciinurse::Chart::ChartBlockProcessor
|
123
|
+
registry.docinfo_processor Asciinurse::Chart::ChartAssetsDocinfoProcessor
|
124
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
var fs = require('fs');
|
2
|
+
var page = require('webpage').create();
|
3
|
+
var system = require('system');
|
4
|
+
|
5
|
+
var args = system.args;
|
6
|
+
|
7
|
+
var scriptDir = args[0].replace(/googlecharts-convert\.js$/,'')
|
8
|
+
var config = fs.read(args[1])
|
9
|
+
var pageContent = fs.read(scriptDir + 'template.html')
|
10
|
+
pageContent = pageContent.replace(/\$\{CONFIG}/g, config);
|
11
|
+
|
12
|
+
var path = args[1] + '.html';
|
13
|
+
fs.write(path, pageContent, 'w');
|
14
|
+
|
15
|
+
page.viewportSize = {
|
16
|
+
width: 1024,
|
17
|
+
height: 768
|
18
|
+
};
|
19
|
+
|
20
|
+
page.open(args[1] + '.html', function() {
|
21
|
+
window.setTimeout(function () {
|
22
|
+
page.render(args[2]);
|
23
|
+
phantom.exit();
|
24
|
+
}, 1000);
|
25
|
+
});
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<meta charset="UTF-8">
|
4
|
+
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
5
|
+
<script type="text/javascript">
|
6
|
+
google.load("visualization", "1.1", {packages: ["corechart", "bar", "line"]});
|
7
|
+
var drawChart = function (id, config) {
|
8
|
+
var div = document.getElementById(id)
|
9
|
+
div.style.width = config['style']['width']
|
10
|
+
div.style.height = config['style']['height']
|
11
|
+
var chart = new config['type'](div);
|
12
|
+
chart.draw(config['data'], config['options']);
|
13
|
+
}
|
14
|
+
</script>
|
15
|
+
</head>
|
16
|
+
<body>
|
17
|
+
<div id="chart"></div>
|
18
|
+
<script type="text/javascript">
|
19
|
+
google.setOnLoadCallback(function () {
|
20
|
+
drawChart('chart', ${CONFIG})
|
21
|
+
})
|
22
|
+
</script>
|
23
|
+
</body>
|
24
|
+
</html>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
google.load("visualization", "1.1", {packages:["corechart", "bar", "line"]});
|
2
|
+
var drawChart = function(id, config) {
|
3
|
+
var div = document.getElementById(id)
|
4
|
+
div.style.width = config['style']['width']
|
5
|
+
div.style.height = config['style']['height']
|
6
|
+
var chart = new config['type'](div);
|
7
|
+
chart.draw(config['data'], config['options']);
|
8
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
type: google.charts.Bar,
|
3
|
+
data: google.visualization.arrayToDataTable(<%= @csv.to_json %>),
|
4
|
+
options: {
|
5
|
+
chart: {
|
6
|
+
title: <%= @title.to_json %>
|
7
|
+
},
|
8
|
+
hAxis: {
|
9
|
+
title: <%= @header.first.to_json %>,
|
10
|
+
minValue: 0
|
11
|
+
},
|
12
|
+
vAxis: {
|
13
|
+
title: <%= @header.last.to_json %> ,
|
14
|
+
minValue: 0
|
15
|
+
},
|
16
|
+
bars: 'horizontal'
|
17
|
+
},
|
18
|
+
style: {
|
19
|
+
width: <%= @width.to_json %>,
|
20
|
+
height: <%= @height.to_json %>
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
type: google.charts.Bar,
|
3
|
+
data: google.visualization.arrayToDataTable(<%= @csv.to_json %>),
|
4
|
+
options: {
|
5
|
+
chart: {
|
6
|
+
title: <%= @title.to_json %>
|
7
|
+
},
|
8
|
+
hAxis: {
|
9
|
+
title: <%= @header.first.to_json %>,
|
10
|
+
minValue: 0
|
11
|
+
},
|
12
|
+
vAxis: {
|
13
|
+
title: <%= @header.last.to_json %> ,
|
14
|
+
minValue: 0
|
15
|
+
},
|
16
|
+
bars: 'vertical'
|
17
|
+
},
|
18
|
+
style: {
|
19
|
+
width: <%= @width.to_json %>,
|
20
|
+
height: <%= @height.to_json %>
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{
|
2
|
+
type: google.visualization.PieChart,
|
3
|
+
data: google.visualization.arrayToDataTable(<%= @csv.to_json %>),
|
4
|
+
options: {
|
5
|
+
chart: {
|
6
|
+
title: <%= @title.to_json %>
|
7
|
+
},
|
8
|
+
pieHole: 0.4
|
9
|
+
},
|
10
|
+
style: {
|
11
|
+
width: <%= @width.to_json %>,
|
12
|
+
height: <%= @height.to_json %>
|
13
|
+
}
|
14
|
+
}
|