nandoc 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,11 +13,14 @@ module NanDoc
13
13
 
14
14
  def aliases; [ 'cnds', 'cns', 'cs' ] end # override create_site short!
15
15
 
16
- def short_desc; 'create a nandoc site' end
16
+ def short_desc
17
+ "#{NanDoc::Config.option_prefix}create a nandoc site"
18
+ end
17
19
 
18
20
  def long_desc
21
+ prefix = NanDoc::Config.option_prefix
19
22
  <<-D.gsub(/\n +/,' ')
20
- (nanDoc hack) Create a new site at the given path. This builds on the
23
+ #{prefix}Create a new site at the given path. This builds on the
21
24
  create_site nanoc3 command. Please see that for more
22
25
  information. Run this next to your README.md file.
23
26
  D
@@ -26,19 +29,26 @@ module NanDoc
26
29
  def usage; "nandoc create_nandoc_site [-m] <path>" end
27
30
 
28
31
  def option_definitions
29
- [
30
- { :long => 'patch-hack', :short => 'p', :argument => :none,
31
- :desc => '(nanDoc hack) use files not patches when necessary' },
32
+ @opt_defs ||= begin
33
+ prefix = NanDoc::Config.option_prefix
34
+ [
35
+ { :long => 'patch-hack', :short => 'p', :argument => :none,
36
+ :desc => "#{prefix} use files not patches when necessary" },
32
37
 
33
- { :long => 'merge-hack', :short => 'm', :argument => :none,
34
- :desc =>
35
- '(nanDoc hack) when site already exists do something clever'
36
- },
37
- { :long => 'merge-hack-reverse', :short => 'M', :argument => :none,
38
- :desc =>
39
- '(nanDoc hack) show the reverse diff of above.'
40
- }
41
- ]
38
+ { :long => 'merge-hack', :short => 'm', :argument => :none,
39
+ :desc =>
40
+ "#{prefix}when site already exists do something clever"
41
+ },
42
+ { :long => 'merge-hack-reverse', :short => 'M', :argument => :none,
43
+ :desc =>
44
+ "#{prefix}show the reverse diff of above."
45
+ },
46
+ { :long => 'prototype', :short=>'t', :argument => :required,
47
+ :default => 'default',
48
+ :desc => "#{prefix}the name of the site prototype to use"
49
+ }
50
+ ]
51
+ end
42
52
  end
43
53
 
44
54
  #
@@ -47,8 +57,13 @@ module NanDoc
47
57
  # stderr hack off.
48
58
  #
49
59
  def run(opts, args, method_opts={:_merge=>true})
60
+ args = store_extra_args(args)
50
61
  opts = normalize_opts opts
51
62
  run_opts_process opts
63
+
64
+ return prototype_run_without_nanoc(args) unless
65
+ @treebis_task.lay_over_nanoc_site?
66
+
52
67
  #
53
68
  # awful: see if nanoc triggers the error message about site
54
69
  # already existing, then take action
@@ -76,6 +91,10 @@ module NanDoc
76
91
  end
77
92
 
78
93
  def run_opts_process opts
94
+
95
+ # not sure where to put this
96
+ initiate_the_supreme_hack_of_the_standard_error_stream
97
+
79
98
  task_abort("you can't have both -M and -m") if
80
99
  opts[:merge_hack] && opts[:merge_hack_reverse]
81
100
  if opts[:datasource]
@@ -86,16 +105,26 @@ module NanDoc
86
105
  end
87
106
  opts[:datasource] = 'nandoc'
88
107
  @patch_hack = opts[:patch_hack]
108
+ prototype_determine opts
89
109
  nil
90
110
  end
91
111
  private :run_opts_process
92
112
 
93
113
  protected
94
114
 
115
+ def err *a
116
+ $stderr.puts(*a)
117
+ end
118
+
119
+ def my_exit
120
+ exit(1);
121
+ end
122
+
95
123
  #
96
124
  # see SupremeStderrHack
97
125
  #
98
126
  def initiate_the_supreme_hack_of_the_standard_error_stream
127
+ return if @extremely_hacked
99
128
  base = Nanoc3::CLI::Base
100
129
  return if base.instance_methods.include?("print_error_orig")
101
130
  base.send(:alias_method, :print_error_orig, :print_error)
@@ -103,8 +132,54 @@ module NanDoc
103
132
  $stderr = SupremeStderrHack.new($stderr)
104
133
  print_error_orig error
105
134
  end
135
+ @extremely_hacked = true
106
136
  end
107
137
 
138
+ def prototype_determine opts
139
+ proto_name = opts[:prototype] || 'default'
140
+ require 'nandoc/support/treebis-extlib' # experimental
141
+ proto_path = "#{NanDoc::Root}/proto/#{proto_name}"
142
+ @treebis_task = Treebis.dir_task(proto_path)
143
+ end
144
+
145
+ def prototype_run
146
+ task = @treebis_task
147
+ names = task.erb_variable_names
148
+ if names.any?
149
+ require 'nandoc/erb/agent'
150
+ Erb::Agent.process_erb_values_from_the_commandline(
151
+ self, task, names, @extra_args
152
+ )
153
+ end
154
+ task.file_utils = Config.file_utils
155
+ task.on(FileUtils.pwd).run(:patch_hack => @patch_hack)
156
+ end
157
+
158
+ def prototype_run_without_nanoc args
159
+ if args.empty?
160
+ err "missing <path> argument."
161
+ err usage
162
+ my_exit
163
+ end
164
+ if args.size > 1
165
+ err "Too many arguments"
166
+ err usage
167
+ my_exit
168
+ end
169
+ path = args.first
170
+ if File.exist?(path) && Dir[path+'/*'].any?
171
+ err "folder already exists (no merge yet): #{path}"
172
+ err usage
173
+ my_exit
174
+ end
175
+ if ! File.exist?(path)
176
+ fu = Config.file_utils
177
+ fu.mkdir_p(path)
178
+ end
179
+ FileUtils.cd(path) do
180
+ prototype_run
181
+ end
182
+ end
108
183
 
109
184
  def site_already_exists opts, args
110
185
  path = args.first
@@ -121,7 +196,14 @@ module NanDoc
121
196
  end
122
197
  end
123
198
 
124
-
199
+ def store_extra_args args
200
+ @extra_args = nil
201
+ if args.length > 1 && args[1] =~ /^-/
202
+ @extra_args = args[1..-1]
203
+ args = args[0..0]
204
+ end
205
+ args
206
+ end
125
207
 
126
208
  #
127
209
  # This is the crux of the whole thing: make the site as the parent
@@ -130,12 +212,9 @@ module NanDoc
130
212
  def site_populate
131
213
  initiate_the_supreme_hack_of_the_standard_error_stream
132
214
  super
133
- task = Treebis.dir_task(NanDoc::Root+'/proto/default')
134
- task.file_utils = Config.file_utils
135
- task.on(FileUtils.pwd).run(:patch_hack => @patch_hack)
215
+ prototype_run
136
216
  end
137
217
 
138
-
139
218
  #
140
219
  # Somehow legitimize these awful hacks with an entire class
141
220
  #
@@ -194,13 +273,14 @@ module NanDoc
194
273
  when :looking_for_error_header
195
274
  if a.first && a.first.include?('/!\ ERROR /!\\')
196
275
  @state = :waiting_for_end_of_error_box
276
+ me = NanDoc::Config.option_prefix
197
277
  @ui.puts <<-HERE.gsub(/^ +/,'')
198
- +--- /!\ ERROR /!\ --------------------------------------------+
199
- | An exception occured while running nandoc. If you think this |
200
- | is a bug in nandoc (likely), please report it at |
201
- | <http://github.com/hipe/nandoc/issues> -- thanks! |
202
- | (it is very likely a treebis patch failure) |
203
- +--------------------------------------------------------------+
278
+ +--- /!\\ ERROR /!\\ ----------------------------------------------+
279
+ | An exception occured while running #{me}. If you think |
280
+ | this is a bug in nanDoc (likely), please report it at |
281
+ | <http://github.com/hipe/nandoc/issues> -- thanks! |
282
+ | (it is very likely a treebis patch failure) |
283
+ +----------------------------------------------------------------+
204
284
  HERE
205
285
  else
206
286
  @ui.puts(*a) # probably just whitespace?
@@ -12,7 +12,9 @@ module NanDoc::Commands
12
12
 
13
13
  def aliases; [ 'd' ] end
14
14
 
15
- def short_desc; 'maybe push and pull some stuff (nanDoc hack)' end
15
+ def short_desc
16
+ "#{NanDoc::Config.option_prefix}maybe push and pull some stuff"
17
+ end
16
18
 
17
19
  def long_desc
18
20
  <<-LONG_DESC.gsub(/\n +/,' ')
