Skip to content

Commit 472d8ae

Browse files
committed
feat: skipComments
1 parent 8f385ef commit 472d8ae

14 files changed

Lines changed: 132 additions & 29 deletions

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,13 @@ Default: `,`
209209

210210
Specifies a single-character string to use as the column separator for each row.
211211

212+
##### skipComments
213+
214+
Type: `Boolean | String`<br>
215+
Default: `false`
216+
217+
Instructs the parser to ignore lines which represent comments in a CSV file. Since there is no specification that dictates what a CSV comment looks like, comments should be considered non-standard. The "most common" character used to signify a comment in a CSV file is `"#"`. If this option is set to `true`, lines which begin with `#` will be skipped. If a custom character is needed to denote a commented line, this option may be set to a string which represents the leading character(s) signifying a comment line.
218+
212219
##### skipLines
213220

214221
Type: `Number`<br>
@@ -275,6 +282,7 @@ Usage: csv-parser [filename?] [options]
275282
--quote,-q Set the quote character ('"' by default)
276283
--remove Remove columns from output by header name
277284
--separator,-s Set the separator character ("," by default)
285+
--skipComments,-c Skip CSV comments that begin with '#'. Set a value to change the comment character.
278286
--skipLines,-l Set the number of lines to skip to before parsing headers
279287
--strict Require column length match headers length
280288
--version,-v Print out the installed version

bin/csv-parser

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const pkg = require('../package.json')
88

99
const argv = minimist(process.argv, {
1010
alias: {
11+
c: 'skipComments',
1112
e: 'escape',
1213
h: 'headers',
1314
o: 'output',
@@ -40,6 +41,7 @@ if (argv.help || (process.stdin.isTTY && !filename)) {
4041
--quote,-q Set the quote character ('"' by default)
4142
--remove Remove headers from output
4243
--separator,-s Set the separator character ("," by default)
44+
--skipComments,-c Skip CSV comments that begin with '#'. Set a value to change the comment character.
4345
--skipLines,-l Set the number of lines to skip to before parsing headers
4446
--strict Require column length match headers length
4547
--version,-v Print out the installed version
@@ -52,6 +54,7 @@ const output = (argv.output && argv.output !== '-') ? fs.createWriteStream(argv.
5254
const options = {
5355
separator: argv.separator,
5456
strict: argv.strict,
57+
skipComments: argv.skipComments,
5558
skipLines: argv.skipLines
5659
}
5760

index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ declare module 'csv-parser' {
1111
quote?: string;
1212
raw?: boolean;
1313
separator?: string;
14+
skipComments?: number | string;
1415
skipLines?: number;
1516
maxRowBytes?: number;
1617
strict?: boolean;

index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const defaults = {
1515
quote: '"',
1616
raw: false,
1717
separator: ',',
18+
skipComments: false,
1819
skipLines: null,
1920
maxRowBytes: Number.MAX_SAFE_INTEGER,
2021
strict: false
@@ -143,6 +144,14 @@ class CsvParser extends Transform {
143144
return this.mapValues({ header, index, value })
144145
}
145146

147+
const { skipComments } = this
148+
if (skipComments) {
149+
const char = typeof skipComments === 'string' ? skipComments : '#'
150+
if (buf[0] === bufferFrom(char)) {
151+
return
152+
}
153+
}
154+
146155
for (let i = start; i < end; i++) {
147156
const isStartingQuote = !isQuoted && buf[i] === this.quote
148157
const isEndingQuote = isQuoted && buf[i] === this.quote && i + 1 <= end && buf[i + 1] === comma

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"commitmsg": "commitlint -e $GIT_PARAMS",
2929
"lint": "eslint .",
3030
"lint-staged": "lint-staged",
31-
"test": "ava test/test.js"
31+
"test": "ava"
3232
},
3333
"dependencies": {
3434
"buffer-alloc": "^1.1.0",

test/comment.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const test = require('ava')
2+
3+
const { collect } = require('./helpers/helper')
4+
5+
test.cb('comment', (t) => {
6+
const verify = (err, lines) => {
7+
t.false(err, 'no err')
8+
t.snapshot(lines)
9+
t.is(lines.length, 2, '2 rowa')
10+
t.end()
11+
}
12+
13+
collect('comment.csv', { skipComments: true }, verify)
14+
})
15+
16+
test.cb('custom comment', (t) => {
17+
const verify = (err, lines) => {
18+
t.false(err, 'no err')
19+
t.snapshot(lines)
20+
t.is(lines.length, 2, '2 rows')
21+
t.end()
22+
}
23+
24+
collect('custom-comment.csv', { skipComments: '~' }, verify)
25+
})

test/data/comment.csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# comment
2+
a,b,c
3+
1,2,3

test/data/custom-comment.csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
~ comment
2+
a,b,c
3+
1,2,3

test/helpers/helper.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const fs = require('fs')
2+
const path = require('path')
3+
4+
const csv = require('../..')
5+
6+
const read = fs.createReadStream
7+
8+
// helpers
9+
function fixture (name) {
10+
return path.join(__dirname, '../data', name)
11+
}
12+
13+
function collect (file, opts, cb) {
14+
if (typeof opts === 'function') return collect(file, null, opts)
15+
const data = read(fixture(file))
16+
const lines = []
17+
const parser = csv(opts)
18+
data
19+
.pipe(parser)
20+
.on('data', (line) => {
21+
lines.push(line)
22+
})
23+
.on('error', (err) => {
24+
cb(err, lines)
25+
})
26+
.on('end', () => {
27+
// eslint-disable-next-line standard/no-callback-literal
28+
cb(false, lines)
29+
})
30+
return parser
31+
}
32+
33+
module.exports = { collect, fixture }

test/snapshots/comment.test.js.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Snapshot report for `test/comment.test.js`
2+
3+
The actual snapshot is saved in `comment.test.js.snap`.
4+
5+
Generated by [AVA](https://ava.li).
6+
7+
## comment
8+
9+
> Snapshot 1
10+
11+
[
12+
Row {
13+
'# comment': 'a',
14+
},
15+
Row {
16+
'# comment': '1',
17+
},
18+
]
19+
20+
## custom comment
21+
22+
> Snapshot 1
23+
24+
[
25+
Row {
26+
'~ comment': 'a',
27+
},
28+
Row {
29+
'~ comment': '1',
30+
},
31+
]

0 commit comments

Comments
 (0)