Repository: typeiii/jquery-csv Branch: main Commit: 555d41d2c256 Files: 116 Total size: 156.6 KB Directory structure: gitextract_i9qi28kc/ ├── .github/ │ ├── ISSUE_TEMPLATE.md │ ├── ISSUE_TEMPLATES/ │ │ ├── DISC_TEMPLATE.md │ │ ├── FEAT_TEMPLATE.md │ │ └── SPEC_TEMPLATE.md │ ├── PULL_REQUEST_TEMPLATE.md │ └── workflows/ │ ├── latest.yml │ ├── npm.yml │ ├── pr.yml │ ├── release.yml │ └── verify.yml ├── .gitignore ├── .npmignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs/ │ ├── algorithm.md │ ├── api.md │ └── hooks-callbacks.md ├── examples/ │ ├── _template.html │ ├── custom-date-parsing.html │ ├── data/ │ │ ├── analytics1.csv │ │ ├── analytics2.csv │ │ ├── sample.csv │ │ ├── sample2.csv │ │ └── sine.csv │ ├── demo.css │ ├── file-handling.html │ ├── flot.html │ ├── from-arrays.html │ ├── from-objects.html │ ├── google-visualization.html │ ├── helpers.js │ ├── snippets/ │ │ ├── esm-usage.js │ │ └── node-usage.js │ ├── to-array.html │ ├── to-arrays.html │ └── to-objects.html ├── package.json ├── src/ │ └── jquery.csv.js └── test/ ├── csv.from_array.js ├── csv.from_arrays.js ├── csv.from_objects.js ├── csv.on_parse_entry_hook.js ├── csv.on_parse_value_hook.js ├── csv.on_post_parse_hook.js ├── csv.on_pre_parse_hook.js ├── csv.parsers.js ├── csv.to_array.js ├── csv.to_arrays.js ├── csv.to_objects.js ├── edge_cases.js ├── fixtures/ │ ├── array.csv │ ├── array.json │ ├── arrays1.csv │ ├── arrays1.json │ ├── arrays2.csv │ ├── arrays2.json │ ├── backslash.csv │ ├── backslash.json │ ├── defaults.csv │ ├── defaults.json │ ├── defaults_fivelines.csv │ ├── delimiter.csv │ ├── delimiter.json │ ├── delimiter_fivelines.csv │ ├── entry_arrays.csv │ ├── entry_arrays.json │ ├── entry_objects.csv │ ├── entry_objects.json │ ├── fixtures.js │ ├── newline_dos.csv │ ├── newline_mac.csv │ ├── newline_unix.csv │ ├── objects.csv │ ├── objects.json │ ├── objects2.csv │ ├── regex.csv │ ├── regex.json │ ├── regex2.csv │ ├── regex2.json │ ├── regex3.csv │ ├── regex3.json │ ├── rfc1.csv │ ├── rfc1.json │ ├── rfc2.csv │ ├── rfc2.json │ ├── rfc3.csv │ ├── rfc3.json │ ├── rfc4.csv │ ├── rfc4.json │ ├── rfc5.csv │ ├── rfc5.json │ ├── rfc6.csv │ ├── rfc6.json │ ├── rfc7.csv │ ├── rfc7.json │ ├── rfcA1.csv │ ├── rfcA1.json │ ├── rfcA2.csv │ ├── rfcA2.json │ ├── rfcA3.csv │ ├── rfcA3.json │ ├── separator.csv │ ├── separator.json │ ├── separator_fivelines.csv │ ├── term_arrays.csv │ ├── term_arrays.json │ ├── term_objects.csv │ ├── term_objects.json │ ├── value_arrays.csv │ ├── value_arrays.json │ ├── value_objects.csv │ └── value_objects.json ├── options.js ├── rfc_amendments.js └── rfc_compliance.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ Is this a bug? If not consider asking on [StackOverflow][StackOverflow]. Does the documentation require improvement? Consider posting a [Feature][Feature] with the the recommended changes. # Subject of the issue Provide a brief description of your issue. ## Environment - Platform: Node | Browser - Version: Chrome 50 - Usage: Load from file | Load from Ajax | Hooks ## Steps to reproduce - step1 - step2 - step3 ## Expected behaviour Tell us what should happen ## Actual behaviour Tell us what happens instead ## References - [name](href) [Feature]: https://github.com/evanplaice/jquery-csv/issues/new?template=FEAT_TEMPLATE.md&labels=feature [StackOverflow]: https://stackoverflow.com/questions/tagged/jquery-csv?mixed=1 ================================================ FILE: .github/ISSUE_TEMPLATES/DISC_TEMPLATE.md ================================================ # Topic ## What Does this Impact? Write a brief description of how this discussion applies to jquery-csv. ## Notes Optionally, compile notes from the discussion here. ## References - [link](href) ================================================ FILE: .github/ISSUE_TEMPLATES/FEAT_TEMPLATE.md ================================================ # the name of the feature A brief description of what the feature aims to accomplish ## Goals - goal - goal ## Checklist - [ ] Is this tested? - [ ] Is documentation up-to-date? ## Details ## References - [name](href) [Specification]: https://github.com/evanplaice/jquery-csv/issues/new?template=SPEC_TEMPLATE.md&labels=specification ================================================ FILE: .github/ISSUE_TEMPLATES/SPEC_TEMPLATE.md ================================================ # the name of the specification A brief description of the specification ## Goals - goal - goal ## Milestones - [ ] milestone - [ ] milestone ## Details Add code snippets and/or a more in-depth description of the implementation details ## References - [name](href) ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ If this PR applies to an existing spec, link to it and delete the rest. ## Checklist - [ ] Is this API breaking? - [ ] Is this tested? - [ ] Is Documentation required? *Note: Don't worry about leaving these unchecked. These exist to quickly identify common requirements.* ## Description Post a brief description of the changes. ## References - [name](href) ================================================ FILE: .github/workflows/latest.yml ================================================ name: Latest on: push: branches: - main paths-ignore: - package.json - package-lock.json jobs: ci: uses: evanplaice/jquery-csv/.github/workflows/verify.yml@main ================================================ FILE: .github/workflows/npm.yml ================================================ name: NPM Release on: workflow_call: jobs: npm: runs-on: ubuntu-latest permissions: contents: read id-token: write steps: - name: Checkout uses: actions/checkout@v4 - name: Setup uses: actions/setup-node@v4 with: registry-url: "https://registry.npmjs.org" cache: npm - run: npm ci - name: Publish run: npm publish --provenance --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} ================================================ FILE: .github/workflows/pr.yml ================================================ name: Pull Request on: [pull_request] jobs: ci: uses: evanplaice/jquery-csv/.github/workflows/verify.yml@main ================================================ FILE: .github/workflows/release.yml ================================================ name: Release on: push: tags: - v* jobs: ci: uses: evanplaice/jquery-csv/.github/workflows/verify.yml@main cd: needs: ci uses: evanplaice/jquery-csv/.github/workflows/npm.yml@main secrets: inherit ================================================ FILE: .github/workflows/verify.yml ================================================ name: Verify on: workflow_call: jobs: verify: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' - name: Install run: npm ci - name: Lint run: npm run lint - name: Test run: npm t # - name: Types # run: npm run types ================================================ FILE: .gitignore ================================================ node_modules package/ .DS_Store *.tgz ================================================ FILE: .npmignore ================================================ .github/ docs/ examples/ package/ test/ .git/ *.tgz .travis.yml CONTRIBUTING.md ================================================ FILE: CONTRIBUTING.md ================================================ # How You Can Help ## Non-code contributions - If you'd like to edit/update the documentation, submit a Pull Request - If you'd like to start a dialog, post a new [Discussion][Discussion] - If you'd like to assist other users of jquery-csv, answer qustions on [StackOverflow][StackOverflow] - If you'd like to promote this project, write articles or blog posts and link back to the project ## Code Contributions - If you'd like to add a new example or test, submit a [Specification][Specification] - If you'd like to propose a new feature, submit a [Feature][Feature] request **DO** - Follow the [Forking Workflow][Forking Workflow] 1. Fork the project 2. Clone your fork 3. Add a remote pointing to the origin repo 3. Create a new `feature` branch 4. Checkout the `feature` branch 5. Commit your changes 6. Rebase your changes onto the latest w/ `git pull --rebase` 7. Post a PR comparing `origin/master` to the `fork/feature` - Provide tests where applicable - Provide documentation updates that apply to the changes - Follow the current style of the project **Don't** - Group multiple features into a single PR - Co-mingle whitespace changes with code changes - Make superficial changes (ie style/structure) to existing code - Make API breaking changes unless they're clearly documented in a Specification [Discussion]: https://github.com/evanplaice/jquery-csv/issues/new?template=DISC_TEMPLATE.md&labels=discussion [StackOverflow]: https://stackoverflow.com/questions/tagged/jquery-csv?mixed=1 [Feature]: https://github.com/evanplaice/jquery-csv/issues/new?template=FEAT_TEMPLATE.md&labels=feature [Specification]: https://github.com/evanplaice/jquery-csv/issues/new?template=SPEC_TEMPLATE.md&labels=specification [Forking Workflow]: https://www.atlassian.com/git/tutorials/comparing-workflows/forking-workflow ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2012 Evan Plaice Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

✓ NOTICE: For a more modern CSV parser, check out the @VanillaES/CSV project ✓

GitHub Releases NPM Release Bundlephobia Latest Status Release Status
# Introduction jQuery-csv is an artifact of a simpler time (ie 2012) when the JS library ecosystem was still very underdeveloped. This was the first and still is one of the fastest spec compliant CSV parsers available. This is a complete, customizable, battle tested, performance optimized CSV parser that follows the traditional jQuery-style of syntax. Featuring a slim Chomsky - Type III parser implementation. Full (that means 100%) [IETF RFC 4180](http://tools.ietf.org/html/rfc4180) compliance. Including coverage for a few edge cases that even the spec fails to cover. Enough with the wind-up... # Features * Convert a CSV String to an array * Convert a multi-line CSV string to a 2D array * Convert a multi-line CSV string to an array of objects (ie header:value pairs) * Convert an array of values to CSV (under development) * Convert an array of objects to CSV (under development) * Hooks/Callbacks to extend the default parsing process * Customizable delimiter (default: ") and separator (default: ,) characters * Node.js support (ie CommonJS importing and async callback support) # Syntax ## Importing **Client-Side** (ie browser) - import via the script element. ```javascript ``` **Server-Side** (ie Node.js) - Import via the standard CommonJS approach. Install the package via NPM ```bash npm i jquery-csv ``` Then import it as a CommonJS module. ```javascript var csv = require('jquery-csv'); ``` ## Usage Each one of the methods can be called with the following form: ```javascript $.csv.function(csv, {options}, callback); ``` | Name | | Description | |-----------|-----------|:------------| | csv | required | The csv data to be transformed. | | options | optional | An object containing user-defined overrides for the default options. | | callback | optional | Used for Node.js-style async callbacks. Uses the form function(err, data). | ## Methods **toArray** Parse a single entry string to an array ```javascript $.csv.toArray(csv); ``` *Documented under API#$.csv.toArray().* **toArrays** Parse a multi-line CSV string to a 2D array ```javascript $.csv.toArrays(csv); ``` *Documented under API#$.csv.toArrays().* **toObjects** Parse a multi-line CSV string to an array of objects ```javascript $.csv.toObjects(csv); ``` *Documented under API#$.csv.toObjects().* **fromArrays** Convert array data to a CSV string ```javascript $.csv.fromArrays(arrays); ``` **fromObjects** Convert an array of objects to a CSV string ```javascript $.csv.fromObjects(objects); ``` # Documentation - [API](./docs/api.md) - [Hooks & Callbacks](./docs/hooks-callbacks.md) - [Algorithm](./docs/algorithm.md) # Use Cases Instead of the typical useless contrived example code, I have provided a handful of simple yet powerful demos. Not only are they fun to play with but a quick peak at the source will show you how simple and easy they were to implement. Feel free to copy and reuse these in your own projects. ## Basic Usage Want to play with the parser and maybe validate your CSV data without all the frills? No need to download the source first, there's a demo for that... [jQuery-CSV - toArray()](http://evanplaice.github.io/jquery-csv/examples/to-array.html) [jQuery-CSV - toArrays()](http://evanplaice.github.io/jquery-csv/examples/to-arrays.html) [jQuery-CSV - fromArrays()](http://evanplaice.github.io/jquery-csv/examples/from-arrays.html) [jQuery-CSV - toObjects()](http://evanplaice.github.io/jquery-csv/examples/to-objects.html) [jQuery-CSV - fromObjects()](http://evanplaice.github.io/jquery-csv/examples/from-objects.html) ## Node.js ESM (EcmaScript Module) Import Here's how to import jQuery-CSV as am ECMAScript module Node.js: [jQuery-CSV - ESM Import Demonstration](http://evanplaice.github.io/jquery-csv/examples/snippets/esm-usage.js) ## Node.js CJS (CommonJS Module) Import Here's how to import jQuery-CSV as CommonJS module Node.js: [jQuery-CSV - CJS Import Demonstration](http://evanplaice.github.io/jquery-csv/examples/snippets/node-usage.js) ## Client-Side File Handling Yes, you read that right. It's now possible to open local files in the browser without firing a single request to the server. The functionality is still pretty new so not all browsers support it (I'm looking @ you IE). If that's not an issue I highly suggest you try it. It's much easier than the traditional client/server approach. [jQuery-CSV - File Handling Demonstration](http://evanplaice.github.io/jquery-csv/examples/file-handling.html) ## jQuery-CSV + Flot Hands down, the most exciting addition to the demo collection so far... You can input the data set using either the text area provided or via uploading CSV data files. Want to plot 5 data sets on the same grid, no problem; Just upload 5 files containing one dataset each. The jQuery-CSV will handle the plumbing while Flot will make it all look pretty. [jQuery-CSV - Flot Demonstration](http://evanplaice.github.io/jquery-csv/examples/flot.html) ## jQuery-CSV + Google Visualization API OK, I lied. This one is even cooler than Flot. Hike up your fancy pants because these things look slick. Don't want to draw a line graph, no problem you can tap into the massive collection of different graph types available. Embedded is a fully configurable dashboard. Warning: You may experience multiple spontaneous 'oh my got that's soo awesome' fits of excitement. Maybe even get stoked. Happens to the best us... [jQuery-CSV - Google Visualization API Demonstration](http://evanplaice.github.io/jquery-csv/examples/google-visualization.html) **jQuery-CSV** coding style is inherited from the [JQuery Core Style Guidelines](https://contribute.jquery.org/style-guide/) ================================================ FILE: docs/algorithm.md ================================================ ## Algorithm Below is the algorithm used to parse a single-line of raw CSV. ![jquery-csv state diagram](algorithms_csv-parser.png) *States:* - (a) initial - (b) delimited - (c) capture delimited - (d) capture undelimited *Transitions:* - (0) return value - (1) opening delimiter - (2) closing delimiter - (3) undelimited data *Source:* ```javascript splitLines: function(csv, delimiter) { var state = 0; var value = ""; var line = ""; var lines = []; function endOfRow() { lines.push(value); value = ""; state = 0; }; csv.replace(/(\"|,|\n|\r|[^\",\r\n]+)/gm, function (m0){ switch (state) { // the start of a value/entry case 0: if (m0 === "\"") { state = 1; } else if (m0 === "\n") { endOfRow(); } else if (/^\r$/.test(m0)) { // carriage returns are ignored } else { value += m0; state = 3; } break; // delimited input case 1: if (m0 === "\"") { state = 2; } else { value += m0; state = 1; } break; // delimiter found in delimited input case 2: // is the delimiter escaped? if (m0 === "\"" && value.substr(value.length - 1) === "\"") { value += m0; state = 1; } else if (m0 === ",") { value += m0; state = 0; } else if (m0 === "\n") { endOfRow(); } else if (m0 === "\r") { // Ignore } else { throw new Error("Illegal state"); } break; // un-delimited input case 3: if (m0 === ",") { value += m0; state = 0; } else if (m0 === "\"") { throw new Error("Unquoted delimiter found"); } else if (m0 === "\n") { endOfRow(); } else if (m0 === "\r") { // Ignore } else { throw new Error("Illegal data"); } break; default: throw new Error("Unknown state"); } return ""; }); if (state != 0) { endOfRow(); } return lines; } ``` ================================================ FILE: docs/api.md ================================================ ## Introduction The following will cover the core utilities provided by `jquery-csv`. The project's home page outlines the most general use cases but this library is capable of much more. If you're interested in learning some of the more advanced capabilities of this library, then you're in the right place. Note: To avoid confusion, assume that the terms row/entry and column/value as both will be used interchangeably. ## Namespaces To keep the library out of the global namespace, everything contained in this library has been organized into a hierarchy of namespaces. ### $.csv The top-level namespace where you will find the primary parser methods and the utility functions needed by them. ### $.options A namespace containing the default option values for the library. If you're looking to change the defaults (as opposed to overriding them) this is where you may do so. ### $.config Created after parser initialization. This is where the settings can be read/modified for an active parser instance. ### $.state Created after parser initialization. This is where the current state of the parser can be read/modified. ### $.hooks A namespace containing helpful user-defined hook callbacks. For more information on what's available refer to the Hooks? page. ### $.parsers Where the parser methods live. They're useful if you just need access to a CSV-specific split-lines function, or a single-entry parser. You can also override the default parser by changing these values inline. ## Core Methods The following methods make up the core of the jquery-csv library. ### $.csv.toArray() Useful for parsing a single entry of CSV data into an array of `[values]`. *Structure:* ```javascript $.csv.toArray(csv, options, callback) ``` *Parameters:* - csv (required) - a string of CSV data - options (optional) - contains a list of user-configurable options - callback (optional) - used for node.js and/or asynchronous processing of data - used to define the callback that is executed when parsing is complete - the callbacks take the standard form [function(err, data){}] *Options:* - separator - an override for the separator character - defaults to a comma(,) - delimiter - an override for the delimiter character - defaults to a double-quote(") ### $.csv.toArrays() Useful for parsing multi-line CSV data into a two-dimensional array of `[record][values].` *Structure:* ```javascript $.csv.toArrays(csv, options, callback) ``` *Parameters:* - csv (required) - a string of CSV data - options (optional) - contains a list of user-configurable options - callback (optional) - used for node.js and/or asynchronous processing of data - used to define the callback that is executed when parsing is complete - the callbacks take the standard form [function(err, data){}] *Options:* - separator - an override for the separator character - defaults to a comma(,) - delimiter - an override for the delimiter character - defaults to a double-quote(") - startIndex (not implemented) - the line where the parser should start processing - defaults to 1 (non-zero based counting) - endIndex (not implemented) - the line the parser should stop after - defaults to EOF ### $.csv.toObjects() Useful for parsing multi-line CSV data into an array of objects representing data in the form `[record][{header:value}]`. Unless overridden, the first line of data is assumed to contain the headers. *Structure:* ```javascript $.csv.toObjects(csv, options, callback) ``` *Parameters:* - csv (required) - a string of CSV data - options (optional) - contains a list of user-configurable options - callback (optional) - used for node.js and/or asynchronous processing of data - used to define the callback that is executed when parsing is complete - the callbacks take the standard form [function(err, data){}] *Options:* - separator - an override for the separator character - defaults to a comma(,) - delimiter - an override for the delimiter character - defaults to a double-quote(") - headerIndex (not implemented) - the line containing the headers - defaults to 1 (non-zero based counting) - startIndex (not implemented) - the line where the parser should start processing - defaults to 2 (non-zero based counting) - endIndex (not implemented) - the line the parser should stop after - defaults to EOF ## Helper Method(s) The following methods may or may not be useful unless you're trying to tackle a specific use case. These methods make up some of the magic that makes the library work. Warning: Replace and/or modify these at your own risk. Their purpose is to override the internal behavior of the parser. Don't expect support if your custom implementation introduces bugs. ```javascript $.csv.splitLines(csv) ``` An advanced line splitter that converts a CSV data string into an array of CSV entries represented in string form. As opposed to the commonly used string.split() function, this is a more advanced line splitting implementation capable of ignoring new-lines contained in the value data. Splitting data by lines may sound trivial (no split('\n) does not work) but under the covers it required the development a special lexer tailored specifically to handle CSV data. *Structure:* ```javascript``` $.csv.parsers.splitLines(csv, options) ``` *Parameters:* - csv (required) - a string of CSV data - options (optional) - contains a list of user-configurable options *Options:* - separator - an override for the separator character - defaults to a comma(,) - delimiter - an override for the delimiter character - defaults to a double-quote(") ================================================ FILE: docs/hooks-callbacks.md ================================================ ## Why hook? CSV as a data format is very loosely implemented. Part of what makes it so versatile is the lack of specific rules to enforce how it should be used. Unfortunately, without such rules it becomes a lot more difficult to define how the data should be interpreted. To keep the library size small and avoid baking in a ton of domain-specific 'magic', an extensible architecture is provided whereby users can define their own 'magic'. ## How it works Hooks work by defining a user-defined function that will be used inline during the parsing process. The point where it's called during parsing depends on the hook used. To use a hook, simply attach a function callback (ie anonymous function) of your design to the hook in the parser options object. No really... it's that easy. ## Available Hooks ### onPreParse() This hook is called before the parser starts processing the dataset. Useful if you need to make a pass to 'clean' the data first. *Usage:* ```javascript // strips empty (illegal) lines from the data before parsing var removeEmptyLines = function(csv, state) { var lines = $.csv.splitLines(csv); var output = []; for(var i=0, len=lines.length; i= start && state.rowNum <= end) { return entry; } return false; } $.csv.toArrays(testHook3, { onParseEntry: rowRange }); ``` ### onParseValue() This hook is called each time a value is parsed. Useful if you want to modify the output values inline, or process-by-column. *Usage:* ```javascript // signals to only parse columns 4 and 5 var columnRange = function(value, state) { var start = 4; var end = 5; if(state.colNum >= start && state.colNum <= end) { return value; } return false; } $.csv.toArrays(testHook2, { onParseValue: columnRange }); ``` ### onPostParse() This hook is called after the parser is complete. Useful if you want to modify the output data. *Usage:* ```javascript // sort the 2D array by the value of the second column var sortByCol2 = function(data) { data.sort(function(a,b){ return a[1] - b[1]; }); return data; } $.csv.toArrays(csv, { onPostParse: sortByCol2 }); ``` ## Available User-Defined Callbacks So... I lied when I said that the library won't provide any user-defined hook callbacks. Some are just too common and valuable to leave out. The following will outline the user-defined callbacks that will be provided with the library by defaults. ### $.csv.hooks.castToScalar(value) This is a onParseValue callback that detects and casts all output values to the correct type. *Usage:* ```javascript var csv = '734,4.5,sda,"555","4523.35","af323"'; var data = $.csv2Array(csv, { onParseValue: $.csv.hooks.castToScalar }); console.log(data); Output: [ 734, 4.5, "sda", 555, 4523.35, "af323"] ] ``` ### Custom User Defined Date Parser This is an example of using a custom function passed to the onParseValue callback that will parse dates *Usage:* ```javascript const csv = '10-11-1995,10/23/1993,12.30.1962,10,hello,5.47'; const parseDates = function(value, state) { // Only try to parse values that include a '.' or '/' or '-' if (value.match(/(\.|\/|\-)/g)) { const date = new Date(value); if (date != 'Invalid Date') return date; } return value; }; const data = $.csv2Array(csv, { onParseValue: parseDates }); Output: [ Wed Oct 11 1995 00:00:00 GMT-0500 (Central Daylight Time), Sat Oct 23 1993 00:00:00 GMT-0500 (Central Daylight Time), Sun Dec 30 1962 00:00:00 GMT-0600 (Central Standard Time), 10, hello, 5.47 ] ``` Aside: There are plenty more use-cases to be discovered for the plethora of hooks. If you feel like you have one that is common enough to justify adding it to the library we'd like to see it. Just create a new 'feature request' in the 'issues' section outlining the details. ================================================ FILE: examples/_template.html ================================================ Template