data/lib/nandoc/config.rb CHANGED
@@ -49,6 +49,29 @@ module NanDoc
49
49
  end
50
50
  end
51
51
  end
52
+
53
+ #
54
+ # Give some visual distinction of what options for a given command
55
+ # are a nanDoc hack
56
+ #
57
+ def option_prefix_colorized
58
+ "(\e[35mnanDoc\e[0m) "
59
+ end
60
+
61
+ def option_prefix_no_color
62
+ '(nanDoc hack) '
63
+ end
64
+
65
+ def option_prefix
66
+ colorize? ?
67
+ option_prefix_colorized :
68
+ option_prefix_no_color
69
+ end
70
+
71
+ #
72
+ # other parts of the app include this module to get convenience methods
73
+ # to some of the config nodes.
74
+ #
52
75
  module Accessors
53
76
  def file_utils
54
77
  NanDoc::Config.file_utils
@@ -0,0 +1,95 @@
1
+ module NanDoc::Erb
2
+ class Agent
3
+
4
+ #
5
+ # whatever weird random and fanciful things we want to do with an ERB tree
6
+ #
7
+
8
+ class << self
9
+ include NanDoc::OptsNormalizer # unnormalize_opt_keys
10
+
11
+ # put parameter values from the command line into the erb files
12
+ # in the task
13
+ #
14
+ # @param [?]
15
+ # @param [Treebis::Task] task - takes erb values
16
+ # @param [Array] names - the list of names it takes
17
+ # @param [Array] argv - ARGV or the like
18
+ #
19
+ def process_erb_values_from_the_commandline cmd, task, names, argv
20
+ @cmd, @task, @names, @argv = cmd, task, names, argv
21
+ @args = nil
22
+ args_none unless argv
23
+ args_parse
24
+ erb_values = args_validate
25
+ task.erb_values(erb_values)
26
+ nil
27
+ end
28
+ private
29
+
30
+ def args_none
31
+ err "Please provide args for the erb templates."
32
+ show_usage
33
+ my_exit
34
+ end
35
+
36
+ def args_parse
37
+ hash = {}
38
+ @argv.each do |str|
39
+ unless /\A--([-_a-z0-9]*)=(.+)\Z/ =~ str
40
+ err "couldn't parse #{str.inspect} -- expecting \"--foo='bar'\""
41
+ show_usage
42
+ my_exit
43
+ end
44
+ hash[normalize_opt_key($1)] = $2
45
+ end
46
+ @args = hash
47
+ end
48
+
49
+ def args_validate
50
+ args = @args.dup
51
+ have = {}
52
+ need = Hash[ @names.map{ |n| [normalize_opt_key(n), true] } ]
53
+ suck = []
54
+ args.each do |k, v|
55
+ if need[k]
56
+ have[k.to_s] = v
57
+ need.delete(k)
58
+ else
59
+ suck.push unnormalize_opt_key(k)
60
+ end
61
+ end
62
+ miss = need.keys.map{ |k| unnormalize_opt_key(k) }
63
+ err "unrecognized erb parameter(s): #{suck.join(' ')}" if suck.any?
64
+ err "missing erb parameter(s): #{miss.join(' ')}" if miss.any?
65
+ if miss.any? or suck.any?
66
+ show_usage;
67
+ my_exit
68
+ end
69
+ have
70
+ end
71
+
72
+ def err *a
73
+ $stderr.puts(*a)
74
+ end
75
+
76
+ def my_exit
77
+ exit(1)
78
+ end
79
+
80
+ def show_usage
81
+ err "usage: nandoc #{@cmd.name} <mysite> -- #{these_things}"
82
+ end
83
+
84
+ def these_things
85
+ names = unnormalize_opt_keys(@names)
86
+ vals = ['foo', 'bar', 'bizz bazz']
87
+ vals2 = Array.new(names.size).map{ |x| vals[ rand(vals.size) ] }
88
+ vals3 = names.zip(vals2)
89
+ vals4 = vals3.map{|(name,val)| "#{name}=\"#{val}\"" }
90
+ str = vals4.join(' ')
91
+ str
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,83 @@
1
+ module Treebis
2
+ #
3
+ # experimental additions to treebis
4
+ #
5
+
6
+ class BlockProbe
7
+ # if needed, etc
8
+ def initialize(&block)
9
+ @sexp = []
10
+ instance_eval(&block)
11
+ end
12
+ attr_reader :sexp
13
+ def method_missing name, *args
14
+ record = [name, *args]
15
+ @sexp.push record
16
+ nil
17
+ end
18
+ end
19
+
20
+ module PathUtils
21
+ def undot path
22
+ $1 if /^(?:\.\/)?(.+)$/ =~ path
23
+ end
24
+ def path_from_full path
25
+ File.join(@from, undot(path))
26
+ end
27
+ def path_from_full_assert path
28
+ fullpath = path_from_full(path)
29
+ unless File.exist?(fullpath)
30
+ name = respond_to?(:name) ? " #{self.name.inspect}" : ''
31
+ fail <<-HERE.gsub(/^ +/, '')
32
+ Treebis task#{name} referred to file #{path}
33
+ that did not exist at #{fullpath}
34
+ HERE
35
+ end
36
+ fullpath
37
+ end
38
+ end
39
+
40
+ class Task
41
+ include PathUtils
42
+ alias_method :initialize_orig, :initialize
43
+ def initialize(*a,&b)
44
+ initialize_orig(*a,&b)
45
+ sexp = reflection_sexp
46
+ props = sexp.select{|x| x.first == :prop }
47
+ set_props(props) if props.any?
48
+ end
49
+ def erb_variable_names
50
+ sexp = reflection_sexp
51
+ filenames = sexp.select{ |x| x.first == :erb }
52
+ names = []
53
+ filenames.each do |node|
54
+ path = path_from_full_assert(node[1])
55
+ names |= erb_variable_names_in_file(path)
56
+ end
57
+ names
58
+ end
59
+ def erb_variable_names_in_file path
60
+ content = File.read(path)
61
+ names = content.scan(/<%= *([_a-z0-9]+) *%>/).map{ |x| x[0] }
62
+ names = names.uniq
63
+ names
64
+ end
65
+ def prop *a
66
+ end
67
+ def reflection_sexp
68
+ BlockProbe.new(&@block).sexp
69
+ end
70
+ private
71
+ def set_props props
72
+ sing = class << self; self end
73
+ props.each do |prop|
74
+ val = prop[2]
75
+ sing.send(:define_method, prop[1]){ val }
76
+ end
77
+ nil
78
+ end
79
+ class RunContext
80
+ def prop(*a); end
81
+ end
82
+ end
83
+ end
@@ -16,10 +16,13 @@ module NanDoc
16
16
  def normalize_opts opts
