ascii_binder 0.0.7 → 0.0.8
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/README.adoc +7 -214
- data/ascii_binder.gemspec +3 -3
- data/bin/ascii_binder +226 -0
- data/bin/asciibinder +97 -26
- data/lib/ascii_binder/helpers.rb +100 -26
- data/lib/ascii_binder/tasks/guards.rb +1 -1
- data/lib/ascii_binder/template_renderer.rb +11 -7
- data/lib/ascii_binder/version.rb +1 -1
- data/templates/.gitignore +9 -0
- data/templates/_build_cfg.yml +29 -0
- data/templates/_distro_map.yml +11 -0
- data/templates/_images/asciibinder-logo-horizontal.png +0 -0
- data/templates/_images/asciibinder_web_logo.svg +125 -0
- data/templates/_images/book_pages_bg.jpg +0 -0
- data/templates/_images/favicon.ico +0 -0
- data/templates/_images/favicon32x32.png +0 -0
- data/templates/_javascripts/.gitkeep +0 -0
- data/templates/_stylesheets/asciibinder.css +562 -0
- data/templates/_templates/_css.html.erb +3 -0
- data/templates/_templates/_nav.html.erb +31 -0
- data/templates/_templates/page.html.erb +96 -0
- data/templates/index-main.html +89 -0
- data/templates/welcome/index.adoc +14 -0
- metadata +22 -3
data/bin/asciibinder
CHANGED
@@ -4,10 +4,20 @@ require 'ascii_binder/helpers'
|
|
4
4
|
require 'pathname'
|
5
5
|
require 'trollop'
|
6
6
|
|
7
|
-
|
8
7
|
include AsciiBinder::Helpers
|
9
8
|
|
10
|
-
|
9
|
+
def call_generate(distro,page=nil)
|
10
|
+
if page == ''
|
11
|
+
page = nil
|
12
|
+
end
|
13
|
+
begin
|
14
|
+
generate_docs(distro,page)
|
15
|
+
rescue Exception => e
|
16
|
+
Trollop::die "Could not generate docs: #{e.message}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
SUB_COMMANDS = %w{help build watch package clean create}
|
11
21
|
Trollop::options do
|
12
22
|
banner <<-EOF
|
13
23
|
Usage:
|
@@ -16,6 +26,8 @@ Usage:
|
|
16
26
|
Commands:
|
17
27
|
build (default action)
|
18
28
|
Builds the HTML docs in the indicated repo dir
|
29
|
+
create
|
30
|
+
Generates a new AsciiBinder repo at the indicated dir
|
19
31
|
watch
|
20
32
|
Starts Guard, which automatically regenerates changed HTML
|
21
33
|
files on the working branch in the repo dir
|
@@ -24,7 +36,7 @@ Commands:
|
|
24
36
|
defined in the _distro_config.yml file
|
25
37
|
clean
|
26
38
|
Remove _preview, _publish and _package dirs created by
|
27
|
-
other
|
39
|
+
other AsciiBinder operations.
|
28
40
|
|
29
41
|
Options:
|
30
42
|
EOF
|
@@ -38,7 +50,7 @@ if cmd.nil?
|
|
38
50
|
cmd = "build"
|
39
51
|
elsif not SUB_COMMANDS.include?(cmd)
|
40
52
|
if not ARGV.empty?
|
41
|
-
Trollop::die "'#{cmd}' is not a valid asciibinder
|
53
|
+
Trollop::die "'#{cmd}' is not a valid asciibinder subcommand. Legal values are '#{SUB_COMMANDS.join('\', \'')}'."
|
42
54
|
else
|
43
55
|
repo_dir = Pathname.new(cmd)
|
44
56
|
cmd = "build"
|
@@ -54,22 +66,44 @@ Usage:
|
|
54
66
|
|
55
67
|
Description:
|
56
68
|
This is the default behavior for the asciibinder utility. When run,
|
57
|
-
|
69
|
+
AsciiBinder reads the _distro_config.yml file out of the working
|
58
70
|
branch of the indicated repo directory and based on that, proceeds to
|
59
71
|
build the working branch version of the documentation for each distro.
|
60
72
|
|
61
|
-
Once the working branch version is built,
|
73
|
+
Once the working branch version is built, AsciiBinder cycles through
|
62
74
|
the other branches named in the _distro_config.yml file until all of
|
63
75
|
the permutations have been built.
|
64
76
|
|
77
|
+
The available options enable you to limit the scope of the build work,
|
78
|
+
as described by the options themselves. Note that the format for the
|
79
|
+
"--page" option is:
|
80
|
+
|
81
|
+
<topic_group>:<topic_file>
|
82
|
+
|
83
|
+
or for subtopics:
|
84
|
+
|
85
|
+
<topic_group>/<subtopic_group>:<topic_file>
|
86
|
+
|
87
|
+
However, if you want to use the --page option extensively, then be
|
88
|
+
aware of the `asciibinder watch` function, which does this for you
|
89
|
+
automatically as you change .adoc files in your working branch.
|
90
|
+
|
65
91
|
Options:
|
66
92
|
EOF
|
67
93
|
opt :distro, "Instead of building all distros, build branches only for the specified distro.", :default => ''
|
94
|
+
opt :page, "Build only the specified page for all distros and only the current working branch.", :default => ''
|
95
|
+
conflicts :distro, :page
|
96
|
+
end
|
97
|
+
when "create"
|
98
|
+
Trollop::options do
|
99
|
+
banner <<-EOF
|
100
|
+
Usage:
|
101
|
+
#$0 create <new_repo_dir>
|
102
|
+
|
103
|
+
Description:
|
104
|
+
Creates a new, bare AsciiBinder repo in the specified directory.
|
105
|
+
EOF
|
68
106
|
end
|
69
|
-
#when "new"
|
70
|
-
# Trollop::options do
|
71
|
-
# opt :initialize, "Create a new AsciiBinder-ready git repo in the target directory.", :default => true
|
72
|
-
# end
|
73
107
|
when "watch"
|
74
108
|
Trollop::options do
|
75
109
|
banner <<-EOF
|
@@ -77,16 +111,23 @@ Usage:
|
|
77
111
|
#$0 watch <repo_dir>
|
78
112
|
|
79
113
|
Description:
|
80
|
-
In watch mode,
|
114
|
+
In watch mode, AsciiBinder starts a Guard process in the foreground.
|
81
115
|
This process watches the repo_dir for changes to the AsciiDoc (.adoc)
|
82
|
-
files. When a change occurs,
|
116
|
+
files. When a change occurs, AsciiBinder regenerates the specific
|
83
117
|
HTML output of the file that was changed, for the working branch only.
|
84
118
|
|
119
|
+
This is the equivalent of running:
|
120
|
+
|
121
|
+
$ asciibinder build --page='<topic_group>:<affected_file>'
|
122
|
+
|
123
|
+
...except that the Guardfile automatically detects and runs this as
|
124
|
+
you work.
|
125
|
+
|
85
126
|
This is meant to be used in conjunction with a web browser that is
|
86
127
|
running a LiveReload plugin. If you are viewing the output HTML page
|
87
128
|
in a browser where LiveReload is active, then every time you save a
|
88
129
|
new version of the .adoc file, the new HTML is automatically
|
89
|
-
|
130
|
+
regenerated and your page view is automatically refreshed.
|
90
131
|
EOF
|
91
132
|
end
|
92
133
|
when "package"
|
@@ -116,40 +157,70 @@ elsif repo_dir.nil?
|
|
116
157
|
if ARGV.length == 1
|
117
158
|
repo_dir = Pathname.new(ARGV.shift)
|
118
159
|
else
|
119
|
-
|
160
|
+
if not cmd == 'create'
|
161
|
+
repo_dir = Pathname.pwd
|
162
|
+
else
|
163
|
+
Trollop::die "Specify a name for the new repo directory."
|
164
|
+
end
|
120
165
|
end
|
121
166
|
end
|
122
167
|
|
123
168
|
# Validate the repo_dir path
|
124
|
-
if
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
169
|
+
if cmd == 'create'
|
170
|
+
if repo_dir.exist?
|
171
|
+
Trollop::die "The specified new repo directory '#{repo_dir}' already exists."
|
172
|
+
end
|
173
|
+
else
|
174
|
+
if not repo_dir.exist?
|
175
|
+
Trollop::die "The specified repo directory '#{repo_dir}' does not exist."
|
176
|
+
elsif not repo_dir.directory?
|
177
|
+
Trollop::die "The specified repo directory path '#{repo_dir}' is not a directory."
|
178
|
+
elsif not repo_dir.readable?
|
179
|
+
Trollop::die "The specified repo directory '#{repo_dir}' is not readable."
|
180
|
+
elsif not repo_dir.writable?
|
181
|
+
Trollop::die "The specified repo directory '#{repo_dir}' cannot be written to."
|
182
|
+
else
|
183
|
+
['.git','_build_cfg.yml','_distro_map.yml','_templates'].each do |file|
|
184
|
+
if not File.exist?(File.join(repo_dir, file))
|
185
|
+
Trollop::die "The specified repo directory '#{repo_dir}' does not appear to be an AsciiBinder repo."
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
132
189
|
end
|
133
190
|
|
134
191
|
# Set the repo root
|
135
192
|
set_source_dir(File.expand_path(repo_dir))
|
136
193
|
|
194
|
+
# Change to the repo dir. This is necessary in order for
|
195
|
+
# AsciiDoctor to work properly.
|
196
|
+
if not cmd == 'create'
|
197
|
+
Dir.chdir source_dir
|
198
|
+
end
|
199
|
+
|
137
200
|
# Do the things with the stuff
|
138
201
|
case cmd
|
139
202
|
when "build"
|
140
203
|
build_distro = cmd_opts[:build] || ''
|
141
|
-
|
204
|
+
refresh_page = cmd_opts[:page] || ''
|
205
|
+
call_generate(build_distro,refresh_page)
|
142
206
|
when "package"
|
143
207
|
clean_up
|
144
|
-
|
208
|
+
call_generate('')
|
145
209
|
package_site = cmd_opts[:site] || ''
|
146
210
|
package_docs(package_site)
|
147
211
|
when "watch"
|
148
|
-
|
149
|
-
|
212
|
+
if not dir_empty?(preview_dir)
|
213
|
+
guardfile_path = File.join(Gem::Specification.find_by_name("ascii_binder").full_gem_path, 'Guardfile')
|
214
|
+
exec("guard -G #{guardfile_path}")
|
215
|
+
else
|
216
|
+
Trollop::die "Run 'asciibinder build' at least once before running 'asciibinder watch'."
|
217
|
+
end
|
150
218
|
when "clean"
|
151
219
|
clean_up
|
152
220
|
puts "Cleaned up #{repo_dir}."
|
221
|
+
when "create"
|
222
|
+
create_new_repo
|
223
|
+
puts "Created new repo in #{repo_dir}."
|
153
224
|
end
|
154
225
|
|
155
226
|
exit
|
data/lib/ascii_binder/helpers.rb
CHANGED
@@ -2,6 +2,7 @@ require 'ascii_binder/template_renderer'
|
|
2
2
|
require 'asciidoctor'
|
3
3
|
require 'asciidoctor/cli'
|
4
4
|
require 'asciidoctor-diagram'
|
5
|
+
require 'fileutils'
|
5
6
|
require 'find'
|
6
7
|
require 'git'
|
7
8
|
require 'logger'
|
@@ -19,10 +20,18 @@ module AsciiBinder
|
|
19
20
|
@source_dir ||= `git rev-parse --show-toplevel`.chomp
|
20
21
|
end
|
21
22
|
|
23
|
+
def self.gem_root_dir
|
24
|
+
@gem_root_dir ||= File.expand_path("../../../", __FILE__)
|
25
|
+
end
|
26
|
+
|
22
27
|
def self.set_source_dir(source_dir)
|
23
28
|
@source_dir = source_dir
|
24
29
|
end
|
25
30
|
|
31
|
+
def template_renderer
|
32
|
+
@template_renderer ||= TemplateRenderer.new(source_dir, template_dir)
|
33
|
+
end
|
34
|
+
|
26
35
|
def self.template_dir
|
27
36
|
@template_dir ||= File.join(source_dir,'_templates')
|
28
37
|
end
|
@@ -47,13 +56,28 @@ module AsciiBinder
|
|
47
56
|
end
|
48
57
|
end
|
49
58
|
|
50
|
-
|
59
|
+
def self.stylesheet_dir
|
60
|
+
@stylesheet_dir ||= File.join(source_dir,STYLESHEET_DIRNAME)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.javascript_dir
|
64
|
+
@javascript_dir ||= File.join(source_dir,JAVASCRIPT_DIRNAME)
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.image_dir
|
68
|
+
@image_dir ||= File.join(source_dir,IMAGE_DIRNAME)
|
69
|
+
end
|
70
|
+
|
71
|
+
def_delegators self, :source_dir, :set_source_dir, :template_dir, :preview_dir, :package_dir, :gem_root_dir, :stylesheet_dir, :javascript_dir, :image_dir
|
51
72
|
|
52
73
|
BUILD_FILENAME = '_build_cfg.yml'
|
53
74
|
DISTRO_MAP_FILENAME = '_distro_map.yml'
|
54
75
|
BUILDER_DIRNAME = '_build_system'
|
55
76
|
PREVIEW_DIRNAME = '_preview'
|
56
77
|
PACKAGE_DIRNAME = '_package'
|
78
|
+
STYLESHEET_DIRNAME = '_stylesheets'
|
79
|
+
JAVASCRIPT_DIRNAME = '_javascripts'
|
80
|
+
IMAGE_DIRNAME = '_images'
|
57
81
|
BLANK_STRING_RE = Regexp.new('^\s*$')
|
58
82
|
|
59
83
|
def build_date
|
@@ -95,8 +119,10 @@ module AsciiBinder
|
|
95
119
|
def local_branches
|
96
120
|
@local_branches ||= begin
|
97
121
|
branches = []
|
98
|
-
|
99
|
-
|
122
|
+
if not git.branches.local.empty?
|
123
|
+
branches << git.branches.local.select{ |b| b.current }[0].name
|
124
|
+
branches << git.branches.local.select{ |b| not b.current }.map{ |b| b.name }
|
125
|
+
end
|
100
126
|
branches.flatten
|
101
127
|
end
|
102
128
|
end
|
@@ -113,13 +139,54 @@ module AsciiBinder
|
|
113
139
|
@distro_map_file ||= File.join(source_dir, DISTRO_MAP_FILENAME)
|
114
140
|
end
|
115
141
|
|
142
|
+
def dir_empty?(dir)
|
143
|
+
Dir.entries(dir).select{ |f| not f.start_with?('.') }.empty?
|
144
|
+
end
|
145
|
+
|
116
146
|
# Protip: Don't cache this! It needs to be reread every time we change branches.
|
117
147
|
def build_config
|
118
148
|
validate_config(YAML.load_stream(open(build_config_file)))
|
119
149
|
end
|
120
150
|
|
151
|
+
def create_new_repo
|
152
|
+
gem_template_dir = File.join(gem_root_dir,"templates")
|
153
|
+
|
154
|
+
# Create the new repo dir
|
155
|
+
begin
|
156
|
+
Dir.mkdir(source_dir)
|
157
|
+
rescue Exception => e
|
158
|
+
raise "Could not create directory '#{source_dir}': #{e.message}"
|
159
|
+
end
|
160
|
+
|
161
|
+
# Copy the basic repo content into the new repo dir
|
162
|
+
Find.find(gem_template_dir).each do |path|
|
163
|
+
next if path == gem_template_dir
|
164
|
+
src_path = Pathname.new(path)
|
165
|
+
tgt_path = src_path.sub(gem_template_dir,source_dir)
|
166
|
+
if src_path.directory?
|
167
|
+
FileUtils.mkdir_p(tgt_path.to_s)
|
168
|
+
else
|
169
|
+
FileUtils.cp src_path.to_s, tgt_path.to_s
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Initialize the git repo and check everything in
|
174
|
+
g = nil
|
175
|
+
begin
|
176
|
+
g = Git.init(source_dir)
|
177
|
+
rescue Exception => e
|
178
|
+
raise "Could not initialize git repo in '#{source_dir}': #{e.message}"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
121
182
|
def find_topic_files
|
122
|
-
file_list =
|
183
|
+
file_list = []
|
184
|
+
Find.find(source_dir).each do |path|
|
185
|
+
next if path.nil? or not path =~ /.*\.adoc/ or path =~ /README/ or path =~ /\/old\//
|
186
|
+
src_path = Pathname.new(path).sub(source_dir,'').to_s
|
187
|
+
next if src_path.split('/').length < 3
|
188
|
+
file_list << src_path
|
189
|
+
end
|
123
190
|
file_list.map{ |path|
|
124
191
|
parts = path.split('/').slice(1..-1);
|
125
192
|
parts.slice(0..-2).join('/') + '/' + parts[-1].split('.')[0]
|
@@ -187,7 +254,8 @@ module AsciiBinder
|
|
187
254
|
args[:subtopic_shim] = '../'
|
188
255
|
end
|
189
256
|
|
190
|
-
|
257
|
+
template_path = File.expand_path("#{source_dir}/_templates/page.html.erb")
|
258
|
+
template_renderer.render(template_path, args)
|
191
259
|
end
|
192
260
|
|
193
261
|
def extract_breadcrumbs(args)
|
@@ -390,6 +458,12 @@ module AsciiBinder
|
|
390
458
|
end
|
391
459
|
|
392
460
|
def generate_docs(build_distro,single_page=nil)
|
461
|
+
# First, test to see if the docs repo has any commits. If the user has just
|
462
|
+
# run `asciibinder create`, there will be no commits to work from, yet.
|
463
|
+
if local_branches.empty?
|
464
|
+
raise "Before you can build the docs, you need at least one commit in your docs repo."
|
465
|
+
end
|
466
|
+
|
393
467
|
single_page_dir = []
|
394
468
|
single_page_file = nil
|
395
469
|
if not single_page.nil?
|
@@ -408,9 +482,6 @@ module AsciiBinder
|
|
408
482
|
puts "Building all distributions."
|
409
483
|
end
|
410
484
|
|
411
|
-
# Cache the page templates
|
412
|
-
TemplateRenderer.initialize_cache(template_dir)
|
413
|
-
|
414
485
|
# First, notify the user of missing local branches
|
415
486
|
missing_branches = []
|
416
487
|
distro_branches(build_distro).sort.each do |dbranch|
|
@@ -480,19 +551,23 @@ module AsciiBinder
|
|
480
551
|
end
|
481
552
|
|
482
553
|
# Create the target dir
|
483
|
-
branch_path
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
# Copy
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
554
|
+
branch_path = File.join(preview_dir,distro,branch_config["dir"])
|
555
|
+
branch_stylesheet_dir = File.join(branch_path,STYLESHEET_DIRNAME)
|
556
|
+
branch_javascript_dir = File.join(branch_path,JAVASCRIPT_DIRNAME)
|
557
|
+
branch_image_dir = File.join(branch_path,IMAGE_DIRNAME)
|
558
|
+
|
559
|
+
# Copy files into the preview area.
|
560
|
+
[[stylesheet_dir, '*css', branch_stylesheet_dir],
|
561
|
+
[javascript_dir, '*js', branch_javascript_dir],
|
562
|
+
[image_dir, '*', branch_image_dir]].each do |dgroup|
|
563
|
+
src_dir = dgroup[0]
|
564
|
+
glob = dgroup[1]
|
565
|
+
tgt_dir = dgroup[2]
|
566
|
+
if Dir.exist?(src_dir) and not dir_empty?(src_dir)
|
567
|
+
FileUtils.mkdir_p tgt_dir
|
568
|
+
FileUtils.cp_r Dir.glob(File.join(src_dir,glob)), tgt_dir
|
569
|
+
end
|
570
|
+
end
|
496
571
|
|
497
572
|
# Build the landing page
|
498
573
|
navigation = nav_tree(distro,branch_build_config)
|
@@ -665,12 +740,11 @@ module AsciiBinder
|
|
665
740
|
:group_id => topic_group['ID'],
|
666
741
|
:subgroup_id => topic_subgroup && topic_subgroup['ID'],
|
667
742
|
:topic_id => topic['ID'],
|
668
|
-
:css_path => "../../#{dir_depth}#{branch_config["dir"]}/
|
669
|
-
:javascripts_path => "../../#{dir_depth}#{branch_config["dir"]}/
|
670
|
-
:images_path => "../../#{dir_depth}#{branch_config["dir"]}/
|
743
|
+
:css_path => "../../#{dir_depth}#{branch_config["dir"]}/#{STYLESHEET_DIRNAME}/",
|
744
|
+
:javascripts_path => "../../#{dir_depth}#{branch_config["dir"]}/#{JAVASCRIPT_DIRNAME}/",
|
745
|
+
:images_path => "../../#{dir_depth}#{branch_config["dir"]}/#{IMAGE_DIRNAME}/",
|
671
746
|
:site_home_path => "../../#{dir_depth}index.html",
|
672
|
-
:
|
673
|
-
:template_dir => template_dir,
|
747
|
+
:template_path => template_dir,
|
674
748
|
}
|
675
749
|
full_file_text = page(page_args)
|
676
750
|
File.write(tgt_file_path,full_file_text)
|
@@ -4,7 +4,7 @@ guard 'shell' do
|
|
4
4
|
full_path = m[0].split('/')
|
5
5
|
src_group_path = full_path.length == 1 ? '' : full_path[0..-2].join('/')
|
6
6
|
filename = full_path[-1][0..-6]
|
7
|
-
system("
|
7
|
+
system("asciibinder build --page='#{src_group_path}:#{filename}'")
|
8
8
|
end
|
9
9
|
}
|
10
10
|
end
|
@@ -2,24 +2,28 @@ require 'tilt'
|
|
2
2
|
|
3
3
|
module AsciiBinder
|
4
4
|
class TemplateRenderer
|
5
|
-
|
6
|
-
@template_cache ||= {}
|
7
|
-
end
|
5
|
+
attr_reader :source_dir, :template_cache
|
8
6
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
7
|
+
def initialize(source_dir,template_directory)
|
8
|
+
@source_dir = source_dir
|
9
|
+
@template_cache = {}
|
10
|
+
Dir.glob(File.join(template_directory, "**/*")).each do |file|
|
11
|
+
@template_cache[file] = Tilt.new(file, :trim => "-")
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
def render(template, args = {})
|
16
|
+
# Inside erb files, template path is local to repo
|
17
|
+
if not template.start_with?(source_dir)
|
18
|
+
template = File.join(source_dir, template)
|
19
|
+
end
|
16
20
|
renderer_for(template).render(self, args).chomp
|
17
21
|
end
|
18
22
|
|
19
23
|
private
|
20
24
|
|
21
25
|
def renderer_for(template)
|
22
|
-
|
26
|
+
template_cache.fetch(File.expand_path(template))
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|