|
@@ -4,6 +4,7 @@
|
4
|
4
|
. "$(sfpath)" || exit 3
|
5
|
5
|
|
6
|
6
|
shellfu import pretty
|
|
7
|
+shellfu import sfdoc
|
7
|
8
|
|
8
|
9
|
|
9
|
10
|
usage() {
|
|
@@ -39,487 +40,6 @@ usage() {
|
39
|
40
|
"in man(1) pager."
|
40
|
41
|
}
|
41
|
42
|
|
42
|
|
-export_as_manpage() {
|
43
|
|
- #
|
44
|
|
- # Export module doc as manpage
|
45
|
|
- #
|
46
|
|
- local module=$1
|
47
|
|
- local mfile
|
48
|
|
- mfile=$(select_mfile "$module") || return 3
|
49
|
|
- mver="v$(shellfu _read_directive "module-version" "$mfile" 2>/dev/null)"
|
50
|
|
- test "$mver" == "v" && mver="(no version)"
|
51
|
|
- export_as_pod "$module" \
|
52
|
|
- | pod2man \
|
53
|
|
- --name "${RealModuleName:-${module^^}}" \
|
54
|
|
- --center "User Contributed Shellfu Documentation" \
|
55
|
|
- --section 3x \
|
56
|
|
- --date "$(date -I -r "$mfile")" \
|
57
|
|
- --release "$module $mver" \
|
58
|
|
- --utf8 -q \`
|
59
|
|
-}
|
60
|
|
-
|
61
|
|
-export_as_markdown() {
|
62
|
|
- #
|
63
|
|
- # Export module doc as Markdown
|
64
|
|
- #
|
65
|
|
- local module=$1
|
66
|
|
- local module_name=${RealModuleName:-$module}
|
67
|
|
- local variable
|
68
|
|
- local function
|
69
|
|
- local vheader_done=false
|
70
|
|
- local fheader_done=false
|
71
|
|
- debug -v module
|
72
|
|
- echo "$module_name"
|
73
|
|
- echo "$module_name" | tr -c '\n' '[=*]'
|
74
|
|
- echo
|
75
|
|
- get_doc "$module" | md_escapes
|
76
|
|
- echo
|
77
|
|
- for variable in $(sf_list v "$module" | cut -d. -f2);
|
78
|
|
- do
|
79
|
|
- debug -v variable
|
80
|
|
- $vheader_done || {
|
81
|
|
- echo
|
82
|
|
- echo Variables
|
83
|
|
- echo ---------
|
84
|
|
- vheader_done=true
|
85
|
|
- }
|
86
|
|
- echo
|
87
|
|
- echo "### \`\$$variable\` ###"
|
88
|
|
- echo ""
|
89
|
|
- get_doc "$module" "v:$variable" | md_escapes
|
90
|
|
- echo
|
91
|
|
- done
|
92
|
|
- for function in $(sf_list f "$module" | cut -d. -f2);
|
93
|
|
- do
|
94
|
|
- debug -v function
|
95
|
|
- $fheader_done || {
|
96
|
|
- echo
|
97
|
|
- echo Functions
|
98
|
|
- echo ---------
|
99
|
|
- fheader_done=true
|
100
|
|
- }
|
101
|
|
- echo
|
102
|
|
- echo "### \`$function()\` ###"
|
103
|
|
- echo ""
|
104
|
|
- get_doc "$module" "f:$function" | md_escapes
|
105
|
|
- echo
|
106
|
|
- done
|
107
|
|
-}
|
108
|
|
-
|
109
|
|
-export_as_pod() {
|
110
|
|
- #
|
111
|
|
- # Export module doc as POD
|
112
|
|
- #
|
113
|
|
- local module=$1
|
114
|
|
- local variable
|
115
|
|
- local function
|
116
|
|
- local vheader_done=false
|
117
|
|
- local fheader_done=false
|
118
|
|
- local indented=false
|
119
|
|
- debug -v module
|
120
|
|
- echo "true <<'=cut'"
|
121
|
|
- echo "=pod"
|
122
|
|
- echo
|
123
|
|
- echo "=head1 NAME"
|
124
|
|
- echo
|
125
|
|
- echo "${RealModuleName:-$module} - $(get_doc "$module" | head -1)"
|
126
|
|
- echo
|
127
|
|
- echo "=head1 DESCRIPTION"
|
128
|
|
- echo
|
129
|
|
- get_doc "$module"
|
130
|
|
- echo
|
131
|
|
- for variable in $(sf_list v "$module" | cut -d. -f2);
|
132
|
|
- do
|
133
|
|
- debug -v variable
|
134
|
|
- $vheader_done || {
|
135
|
|
- echo
|
136
|
|
- echo "=head1 VARIABLES"
|
137
|
|
- vheader_done=true
|
138
|
|
- echo
|
139
|
|
- echo "=over 8"
|
140
|
|
- echo
|
141
|
|
- indented=true
|
142
|
|
- }
|
143
|
|
- echo
|
144
|
|
- echo "=item I<\$$variable>"
|
145
|
|
- echo
|
146
|
|
- get_doc "$module" "v:$variable"
|
147
|
|
- echo
|
148
|
|
- done
|
149
|
|
- $indented && {
|
150
|
|
- echo "=back"
|
151
|
|
- echo
|
152
|
|
- }
|
153
|
|
- for function in $(sf_list f "$module" | cut -d. -f2);
|
154
|
|
- do
|
155
|
|
- debug -v function
|
156
|
|
- $fheader_done || {
|
157
|
|
- echo
|
158
|
|
- echo "=head1 FUNCTIONS"
|
159
|
|
- fheader_done=true
|
160
|
|
- echo
|
161
|
|
- echo "=over 8"
|
162
|
|
- echo
|
163
|
|
- indented=true
|
164
|
|
- }
|
165
|
|
- echo
|
166
|
|
- echo "=item I<$function()>"
|
167
|
|
- echo
|
168
|
|
- get_doc "$module" "f:$function"
|
169
|
|
- echo
|
170
|
|
- done
|
171
|
|
- $indented && {
|
172
|
|
- echo "=back"
|
173
|
|
- echo
|
174
|
|
- }
|
175
|
|
- echo "=encoding $Encoding"
|
176
|
|
- echo "=cut"
|
177
|
|
-}
|
178
|
|
-
|
179
|
|
-filter_body() {
|
180
|
|
- #
|
181
|
|
- # Filter part $1 of body on stdin
|
182
|
|
- #
|
183
|
|
- local part=$1
|
184
|
|
- case "$part" in
|
185
|
|
- f:*) filter_fun "${part:2}" ;;
|
186
|
|
- v:*) filter_var "${part:2}" ;;
|
187
|
|
- *) warn "bug: invalid part specification $part" ;;
|
188
|
|
- esac
|
189
|
|
-}
|
190
|
|
-
|
191
|
|
-filter_doc() {
|
192
|
|
- #
|
193
|
|
- # Filter docstring for part $1 from object body on stdin
|
194
|
|
- #
|
195
|
|
- local part=$1
|
196
|
|
- case $part in
|
197
|
|
- "") filter_mdoc ;;
|
198
|
|
- v:*) filter_vdoc ;;
|
199
|
|
- f:*) filter_fdoc ;;
|
200
|
|
- *) warn "bug: invalid part specification: $part" ;;
|
201
|
|
- esac
|
202
|
|
-}
|
203
|
|
-
|
204
|
|
-filter_fun() {
|
205
|
|
- #
|
206
|
|
- # From module body on stdin, filter out function named $1
|
207
|
|
- #
|
208
|
|
- # Function definition should look like:
|
209
|
|
- #
|
210
|
|
- # foo_fun() {
|
211
|
|
- # foo=$1
|
212
|
|
- # }
|
213
|
|
- #
|
214
|
|
- # That is,
|
215
|
|
- #
|
216
|
|
- # * no `function` keyword,
|
217
|
|
- # * name starts the first line,
|
218
|
|
- # * name is followed by '() {' with no additional spaces,
|
219
|
|
- # * function end is denoted by line with a single '}'.
|
220
|
|
- #
|
221
|
|
- local fn_name=$1
|
222
|
|
- name=$fn_name perl -we '
|
223
|
|
- undef $/;
|
224
|
|
- my $name = $ENV{name};
|
225
|
|
- my ($fbody) = <> =~ m/^($name\(\) \{.*?^\}$)/ms;
|
226
|
|
- print "$fbody\n" if defined $fbody;
|
227
|
|
- '
|
228
|
|
-}
|
229
|
|
-
|
230
|
|
-filter_fdoc() {
|
231
|
|
- #
|
232
|
|
- # Filter docstring from function body on stdin
|
233
|
|
- #
|
234
|
|
- # Look for:
|
235
|
|
- #
|
236
|
|
- # 1. line "^ #$" to open docstring - this must be
|
237
|
|
- # the first one after function name (`fun() {`)
|
238
|
|
- # 2. block of consecutive docstring lines (i.e. matching
|
239
|
|
- # "^ # " or "^ #$"
|
240
|
|
- # 3. last "^ #$" line to close docstring.
|
241
|
|
- # 4. Next line must not match any of the patterns above.
|
242
|
|
- #
|
243
|
|
- # For example, stdin like this:
|
244
|
|
- #
|
245
|
|
- # myfun() {
|
246
|
|
- # #
|
247
|
|
- # # Do my thing with foo $1
|
248
|
|
- # #
|
249
|
|
- # # Detailed description, possibly spanning
|
250
|
|
- # # several paragraph.
|
251
|
|
- # #
|
252
|
|
- # # The format here should be Markdown.
|
253
|
|
- # #
|
254
|
|
- # local foo=$1
|
255
|
|
- # printf %p "${foo:4}"
|
256
|
|
- # }
|
257
|
|
- #
|
258
|
|
- # would be read as:
|
259
|
|
- #
|
260
|
|
- # Do my thing with foo $1
|
261
|
|
- #
|
262
|
|
- # Detailed description, possibly spanning
|
263
|
|
- # several paragraph.
|
264
|
|
- #
|
265
|
|
- # The format here should be Markdown.
|
266
|
|
- #
|
267
|
|
- # However if we added following line right before the `local`
|
268
|
|
- # declaration
|
269
|
|
- #
|
270
|
|
- # #FIXME: TODO/FIXME lines are not dropped properly
|
271
|
|
- #
|
272
|
|
- # it **will not** be considered part of the docstring. This is
|
273
|
|
- # to allow for special comments tools like TODO/FIXME or
|
274
|
|
- # data for lint-like tools that are not part of function
|
275
|
|
- # description.
|
276
|
|
- #
|
277
|
|
- perl -we '
|
278
|
|
- my $isdoc;
|
279
|
|
- while (<>) {
|
280
|
|
- if (m/^ #$/) {
|
281
|
|
- $isdoc = 1;
|
282
|
|
- } elsif (m/^ [^#]/) {
|
283
|
|
- exit;
|
284
|
|
- }
|
285
|
|
- next unless $isdoc;
|
286
|
|
- s/^ //;
|
287
|
|
- print;
|
288
|
|
- }' | strip_doc
|
289
|
|
-}
|
290
|
|
-
|
291
|
|
-filter_mdoc() {
|
292
|
|
- #
|
293
|
|
- # From module body on stdin, filter module doc
|
294
|
|
- #
|
295
|
|
- # Example:
|
296
|
|
- #
|
297
|
|
- # #!/bin/bash
|
298
|
|
- # #
|
299
|
|
- # # legal stuff
|
300
|
|
- #
|
301
|
|
- # shellfu import irrelevant_stuff
|
302
|
|
- #
|
303
|
|
- # #
|
304
|
|
- # # Module is cool this
|
305
|
|
- # #
|
306
|
|
- # # Ok so this is my
|
307
|
|
- # # "module", heh...
|
308
|
|
- # #
|
309
|
|
- #
|
310
|
|
- perl -we '
|
311
|
|
- sub ok_chunk {
|
312
|
|
- my $chunk = shift;
|
313
|
|
- my @lines = split "\n", $_;
|
314
|
|
- chomp @lines;
|
315
|
|
- return 0 unless (defined $lines[0] and $lines[0] eq "#");
|
316
|
|
- return 0 unless $lines[$#lines] eq "#";
|
317
|
|
- foreach (@lines) {
|
318
|
|
- return 0 unless (m/^#$/ or m/^# /);
|
319
|
|
- }
|
320
|
|
- return 1
|
321
|
|
- }
|
322
|
|
- my @chunks;
|
323
|
|
- my @lines;
|
324
|
|
- $/ = "\n\n";
|
325
|
|
- @chunks = <STDIN>;
|
326
|
|
- foreach (@chunks) {
|
327
|
|
- if (ok_chunk "$_") {
|
328
|
|
- s/\n+$//;
|
329
|
|
- print "$_\n";
|
330
|
|
- exit 0;
|
331
|
|
- }
|
332
|
|
- }
|
333
|
|
- exit 1
|
334
|
|
- ' | strip_doc
|
335
|
|
-}
|
336
|
|
-
|
337
|
|
-filter_var() {
|
338
|
|
- #
|
339
|
|
- # From module body on stdin, filter variable definition named $1
|
340
|
|
- #
|
341
|
|
- # Look for:
|
342
|
|
- #
|
343
|
|
- # 1. Empty line, followed by line with single hash sign
|
344
|
|
- # 2. Set of consecutive docstring lines (start with '# ')
|
345
|
|
- # 3. Another "#" followed by one or more variable definitions (start
|
346
|
|
- # with $name or \w+, followed by equal sign), at least one of which
|
347
|
|
- # must be $1
|
348
|
|
- # 4. Empty line or EOF
|
349
|
|
- #
|
350
|
|
- # and return what is found.
|
351
|
|
- #
|
352
|
|
- # For example:
|
353
|
|
- #
|
354
|
|
- # #
|
355
|
|
- # # My variable
|
356
|
|
- # #
|
357
|
|
- # my_var=foo
|
358
|
|
- #
|
359
|
|
- # is found if $1 is 'my_var'
|
360
|
|
- #
|
361
|
|
- # A more advanced example:
|
362
|
|
- #
|
363
|
|
- # #
|
364
|
|
- # # Bar variables
|
365
|
|
- # #
|
366
|
|
- # # These serve similar purpose; the difference is
|
367
|
|
- # # obvious
|
368
|
|
- # #
|
369
|
|
- # bar_1=one
|
370
|
|
- # bar_2=two
|
371
|
|
- # bar_3=three
|
372
|
|
- #
|
373
|
|
- # is found if $1 is either 'bar_1', 'bar_2' or 'bar_3'. This allows
|
374
|
|
- # for a docstring being shared among closely related variables.
|
375
|
|
- #
|
376
|
|
- local oname=$1 # object name
|
377
|
|
- local state # void, edge, dstr, vstr, junk
|
378
|
|
- local o_end # object ended; is complete
|
379
|
|
- local cache # buffer of hope
|
380
|
|
- # parse and keep each var docstring in cache;
|
381
|
|
- # then decide whether or not print the cache
|
382
|
|
- cache=$(mktemp -t shellfu_doc.filter_var.XXXXXXXX)
|
383
|
|
- state=junk
|
384
|
|
- o_end=false
|
385
|
|
- while read -r line;
|
386
|
|
- do
|
387
|
|
- case $state:$line in
|
388
|
|
- # looks like void
|
389
|
|
- void:) state=void; o_end=false ;;
|
390
|
|
- edge:) state=void; o_end=true ;;
|
391
|
|
- dstr:) state=void; o_end=true ;;
|
392
|
|
- vstr:) state=void; o_end=true ;;
|
393
|
|
- junk:) state=void; o_end=false ;;
|
394
|
|
- # looks like edge
|
395
|
|
- void:"#") state=edge; o_end=false ;;
|
396
|
|
- edge:"#") state=dstr; o_end=false ;;
|
397
|
|
- dstr:"#") state=dstr; o_end=false ;;
|
398
|
|
- vstr:"#") state=dstr; o_end=false ;;
|
399
|
|
- junk:"#") state=junk; o_end=false ;;
|
400
|
|
- # looks like docstring
|
401
|
|
- void:"# "*) state=junk; o_end=false ;;
|
402
|
|
- edge:"# "*) state=dstr; o_end=false ;;
|
403
|
|
- dstr:"# "*) state=dstr; o_end=false ;;
|
404
|
|
- vstr:"# "*) state=dstr; o_end=false ;;
|
405
|
|
- junk:"# "*) state=junk; o_end=false ;;
|
406
|
|
- # looks like junk
|
407
|
|
- void:"#"*) state=junk; o_end=false ;;
|
408
|
|
- edge:"#"*) state=junk; o_end=false ;;
|
409
|
|
- dstr:"#"*) state=junk; o_end=false ;;
|
410
|
|
- vstr:"#"*) state=junk; o_end=false ;;
|
411
|
|
- junk:"#"*) state=junk; o_end=false ;;
|
412
|
|
- # looks like variable string
|
413
|
|
- void:*=*) state=vstr; o_end=false ;;
|
414
|
|
- edge:*=*) state=junk; o_end=false ;;
|
415
|
|
- dstr:*=*) state=vstr; o_end=false ;;
|
416
|
|
- vstr:*=*) state=vstr; o_end=false ;;
|
417
|
|
- junk:*=*) state=junk; o_end=false ;;
|
418
|
|
- # looks like something else
|
419
|
|
- *) state=junk; o_end=false ;;
|
420
|
|
- esac
|
421
|
|
- case $state in
|
422
|
|
- edge|dstr|vstr) echo "$line" >> "$cache" ;;
|
423
|
|
- esac
|
424
|
|
- if $o_end;
|
425
|
|
- then
|
426
|
|
- if grep -q "^$oname=" "$cache"; # it's our wanted object
|
427
|
|
- then
|
428
|
|
- cat "$cache"
|
429
|
|
- rm "$cache"
|
430
|
|
- return 0
|
431
|
|
- fi
|
432
|
|
- rm "$cache"
|
433
|
|
- fi
|
434
|
|
- done
|
435
|
|
- rm "$cache"
|
436
|
|
- return 1
|
437
|
|
-}
|
438
|
|
-
|
439
|
|
-filter_vdoc() {
|
440
|
|
- #
|
441
|
|
- # From variable definition body on stdin, filter doc
|
442
|
|
- #
|
443
|
|
- # Example:
|
444
|
|
- #
|
445
|
|
- # #
|
446
|
|
- # # Bar variables
|
447
|
|
- # #
|
448
|
|
- # # These serve similar purpose; the difference is
|
449
|
|
- # # obvious
|
450
|
|
- # #
|
451
|
|
- # bar_1=one
|
452
|
|
- # bar_2=two
|
453
|
|
- # bar_3=three
|
454
|
|
- #
|
455
|
|
- grep '^#' | strip_doc
|
456
|
|
-}
|
457
|
|
-
|
458
|
|
-get_doc() {
|
459
|
|
- #
|
460
|
|
- # Show doc for part $2 of module $1
|
461
|
|
- #
|
462
|
|
- local module=$1
|
463
|
|
- local part=$2
|
464
|
|
- get_part "$module" "$part" | filter_doc "$part"
|
465
|
|
-}
|
466
|
|
-
|
467
|
|
-get_part() {
|
468
|
|
- #
|
469
|
|
- # Print part $2 (f|v:name) of module $1
|
470
|
|
- #
|
471
|
|
- # Part has format
|
472
|
|
- #
|
473
|
|
- # TYPE:NAME
|
474
|
|
- #
|
475
|
|
- # where TYPE is 'v' for variables and f for functions, and
|
476
|
|
- # NAME is name of the part.
|
477
|
|
- #
|
478
|
|
- # If part is not specified, whole module file is printed.
|
479
|
|
- #
|
480
|
|
- local module=$1
|
481
|
|
- local part=$2
|
482
|
|
- local mfile
|
483
|
|
- mfile=$(select_mfile "$module") || return 3
|
484
|
|
- test -n "$mfile" || return 1
|
485
|
|
- test -n "$part" || { cat "$mfile"; return $?; }
|
486
|
|
- <"$mfile" filter_body "$part"
|
487
|
|
-}
|
488
|
|
-
|
489
|
|
-md_escapes() {
|
490
|
|
- #
|
491
|
|
- # Do additional escapes for Markdown
|
492
|
|
- #
|
493
|
|
- # In docstrings, references to variables are often done
|
494
|
|
- # without backticks; add these to prevent interpreting
|
495
|
|
- # underscores in variable names as cursive.
|
496
|
|
- #
|
497
|
|
- perl -ne '
|
498
|
|
- my @bigwords = ();
|
499
|
|
- my @newwords = ();
|
500
|
|
- if (m|^ |) {
|
501
|
|
- print; # probably code -- leave be
|
502
|
|
- } else {
|
503
|
|
- @bigwords = split " ";
|
504
|
|
- foreach (@bigwords) {
|
505
|
|
- if (m|`\w+\(\)`|) {
|
506
|
|
- push @newwords, $_; # function: escaped
|
507
|
|
- } elsif (m|(.*)\b(\w+)\(\)(.*)|) {
|
508
|
|
- push @newwords, "$1`$2()`$3"; # function: needs escape
|
509
|
|
- } elsif (m|`\$\w+`|) {
|
510
|
|
- push @newwords, $_; # variable: escaped
|
511
|
|
- } elsif (m|(.*)\$(\w+)(.*)|) {
|
512
|
|
- push @newwords, "$1`\$$2`$3"; # variable: needs escape
|
513
|
|
- } else {
|
514
|
|
- push @newwords, $_; # a normal word
|
515
|
|
- }
|
516
|
|
- }
|
517
|
|
- print join " ", @newwords;
|
518
|
|
- print "\n";
|
519
|
|
- }
|
520
|
|
- '
|
521
|
|
-}
|
522
|
|
-
|
523
|
43
|
select_mfile() {
|
524
|
44
|
#
|
525
|
45
|
# Find and/or verify file that holds module $1
|
|
@@ -530,143 +50,80 @@ select_mfile() {
|
530
|
50
|
*/*) mfile="$module" ;;
|
531
|
51
|
*) mfile=$(shellfu _select_mfile "$module") ;;
|
532
|
52
|
esac
|
|
53
|
+ debug -v mfile
|
533
|
54
|
test -n "$mfile" || { warn "no such module found: $module"; return 3; }
|
534
|
55
|
test -f "$mfile" || { warn "no such file found: $mfile"; return 3; }
|
535
|
56
|
echo "$mfile"
|
536
|
57
|
}
|
537
|
58
|
|
538
|
|
-sf_list() {
|
539
|
|
- #
|
540
|
|
- # List all objects of type $1 in module $2
|
541
|
|
- #
|
542
|
|
- local otype=$1
|
543
|
|
- local module=$2
|
544
|
|
- local mfile
|
545
|
|
- mfile=$(select_mfile "$module") || return 3
|
546
|
|
- case $otype in
|
547
|
|
- f)
|
548
|
|
- grep -HE '^[[:alnum:]_]+\(\) \{' "$mfile" \
|
549
|
|
- | sed -e 's|(.*||; s|\.sh:|.|; s|^.*/||'
|
550
|
|
- ;;
|
551
|
|
- v)
|
552
|
|
- grep -HE '^[[:alnum:]_]+=' "$mfile" \
|
553
|
|
- | sed -e 's|=.*||; s|\.sh:|.|; s|^.*/||'
|
554
|
|
- ;;
|
555
|
|
- *)
|
556
|
|
- warn "bug: invalid object type: $otype"
|
557
|
|
- ;;
|
558
|
|
- esac \
|
559
|
|
- | sf_flt_hidden
|
560
|
|
-}
|
561
|
|
-
|
562
|
|
-sf_list_modules() {
|
563
|
|
- #
|
564
|
|
- # List all module files
|
565
|
|
- #
|
566
|
|
- shellfu _list_mfiles \
|
567
|
|
- | sed 's|\.sh$||; s|.*/||;' \
|
568
|
|
- | sf_flt_hidden
|
569
|
|
-}
|
570
|
|
-
|
571
|
|
-sf_flt_hidden() {
|
572
|
|
- $ShowHidden && cat && return
|
573
|
|
- grep -v ^_ | grep -v \\._
|
574
|
|
-}
|
575
|
|
-
|
576
|
|
-strip_doc() {
|
577
|
|
- #
|
578
|
|
- # Strip doc out of Shellfu docstring
|
579
|
|
- #
|
580
|
|
- # From e.g.
|
581
|
|
- #
|
582
|
|
- # #
|
583
|
|
- # # foo
|
584
|
|
- # #
|
585
|
|
- # # bar
|
586
|
|
- # # baz
|
587
|
|
- # #
|
588
|
|
- #
|
589
|
|
- # where first and last line are mandatory and each line
|
590
|
|
- # must be either '#' or '# *', get:
|
591
|
|
- #
|
592
|
|
- # foo
|
593
|
|
- #
|
594
|
|
- # bar
|
595
|
|
- # baz
|
596
|
|
- #
|
597
|
|
- # just as when you're parsing this text by eyes.
|
598
|
|
- #
|
599
|
|
- head -n -1 \
|
600
|
|
- | tail -n +2 \
|
601
|
|
- | sed -e 's/^#$//; s/^# //;'
|
602
|
|
-}
|
603
|
|
-
|
604
|
59
|
main() {
|
605
|
|
- local ShowHidden # show hidden objects?
|
606
|
60
|
local action # what to do
|
607
|
61
|
local format # export format
|
608
|
62
|
local module # module name or path/to/module.sh
|
609
|
63
|
local m # module helper var
|
610
|
64
|
local RealModuleName # name to override eg. if accessing via filename
|
611
|
|
- local Encoding # encoding
|
612
|
|
- ShowHidden=false
|
|
65
|
+ local encoding # encoding
|
|
66
|
+ local mpath # path to module file
|
613
|
67
|
action=man
|
614
|
68
|
format=markdown
|
615
|
|
- Encoding=utf8
|
|
69
|
+ encoding=utf8
|
616
|
70
|
#shellcheck disable=SC2034
|
617
|
71
|
while true; do case "$1" in
|
618
|
72
|
-d|--debug) PRETTY_DEBUG=true; shift ;;
|
619
|
|
- -a|--all) ShowHidden=true; shift ;;
|
|
73
|
+ -a|--all) SFDOC_SHOW_HIDDEN=true; shift ;;
|
620
|
74
|
-I|--include) SHELLFU_PATH="$2:$SHELLFU_PATH"; shift 2 || usage ;;
|
621
|
75
|
-l|--ls) action=lsx; shift; break ;;
|
622
|
76
|
-L|--lsmod) action=lsm; shift; break ;;
|
623
|
77
|
--lsvar) action=lsv; shift; break ;;
|
624
|
78
|
--lsfun) action=lsf; shift; break ;;
|
625
|
79
|
-e|--export) action=exp; format="$2"; shift 2 || usage; break ;;
|
626
|
|
- --encoding) Encoding="$2"; shift 2 || usage ;;
|
|
80
|
+ --encoding) encoding="$2"; shift 2 || usage ;;
|
627
|
81
|
--name) RealModuleName="$2"; shift 2 || usage ;;
|
628
|
82
|
-*) usage ;;
|
629
|
83
|
*) break ;;
|
630
|
84
|
esac done
|
631
|
85
|
module="$1"; shift
|
632
|
|
- debug -v SHELLFU_INCLUDE SHELLFU_PATH
|
633
|
|
- debug -v action ShowHidden format module RealModuleName
|
|
86
|
+ debug -v SHELLFU_INCLUDE SHELLFU_PATH SFDOC_SHOW_HIDDEN
|
|
87
|
+ debug -v action format module RealModuleName
|
634
|
88
|
case $action:$module in
|
635
|
89
|
lsx:*|lsm:*) true ;;
|
636
|
90
|
*:) usage ;;
|
637
|
91
|
esac
|
|
92
|
+ case $action in
|
|
93
|
+ lsm) : ;;
|
|
94
|
+ *) mpath=$(select_mfile "$module") || die ;;
|
|
95
|
+ esac
|
638
|
96
|
case $action in
|
639
|
97
|
exp) # --export
|
640
|
98
|
grep -qw "$format" <<<manpage,markdown,pod \
|
641
|
99
|
|| die "unknown format: $format"
|
642
|
|
- "export_as_$format" "$module"
|
|
100
|
+ sfdoc__export "$format" "${RealModuleName:-$module}" "$mpath"
|
643
|
101
|
;;
|
644
|
102
|
lsm) # --lsmod
|
645
|
|
- sf_list_modules | sort
|
|
103
|
+ sfdoc__ls_m | sort
|
646
|
104
|
;;
|
647
|
105
|
lsv) # --lsvar MODULE
|
648
|
|
- sf_list v "$module" | sort
|
|
106
|
+ sfdoc__ls v "$mpath" | sort
|
649
|
107
|
;;
|
650
|
108
|
lsf) # --lsfun MODULE
|
651
|
|
- sf_list f "$module" | sort
|
|
109
|
+ sfdoc__ls f "$mpath" | sort
|
652
|
110
|
;;
|
653
|
111
|
lsx) # --ls [MODULE]
|
654
|
112
|
case $module in
|
655
|
|
- "") sf_list_modules ;;
|
656
|
|
- *) echo "$module" ;;
|
|
113
|
+ "") shellfu _list_mfiles ;;
|
|
114
|
+ *) echo "$mpath" ;;
|
657
|
115
|
esac \
|
658
|
116
|
| while read -r m;
|
659
|
117
|
do
|
660
|
|
- sf_list v "$m"
|
661
|
|
- sf_list f "$m"
|
|
118
|
+ sfdoc__ls v "$m"
|
|
119
|
+ sfdoc__ls f "$m"
|
662
|
120
|
done \
|
663
|
121
|
| sort
|
664
|
122
|
;;
|
665
|
123
|
man)
|
666
|
124
|
which pod2man &>/dev/null \
|
667
|
125
|
|| die "pod2man is missing cannot use man page mode"
|
668
|
|
- select_mfile "$module" >/dev/null || return 3
|
669
|
|
- export_as_manpage "$module" \
|
|
126
|
+ sfdoc__export manpage "${RealModuleName:-$module}" "$mpath" \
|
670
|
127
|
| man -l -
|
671
|
128
|
;;
|
672
|
129
|
esac
|