17
17
  opts = opts.dup
18
18
  opts.keys.select{|x| x.to_s.index('-') }.each do |k|
19
- opts[k.to_s.gsub('-','_').to_sym] = opts.delete(k)
19
+ opts[normalize_opt_key(k)] = opts.delete(k)
20
20
  end
21
21
  opts
22
22
  end
23
+ def normalize_opt_key k
24
+ k.to_s.gsub('-','_').to_sym
25
+ end
23
26
  def unnormalize_opt_keys keys
24
27
  keys.map{|x| unnormalize_opt_key(x)}
25
28
  end
@@ -4,7 +4,7 @@ namespace :nandoc do
4
4
  desc "#{prefix} Upload the compiled site using rsync, shows command"
5
5
  task :rsync do
6
6
  require 'nandoc/deployers/rsync'
7
-
7
+
8
8
  dry_run = !!ENV['dry_run']
9
9
  config_name = ENV['config'] || :default
10
10
 
data/proto/README.md CHANGED
@@ -5,7 +5,9 @@ This document presents three implementation alternatives of NanDoc site creation
5
5
 
6
6
  ### Prototypes
7
7
 
8
- Each folder in this folder is a 'prototype' nanoc installation. (Probably only one folder, called 'default'.) (The folder called 'misc' holds one-off templates for ad-hoc stuff, maybe for helpers etc.)
8
+ Almost each folder in this folder is a 'prototype' nanDoc installation. Most users will only ever use the `default` prototype and not worry about other prototypes.
9
+
10
+ The folder called 'misc' holds one-off templates for ad-hoc stuff, maybe for helpers etc.
9
11
 
10
12
  The result of each such prototype is comparable to the filetree you get from a default nanoc 'create_site' command, but altered accordingly to be a NanDoc site, whatever that will come to mean.
11
13
 
@@ -14,7 +16,7 @@ The result of each such prototype is comparable to the filetree you get from a d
14
16
 
15
17
  The prototype site(s) in this folder is probably expressed as a cangeset to an existing default filetree created by `nanoc create_site <my-site>`. Given that the default NanDoc site is rougly 90% the same as a default Nanoc3 site ATTOTW, the author felt that it would be best to represent the default NanDoc site as a diff of the default Nanoc site.[^1]
