webby 0.7.4 → 0.8.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.
- data/History.txt +19 -0
- data/Manifest.txt +19 -6
- data/README.txt +21 -5
- data/Rakefile +2 -3
- data/data/Rakefile +1 -1
- data/data/lib/breadcrumbs.rb +28 -0
- data/data/tasks/create.rake +0 -1
- data/data/tasks/deploy.rake +0 -1
- data/data/tasks/growl.rake +0 -1
- data/data/tasks/heel.rake +2 -3
- data/data/tasks/setup.rb +0 -1
- data/data/templates/_partial.erb +10 -0
- data/data/templates/atom_feed.erb +34 -0
- data/examples/webby/content/manual/index.txt +11 -13
- data/examples/webby/content/tutorial/index.txt +1 -1
- data/examples/webby/tasks/heel.rake +2 -2
- data/examples/webby/tasks/setup.rb +6 -1
- data/lib/webby.rb +50 -23
- data/lib/webby/auto_builder.rb +4 -2
- data/lib/webby/builder.rb +6 -5
- data/lib/webby/filters.rb +6 -7
- data/lib/webby/filters/outline.rb +4 -2
- data/lib/webby/filters/tidy.rb +4 -2
- data/lib/webby/helpers.rb +32 -0
- data/lib/webby/helpers/coderay_helper.rb +78 -0
- data/lib/webby/helpers/graphviz_helper.rb +158 -0
- data/lib/webby/helpers/tag_helper.rb +9 -4
- data/lib/webby/helpers/tex_img_helper.rb +181 -0
- data/lib/webby/helpers/url_helper.rb +12 -11
- data/lib/webby/renderer.rb +97 -18
- data/lib/webby/resources.rb +82 -0
- data/lib/webby/{pages_db.rb → resources/db.rb} +63 -33
- data/lib/webby/{file.rb → resources/file.rb} +27 -24
- data/lib/webby/resources/layout.rb +65 -0
- data/lib/webby/resources/page.rb +109 -0
- data/lib/webby/resources/partial.rb +81 -0
- data/lib/webby/resources/resource.rb +145 -0
- data/lib/webby/resources/static.rb +54 -0
- data/lib/webby/stelan/mktemp.rb +137 -0
- data/lib/webby/stelan/spawner.rb +5 -1
- data/lib/webby/utils.rb +3 -1
- data/lib/webby/webby_task.rb +43 -24
- data/spec/spec_helper.rb +12 -1
- data/spec/webby/{file_spec.rb → resources/file_spec.rb} +21 -22
- data/tasks/ann.rake +76 -0
- data/tasks/annotations.rake +6 -14
- data/tasks/bones.rake +40 -0
- data/tasks/doc.rake +1 -2
- data/tasks/gem.rake +29 -2
- data/tasks/manifest.rake +15 -21
- data/tasks/post_load.rake +22 -8
- data/tasks/setup.rb +53 -15
- data/tasks/spec.rake +13 -0
- metadata +22 -9
- data/lib/webby/filters/coderay.rb +0 -98
- data/lib/webby/filters/graphviz.rb +0 -189
- data/lib/webby/resource.rb +0 -293
data/tasks/post_load.rake
CHANGED
@@ -3,16 +3,30 @@
|
|
3
3
|
# This file does not define any rake tasks. It is used to load some project
|
4
4
|
# settings if they are not defined by the user.
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
end
|
6
|
+
PROJ.rdoc_exclude << "^#{Regexp.escape(PROJ.manifest_file)}$"
|
7
|
+
PROJ.exclude << "^#{Regexp.escape(PROJ.ann_file)}$"
|
9
8
|
|
10
|
-
|
11
|
-
|
9
|
+
PROJ.instance_variable_get(:@table).each do |key,val|
|
10
|
+
next unless val.instance_of? Array
|
11
|
+
next if key == :dependencies
|
12
|
+
val.flatten!
|
12
13
|
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
PROJ.changes ||= paragraphs_of(PROJ.history_file, 0..1).join("\n\n")
|
16
|
+
|
17
|
+
PROJ.description ||= paragraphs_of(PROJ.readme_file, 'description').join("\n\n")
|
18
|
+
|
19
|
+
PROJ.summary ||= PROJ.description.split('.').first
|
20
|
+
|
21
|
+
PROJ.files ||=
|
22
|
+
if test(?f, PROJ.manifest_file)
|
23
|
+
files = File.readlines(PROJ.manifest_file).map {|fn| fn.chomp.strip}
|
24
|
+
files.delete ''
|
25
|
+
files
|
26
|
+
else [] end
|
27
|
+
|
28
|
+
PROJ.executables ||= PROJ.files.find_all {|fn| fn =~ %r/^bin/}
|
29
|
+
|
30
|
+
PROJ.rdoc_main ||= PROJ.readme_file
|
17
31
|
|
18
32
|
# EOF
|
data/tasks/setup.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
# $Id
|
1
|
+
# $Id$
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'rake'
|
5
|
+
require 'rake/clean'
|
5
6
|
require 'fileutils'
|
6
7
|
require 'ostruct'
|
7
8
|
|
@@ -17,6 +18,10 @@ PROJ.url = nil
|
|
17
18
|
PROJ.version = ENV['VERSION'] || '0.0.0'
|
18
19
|
PROJ.rubyforge_name = nil
|
19
20
|
PROJ.exclude = %w(tmp$ bak$ ~$ CVS .svn/ ^pkg/ ^doc/)
|
21
|
+
PROJ.release_name = ENV['RELEASE']
|
22
|
+
PROJ.history_file = 'History.txt'
|
23
|
+
PROJ.manifest_file = 'Manifest.txt'
|
24
|
+
PROJ.readme_file = 'README.txt'
|
20
25
|
|
21
26
|
# Rspec
|
22
27
|
PROJ.specs = FileList['spec/**/*_spec.rb']
|
@@ -28,13 +33,16 @@ PROJ.test_file = 'test/all.rb'
|
|
28
33
|
PROJ.test_opts = []
|
29
34
|
|
30
35
|
# Rcov
|
31
|
-
PROJ.
|
36
|
+
PROJ.rcov_dir = 'coverage'
|
37
|
+
PROJ.rcov_opts = %w[--sort coverage -T]
|
38
|
+
PROJ.rcov_threshold = 90.0
|
39
|
+
PROJ.rcov_threshold_exact = false
|
32
40
|
|
33
41
|
# Rdoc
|
34
42
|
PROJ.rdoc_opts = []
|
35
43
|
PROJ.rdoc_include = %w(^lib/ ^bin/ ^ext/ .txt$)
|
36
|
-
PROJ.rdoc_exclude = %w(extconf.rb$
|
37
|
-
PROJ.rdoc_main =
|
44
|
+
PROJ.rdoc_exclude = %w(extconf.rb$)
|
45
|
+
PROJ.rdoc_main = nil
|
38
46
|
PROJ.rdoc_dir = 'doc'
|
39
47
|
PROJ.rdoc_remote_dir = nil
|
40
48
|
|
@@ -45,20 +53,17 @@ PROJ.libs = []
|
|
45
53
|
%w(lib ext).each {|dir| PROJ.libs << dir if test ?d, dir}
|
46
54
|
|
47
55
|
# Gem Packaging
|
48
|
-
PROJ.files =
|
49
|
-
|
50
|
-
files = File.readlines('Manifest.txt').map {|fn| fn.chomp.strip}
|
51
|
-
files.delete ''
|
52
|
-
files
|
53
|
-
else [] end
|
54
|
-
PROJ.executables = PROJ.files.find_all {|fn| fn =~ %r/^bin/}
|
56
|
+
PROJ.files = nil
|
57
|
+
PROJ.executables = nil
|
55
58
|
PROJ.dependencies = []
|
56
59
|
PROJ.need_tar = true
|
57
60
|
PROJ.need_zip = false
|
61
|
+
PROJ.post_install_message = nil
|
58
62
|
|
59
63
|
# File Annotations
|
60
|
-
PROJ.annotation_exclude =
|
64
|
+
PROJ.annotation_exclude = %w(^tasks/setup.rb$)
|
61
65
|
PROJ.annotation_extensions = %w(.txt .rb .erb) << ''
|
66
|
+
PROJ.annotation_tags = %w(FIXME OPTIMIZE TODO)
|
62
67
|
|
63
68
|
# Subversion Repository
|
64
69
|
PROJ.svn = false
|
@@ -67,6 +72,21 @@ PROJ.svn_trunk = 'trunk'
|
|
67
72
|
PROJ.svn_tags = 'tags'
|
68
73
|
PROJ.svn_branches = 'branches'
|
69
74
|
|
75
|
+
# Announce
|
76
|
+
PROJ.ann_file = 'announcement.txt'
|
77
|
+
PROJ.ann_text = nil
|
78
|
+
PROJ.ann_paragraphs = []
|
79
|
+
PROJ.ann_email = {
|
80
|
+
:from => nil,
|
81
|
+
:to => %w(ruby-talk@ruby-lang.org),
|
82
|
+
:server => 'localhost',
|
83
|
+
:port => 25,
|
84
|
+
:domain => ENV['HOSTNAME'],
|
85
|
+
:acct => nil,
|
86
|
+
:passwd => nil,
|
87
|
+
:authtype => :plain
|
88
|
+
}
|
89
|
+
|
70
90
|
# Load the other rake files in the tasks folder
|
71
91
|
rakefiles = Dir.glob('tasks/*.rake').sort
|
72
92
|
rakefiles.unshift(rakefiles.delete('tasks/post_load.rake')).compact!
|
@@ -99,8 +119,8 @@ SUDO = if WIN32 then ''
|
|
99
119
|
else '' end
|
100
120
|
end
|
101
121
|
|
102
|
-
RCOV = WIN32 ? 'rcov.
|
103
|
-
GEM = WIN32 ? 'gem.
|
122
|
+
RCOV = WIN32 ? 'rcov.bat' : 'rcov'
|
123
|
+
GEM = WIN32 ? 'gem.bat' : 'gem'
|
104
124
|
|
105
125
|
%w(rcov spec/rake/spectask rubyforge bones facets/ansicode).each do |lib|
|
106
126
|
begin
|
@@ -149,7 +169,10 @@ def depend_on( name, version = nil )
|
|
149
169
|
spec = Gem.source_index.find_name(name).last
|
150
170
|
version = spec.version.to_s if version.nil? and !spec.nil?
|
151
171
|
|
152
|
-
PROJ.dependencies <<
|
172
|
+
PROJ.dependencies << case version
|
173
|
+
when nil; [name]
|
174
|
+
when %r/^\d/; [name, ">= #{version}"]
|
175
|
+
else [name, version] end
|
153
176
|
end
|
154
177
|
|
155
178
|
# Adds the given arguments to the include path if they are not already there
|
@@ -186,4 +209,19 @@ def in_directory( dir, &block )
|
|
186
209
|
end
|
187
210
|
end
|
188
211
|
|
212
|
+
# Scans the current working directory and creates a list of files that are
|
213
|
+
# candidates to be in the manifest.
|
214
|
+
#
|
215
|
+
def manifest_files
|
216
|
+
files = []
|
217
|
+
exclude = Regexp.new(PROJ.exclude.join('|'))
|
218
|
+
Find.find '.' do |path|
|
219
|
+
path.sub! %r/^(\.\/|\/)/o, ''
|
220
|
+
next unless test ?f, path
|
221
|
+
next if path =~ exclude
|
222
|
+
files << path
|
223
|
+
end
|
224
|
+
files.sort!
|
225
|
+
end
|
226
|
+
|
189
227
|
# EOF
|
data/tasks/spec.rake
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# $Id$
|
2
2
|
|
3
3
|
if HAVE_SPEC_RAKE_SPECTASK
|
4
|
+
require 'spec/rake/verify_rcov'
|
4
5
|
|
5
6
|
namespace :spec do
|
6
7
|
|
7
8
|
desc 'Run all specs with basic output'
|
8
9
|
Spec::Rake::SpecTask.new(:run) do |t|
|
10
|
+
t.ruby_opts = PROJ.ruby_opts
|
9
11
|
t.spec_opts = PROJ.spec_opts
|
10
12
|
t.spec_files = PROJ.specs
|
11
13
|
t.libs += PROJ.libs
|
@@ -13,6 +15,7 @@ namespace :spec do
|
|
13
15
|
|
14
16
|
desc 'Run all specs with text output'
|
15
17
|
Spec::Rake::SpecTask.new(:specdoc) do |t|
|
18
|
+
t.ruby_opts = PROJ.ruby_opts
|
16
19
|
t.spec_opts = PROJ.spec_opts + ['--format', 'specdoc']
|
17
20
|
t.spec_files = PROJ.specs
|
18
21
|
t.libs += PROJ.libs
|
@@ -21,12 +24,22 @@ namespace :spec do
|
|
21
24
|
if HAVE_RCOV
|
22
25
|
desc 'Run all specs with RCov'
|
23
26
|
Spec::Rake::SpecTask.new(:rcov) do |t|
|
27
|
+
t.ruby_opts = PROJ.ruby_opts
|
24
28
|
t.spec_opts = PROJ.spec_opts
|
25
29
|
t.spec_files = PROJ.specs
|
26
30
|
t.libs += PROJ.libs
|
27
31
|
t.rcov = true
|
32
|
+
t.rcov_dir = PROJ.rcov_dir
|
28
33
|
t.rcov_opts = PROJ.rcov_opts + ['--exclude', 'spec']
|
29
34
|
end
|
35
|
+
|
36
|
+
RCov::VerifyTask.new(:verify) do |t|
|
37
|
+
t.threshold = PROJ.rcov_threshold
|
38
|
+
t.index_html = File.join(PROJ.rcov_dir, 'index.html')
|
39
|
+
t.require_exact_threshold = PROJ.rcov_threshold_exact
|
40
|
+
end
|
41
|
+
|
42
|
+
task :verify => :rcov
|
30
43
|
end
|
31
44
|
|
32
45
|
end # namespace :spec
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Pease
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-02-
|
12
|
+
date: 2008-02-28 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 0.7.
|
49
|
+
version: 0.7.1
|
50
50
|
version:
|
51
51
|
- !ruby/object:Gem::Dependency
|
52
52
|
name: rake
|
@@ -109,11 +109,14 @@ files:
|
|
109
109
|
- data/content/css/site.css
|
110
110
|
- data/content/index.txt
|
111
111
|
- data/layouts/default.rhtml
|
112
|
+
- data/lib/breadcrumbs.rb
|
112
113
|
- data/tasks/create.rake
|
113
114
|
- data/tasks/deploy.rake
|
114
115
|
- data/tasks/growl.rake
|
115
116
|
- data/tasks/heel.rake
|
116
117
|
- data/tasks/setup.rb
|
118
|
+
- data/templates/_partial.erb
|
119
|
+
- data/templates/atom_feed.erb
|
117
120
|
- data/templates/page.erb
|
118
121
|
- examples/webby/Rakefile
|
119
122
|
- examples/webby/content/css/blueprint/print.css
|
@@ -138,32 +141,42 @@ files:
|
|
138
141
|
- lib/webby.rb
|
139
142
|
- lib/webby/auto_builder.rb
|
140
143
|
- lib/webby/builder.rb
|
141
|
-
- lib/webby/file.rb
|
142
144
|
- lib/webby/filters.rb
|
143
145
|
- lib/webby/filters/basepath.rb
|
144
|
-
- lib/webby/filters/coderay.rb
|
145
146
|
- lib/webby/filters/erb.rb
|
146
|
-
- lib/webby/filters/graphviz.rb
|
147
147
|
- lib/webby/filters/haml.rb
|
148
148
|
- lib/webby/filters/markdown.rb
|
149
149
|
- lib/webby/filters/outline.rb
|
150
150
|
- lib/webby/filters/sass.rb
|
151
151
|
- lib/webby/filters/textile.rb
|
152
152
|
- lib/webby/filters/tidy.rb
|
153
|
+
- lib/webby/helpers.rb
|
154
|
+
- lib/webby/helpers/coderay_helper.rb
|
155
|
+
- lib/webby/helpers/graphviz_helper.rb
|
153
156
|
- lib/webby/helpers/tag_helper.rb
|
157
|
+
- lib/webby/helpers/tex_img_helper.rb
|
154
158
|
- lib/webby/helpers/url_helper.rb
|
155
159
|
- lib/webby/main.rb
|
156
|
-
- lib/webby/pages_db.rb
|
157
160
|
- lib/webby/renderer.rb
|
158
|
-
- lib/webby/
|
161
|
+
- lib/webby/resources.rb
|
162
|
+
- lib/webby/resources/db.rb
|
163
|
+
- lib/webby/resources/file.rb
|
164
|
+
- lib/webby/resources/layout.rb
|
165
|
+
- lib/webby/resources/page.rb
|
166
|
+
- lib/webby/resources/partial.rb
|
167
|
+
- lib/webby/resources/resource.rb
|
168
|
+
- lib/webby/resources/static.rb
|
169
|
+
- lib/webby/stelan/mktemp.rb
|
159
170
|
- lib/webby/stelan/paginator.rb
|
160
171
|
- lib/webby/stelan/spawner.rb
|
161
172
|
- lib/webby/utils.rb
|
162
173
|
- lib/webby/webby_task.rb
|
163
174
|
- spec/spec.opts
|
164
175
|
- spec/spec_helper.rb
|
165
|
-
- spec/webby/file_spec.rb
|
176
|
+
- spec/webby/resources/file_spec.rb
|
177
|
+
- tasks/ann.rake
|
166
178
|
- tasks/annotations.rake
|
179
|
+
- tasks/bones.rake
|
167
180
|
- tasks/doc.rake
|
168
181
|
- tasks/gem.rake
|
169
182
|
- tasks/manifest.rake
|
@@ -1,98 +0,0 @@
|
|
1
|
-
# $Id: coderay.rb 113 2008-01-26 23:09:13Z tim_pease $
|
2
|
-
|
3
|
-
require 'enumerator'
|
4
|
-
require 'hpricot'
|
5
|
-
try_require 'coderay'
|
6
|
-
|
7
|
-
module Webby
|
8
|
-
module Filters
|
9
|
-
|
10
|
-
# The CodeRay applies syntax highlighting to source code embedded in a
|
11
|
-
# webpage. The CodeRay highlighting engine is used for the HTML markup of
|
12
|
-
# the source code. A set of <coderay>...</coderay> tags is used to denote
|
13
|
-
# which sections of the page should be highlighted.
|
14
|
-
#
|
15
|
-
# Options can be passed to the CodeRay engine via attributes in the
|
16
|
-
# <coderay> tag.
|
17
|
-
#
|
18
|
-
# <coderay lang="ruby" line_numbers="inline">
|
19
|
-
# # Initializer for the class.
|
20
|
-
# def initialize( string )
|
21
|
-
# @str = stirng
|
22
|
-
# end
|
23
|
-
# </coderay>
|
24
|
-
#
|
25
|
-
# The supported CodeRay options are the following:
|
26
|
-
#
|
27
|
-
# lang : the language to highlight (ruby, c, html, ...)
|
28
|
-
# line_numbers : include line numbers in 'table', 'inline',
|
29
|
-
# or 'list'
|
30
|
-
# line_number_start : where to start with line number counting
|
31
|
-
# bold_every : make every n-th number appear bold
|
32
|
-
# tab_width : convert tab characters to n spaces
|
33
|
-
#
|
34
|
-
class CodeRay
|
35
|
-
|
36
|
-
# call-seq:
|
37
|
-
# CodeRay.new( string, filters = nil )
|
38
|
-
#
|
39
|
-
# Creates a new CodeRay filter that will operate on the given _string_.
|
40
|
-
#
|
41
|
-
def initialize( str, filters = nil )
|
42
|
-
@str = str
|
43
|
-
@filters = filters
|
44
|
-
end
|
45
|
-
|
46
|
-
# call-seq:
|
47
|
-
# to_html => string
|
48
|
-
#
|
49
|
-
# Process the original text string passed to the filter when it was
|
50
|
-
# created and output HTML formatted text. Any text between
|
51
|
-
# <coderay>...</coderay> tags will have syntax highlighting applied to the
|
52
|
-
# text via the CodeRay gem.
|
53
|
-
#
|
54
|
-
def to_html
|
55
|
-
doc = Hpricot(@str)
|
56
|
-
doc.search('//coderay') do |cr|
|
57
|
-
text = cr.inner_html.strip
|
58
|
-
lang = (cr['lang'] || 'ruby').to_sym
|
59
|
-
|
60
|
-
opts = {}
|
61
|
-
%w(line_numbers to_sym
|
62
|
-
line_number_start to_i
|
63
|
-
bold_every to_i
|
64
|
-
tab_width to_i).each_slice(2) do |key,convert|
|
65
|
-
next if cr[key].nil?
|
66
|
-
opts[key.to_sym] = cr[key].send(convert)
|
67
|
-
end
|
68
|
-
|
69
|
-
#cr.swap(CodeRay.scan(text, lang).html(opts).div)
|
70
|
-
out = "<div class=\"CodeRay\"><pre>\n"
|
71
|
-
out << ::CodeRay.scan(text, lang).html(opts)
|
72
|
-
out << "\n</pre></div>"
|
73
|
-
|
74
|
-
@filters.each do |f|
|
75
|
-
case f
|
76
|
-
when 'textile'
|
77
|
-
out.insert 0, "<notextile>\n"
|
78
|
-
out << "\n</notextile>"
|
79
|
-
end
|
80
|
-
end unless @filters.nil?
|
81
|
-
|
82
|
-
cr.swap out
|
83
|
-
end
|
84
|
-
|
85
|
-
doc.to_html
|
86
|
-
end
|
87
|
-
|
88
|
-
end # class CodeRay
|
89
|
-
|
90
|
-
# Render text via the CodeRay syntax highlighter library.
|
91
|
-
register :coderay do |input, cursor|
|
92
|
-
Filters::CodeRay.new(input, cursor.remaining_filters).to_html
|
93
|
-
end
|
94
|
-
|
95
|
-
end # module Filters
|
96
|
-
end # module Webby
|
97
|
-
|
98
|
-
# EOF
|
@@ -1,189 +0,0 @@
|
|
1
|
-
# $Id: graphviz.rb 113 2008-01-26 23:09:13Z tim_pease $
|
2
|
-
|
3
|
-
require 'hpricot'
|
4
|
-
require 'fileutils'
|
5
|
-
require 'tempfile'
|
6
|
-
|
7
|
-
module Webby
|
8
|
-
module Filters
|
9
|
-
|
10
|
-
# The Graphviz filter processes DOT scripts in a webpage and replaces them
|
11
|
-
# with generated image files. A set of <graphviz>...</graphviz> tags is
|
12
|
-
# used to denote which section(s) of the page contains DOT scripts.
|
13
|
-
#
|
14
|
-
# Options can be passed to the Graphviz filter using attributes in the
|
15
|
-
# <graphviz> tag.
|
16
|
-
#
|
17
|
-
# <graphviz path="images" type="gif" cmd="dot">
|
18
|
-
# digraph graph_1 {
|
19
|
-
# graph [URL="default.html"]
|
20
|
-
# a [URL="a.html"]
|
21
|
-
# b [URL="b.html"]
|
22
|
-
# c [URL="c.html"]
|
23
|
-
# a -> b -> c
|
24
|
-
# a -> c
|
25
|
-
# }
|
26
|
-
# </graphviz>
|
27
|
-
#
|
28
|
-
# If the DOT script contains *URL* or *href* attributes on any of the nodes
|
29
|
-
# or edges, then an image map will be generated and the image will be
|
30
|
-
# "clikcable" in the webpage. If *URL* or *href* attributes do not appear in
|
31
|
-
# the DOT script, then a regular image will be inserted into the webpage.
|
32
|
-
#
|
33
|
-
# The image is inserted into the page using an HTML <img /> tag. A
|
34
|
-
# corresponding <map>...</map> element will be inserted if needed.
|
35
|
-
#
|
36
|
-
# The supported Graphviz options are the following:
|
37
|
-
#
|
38
|
-
# path : where generated images will be stored
|
39
|
-
# [default is "/"]
|
40
|
-
# type : the type of image to generate (png, jpeg, gif)
|
41
|
-
# [default is png]
|
42
|
-
# cmd : the Graphviz command to use when generating images
|
43
|
-
# (dot, neato, twopi, circo, fdp) [default is dot]
|
44
|
-
#
|
45
|
-
# the following options are passed as-is to the generated <img /> tag
|
46
|
-
# style : CSS styles to apply to the <img />
|
47
|
-
# class : CSS class to apply to the <img />
|
48
|
-
# id : HTML identifier
|
49
|
-
# alt : alternate text for the <img />
|
50
|
-
#
|
51
|
-
class Graphviz
|
52
|
-
|
53
|
-
class Error < StandardError; end # :nodoc:
|
54
|
-
|
55
|
-
# call-seq:
|
56
|
-
# Graphviz.new( string, filters = nil )
|
57
|
-
#
|
58
|
-
# Creates a new Graphviz filter that will operate on the given _string_.
|
59
|
-
# The optional _filters_ describe filters that will be applied to the
|
60
|
-
# output string returned by the Graphviz filter.
|
61
|
-
#
|
62
|
-
def initialize( str, filters = nil )
|
63
|
-
@str = str
|
64
|
-
@filters = filters
|
65
|
-
|
66
|
-
# create a temporary file for holding any error messages
|
67
|
-
# from the graphviz program
|
68
|
-
@err = Tempfile.new('graphviz_err')
|
69
|
-
@err.close
|
70
|
-
end
|
71
|
-
|
72
|
-
# call-seq:
|
73
|
-
# to_html => string
|
74
|
-
#
|
75
|
-
# Process the original text string passed to the filter when it was
|
76
|
-
# created and output HTML formatted text. Any text between
|
77
|
-
# <graphviz>...</graphviz> tags will have the contained DOT syntax
|
78
|
-
# converted into an image and then included into the resulting HTML text.
|
79
|
-
#
|
80
|
-
def to_html
|
81
|
-
doc = Hpricot(@str)
|
82
|
-
doc.search('//graphviz') do |gviz|
|
83
|
-
|
84
|
-
path = gviz['path']
|
85
|
-
cmd = gviz['cmd'] || 'dot'
|
86
|
-
type = gviz['type'] || 'png'
|
87
|
-
text = gviz.inner_html.strip # the DOT script to process
|
88
|
-
|
89
|
-
# if we don't have a DOT script, then replace it with
|
90
|
-
# the empty text and move on to the next graphviz tags
|
91
|
-
if text.empty?
|
92
|
-
gviz.swap text
|
93
|
-
next
|
94
|
-
end
|
95
|
-
|
96
|
-
# ensure the requested graphviz command actually exists
|
97
|
-
%x[#{cmd} -V 2>&1]
|
98
|
-
unless 0 == $?.exitstatus
|
99
|
-
raise NameError, "'#{cmd}' not found on the path"
|
100
|
-
end
|
101
|
-
|
102
|
-
# pull the name of the graph|digraph out of the DOT script
|
103
|
-
name = text.match(%r/\A\s*(?:strict\s+)?(?:di)?graph\s+([A-Za-z_][A-Za-z0-9_]*)\s+\{/o)[1]
|
104
|
-
|
105
|
-
# see if the user includes any URL or href attributes
|
106
|
-
# if so, then we need to create an imagemap
|
107
|
-
usemap = text.match(%r/(?:URL|href)\s*=/o) != nil
|
108
|
-
|
109
|
-
# generate the image filename based on the path, graph name, and type
|
110
|
-
# of image to generate
|
111
|
-
image_fn = path.nil? ? name.dup : ::File.join(path, name)
|
112
|
-
image_fn = ::File.join('', image_fn) << '.' << type
|
113
|
-
|
114
|
-
# create the HTML img tag
|
115
|
-
out = "<img src=\"#{image_fn}\""
|
116
|
-
|
117
|
-
%w[class style id alt].each do |attr|
|
118
|
-
next if gviz[attr].nil?
|
119
|
-
out << " %s=\"%s\"" % [attr, gviz[attr]]
|
120
|
-
end
|
121
|
-
|
122
|
-
out << " usemap=\"\##{name}\"" if usemap
|
123
|
-
out << " />\n"
|
124
|
-
|
125
|
-
# generate the image map if needed
|
126
|
-
if usemap
|
127
|
-
IO.popen("#{cmd} -Tcmapx 2> #{@err.path}", 'r+') do |io|
|
128
|
-
io.write text
|
129
|
-
io.close_write
|
130
|
-
out << io.read
|
131
|
-
end
|
132
|
-
error_check
|
133
|
-
end
|
134
|
-
|
135
|
-
# generate the image using graphviz -- but first ensure that the
|
136
|
-
# path exists
|
137
|
-
out_dir = ::Webby.site.output_dir
|
138
|
-
out_file = ::File.join(out_dir, image_fn)
|
139
|
-
FileUtils.mkpath(::File.join(out_dir, path)) unless path.nil?
|
140
|
-
cmd = "#{cmd} -T#{type} -o #{out_file} 2> #{@err.path}"
|
141
|
-
|
142
|
-
IO.popen(cmd, 'w') {|io| io.write text}
|
143
|
-
error_check
|
144
|
-
|
145
|
-
# see if we need to put some guards around the output
|
146
|
-
# (specifically for textile)
|
147
|
-
@filters.each do |f|
|
148
|
-
case f
|
149
|
-
when 'textile'
|
150
|
-
out.insert 0, "<notextile>\n"
|
151
|
-
out << "\n</notextile>"
|
152
|
-
end
|
153
|
-
end unless @filters.nil?
|
154
|
-
|
155
|
-
gviz.swap out
|
156
|
-
end
|
157
|
-
|
158
|
-
doc.to_html
|
159
|
-
end
|
160
|
-
|
161
|
-
|
162
|
-
private
|
163
|
-
|
164
|
-
# call-seq:
|
165
|
-
# error_check
|
166
|
-
#
|
167
|
-
# Check the temporary error file to see if it contains any error messages
|
168
|
-
# from the graphviz program. If it is not empty, then read the contents
|
169
|
-
# and log an error message and raise an exception.
|
170
|
-
#
|
171
|
-
def error_check
|
172
|
-
if ::File.size(@err.path) != 0
|
173
|
-
msg = "\n" << ::File.read(@err.path).strip
|
174
|
-
raise Error, msg
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
end # class Graphviz
|
179
|
-
|
180
|
-
# Render text into iamges via the Graphviz programs.
|
181
|
-
#
|
182
|
-
register :graphviz do |input, cursor|
|
183
|
-
Filters::Graphviz.new(input, cursor.remaining_filters).to_html
|
184
|
-
end
|
185
|
-
|
186
|
-
end # module Filters
|
187
|
-
end # module Webby
|
188
|
-
|
189
|
-
# EOF
|