cssgrep 1.2.0 → 1.4.0
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.
- package/CHANGELOG.md +64 -1
- package/README.md +177 -4
- package/{index.js → cli.js} +552 -153
- package/completions/_cssgrep +9 -0
- package/completions/cssgrep.bash +2 -2
- package/completions/cssgrep.fish +9 -0
- package/index.d.ts +93 -0
- package/lib.js +419 -0
- package/man/cssgrep.1 +156 -10
- package/package.json +14 -10
package/man/cssgrep.1
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.\" Man page for cssgrep. Keep the OPTIONS section in sync with the USAGE
|
|
2
|
-
.\" string in
|
|
3
|
-
.TH CSSGREP 1 "2026-07-
|
|
2
|
+
.\" string in cli.js.
|
|
3
|
+
.TH CSSGREP 1 "2026-07-07" "cssgrep 1.4.0" "User Commands"
|
|
4
4
|
.SH NAME
|
|
5
5
|
cssgrep \- search HTML by CSS selector, grep-style
|
|
6
6
|
.SH SYNOPSIS
|
|
@@ -13,6 +13,13 @@ cssgrep \- search HTML by CSS selector, grep-style
|
|
|
13
13
|
.B \-r
|
|
14
14
|
.IR dir ...
|
|
15
15
|
.br
|
|
16
|
+
.B cssgrep
|
|
17
|
+
.B \-e
|
|
18
|
+
.RI \(aq[ label =] sel \(aq
|
|
19
|
+
.RB [ \-e
|
|
20
|
+
\&...]
|
|
21
|
+
.RI [ file ...]
|
|
22
|
+
.br
|
|
16
23
|
.B cat
|
|
17
24
|
.I file.html
|
|
18
25
|
| \fBcssgrep\fR \fIselector\fR
|
|
@@ -39,17 +46,43 @@ skipped with a note on standard error, suppressible with
|
|
|
39
46
|
.B \-s
|
|
40
47
|
or
|
|
41
48
|
.BR \-q .
|
|
42
|
-
One line is printed per match.
|
|
43
49
|
As with
|
|
44
50
|
.BR grep ,
|
|
45
|
-
|
|
51
|
+
each matching line is printed on its own, once \(em however many matches sit
|
|
52
|
+
on it. With
|
|
53
|
+
.B \-n
|
|
54
|
+
there is one record per
|
|
55
|
+
.IR match ,
|
|
56
|
+
each with its own locator. A
|
|
46
57
|
.RI " file :"
|
|
47
|
-
prefix is added when searching multiple files
|
|
48
|
-
.IR line : col
|
|
49
|
-
locator appears only with
|
|
50
|
-
.BR \-n .
|
|
58
|
+
prefix is added when searching multiple files.
|
|
51
59
|
.SH OPTIONS
|
|
52
60
|
.TP
|
|
61
|
+
.BR \-e ", " \-\-selector " [\fIlabel\fR=]\fIsel\fR"
|
|
62
|
+
Add a selector (repeatable). Matches from all
|
|
63
|
+
.B \-e
|
|
64
|
+
selectors merge into one document-order stream, each tagged
|
|
65
|
+
.RI [ label ]
|
|
66
|
+
in the output (and as a
|
|
67
|
+
.I label
|
|
68
|
+
field with
|
|
69
|
+
.BR \-\-json ).
|
|
70
|
+
An unlabeled selector is tagged with its own text. A label is an identifier
|
|
71
|
+
before a
|
|
72
|
+
.BR = ;
|
|
73
|
+
a
|
|
74
|
+
.B =
|
|
75
|
+
outside brackets is never valid CSS, so attribute selectors like
|
|
76
|
+
.I [href=x]
|
|
77
|
+
are never mistaken for labels.
|
|
78
|
+
.B \-m
|
|
79
|
+
and
|
|
80
|
+
.B \-M
|
|
81
|
+
cap the merged stream, and print modes apply to every selector alike. With
|
|
82
|
+
.BR \-e ,
|
|
83
|
+
every positional argument is a file path, as with
|
|
84
|
+
.BR "grep \-e" .
|
|
85
|
+
.TP
|
|
53
86
|
.BR \-r ", " \-\-recursive
|
|
54
87
|
Recurse into directory arguments (defaults to the current directory if none
|
|
55
88
|
are given).
|
|
@@ -126,7 +159,11 @@ Print the matched node's text content, whitespace collapsed.
|
|
|
126
159
|
.TP
|
|
127
160
|
.B \-\-json
|
|
128
161
|
Print one JSON object per match (NDJSON) with
|
|
129
|
-
.IR file ", " line ", " col ", " html ", " text
|
|
162
|
+
.IR file ", " line ", " col ", " html ", " text
|
|
163
|
+
(plus
|
|
164
|
+
.I label
|
|
165
|
+
with
|
|
166
|
+
.BR \-e ).
|
|
130
167
|
.TP
|
|
131
168
|
.BI \-\-parent " n"
|
|
132
169
|
Report the
|
|
@@ -232,10 +269,94 @@ Globs for
|
|
|
232
269
|
support
|
|
233
270
|
.BR * " (within a path segment), " ** " (across " / ),
|
|
234
271
|
.BR ? " (one non-slash char), and brace alternation like " *.{html,htm} .
|
|
272
|
+
.SH WATCH MODE
|
|
273
|
+
.TP
|
|
274
|
+
.B \-\-watch
|
|
275
|
+
Keep running and repeat the search whenever a watched file changes. Requires
|
|
276
|
+
file or directory arguments (standard input cannot be watched); cannot be
|
|
277
|
+
combined with
|
|
278
|
+
.B \-q
|
|
279
|
+
or the rewrite operations. Runs until interrupted; Ctrl-C exits with
|
|
280
|
+
status 0, like
|
|
281
|
+
.BR watch (1).
|
|
282
|
+
.TP
|
|
283
|
+
.B \-\-no\-clear
|
|
284
|
+
With
|
|
285
|
+
.B \-\-watch
|
|
286
|
+
on a terminal: append run results instead of clearing the screen.
|
|
287
|
+
.PP
|
|
288
|
+
Output adapts to its destination, like
|
|
289
|
+
.BR \-\-color=auto :
|
|
290
|
+
on a terminal each run clears the screen and reprints; piped output contains
|
|
291
|
+
no escape codes and appends each run after a
|
|
292
|
+
.RI \(dq== " HH:MM:SS changed-file " ==\(dq
|
|
293
|
+
separator; with
|
|
294
|
+
.B \-\-json
|
|
295
|
+
each rerun emits an NDJSON
|
|
296
|
+
.I {"event":"run","changed":...,"matches":n}
|
|
297
|
+
record followed by the match records.
|
|
298
|
+
.PP
|
|
299
|
+
Every rerun repeats the full directory walk, so new files are discovered (and
|
|
300
|
+
deleted ones dropped) under the same
|
|
301
|
+
.BR \-\-include / \-\-ignore / \-\-ext
|
|
302
|
+
rules as a fresh invocation; change bursts are debounced. Watching uses the
|
|
303
|
+
operating system's native file events (no polling), which may be unreliable
|
|
304
|
+
on network or virtual filesystems.
|
|
305
|
+
.SH REWRITING
|
|
306
|
+
Five repeatable, freely combinable operations edit the matched elements
|
|
307
|
+
instead of reporting them:
|
|
308
|
+
.TP
|
|
309
|
+
.BI \-\-add\-class " c"
|
|
310
|
+
Add a class to each matched element (deduplicated; attribute created if
|
|
311
|
+
missing).
|
|
312
|
+
.TP
|
|
313
|
+
.BI \-\-remove\-class " c"
|
|
314
|
+
Remove a class; the attribute is dropped when emptied.
|
|
315
|
+
.TP
|
|
316
|
+
.BI \-\-set\-attr " k=v"
|
|
317
|
+
Set attribute
|
|
318
|
+
.I k
|
|
319
|
+
to
|
|
320
|
+
.IR v ,
|
|
321
|
+
adding it if missing. The value is escaped.
|
|
322
|
+
.TP
|
|
323
|
+
.BI \-\-remove\-attr " k"
|
|
324
|
+
Remove attribute
|
|
325
|
+
.I k
|
|
326
|
+
(all source occurrences).
|
|
327
|
+
.TP
|
|
328
|
+
.BI \-\-rename\-tag " t"
|
|
329
|
+
Rename the element \(em its closing tag too, when one explicitly exists
|
|
330
|
+
(voids like
|
|
331
|
+
.IR <img> ,
|
|
332
|
+
self-closing and implied closes are left without one).
|
|
333
|
+
.TP
|
|
334
|
+
.B \-\-diff
|
|
335
|
+
Emit a unified diff instead of the rewritten document. Required for multiple
|
|
336
|
+
files; apply with
|
|
337
|
+
.BR git-apply (1)
|
|
338
|
+
or
|
|
339
|
+
.BR patch (1).
|
|
340
|
+
.PP
|
|
341
|
+
Only the matched tags' bytes change: matching runs once against the original
|
|
342
|
+
document and edits are byte-splices, so quoting, entities and formatting
|
|
343
|
+
everywhere else pass through untouched. Operations compose in a fixed order
|
|
344
|
+
\(em rename \(-> remove-attr \(-> set-attr \(-> remove-class \(-> add-class
|
|
345
|
+
\(em regardless of argument order.
|
|
346
|
+
.B \-\-parent
|
|
347
|
+
composes with rewriting. A single input prints the rewritten document to
|
|
348
|
+
standard output;
|
|
349
|
+
.B cssgrep
|
|
350
|
+
never writes a file. Input that is not valid UTF-8 is refused (exit 2).
|
|
351
|
+
Rewriting cannot be combined with
|
|
352
|
+
.BR \-n ", " \-p ", " \-\-attr ", " \-\-text ", " \-\-json ", " \-c ", "
|
|
353
|
+
.BR \-l ", " \-L ", " \-q ", " \-A / \-B / \-C ", " \-m / \-M ", " \-w ", "
|
|
354
|
+
.BR \-0 " or " \-e .
|
|
355
|
+
Exit status: 0 if anything was edited, 1 if nothing matched, 2 on error.
|
|
235
356
|
.SH EXIT STATUS
|
|
236
357
|
.TP
|
|
237
358
|
.B 0
|
|
238
|
-
One or more matches were found.
|
|
359
|
+
One or more matches were found (or, when rewriting, edits were made).
|
|
239
360
|
.TP
|
|
240
361
|
.B 1
|
|
241
362
|
No matches were found.
|
|
@@ -255,6 +376,31 @@ Recurse a tree, skipping vendored files:
|
|
|
255
376
|
.TP
|
|
256
377
|
Extract attribute values for scripting:
|
|
257
378
|
.B cssgrep \-\-attr href "a.external" page.html
|
|
379
|
+
.TP
|
|
380
|
+
Scrape several labeled fields in one pass:
|
|
381
|
+
.B cssgrep \-e "title=h1" \-e "price=.card .price" \-\-json page.html
|
|
382
|
+
.TP
|
|
383
|
+
Rename every <b> to <strong> across a tree, review, then apply:
|
|
384
|
+
.B cssgrep b \-\-rename\-tag strong \-r src/ \-\-diff | git apply
|
|
385
|
+
.SH INVERTING MATCHES
|
|
386
|
+
There is no
|
|
387
|
+
.B \-v
|
|
388
|
+
flag: CSS expresses inversion in the selector itself via
|
|
389
|
+
.BR :not() " (complex selectors and selector lists included) and " :has() ,
|
|
390
|
+
scoped to the elements of interest \(em a flag would have to invent its own
|
|
391
|
+
answer to \(lqwhich non-matching elements?\(rq.
|
|
392
|
+
.TP
|
|
393
|
+
Images missing alt text:
|
|
394
|
+
.B cssgrep \(dqimg:not([alt])\(dq \-rn .
|
|
395
|
+
.TP
|
|
396
|
+
Cards containing no link:
|
|
397
|
+
.B cssgrep \(dqdiv.card:not(:has(a))\(dq page.html
|
|
398
|
+
.TP
|
|
399
|
+
Links outside nav and footer:
|
|
400
|
+
.B cssgrep \(dqa:not(nav a, footer a)\(dq page.html
|
|
401
|
+
.PP
|
|
402
|
+
For whole files without any match, use
|
|
403
|
+
.BR \-L .
|
|
258
404
|
.SH VIM INTEGRATION
|
|
259
405
|
Wire
|
|
260
406
|
.B cssgrep
|
package/package.json
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cssgrep",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Search HTML by CSS selector and print matches grep-style (file:line:col with -n).",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "lib.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
6
7
|
"bin": {
|
|
7
|
-
"cssgrep": "
|
|
8
|
+
"cssgrep": "cli.js"
|
|
8
9
|
},
|
|
9
10
|
"man": "./man/cssgrep.1",
|
|
10
11
|
"files": [
|
|
11
|
-
"
|
|
12
|
+
"lib.js",
|
|
13
|
+
"cli.js",
|
|
14
|
+
"index.d.ts",
|
|
12
15
|
"README.md",
|
|
13
16
|
"CHANGELOG.md",
|
|
14
17
|
"LICENSE",
|
|
@@ -28,13 +31,14 @@
|
|
|
28
31
|
"homepage": "https://github.com/msbatarce/cssgrep#readme",
|
|
29
32
|
"scripts": {
|
|
30
33
|
"test": "node test.js",
|
|
31
|
-
"build:linux-x64": "bun build ./
|
|
32
|
-
"build:linux-arm64": "bun build ./
|
|
33
|
-
"build:darwin-x64": "bun build ./
|
|
34
|
-
"build:darwin-arm64": "bun build ./
|
|
35
|
-
"build:windows-x64": "bun build ./
|
|
34
|
+
"build:linux-x64": "bun build ./cli.js --compile --target=bun-linux-x64 --outfile dist/cssgrep-linux-x64",
|
|
35
|
+
"build:linux-arm64": "bun build ./cli.js --compile --target=bun-linux-arm64 --outfile dist/cssgrep-linux-arm64",
|
|
36
|
+
"build:darwin-x64": "bun build ./cli.js --compile --target=bun-darwin-x64 --outfile dist/cssgrep-darwin-x64",
|
|
37
|
+
"build:darwin-arm64": "bun build ./cli.js --compile --target=bun-darwin-arm64 --outfile dist/cssgrep-darwin-arm64",
|
|
38
|
+
"build:windows-x64": "bun build ./cli.js --compile --target=bun-windows-x64 --outfile dist/cssgrep-windows-x64.exe",
|
|
36
39
|
"build:binaries": "npm run build:linux-x64 && npm run build:linux-arm64 && npm run build:darwin-x64 && npm run build:darwin-arm64 && npm run build:windows-x64",
|
|
37
|
-
"build:sea": "node scripts/build-sea.js"
|
|
40
|
+
"build:sea": "node scripts/build-sea.js",
|
|
41
|
+
"bench": "node bench/bench.js"
|
|
38
42
|
},
|
|
39
43
|
"keywords": [
|
|
40
44
|
"css",
|