├── .gitignore
├── LICENSE-GPL3.txt
├── LICENSE-MIT.txt
├── changelog.txt
├── dist
├── test
│ ├── arrayToCsv.js
│ ├── csvToArray.js
│ ├── csvToObject.js
│ ├── lib
│ │ ├── qunit-1.13.0.css
│ │ └── qunit-1.13.0.js
│ ├── objectToCsv.js
│ └── tests.html
└── ucsv-1.2.0.min.js
├── docs
├── api.js
├── assets
│ ├── css
│ │ ├── external-small.png
│ │ ├── logo.png
│ │ └── main.css
│ ├── favicon.png
│ ├── img
│ │ └── spinner.gif
│ ├── index.html
│ ├── js
│ │ ├── api-filter.js
│ │ ├── api-list.js
│ │ ├── api-search.js
│ │ ├── apidocs.js
│ │ └── yui-prettify.js
│ └── vendor
│ │ └── prettify
│ │ ├── CHANGES.html
│ │ ├── COPYING
│ │ ├── README.html
│ │ ├── prettify-min.css
│ │ └── prettify-min.js
├── classes
│ ├── CSV.html
│ └── index.html
├── data.json
├── files
│ ├── index.html
│ ├── source_core.js.html
│ └── source_intro.js.html
├── index.html
└── modules
│ └── index.html
├── gruntfile.js
├── package.json
├── readme.md
├── source
├── core.js
├── intro.js
└── outro.js
└── test
├── arrayToCsv.js
├── csvToArray.js
├── csvToObject.js
├── internal.js
├── lib
├── qunit-1.13.0.css
└── qunit-1.13.0.js
├── objectToCsv.js
└── tests.html
/.gitignore:
--------------------------------------------------------------------------------
1 | junk
2 | node_modules
--------------------------------------------------------------------------------
/LICENSE-GPL3.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uselesscode/ucsv/d7c653add0832633a08134e79634459a0b8bfcc3/LICENSE-GPL3.txt
--------------------------------------------------------------------------------
/LICENSE-MIT.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2014 Peter Johnson, http://www.UselessCode.org
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/changelog.txt:
--------------------------------------------------------------------------------
1 | 1.2.0
2 | ---
3 | New features and changes
4 | * New csvToObject and objectToCsv methods to read and write CSV data as an
5 | array of objects.
6 | * Converted build system from Apache Ant to Grunt.
7 | * Converted documentation from JSDoc to YUIDoc.
8 | * csvToArray now takes a configuration object as it's second parameter instead
9 | of a boolean. In this version the old semantic is still supported but
10 | deprecated and will likely be removed in the next version due to upcoming
11 | backwards compatibility breaking changes in the library.
12 |
13 | Bug fixes
14 | * If an undefined value is in the input to arrayToCsv it will now be considered
15 | an empty field.
16 | * When reading CSV files unquoted numbers are treated as numbers even with
17 | leading or trailing whitespace.
18 |
19 | 1.1.0
20 | ---
21 | * Added support for use as a CommonJS module. This enables using UCSV as a
22 | library in Mozilla (Jetpack) Add-ons. It should also allow use in Node.js
23 | environments. Moved the strict mode declaration into the closure and cleaned
24 | up some other formatting to make JSLint happy.
25 |
26 | 1.0.3
27 | ---
28 | * Bug fix in arrayToCsv. arrayToCsv now wraps lines containing newline
29 | characters with double-quotes as was originally intended. Thanks goes to Colin
30 | Keenan for discovering and reporting this bug. (http://code.google.com/p/rentap/)
31 |
32 | 1.0.2
33 | ---
34 | * csvToArray now returns empty fields as nulls instead of empty strings as
35 | suggested by Leon Bambrick (http://secretGeek.net).
36 | * csvToArray now converts non-quoted integers and floats to the appropriate type
37 | instead of assuming they are strings.
38 |
39 | * Minor spelling fix.
40 |
41 | 1.0.1
42 | ---
43 | * A couple of tweaks to get JSLint passing again.
44 | * Removed the global flag from the trim function's RegExps to improve the performance.
45 |
--------------------------------------------------------------------------------
/dist/test/arrayToCsv.js:
--------------------------------------------------------------------------------
1 | /*global strictEqual, module */
2 | (function () {
3 | "use strict";
4 | module('arrayToCsv');
5 |
6 | test('arrayToCsv strings', function () {
7 | var csvArray = [
8 | ['XBOX "XBONE" One', 2013],
9 | ['Nintendo 64, AKA Nintendo Ultra 64', 1996],
10 | ['Playstation\n4', 2013]
11 | ],
12 | expected = '"XBOX ""XBONE"" One",2013\n' +
13 | '"Nintendo 64, AKA Nintendo Ultra 64",1996\n' +
14 | '"Playstation\n4",2013\n',
15 | csv = CSV.arrayToCsv(csvArray);
16 | strictEqual(csv, expected, 'Outputted correct CSV');
17 | });
18 |
19 | test('arrayToCsv integers', function () {
20 | var csvArray = [[1, 2, 3], [4, 5, 6]],
21 | csv = CSV.arrayToCsv(csvArray),
22 | expected = '1,2,3\n4,5,6\n';
23 | strictEqual(csv, expected, 'Outputted correct CSV');
24 | });
25 |
26 | test('arrayToCsv no trim', function () {
27 | var csvArray = [['no need to trim', ' should not trim 1', 'should not trim 2 ', ' should not trim 3 ']],
28 | csv = CSV.arrayToCsv(csvArray),
29 | expected = 'no need to trim," should not trim 1","should not trim 2 "," should not trim 3 "\n';
30 | strictEqual(csv, expected);
31 | });
32 |
33 | test('arrayToCsv nulls are empty fields', function () {
34 | var csvArray = [["Tom", null, "Harry"]],
35 | csv = CSV.arrayToCsv(csvArray),
36 | expected = 'Tom,,Harry\n';
37 | strictEqual(csv, expected);
38 | });
39 |
40 | test('arrayToCsv undefined values are empty fields', function () {
41 | var csvArray = [["Tom", undefined, "Harry"]],
42 | csv = CSV.arrayToCsv(csvArray),
43 | expected = 'Tom,,Harry\n';
44 | strictEqual(csv, expected);
45 | });
46 |
47 | test('arrayToCsv integers and quoted integers', function () {
48 | var csvArray = [[1, 2, "3"]],
49 | csv = CSV.arrayToCsv(csvArray),
50 | expected = '1,2,"3"\n';
51 | strictEqual(csv, expected);
52 | });
53 |
54 | test('arrayToCsv floats and quoted floats', function () {
55 | var csvArray = [[1.5, 2.2, "3.14"]],
56 | csv = CSV.arrayToCsv(csvArray),
57 | expected = '1.5,2.2,"3.14"\n';
58 | strictEqual(csv, expected);
59 | });
60 |
61 | test('arrayToCsv empty strings are empty strings', function () {
62 | var csvArray = [["a", "", "b"]],
63 | csv = CSV.arrayToCsv(csvArray),
64 | expected = 'a,"",b\n';
65 | strictEqual(csv, expected);
66 | });
67 |
68 | test('arrayToCsv newline in string', function () {
69 | var csvArray = [["a", "b\nc", "d"]],
70 | csv = CSV.arrayToCsv(csvArray),
71 | expected = 'a,"b\nc",d\n';
72 | strictEqual(csv, expected);
73 | });
74 | }());
75 |
--------------------------------------------------------------------------------
/dist/test/csvToArray.js:
--------------------------------------------------------------------------------
1 | /*global deepEqual, module */
2 | (function () {
3 | "use strict";
4 | module('csvToArray');
5 |
6 | test('csvToArray strings', function () {
7 | var csv = '"XBOX ""XBONE"" One",2013\n' +
8 | '"Nintendo 64, AKA Nintendo Ultra 64",1996\n' +
9 | '"Playstation\n4",2013\n',
10 | expected = [
11 | ['XBOX "XBONE" One', 2013],
12 | ['Nintendo 64, AKA Nintendo Ultra 64', 1996],
13 | ['Playstation\n4', 2013]
14 | ],
15 | result = CSV.csvToArray(csv);
16 | deepEqual(result, expected);
17 | });
18 |
19 | test('csvToArray integers', function () {
20 | var csv = '1,2,3\n4,5,6',
21 | expected = [
22 | [1, 2, 3],
23 | [4, 5, 6]
24 | ],
25 | result = CSV.csvToArray(csv);
26 |
27 | deepEqual(result, expected);
28 | });
29 |
30 | test('csvToArray no config', function () {
31 | var csv = 'no need to trim, should not trim 1,should not trim 2 , should not trim 3 \n"quoted 1"," quoted 2","quoted 3 "," quoted 4 "',
32 | expected = [
33 | ['no need to trim', ' should not trim 1', 'should not trim 2 ', ' should not trim 3 '],
34 | ['quoted 1', ' quoted 2', 'quoted 3 ', ' quoted 4 ']
35 | ],
36 | result = CSV.csvToArray(csv);
37 |
38 | deepEqual(result, expected);
39 | });
40 |
41 | test('csvToArray integers', function () {
42 | var csv = '1,2,3\n4,5,6',
43 | expected = [
44 | [1, 2, 3],
45 | [4, 5, 6]
46 | ],
47 | result = CSV.csvToArray(csv);
48 |
49 | deepEqual(result, expected);
50 | });
51 |
52 | test('csvToArray integers with trailing newline', function () {
53 | var csv = '1,2,3\n4,5,6\n',
54 | expected = [
55 | [1, 2, 3],
56 | [4, 5, 6]
57 | ],
58 | result = CSV.csvToArray(csv);
59 |
60 | deepEqual(result, expected);
61 | });
62 |
63 | test('csvToArray config === false', function () {
64 | var csv = 'no need to trim, should not trim 1,should not trim 2 , should not trim 3 \n"quoted 1"," quoted 2","quoted 3 "," quoted 4 "',
65 | expected = [
66 | ['no need to trim', ' should not trim 1', 'should not trim 2 ', ' should not trim 3 '],
67 | ['quoted 1', ' quoted 2', 'quoted 3 ', ' quoted 4 ']
68 | ],
69 | result = CSV.csvToArray(csv, false);
70 | deepEqual(result, expected);
71 | });
72 |
73 | test('csvToArray config === true (legacy trim)', function () {
74 | var csv = 'no need to trim, should trim 1,should trim 2 , should trim 3 \n"quoted 1"," quoted 2","quoted 3 "," quoted 4 "',
75 | expected = [
76 | ['no need to trim', 'should trim 1', 'should trim 2', 'should trim 3'],
77 | ['quoted 1', ' quoted 2', 'quoted 3 ', ' quoted 4 ']
78 | ],
79 | result = CSV.csvToArray(csv, true);
80 | deepEqual(result, expected);
81 | });
82 |
83 | test('csvToArray config trim', function () {
84 | var csv = 'no need to trim, should trim 1,should trim 2 , should trim 3 \n"quoted 1"," quoted 2","quoted 3 "," quoted 4 "',
85 | expected = [
86 | ['no need to trim', 'should trim 1', 'should trim 2', 'should trim 3'],
87 | ['quoted 1', ' quoted 2', 'quoted 3 ', ' quoted 4 ']
88 | ],
89 | result = CSV.csvToArray(csv, {trim: true});
90 | deepEqual(result, expected);
91 | });
92 |
93 | test('csvToArray empty fields are null', function () {
94 | var csv = 'Billy West, Fry\nDavid X. Cohen,\nJohn Di Maggio,Bender',
95 | expected = [
96 | ['Billy West', 'Fry'],
97 | ['David X. Cohen', null],
98 | ['John Di Maggio', 'Bender']
99 | ],
100 | result = CSV.csvToArray(csv, true);
101 |
102 | deepEqual(result, expected);
103 | });
104 |
105 | test('csvToArray integers and quoted integers', function () {
106 | var csv = '1,2,"3"',
107 | expected = [
108 | [1, 2, '3']
109 | ],
110 | result = CSV.csvToArray(csv, true);
111 | deepEqual(result, expected);
112 | });
113 |
114 | test('csvToArray floats and quoted floats', function () {
115 | var csv = '1.5,2.2,"3.14"',
116 | expected = [
117 | [1.5, 2.2, '3.14']
118 | ],
119 | result = CSV.csvToArray(csv, true);
120 |
121 | deepEqual(result, expected);
122 | });
123 |
124 | test('csvToArray numbers are interpreted as numbers even when not trimming fields', function () {
125 | var csv = ' 1 , 2, 3.14',
126 | expected = [
127 | [1, 2, 3.14]
128 | ],
129 | result = CSV.csvToArray(csv, true);
130 | ok(Array.isArray(result), 'Result is an array');
131 | deepEqual(result, expected);
132 | });
133 |
134 | test('csvToArray newline in string', function () {
135 | var csv = 'a,"b\nc",d',
136 | expected = [
137 | ['a', 'b\nc', 'd']
138 | ],
139 | result = CSV.csvToArray(csv, true);
140 | deepEqual(result, expected);
141 | });
142 | }());
143 |
--------------------------------------------------------------------------------
/dist/test/csvToObject.js:
--------------------------------------------------------------------------------
1 | /*global deepEqual, module */
2 | (function () {
3 | "use strict";
4 | module('csvToObject');
5 | // All the actual parsing is done by csvToArray, so these tests do not thoroughly cover all aspects
6 | // of the parsing, only things particular to csvToObject since the other details of parsing are already
7 | // tested in the tests for csvToArray.
8 |
9 | test('csvToObject explicit headings, no trim', function () {
10 | var headings = [' console ', 'introduced'],
11 | csv = 'XBOX , 2001\n' +
12 | 'Nintendo 64,1996\n' +
13 | ' Playstation,1994\n',
14 | expected = [
15 | {
16 | ' console ': 'XBOX ',
17 | 'introduced': 2001,
18 | },
19 | {
20 | ' console ': 'Nintendo 64',
21 | 'introduced': 1996
22 | },
23 | {
24 | ' console ': ' Playstation',
25 | 'introduced': 1994
26 | }
27 | ],
28 | result = CSV.csvToObject(csv, {columns: headings});
29 |
30 | deepEqual(result, expected);
31 | });
32 |
33 | test('csvToObject implicit headings, no trim', function () {
34 | var csv = ' console ,introduced\n' +
35 | 'XBOX , 2001\n' +
36 | 'Nintendo 64,1996\n' +
37 | ' Playstation,1994\n',
38 | expected = [
39 | {
40 | ' console ': 'XBOX ',
41 | 'introduced': 2001,
42 | },
43 | {
44 | ' console ': 'Nintendo 64',
45 | 'introduced': 1996
46 | },
47 | {
48 | ' console ': ' Playstation',
49 | 'introduced': 1994
50 | }
51 | ],
52 | result = CSV.csvToObject(csv);
53 |
54 | deepEqual(result, expected);
55 | });
56 |
57 | test('csvToObject explicit headings with trim', function () {
58 | var headings = [' console ', 'introduced'],
59 | csv = 'XBOX , 2001\n' +
60 | 'Nintendo 64,1996\n' +
61 | ' Playstation,1994\n',
62 | expected = [
63 | {
64 | ' console ': 'XBOX',
65 | 'introduced': 2001,
66 | },
67 | {
68 | ' console ': 'Nintendo 64',
69 | 'introduced': 1996
70 | },
71 | {
72 | ' console ': 'Playstation',
73 | 'introduced': 1994
74 | }
75 | ],
76 | result = CSV.csvToObject(csv, {columns: headings, trim: true});
77 |
78 | deepEqual(result, expected);
79 | });
80 |
81 | test('csvToObject implicit headings', function () {
82 | var csv = ' console , introduced\n' +
83 | 'XBOX , 2001\n' +
84 | 'Nintendo 64,1996\n' +
85 | ' Playstation,1994\n',
86 | expected = [
87 | {
88 | 'console': 'XBOX',
89 | 'introduced': 2001,
90 | },
91 | {
92 | 'console': 'Nintendo 64',
93 | 'introduced': 1996
94 | },
95 | {
96 | 'console': 'Playstation',
97 | 'introduced': 1994
98 | }
99 | ],
100 | result = CSV.csvToObject(csv, {trim: true});
101 |
102 | deepEqual(result, expected);
103 | });
104 | }());
105 |
--------------------------------------------------------------------------------
/dist/test/lib/qunit-1.13.0.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * QUnit 1.13.0
3 | * http://qunitjs.com/
4 | *
5 | * Copyright 2013 jQuery Foundation and other contributors
6 | * Released under the MIT license
7 | * http://jquery.org/license
8 | *
9 | * Date: 2014-01-04T17:09Z
10 | */
11 |
12 | /** Font Family and Sizes */
13 |
14 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
15 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
16 | }
17 |
18 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
19 | #qunit-tests { font-size: smaller; }
20 |
21 |
22 | /** Resets */
23 |
24 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
25 | margin: 0;
26 | padding: 0;
27 | }
28 |
29 |
30 | /** Header */
31 |
32 | #qunit-header {
33 | padding: 0.5em 0 0.5em 1em;
34 |
35 | color: #8699a4;
36 | background-color: #0d3349;
37 |
38 | font-size: 1.5em;
39 | line-height: 1em;
40 | font-weight: normal;
41 |
42 | border-radius: 5px 5px 0 0;
43 | -moz-border-radius: 5px 5px 0 0;
44 | -webkit-border-top-right-radius: 5px;
45 | -webkit-border-top-left-radius: 5px;
46 | }
47 |
48 | #qunit-header a {
49 | text-decoration: none;
50 | color: #c2ccd1;
51 | }
52 |
53 | #qunit-header a:hover,
54 | #qunit-header a:focus {
55 | color: #fff;
56 | }
57 |
58 | #qunit-testrunner-toolbar label {
59 | display: inline-block;
60 | padding: 0 .5em 0 .1em;
61 | }
62 |
63 | #qunit-banner {
64 | height: 5px;
65 | }
66 |
67 | #qunit-testrunner-toolbar {
68 | padding: 0.5em 0 0.5em 2em;
69 | color: #5E740B;
70 | background-color: #eee;
71 | overflow: hidden;
72 | }
73 |
74 | #qunit-userAgent {
75 | padding: 0.5em 0 0.5em 2.5em;
76 | background-color: #2b81af;
77 | color: #fff;
78 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
79 | }
80 |
81 | #qunit-modulefilter-container {
82 | float: right;
83 | }
84 |
85 | /** Tests: Pass/Fail */
86 |
87 | #qunit-tests {
88 | list-style-position: inside;
89 | }
90 |
91 | #qunit-tests li {
92 | padding: 0.4em 0.5em 0.4em 2.5em;
93 | border-bottom: 1px solid #fff;
94 | list-style-position: inside;
95 | }
96 |
97 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
98 | display: none;
99 | }
100 |
101 | #qunit-tests li strong {
102 | cursor: pointer;
103 | }
104 |
105 | #qunit-tests li a {
106 | padding: 0.5em;
107 | color: #c2ccd1;
108 | text-decoration: none;
109 | }
110 | #qunit-tests li a:hover,
111 | #qunit-tests li a:focus {
112 | color: #000;
113 | }
114 |
115 | #qunit-tests li .runtime {
116 | float: right;
117 | font-size: smaller;
118 | }
119 |
120 | .qunit-assert-list {
121 | margin-top: 0.5em;
122 | padding: 0.5em;
123 |
124 | background-color: #fff;
125 |
126 | border-radius: 5px;
127 | -moz-border-radius: 5px;
128 | -webkit-border-radius: 5px;
129 | }
130 |
131 | .qunit-collapsed {
132 | display: none;
133 | }
134 |
135 | #qunit-tests table {
136 | border-collapse: collapse;
137 | margin-top: .2em;
138 | }
139 |
140 | #qunit-tests th {
141 | text-align: right;
142 | vertical-align: top;
143 | padding: 0 .5em 0 0;
144 | }
145 |
146 | #qunit-tests td {
147 | vertical-align: top;
148 | }
149 |
150 | #qunit-tests pre {
151 | margin: 0;
152 | white-space: pre-wrap;
153 | word-wrap: break-word;
154 | }
155 |
156 | #qunit-tests del {
157 | background-color: #e0f2be;
158 | color: #374e0c;
159 | text-decoration: none;
160 | }
161 |
162 | #qunit-tests ins {
163 | background-color: #ffcaca;
164 | color: #500;
165 | text-decoration: none;
166 | }
167 |
168 | /*** Test Counts */
169 |
170 | #qunit-tests b.counts { color: black; }
171 | #qunit-tests b.passed { color: #5E740B; }
172 | #qunit-tests b.failed { color: #710909; }
173 |
174 | #qunit-tests li li {
175 | padding: 5px;
176 | background-color: #fff;
177 | border-bottom: none;
178 | list-style-position: inside;
179 | }
180 |
181 | /*** Passing Styles */
182 |
183 | #qunit-tests li li.pass {
184 | color: #3c510c;
185 | background-color: #fff;
186 | border-left: 10px solid #C6E746;
187 | }
188 |
189 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
190 | #qunit-tests .pass .test-name { color: #366097; }
191 |
192 | #qunit-tests .pass .test-actual,
193 | #qunit-tests .pass .test-expected { color: #999999; }
194 |
195 | #qunit-banner.qunit-pass { background-color: #C6E746; }
196 |
197 | /*** Failing Styles */
198 |
199 | #qunit-tests li li.fail {
200 | color: #710909;
201 | background-color: #fff;
202 | border-left: 10px solid #EE5757;
203 | white-space: pre;
204 | }
205 |
206 | #qunit-tests > li:last-child {
207 | border-radius: 0 0 5px 5px;
208 | -moz-border-radius: 0 0 5px 5px;
209 | -webkit-border-bottom-right-radius: 5px;
210 | -webkit-border-bottom-left-radius: 5px;
211 | }
212 |
213 | #qunit-tests .fail { color: #000000; background-color: #EE5757; }
214 | #qunit-tests .fail .test-name,
215 | #qunit-tests .fail .module-name { color: #000000; }
216 |
217 | #qunit-tests .fail .test-actual { color: #EE5757; }
218 | #qunit-tests .fail .test-expected { color: green; }
219 |
220 | #qunit-banner.qunit-fail { background-color: #EE5757; }
221 |
222 |
223 | /** Result */
224 |
225 | #qunit-testresult {
226 | padding: 0.5em 0.5em 0.5em 2.5em;
227 |
228 | color: #2b81af;
229 | background-color: #D2E0E6;
230 |
231 | border-bottom: 1px solid white;
232 | }
233 | #qunit-testresult .module-name {
234 | font-weight: bold;
235 | }
236 |
237 | /** Fixture */
238 |
239 | #qunit-fixture {
240 | position: absolute;
241 | top: -10000px;
242 | left: -10000px;
243 | width: 1000px;
244 | height: 1000px;
245 | }
246 |
--------------------------------------------------------------------------------
/dist/test/objectToCsv.js:
--------------------------------------------------------------------------------
1 | /*global strictEqual, module */
2 | (function () {
3 | "use strict";
4 | module('objectToCsv');
5 |
6 | test('objectToCsv explicit headings', function () {
7 | var headings = ['console', 'introduced'],
8 | objs = [
9 | {
10 | 'console': 'XBOX',
11 | 'introduced': 2001,
12 | },
13 | {
14 | 'console': 'Nintendo 64',
15 | 'introduced': 1996
16 | },
17 | {
18 | 'console': 'Playstation',
19 | 'introduced': 1994
20 | }
21 | ],
22 | expected = 'console,introduced\n' +
23 | 'XBOX,2001\n' +
24 | 'Nintendo 64,1996\n' +
25 | 'Playstation,1994\n',
26 | result = CSV.objectToCsv(objs, {columns: headings});
27 |
28 | strictEqual(result, expected);
29 | });
30 |
31 | test('objectToCsv implicit headings', function () {
32 | var objs = [
33 | {
34 | 'console': 'XBOX',
35 | 'introduced': 2001,
36 | },
37 | {
38 | 'console': 'Nintendo 64',
39 | 'introduced': 1996
40 | },
41 | {
42 | 'console': 'Playstation',
43 | 'introduced': 1994
44 | }
45 | ],
46 | expected = 'console,introduced\n' +
47 | 'XBOX,2001\n' +
48 | 'Nintendo 64,1996\n' +
49 | 'Playstation,1994\n',
50 | result = CSV.objectToCsv(objs);
51 |
52 | strictEqual(result, expected);
53 | });
54 |
55 | test('objectToCsv implicit headings, missing and extra fields', function () {
56 | var objs = [
57 | {
58 | 'console': 'XBOX',
59 | 'introduced': 2001,
60 | },
61 | {
62 | 'console': 'Nintendo 64',
63 | 'discontinued': 2003
64 | },
65 | {
66 | 'console': 'Playstation',
67 | 'introduced': 1994
68 | }
69 | ],
70 | expected = 'console,introduced,discontinued\n' +
71 | 'XBOX,2001,\n' +
72 | 'Nintendo 64,,2003\n' +
73 | 'Playstation,1994,\n',
74 | result = CSV.objectToCsv(objs);
75 |
76 | strictEqual(result, expected);
77 | });
78 |
79 | test('objectToCsv explicit headings, missing and extra fields', function () {
80 | var headings = ['console', 'introduced'],
81 | objs = [
82 | {
83 | 'console': 'XBOX',
84 | 'introduced': 2001,
85 | },
86 | {
87 | 'console': 'Nintendo 64',
88 | 'discontinued': 2003
89 | },
90 | {
91 | 'console': 'Playstation',
92 | 'introduced': 1994
93 | }
94 | ],
95 | expected = 'console,introduced\n' +
96 | 'XBOX,2001\n' +
97 | 'Nintendo 64,\n' +
98 | 'Playstation,1994\n',
99 | result = CSV.objectToCsv(objs, {columns: headings});
100 |
101 | strictEqual(result, expected);
102 | });
103 |
104 | test('objectToCsv with includeColumns = true', function () {
105 | var headings = ['console', 'introduced'],
106 | objs = [
107 | {
108 | 'console': 'XBOX',
109 | 'introduced': 2001,
110 | },
111 | {
112 | 'console': 'Nintendo 64',
113 | 'introduced': 1996
114 | },
115 | {
116 | 'console': 'Playstation',
117 | 'introduced': 1994
118 | }
119 | ],
120 | expected = 'console,introduced\n' +
121 | 'XBOX,2001\n' +
122 | 'Nintendo 64,1996\n' +
123 | 'Playstation,1994\n',
124 | result = CSV.objectToCsv(objs, {columns: headings, includeColumns: true});
125 |
126 | strictEqual(result, expected);
127 | });
128 |
129 | test('objectToCsv with includeColumns = false', function () {
130 | var headings = ['console', 'introduced'],
131 | objs = [
132 | {
133 | 'console': 'XBOX',
134 | 'introduced': 2001,
135 | },
136 | {
137 | 'console': 'Nintendo 64',
138 | 'introduced': 1996
139 | },
140 | {
141 | 'console': 'Playstation',
142 | 'introduced': 1994
143 | }
144 | ],
145 | expected = 'XBOX,2001\n' +
146 | 'Nintendo 64,1996\n' +
147 | 'Playstation,1994\n',
148 | result = CSV.objectToCsv(objs, {columns: headings, includeColumns: false});
149 |
150 | strictEqual(result, expected);
151 | });
152 |
153 | test('objectToCsv with commas double quotes and newlines', function () {
154 | var headings = ['console', 'introduced'],
155 | objs = [
156 | {
157 | 'console': 'XBOX "XBONE" One',
158 | 'introduced': 2013,
159 | },
160 | {
161 | 'console': 'Nintendo 64, AKA Nintendo Ultra 64',
162 | 'introduced': 1996
163 | },
164 | {
165 | 'console': 'Playstation\n4',
166 | 'introduced': 2013
167 | }
168 | ],
169 | expected = '"XBOX ""XBONE"" One",2013\n' +
170 | '"Nintendo 64, AKA Nintendo Ultra 64",1996\n' +
171 | '"Playstation\n4",2013\n',
172 | result = CSV.objectToCsv(objs, {columns: headings, includeColumns: false});
173 |
174 | strictEqual(result, expected);
175 | });
176 | }());
177 |
--------------------------------------------------------------------------------
/dist/test/tests.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | QUnit Example
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/dist/ucsv-1.2.0.min.js:
--------------------------------------------------------------------------------
1 | /*! ucsv v1.2.0 2014-04-09
2 | * Copyright 2014 Peter Johnson
3 | * Licensed MIT, GPL-3.0
4 | * https://github.com/uselesscode/ucsv
5 | */
6 | var CSV=function(){"use strict";var a=/^\d+$/,b=/^\d*\.\d+$|^\d+\.\d*$/,c=/^\s|\s$|,|"|\n/,d=function(){return String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^\s*/,"").replace(/\s*$/,"")}}(),e=function(a){return"[object Number]"===Object.prototype.toString.apply(a)},f=function(a){return"[object String]"===Object.prototype.toString.apply(a)},g=function(a){return"\n"!==a.charAt(a.length-1)?a:a.substring(0,a.length-1)},h=function(d){return f(d)?(d=d.replace(/"/g,'""'),c.test(d)||a.test(d)||b.test(d)?d='"'+d+'"':""===d&&(d='""')):d=e(d)?d.toString(10):null===d||void 0===d?"":d.toString(),d},i={arrayToCsv:function(a){var b,c,d,e,f="";for(d=0;dd;d+=1)b[c[d]]=a[d];return b})},objectToCsv:function(a,b){b=void 0!==b?b:{};var c=b.columns,d=b.includeColumns,e="",f="",g=function(b){var d,e,f,g="",i=a.length,j=c.length;for(e=0;i>e;e+=1){for(b=a[e],f=0;j>f;f+=1)d=c[f],g+=h(b[d]),g+=j-1>f?",":"";g+="\n"}return g},i=function(){var b,d,e,f,g,i,j,k=[],l=a.length,m=[];for(g=0;l>g;g+=1){e=a[g],j=[];for(f in e)e.hasOwnProperty(f)&&(i=k.indexOf(f),-1===i&&(i=k.push(f),i-=1),j[i]=h(e[f]));0===g&&(b=j.length),m.push(j)}return d=k.length,b!==d&&m.forEach(function(a){a.length=d}),c=k,m.map(function(a){return a.join(",")}).join("\n")+"\n"};return d=void 0===d?!0:!!d,e=void 0!==c?g():i(),d&&(c.forEach(function(a){f+=h(a)+","}),f=f.substring(0,f.length-1),e=f+"\n"+e),e}};return"object"==typeof exports&&(exports.arrayToCsv=i.arrayToCsv,exports.csvToArray=i.csvToArray,exports.objectToCsv=i.objectToCsv,exports.csvToObject=i.csvToObject),i}();
7 |
--------------------------------------------------------------------------------
/docs/api.js:
--------------------------------------------------------------------------------
1 | YUI.add("yuidoc-meta", function(Y) {
2 | Y.YUIDoc = { meta: {
3 | "classes": [
4 | "CSV"
5 | ],
6 | "modules": [],
7 | "allModules": []
8 | } };
9 | });
--------------------------------------------------------------------------------
/docs/assets/css/external-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uselesscode/ucsv/d7c653add0832633a08134e79634459a0b8bfcc3/docs/assets/css/external-small.png
--------------------------------------------------------------------------------
/docs/assets/css/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uselesscode/ucsv/d7c653add0832633a08134e79634459a0b8bfcc3/docs/assets/css/logo.png
--------------------------------------------------------------------------------
/docs/assets/css/main.css:
--------------------------------------------------------------------------------
1 | /*
2 | Font sizes for all selectors other than the body are given in percentages,
3 | with 100% equal to 13px. To calculate a font size percentage, multiply the
4 | desired size in pixels by 7.6923076923.
5 |
6 | Here's a quick lookup table:
7 |
8 | 10px - 76.923%
9 | 11px - 84.615%
10 | 12px - 92.308%
11 | 13px - 100%
12 | 14px - 107.692%
13 | 15px - 115.385%
14 | 16px - 123.077%
15 | 17px - 130.769%
16 | 18px - 138.462%
17 | 19px - 146.154%
18 | 20px - 153.846%
19 | */
20 |
21 | html {
22 | background: #fff;
23 | color: #333;
24 | overflow-y: scroll;
25 | }
26 |
27 | body {
28 | /*font: 13px/1.4 'Lucida Grande', 'Lucida Sans Unicode', 'DejaVu Sans', 'Bitstream Vera Sans', 'Helvetica', 'Arial', sans-serif;*/
29 | font: 13px/1.4 'Helvetica', 'Arial', sans-serif;
30 | margin: 0;
31 | padding: 0;
32 | }
33 |
34 | /* -- Links ----------------------------------------------------------------- */
35 | a {
36 | color: #356de4;
37 | text-decoration: none;
38 | }
39 |
40 | .hidden {
41 | display: none;
42 | }
43 |
44 | a:hover { text-decoration: underline; }
45 |
46 | /* "Jump to Table of Contents" link is shown to assistive tools, but hidden from
47 | sight until it's focused. */
48 | .jump {
49 | position: absolute;
50 | padding: 3px 6px;
51 | left: -99999px;
52 | top: 0;
53 | }
54 |
55 | .jump:focus { left: 40%; }
56 |
57 | /* -- Paragraphs ------------------------------------------------------------ */
58 | p { margin: 1.3em 0; }
59 | dd p, td p { margin-bottom: 0; }
60 | dd p:first-child, td p:first-child { margin-top: 0; }
61 |
62 | /* -- Headings -------------------------------------------------------------- */
63 | h1, h2, h3, h4, h5, h6 {
64 | color: #D98527;/*was #f80*/
65 | font-family: 'Trebuchet MS', sans-serif;
66 | font-weight: bold;
67 | line-height: 1.1;
68 | margin: 1.1em 0 0.5em;
69 | }
70 |
71 | h1 {
72 | font-size: 184.6%;
73 | color: #30418C;
74 | margin: 0.75em 0 0.5em;
75 | }
76 |
77 | h2 {
78 | font-size: 153.846%;
79 | color: #E48A2B;
80 | }
81 |
82 | h3 { font-size: 138.462%; }
83 |
84 | h4 {
85 | border-bottom: 1px solid #DBDFEA;
86 | color: #E48A2B;
87 | font-size: 115.385%;
88 | font-weight: normal;
89 | padding-bottom: 2px;
90 | }
91 |
92 | h5, h6 { font-size: 107.692%; }
93 |
94 | /* -- Code and examples ----------------------------------------------------- */
95 | code, kbd, pre, samp {
96 | font-family: Menlo, Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;
97 | font-size: 92.308%;
98 | line-height: 1.35;
99 | }
100 |
101 | p code, p kbd, p samp, li code {
102 | background: #FCFBFA;
103 | border: 1px solid #EFEEED;
104 | padding: 0 3px;
105 | }
106 |
107 | a code, a kbd, a samp,
108 | pre code, pre kbd, pre samp,
109 | table code, table kbd, table samp,
110 | .intro code, .intro kbd, .intro samp,
111 | .toc code, .toc kbd, .toc samp {
112 | background: none;
113 | border: none;
114 | padding: 0;
115 | }
116 |
117 | pre.code, pre.terminal, pre.cmd {
118 | overflow-x: auto;
119 | *overflow-x: scroll;
120 | padding: 0.3em 0.6em;
121 | }
122 |
123 | pre.code {
124 | background: #FCFBFA;
125 | border: 1px solid #EFEEED;
126 | border-left-width: 5px;
127 | }
128 |
129 | pre.terminal, pre.cmd {
130 | background: #F0EFFC;
131 | border: 1px solid #D0CBFB;
132 | border-left: 5px solid #D0CBFB;
133 | }
134 |
135 | /* Don't reduce the font size of // elements inside
136 | blocks. */
137 | pre code, pre kbd, pre samp { font-size: 100%; }
138 |
139 | /* Used to denote text that shouldn't be selectable, such as line numbers or
140 | shell prompts. Guess which browser this doesn't work in. */
141 | .noselect {
142 | -moz-user-select: -moz-none;
143 | -khtml-user-select: none;
144 | -webkit-user-select: none;
145 | -o-user-select: none;
146 | user-select: none;
147 | }
148 |
149 | /* -- Lists ----------------------------------------------------------------- */
150 | dd { margin: 0.2em 0 0.7em 1em; }
151 | dl { margin: 1em 0; }
152 | dt { font-weight: bold; }
153 |
154 | /* -- Tables ---------------------------------------------------------------- */
155 | caption, th { text-align: left; }
156 |
157 | table {
158 | border-collapse: collapse;
159 | width: 100%;
160 | }
161 |
162 | td, th {
163 | border: 1px solid #fff;
164 | padding: 5px 12px;
165 | vertical-align: top;
166 | }
167 |
168 | td { background: #E6E9F5; }
169 | td dl { margin: 0; }
170 | td dl dl { margin: 1em 0; }
171 | td pre:first-child { margin-top: 0; }
172 |
173 | th {
174 | background: #D2D7E6;/*#97A0BF*/
175 | border-bottom: none;
176 | border-top: none;
177 | color: #000;/*#FFF1D5*/
178 | font-family: 'Trebuchet MS', sans-serif;
179 | font-weight: bold;
180 | line-height: 1.3;
181 | white-space: nowrap;
182 | }
183 |
184 |
185 | /* -- Layout and Content ---------------------------------------------------- */
186 | #doc {
187 | margin: auto;
188 | min-width: 1024px;
189 | }
190 |
191 | .content { padding: 0 20px 0 25px; }
192 |
193 | .sidebar {
194 | padding: 0 15px 0 10px;
195 | }
196 | #bd {
197 | padding: 7px 0 130px;
198 | position: relative;
199 | width: 99%;
200 | }
201 |
202 | /* -- Table of Contents ----------------------------------------------------- */
203 |
204 | /* The #toc id refers to the single global table of contents, while the .toc
205 | class refers to generic TOC lists that could be used throughout the page. */
206 |
207 | .toc code, .toc kbd, .toc samp { font-size: 100%; }
208 | .toc li { font-weight: bold; }
209 | .toc li li { font-weight: normal; }
210 |
211 | /* -- Intro and Example Boxes ----------------------------------------------- */
212 | /*
213 | .intro, .example { margin-bottom: 2em; }
214 | .example {
215 | -moz-border-radius: 4px;
216 | -webkit-border-radius: 4px;
217 | border-radius: 4px;
218 | -moz-box-shadow: 0 0 5px #bfbfbf;
219 | -webkit-box-shadow: 0 0 5px #bfbfbf;
220 | box-shadow: 0 0 5px #bfbfbf;
221 | padding: 1em;
222 | }
223 | .intro {
224 | background: none repeat scroll 0 0 #F0F1F8; border: 1px solid #D4D8EB; padding: 0 1em;
225 | }
226 | */
227 |
228 | /* -- Other Styles ---------------------------------------------------------- */
229 |
230 | /* These are probably YUI-specific, and should be moved out of Selleck's default
231 | theme. */
232 |
233 | .button {
234 | border: 1px solid #dadada;
235 | -moz-border-radius: 3px;
236 | -webkit-border-radius: 3px;
237 | border-radius: 3px;
238 | color: #444;
239 | display: inline-block;
240 | font-family: Helvetica, Arial, sans-serif;
241 | font-size: 92.308%;
242 | font-weight: bold;
243 | padding: 4px 13px 3px;
244 | -moz-text-shadow: 1px 1px 0 #fff;
245 | -webkit-text-shadow: 1px 1px 0 #fff;
246 | text-shadow: 1px 1px 0 #fff;
247 | white-space: nowrap;
248 |
249 | background: #EFEFEF; /* old browsers */
250 | background: -moz-linear-gradient(top, #f5f5f5 0%, #efefef 50%, #e5e5e5 51%, #dfdfdf 100%); /* firefox */
251 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f5f5f5), color-stop(50%,#efefef), color-stop(51%,#e5e5e5), color-stop(100%,#dfdfdf)); /* webkit */
252 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5f5f5', endColorstr='#dfdfdf',GradientType=0 ); /* ie */
253 | }
254 |
255 | .button:hover {
256 | border-color: #466899;
257 | color: #fff;
258 | text-decoration: none;
259 | -moz-text-shadow: 1px 1px 0 #222;
260 | -webkit-text-shadow: 1px 1px 0 #222;
261 | text-shadow: 1px 1px 0 #222;
262 |
263 | background: #6396D8; /* old browsers */
264 | background: -moz-linear-gradient(top, #6396D8 0%, #5A83BC 50%, #547AB7 51%, #466899 100%); /* firefox */
265 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6396D8), color-stop(50%,#5A83BC), color-stop(51%,#547AB7), color-stop(100%,#466899)); /* webkit */
266 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6396D8', endColorstr='#466899',GradientType=0 ); /* ie */
267 | }
268 |
269 | .newwindow { text-align: center; }
270 |
271 | .header .version em {
272 | display: block;
273 | text-align: right;
274 | }
275 |
276 |
277 | #classdocs .item {
278 | border-bottom: 1px solid #466899;
279 | margin: 1em 0;
280 | padding: 1.5em;
281 | }
282 |
283 | #classdocs .item .params p,
284 | #classdocs .item .returns p,{
285 | display: inline;
286 | }
287 |
288 | #classdocs .item em code, #classdocs .item em.comment {
289 | color: green;
290 | }
291 |
292 | #classdocs .item em.comment a {
293 | color: green;
294 | text-decoration: underline;
295 | }
296 |
297 | #classdocs .foundat {
298 | font-size: 11px;
299 | font-style: normal;
300 | }
301 |
302 | .attrs .emits {
303 | margin-left: 2em;
304 | padding: .5em;
305 | border-left: 1px dashed #ccc;
306 | }
307 |
308 | abbr {
309 | border-bottom: 1px dashed #ccc;
310 | font-size: 80%;
311 | cursor: help;
312 | }
313 |
314 | .prettyprint li.L0,
315 | .prettyprint li.L1,
316 | .prettyprint li.L2,
317 | .prettyprint li.L3,
318 | .prettyprint li.L5,
319 | .prettyprint li.L6,
320 | .prettyprint li.L7,
321 | .prettyprint li.L8 {
322 | list-style: decimal;
323 | }
324 |
325 | ul li p {
326 | margin-top: 0;
327 | }
328 |
329 | .method .name {
330 | font-size: 110%;
331 | }
332 |
333 | .apidocs .methods .extends .method,
334 | .apidocs .properties .extends .property,
335 | .apidocs .attrs .extends .attr,
336 | .apidocs .events .extends .event {
337 | font-weight: bold;
338 | }
339 |
340 | .apidocs .methods .extends .inherited,
341 | .apidocs .properties .extends .inherited,
342 | .apidocs .attrs .extends .inherited,
343 | .apidocs .events .extends .inherited {
344 | font-weight: normal;
345 | }
346 |
347 | #hd {
348 | background: whiteSmoke;
349 | background: -moz-linear-gradient(top,#DCDBD9 0,#F6F5F3 100%);
350 | background: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#DCDBD9),color-stop(100%,#F6F5F3));
351 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dcdbd9',endColorstr='#F6F5F3',GradientType=0);
352 | border-bottom: 1px solid #DFDFDF;
353 | padding: 0 15px 1px 20px;
354 | margin-bottom: 15px;
355 | }
356 |
357 | #hd img {
358 | margin-right: 10px;
359 | vertical-align: middle;
360 | }
361 |
362 |
363 | /* -- API Docs CSS ---------------------------------------------------------- */
364 |
365 | /*
366 | This file is organized so that more generic styles are nearer the top, and more
367 | specific styles are nearer the bottom of the file. This allows us to take full
368 | advantage of the cascade to avoid redundant style rules. Please respect this
369 | convention when making changes.
370 | */
371 |
372 | /* -- Generic TabView styles ------------------------------------------------ */
373 |
374 | /*
375 | These styles apply to all API doc tabviews. To change styles only for a
376 | specific tabview, see the other sections below.
377 | */
378 |
379 | .yui3-js-enabled .apidocs .tabview {
380 | visibility: hidden; /* Hide until the TabView finishes rendering. */
381 | _visibility: visible;
382 | }
383 |
384 | .apidocs .tabview.yui3-tabview-content { visibility: visible; }
385 | .apidocs .tabview .yui3-tabview-panel { background: #fff; }
386 |
387 | /* -- Generic Content Styles ------------------------------------------------ */
388 |
389 | /* Headings */
390 | h2, h3, h4, h5, h6 {
391 | border: none;
392 | color: #30418C;
393 | font-weight: bold;
394 | text-decoration: none;
395 | }
396 |
397 | .link-docs {
398 | float: right;
399 | font-size: 15px;
400 | margin: 4px 4px 6px;
401 | padding: 6px 30px 5px;
402 | }
403 |
404 | .apidocs { zoom: 1; }
405 |
406 | /* Generic box styles. */
407 | .apidocs .box {
408 | border: 1px solid;
409 | border-radius: 3px;
410 | margin: 1em 0;
411 | padding: 0 1em;
412 | }
413 |
414 | /* A flag is a compact, capsule-like indicator of some kind. It's used to
415 | indicate private and protected items, item return types, etc. in an
416 | attractive and unobtrusive way. */
417 | .apidocs .flag {
418 | background: #bababa;
419 | border-radius: 3px;
420 | color: #fff;
421 | font-size: 11px;
422 | margin: 0 0.5em;
423 | padding: 2px 4px 1px;
424 | }
425 |
426 | /* Class/module metadata such as "Uses", "Extends", "Defined in", etc. */
427 | .apidocs .meta {
428 | background: #f9f9f9;
429 | border-color: #efefef;
430 | color: #555;
431 | font-size: 11px;
432 | padding: 3px 6px;
433 | }
434 |
435 | .apidocs .meta p { margin: 0; }
436 |
437 | /* Deprecation warning. */
438 | .apidocs .box.deprecated,
439 | .apidocs .flag.deprecated {
440 | background: #fdac9f;
441 | border: 1px solid #fd7775;
442 | }
443 |
444 | .apidocs .box.deprecated p { margin: 0.5em 0; }
445 | .apidocs .flag.deprecated { color: #333; }
446 |
447 | /* Module/Class intro description. */
448 | .apidocs .intro {
449 | background: #f0f1f8;
450 | border-color: #d4d8eb;
451 | }
452 |
453 | /* Loading spinners. */
454 | #bd.loading .apidocs,
455 | #api-list.loading .yui3-tabview-panel {
456 | background: #fff url(../img/spinner.gif) no-repeat center 70px;
457 | min-height: 150px;
458 | }
459 |
460 | #bd.loading .apidocs .content,
461 | #api-list.loading .yui3-tabview-panel .apis {
462 | display: none;
463 | }
464 |
465 | .apidocs .no-visible-items { color: #666; }
466 |
467 | /* Generic inline list. */
468 | .apidocs ul.inline {
469 | display: inline;
470 | list-style: none;
471 | margin: 0;
472 | padding: 0;
473 | }
474 |
475 | .apidocs ul.inline li { display: inline; }
476 |
477 | /* Comma-separated list. */
478 | .apidocs ul.commas li:after { content: ','; }
479 | .apidocs ul.commas li:last-child:after { content: ''; }
480 |
481 | /* Keyboard shortcuts. */
482 | kbd .cmd { font-family: Monaco, Helvetica; }
483 |
484 | /* -- Generic Access Level styles ------------------------------------------- */
485 | .apidocs .item.protected,
486 | .apidocs .item.private,
487 | .apidocs .index-item.protected,
488 | .apidocs .index-item.deprecated,
489 | .apidocs .index-item.private {
490 | display: none;
491 | }
492 |
493 | .show-deprecated .item.deprecated,
494 | .show-deprecated .index-item.deprecated,
495 | .show-protected .item.protected,
496 | .show-protected .index-item.protected,
497 | .show-private .item.private,
498 | .show-private .index-item.private {
499 | display: block;
500 | }
501 |
502 | .hide-inherited .item.inherited,
503 | .hide-inherited .index-item.inherited {
504 | display: none;
505 | }
506 |
507 | /* -- Generic Item Index styles --------------------------------------------- */
508 | .apidocs .index { margin: 1.5em 0 3em; }
509 |
510 | .apidocs .index h3 {
511 | border-bottom: 1px solid #efefef;
512 | color: #333;
513 | font-size: 13px;
514 | margin: 2em 0 0.6em;
515 | padding-bottom: 2px;
516 | }
517 |
518 | .apidocs .index .no-visible-items { margin-top: 2em; }
519 |
520 | .apidocs .index-list {
521 | border-color: #efefef;
522 | font-size: 12px;
523 | list-style: none;
524 | margin: 0;
525 | padding: 0;
526 | -moz-column-count: 4;
527 | -moz-column-gap: 10px;
528 | -moz-column-width: 170px;
529 | -ms-column-count: 4;
530 | -ms-column-gap: 10px;
531 | -ms-column-width: 170px;
532 | -o-column-count: 4;
533 | -o-column-gap: 10px;
534 | -o-column-width: 170px;
535 | -webkit-column-count: 4;
536 | -webkit-column-gap: 10px;
537 | -webkit-column-width: 170px;
538 | column-count: 4;
539 | column-gap: 10px;
540 | column-width: 170px;
541 | }
542 |
543 | .apidocs .no-columns .index-list {
544 | -moz-column-count: 1;
545 | -ms-column-count: 1;
546 | -o-column-count: 1;
547 | -webkit-column-count: 1;
548 | column-count: 1;
549 | }
550 |
551 | .apidocs .index-item { white-space: nowrap; }
552 |
553 | .apidocs .index-item .flag {
554 | background: none;
555 | border: none;
556 | color: #afafaf;
557 | display: inline;
558 | margin: 0 0 0 0.2em;
559 | padding: 0;
560 | }
561 |
562 | /* -- Generic API item styles ----------------------------------------------- */
563 | .apidocs .args {
564 | display: inline;
565 | margin: 0 0.5em;
566 | }
567 |
568 | .apidocs .flag.chainable { background: #46ca3b; }
569 | .apidocs .flag.protected { background: #9b86fc; }
570 | .apidocs .flag.private { background: #fd6b1b; }
571 | .apidocs .flag.async { background: #356de4; }
572 | .apidocs .flag.required { background: #e60923; }
573 |
574 | .apidocs .item {
575 | border-bottom: 1px solid #efefef;
576 | margin: 1.5em 0 2em;
577 | padding-bottom: 2em;
578 | }
579 |
580 | .apidocs .item h4,
581 | .apidocs .item h5,
582 | .apidocs .item h6 {
583 | color: #333;
584 | font-family: inherit;
585 | font-size: 100%;
586 | }
587 |
588 | .apidocs .item .description p,
589 | .apidocs .item pre.code {
590 | margin: 1em 0 0;
591 | }
592 |
593 | .apidocs .item .meta {
594 | background: none;
595 | border: none;
596 | padding: 0;
597 | }
598 |
599 | .apidocs .item .name {
600 | display: inline;
601 | font-size: 14px;
602 | }
603 |
604 | .apidocs .item .type,
605 | .apidocs .item .type a,
606 | .apidocs .returns-inline {
607 | color: #555;
608 | }
609 |
610 | .apidocs .item .type,
611 | .apidocs .returns-inline {
612 | font-size: 11px;
613 | margin: 0 0 0 0;
614 | }
615 |
616 | .apidocs .item .type a { border-bottom: 1px dotted #afafaf; }
617 | .apidocs .item .type a:hover { border: none; }
618 |
619 | /* -- Item Parameter List --------------------------------------------------- */
620 | .apidocs .params-list {
621 | list-style: square;
622 | margin: 1em 0 0 2em;
623 | padding: 0;
624 | }
625 |
626 | .apidocs .param { margin-bottom: 1em; }
627 |
628 | .apidocs .param .type,
629 | .apidocs .param .type a {
630 | color: #666;
631 | }
632 |
633 | .apidocs .param .type {
634 | margin: 0 0 0 0.5em;
635 | *margin-left: 0.5em;
636 | }
637 |
638 | .apidocs .param-name { font-weight: bold; }
639 |
640 | /* -- Item "Emits" block ---------------------------------------------------- */
641 | .apidocs .item .emits {
642 | background: #f9f9f9;
643 | border-color: #eaeaea;
644 | }
645 |
646 | /* -- Item "Returns" block -------------------------------------------------- */
647 | .apidocs .item .returns .type,
648 | .apidocs .item .returns .type a {
649 | font-size: 100%;
650 | margin: 0;
651 | }
652 |
653 | /* -- Class Constructor block ----------------------------------------------- */
654 | .apidocs .constructor .item {
655 | border: none;
656 | padding-bottom: 0;
657 | }
658 |
659 | /* -- File Source View ------------------------------------------------------ */
660 | .apidocs .file pre.code,
661 | #doc .apidocs .file pre.prettyprint {
662 | background: inherit;
663 | border: none;
664 | overflow: visible;
665 | padding: 0;
666 | }
667 |
668 | .apidocs .L0,
669 | .apidocs .L1,
670 | .apidocs .L2,
671 | .apidocs .L3,
672 | .apidocs .L4,
673 | .apidocs .L5,
674 | .apidocs .L6,
675 | .apidocs .L7,
676 | .apidocs .L8,
677 | .apidocs .L9 {
678 | background: inherit;
679 | }
680 |
681 | /* -- Submodule List -------------------------------------------------------- */
682 | .apidocs .module-submodule-description {
683 | font-size: 12px;
684 | margin: 0.3em 0 1em;
685 | }
686 |
687 | .apidocs .module-submodule-description p:first-child { margin-top: 0; }
688 |
689 | /* -- Sidebar TabView ------------------------------------------------------- */
690 | #api-tabview { margin-top: 0.6em; }
691 |
692 | #api-tabview-filter,
693 | #api-tabview-panel {
694 | border: 1px solid #dfdfdf;
695 | }
696 |
697 | #api-tabview-filter {
698 | border-bottom: none;
699 | border-top: none;
700 | padding: 0.6em 10px 0 10px;
701 | }
702 |
703 | #api-tabview-panel { border-top: none; }
704 | #api-filter { width: 97%; }
705 |
706 | /* -- Content TabView ------------------------------------------------------- */
707 | #classdocs .yui3-tabview-panel { border: none; }
708 |
709 | /* -- Source File Contents -------------------------------------------------- */
710 | .prettyprint li.L0,
711 | .prettyprint li.L1,
712 | .prettyprint li.L2,
713 | .prettyprint li.L3,
714 | .prettyprint li.L5,
715 | .prettyprint li.L6,
716 | .prettyprint li.L7,
717 | .prettyprint li.L8 {
718 | list-style: decimal;
719 | }
720 |
721 | /* -- API options ----------------------------------------------------------- */
722 | #api-options {
723 | font-size: 11px;
724 | margin-top: 2.2em;
725 | position: absolute;
726 | right: 1.5em;
727 | }
728 |
729 | /*#api-options label { margin-right: 0.6em; }*/
730 |
731 | /* -- API list -------------------------------------------------------------- */
732 | #api-list {
733 | margin-top: 1.5em;
734 | *zoom: 1;
735 | }
736 |
737 | .apis {
738 | font-size: 12px;
739 | line-height: 1.4;
740 | list-style: none;
741 | margin: 0;
742 | padding: 0.5em 0 0.5em 0.4em;
743 | }
744 |
745 | .apis a {
746 | border: 1px solid transparent;
747 | display: block;
748 | margin: 0 0 0 -4px;
749 | padding: 1px 4px 0;
750 | text-decoration: none;
751 | _border: none;
752 | _display: inline;
753 | }
754 |
755 | .apis a:hover,
756 | .apis a:focus {
757 | background: #E8EDFC;
758 | background: -moz-linear-gradient(top, #e8edfc 0%, #becef7 100%);
759 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#E8EDFC), color-stop(100%,#BECEF7));
760 | border-color: #AAC0FA;
761 | border-radius: 3px;
762 | color: #333;
763 | outline: none;
764 | }
765 |
766 | .api-list-item a:hover,
767 | .api-list-item a:focus {
768 | font-weight: bold;
769 | text-shadow: 1px 1px 1px #fff;
770 | }
771 |
772 | .apis .message { color: #888; }
773 | .apis .result a { padding: 3px 5px 2px; }
774 |
775 | .apis .result .type {
776 | right: 4px;
777 | top: 7px;
778 | }
779 |
780 | .api-list-item .yui3-highlight {
781 | font-weight: bold;
782 | }
783 |
784 |
--------------------------------------------------------------------------------
/docs/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uselesscode/ucsv/d7c653add0832633a08134e79634459a0b8bfcc3/docs/assets/favicon.png
--------------------------------------------------------------------------------
/docs/assets/img/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uselesscode/ucsv/d7c653add0832633a08134e79634459a0b8bfcc3/docs/assets/img/spinner.gif
--------------------------------------------------------------------------------
/docs/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Redirector
5 |
6 |
7 |
8 | Click here to redirect
9 |
10 |
11 |
--------------------------------------------------------------------------------
/docs/assets/js/api-filter.js:
--------------------------------------------------------------------------------
1 | YUI.add('api-filter', function (Y) {
2 |
3 | Y.APIFilter = Y.Base.create('apiFilter', Y.Base, [Y.AutoCompleteBase], {
4 | // -- Initializer ----------------------------------------------------------
5 | initializer: function () {
6 | this._bindUIACBase();
7 | this._syncUIACBase();
8 | },
9 | getDisplayName: function(name) {
10 |
11 | Y.each(Y.YUIDoc.meta.allModules, function(i) {
12 | if (i.name === name && i.displayName) {
13 | name = i.displayName;
14 | }
15 | });
16 |
17 | return name;
18 | }
19 |
20 | }, {
21 | // -- Attributes -----------------------------------------------------------
22 | ATTRS: {
23 | resultHighlighter: {
24 | value: 'phraseMatch'
25 | },
26 |
27 | // May be set to "classes" or "modules".
28 | queryType: {
29 | value: 'classes'
30 | },
31 |
32 | source: {
33 | valueFn: function() {
34 | var self = this;
35 | return function(q) {
36 | var data = Y.YUIDoc.meta[self.get('queryType')],
37 | out = [];
38 | Y.each(data, function(v) {
39 | if (v.toLowerCase().indexOf(q.toLowerCase()) > -1) {
40 | out.push(v);
41 | }
42 | });
43 | return out;
44 | };
45 | }
46 | }
47 | }
48 | });
49 |
50 | }, '3.4.0', {requires: [
51 | 'autocomplete-base', 'autocomplete-highlighters', 'autocomplete-sources'
52 | ]});
53 |
--------------------------------------------------------------------------------
/docs/assets/js/api-list.js:
--------------------------------------------------------------------------------
1 | YUI.add('api-list', function (Y) {
2 |
3 | var Lang = Y.Lang,
4 | YArray = Y.Array,
5 |
6 | APIList = Y.namespace('APIList'),
7 |
8 | classesNode = Y.one('#api-classes'),
9 | inputNode = Y.one('#api-filter'),
10 | modulesNode = Y.one('#api-modules'),
11 | tabviewNode = Y.one('#api-tabview'),
12 |
13 | tabs = APIList.tabs = {},
14 |
15 | filter = APIList.filter = new Y.APIFilter({
16 | inputNode : inputNode,
17 | maxResults: 1000,
18 |
19 | on: {
20 | results: onFilterResults
21 | }
22 | }),
23 |
24 | search = APIList.search = new Y.APISearch({
25 | inputNode : inputNode,
26 | maxResults: 100,
27 |
28 | on: {
29 | clear : onSearchClear,
30 | results: onSearchResults
31 | }
32 | }),
33 |
34 | tabview = APIList.tabview = new Y.TabView({
35 | srcNode : tabviewNode,
36 | panelNode: '#api-tabview-panel',
37 | render : true,
38 |
39 | on: {
40 | selectionChange: onTabSelectionChange
41 | }
42 | }),
43 |
44 | focusManager = APIList.focusManager = tabviewNode.plug(Y.Plugin.NodeFocusManager, {
45 | circular : true,
46 | descendants: '#api-filter, .yui3-tab-panel-selected .api-list-item a, .yui3-tab-panel-selected .result a',
47 | keys : {next: 'down:40', previous: 'down:38'}
48 | }).focusManager,
49 |
50 | LIST_ITEM_TEMPLATE =
51 | ' ' +
52 | '{displayName} ' +
53 | ' ';
54 |
55 | // -- Init ---------------------------------------------------------------------
56 |
57 | // Duckpunch FocusManager's key event handling to prevent it from handling key
58 | // events when a modifier is pressed.
59 | Y.before(function (e, activeDescendant) {
60 | if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
61 | return new Y.Do.Prevent();
62 | }
63 | }, focusManager, '_focusPrevious', focusManager);
64 |
65 | Y.before(function (e, activeDescendant) {
66 | if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
67 | return new Y.Do.Prevent();
68 | }
69 | }, focusManager, '_focusNext', focusManager);
70 |
71 | // Create a mapping of tabs in the tabview so we can refer to them easily later.
72 | tabview.each(function (tab, index) {
73 | var name = tab.get('label').toLowerCase();
74 |
75 | tabs[name] = {
76 | index: index,
77 | name : name,
78 | tab : tab
79 | };
80 | });
81 |
82 | // Switch tabs on Ctrl/Cmd-Left/Right arrows.
83 | tabviewNode.on('key', onTabSwitchKey, 'down:37,39');
84 |
85 | // Focus the filter input when the `/` key is pressed.
86 | Y.one(Y.config.doc).on('key', onSearchKey, 'down:83');
87 |
88 | // Keep the Focus Manager up to date.
89 | inputNode.on('focus', function () {
90 | focusManager.set('activeDescendant', inputNode);
91 | });
92 |
93 | // Update all tabview links to resolved URLs.
94 | tabview.get('panelNode').all('a').each(function (link) {
95 | link.setAttribute('href', link.get('href'));
96 | });
97 |
98 | // -- Private Functions --------------------------------------------------------
99 | function getFilterResultNode() {
100 | return filter.get('queryType') === 'classes' ? classesNode : modulesNode;
101 | }
102 |
103 | // -- Event Handlers -----------------------------------------------------------
104 | function onFilterResults(e) {
105 | var frag = Y.one(Y.config.doc.createDocumentFragment()),
106 | resultNode = getFilterResultNode(),
107 | typePlural = filter.get('queryType'),
108 | typeSingular = typePlural === 'classes' ? 'class' : 'module';
109 |
110 | if (e.results.length) {
111 | YArray.each(e.results, function (result) {
112 | frag.append(Lang.sub(LIST_ITEM_TEMPLATE, {
113 | rootPath : APIList.rootPath,
114 | displayName : filter.getDisplayName(result.highlighted),
115 | name : result.text,
116 | typePlural : typePlural,
117 | typeSingular: typeSingular
118 | }));
119 | });
120 | } else {
121 | frag.append(
122 | '' +
123 | 'No ' + typePlural + ' found.' +
124 | ' '
125 | );
126 | }
127 |
128 | resultNode.empty(true);
129 | resultNode.append(frag);
130 |
131 | focusManager.refresh();
132 | }
133 |
134 | function onSearchClear(e) {
135 |
136 | focusManager.refresh();
137 | }
138 |
139 | function onSearchKey(e) {
140 | var target = e.target;
141 |
142 | if (target.test('input,select,textarea')
143 | || target.get('isContentEditable')) {
144 | return;
145 | }
146 |
147 | e.preventDefault();
148 |
149 | inputNode.focus();
150 | focusManager.refresh();
151 | }
152 |
153 | function onSearchResults(e) {
154 | var frag = Y.one(Y.config.doc.createDocumentFragment());
155 |
156 | if (e.results.length) {
157 | YArray.each(e.results, function (result) {
158 | frag.append(result.display);
159 | });
160 | } else {
161 | frag.append(
162 | '' +
163 | 'No results found. Maybe you\'ll have better luck with a ' +
164 | 'different query?' +
165 | ' '
166 | );
167 | }
168 |
169 |
170 | focusManager.refresh();
171 | }
172 |
173 | function onTabSelectionChange(e) {
174 | var tab = e.newVal,
175 | name = tab.get('label').toLowerCase();
176 |
177 | tabs.selected = {
178 | index: tab.get('index'),
179 | name : name,
180 | tab : tab
181 | };
182 |
183 | switch (name) {
184 | case 'classes': // fallthru
185 | case 'modules':
186 | filter.setAttrs({
187 | minQueryLength: 0,
188 | queryType : name
189 | });
190 |
191 | search.set('minQueryLength', -1);
192 |
193 | // Only send a request if this isn't the initially-selected tab.
194 | if (e.prevVal) {
195 | filter.sendRequest(filter.get('value'));
196 | }
197 | break;
198 |
199 | case 'everything':
200 | filter.set('minQueryLength', -1);
201 | search.set('minQueryLength', 1);
202 |
203 | if (search.get('value')) {
204 | search.sendRequest(search.get('value'));
205 | } else {
206 | inputNode.focus();
207 | }
208 | break;
209 |
210 | default:
211 | // WTF? We shouldn't be here!
212 | filter.set('minQueryLength', -1);
213 | search.set('minQueryLength', -1);
214 | }
215 |
216 | if (focusManager) {
217 | setTimeout(function () {
218 | focusManager.refresh();
219 | }, 1);
220 | }
221 | }
222 |
223 | function onTabSwitchKey(e) {
224 | var currentTabIndex = tabs.selected.index;
225 |
226 | if (!(e.ctrlKey || e.metaKey)) {
227 | return;
228 | }
229 |
230 | e.preventDefault();
231 |
232 | switch (e.keyCode) {
233 | case 37: // left arrow
234 | if (currentTabIndex > 0) {
235 | tabview.selectChild(currentTabIndex - 1);
236 | inputNode.focus();
237 | }
238 | break;
239 |
240 | case 39: // right arrow
241 | if (currentTabIndex < (Y.Object.size(tabs) - 2)) {
242 | tabview.selectChild(currentTabIndex + 1);
243 | inputNode.focus();
244 | }
245 | break;
246 | }
247 | }
248 |
249 | }, '3.4.0', {requires: [
250 | 'api-filter', 'api-search', 'event-key', 'node-focusmanager', 'tabview'
251 | ]});
252 |
--------------------------------------------------------------------------------
/docs/assets/js/api-search.js:
--------------------------------------------------------------------------------
1 | YUI.add('api-search', function (Y) {
2 |
3 | var Lang = Y.Lang,
4 | Node = Y.Node,
5 | YArray = Y.Array;
6 |
7 | Y.APISearch = Y.Base.create('apiSearch', Y.Base, [Y.AutoCompleteBase], {
8 | // -- Public Properties ----------------------------------------------------
9 | RESULT_TEMPLATE:
10 | '' +
11 | '' +
12 | '{name} ' +
13 | '{resultType} ' +
14 | '{description}
' +
15 | '{class} ' +
16 | ' ' +
17 | ' ',
18 |
19 | // -- Initializer ----------------------------------------------------------
20 | initializer: function () {
21 | this._bindUIACBase();
22 | this._syncUIACBase();
23 | },
24 |
25 | // -- Protected Methods ----------------------------------------------------
26 | _apiResultFilter: function (query, results) {
27 | // Filter components out of the results.
28 | return YArray.filter(results, function (result) {
29 | return result.raw.resultType === 'component' ? false : result;
30 | });
31 | },
32 |
33 | _apiResultFormatter: function (query, results) {
34 | return YArray.map(results, function (result) {
35 | var raw = Y.merge(result.raw), // create a copy
36 | desc = raw.description || '';
37 |
38 | // Convert description to text and truncate it if necessary.
39 | desc = Node.create('' + desc + '
').get('text');
40 |
41 | if (desc.length > 65) {
42 | desc = Y.Escape.html(desc.substr(0, 65)) + ' …';
43 | } else {
44 | desc = Y.Escape.html(desc);
45 | }
46 |
47 | raw['class'] || (raw['class'] = '');
48 | raw.description = desc;
49 |
50 | // Use the highlighted result name.
51 | raw.name = result.highlighted;
52 |
53 | return Lang.sub(this.RESULT_TEMPLATE, raw);
54 | }, this);
55 | },
56 |
57 | _apiTextLocator: function (result) {
58 | return result.displayName || result.name;
59 | }
60 | }, {
61 | // -- Attributes -----------------------------------------------------------
62 | ATTRS: {
63 | resultFormatter: {
64 | valueFn: function () {
65 | return this._apiResultFormatter;
66 | }
67 | },
68 |
69 | resultFilters: {
70 | valueFn: function () {
71 | return this._apiResultFilter;
72 | }
73 | },
74 |
75 | resultHighlighter: {
76 | value: 'phraseMatch'
77 | },
78 |
79 | resultListLocator: {
80 | value: 'data.results'
81 | },
82 |
83 | resultTextLocator: {
84 | valueFn: function () {
85 | return this._apiTextLocator;
86 | }
87 | },
88 |
89 | source: {
90 | value: '/api/v1/search?q={query}&count={maxResults}'
91 | }
92 | }
93 | });
94 |
95 | }, '3.4.0', {requires: [
96 | 'autocomplete-base', 'autocomplete-highlighters', 'autocomplete-sources',
97 | 'escape'
98 | ]});
99 |
--------------------------------------------------------------------------------
/docs/assets/js/apidocs.js:
--------------------------------------------------------------------------------
1 | YUI().use(
2 | 'yuidoc-meta',
3 | 'api-list', 'history-hash', 'node-screen', 'node-style', 'pjax',
4 | function (Y) {
5 |
6 | var win = Y.config.win,
7 | localStorage = win.localStorage,
8 |
9 | bdNode = Y.one('#bd'),
10 |
11 | pjax,
12 | defaultRoute,
13 |
14 | classTabView,
15 | selectedTab;
16 |
17 | // Kill pjax functionality unless serving over HTTP.
18 | if (!Y.getLocation().protocol.match(/^https?\:/)) {
19 | Y.Router.html5 = false;
20 | }
21 |
22 | // Create the default route with middleware which enables syntax highlighting
23 | // on the loaded content.
24 | defaultRoute = Y.Pjax.defaultRoute.concat(function (req, res, next) {
25 | prettyPrint();
26 | bdNode.removeClass('loading');
27 |
28 | next();
29 | });
30 |
31 | pjax = new Y.Pjax({
32 | container : '#docs-main',
33 | contentSelector: '#docs-main > .content',
34 | linkSelector : '#bd a',
35 | titleSelector : '#xhr-title',
36 |
37 | navigateOnHash: true,
38 | root : '/',
39 | routes : [
40 | // -- / ----------------------------------------------------------------
41 | {
42 | path : '/(index.html)?',
43 | callbacks: defaultRoute
44 | },
45 |
46 | // -- /classes/* -------------------------------------------------------
47 | {
48 | path : '/classes/:class.html*',
49 | callbacks: [defaultRoute, 'handleClasses']
50 | },
51 |
52 | // -- /files/* ---------------------------------------------------------
53 | {
54 | path : '/files/*file',
55 | callbacks: [defaultRoute, 'handleFiles']
56 | },
57 |
58 | // -- /modules/* -------------------------------------------------------
59 | {
60 | path : '/modules/:module.html*',
61 | callbacks: defaultRoute
62 | }
63 | ]
64 | });
65 |
66 | // -- Utility Functions --------------------------------------------------------
67 |
68 | pjax.checkVisibility = function (tab) {
69 | tab || (tab = selectedTab);
70 |
71 | if (!tab) { return; }
72 |
73 | var panelNode = tab.get('panelNode'),
74 | visibleItems;
75 |
76 | // If no items are visible in the tab panel due to the current visibility
77 | // settings, display a message to that effect.
78 | visibleItems = panelNode.all('.item,.index-item').some(function (itemNode) {
79 | if (itemNode.getComputedStyle('display') !== 'none') {
80 | return true;
81 | }
82 | });
83 |
84 | panelNode.all('.no-visible-items').remove();
85 |
86 | if (!visibleItems) {
87 | if (Y.one('#index .index-item')) {
88 | panelNode.append(
89 | '' +
90 | '
' +
91 | 'Some items are not shown due to the current visibility ' +
92 | 'settings. Use the checkboxes at the upper right of this ' +
93 | 'page to change the visibility settings.' +
94 | '
' +
95 | '
'
96 | );
97 | } else {
98 | panelNode.append(
99 | '' +
100 | '
' +
101 | 'This class doesn\'t provide any methods, properties, ' +
102 | 'attributes, or events.' +
103 | '
' +
104 | '
'
105 | );
106 | }
107 | }
108 |
109 | // Hide index sections without any visible items.
110 | Y.all('.index-section').each(function (section) {
111 | var items = 0,
112 | visibleItems = 0;
113 |
114 | section.all('.index-item').each(function (itemNode) {
115 | items += 1;
116 |
117 | if (itemNode.getComputedStyle('display') !== 'none') {
118 | visibleItems += 1;
119 | }
120 | });
121 |
122 | section.toggleClass('hidden', !visibleItems);
123 | section.toggleClass('no-columns', visibleItems < 4);
124 | });
125 | };
126 |
127 | pjax.initClassTabView = function () {
128 | if (!Y.all('#classdocs .api-class-tab').size()) {
129 | return;
130 | }
131 |
132 | if (classTabView) {
133 | classTabView.destroy();
134 | selectedTab = null;
135 | }
136 |
137 | classTabView = new Y.TabView({
138 | srcNode: '#classdocs',
139 |
140 | on: {
141 | selectionChange: pjax.onTabSelectionChange
142 | }
143 | });
144 |
145 | pjax.updateTabState();
146 | classTabView.render();
147 | };
148 |
149 | pjax.initLineNumbers = function () {
150 | var hash = win.location.hash.substring(1),
151 | container = pjax.get('container'),
152 | hasLines, node;
153 |
154 | // Add ids for each line number in the file source view.
155 | container.all('.linenums>li').each(function (lineNode, index) {
156 | lineNode.set('id', 'l' + (index + 1));
157 | lineNode.addClass('file-line');
158 | hasLines = true;
159 | });
160 |
161 | // Scroll to the desired line.
162 | if (hasLines && /^l\d+$/.test(hash)) {
163 | if ((node = container.getById(hash))) {
164 | win.scroll(0, node.getY());
165 | }
166 | }
167 | };
168 |
169 | pjax.initRoot = function () {
170 | var terminators = /^(?:classes|files|modules)$/,
171 | parts = pjax._getPathRoot().split('/'),
172 | root = [],
173 | i, len, part;
174 |
175 | for (i = 0, len = parts.length; i < len; i += 1) {
176 | part = parts[i];
177 |
178 | if (part.match(terminators)) {
179 | // Makes sure the path will end with a "/".
180 | root.push('');
181 | break;
182 | }
183 |
184 | root.push(part);
185 | }
186 |
187 | pjax.set('root', root.join('/'));
188 | };
189 |
190 | pjax.updateTabState = function (src) {
191 | var hash = win.location.hash.substring(1),
192 | defaultTab, node, tab, tabPanel;
193 |
194 | function scrollToNode() {
195 | if (node.hasClass('protected')) {
196 | Y.one('#api-show-protected').set('checked', true);
197 | pjax.updateVisibility();
198 | }
199 |
200 | if (node.hasClass('private')) {
201 | Y.one('#api-show-private').set('checked', true);
202 | pjax.updateVisibility();
203 | }
204 |
205 | setTimeout(function () {
206 | // For some reason, unless we re-get the node instance here,
207 | // getY() always returns 0.
208 | var node = Y.one('#classdocs').getById(hash);
209 | win.scrollTo(0, node.getY() - 70);
210 | }, 1);
211 | }
212 |
213 | if (!classTabView) {
214 | return;
215 | }
216 |
217 | if (src === 'hashchange' && !hash) {
218 | defaultTab = 'index';
219 | } else {
220 | if (localStorage) {
221 | defaultTab = localStorage.getItem('tab_' + pjax.getPath()) ||
222 | 'index';
223 | } else {
224 | defaultTab = 'index';
225 | }
226 | }
227 |
228 | if (hash && (node = Y.one('#classdocs').getById(hash))) {
229 | if ((tabPanel = node.ancestor('.api-class-tabpanel', true))) {
230 | if ((tab = Y.one('#classdocs .api-class-tab.' + tabPanel.get('id')))) {
231 | if (classTabView.get('rendered')) {
232 | Y.Widget.getByNode(tab).set('selected', 1);
233 | } else {
234 | tab.addClass('yui3-tab-selected');
235 | }
236 | }
237 | }
238 |
239 | // Scroll to the desired element if this is a hash URL.
240 | if (node) {
241 | if (classTabView.get('rendered')) {
242 | scrollToNode();
243 | } else {
244 | classTabView.once('renderedChange', scrollToNode);
245 | }
246 | }
247 | } else {
248 | tab = Y.one('#classdocs .api-class-tab.' + defaultTab);
249 |
250 | // When the `defaultTab` node isn't found, `localStorage` is stale.
251 | if (!tab && defaultTab !== 'index') {
252 | tab = Y.one('#classdocs .api-class-tab.index');
253 | }
254 |
255 | if (classTabView.get('rendered')) {
256 | Y.Widget.getByNode(tab).set('selected', 1);
257 | } else {
258 | tab.addClass('yui3-tab-selected');
259 | }
260 | }
261 | };
262 |
263 | pjax.updateVisibility = function () {
264 | var container = pjax.get('container');
265 |
266 | container.toggleClass('hide-inherited',
267 | !Y.one('#api-show-inherited').get('checked'));
268 |
269 | container.toggleClass('show-deprecated',
270 | Y.one('#api-show-deprecated').get('checked'));
271 |
272 | container.toggleClass('show-protected',
273 | Y.one('#api-show-protected').get('checked'));
274 |
275 | container.toggleClass('show-private',
276 | Y.one('#api-show-private').get('checked'));
277 |
278 | pjax.checkVisibility();
279 | };
280 |
281 | // -- Route Handlers -----------------------------------------------------------
282 |
283 | pjax.handleClasses = function (req, res, next) {
284 | var status = res.ioResponse.status;
285 |
286 | // Handles success and local filesystem XHRs.
287 | if (!status || (status >= 200 && status < 300)) {
288 | pjax.initClassTabView();
289 | }
290 |
291 | next();
292 | };
293 |
294 | pjax.handleFiles = function (req, res, next) {
295 | var status = res.ioResponse.status;
296 |
297 | // Handles success and local filesystem XHRs.
298 | if (!status || (status >= 200 && status < 300)) {
299 | pjax.initLineNumbers();
300 | }
301 |
302 | next();
303 | };
304 |
305 | // -- Event Handlers -----------------------------------------------------------
306 |
307 | pjax.onNavigate = function (e) {
308 | var hash = e.hash,
309 | originTarget = e.originEvent && e.originEvent.target,
310 | tab;
311 |
312 | if (hash) {
313 | tab = originTarget && originTarget.ancestor('.yui3-tab', true);
314 |
315 | if (hash === win.location.hash) {
316 | pjax.updateTabState('hashchange');
317 | } else if (!tab) {
318 | win.location.hash = hash;
319 | }
320 |
321 | e.preventDefault();
322 | return;
323 | }
324 |
325 | // Only scroll to the top of the page when the URL doesn't have a hash.
326 | this.set('scrollToTop', !e.url.match(/#.+$/));
327 |
328 | bdNode.addClass('loading');
329 | };
330 |
331 | pjax.onOptionClick = function (e) {
332 | pjax.updateVisibility();
333 | };
334 |
335 | pjax.onTabSelectionChange = function (e) {
336 | var tab = e.newVal,
337 | tabId = tab.get('contentBox').getAttribute('href').substring(1);
338 |
339 | selectedTab = tab;
340 |
341 | // If switching from a previous tab (i.e., this is not the default tab),
342 | // replace the history entry with a hash URL that will cause this tab to
343 | // be selected if the user navigates away and then returns using the back
344 | // or forward buttons.
345 | if (e.prevVal && localStorage) {
346 | localStorage.setItem('tab_' + pjax.getPath(), tabId);
347 | }
348 |
349 | pjax.checkVisibility(tab);
350 | };
351 |
352 | // -- Init ---------------------------------------------------------------------
353 |
354 | pjax.on('navigate', pjax.onNavigate);
355 |
356 | pjax.initRoot();
357 | pjax.upgrade();
358 | pjax.initClassTabView();
359 | pjax.initLineNumbers();
360 | pjax.updateVisibility();
361 |
362 | Y.APIList.rootPath = pjax.get('root');
363 |
364 | Y.one('#api-options').delegate('click', pjax.onOptionClick, 'input');
365 |
366 | Y.on('hashchange', function (e) {
367 | pjax.updateTabState('hashchange');
368 | }, win);
369 |
370 | });
371 |
--------------------------------------------------------------------------------
/docs/assets/js/yui-prettify.js:
--------------------------------------------------------------------------------
1 | YUI().use('node', function(Y) {
2 | var code = Y.all('.prettyprint.linenums');
3 | if (code.size()) {
4 | code.each(function(c) {
5 | var lis = c.all('ol li'),
6 | l = 1;
7 | lis.each(function(n) {
8 | n.prepend(' ');
9 | l++;
10 | });
11 | });
12 | var h = location.hash;
13 | location.hash = '';
14 | h = h.replace('LINE_', 'LINENUM_');
15 | location.hash = h;
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/docs/assets/vendor/prettify/CHANGES.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Change Log
5 |
6 |
7 | README
8 |
9 | Known Issues
10 |
11 | Perl formatting is really crappy. Partly because the author is lazy and
12 | partly because Perl is
13 | hard to parse.
14 | On some browsers, <code>
elements with newlines in the text
15 | which use CSS to specify white-space:pre
will have the newlines
16 | improperly stripped if the element is not attached to the document at the time
17 | the stripping is done. Also, on IE 6, all newlines will be stripped from
18 | <code>
elements because of the way IE6 produces
19 | innerHTML
. Workaround: use <pre>
for code with
20 | newlines.
21 |
22 |
23 | Change Log
24 | 29 March 2007
25 |
26 | Added tests for PHP support
27 | to address
28 | issue 3 .
30 | Fixed
31 | bug : prettyPrintOne
was not halting. This was not
33 | reachable through the normal entry point.
34 | Fixed
35 | bug : recursing into a script block or PHP tag that was not properly
37 | closed would not silently drop the content.
38 | (test )
39 | Fixed
40 | bug : was eating tabs
42 | (test )
43 | Fixed entity handling so that the caveat
44 |
45 | Caveats: please properly escape less-thans. x<y
46 | instead of x<y , and use " instead of
47 | " for string delimiters.
48 |
49 | is no longer applicable.
50 | Added noisefree's C#
51 | patch
53 | Added a distribution that has comments and
54 | whitespace removed to reduce download size from 45.5kB to 12.8kB.
55 |
56 | 4 Jul 2008
57 |
58 | Added language specific formatters that are triggered by the presence
59 | of a lang-<language-file-extension>
60 | Fixed bug : python handling of '''string'''
61 | Fixed bug: /
in regex [charsets] should not end regex
62 |
63 | 5 Jul 2008
64 |
65 | Defined language extensions for Lisp and Lua
66 |
67 | 14 Jul 2008
68 |
69 | Language handlers for F#, OCAML, SQL
70 | Support for nocode
spans to allow embedding of line
71 | numbers and code annotations which should not be styled or otherwise
72 | affect the tokenization of prettified code.
73 | See the issue 22
74 | testcase .
75 |
76 | 6 Jan 2009
77 |
78 | Language handlers for Visual Basic, Haskell, CSS, and WikiText
79 | Added .mxml extension to the markup style handler for
80 | Flex MXML files . See
81 | issue 37 .
84 | Added .m extension to the C style handler so that Objective
85 | C source files properly highlight. See
86 | issue 58 .
89 | Changed HTML lexer to use the same embedded source mechanism as the
90 | wiki language handler, and changed to use the registered
91 | CSS handler for STYLE element content.
92 |
93 | 21 May 2009
94 |
95 | Rewrote to improve performance on large files.
96 | See benchmarks .
97 | Fixed bugs with highlighting of Haskell line comments, Lisp
98 | number literals, Lua strings, C preprocessor directives,
99 | newlines in Wiki code on Windows, and newlines in IE6.
100 |
101 | 14 August 2009
102 |
103 | Fixed prettifying of <code>
blocks with embedded newlines.
104 |
105 | 3 October 2009
106 |
107 | Fixed prettifying of XML/HTML tags that contain uppercase letters.
108 |
109 | 19 July 2010
110 |
111 | Added support for line numbers. Bug
112 | 22
114 | Added YAML support. Bug
115 | 123
117 | Added VHDL support courtesy Le Poussin.
118 | IE performance improvements. Bug
119 | 102 courtesy jacobly.
121 | A variety of markup formatting fixes courtesy smain and thezbyg.
122 | Fixed copy and paste in IE[678].
123 | Changed output to use  
instead of
124 |
so that the output works when embedded in XML.
125 | Bug
126 | 108 .
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/docs/assets/vendor/prettify/COPYING:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/docs/assets/vendor/prettify/README.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | Javascript code prettifier
7 |
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 | Languages : CH
20 | Javascript code prettifier
21 |
22 | Setup
23 |
24 | Download a distribution
25 | Include the script and stylesheets in your document
26 | (you will need to make sure the css and js file are on your server, and
27 | adjust the paths in the script and link tag)
28 |
29 | <link href="prettify.css" type="text/css" rel="stylesheet" />
30 | <script type="text/javascript" src="prettify.js"></script>
31 | Add onload="prettyPrint()"
to your
32 | document's body tag.
33 | Modify the stylesheet to get the coloring you prefer
34 |
35 |
36 | Usage
37 | Put code snippets in
38 | <pre class="prettyprint">...</pre>
39 | or <code class="prettyprint">...</code>
40 | and it will automatically be pretty printed.
41 |
42 |
43 |
44 | The original
45 | Prettier
46 |
47 | class Voila {
49 | public:
50 | // Voila
51 | static const string VOILA = "Voila";
52 |
53 | // will not interfere with embedded tags .
54 | }
55 |
56 | class Voila {
57 | public:
58 | // Voila
59 | static const string VOILA = "Voila";
60 |
61 | // will not interfere with embedded tags .
62 | }
63 |
64 |
65 | FAQ
66 | Which languages does it work for?
67 | The comments in prettify.js are authoritative but the lexer
68 | should work on a number of languages including C and friends,
69 | Java, Python, Bash, SQL, HTML, XML, CSS, Javascript, and Makefiles.
70 | It works passably on Ruby, PHP, VB, and Awk and a decent subset of Perl
71 | and Ruby, but, because of commenting conventions, doesn't work on
72 | Smalltalk, or CAML-like languages.
73 |
74 | LISPy languages are supported via an extension:
75 | lang-lisp.js
.
77 | And similarly for
78 | CSS
,
80 | Haskell
,
82 | Lua
,
84 | OCAML, SML, F#
,
86 | Visual Basic
,
88 | SQL
,
90 | Protocol Buffers
, and
92 | WikiText
..
94 |
95 |
If you'd like to add an extension for your favorite language, please
96 | look at src/lang-lisp.js and file an
97 | issue including your language extension, and a testcase.
99 |
100 | How do I specify which language my code is in?
101 | You don't need to specify the language since prettyprint()
102 | will guess. You can specify a language by specifying the language extension
103 | along with the prettyprint
class like so:
104 | <pre class="prettyprint lang-html ">
106 | The lang-* class specifies the language file extensions.
107 | File extensions supported by default include
108 | "bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html",
109 | "java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
110 | "xhtml", "xml", "xsl".
111 | </pre>
112 |
113 | It doesn't work on <obfuscated code sample> ?
114 | Yes. Prettifying obfuscated code is like putting lipstick on a pig
115 | — i.e. outside the scope of this tool.
116 |
117 | Which browsers does it work with?
118 | It's been tested with IE 6, Firefox 1.5 & 2, and Safari 2.0.4.
119 | Look at the test page to see if it
120 | works in your browser.
121 |
122 | What's changed?
123 | See the change log
124 |
125 | Why doesn't Prettyprinting of strings work on WordPress?
126 | Apparently wordpress does "smart quoting" which changes close quotes.
127 | This causes end quotes to not match up with open quotes.
128 |
This breaks prettifying as well as copying and pasting of code samples.
129 | See
130 | WordPress's help center for info on how to stop smart quoting of code
132 | snippets.
133 |
134 | How do I put line numbers in my code?
135 | You can use the linenums
class to turn on line
136 | numbering. If your code doesn't start at line number 1, you can
137 | add a colon and a line number to the end of that class as in
138 | linenums:52
.
139 |
140 |
For example
141 |
<pre class="prettyprint linenums:4 "
142 | >// This is line 4.
143 | foo();
144 | bar();
145 | baz();
146 | boo();
147 | far();
148 | faz();
149 | <pre>
150 | produces
151 | // This is line 4.
153 | foo();
154 | bar();
155 | baz();
156 | boo();
157 | far();
158 | faz();
159 |
160 |
161 | How do I prevent a portion of markup from being marked as code?
162 | You can use the nocode
class to identify a span of markup
163 | that is not code.
164 |
<pre class=prettyprint>
165 | int x = foo(); /* This is a comment <span class="nocode">This is not code</span>
166 | Continuation of comment */
167 | int y = bar();
168 | </pre>
169 | produces
170 |
171 | int x = foo(); /* This is a comment This is not code
172 | Continuation of comment */
173 | int y = bar();
174 |
175 |
176 | For a more complete example see the issue22
177 | testcase .
178 |
179 | I get an error message "a is not a function" or "opt_whenDone is not a function"
180 | If you are calling prettyPrint
via an event handler, wrap it in a function.
181 | Instead of doing
182 |
183 | addEventListener('load', prettyPrint, false);
185 |
186 | wrap it in a closure like
187 |
188 | addEventListener('load', function (event) { prettyPrint() }, false);
190 |
191 | so that the browser does not pass an event object to prettyPrint
which
192 | will confuse it.
193 |
194 |
195 |
196 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/docs/assets/vendor/prettify/prettify-min.css:
--------------------------------------------------------------------------------
1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
--------------------------------------------------------------------------------
/docs/assets/vendor/prettify/prettify-min.js:
--------------------------------------------------------------------------------
1 | window.PR_SHOULD_USE_CONTINUATION=true;var prettyPrintOne;var prettyPrint;(function(){var O=window;var j=["break,continue,do,else,for,if,return,while"];var v=[j,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var q=[v,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var m=[q,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var y=[q,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var T=[y,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"];var s="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes";var x=[q,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var t="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var J=[j,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var g=[j,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var I=[j,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var B=[m,T,x,t+J,g,I];var f=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;var D="str";var A="kwd";var k="com";var Q="typ";var H="lit";var M="pun";var G="pln";var n="tag";var F="dec";var K="src";var R="atn";var o="atv";var P="nocode";var N="(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function l(ab){var af=0;var U=false;var ae=false;for(var X=0,W=ab.length;X122)){if(!(am<65||ai>90)){ah.push([Math.max(65,ai)|32,Math.min(am,90)|32])}if(!(am<97||ai>122)){ah.push([Math.max(97,ai)&~32,Math.min(am,122)&~32])}}}}ah.sort(function(aw,av){return(aw[0]-av[0])||(av[1]-aw[1])});var ak=[];var aq=[];for(var at=0;atau[0]){if(au[1]+1>au[0]){ao.push("-")}ao.push(V(au[1]))}}ao.push("]");return ao.join("")}function Y(an){var al=an.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var aj=al.length;var ap=[];for(var am=0,ao=0;am=2&&ak==="["){al[am]=Z(ai)}else{if(ak!=="\\"){al[am]=ai.replace(/[a-zA-Z]/g,function(aq){var ar=aq.charCodeAt(0);return"["+String.fromCharCode(ar&~32,ar|32)+"]"})}}}}return al.join("")}var ac=[];for(var X=0,W=ab.length;X=0;){U[ae.charAt(ag)]=aa}}var ah=aa[1];var ac=""+ah;if(!ai.hasOwnProperty(ac)){aj.push(ah);ai[ac]=null}}aj.push(/[\0-\uffff]/);X=l(aj)})();var Z=V.length;var Y=function(aj){var ab=aj.sourceCode,aa=aj.basePos;var af=[aa,G];var ah=0;var ap=ab.match(X)||[];var al={};for(var ag=0,at=ap.length;ag=5&&"lang-"===ar.substring(0,5);if(ao&&!(ak&&typeof ak[1]==="string")){ao=false;ar=K}if(!ao){al[ai]=ar}}var ad=ah;ah+=ai.length;if(!ao){af.push(aa+ad,ar)}else{var an=ak[1];var am=ai.indexOf(an);var ae=am+an.length;if(ak[2]){ae=ai.length-ak[2].length;am=ae-an.length}var au=ar.substring(5);C(aa+ad,ai.substring(0,am),Y,af);C(aa+ad+am,an,r(au,an),af);C(aa+ad+ae,ai.substring(ae),Y,af)}}aj.decorations=af};return Y}function i(V){var Y=[],U=[];if(V.tripleQuotedStrings){Y.push([D,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(V.multiLineStrings){Y.push([D,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{Y.push([D,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(V.verbatimStrings){U.push([D,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var ab=V.hashComments;if(ab){if(V.cStyleComments){if(ab>1){Y.push([k,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{Y.push([k,/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}U.push([D,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null])}else{Y.push([k,/^#[^\r\n]*/,null,"#"])}}if(V.cStyleComments){U.push([k,/^\/\/[^\r\n]*/,null]);U.push([k,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(V.regexLiterals){var aa=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");U.push(["lang-regex",new RegExp("^"+N+"("+aa+")")])}var X=V.types;if(X){U.push([Q,X])}var W=(""+V.keywords).replace(/^ | $/g,"");if(W.length){U.push([A,new RegExp("^(?:"+W.replace(/[\s,]+/g,"|")+")\\b"),null])}Y.push([G,/^\s+/,null," \r\n\t\xA0"]);var Z=/^.[^\s\w\.$@\'\"\`\/\\]*/;U.push([H,/^@[a-z_$][a-z_$@0-9]*/i,null],[Q,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[G,/^[a-z_$][a-z_$@0-9]*/i,null],[H,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[G,/^\\[\s\S]?/,null],[M,Z,null]);return h(Y,U)}var L=i({keywords:B,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function S(W,ah,aa){var V=/(?:^|\s)nocode(?:\s|$)/;var ac=/\r\n?|\n/;var ad=W.ownerDocument;var ag=ad.createElement("li");while(W.firstChild){ag.appendChild(W.firstChild)}var X=[ag];function af(am){switch(am.nodeType){case 1:if(V.test(am.className)){break}if("br"===am.nodeName){ae(am);if(am.parentNode){am.parentNode.removeChild(am)}}else{for(var ao=am.firstChild;ao;ao=ao.nextSibling){af(ao)}}break;case 3:case 4:if(aa){var an=am.nodeValue;var ak=an.match(ac);if(ak){var aj=an.substring(0,ak.index);am.nodeValue=aj;var ai=an.substring(ak.index+ak[0].length);if(ai){var al=am.parentNode;al.insertBefore(ad.createTextNode(ai),am.nextSibling)}ae(am);if(!aj){am.parentNode.removeChild(am)}}}break}}function ae(al){while(!al.nextSibling){al=al.parentNode;if(!al){return}}function aj(am,at){var ar=at?am.cloneNode(false):am;var ap=am.parentNode;if(ap){var aq=aj(ap,1);var ao=am.nextSibling;aq.appendChild(ar);for(var an=ao;an;an=ao){ao=an.nextSibling;aq.appendChild(an)}}return ar}var ai=aj(al.nextSibling,0);for(var ak;(ak=ai.parentNode)&&ak.nodeType===1;){ai=ak}X.push(ai)}for(var Z=0;Z=U){aj+=2}if(Y>=ar){ac+=2}}}finally{if(au){au.style.display=ak}}}var u={};function d(W,X){for(var U=X.length;--U>=0;){var V=X[U];if(!u.hasOwnProperty(V)){u[V]=W}else{if(O.console){console.warn("cannot override language handler %s",V)}}}}function r(V,U){if(!(V&&u.hasOwnProperty(V))){V=/^\s*]*(?:>|$)/],[k,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[M,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^
11 |
12 |
13 |
14 |
15 |
25 |
26 |
27 |
28 |
56 |
57 |
58 |
59 | Show:
60 |
61 |
62 | Inherited
63 |
64 |
65 |
66 |
67 | Protected
68 |
69 |
70 |
71 |
72 | Private
73 |
74 |
75 |
76 | Deprecated
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
File: source\core.js
86 |
87 |
88 |
89 | var rxIsInt = /^\d+$/,
90 | rxIsFloat = /^\d*\.\d+$|^\d+\.\d*$/,
91 | // If a string has leading or trailing space,
92 | // contains a comma double quote or a newline
93 | // it needs to be quoted in CSV output
94 | rxNeedsQuoting = /^\s|\s$|,|"|\n/,
95 | trim = (function () {
96 | // Fx 3.1 has a native trim function, it's about 10x faster, use it if it exists
97 | if (String.prototype.trim) {
98 | return function (s) {
99 | return s.trim();
100 | };
101 | }
102 | return function (s) {
103 | return s.replace(/^\s*/, '').replace(/\s*$/, '');
104 | };
105 | }()),
106 |
107 | isNumber = function (o) {
108 | return Object.prototype.toString.apply(o) === '[object Number]';
109 | },
110 |
111 | isString = function (o) {
112 | return Object.prototype.toString.apply(o) === '[object String]';
113 | },
114 |
115 | chomp = function (s) {
116 | if (s.charAt(s.length - 1) !== "\n") {
117 | // Does not end with \n, just return string
118 | return s;
119 | }
120 | // Remove the \n
121 | return s.substring(0, s.length - 1);
122 | },
123 |
124 | prepField = function (field) {
125 | if (isString(field)) {
126 | // Escape any " with double " ("")
127 | field = field.replace(/"/g, '""');
128 |
129 | // If the field starts or ends with whitespace, contains " or , or a newline or
130 | // is a string representing a number, quote it.
131 | if (rxNeedsQuoting.test(field) || rxIsInt.test(field) || rxIsFloat.test(field)) {
132 | field = '"' + field + '"';
133 | // quote empty strings
134 | } else if (field === "") {
135 | field = '""';
136 | }
137 | } else if (isNumber(field)) {
138 | field = field.toString(10);
139 | } else if (field === null || field === undefined) {
140 | field = '';
141 | } else {
142 | field = field.toString();
143 | }
144 | return field;
145 | },
146 |
147 | CSV = {
148 | /**
149 | Converts an array into a Comma Separated Values string.
150 | Each item in the array should be an array that represents one row in the CSV.
151 | Nulls and undefined values are interpreted as empty fields.
152 |
153 | @method arrayToCsv
154 | @param {String} a The array to convert
155 |
156 | @returns {String} A CSV representation of the provided array.
157 | @for CSV
158 | @public
159 | @static
160 | @example
161 | var csv,
162 | books = [
163 | ['JavaScript: The Good Parts', 'Crockford, Douglas', 2008],
164 | ['Object-Oriented JavaScript', 'Stefanov, Stoyan', 2008],
165 | ['Effective JavaScript', 'Herman, David', 2012]
166 | ];
167 |
168 | csv = CSV.arrayToCsv(books);
169 |
170 | // csv now contains:
171 | //
172 | // JavaScript: The Good Parts,"Crockford, Douglas",2008\n
173 | // Object-Oriented JavaScript,"Stefanov, Stoyan",2008\n
174 | // Effective JavaScript,"Herman, David",2012\n
175 | */
176 | arrayToCsv: function (a) {
177 | var cur,
178 | out = '',
179 | row,
180 | i,
181 | j;
182 |
183 | for (i = 0; i < a.length; i += 1) {
184 | row = a[i];
185 | for (j = 0; j < row.length; j += 1) {
186 | cur = row[j];
187 |
188 | cur = prepField(cur);
189 |
190 | out += j < row.length - 1 ? cur + ',' : cur;
191 | }
192 | // End record
193 | out += "\n";
194 | }
195 |
196 | return out;
197 | },
198 |
199 | /**
200 | Converts a Comma Separated Values string into a multi-dimensional array.
201 | Each row in the CSV becomes an array.
202 | Empty fields are converted to nulls and non-quoted numbers are converted to integers or floats.
203 |
204 | @method csvToArray
205 | @return {Array} The CSV parsed as an array
206 | @param {String} s The string to convert
207 | @param {Object} [config] Object literal with extra configuration. For historical reasons setting config to `true` is the same as passing `{trim: true}`, but this usage is deprecated and will likely be removed in the next version.
208 | @param {Boolean} [config.trim=false] If set to True leading and trailing whitespace is stripped off of each non-quoted field as it is imported
209 | @for CSV
210 | @static
211 | @example
212 | var books,
213 | csv = 'JavaScript: The Good Parts,"Crockford, Douglas",2008\n' +
214 | 'Object-Oriented JavaScript,"Stefanov, Stoyan",2008\n' +
215 | 'Effective JavaScript,"Herman, David",2012\n';
216 |
217 | books = CSV.csvToArray(csv);
218 |
219 | // books now equals:
220 | // [
221 | // ['JavaScript: The Good Parts', 'Crockford, Douglas', 2008],
222 | // ['Object-Oriented JavaScript', 'Stefanov, Stoyan', 2008],
223 | // ['Effective JavaScript', 'Herman, David', 2012]
224 | // ];
225 | */
226 | csvToArray: function (s, config) {
227 | // Get rid of any trailing \n
228 | s = chomp(s);
229 |
230 | if (config === true) {
231 | config = {
232 | trim: true
233 | };
234 | } else {
235 | config = config || {};
236 | }
237 |
238 | var cur = '', // The character we are currently processing.
239 | inQuote = false,
240 | fieldQuoted = false,
241 | field = '', // Buffer for building up the current field
242 | row = [],
243 | out = [],
244 | trimIt = config.trim === true ? true : false,
245 | i,
246 | processField = function (field) {
247 | var trimmedField = trim(field);
248 | if (fieldQuoted !== true) {
249 | // If field is empty set to null
250 | if (field === '') {
251 | field = null;
252 | // If the field was not quoted and we are trimming fields, trim it
253 | } else if (trimIt === true) {
254 | field = trimmedField;
255 | }
256 |
257 | // Convert unquoted numbers to numbers
258 | if (rxIsInt.test(trimmedField) || rxIsFloat.test(trimmedField)) {
259 | field = +trimmedField;
260 | }
261 | }
262 | return field;
263 | };
264 |
265 | for (i = 0; i < s.length; i += 1) {
266 | cur = s.charAt(i);
267 |
268 | // If we are at a EOF or EOR
269 | if (inQuote === false && (cur === ',' || cur === "\n")) {
270 | field = processField(field);
271 | // Add the current field to the current row
272 | row.push(field);
273 | // If this is EOR append row to output and flush row
274 | if (cur === "\n") {
275 | out.push(row);
276 | row = [];
277 | }
278 | // Flush the field buffer
279 | field = '';
280 | fieldQuoted = false;
281 | } else {
282 | // If it's not a ", add it to the field buffer
283 | if (cur !== '"') {
284 | field += cur;
285 | } else {
286 | if (!inQuote) {
287 | // We are not in a quote, start a quote
288 | inQuote = true;
289 | fieldQuoted = true;
290 | } else {
291 | // Next char is ", this is an escaped "
292 | if (s.charAt(i + 1) === '"') {
293 | field += '"';
294 | // Skip the next char
295 | i += 1;
296 | } else {
297 | // It's not escaping, so end quote
298 | inQuote = false;
299 | }
300 | }
301 | }
302 | }
303 | }
304 |
305 | // Add the last field
306 | field = processField(field);
307 | row.push(field);
308 | out.push(row);
309 |
310 | return out;
311 | },
312 | /**
313 | Converts a Comma Separated Values string into an array of objects.
314 | Each row in the CSV becomes an object with properties named after each column.
315 | Empty fields are converted to nulls and non-quoted numbers are converted to integers or floats.
316 |
317 | @method csvToObject
318 | @since 1.2.0
319 | @return {Array} The CSV parsed as an array of objects
320 | @param {String} s The string containing CSV data to convert
321 | @param {Object} config Object literal with extra configuration
322 | @param {Array} [config.columns] An array containing the name of each column in the CSV data. If not
323 | provided, the first row of the CSV data is assumed to contain the column names.
324 | @param {Boolean} [config.trim] If true any field parsed from the CSV data will have leading and
325 | trailing whitespace trimmed
326 | @for CSV
327 | @static
328 | @example
329 | var books,
330 | csv = 'title,author,year\n' +
331 | 'JavaScript: The Good Parts,"Crockford, Douglas",2008\n' +
332 | 'Object-Oriented JavaScript,"Stefanov, Stoyan",2008\n' +
333 | 'Effective JavaScript,"Herman, David",2012\n';
334 |
335 | books = CSV.csvToObject(csv);
336 |
337 | // books now equals:
338 | // [
339 | // {
340 | // title: 'JavaScript: The Good Parts',
341 | // author: 'Crockford, Douglas',
342 | // year: 2008
343 | // },
344 | // {
345 | // title: 'Object-Oriented JavaScript',
346 | // author: 'Stefanov, Stoyan',
347 | // year: 2008
348 | // },
349 | // {
350 | // title: 'Effective JavaScript',
351 | // author: 'Herman, David',
352 | // year: 2012
353 | // }
354 | // ];
355 | */
356 | csvToObject: function (s, config) {
357 | config = config !== undefined ? config : {};
358 | var columns = config.columns,
359 | trimIt = !!config.trim,
360 | csvArray = this.csvToArray(s, trimIt);
361 |
362 | // if columns were not provided, assume they are
363 | // in the first row
364 | if (!columns) {
365 | columns = csvArray.shift();
366 | }
367 |
368 | return csvArray.map(function (row) {
369 | var obj = {},
370 | i = 0,
371 | len = columns.length;
372 | for (; i < len; i += 1) {
373 | obj[columns[i]] = row[i];
374 | }
375 | return obj;
376 | });
377 | },
378 |
379 | /**
380 | Converts an array of objects into Comma Separated Values data
381 | Each propery on the objects becomes a column in the CSV data.
382 |
383 | @method objectToCsv
384 | @since 1.2.0
385 | @return {String} CSV data, each row representing an object from the input array, each field representing a property from those objects
386 | @param {String} arr An array of objects to be converted into CSV
387 | @param {Object} config Object literal with extra configuration
388 | @param {Array} [config.columns] An array containing the name of each column in the CSV data. If not
389 | provided, the column names will be inferred from the property names of the objects. Explicitly
390 | defining column names has several advantages:
391 |
392 | * It is faster since all column names are already known.
393 | * It allows you to specify a subset of the properties to use if you wish to.
394 | * It allows you to control what order the columns are output in, since the `for...in` statement used to infer field names does not guarantee a specific order.
395 |
396 | @param {Boolean} [config.includeColumns=true] By default `objectToCsv` outputs the column names as
397 | the first row of the CSV data. Set to false to prevent this.
398 | @for CSV
399 | @static
400 | @example
401 | var csv,
402 | books = [
403 | {
404 | title: 'JavaScript: The Good Parts',
405 | author: 'Crockford, Douglas',
406 | year: 2008
407 | },
408 | {
409 | title: 'Object-Oriented JavaScript',
410 | author: 'Stefanov, Stoyan',
411 | year: 2008
412 | },
413 | {
414 | title: 'Effective JavaScript',
415 | author: 'Herman, David',
416 | year: 2012
417 | }
418 | ];
419 |
420 | csv = CSV.objectToCsv(books);
421 |
422 | // csv now contains:
423 | //
424 | // title,author,year\n
425 | // JavaScript: The Good Parts,"Crockford, Douglas",2008\n
426 | // Object-Oriented JavaScript,"Stefanov, Stoyan",2008\n
427 | // Effective JavaScript,"Herman, David",2012\n
428 | */
429 | objectToCsv: function (arr, config) {
430 | config = config !== undefined ? config : {};
431 | var columns = config.columns,
432 | includeColumns = config.includeColumns,
433 | csv = '',
434 | csvColumns = '',
435 | processKnownColumns = function (obj) {
436 | var out = '',
437 | prop,
438 | i,
439 | len = arr.length,
440 | j,
441 | jlen = columns.length;
442 |
443 | for (i = 0; i < len; i += 1) {
444 | obj = arr[i];
445 | for (j = 0; j < jlen; j += 1) {
446 | prop = columns[j];
447 | out += prepField(obj[prop]);
448 | out += j < jlen - 1 ? ',' : '';
449 | }
450 | out += '\n';
451 | }
452 | return out;
453 | },
454 | processUnknownColumns = function () {
455 | var cols = [],
456 | firstRowLength,
457 | finalRowLength,
458 | obj,
459 | prop,
460 | i,
461 | currentCol,
462 | len = arr.length,
463 | row,
464 | out = [];
465 |
466 | for (i = 0; i < len; i += 1) {
467 | obj = arr[i];
468 | row = [];
469 |
470 | // loop over all props in obj,
471 | for (prop in obj) {
472 | if (obj.hasOwnProperty(prop)) {
473 | currentCol = cols.indexOf(prop);
474 | // if this prop does not have a column yet
475 | if (currentCol === -1) {
476 | currentCol = cols.push(prop);
477 | currentCol -= 1;
478 | }
479 | row[currentCol] = prepField(obj[prop]);
480 | }
481 | }
482 |
483 | if (i === 0) {
484 | firstRowLength = row.length;
485 | }
486 |
487 | out.push(row);
488 | }
489 |
490 | finalRowLength = cols.length;
491 |
492 | // if some objects had properties that weren't on all the object
493 | // we need to resize each row.
494 | if (firstRowLength !== finalRowLength) {
495 | out.forEach(function (row) {
496 | row.length = finalRowLength;
497 | });
498 | }
499 |
500 | // export cols to our parent scope so
501 | // includeColumns can use it
502 | columns = cols;
503 |
504 | return out.map(function (row) {
505 | return row.join(',');
506 | }).join('\n') + '\n';
507 | };
508 |
509 | includeColumns = includeColumns === undefined ? true : !!includeColumns;
510 |
511 | if (columns !== undefined) {
512 | csv = processKnownColumns();
513 | } else {
514 | csv = processUnknownColumns();
515 | }
516 |
517 | if (includeColumns) {
518 | columns.forEach(function (col) {
519 | csvColumns += prepField(col) + ',';
520 | });
521 | csvColumns = csvColumns.substring(0, csvColumns.length - 1);
522 | csv = csvColumns + '\n' + csv;
523 | }
524 |
525 | return csv;
526 | }
527 | };
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |