nandoc 0.0.2 → 0.0.3

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.
@@ -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