diff --git a/packages/basics/src/bib-parse.js b/packages/basics/src/bib-parse.js new file mode 100644 index 00000000..8f539749 --- /dev/null +++ b/packages/basics/src/bib-parse.js @@ -0,0 +1,53 @@ +import { StringDecoder } from 'string_decoder'; +import BibtexParser from 'bib2json'; + +function BIBParse(data, feed) { + if (!this.decoder) { + this.decoder = new StringDecoder('utf8'); + this.remainder = ''; + this.counter = 0; + this.parser = new BibtexParser((entry) => { + feed.write(entry); + }); + } + if (this.isLast()) { + this.remainder += this.decoder.end(); + if (this.remainder && this.counter > 1) { + this.parser.parse(this.remainder); + } + return feed.close(); + } + let chunk; + if (Buffer.isBuffer(data)) { + chunk = this.decoder.write(data); + } else if (typeof data === 'string') { + chunk = data; + } else { + chunk = ''; + } + this.parser.parse(chunk); + this.counter += 1; + feed.end(); +} + +/** + * Take a `String` and split it at bibtext entry. + * + * Input: + * + * ```json + * ["@article{my_article,\ntitle = {Hello world},\n", "journal = \"Some Journal\"\n"] + * ``` + * + * Output: + * + * ```json + * ["a", "b", "c", "d"] + * ``` + * + * @name BIBParse + * @returns {Object} + */ +export default { + BIBParse, +}; diff --git a/packages/basics/test/bib-parse.js b/packages/basics/test/bib-parse.js new file mode 100644 index 00000000..dc418054 --- /dev/null +++ b/packages/basics/test/bib-parse.js @@ -0,0 +1,75 @@ +import from from 'from'; +import ezs from '../../core/src'; +import ezsBasics from '../src'; + +ezs.use(ezsBasics); + +describe('BIBParse', () => { + it('should return a entry #1', (done) => { + from(['@article{my_article,\ntitle = {Hello world},\n', 'journal = "Some Journal"\n}']) + .pipe(ezs('BIBParse')) + .on('error', (err) => done(err)) + .on('data', (data) => { + expect(typeof data).toBe('object'); + expect(data.ObjectType).toBe('entry'); + }) + .on('end', () => { + done(); + }); + }); + it('should return a entry #2', (done) => { + from(['@article{my_article,\ntitle = {Hello world},\njournal = "Some Journal"\n}']) + .pipe(ezs('BIBParse')) + .on('error', (err) => done(err)) + .on('data', (data) => { + expect(typeof data).toBe('object'); + expect(data.ObjectType).toBe('entry'); + }) + .on('end', () => { + done(); + }); + }); + it('should return a entry #3', (done) => { + from(['@article{my_article,\ntitle = {Hello world},\n', 1, 'journal = "Some Journal"\n}']) + .pipe(ezs('BIBParse')) + .on('error', (err) => done(err)) + .on('data', (data) => { + expect(typeof data).toBe('object'); + expect(data.ObjectType).toBe('entry'); + }) + .on('end', () => { + done(); + }); + }); + it('should return a entry #3', (done) => { + from([ + Buffer.from('@article{my_article,\ntitle = {Hello world},\n'), + Buffer.from('journal = "Some'), + Buffer.from([0xE2]), + Buffer.from([0x82]), + Buffer.from([0xAC]), + Buffer.from('Journal"\n}'), + Buffer.from([0xC2]), + ]) + .pipe(ezs('BIBParse')) + .on('error', (err) => done(err)) + .on('data', (data) => { + expect(typeof data).toBe('object'); + expect(data.ObjectType).toBe('entry'); + }) + .on('end', () => { + done(); + }); + }); + + it('should return no entry', (done) => { + from(['@my_article,\ntitle = {Hello world},\n', 'journal = ']) + .pipe(ezs('BIBParse')) + .on('error', (err) => done(err)) + .on('data', () => done(new Error('no way'))) + .on('end', () => { + done(); + }); + }); + +});