nandoc 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|