Description

[description]


Usage

[code]

Input


Result

================================================ FILE: examples/custom-date-parsing.html ================================================ Custom Date Parsing

Description

Using a custom defined hook to parse dates


Usage

const parseDates = function(value, state) {
  if (value.match(/(\.|\/|\-)/g)) {
    const date = new Date(value);
  
    if (date != 'Invalid Date')
      return date;
  }
  
    return value;
};
  
const data = $.csv2Array(csv, { onParseValue: parseDates });

Input


Result

================================================ FILE: examples/data/analytics1.csv ================================================ 1,30 2,44 3,30 4,12 5,14 6,42 7,43 8,25 9,48 10,35 11,12 12,8 13,57 14,48 15,49 16,41 17,24 18,14 19,22 20,46 21,54 22,83 23,68 24,63 25,26 26,34 27,60 28,55 29,77 30,73 31,42 ================================================ FILE: examples/data/analytics2.csv ================================================ 1,21 2,26 3,61 4,70 5,50 6,66 7,43 8,29 9,30 10,71 11,74 12,77 13,74 14,63 15,25 16,18 17,64 18,77 19,84 20,85 21,71 22,36 23,22 24,82 25,99 26,97 27,92 28,67 29,37 30,59 31,111 ================================================ FILE: examples/data/sample.csv ================================================ ID,iManufacturer,iMPartNumber,iSerialNumber,iSimCategory,iPartType,iDescription,iGroup,iLocation,iSold 1,"Evans & Sutherland","230-132-111AA",,"Visual","PCB",,1,"Offsite", 2,"Evans & Sutherland","230-132-111AA",,"Visual","PCB",,1,"Offsite", 3,"Evans & Sutherland","230-120-112AC",,"Visual","PCB",,1,"Offsite", 4,"Evans & Sutherland","230-120-112AC",,"Visual","PCB",,1,"Offsite", 5,"Evans & Sutherland","230-120-112AC",,"Visual","PCB",,1,"Offsite", 6,"Evans & Sutherland","230-120-112AC",,"Visual","PCB",,1,"Offsite", 7,"Evans & Sutherland","230-120-112AC",,"Visual","PCB",,1,"Offsite", 8,"Evans & Sutherland","230-120-112AC",,"Visual","PCB",,1,"Offsite", 9,"Evans & Sutherland","230-120-112AC",,"Visual","PCB",,1,"Offsite", 10,"Evans & Sutherland","230-121-150AC",,"Visual","PCB",,1,"Offsite", 11,"Evans & Sutherland","230-121-150AC",,"Visual","PCB",,1,"Offsite", 12,"Evans & Sutherland","230-121-150AC",,"Visual","PCB",,1,"Offsite", 13,"Evans & Sutherland","230-121-150AC",,"Visual","PCB",,1,"Offsite", 14,"Evans & Sutherland","230-121-150AC",,"Visual","PCB",,1,"Offsite", 15,"Evans & Sutherland","230-140-110DA",,"Visual","PCB",,1,"Offsite", 16,"Evans & Sutherland","230-140-110DA",,"Visual","PCB",,1,"Offsite", 17,"Evans & Sutherland","230-140-110DA",,"Visual","PCB",,1,"Offsite", 18,"Evans & Sutherland","230-140-110DA",,"Visual","PCB",,1,"Offsite", 19,"Evans & Sutherland","230-140-110DA",,"Visual","PCB",,1,"Offsite", 20,"Evans & Sutherland","230-140-110DA",,"Visual","PCB",,1,"Offsite", 21,"Evans & Sutherland","230-140-110DA",,"Visual","PCB",,1,"Offsite", 22,"Evans & Sutherland","230-140-110DA",,"Visual","PCB",,1,"Offsite", 23,"Evans & Sutherland","230-120-112AB",,"Visual","PCB",,1,"Offsite", 24,"Evans & Sutherland","230-120-112AB",,"Visual","PCB",,1,"Offsite", 25,"Evans & Sutherland","230-120-112AB",,"Visual","PCB",,1,"Offsite", 26,"Evans & Sutherland","230-113-130CF",,"Visual","PCB",,1,"Offsite", 27,"Evans & Sutherland","230-114-111AA",,"Visual","PCB",,1,"Offsite", 28,"Evans & Sutherland","230-114-111AA",,"Visual","PCB",,1,"Offsite", 29,"Evans & Sutherland","230-110-130AC",,"Visual","PCB",,1,"Offsite", 30,"Evans & Sutherland","230-116-121AA",,"Visual","PCB",,1,"Offsite", 31,"Evans & Sutherland","230-116-121AA",,"Visual","PCB",,1,"Offsite", 32,"Evans & Sutherland","230-116-121AA",,"Visual","PCB",,1,"Offsite", 33,"Evans & Sutherland","230-116-121AA",,"Visual","PCB",,1,"Offsite", 34,"Evans & Sutherland","230-116-121AA",,"Visual","PCB",,1,"Offsite", 35,"Evans & Sutherland","230-116-121AA",,"Visual","PCB",,1,"Offsite", 36,"Evans & Sutherland","230-116-121AA",,"Visual","PCB",,1,"Offsite", 37,"Evans & Sutherland","230-116-121AA",,"Visual","PCB",,1,"Offsite", 38,"Evans & Sutherland","230-116-121AA",,"Visual","PCB",,1,"Offsite", 39,"Evans & Sutherland","230-116-121AA",,"Visual","PCB",,1,"Offsite", 40,"Evans & Sutherland","230-132-111AB",,"Visual","PCB",,1,"Offsite", 41,"Evans & Sutherland","230-121-150AB",,"Visual","PCB",,1,"Offsite", 42,"Evans & Sutherland","230-121-150AB",,"Visual","PCB",,1,"Offsite", 43,"Evans & Sutherland","230-121-150AB",,"Visual","PCB",,1,"Offsite", 44,"Evans & Sutherland","230-113-130CD",,"Visual","PCB",,1,"Offsite", 45,"Evans & Sutherland","230-113-130CD",,"Visual","PCB",,1,"Offsite", 46,"Evans & Sutherland","230-111-207AA",,"Visual","PCB",,1,"Offsite", 47,"Evans & Sutherland","230-111-207AA",,"Visual","PCB",,1,"Offsite", 48,"Evans & Sutherland","230040-146AD",,"Visual","Backplane Chassis",,1,"Offsite", 49,"Evans & Sutherland","230040-146AD",,"Visual","Backplane Chassis",,1,"Offsite", 50,"Evans & Sutherland","230040-146AD",,"Visual","Backplane Chassis",,1,"Offsite", 51,"Pioneer Magnetics","801966-105XA",,"Visual","Power Supply","5v 300A 208/230 50/60 Model # 250LB-2-3P",1,"Offsite", 52,"Pioneer Magnetics","801966-105XA",,"Visual","Power Supply","5v 300A 208/230 50/60 Model # 250LB-2-3P",1,"Offsite", 53,"Pioneer Magnetics","801966-105XA",,"Visual","Power Supply","5v 300A 208/230 50/60 Model # 250LB-2-3P",1,"Offsite", 54,"Evans & Sutherland",,,"Visual","Misc","Cabinet Fan Assembly",1,"Offsite", 55,"Evans & Sutherland",,,"Visual","Misc","Power Controller",1,"Offsite", 56,"Varia Datamachines",,,"Visual",,"Sperry Univac V77 - Upper Memory Board",2,"Offsite",0 57,"Varia Datamachines",,,"Visual",,"Sperry Univac V77 - Lower Memory Board",2,"Offsite",0 58,"Varia Datamachines",,,"Visual",,"Sperry Univac V77 - Processor Board",2,"Offsite",0 59,"Varia Datamachines",,,"Visual",,"Sperry Univac V77 - Memory Map Board",2,"Offsite",0 60,"Varia Datamachines",,,"Visual",,"Sperry Univac V77 - Option Board",2,"Offsite",0 61,"Varia Datamachines",,,"Visual",,"Sperry Univac V77 - I/O Port Board",2,"Offsite",0 62,"Varia Datamachines",,,"Visual",,"Sperry Univac V77 - I/O Extension Power Supply",2,"Offsite",0 63,"Varia Datamachines",,,"Visual",,"Sperry Univac V77 - Disk Unit w/ HDD and 8” FDD",2,"Offsite",0 64,"Varia Datamachines",,,"Visual",,"Sperry Univac V77 - CPU Power Supply",2,"Offsite",0 65,"Varia Datamachines",,,"Visual",,"Sperry Univac V77 - Memory Power Supply",2,"Offsite",0 66,"VITAL",,,"Visual",,"Vital IV Interface - Peddle",2,"Offsite",0 67,"VITAL",,,"Visual",,"Vital IV Interface - Terminator Shoe",2,"Offsite",0 68,"VITAL",,,"Visual",,"Vital IV Interface - I/O Expander",2,"Offsite",0 69,"VITAL",,,"Visual",,"Vital IV Interface - I/O Expander Paddele",2,"Offsite",0 70,"VITAL",,,"Visual",,"Vital IV Interface - S-Bus Controller",2,"Offsite",0 71,"VITAL",,,"Visual",,"Vital IV Interface - PIM #1",2,"Offsite",0 72,"VITAL",,,"Visual",,"Vital IV Interface - PIM #2",2,"Offsite",0 73,"VITAL",,,"Visual",,"Vital IV Interface - BIC #1",2,"Offsite",0 74,"VITAL",,,"Visual",,"Vital IV Interface – PMAC",2,"Offsite",0 75,"VITAL",,,"Visual",,"Vital IV Interface - DIOC",2,"Offsite",0 76,"VITAL",,,"Visual",,"Vital IV Interface - BIC #3",2,"Offsite",0 77,"VITAL",,,"Visual",,"Vital IV Interface - Matrix Multiplier",2,"Offsite",0 78,"VITAL",,,"Visual",,"Vital IV TASK - A1A1 FOV",2,"Offsite",0 79,"VITAL",,,"Visual",,"Vital IV TASK - A1A2 MM",2,"Offsite",0 80,"VITAL",,,"Visual",,"Vital IV TASK - A1A3 ACC",2,"Offsite",0 81,"VITAL",,,"Visual",,"Vital IV TASK - A1A4 IS",2,"Offsite",0 82,"VITAL",,,"Visual",,"Vital IV TASK - A1A5 PD",2,"Offsite",0 83,"VITAL",,,"Visual",,"Vital IV TASK - A1A6 Int/Def",2,"Offsite",0 84,"VITAL",,,"Visual",,"Vital IV TASK - A1A7 OB",2,"Offsite",0 85,"VITAL",,,"Visual",,"Vital IV TASK - A1A9 SB",2,"Offsite",0 86,"VITAL",,,"Visual",,"Vital IV TASK - A1A10 SF",2,"Offsite",0 87,"VITAL",,,"Visual",,"Vital IV RBOS - A2A1-A5 OL",2,"Offsite",0 88,"VITAL",,,"Visual",,"Vital IV RBOS - A2A6 OC/DEF",2,"Offsite",0 89,"VITAL",,,"Visual",,"Vital IV RBOS - A2A8 D/A",2,"Offsite",0 90,"VITAL",,,"Visual",,"Vital IV RBOS - A2A9 XC",2,"Offsite",0 91,"VITAL",,,"Visual",,"Vital IV RBOS - A2A10 CL",2,"Offsite",0 92,"VITAL",,,"Visual",,"Vital IV RBOS - A2A11 YC",2,"Offsite",0 93,"VITAL",,,"Visual",,"Vital IV RBOS - A2A12 LLS",2,"Offsite",0 94,"VITAL",,,"Visual",,"Vital IV RBOS - A2A13 ZC",2,"Offsite",0 95,"CITRONIX","H06G2072-4",,"Visual",,"VITAL Monitor Power Supply",2,"Offsite",0 96,,,,"Visual",,"VT220 Terminal",2,"Offsite",0 97,,,,"Visual",,"VT220 Terminal",2,"Offsite",0 98,"Mannisman","MT88",,"Visual",,"Tally Matrix Printer",2,"Offsite",0 99,,,,"Visual",,"DIGITAL Laserwriter Printer",2,"Offsite",0 100,,,,"Visual",,"DIGITAL Laserwriter Printer",2,"Offsite",0 101,,,,"Visual",,"Signal Cable - IG <-> Monitor",2,"Offsite",0 102,,,,"Visual",,"Signal Cable - IG <-> Monitor",2,"Offsite",0 103,,,,"Visual",,"Signal Cable - IG <-> Monitor",2,"Offsite",0 104,,,,"Visual",,"One Short Signal Cable",2,"Offsite",0 105,"VITAL","H06G2033-1",,"Visual",,"Interface Unit",2,"Offsite",0 106,,,,"Visual",,"Two Channel Main Power Cable",2,"Offsite",0 107,,,,"Visual",,"One Monitor Main Power Cable",2,"Offsite",0 108,,,,"Visual",,"One Interface Power Cable",2,"Offsite",0 109,"Gould-Encore","160-103025-001",79292031,"Host Computer","PCB","ADS MOD 9122",3,"1A1",0 110,"Gould-Encore","160-103109-001K","TNP 20985","Host Computer","PCB","Real Time Option Module MOD 2345",3,"1A1",0 111,"Gould-Encore","160-103175-001K","SMP 24421","Host Computer","PCB","Terminal, Line Printer, Console Controller MOD 9005",3,"1A1",0 112,"Gould-Encore","160-103478-005D","PB 191078","Host Computer","PCB","IMM",3,"1A2",0 113,"Gould-Encore","160-103196-001F","LFP 6830","Host Computer","PCB","Control Panel, Serial",3,"1A2",0 114,"Gould-Encore","160-103210-001C","SMP 18186","Host Computer","PCB","MTC",3,"1A2",0 115,"Gould-Encore","160-103249-005A","NHP 16162","Host Computer","PCB","MMB Set A 1-2 For Dynamic Test",3,"1A3",0 116,"Gould-Encore","160-103249-005A","NHP 16305","Host Computer","PCB","MMB Set A 2-2",3,"1A3",0 117,"Gould-Encore","160-103249-005A","HE 411146","Host Computer","PCB","MMB Set B 1-2",3,"1A3",0 118,"Gould-Encore","160-103249-005A","NHP 16194","Host Computer","PCB","MMB Set B 2-2",3,"1A3",0 119,"Gould-Encore","160-103249-005A","NHP 16163","Host Computer","PCB","MMB Set C 1-2",3,"1A3",0 120,"Gould-Encore","160-103249-005A",49053,"Host Computer","PCB","MMB Set C 2-2",3,"1A3",0 121,"Gould-Encore","160-103249-005A","ES 391119","Host Computer","PCB","MMB Set D 1-2",3,"1A4",0 122,"Gould-Encore","160-103249-005A","WA 241207","Host Computer","PCB","MMB Set D 2-2 For Dynamic Test",3,"1A4",0 123,"Gould-Encore","160-103265-002H","HE 421214","Host Computer","PCB","MBC Set 1-3",3,"1A4",0 124,"Gould-Encore","160-103265-002H","NR 121278","Host Computer","PCB","MBC Set 2-3",3,"1A4",0 125,"Gould-Encore","160-103265-002H","BR 451344","Host Computer","PCB","MBC Set 3-3 For Dynamic Test",3,"1A4",0 126,"Gould-Encore","EPOCH90 Rev K",1083,"Host Computer","PCB","Epoch Processor ",3,"1A4",0 127,"Gould-Encore","160-103308-001N","WA 261194","Host Computer","PCB","Floating Point Processor MOD 2341 Set A 1-2",3,"1B1",0 128,"Gould-Encore","160-103309-001R","NHP 15821","Host Computer","PCB","Floating Point Processor MOD 2341 Set A 2-2",3,"1B1",0 129,"Gould-Encore","160-103308-001L","KA 141748","Host Computer","PCB","Floating Point Processor MOD 2341 Set B 1-2",3,"1B1",0 130,"Gould-Encore","160-103309-001M","CW 071508","Host Computer","PCB","Floating Point Processor MOD 2341 Set B 2-2",3,"1B1",0 131,"Gould-Encore","160-103308-001N","BR 461072","Host Computer","PCB","Floating Point Processor MOD 2341 Set A 1-2",3,"1B1",0 132,"Gould-Encore","160-103309-001P","BR 471385","Host Computer","PCB","Floating Point Processor MOD 2341 Set A 2-2",3,"1B1",0 133,"Gould-Encore","160-103308-001N","FAP 3297","Host Computer","PCB","Floating Point Processor Set B 1-2",3,"1B2",0 134,"Gould-Encore","160-103309-001R","FAP 3247","Host Computer","PCB","Floating Point Processor Set B 2-2",3,"1B2",0 135,"Gould-Encore","160-103436-001F","SMP 19282","Host Computer","PCB","CPU Processor Set A 1-3 ",3,"1B2",0 136,"Gould-Encore","160-103437-001E","SMP 19289","Host Computer","PCB","CPU Processor Set A 2-3",3,"1B2",0 137,"Gould-Encore","160-103438-001D","SMP 19305","Host Computer","PCB","CPU Processor Set A 3-3",3,"1B2",0 138,"Gould-Encore","160-103436-001F","SMP 16517","Host Computer","PCB","CPU Processor Set B 1-3",3,"1B2",0 139,"Gould-Encore","160-103437-001E","SMP 16552","Host Computer","PCB","CPU Processor Set B 2-3",3,"1B2",0 140,"Gould-Encore","160-103438-001A","AS 361101","Host Computer","PCB","CPU Processor Set B 3-3",3,"1B2",0 141,"Gould-Encore","160-103436-001F","PM 331697","Host Computer","PCB","CPU Processor Set C 1-3",3,"1B3",0 142,"Gould-Encore","160-103437-001E","PM 331638","Host Computer","PCB","CPU Processor Set C 2-3",3,"1B3",0 143,"Gould-Encore","160-103438-001D","PM 331611","Host Computer","PCB","CPU Processor Set C 3-3",3,"1B3",0 144,"Gould-Encore","160-103436-001B","ATZ 90063","Host Computer","PCB","CPU Processor MOD 2005 Set 1-3",3,"1B4",0 145,"Gould-Encore","160-103437-001B","TC 470118","Host Computer","PCB","CPU Processor MOD 2005 Set 2-3",3,"1B4",0 146,"Gould-Encore","160-103438-001D","SMP 19319","Host Computer","PCB","CPU Processor MOD 2005 Set 3-3",3,"1B4",0 147,"Gould-Encore","160-103509-001H",501,"Host Computer","PCB","PCB Set 1-3 - IOP/DI",3,"1B4",0 148,"Gould-Encore","160-103519-001H","A642","Host Computer","PCB","PCB Set 2-3 - IOP",3,"1B4",0 149,"Gould-Encore","160-103998-001",2192880,"Host Computer","PCB","PCB Set 3-3 - Module DE, Interface PC",3,"1B4",0 150,"Gould-Encore","160-103554-001C","PWP 01208","Host Computer","PCB","HSD",3,"1B4",0 151,"LH Research","845293-051","8331441AC","Host Computer","Power Supply","5v 40a, 15v 11a, 15v 5a, 5v 1a 115vac",3,"1C1",0 152,"LH Research","845293-051","8353670AD","Host Computer","Power Supply","5v 40a, 15v 11a, 15v 5a, 5v 1a 115vac",3,"1C1",0 153,"LH Research","845293-051","8353660AD","Host Computer","Power Supply","5v 40a, 15v 11a, 15v 5a, 5v 1a 115vac",3,"1C1",0 154,"LH Research","845293-051","8372000AF","Host Computer","Power Supply","5v 40a, 15v 11a, 15v 5a, 5v 1a 115vac",3,"1C1",0 155,"LH Research","845293-051","8235235Y","Host Computer","Power Supply","5v 40a, 15v 11a, 15v 5a, 5v 1a 115vac",3,"1C2",0 156,"LH Research","846764-002","P8303164U","Host Computer","Power Supply","5v 200a",3,"1C2",0 157,"Powertec","9K5-200-17",11118,"Host Computer","Power Supply","5v 200a 115/230 vac",3,"1C2",0 158,"Powertec","9K5-200-17",12264,"Host Computer","Power Supply","5v 200a 115/230 vac",3,"1C2",0 159,"Powertec","9K5-200-17",9703,"Host Computer","Power Supply","5v 200a 115/230 vac",3,"1C3",0 160,"Powertec","9N5-150-17",2296,"Host Computer","Power Supply","5v 150a 115/230 vac",3,"1C3",0 161,"Powertec","9N5-150-17",7274,"Host Computer","Power Supply","5v 150a 115/230 vac",3,"1C3",0 162,"Powertec","9K5-200-17",3476,"Host Computer","Power Supply","5v 200a 115/230 vac",3,"1C3",0 163,"Powertec","9K5-200-17",1132,"Host Computer","Power Supply","5v 200a 115/230 vac",3,"1C4",0 164,"Powertec","9N5-150-17",27356,"Host Computer","Power Supply","26v 6a 115vac",3,"1C4",0 165,"Powertec","9N5-150-17",22174,"Host Computer","Power Supply","26v 6a 115vac",3,"1C4",0 166,"Secur-A-Stor",400976,17746,"Host Computer","Disc Drive","SCSI Host Disc Drive",3,"1C5",0 167,"Crown","Model D75",22208,"Linkage","Amplifier","240 Watts 120 vac",3,"Offshelf",0 168,"Crown","Model D75",22210,"Linkage","Amplifier","240 Watts 120 vac",3,"Offshelf",0 169,"Singer Link","2010839-04","C005","Linkage","PCB","Fail Safe Force Amp. Card",4,"Prepacked",0 170,"Singer Link","2010846-03",22,"Linkage","PCB","Logic 1 Card (Serviceable)",4,"Prepacked",0 171,"Singer Link","2010859-02","0264P","Linkage","PCB","I/O Card",4,"Prepacked",0 172,"Singer Link","2010861-02",1203,"Linkage","PCB","Lamp Driver Card",4,"Prepacked",0 173,"Singer Link","2010862-02","0191P","Linkage","PCB","Sequence 2 Card",4,"Prepacked",0 174,"Singer Link","2010863-09",36378,"Linkage","PCB","DC Power Fault Dect",4,"Prepacked",0 175,"Singer Link",2010864,"C0012","Linkage","PCB","Hybrid Card. Condition - Repairable",4,"Prepacked",0 176,"Singer Link","2010864-02",2,"Linkage","PCB","Hybrid Card",4,"Prepacked",0 177,"Singer Link","2010864-02",10,"Linkage","PCB","Hybrid Card",4,"Prepacked",0 178,"Singer Link","2010881-02","R10976","Linkage","PCB","AO/AI Card",4,"Prepacked",0 179,"Singer Link","2010919-01","C0002","Linkage","PCB","Power Sequence Card",4,"Prepacked",0 180,"Singer Link","2010928-01","C0059","Linkage","PCB","Terminator Card Subcontroller",4,"Prepacked",0 181,"Singer Link","2010959-01","0029P","Linkage","PCB","Pump Logic Hyd",4,"Prepacked",0 182,"Singer Link","2010975-03",910,"Linkage","PCB","Subcontroller Card",4,"Prepacked",0 183,"Singer Link","2010975-03",422,"Linkage","PCB","Subcontroller Card",4,"Prepacked",0 184,"Singer Link","2010975-03",425,"Linkage","PCB","Subcontroller Card",4,"Prepacked",0 185,"Singer Link","2010975-03",399,"Linkage","PCB","Subcontroller Card. Condition - Repairable",4,"Prepacked",0 186,"Singer Link","2010975-03",430,"Linkage","PCB","Subcontroller Card",4,"Prepacked",0 187,"Singer Link","2010983-01",24,"Linkage","PCB","Logic II Card",4,"Prepacked",0 188,"Singer Link","2010983-01",31,"Linkage","PCB","Logic II Card",4,"Prepacked",0 189,"Singer Link","2014047-001",89,"Linkage","PCB","Memory Card",4,"Prepacked",0 190,"Singer Link","2018509-01",19,"Linkage","PCB","Master Controller Panel",4,"Prepacked",0 191,"Singer Link","2058402-001","0013P","Linkage","PCB","Sel DMA No. 2",4,"Prepacked",0 192,"Singer Link","2058404-001","C0012","Linkage","PCB","Sel DMA No. 1",4,"Prepacked",0 193,"Singer Link","2062361-02","C0003","Linkage","PCB","Isolator Aural Cue Card",4,"Prepacked",0 194,"Singer Link","2062442-01","C0728","Linkage","PCB","I/O Card (Solid State Relay)",4,"Prepacked",0 195,"Singer Link","2070213-01","C0108","Linkage","PCB","I/O Card (Circuit Breaker)",4,"Prepacked",0 196,"Singer Link","2070215-02","R0010","Linkage","PCB","Syncro Output Card",4,"Prepacked",0 197,"Singer Link","2070216-01",107,"Linkage","PCB","I/O Card (System Card 2)",4,"Prepacked",0 198,"Singer Link","2070217-01",192,"Linkage","PCB","I/O Card (System Card 3)",4,"Prepacked",0 199,"Singer Link","2070218-01",533,"Linkage","PCB","I/O Card (Relay Card). Condition - Repairable",4,"Prepacked",0 200,"Singer Link","2070230-02","0013P","Linkage","PCB","Lamp Dimmer Card",4,"Prepacked",0 201,"Singer Link","2070881-01","C0007","Linkage","PCB","Relay Floor Air Conditioning",4,"Prepacked",0 202,"Singer Link","2071073-002",62,"Linkage","PCB","Servo Control Card",4,"Prepacked",0 203,"Singer Link","2071078-002","C0005","Linkage","PCB","Power Control Card",4,"Prepacked",0 204,"Singer Link","2080723-001",2,"Linkage","PCB","Circuit Board",4,"Prepacked",0 205,"Singer Link","2080723-001",1,"Linkage","PCB","Circuit Board",4,"Prepacked",0 206,"Singer Link","2090599-01",34,"Linkage","PCB","RA Drive & Compass Amp. Card. Condition Unserviceable",4,"Prepacked",0 207,"Singer Link","2092708-01","C0004","Linkage","PCB","IRCU Lamp Due Card",4,"Prepacked",0 208,"Singer Link","2092713-01","0004C","Linkage","PCB","Digital Test Card",4,"Prepacked",0 209,"Singer Link","2114719-006","C1009D","Linkage","PCB","Force / Servo Amp. Card",4,"Prepacked",0 210,"Singer Link","2114719-006","C0001","Linkage","PCB","Force / Servo Amp. Card",4,"Prepacked",0 211,"Singer Link","2114719-006","1008P","Linkage","PCB","Force / Servo Amp. Card",4,"Prepacked",0 212,"Singer Link","2114719-006","0005P","Linkage","PCB","Force / Servo Amp. Card",4,"Prepacked",0 213,"Singer Link","2114726-001","C0014","Linkage","PCB","Latency Test Filter & Buffer Card",4,"Prepacked",0 214,"Singer Link","2123081-001",391,"Linkage","PCB","I/O Card",4,"Prepacked",0 215,"Singer Link","2123081-001",392,"Linkage","PCB","I/O Card",4,"Prepacked",0 216,"Singer Link","2123081-001","0784P","Linkage","PCB","I/O Card",4,"Prepacked",0 217,"Singer Link","2123081-001",399,"Linkage","PCB","I/O Card",4,"Prepacked",0 218,"Singer Link","2128702-004",1,"Linkage","PCB","Aileron Control Loading Card",4,"Prepacked",0 219,"Singer Link","2128702-005",35378,"Linkage","PCB","Elevator Control Loading Card",4,"Prepacked",0 220,"Singer Link","2128702-006","C0001","Linkage","PCB","Rudder Control Loading Card",4,"Prepacked",0 221,"Singer Link","2128704-001","C0003","Linkage","PCB","Input Message Assembler Card",4,"Prepacked",0 222,"Singer Link","2128706-001","C0002","Linkage","PCB","Input Message Control Card",4,"Prepacked",0 223,"Singer Link","2128707-001",36378,"Linkage","PCB","Output Message Assembler Card. Condition - Repairable",4,"Prepacked",0 224,"Singer Link","2128708-001","C0004","Linkage","PCB","Memory Control Card",4,"Prepacked",0 225,"Singer Link","2128709-001","C0003","Linkage","PCB","Pointer Data Control Card",4,"Prepacked",0 226,"Singer Link","2128710-001","C0005","Linkage","PCB","Test Message Control 1 Card",4,"Prepacked",0 227,"Singer Link","2128711-001","C0002","Linkage","PCB","Output Port Card",4,"Prepacked",0 228,"Singer Link","2128712-001","C0003","Linkage","PCB","Test Message Control 2 Card",4,"Prepacked",0 229,"Singer Link","2131555-003","C0003","Linkage","PCB","Component Misc. Flt. Director Card",4,"Prepacked",0 230,"Singer Link","2131556-001","C0001","Linkage","PCB","GPWS Misc. Card",4,"Prepacked",0 231,"Singer Link","2131559-001","A2584","Linkage","PCB","Circuit Card. Condition - ??",4,"Prepacked",0 232,"Singer Link","2131563-001","C0004","Linkage","PCB","Control Loading Misc. Card",4,"Prepacked",0 233,"Singer Link","3015626-001",4,"Linkage","PCB","Serial Data IRCU Interface",4,"Prepacked",0 234,"Singer Link","3099328-001",24,"Linkage","PCB","D/S ESRD Card",4,"Prepacked",0 235,"Singer Link","3099328-001",25,"Linkage","PCB","D/S ESRD Card. Condition - Unserviceable",4,"Prepacked",0 236,"Singer Link","3099328-001",57,"Linkage","PCB","D/S ESRD Card",4,"Prepacked",0 237,"Singer Link","7464814-30","C0195","Linkage","PCB","I/O Card",4,"Prepacked",0 238,"Singer Link","7464848-10","C0142","Linkage","PCB","Monitor and Briefing Audio Card",4,"Prepacked",0 239,"Singer Link","2010975-03",429,"Linkage","PCB",,4,"Box 8",0 240,"Singer Link","2010859-02",1130,"Linkage","PCB",,4,"Box 8",0 241,"Singer Link","2010859-02",1121,"Linkage","PCB",,4,"Box 8",0 242,"Singer Link","2010213-01",220,"Linkage","PCB",,4,"Box 8",0 243,"Singer Link","2010213-01",224,"Linkage","PCB",,4,"Box 8",0 244,"Singer Link","2010859-02",1123,"Linkage","PCB",,4,"Box 8",0 245,"Singer Link","2010859-02",1122,"Linkage","PCB",,4,"Box 8",0 246,"Singer Link","2010859-02",1126,"Linkage","PCB",,4,"Box 8",0 247,"Singer Link","2070213-01",222,"Linkage","PCB",,4,"Box 8",0 248,"Singer Link","2070218-01",530,"Linkage","PCB",,4,"Box 8",0 249,"Singer Link","2010859-02",1128,"Linkage","PCB",,4,"Box 8",0 250,"Singer Link","2062444-03","No SN","Linkage","PCB",,4,"Box 8",0 251,"Singer Link","2062444-02",56,"Linkage","PCB",,4,"Box9",0 252,"Singer Link","3015628-001",17,"Linkage","PCB",,4,"Box9",0 253,"Singer Link","2010975-03",421,"Linkage","PCB",,4,"Box9",0 254,"Singer Link","2062436-01",470,"Linkage","PCB",,4,"Box9",0 255,"Singer Link","2062436-01",465,"Linkage","PCB",,4,"Box9",0 256,"Singer Link","2090598-01",9,"Linkage","PCB",,4,"Box9",0 257,"Singer Link","2062436-01",469,"Linkage","PCB",,4,"Box9",0 258,"Singer Link","2062436-01",468,"Linkage","PCB",,4,"Box9",0 259,"Singer Link","2062436-01",466,"Linkage","PCB",,4,"Box9",0 260,"Singer Link","2123081-001",408,"Linkage","PCB",,4,"Box9",0 261,"Singer Link","2062422-01",49,"Linkage","PCB",,4,"Box9",0 262,"Singer Link","2092706-02",1,"Linkage","PCB",,4,"Box9",0 263,"Singer Link","7464848-10",125,"Linkage","PCB",,4,"BFB",0 264,"Singer Link","2090607-01",1,"Linkage","PCB",,4,"BFB",0 265,"Singer Link","2010975-03",426,"Linkage","PCB",,4,"BFB",0 266,"Singer Link","2010837-02",435,"Linkage","PCB",,4,"BFB",0 267,"Singer Link","2010834-02",103,"Linkage","PCB",,4,"BFB",0 268,"Singer Link","2010837-02",434,"Linkage","PCB",,4,"BFB",0 269,"Singer Link","2010833-02",63,"Linkage","PCB",,4,"BFB",0 270,"Singer Link","2090603-02",128,"Linkage","PCB",,4,"BFB",0 271,"Singer Link","2090603-01",127,"Linkage","PCB",,4,"BFB",0 272,"Singer Link","2010837-02",433,"Linkage","PCB",,4,"BFB",0 273,"Singer Link","2010834-03",132,"Linkage","PCB",,4,"BFB",0 274,"Singer Link","2010836-02",145,"Linkage","PCB",,4,"BFB",0 275,"Singer Link","2010949-01",158,"Linkage","PCB",,4,"BFB",0 276,"Singer Link","2090601-01",116,"Linkage","PCB",,4,"BFB",0 277,"Singer Link","2082590-01",4,"Linkage","PCB",,4,"BFB",0 278,"Singer Link","2124345-001",910,"Linkage","PCB",,4,"BFB",0 279,"Singer Link","2070218-01",528,"Linkage","PCB",,4,"BFB",0 280,"Singer Link","2062436-01",467,"Linkage","PCB",,4,"BFB",0 281,"Singer Link","2010975-03",427,"Linkage","PCB",,4,"BFB",0 282,"Singer Link","2010861-02",209,"Linkage","PCB",,4,"BFB",0 283,"Singer Link","2123081-001",332,"Linkage","PCB",,4,"BFB",0 284,"Singer Link","2123081-001",414,"Linkage","PCB",,4,"BFB",0 285,"Singer Link","2123081-001",400,"Linkage","PCB",,4,"BFB",0 286,"Singer Link","2070213-01",218,"Linkage","PCB",,4,"BFB",0 287,"Singer Link","2070218-01","No SN","Linkage","PCB",,4,"BFB",0 288,"Singer Link","2070218-01",529,"Linkage","PCB",,4,"BFB",0 289,"Singer Link","3099328-001",44,"Linkage","PCB",,4,"BFB",0 290,"Singer Link","3099328-001",33,"Linkage","PCB",,4,"BFB",0 291,"Singer Link","3099328-001",23,"Linkage","PCB",,4,"BFB",0 292,"Singer Link","2070219-01",174,"Linkage","PCB",,4,"BFB",0 293,"Singer Link","3015626-001",9,"Linkage","PCB",,4,"BFB",0 294,"Singer Link","3015626-001",8,"Linkage","PCB",,4,"BFB",0 295,"Singer Link","2070218-01",526,"Linkage","PCB",,4,"BFB",0 296,"Singer Link","2010975-03",417,"Linkage","PCB",,4,"Box1",0 297,"Singer Link","2010861-02",1110,"Linkage","PCB",,4,"Box1",0 298,"Singer Link","2010861-02",1204,"Linkage","PCB",,4,"Box1",0 299,"Singer Link","2062442-01",604,"Linkage","PCB",,4,"Box1",0 300,"Singer Link","2062442-01",603,"Linkage","PCB",,4,"Box1",0 301,"Singer Link","2062442-01",602,"Linkage","PCB",,4,"Box1",0 302,"Singer Link","2070213-01","No SN","Linkage","PCB",,4,"Box1",0 303,"Singer Link","2010859-02",1125,"Linkage","PCB",,4,"Box1",0 304,"Singer Link","2010859-02",1129,"Linkage","PCB",,4,"Box1",0 305,"Singer Link","2123081-001",404,"Linkage","PCB",,4,"Box1",0 306,"Singer Link","2123081-001",396,"Linkage","PCB",,4,"Box1",0 307,"Singer Link","2123081-001",397,"Linkage","PCB",,4,"Box1",0 308,"Singer Link","2070218-01",539,"Linkage","PCB",,4,"Box1",0 309,"Singer Link","2070218-01",531,"Linkage","PCB",,4,"Box1",0 310,"Singer Link","2070218-01",510,"Linkage","PCB",,4,"Box1",0 311,"Singer Link","2123081-001",412,"Linkage","PCB",,4,"Box2",0 312,"Singer Link","2087685-02",1000,"Linkage","PCB",,4,"Box2",0 313,"Singer Link","2010975-03","No SN","Linkage","PCB",,4,"Box2",0 314,"Singer Link","3099328-001",30,"Linkage","PCB",,4,"Box2",0 315,"Singer Link","3099328-001",10,"Linkage","PCB",,4,"Box2",0 316,"Singer Link","3099328-001",43,"Linkage","PCB",,4,"Box2",0 317,"Singer Link","2070218-01",527,"Linkage","PCB",,4,"Box2",0 318,"Singer Link","2070216-01",252,"Linkage","PCB",,4,"Box2",0 319,"Singer Link","2070218-01",536,"Linkage","PCB",,4,"Box2",0 320,"Singer Link","2070219-01",175,"Linkage","PCB",,4,"Box2",0 321,"Singer Link","2123081-001",407,"Linkage","PCB",,4,"Box2",0 322,"Singer Link","2123081-001",402,"Linkage","PCB",,4,"Box3",0 323,"Singer Link","2090599-01","No SN","Linkage","PCB",,4,"Box3",0 324,"Singer Link","2131563-001",3,"Linkage","PCB",,4,"Box3",0 325,"Singer Link","2080723-01",,"Linkage","PCB",,4,"Box3",0 326,"Singer Link","2123081-001",393,"Linkage","PCB",,4,"Box3",0 327,"Singer Link","2123081-001",403,"Linkage","PCB",,4,"Box3",0 328,"Singer Link","2128702-006",1000,"Linkage","PCB",,4,"Box3",0 329,"Singer Link","2128702-005","0003P","Linkage","PCB",,4,"Box3",0 330,"Singer Link","2128702-004","C0003","Linkage","PCB",,4,"Box3",0 331,"Singer Link","2123081-001",394,"Linkage","PCB",,4,"Box3",0 332,"Singer Link","2123081-001",398,"Linkage","PCB",,4,"Box3",0 333,"Singer Link","2070213-01","No SN","Linkage","PCB",,4,"Box3",0 334,"Singer Link","2010975-03",448,"Linkage","PCB",,4,"Box3",0 335,"Singer Link","2123081-001",415,"Linkage","PCB",,4,"Box4",0 336,"Singer Link","2123081-001",416,"Linkage","PCB",,4,"Box4",0 337,"Singer Link","2123081-001",405,"Linkage","PCB",,4,"Box4",0 338,"Singer Link","2123081-001",395,"Linkage","PCB",,4,"Box4",0 339,"Singer Link","2123081-001",401,"Linkage","PCB",,4,"Box4",0 340,"Singer Link","2010860-02",204,"Linkage","PCB",,4,"Box4",0 341,"Singer Link","2010861-02",1113,"Linkage","PCB",,4,"Box4",0 342,"Singer Link","2010975-03",423,"Linkage","PCB",,4,"Box4",0 343,"Singer Link","3099328-001",41,"Linkage","PCB",,4,"Box4",0 344,"Singer Link","3099328-001",40,"Linkage","PCB",,4,"Box4",0 345,"Singer Link","3099328-001",34,"Linkage","PCB",,4,"Box4",0 346,"Singer Link","3099328-001",6,"Linkage","PCB",,4,"Box4",0 347,"Singer Link","3099328-001",42,"Linkage","PCB",,4,"Box5",0 348,"Singer Link","3099328-001",66,"Linkage","PCB",,4,"Box5",0 349,"Singer Link","3099328-001",26,"Linkage","PCB",,4,"Box5",0 350,"Singer Link","2070216-01",253,"Linkage","PCB",,4,"Box5",0 351,"Singer Link","2070218-01",525,"Linkage","PCB",,4,"Box5",0 352,"Singer Link","2123081-01",413,"Linkage","PCB",,4,"Box5",0 353,"Singer Link","2070219-01",171,"Linkage","PCB",,4,"Box5",0 354,"Singer Link","2070219-01",176,"Linkage","PCB",,4,"Box5",0 355,"Singer Link","2123081-001",409,"Linkage","PCB",,4,"Box5",0 356,"Singer Link","2090599-01","0042P","Linkage","PCB",,4,"Box5",0 357,"Singer Link","2010975-03",420,"Linkage","PCB",,4,"Box5",0 358,"Singer Link","2010975-03",419,"Linkage","PCB",,4,"Box5",0 359,"Singer Link","7464834-10",36,"Linkage","PCB",,4,"Box6",0 360,"Singer Link","7464834-10",35,"Linkage","PCB",,4,"Box6",0 361,"Singer Link","7464834-10",32,"Linkage","PCB",,4,"Box6",0 362,"Singer Link","7464834-10","No SN","Linkage","PCB",,4,"Box6",0 363,"Singer Link","2070218-01",566,"Linkage","PCB",,4,"Box6",0 364,"Singer Link","2070216-01",106,"Linkage","PCB",,4,"Box6",0 365,"Singer Link","2070219-01",177,"Linkage","PCB",,4,"Box6",0 366,"Singer Link","2070218-01",534,"Linkage","PCB",,4,"Box6",0 367,"Singer Link","2062442-01",601,"Linkage","PCB",,4,"Box6",0 368,"Singer Link","2010861-02",1064,"Linkage","PCB",,4,"Box6",0 369,"Singer Link","2010861-02",1107,"Linkage","PCB",,4,"Box6",0 370,"Singer Link","7464814-30",180,"Linkage","PCB",,4,"Box6",0 371,"Singer Link","2070217-01","No SN","Linkage","PCB",,4,"Box6",0 372,"Singer Link","2010861-02",1108,"Linkage","PCB",,4,"Box7",0 373,"Singer Link","2010861-02",1109,"Linkage","PCB",,4,"Box7",0 374,"Singer Link","2010975-03",424,"Linkage","PCB",,4,"Box7",0 375,"Singer Link","2010859-02",1120,"Linkage","PCB",,4,"Box7",0 376,"Singer Link","2010859-02",1127,"Linkage","PCB",,4,"Box7",0 377,"Singer Link","2070219-01",172,"Linkage","PCB",,4,"Box7",0 378,"Singer Link","2070218-01",538,"Linkage","PCB",,4,"Box7",0 379,"Singer Link","2123081-001",411,"Linkage","PCB",,4,"Box7",0 380,"Singer Link","2123081-001",410,"Linkage","PCB",,4,"Box7",0 381,"Singer Link","2070215-01",126,"Linkage","PCB",,4,"Box7",0 382,"Singer Link","2070219-01",182,"Linkage","PCB",,4,"Box7",0 383,"Singer Link","2070215-01",168,"Linkage","PCB",,4,"Box7",0 384,"Singer Link","2010859-02",1124,"Linkage","PCB",,4,"Box7",0 385,"Singer Link","2010218-01",537,"Linkage","PCB",,4,"Box 8",0 386,"Singer Link","2010975-03",161,"Linkage","PCB",,4,"Box 8",0 387,"Singer Link","2070213-01",219,"Linkage","PCB",,4,"Box 8",0 388,"Singer Link","2070245-01/2145549-001",11,"Linkage","PCB","Lighting/Power Distribution Cards",4,"Box 9",0 389,"Singer Link","2070245-01/2145549-001",22,"Linkage","PCB","Lighting/Power Distribution Cards",4,"Box 9", ================================================ FILE: examples/data/sample2.csv ================================================ "TimeStamp (ms)","MID 128|PID 91|Accelerator pedal position (%)","MID 128|PID 92|Engine load(%)","MID 128|PID 100|Engine oil pressure (bar)","MID 128|PID 105|Intake manifold temperature (N0C)","MID 128|PID 110|Engine coolant temperature (N0C)","MID 128|PID 190|Engine speed (r/min)" 115,10.4,0,0,0,0,0 175,,40,,,, 309,,,4.55,,, 529,,,,17,, 630,,,,,46, 682,,,,,,1011.25 751,10.4,,,,, 803,,40,,,, 856,,,4.55,,, 921,,,,17,, 1013,,,,,46, 1521,,,,,,1016.5 1593,10.4,,,,, 1641,,39,,,, 1704,,,4.58,,, 1761,,,,17,, 1832,,,,,46, 1897,,,,,,1023 1961,10.4,,,,, 2025,,37,,,, 2088,,,4.58,,, 2145,,,,17,, 2217,,,,,46, 2283,,,,,,1022.25 2344,10.4,,,,, 2408,,36,,,, 2464,,,4.58,,, 2576,,,,17,, 2633,,,,,46, 2698,,,,,,1001 2767,10.4,,,,, ================================================ FILE: examples/data/sine.csv ================================================ 0,0.5 0.01,0.5313952597646567 0.02,0.5626666167821521 0.03,0.5936906572928623 0.04,0.6243449435824274 0.05,0.6545084971874737 0.060000000000000005,0.684062276342339 0.07,0.7128896457825363 0.08,0.7408768370508576 0.09,0.7679133974894983 0.09999999999999999,0.7938926261462365 0.10999999999999999,0.8187119948743449 0.11999999999999998,0.8422735529643443 0.12999999999999998,0.8644843137107057 0.13999999999999999,0.8852566213878945 0.15,0.9045084971874736 0.16,0.9221639627510074 0.17,0.9381533400219317 0.18000000000000002,0.9524135262330098 0.19000000000000003,0.9648882429441257 0.20000000000000004,0.9755282581475768 0.21000000000000005,0.9842915805643155 0.22000000000000006,0.9911436253643444 0.23000000000000007,0.996057350657239 0.24000000000000007,0.9990133642141358 0.25000000000000006,1 0.26000000000000006,0.9990133642141358 0.2700000000000001,0.9960573506572389 0.2800000000000001,0.9911436253643442 0.2900000000000001,0.9842915805643154 0.3000000000000001,0.9755282581475766 0.3100000000000001,0.9648882429441255 0.3200000000000001,0.9524135262330096 0.3300000000000001,0.9381533400219315 0.34000000000000014,0.9221639627510072 0.35000000000000014,0.9045084971874733 0.36000000000000015,0.8852566213878942 0.37000000000000016,0.8644843137107052 0.38000000000000017,0.8422735529643438 0.3900000000000002,0.8187119948743442 0.4000000000000002,0.7938926261462359 0.4100000000000002,0.7679133974894976 0.4200000000000002,0.7408768370508568 0.4300000000000002,0.7128896457825354 0.4400000000000002,0.6840622763423381 0.45000000000000023,0.6545084971874727 0.46000000000000024,0.6243449435824263 0.47000000000000025,0.5936906572928612 0.48000000000000026,0.5626666167821509 0.49000000000000027,0.5313952597646555 0.5000000000000002,0.4999999999999987 0.5100000000000002,0.468604740235342 0.5200000000000002,0.43733338321784654 0.5300000000000002,0.4063093427071363 0.5400000000000003,0.3756550564175712 0.5500000000000003,0.3454915028125249 0.5600000000000003,0.3159377236576596 0.5700000000000003,0.2871103542174622 0.5800000000000003,0.25912316294914095 0.5900000000000003,0.23208660251050028 0.6000000000000003,0.20610737385376204 0.6100000000000003,0.1812880051256538 0.6200000000000003,0.15772644703565436 0.6300000000000003,0.135515686289293 0.6400000000000003,0.11474337861210421 0.6500000000000004,0.09549150281252528 0.6600000000000004,0.07783603724899163 0.6700000000000004,0.06184665997806754 0.6800000000000004,0.04758647376698977 0.6900000000000004,0.03511175705587394 0.7000000000000004,0.024471741852422957 0.7100000000000004,0.015708419435684295 0.7200000000000004,0.008856374635655584 0.7300000000000004,0.003942649342761062 0.7400000000000004,0.0009866357858642205 0.7500000000000004,0 0.7600000000000005,0.0009866357858642205 0.7700000000000005,0.0039426493427610065 0.7800000000000005,0.008856374635655528 0.7900000000000005,0.01570841943568424 0.8000000000000005,0.0244717418524229 0.8100000000000005,0.03511175705587388 0.8200000000000005,0.047586473766989656 0.8300000000000005,0.061846659978067486 0.8400000000000005,0.07783603724899157 0.8500000000000005,0.09549150281252516 0.8600000000000005,0.1147433786121041 0.8700000000000006,0.13551568628929272 0.8800000000000006,0.15772644703565392 0.8900000000000006,0.18128800512565313 0.9000000000000006,0.2061073738537612 0.9100000000000006,0.23208660251049917 0.9200000000000006,0.2591231629491396 0.9300000000000006,0.2871103542174607 0.9400000000000006,0.31593772365765777 0.9500000000000006,0.34549150281252283 0.9600000000000006,0.3756550564175689 0.9700000000000006,0.4063093427071337 0.9800000000000006,0.4373333832178437 0.9900000000000007,0.46860474023533893 ================================================ FILE: examples/demo.css ================================================ body { font-family: 'Lato', san-serif; } h1, h2, h3, h4, h5 { font-family: 'Roboto', sans-serif; font-weight: 900; margin: 0; } h2 { margin-bottom: 10px; } hr { margin: 20px; } textarea { width:100%; white-space: nowrap; } code { font-family: 'Source Code Pro', monospace; } #header { position: fixed; top: 0px; left: 0px; width: 100%; height: 50px; background: #333333; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); z-index: 999; } #title { float: left; padding-top: 10px; padding-left: 10%; color: white; font-size: 1.25rem; } #link { float: right; padding-top: 10px; padding-right: 10%; font-size: 1.25rem; font-weight: 600; text-decoration: none; } #link a, #link a:hover { color: mediumorchid; text-decoration: none; } #container { width: 80%; max-width: 960px; padding: 0 50px 0 50px; margin: 0 auto; display: block; overflow-x: hidden; background: #F0F0F0; } #content { background: #F0F0F0; margin: 50px auto 0 auto; padding: 20px 0 20px 0; } #run { margin-top: 10px; border-radius: 15%; } #result { width: 100%; height: 200px; overflow: auto; } ================================================ FILE: examples/file-handling.html ================================================ File Handling

