FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
nushell.github.io/make_docs.nu at main · nushell/nushell.github.io · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
nushell
/
nushell.github.io
Public
Notifications
You must be signed in to change notification settings
Fork
560
Star
258
Code
Issues
49
Pull requests
20
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
nushell.github.io
/
make_docs.nu
Copy path
More file actions
More file actions
Latest commit
History
History
History
501 lines (436 loc) · 14.5 KB
Breadcrumbs
nushell.github.io
/
make_docs.nu
Copy path
File metadata and controls
501 lines (436 loc) · 14.5 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
def
plugin-paths
[
nu_path
?:
path
] {
const
PLUGINS
=
[
nu_plugin_inc
,
nu_plugin_gstat
,
nu_plugin_query
,
nu_plugin_polars
,
nu_plugin_formats
,
]
# If no custom path is provided, default to the
# directory of the currently running nu
let
nu_dir
=
match
$nu_path
{
null
=>
(
$nu
.current-exe
|
path dirname
)
_
=>
(
$nu_path
|
path dirname
)
}
let
plugin_paths
=
$PLUGINS
|
each
{|
plugin
|
match
(
sys host
|
get
name
) {
'
Windows
'
=>
$'
(
$nu_dir
|
path join
$plugin
).exe
'
_
=>
$'
(
$nu_dir
|
path join
$plugin
)
'
}
}
let
decorated
=
$plugin_paths
|
wrap
path
|
insert
exists
{|
x
|
$x.path
|
path exists
}
$decorated
|
where
not
exists
|
each
{|
x
|
print
$"
(
ansi red
)No plugin under path '(
$x.path
)', will be skipped...(
ansi reset
)
"
}
$decorated
|
where
exists
|
get
path
}
def
plugin-args
[
plugins
:
list
] {
$plugins
|
each
{|
plugin
| [
'
--plugins
'
$plugin
] }
|
flatten
}
# get all command names from a clean scope
def
command-names
[] {
let
plugins
=
(
plugin-paths
)
let
plugin_args
=
(
plugin-args
$plugins
)
run-external
$nu
.current-exe
'
--no-config-file
'
...
$plugin_args
'
--commands
'
'
scope commands | select name | to json
'
|
from json
}
def
html-escape
[] {
to html
|
parse
--
regex
'
<body>(?<html>.*)</body>
'
|
get
html.0
}
# remove invalid characters from a path
#
# # Examples
# using the standard library
# ```nushell
# use std.nu
#
# std assert eq ("foo/bar baz/foooo" | safe-path) "foo/bar_baz/foooo"
# std assert eq ("invalid ? path" | safe-path) "invalid__path"
# ```
def
safe-path
[] {
$in
|
str replace
--
all
'
\?
'
'
'
|
str replace
--
all
'
'
'
_
'
}
# optional helper to run make_docs in a new subshell with core plugins installed
#
# To use:
# `source make_docs`
# `make_docs` or `make_docs path_to_nu`
def
make_docs
[
nu_path
?:
path
# Path to the Nushell executable to use
] {
let
$nu_path
=
(
$nu_path
|
default
$nu
.current-exe
)
let
plugins
=
(
plugin-paths
$nu_path
)
let
plugin_args
=
(
plugin-args
$plugins
)
run-external
$nu_path
"
--no-config-file
"
...
$plugin_args
(
$env
.FILE_PWD
|
path join
'
make_docs.nu
'
)
"
generate
"
}
# generate the YAML frontmatter of a command
#
# # Examples
# - the `bits` command in `commands/docs/bits.md`
# ```yaml
# ---
# title: bits
# categories: |
# bits
# version: 0.76.1
# bits: |
# Various commands for working with bits.
# usage: |
# Various commands for working with bits.
# editLink: false # turns off the "Edit this page in GitHub for commands"
# contributors: false # turns off the contributors list since it is not accurate for commands
# ---
# ```
# - the `dfr min` command in `commands/docs/dfr_min.md`
# ```yaml
# ---
# title: dfr min
# categories: |
# expression
# lazyframe
# version: 0.76.0
# expression: |
# Creates a min expression
# lazyframe: |
# Aggregates columns to their min value
# usage: |
# Creates a min expression
# Aggregates columns to their min value
# editLink: false
# contributors: false
# ---
# ```
def
command-frontmatter
[
commands_group
,
command_name
] {
let
commands_list
=
(
$commands_group
|
get
$command_name
)
let
category_list
=
(
$commands_list
|
get
category
|
str join
$"
(
char newline
)
"
)
let
nu_version
=
(
version
)
.version
let
category_matter
=
(
$commands_list
|
get
category
|
each
{ |
category
|
let
usage
=
(
$commands_list
|
where
category
==
$category
|
get
description
|
str join
(
char newline
))
$'
(
$category
|
str snake-case
): |(
char newline
) (
$usage
)
'
}
|
str join
(
char newline
)
)
let
indented_usage
=
(
$commands_list
|
get
description
|
each
{|
elt
|
$"
(
$elt
)
"
}
|
str join
(
char newline
)
)
let
feature
=
if
$command_name
=~
'
^dfr
'
{
"
dataframe
"
}
else
{
"
default
"
}
# This is going in the frontmatter as a multiline YAML string, so indentation matters
$"
---
title: (
$command_name
)
categories: |
(
$category_list
)
version: (
$nu_version
)
(
$category_matter
)
usage: |
(
$indented_usage
)
editLink: false
contributors: false
---
"
}
# generate the whole command documentation
#
# TODO: be more detailed here
def
command-doc
[
command
] {
let
top
=
$"
# `(
$command.name
)` for [(
$command.category
)]
\(
/commands/categories/(
$command.category
).md
\)
<div class='command-title'>(
$command.description
|
html-escape
)</div>
"
let
columns
=
(
$command.signatures
|
columns
)
let
no_sig
=
(
$command
|
get
signatures
|
is-empty
)
let
sig
=
if
$no_sig
{
'
'
}
else
{
(
$command.signatures
|
get
$columns.0
|
each
{ |
param
|
if
$param.parameter_type
==
"
positional
"
{
$"
(
'
(
'
)(
$param.parameter_name
)(
'
)
'
)
"
}
else if
$param.parameter_type
==
"
rest
"
{
$"
...rest
"
}
}
|
str join
"
"
)
}
let
command_type
=
$"
## Command Type
`(
$command.type
)`
"
let
signatures
=
$"
## Signature
```> (
$command.name
) {flags} (
$sig
)```
"
let
flag_types
=
[
'
named
'
,
'
switch
'
]
let
no_flags
=
if
$no_sig
{
true
}
else
{
$command.signatures
|
get
$columns.0
|
where
parameter_type
in
$flag_types
|
is-empty
}
let
flags
=
if
$no_flags
{
'
'
}
else
{
(
$command.signatures
|
get
$columns.0
|
each
{ |
param
|
let
start
=
$'
- `--(
$param.parameter_name
)
'
let
end
=
$'
`: (
$param.description
)
'
let
short_flag
=
(
if
(
$param.short_flag
|
is-empty
) {
'
'
}
else
{
$'
, -(
$param.short_flag
)
'
})
if
$param.parameter_type
==
'
switch
'
{
$'
(
$start
)(
$short_flag
)(
$end
)
'
}
else if
$param.parameter_type
==
'
named
'
{
$'
(
$start
)(
$short_flag
) {(
$param.syntax_shape
)}(
$end
)
'
}
}
|
str join
(
char newline
))
}
let
flags
=
if
$no_flags
{
"
"
}
else
{
$"
## Flags
(
$flags
)
"
}
let
param_types
=
[
'
rest
'
,
'
positional
'
]
let
no_param
=
if
$no_sig
{
true
}
else
{
$command.signatures
|
get
$columns.0
|
where
parameter_type
in
$param_types
|
is-empty
}
let
params
=
if
$no_param
{
'
'
}
else
{
(
$command.signatures
|
get
$columns.0
|
each
{ |
param
|
if
$param.parameter_type
==
"
positional
"
{
$"
- `(
$param.parameter_name
)`: (
$param.description
)
"
}
else if
$param.parameter_type
==
"
rest
"
{
$"
- `...rest`: (
$param.description
)
"
}
}
|
str join
(
char newline
))
}
let
parameters
=
if
$no_param
{
"
"
}
else
{
$"
## Parameters
(
$params
)
"
}
let
ex
=
$command.extra_description
# Certain commands' extra_description is wrapped in code block markup to prevent their code from
# being interpreted as markdown. This is strictly hard-coded for now.
let
extra_description
=
if
$ex
==
"
"
{
"
"
}
else if
$command.name
in
[
'
def-env
'
'
export def-env
'
'
as-date
'
'
as-datetime
'
ansi
] {
$"
## Notes
```text
(
$ex
)
```
"
}
else
{
$"
## Notes
(
$ex
)
"
}
let
sigs
=
scope commands
|
where
name
==
$command.name
|
select
signatures
|
get
0
|
get
signatures
|
values
mut
input_output
=
[]
for
s
in
$sigs
{
let
input
=
$s
|
where
parameter_type
==
'
input
'
|
get
0
|
get
syntax_shape
let
output
=
$s
|
where
parameter_type
==
'
output
'
|
get
0
|
get
syntax_shape
# FIXME: Parentheses are required here to mutate $input_output, otherwise it won't work, maybe a bug?
$input_output
=
(
$input_output
|
append
[[
input
output
]; [
$input
$output
]])
}
# Input/output types: use help commands
let
input_output_table
=
(
help commands
|
where
name
==
$command.name
|
get
input_output
|
first
|
to md
--
pretty
|
str replace
-
a
'
<
'
'
<
'
|
str replace
-
a
'
>
'
'
>
'
)
let
in_out
=
if
(
$input_output_table
|
is-empty
) {
'
'
}
else
{
[
'
'
,
'
## Input/output types:
'
,
'
'
,
$input_output_table
,
'
'
]
|
str join
(
char newline
)
}
let
examples
=
if
(
$command.examples
|
length
)
>
0
{
let
example_top
=
$"
## Examples(
char newline
)(
char newline
)
"
let
$examples
=
(
$command.examples
|
each
{ |
example
|
let
result
=
(
do
-
i
{
$example.result
|
try
{
table
--
expand
}
catch
{
$in
} } )
$"
(
$example.description
)
```nu
> (
$example.example
)
(
$result
|
if
(
$result
|
describe
)
==
"
string
"
{
ansi strip
}
else
{
$in
})
```
"
}
|
str join
)
$example_top
+
$examples
}
else
{
"
"
}
# Typically a root command that has sub commands should be one word command
let
one_word_cmd
=
(
$command.name
|
split row
'
'
|
length
)
==
1
let
sub_commands
=
if
$one_word_cmd
{
scope commands
|
where
name
=~
$'
^(
$command.name
)
'
}
else
{ [] }
let
sub_commands
=
if
$one_word_cmd
and
(
$sub_commands
|
length
)
>
0
{
let
commands
=
$sub_commands
|
select
name
description
type
|
update
name
{|
row
|
$"
[`(
$row.name
)`]
\(
/commands/docs/(
$row.name
|
safe-path
).md
\)
"
}
|
upsert
description
{|
row
|
$row.description
|
str replace
-
a
'
<
'
'
\<
'
|
str replace
-
a
'
>
'
'
\>
'
}
|
to md
--
pretty
[
'
'
,
'
## Subcommands:
'
,
'
'
,
$commands
,
'
'
]
|
str join
(
char newline
)
}
else
{
'
'
}
let
plugin_commands
=
(
plugin list
|
update
commands
{
each
{|
command
|
match
$command
{
{
name
:
$name
}
=>
$name
_
=>
$command
}
} }
|
flatten
)
let
plugin_warning
=
if
(
$command.name
in
$plugin_commands.commands
) {
let
plugin
=
(
$plugin_commands
|
where
commands
==
$command.name
|
first
)
[
$"
::: warning This command requires a plugin
"
$"
The `(
$command.name
)` command resides in the `(
$plugin.name
)` plugin.
"
$"
To use this command, you must install and register `(
$plugin.filename
|
path basename
)`.
"
"
See the [Plugins]\(/book/plugins.html) chapter in the book for more information.
"
"
:::
"
"
"
"
"
]
|
to text
}
else
{
'
'
}
let
doc
=
(
(
$top
+
$plugin_warning
+
$command_type
+
$signatures
+
$flags
+
$parameters
+
$in_out
+
$examples
+
$extra_description
+
$sub_commands
)
|
lines
|
each
{|
line
| (
$line
|
str trim
-
r
) }
|
str join
(
char newline
)
)
$doc
}
# generate the full documentation page of a given command
#
# this command will
# 1. compute the frontmatter of the command, i.e. the YAML header
# 2. compute the actual content of the documentation
# 3. concatenate them
# 4. save that to `commands/docs/<command>.md`
#
# # Examples
# - the `bits` command at https://nushell.sh/commands/docs/bits.html
# - the `bits and` subcommand at https://nushell.sh/commands/docs/bits_and.html
def
generate-command
[
commands_group
command_name
] {
let
safe_name
=
(
$command_name
|
safe-path
)
let
doc_path
=
([
'
.
'
,
'
commands
'
,
'
docs
'
,
$'
(
$safe_name
).md
'
]
|
path join
)
let
frontmatter
=
(
command-frontmatter
$commands_group
$command_name
)
let
note
=
"
<!-- This file is automatically generated. Please edit the command in https://github.com/nushell/nushell instead. -->
"
let
doc
=
(
$commands_group
|
get
$command_name
|
each
{ |
command
|
command-doc
$command
}
|
str join
)
[
$frontmatter
$note
$doc
]
|
str join
"
\n
"
|
save
--
raw
--
force
$doc_path
$doc_path
}
# generate the list of all categories in a TS file used by `vuepress`
#
# this will modify `.vuepress/configs/sidebar/command_categories.ts`
#
# # Example
# the sidebar file has following format
# ```typescript
# export const commandCategories = [
# '/commands/categories/<categ_1>.md',
# '/commands/categories/<categ_2>.md',
# ...
# ];
# ```
# and contains all the categories given by `scope commands | get category | uniq`
#
# this file is responsible for the sidebar containing the categories that one can see in
#
# https://nushell.sh/commands/
def
generate-category-sidebar
[
unique_categories
] {
let
sidebar_path
=
([
'
.
'
,
'
.vuepress
'
,
'
configs
'
,
"
sidebar
"
,
"
command_categories.ts
"
]
|
path join
)
let
list_content
=
(
$unique_categories
|
each
{ ||
safe-path
}
|
each
{ |
category
|
$"
'/commands/categories/(
$category
).md',
"
}
|
str join
(
char newline
)
)
$"
export const commandCategories = [
(
$list_content
)
];
"
|
save
--
raw
--
force
$sidebar_path
}
# generate one category file in `commands/categories/`
#
# # Example
# for the `bits` category, that might look, once rendered, like
#
# https://nushell.sh/commands/categories/bits.html
def
generate-category
[
category
] {
let
safe_name
=
(
$category
|
safe-path
)
let
doc_path
=
([
'
.
'
,
'
commands
'
,
'
categories
'
,
$'
(
$safe_name
).md
'
]
|
path join
)
$"
---
editLink: false
contributors: false
---
# (
$category
|
str title-case
)
<script>
import pages from '@temp/pages'
export default {
computed: {
commands
\(\)
{
return pages
.filter
\(
p => p.path.includes
\(
'/commands/docs/'
\)\)
.filter
\(
p => p.frontmatter.categories.includes
\(
'(
$category
)'
\)\)
.sort
\(\(
a,b
\)
=>
\(
a.title > b.title
\)
? 1 :
\(\(
b.title > a.title
\)
? -1 : 0
\)\)
;
}
}
}
</script>
<table>
<thead>
<tr>
<th>Command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr v-for=
\"
command in commands
\"
>
<td><a :href=
\"
$withBase
\(
command.path
\)\"
>{{ command.title }}</a></td>
<td style=
\"
white-space: pre-wrap;
\"
>{{ command.frontmatter.usage }}</td>
</tr>
</tbody>
</table>
"
|
save
--
raw
--
force
$doc_path
$doc_path
}
# Start generation in a clean process with the bundled plugins loaded.
def
main
[] {
make_docs
}
def
"main generate"
[] {
# Old commands are currently not deleted because some of them
# are platform-specific (currently `exec`, `registry query`), and a single run of this script will not regenerate
# all of them.
#do -i { rm commands/docs/*.md }
let
commands
=
(
scope commands
|
join
(
command-names
)
name
|
sort-by
category
)
let
commands_group
=
(
$commands
|
group-by
name
)
let
unique_commands
=
(
$commands_group
|
columns
)
let
unique_categories
=
(
$commands
|
get
category
|
uniq
)
let
number_generated_commands
=
(
$unique_commands
|
par-each
{ |
command_name
|
generate-command
$commands_group
$command_name
}
|
length
)
print
$"
(
$number_generated_commands
) commands written
"
generate-category-sidebar
$unique_categories
let
number_generated_categories
=
(
$unique_categories
|
each
{ |
category
|
generate-category
$category
}
|
length
)
print
$"
(
$number_generated_categories
) categories written
"
}
Back
|
FazBrowse Home
|
New Git URL