16
18
 
17
- [^1]: At such time as this percentage drops significantly we will reconsider this decision.
19
+ [^1]: At such time as this percentage drops significantly we will reconsider this decision. -- @todo this is no longer the case.
18
20
 
19
21
  Thus the changesets here are the minimal readable expression of changes we want to make to a default nanoc site tree, to alter it to be a default NanDoc
20
22
  site tree. These changesets are expressed using a Treebis 'patch' which is some files along with a Treebis task. (See documentation there for gory details.)
@@ -21,12 +21,15 @@ enable_output_diff: false
21
21
 
22
22
 
23
23
  # nanDoc: here is an example deployment config node.
24
- # uncomment this, get it right, and try `rake deploy:rsync` from your mysite
25
- # directory
24
+ # uncomment this, get it right, and try
25
+ # `rake config={default|rubyforge} deploy:rsync` from your mysite
26
+ # directory (or rake `nandoc:deploy:rsync` whatever that does.)
27
+ #
26
28
  # deploy:
27
29
  # default:
28
30
  # dst: "hipeland.org:/var/sites/nandoc.hipeland.org"
29
- #
31
+ # rubyforge:
32
+ # dst: hipe@rubyforge.org:/var/www/gforge-projects/nandoc
30
33
 
31
34
  # The data sources where nanoc loads its data from. This is an array of
32
35
  # hashes; each array element represents a single data source. By default,
@@ -4,6 +4,7 @@
4
4
  # to the folder containing this file.
5
5
 
6
6
  Treebis.tasks.task(:default) do
7
+ prop :lay_over_nanoc_site?, true
7
8
  # opts[:patch_hack] = true
8
9
  remove './content/index.html' # assume we will use README.md for now.
9
10
  # we don't want multiple '/' @items.
@@ -0,0 +1,2 @@
1
+ require 'nanoc3/tasks'
2
+ require 'nandoc/tasks'
@@ -0,0 +1,4 @@
1
+ # added by nanDoc (not really):
2
+ deploy:
3
+ default:
4
+ dst: <%= rubyforge_username %>@rubyforge.org:/var/www/gforge-projects/<%= rubyforge_project_name %>
@@ -0,0 +1,5 @@
1
+ <html>
2
+ <head>
3
+ <meta HTTP-EQUIV="REFRESH" content="0; url=<%= url %>">
4
+ </head>
5
+ </html>
@@ -0,0 +1,10 @@
1
+ # This is a treebis patch file for this folder and its contents.
2
+ # See the README sibling to the folder containing this file.
3
+
4
+ Treebis.tasks.task(:"rubyforge-redirect") do
5
+ prop :lay_over_nanoc_site?, false
6
+ copy './Rakefile'
7
+ erb './config.yaml'
8
+ mkdir_p './output/'
9
+ erb './output/index.html'
10
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
9
- version: 0.0.2
8
+ - 3
9
+ version: 0.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Chip Malice
@@ -86,6 +86,7 @@ files:
86
86
  - lib/nandoc/cri-hacks.rb
87
87
  - lib/nandoc/data-source.rb
88
88
  - lib/nandoc/deployers/rsync.rb
89
+ - lib/nandoc/erb/agent.rb
89
90
  - lib/nandoc/filters.rb
90
91
  - lib/nandoc/helpers.rb
91
92
  - lib/nandoc/helpers/menu-bouncy.rb
@@ -111,6 +112,7 @@ files:
111
112
  - lib/nandoc/support/site-merge.rb
112
113
  - lib/nandoc/support/site-methods.rb
113
114
  - lib/nandoc/support/stream-colorizer.rb
115
+ - lib/nandoc/support/treebis-extlib.rb
114
116
  - lib/nandoc/tasks.rb
115
117
  - lib/nandoc/tasks/nandoc/deploy.rake
116
118
  - lib/nandoc/test/diff-to-string.rb
@@ -133,6 +135,10 @@ files:
133
135
  - proto/default/lib/default.rb
134
136
  - proto/default/treebis-task.rb
135
137
  - proto/misc/orphan-surrogate.md
138
+ - proto/rubyforge-redirect/Rakefile
139
+ - proto/rubyforge-redirect/config.yaml
140
+ - proto/rubyforge-redirect/output/index.html
141
+ - proto/rubyforge-redirect/treebis-task.rb
136
142
  - test/test.rb
137
143
  - README
138
144
  has_rdoc: true