Description

The following demonstrates how to use the HTML5 File API to load a file from the client.


Input


FileInfo


Result

================================================ FILE: examples/flot.html ================================================ Flot

Description

Flot is a popular library used to generate graphs in Javascript.

This Demo generates a basic Flot line graph using CSV as the input data.


Load File


Load Data


Plot

Data

================================================ FILE: examples/from-arrays.html ================================================ From Arrays

Description

Used to format a fixed 2D array of data as CSV.


Usage

var result = $.csv.fromArrays(input);

Input


Result

================================================ FILE: examples/from-objects.html ================================================ From Objects

Description

Used to format an array of structured objects as CSV.


Usage

var result = $.csv.fromObjects(input);

Input


Result

================================================ FILE: examples/google-visualization.html ================================================ Google Visualization

Description

Google Visualization API is a powerful too used to generate graphs in Javascript.

This Demo generates a basic scatter plot CSV as the input data.


Load File

sample.csv

Load Data


Plot


Data

================================================ FILE: examples/helpers.js ================================================ const global = window global.isFileAPIAvailable = function () { // Check for the various File API support. if (window.File && window.FileReader && window.FileList && window.Blob) { // Great success! All the File APIs are supported. return true } else { // source: File API availability - http://caniuse.com/#feat=fileapi // source: availability - http://html5doctor.com/the-output-element/ document.writeln('The HTML5 APIs used in this form are only available in the following browsers:
') // 6.0 File API & 13.0 document.writeln(' - Google Chrome: 13.0 or later
') // 3.6 File API & 6.0 document.writeln(' - Mozilla Firefox: 6.0 or later
') // 10.0 File API & 10.0 document.writeln(' - Internet Explorer: Not supported (partial support expected in 10.0)
') // ? File API & 5.1 document.writeln(' - Safari: Not supported
') // ? File API & 9.2 document.writeln(' - Opera: Not supported') return false } } // Used to generate the data for the sine wave demo // source: http://coding.smashingmagazine.com/2011/10/04/quick-look-math-animations-javascript/ global.drawSine = function () { let counter = 0 // 100 iterations const increase = Math.PI * 2 / 100 for (let i = 0; i <= 1; i += 0.01) { const x = i const y = Math.sin(counter) / 2 + 0.5 counter += increase console.log(x + ',' + y) } } ================================================ FILE: examples/snippets/esm-usage.js ================================================ import * as csv from 'jquery-csv' import * as fs from 'fs' const sample = './data/sample.csv' fs.readFile(sample, 'UTF-8', (err, fileContent) => { if (err) { console.log(err) } csv.toArrays(fileContent, {}, (err, data) => { if (err) { console.log(err) } for (let i = 0, len = data.length; i < len; i++) { console.log(data[i]) } }) }) ================================================ FILE: examples/snippets/node-usage.js ================================================ /* eslint-disable no-unused-vars */ const fs = require('fs') const csv = require('jquery-csv') const sample = './data/sample.csv' fs.readFile(sample, 'UTF-8', function (err, csv) { if (err) { console.log(err) } csv.toArrays(csv, {}, function (err, data) { if (err) { console.log(err) } for (let i = 0, len = data.length; i < len; i++) { console.log(data[i]) } }) }) ================================================ FILE: examples/to-array.html ================================================ To Array

Description

Used to parse a single line of CSV data into an array of values.


Usage

var result = $.csv.toArray(input);

Input


Result

================================================ FILE: examples/to-arrays.html ================================================ To Arrays

Description

Used to parse multi-line CSV data into a JavaScript 2D (two-dimensional) array.


Usage

var result = $.csv.toArrays(input);

Input


Result

================================================ FILE: examples/to-objects.html ================================================ To Objects

Description

Used to convert multi-line CSV data into an array objects containing the data as key-value (ie header:value) pairs.


Usage

var result = $.csv.toObjects(input);

Input


Result

================================================ FILE: package.json ================================================ { "name": "jquery-csv", "version": "1.0.40", "description": "A jQuery CSV parser plugin. Battle Tested | Optimized | 100% IETF RFC 4180 Complete", "license": "MIT", "repository": { "type": "git", "url": "git+ssh://git@github.com/evanplaice/jquery-csv.git" }, "author": { "name": "Evan Plaice", "email": "evan.plaice@gmail.com", "url": "http://evanplaice.com" }, "contributors": [ { "name": "Colton Ehrman", "email": "coltonje95@gmail.com", "url": "http://coltonehrman.com" } ], "main": "src/jquery.csv.js", "scripts": { "start": "npx live-server", "test": "tape ./test/*.js", "lint": "standard", "minify": "npx uglify-js src/jquery.csv.js -o src/jquery.csv.min.js --compress --mangle", "package": "npx rimraf package && npm pack | tail -n 1 | xargs tar -xf", "preversion": "npm run lint && npm run test", "postversion": "git push --follow-tags" }, "devDependencies": { "standard": "^17.1.0", "tape": "^5.8.1" }, "standard": { "globals": [ "$", "jQuery" ] } } ================================================ FILE: src/jquery.csv.js ================================================ /* eslint no-prototype-builtins: 0 */ /** * jQuery-csv (jQuery Plugin) * * This document is licensed as free software under the terms of the * MIT License: http://www.opensource.org/licenses/mit-license.php * * Acknowledgements: * The original design and influence to implement this library as a jquery * plugin is influenced by jquery-json (http://code.google.com/p/jquery-json/). * If you're looking to use native JSON.Stringify but want additional backwards * compatibility for browsers that don't support it, I highly recommend you * check it out. * * A special thanks goes out to rwk@acm.org for providing a lot of valuable * feedback to the project including the core for the new FSM * (Finite State Machine) parsers. If you're looking for a stable TSV parser * be sure to take a look at jquery-tsv (http://code.google.com/p/jquery-tsv/). * For legal purposes I'll include the "NO WARRANTY EXPRESSED OR IMPLIED. * USE AT YOUR OWN RISK.". Which, in 'layman's terms' means, by using this * library you are accepting responsibility if it breaks your code. * * Legal jargon aside, I will do my best to provide a useful and stable core * that can effectively be built on. * * Copyrighted 2012 by Evan Plaice. */ RegExp.escape = function (s) { return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') }; (function () { 'use strict' let $ // to keep backwards compatibility if (typeof jQuery !== 'undefined' && jQuery) { $ = jQuery } else { $ = {} } /** * jQuery.csv.defaults * Encapsulates the method paramater defaults for the CSV plugin module. */ $.csv = { defaults: { separator: ',', delimiter: '"', headers: true }, hooks: { castToScalar: function (value, state) { const hasDot = /\./ if (isNaN(value)) { return value } else { if (hasDot.test(value)) { return parseFloat(value) } else { const integer = parseInt(value) if (isNaN(integer)) { return null } else { return integer } } } } }, parsers: { parse: function (csv, options) { // cache settings const separator = options.separator const delimiter = options.delimiter // set initial state if it's missing if (!options.state.rowNum) { options.state.rowNum = 1 } if (!options.state.colNum) { options.state.colNum = 1 } // clear initial state const data = [] let entry = [] let state = 0 let value = '' let exit = false function endOfEntry () { // reset the state state = 0 value = '' // if 'start' hasn't been met, don't output if (options.start && options.state.rowNum < options.start) { // update global state entry = [] options.state.rowNum++ options.state.colNum = 1 return } if (options.onParseEntry === undefined) { // onParseEntry hook not set data.push(entry) } else { const hookVal = options.onParseEntry(entry, options.state) // onParseEntry Hook // false skips the row, configurable through a hook if (hookVal !== false) { data.push(hookVal) } } // console.log('entry:' + entry); // cleanup entry = [] // if 'end' is met, stop parsing if (options.end && options.state.rowNum >= options.end) { exit = true } // update global state options.state.rowNum++ options.state.colNum = 1 } function endOfValue () { if (options.onParseValue === undefined) { // onParseValue hook not set entry.push(value) } else if (options.headers && options.state.rowNum === 1) { // don't onParseValue object headers entry.push(value) } else { const hook = options.onParseValue(value, options.state) // onParseValue Hook // false skips the row, configurable through a hook if (hook !== false) { entry.push(hook) } } // console.log('value:' + value); // reset the state value = '' state = 0 // update global state options.state.colNum++ } // escape regex-specific control chars const escSeparator = RegExp.escape(separator) const escDelimiter = RegExp.escape(delimiter) // compile the regEx str using the custom delimiter/separator let match = /(D|S|\r\n|\n|\r|[^DS\r\n]+)/ let matchSrc = match.source matchSrc = matchSrc.replace(/S/g, escSeparator) matchSrc = matchSrc.replace(/D/g, escDelimiter) match = new RegExp(matchSrc, 'gm') // put on your fancy pants... // process control chars individually, use look-ahead on non-control chars csv.replace(match, function (m0) { if (exit) { return } switch (state) { // the start of a value case 0: // null last value if (m0 === separator) { value += '' endOfValue() break } // opening delimiter if (m0 === delimiter) { state = 1 break } // null last value if (/^(\r\n|\n|\r)$/.test(m0)) { endOfValue() endOfEntry() break } // un-delimited value value += m0 state = 3 break // delimited input case 1: // second delimiter? check further if (m0 === delimiter) { state = 2 break } // delimited data value += m0 state = 1 break // delimiter found in delimited input case 2: // escaped delimiter? if (m0 === delimiter) { value += m0 state = 1 break } // null value if (m0 === separator) { endOfValue() break } // end of entry if (/^(\r\n|\n|\r)$/.test(m0)) { endOfValue() endOfEntry() break } // broken paser? throw Error('CSVDataError: Illegal State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']') // un-delimited input case 3: // null last value if (m0 === separator) { endOfValue() break } // end of entry if (/^(\r\n|\n|\r)$/.test(m0)) { endOfValue() endOfEntry() break } if (m0 === delimiter) { // non-compliant data throw Error('CSVDataError: Illegal Quote [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']') } // broken parser? throw Error('CSVDataError: Illegal Data [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']') default: // shenanigans throw Error('CSVDataError: Unknown State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']') } // console.log('val:' + m0 + ' state:' + state); }) // submit the last entry // ignore null last line if (entry.length !== 0) { endOfValue() endOfEntry() } return data }, // a csv-specific line splitter splitLines: function (csv, options) { if (!csv) { return undefined } options = options || {} // cache settings const separator = options.separator || $.csv.defaults.separator const delimiter = options.delimiter || $.csv.defaults.delimiter // set initial state if it's missing options.state = options.state || {} if (!options.state.rowNum) { options.state.rowNum = 1 } // clear initial state const entries = [] let state = 0 let entry = '' let exit = false function endOfLine () { // reset the state state = 0 // if 'start' hasn't been met, don't output if (options.start && options.state.rowNum < options.start) { // update global state entry = '' options.state.rowNum++ return } if (options.onParseEntry === undefined) { // onParseEntry hook not set entries.push(entry) } else { const hookVal = options.onParseEntry(entry, options.state) // onParseEntry Hook // false skips the row, configurable through a hook if (hookVal !== false) { entries.push(hookVal) } } // cleanup entry = '' // if 'end' is met, stop parsing if (options.end && options.state.rowNum >= options.end) { exit = true } // update global state options.state.rowNum++ } // escape regex-specific control chars const escSeparator = RegExp.escape(separator) const escDelimiter = RegExp.escape(delimiter) // compile the regEx str using the custom delimiter/separator let match = /(D|S|\n|\r|[^DS\r\n]+)/ let matchSrc = match.source matchSrc = matchSrc.replace(/S/g, escSeparator) matchSrc = matchSrc.replace(/D/g, escDelimiter) match = new RegExp(matchSrc, 'gm') // put on your fancy pants... // process control chars individually, use look-ahead on non-control chars csv.replace(match, function (m0) { if (exit) { return } switch (state) { // the start of a value/entry case 0: // null value if (m0 === separator) { entry += m0 state = 0 break } // opening delimiter if (m0 === delimiter) { entry += m0 state = 1 break } // end of line if (m0 === '\n') { endOfLine() break } // phantom carriage return if (/^\r$/.test(m0)) { break } // un-delimit value entry += m0 state = 3 break // delimited input case 1: // second delimiter? check further if (m0 === delimiter) { entry += m0 state = 2 break } // delimited data entry += m0 state = 1 break // delimiter found in delimited input case 2: { // escaped delimiter? const prevChar = entry.substr(entry.length - 1) if (m0 === delimiter && prevChar === delimiter) { entry += m0 state = 1 break } // end of value if (m0 === separator) { entry += m0 state = 0 break } // end of line if (m0 === '\n') { endOfLine() break } // phantom carriage return if (m0 === '\r') { break } // broken paser? throw Error('CSVDataError: Illegal state [Row:' + options.state.rowNum + ']') } // un-delimited input case 3: // null value if (m0 === separator) { entry += m0 state = 0 break } // end of line if (m0 === '\n') { endOfLine() break } // phantom carriage return if (m0 === '\r') { break } // non-compliant data if (m0 === delimiter) { throw Error('CSVDataError: Illegal quote [Row:' + options.state.rowNum + ']') } // broken parser? throw Error('CSVDataError: Illegal state [Row:' + options.state.rowNum + ']') default: // shenanigans throw Error('CSVDataError: Unknown state [Row:' + options.state.rowNum + ']') } // console.log('val:' + m0 + ' state:' + state); }) // submit the last entry // ignore null last line if (entry !== '') { endOfLine() } return entries }, // a csv entry parser parseEntry: function (csv, options) { // cache settings const separator = options.separator const delimiter = options.delimiter // set initial state if it's missing if (!options.state.rowNum) { options.state.rowNum = 1 } if (!options.state.colNum) { options.state.colNum = 1 } // clear initial state const entry = [] let state = 0 let value = '' function endOfValue () { if (options.onParseValue === undefined) { // onParseValue hook not set entry.push(value) } else { const hook = options.onParseValue(value, options.state) // onParseValue Hook // false skips the value, configurable through a hook if (hook !== false) { entry.push(hook) } } // reset the state value = '' state = 0 // update global state options.state.colNum++ } // checked for a cached regEx first if (!options.match) { // escape regex-specific control chars const escSeparator = RegExp.escape(separator) const escDelimiter = RegExp.escape(delimiter) // compile the regEx str using the custom delimiter/separator const match = /(D|S|\n|\r|[^DS\r\n]+)/ let matchSrc = match.source matchSrc = matchSrc.replace(/S/g, escSeparator) matchSrc = matchSrc.replace(/D/g, escDelimiter) options.match = new RegExp(matchSrc, 'gm') } // put on your fancy pants... // process control chars individually, use look-ahead on non-control chars csv.replace(options.match, function (m0) { switch (state) { // the start of a value case 0: // null last value if (m0 === separator) { value += '' endOfValue() break } // opening delimiter if (m0 === delimiter) { state = 1 break } // skip un-delimited new-lines if (m0 === '\n' || m0 === '\r') { break } // un-delimited value value += m0 state = 3 break // delimited input case 1: // second delimiter? check further if (m0 === delimiter) { state = 2 break } // delimited data value += m0 state = 1 break // delimiter found in delimited input case 2: // escaped delimiter? if (m0 === delimiter) { value += m0 state = 1 break } // null value if (m0 === separator) { endOfValue() break } // skip un-delimited new-lines if (m0 === '\n' || m0 === '\r') { break } // broken paser? throw Error('CSVDataError: Illegal State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']') // un-delimited input case 3: // null last value if (m0 === separator) { endOfValue() break } // skip un-delimited new-lines if (m0 === '\n' || m0 === '\r') { break } // non-compliant data if (m0 === delimiter) { throw Error('CSVDataError: Illegal Quote [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']') } // broken parser? throw Error('CSVDataError: Illegal Data [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']') default: // shenanigans throw Error('CSVDataError: Unknown State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']') } // console.log('val:' + m0 + ' state:' + state); }) // submit the last value endOfValue() return entry } }, helpers: { /** * $.csv.helpers.collectPropertyNames(objectsArray) * Collects all unique property names from all passed objects. * * @param {Array} objects Objects to collect properties from. * * Returns an array of property names (array will be empty, * if objects have no own properties). */ collectPropertyNames: function (objects) { let o = [] let propName = [] const props = [] for (o in objects) { for (propName in objects[o]) { if ((objects[o].hasOwnProperty(propName)) && (props.indexOf(propName) < 0) && (typeof objects[o][propName] !== 'function')) { props.push(propName) } } } return props } }, /** * $.csv.toArray(csv) * Converts a CSV entry string to a javascript array. * * @param {Array} csv The string containing the CSV data. * @param {Object} [options] An object containing user-defined options. * @param {Character} [separator] An override for the separator character. Defaults to a comma(,). * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote("). * * This method deals with simple CSV strings only. It's useful if you only * need to parse a single entry. If you need to parse more than one line, * use $.csv2Array instead. */ toArray: function (csv, options, callback) { // if callback was passed to options swap callback with options if (options !== undefined && typeof (options) === 'function') { if (callback !== undefined) { return console.error('You cannot 3 arguments with the 2nd argument being a function') } callback = options options = {} } options = (options !== undefined ? options : {}) const config = {} config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false) config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter const state = (options.state !== undefined ? options.state : {}) // setup options = { delimiter: config.delimiter, separator: config.separator, onParseEntry: options.onParseEntry, onParseValue: options.onParseValue, state } const entry = $.csv.parsers.parseEntry(csv, options) // push the value to a callback if one is defined if (!config.callback) { return entry } else { config.callback('', entry) } }, /** * $.csv.toArrays(csv) * Converts a CSV string to a javascript array. * * @param {String} csv The string containing the raw CSV data. * @param {Object} [options] An object containing user-defined options. * @param {Character} [separator] An override for the separator character. Defaults to a comma(,). * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote("). * * This method deals with multi-line CSV. The breakdown is simple. The first * dimension of the array represents the line (or entry/row) while the second * dimension contains the values (or values/columns). */ toArrays: function (csv, options, callback) { // if callback was passed to options swap callback with options if (options !== undefined && typeof (options) === 'function') { if (callback !== undefined) { return console.error('You cannot 3 arguments with the 2nd argument being a function') } callback = options options = {} } options = (options !== undefined ? options : {}) const config = {} config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false) config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter // setup let data = [] options = { delimiter: config.delimiter, separator: config.separator, onPreParse: options.onPreParse, onParseEntry: options.onParseEntry, onParseValue: options.onParseValue, onPostParse: options.onPostParse, start: options.start, end: options.end, state: { rowNum: 1, colNum: 1 } } // onPreParse hook if (options.onPreParse !== undefined) { csv = options.onPreParse(csv, options.state) } // parse the data data = $.csv.parsers.parse(csv, options) // onPostParse hook if (options.onPostParse !== undefined) { data = options.onPostParse(data, options.state) } // push the value to a callback if one is defined if (!config.callback) { return data } else { config.callback('', data) } }, /** * $.csv.toObjects(csv) * Converts a CSV string to a javascript object. * @param {String} csv The string containing the raw CSV data. * @param {Object} [options] An object containing user-defined options. * @param {Character} [separator] An override for the separator character. Defaults to a comma(,). * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote("). * @param {Boolean} [headers] Indicates whether the data contains a header line. Defaults to true. * * This method deals with multi-line CSV strings. Where the headers line is * used as the key for each value per entry. */ toObjects: function (csv, options, callback) { // if callback was passed to options swap callback with options if (options !== undefined && typeof (options) === 'function') { if (callback !== undefined) { return console.error('You cannot 3 arguments with the 2nd argument being a function') } callback = options options = {} } options = (options !== undefined ? options : {}) const config = {} config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false) config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter config.headers = 'headers' in options ? options.headers : $.csv.defaults.headers options.start = 'start' in options ? options.start : 1 // account for headers if (config.headers) { options.start++ } if (options.end && config.headers) { options.end++ } // setup let lines = [] let data = [] options = { delimiter: config.delimiter, separator: config.separator, onPreParse: options.onPreParse, onParseEntry: options.onParseEntry, onParseValue: options.onParseValue, onPostParse: options.onPostParse, start: options.start, end: options.end, state: { rowNum: 1, colNum: 1 }, match: false, transform: options.transform } // fetch the headers const headerOptions = { delimiter: config.delimiter, separator: config.separator, start: 1, end: 1, state: { rowNum: 1, colNum: 1 }, headers: true } // onPreParse hook if (options.onPreParse !== undefined) { csv = options.onPreParse(csv, options.state) } // parse the csv const headerLine = $.csv.parsers.splitLines(csv, headerOptions) const headers = $.csv.toArray(headerLine[0], headerOptions) // fetch the data lines = $.csv.parsers.splitLines(csv, options) // reset the state for re-use options.state.colNum = 1 if (headers) { options.state.rowNum = 2 } else { options.state.rowNum = 1 } // convert data to objects for (let i = 0, len = lines.length; i < len; i++) { const entry = $.csv.toArray(lines[i], options) const object = {} for (let j = 0; j < headers.length; j++) { object[headers[j]] = entry[j] } if (options.transform !== undefined) { data.push(options.transform.call(undefined, object)) } else { data.push(object) } // update row state options.state.rowNum++ } // onPostParse hook if (options.onPostParse !== undefined) { data = options.onPostParse(data, options.state) } // push the value to a callback if one is defined if (!config.callback) { return data } else { config.callback('', data) } }, /** * $.csv.fromArrays(arrays) * Converts a javascript array to a CSV String. * * @param {Array} arrays An array containing an array of CSV entries. * @param {Object} [options] An object containing user-defined options. * @param {Character} [separator] An override for the separator character. Defaults to a comma(,). * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote("). * * This method generates a CSV file from an array of arrays (representing entries). */ fromArrays: function (arrays, options, callback) { // if callback was passed to options swap callback with options if (options !== undefined && typeof (options) === 'function') { if (callback !== undefined) { return console.error('You cannot 3 arguments with the 2nd argument being a function') } callback = options options = {} } options = (options !== undefined ? options : {}) const config = {} config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false) config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter let output = '' for (let i = 0; i < arrays.length; i++) { const line = arrays[i] const lineValues = [] for (let j = 0; j < line.length; j++) { let strValue = (line[j] === undefined || line[j] === null) ? '' : line[j].toString() if (strValue.indexOf(config.delimiter) > -1) { strValue = strValue.replace(new RegExp(config.delimiter, 'g'), config.delimiter + config.delimiter) } let escMatcher = '\n|\r|S|D' escMatcher = escMatcher.replace('S', config.separator) escMatcher = escMatcher.replace('D', config.delimiter) if (strValue.search(escMatcher) > -1) { strValue = config.delimiter + strValue + config.delimiter } lineValues.push(strValue) } output += lineValues.join(config.separator) + '\n' } // push the value to a callback if one is defined if (!config.callback) { return output } else { config.callback('', output) } }, /** * $.csv.fromObjects(objects) * Converts a javascript dictionary to a CSV string. * * @param {Object} objects An array of objects containing the data. * @param {Object} [options] An object containing user-defined options. * @param {Character} [separator] An override for the separator character. Defaults to a comma(,). * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote("). * @param {Character} [sortOrder] Sort order of columns (named after * object properties). Use 'alpha' for alphabetic. Default is 'declare', * which means, that properties will _probably_ appear in order they were * declared for the object. But without any guarantee. * @param {Character or Array} [manualOrder] Manually order columns. May be * a strin in a same csv format as an output or an array of header names * (array items won't be parsed). All the properties, not present in * `manualOrder` will be appended to the end in accordance with `sortOrder` * option. So the `manualOrder` always takes preference, if present. * * This method generates a CSV file from an array of objects (name:value pairs). * It starts by detecting the headers and adding them as the first line of * the CSV file, followed by a structured dump of the data. */ fromObjects: function (objects, options, callback) { // if callback was passed to options swap callback with options if (options !== undefined && typeof (options) === 'function') { if (callback !== undefined) { return console.error('You cannot 3 arguments with the 2nd argument being a function') } callback = options options = {} } options = (options !== undefined ? options : {}) const config = {} config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false) config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter config.headers = 'headers' in options ? options.headers : $.csv.defaults.headers config.sortOrder = 'sortOrder' in options ? options.sortOrder : 'declare' config.manualOrder = 'manualOrder' in options ? options.manualOrder : [] config.transform = options.transform if (typeof config.manualOrder === 'string') { config.manualOrder = $.csv.toArray(config.manualOrder, config) } if (config.transform !== undefined) { const origObjects = objects objects = [] for (let i = 0; i < origObjects.length; i++) { objects.push(config.transform.call(undefined, origObjects[i])) } } let props = $.csv.helpers.collectPropertyNames(objects) if (config.sortOrder === 'alpha') { props.sort() } if (config.manualOrder.length > 0) { const propsManual = [].concat(config.manualOrder) for (let p = 0; p < props.length; p++) { if (propsManual.indexOf(props[p]) < 0) { propsManual.push(props[p]) } } props = propsManual } let line const output = [] let propName if (config.headers) { output.push(props) } for (let o = 0; o < objects.length; o++) { line = [] for (let p = 0; p < props.length; p++) { propName = props[p] if (propName in objects[o] && typeof objects[o][propName] !== 'function') { line.push(objects[o][propName]) } else { line.push('') } } output.push(line) } // push the value to a callback if one is defined return $.csv.fromArrays(output, options, config.callback) } } // Maintenance code to maintain backward-compatibility // Will be removed in release 1.0 $.csvEntry2Array = $.csv.toArray $.csv2Array = $.csv.toArrays $.csv2Dictionary = $.csv.toObjects // CommonJS module is defined if (typeof module !== 'undefined' && module.exports) { module.exports = $.csv } }).call(this) ================================================ FILE: test/csv.from_array.js ================================================ /* eslint-disable no-unused-vars */ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.fromArray()', (t) => { t.end() }) // TODO: Implement csv.fromArray() // test('should be able to format a multi-cell entry', (t) => { // let result = csv.fromArray(fixtures.array_obj) // let expect = fixtures.array_csv // t.deepEqual(result, expect) // t.end() // }) ================================================ FILE: test/csv.from_arrays.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.fromArrays() - should be able to format multi-entry/multi-cell data set', (t) => { const result = csv.fromArrays(fixtures.arrays1_obj) const expect = fixtures.arrays1_csv t.deepEqual(result, expect) t.end() }) test('$.csv.fromArrays() - should be able to format multi-entry/multi-cell data set with escaped delimiters', (t) => { const result = csv.fromArrays(fixtures.arrays2_obj) console.dir(result) const expect = fixtures.arrays2_csv t.deepEqual(result, expect) t.end() }) ================================================ FILE: test/csv.from_objects.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.fromObjects() - should parse javascript object to a csv', (t) => { const result = csv.fromObjects(fixtures.objects_obj) t.deepEquals(result, fixtures.objects2_csv) t.end() }) ================================================ FILE: test/csv.on_parse_entry_hook.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.toObjects onParseEntry hook callback - should be passed the data and state', (t) => { let passedData, passedState csv.toObjects(fixtures.objects_csv, { onParseEntry: (data, state) => { passedData = data passedState = state return data } }) t.isNot(passedData, null, 'data argument should not be null') t.isNot(passedState, null, 'state argument should not be null') t.end() }) test('$.csv.toArrays onParseEntry hook callback - should be passed the data and state', (t) => { let passedData, passedState csv.toArrays(fixtures.arrays1_csv, { onParseEntry: (data, state) => { passedData = data passedState = state return data } }) t.isNot(passedData, null, 'data argument should not be null') t.isNot(passedState, null, 'state argument should not be null') t.end() }) test('$.csv.toObjects onParseEntry hook callback - should affect return value', (t) => { const returnMutatedEntry = (entry, state) => (state.rowNum === 2) ? false : entry const result = csv.toObjects(fixtures.entry_objects_csv, { onParseEntry: returnMutatedEntry }) t.deepEqual(result, fixtures.entry_objects_obj, 'return value should reflect what was returned from callback') t.end() }) test('$.csv.toArrays onParseEntry hook callback - should affect return value', (t) => { const returnMutatedEntry = (entry, state) => (state.rowNum === 2) ? false : entry const result = csv.toArrays(fixtures.entry_arrays_csv, { onParseEntry: returnMutatedEntry }) t.deepEqual(result, fixtures.entry_arrays_obj, 'return value should reflect what was returned from callback') t.end() }) test('$.csv.toObjects onParseEntry hook callback - should have correct state', (t) => { const checkEntryState = (entry, state) => { if (state.rowNum === 3) { t.equal(entry, 'keep3') } return entry } csv.toObjects(fixtures.entry_objects_csv, { onParseEntry: checkEntryState }) t.end() }) test('$.csv.toArrays onParseEntry hook callback - should have correct state', (t) => { const checkEntryState = (entry, state) => { if (state.rowNum === 3) { t.deepEqual(entry, ['keep3']) } return entry } csv.toArrays(fixtures.entry_arrays_csv, { onParseEntry: checkEntryState }) t.end() }) ================================================ FILE: test/csv.on_parse_value_hook.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.toObjects onParseValue hook callback - should be passed the data and state', (t) => { let passedData, passedState csv.toObjects(fixtures.objects_csv, { onParseValue: (data, state) => { passedData = data passedState = state return data } }) t.isNot(passedData, null, 'data argument should not be null') t.isNot(passedState, null, 'state argument should not be null') t.end() }) test('$.csv.toArrays onParseValue hook callback - should be passed the data and state', (t) => { let passedData, passedState csv.toArrays(fixtures.arrays1_csv, { onParseValue: (data, state) => { passedData = data passedState = state return data } }) t.isNot(passedData, null, 'data argument should not be null') t.isNot(passedState, null, 'state argument should not be null') t.end() }) test('$.csv.toObjects onParseValue hook callback - should affect return value', (t) => { const returnMutatedValues = (value) => value + 'a' const result = csv.toObjects(fixtures.value_objects_csv, { onParseValue: returnMutatedValues }) t.deepEqual(result, fixtures.value_objects_obj, 'return value should reflect what was returned from callback') t.end() }) test('$.csv.toObjects onParseValue hook callback - should have correct state', (t) => { const checkValueState = (value, state) => { if (state.rowNum === 2 && state.colNum === 3) { t.equal(value, 'some') } return value } csv.toObjects(fixtures.value_objects_csv, { onParseValue: checkValueState }) t.end() }) test('$.csv.toArrays onParseValue hook callback - should have correct state', (t) => { const checkValueState = (value, state) => { if (state.rowNum === 1 && state.colNum === 3) { t.equal(value, 'some') } return value } csv.toArrays(fixtures.value_arrays_csv, { onParseValue: checkValueState }) t.end() }) ================================================ FILE: test/csv.on_post_parse_hook.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.toObjects onPostParse hook callback - should be passed the data and state', (t) => { let passedData, passedState csv.toObjects(fixtures.objects_csv, { onPostParse: (data, state) => { passedData = data passedState = state } }) t.isNot(passedData, null, 'data argument should not be null') t.isNot(passedState, null, 'state argument should not be null') t.end() }) test('$.csv.toArrays onPostParse hook callback - should be passed the data and state', (t) => { let passedData, passedState csv.toArrays(fixtures.arrays1_csv, { onPostParse: (data, state) => { passedData = data passedState = state } }) t.isNot(passedData, null, 'data argument should not be null') t.isNot(passedState, null, 'state argument should not be null') t.end() }) test('$.csv.toObjects onPostParse hook callback - should affect return value', (t) => { const returnEmptyArray = () => [] const result = csv.toObjects(fixtures.objects_csv, { onPostParse: returnEmptyArray }) t.deepEqual(result, [], 'return value should reflect what was returned from callback') t.end() }) test('$.csv.toArrays onPostParse hook callback - should affect return value', (t) => { const returnEmptyArray = () => [] const result = csv.toArrays(fixtures.arrays1_csv, { onPostParse: returnEmptyArray }) t.deepEqual(result, [], 'return value should reflect what was returned from callback') t.end() }) ================================================ FILE: test/csv.on_pre_parse_hook.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.toObjects onPreParse hook callback - should be passed the raw csv and state', (t) => { let passedCSV, passedState csv.toObjects(fixtures.objects_csv, { onPreParse: (csv, state) => { passedCSV = csv passedState = state return csv } }) t.isNot(passedCSV, null, 'data argument should not be null') t.isNot(passedState, null, 'state argument should not be null') t.end() }) test('$.csv.toArrays onPreParse hook callback - should be passed the raw csv and state', (t) => { let passedCSV, passedState csv.toArrays(fixtures.arrays1_csv, { onPreParse: (csv, state) => { passedCSV = csv passedState = state return csv } }) t.isNot(passedCSV, null, 'data argument should not be null') t.isNot(passedState, null, 'state argument should not be null') t.end() }) test('$.csv.toObjects onPreParse hook callback - should affect return value', (t) => { const returnEmptyCSV = () => 'header\n""' const result = csv.toObjects(fixtures.objects_csv, { onPreParse: returnEmptyCSV }) t.deepEqual(result, [{ header: '' }], 'return value should reflect what was returned from callback') t.end() }) test('$.csv.toArrays onPreParse hook callback - should affect return value', (t) => { const returnEmptyCSV = () => '' const result = csv.toArrays(fixtures.arrays1_csv, { onPreParse: returnEmptyCSV }) t.deepEqual(result, [], 'return value should reflect what was returned from callback') t.end() }) ================================================ FILE: test/csv.parsers.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.parsers.splitLines() - should correctly split lines with default options', (t) => { const result = csv.parsers.splitLines(fixtures.defaults_fivelines_csv) t.equal(typeof (result), 'object', 'the returned object should be an array') t.true(Array.isArray(result), 'the returned object should be an array') t.equal(result.length, 5, 'the returned array should contain 5 lines') t.end() }) test('$.csv.parsers.splitLines() - should correctly split lines with custom separator', (t) => { const options = { separator: ';' } const result = csv.parsers.splitLines(fixtures.separator_fivelines_csv, options) t.equal(typeof (result), 'object', 'the returned object should be an array') t.true(Array.isArray(result), 'the returned object should be an array') t.equal(result.length, 5, 'the returned array should contain 5 lines') t.end() }) test('$.csv.parsers.splitLines() - should throw an error for using the wrong separator', (t) => { const options = { separator: ';' } function splitLines () { csv.parsers.splitLines(fixtures.defaults_fivelines_csv, options) } t.throws(splitLines) t.end() }) test('$.csv.parsers.splitLines() - should correctly split lines with custom delimiter', (t) => { const options = { delimiter: "'" } const result = csv.parsers.splitLines(fixtures.delimiter_fivelines_csv, options) t.equal(typeof (result), 'object', 'the returned object should be an array') t.true(Array.isArray(result), 'the returned object should be an array') t.equal(result.length, 5, 'the returned array should contain 5 lines') t.end() }) test('$.csv.parsers.splitLines() - should return undefined when csv is undefined', (t) => { const result = csv.parsers.splitLines() t.equal(typeof (result), 'undefined') t.end() }) ================================================ FILE: test/csv.to_array.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.toArray() - should be able to parse an entry containing multiple cells', (t) => { const result = csv.toArray(fixtures.array_csv) const expect = fixtures.array_obj t.deepEqual(result, expect) t.end() }) test('$.csv.toArray() - should return [""] when input is empty', (t) => { const result = csv.toArray('') t.equal(result.length, 1) t.end() }) test('$.csv.toArray() - should return ["a1"] when input is "a1"', (t) => { const result = csv.toArray('a1') t.equal(result.length, 1) t.equal(result[0], 'a1') t.end() }) ================================================ FILE: test/csv.to_arrays.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.toArrays() - should be able to parse multi-entry/multi-cell input', (t) => { const result = csv.toArrays(fixtures.arrays1_csv) const expect = fixtures.arrays1_obj t.deepEqual(result, expect) t.end() }) test('$.csv.toArrays() - should be able to parse multi-entry/multi-cell input with escaped delimiters', (t) => { const result = csv.toArrays(fixtures.arrays2_csv) const expect = fixtures.arrays2_obj t.deepEqual(result, expect) t.end() }) ================================================ FILE: test/csv.to_objects.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('$.csv.toObjects() - should parse csv to a javascript object', (t) => { const result = csv.toObjects(fixtures.objects_csv) t.deepEquals(result, fixtures.objects_obj) t.end() }) ================================================ FILE: test/edge_cases.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('Edge Case - should properly escape backslashes', (t) => { const result = csv.toObjects(fixtures.backslash_csv) const expect = fixtures.backslash_obj t.deepEqual(result, expect) t.end() }) test('Edge Case - should support \\n (unix) line endings', (t) => { const result = csv.toArrays(fixtures.newline_unix) t.equal(result.length, 2) t.end() }) test('Edge Case - should support \\r (mac) line endings', (t) => { const result = csv.toArrays(fixtures.newline_mac) t.equal(result.length, 2) t.end() }) test('Edge Case - should support \\r\\n (dos) line endings', (t) => { const result = csv.toArrays(fixtures.newline_dos) t.equal(result.length, 2) t.end() }) ================================================ FILE: test/fixtures/array.csv ================================================ "You will come back stronger then ever","like Lance Armstrong","but with two balls" ================================================ FILE: test/fixtures/array.json ================================================ [ "You will come back stronger then ever", "like Lance Armstrong", "but with two balls" ] ================================================ FILE: test/fixtures/arrays1.csv ================================================ All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... ================================================ FILE: test/fixtures/arrays1.json ================================================ [ ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."] ] ================================================ FILE: test/fixtures/arrays2.csv ================================================ All work,and no play,makes Jack,a dull boy... All work,and no play,"makes ""Jack",a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,"a ""dull"" boy..." All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... "All ""work",and no play,makes Jack,a dull boy... All work,and no play,makes Jack,a dull boy... ================================================ FILE: test/fixtures/arrays2.json ================================================ [ ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes \"Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a \"dull\" boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."], ["All \"work","and no play","makes Jack","a dull boy..."], ["All work","and no play","makes Jack","a dull boy..."] ] ================================================ FILE: test/fixtures/backslash.csv ================================================ test1,test2 data1,data2\3 ================================================ FILE: test/fixtures/backslash.json ================================================ [ { "test1":"data1", "test2":"data2\\3" } ] ================================================ FILE: test/fixtures/defaults.csv ================================================ "1","he said ""you are crazy""","one "", two "", three """ ================================================ FILE: test/fixtures/defaults.json ================================================ [ "1", "he said \"you are crazy\"", "one \", two \", three \"" ] ================================================ FILE: test/fixtures/defaults_fivelines.csv ================================================ "1","he said ""you are crazy""","one "", two "", three """ "2","he said ""you are crazy""","one "", two "", three """ "3","he said ""you are crazy""","one "", two "", three """ "4","he said ""you are crazy""","one "", two "", three """ "5","he said ""you are crazy""","one "", two "", three """ ================================================ FILE: test/fixtures/delimiter.csv ================================================ '2','he said ''you are crazy''','one '', two '', three ''' ================================================ FILE: test/fixtures/delimiter.json ================================================ [ "2", "he said 'you are crazy'", "one ', two ', three '" ] ================================================ FILE: test/fixtures/delimiter_fivelines.csv ================================================ '2','he said ''you are crazy''','one '', two '', three ''' '2','he said ''you are crazy''','one '', two '', three ''' '2','he said ''you are crazy''','one '', two '', three ''' '2','he said ''you are crazy''','one '', two '', three ''' '2','he said ''you are crazy''','one '', two '', three ''' ================================================ FILE: test/fixtures/entry_arrays.csv ================================================ keep1 remove2 keep3 keep4 ================================================ FILE: test/fixtures/entry_arrays.json ================================================ [ ["keep1"], ["keep3"], ["keep4"] ] ================================================ FILE: test/fixtures/entry_objects.csv ================================================ header remove2 keep3 keep4 ================================================ FILE: test/fixtures/entry_objects.json ================================================ [ { "header": "keep3" }, { "header": "keep4" } ] ================================================ FILE: test/fixtures/fixtures.js ================================================ const fs = require('fs') function csvFixture (fixtureName) { return fs.readFileSync('./test/fixtures/' + fixtureName + '.csv', 'utf8') } function jsonFixture (fixtureName) { return JSON.parse(fs.readFileSync('./test/fixtures/' + fixtureName + '.json')) } module.exports = { array_csv: csvFixture('array'), array_obj: jsonFixture('array'), arrays1_csv: csvFixture('arrays1'), arrays1_obj: jsonFixture('arrays1'), arrays2_csv: csvFixture('arrays2'), arrays2_obj: jsonFixture('arrays2'), rfc1_csv: csvFixture('rfc1'), rfc1_obj: jsonFixture('rfc1'), rfc2_csv: csvFixture('rfc2'), rfc2_obj: jsonFixture('rfc2'), rfc3_csv: csvFixture('rfc3'), rfc3_obj: jsonFixture('rfc3'), rfc4_csv: csvFixture('rfc4'), rfc4_obj: jsonFixture('rfc4'), rfc5_csv: csvFixture('rfc5'), rfc5_obj: jsonFixture('rfc5'), rfc6_csv: csvFixture('rfc6'), rfc6_obj: jsonFixture('rfc6'), rfc7_csv: csvFixture('rfc7'), rfc7_obj: jsonFixture('rfc7'), rfcA1_csv: csvFixture('rfcA1'), rfcA1_obj: jsonFixture('rfcA1'), rfcA2_csv: csvFixture('rfcA2'), rfcA2_obj: jsonFixture('rfcA2'), rfcA3_csv: csvFixture('rfcA3'), rfcA3_obj: jsonFixture('rfcA3'), newline_unix: csvFixture('newline_unix'), newline_dos: csvFixture('newline_dos'), newline_mac: csvFixture('newline_mac'), defaults_csv: csvFixture('defaults'), defaults_obj: jsonFixture('defaults'), defaults_fivelines_csv: csvFixture('defaults_fivelines'), delimiter_csv: csvFixture('delimiter'), delimiter_obj: jsonFixture('delimiter'), delimiter_fivelines_csv: csvFixture('delimiter_fivelines'), separator_csv: csvFixture('separator'), separator_obj: jsonFixture('separator'), separator_fivelines_csv: csvFixture('separator_fivelines'), regex_csv: csvFixture('regex'), regex_obj: jsonFixture('regex'), regex2_csv: csvFixture('regex2'), regex2_obj: jsonFixture('regex2'), regex3_csv: csvFixture('regex3'), regex3_obj: jsonFixture('regex3'), term_arrays_csv: csvFixture('term_arrays'), term_arrays_obj: jsonFixture('term_arrays'), term_objects_csv: csvFixture('term_objects'), term_objects_obj: jsonFixture('term_objects'), backslash_csv: csvFixture('backslash'), backslash_obj: jsonFixture('backslash'), objects_csv: csvFixture('objects'), objects_obj: jsonFixture('objects'), objects2_csv: csvFixture('objects2'), value_arrays_csv: csvFixture('value_arrays'), value_arrays_obj: jsonFixture('value_arrays'), value_objects_csv: csvFixture('value_objects'), value_objects_obj: jsonFixture('value_objects'), entry_arrays_csv: csvFixture('entry_arrays'), entry_arrays_obj: jsonFixture('entry_arrays'), entry_objects_csv: csvFixture('entry_objects'), entry_objects_obj: jsonFixture('entry_objects') } ================================================ FILE: test/fixtures/newline_dos.csv ================================================ a1 a2 ================================================ FILE: test/fixtures/newline_mac.csv ================================================ a1 a2 ================================================ FILE: test/fixtures/newline_unix.csv ================================================ a1 a2 ================================================ FILE: test/fixtures/objects.csv ================================================ "ID","iManufacturer","iMPartNumber","iSerialNumber","iSimCategory","iPartType","iDescription","iGroup","iLocation","iSold" "1","Evans & Sutherland","230-132-111AA","","Visual","PCB","","1","Offsite","" "2","Evans & Sutherland","230-132-111AA","","Visual","PCB","","1","Offsite","" "3","Evans & Sutherland","230-120-112AC","","Visual","PCB","","1","Offsite","" "4","Evans & Sutherland","230-120-112AC","","Visual","PCB","","1","Offsite","" "5","Evans & Sutherland","230-120-112AC","","Visual","PCB","","1","Offsite","" "6","Evans & Sutherland","230-120-112AC","","Visual","PCB","","1","Offsite","" "7","Evans & Sutherland","230-120-112AC","","Visual","PCB","","1","Offsite","" "8","Evans & Sutherland","230-120-112AC","","Visual","PCB","","1","Offsite","" "9","Evans & Sutherland","230-120-112AC","","Visual","PCB","","1","Offsite","" "10","Evans & Sutherland","230-121-150AC","","Visual","PCB","","1","Offsite","" ================================================ FILE: test/fixtures/objects.json ================================================ [ { "ID":"1", "iManufacturer":"Evans & Sutherland", "iMPartNumber":"230-132-111AA", "iSerialNumber":"", "iSimCategory":"Visual", "iPartType":"PCB", "iDescription":"", "iGroup":"1", "iLocation":"Offsite", "iSold":"" }, { "ID":"2", "iManufacturer":"Evans & Sutherland", "iMPartNumber":"230-132-111AA", "iSerialNumber":"", "iSimCategory":"Visual", "iPartType":"PCB", "iDescription":"", "iGroup":"1", "iLocation":"Offsite", "iSold":"" }, { "ID":"3", "iManufacturer":"Evans & Sutherland", "iMPartNumber":"230-120-112AC", "iSerialNumber":"", "iSimCategory":"Visual", "iPartType":"PCB", "iDescription":"", "iGroup":"1", "iLocation":"Offsite", "iSold":"" }, { "ID":"4", "iManufacturer":"Evans & Sutherland", "iMPartNumber":"230-120-112AC", "iSerialNumber":"", "iSimCategory":"Visual", "iPartType":"PCB", "iDescription":"", "iGroup":"1", "iLocation":"Offsite", "iSold":"" }, { "ID":"5", "iManufacturer":"Evans & Sutherland", "iMPartNumber":"230-120-112AC", "iSerialNumber":"", "iSimCategory":"Visual", "iPartType":"PCB", "iDescription":"", "iGroup":"1", "iLocation":"Offsite", "iSold":"" }, { "ID":"6", "iManufacturer":"Evans & Sutherland", "iMPartNumber":"230-120-112AC", "iSerialNumber":"", "iSimCategory":"Visual", "iPartType":"PCB", "iDescription":"", "iGroup":"1", "iLocation":"Offsite", "iSold":"" }, { "ID":"7", "iManufacturer":"Evans & Sutherland", "iMPartNumber":"230-120-112AC", "iSerialNumber":"", "iSimCategory":"Visual", "iPartType":"PCB", "iDescription":"", "iGroup":"1", "iLocation":"Offsite", "iSold":"" }, { "ID":"8", "iManufacturer":"Evans & Sutherland", "iMPartNumber":"230-120-112AC", "iSerialNumber":"", "iSimCategory":"Visual", "iPartType":"PCB", "iDescription":"", "iGroup":"1", "iLocation":"Offsite", "iSold":"" }, { "ID":"9", "iManufacturer":"Evans & Sutherland", "iMPartNumber":"230-120-112AC", "iSerialNumber":"", "iSimCategory":"Visual", "iPartType":"PCB", "iDescription":"", "iGroup":"1", "iLocation":"Offsite", "iSold":"" }, { "ID":"10", "iManufacturer":"Evans & Sutherland", "iMPartNumber":"230-121-150AC", "iSerialNumber":"", "iSimCategory":"Visual", "iPartType":"PCB", "iDescription":"", "iGroup":"1", "iLocation":"Offsite", "iSold":"" } ] ================================================ FILE: test/fixtures/objects2.csv ================================================ ID,iManufacturer,iMPartNumber,iSerialNumber,iSimCategory,iPartType,iDescription,iGroup,iLocation,iSold 1,Evans & Sutherland,230-132-111AA,,Visual,PCB,,1,Offsite, 2,Evans & Sutherland,230-132-111AA,,Visual,PCB,,1,Offsite, 3,Evans & Sutherland,230-120-112AC,,Visual,PCB,,1,Offsite, 4,Evans & Sutherland,230-120-112AC,,Visual,PCB,,1,Offsite, 5,Evans & Sutherland,230-120-112AC,,Visual,PCB,,1,Offsite, 6,Evans & Sutherland,230-120-112AC,,Visual,PCB,,1,Offsite, 7,Evans & Sutherland,230-120-112AC,,Visual,PCB,,1,Offsite, 8,Evans & Sutherland,230-120-112AC,,Visual,PCB,,1,Offsite, 9,Evans & Sutherland,230-120-112AC,,Visual,PCB,,1,Offsite, 10,Evans & Sutherland,230-121-150AC,,Visual,PCB,,1,Offsite, ================================================ FILE: test/fixtures/regex.csv ================================================ "4"|"he said ""you are crazy"""|"one "", two "", three """ ================================================ FILE: test/fixtures/regex.json ================================================ [ "4", "he said \"you are crazy\"", "one \", two \", three \"" ] ================================================ FILE: test/fixtures/regex2.csv ================================================ "3"("he said ""you are crazy"""("one "", two "", three """ ================================================ FILE: test/fixtures/regex2.json ================================================ [ "3", "he said \"you are crazy\"", "one \", two \", three \"" ] ================================================ FILE: test/fixtures/regex3.csv ================================================ *3*,*he said **you are crazy***,*one **, two **, three *** ================================================ FILE: test/fixtures/regex3.json ================================================ [ "3", "he said *you are crazy*", "one *, two *, three *" ] ================================================ FILE: test/fixtures/rfc1.csv ================================================ aaa,bbb,ccc zzz,yyy,xxx ================================================ FILE: test/fixtures/rfc1.json ================================================ [ [ "aaa", "bbb", "ccc" ], [ "zzz", "yyy", "xxx" ] ] ================================================ FILE: test/fixtures/rfc2.csv ================================================ aaa,bbb,ccc zzz,yyy,xxx ================================================ FILE: test/fixtures/rfc2.json ================================================ [ [ "aaa", "bbb", "ccc" ], [ "zzz", "yyy", "xxx" ] ] ================================================ FILE: test/fixtures/rfc3.csv ================================================ field1,field2,field3 aaa,bbb,ccc zzz,yyy,xxx ================================================ FILE: test/fixtures/rfc3.json ================================================ [ { "field1":"aaa", "field2":"bbb", "field3":"ccc" }, { "field1":"zzz", "field2":"yyy", "field3":"xxx" } ] ================================================ FILE: test/fixtures/rfc4.csv ================================================ aaa , bbb, c cc ================================================ FILE: test/fixtures/rfc4.json ================================================ [ "aaa ", " bbb", " c cc" ] ================================================ FILE: test/fixtures/rfc5.csv ================================================ "aaa","bbb","ccc" zzz,yyy,xxx ================================================ FILE: test/fixtures/rfc5.json ================================================ [ [ "aaa", "bbb", "ccc" ], [ "zzz", "yyy", "xxx" ] ] ================================================ FILE: test/fixtures/rfc6.csv ================================================ "aaa","b\r\nbb","cc,c" zzz,yyy,xxx ================================================ FILE: test/fixtures/rfc6.json ================================================ [ [ "aaa", "b\\r\\nbb", "cc,c" ], [ "zzz", "yyy", "xxx" ] ] ================================================ FILE: test/fixtures/rfc7.csv ================================================ "aaa","b""bb","ccc" ================================================ FILE: test/fixtures/rfc7.json ================================================ [ "aaa", "b\"bb", "ccc" ] ================================================ FILE: test/fixtures/rfcA1.csv ================================================ aaa,,ccc ================================================ FILE: test/fixtures/rfcA1.json ================================================ [ "aaa", "", "ccc" ] ================================================ FILE: test/fixtures/rfcA2.csv ================================================ "aaa","","ccc" ================================================ FILE: test/fixtures/rfcA2.json ================================================ [ "aaa", "", "ccc" ] ================================================ FILE: test/fixtures/rfcA3.csv ================================================ "aaa","bbb", ================================================ FILE: test/fixtures/rfcA3.json ================================================ [ "aaa", "bbb", "" ] ================================================ FILE: test/fixtures/separator.csv ================================================ "3";"he said ""you are crazy""";"one "", two "", three """ ================================================ FILE: test/fixtures/separator.json ================================================ [ "3", "he said \"you are crazy\"", "one \", two \", three \"" ] ================================================ FILE: test/fixtures/separator_fivelines.csv ================================================ "3";"he said ""you are crazy""";"one "", two "", three """ "3";"he said ""you are crazy""";"one "", two "", three """ "3";"he said ""you are crazy""";"one "", two "", three """ "3";"he said ""you are crazy""";"one "", two "", three """ "3";"he said ""you are crazy""";"one "", two "", three """ ================================================ FILE: test/fixtures/term_arrays.csv ================================================ *Look*:*there's two women*:*fucking a polar bear!* *Don't*:*tell me these things*:*not now man.* ================================================ FILE: test/fixtures/term_arrays.json ================================================ [ [ "Look", "there's two women", "fucking a polar bear!" ], [ "Don't", "tell me these things", "not now man." ] ] ================================================ FILE: test/fixtures/term_objects.csv ================================================ ^preposition^&^evaluation^&^response^ ^One toke?^&^you poor fool!^&^wait till you see those goddamn bats.^ ^Wait!^&^we can't stop here^&^this is bat country.^ ================================================ FILE: test/fixtures/term_objects.json ================================================ [ { "preposition":"One toke?", "evaluation":"you poor fool!", "response":"wait till you see those goddamn bats." }, { "preposition":"Wait!", "evaluation":"we can't stop here", "response":"this is bat country." } ] ================================================ FILE: test/fixtures/value_arrays.csv ================================================ this,is,some,data ================================================ FILE: test/fixtures/value_arrays.json ================================================ [ [ "thisa", "isa", "somea", "dataa" ] ] ================================================ FILE: test/fixtures/value_objects.csv ================================================ h1,h2,h3,h4 this,is,some,data ================================================ FILE: test/fixtures/value_objects.json ================================================ [ { "h1": "thisa", "h2": "isa", "h3": "somea", "h4": "dataa" } ] ================================================ FILE: test/options.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('Options - should parse using the default terminals', (t) => { const result = csv.toArray(fixtures.defaults_csv) const expect = fixtures.defaults_obj t.deepEqual(result, expect) t.end() }) test('Options - should parse using a custom delimiter', (t) => { const options = { delimiter: '\'' } const result = csv.toArray(fixtures.delimiter_csv, options) const expect = fixtures.delimiter_obj t.deepEqual(result, expect) t.end() }) test('Options - should parse using a custom separator', (t) => { const options = { separator: ';' } const result = csv.toArray(fixtures.separator_csv, options) const expect = fixtures.separator_obj t.deepEqual(result, expect) t.end() }) test('Options - should properly escape regex special chars', (t) => { const options = { separator: '|' } const result = csv.toArray(fixtures.regex_csv, options) const expect = fixtures.regex_obj t.deepEqual(result, expect) t.end() }) test('Options - should properly escape regex ( chars', (t) => { const options = { separator: '(' } const result = csv.toArray(fixtures.regex2_csv, options) const expect = fixtures.regex2_obj t.deepEqual(result, expect) t.end() }) test('Options - should properly escape regex * chars', (t) => { const options = { delimiter: '*' } const result = csv.toArray(fixtures.regex3_csv, options) const expect = fixtures.regex3_obj t.deepEqual(result, expect) t.end() }) test('Options - should support custom terminals via toArrays()', (t) => { const options = { delimiter: '*', separator: ':' } const result = csv.toArrays(fixtures.term_arrays_csv, options) const expect = fixtures.term_arrays_obj t.deepEqual(result, expect) t.end() }) test('Options - should support custom terminals via toObjects()', (t) => { const options = { delimiter: '^', separator: '&' } const result = csv.toObjects(fixtures.term_objects_csv, options) const expect = fixtures.term_objects_obj t.deepEqual(result, expect) t.end() }) ================================================ FILE: test/rfc_amendments.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('RFC Amendment #1 - An unquoted field may contain a null (ie empty) value', (t) => { const result = csv.toArray(fixtures.rfcA1_csv) const expect = fixtures.rfcA1_obj t.deepEqual(result, expect) t.end() }) test('RFC Amendment #2 - A quoted field may contain a null (ie empty) value', (t) => { const result = csv.toArray(fixtures.rfcA2_csv) const expect = fixtures.rfcA2_obj t.deepEqual(result, expect) t.end() }) test('RFC Amendment #3 - The last field in an entry may contain a null (ie empty) value', (t) => { const result = csv.toArray(fixtures.rfcA3_csv) const expect = fixtures.rfcA3_obj t.deepEqual(result, expect) t.end() }) ================================================ FILE: test/rfc_compliance.js ================================================ const test = require('tape') const csv = require('../src/jquery.csv.js') const fixtures = require('./fixtures/fixtures.js') test('RFC Rule #1 - One entry per line, each line ends with a newline', (t) => { const result = csv.toArrays(fixtures.rfc1_csv) const expect = fixtures.rfc1_obj t.deepEqual(result, expect) t.end() }) test('RFC Rule #2 - Trailing newline at the end of the file ommitted', (t) => { const result = csv.toArrays(fixtures.rfc2_csv) const expect = fixtures.rfc2_obj t.deepEqual(result, expect) t.end() }) test('RFC Rule #3 - First row contains header data', (t) => { const result = csv.toObjects(fixtures.rfc3_csv) const expect = fixtures.rfc3_obj t.deepEqual(result, expect) t.end() }) test('RFC Rule #4 - Spaces are considered data and entries should not contain a trailing comma', (t) => { const result = csv.toArray(fixtures.rfc4_csv) const expect = fixtures.rfc4_obj t.deepEqual(result, expect) t.end() }) test('RFC Rule #5 - Lines may or may not be delimited by double-quotes', (t) => { const result = csv.toArrays(fixtures.rfc5_csv) const expect = fixtures.rfc5_obj t.deepEqual(result, expect) t.end() }) test('RFC Rule #6 - Fields containing line breaks, double-quotes, and commas should be enclosed in double-quotes', (t) => { const result = csv.toArrays(fixtures.rfc6_csv) const expect = fixtures.rfc6_obj t.deepEqual(result, expect) t.end() }) test('RFC Rule #7 - If double-quotes are used to enclose fields, then a double-quote appering inside a field must be escaped by a preceding it with another double-quote', (t) => { const result = csv.toArray(fixtures.rfc7_csv) const expect = fixtures.rfc7_obj t.deepEqual(result, expect) t.end() })