nandoc 0.0.1
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/README +124 -0
- data/Rakefile +53 -0
- data/bin/nandoc +6 -0
- data/doc/CREDITS.md +6 -0
- data/doc/FAQ/why-not-wiki.md +20 -0
- data/doc/FAQ.md +68 -0
- data/doc/TODOs-and-BUGs.md +15 -0
- data/doc/bar/baz.md +4 -0
- data/doc/bar/bliff.md +8 -0
- data/doc/foo.md +5 -0
- data/doc/getting-started.rb +13 -0
- data/doc/svg/less-fonts.svg +21 -0
- data/lib/nandoc/commands/create-nandoc-site.rb +225 -0
- data/lib/nandoc/commands/diff.rb +279 -0
- data/lib/nandoc/config.rb +58 -0
- data/lib/nandoc/cri-hacks.rb +13 -0
- data/lib/nandoc/data-source.rb +239 -0
- data/lib/nandoc/filters.rb +661 -0
- data/lib/nandoc/helpers/menu-bouncy.rb +109 -0
- data/lib/nandoc/helpers/site-map.rb +157 -0
- data/lib/nandoc/helpers/top-nav.rb +47 -0
- data/lib/nandoc/helpers.rb +42 -0
- data/lib/nandoc/item-class-hacks.rb +57 -0
- data/lib/nandoc/nandoc.persistent.json +3 -0
- data/lib/nandoc/parse-readme.rb +95 -0
- data/lib/nandoc/spec-doc/mini-test/spec-instance-methods.rb +0 -0
- data/lib/nandoc/spec-doc/mini-test.rb +105 -0
- data/lib/nandoc/spec-doc/mock-prompt.rb +121 -0
- data/lib/nandoc/spec-doc/support-modules.rb +158 -0
- data/lib/nandoc/spec-doc/test-case-agent.rb +57 -0
- data/lib/nandoc/spec-doc/test-framework-dispatcher.rb +15 -0
- data/lib/nandoc/spec-doc/test-framework-proxy.rb +78 -0
- data/lib/nandoc/spec-doc.rb +46 -0
- data/lib/nandoc/support/diff-proxy.rb +113 -0
- data/lib/nandoc/support/orphanage.rb +77 -0
- data/lib/nandoc/support/path-tardo.rb +85 -0
- data/lib/nandoc/support/regexp-enhance.rb +76 -0
- data/lib/nandoc/support/site-diff.rb +46 -0
- data/lib/nandoc/support/site-merge.rb +62 -0
- data/lib/nandoc/support/site-methods.rb +69 -0
- data/lib/nandoc/support/stream-colorizer.rb +203 -0
- data/lib/nandoc/support-modules.rb +270 -0
- data/lib/nandoc/test/diff-to-string.rb +251 -0
- data/lib/nandoc/test/minitest-extlib.rb +53 -0
- data/lib/nandoc/treebis/NOGIT-DOCS/NEWS.md +5 -0
- data/lib/nandoc/treebis/NOGIT-README.md +65 -0
- data/lib/nandoc/treebis/nandoc.persistent.json +3 -0
- data/lib/nandoc.rb +48 -0
- data/proto/README.md +31 -0
- data/proto/default/Rakefile +1 -0
- data/proto/default/Rules +46 -0
- data/proto/default/config.yaml +57 -0
- data/proto/default/content/css/nanoc-dist-altered.css +213 -0
- data/proto/default/content/css/trollop-subset.css +116 -0
- data/proto/default/content/js/menu-bouncy.js +126 -0
- data/proto/default/content/stylesheet.css.diff +20 -0
- data/proto/default/content/vendor/jquery-1.3.js +4241 -0
- data/proto/default/content/vendor/jquery.easing.1.3.js +205 -0
- data/proto/default/layouts/default.html +70 -0
- data/proto/default/lib/default.orig.rb +2 -0
- data/proto/default/lib/default.rb +5 -0
- data/proto/default/treebis-task.rb +28 -0
- data/proto/misc/orphan-surrogate.md +6 -0
- data/test/test.rb +102 -0
- metadata +166 -0
@@ -0,0 +1,279 @@
|
|
1
|
+
support = File.expand_path('../../support', __FILE__)
|
2
|
+
require support + '/diff-proxy.rb'
|
3
|
+
require support + '/path-tardo.rb'
|
4
|
+
require support + '/site-methods.rb'
|
5
|
+
|
6
|
+
module NanDoc::Commands
|
7
|
+
class Diff < ::Cri::Command
|
8
|
+
NanDoc.persistent_delegate_to(self) # persistent_set(), persistent_get()
|
9
|
+
include NanDoc::CliCommandHelpers, NanDoc::PathTardo, NanDoc::SiteMethods
|
10
|
+
|
11
|
+
def name; 'diff' end
|
12
|
+
|
13
|
+
def aliases; [ 'd' ] end
|
14
|
+
|
15
|
+
def short_desc; 'maybe push and pull some stuff (nanDoc hack)' end
|
16
|
+
|
17
|
+
def long_desc
|
18
|
+
<<-LONG_DESC.gsub(/\n +/,' ')
|
19
|
+
Patch a subtree of <my-site>/content with the same subtree in
|
20
|
+
<my-site>/output with (--content-to-output|-c). (default). Opposite
|
21
|
+
direction with -C.
|
22
|
+
|
23
|
+
Patch a subtree of <prototypes>/<the-prototype> with the same
|
24
|
+
subtree of <my-site>/content with (--content-to-prototype|-p).
|
25
|
+
(For patching nanDoc prototypes.) Opposite direction with -P.
|
26
|
+
|
27
|
+
This operates on a subset of the indicated trees, for now either
|
28
|
+
the css folders in <my-site>/output/ and <my-site>/content/ or the
|
29
|
+
layout folders between the prototype and the <my-site>. Indicate
|
30
|
+
which with -s (css|layouts) (default: css)
|
31
|
+
|
32
|
+
So, with this wierd chain, you can tweak your CSS, for example,
|
33
|
+
in the generated output and then push these changes all the way back to
|
34
|
+
the prototype with -cY and then -pY
|
35
|
+
|
36
|
+
Or you can undo your changes pulling all the way back from the prototype
|
37
|
+
with -PY and then -CY
|
38
|
+
LONG_DESC
|
39
|
+
end
|
40
|
+
|
41
|
+
def usage;
|
42
|
+
'nandoc diff [-c|-C|-p|-P] [-s (css|layouts|js|root)] [-Y [-b]] [<path>]'
|
43
|
+
end
|
44
|
+
|
45
|
+
def option_definitions
|
46
|
+
pttp = 'pass-thru to patch. only for use with -Y'
|
47
|
+
[ { :long => 'backup', :short => 'b', :argument=>:none,
|
48
|
+
:desc => pttp
|
49
|
+
},
|
50
|
+
{ :long => 'content-to-output', :short => 'c', :argument => :none,
|
51
|
+
:desc => 'show diff or patch content with output (default)'
|
52
|
+
},
|
53
|
+
{ :long => 'content-to-proto', :short => 'P', :argument => :none,
|
54
|
+
:desc => 'show diff or patch content with proto (sure why not)'
|
55
|
+
},
|
56
|
+
{ :long => 'dry-run', :short => 'r', :argument => :none,
|
57
|
+
:desc => pttp
|
58
|
+
},
|
59
|
+
{ :long => 'output-to-content', :short => 'C', :argument => :none,
|
60
|
+
:desc => 'show diff or patch output with content (kind of weird)'
|
61
|
+
},
|
62
|
+
{ :long => 'patch', :short => 'Y', :argument => :none,
|
63
|
+
:desc => 'apply the patch to the target (no undo!)'
|
64
|
+
},
|
65
|
+
{ :long => 'proto-to-content', :short => 'p', :argument => :none,
|
66
|
+
:desc => ("show diff or patch prototype with content\n"<<
|
67
|
+
(' '*22)+"(this would be for patching/altering nandoc)")
|
68
|
+
},
|
69
|
+
{ :long => 'subset', :short => 's', :argument => :required,
|
70
|
+
:desc => "'css' or 'layouts' or 'js' (default: css)"
|
71
|
+
}
|
72
|
+
]
|
73
|
+
end
|
74
|
+
|
75
|
+
def run opts, args
|
76
|
+
opts = normalize_opts opts
|
77
|
+
site_path = deduce_site_path_or_fail(args)
|
78
|
+
src, dest = deduce_src_and_dest site_path, opts
|
79
|
+
subset = subsets.parse(opts)
|
80
|
+
if opts[:patch] # @todo this doesn't belong here probably
|
81
|
+
patch_opts = process_patch_opts(opts, src, dest, site_path)
|
82
|
+
go_patch src, dest, subset, site_path, patch_opts
|
83
|
+
else
|
84
|
+
process_diff_opts(opts) and fail("no more opts for this guy")
|
85
|
+
go_diff src, dest, subset, site_path
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def deduce_root_paths src, dest, site_path
|
92
|
+
@diff_method = :diff_root_subset
|
93
|
+
path_src = deduce_subfolder_path site_path, src
|
94
|
+
path_dst = deduce_subfolder_path site_path, dest
|
95
|
+
if path_src == path_dst
|
96
|
+
task_abort("source and destination paths are the same. "<<
|
97
|
+
"did you forget -p or -P ?\nusage: #{usage}\n"<<
|
98
|
+
invite_to_more_command_help)
|
99
|
+
end
|
100
|
+
[path_src, path_dst]
|
101
|
+
end
|
102
|
+
|
103
|
+
def deduce_subfolder_path site_path, which, sub=nil
|
104
|
+
tox =
|
105
|
+
case which
|
106
|
+
when :output; [site_path, sub ? 'output' : nil, sub]
|
107
|
+
when :content; [site_path, sub ? 'content': nil, sub]
|
108
|
+
when :proto; [proto_path(site_path), sub ? 'content' : nil, sub]
|
109
|
+
else fail(
|
110
|
+
"implement me: get #{which.to_s} subpath")
|
111
|
+
end
|
112
|
+
File.join(tox.compact)
|
113
|
+
end
|
114
|
+
|
115
|
+
def deduce_subfolder_paths sub, src, dest, site_path
|
116
|
+
paths = [src, dest].map do |which|
|
117
|
+
deduce_subfolder_path site_path, which, sub
|
118
|
+
end
|
119
|
+
paths
|
120
|
+
end
|
121
|
+
|
122
|
+
def deduce_layout_paths src, dest, site_path
|
123
|
+
if [src, dest].index(:output)
|
124
|
+
task_abort "Sorry, it doesn't make sense to look at layout " <<
|
125
|
+
"in output directory because there is none.\n" <<
|
126
|
+
"Please use -P or -p to compare layout btwn proto and <my-site>.\n"<<
|
127
|
+
"usage: #{usage}\n#{invite_to_more_command_help}"
|
128
|
+
end
|
129
|
+
paths = [src, dest].map do |which|
|
130
|
+
case which
|
131
|
+
when :content; site_path + '/layouts'
|
132
|
+
when :proto; proto_path(site_path)+'/layouts'
|
133
|
+
else fail(
|
134
|
+
"implement me: get #{which.to_s} path from #{src.inspect}")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
paths
|
138
|
+
end
|
139
|
+
|
140
|
+
def deduce_paths src, dest, subset, site_path
|
141
|
+
paths = case subset
|
142
|
+
when 'css'; deduce_subfolder_paths 'css', src, dest, site_path
|
143
|
+
when 'layouts'; deduce_layout_paths src, dest, site_path
|
144
|
+
when 'js'; deduce_subfolder_paths 'js', src, dest, site_path
|
145
|
+
when 'root'; deduce_root_paths src, dest, site_path
|
146
|
+
else; fail("unimplemented subset: #{subset}")
|
147
|
+
end
|
148
|
+
src_path, dest_path = paths
|
149
|
+
assert_path "source path", src_path
|
150
|
+
assert_path "destination path", dest_path
|
151
|
+
[src_path, dest_path]
|
152
|
+
end
|
153
|
+
|
154
|
+
def deduce_src_and_dest site_path, opts
|
155
|
+
flag = exclusive_opt_flags(opts) do
|
156
|
+
flags :content_to_output, :content_to_proto,
|
157
|
+
:output_to_content, :proto_to_content
|
158
|
+
default '-c', :content_to_output
|
159
|
+
end
|
160
|
+
/\A(.+)_to_(.+)\Z/ =~ flag.to_s or fail("no: #{flag}")
|
161
|
+
src, dest = $1.to_sym, $2.to_sym
|
162
|
+
[src, dest]
|
163
|
+
end
|
164
|
+
|
165
|
+
def diff_normal src_path, dest_path
|
166
|
+
NanDoc::DiffProxy.diff(src_path, dest_path)
|
167
|
+
end
|
168
|
+
|
169
|
+
def diff_root_subset src, dest
|
170
|
+
require File.expand_path('../../support/site-diff.rb', __FILE__)
|
171
|
+
thing = NanDoc::SiteDiff.new(src, dest)
|
172
|
+
thing.get_diff_object
|
173
|
+
end
|
174
|
+
|
175
|
+
def get_diff_object(*a)
|
176
|
+
@diff_method = :diff_normal
|
177
|
+
src_path, dest_path = deduce_paths(*a)
|
178
|
+
diff = case @diff_method # no send() b/c trace stacks look dumb
|
179
|
+
when :diff_normal; diff_normal(src_path, dest_path)
|
180
|
+
when :diff_root_subset; diff_root_subset(src_path, dest_path)
|
181
|
+
end
|
182
|
+
if diff.error?
|
183
|
+
task_abort diff.error
|
184
|
+
end
|
185
|
+
diff
|
186
|
+
end
|
187
|
+
|
188
|
+
def go_diff(*a)
|
189
|
+
diff = get_diff_object(*a)
|
190
|
+
$stderr.puts diff.command
|
191
|
+
if $stdout.tty? && NanDoc::Config.colorize?
|
192
|
+
diff.colorize($stdout, :styles => NanDoc::Config.diff_stylesheet)
|
193
|
+
else
|
194
|
+
$stdout.puts diff.to_s
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def go_patch *a
|
199
|
+
patch_opts = a.pop
|
200
|
+
pass_thru = patch_opts[:pass_thru] or fail('suxxorz')
|
201
|
+
diff = get_diff_object(*a)
|
202
|
+
|
203
|
+
# Make a tempdir and write the diff to a file
|
204
|
+
tmpdir = empty_tmpdir('for-a-patch')
|
205
|
+
Treebis::Task.new do
|
206
|
+
notice 'command', diff.command
|
207
|
+
write 'diff', diff.to_s
|
208
|
+
end.on(tmpdir).run
|
209
|
+
|
210
|
+
# Patch this sucker and pray we didn't mess up too badly
|
211
|
+
Treebis::Task.new do
|
212
|
+
from tmpdir
|
213
|
+
apply 'diff', pass_thru
|
214
|
+
end.on('.').run
|
215
|
+
end
|
216
|
+
|
217
|
+
def subsets
|
218
|
+
cmd = self
|
219
|
+
@subsets ||= OptEnum.new do |oe|
|
220
|
+
command cmd
|
221
|
+
name :subset
|
222
|
+
values %w(css layouts js root)
|
223
|
+
default 'css'
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def proto_path site_path
|
228
|
+
config = parse_config_for_site_path site_path
|
229
|
+
result = path_tardo(config, 'data_sources/[0]/site_prototype')
|
230
|
+
if result.found?
|
231
|
+
thing_in_config = result.value
|
232
|
+
full_path = "proto/#{thing_in_config}"
|
233
|
+
full_path
|
234
|
+
else
|
235
|
+
task_abort(
|
236
|
+
result.error_message + " in " + config_path_for_site_path(site_path)
|
237
|
+
)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
PatchPassThru = [:backup, :dry_run, :directory]
|
242
|
+
def process_diff_opts opts
|
243
|
+
if (bad = opts.keys & PatchPassThru).any?
|
244
|
+
bads = bad.map{|x| unnormalize_opt_key(x)}.join('and')
|
245
|
+
task_abort "#{bads} cannot be used with diffing only patching.\n"<<
|
246
|
+
"usage: #{usage}\n#{invite_to_more_command_help}"
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def process_patch_opts opts, src, dest, site_path
|
251
|
+
keys = opts.keys & PatchPassThru
|
252
|
+
switches = keys.map{|k| unnormalize_opt_key(k)}
|
253
|
+
switch_h = Hash[switches.zip(Array.new(switches.size, ''))]
|
254
|
+
switch_h['--posix'] = '' # always on else patches don't work
|
255
|
+
process_patch_opts_for_directory switch_h, opts, src, dest, site_path
|
256
|
+
{:pass_thru => switch_h }
|
257
|
+
end
|
258
|
+
|
259
|
+
#
|
260
|
+
# when applying a root-based patch to a prototype we will have to change
|
261
|
+
# directory to that prototype, just for when we apply the patch. and..?
|
262
|
+
#
|
263
|
+
def process_patch_opts_for_directory switch_h, opts, src, dest, site_path
|
264
|
+
return unless opts[:subset] == 'root'
|
265
|
+
if ! opts[:proto_to_content]
|
266
|
+
task_abort("we need to test this for root patching for this target")
|
267
|
+
end
|
268
|
+
# it's not explicitly an available pass-thru option
|
269
|
+
fail("huh?") if switch_h['--directory'] ||
|
270
|
+
switch_h.keys.grep(/^-p\d+$/).any?
|
271
|
+
proto = proto_path(site_path)
|
272
|
+
# for a path like './a/Rules', we cd to the root of the proto, so we
|
273
|
+
# want to disregard two levels of path context.
|
274
|
+
switch_h['-p2'] = ''
|
275
|
+
switch_h['--directory'] = proto
|
276
|
+
nil
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module NanDoc
|
2
|
+
module Config
|
3
|
+
extend self
|
4
|
+
|
5
|
+
#
|
6
|
+
# this name etc etc
|
7
|
+
#
|
8
|
+
|
9
|
+
@orphan_surrogate_filename = Root + '/proto/misc/orphan-surrogate.md'
|
10
|
+
attr_accessor :orphan_surrogate_filename
|
11
|
+
|
12
|
+
|
13
|
+
#
|
14
|
+
# in the future make this smarter. i don't like now nanoc handles color
|
15
|
+
# (a command line argument?) There should be an autodetect, and/or set
|
16
|
+
# last setting in sticky json file; or however it is it is done. @todo
|
17
|
+
#
|
18
|
+
def colorize?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# everybody wants to look like git
|
24
|
+
#
|
25
|
+
def diff_stylesheet
|
26
|
+
@diff_stylesheet ||= {
|
27
|
+
:header => [:bold, :yellow],
|
28
|
+
:add => [:bold, :green],
|
29
|
+
:remove => [:bold, :red],
|
30
|
+
:range => [:bold, :magenta]
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# some FileUtils actions are wrapped with this proxy to allow
|
36
|
+
# formatting and customizations from the typical FileUtils actions,
|
37
|
+
# to indent and colorize the notice stream sorta like nanoc does
|
38
|
+
#
|
39
|
+
|
40
|
+
def file_utils
|
41
|
+
@file_utils ||= begin
|
42
|
+
Treebis::FileUtilsProxy.new do |fu|
|
43
|
+
fu.pretty!
|
44
|
+
fu.color?{ NanDoc::Config.colorize? }
|
45
|
+
fu.prefix = ' ' * 6 # like nanoc
|
46
|
+
fu.ui = proc{ $stdout }
|
47
|
+
# it's normally $stderr, it needs to be reference-like
|
48
|
+
# so that capture3 will work!
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
module Accessors
|
53
|
+
def file_utils
|
54
|
+
NanDoc::Config.file_utils
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Cri
|
2
|
+
class Base
|
3
|
+
# hack
|
4
|
+
include NanDoc::TaskCommon
|
5
|
+
def remove_command command_class
|
6
|
+
if idx = @commands.index{|x| x.kind_of?(command_class) }
|
7
|
+
@commands.delete_at(idx)
|
8
|
+
else
|
9
|
+
task_abort("command not found of class #{command_class}")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
module NanDoc
|
2
|
+
|
3
|
+
class DataSource < ::Nanoc3::DataSources::FilesystemUnified
|
4
|
+
#
|
5
|
+
# Make a Nanoc3 DataSource class as necessary to A) pull in
|
6
|
+
# content files that exist outside of the <my-site>/content directory and
|
7
|
+
# B) allow one of those files to act as the root index page for the
|
8
|
+
# generated site, as indicated by config.yaml. and C) rescue orphan
|
9
|
+
# files that have a parent directory but no parent file, and
|
10
|
+
# D) to see as text files without an extension (e.g. README)
|
11
|
+
#
|
12
|
+
# Some of the hacks in this file are the worst in the whole project. @todo
|
13
|
+
#
|
14
|
+
|
15
|
+
|
16
|
+
include NanDoc::TaskCommon # task_abort()
|
17
|
+
|
18
|
+
def initialize *a
|
19
|
+
super(*a)
|
20
|
+
|
21
|
+
# hack to see as text files without an extension!
|
22
|
+
unless @site.config[:text_extensions].include?(nil)
|
23
|
+
@site.config[:text_extensions].unshift(nil)
|
24
|
+
end
|
25
|
+
@hax_filename_for_last = nil
|
26
|
+
@config = a.last
|
27
|
+
@basenames = @config[:source_file_basenames] or
|
28
|
+
fail("must have source_file_basenames in config.yaml "<<
|
29
|
+
"for nandoc to work."
|
30
|
+
)
|
31
|
+
@hax_mode = false # this gets turned on when we are doing s/thing weird
|
32
|
+
@hax_root_found = false
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# the content filename for ../README is ../README
|
37
|
+
#
|
38
|
+
def filename_for(base_filename, ext)
|
39
|
+
return super unless @hax_mode && ext.nil?
|
40
|
+
if @hax_filename_for_last != base_filename
|
41
|
+
@hax_filename_for_last = base_filename
|
42
|
+
return super
|
43
|
+
else
|
44
|
+
base_filename
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
#
|
50
|
+
# Hack the items returned by this datasource object to include also
|
51
|
+
# files outside of the <my-site>/content directory, e.g. README.md
|
52
|
+
# or README/**/*, NEWS.md, based on settings in the config.
|
53
|
+
#
|
54
|
+
# Rescue orphan nodes with no parent page somehow.
|
55
|
+
#
|
56
|
+
def items
|
57
|
+
_ = Nanoc3::Item # autoload it now for easier step debug-ging
|
58
|
+
these = super
|
59
|
+
dot_dot_names = @basenames.map{|x| "../#{x}"}
|
60
|
+
@hax_mode = true
|
61
|
+
additional = dot_dot_names.map do |basename|
|
62
|
+
if File.file?(basename) # was different
|
63
|
+
load_objects(basename, 'item', Nanoc3::Item)
|
64
|
+
else
|
65
|
+
load_objects(basename, 'item', Nanoc3::Item)
|
66
|
+
end
|
67
|
+
end.compact.flatten(1)
|
68
|
+
@hax_mode = false
|
69
|
+
error_for_no_files(dot_dot_names) if additional.empty?
|
70
|
+
res = these + additional
|
71
|
+
orphan_rescue(res)
|
72
|
+
res
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
#
|
78
|
+
# a hook to grab the folder name that later gets stripped out
|
79
|
+
# also a supremely ugly hack to get e.g. ../README.md
|
80
|
+
#
|
81
|
+
def all_split_files_in dir_name
|
82
|
+
return super unless @hax_mode
|
83
|
+
@hax_last_dirname = dir_name
|
84
|
+
ret = super
|
85
|
+
lone_files = ["#{dir_name}.md", dir_name]
|
86
|
+
lone_file = find_first_file(lone_files)
|
87
|
+
if lone_file # e.g. '../README.md', 'README'
|
88
|
+
@hax_last_filename = lone_file.dup
|
89
|
+
class << lone_file
|
90
|
+
#
|
91
|
+
# supremely fragile hack:
|
92
|
+
# make it so that it ignores the next + operation in the first
|
93
|
+
# line of Nanoc3::DataSources::Filesystem#all_split_files_in()
|
94
|
+
# this is shorter and easier than overriding and rewring
|
95
|
+
# the above function but it is a supreme haxie guaranteed to fail
|
96
|
+
# one day!!!
|
97
|
+
#
|
98
|
+
def + _; self end
|
99
|
+
end
|
100
|
+
other = super(lone_file)
|
101
|
+
ret.merge!(other)
|
102
|
+
end
|
103
|
+
ret
|
104
|
+
end
|
105
|
+
|
106
|
+
# removed old deal_with_index_page_children in e7bf7ee
|
107
|
+
|
108
|
+
#
|
109
|
+
# We crap out if we didn't find any weird files because after all
|
110
|
+
# this is NanDoc.
|
111
|
+
#
|
112
|
+
def error_for_no_files files
|
113
|
+
task_abort <<-HERE.gsub(/\n +/,"\n").strip
|
114
|
+
No matching content file(s) found at or under (#{files.join(', ')})
|
115
|
+
from here. (This corresponds to the 'source_file_basenames' setting in
|
116
|
+
config.yaml.) Did you generate the NanDoc site in the right directory?
|
117
|
+
HERE
|
118
|
+
end
|
119
|
+
|
120
|
+
def find_first_file names
|
121
|
+
names.detect{ |n| File.file?(n) }
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# We don't seem to want any urls with uppercase characters in them
|
126
|
+
# because .. not sure. But the rsync by default downcases our files.
|
127
|
+
# It's probably a good habbit to do this. If we want to accept a variety
|
128
|
+
# of casing with our server that's ok but internally we should keep it consistent
|
129
|
+
# and simple. (This causes gotchas sometimes when moving from a case-insensitive
|
130
|
+
# filesystem like that of OSX to a case-sensitive one like that of debian.)
|
131
|
+
# The titles of items, on the other hand ...
|
132
|
+
#
|
133
|
+
def identifier_normalize identifier
|
134
|
+
if /[A-Z]/ =~ identifier
|
135
|
+
use_identifier = identifier.downcase
|
136
|
+
else
|
137
|
+
use_identifier = identifier
|
138
|
+
end
|
139
|
+
use_identifier
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# more crazy hacks - normally content/foo/bar.html => "/foo/bar/" but
|
144
|
+
# for this case we don't want to have stripped the containing folder,
|
145
|
+
# *and* we try to hack it so that it's laid alongside content in
|
146
|
+
# the content folder for the final site. (or not, here)
|
147
|
+
# also we need to make sure one item is '/' somehow
|
148
|
+
# @todo unhack this whole page
|
149
|
+
#
|
150
|
+
# @todo some stuff that happens in the orphanage should happen here
|
151
|
+
# instead
|
152
|
+
#
|
153
|
+
def identifier_for_filename fn
|
154
|
+
return super unless @hax_mode
|
155
|
+
if 'md' == fn # there has to be a better way :(
|
156
|
+
no_dot_dot = dot_dot_strip_assert(@hax_last_filename)
|
157
|
+
if no_dot_dot == @config[:use_as_main_index] # 'README.md'
|
158
|
+
identifier = '/' # overwrite the index.html generated by nandoc!
|
159
|
+
else
|
160
|
+
# '../README.md' => 'README.md' => '/README/'
|
161
|
+
identifier = super(no_dot_dot)
|
162
|
+
end
|
163
|
+
else
|
164
|
+
if fn
|
165
|
+
if dot_dot_has?(fn)
|
166
|
+
fail("fix this -- should never have dot dot name here: #{hn}")
|
167
|
+
end
|
168
|
+
identifier = super(fn)
|
169
|
+
else
|
170
|
+
identifier = dot_dot_strip_assert(@hax_last_dirname)+'/'
|
171
|
+
end
|
172
|
+
end
|
173
|
+
# before we get to resuce orphans we need to make sure we have
|
174
|
+
# resolved some file as a site root. First one wins.
|
175
|
+
if ! @hax_root_found
|
176
|
+
shorter = slash_strip_assert(identifier)
|
177
|
+
if @basenames.include?(shorter)
|
178
|
+
@hax_root_found = true
|
179
|
+
identifier = '/'
|
180
|
+
end
|
181
|
+
end
|
182
|
+
use_identifier = identifier_normalize(identifier)
|
183
|
+
use_identifier
|
184
|
+
end
|
185
|
+
|
186
|
+
#
|
187
|
+
# A) Experimentally generate index pages for child nodes without them
|
188
|
+
# B) merge many filesystem roots to one docroot (hack!) per 'basenames'
|
189
|
+
# (undefined on name collision)
|
190
|
+
#
|
191
|
+
def orphan_rescue items
|
192
|
+
require File.expand_path('../support/orphanage.rb', __FILE__)
|
193
|
+
Orphanage.rescue_orphans(@config, items)
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
module ItemMethods
|
199
|
+
# must have @items. make public if u need it
|
200
|
+
|
201
|
+
def find_parent item_identifier
|
202
|
+
parent_path = parent_identifier(item_identifier)
|
203
|
+
parent = @items.find { |p| p.identifier == parent_path }
|
204
|
+
parent
|
205
|
+
end
|
206
|
+
def identifier_bare_rootname identifier
|
207
|
+
/\A\/([^\/]+)\// =~ identifier and $1
|
208
|
+
end
|
209
|
+
def identifier_bare_rootname_assert identifier
|
210
|
+
identifier_bare_rootname(identifier) or
|
211
|
+
fail("hack fail: couldn't find rootname for #{identifier.inspect}")
|
212
|
+
end
|
213
|
+
# exactly one leading and one trailing slash
|
214
|
+
def slash_strip identifier
|
215
|
+
/\A\/(.+)\/\Z/ =~ identifier and $1
|
216
|
+
end
|
217
|
+
def slash_strip_assert identifier
|
218
|
+
slash_strip(identifier) or fail("hack fail: #{identifier}")
|
219
|
+
end
|
220
|
+
def parent_identifier identifier
|
221
|
+
identifier.sub(/[^\/]+\/$/, '')
|
222
|
+
end
|
223
|
+
def site_root
|
224
|
+
@site_root ||= @items.find{|x| x.identifier == '/' }
|
225
|
+
end
|
226
|
+
def dot_dot_has? str
|
227
|
+
/\A\.\./ =~ str
|
228
|
+
end
|
229
|
+
def dot_dot_strip str
|
230
|
+
/\A\.\.(.*)\Z/ =~ str and $1
|
231
|
+
end
|
232
|
+
def dot_dot_strip_assert str
|
233
|
+
dot_dot_strip(str) or
|
234
|
+
fail("hack fail: no leading dot dot: #{str.inspect}")
|
235
|
+
end
|
236
|
+
end
|
237
|
+
include ItemMethods
|
238
|
+
end
|
239
|
+
end
|