File: help.jq

package info (click to toggle)
fq 0.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 106,624 kB
  • sloc: xml: 2,835; makefile: 250; sh: 241; exp: 57; ansic: 21
file content (263 lines) | stat: -rw-r--r-- 7,277 bytes parent folder | download
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
include "internal";
include "interp";
include "query";
include "eval";
include "repl";
include "decode";
include "funcs";
include "options";
include "args";

# TODO: variants, values, keywords?
# TODO: store some other way?
def _help_functions:
  { length:
      { summary: "Length of string, array, object, etc"
      , doc:
"- For string number of unicode codepoints
- For array number of elements in array
- For object number of key-value pairs
- For null zero
- For number the number itself
- For boolean is an error
"
      , examples:
          [ [[1,2,3], "length"]
          , ["abc", "length"]
          , [{a: 1, b: 2}, "length"]
          , [null, "length"]
          , [123, "length"]
          , [true, "length"]
          ]
      }
  , "..":
      { summary: "Recursive descent of ."
      , doc:
"Recursively descend . and output each value.
Same as recurse without argument.
"
      , examples:
          [ ["a", ".."]
          , [[1,2,3], ".."]
          , [{a: 1, b: {c: 3}}, ".."]
          ]
      }
  , empty:
      { summary: "Output nothing"
      , doc:
"Output no value, not even null, and cause backtrack.
"
      , examples:
          [ ["empty"]
          , ["[1,empty,2]"]
          ]
      }
  };

def help($_): error("help must be alone or last in pipeline. ex: help(length) or ... | help");
def help: help(null);

def _help_format_enrich($arg0; $f; $include_basic):
  ( if $include_basic then
      .examples +=
        [ {comment: "Decode file as \($f.name)", shell: "fq -d \($f.name) . file"}
        , {comment: "Decode value as \($f.name)", expr: "\($f.name)"}
        ]
    end
  | if $f.decode_in_arg then
      .examples +=
        [ { comment: "Decode file using \($f.name) options"
          , shell: "\($arg0) -d \($f.name)\($f.decode_in_arg | to_entries | map(" -o ", .key, "=", (.value | tojson)) | join("")) . file"
          }
        , { comment: "Decode value as \($f.name)"
          , expr: "\($f.name)(\($f.decode_in_arg | to_jq))"
          }
        ]
    end
  );

def _help($arg0; $topic):
  ( $topic
  | if  . == "usage" then
      "Usage: \($arg0) [OPTIONS] [--] [EXPR] [FILE...]"
    elif . == "example_usage" then
      ( "Example usages:"
      , "  fq . file"
      , "  fq d file"
      , "  fq -V '.path[1].value' file"
      , "  fq tovalue file"
      , "  fq -r to_toml file.yml"
      , "  fq -s -d html 'map(.html.head.title?)' *.html"
      , "  cat file.cbor | fq -d cbor torepr"
      , "  fq 'grep(\"^main$\") | parent' /bin/ls"
      , "  fq -i"
      )
    elif . == "banner" then
      ( "fq - jq for binary formats"
      , "Tool, language and decoders for working with binary data."
      , "For more information see https://github.com/wader/fq"
      )
    elif . == "args" then
      args_help_text(_opt_cli_opts)
    elif . == "options" then
      ( [ ( options
          | _opt_cli_arg_from_options
          )
        | to_entries[]
        | [(.key+"  "), .value | tostring]
        ]
      | table(
          .;
          map(
            ( . as $rc
            # right pad format name to align description
            | if .column == 0 then .string | rpad(" "; $rc.maxwidth)
              else $rc.string
              end
            )
          ) | join("")
        )
      )
    elif . == "formats" then
      ( [ formats
        | to_entries[]
        | [(.key+"  "), .value.description]
        ]
      | table(
          .;
          map(
            ( . as $rc
            # right pad format name to align description
            | if .column == 0 then .string | rpad(" "; $rc.maxwidth)
              else $rc.string
              end
            )
          ) | join("")
        )
      )
    elif _registry.formats | has($topic) then
      ( _registry.formats[$topic] as $f
      | (_format_func($f.name; "_help")? // {} | _help_format_enrich($arg0; $f; true)) as $fhelp
      | ((_registry.files[][] | select(.name=="\($topic).md").data) // false) as $doc
      | "\($f.name): \($f.description) decoder"
      , ""
      , if $f.decode_in_arg then
          ( $f.decode_in_arg
          | to_entries
          | map(["  \(.key)=\(.value | tojson)  ", $f.decode_in_arg_doc[.key]])
          | "Options"
          , "======="
          , ""
          , table(
              .;
              map(
                ( . as $rc
                # right pad format name to align description
                | if .column == 0 then .string | rpad(" "; $rc.maxwidth)
                  else $rc.string
                  end
                )
              ) | join("")
            )
          , ""
          )
        else empty
        end
      , "Decode examples"
      , "==============="
      , ""
      , ( $fhelp.examples[]
        | "  # \(.comment)"
        , if .shell then "  $ \(.shell)"
          elif .expr then "  ... | \(.expr)"
          else empty
          end
        )
      , ""
      , if $doc then $doc | markdown | _markdown_to_text(options.width; -2)
        else empty
        end
      )
    elif _help_functions | has($topic) then
      ( _help_functions[$topic] as $hf
      | "\($topic): \($hf.summary)"
      , $hf.doc
      , if $hf.examples then
          ( "Examples:"
          , ( $hf.examples[]
            | . as $e
            | if length == 1 then
                ( "> \($e[0])"
                , (null | try (_eval($e[0]; {}) | tojson) catch "error: \(.)")
                )
              else
                ( "> \($e[0] | tojson) | \($e[1])"
                , ($e[0] | try (_eval($e[1]; {}) | tojson) catch "error: \(.)")
                )
              end
            )
          )
        end
      )
    else
      # help(unknown)
      # TODO: check builtin
      ( ( . # TODO: extract
        | builtins
        | map(split("/") | {key: .[0], value: true})
        | from_entries
        ) as $builtins
      | ( . # TODO: extract
        | scope
        | map({key: ., value: true})
        | from_entries
        ) as $scope
      | if $builtins | has($topic) then
          "\($topic) is builtin function"
        elif $scope | has($topic) then
          "\($topic) is a function or variable"
        else
          "don't know what \($topic) is "
        end
      | println
      )
    end
  );

# TODO: refactor
 def _help_slurp($query):
  def _name:
    if _query_is_func then _query_func_name
    elif _query_is_string then _query_string_str
    else _query_tostring
    end;
  if $query.orig | _query_is_func then
    ( ($query.orig | _query_func_args) as $args
    | ($args | length) as $argc
    | if $args == null then
        # help
        ( "Type expression to evaluate"
        , "help(...)   Help for topic. Ex: help(mp4), help(\"mp4\")"
        , "\\t          Completion"
        , "Up/Down     History"
        , "... | repl  Start a new REPL"
        , "^C          Interrupt execution"
        , "^D          Exit REPL"
        ) | println
      elif $argc == 1 then
        ( _help("fq"; $args[0] | _name)
        | println
        )
      else
        _eval_error("compile"; "help must be last in pipeline. ex: help(length) or ... | help")
      end
    )
  else
    # ... | help
    # TODO: check builtin
    ( _repl_slurp_eval($query.rewrite) as $outputs
    | "value help"
    , $outputs
    | display
    )
  end;