cssgrep 1.4.0 → 1.5.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 CHANGED
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.5.0] - 2026-07-12
11
+
12
+ ### Added
13
+ - `--json` records now include `attribs`, the matched element's attribute
14
+ object (names lowercased by the parser) — the same field the library's
15
+ `Match` exposes, so scraping pipelines get attribute data without a second
16
+ pass (e.g. `jq -r .attribs.href`).
17
+
10
18
  ## [1.4.0] - 2026-07-07
11
19
 
12
20
  ### Fixed
@@ -125,7 +133,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
125
133
  - `-0`/`--null`, `--color`, `-w`/`--max-width`, `-V`/`--version`.
126
134
  - Standalone binaries (Bun, Node SEA), shell completions, and a man page.
127
135
 
128
- [Unreleased]: https://github.com/msbatarce/cssgrep/compare/v1.4.0...HEAD
136
+ [Unreleased]: https://github.com/msbatarce/cssgrep/compare/v1.5.0...HEAD
137
+ [1.5.0]: https://github.com/msbatarce/cssgrep/compare/v1.4.0...v1.5.0
129
138
  [1.4.0]: https://github.com/msbatarce/cssgrep/compare/v1.3.0...v1.4.0
130
139
  [1.3.0]: https://github.com/msbatarce/cssgrep/compare/v1.2.0...v1.3.0
131
140
  [1.2.0]: https://github.com/msbatarce/cssgrep/compare/v1.1.0...v1.2.0
package/README.md CHANGED
@@ -90,7 +90,7 @@ own `line:col` locator (that per-match precision is the point of the tool). A
90
90
  | `-p`, `--print` | Pretty-print the matched node's HTML, re-indented from scratch (works on minified input). No `line:col` locator is shown. |
91
91
  | `--attr <name>` | Print the value of attribute `<name>` for each match (nodes without it are skipped; if every match is skipped the exit status is 1). The name is matched case-insensitively. Honors `-n` and `-w`. |
92
92
  | `--text` | Print the matched node's text content, whitespace collapsed. Honors `-n` and `-w`. |
93
- | `--json` | Print one JSON object per match (NDJSON), with `file`, `line`, `col`, `html`, `text` — plus `label` when `-e` is used. |
93
+ | `--json` | Print one JSON object per match (NDJSON), with `file`, `line`, `col`, `attribs` (the element's attributes, names lowercased), `html`, `text` — plus `label` when `-e` is used. |
94
94
  | `--parent <n>` | Report the `n`-th element ancestor of each match instead of the match itself (de-duplicated). Pairs well with `-p`. |
95
95
  | `-w`, `--max-width <n>` | Truncate the shown line to `n` columns (adds `…`). Value attaches or follows: `-w100`, `-w 100`, `--max-width=100`. |
96
96
  | `-A`, `--after-context <n>` | Print `n` source lines after each match. |
@@ -187,8 +187,8 @@ $ cssgrep -n -e 'title=h1' -e 'price=.card .price' page.html
187
187
  9:12 [price] <span class="price">$4.99</span>
188
188
 
189
189
  $ cssgrep --json -e 'title=h1' -e 'price=.card .price' page.html
190
- {"file":"page.html","line":3,"col":5,"label":"title","html":"<h1>Widget</h1>","text":"Widget"}
191
- {"file":"page.html","line":9,"col":12,"label":"price","html":"...","text":"$4.99"}
190
+ {"file":"page.html","line":3,"col":5,"label":"title","attribs":{},"html":"<h1>Widget</h1>","text":"Widget"}
191
+ {"file":"page.html","line":9,"col":12,"label":"price","attribs":{"class":"price"},"html":"...","text":"$4.99"}
192
192
  ```
193
193
 
194
194
  The label is anything matching `[A-Za-z_][A-Za-z0-9_-]*` before a `=`; since a
package/cli.js CHANGED
@@ -23,7 +23,7 @@ function loadPrettyPrinter() {
23
23
  // package.json, so it survives compilation into a standalone binary (Bun
24
24
  // --compile / Node SEA), where package.json won't sit next to the executable.
25
25
  // Keep in sync with package.json on release.
26
- const VERSION = '1.4.0';
26
+ const VERSION = '1.5.0';
27
27
 
28
28
  const USAGE = `cssgrep - search HTML by CSS selector, grep-style.
29
29
 
@@ -58,7 +58,7 @@ Options:
58
58
  --attr <name> Print the value of attribute <name> (skips nodes without it).
59
59
  --text Print the matched node's text content (whitespace collapsed).
60
60
  --json Print one JSON record per match (NDJSON: file,line,col,
61
- html,text; plus label with -e).
61
+ attribs,html,text; plus label with -e).
62
62
  --parent <n> Report the n-th ancestor of each match instead (dedup'd).
63
63
  -w, --max-width <n> Truncate the shown line to <n> columns (ellipsis added).
64
64
  -A, --after-context <n> Print <n> source lines after each match.
@@ -668,10 +668,11 @@ function searchSource(src, name, showLabel, opts, out, limit = Infinity) {
668
668
  // matches lacking the attribute, and --parent dedup can merge several
669
669
  // matches into one printed ancestor.
670
670
  if (opts.json) {
671
- // NDJSON: one self-contained record per match. `html` is the exact source
672
- // slice; newlines are escaped by JSON.stringify, so each record stays on
673
- // one line. Ignores --color and -n (line/col are always present). `label`
674
- // appears only with -e.
671
+ // NDJSON: one self-contained record per match. `attribs` mirrors the lib
672
+ // Match's field (names lowercased by the parser) so scraping never needs
673
+ // a second pass; `html` is the exact source slice; newlines are escaped
674
+ // by JSON.stringify, so each record stays on one line. Ignores --color
675
+ // and -n (line/col are always present). `label` appears only with -e.
675
676
  const posState = {};
676
677
  for (const { el, label: selLabel } of targets) {
677
678
  const off = el.startIndex == null ? 0 : el.startIndex;
@@ -682,6 +683,7 @@ function searchSource(src, name, showLabel, opts, out, limit = Infinity) {
682
683
  line: pos.line,
683
684
  col: pos.bcol,
684
685
  ...(selLabel !== null && { label: selLabel }),
686
+ attribs: el.attribs || {},
685
687
  html: src.slice(off, nodeEnd),
686
688
  text: collapseWs(textOf(el)),
687
689
  }));
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
2
  .\" string in cli.js.
3
- .TH CSSGREP 1 "2026-07-07" "cssgrep 1.4.0" "User Commands"
3
+ .TH CSSGREP 1 "2026-07-12" "cssgrep 1.5.0" "User Commands"
4
4
  .SH NAME
5
5
  cssgrep \- search HTML by CSS selector, grep-style
6
6
  .SH SYNOPSIS
@@ -159,11 +159,13 @@ Print the matched node's text content, whitespace collapsed.
159
159
  .TP
160
160
  .B \-\-json
161
161
  Print one JSON object per match (NDJSON) with
162
- .IR file ", " line ", " col ", " html ", " text
162
+ .IR file ", " line ", " col ", " attribs ", " html ", " text
163
163
  (plus
164
164
  .I label
165
165
  with
166
166
  .BR \-e ).
167
+ .I attribs
168
+ is the element's attribute object, names lowercased by the parser.
167
169
  .TP
168
170
  .BI \-\-parent " n"
169
171
  Report the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cssgrep",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Search HTML by CSS selector and print matches grep-style (file:line:col with -n).",
5
5
  "main": "lib.js",
6
6
  "types": "index.d.ts",